11import { Test , TestingModule } from '@nestjs/testing' ;
2+ import { NotFoundException } from '@nestjs/common' ;
23import { LimitsService } from './limits.service' ;
34import { PrismaService } from '../prisma/prisma.service' ;
45
56describe ( 'LimitsService' , ( ) => {
67 let service : LimitsService ;
78 let prisma : any ;
89
10+ const walletId = 'wallet-uuid-1' ;
11+
912 beforeEach ( async ( ) => {
1013 prisma = {
11- userLimit : {
14+ walletLimit : {
1215 upsert : jest . fn ( ) ,
1316 findUnique : jest . fn ( ) ,
17+ delete : jest . fn ( ) ,
1418 } ,
15- payment : {
16- aggregate : jest . fn ( ) ,
19+ transaction : {
20+ findMany : jest . fn ( ) ,
1721 } ,
1822 } ;
1923
@@ -29,50 +33,88 @@ describe('LimitsService', () => {
2933 } ) ;
3034
3135 describe ( 'setLimits' , ( ) => {
32- it ( 'should upsert limits' , async ( ) => {
33- await service . setLimits ( 1 , 100 , 10 ) ;
34- expect ( prisma . userLimit . upsert ) . toHaveBeenCalledWith ( {
35- where : { userId : 1 } ,
36+ it ( 'should upsert wallet limits' , async ( ) => {
37+ await service . setLimits ( walletId , 100 , 10 ) ;
38+ expect ( prisma . walletLimit . upsert ) . toHaveBeenCalledWith ( {
39+ where : { walletId } ,
3640 update : { dailyLimit : 100 , perTransactionLimit : 10 } ,
37- create : { userId : 1 , dailyLimit : 100 , perTransactionLimit : 10 } ,
41+ create : { walletId , dailyLimit : 100 , perTransactionLimit : 10 } ,
3842 } ) ;
3943 } ) ;
4044 } ) ;
4145
46+ describe ( 'getLimits' , ( ) => {
47+ it ( 'should return limits for a wallet' , async ( ) => {
48+ const limit = { walletId, dailyLimit : 100 , perTransactionLimit : 10 } ;
49+ prisma . walletLimit . findUnique . mockResolvedValue ( limit ) ;
50+ const result = await service . getLimits ( walletId ) ;
51+ expect ( result ) . toEqual ( limit ) ;
52+ expect ( prisma . walletLimit . findUnique ) . toHaveBeenCalledWith ( { where : { walletId } } ) ;
53+ } ) ;
54+ } ) ;
55+
4256 describe ( 'checkLimits' , ( ) => {
4357 it ( 'should pass if no limits set' , async ( ) => {
44- prisma . userLimit . findUnique . mockResolvedValue ( null ) ;
45- await expect ( service . checkLimits ( 1 , 100 ) ) . resolves . not . toThrow ( ) ;
58+ prisma . walletLimit . findUnique . mockResolvedValue ( null ) ;
59+ await expect ( service . checkLimits ( walletId , 100 ) ) . resolves . not . toThrow ( ) ;
4660 } ) ;
4761
48- it ( 'should throw if per transaction limit exceeded' , async ( ) => {
49- prisma . userLimit . findUnique . mockResolvedValue ( {
62+ it ( 'should throw if per- transaction limit exceeded' , async ( ) => {
63+ prisma . walletLimit . findUnique . mockResolvedValue ( {
5064 perTransactionLimit : 50 ,
5165 dailyLimit : 1000 ,
5266 } ) ;
53- await expect ( service . checkLimits ( 1 , 100 ) ) . rejects . toThrow (
67+ await expect ( service . checkLimits ( walletId , 100 ) ) . rejects . toThrow (
5468 'Transaction limit exceeded' ,
5569 ) ;
5670 } ) ;
5771
5872 it ( 'should throw if daily limit exceeded' , async ( ) => {
59- prisma . userLimit . findUnique . mockResolvedValue ( {
73+ prisma . walletLimit . findUnique . mockResolvedValue ( {
6074 perTransactionLimit : 200 ,
6175 dailyLimit : 100 ,
6276 } ) ;
63- prisma . payment . aggregate . mockResolvedValue ( { _sum : { amount : 50 } } ) ;
64- await expect ( service . checkLimits ( 1 , 60 ) ) . rejects . toThrow (
77+ prisma . transaction . findMany . mockResolvedValue ( [ { amount : '50' } ] ) ;
78+ await expect ( service . checkLimits ( walletId , 60 ) ) . rejects . toThrow (
6579 'Daily limit exceeded' ,
6680 ) ;
6781 } ) ;
6882
6983 it ( 'should pass if within limits' , async ( ) => {
70- prisma . userLimit . findUnique . mockResolvedValue ( {
84+ prisma . walletLimit . findUnique . mockResolvedValue ( {
7185 perTransactionLimit : 200 ,
7286 dailyLimit : 100 ,
7387 } ) ;
74- prisma . payment . aggregate . mockResolvedValue ( { _sum : { amount : 40 } } ) ;
75- await expect ( service . checkLimits ( 1 , 50 ) ) . resolves . not . toThrow ( ) ;
88+ prisma . transaction . findMany . mockResolvedValue ( [ { amount : '40' } ] ) ;
89+ await expect ( service . checkLimits ( walletId , 50 ) ) . resolves . not . toThrow ( ) ;
90+ } ) ;
91+
92+ it ( 'should aggregate transactions by senderWalletId since start of day' , async ( ) => {
93+ prisma . walletLimit . findUnique . mockResolvedValue ( {
94+ perTransactionLimit : 200 ,
95+ dailyLimit : 1000 ,
96+ } ) ;
97+ prisma . transaction . findMany . mockResolvedValue ( [ ] ) ;
98+ await service . checkLimits ( walletId , 50 ) ;
99+
100+ const call = prisma . transaction . findMany . mock . calls [ 0 ] [ 0 ] ;
101+ expect ( call . where . senderWalletId ) . toBe ( walletId ) ;
102+ expect ( call . where . createdAt . gte ) . toBeInstanceOf ( Date ) ;
103+ } ) ;
104+ } ) ;
105+
106+ describe ( 'removeLimits' , ( ) => {
107+ it ( 'should delete limits for a wallet' , async ( ) => {
108+ const limit = { walletId, dailyLimit : 100 , perTransactionLimit : 10 } ;
109+ prisma . walletLimit . findUnique . mockResolvedValue ( limit ) ;
110+ prisma . walletLimit . delete . mockResolvedValue ( limit ) ;
111+ await service . removeLimits ( walletId ) ;
112+ expect ( prisma . walletLimit . delete ) . toHaveBeenCalledWith ( { where : { walletId } } ) ;
113+ } ) ;
114+
115+ it ( 'should throw NotFoundException if no limits exist' , async ( ) => {
116+ prisma . walletLimit . findUnique . mockResolvedValue ( null ) ;
117+ await expect ( service . removeLimits ( walletId ) ) . rejects . toThrow ( NotFoundException ) ;
76118 } ) ;
77119 } ) ;
78120} ) ;
0 commit comments