-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(context): add unit tests (#755)
This PR adds tests to the `context` subcommands using the new configuration system implemented in #736
- Loading branch information
Showing
15 changed files
with
639 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package context_test | ||
|
||
import ( | ||
"os" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
|
||
"github.com/hetznercloud/cli/internal/cmd/context" | ||
"github.com/hetznercloud/cli/internal/testutil" | ||
) | ||
|
||
func TestActive(t *testing.T) { | ||
|
||
testConfig := ` | ||
active_context = "my-context" | ||
[[contexts]] | ||
name = "my-context" | ||
token = "super secret token" | ||
` | ||
|
||
type testCase struct { | ||
name string | ||
args []string | ||
config string | ||
err string | ||
expOut string | ||
expErr string | ||
preRun func() | ||
postRun func() | ||
} | ||
|
||
testCases := []testCase{ | ||
{ | ||
name: "no arguments", | ||
args: []string{}, | ||
config: testConfig, | ||
expOut: "my-context\n", | ||
}, | ||
{ | ||
name: "no config", | ||
args: []string{}, | ||
}, | ||
{ | ||
name: "from env", | ||
args: []string{}, | ||
config: testConfig, | ||
preRun: func() { | ||
_ = os.Setenv("HCLOUD_CONTEXT", "abcdef") | ||
}, | ||
postRun: func() { | ||
_ = os.Unsetenv("HCLOUD_CONTEXT") | ||
}, | ||
// 'abcdef' does not exist, so there is nothing printed to stdout. | ||
// The warning 'active context "abcdef" not found' should be printed to stderr during config loading, which | ||
// is before stderr is captured. | ||
}, | ||
{ | ||
name: "invalid config", | ||
args: []string{}, | ||
config: `active_context = "invalid-context-name"`, | ||
// if there is no context with the name of the active_context, there should be no output. See above | ||
}, | ||
} | ||
|
||
for _, tt := range testCases { | ||
t.Run(tt.name, func(t *testing.T) { | ||
|
||
if tt.preRun != nil { | ||
tt.preRun() | ||
} | ||
if tt.postRun != nil { | ||
defer tt.postRun() | ||
} | ||
|
||
fx := testutil.NewFixtureWithConfigFile(t, []byte(tt.config)) | ||
defer fx.Finish() | ||
|
||
cmd := context.NewActiveCommand(fx.State()) | ||
out, errOut, err := fx.Run(cmd, tt.args) | ||
|
||
if tt.err == "" { | ||
assert.NoError(t, err) | ||
} else { | ||
assert.EqualError(t, err, tt.err) | ||
} | ||
assert.Equal(t, tt.expErr, errOut) | ||
assert.Equal(t, tt.expOut, out) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
package context_test | ||
|
||
import ( | ||
"io" | ||
"syscall" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
|
||
"github.com/hetznercloud/cli/internal/cmd/context" | ||
"github.com/hetznercloud/cli/internal/testutil" | ||
) | ||
|
||
func TestCreate(t *testing.T) { | ||
|
||
testConfig := ` | ||
active_context = "my-context" | ||
[[contexts]] | ||
name = "my-context" | ||
token = "super secret token" | ||
` | ||
|
||
type testCase struct { | ||
name string | ||
args []string | ||
config string | ||
isTerm bool | ||
token string | ||
err string | ||
expErr string | ||
expOut string | ||
} | ||
|
||
testCases := []testCase{ | ||
{ | ||
name: "new context", | ||
args: []string{"new-context"}, | ||
isTerm: true, | ||
config: testConfig, | ||
token: "q4acIB6pq2CwsPqF+dNR2B6NTrv4yxmsspvDC1a02OqfMQeCz7nOk4A3pcJha8ix", | ||
expOut: `Token: | ||
active_context = "new-context" | ||
[[contexts]] | ||
name = "my-context" | ||
token = "super secret token" | ||
[[contexts]] | ||
name = "new-context" | ||
token = "q4acIB6pq2CwsPqF+dNR2B6NTrv4yxmsspvDC1a02OqfMQeCz7nOk4A3pcJha8ix" | ||
Context new-context created and activated | ||
`, | ||
}, | ||
{ | ||
name: "not terminal", | ||
args: []string{"new-context"}, | ||
isTerm: false, | ||
config: testConfig, | ||
err: "context create is an interactive command", | ||
expErr: "Error: context create is an interactive command\n", | ||
}, | ||
{ | ||
name: "existing context", | ||
args: []string{"my-context"}, | ||
isTerm: true, | ||
config: testConfig, | ||
token: "q4acIB6pq2CwsPqF+dNR2B6NTrv4yxmsspvDC1a02OqfMQeCz7nOk4A3pcJha8ix", | ||
err: "name already used", | ||
expErr: "Error: name already used\n", | ||
}, | ||
{ | ||
name: "invalid name", | ||
args: []string{""}, | ||
isTerm: true, | ||
config: testConfig, | ||
err: "invalid name", | ||
expErr: "Error: invalid name\n", | ||
}, | ||
{ | ||
name: "token too short", | ||
args: []string{"new-context"}, | ||
isTerm: true, | ||
config: testConfig, | ||
token: "abc", | ||
err: "EOF", | ||
expErr: "Error: EOF\n", | ||
expOut: "Token: \nEntered token is invalid (must be exactly 64 characters long)\nToken: \n", | ||
}, | ||
} | ||
|
||
for _, tt := range testCases { | ||
t.Run(tt.name, func(t *testing.T) { | ||
fx := testutil.NewFixtureWithConfigFile(t, []byte(tt.config)) | ||
defer fx.Finish() | ||
|
||
fx.Terminal.EXPECT().StdoutIsTerminal().Return(tt.isTerm) | ||
|
||
isFirstCall := true | ||
fx.Terminal.EXPECT().ReadPassword(int(syscall.Stdin)).DoAndReturn(func(_ int) ([]byte, error) { | ||
if isFirstCall { | ||
isFirstCall = false | ||
return []byte(tt.token), nil | ||
} | ||
// return EOF after first call to prevent infinite loop | ||
return nil, io.EOF | ||
}).AnyTimes() | ||
|
||
cmd := context.NewCreateCommand(fx.State()) | ||
out, errOut, err := fx.Run(cmd, tt.args) | ||
|
||
if tt.err == "" { | ||
assert.NoError(t, err) | ||
} else { | ||
assert.EqualError(t, err, tt.err) | ||
} | ||
assert.Equal(t, tt.expErr, errOut) | ||
assert.Equal(t, tt.expOut, out) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package context_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
|
||
"github.com/hetznercloud/cli/internal/cmd/context" | ||
"github.com/hetznercloud/cli/internal/testutil" | ||
) | ||
|
||
func TestDelete(t *testing.T) { | ||
|
||
testConfig := ` | ||
active_context = "my-context" | ||
[[contexts]] | ||
name = "my-context" | ||
token = "super secret token" | ||
[[contexts]] | ||
name = "my-other-context" | ||
token = "super secret token" | ||
` | ||
|
||
type testCase struct { | ||
name string | ||
args []string | ||
config string | ||
err string | ||
expErr string | ||
expOut string | ||
} | ||
|
||
testCases := []testCase{ | ||
{ | ||
name: "delete active context", | ||
args: []string{"my-context"}, | ||
config: testConfig, | ||
expErr: "Warning: You are deleting the currently active context. Please select a new active context.\n", | ||
expOut: `active_context = "" | ||
[[contexts]] | ||
name = "my-other-context" | ||
token = "super secret token" | ||
`, | ||
}, | ||
{ | ||
name: "delete inactive context", | ||
args: []string{"my-other-context"}, | ||
config: testConfig, | ||
expOut: `active_context = "my-context" | ||
[[contexts]] | ||
name = "my-context" | ||
token = "super secret token" | ||
`, | ||
}, | ||
{ | ||
name: "delete non-existing context", | ||
args: []string{"non-existing-context"}, | ||
config: testConfig, | ||
err: "context not found: non-existing-context", | ||
expErr: "Error: context not found: non-existing-context\n", | ||
}, | ||
} | ||
|
||
for _, tt := range testCases { | ||
t.Run(tt.name, func(t *testing.T) { | ||
fx := testutil.NewFixtureWithConfigFile(t, []byte(tt.config)) | ||
defer fx.Finish() | ||
|
||
cmd := context.NewDeleteCommand(fx.State()) | ||
out, errOut, err := fx.Run(cmd, tt.args) | ||
|
||
if tt.err == "" { | ||
assert.NoError(t, err) | ||
} else { | ||
assert.EqualError(t, err, tt.err) | ||
} | ||
assert.Equal(t, tt.expErr, errOut) | ||
assert.Equal(t, tt.expOut, out) | ||
}) | ||
} | ||
} |
Oops, something went wrong.