From 3e96fcd06d8ce4e4efd879efda0b011688393e1c Mon Sep 17 00:00:00 2001 From: Zach Date: Tue, 10 Mar 2026 13:27:36 -0700 Subject: [PATCH] (refactor) make dev-server, login, and sourcemaps commands testable via CallCmd() Wire NewStartServerCmd, NewLoginCmd, and NewSourcemapsCmd through the existing APIClients struct instead of constructing hardcoded real clients inline. Add dev_server.MockClient and three tests for start_server.go. --- cmd/dev_server/start_server_test.go | 63 +++++++++++++++++++++++++++++ cmd/root.go | 6 +-- internal/dev_server/mock_client.go | 15 +++++++ 3 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 cmd/dev_server/start_server_test.go create mode 100644 internal/dev_server/mock_client.go diff --git a/cmd/dev_server/start_server_test.go b/cmd/dev_server/start_server_test.go new file mode 100644 index 00000000..8d723f44 --- /dev/null +++ b/cmd/dev_server/start_server_test.go @@ -0,0 +1,63 @@ +package dev_server_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/launchdarkly/ldcli/cmd" + "github.com/launchdarkly/ldcli/internal/analytics" + "github.com/launchdarkly/ldcli/internal/dev_server" +) + +func TestStartServerCmd(t *testing.T) { + baseArgs := []string{ + "dev-server", "start", + "--access-token", "test-token", + "--project", "test-proj", + "--source", "staging", + } + + t.Run("calls RunServer with parsed context JSON", func(t *testing.T) { + mockClient := &dev_server.MockClient{} + _, err := cmd.CallCmd( + t, + cmd.APIClients{DevClient: mockClient}, + analytics.NoopClientFn{}.Tracker(), + append(baseArgs, "--context", `{"kind":"user","key":"test-user"}`), + ) + + require.NoError(t, err) + assert.True(t, mockClient.RunServerCalled) + require.NotNil(t, mockClient.RunServerParams.InitialProjectSettings.Context) + assert.Equal(t, "test-user", mockClient.RunServerParams.InitialProjectSettings.Context.Key()) + }) + + t.Run("calls RunServer with parsed override JSON", func(t *testing.T) { + mockClient := &dev_server.MockClient{} + _, err := cmd.CallCmd( + t, + cmd.APIClients{DevClient: mockClient}, + analytics.NoopClientFn{}.Tracker(), + append(baseArgs, "--override", `{"my-flag": true}`), + ) + + require.NoError(t, err) + assert.True(t, mockClient.RunServerCalled) + assert.Len(t, mockClient.RunServerParams.InitialProjectSettings.Overrides, 1) + }) + + t.Run("returns error for malformed context JSON", func(t *testing.T) { + mockClient := &dev_server.MockClient{} + _, err := cmd.CallCmd( + t, + cmd.APIClients{DevClient: mockClient}, + analytics.NoopClientFn{}.Tracker(), + append(baseArgs, "--context", `not-valid-json`), + ) + + require.Error(t, err) + assert.False(t, mockClient.RunServerCalled) + }) +} diff --git a/cmd/root.go b/cmd/root.go index c6989b36..99a23158 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -201,10 +201,10 @@ func NewRootCommand( configCmd := configcmd.NewConfigCmd(configService, analyticsTrackerFn) cmd.AddCommand(configCmd.Cmd()) cmd.AddCommand(NewQuickStartCmd(analyticsTrackerFn, clients.EnvironmentsClient, clients.FlagsClient)) - cmd.AddCommand(logincmd.NewLoginCmd(resources.NewClient(version))) + cmd.AddCommand(logincmd.NewLoginCmd(clients.ResourcesClient)) cmd.AddCommand(resourcecmd.NewResourcesCmd()) - cmd.AddCommand(devcmd.NewDevServerCmd(resources.NewClient(version), analyticsTrackerFn, dev_server.NewClient(version))) - cmd.AddCommand(sourcemapscmd.NewSourcemapsCmd(resources.NewClient(version), analyticsTrackerFn)) + cmd.AddCommand(devcmd.NewDevServerCmd(clients.ResourcesClient, analyticsTrackerFn, clients.DevClient)) + cmd.AddCommand(sourcemapscmd.NewSourcemapsCmd(clients.ResourcesClient, analyticsTrackerFn)) resourcecmd.AddAllResourceCmds(cmd, clients.ResourcesClient, analyticsTrackerFn) // add non-generated commands diff --git a/internal/dev_server/mock_client.go b/internal/dev_server/mock_client.go new file mode 100644 index 00000000..b0ce0412 --- /dev/null +++ b/internal/dev_server/mock_client.go @@ -0,0 +1,15 @@ +package dev_server + +import "context" + +type MockClient struct { + RunServerCalled bool + RunServerParams ServerParams +} + +var _ Client = &MockClient{} + +func (c *MockClient) RunServer(ctx context.Context, params ServerParams) { + c.RunServerCalled = true + c.RunServerParams = params +}