-
Notifications
You must be signed in to change notification settings - Fork 31
test: increase test coverage in cmd/ and internal/[api | config | deputil] #392
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
a155ba5
28f1bf2
58c9c3f
c2f5c7e
e2e0ed5
c4dbb36
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
|---|---|---|
|
|
@@ -519,3 +519,77 @@ func TestClient_DeveloperAppInstall_RequestAppApproval(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 Test_Client_ConnectionsOpen(t *testing.T) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧮 quibble(non-blocking): Forgive me for not searching too much up, but if tests have alphabetical order in this file? 👾 ramble: I'd be curious if separating API methods into different files gives us the most confidence toward focused tests. Not something to change now of course, but it'd be curious pattern for ongoing additions!
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately, it's not alphabetized. The file looks like it started off being alphabetical, but after line 200, it's a free-for-all. Commit e2e0ed5 attempts to move these functions where they should be. A challenge with alphabetizing is that logically we want to group getters/setters but alphabetically they are separated. Something for us to think about.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Personally, I prefer small files would be open to a single file for each API method. But Golang tends to prefer fewer, longer files. That's probably why we are taking the current approach. |
||
| 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) | ||
| } | ||
| }) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,6 +24,44 @@ import ( | |
| "github.com/stretchr/testify/assert" | ||
| ) | ||
|
|
||
| func Test_SetFlags(t *testing.T) { | ||
| fs := slackdeps.NewFsMock() | ||
| os := slackdeps.NewOsMock() | ||
| config := NewConfig(fs, os) | ||
| cmd := &cobra.Command{} | ||
| cmd.Flags().String("test-flag", "default", "a test flag") | ||
|
|
||
| config.SetFlags(cmd) | ||
| assert.NotNil(t, config.Flags) | ||
| f := config.Flags.Lookup("test-flag") | ||
| assert.NotNil(t, f) | ||
| assert.Equal(t, "default", f.DefValue) | ||
| } | ||
|
|
||
| func Test_InitializeGlobalFlags(t *testing.T) { | ||
| fs := slackdeps.NewFsMock() | ||
| os := slackdeps.NewOsMock() | ||
| config := NewConfig(fs, os) | ||
| cmd := &cobra.Command{} | ||
|
|
||
| config.InitializeGlobalFlags(cmd) | ||
|
|
||
| // Verify that key persistent flags were registered | ||
| flagNames := []string{ | ||
| "apihost", "app", "config-dir", "experiment", | ||
| "force", "no-color", "skip-update", "slackdev", | ||
| "runtime", "team", "token", "verbose", | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧮 quibble: Separating these to newlines might be nice for fast reading. I assumed this was a map at first! Perhaps this can be a table test? tests := map[string]struct{
shorthand string
longform string
}{
"apihost": {
longform: "apihost",
},
"app": {
longform: "app",
shortform: "a",
},
}IIRC? Forgive me if
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| for _, name := range flagNames { | ||
| f := cmd.PersistentFlags().Lookup(name) | ||
| assert.NotNil(t, f, "flag %s should be registered", name) | ||
| } | ||
|
|
||
| // Verify hidden flags | ||
| assert.True(t, cmd.PersistentFlags().Lookup("apihost").Hidden) | ||
| assert.True(t, cmd.PersistentFlags().Lookup("slackdev").Hidden) | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. note: I went back-and-forth on whether to have this test, but it's nice to have a test that locks-in and confirms that our expected global flags and hidden flags haven't changed without intention. |
||
| } | ||
|
|
||
| func TestDeprecatedFlagSubstitutions(t *testing.T) { | ||
| tests := map[string]struct { | ||
| expectedWarnings []string | ||
|
|
||
There was a problem hiding this comment.
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
cmdlevel is preferred?There was a problem hiding this comment.
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!