Live video on the AT Protocol
1package statedb
2
3import (
4 "testing"
5
6 "github.com/stretchr/testify/require"
7 "stream.place/streamplace/pkg/streamplace"
8)
9
10func TestWebhookCreation(t *testing.T) {
11 WithAllDatabases(t, func(state *StatefulDB) {
12 webhook := &Webhook{
13 UserDID: "did:web:example.com",
14 URL: "https://example.com",
15 Events: []byte(`["test"]`),
16 Active: true,
17 }
18 err := state.CreateWebhook(webhook)
19 require.NoError(t, err)
20 activeWebhooks, err := state.GetActiveWebhooksForUser("did:web:example.com", "test")
21 require.NoError(t, err)
22 require.Len(t, activeWebhooks, 1)
23 require.Equal(t, webhook.URL, activeWebhooks[0].URL)
24 require.Equal(t, webhook.Events, activeWebhooks[0].Events)
25 })
26}
27
28func TestWebhookUpdatePartially(t *testing.T) {
29 WithAllDatabases(t, func(state *StatefulDB) {
30 webhook := &Webhook{
31 ID: "webhook1",
32 UserDID: "did:web:example.com",
33 URL: "https://example.com",
34 Events: []byte(`["test"]`),
35 }
36 err := state.CreateWebhook(webhook)
37 require.NoError(t, err)
38
39 // Update only the URL
40 webhook.URL = "https://newexample.com"
41 updatedWebhook, err := state.UpdateWebhook(webhook.ID, webhook.UserDID,
42 map[string]any{
43 "url": webhook.URL,
44 },
45 )
46 require.NoError(t, err)
47
48 require.NoError(t, err)
49 require.Equal(t, "https://newexample.com", updatedWebhook.URL)
50 require.JSONEq(t, `["test"]`, string(updatedWebhook.Events))
51 })
52}
53
54func TestWebhookCrossUserAccess(t *testing.T) {
55 WithAllDatabases(t, func(state *StatefulDB) {
56 webhook := &Webhook{
57 ID: "webhook2",
58 UserDID: "did:web:example.com",
59 URL: "https://example.com",
60 Events: []byte(`["test"]`),
61 }
62 err := state.CreateWebhook(webhook)
63 require.NoError(t, err)
64
65 // malicious user tries to update
66 _, err = state.UpdateWebhook(webhook.ID, "did:web:not.example.com",
67 map[string]any{
68 "url": "https://malicious.com",
69 },
70 )
71 require.Error(t, err)
72
73 // malicious user tries to delete
74 err = state.DeleteWebhook(webhook.ID, "did:web:not.example.com")
75 require.Error(t, err)
76 })
77}
78
79func TestWebhookDelete(t *testing.T) {
80 WithAllDatabases(t, func(state *StatefulDB) {
81 webhook := &Webhook{
82 ID: "webhook3",
83 UserDID: "did:web:example.com",
84 URL: "https://example.com",
85 Events: []byte(`["test"]`),
86 }
87 err := state.CreateWebhook(webhook)
88 require.NoError(t, err)
89
90 err = state.DeleteWebhook(webhook.ID, webhook.UserDID)
91 require.NoError(t, err)
92 _, err = state.GetWebhook(webhook.ID, webhook.UserDID)
93 require.Error(t, err)
94 require.Contains(t, err.Error(), "webhook not found")
95 })
96}
97
98func TestWebhookListPaginationAndFilters(t *testing.T) {
99 WithAllDatabases(t, func(state *StatefulDB) {
100 // clear for clean tests
101 state.DB.Where("1 = 1").Delete(&Webhook{})
102
103 for i := 1; i <= 5; i++ {
104 webhook := &Webhook{
105 UserDID: "did:web:example.com",
106 URL: "https://example.com/" + string(rune(i)),
107 Events: []byte(`["test"]`),
108 Active: i%2 == 0,
109 }
110 t.Logf("webhook should be %v", webhook.Active)
111 err := state.CreateWebhook(webhook)
112 require.NoError(t, err)
113
114 // Debug: verify what was actually saved
115 savedWebhook, err := state.GetWebhook(webhook.ID, webhook.UserDID)
116 require.NoError(t, err)
117 t.Logf("Webhook %d: expected active=%v, saved active=%v", i, webhook.Active, savedWebhook.Active)
118 }
119
120 // with paging
121 webhooks, err := state.ListWebhooks("did:web:example.com", 2, 1, map[string]any{})
122 require.NoError(t, err)
123 require.Len(t, webhooks, 2)
124
125 // with filter
126 activeWebhooks, err := state.ListWebhooks("did:web:example.com", 5, 0, map[string]any{"active": true})
127 require.NoError(t, err)
128 require.Len(t, activeWebhooks, 2)
129 })
130}
131
132func TestWebhookCreateEmptyURLFails(t *testing.T) {
133 WithAllDatabases(t, func(state *StatefulDB) {
134 webhook := &Webhook{UserDID: "did:web:example.com", URL: "", Events: []byte(`["test"]`)}
135 err := state.CreateWebhook(webhook)
136 require.Error(t, err)
137 })
138}
139
140func TestWebhookConversionFunctions(t *testing.T) {
141 WithAllDatabases(t, func(state *StatefulDB) {
142 // Test FromLexiconInput conversion
143 active := true
144 prefix := "test-prefix"
145 suffix := "test-suffix"
146 name := "test-name"
147 description := "test description"
148
149 input := &streamplace.ServerCreateWebhook_Input{
150 Url: "https://example.com/webhook",
151 Events: []string{"chat", "livestream"},
152 Active: &active,
153 Prefix: &prefix,
154 Suffix: &suffix,
155 Name: &name,
156 Description: &description,
157 Rewrite: []*streamplace.ServerDefs_RewriteRule{
158 {From: "old", To: "new"},
159 {From: "hello", To: "hi"},
160 },
161 }
162
163 webhook, err := WebhookFromLexiconInput(input, "did:web:example.com", "test-webhook-id")
164 require.NoError(t, err)
165 require.Equal(t, "test-webhook-id", webhook.ID)
166 require.Equal(t, "did:web:example.com", webhook.UserDID)
167 require.Equal(t, "https://example.com/webhook", webhook.URL)
168 require.True(t, webhook.Active)
169 require.Equal(t, "test-prefix", webhook.Prefix)
170 require.Equal(t, "test-suffix", webhook.Suffix)
171 require.Equal(t, "test-name", webhook.Name)
172 require.Equal(t, "test description", webhook.Description)
173
174 // Save to database and retrieve
175 err = state.CreateWebhook(webhook)
176 require.NoError(t, err)
177
178 retrievedWebhook, err := state.GetWebhook("test-webhook-id", "did:web:example.com")
179 require.NoError(t, err)
180
181 // Test ToLexicon conversion
182 lexiconWebhook, err := retrievedWebhook.ToLexicon()
183 require.NoError(t, err)
184 require.Equal(t, "test-webhook-id", lexiconWebhook.Id)
185 require.Equal(t, "https://example.com/webhook", lexiconWebhook.Url)
186 require.True(t, lexiconWebhook.Active)
187 require.Equal(t, []string{"chat", "livestream"}, lexiconWebhook.Events)
188 require.NotNil(t, lexiconWebhook.Prefix)
189 require.Equal(t, "test-prefix", *lexiconWebhook.Prefix)
190 require.NotNil(t, lexiconWebhook.Suffix)
191 require.Equal(t, "test-suffix", *lexiconWebhook.Suffix)
192 require.NotNil(t, lexiconWebhook.Name)
193 require.Equal(t, "test-name", *lexiconWebhook.Name)
194 require.NotNil(t, lexiconWebhook.Description)
195 require.Equal(t, "test description", *lexiconWebhook.Description)
196 require.Len(t, lexiconWebhook.Rewrite, 2)
197 require.Equal(t, "old", lexiconWebhook.Rewrite[0].From)
198 require.Equal(t, "new", lexiconWebhook.Rewrite[0].To)
199 require.Equal(t, "hello", lexiconWebhook.Rewrite[1].From)
200 require.Equal(t, "hi", lexiconWebhook.Rewrite[1].To)
201 })
202}