node-mongo-demo
node.js and mongodb demo
git clone https://9o.is/git/node-mongo-demo.git
lucky7.int.test.js
(3497B)
1 import lucky7 from '../src/api/lucky7.js';
2 import { changeStream } from '../src/api/lucky7-bets.js';
3 import { jest } from '@jest/globals';
4 import express from 'express';
5 import bodyParser from "body-parser";
6 import jwt from 'jsonwebtoken';
7 import request from 'supertest';
8
9 describe('Lucky7', () => {
10 let app;
11
12 beforeAll(() => {
13 app = express();
14 app.use(bodyParser.json());
15 app.use(lucky7);
16 });
17
18 describe('POST /sessions', () => {
19 let sessionId;
20
21 const post = () =>
22 auth(request(app).post('/sessions'));
23
24 it('creates', async () => {
25 const res = await post();
26
27 expect(res.status).toBe(201);
28 expect(res.body).toHaveProperty('id');
29 expect(res.body).toHaveProperty('createdAt');
30
31 sessionId = res.body.id;
32 });
33
34 it('fetches existing session', async () => {
35 const res = await post();
36
37 expect(res.status).toBe(201);
38 expect(res.body.id).toBe(sessionId);
39 });
40 });
41
42 describe('POST /bets', () => {
43 let betId;
44
45 const post = body =>
46 auth(request(app).post('/bets').send(body));
47
48 beforeAll(() => {
49 jest.useFakeTimers({ doNotFake: ['nextTick'] });
50 });
51
52 it('creates', async () => {
53 const res = await post({ lucky: true });
54
55 expect(res.status).toBe(201);
56 expect(res.body).toHaveProperty('id');
57 expect(res.body).toHaveProperty('state');
58 expect(res.body).toHaveProperty('rollAt');
59 expect(res.body).toHaveProperty('lucky');
60 expect(res.body).not.toHaveProperty('roll');
61 expect(res.body).not.toHaveProperty('win');
62 expect(res.body.lucky).toBe(true);
63
64 betId = res.body.id;
65 });
66
67 it('updates existing bet', async () => {
68 const res = await post({ lucky: false });
69
70 expect(res.status).toBe(201);
71 expect(res.body.id).toBe(betId);
72 expect(res.body.lucky).toBe(false);
73 });
74
75 it('errors on invalid input', async () => {
76 const res = await post({});
77
78 expect(res.status).toBe(400);
79 expect(res.body.error.details[0].message).toBe(
80 '"lucky" is required',
81 );
82 });
83
84 it('errors on unplayable session', async () => {
85 // advance 10 seconds
86 jest.advanceTimersByTime(10 * 1000);
87
88 const res = await post({ lucky: true });
89
90 expect(res.status).toBe(409);
91 expect(res.body.code).toBe('SESSION_TIMER');
92 });
93
94 it('errors on expiring session', async () => {
95 // advance almost 1 day
96 jest.advanceTimersByTime(86390 * 1000);
97
98 const res = await post({ lucky: true });
99
100 expect(res.status).toBe(409);
101 expect(res.body.code).toBe('SESSION_EXPIRING');
102 });
103
104 });
105
106 it('GET /leaderboard/streaks', async () => {
107 const res = await request(app).get('/leaderboard/streaks');
108
109 expect(res.status).toBe(200);
110 expect(Array.isArray(res.body)).toBe(true);
111 });
112
113 afterAll(async () => {
114 await changeStream.close();
115 });
116 });
117
118 function auth(request) {
119 const token = jwt.sign(
120 { _id: '6799219573e6c41d3aaece71' },
121 'test',
122 { expiresIn: '1h' }
123 );
124
125 return request.set('Authorization', `Bearer ${token}`);
126 }