@@ -339,6 +339,79 @@ func TestInflightDispatchesMetric(t *testing.T) {
339
339
},testutil .WaitShort ,testutil .IntervalFast )
340
340
}
341
341
342
+ func TestCustomMethodMetricCollection (t * testing.T ) {
343
+ t .Parallel ()
344
+
345
+ // SETUP
346
+ if ! dbtestutil .WillUsePostgres () {
347
+ // UpdateNotificationTemplateMethodByID only makes sense with a real database.
348
+ t .Skip ("This test requires postgres; it relies on business-logic only implemented in the database" )
349
+ }
350
+ ctx ,logger ,store := setup (t )
351
+
352
+ var (
353
+ reg = prometheus .NewRegistry ()
354
+ metrics = notifications .NewMetrics (reg )
355
+ template = notifications .TemplateWorkspaceDeleted
356
+ anotherTemplate = notifications .TemplateWorkspaceDormant
357
+ )
358
+
359
+ const (
360
+ customMethod = database .NotificationMethodWebhook
361
+ defaultMethod = database .NotificationMethodSmtp
362
+ )
363
+
364
+ // GIVEN: a template whose notification method differs from the default.
365
+ out ,err := store .UpdateNotificationTemplateMethodByID (ctx , database.UpdateNotificationTemplateMethodByIDParams {
366
+ ID :template ,
367
+ Method : database.NullNotificationMethod {NotificationMethod :customMethod ,Valid :true },
368
+ })
369
+ require .NoError (t ,err )
370
+ require .Equal (t ,customMethod ,out .Method .NotificationMethod )
371
+
372
+ // WHEN: two notifications (each with different templates) are enqueued.
373
+ cfg := defaultNotificationsConfig (defaultMethod )
374
+ mgr ,err := notifications .NewManager (cfg ,store ,metrics ,logger .Named ("manager" ))
375
+ require .NoError (t ,err )
376
+ t .Cleanup (func () {
377
+ assert .NoError (t ,mgr .Stop (ctx ))
378
+ })
379
+
380
+ smtpHandler := & fakeHandler {}
381
+ webhookHandler := & fakeHandler {}
382
+ mgr .WithHandlers (map [database.NotificationMethod ]notifications.Handler {
383
+ defaultMethod :smtpHandler ,
384
+ customMethod :webhookHandler ,
385
+ })
386
+
387
+ enq ,err := notifications .NewStoreEnqueuer (cfg ,store ,defaultHelpers (),logger .Named ("enqueuer" ))
388
+ require .NoError (t ,err )
389
+
390
+ user := createSampleUser (t ,store )
391
+
392
+ _ ,err = enq .Enqueue (ctx ,user .ID ,template ,map [string ]string {"type" :"success" },"test" )
393
+ _ ,err = enq .Enqueue (ctx ,user .ID ,anotherTemplate ,map [string ]string {"type" :"success" },"test" )
394
+
395
+ mgr .Run (ctx )
396
+
397
+ // THEN: the fake handlers to "dispatch" the notifications.
398
+ require .Eventually (t ,func ()bool {
399
+ smtpHandler .mu .RLock ()
400
+ webhookHandler .mu .RLock ()
401
+ defer smtpHandler .mu .RUnlock ()
402
+ defer webhookHandler .mu .RUnlock ()
403
+
404
+ return len (smtpHandler .succeeded )== 1 && len (smtpHandler .failed )== 0 &&
405
+ len (webhookHandler .succeeded )== 1 && len (webhookHandler .failed )== 0
406
+ },testutil .WaitShort ,testutil .IntervalFast )
407
+
408
+ // THEN: we should have metric series for both the default and custom notification methods.
409
+ require .Eventually (t ,func ()bool {
410
+ return promtest .ToFloat64 (metrics .DispatchAttempts .WithLabelValues (string (defaultMethod ),anotherTemplate .String (),notifications .ResultSuccess ))> 0 &&
411
+ promtest .ToFloat64 (metrics .DispatchAttempts .WithLabelValues (string (customMethod ),template .String (),notifications .ResultSuccess ))> 0
412
+ },testutil .WaitShort ,testutil .IntervalFast )
413
+ }
414
+
342
415
// hasMatchingFingerprint checks if the given metric's series fingerprint matches the reference fingerprint.
343
416
func hasMatchingFingerprint (metric * dto.Metric ,fp model.Fingerprint )bool {
344
417
return fingerprintLabelPairs (metric .Label )== fp