update dependencies and devDependencies, address lint issues
[squeep-indie-auther] / test / src / chores.js
1 'use strict';
2
3 const assert = require('assert');
4 const sinon = require('sinon');
5 const StubDB = require('../stub-db');
6 const StubLogger = require('../stub-logger');
7 const Chores = require('../../src/chores');
8
9 const snooze = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
10
11 const expectedException = new Error('oh no');
12
13 describe('Chores', function () {
14 let chores, stubLogger, stubDb, stubQueuePublisher, options;
15 beforeEach(function () {
16 stubLogger = new StubLogger();
17 stubLogger._reset();
18 stubDb = new StubDB();
19 stubDb._reset();
20 stubQueuePublisher = {
21 publish: sinon.stub(),
22 };
23 });
24 afterEach(function () {
25 chores?.stopAllChores();
26 sinon.restore();
27 });
28
29 describe('constructor', function () {
30 this.slow(200);
31 it('empty options, no cleaning', async function () {
32 options = undefined;
33 chores = new Chores(stubLogger, stubDb, stubQueuePublisher, options);
34 assert.strictEqual(chores.chores.cleanTokens.timeoutObj, undefined);
35 assert.strictEqual(chores.chores.cleanScopes.timeoutObj, undefined);
36 assert.strictEqual(chores.chores.publishTickets.timeoutObj, undefined);
37 });
38
39 it('cleans scopes', async function () {
40 options = {
41 chores: {
42 scopeCleanupMs: 1,
43 },
44 };
45 chores = new Chores(stubLogger, stubDb, stubQueuePublisher, options);
46 await snooze(50);
47 assert(chores.chores.cleanScopes.timeoutObj);
48 assert(chores.db.scopeCleanup.called);
49 });
50
51 it('cleans tokens', async function () {
52 options = {
53 chores: {
54 tokenCleanupMs: 1,
55 },
56 manager: {
57 codeValidityTimeoutMs: 10,
58 },
59 };
60 chores = new Chores(stubLogger, stubDb, stubQueuePublisher, options);
61 await snooze(50);
62 assert(chores.chores.cleanTokens.timeoutObj);
63 assert(chores.db.tokenCleanup.called);
64 });
65
66 it('publishes tickets', async function () {
67 options = {
68 chores: {
69 publishTicketsMs: 1,
70 },
71 queues: {
72 ticketRedeemedName: 'queue',
73 },
74 };
75 chores = new Chores(stubLogger, stubDb, stubQueuePublisher, options);
76 await snooze(50);
77 assert(chores.chores.publishTickets.timeoutObj);
78 assert(chores.db.ticketTokenGetUnpublished.called);
79 });
80
81 }); // constructor
82
83 describe('cleanTokens', function () {
84 it('logs cleaning', async function () {
85 const cleaned = 10;
86 options = {
87 chores: {
88 tokenCleanupMs: 100,
89 },
90 manager: {
91 codeValidityTimeoutMs: 10,
92 },
93 };
94 stubDb.tokenCleanup.resolves(cleaned);
95 chores = new Chores(stubLogger, stubDb, stubQueuePublisher, options);
96 clearTimeout(chores.cleanTokensTimeout);
97 await chores.cleanTokens();
98 assert(stubLogger.info.called);
99 });
100 it('covers failure', async function () {
101 options = {
102 chores: {
103 tokenCleanupMs: 1,
104 },
105 manager: {
106 codeValidityTimeoutMs: 10,
107 },
108 };
109 stubDb.tokenCleanup.rejects(expectedException);
110 chores = new Chores(stubLogger, stubDb, stubQueuePublisher, options);
111 await assert.rejects(() => chores.cleanTokens(), expectedException);
112 });
113 it('covers default', async function () {
114 stubDb.tokenCleanup.resolves(0);
115 chores = new Chores(stubLogger, stubDb, stubQueuePublisher, {
116 manager: {
117 codeValidityTimeoutMs: 10,
118 },
119 });
120 await chores.cleanTokens();
121 assert(stubDb.tokenCleanup.called);
122 });
123 }); // cleanTokens
124
125 describe('cleanScopes', function () {
126 it('logs cleaning', async function () {
127 const cleaned = 10;
128 options = {
129 chores: {
130 scopeCleanupMs: 100,
131 },
132 };
133 stubDb.scopeCleanup.resolves(cleaned);
134 chores = new Chores(stubLogger, stubDb, stubQueuePublisher, options);
135 clearTimeout(chores.cleanScopesTimeout);
136 await chores.cleanScopes();
137 assert(stubLogger.info.called);
138 });
139 it('covers failure', async function () {
140 options = {
141 chores: {
142 scopeCleanupMs: 1,
143 },
144 };
145 stubDb.scopeCleanup.rejects(expectedException);
146 chores = new Chores(stubLogger, stubDb, stubQueuePublisher, options);
147 await assert.rejects(() => chores.cleanScopes(), expectedException);
148 });
149 it('covers default', async function () {
150 stubDb.scopeCleanup.resolves(0);
151 chores = new Chores(stubLogger, stubDb, stubQueuePublisher, {});
152 await chores.cleanScopes();
153 assert(stubDb.scopeCleanup.called);
154 });
155 }); // cleanScopes
156
157 describe('publishTickets', function () {
158 beforeEach(function () {
159 options = {
160 queues: {
161 ticketRedeemedName: 'queue',
162 },
163 };
164 stubDb.ticketTokenGetUnpublished.resolves([{
165 ticket: 'xxxTICKETxxx',
166 resource: 'https://resource.example.com/',
167 subject: 'https://subject.example.com/',
168 iss: null,
169 }]);
170 chores = new Chores(stubLogger, stubDb, stubQueuePublisher, options);
171 });
172 it('publishes a ticket', async function () {
173 await chores.publishTickets();
174 assert(stubQueuePublisher.publish.called);
175 assert(stubDb.ticketTokenPublished.called);
176 });
177 it('covers error', async function () {
178 stubQueuePublisher.publish.rejects(expectedException);
179 await chores.publishTickets();
180 assert(stubQueuePublisher.publish.called);
181 assert(stubDb.ticketTokenPublished.notCalled);
182 });
183 }); // publishTickets
184
185 }); // Chores