mirror of
https://github.com/hanzoskill/mogcli.git
synced 2026-10-30 21:03:34 +00:00
539 lines
12 KiB
Go
539 lines
12 KiB
Go
package cli
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"net/url"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/visionik/mogcli/internal/testutil"
|
|
)
|
|
|
|
func TestContactsListCmd_Run(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cmd *ContactsListCmd
|
|
root *Root
|
|
mockResp []byte
|
|
mockErr error
|
|
wantErr bool
|
|
wantInOut string
|
|
}{
|
|
{
|
|
name: "successful list contacts",
|
|
cmd: &ContactsListCmd{Max: 50},
|
|
root: &Root{},
|
|
mockResp: mustJSON(map[string]interface{}{
|
|
"value": []map[string]interface{}{
|
|
{
|
|
"id": "contact-123",
|
|
"displayName": "John Doe",
|
|
"emailAddresses": []map[string]string{
|
|
{"address": "[email protected]"},
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
wantInOut: "John Doe",
|
|
},
|
|
{
|
|
name: "JSON output",
|
|
cmd: &ContactsListCmd{Max: 50},
|
|
root: &Root{JSON: true},
|
|
mockResp: mustJSON(map[string]interface{}{
|
|
"value": []map[string]interface{}{
|
|
{"id": "contact-123", "displayName": "Test User"},
|
|
},
|
|
}),
|
|
wantInOut: `"displayName": "Test User"`,
|
|
},
|
|
{
|
|
name: "API error",
|
|
cmd: &ContactsListCmd{Max: 50},
|
|
root: &Root{},
|
|
mockErr: errors.New("API error"),
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
mock := &testutil.MockClient{
|
|
GetFunc: func(ctx context.Context, path string, query url.Values) ([]byte, error) {
|
|
return tt.mockResp, tt.mockErr
|
|
},
|
|
}
|
|
tt.root.ClientFactory = mockClientFactory(mock)
|
|
|
|
var output string
|
|
err := error(nil)
|
|
output = captureOutput(func() {
|
|
err = tt.cmd.Run(tt.root)
|
|
})
|
|
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
if tt.wantInOut != "" {
|
|
assert.Contains(t, output, tt.wantInOut)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestContactsSearchCmd_Run(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cmd *ContactsSearchCmd
|
|
root *Root
|
|
mockResp []byte
|
|
mockErr error
|
|
wantErr bool
|
|
wantInOut string
|
|
}{
|
|
{
|
|
name: "successful search",
|
|
cmd: &ContactsSearchCmd{Query: "John"},
|
|
root: &Root{},
|
|
mockResp: mustJSON(map[string]interface{}{
|
|
"value": []map[string]interface{}{
|
|
{
|
|
"id": "contact-123",
|
|
"displayName": "John Doe",
|
|
"emailAddresses": []map[string]string{
|
|
{"address": "[email protected]"},
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
wantInOut: "John Doe",
|
|
},
|
|
{
|
|
name: "JSON output",
|
|
cmd: &ContactsSearchCmd{Query: "test"},
|
|
root: &Root{JSON: true},
|
|
mockResp: mustJSON(map[string]interface{}{
|
|
"value": []map[string]interface{}{
|
|
{"id": "contact-123", "displayName": "Test"},
|
|
},
|
|
}),
|
|
wantInOut: `"displayName": "Test"`,
|
|
},
|
|
{
|
|
name: "API error",
|
|
cmd: &ContactsSearchCmd{Query: "test"},
|
|
root: &Root{},
|
|
mockErr: errors.New("API error"),
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
mock := &testutil.MockClient{
|
|
GetFunc: func(ctx context.Context, path string, query url.Values) ([]byte, error) {
|
|
return tt.mockResp, tt.mockErr
|
|
},
|
|
}
|
|
tt.root.ClientFactory = mockClientFactory(mock)
|
|
|
|
var output string
|
|
err := error(nil)
|
|
output = captureOutput(func() {
|
|
err = tt.cmd.Run(tt.root)
|
|
})
|
|
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
if tt.wantInOut != "" {
|
|
assert.Contains(t, output, tt.wantInOut)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestContactsGetCmd_Run(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cmd *ContactsGetCmd
|
|
root *Root
|
|
mockResp []byte
|
|
mockErr error
|
|
wantErr bool
|
|
wantInOut string
|
|
}{
|
|
{
|
|
name: "successful get contact",
|
|
cmd: &ContactsGetCmd{ID: "contact-123"},
|
|
root: &Root{},
|
|
mockResp: mustJSON(map[string]interface{}{
|
|
"id": "contact-123",
|
|
"displayName": "John Doe",
|
|
"emailAddresses": []map[string]string{
|
|
{"address": "[email protected]"},
|
|
},
|
|
"businessPhones": []string{"555-1234"},
|
|
"mobilePhone": "555-5678",
|
|
"companyName": "Acme Inc",
|
|
"jobTitle": "Engineer",
|
|
}),
|
|
wantInOut: "John Doe",
|
|
},
|
|
{
|
|
name: "JSON output",
|
|
cmd: &ContactsGetCmd{ID: "contact-123"},
|
|
root: &Root{JSON: true},
|
|
mockResp: mustJSON(map[string]interface{}{
|
|
"id": "contact-123",
|
|
"displayName": "Test User",
|
|
}),
|
|
wantInOut: `"displayName": "Test User"`,
|
|
},
|
|
{
|
|
name: "contact not found",
|
|
cmd: &ContactsGetCmd{ID: "invalid"},
|
|
root: &Root{},
|
|
mockErr: errors.New("ResourceNotFound"),
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
mock := &testutil.MockClient{
|
|
GetFunc: func(ctx context.Context, path string, query url.Values) ([]byte, error) {
|
|
return tt.mockResp, tt.mockErr
|
|
},
|
|
}
|
|
tt.root.ClientFactory = mockClientFactory(mock)
|
|
|
|
var output string
|
|
err := error(nil)
|
|
output = captureOutput(func() {
|
|
err = tt.cmd.Run(tt.root)
|
|
})
|
|
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
if tt.wantInOut != "" {
|
|
assert.Contains(t, output, tt.wantInOut)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestContactsCreateCmd_Run(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cmd *ContactsCreateCmd
|
|
mockResp []byte
|
|
mockErr error
|
|
wantErr bool
|
|
wantInOut string
|
|
}{
|
|
{
|
|
name: "successful create with name only",
|
|
cmd: &ContactsCreateCmd{Name: "New Contact"},
|
|
mockResp: mustJSON(map[string]interface{}{
|
|
"id": "contact-new-123",
|
|
"displayName": "New Contact",
|
|
}),
|
|
wantInOut: "Contact created",
|
|
},
|
|
{
|
|
name: "create with all fields",
|
|
cmd: &ContactsCreateCmd{
|
|
Name: "Full Contact",
|
|
Email: "[email protected]",
|
|
Phone: "555-1234",
|
|
Company: "Company Inc",
|
|
Title: "Manager",
|
|
},
|
|
mockResp: mustJSON(map[string]interface{}{
|
|
"id": "contact-new-456",
|
|
"displayName": "Full Contact",
|
|
}),
|
|
wantInOut: "Contact created",
|
|
},
|
|
{
|
|
name: "API error",
|
|
cmd: &ContactsCreateCmd{Name: "Test"},
|
|
mockErr: errors.New("API error"),
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
mock := &testutil.MockClient{
|
|
PostFunc: func(ctx context.Context, path string, body interface{}) ([]byte, error) {
|
|
return tt.mockResp, tt.mockErr
|
|
},
|
|
}
|
|
root := &Root{ClientFactory: mockClientFactory(mock)}
|
|
|
|
var output string
|
|
err := error(nil)
|
|
output = captureOutput(func() {
|
|
err = tt.cmd.Run(root)
|
|
})
|
|
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
if tt.wantInOut != "" {
|
|
assert.Contains(t, output, tt.wantInOut)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestContactsUpdateCmd_Run(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cmd *ContactsUpdateCmd
|
|
mockErr error
|
|
wantErr bool
|
|
wantInOut string
|
|
}{
|
|
{
|
|
name: "successful update name",
|
|
cmd: &ContactsUpdateCmd{
|
|
ID: "contact-123",
|
|
Name: "Updated Name",
|
|
},
|
|
wantInOut: "Contact updated",
|
|
},
|
|
{
|
|
name: "update all fields",
|
|
cmd: &ContactsUpdateCmd{
|
|
ID: "contact-123",
|
|
Name: "Updated",
|
|
Email: "[email protected]",
|
|
Phone: "555-9999",
|
|
Company: "New Co",
|
|
Title: "Director",
|
|
},
|
|
wantInOut: "Contact updated",
|
|
},
|
|
{
|
|
name: "no updates specified",
|
|
cmd: &ContactsUpdateCmd{ID: "contact-123"},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "API error",
|
|
cmd: &ContactsUpdateCmd{
|
|
ID: "contact-123",
|
|
Name: "Update",
|
|
},
|
|
mockErr: errors.New("API error"),
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
mock := &testutil.MockClient{
|
|
PatchFunc: func(ctx context.Context, path string, body interface{}) ([]byte, error) {
|
|
return []byte(`{}`), tt.mockErr
|
|
},
|
|
}
|
|
root := &Root{ClientFactory: mockClientFactory(mock)}
|
|
|
|
var output string
|
|
err := error(nil)
|
|
output = captureOutput(func() {
|
|
err = tt.cmd.Run(root)
|
|
})
|
|
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
if tt.wantInOut != "" {
|
|
assert.Contains(t, output, tt.wantInOut)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestContactsDeleteCmd_Run(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cmd *ContactsDeleteCmd
|
|
mockErr error
|
|
wantErr bool
|
|
wantInOut string
|
|
}{
|
|
{
|
|
name: "successful delete",
|
|
cmd: &ContactsDeleteCmd{ID: "contact-123"},
|
|
wantInOut: "Contact deleted",
|
|
},
|
|
{
|
|
name: "API error",
|
|
cmd: &ContactsDeleteCmd{ID: "contact-123"},
|
|
mockErr: errors.New("API error"),
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
mock := &testutil.MockClient{
|
|
DeleteFunc: func(ctx context.Context, path string) error {
|
|
return tt.mockErr
|
|
},
|
|
}
|
|
root := &Root{ClientFactory: mockClientFactory(mock)}
|
|
|
|
var output string
|
|
err := error(nil)
|
|
output = captureOutput(func() {
|
|
err = tt.cmd.Run(root)
|
|
})
|
|
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
if tt.wantInOut != "" {
|
|
assert.Contains(t, output, tt.wantInOut)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestContactsDirectoryCmd_Run(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cmd *ContactsDirectoryCmd
|
|
root *Root
|
|
mockResp []byte
|
|
mockErr error
|
|
wantErr bool
|
|
wantInOut string
|
|
}{
|
|
{
|
|
name: "successful directory search",
|
|
cmd: &ContactsDirectoryCmd{Query: "john"},
|
|
root: &Root{},
|
|
mockResp: mustJSON(map[string]interface{}{
|
|
"value": []map[string]interface{}{
|
|
{
|
|
"id": "user-123",
|
|
"displayName": "John Smith",
|
|
"mail": "[email protected]",
|
|
"jobTitle": "Developer",
|
|
},
|
|
},
|
|
}),
|
|
wantInOut: "John Smith",
|
|
},
|
|
{
|
|
name: "JSON output",
|
|
cmd: &ContactsDirectoryCmd{Query: "test"},
|
|
root: &Root{JSON: true},
|
|
mockResp: mustJSON(map[string]interface{}{
|
|
"value": []map[string]interface{}{
|
|
{"id": "user-123", "displayName": "Test User"},
|
|
},
|
|
}),
|
|
wantInOut: `"displayName": "Test User"`,
|
|
},
|
|
{
|
|
name: "API error",
|
|
cmd: &ContactsDirectoryCmd{Query: "test"},
|
|
root: &Root{},
|
|
mockErr: errors.New("API error"),
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
mock := &testutil.MockClient{
|
|
GetFunc: func(ctx context.Context, path string, query url.Values) ([]byte, error) {
|
|
return tt.mockResp, tt.mockErr
|
|
},
|
|
}
|
|
tt.root.ClientFactory = mockClientFactory(mock)
|
|
|
|
var output string
|
|
err := error(nil)
|
|
output = captureOutput(func() {
|
|
err = tt.cmd.Run(tt.root)
|
|
})
|
|
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
if tt.wantInOut != "" {
|
|
assert.Contains(t, output, tt.wantInOut)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Test type unmarshaling
|
|
func TestContact_Unmarshal(t *testing.T) {
|
|
jsonData := `{
|
|
"id": "contact-123",
|
|
"displayName": "John Doe",
|
|
"emailAddresses": [
|
|
{"address": "[email protected]", "name": "John Doe"}
|
|
],
|
|
"businessPhones": ["555-1234", "555-5678"],
|
|
"mobilePhone": "555-9999",
|
|
"companyName": "Acme Inc",
|
|
"jobTitle": "Engineer"
|
|
}`
|
|
|
|
var contact Contact
|
|
err := json.Unmarshal([]byte(jsonData), &contact)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "contact-123", contact.ID)
|
|
assert.Equal(t, "John Doe", contact.DisplayName)
|
|
assert.Len(t, contact.EmailAddresses, 1)
|
|
assert.Equal(t, "[email protected]", contact.EmailAddresses[0].Address)
|
|
assert.Len(t, contact.BusinessPhones, 2)
|
|
assert.Equal(t, "555-9999", contact.MobilePhone)
|
|
assert.Equal(t, "Acme Inc", contact.CompanyName)
|
|
assert.Equal(t, "Engineer", contact.JobTitle)
|
|
}
|
|
|
|
func TestDirectoryUser_Unmarshal(t *testing.T) {
|
|
jsonData := `{
|
|
"id": "user-123",
|
|
"displayName": "John Smith",
|
|
"mail": "[email protected]",
|
|
"jobTitle": "Developer"
|
|
}`
|
|
|
|
var user DirectoryUser
|
|
err := json.Unmarshal([]byte(jsonData), &user)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "user-123", user.ID)
|
|
assert.Equal(t, "John Smith", user.DisplayName)
|
|
assert.Equal(t, "[email protected]", user.Mail)
|
|
assert.Equal(t, "Developer", user.JobTitle)
|
|
}
|