Skip to content

Commit

Permalink
CLI Pagination: astro workspace switch command is throwing an error (#…
Browse files Browse the repository at this point in the history
…704)

* fixed workspace switch pagination on quit selection throws an error

* fixed lint issue

* added test cases for workspace switch quit and unable to parse error
  • Loading branch information
ajayy004 authored Aug 30, 2022
1 parent 6d432c0 commit f33e5e5
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 30 deletions.
35 changes: 22 additions & 13 deletions software/workspace/workspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ type workspacePaginationOptions struct {
userSelection int
}

type workspaceSelection struct {
id string
quit bool
err error
}

const (
defaultWorkspacePaginationOptions = "f. first p. previous n. next q. quit\n> "
workspacePaginationWithoutNextOptions = "f. first p. previous q. quit\n> "
Expand Down Expand Up @@ -156,7 +162,7 @@ var workspacesPromptPaginatedOption = func(pageSize, pageNumber, totalRecord int
}
}

func getWorkspaceSelection(pageSize, pageNumber int, client houston.ClientInterface, out io.Writer) (string, error) {
func getWorkspaceSelection(pageSize, pageNumber int, client houston.ClientInterface, out io.Writer) workspaceSelection {
tab := newTableOut()
tab.GetUserInput = true
var ws []houston.Workspace
Expand All @@ -168,12 +174,12 @@ func getWorkspaceSelection(pageSize, pageNumber int, client houston.ClientInterf
ws, err = client.ListWorkspaces()
}
if err != nil {
return "", err
return workspaceSelection{id: "", quit: false, err: err}
}

c, err := config.GetCurrentContext()
if err != nil {
return "", err
return workspaceSelection{id: "", quit: false, err: err}
}

for i := range ws {
Expand All @@ -193,39 +199,42 @@ func getWorkspaceSelection(pageSize, pageNumber int, client houston.ClientInterf

tabPrintErr := tab.PrintWithPageNumber(pageNumber*pageSize, out)
if tabPrintErr != nil {
return "", fmt.Errorf("unable to print with page number: %w", tabPrintErr)
return workspaceSelection{id: "", quit: false, err: fmt.Errorf("unable to print with page number: %w", tabPrintErr)}
}
totalRecords := len(ws)

if pageSize > 0 {
selectedOption := workspacesPromptPaginatedOption(pageSize, pageNumber, totalRecords)
if selectedOption.quit {
if selectedOption.userSelection == 0 {
return "", nil
return workspaceSelection{id: "", quit: true, err: nil}
}
return ws[selectedOption.userSelection-1].ID, nil
return workspaceSelection{id: ws[selectedOption.userSelection-1].ID, quit: false, err: nil}
}
return getWorkspaceSelection(selectedOption.pageSize, selectedOption.pageNumber, client, out)
}

in := input.Text("\n> ")
i, err := strconv.ParseInt(in, 10, 64) //nolint:gomnd
if err != nil {
return "", fmt.Errorf("cannot parse %s to int: %w", in, err)
return workspaceSelection{id: "", quit: false, err: fmt.Errorf("cannot parse %s to int: %w", in, err)}
}

return ws[i-1].ID, nil
return workspaceSelection{id: ws[i-1].ID, quit: false, err: nil}
}

// Switch switches workspaces
func Switch(id string, pageSize int, client houston.ClientInterface, out io.Writer) error {
if id == "" {
_id, err := getWorkspaceSelection(pageSize, 0, client, out)
if err != nil {
return err
workspaceSelection := getWorkspaceSelection(pageSize, 0, client, out)

if workspaceSelection.quit {
return nil
}
if workspaceSelection.err != nil {
return workspaceSelection.err
}

id = _id
id = workspaceSelection.id
}
// validate workspace
_, err := client.GetWorkspace(id)
Expand Down
96 changes: 79 additions & 17 deletions software/workspace/workspace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ func TestGetWorkspaceSelectionError(t *testing.T) {
api.On("ListWorkspaces").Return(nil, errMock)

buf := new(bytes.Buffer)
_, err := getWorkspaceSelection(0, 0, api, buf)
assert.EqualError(t, err, errMock.Error())
workspaceSelection := getWorkspaceSelection(0, 0, api, buf)
assert.EqualError(t, workspaceSelection.err, errMock.Error())
api.AssertExpectations(t)
}

Expand Down Expand Up @@ -252,6 +252,67 @@ contexts:
api.AssertExpectations(t)
}

func TestSwitchWithQuitSelection(t *testing.T) {
// prepare test config and init it
configRaw := []byte(`cloud:
api:
port: "443"
protocol: https
ws_protocol: wss
context: localhost
contexts:
localhost:
domain: localhost
token: token
last_used_workspace: ck05r3bor07h40d02y2hw4n4v
workspace:
`)
fs := afero.NewMemMapFs()
_ = afero.WriteFile(fs, config.HomeConfigFile, configRaw, 0o777)
config.InitConfig(fs)

api := new(mocks.ClientInterface)
api.On("PaginatedListWorkspaces", 10, 0).Return(mockWorkspaceList, nil)

defer testUtil.MockUserInput(t, "q")()

buf := new(bytes.Buffer)
err := Switch("", 10, api, buf)
assert.NoError(t, err)
api.AssertExpectations(t)
}

func TestSwitchWithError(t *testing.T) {
// prepare test config and init it
configRaw := []byte(`cloud:
api:
port: "443"
protocol: https
ws_protocol: wss
context: localhost
contexts:
localhost:
domain: localhost
token: token
last_used_workspace: ck05r3bor07h40d02y2hw4n4v
workspace:
`)
fs := afero.NewMemMapFs()
_ = afero.WriteFile(fs, config.HomeConfigFile, configRaw, 0o777)
config.InitConfig(fs)

api := new(mocks.ClientInterface)
api.On("ListWorkspaces").Return(mockWorkspaceList, nil)

defer testUtil.MockUserInput(t, "y")()

buf := new(bytes.Buffer)
err := Switch("", 0, api, buf)
assert.Contains(t, err.Error(), "cannot parse y to int")
assert.Contains(t, buf.String(), mockWorkspace.ID)
api.AssertExpectations(t)
}

func TestSwitchHoustonError(t *testing.T) {
// prepare test config and init it
configRaw := []byte(`cloud:
Expand Down Expand Up @@ -324,47 +385,48 @@ func TestGetWorkspaceSelection(t *testing.T) {
err := config.ResetCurrentContext()
assert.NoError(t, err)
out := new(bytes.Buffer)
resp, err := getWorkspaceSelection(0, 0, api, out)
workspaceSelection := getWorkspaceSelection(0, 0, api, out)

assert.Contains(t, err.Error(), "no context set, have you authenticated to Astro or Astronomer Software? Run astro login and try again")
assert.Equal(t, "", resp)
assert.Contains(t, workspaceSelection.err.Error(), "no context set, have you authenticated to Astro or Astronomer Software? Run astro login and try again")
assert.Equal(t, "", workspaceSelection.id)
})

testUtil.InitTestConfig("software")

t.Run("success", func(t *testing.T) {
out := new(bytes.Buffer)
defer testUtil.MockUserInput(t, "1")()
resp, err := getWorkspaceSelection(0, 0, api, out)
workspaceSelection := getWorkspaceSelection(0, 0, api, out)

assert.NoError(t, err)
assert.Equal(t, "ck05r3bor07h40d02y2hw4n4v", resp)
assert.NoError(t, workspaceSelection.err)
assert.Equal(t, "ck05r3bor07h40d02y2hw4n4v", workspaceSelection.id)
})

t.Run("success with pagination", func(t *testing.T) {
out := new(bytes.Buffer)
defer testUtil.MockUserInput(t, "1")()
resp, err := getWorkspaceSelection(10, 0, api, out)
workspaceSelection := getWorkspaceSelection(10, 0, api, out)

assert.NoError(t, err)
assert.Equal(t, "ck05r3bor07h40d02y2hw4n4v", resp)
assert.NoError(t, workspaceSelection.err)
assert.Equal(t, "ck05r3bor07h40d02y2hw4n4v", workspaceSelection.id)
})

t.Run("invalid selection", func(t *testing.T) {
out := new(bytes.Buffer)
defer testUtil.MockUserInput(t, "y")()
resp, err := getWorkspaceSelection(0, 0, api, out)
workspaceSelection := getWorkspaceSelection(0, 0, api, out)

assert.Contains(t, err.Error(), "cannot parse y to int")
assert.Equal(t, "", resp)
assert.Contains(t, workspaceSelection.err.Error(), "cannot parse y to int")
assert.Equal(t, "", workspaceSelection.id)
})

t.Run("quit selection when paginated", func(t *testing.T) {
out := new(bytes.Buffer)
defer testUtil.MockUserInput(t, "q")()
resp, err := getWorkspaceSelection(10, 0, api, out)
assert.Nil(t, err)
assert.Equal(t, "", resp)
workspaceSelection := getWorkspaceSelection(10, 0, api, out)
assert.Nil(t, workspaceSelection.err)
assert.Equal(t, "", workspaceSelection.id)
assert.Equal(t, true, workspaceSelection.quit)
})
}

Expand Down

0 comments on commit f33e5e5

Please sign in to comment.