Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions cmd/datastore/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -465,3 +465,55 @@ func prepareExportMockData(cm *shared.ClientsMock, numberOfItems int, maxItemsTo
}
return data, nil
}

func Test_getExpressionPatterns(t *testing.T) {
tests := map[string]struct {
expression string
wantAttrs int
wantVals int
}{
"expression with attributes and values": {
expression: "#name = :name AND #status = :status",
wantAttrs: 2,
wantVals: 2,
},
"empty expression": {
expression: "",
wantAttrs: 0,
wantVals: 0,
},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
attrs, vals := getExpressionPatterns(tc.expression)
assert.Len(t, attrs, tc.wantAttrs)
assert.Len(t, vals, tc.wantVals)
})
}
}

func Test_mapAttributeFlag(t *testing.T) {
tests := map[string]struct {
flag string
wantErr bool
}{
"valid JSON": {
flag: `{"#name":"name"}`,
},
"invalid JSON": {
flag: `not json`,
wantErr: true,
},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
result, err := mapAttributeFlag(tc.flag)
if tc.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.NotNil(t, result)
}
})
}
}
Comment on lines +495 to +519
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 thought: Unit tests matching each function is a kind pattern since IMHO it also encourages tests at the cmd level is preferred?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, I think we could actually reduce our overall tests and have the same coverage by testing through the command level. We've had success with some of the simpler, newer commands and hopefully we can bring that to the original, complex commands!

74 changes: 74 additions & 0 deletions internal/api/app_test.go
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⭐ praise: More praises for API tests! These are so good!

Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,44 @@ import (
"github.com/stretchr/testify/require"
)

func Test_Client_ConnectionsOpen(t *testing.T) {
tests := map[string]struct {
httpResponseJSON string
wantErr bool
errMessage string
expectedURL string
}{
"OK result": {
httpResponseJSON: `{"ok":true,"url":"wss://example.com/ws"}`,
expectedURL: "wss://example.com/ws",
},
"Error result": {
httpResponseJSON: `{"ok":false,"error":"token_revoked"}`,
wantErr: true,
errMessage: "token_revoked",
},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
ctx := slackcontext.MockContext(t.Context())
c, teardown := NewFakeClient(t, FakeClientParams{
ExpectedMethod: appConnectionsOpenMethod,
Response: tc.httpResponseJSON,
})
defer teardown()

result, err := c.ConnectionsOpen(ctx, "token")
if tc.wantErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.errMessage)
} else {
require.NoError(t, err)
require.Equal(t, tc.expectedURL, result.URL)
}
})
}
}

func TestClient_CreateApp_Ok(t *testing.T) {
ctx := slackcontext.MockContext(t.Context())
c, teardown := NewFakeClient(t, FakeClientParams{
Expand Down Expand Up @@ -80,6 +118,42 @@ func TestClient_ExportAppManifest_CommonErrors(t *testing.T) {
})
}

func Test_Client_GetAppStatus(t *testing.T) {
tests := map[string]struct {
httpResponseJSON string
wantErr bool
errMessage string
}{
"OK result": {
httpResponseJSON: `{"ok":true,"apps":[{"app_id":"A123","status":"installed"}]}`,
},
"Error result": {
httpResponseJSON: `{"ok":false,"error":"invalid_app"}`,
wantErr: true,
errMessage: "invalid_app",
},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
ctx := slackcontext.MockContext(t.Context())
c, teardown := NewFakeClient(t, FakeClientParams{
ExpectedMethod: appStatusMethod,
Response: tc.httpResponseJSON,
})
defer teardown()

result, err := c.GetAppStatus(ctx, "token", []string{"A123"}, "T123")
if tc.wantErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.errMessage)
} else {
require.NoError(t, err)
require.NotNil(t, result)
}
})
}
}

func TestClient_UpdateApp_OK(t *testing.T) {
ctx := slackcontext.MockContext(t.Context())
c, teardown := NewFakeClient(t, FakeClientParams{
Expand Down
189 changes: 189 additions & 0 deletions internal/api/datastore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -490,3 +490,192 @@ func TestClient_AppsDatastoreGet(t *testing.T) {
})
}
}

func Test_Client_AppsDatastoreBulkPut(t *testing.T) {
tests := map[string]struct {
request types.AppDatastoreBulkPut
httpResponseJSON string
statusCode int
wantErr bool
errMessage string
}{
"success": {
request: types.AppDatastoreBulkPut{
Datastore: "my_ds",
App: "A1",
Items: []map[string]interface{}{{"id": "1", "name": "test"}},
},
httpResponseJSON: `{"ok":true,"datastore":"my_ds"}`,
},
"api_error": {
request: types.AppDatastoreBulkPut{
Datastore: "my_ds",
App: "A1",
Items: []map[string]interface{}{{"id": "1"}},
},
httpResponseJSON: `{"ok":false,"error":"datastore_error"}`,
wantErr: true,
errMessage: "datastore_error",
},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
ctx := slackcontext.MockContext(t.Context())
c, teardown := NewFakeClient(t, FakeClientParams{
ExpectedMethod: appDatastoreBulkPutMethod,
Response: tc.httpResponseJSON,
StatusCode: tc.statusCode,
})
defer teardown()
_, err := c.AppsDatastoreBulkPut(ctx, "token", tc.request)
if tc.wantErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.errMessage)
} else {
require.NoError(t, err)
}
})
}
}

func Test_Client_AppsDatastoreCount(t *testing.T) {
tests := map[string]struct {
request types.AppDatastoreCount
httpResponseJSON string
statusCode int
wantCount int
wantErr bool
errMessage string
}{
"success": {
request: types.AppDatastoreCount{
Datastore: "my_ds",
App: "A1",
},
httpResponseJSON: `{"ok":true,"datastore":"my_ds","count":42}`,
wantCount: 42,
},
"api_error": {
request: types.AppDatastoreCount{
Datastore: "my_ds",
App: "A1",
},
httpResponseJSON: `{"ok":false,"error":"datastore_error"}`,
wantErr: true,
errMessage: "datastore_error",
},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
ctx := slackcontext.MockContext(t.Context())
c, teardown := NewFakeClient(t, FakeClientParams{
ExpectedMethod: appDatastoreCountMethod,
Response: tc.httpResponseJSON,
StatusCode: tc.statusCode,
})
defer teardown()
got, err := c.AppsDatastoreCount(ctx, "token", tc.request)
if tc.wantErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.errMessage)
} else {
require.NoError(t, err)
require.Equal(t, tc.wantCount, got.Count)
}
})
}
}

func Test_Client_AppsDatastoreBulkDelete(t *testing.T) {
tests := map[string]struct {
request types.AppDatastoreBulkDelete
httpResponseJSON string
statusCode int
wantErr bool
errMessage string
}{
"success": {
request: types.AppDatastoreBulkDelete{
Datastore: "my_ds",
App: "A1",
IDs: []string{"id1", "id2"},
},
httpResponseJSON: `{"ok":true}`,
},
"api_error": {
request: types.AppDatastoreBulkDelete{
Datastore: "my_ds",
App: "A1",
IDs: []string{"id1"},
},
httpResponseJSON: `{"ok":false,"error":"not_found"}`,
wantErr: true,
errMessage: "not_found",
},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
ctx := slackcontext.MockContext(t.Context())
c, teardown := NewFakeClient(t, FakeClientParams{
ExpectedMethod: appDatastoreBulkDeleteMethod,
Response: tc.httpResponseJSON,
StatusCode: tc.statusCode,
})
defer teardown()
_, err := c.AppsDatastoreBulkDelete(ctx, "token", tc.request)
if tc.wantErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.errMessage)
} else {
require.NoError(t, err)
}
})
}
}

func Test_Client_AppsDatastoreBulkGet(t *testing.T) {
tests := map[string]struct {
request types.AppDatastoreBulkGet
httpResponseJSON string
statusCode int
wantErr bool
errMessage string
}{
"success": {
request: types.AppDatastoreBulkGet{
Datastore: "my_ds",
App: "A1",
IDs: []string{"id1", "id2"},
},
httpResponseJSON: `{"ok":true,"datastore":"my_ds","items":[{"id":"id1","name":"test"}]}`,
},
"api_error": {
request: types.AppDatastoreBulkGet{
Datastore: "my_ds",
App: "A1",
IDs: []string{"id1"},
},
httpResponseJSON: `{"ok":false,"error":"not_found"}`,
wantErr: true,
errMessage: "not_found",
},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
ctx := slackcontext.MockContext(t.Context())
c, teardown := NewFakeClient(t, FakeClientParams{
ExpectedMethod: appDatastoreBulkGetMethod,
Response: tc.httpResponseJSON,
StatusCode: tc.statusCode,
})
defer teardown()
_, err := c.AppsDatastoreBulkGet(ctx, "token", tc.request)
if tc.wantErr {
require.Error(t, err)
require.Contains(t, err.Error(), tc.errMessage)
} else {
require.NoError(t, err)
}
})
}
}
Loading
Loading