Skip to content

Commit 8e4c0aa

Browse files
authored
test: increase test coverage in cmd/ and internal/[api | config | deputil] (#392)
* test: increase test coverage in cmd/ and internal/api|config|deputil * test: rewrite api app tests as table-driven tests Consolidate GetAppStatus and ConnectionsOpen tests from separate ok/error functions into table-driven tests using the map pattern. * test: normalize test function names to use Test_ prefix convention * test: try to alphabetized app_test.go * test: refactor InitializeGlobalFlags to table-driven test with flag details
1 parent 7b3e445 commit 8e4c0aa

5 files changed

Lines changed: 424 additions & 0 deletions

File tree

cmd/datastore/query_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,3 +465,55 @@ func prepareExportMockData(cm *shared.ClientsMock, numberOfItems int, maxItemsTo
465465
}
466466
return data, nil
467467
}
468+
469+
func Test_getExpressionPatterns(t *testing.T) {
470+
tests := map[string]struct {
471+
expression string
472+
wantAttrs int
473+
wantVals int
474+
}{
475+
"expression with attributes and values": {
476+
expression: "#name = :name AND #status = :status",
477+
wantAttrs: 2,
478+
wantVals: 2,
479+
},
480+
"empty expression": {
481+
expression: "",
482+
wantAttrs: 0,
483+
wantVals: 0,
484+
},
485+
}
486+
for name, tc := range tests {
487+
t.Run(name, func(t *testing.T) {
488+
attrs, vals := getExpressionPatterns(tc.expression)
489+
assert.Len(t, attrs, tc.wantAttrs)
490+
assert.Len(t, vals, tc.wantVals)
491+
})
492+
}
493+
}
494+
495+
func Test_mapAttributeFlag(t *testing.T) {
496+
tests := map[string]struct {
497+
flag string
498+
wantErr bool
499+
}{
500+
"valid JSON": {
501+
flag: `{"#name":"name"}`,
502+
},
503+
"invalid JSON": {
504+
flag: `not json`,
505+
wantErr: true,
506+
},
507+
}
508+
for name, tc := range tests {
509+
t.Run(name, func(t *testing.T) {
510+
result, err := mapAttributeFlag(tc.flag)
511+
if tc.wantErr {
512+
assert.Error(t, err)
513+
} else {
514+
assert.NoError(t, err)
515+
assert.NotNil(t, result)
516+
}
517+
})
518+
}
519+
}

internal/api/app_test.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,44 @@ import (
3434
"github.com/stretchr/testify/require"
3535
)
3636

37+
func Test_Client_ConnectionsOpen(t *testing.T) {
38+
tests := map[string]struct {
39+
httpResponseJSON string
40+
wantErr bool
41+
errMessage string
42+
expectedURL string
43+
}{
44+
"OK result": {
45+
httpResponseJSON: `{"ok":true,"url":"wss://example.com/ws"}`,
46+
expectedURL: "wss://example.com/ws",
47+
},
48+
"Error result": {
49+
httpResponseJSON: `{"ok":false,"error":"token_revoked"}`,
50+
wantErr: true,
51+
errMessage: "token_revoked",
52+
},
53+
}
54+
for name, tc := range tests {
55+
t.Run(name, func(t *testing.T) {
56+
ctx := slackcontext.MockContext(t.Context())
57+
c, teardown := NewFakeClient(t, FakeClientParams{
58+
ExpectedMethod: appConnectionsOpenMethod,
59+
Response: tc.httpResponseJSON,
60+
})
61+
defer teardown()
62+
63+
result, err := c.ConnectionsOpen(ctx, "token")
64+
if tc.wantErr {
65+
require.Error(t, err)
66+
require.Contains(t, err.Error(), tc.errMessage)
67+
} else {
68+
require.NoError(t, err)
69+
require.Equal(t, tc.expectedURL, result.URL)
70+
}
71+
})
72+
}
73+
}
74+
3775
func TestClient_CreateApp_Ok(t *testing.T) {
3876
ctx := slackcontext.MockContext(t.Context())
3977
c, teardown := NewFakeClient(t, FakeClientParams{
@@ -80,6 +118,42 @@ func TestClient_ExportAppManifest_CommonErrors(t *testing.T) {
80118
})
81119
}
82120

121+
func Test_Client_GetAppStatus(t *testing.T) {
122+
tests := map[string]struct {
123+
httpResponseJSON string
124+
wantErr bool
125+
errMessage string
126+
}{
127+
"OK result": {
128+
httpResponseJSON: `{"ok":true,"apps":[{"app_id":"A123","status":"installed"}]}`,
129+
},
130+
"Error result": {
131+
httpResponseJSON: `{"ok":false,"error":"invalid_app"}`,
132+
wantErr: true,
133+
errMessage: "invalid_app",
134+
},
135+
}
136+
for name, tc := range tests {
137+
t.Run(name, func(t *testing.T) {
138+
ctx := slackcontext.MockContext(t.Context())
139+
c, teardown := NewFakeClient(t, FakeClientParams{
140+
ExpectedMethod: appStatusMethod,
141+
Response: tc.httpResponseJSON,
142+
})
143+
defer teardown()
144+
145+
result, err := c.GetAppStatus(ctx, "token", []string{"A123"}, "T123")
146+
if tc.wantErr {
147+
require.Error(t, err)
148+
require.Contains(t, err.Error(), tc.errMessage)
149+
} else {
150+
require.NoError(t, err)
151+
require.NotNil(t, result)
152+
}
153+
})
154+
}
155+
}
156+
83157
func TestClient_UpdateApp_OK(t *testing.T) {
84158
ctx := slackcontext.MockContext(t.Context())
85159
c, teardown := NewFakeClient(t, FakeClientParams{

internal/api/datastore_test.go

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,3 +490,192 @@ func TestClient_AppsDatastoreGet(t *testing.T) {
490490
})
491491
}
492492
}
493+
494+
func Test_Client_AppsDatastoreBulkPut(t *testing.T) {
495+
tests := map[string]struct {
496+
request types.AppDatastoreBulkPut
497+
httpResponseJSON string
498+
statusCode int
499+
wantErr bool
500+
errMessage string
501+
}{
502+
"success": {
503+
request: types.AppDatastoreBulkPut{
504+
Datastore: "my_ds",
505+
App: "A1",
506+
Items: []map[string]interface{}{{"id": "1", "name": "test"}},
507+
},
508+
httpResponseJSON: `{"ok":true,"datastore":"my_ds"}`,
509+
},
510+
"api_error": {
511+
request: types.AppDatastoreBulkPut{
512+
Datastore: "my_ds",
513+
App: "A1",
514+
Items: []map[string]interface{}{{"id": "1"}},
515+
},
516+
httpResponseJSON: `{"ok":false,"error":"datastore_error"}`,
517+
wantErr: true,
518+
errMessage: "datastore_error",
519+
},
520+
}
521+
for name, tc := range tests {
522+
t.Run(name, func(t *testing.T) {
523+
ctx := slackcontext.MockContext(t.Context())
524+
c, teardown := NewFakeClient(t, FakeClientParams{
525+
ExpectedMethod: appDatastoreBulkPutMethod,
526+
Response: tc.httpResponseJSON,
527+
StatusCode: tc.statusCode,
528+
})
529+
defer teardown()
530+
_, err := c.AppsDatastoreBulkPut(ctx, "token", tc.request)
531+
if tc.wantErr {
532+
require.Error(t, err)
533+
require.Contains(t, err.Error(), tc.errMessage)
534+
} else {
535+
require.NoError(t, err)
536+
}
537+
})
538+
}
539+
}
540+
541+
func Test_Client_AppsDatastoreCount(t *testing.T) {
542+
tests := map[string]struct {
543+
request types.AppDatastoreCount
544+
httpResponseJSON string
545+
statusCode int
546+
wantCount int
547+
wantErr bool
548+
errMessage string
549+
}{
550+
"success": {
551+
request: types.AppDatastoreCount{
552+
Datastore: "my_ds",
553+
App: "A1",
554+
},
555+
httpResponseJSON: `{"ok":true,"datastore":"my_ds","count":42}`,
556+
wantCount: 42,
557+
},
558+
"api_error": {
559+
request: types.AppDatastoreCount{
560+
Datastore: "my_ds",
561+
App: "A1",
562+
},
563+
httpResponseJSON: `{"ok":false,"error":"datastore_error"}`,
564+
wantErr: true,
565+
errMessage: "datastore_error",
566+
},
567+
}
568+
for name, tc := range tests {
569+
t.Run(name, func(t *testing.T) {
570+
ctx := slackcontext.MockContext(t.Context())
571+
c, teardown := NewFakeClient(t, FakeClientParams{
572+
ExpectedMethod: appDatastoreCountMethod,
573+
Response: tc.httpResponseJSON,
574+
StatusCode: tc.statusCode,
575+
})
576+
defer teardown()
577+
got, err := c.AppsDatastoreCount(ctx, "token", tc.request)
578+
if tc.wantErr {
579+
require.Error(t, err)
580+
require.Contains(t, err.Error(), tc.errMessage)
581+
} else {
582+
require.NoError(t, err)
583+
require.Equal(t, tc.wantCount, got.Count)
584+
}
585+
})
586+
}
587+
}
588+
589+
func Test_Client_AppsDatastoreBulkDelete(t *testing.T) {
590+
tests := map[string]struct {
591+
request types.AppDatastoreBulkDelete
592+
httpResponseJSON string
593+
statusCode int
594+
wantErr bool
595+
errMessage string
596+
}{
597+
"success": {
598+
request: types.AppDatastoreBulkDelete{
599+
Datastore: "my_ds",
600+
App: "A1",
601+
IDs: []string{"id1", "id2"},
602+
},
603+
httpResponseJSON: `{"ok":true}`,
604+
},
605+
"api_error": {
606+
request: types.AppDatastoreBulkDelete{
607+
Datastore: "my_ds",
608+
App: "A1",
609+
IDs: []string{"id1"},
610+
},
611+
httpResponseJSON: `{"ok":false,"error":"not_found"}`,
612+
wantErr: true,
613+
errMessage: "not_found",
614+
},
615+
}
616+
for name, tc := range tests {
617+
t.Run(name, func(t *testing.T) {
618+
ctx := slackcontext.MockContext(t.Context())
619+
c, teardown := NewFakeClient(t, FakeClientParams{
620+
ExpectedMethod: appDatastoreBulkDeleteMethod,
621+
Response: tc.httpResponseJSON,
622+
StatusCode: tc.statusCode,
623+
})
624+
defer teardown()
625+
_, err := c.AppsDatastoreBulkDelete(ctx, "token", tc.request)
626+
if tc.wantErr {
627+
require.Error(t, err)
628+
require.Contains(t, err.Error(), tc.errMessage)
629+
} else {
630+
require.NoError(t, err)
631+
}
632+
})
633+
}
634+
}
635+
636+
func Test_Client_AppsDatastoreBulkGet(t *testing.T) {
637+
tests := map[string]struct {
638+
request types.AppDatastoreBulkGet
639+
httpResponseJSON string
640+
statusCode int
641+
wantErr bool
642+
errMessage string
643+
}{
644+
"success": {
645+
request: types.AppDatastoreBulkGet{
646+
Datastore: "my_ds",
647+
App: "A1",
648+
IDs: []string{"id1", "id2"},
649+
},
650+
httpResponseJSON: `{"ok":true,"datastore":"my_ds","items":[{"id":"id1","name":"test"}]}`,
651+
},
652+
"api_error": {
653+
request: types.AppDatastoreBulkGet{
654+
Datastore: "my_ds",
655+
App: "A1",
656+
IDs: []string{"id1"},
657+
},
658+
httpResponseJSON: `{"ok":false,"error":"not_found"}`,
659+
wantErr: true,
660+
errMessage: "not_found",
661+
},
662+
}
663+
for name, tc := range tests {
664+
t.Run(name, func(t *testing.T) {
665+
ctx := slackcontext.MockContext(t.Context())
666+
c, teardown := NewFakeClient(t, FakeClientParams{
667+
ExpectedMethod: appDatastoreBulkGetMethod,
668+
Response: tc.httpResponseJSON,
669+
StatusCode: tc.statusCode,
670+
})
671+
defer teardown()
672+
_, err := c.AppsDatastoreBulkGet(ctx, "token", tc.request)
673+
if tc.wantErr {
674+
require.Error(t, err)
675+
require.Contains(t, err.Error(), tc.errMessage)
676+
} else {
677+
require.NoError(t, err)
678+
}
679+
})
680+
}
681+
}

0 commit comments

Comments
 (0)