@@ -2,6 +2,8 @@ package webpush_test
2
2
3
3
import (
4
4
"context"
5
+ "encoding/json"
6
+ "io"
5
7
"net/http"
6
8
"net/http/httptest"
7
9
"testing"
@@ -32,7 +34,9 @@ func TestPush(t *testing.T) {
32
34
t .Run ("SuccessfulDelivery" , func (t * testing.T ) {
33
35
t .Parallel ()
34
36
ctx := testutil .Context (t , testutil .WaitShort )
35
- manager , store , serverURL := setupPushTest (ctx , t , func (w http.ResponseWriter , _ * http.Request ) {
37
+ msg := randomWebpushMessage (t )
38
+ manager , store , serverURL := setupPushTest (ctx , t , func (w http.ResponseWriter , r * http.Request ) {
39
+ assertWebpushPayload (t , r )
36
40
w .WriteHeader (http .StatusOK )
37
41
})
38
42
user := dbgen .User (t , store , database.User {})
@@ -45,16 +49,7 @@ func TestPush(t *testing.T) {
45
49
})
46
50
require .NoError (t , err )
47
51
48
- notification := codersdk.WebpushMessage {
49
- Title : "Test Title" ,
50
- Body : "Test Body" ,
51
- Actions : []codersdk.WebpushMessageAction {
52
- {Label : "View" , URL : "https://coder.com/view" },
53
- },
54
- Icon : "workspace" ,
55
- }
56
-
57
- err = manager .Dispatch (ctx , user .ID , notification )
52
+ err = manager .Dispatch (ctx , user .ID , msg )
58
53
require .NoError (t , err )
59
54
60
55
subscriptions , err := store .GetWebpushSubscriptionsByUserID (ctx , user .ID )
@@ -66,7 +61,8 @@ func TestPush(t *testing.T) {
66
61
t .Run ("ExpiredSubscription" , func (t * testing.T ) {
67
62
t .Parallel ()
68
63
ctx := testutil .Context (t , testutil .WaitShort )
69
- manager , store , serverURL := setupPushTest (ctx , t , func (w http.ResponseWriter , _ * http.Request ) {
64
+ manager , store , serverURL := setupPushTest (ctx , t , func (w http.ResponseWriter , r * http.Request ) {
65
+ assertWebpushPayload (t , r )
70
66
w .WriteHeader (http .StatusGone )
71
67
})
72
68
user := dbgen .User (t , store , database.User {})
@@ -79,12 +75,8 @@ func TestPush(t *testing.T) {
79
75
})
80
76
require .NoError (t , err )
81
77
82
- notification := codersdk.WebpushMessage {
83
- Title : "Test Title" ,
84
- Body : "Test Body" ,
85
- }
86
-
87
- err = manager .Dispatch (ctx , user .ID , notification )
78
+ msg := randomWebpushMessage (t )
79
+ err = manager .Dispatch (ctx , user .ID , msg )
88
80
require .NoError (t , err )
89
81
90
82
subscriptions , err := store .GetWebpushSubscriptionsByUserID (ctx , user .ID )
@@ -95,7 +87,8 @@ func TestPush(t *testing.T) {
95
87
t .Run ("FailedDelivery" , func (t * testing.T ) {
96
88
t .Parallel ()
97
89
ctx := testutil .Context (t , testutil .WaitShort )
98
- manager , store , serverURL := setupPushTest (ctx , t , func (w http.ResponseWriter , _ * http.Request ) {
90
+ manager , store , serverURL := setupPushTest (ctx , t , func (w http.ResponseWriter , r * http.Request ) {
91
+ assertWebpushPayload (t , r )
99
92
w .WriteHeader (http .StatusBadRequest )
100
93
w .Write ([]byte ("Invalid request" ))
101
94
})
@@ -110,12 +103,8 @@ func TestPush(t *testing.T) {
110
103
})
111
104
require .NoError (t , err )
112
105
113
- notification := codersdk.WebpushMessage {
114
- Title : "Test Title" ,
115
- Body : "Test Body" ,
116
- }
117
-
118
- err = manager .Dispatch (ctx , user .ID , notification )
106
+ msg := randomWebpushMessage (t )
107
+ err = manager .Dispatch (ctx , user .ID , msg )
119
108
require .Error (t , err )
120
109
assert .Contains (t , err .Error (), "Invalid request" )
121
110
@@ -130,13 +119,15 @@ func TestPush(t *testing.T) {
130
119
ctx := testutil .Context (t , testutil .WaitShort )
131
120
var okEndpointCalled bool
132
121
var goneEndpointCalled bool
133
- manager , store , serverOKURL := setupPushTest (ctx , t , func (w http.ResponseWriter , _ * http.Request ) {
122
+ manager , store , serverOKURL := setupPushTest (ctx , t , func (w http.ResponseWriter , r * http.Request ) {
134
123
okEndpointCalled = true
124
+ assertWebpushPayload (t , r )
135
125
w .WriteHeader (http .StatusOK )
136
126
})
137
127
138
- serverGone := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , _ * http.Request ) {
128
+ serverGone := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
139
129
goneEndpointCalled = true
130
+ assertWebpushPayload (t , r )
140
131
w .WriteHeader (http .StatusGone )
141
132
}))
142
133
defer serverGone .Close ()
@@ -163,15 +154,8 @@ func TestPush(t *testing.T) {
163
154
})
164
155
require .NoError (t , err )
165
156
166
- notification := codersdk.WebpushMessage {
167
- Title : "Test Title" ,
168
- Body : "Test Body" ,
169
- Actions : []codersdk.WebpushMessageAction {
170
- {Label : "View" , URL : "https://coder.com/view" },
171
- },
172
- }
173
-
174
- err = manager .Dispatch (ctx , user .ID , notification )
157
+ msg := randomWebpushMessage (t )
158
+ err = manager .Dispatch (ctx , user .ID , msg )
175
159
require .NoError (t , err )
176
160
assert .True (t , okEndpointCalled , "The valid endpoint should be called" )
177
161
assert .True (t , goneEndpointCalled , "The expired endpoint should be called" )
@@ -189,8 +173,9 @@ func TestPush(t *testing.T) {
189
173
190
174
ctx := testutil .Context (t , testutil .WaitShort )
191
175
var requestReceived bool
192
- manager , store , serverURL := setupPushTest (ctx , t , func (w http.ResponseWriter , _ * http.Request ) {
176
+ manager , store , serverURL := setupPushTest (ctx , t , func (w http.ResponseWriter , r * http.Request ) {
193
177
requestReceived = true
178
+ assertWebpushPayload (t , r )
194
179
w .WriteHeader (http .StatusOK )
195
180
})
196
181
@@ -205,17 +190,8 @@ func TestPush(t *testing.T) {
205
190
})
206
191
require .NoError (t , err , "Failed to insert push subscription" )
207
192
208
- notification := codersdk.WebpushMessage {
209
- Title : "Test Notification" ,
210
- Body : "This is a test notification body" ,
211
- Actions : []codersdk.WebpushMessageAction {
212
- {Label : "View Workspace" , URL : "https://coder.com/workspace/123" },
213
- {Label : "Cancel" , URL : "https://coder.com/cancel" },
214
- },
215
- Icon : "workspace-icon" ,
216
- }
217
-
218
- err = manager .Dispatch (ctx , user .ID , notification )
193
+ msg := randomWebpushMessage (t )
194
+ err = manager .Dispatch (ctx , user .ID , msg )
219
195
require .NoError (t , err , "The push notification should be dispatched successfully" )
220
196
require .True (t , requestReceived , "The push notification request should have been received by the server" )
221
197
})
@@ -242,15 +218,42 @@ func TestPush(t *testing.T) {
242
218
})
243
219
}
244
220
221
+ func randomWebpushMessage (t testing.TB ) codersdk.WebpushMessage {
222
+ t .Helper ()
223
+ return codersdk.WebpushMessage {
224
+ Title : testutil .GetRandomName (t ),
225
+ Body : testutil .GetRandomName (t ),
226
+
227
+ Actions : []codersdk.WebpushMessageAction {
228
+ {Label : "A" , URL : "https://example.com/a" },
229
+ {Label : "B" , URL : "https://example.com/b" },
230
+ },
231
+ Icon : "https://example.com/icon.png" ,
232
+ }
233
+ }
234
+
235
+ func assertWebpushPayload (t testing.TB , r * http.Request ) {
236
+ t .Helper ()
237
+ assert .Equal (t , http .MethodPost , r .Method )
238
+ assert .Equal (t , "application/octet-stream" , r .Header .Get ("Content-Type" ))
239
+ assert .Equal (t , r .Header .Get ("content-encoding" ), "aes128gcm" )
240
+ assert .Contains (t , r .Header .Get ("Authorization" ), "vapid" )
241
+
242
+ // Attempting to decode the request body as JSON should fail as it is
243
+ // encrypted.
244
+ assert .Error (t , json .NewDecoder (r .Body ).Decode (io .Discard ))
245
+ }
246
+
245
247
// setupPushTest creates a common test setup for webpush notification tests
246
248
func setupPushTest (ctx context.Context , t * testing.T , handlerFunc func (w http.ResponseWriter , r * http.Request )) (webpush.Dispatcher , database.Store , string ) {
249
+ t .Helper ()
247
250
logger := slogtest .Make (t , & slogtest.Options {IgnoreErrors : true }).Leveled (slog .LevelDebug )
248
251
db , _ := dbtestutil .NewDB (t )
249
252
250
253
server := httptest .NewServer (http .HandlerFunc (handlerFunc ))
251
254
t .Cleanup (server .Close )
252
255
253
- manager , err := webpush .New (ctx , & logger , db )
256
+ manager , err := webpush .New (ctx , & logger , db , "http://example.com" )
254
257
require .NoError (t , err , "Failed to create webpush manager" )
255
258
256
259
return manager , db , server .URL
0 commit comments