@@ -0,0 +1,306 @@
1 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ package apiclient_test
2 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
3 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ import (
4 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "encoding/json"
5 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "net/http"
6 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "net/http/httptest"
7 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "testing"
8 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
9 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "github.com/conflicthq/scuttlebot/cmd/scuttlectl/internal/apiclient"
10 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ )
11 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
12 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ func newServer(t *testing.T, handler http.Handler) (*httptest.Server, *apiclient.Client) {
13 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Helper()
14 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ srv := httptest.NewServer(handler)
15 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Cleanup(srv.Close)
16 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return srv, apiclient.New(srv.URL, "test-token")
17 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
18 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
19 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ func TestStatus(t *testing.T) {
20 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ srv, client := newServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
21 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if r.URL.Path != "/v1/status" || r.Method != http.MethodGet {
22 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ http.NotFound(w, r)
23 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return
24 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
25 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assertBearer(t, r)
26 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ w.Header().Set("Content-Type", "application/json")
27 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, _ = w.Write([]byte(`{"status":"ok"}`))
28 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }))
29 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _ = srv
30 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
31 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ raw, err := client.Status()
32 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err != nil {
33 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Fatal(err)
34 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
35 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ var got map[string]string
36 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err := json.Unmarshal(raw, &got); err != nil {
37 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Fatal(err)
38 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
39 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if got["status"] != "ok" {
40 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Errorf("status: got %q", got["status"])
41 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
42 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
43 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
44 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ func TestListAgents(t *testing.T) {
45 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, client := newServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
46 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assertBearer(t, r)
47 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ w.Header().Set("Content-Type", "application/json")
48 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, _ = w.Write([]byte(`{"agents":[{"nick":"claude-1"}]}`))
49 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }))
50 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
51 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ raw, err := client.ListAgents()
52 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err != nil {
53 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Fatal(err)
54 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
55 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if len(raw) == 0 {
56 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Error("expected non-empty response")
57 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
58 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
59 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
60 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ func TestGetAgent(t *testing.T) {
61 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, client := newServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
62 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assertBearer(t, r)
63 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if r.URL.Path != "/v1/agents/claude-1" {
64 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ http.NotFound(w, r)
65 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return
66 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
67 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ w.Header().Set("Content-Type", "application/json")
68 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, _ = w.Write([]byte(`{"nick":"claude-1","type":"worker"}`))
69 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }))
70 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
71 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ raw, err := client.GetAgent("claude-1")
72 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err != nil {
73 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Fatal(err)
74 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
75 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ var got map[string]string
76 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err := json.Unmarshal(raw, &got); err != nil {
77 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Fatal(err)
78 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
79 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if got["nick"] != "claude-1" {
80 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Errorf("nick: got %q", got["nick"])
81 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
82 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
83 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
84 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ func TestRegisterAgent(t *testing.T) {
85 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ var gotBody map[string]any
86 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, client := newServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
87 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assertBearer(t, r)
88 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err := json.NewDecoder(r.Body).Decode(&gotBody); err != nil {
89 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ http.Error(w, err.Error(), http.StatusBadRequest)
90 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return
91 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
92 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ w.Header().Set("Content-Type", "application/json")
93 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ w.WriteHeader(http.StatusCreated)
94 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, _ = w.Write([]byte(`{"nick":"claude-1","credentials":{"passphrase":"secret"}}`))
95 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }))
96 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
97 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ raw, err := client.RegisterAgent("claude-1", "worker", []string{"#general"})
98 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err != nil {
99 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Fatal(err)
100 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
101 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if raw == nil {
102 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Error("expected response body")
103 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
104 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if gotBody["nick"] != "claude-1" {
105 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Errorf("body nick: got %v", gotBody["nick"])
106 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
107 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if gotBody["type"] != "worker" {
108 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Errorf("body type: got %v", gotBody["type"])
109 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
110 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
111 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
112 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ func TestRevokeAgent(t *testing.T) {
113 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ called := false
114 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, client := newServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
115 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assertBearer(t, r)
116 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if r.URL.Path == "/v1/agents/claude-1/revoke" && r.Method == http.MethodPost {
117 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ called = true
118 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ w.Header().Set("Content-Type", "application/json")
119 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, _ = w.Write([]byte(`{}`))
120 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ } else {
121 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ http.NotFound(w, r)
122 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
123 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }))
124 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
125 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err := client.RevokeAgent("claude-1"); err != nil {
126 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Fatal(err)
127 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
128 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if !called {
129 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Error("revoke endpoint not called")
130 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
131 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
132 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
133 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ func TestRotateAgent(t *testing.T) {
134 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, client := newServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
135 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assertBearer(t, r)
136 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ w.Header().Set("Content-Type", "application/json")
137 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, _ = w.Write([]byte(`{"passphrase":"newpass"}`))
138 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }))
139 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
140 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ raw, err := client.RotateAgent("claude-1")
141 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err != nil {
142 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Fatal(err)
143 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
144 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ var got map[string]string
145 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err := json.Unmarshal(raw, &got); err != nil {
146 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Fatal(err)
147 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
148 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if got["passphrase"] != "newpass" {
149 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Errorf("passphrase: got %q", got["passphrase"])
150 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
151 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
152 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
153 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ func TestDeleteAgent(t *testing.T) {
154 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ called := false
155 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, client := newServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
156 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assertBearer(t, r)
157 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if r.Method == http.MethodDelete && r.URL.Path == "/v1/agents/claude-1" {
158 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ called = true
159 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ w.WriteHeader(http.StatusNoContent)
160 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ } else {
161 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ http.NotFound(w, r)
162 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
163 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }))
164 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
165 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err := client.DeleteAgent("claude-1"); err != nil {
166 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Fatal(err)
167 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
168 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if !called {
169 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Error("delete endpoint not called")
170 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
171 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
172 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
173 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ func TestListChannels(t *testing.T) {
174 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, client := newServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
175 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assertBearer(t, r)
176 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ w.Header().Set("Content-Type", "application/json")
177 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, _ = w.Write([]byte(`{"channels":["#general","#ops"]}`))
178 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }))
179 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
180 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ raw, err := client.ListChannels()
181 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err != nil {
182 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Fatal(err)
183 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
184 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if len(raw) == 0 {
185 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Error("expected non-empty response")
186 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
187 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
188 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
189 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ func TestDeleteChannel(t *testing.T) {
190 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ called := false
191 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, client := newServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
192 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assertBearer(t, r)
193 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if r.Method == http.MethodDelete && r.URL.Path == "/v1/channels/general" {
194 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ called = true
195 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ w.WriteHeader(http.StatusNoContent)
196 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ } else {
197 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ http.NotFound(w, r)
198 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
199 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }))
200 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
201 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ // should strip the leading #
202 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err := client.DeleteChannel("#general"); err != nil {
203 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Fatal(err)
204 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
205 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if !called {
206 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Error("delete channel endpoint not called")
207 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
208 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
209 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
210 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ func TestGetLLMBackend(t *testing.T) {
211 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, client := newServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
212 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assertBearer(t, r)
213 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ w.Header().Set("Content-Type", "application/json")
214 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, _ = w.Write([]byte(`{"backends":[{"name":"anthropic","backend":"anthropic"},{"name":"ollama","backend":"ollama"}]}`))
215 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }))
216 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
217 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ raw, err := client.GetLLMBackend("ollama")
218 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err != nil {
219 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Fatal(err)
220 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
221 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ var got map[string]string
222 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err := json.Unmarshal(raw, &got); err != nil {
223 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Fatal(err)
224 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
225 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if got["name"] != "ollama" {
226 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Errorf("name: got %q", got["name"])
227 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
228 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
229 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
230 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ func TestGetLLMBackendNotFound(t *testing.T) {
231 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, client := newServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
232 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assertBearer(t, r)
233 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ w.Header().Set("Content-Type", "application/json")
234 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, _ = w.Write([]byte(`{"backends":[]}`))
235 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }))
236 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
237 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, err := client.GetLLMBackend("nonexistent")
238 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err == nil {
239 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Error("expected error for missing backend, got nil")
240 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
241 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
242 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
243 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ func TestAPIError(t *testing.T) {
244 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, client := newServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
245 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ w.Header().Set("Content-Type", "application/json")
246 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ w.WriteHeader(http.StatusUnauthorized)
247 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, _ = w.Write([]byte(`{"error":"invalid token"}`))
248 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }))
249 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
250 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, err := client.Status()
251 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err == nil {
252 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Fatal("expected error, got nil")
253 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
254 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err.Error() != "API error 401: invalid token" {
255 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Errorf("error message: got %q", err.Error())
256 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
257 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
258 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
259 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ func TestAddAdmin(t *testing.T) {
260 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ var gotBody map[string]string
261 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, client := newServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
262 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assertBearer(t, r)
263 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _ = json.NewDecoder(r.Body).Decode(&gotBody)
264 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ w.Header().Set("Content-Type", "application/json")
265 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ w.WriteHeader(http.StatusCreated)
266 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, _ = w.Write([]byte(`{"username":"alice"}`))
267 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }))
268 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
269 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ raw, err := client.AddAdmin("alice", "hunter2")
270 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err != nil {
271 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Fatal(err)
272 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
273 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if raw == nil {
274 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Error("expected response")
275 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
276 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if gotBody["username"] != "alice" || gotBody["password"] != "hunter2" {
277 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Errorf("body: got %v", gotBody)
278 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
279 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
280 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
281 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ func TestRemoveAdmin(t *testing.T) {
282 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ called := false
283 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ _, client := newServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
284 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assertBearer(t, r)
285 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if r.Method == http.MethodDelete && r.URL.Path == "/v1/admins/alice" {
286 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ called = true
287 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ w.WriteHeader(http.StatusNoContent)
288 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ } else {
289 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ http.NotFound(w, r)
290 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
291 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }))
292 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
293 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if err := client.RemoveAdmin("alice"); err != nil {
294 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Fatal(err)
295 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
296 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if !called {
297 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Error("remove admin endpoint not called")
298 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
299 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
300 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
301 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ func assertBearer(t *testing.T, r *http.Request) {
302 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Helper()
303 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if r.Header.Get("Authorization") != "Bearer test-token" {
304 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ t.Errorf("Authorization header: got %q", r.Header.Get("Authorization"))
305 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
306 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }