diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 82f5af7..1f73031 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "3.1.6" + ".": "3.2.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 71fe91f..b63c0fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## 3.2.0 (2026-03-06) + +Full Changelog: [v3.1.6...v3.2.0](https://github.com/trycourier/courier-cli/compare/v3.1.6...v3.2.0) + +### Features + +* add `--max-items` flag for paginated/streaming endpoints ([1b04d3a](https://github.com/trycourier/courier-cli/commit/1b04d3ac7ba4296f61e0b0c857e2275032b0dbe0)) +* support passing required body params through pipes ([a555982](https://github.com/trycourier/courier-cli/commit/a555982030cb1767e781eeeb88c72a4de084fde9)) + + +### Bug Fixes + +* fix for encoding arrays with `any` type items ([e5d46ce](https://github.com/trycourier/courier-cli/commit/e5d46ce9dfc8fce75ad022d7056b9844d0aed4c2)) + + +### Chores + +* **internal:** codegen related update ([05da3b8](https://github.com/trycourier/courier-cli/commit/05da3b8bce65dc6b4418aafa51e163bbc29e8275)) + ## 3.1.6 (2026-03-04) Full Changelog: [v3.1.5...v3.1.6](https://github.com/trycourier/courier-cli/compare/v3.1.5...v3.1.6) diff --git a/internal/apiform/encoder.go b/internal/apiform/encoder.go index 16ca44b..857fe14 100644 --- a/internal/apiform/encoder.go +++ b/internal/apiform/encoder.go @@ -101,6 +101,15 @@ func (e *encoder) encodeArray(key string, val reflect.Value, writer *multipart.W var values []string for i := 0; i < val.Len(); i++ { item := val.Index(i) + if (item.Kind() == reflect.Pointer || item.Kind() == reflect.Interface) && item.IsNil() { + // Null values are sent as an empty string + values = append(values, "") + continue + } + // If item is an interface, reduce it to the concrete type + if item.Kind() == reflect.Interface { + item = item.Elem() + } var strValue string switch item.Kind() { case reflect.String: diff --git a/internal/binaryparam/binary_param.go b/internal/binaryparam/binary_param.go index 79357a3..40d4ecf 100644 --- a/internal/binaryparam/binary_param.go +++ b/internal/binaryparam/binary_param.go @@ -17,7 +17,7 @@ func FileOrStdin(stdin io.ReadCloser, path string) (io.ReadCloser, bool, error) // When the special glyph "-" is used, read from stdin. Although probably less necessary, also support // special Unix files that refer to stdin. switch path { - case stdinGlyph, "/dev/fd/0", "/dev/stdin": + case "", stdinGlyph, "/dev/fd/0", "/dev/stdin": return stdin, true, nil } diff --git a/internal/binaryparam/binary_param_test.go b/internal/binaryparam/binary_param_test.go index bdac3e9..7a66682 100644 --- a/internal/binaryparam/binary_param_test.go +++ b/internal/binaryparam/binary_param_test.go @@ -28,57 +28,32 @@ func TestFileOrStdin(t *testing.T) { require.False(t, stdinInUse) }) - t.Run("WithStdinGlyph", func(t *testing.T) { - tempFile := t.TempDir() + "/test_file.txt" - require.NoError(t, os.WriteFile(tempFile, []byte(expectedContents), 0600)) - - stubStdin, err := os.Open(tempFile) - require.NoError(t, err) - t.Cleanup(func() { require.NoError(t, stubStdin.Close()) }) - - readCloser, stdinInUse, err := FileOrStdin(stubStdin, "-") - require.NoError(t, err) - - actualContents, err := io.ReadAll(readCloser) - require.NoError(t, err) - require.Equal(t, expectedContents, string(actualContents)) - - require.True(t, stdinInUse) - }) - - t.Run("WithDevFD0File", func(t *testing.T) { - tempFile := t.TempDir() + "/dev_fd_0" - require.NoError(t, os.WriteFile(tempFile, []byte(expectedContents), 0600)) - - stubStdin, err := os.Open(tempFile) - require.NoError(t, err) - t.Cleanup(func() { require.NoError(t, stubStdin.Close()) }) - - readCloser, stdinInUse, err := FileOrStdin(stubStdin, "/dev/fd/0") - require.NoError(t, err) - - actualContents, err := io.ReadAll(readCloser) - require.NoError(t, err) - require.Equal(t, expectedContents, string(actualContents)) - - require.True(t, stdinInUse) - }) - - t.Run("WithDevStdinFile", func(t *testing.T) { - tempFile := t.TempDir() + "/dev_stdin" - require.NoError(t, os.WriteFile(tempFile, []byte(expectedContents), 0600)) - - stubStdin, err := os.Open(tempFile) - require.NoError(t, err) - t.Cleanup(func() { require.NoError(t, stubStdin.Close()) }) - - readCloser, stdinInUse, err := FileOrStdin(stubStdin, "/dev/stdin") - require.NoError(t, err) - - actualContents, err := io.ReadAll(readCloser) - require.NoError(t, err) - require.Equal(t, expectedContents, string(actualContents)) - - require.True(t, stdinInUse) - }) + stdinTests := []struct { + testName string + path string + }{ + {"TestEmptyString", ""}, + {"TestDash", "-"}, + {"TestDevStdin", "/dev/stdin"}, + {"TestDevFD0", "/dev/fd/0"}, + } + for _, test := range stdinTests { + t.Run(test.testName, func(t *testing.T) { + tempFile := t.TempDir() + "/test_file.txt" + require.NoError(t, os.WriteFile(tempFile, []byte(expectedContents), 0600)) + + stubStdin, err := os.Open(tempFile) + require.NoError(t, err) + t.Cleanup(func() { require.NoError(t, stubStdin.Close()) }) + + readCloser, stdinInUse, err := FileOrStdin(stubStdin, test.path) + require.NoError(t, err) + + actualContents, err := io.ReadAll(readCloser) + require.NoError(t, err) + require.Equal(t, expectedContents, string(actualContents)) + + require.True(t, stdinInUse) + }) + } } diff --git a/internal/mocktest/mocktest.go b/internal/mocktest/mocktest.go index 0548a00..460e219 100644 --- a/internal/mocktest/mocktest.go +++ b/internal/mocktest/mocktest.go @@ -1,6 +1,7 @@ package mocktest import ( + "bytes" "context" "fmt" "net" @@ -14,6 +15,7 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -54,8 +56,14 @@ func restoreNetwork(origClient, origDefault http.RoundTripper) { } // TestRunMockTestWithFlags runs a test against a mock server with the provided -// CLI flags and ensures it succeeds -func TestRunMockTestWithFlags(t *testing.T, flags ...string) { +// CLI args and ensures it succeeds +func TestRunMockTestWithFlags(t *testing.T, args ...string) { + TestRunMockTestWithPipeAndFlags(t, nil, args...) +} + +// TestRunMockTestWithPipeAndFlags runs a test against a mock server with the provided +// data piped over stdin and CLI args and ensures it succeeds +func TestRunMockTestWithPipeAndFlags(t *testing.T, pipeData []byte, args ...string) { origClient, origDefault := blockNetworkExceptMockServer() defer restoreNetwork(origClient, origDefault) @@ -71,52 +79,18 @@ func TestRunMockTestWithFlags(t *testing.T, flags ...string) { _, filename, _, ok := runtime.Caller(0) require.True(t, ok, "Could not get current file path") dirPath := filepath.Dir(filename) - project := filepath.Join(dirPath, "..", "..", "cmd", "...") - - args := []string{"run", project, "--base-url", mockServerURL.String()} - args = append(args, flags...) - - t.Logf("Testing command: courier %s", strings.Join(args[4:], " ")) - - cliCmd := exec.Command("go", args...) - - // Pipe the CLI tool's output into `head` so it doesn't hang when simulating - // paginated or streamed endpoints. 100 lines of output should be enough to - // test that the API endpoint worked, or report back a meaningful amount of - // data if something went wrong. - headCmd := exec.Command("head", "-n", "100") - pipe, err := cliCmd.StdoutPipe() - require.NoError(t, err, "Failed to create pipe for CLI command") - headCmd.Stdin = pipe - - // Capture `head` output and CLI command stderr outputs: - var output strings.Builder - headCmd.Stdout = &output - headCmd.Stderr = &output - cliCmd.Stderr = &output - - // First start `head`, so it's ready for data to come in: - err = headCmd.Start() - require.NoError(t, err, "Failed to start `head` command") - - // Next start the CLI command so it can pipe data to `head` without - // buffering any data in advance: - err = cliCmd.Start() - require.NoError(t, err, "Failed to start CLI command") - - // Ensure that the stdout pipe is closed as soon as `head` exits, to let the - // CLI tool know that no more output is needed and it can stop streaming - // test data for streaming/paginated endpoints. This needs to happen before - // calling `cliCmd.Wait()`, otherwise there will be a deadlock. - err = headCmd.Wait() - pipe.Close() - require.NoError(t, err, "`head` command finished with an error") - - // Finally, wait for the CLI tool to finish up: - err = cliCmd.Wait() - require.NoError(t, err, "CLI command failed\n%s", output.String()) - - t.Logf("Test passed successfully\nOutput:\n%s", output.String()) + project := filepath.Join(dirPath, "..", "..", "cmd", "courier") + + args = append([]string{"run", project, "--base-url", mockServerURL.String()}, args...) + + t.Logf("Testing command: go run ./cmd/courier %s", strings.Join(args[2:], " ")) + + cmd := exec.Command("go", args...) + cmd.Stdin = bytes.NewReader(pipeData) + output, err := cmd.CombinedOutput() + assert.NoError(t, err, "Test failed\nError: %v\nOutput: %s", err, output) + + t.Logf("Test passed successfully\nOutput:\n%s", string(output)) } func TestFile(t *testing.T, contents string) string { diff --git a/internal/requestflag/requestflag.go b/internal/requestflag/requestflag.go index cb11412..986afed 100644 --- a/internal/requestflag/requestflag.go +++ b/internal/requestflag/requestflag.go @@ -110,6 +110,40 @@ func ExtractRequestContents(cmd *cli.Command) RequestContents { return res } +func GetMissingRequiredFlags(cmd *cli.Command, body any) []cli.Flag { + missing := []cli.Flag{} + for _, flag := range cmd.Flags { + if flag.IsSet() { + continue + } + + if required, ok := flag.(cli.RequiredFlag); ok && required.IsRequired() { + missing = append(missing, flag) + continue + } + + if r, ok := flag.(RequiredFlagOrStdin); !ok || !r.IsRequiredAsFlagOrStdin() { + continue + } + + if toSend, ok := flag.(InRequest); ok { + if toSend.IsBodyRoot() { + if body != nil { + continue + } + } else if bodyPath := toSend.GetBodyPath(); bodyPath != "" { + if bodyMap, ok := body.(map[string]any); ok { + if _, found := bodyMap[bodyPath]; found { + continue + } + } + } + } + missing = append(missing, flag) + } + return missing +} + // Implementation of the cli.Flag interface var _ cli.Flag = (*Flag[any])(nil) // Type assertion to ensure interface compliance @@ -221,6 +255,19 @@ func (f *Flag[T]) SetCategory(c string) { var _ cli.RequiredFlag = (*Flag[any])(nil) // Type assertion to ensure interface compliance func (f *Flag[T]) IsRequired() bool { + // Intentionally don't use `f.Required`, because request flags may be passed + // over stdin as well as by flag. + if f.BodyPath != "" || f.BodyRoot { + return false + } + return f.Required +} + +type RequiredFlagOrStdin interface { + IsRequiredAsFlagOrStdin() bool +} + +func (f *Flag[T]) IsRequiredAsFlagOrStdin() bool { return f.Required } diff --git a/pkg/cmd/audience_test.go b/pkg/cmd/audience_test.go index 1652020..ae000eb 100644 --- a/pkg/cmd/audience_test.go +++ b/pkg/cmd/audience_test.go @@ -11,69 +11,95 @@ import ( func TestAudiencesRetrieve(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "audiences", "retrieve", - "--api-key", "string", - "--audience-id", "audience_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "audiences", "retrieve", + "--api-key", "string", + "--audience-id", "audience_id", + ) + }) } func TestAudiencesUpdate(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "audiences", "update", - "--api-key", "string", - "--audience-id", "audience_id", - "--description", "description", - "--filter", "{filters: [{operator: operator, filters: [], path: path, value: value}]}", - "--name", "name", - "--operator", "AND", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "audiences", "update", + "--api-key", "string", + "--audience-id", "audience_id", + "--description", "description", + "--filter", "{filters: [{operator: operator, filters: [], path: path, value: value}]}", + "--name", "name", + "--operator", "AND", + ) + }) - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(audiencesUpdate) + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(audiencesUpdate) - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "audiences", "update", - "--audience-id", "audience_id", - "--description", "description", - "--filter.filters", "[{operator: operator, filters: [], path: path, value: value}]", - "--name", "name", - "--operator", "AND", - ) + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "audiences", "update", + "--api-key", "string", + "--audience-id", "audience_id", + "--description", "description", + "--filter.filters", "[{operator: operator, filters: [], path: path, value: value}]", + "--name", "name", + "--operator", "AND", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "description: description\n" + + "filter:\n" + + " filters:\n" + + " - operator: operator\n" + + " filters: []\n" + + " path: path\n" + + " value: value\n" + + "name: name\n" + + "operator: AND\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "audiences", "update", + "--api-key", "string", + "--audience-id", "audience_id", + ) + }) } func TestAudiencesList(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "audiences", "list", - "--api-key", "string", - "--cursor", "cursor", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "audiences", "list", + "--api-key", "string", + "--cursor", "cursor", + ) + }) } func TestAudiencesDelete(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "audiences", "delete", - "--api-key", "string", - "--audience-id", "audience_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "audiences", "delete", + "--api-key", "string", + "--audience-id", "audience_id", + ) + }) } func TestAudiencesListMembers(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "audiences", "list-members", - "--api-key", "string", - "--audience-id", "audience_id", - "--cursor", "cursor", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "audiences", "list-members", + "--api-key", "string", + "--audience-id", "audience_id", + "--cursor", "cursor", + ) + }) } diff --git a/pkg/cmd/auditevent_test.go b/pkg/cmd/auditevent_test.go index be6179e..badb758 100644 --- a/pkg/cmd/auditevent_test.go +++ b/pkg/cmd/auditevent_test.go @@ -10,20 +10,22 @@ import ( func TestAuditEventsRetrieve(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "audit-events", "retrieve", - "--api-key", "string", - "--audit-event-id", "audit-event-id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "audit-events", "retrieve", + "--api-key", "string", + "--audit-event-id", "audit-event-id", + ) + }) } func TestAuditEventsList(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "audit-events", "list", - "--api-key", "string", - "--cursor", "cursor", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "audit-events", "list", + "--api-key", "string", + "--cursor", "cursor", + ) + }) } diff --git a/pkg/cmd/auth_test.go b/pkg/cmd/auth_test.go index 642004c..fb43a32 100644 --- a/pkg/cmd/auth_test.go +++ b/pkg/cmd/auth_test.go @@ -10,11 +10,25 @@ import ( func TestAuthIssueToken(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "auth", "issue-token", - "--api-key", "string", - "--expires-in", "$YOUR_NUMBER days", - "--scope", "user_id:$YOUR_USER_ID write:user-tokens inbox:read:messages inbox:write:events read:preferences write:preferences read:brands", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "auth", "issue-token", + "--api-key", "string", + "--expires-in", "$YOUR_NUMBER days", + "--scope", "user_id:$YOUR_USER_ID write:user-tokens inbox:read:messages inbox:write:events read:preferences write:preferences read:brands", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "expires_in: $YOUR_NUMBER days\n" + + "scope: >-\n" + + " user_id:$YOUR_USER_ID write:user-tokens inbox:read:messages inbox:write:events\n" + + " read:preferences write:preferences read:brands\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "auth", "issue-token", + "--api-key", "string", + ) + }) } diff --git a/pkg/cmd/automation_test.go b/pkg/cmd/automation_test.go index e70ec30..3f3030b 100644 --- a/pkg/cmd/automation_test.go +++ b/pkg/cmd/automation_test.go @@ -10,11 +10,12 @@ import ( func TestAutomationsList(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "automations", "list", - "--api-key", "string", - "--cursor", "cursor", - "--version", "published", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "automations", "list", + "--api-key", "string", + "--cursor", "cursor", + "--version", "published", + ) + }) } diff --git a/pkg/cmd/automationinvoke_test.go b/pkg/cmd/automationinvoke_test.go index 30f2405..1f0f2d2 100644 --- a/pkg/cmd/automationinvoke_test.go +++ b/pkg/cmd/automationinvoke_test.go @@ -11,46 +11,97 @@ import ( func TestAutomationsInvokeInvokeAdHoc(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "automations:invoke", "invoke-ad-hoc", - "--api-key", "string", - "--automation", "{steps: [{action: delay, duration: duration, until: 20240408T080910.123}, {action: send, brand: brand, data: {foo: bar}, profile: {foo: bar}, recipient: recipient, template: 64TP5HKPFTM8VTK1Y75SJDQX9JK0}], cancelation_token: delay-send--user-yes--abc-123}", - "--brand", "brand", - "--data", "{name: bar}", - "--profile", "{tenant_id: bar}", - "--recipient", "user-yes", - "--template", "template", - ) - - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(automationsInvokeInvokeAdHoc) - - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "automations:invoke", "invoke-ad-hoc", - "--automation.steps", "[{action: delay, duration: duration, until: 20240408T080910.123}, {action: send, brand: brand, data: {foo: bar}, profile: {foo: bar}, recipient: recipient, template: 64TP5HKPFTM8VTK1Y75SJDQX9JK0}]", - "--automation.cancelation-token", "delay-send--user-yes--abc-123", - "--brand", "brand", - "--data", "{name: bar}", - "--profile", "{tenant_id: bar}", - "--recipient", "user-yes", - "--template", "template", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "automations:invoke", "invoke-ad-hoc", + "--api-key", "string", + "--automation", "{steps: [{action: delay, duration: duration, until: 20240408T080910.123}, {action: send, brand: brand, data: {foo: bar}, profile: {foo: bar}, recipient: recipient, template: 64TP5HKPFTM8VTK1Y75SJDQX9JK0}], cancelation_token: delay-send--user-yes--abc-123}", + "--brand", "brand", + "--data", "{name: bar}", + "--profile", "{tenant_id: bar}", + "--recipient", "user-yes", + "--template", "template", + ) + }) + + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(automationsInvokeInvokeAdHoc) + + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "automations:invoke", "invoke-ad-hoc", + "--api-key", "string", + "--automation.steps", "[{action: delay, duration: duration, until: 20240408T080910.123}, {action: send, brand: brand, data: {foo: bar}, profile: {foo: bar}, recipient: recipient, template: 64TP5HKPFTM8VTK1Y75SJDQX9JK0}]", + "--automation.cancelation-token", "delay-send--user-yes--abc-123", + "--brand", "brand", + "--data", "{name: bar}", + "--profile", "{tenant_id: bar}", + "--recipient", "user-yes", + "--template", "template", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "automation:\n" + + " steps:\n" + + " - action: delay\n" + + " duration: duration\n" + + " until: 20240408T080910.123\n" + + " - action: send\n" + + " brand: brand\n" + + " data:\n" + + " foo: bar\n" + + " profile:\n" + + " foo: bar\n" + + " recipient: recipient\n" + + " template: 64TP5HKPFTM8VTK1Y75SJDQX9JK0\n" + + " cancelation_token: delay-send--user-yes--abc-123\n" + + "brand: brand\n" + + "data:\n" + + " name: bar\n" + + "profile:\n" + + " tenant_id: bar\n" + + "recipient: user-yes\n" + + "template: template\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "automations:invoke", "invoke-ad-hoc", + "--api-key", "string", + ) + }) } func TestAutomationsInvokeInvokeByTemplate(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "automations:invoke", "invoke-by-template", - "--api-key", "string", - "--template-id", "templateId", - "--recipient", "recipient", - "--brand", "brand", - "--data", "{foo: bar}", - "--profile", "{foo: bar}", - "--template", "template", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "automations:invoke", "invoke-by-template", + "--api-key", "string", + "--template-id", "templateId", + "--recipient", "recipient", + "--brand", "brand", + "--data", "{foo: bar}", + "--profile", "{foo: bar}", + "--template", "template", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "recipient: recipient\n" + + "brand: brand\n" + + "data:\n" + + " foo: bar\n" + + "profile:\n" + + " foo: bar\n" + + "template: template\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "automations:invoke", "invoke-by-template", + "--api-key", "string", + "--template-id", "templateId", + ) + }) } diff --git a/pkg/cmd/brand_test.go b/pkg/cmd/brand_test.go index bf903f0..6a33963 100644 --- a/pkg/cmd/brand_test.go +++ b/pkg/cmd/brand_test.go @@ -11,86 +11,223 @@ import ( func TestBrandsCreate(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "brands", "create", - "--api-key", "string", - "--name", "name", - "--id", "id", - "--settings", "{colors: {primary: primary, secondary: secondary}, email: {footer: {content: content, inheritDefault: true}, head: {inheritDefault: true, content: content}, header: {logo: {href: href, image: image}, barColor: barColor, inheritDefault: true}, templateOverride: {enabled: true, backgroundColor: backgroundColor, blocksBackgroundColor: blocksBackgroundColor, footer: footer, head: head, header: header, width: width, mjml: {enabled: true, backgroundColor: backgroundColor, blocksBackgroundColor: blocksBackgroundColor, footer: footer, head: head, header: header, width: width}, footerBackgroundColor: footerBackgroundColor, footerFullWidth: true}}, inapp: {colors: {primary: primary, secondary: secondary}, icons: {bell: bell, message: message}, widgetBackground: {bottomColor: bottomColor, topColor: topColor}, borderRadius: borderRadius, disableMessageIcon: true, fontFamily: fontFamily, placement: top}}", - "--snippets", "{items: [{name: name, value: value}]}", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "brands", "create", + "--api-key", "string", + "--name", "name", + "--id", "id", + "--settings", "{colors: {primary: primary, secondary: secondary}, email: {footer: {content: content, inheritDefault: true}, head: {inheritDefault: true, content: content}, header: {logo: {href: href, image: image}, barColor: barColor, inheritDefault: true}, templateOverride: {enabled: true, backgroundColor: backgroundColor, blocksBackgroundColor: blocksBackgroundColor, footer: footer, head: head, header: header, width: width, mjml: {enabled: true, backgroundColor: backgroundColor, blocksBackgroundColor: blocksBackgroundColor, footer: footer, head: head, header: header, width: width}, footerBackgroundColor: footerBackgroundColor, footerFullWidth: true}}, inapp: {colors: {primary: primary, secondary: secondary}, icons: {bell: bell, message: message}, widgetBackground: {bottomColor: bottomColor, topColor: topColor}, borderRadius: borderRadius, disableMessageIcon: true, fontFamily: fontFamily, placement: top}}", + "--snippets", "{items: [{name: name, value: value}]}", + ) + }) - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(brandsCreate) + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(brandsCreate) - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "brands", "create", - "--name", "name", - "--id", "id", - "--settings.colors", "{primary: primary, secondary: secondary}", - "--settings.email", "{footer: {content: content, inheritDefault: true}, head: {inheritDefault: true, content: content}, header: {logo: {href: href, image: image}, barColor: barColor, inheritDefault: true}, templateOverride: {enabled: true, backgroundColor: backgroundColor, blocksBackgroundColor: blocksBackgroundColor, footer: footer, head: head, header: header, width: width, mjml: {enabled: true, backgroundColor: backgroundColor, blocksBackgroundColor: blocksBackgroundColor, footer: footer, head: head, header: header, width: width}, footerBackgroundColor: footerBackgroundColor, footerFullWidth: true}}", - "--settings.inapp", "{colors: {primary: primary, secondary: secondary}, icons: {bell: bell, message: message}, widgetBackground: {bottomColor: bottomColor, topColor: topColor}, borderRadius: borderRadius, disableMessageIcon: true, fontFamily: fontFamily, placement: top}", - "--snippets.items", "[{name: name, value: value}]", - ) + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "brands", "create", + "--api-key", "string", + "--name", "name", + "--id", "id", + "--settings.colors", "{primary: primary, secondary: secondary}", + "--settings.email", "{footer: {content: content, inheritDefault: true}, head: {inheritDefault: true, content: content}, header: {logo: {href: href, image: image}, barColor: barColor, inheritDefault: true}, templateOverride: {enabled: true, backgroundColor: backgroundColor, blocksBackgroundColor: blocksBackgroundColor, footer: footer, head: head, header: header, width: width, mjml: {enabled: true, backgroundColor: backgroundColor, blocksBackgroundColor: blocksBackgroundColor, footer: footer, head: head, header: header, width: width}, footerBackgroundColor: footerBackgroundColor, footerFullWidth: true}}", + "--settings.inapp", "{colors: {primary: primary, secondary: secondary}, icons: {bell: bell, message: message}, widgetBackground: {bottomColor: bottomColor, topColor: topColor}, borderRadius: borderRadius, disableMessageIcon: true, fontFamily: fontFamily, placement: top}", + "--snippets.items", "[{name: name, value: value}]", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "name: name\n" + + "id: id\n" + + "settings:\n" + + " colors:\n" + + " primary: primary\n" + + " secondary: secondary\n" + + " email:\n" + + " footer:\n" + + " content: content\n" + + " inheritDefault: true\n" + + " head:\n" + + " inheritDefault: true\n" + + " content: content\n" + + " header:\n" + + " logo:\n" + + " href: href\n" + + " image: image\n" + + " barColor: barColor\n" + + " inheritDefault: true\n" + + " templateOverride:\n" + + " enabled: true\n" + + " backgroundColor: backgroundColor\n" + + " blocksBackgroundColor: blocksBackgroundColor\n" + + " footer: footer\n" + + " head: head\n" + + " header: header\n" + + " width: width\n" + + " mjml:\n" + + " enabled: true\n" + + " backgroundColor: backgroundColor\n" + + " blocksBackgroundColor: blocksBackgroundColor\n" + + " footer: footer\n" + + " head: head\n" + + " header: header\n" + + " width: width\n" + + " footerBackgroundColor: footerBackgroundColor\n" + + " footerFullWidth: true\n" + + " inapp:\n" + + " colors:\n" + + " primary: primary\n" + + " secondary: secondary\n" + + " icons:\n" + + " bell: bell\n" + + " message: message\n" + + " widgetBackground:\n" + + " bottomColor: bottomColor\n" + + " topColor: topColor\n" + + " borderRadius: borderRadius\n" + + " disableMessageIcon: true\n" + + " fontFamily: fontFamily\n" + + " placement: top\n" + + "snippets:\n" + + " items:\n" + + " - name: name\n" + + " value: value\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "brands", "create", + "--api-key", "string", + ) + }) } func TestBrandsRetrieve(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "brands", "retrieve", - "--api-key", "string", - "--brand-id", "brand_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "brands", "retrieve", + "--api-key", "string", + "--brand-id", "brand_id", + ) + }) } func TestBrandsUpdate(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "brands", "update", - "--api-key", "string", - "--brand-id", "brand_id", - "--name", "name", - "--settings", "{colors: {primary: primary, secondary: secondary}, email: {footer: {content: content, inheritDefault: true}, head: {inheritDefault: true, content: content}, header: {logo: {href: href, image: image}, barColor: barColor, inheritDefault: true}, templateOverride: {enabled: true, backgroundColor: backgroundColor, blocksBackgroundColor: blocksBackgroundColor, footer: footer, head: head, header: header, width: width, mjml: {enabled: true, backgroundColor: backgroundColor, blocksBackgroundColor: blocksBackgroundColor, footer: footer, head: head, header: header, width: width}, footerBackgroundColor: footerBackgroundColor, footerFullWidth: true}}, inapp: {colors: {primary: primary, secondary: secondary}, icons: {bell: bell, message: message}, widgetBackground: {bottomColor: bottomColor, topColor: topColor}, borderRadius: borderRadius, disableMessageIcon: true, fontFamily: fontFamily, placement: top}}", - "--snippets", "{items: [{name: name, value: value}]}", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "brands", "update", + "--api-key", "string", + "--brand-id", "brand_id", + "--name", "name", + "--settings", "{colors: {primary: primary, secondary: secondary}, email: {footer: {content: content, inheritDefault: true}, head: {inheritDefault: true, content: content}, header: {logo: {href: href, image: image}, barColor: barColor, inheritDefault: true}, templateOverride: {enabled: true, backgroundColor: backgroundColor, blocksBackgroundColor: blocksBackgroundColor, footer: footer, head: head, header: header, width: width, mjml: {enabled: true, backgroundColor: backgroundColor, blocksBackgroundColor: blocksBackgroundColor, footer: footer, head: head, header: header, width: width}, footerBackgroundColor: footerBackgroundColor, footerFullWidth: true}}, inapp: {colors: {primary: primary, secondary: secondary}, icons: {bell: bell, message: message}, widgetBackground: {bottomColor: bottomColor, topColor: topColor}, borderRadius: borderRadius, disableMessageIcon: true, fontFamily: fontFamily, placement: top}}", + "--snippets", "{items: [{name: name, value: value}]}", + ) + }) + + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(brandsUpdate) - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(brandsUpdate) + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "brands", "update", + "--api-key", "string", + "--brand-id", "brand_id", + "--name", "name", + "--settings.colors", "{primary: primary, secondary: secondary}", + "--settings.email", "{footer: {content: content, inheritDefault: true}, head: {inheritDefault: true, content: content}, header: {logo: {href: href, image: image}, barColor: barColor, inheritDefault: true}, templateOverride: {enabled: true, backgroundColor: backgroundColor, blocksBackgroundColor: blocksBackgroundColor, footer: footer, head: head, header: header, width: width, mjml: {enabled: true, backgroundColor: backgroundColor, blocksBackgroundColor: blocksBackgroundColor, footer: footer, head: head, header: header, width: width}, footerBackgroundColor: footerBackgroundColor, footerFullWidth: true}}", + "--settings.inapp", "{colors: {primary: primary, secondary: secondary}, icons: {bell: bell, message: message}, widgetBackground: {bottomColor: bottomColor, topColor: topColor}, borderRadius: borderRadius, disableMessageIcon: true, fontFamily: fontFamily, placement: top}", + "--snippets.items", "[{name: name, value: value}]", + ) + }) - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "brands", "update", - "--brand-id", "brand_id", - "--name", "name", - "--settings.colors", "{primary: primary, secondary: secondary}", - "--settings.email", "{footer: {content: content, inheritDefault: true}, head: {inheritDefault: true, content: content}, header: {logo: {href: href, image: image}, barColor: barColor, inheritDefault: true}, templateOverride: {enabled: true, backgroundColor: backgroundColor, blocksBackgroundColor: blocksBackgroundColor, footer: footer, head: head, header: header, width: width, mjml: {enabled: true, backgroundColor: backgroundColor, blocksBackgroundColor: blocksBackgroundColor, footer: footer, head: head, header: header, width: width}, footerBackgroundColor: footerBackgroundColor, footerFullWidth: true}}", - "--settings.inapp", "{colors: {primary: primary, secondary: secondary}, icons: {bell: bell, message: message}, widgetBackground: {bottomColor: bottomColor, topColor: topColor}, borderRadius: borderRadius, disableMessageIcon: true, fontFamily: fontFamily, placement: top}", - "--snippets.items", "[{name: name, value: value}]", - ) + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "name: name\n" + + "settings:\n" + + " colors:\n" + + " primary: primary\n" + + " secondary: secondary\n" + + " email:\n" + + " footer:\n" + + " content: content\n" + + " inheritDefault: true\n" + + " head:\n" + + " inheritDefault: true\n" + + " content: content\n" + + " header:\n" + + " logo:\n" + + " href: href\n" + + " image: image\n" + + " barColor: barColor\n" + + " inheritDefault: true\n" + + " templateOverride:\n" + + " enabled: true\n" + + " backgroundColor: backgroundColor\n" + + " blocksBackgroundColor: blocksBackgroundColor\n" + + " footer: footer\n" + + " head: head\n" + + " header: header\n" + + " width: width\n" + + " mjml:\n" + + " enabled: true\n" + + " backgroundColor: backgroundColor\n" + + " blocksBackgroundColor: blocksBackgroundColor\n" + + " footer: footer\n" + + " head: head\n" + + " header: header\n" + + " width: width\n" + + " footerBackgroundColor: footerBackgroundColor\n" + + " footerFullWidth: true\n" + + " inapp:\n" + + " colors:\n" + + " primary: primary\n" + + " secondary: secondary\n" + + " icons:\n" + + " bell: bell\n" + + " message: message\n" + + " widgetBackground:\n" + + " bottomColor: bottomColor\n" + + " topColor: topColor\n" + + " borderRadius: borderRadius\n" + + " disableMessageIcon: true\n" + + " fontFamily: fontFamily\n" + + " placement: top\n" + + "snippets:\n" + + " items:\n" + + " - name: name\n" + + " value: value\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "brands", "update", + "--api-key", "string", + "--brand-id", "brand_id", + ) + }) } func TestBrandsList(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "brands", "list", - "--api-key", "string", - "--cursor", "cursor", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "brands", "list", + "--api-key", "string", + "--cursor", "cursor", + ) + }) } func TestBrandsDelete(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "brands", "delete", - "--api-key", "string", - "--brand-id", "brand_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "brands", "delete", + "--api-key", "string", + "--brand-id", "brand_id", + ) + }) } diff --git a/pkg/cmd/bulk_test.go b/pkg/cmd/bulk_test.go index d9650b5..848f7a7 100644 --- a/pkg/cmd/bulk_test.go +++ b/pkg/cmd/bulk_test.go @@ -11,83 +11,179 @@ import ( func TestBulkAddUsers(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "bulk", "add-users", - "--api-key", "string", - "--job-id", "job_id", - "--user", "{data: {}, preferences: {categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}, profile: {foo: bar}, recipient: recipient, to: {account_id: account_id, context: {tenant_id: tenant_id}, data: {foo: bar}, email: email, list_id: list_id, locale: locale, phone_number: phone_number, preferences: {notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}], source: subscription}}, categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}], source: subscription}}, templateId: templateId}, tenant_id: tenant_id, user_id: user_id}}", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "bulk", "add-users", + "--api-key", "string", + "--job-id", "job_id", + "--user", "{data: {}, preferences: {categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}, profile: {foo: bar}, recipient: recipient, to: {account_id: account_id, context: {tenant_id: tenant_id}, data: {foo: bar}, email: email, list_id: list_id, locale: locale, phone_number: phone_number, preferences: {notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}], source: subscription}}, categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}], source: subscription}}, templateId: templateId}, tenant_id: tenant_id, user_id: user_id}}", + ) + }) - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(bulkAddUsers) + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(bulkAddUsers) - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "bulk", "add-users", - "--job-id", "job_id", - "--user.data", "{}", - "--user.preferences", "{categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}", - "--user.profile", "{foo: bar}", - "--user.recipient", "recipient", - "--user.to", "{account_id: account_id, context: {tenant_id: tenant_id}, data: {foo: bar}, email: email, list_id: list_id, locale: locale, phone_number: phone_number, preferences: {notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}], source: subscription}}, categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}], source: subscription}}, templateId: templateId}, tenant_id: tenant_id, user_id: user_id}", - ) + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "bulk", "add-users", + "--api-key", "string", + "--job-id", "job_id", + "--user.data", "{}", + "--user.preferences", "{categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}", + "--user.profile", "{foo: bar}", + "--user.recipient", "recipient", + "--user.to", "{account_id: account_id, context: {tenant_id: tenant_id}, data: {foo: bar}, email: email, list_id: list_id, locale: locale, phone_number: phone_number, preferences: {notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}], source: subscription}}, categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}], source: subscription}}, templateId: templateId}, tenant_id: tenant_id, user_id: user_id}", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "users:\n" + + " - data: {}\n" + + " preferences:\n" + + " categories:\n" + + " foo:\n" + + " status: OPTED_IN\n" + + " channel_preferences:\n" + + " - channel: direct_message\n" + + " rules:\n" + + " - until: until\n" + + " start: start\n" + + " notifications:\n" + + " foo:\n" + + " status: OPTED_IN\n" + + " channel_preferences:\n" + + " - channel: direct_message\n" + + " rules:\n" + + " - until: until\n" + + " start: start\n" + + " profile:\n" + + " foo: bar\n" + + " recipient: recipient\n" + + " to:\n" + + " account_id: account_id\n" + + " context:\n" + + " tenant_id: tenant_id\n" + + " data:\n" + + " foo: bar\n" + + " email: email\n" + + " list_id: list_id\n" + + " locale: locale\n" + + " phone_number: phone_number\n" + + " preferences:\n" + + " notifications:\n" + + " foo:\n" + + " status: OPTED_IN\n" + + " channel_preferences:\n" + + " - channel: direct_message\n" + + " rules:\n" + + " - until: until\n" + + " start: start\n" + + " source: subscription\n" + + " categories:\n" + + " foo:\n" + + " status: OPTED_IN\n" + + " channel_preferences:\n" + + " - channel: direct_message\n" + + " rules:\n" + + " - until: until\n" + + " start: start\n" + + " source: subscription\n" + + " templateId: templateId\n" + + " tenant_id: tenant_id\n" + + " user_id: user_id\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "bulk", "add-users", + "--api-key", "string", + "--job-id", "job_id", + ) + }) } func TestBulkCreateJob(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "bulk", "create-job", - "--api-key", "string", - "--message", "{event: event, brand: brand, content: {body: body, title: title}, data: {foo: bar}, locale: {foo: {foo: bar}}, override: {foo: bar}, template: template}", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "bulk", "create-job", + "--api-key", "string", + "--message", "{event: event, brand: brand, content: {body: body, title: title}, data: {foo: bar}, locale: {foo: {foo: bar}}, override: {foo: bar}, template: template}", + ) + }) + + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(bulkCreateJob) - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(bulkCreateJob) + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "bulk", "create-job", + "--api-key", "string", + "--message.event", "event", + "--message.brand", "brand", + "--message.content", "{body: body, title: title}", + "--message.data", "{foo: bar}", + "--message.locale", "{foo: {foo: bar}}", + "--message.override", "{foo: bar}", + "--message.template", "template", + ) + }) - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "bulk", "create-job", - "--message.event", "event", - "--message.brand", "brand", - "--message.content", "{body: body, title: title}", - "--message.data", "{foo: bar}", - "--message.locale", "{foo: {foo: bar}}", - "--message.override", "{foo: bar}", - "--message.template", "template", - ) + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "message:\n" + + " event: event\n" + + " brand: brand\n" + + " content:\n" + + " body: body\n" + + " title: title\n" + + " data:\n" + + " foo: bar\n" + + " locale:\n" + + " foo:\n" + + " foo: bar\n" + + " override:\n" + + " foo: bar\n" + + " template: template\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "bulk", "create-job", + "--api-key", "string", + ) + }) } func TestBulkListUsers(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "bulk", "list-users", - "--api-key", "string", - "--job-id", "job_id", - "--cursor", "cursor", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "bulk", "list-users", + "--api-key", "string", + "--job-id", "job_id", + "--cursor", "cursor", + ) + }) } func TestBulkRetrieveJob(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "bulk", "retrieve-job", - "--api-key", "string", - "--job-id", "job_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "bulk", "retrieve-job", + "--api-key", "string", + "--job-id", "job_id", + ) + }) } func TestBulkRunJob(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "bulk", "run-job", - "--api-key", "string", - "--job-id", "job_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "bulk", "run-job", + "--api-key", "string", + "--job-id", "job_id", + ) + }) } diff --git a/pkg/cmd/cmdutil.go b/pkg/cmd/cmdutil.go index a7046b1..e3c8bd7 100644 --- a/pkg/cmd/cmdutil.go +++ b/pkg/cmd/cmdutil.go @@ -350,7 +350,7 @@ type HasRawJSON interface { // For an iterator over different value types, display its values to the user in // different formats. -func ShowJSONIterator[T any](stdout *os.File, title string, iter jsonview.Iterator[T], format string, transform string) error { +func ShowJSONIterator[T any](stdout *os.File, title string, iter jsonview.Iterator[T], format string, transform string, itemsToDisplay int64) error { if format == "explore" { return jsonview.ExploreJSONStream(title, iter) } @@ -366,6 +366,9 @@ func ShowJSONIterator[T any](stdout *os.File, title string, iter jsonview.Iterat output := []byte{} numberOfNewlines := 0 for iter.Next() { + if itemsToDisplay == 0 { + break + } item := iter.Current() var obj gjson.Result if hasRaw, ok := any(item).(HasRawJSON); ok { @@ -383,6 +386,7 @@ func ShowJSONIterator[T any](stdout *os.File, title string, iter jsonview.Iterat } output = append(output, json...) + itemsToDisplay -= 1 numberOfNewlines += countTerminalLines(json, terminalWidth) // If the output won't fit in the terminal window, stream it to a pager @@ -409,6 +413,9 @@ func ShowJSONIterator[T any](stdout *os.File, title string, iter jsonview.Iterat } for iter.Next() { + if itemsToDisplay == 0 { + break + } item := iter.Current() var obj gjson.Result if hasRaw, ok := any(item).(HasRawJSON); ok { @@ -423,6 +430,7 @@ func ShowJSONIterator[T any](stdout *os.File, title string, iter jsonview.Iterat if err := ShowJSON(pager, title, obj, format, transform); err != nil { return err } + itemsToDisplay -= 1 } return iter.Err() }) diff --git a/pkg/cmd/flagoptions.go b/pkg/cmd/flagoptions.go index 5edc613..35ce837 100644 --- a/pkg/cmd/flagoptions.go +++ b/pkg/cmd/flagoptions.go @@ -41,6 +41,9 @@ const ( ) func embedFiles(obj any, embedStyle FileEmbedStyle) (any, error) { + if obj == nil { + return obj, nil + } v := reflect.ValueOf(obj) result, err := embedFilesValue(v, embedStyle) if err != nil { @@ -207,40 +210,53 @@ func flagOptions( // This parameter is true if stdin is already in use to pass a binary parameter by using the special value // "-". In this case, we won't attempt to read it as a JSON/YAML blob for options setting. - stdinInUse bool, + ignoreStdin bool, ) ([]option.RequestOption, error) { var options []option.RequestOption if cmd.Bool("debug") { options = append(options, option.WithMiddleware(debugmiddleware.NewRequestLogger().Middleware())) } - flagContents := requestflag.ExtractRequestContents(cmd) + requestContents := requestflag.ExtractRequestContents(cmd) - var bodyData any - var pipeData []byte - if isInputPiped() && !stdinInUse { - var err error - pipeData, err = io.ReadAll(os.Stdin) + if bodyType != ApplicationOctetStream && isInputPiped() && !ignoreStdin { + pipeData, err := io.ReadAll(os.Stdin) if err != nil { return nil, err } - } - if len(pipeData) > 0 { - if err := yaml.Unmarshal(pipeData, &bodyData); err == nil { - if bodyMap, ok := bodyData.(map[string]any); ok { - if flagMap, ok := flagContents.Body.(map[string]any); ok { - maps.Copy(bodyMap, flagMap) + if len(pipeData) > 0 { + var bodyData any + if err := yaml.Unmarshal(pipeData, &bodyData); err == nil { + if bodyMap, ok := bodyData.(map[string]any); ok { + if flagMap, ok := requestContents.Body.(map[string]any); ok { + maps.Copy(bodyMap, flagMap) + requestContents.Body = bodyMap + } else { + bodyData = requestContents.Body + } + } else if flagMap, ok := requestContents.Body.(map[string]any); ok && len(flagMap) > 0 { + return nil, fmt.Errorf("Cannot merge flags with a body that is not a map: %v", bodyData) } else { - bodyData = flagContents.Body + requestContents.Body = bodyData } - } else if flagMap, ok := flagContents.Body.(map[string]any); ok && len(flagMap) > 0 { - return nil, fmt.Errorf("Cannot merge flags with a body that is not a map: %v", bodyData) } } - } else { - // No piped input, just use body flag values as a map - bodyData = flagContents.Body + } + + if missingFlags := requestflag.GetMissingRequiredFlags(cmd, requestContents.Body); len(missingFlags) > 0 { + var buf bytes.Buffer + cli.HelpPrinter(&buf, cli.SubcommandHelpTemplate, cmd) + usage := buf.String() + if len(missingFlags) == 1 { + return nil, fmt.Errorf("%sRequired flag %q not set", usage, missingFlags[0].Names()[0]) + } else { + names := []string{} + for _, flag := range missingFlags { + names = append(names, flag.Names()[0]) + } + return nil, fmt.Errorf("%sRequired flags %q not set", usage, strings.Join(names, ", ")) + } } // Embed files passed as "@file.jpg" in the request body, headers, and query: @@ -248,19 +264,22 @@ func flagOptions( if bodyType == ApplicationOctetStream || bodyType == MultipartFormEncoded { embedStyle = EmbedIOReader } - bodyData, err := embedFiles(bodyData, embedStyle) - if err != nil { + + if embedded, err := embedFiles(requestContents.Body, embedStyle); err != nil { return nil, err + } else { + requestContents.Body = embedded } - if headersWithFiles, err := embedFiles(flagContents.Headers, EmbedText); err != nil { + + if headersWithFiles, err := embedFiles(requestContents.Headers, EmbedText); err != nil { return nil, err } else { - flagContents.Headers = headersWithFiles.(map[string]any) + requestContents.Headers = headersWithFiles.(map[string]any) } - if queriesWithFiles, err := embedFiles(flagContents.Queries, EmbedText); err != nil { + if queriesWithFiles, err := embedFiles(requestContents.Queries, EmbedText); err != nil { return nil, err } else { - flagContents.Queries = queriesWithFiles.(map[string]any) + requestContents.Queries = queriesWithFiles.(map[string]any) } querySettings := apiquery.QuerySettings{ @@ -269,7 +288,7 @@ func flagOptions( } // Add query parameters: - if values, err := apiquery.MarshalWithSettings(flagContents.Queries, querySettings); err != nil { + if values, err := apiquery.MarshalWithSettings(requestContents.Queries, querySettings); err != nil { return nil, err } else { for k, vs := range values { @@ -289,7 +308,7 @@ func flagOptions( NestedFormat: apiquery.NestedQueryFormatDots, ArrayFormat: apiquery.ArrayQueryFormatRepeat, } - if values, err := apiquery.MarshalWithSettings(flagContents.Headers, headerSettings); err != nil { + if values, err := apiquery.MarshalWithSettings(requestContents.Headers, headerSettings); err != nil { return nil, err } else { for k, vs := range values { @@ -312,9 +331,9 @@ func flagOptions( writer := multipart.NewWriter(buf) // For multipart/form-encoded, we need a map structure - bodyMap, ok := bodyData.(map[string]any) + bodyMap, ok := requestContents.Body.(map[string]any) if !ok { - return nil, fmt.Errorf("Cannot send a non-map value to a form-encoded endpoint: %v\n", bodyData) + return nil, fmt.Errorf("Cannot send a non-map value to a form-encoded endpoint: %v\n", requestContents.Body) } encodingFormat := apiform.FormatComma if err := apiform.MarshalWithSettings(bodyMap, writer, encodingFormat); err != nil { @@ -326,19 +345,25 @@ func flagOptions( options = append(options, option.WithRequestBody(writer.FormDataContentType(), buf)) case ApplicationJSON: - bodyBytes, err := json.Marshal(bodyData) + bodyBytes, err := json.Marshal(requestContents.Body) if err != nil { return nil, err } options = append(options, option.WithRequestBody("application/json", bodyBytes)) case ApplicationOctetStream: - if bodyBytes, ok := bodyData.([]byte); ok { + // If there is a body root parameter, that will handle setting the request body, we don't need to do it here. + for _, flag := range cmd.Flags { + if toSend, ok := flag.(requestflag.InRequest); ok && toSend.IsBodyRoot() { + return options, nil + } + } + if bodyBytes, ok := requestContents.Body.([]byte); ok { options = append(options, option.WithRequestBody("application/octet-stream", bodyBytes)) - } else if bodyStr, ok := bodyData.(string); ok { + } else if bodyStr, ok := requestContents.Body.(string); ok { options = append(options, option.WithRequestBody("application/octet-stream", []byte(bodyStr))) } else { - return nil, fmt.Errorf("Unsupported body for application/octet-stream: %v", bodyData) + return nil, fmt.Errorf("Unsupported body for application/octet-stream: %v", requestContents.Body) } default: diff --git a/pkg/cmd/inbound_test.go b/pkg/cmd/inbound_test.go index 28fb686..706d874 100644 --- a/pkg/cmd/inbound_test.go +++ b/pkg/cmd/inbound_test.go @@ -10,14 +10,32 @@ import ( func TestInboundTrackEvent(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "inbound", "track-event", - "--api-key", "string", - "--event", "New Order Placed", - "--message-id", "4c62c457-b329-4bea-9bfc-17bba86c393f", - "--properties", "{order_id: bar, total_orders: bar, last_order_id: bar}", - "--type", "track", - "--user-id", "1234", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "inbound", "track-event", + "--api-key", "string", + "--event", "New Order Placed", + "--message-id", "4c62c457-b329-4bea-9bfc-17bba86c393f", + "--properties", "{order_id: bar, total_orders: bar, last_order_id: bar}", + "--type", "track", + "--user-id", "1234", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "event: New Order Placed\n" + + "messageId: 4c62c457-b329-4bea-9bfc-17bba86c393f\n" + + "properties:\n" + + " order_id: bar\n" + + " total_orders: bar\n" + + " last_order_id: bar\n" + + "type: track\n" + + "userId: '1234'\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "inbound", "track-event", + "--api-key", "string", + ) + }) } diff --git a/pkg/cmd/list_test.go b/pkg/cmd/list_test.go index 891e339..c9d4598 100644 --- a/pkg/cmd/list_test.go +++ b/pkg/cmd/list_test.go @@ -11,66 +11,101 @@ import ( func TestListsRetrieve(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "lists", "retrieve", - "--api-key", "string", - "--list-id", "list_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "lists", "retrieve", + "--api-key", "string", + "--list-id", "list_id", + ) + }) } func TestListsUpdate(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "lists", "update", - "--api-key", "string", - "--list-id", "list_id", - "--name", "name", - "--preferences", "{categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "lists", "update", + "--api-key", "string", + "--list-id", "list_id", + "--name", "name", + "--preferences", "{categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}", + ) + }) - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(listsUpdate) + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(listsUpdate) - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "lists", "update", - "--list-id", "list_id", - "--name", "name", - "--preferences.categories", "{foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}", - "--preferences.notifications", "{foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}", - ) + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "lists", "update", + "--api-key", "string", + "--list-id", "list_id", + "--name", "name", + "--preferences.categories", "{foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}", + "--preferences.notifications", "{foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "name: name\n" + + "preferences:\n" + + " categories:\n" + + " foo:\n" + + " status: OPTED_IN\n" + + " channel_preferences:\n" + + " - channel: direct_message\n" + + " rules:\n" + + " - until: until\n" + + " start: start\n" + + " notifications:\n" + + " foo:\n" + + " status: OPTED_IN\n" + + " channel_preferences:\n" + + " - channel: direct_message\n" + + " rules:\n" + + " - until: until\n" + + " start: start\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "lists", "update", + "--api-key", "string", + "--list-id", "list_id", + ) + }) } func TestListsList(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "lists", "list", - "--api-key", "string", - "--cursor", "cursor", - "--pattern", "pattern", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "lists", "list", + "--api-key", "string", + "--cursor", "cursor", + "--pattern", "pattern", + ) + }) } func TestListsDelete(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "lists", "delete", - "--api-key", "string", - "--list-id", "list_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "lists", "delete", + "--api-key", "string", + "--list-id", "list_id", + ) + }) } func TestListsRestore(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "lists", "restore", - "--api-key", "string", - "--list-id", "list_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "lists", "restore", + "--api-key", "string", + "--list-id", "list_id", + ) + }) } diff --git a/pkg/cmd/listsubscription_test.go b/pkg/cmd/listsubscription_test.go index b173839..c3a3406 100644 --- a/pkg/cmd/listsubscription_test.go +++ b/pkg/cmd/listsubscription_test.go @@ -11,93 +11,190 @@ import ( func TestListsSubscriptionsList(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "lists:subscriptions", "list", - "--api-key", "string", - "--list-id", "list_id", - "--cursor", "cursor", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "lists:subscriptions", "list", + "--api-key", "string", + "--list-id", "list_id", + "--cursor", "cursor", + ) + }) } func TestListsSubscriptionsAdd(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "lists:subscriptions", "add", - "--api-key", "string", - "--list-id", "list_id", - "--recipient", "{recipientId: recipientId, preferences: {categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}}", - ) - - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(listsSubscriptionsAdd) - - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "lists:subscriptions", "add", - "--list-id", "list_id", - "--recipient.recipient-id", "recipientId", - "--recipient.preferences", "{categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "lists:subscriptions", "add", + "--api-key", "string", + "--list-id", "list_id", + "--recipient", "{recipientId: recipientId, preferences: {categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}}", + ) + }) + + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(listsSubscriptionsAdd) + + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "lists:subscriptions", "add", + "--api-key", "string", + "--list-id", "list_id", + "--recipient.recipient-id", "recipientId", + "--recipient.preferences", "{categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "recipients:\n" + + " - recipientId: recipientId\n" + + " preferences:\n" + + " categories:\n" + + " foo:\n" + + " status: OPTED_IN\n" + + " channel_preferences:\n" + + " - channel: direct_message\n" + + " rules:\n" + + " - until: until\n" + + " start: start\n" + + " notifications:\n" + + " foo:\n" + + " status: OPTED_IN\n" + + " channel_preferences:\n" + + " - channel: direct_message\n" + + " rules:\n" + + " - until: until\n" + + " start: start\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "lists:subscriptions", "add", + "--api-key", "string", + "--list-id", "list_id", + ) + }) } func TestListsSubscriptionsSubscribe(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "lists:subscriptions", "subscribe", - "--api-key", "string", - "--list-id", "list_id", - "--recipient", "{recipientId: recipientId, preferences: {categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}}", - ) - - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(listsSubscriptionsSubscribe) - - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "lists:subscriptions", "subscribe", - "--list-id", "list_id", - "--recipient.recipient-id", "recipientId", - "--recipient.preferences", "{categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "lists:subscriptions", "subscribe", + "--api-key", "string", + "--list-id", "list_id", + "--recipient", "{recipientId: recipientId, preferences: {categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}}", + ) + }) + + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(listsSubscriptionsSubscribe) + + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "lists:subscriptions", "subscribe", + "--api-key", "string", + "--list-id", "list_id", + "--recipient.recipient-id", "recipientId", + "--recipient.preferences", "{categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "recipients:\n" + + " - recipientId: recipientId\n" + + " preferences:\n" + + " categories:\n" + + " foo:\n" + + " status: OPTED_IN\n" + + " channel_preferences:\n" + + " - channel: direct_message\n" + + " rules:\n" + + " - until: until\n" + + " start: start\n" + + " notifications:\n" + + " foo:\n" + + " status: OPTED_IN\n" + + " channel_preferences:\n" + + " - channel: direct_message\n" + + " rules:\n" + + " - until: until\n" + + " start: start\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "lists:subscriptions", "subscribe", + "--api-key", "string", + "--list-id", "list_id", + ) + }) } func TestListsSubscriptionsSubscribeUser(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "lists:subscriptions", "subscribe-user", - "--api-key", "string", - "--list-id", "list_id", - "--user-id", "user_id", - "--preferences", "{categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}", - ) - - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(listsSubscriptionsSubscribeUser) - - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "lists:subscriptions", "subscribe-user", - "--list-id", "list_id", - "--user-id", "user_id", - "--preferences.categories", "{foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}", - "--preferences.notifications", "{foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "lists:subscriptions", "subscribe-user", + "--api-key", "string", + "--list-id", "list_id", + "--user-id", "user_id", + "--preferences", "{categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}", + ) + }) + + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(listsSubscriptionsSubscribeUser) + + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "lists:subscriptions", "subscribe-user", + "--api-key", "string", + "--list-id", "list_id", + "--user-id", "user_id", + "--preferences.categories", "{foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}", + "--preferences.notifications", "{foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "preferences:\n" + + " categories:\n" + + " foo:\n" + + " status: OPTED_IN\n" + + " channel_preferences:\n" + + " - channel: direct_message\n" + + " rules:\n" + + " - until: until\n" + + " start: start\n" + + " notifications:\n" + + " foo:\n" + + " status: OPTED_IN\n" + + " channel_preferences:\n" + + " - channel: direct_message\n" + + " rules:\n" + + " - until: until\n" + + " start: start\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "lists:subscriptions", "subscribe-user", + "--api-key", "string", + "--list-id", "list_id", + "--user-id", "user_id", + ) + }) } func TestListsSubscriptionsUnsubscribeUser(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "lists:subscriptions", "unsubscribe-user", - "--api-key", "string", - "--list-id", "list_id", - "--user-id", "user_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "lists:subscriptions", "unsubscribe-user", + "--api-key", "string", + "--list-id", "list_id", + "--user-id", "user_id", + ) + }) } diff --git a/pkg/cmd/message_test.go b/pkg/cmd/message_test.go index f2b4c64..fcc7b47 100644 --- a/pkg/cmd/message_test.go +++ b/pkg/cmd/message_test.go @@ -10,64 +10,69 @@ import ( func TestMessagesRetrieve(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "messages", "retrieve", - "--api-key", "string", - "--message-id", "message_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "messages", "retrieve", + "--api-key", "string", + "--message-id", "message_id", + ) + }) } func TestMessagesList(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "messages", "list", - "--api-key", "string", - "--archived=true", - "--cursor", "cursor", - "--enqueued-after", "enqueued_after", - "--event", "event", - "--list", "list", - "--message-id", "messageId", - "--notification", "notification", - "--provider", "string", - "--recipient", "recipient", - "--status", "string", - "--tag", "string", - "--tags", "tags", - "--tenant-id", "tenant_id", - "--trace-id", "traceId", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "messages", "list", + "--api-key", "string", + "--archived=true", + "--cursor", "cursor", + "--enqueued-after", "enqueued_after", + "--event", "event", + "--list", "list", + "--message-id", "messageId", + "--notification", "notification", + "--provider", "string", + "--recipient", "recipient", + "--status", "string", + "--tag", "string", + "--tags", "tags", + "--tenant-id", "tenant_id", + "--trace-id", "traceId", + ) + }) } func TestMessagesCancel(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "messages", "cancel", - "--api-key", "string", - "--message-id", "message_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "messages", "cancel", + "--api-key", "string", + "--message-id", "message_id", + ) + }) } func TestMessagesContent(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "messages", "content", - "--api-key", "string", - "--message-id", "message_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "messages", "content", + "--api-key", "string", + "--message-id", "message_id", + ) + }) } func TestMessagesHistory(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "messages", "history", - "--api-key", "string", - "--message-id", "message_id", - "--type", "type", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "messages", "history", + "--api-key", "string", + "--message-id", "message_id", + "--type", "type", + ) + }) } diff --git a/pkg/cmd/notification_test.go b/pkg/cmd/notification_test.go index 645070a..d89d00a 100644 --- a/pkg/cmd/notification_test.go +++ b/pkg/cmd/notification_test.go @@ -10,21 +10,23 @@ import ( func TestNotificationsList(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "notifications", "list", - "--api-key", "string", - "--cursor", "cursor", - "--notes=true", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "notifications", "list", + "--api-key", "string", + "--cursor", "cursor", + "--notes=true", + ) + }) } func TestNotificationsRetrieveContent(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "notifications", "retrieve-content", - "--api-key", "string", - "--id", "id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "notifications", "retrieve-content", + "--api-key", "string", + "--id", "id", + ) + }) } diff --git a/pkg/cmd/notificationcheck_test.go b/pkg/cmd/notificationcheck_test.go index c846bfa..835bbaa 100644 --- a/pkg/cmd/notificationcheck_test.go +++ b/pkg/cmd/notificationcheck_test.go @@ -11,48 +11,68 @@ import ( func TestNotificationsChecksUpdate(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "notifications:checks", "update", - "--api-key", "string", - "--id", "id", - "--submission-id", "submissionId", - "--check", "{id: id, status: RESOLVED, type: custom}", - ) - - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(notificationsChecksUpdate) - - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "notifications:checks", "update", - "--id", "id", - "--submission-id", "submissionId", - "--check.id", "id", - "--check.status", "RESOLVED", - "--check.type", "custom", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "notifications:checks", "update", + "--api-key", "string", + "--id", "id", + "--submission-id", "submissionId", + "--check", "{id: id, status: RESOLVED, type: custom}", + ) + }) + + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(notificationsChecksUpdate) + + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "notifications:checks", "update", + "--api-key", "string", + "--id", "id", + "--submission-id", "submissionId", + "--check.id", "id", + "--check.status", "RESOLVED", + "--check.type", "custom", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "checks:\n" + + " - id: id\n" + + " status: RESOLVED\n" + + " type: custom\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "notifications:checks", "update", + "--api-key", "string", + "--id", "id", + "--submission-id", "submissionId", + ) + }) } func TestNotificationsChecksList(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "notifications:checks", "list", - "--api-key", "string", - "--id", "id", - "--submission-id", "submissionId", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "notifications:checks", "list", + "--api-key", "string", + "--id", "id", + "--submission-id", "submissionId", + ) + }) } func TestNotificationsChecksDelete(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "notifications:checks", "delete", - "--api-key", "string", - "--id", "id", - "--submission-id", "submissionId", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "notifications:checks", "delete", + "--api-key", "string", + "--id", "id", + "--submission-id", "submissionId", + ) + }) } diff --git a/pkg/cmd/notificationdraft_test.go b/pkg/cmd/notificationdraft_test.go index 66c6337..cc8619e 100644 --- a/pkg/cmd/notificationdraft_test.go +++ b/pkg/cmd/notificationdraft_test.go @@ -10,10 +10,11 @@ import ( func TestNotificationsDraftRetrieveContent(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "notifications:draft", "retrieve-content", - "--api-key", "string", - "--id", "id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "notifications:draft", "retrieve-content", + "--api-key", "string", + "--id", "id", + ) + }) } diff --git a/pkg/cmd/profile_test.go b/pkg/cmd/profile_test.go index d5b159d..9ef0f21 100644 --- a/pkg/cmd/profile_test.go +++ b/pkg/cmd/profile_test.go @@ -11,66 +11,111 @@ import ( func TestProfilesCreate(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "profiles", "create", - "--api-key", "string", - "--user-id", "user_id", - "--profile", "{foo: bar}", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "profiles", "create", + "--api-key", "string", + "--user-id", "user_id", + "--profile", "{foo: bar}", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "profile:\n" + + " foo: bar\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "profiles", "create", + "--api-key", "string", + "--user-id", "user_id", + ) + }) } func TestProfilesRetrieve(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "profiles", "retrieve", - "--api-key", "string", - "--user-id", "user_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "profiles", "retrieve", + "--api-key", "string", + "--user-id", "user_id", + ) + }) } func TestProfilesUpdate(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "profiles", "update", - "--api-key", "string", - "--user-id", "user_id", - "--patch", "{op: op, path: path, value: value}", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "profiles", "update", + "--api-key", "string", + "--user-id", "user_id", + "--patch", "{op: op, path: path, value: value}", + ) + }) + + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(profilesUpdate) - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(profilesUpdate) + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "profiles", "update", + "--api-key", "string", + "--user-id", "user_id", + "--patch.op", "op", + "--patch.path", "path", + "--patch.value", "value", + ) + }) - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "profiles", "update", - "--user-id", "user_id", - "--patch.op", "op", - "--patch.path", "path", - "--patch.value", "value", - ) + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "patch:\n" + + " - op: op\n" + + " path: path\n" + + " value: value\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "profiles", "update", + "--api-key", "string", + "--user-id", "user_id", + ) + }) } func TestProfilesDelete(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "profiles", "delete", - "--api-key", "string", - "--user-id", "user_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "profiles", "delete", + "--api-key", "string", + "--user-id", "user_id", + ) + }) } func TestProfilesReplace(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "profiles", "replace", - "--api-key", "string", - "--user-id", "user_id", - "--profile", "{foo: bar}", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "profiles", "replace", + "--api-key", "string", + "--user-id", "user_id", + "--profile", "{foo: bar}", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "profile:\n" + + " foo: bar\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "profiles", "replace", + "--api-key", "string", + "--user-id", "user_id", + ) + }) } diff --git a/pkg/cmd/profilelist_test.go b/pkg/cmd/profilelist_test.go index ae6b8b9..3705a42 100644 --- a/pkg/cmd/profilelist_test.go +++ b/pkg/cmd/profilelist_test.go @@ -11,44 +11,78 @@ import ( func TestProfilesListsRetrieve(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "profiles:lists", "retrieve", - "--api-key", "string", - "--user-id", "user_id", - "--cursor", "cursor", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "profiles:lists", "retrieve", + "--api-key", "string", + "--user-id", "user_id", + "--cursor", "cursor", + ) + }) } func TestProfilesListsDelete(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "profiles:lists", "delete", - "--api-key", "string", - "--user-id", "user_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "profiles:lists", "delete", + "--api-key", "string", + "--user-id", "user_id", + ) + }) } func TestProfilesListsSubscribe(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "profiles:lists", "subscribe", - "--api-key", "string", - "--user-id", "user_id", - "--list", "{listId: listId, preferences: {categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}}", - ) - - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(profilesListsSubscribe) - - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "profiles:lists", "subscribe", - "--user-id", "user_id", - "--list.list-id", "listId", - "--list.preferences", "{categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "profiles:lists", "subscribe", + "--api-key", "string", + "--user-id", "user_id", + "--list", "{listId: listId, preferences: {categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}}", + ) + }) + + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(profilesListsSubscribe) + + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "profiles:lists", "subscribe", + "--api-key", "string", + "--user-id", "user_id", + "--list.list-id", "listId", + "--list.preferences", "{categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}, notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}]}}}", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "lists:\n" + + " - listId: listId\n" + + " preferences:\n" + + " categories:\n" + + " foo:\n" + + " status: OPTED_IN\n" + + " channel_preferences:\n" + + " - channel: direct_message\n" + + " rules:\n" + + " - until: until\n" + + " start: start\n" + + " notifications:\n" + + " foo:\n" + + " status: OPTED_IN\n" + + " channel_preferences:\n" + + " - channel: direct_message\n" + + " rules:\n" + + " - until: until\n" + + " start: start\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "profiles:lists", "subscribe", + "--api-key", "string", + "--user-id", "user_id", + ) + }) } diff --git a/pkg/cmd/request_test.go b/pkg/cmd/request_test.go index 52fdb87..1be0fd9 100644 --- a/pkg/cmd/request_test.go +++ b/pkg/cmd/request_test.go @@ -10,10 +10,11 @@ import ( func TestRequestsArchive(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "requests", "archive", - "--api-key", "string", - "--request-id", "request_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "requests", "archive", + "--api-key", "string", + "--request-id", "request_id", + ) + }) } diff --git a/pkg/cmd/send_test.go b/pkg/cmd/send_test.go index 9dcb399..48aca4a 100644 --- a/pkg/cmd/send_test.go +++ b/pkg/cmd/send_test.go @@ -11,33 +11,151 @@ import ( func TestSendMessage(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "send", "message", - "--api-key", "string", - "--message", "{brand_id: brand_id, channels: {foo: {brand_id: brand_id, if: if, metadata: {utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}, override: {foo: bar}, providers: [string], routing_method: all, timeouts: {channel: 0, provider: 0}}}, content: {body: body, title: title}, context: {tenant_id: tenant_id}, data: {foo: bar}, delay: {duration: 0, timezone: timezone, until: until}, expiry: {expires_in: string, expires_at: expires_at}, metadata: {event: event, tags: [string], trace_id: trace_id, utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}, preferences: {subscription_topic_id: subscription_topic_id}, providers: {foo: {if: if, metadata: {utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}, override: {foo: bar}, timeouts: 0}}, routing: {channels: [string], method: all}, template: template_id, timeout: {channel: {foo: 0}, criteria: no-escalation, escalation: 0, message: 0, provider: {foo: 0}}, to: {account_id: account_id, context: {tenant_id: tenant_id}, data: {foo: bar}, email: email, list_id: list_id, locale: locale, phone_number: phone_number, preferences: {notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}], source: subscription}}, categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}], source: subscription}}, templateId: templateId}, tenant_id: tenant_id, user_id: user_id}}", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "send", "message", + "--api-key", "string", + "--message", "{brand_id: brand_id, channels: {foo: {brand_id: brand_id, if: if, metadata: {utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}, override: {foo: bar}, providers: [string], routing_method: all, timeouts: {channel: 0, provider: 0}}}, content: {body: body, title: title}, context: {tenant_id: tenant_id}, data: {foo: bar}, delay: {duration: 0, timezone: timezone, until: until}, expiry: {expires_in: string, expires_at: expires_at}, metadata: {event: event, tags: [string], trace_id: trace_id, utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}, preferences: {subscription_topic_id: subscription_topic_id}, providers: {foo: {if: if, metadata: {utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}, override: {foo: bar}, timeouts: 0}}, routing: {channels: [string], method: all}, template: template_id, timeout: {channel: {foo: 0}, criteria: no-escalation, escalation: 0, message: 0, provider: {foo: 0}}, to: {account_id: account_id, context: {tenant_id: tenant_id}, data: {foo: bar}, email: email, list_id: list_id, locale: locale, phone_number: phone_number, preferences: {notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}], source: subscription}}, categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}], source: subscription}}, templateId: templateId}, tenant_id: tenant_id, user_id: user_id}}", + ) + }) - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(sendMessage) + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(sendMessage) - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "send", "message", - "--message.brand-id", "brand_id", - "--message.channels", "{foo: {brand_id: brand_id, if: if, metadata: {utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}, override: {foo: bar}, providers: [string], routing_method: all, timeouts: {channel: 0, provider: 0}}}", - "--message.content", "{body: body, title: title}", - "--message.context", "{tenant_id: tenant_id}", - "--message.data", "{foo: bar}", - "--message.delay", "{duration: 0, timezone: timezone, until: until}", - "--message.expiry", "{expires_in: string, expires_at: expires_at}", - "--message.metadata", "{event: event, tags: [string], trace_id: trace_id, utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}", - "--message.preferences", "{subscription_topic_id: subscription_topic_id}", - "--message.providers", "{foo: {if: if, metadata: {utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}, override: {foo: bar}, timeouts: 0}}", - "--message.routing", "{channels: [string], method: all}", - "--message.template", "template_id", - "--message.timeout", "{channel: {foo: 0}, criteria: no-escalation, escalation: 0, message: 0, provider: {foo: 0}}", - "--message.to", "{account_id: account_id, context: {tenant_id: tenant_id}, data: {foo: bar}, email: email, list_id: list_id, locale: locale, phone_number: phone_number, preferences: {notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}], source: subscription}}, categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}], source: subscription}}, templateId: templateId}, tenant_id: tenant_id, user_id: user_id}", - ) + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "send", "message", + "--api-key", "string", + "--message.brand-id", "brand_id", + "--message.channels", "{foo: {brand_id: brand_id, if: if, metadata: {utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}, override: {foo: bar}, providers: [string], routing_method: all, timeouts: {channel: 0, provider: 0}}}", + "--message.content", "{body: body, title: title}", + "--message.context", "{tenant_id: tenant_id}", + "--message.data", "{foo: bar}", + "--message.delay", "{duration: 0, timezone: timezone, until: until}", + "--message.expiry", "{expires_in: string, expires_at: expires_at}", + "--message.metadata", "{event: event, tags: [string], trace_id: trace_id, utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}", + "--message.preferences", "{subscription_topic_id: subscription_topic_id}", + "--message.providers", "{foo: {if: if, metadata: {utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}, override: {foo: bar}, timeouts: 0}}", + "--message.routing", "{channels: [string], method: all}", + "--message.template", "template_id", + "--message.timeout", "{channel: {foo: 0}, criteria: no-escalation, escalation: 0, message: 0, provider: {foo: 0}}", + "--message.to", "{account_id: account_id, context: {tenant_id: tenant_id}, data: {foo: bar}, email: email, list_id: list_id, locale: locale, phone_number: phone_number, preferences: {notifications: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}], source: subscription}}, categories: {foo: {status: OPTED_IN, channel_preferences: [{channel: direct_message}], rules: [{until: until, start: start}], source: subscription}}, templateId: templateId}, tenant_id: tenant_id, user_id: user_id}", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "message:\n" + + " brand_id: brand_id\n" + + " channels:\n" + + " foo:\n" + + " brand_id: brand_id\n" + + " if: if\n" + + " metadata:\n" + + " utm:\n" + + " campaign: campaign\n" + + " content: content\n" + + " medium: medium\n" + + " source: source\n" + + " term: term\n" + + " override:\n" + + " foo: bar\n" + + " providers:\n" + + " - string\n" + + " routing_method: all\n" + + " timeouts:\n" + + " channel: 0\n" + + " provider: 0\n" + + " content:\n" + + " body: body\n" + + " title: title\n" + + " context:\n" + + " tenant_id: tenant_id\n" + + " data:\n" + + " foo: bar\n" + + " delay:\n" + + " duration: 0\n" + + " timezone: timezone\n" + + " until: until\n" + + " expiry:\n" + + " expires_in: string\n" + + " expires_at: expires_at\n" + + " metadata:\n" + + " event: event\n" + + " tags:\n" + + " - string\n" + + " trace_id: trace_id\n" + + " utm:\n" + + " campaign: campaign\n" + + " content: content\n" + + " medium: medium\n" + + " source: source\n" + + " term: term\n" + + " preferences:\n" + + " subscription_topic_id: subscription_topic_id\n" + + " providers:\n" + + " foo:\n" + + " if: if\n" + + " metadata:\n" + + " utm:\n" + + " campaign: campaign\n" + + " content: content\n" + + " medium: medium\n" + + " source: source\n" + + " term: term\n" + + " override:\n" + + " foo: bar\n" + + " timeouts: 0\n" + + " routing:\n" + + " channels:\n" + + " - string\n" + + " method: all\n" + + " template: template_id\n" + + " timeout:\n" + + " channel:\n" + + " foo: 0\n" + + " criteria: no-escalation\n" + + " escalation: 0\n" + + " message: 0\n" + + " provider:\n" + + " foo: 0\n" + + " to:\n" + + " account_id: account_id\n" + + " context:\n" + + " tenant_id: tenant_id\n" + + " data:\n" + + " foo: bar\n" + + " email: email\n" + + " list_id: list_id\n" + + " locale: locale\n" + + " phone_number: phone_number\n" + + " preferences:\n" + + " notifications:\n" + + " foo:\n" + + " status: OPTED_IN\n" + + " channel_preferences:\n" + + " - channel: direct_message\n" + + " rules:\n" + + " - until: until\n" + + " start: start\n" + + " source: subscription\n" + + " categories:\n" + + " foo:\n" + + " status: OPTED_IN\n" + + " channel_preferences:\n" + + " - channel: direct_message\n" + + " rules:\n" + + " - until: until\n" + + " start: start\n" + + " source: subscription\n" + + " templateId: templateId\n" + + " tenant_id: tenant_id\n" + + " user_id: user_id\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "send", "message", + "--api-key", "string", + ) + }) } diff --git a/pkg/cmd/tenant_test.go b/pkg/cmd/tenant_test.go index 15fc56d..4ef3003 100644 --- a/pkg/cmd/tenant_test.go +++ b/pkg/cmd/tenant_test.go @@ -11,76 +11,107 @@ import ( func TestTenantsRetrieve(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "tenants", "retrieve", - "--api-key", "string", - "--tenant-id", "tenant_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "tenants", "retrieve", + "--api-key", "string", + "--tenant-id", "tenant_id", + ) + }) } func TestTenantsUpdate(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "tenants", "update", - "--api-key", "string", - "--tenant-id", "tenant_id", - "--name", "name", - "--brand-id", "brand_id", - "--default-preferences", "{items: [{status: OPTED_OUT, custom_routing: [direct_message], has_custom_routing: true, id: id}]}", - "--parent-tenant-id", "parent_tenant_id", - "--properties", "{foo: bar}", - "--user-profile", "{foo: bar}", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "tenants", "update", + "--api-key", "string", + "--tenant-id", "tenant_id", + "--name", "name", + "--brand-id", "brand_id", + "--default-preferences", "{items: [{status: OPTED_OUT, custom_routing: [direct_message], has_custom_routing: true, id: id}]}", + "--parent-tenant-id", "parent_tenant_id", + "--properties", "{foo: bar}", + "--user-profile", "{foo: bar}", + ) + }) - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(tenantsUpdate) + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(tenantsUpdate) - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "tenants", "update", - "--tenant-id", "tenant_id", - "--name", "name", - "--brand-id", "brand_id", - "--default-preferences.items", "[{status: OPTED_OUT, custom_routing: [direct_message], has_custom_routing: true, id: id}]", - "--parent-tenant-id", "parent_tenant_id", - "--properties", "{foo: bar}", - "--user-profile", "{foo: bar}", - ) + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "tenants", "update", + "--api-key", "string", + "--tenant-id", "tenant_id", + "--name", "name", + "--brand-id", "brand_id", + "--default-preferences.items", "[{status: OPTED_OUT, custom_routing: [direct_message], has_custom_routing: true, id: id}]", + "--parent-tenant-id", "parent_tenant_id", + "--properties", "{foo: bar}", + "--user-profile", "{foo: bar}", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "name: name\n" + + "brand_id: brand_id\n" + + "default_preferences:\n" + + " items:\n" + + " - status: OPTED_OUT\n" + + " custom_routing:\n" + + " - direct_message\n" + + " has_custom_routing: true\n" + + " id: id\n" + + "parent_tenant_id: parent_tenant_id\n" + + "properties:\n" + + " foo: bar\n" + + "user_profile:\n" + + " foo: bar\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "tenants", "update", + "--api-key", "string", + "--tenant-id", "tenant_id", + ) + }) } func TestTenantsList(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "tenants", "list", - "--api-key", "string", - "--cursor", "cursor", - "--limit", "0", - "--parent-tenant-id", "parent_tenant_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "tenants", "list", + "--api-key", "string", + "--cursor", "cursor", + "--limit", "0", + "--parent-tenant-id", "parent_tenant_id", + ) + }) } func TestTenantsDelete(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "tenants", "delete", - "--api-key", "string", - "--tenant-id", "tenant_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "tenants", "delete", + "--api-key", "string", + "--tenant-id", "tenant_id", + ) + }) } func TestTenantsListUsers(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "tenants", "list-users", - "--api-key", "string", - "--tenant-id", "tenant_id", - "--cursor", "cursor", - "--limit", "0", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "tenants", "list-users", + "--api-key", "string", + "--tenant-id", "tenant_id", + "--cursor", "cursor", + "--limit", "0", + ) + }) } diff --git a/pkg/cmd/tenantpreferenceitem_test.go b/pkg/cmd/tenantpreferenceitem_test.go index 70fd308..c030467 100644 --- a/pkg/cmd/tenantpreferenceitem_test.go +++ b/pkg/cmd/tenantpreferenceitem_test.go @@ -10,25 +10,42 @@ import ( func TestTenantsPreferencesItemsUpdate(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "tenants:preferences:items", "update", - "--api-key", "string", - "--tenant-id", "tenant_id", - "--topic-id", "topic_id", - "--status", "OPTED_IN", - "--custom-routing", "[inbox]", - "--has-custom-routing=true", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "tenants:preferences:items", "update", + "--api-key", "string", + "--tenant-id", "tenant_id", + "--topic-id", "topic_id", + "--status", "OPTED_IN", + "--custom-routing", "[inbox]", + "--has-custom-routing=true", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "status: OPTED_IN\n" + + "custom_routing:\n" + + " - inbox\n" + + "has_custom_routing: true\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "tenants:preferences:items", "update", + "--api-key", "string", + "--tenant-id", "tenant_id", + "--topic-id", "topic_id", + ) + }) } func TestTenantsPreferencesItemsDelete(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "tenants:preferences:items", "delete", - "--api-key", "string", - "--tenant-id", "tenant_id", - "--topic-id", "topic_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "tenants:preferences:items", "delete", + "--api-key", "string", + "--tenant-id", "tenant_id", + "--topic-id", "topic_id", + ) + }) } diff --git a/pkg/cmd/tenanttemplate_test.go b/pkg/cmd/tenanttemplate_test.go index 354ed67..8bc6b17 100644 --- a/pkg/cmd/tenanttemplate_test.go +++ b/pkg/cmd/tenanttemplate_test.go @@ -11,64 +11,139 @@ import ( func TestTenantsTemplatesRetrieve(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "tenants:templates", "retrieve", - "--api-key", "string", - "--tenant-id", "tenant_id", - "--template-id", "template_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "tenants:templates", "retrieve", + "--api-key", "string", + "--tenant-id", "tenant_id", + "--template-id", "template_id", + ) + }) } func TestTenantsTemplatesList(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "tenants:templates", "list", - "--api-key", "string", - "--tenant-id", "tenant_id", - "--cursor", "cursor", - "--limit", "0", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "tenants:templates", "list", + "--api-key", "string", + "--tenant-id", "tenant_id", + "--cursor", "cursor", + "--limit", "0", + ) + }) } func TestTenantsTemplatesPublish(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "tenants:templates", "publish", - "--api-key", "string", - "--tenant-id", "tenant_id", - "--template-id", "template_id", - "--version", "version", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "tenants:templates", "publish", + "--api-key", "string", + "--tenant-id", "tenant_id", + "--template-id", "template_id", + "--version", "version", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("version: version") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "tenants:templates", "publish", + "--api-key", "string", + "--tenant-id", "tenant_id", + "--template-id", "template_id", + ) + }) } func TestTenantsTemplatesReplace(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "tenants:templates", "replace", - "--api-key", "string", - "--tenant-id", "tenant_id", - "--template-id", "template_id", - "--template", "{content: {elements: [{channels: [string], if: if, loop: loop, ref: ref, type: text}], version: version}, channels: {foo: {brand_id: brand_id, if: if, metadata: {utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}, override: {foo: bar}, providers: [string], routing_method: all, timeouts: {channel: 0, provider: 0}}}, providers: {foo: {if: if, metadata: {utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}, override: {foo: bar}, timeouts: 0}}, routing: {channels: [string], method: all}}", - "--published=true", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "tenants:templates", "replace", + "--api-key", "string", + "--tenant-id", "tenant_id", + "--template-id", "template_id", + "--template", "{content: {elements: [{channels: [string], if: if, loop: loop, ref: ref, type: text}], version: version}, channels: {foo: {brand_id: brand_id, if: if, metadata: {utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}, override: {foo: bar}, providers: [string], routing_method: all, timeouts: {channel: 0, provider: 0}}}, providers: {foo: {if: if, metadata: {utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}, override: {foo: bar}, timeouts: 0}}, routing: {channels: [string], method: all}}", + "--published=true", + ) + }) + + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(tenantsTemplatesReplace) - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(tenantsTemplatesReplace) + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "tenants:templates", "replace", + "--api-key", "string", + "--tenant-id", "tenant_id", + "--template-id", "template_id", + "--template.content", "{elements: [{channels: [string], if: if, loop: loop, ref: ref, type: text}], version: version}", + "--template.channels", "{foo: {brand_id: brand_id, if: if, metadata: {utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}, override: {foo: bar}, providers: [string], routing_method: all, timeouts: {channel: 0, provider: 0}}}", + "--template.providers", "{foo: {if: if, metadata: {utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}, override: {foo: bar}, timeouts: 0}}", + "--template.routing", "{channels: [string], method: all}", + "--published=true", + ) + }) - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "tenants:templates", "replace", - "--tenant-id", "tenant_id", - "--template-id", "template_id", - "--template.content", "{elements: [{channels: [string], if: if, loop: loop, ref: ref, type: text}], version: version}", - "--template.channels", "{foo: {brand_id: brand_id, if: if, metadata: {utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}, override: {foo: bar}, providers: [string], routing_method: all, timeouts: {channel: 0, provider: 0}}}", - "--template.providers", "{foo: {if: if, metadata: {utm: {campaign: campaign, content: content, medium: medium, source: source, term: term}}, override: {foo: bar}, timeouts: 0}}", - "--template.routing", "{channels: [string], method: all}", - "--published=true", - ) + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "template:\n" + + " content:\n" + + " elements:\n" + + " - channels:\n" + + " - string\n" + + " if: if\n" + + " loop: loop\n" + + " ref: ref\n" + + " type: text\n" + + " version: version\n" + + " channels:\n" + + " foo:\n" + + " brand_id: brand_id\n" + + " if: if\n" + + " metadata:\n" + + " utm:\n" + + " campaign: campaign\n" + + " content: content\n" + + " medium: medium\n" + + " source: source\n" + + " term: term\n" + + " override:\n" + + " foo: bar\n" + + " providers:\n" + + " - string\n" + + " routing_method: all\n" + + " timeouts:\n" + + " channel: 0\n" + + " provider: 0\n" + + " providers:\n" + + " foo:\n" + + " if: if\n" + + " metadata:\n" + + " utm:\n" + + " campaign: campaign\n" + + " content: content\n" + + " medium: medium\n" + + " source: source\n" + + " term: term\n" + + " override:\n" + + " foo: bar\n" + + " timeouts: 0\n" + + " routing:\n" + + " channels:\n" + + " - string\n" + + " method: all\n" + + "published: true\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "tenants:templates", "replace", + "--api-key", "string", + "--tenant-id", "tenant_id", + "--template-id", "template_id", + ) + }) } diff --git a/pkg/cmd/tenanttemplateversion_test.go b/pkg/cmd/tenanttemplateversion_test.go index 7be0286..7eba1c9 100644 --- a/pkg/cmd/tenanttemplateversion_test.go +++ b/pkg/cmd/tenanttemplateversion_test.go @@ -10,12 +10,13 @@ import ( func TestTenantsTemplatesVersionsRetrieve(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "tenants:templates:versions", "retrieve", - "--api-key", "string", - "--tenant-id", "tenant_id", - "--template-id", "template_id", - "--version", "version", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "tenants:templates:versions", "retrieve", + "--api-key", "string", + "--tenant-id", "tenant_id", + "--template-id", "template_id", + "--version", "version", + ) + }) } diff --git a/pkg/cmd/translation_test.go b/pkg/cmd/translation_test.go index 7b6f5e9..aedddfa 100644 --- a/pkg/cmd/translation_test.go +++ b/pkg/cmd/translation_test.go @@ -10,23 +10,36 @@ import ( func TestTranslationsRetrieve(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "translations", "retrieve", - "--api-key", "string", - "--domain", "domain", - "--locale", "locale", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "translations", "retrieve", + "--api-key", "string", + "--domain", "domain", + "--locale", "locale", + ) + }) } func TestTranslationsUpdate(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "translations", "update", - "--api-key", "string", - "--domain", "domain", - "--locale", "locale", - "--body", "body", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "translations", "update", + "--api-key", "string", + "--domain", "domain", + "--locale", "locale", + "--body", "body", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("body") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "translations", "update", + "--api-key", "string", + "--domain", "domain", + "--locale", "locale", + ) + }) } diff --git a/pkg/cmd/userpreference_test.go b/pkg/cmd/userpreference_test.go index e2ab7cc..7dfe42c 100644 --- a/pkg/cmd/userpreference_test.go +++ b/pkg/cmd/userpreference_test.go @@ -11,51 +11,74 @@ import ( func TestUsersPreferencesRetrieve(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "users:preferences", "retrieve", - "--api-key", "string", - "--user-id", "user_id", - "--tenant-id", "tenant_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "users:preferences", "retrieve", + "--api-key", "string", + "--user-id", "user_id", + "--tenant-id", "tenant_id", + ) + }) } func TestUsersPreferencesRetrieveTopic(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "users:preferences", "retrieve-topic", - "--api-key", "string", - "--user-id", "user_id", - "--topic-id", "topic_id", - "--tenant-id", "tenant_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "users:preferences", "retrieve-topic", + "--api-key", "string", + "--user-id", "user_id", + "--topic-id", "topic_id", + "--tenant-id", "tenant_id", + ) + }) } func TestUsersPreferencesUpdateOrCreateTopic(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "users:preferences", "update-or-create-topic", - "--api-key", "string", - "--user-id", "user_id", - "--topic-id", "topic_id", - "--topic", "{status: OPTED_IN, custom_routing: [inbox, email], has_custom_routing: true}", - "--tenant-id", "tenant_id", - ) - - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(usersPreferencesUpdateOrCreateTopic) - - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "users:preferences", "update-or-create-topic", - "--user-id", "user_id", - "--topic-id", "topic_id", - "--topic.status", "OPTED_IN", - "--topic.custom-routing", "[inbox, email]", - "--topic.has-custom-routing=true", - "--tenant-id", "tenant_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "users:preferences", "update-or-create-topic", + "--api-key", "string", + "--user-id", "user_id", + "--topic-id", "topic_id", + "--topic", "{status: OPTED_IN, custom_routing: [inbox, email], has_custom_routing: true}", + "--tenant-id", "tenant_id", + ) + }) + + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(usersPreferencesUpdateOrCreateTopic) + + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "users:preferences", "update-or-create-topic", + "--api-key", "string", + "--user-id", "user_id", + "--topic-id", "topic_id", + "--topic.status", "OPTED_IN", + "--topic.custom-routing", "[inbox, email]", + "--topic.has-custom-routing=true", + "--tenant-id", "tenant_id", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "topic:\n" + + " status: OPTED_IN\n" + + " custom_routing:\n" + + " - inbox\n" + + " - email\n" + + " has_custom_routing: true\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "users:preferences", "update-or-create-topic", + "--api-key", "string", + "--user-id", "user_id", + "--topic-id", "topic_id", + "--tenant-id", "tenant_id", + ) + }) } diff --git a/pkg/cmd/usertenant_test.go b/pkg/cmd/usertenant_test.go index 1695dfb..2c4a1fd 100644 --- a/pkg/cmd/usertenant_test.go +++ b/pkg/cmd/usertenant_test.go @@ -11,70 +11,106 @@ import ( func TestUsersTenantsList(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "users:tenants", "list", - "--api-key", "string", - "--user-id", "user_id", - "--cursor", "cursor", - "--limit", "0", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "users:tenants", "list", + "--api-key", "string", + "--user-id", "user_id", + "--cursor", "cursor", + "--limit", "0", + ) + }) } func TestUsersTenantsAddMultiple(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "users:tenants", "add-multiple", - "--api-key", "string", - "--user-id", "user_id", - "--tenant", "{tenant_id: tenant_id, profile: {foo: bar}, type: user, user_id: user_id}", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "users:tenants", "add-multiple", + "--api-key", "string", + "--user-id", "user_id", + "--tenant", "{tenant_id: tenant_id, profile: {foo: bar}, type: user, user_id: user_id}", + ) + }) - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(usersTenantsAddMultiple) + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(usersTenantsAddMultiple) - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "users:tenants", "add-multiple", - "--user-id", "user_id", - "--tenant.tenant-id", "tenant_id", - "--tenant.profile", "{foo: bar}", - "--tenant.type", "user", - "--tenant.user-id", "user_id", - ) + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "users:tenants", "add-multiple", + "--api-key", "string", + "--user-id", "user_id", + "--tenant.tenant-id", "tenant_id", + "--tenant.profile", "{foo: bar}", + "--tenant.type", "user", + "--tenant.user-id", "user_id", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "tenants:\n" + + " - tenant_id: tenant_id\n" + + " profile:\n" + + " foo: bar\n" + + " type: user\n" + + " user_id: user_id\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "users:tenants", "add-multiple", + "--api-key", "string", + "--user-id", "user_id", + ) + }) } func TestUsersTenantsAddSingle(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "users:tenants", "add-single", - "--api-key", "string", - "--user-id", "user_id", - "--tenant-id", "tenant_id", - "--profile", "{foo: bar}", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "users:tenants", "add-single", + "--api-key", "string", + "--user-id", "user_id", + "--tenant-id", "tenant_id", + "--profile", "{foo: bar}", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "profile:\n" + + " foo: bar\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "users:tenants", "add-single", + "--api-key", "string", + "--user-id", "user_id", + "--tenant-id", "tenant_id", + ) + }) } func TestUsersTenantsRemoveAll(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "users:tenants", "remove-all", - "--api-key", "string", - "--user-id", "user_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "users:tenants", "remove-all", + "--api-key", "string", + "--user-id", "user_id", + ) + }) } func TestUsersTenantsRemoveSingle(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "users:tenants", "remove-single", - "--api-key", "string", - "--user-id", "user_id", - "--tenant-id", "tenant_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "users:tenants", "remove-single", + "--api-key", "string", + "--user-id", "user_id", + "--tenant-id", "tenant_id", + ) + }) } diff --git a/pkg/cmd/usertoken_test.go b/pkg/cmd/usertoken_test.go index 510ff4c..f9d2fa4 100644 --- a/pkg/cmd/usertoken_test.go +++ b/pkg/cmd/usertoken_test.go @@ -11,108 +11,159 @@ import ( func TestUsersTokensRetrieve(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "users:tokens", "retrieve", - "--api-key", "string", - "--user-id", "user_id", - "--token", "token", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "users:tokens", "retrieve", + "--api-key", "string", + "--user-id", "user_id", + "--token", "token", + ) + }) } func TestUsersTokensUpdate(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "users:tokens", "update", - "--api-key", "string", - "--user-id", "user_id", - "--token", "token", - "--patch", "{op: op, path: path, value: value}", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "users:tokens", "update", + "--api-key", "string", + "--user-id", "user_id", + "--token", "token", + "--patch", "{op: op, path: path, value: value}", + ) + }) - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(usersTokensUpdate) + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(usersTokensUpdate) - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "users:tokens", "update", - "--user-id", "user_id", - "--token", "token", - "--patch.op", "op", - "--patch.path", "path", - "--patch.value", "value", - ) + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "users:tokens", "update", + "--api-key", "string", + "--user-id", "user_id", + "--token", "token", + "--patch.op", "op", + "--patch.path", "path", + "--patch.value", "value", + ) + }) + + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "patch:\n" + + " - op: op\n" + + " path: path\n" + + " value: value\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "users:tokens", "update", + "--api-key", "string", + "--user-id", "user_id", + "--token", "token", + ) + }) } func TestUsersTokensList(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "users:tokens", "list", - "--api-key", "string", - "--user-id", "user_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "users:tokens", "list", + "--api-key", "string", + "--user-id", "user_id", + ) + }) } func TestUsersTokensDelete(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "users:tokens", "delete", - "--api-key", "string", - "--user-id", "user_id", - "--token", "token", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "users:tokens", "delete", + "--api-key", "string", + "--user-id", "user_id", + "--token", "token", + ) + }) } func TestUsersTokensAddMultiple(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "users:tokens", "add-multiple", - "--api-key", "string", - "--user-id", "user_id", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "users:tokens", "add-multiple", + "--api-key", "string", + "--user-id", "user_id", + ) + }) } func TestUsersTokensAddSingle(t *testing.T) { t.Skip("Mock server tests are disabled") - mocktest.TestRunMockTestWithFlags( - t, - "users:tokens", "add-single", - "--api-key", "string", - "--user-id", "user_id", - "--token", "token", - "--provider-key", "firebase-fcm", - "--device", "{ad_id: ad_id, app_id: app_id, device_id: device_id, manufacturer: manufacturer, model: model, platform: platform}", - "--expiry-date", "string", - "--properties", "{}", - "--tracking", "{ip: ip, lat: lat, long: long, os_version: os_version}", - ) + t.Run("regular flags", func(t *testing.T) { + mocktest.TestRunMockTestWithFlags( + t, "users:tokens", "add-single", + "--api-key", "string", + "--user-id", "user_id", + "--token", "token", + "--provider-key", "firebase-fcm", + "--device", "{ad_id: ad_id, app_id: app_id, device_id: device_id, manufacturer: manufacturer, model: model, platform: platform}", + "--expiry-date", "string", + "--properties", "{}", + "--tracking", "{ip: ip, lat: lat, long: long, os_version: os_version}", + ) + }) + + t.Run("inner flags", func(t *testing.T) { + // Check that inner flags have been set up correctly + requestflag.CheckInnerFlags(usersTokensAddSingle) - // Check that inner flags have been set up correctly - requestflag.CheckInnerFlags(usersTokensAddSingle) + // Alternative argument passing style using inner flags + mocktest.TestRunMockTestWithFlags( + t, "users:tokens", "add-single", + "--api-key", "string", + "--user-id", "user_id", + "--token", "token", + "--provider-key", "firebase-fcm", + "--device.ad-id", "ad_id", + "--device.app-id", "app_id", + "--device.device-id", "device_id", + "--device.manufacturer", "manufacturer", + "--device.model", "model", + "--device.platform", "platform", + "--expiry-date", "string", + "--properties", "{}", + "--tracking.ip", "ip", + "--tracking.lat", "lat", + "--tracking.long", "long", + "--tracking.os-version", "os_version", + ) + }) - // Alternative argument passing style using inner flags - mocktest.TestRunMockTestWithFlags( - t, - "users:tokens", "add-single", - "--user-id", "user_id", - "--token", "token", - "--provider-key", "firebase-fcm", - "--device.ad-id", "ad_id", - "--device.app-id", "app_id", - "--device.device-id", "device_id", - "--device.manufacturer", "manufacturer", - "--device.model", "model", - "--device.platform", "platform", - "--expiry-date", "string", - "--properties", "{}", - "--tracking.ip", "ip", - "--tracking.lat", "lat", - "--tracking.long", "long", - "--tracking.os-version", "os_version", - ) + t.Run("piping data", func(t *testing.T) { + // Test piping YAML data over stdin + pipeData := []byte("" + + "provider_key: firebase-fcm\n" + + "device:\n" + + " ad_id: ad_id\n" + + " app_id: app_id\n" + + " device_id: device_id\n" + + " manufacturer: manufacturer\n" + + " model: model\n" + + " platform: platform\n" + + "expiry_date: string\n" + + "properties: {}\n" + + "tracking:\n" + + " ip: ip\n" + + " lat: lat\n" + + " long: long\n" + + " os_version: os_version\n") + mocktest.TestRunMockTestWithPipeAndFlags( + t, pipeData, "users:tokens", "add-single", + "--api-key", "string", + "--user-id", "user_id", + "--token", "token", + ) + }) } diff --git a/pkg/cmd/version.go b/pkg/cmd/version.go index c270687..f5bf4c1 100644 --- a/pkg/cmd/version.go +++ b/pkg/cmd/version.go @@ -2,4 +2,4 @@ package cmd -const Version = "3.1.6" // x-release-please-version +const Version = "3.2.0" // x-release-please-version