node-mongo-demo

node.js and mongodb demo

git clone https://9o.is/git/node-mongo-demo.git

lucky7-bet-events.unit.test.js

(6791B)


      1 import { subscribe, onChange } from '../src/events/lucky7-bets.js';
      2 import mongoose from 'mongoose';
      3 import { jest } from '@jest/globals';
      4 
      5 describe('Bet Events', () => {
      6     it('insert', () => {
      7         setTime('2024-01-01T00:00:00Z');
      8 
      9         const stream = createStream();
     10         const bet = {
     11             _id: id(),
     12             userId: id(),
     13             lucky: true,
     14             roll: [3,4],
     15             rollAt: new Date('2024-01-01T00:00:15Z'),
     16         };
     17 
     18         subscribe(bet.userId.toString(), stream);
     19         onChange(createInsertEvent(bet));
     20 
     21         expect(stream.writeJson).toHaveBeenCalledTimes(1);
     22         expect(stream.writeJson).toHaveBeenCalledWith({
     23             operationType: 'insert',
     24             bet: {
     25                 id: bet._id.toString(),
     26                 state: 'pending',
     27                 lucky: bet.lucky,
     28                 rollAt: bet.rollAt,
     29                 roll: undefined,
     30                 win: undefined,
     31             },
     32         });
     33     });
     34 
     35     it('update', () => {
     36         setTime('2024-01-01T00:00:00Z');
     37 
     38         const stream = createStream();
     39         const bet = {
     40             _id: id(),
     41             userId: id(),
     42             lucky: true,
     43             rollAt: new Date('2024-01-01T00:00:15Z'),
     44         };
     45 
     46         subscribe(bet.userId.toString(), stream);
     47         onChange(createInsertEvent(bet));
     48         onChange(createUpdateEvent(bet._id, { lucky: false }));
     49 
     50         expect(stream.writeJson).toHaveBeenCalledTimes(2);
     51         expect(stream.writeJson).toHaveBeenNthCalledWith(2, {
     52             operationType: 'update',
     53             bet: {
     54                 id: bet._id.toString(),
     55                 state: 'pending',
     56                 lucky: false,
     57             },
     58         });
     59     });
     60 
     61     it('finished event', () => {
     62         setTime('2024-01-01T00:00:00Z');
     63 
     64         const stream = createStream();
     65         const bet = {
     66             _id: id(),
     67             userId: id(),
     68             lucky: true,
     69             roll: [3,4],
     70             rollAt: new Date('2024-01-01T00:00:15Z'),
     71         };
     72 
     73         subscribe(bet.userId.toString(), stream);
     74         onChange(createInsertEvent(bet));
     75 
     76         jest.advanceTimersByTime(14999);
     77         expect(stream.writeJson).toHaveBeenCalledTimes(1);
     78 
     79         jest.advanceTimersByTime(1);
     80         expect(stream.writeJson).toHaveBeenCalledTimes(2);
     81 
     82         expect(stream.writeJson).toHaveBeenNthCalledWith(2, {
     83             operationType: 'update',
     84             bet: {
     85                 id: bet._id.toString(),
     86                 state: 'finished',
     87                 lucky: bet.lucky,
     88                 rollAt: bet.rollAt,
     89                 roll: bet.roll,
     90                 win: true,
     91             },
     92         });
     93     });
     94 
     95     it('ignores other user\' events', () => {
     96         setTime('2024-01-01T00:00:00Z');
     97 
     98         const stream = createStream();
     99         const userId = id();
    100         const bet = {
    101             _id: id(),
    102             userId: id(),
    103             lucky: true,
    104             roll: [3,4],
    105             rollAt: new Date('2024-01-01T00:00:15Z'),
    106         };
    107 
    108         subscribe(userId.toString(), stream);
    109         onChange(createInsertEvent(bet));
    110 
    111         expect(stream.writeJson).toHaveBeenCalledTimes(0);
    112     });
    113 
    114     it('multiple bets', () => {
    115         setTime('2024-01-01T00:00:00Z');
    116 
    117         const stream = createStream();
    118         const userId = id();
    119 
    120         const bet1 = {
    121             _id: id(),
    122             userId,
    123             lucky: true,
    124             roll: [3,4],
    125             rollAt: new Date('2024-01-01T00:00:15Z'),
    126         };
    127 
    128         const bet2 = {
    129             _id: id(),
    130             userId,
    131             lucky: false,
    132             roll: [5,2],
    133             rollAt: new Date('2024-01-01T00:00:10Z'),
    134         };
    135 
    136         subscribe(userId.toString(), stream);
    137         onChange(createInsertEvent(bet1));
    138         onChange(createInsertEvent(bet2));
    139 
    140         expect(stream.writeJson).toHaveBeenCalledTimes(2);
    141 
    142         expect(stream.writeJson).toHaveBeenCalledWith({
    143             operationType: 'insert',
    144             bet: {
    145                 id: bet1._id.toString(),
    146                 state: 'pending',
    147                 lucky: bet1.lucky,
    148                 rollAt: bet1.rollAt,
    149                 roll: undefined,
    150                 win: undefined,
    151             },
    152         });
    153 
    154         expect(stream.writeJson).toHaveBeenCalledWith({
    155             operationType: 'insert',
    156             bet: {
    157                 id: bet2._id.toString(),
    158                 state: 'pending',
    159                 lucky: bet2.lucky,
    160                 rollAt: bet2.rollAt,
    161                 roll: undefined,
    162                 win: undefined,
    163             },
    164         });
    165     });
    166 
    167     it('multiple users', () => {
    168         setTime('2024-01-01T00:00:00Z');
    169 
    170         const user1Id = id();
    171         const user2Id = id();
    172         const stream1 = createStream();
    173         const stream2 = createStream();
    174 
    175         const bet1 = {
    176             _id: id(),
    177             userId: user1Id,
    178             lucky: true,
    179             roll: [3,4],
    180             rollAt: new Date('2024-01-01T00:00:15Z'),
    181         };
    182 
    183         const bet2 = {
    184             _id: id(),
    185             userId: user2Id,
    186             lucky: false,
    187             roll: [5,2],
    188             rollAt: new Date('2024-01-01T00:00:10Z'),
    189         };
    190 
    191         subscribe(user1Id.toString(), stream1);
    192         subscribe(user2Id.toString(), stream2);
    193 
    194         onChange(createInsertEvent(bet2));
    195         onChange(createInsertEvent(bet1));
    196 
    197         expect(stream1.writeJson).toHaveBeenCalledTimes(1);
    198         expect(stream1.writeJson).toHaveBeenCalledWith({
    199             operationType: 'insert',
    200             bet: {
    201                 id: bet1._id.toString(),
    202                 state: 'pending',
    203                 lucky: bet1.lucky,
    204                 rollAt: bet1.rollAt,
    205                 roll: undefined,
    206                 win: undefined,
    207             },
    208         });
    209 
    210         expect(stream2.writeJson).toHaveBeenCalledTimes(1);
    211         expect(stream2.writeJson).toHaveBeenCalledWith({
    212             operationType: 'insert',
    213             bet: {
    214                 id: bet2._id.toString(),
    215                 state: 'pending',
    216                 lucky: bet2.lucky,
    217                 rollAt: bet2.rollAt,
    218                 roll: undefined,
    219                 win: undefined,
    220             },
    221         });
    222     });
    223 });
    224 
    225 function createInsertEvent(fullDocument) {
    226     return {
    227         operationType: 'insert',
    228         fullDocument,
    229     };
    230 }
    231 
    232 function createUpdateEvent(_id, updatedFields) {
    233     return {
    234         operationType: 'update',
    235         documentKey: {
    236             _id,
    237         },
    238         updateDescription: {
    239             updatedFields,
    240         },
    241     };
    242 }
    243 
    244 function createStream() {
    245     return {
    246         writeJson: jest.fn(),
    247         onClose: () => {},
    248     };
    249 }
    250 
    251 function id(x) {
    252     return new mongoose.Types.ObjectId(x);
    253 }
    254 
    255 function setTime(dt) {
    256     jest.useFakeTimers().setSystemTime(new Date(dt));
    257 }