-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathclient_login_test.go
More file actions
121 lines (108 loc) · 3.67 KB
/
client_login_test.go
File metadata and controls
121 lines (108 loc) · 3.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package login
import (
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
configpkg "github.com/hookdeck/hookdeck-cli/pkg/config"
"github.com/hookdeck/hookdeck-cli/pkg/hookdeck"
"github.com/stretchr/testify/require"
)
// TestLogin_validateNonUnauthorizedStillFails verifies that credential
// verification errors other than 401 are returned immediately (no browser flow).
func TestLogin_validateNonUnauthorizedStillFails(t *testing.T) {
configpkg.ResetAPIClientForTesting()
t.Cleanup(configpkg.ResetAPIClientForTesting)
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if strings.HasSuffix(r.URL.Path, "/cli-auth/validate") {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(`{"message":"server boom"}`))
return
}
t.Fatalf("unexpected request %s %s", r.Method, r.URL.Path)
}))
t.Cleanup(ts.Close)
cfg := &configpkg.Config{
APIBaseURL: ts.URL,
DeviceName: "test-device",
LogLevel: "error",
TelemetryDisabled: true,
}
cfg.Profile = configpkg.Profile{
Name: "default",
APIKey: "hk_test_123456789012",
Config: cfg,
}
err := Login(cfg, strings.NewReader("\n"))
require.Error(t, err)
}
// TestLogin_unauthorizedValidateStartsBrowserFlow checks that a 401 from
// validate is followed by POST /cli-auth (browser login), then a successful poll.
func TestLogin_unauthorizedValidateStartsBrowserFlow(t *testing.T) {
configpkg.ResetAPIClientForTesting()
t.Cleanup(configpkg.ResetAPIClientForTesting)
oldCan := canOpenBrowser
oldOpen := openBrowser
canOpenBrowser = func() bool { return false }
openBrowser = func(string) error { return nil }
t.Cleanup(func() {
canOpenBrowser = oldCan
openBrowser = oldOpen
})
pollHits := 0
var serverURL string
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method == http.MethodGet && strings.HasSuffix(r.URL.Path, "/cli-auth/validate"):
w.WriteHeader(http.StatusUnauthorized)
_, _ = w.Write([]byte("Unauthorized"))
case r.Method == http.MethodPost && strings.HasSuffix(r.URL.Path, "/cli-auth"):
pollURL := serverURL + hookdeck.APIPathPrefix + "/cli-auth/poll?key=pollkey"
body, err := json.Marshal(map[string]string{
"browser_url": "https://example.test/auth",
"poll_url": pollURL,
})
require.NoError(t, err)
_, _ = w.Write(body)
case r.Method == http.MethodGet && strings.Contains(r.URL.Path, "/cli-auth/poll"):
pollHits++
resp := map[string]interface{}{
"claimed": true,
"key": "hk_test_newkey_abcdefghij",
"team_id": "tm_1",
"team_mode": "gateway",
"team_name": "Proj",
"user_name": "U",
"user_email": "u@example.com",
"organization_name": "Org",
"organization_id": "org_1",
"client_id": "cl_1",
}
enc, err := json.Marshal(resp)
require.NoError(t, err)
_, _ = w.Write(enc)
default:
t.Fatalf("unexpected request %s %s", r.Method, r.URL.Path)
}
}))
serverURL = ts.URL
t.Cleanup(ts.Close)
configPath := filepath.Join(t.TempDir(), "config.toml")
require.NoError(t, os.WriteFile(configPath, []byte(`profile = "default"
[default]
api_key = "hk_test_oldkey_abcdefghij"
`), 0o600))
cfg, err := configpkg.LoadConfigFromFile(configPath)
require.NoError(t, err)
cfg.APIBaseURL = ts.URL
cfg.DeviceName = "test-device"
cfg.LogLevel = "error"
cfg.TelemetryDisabled = true
err = Login(cfg, strings.NewReader("\n"))
require.NoError(t, err)
require.Equal(t, 1, pollHits, "poll should run once with immediate claimed=true")
require.Equal(t, "hk_test_newkey_abcdefghij", cfg.Profile.APIKey)
}