4
4
"context"
5
5
"encoding/json"
6
6
"fmt"
7
+ "golang.org/x/exp/slices"
8
+ "golang.org/x/xerrors"
7
9
"net/http"
8
10
"net/http/httptest"
9
11
"net/url"
@@ -37,19 +39,24 @@ func TestMain(m *testing.M) {
37
39
}
38
40
39
41
// TestBasicNotificationRoundtrip enqueues a message to the store, waits for it to be acquired by a notifier,
40
- // and passes it off to a fake handler.
42
+ // passes it off to a fake handler, and ensures the results are synchronized to the store .
41
43
func TestBasicNotificationRoundtrip (t * testing.T ) {
42
44
t .Parallel ()
43
45
44
46
// SETUP
45
- ctx , logger , db := setupInMemory (t )
47
+ if ! dbtestutil .WillUsePostgres () {
48
+ t .Skip ("This test requires postgres; it relies on business-logic only implemented in the database" )
49
+ }
50
+
51
+ ctx , logger , db := setup (t )
46
52
method := database .NotificationMethodSmtp
47
53
48
54
// GIVEN: a manager with standard config but a faked dispatch handler
49
55
handler := & fakeHandler {}
50
-
56
+ interceptor := & bulkUpdateInterceptor { Store : db }
51
57
cfg := defaultNotificationsConfig (method )
52
- mgr , err := notifications .NewManager (cfg , db , logger .Named ("manager" ))
58
+ cfg .RetryInterval = serpent .Duration (time .Hour ) // Ensure retries don't interfere with the test
59
+ mgr , err := notifications .NewManager (cfg , interceptor , logger .Named ("manager" ))
53
60
require .NoError (t , err )
54
61
mgr .WithHandlers (map [database.NotificationMethod ]notifications.Handler {method : handler })
55
62
t .Cleanup (func () {
@@ -68,17 +75,33 @@ func TestBasicNotificationRoundtrip(t *testing.T) {
68
75
69
76
mgr .Run (ctx )
70
77
71
- // THEN: we expect that the handler will have received the notifications for delivery
78
+ // THEN: we expect that the handler will have received the notifications for dispatch
72
79
require .Eventually (t , func () bool {
73
80
handler .mu .RLock ()
74
81
defer handler .mu .RUnlock ()
75
- return handler .succeeded == sid .String ()
76
- }, testutil .WaitLong , testutil .IntervalMedium )
82
+ return slices .Contains (handler .succeeded , sid .String ()) &&
83
+ slices .Contains (handler .failed , fid .String ())
84
+ }, testutil .WaitLong , testutil .IntervalFast )
85
+
86
+ // THEN: we expect the store to be called with the updates of the earlier dispatches
77
87
require .Eventually (t , func () bool {
78
- handler .mu .RLock ()
79
- defer handler .mu .RUnlock ()
80
- return handler .failed == fid .String ()
81
- }, testutil .WaitLong , testutil .IntervalMedium )
88
+ return interceptor .sent .Load () == 1 &&
89
+ interceptor .failed .Load () == 1
90
+ }, testutil .WaitShort , testutil .IntervalFast )
91
+
92
+ // THEN: we verify that the store contains notifications in their expected state
93
+ success , err := db .GetNotificationMessagesByStatus (ctx , database.GetNotificationMessagesByStatusParams {
94
+ Status : database .NotificationMessageStatusSent ,
95
+ Limit : 10 ,
96
+ })
97
+ require .NoError (t , err )
98
+ require .Len (t , success , 1 )
99
+ failed , err := db .GetNotificationMessagesByStatus (ctx , database.GetNotificationMessagesByStatusParams {
100
+ Status : database .NotificationMessageStatusTemporaryFailure ,
101
+ Limit : 10 ,
102
+ })
103
+ require .NoError (t , err )
104
+ require .Len (t , failed , 1 )
82
105
}
83
106
84
107
func TestSMTPDispatch (t * testing.T ) {
@@ -517,8 +540,8 @@ func TestInvalidConfig(t *testing.T) {
517
540
type fakeHandler struct {
518
541
mu sync.RWMutex
519
542
520
- succeeded string
521
- failed string
543
+ succeeded [] string
544
+ failed [] string
522
545
}
523
546
524
547
func (f * fakeHandler ) Dispatcher (payload types.MessagePayload , _ , _ string ) (dispatch.DeliveryFunc , error ) {
@@ -527,11 +550,12 @@ func (f *fakeHandler) Dispatcher(payload types.MessagePayload, _, _ string) (dis
527
550
defer f .mu .Unlock ()
528
551
529
552
if payload .Labels ["type" ] == "success" {
530
- f .succeeded = msgID .String ()
531
- } else {
532
- f .failed = msgID .String ()
553
+ f .succeeded = append (f .succeeded , msgID .String ())
554
+ return false , nil
533
555
}
534
- return false , nil
556
+
557
+ f .failed = append (f .failed , msgID .String ())
558
+ return true , xerrors .New ("oops" )
535
559
}, nil
536
560
}
537
561
0 commit comments