@@ -2,27 +2,40 @@ import { Test, TestingModule } from '@nestjs/testing';
22import { NotFoundException , InternalServerErrorException } from '@nestjs/common' ;
33import { PushNotificationService } from './push-notification.service' ;
44import { SUPABASE_CLIENT } from './supabase.provider' ;
5- import { env } from '../config/env.config' ;
65
76describe ( 'PushNotificationService' , ( ) => {
87 let service : PushNotificationService ;
9- const mockSelect = jest . fn ( ) ;
8+
9+ // Tracks what mockSelect should resolve to for the next call
10+ let selectResult : { data : unknown ; error : unknown } = { data : [ ] , error : null } ;
11+
12+ const mockEq = jest . fn ( ) ;
13+ const mockIn = jest . fn ( ) ;
1014 const mockSingle = jest . fn ( ) ;
1115 const mockUpsert = jest . fn ( ( ) => ( { select : ( ) => ( { single : mockSingle } ) } ) ) ;
12- const mockDelete = jest . fn ( ( ) => ( { eq : jest . fn ( ) . mockReturnThis ( ) , in : jest . fn ( ) . mockReturnThis ( ) } ) ) ;
16+ const mockDelete = jest . fn ( ( ) => ( {
17+ eq : jest . fn ( ) . mockReturnThis ( ) ,
18+ in : jest . fn ( ) . mockResolvedValue ( { error : null } ) ,
19+ } ) ) ;
20+
21+ // select('*').eq(...) must return a Promise
22+ const mockSelect = jest . fn ( ( ) => ( {
23+ eq : jest . fn ( ) . mockResolvedValue ( selectResult ) ,
24+ } ) ) ;
1325
1426 const supabaseMock = {
1527 from : jest . fn ( ( ) => ( {
1628 upsert : mockUpsert ,
1729 delete : mockDelete ,
1830 select : mockSelect ,
19- eq : jest . fn ( ) . mockReturnThis ( ) ,
20- in : jest . fn ( ) . mockReturnThis ( ) ,
31+ eq : mockEq ,
32+ in : mockIn ,
2133 } ) ) ,
2234 } ;
2335
2436 beforeEach ( async ( ) => {
2537 jest . clearAllMocks ( ) ;
38+ selectResult = { data : [ ] , error : null } ;
2639
2740 const module : TestingModule = await Test . createTestingModule ( {
2841 providers : [
@@ -46,29 +59,28 @@ describe('PushNotificationService', () => {
4659 } ) ;
4760
4861 it ( 'unregisters a device token' , async ( ) => {
49- mockDelete . mockReturnValue ( { eq : jest . fn ( ) . mockReturnThis ( ) , in : jest . fn ( ) . mockReturnThis ( ) } ) ;
5062 await service . unregisterDeviceToken ( 'GABC' , 'tok' ) ;
5163 expect ( supabaseMock . from ) . toHaveBeenCalledWith ( 'push_tokens' ) ;
5264 expect ( mockDelete ) . toHaveBeenCalled ( ) ;
5365 } ) ;
5466
5567 it ( 'gets device tokens for a user' , async ( ) => {
56- mockSelect . mockReturnValue ( { eq : jest . fn ( ) . mockReturnThis ( ) , data : [ { user_address : 'GABC' , device_token : 'tok' , platform : 'fcm' } ] , error : null } ) ;
68+ selectResult = { data : [ { user_address : 'GABC' , device_token : 'tok' , platform : 'fcm' } ] , error : null } ;
5769
5870 const tokens = await service . getDeviceTokens ( 'GABC' ) ;
5971
6072 expect ( tokens ) . toEqual ( [ { user_address : 'GABC' , device_token : 'tok' , platform : 'fcm' } ] ) ;
6173 expect ( supabaseMock . from ) . toHaveBeenCalledWith ( 'push_tokens' ) ;
74+ expect ( mockSelect ) . toHaveBeenCalledWith ( '*' ) ;
6275 } ) ;
6376
6477 it ( 'throws NotFoundException when sendToUser has no tokens' , async ( ) => {
65- mockSelect . mockReturnValue ( { eq : jest . fn ( ) . mockReturnThis ( ) , data : [ ] , error : null } ) ;
78+ selectResult = { data : [ ] , error : null } ;
6679 await expect ( service . sendToUser ( 'GABC' , { title : 'hi' , body : 'hello' } ) ) . rejects . toThrow ( NotFoundException ) ;
6780 } ) ;
6881
6982 it ( 'throws InternalServerErrorException when FCM is not configured' , async ( ) => {
70- mockSelect . mockReturnValue ( { eq : jest . fn ( ) . mockReturnThis ( ) , data : [ { user_address : 'GABC' , device_token : 'tok' , platform : 'fcm' } ] , error : null } ) ;
71-
83+ selectResult = { data : [ { user_address : 'GABC' , device_token : 'tok' , platform : 'fcm' } ] , error : null } ;
7284 await expect ( service . sendToUser ( 'GABC' , { title : 'hi' , body : 'hello' } ) ) . rejects . toThrow ( InternalServerErrorException ) ;
7385 } ) ;
7486} ) ;
0 commit comments