|
24a217e…
|
lmata
|
1 |
package api |
|
24a217e…
|
lmata
|
2 |
|
|
24a217e…
|
lmata
|
3 |
import ( |
|
24a217e…
|
lmata
|
4 |
"bytes" |
|
24a217e…
|
lmata
|
5 |
"context" |
|
24a217e…
|
lmata
|
6 |
"encoding/json" |
|
24a217e…
|
lmata
|
7 |
"io" |
|
24a217e…
|
lmata
|
8 |
"log/slog" |
|
24a217e…
|
lmata
|
9 |
"net/http" |
|
24a217e…
|
lmata
|
10 |
"net/http/httptest" |
|
24a217e…
|
lmata
|
11 |
"testing" |
|
24a217e…
|
lmata
|
12 |
|
|
68677f9…
|
noreply
|
13 |
"github.com/conflicthq/scuttlebot/internal/auth" |
|
24a217e…
|
lmata
|
14 |
"github.com/conflicthq/scuttlebot/internal/bots/bridge" |
|
24a217e…
|
lmata
|
15 |
"github.com/conflicthq/scuttlebot/internal/registry" |
|
24a217e…
|
lmata
|
16 |
) |
|
24a217e…
|
lmata
|
17 |
|
|
24a217e…
|
lmata
|
18 |
type stubChatBridge struct { |
|
24a217e…
|
lmata
|
19 |
touched []struct { |
|
24a217e…
|
lmata
|
20 |
channel string |
|
24a217e…
|
lmata
|
21 |
nick string |
|
24a217e…
|
lmata
|
22 |
} |
|
24a217e…
|
lmata
|
23 |
} |
|
24a217e…
|
lmata
|
24 |
|
|
24a217e…
|
lmata
|
25 |
func (b *stubChatBridge) Channels() []string { return nil } |
|
24a217e…
|
lmata
|
26 |
func (b *stubChatBridge) JoinChannel(string) {} |
|
5ac549c…
|
lmata
|
27 |
func (b *stubChatBridge) LeaveChannel(string) {} |
|
24a217e…
|
lmata
|
28 |
func (b *stubChatBridge) Messages(string) []bridge.Message { return nil } |
|
24a217e…
|
lmata
|
29 |
func (b *stubChatBridge) Subscribe(string) (<-chan bridge.Message, func()) { |
|
24a217e…
|
lmata
|
30 |
return make(chan bridge.Message), func() {} |
|
24a217e…
|
lmata
|
31 |
} |
|
24a217e…
|
lmata
|
32 |
func (b *stubChatBridge) Send(context.Context, string, string, string) error { return nil } |
|
f3c383e…
|
noreply
|
33 |
func (b *stubChatBridge) SendWithMeta(_ context.Context, _, _, _ string, _ *bridge.Meta) error { |
|
f3c383e…
|
noreply
|
34 |
return nil |
|
f3c383e…
|
noreply
|
35 |
} |
|
6d94dfd…
|
noreply
|
36 |
func (b *stubChatBridge) Stats() bridge.Stats { return bridge.Stats{} } |
|
6d94dfd…
|
noreply
|
37 |
func (b *stubChatBridge) Users(string) []string { return nil } |
|
6d94dfd…
|
noreply
|
38 |
func (b *stubChatBridge) UsersWithModes(string) []bridge.UserInfo { return nil } |
|
6d94dfd…
|
noreply
|
39 |
func (b *stubChatBridge) ChannelModes(string) string { return "" } |
|
cca45cb…
|
lmata
|
40 |
func (b *stubChatBridge) RefreshNames(string) {} |
|
24a217e…
|
lmata
|
41 |
func (b *stubChatBridge) TouchUser(channel, nick string) { |
|
24a217e…
|
lmata
|
42 |
b.touched = append(b.touched, struct{ channel, nick string }{channel: channel, nick: nick}) |
|
24a217e…
|
lmata
|
43 |
} |
|
24a217e…
|
lmata
|
44 |
|
|
24a217e…
|
lmata
|
45 |
func TestHandleChannelPresence(t *testing.T) { |
|
24a217e…
|
lmata
|
46 |
t.Helper() |
|
24a217e…
|
lmata
|
47 |
|
|
24a217e…
|
lmata
|
48 |
bridgeStub := &stubChatBridge{} |
|
24a217e…
|
lmata
|
49 |
reg := registry.New(nil, []byte("test-signing-key")) |
|
24a217e…
|
lmata
|
50 |
logger := slog.New(slog.NewTextHandler(io.Discard, nil)) |
|
68677f9…
|
noreply
|
51 |
srv := httptest.NewServer(New(reg, auth.TestStore("token"), bridgeStub, nil, nil, nil, nil, nil, "", logger).Handler()) |
|
24a217e…
|
lmata
|
52 |
defer srv.Close() |
|
24a217e…
|
lmata
|
53 |
|
|
24a217e…
|
lmata
|
54 |
body, _ := json.Marshal(map[string]string{"nick": "codex-test"}) |
|
24a217e…
|
lmata
|
55 |
req, err := http.NewRequest(http.MethodPost, srv.URL+"/v1/channels/general/presence", bytes.NewReader(body)) |
|
24a217e…
|
lmata
|
56 |
if err != nil { |
|
24a217e…
|
lmata
|
57 |
t.Fatal(err) |
|
24a217e…
|
lmata
|
58 |
} |
|
24a217e…
|
lmata
|
59 |
req.Header.Set("Authorization", "Bearer token") |
|
24a217e…
|
lmata
|
60 |
req.Header.Set("Content-Type", "application/json") |
|
24a217e…
|
lmata
|
61 |
|
|
24a217e…
|
lmata
|
62 |
resp, err := http.DefaultClient.Do(req) |
|
24a217e…
|
lmata
|
63 |
if err != nil { |
|
24a217e…
|
lmata
|
64 |
t.Fatal(err) |
|
24a217e…
|
lmata
|
65 |
} |
|
24a217e…
|
lmata
|
66 |
defer resp.Body.Close() |
|
24a217e…
|
lmata
|
67 |
if resp.StatusCode != http.StatusNoContent { |
|
24a217e…
|
lmata
|
68 |
t.Fatalf("status = %d, want %d", resp.StatusCode, http.StatusNoContent) |
|
24a217e…
|
lmata
|
69 |
} |
|
24a217e…
|
lmata
|
70 |
if len(bridgeStub.touched) != 1 { |
|
24a217e…
|
lmata
|
71 |
t.Fatalf("TouchUser calls = %d, want 1", len(bridgeStub.touched)) |
|
24a217e…
|
lmata
|
72 |
} |
|
24a217e…
|
lmata
|
73 |
if bridgeStub.touched[0].channel != "#general" || bridgeStub.touched[0].nick != "codex-test" { |
|
24a217e…
|
lmata
|
74 |
t.Fatalf("TouchUser args = %#v", bridgeStub.touched[0]) |
|
24a217e…
|
lmata
|
75 |
} |
|
24a217e…
|
lmata
|
76 |
} |
|
24a217e…
|
lmata
|
77 |
|
|
24a217e…
|
lmata
|
78 |
func TestHandleChannelPresenceRequiresNick(t *testing.T) { |
|
24a217e…
|
lmata
|
79 |
t.Helper() |
|
24a217e…
|
lmata
|
80 |
|
|
24a217e…
|
lmata
|
81 |
bridgeStub := &stubChatBridge{} |
|
24a217e…
|
lmata
|
82 |
reg := registry.New(nil, []byte("test-signing-key")) |
|
24a217e…
|
lmata
|
83 |
logger := slog.New(slog.NewTextHandler(io.Discard, nil)) |
|
68677f9…
|
noreply
|
84 |
srv := httptest.NewServer(New(reg, auth.TestStore("token"), bridgeStub, nil, nil, nil, nil, nil, "", logger).Handler()) |
|
24a217e…
|
lmata
|
85 |
defer srv.Close() |
|
24a217e…
|
lmata
|
86 |
|
|
24a217e…
|
lmata
|
87 |
body, _ := json.Marshal(map[string]string{}) |
|
24a217e…
|
lmata
|
88 |
req, err := http.NewRequest(http.MethodPost, srv.URL+"/v1/channels/general/presence", bytes.NewReader(body)) |
|
24a217e…
|
lmata
|
89 |
if err != nil { |
|
24a217e…
|
lmata
|
90 |
t.Fatal(err) |
|
24a217e…
|
lmata
|
91 |
} |
|
24a217e…
|
lmata
|
92 |
req.Header.Set("Authorization", "Bearer token") |
|
24a217e…
|
lmata
|
93 |
req.Header.Set("Content-Type", "application/json") |
|
24a217e…
|
lmata
|
94 |
|
|
24a217e…
|
lmata
|
95 |
resp, err := http.DefaultClient.Do(req) |
|
24a217e…
|
lmata
|
96 |
if err != nil { |
|
24a217e…
|
lmata
|
97 |
t.Fatal(err) |
|
24a217e…
|
lmata
|
98 |
} |
|
24a217e…
|
lmata
|
99 |
defer resp.Body.Close() |
|
24a217e…
|
lmata
|
100 |
if resp.StatusCode != http.StatusBadRequest { |
|
24a217e…
|
lmata
|
101 |
t.Fatalf("status = %d, want %d", resp.StatusCode, http.StatusBadRequest) |
|
24a217e…
|
lmata
|
102 |
} |
|
24a217e…
|
lmata
|
103 |
if len(bridgeStub.touched) != 0 { |
|
24a217e…
|
lmata
|
104 |
t.Fatalf("TouchUser calls = %d, want 0", len(bridgeStub.touched)) |
|
24a217e…
|
lmata
|
105 |
} |
|
24a217e…
|
lmata
|
106 |
} |