-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add toggle flag step #111
Changes from all commits
1198a77
08c92c6
a920be7
58b1958
6fbd79b
b1d2fd5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -89,3 +89,83 @@ func TestUpdate(t *testing.T) { | |
assert.EqualError(t, err, "base-uri is invalid"+errorHelp) | ||
}) | ||
} | ||
|
||
func TestToggle(t *testing.T) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added tests to make sure i didn't break anything |
||
errorHelp := ". See `ldcli flags toggle-on --help` for supported flags and usage." | ||
mockArgs := []interface{}{ | ||
"testAccessToken", | ||
"http://test.com", | ||
"test-proj-key", | ||
"test-flag-key", | ||
[]flags.UpdateInput{ | ||
{ | ||
Op: "replace", | ||
Path: "/environments/test-env-key/on", | ||
Value: true, | ||
}, | ||
}, | ||
} | ||
t.Run("with valid flags calls projects API", func(t *testing.T) { | ||
client := flags.MockClient{} | ||
client. | ||
On("Update", mockArgs...). | ||
Return([]byte(cmd.ValidResponse), nil) | ||
args := []string{ | ||
"flags", "toggle-on", | ||
"--access-token", "testAccessToken", | ||
"--base-uri", "http://test.com", | ||
"--flag", "test-flag-key", | ||
"--project", "test-proj-key", | ||
"--environment", "test-env-key", | ||
} | ||
|
||
output, err := cmd.CallCmd(t, nil, &client, nil, nil, args) | ||
|
||
require.NoError(t, err) | ||
assert.JSONEq(t, `{"valid": true}`, string(output)) | ||
}) | ||
|
||
t.Run("with an error response is an error", func(t *testing.T) { | ||
client := flags.MockClient{} | ||
client. | ||
On("Update", mockArgs...). | ||
Return([]byte(`{}`), errors.NewError("An error")) | ||
args := []string{ | ||
"flags", "toggle-on", | ||
"--access-token", "testAccessToken", | ||
"--base-uri", "http://test.com", | ||
"--flag", "test-flag-key", | ||
"--project", "test-proj-key", | ||
"--environment", "test-env-key", | ||
} | ||
|
||
_, err := cmd.CallCmd(t, nil, &client, nil, nil, args) | ||
|
||
require.EqualError(t, err, "An error") | ||
}) | ||
|
||
t.Run("with missing required flags is an error", func(t *testing.T) { | ||
args := []string{ | ||
"flags", "toggle-on", | ||
} | ||
|
||
_, err := cmd.CallCmd(t, nil, &flags.MockClient{}, nil, nil, args) | ||
|
||
assert.EqualError(t, err, `required flag(s) "access-token", "environment", "flag", "project" not set`+errorHelp) | ||
}) | ||
|
||
t.Run("with invalid base-uri is an error", func(t *testing.T) { | ||
args := []string{ | ||
"flags", "toggle-on", | ||
"--access-token", "testAccessToken", | ||
"--base-uri", "invalid", | ||
"--flag", "test-flag-key", | ||
"--project", "test-proj-key", | ||
"--environment", "test-env-key", | ||
} | ||
|
||
_, err := cmd.CallCmd(t, nil, &flags.MockClient{}, nil, nil, args) | ||
|
||
assert.EqualError(t, err, "base-uri is invalid"+errorHelp) | ||
}) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,11 @@ import ( | |
"ldcli/internal/flags" | ||
) | ||
|
||
const ( | ||
defaultProjKey = "default" | ||
defaultEnvKey = "test" | ||
) | ||
|
||
// ContainerModel is a high level container model that controls the nested models wher each | ||
// represents a step in the quick-start flow. | ||
type ContainerModel struct { | ||
|
@@ -23,13 +28,14 @@ type ContainerModel struct { | |
accessToken string | ||
baseUri string | ||
currentModel tea.Model | ||
sdkKind string | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. like flagKey storing anything we might need in a subsequent step on the container model |
||
} | ||
|
||
func NewContainerModel(flagsClient flags.Client, accessToken string, baseUri string) tea.Model { | ||
return ContainerModel{ | ||
accessToken: accessToken, | ||
baseUri: baseUri, | ||
currentModel: NewCreateFlagModel(flagsClient), | ||
currentModel: NewCreateFlagModel(flagsClient, accessToken, baseUri), | ||
flagsClient: flagsClient, | ||
} | ||
} | ||
|
@@ -53,18 +59,19 @@ func (m ContainerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { | |
case choseSDKMsg: | ||
m.currentModel = NewShowSDKInstructionsModel(m.accessToken, m.baseUri, msg.canonicalName, msg.url, m.flagKey) | ||
cmd = m.currentModel.Init() | ||
m.sdkKind = msg.sdkKind | ||
case createdFlagMsg: | ||
m.currentModel = NewChooseSDKModel() | ||
m.flagKey = msg.flagKey // TODO: figure out if we maintain state here or pass in another message | ||
case errMsg: | ||
m.err = msg.err | ||
case noInstructionsMsg: | ||
// TODO: set currentModel to toggle flag model | ||
// m.currentModel = NewToggleFlagModel(m.flagsClient, m.flagKey) | ||
case fetchedSDKInstructions, fetchedEnv: | ||
// skip the ShowSDKInstructionsModel and move along to toggling the flag | ||
m.currentModel = NewToggleFlagModel(m.flagsClient, m.accessToken, m.baseUri, m.flagKey, m.sdkKind) | ||
case fetchedSDKInstructions, fetchedEnv, toggledFlagMsg: | ||
m.currentModel, cmd = m.currentModel.Update(msg) | ||
case showToggleFlagMsg: | ||
m.currentModel = NewToggleFlagModel(m.flagKey) | ||
m.currentModel = NewToggleFlagModel(m.flagsClient, m.accessToken, m.baseUri, m.flagKey, m.sdkKind) | ||
default: | ||
log.Println("container default - bad", msg) | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,10 +2,6 @@ package quickstart | |
|
||
import ( | ||
"fmt" | ||
"ldcli/cmd/cliflags" | ||
|
||
"github.com/spf13/viper" | ||
|
||
"ldcli/internal/flags" | ||
|
||
"github.com/charmbracelet/bubbles/key" | ||
|
@@ -17,20 +13,24 @@ import ( | |
const defaultFlagName = "my new flag" | ||
|
||
type createFlagModel struct { | ||
client flags.Client | ||
textInput textinput.Model | ||
accessToken string | ||
baseUri string | ||
client flags.Client | ||
textInput textinput.Model | ||
} | ||
|
||
func NewCreateFlagModel(client flags.Client) tea.Model { | ||
func NewCreateFlagModel(client flags.Client, accessToken, baseUri string) tea.Model { | ||
ti := textinput.New() | ||
ti.Focus() | ||
ti.CharLimit = 156 | ||
ti.Width = 20 | ||
ti.Placeholder = defaultFlagName | ||
|
||
return createFlagModel{ | ||
client: client, | ||
textInput: ti, | ||
accessToken: accessToken, | ||
baseUri: baseUri, | ||
client: client, | ||
textInput: ti, | ||
} | ||
} | ||
|
||
|
@@ -53,10 +53,7 @@ func (m createFlagModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { | |
return m, sendErr(err) | ||
} | ||
|
||
accessToken := viper.GetString(cliflags.AccessTokenFlag) | ||
baseUri := viper.GetString(cliflags.BaseURIFlag) | ||
Comment on lines
-56
to
-57
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. removed this since we have this at the container level/should set these values on the createFlagModel |
||
|
||
return m, sendCreateFlagMsg(m.client, accessToken, baseUri, input, flagKey, "default") | ||
return m, sendCreateFlagMsg(m.client, m.accessToken, m.baseUri, input, flagKey, defaultProjKey) | ||
case key.Matches(msg, keys.Quit): | ||
return m, tea.Quit | ||
default: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,25 @@ func sendErr(err error) tea.Cmd { | |
} | ||
} | ||
|
||
type toggledFlagMsg struct{} | ||
|
||
func sendToggleFlagMsg(client flags.Client, accessToken, baseUri, flagKey string, enabled bool) tea.Cmd { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it make more sense to name this after the message it sends, so in this case it would be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ya I did actually get a bit tripped on this looking for the the actual msg type it specified when I picked it back up again, but it is also Doing The Thing here |
||
return func() tea.Msg { | ||
_, err := client.Update( | ||
context.Background(), | ||
accessToken, | ||
baseUri, | ||
flagKey, | ||
defaultProjKey, | ||
flags.BuildToggleFlagPatch(defaultEnvKey, enabled), | ||
) | ||
if err != nil { | ||
return sendErr(err) | ||
} | ||
return toggledFlagMsg{} | ||
} | ||
} | ||
|
||
type createdFlagMsg struct { | ||
flagKey string | ||
} | ||
|
@@ -75,6 +94,7 @@ type fetchedSDKInstructions struct { | |
type choseSDKMsg struct { | ||
canonicalName string | ||
displayName string | ||
sdkKind string | ||
url string | ||
} | ||
|
||
|
@@ -88,6 +108,7 @@ func sendChoseSDKMsg(sdk sdkDetail) tea.Cmd { | |
canonicalName: sdk.canonicalName, | ||
displayName: sdk.displayName, | ||
url: sdk.url, | ||
sdkKind: sdk.kind, | ||
} | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refactored this to play better with where we call this in the quickstart