3 /* This provides implementation coverage, stubbing parts of better-sqlite3. */
5 const assert
= require('node:assert');
6 const sinon
= require('sinon');
7 const DBStub
= require('../../stub-db');
8 const stubLogger
= require('../../stub-logger');
9 const DB
= require('../../../src/db/sqlite');
10 const DBErrors
= require('../../../src/db/errors');
11 const common
= require('../../../src/common');
12 const Config
= require('../../../config');
14 const noExpectedException
= 'did not receive expected exception';
16 describe('DatabaseSQLite', function () {
18 let dbCtx
, claimant
, claimTimeoutSeconds
, callback
, subscriptionId
, topicId
, verificationId
;
19 let topicUrl
, leaseSeconds
, secret
, httpRemoteAddr
, httpFrom
, retryDelays
, wanted
;
21 options
= new Config('test');
22 options
.db
.connectionString
= 'sqlite://:memory:';
23 db
= new DB(stubLogger
, options
);
25 beforeEach(function () {
28 claimant
= '19af19b8-6be3-4a6f-8946-65f5f1ccc5d7';
29 claimTimeoutSeconds
= 300;
30 subscriptionId
= 'fbaf8f19-ed9c-4a21-89ae-98b7005e3bf6';
31 topicUrl
= 'https://example.com/blog';
32 callback
= 'https://example.com/callback?id=123';
33 topicId
= 'c59d4bda-10ad-41d9-99df-4ce8bc331424';
34 verificationId
= '55cd7748-d2d5-11eb-b355-0025905f714a';
38 httpRemoteAddr
= '127.0.0.1';
39 httpFrom
= 'user@example.com';
42 afterEach(function () {
46 it('covers options', function () {
47 const xoptions
= new Config('test');
48 delete xoptions
.db
.connectionString
;
49 db
= new DB(stubLogger
, xoptions
);
52 // Ensure all interface methods are implemented
53 describe('Implementation', function () {
54 it('implements interface', async
function () {
55 const results
= await Promise
.allSettled(DBStub
._implementation
.map(async (fn
) => {
57 // eslint-disable-next-line security/detect-object-injection
60 assert(!(e
instanceof DBErrors
.NotImplemented
), `${fn} not implemented`);
63 const failures
= results
.filter((x
) => x
.status
=== 'rejected');
64 assert(!failures
.length
, failures
.map((x
) => {
65 x
= x
.reason
.toString();
66 return x
.slice(x
.indexOf(': '));
71 describe('_initTables', function () {
73 beforeEach(function () {
74 preparedGet
= sinon
.stub();
75 sinon
.stub(db
.db
, 'prepare').returns({
82 sinon
.stub(db
, '_currentSchema').returns(db
.schemaVersionsSupported
.min
);
83 sinon
.stub(db
.db
, 'exec');
85 it('covers migration', async
function() {
86 preparedGet
.returns({});
87 await db
._initTables();
88 assert(db
.db
.exec
.called
);
90 it('covers migration failure', async
function() {
91 const expected
= new Error('oh no');
92 preparedGet
.returns({});
93 db
.db
.exec
.throws(expected
);
95 await db
._initTables();
96 assert
.fail(noExpectedException
);
98 assert
.deepStrictEqual(e
, expected
);
103 describe('_currentSchema', function () {
104 it('covers', async
function () {
105 const version
= { major: 1, minor: 0, patch: 0 };
106 sinon
.stub(db
.db
, 'prepare').returns({
109 const result
= await db
._currentSchema();
110 assert
.deepStrictEqual(result
, version
);
112 }); // _currentSchema
114 describe('_closeConnection', function () {
115 it('success', async
function () {
116 sinon
.stub(db
.db
, 'close');
117 await db
._closeConnection();
118 assert(db
.db
.close
.called
);
120 it('failure', async
function () {
121 const expected
= new Error();
122 sinon
.stub(db
.db
, 'close').throws(expected
);
124 await db
._closeConnection();
125 assert
.fail(noExpectedException
);
127 assert
.deepStrictEqual(e
, expected
);
130 }); // _closeConnection
132 describe('_purgeTables', function () {
133 beforeEach(function () {
134 sinon
.stub(db
.db
, 'prepare').returns({
138 it('covers not really', async
function () {
139 await db
._purgeTables(false);
140 assert(!db
.db
.prepare
.called
);
142 it('success', async
function () {
143 await db
._purgeTables(true);
144 assert(db
.db
.prepare
.called
);
146 it('failure', async
function () {
147 const expected
= new Error();
148 db
.db
.prepare
.restore();
149 sinon
.stub(db
.db
, 'prepare').throws(expected
);
151 await db
._purgeTables(true);
152 assert
.fail(noExpectedException
);
154 assert
.deepStrictEqual(e
, expected
);
159 describe('_optimize', function () {
161 beforeEach(function () {
162 origOAC
= db
.optimizeAfterChanges
;
163 sinon
.stub(db
.statement
._optimize
, 'all');
164 sinon
.stub(db
.db
, 'pragma');
166 this.afterEach(function () {
167 db
.optimizeAfterChanges
= origOAC
;
169 it('covers', async
function () {
170 db
.optimizeAfterChanges
= 10;
171 db
.changesSinceLastOptimize
= BigInt(20);
172 await db
._optimize();
173 assert(db
.db
.pragma
.called
);
175 it('covers none', async
function () {
176 db
.optimizeAfterChanges
= 0;
177 await db
._optimize();
178 assert(!db
.db
.pragma
.called
);
180 it('covers not enough changes', async
function () {
181 db
.optimizeAfterChanges
= 10;
182 db
.changesSinceLastOptimize
= BigInt(5);
183 await db
._optimize();
184 assert(!db
.db
.pragma
.called
);
188 describe('_deOphidiate', function () {
189 it('covers non-array', function () {
196 const result
= DB
._deOphidiate(obj
);
197 assert
.deepStrictEqual(result
, expected
);
199 it('covers array', function () {
216 const result
= DB
._deOphidiate(rows
);
217 assert
.deepStrictEqual(result
, expected
);
221 describe('_topicDataToNative', function () {
222 it('covers', function () {
223 const now
= new Date();
224 const nowEpoch
= now
.getTime() / 1000;
229 lastPublish: nowEpoch
,
230 contentFetchNextAttempt: nowEpoch
,
231 contentUpdated: nowEpoch
,
232 url: 'https://example.com/',
239 contentFetchNextAttempt: now
,
243 const result
= DB
._topicDataToNative(topic
);
244 assert
.deepStrictEqual(result
, expected
);
246 it('covers empty', function () {
247 const topic
= undefined;
248 const result
= DB
._topicDataToNative(topic
);
249 assert
.deepStrictEqual(result
, topic
);
251 }); // _topicDataToNative
253 describe('healthCheck', function () {
255 beforeEach(function () {
258 afterEach(function () {
261 it('covers', function () {
264 it('covers failure', function () {
265 db
.db
= { open: false };
268 assert
.fail(noExpectedException
);
270 assert(e
instanceof DBErrors
.UnexpectedResult
);
275 describe('context', function () {
276 it('covers', async
function () {
277 await db
.context(common
.nop
);
281 describe('transaction', function () {
282 it('covers', async
function () {
283 await db
.transaction(db
.db
, common
.nop
);
285 it('covers no context', async
function () {
286 await db
.transaction(undefined, common
.nop
);
290 describe('authenticationSuccess', function () {
292 beforeEach(function () {
293 identifier
= 'username';
295 it('success', async
function() {
298 lastInsertRowid: undefined,
300 sinon
.stub(db
.statement
.authenticationSuccess
, 'run').returns(dbResult
);
301 await db
.authenticationSuccess(dbCtx
, identifier
);
303 it('failure', async
function () {
306 lastInsertRowid: undefined,
308 sinon
.stub(db
.statement
.authenticationSuccess
, 'run').returns(dbResult
);
310 await db
.authenticationSuccess(dbCtx
, identifier
);
311 assert
.fail(noExpectedException
);
313 assert(e
instanceof DBErrors
.UnexpectedResult
);
316 }); // authenticationSuccess
318 describe('authenticationGet', function () {
319 let identifier
, credential
;
320 beforeEach(function () {
321 identifier
= 'username';
322 credential
= '$z$foo';
324 it('success', async
function() {
329 sinon
.stub(db
.statement
.authenticationGet
, 'get').returns(expected
);
330 const result
= await db
.authenticationGet(dbCtx
, identifier
);
331 assert
.deepStrictEqual(result
, expected
);
333 it('failure', async
function () {
334 const expected
= new Error();
335 sinon
.stub(db
.statement
.authenticationGet
, 'get').throws(expected
);
337 await db
.authenticationGet(dbCtx
, identifier
);
338 assert
.fail(noExpectedException
);
340 assert
.deepStrictEqual(e
, expected
);
343 }); // authenticationGet
345 describe('authenticationUpsert', function () {
346 let identifier
, credential
, otpKey
;
347 beforeEach(function () {
348 identifier
= 'username';
349 credential
= '$z$foo';
350 otpKey
= '12345678901234567890123456789012';
352 it('success', async
function() {
355 lastInsertRowid: undefined,
357 sinon
.stub(db
.statement
.authenticationUpsert
, 'run').returns(dbResult
);
358 await db
.authenticationUpsert(dbCtx
, identifier
, credential
, otpKey
);
360 it('failure', async
function () {
363 lastInsertRowid: undefined,
365 sinon
.stub(db
.statement
.authenticationUpsert
, 'run').returns(dbResult
);
367 await db
.authenticationUpsert(dbCtx
, identifier
, credential
, otpKey
);
368 assert
.fail(noExpectedException
);
370 assert(e
instanceof DBErrors
.UnexpectedResult
);
373 }); // authenticationUpsert
375 describe('authenticationUpdateCredential', function () {
376 let identifier
, credential
;
377 beforeEach(function () {
378 identifier
= 'username';
379 credential
= '$z$foo';
381 it('success', async
function() {
384 lastInsertRowid: undefined,
386 sinon
.stub(db
.statement
.authenticationUpdateCredential
, 'run').returns(dbResult
);
387 await db
.authenticationUpdateCredential(dbCtx
, identifier
, credential
);
389 it('failure', async
function () {
392 lastInsertRowid: undefined,
394 sinon
.stub(db
.statement
.authenticationUpdateCredential
, 'run').returns(dbResult
);
396 await db
.authenticationUpdateCredential(dbCtx
, identifier
, credential
);
397 assert
.fail(noExpectedException
);
399 assert(e
instanceof DBErrors
.UnexpectedResult
);
402 }); // authenticationUpdateCredential
404 describe('authenticationUpdateOTPKey', function () {
405 let identifier
, otpKey
;
406 beforeEach(function () {
407 identifier
= 'username';
408 otpKey
= '12345678901234567890123456789012';
410 it('success', async
function() {
413 lastInsertRowid: undefined,
415 sinon
.stub(db
.statement
.authenticationUpdateOtpKey
, 'run').returns(dbResult
);
416 await db
.authenticationUpdateOTPKey(dbCtx
, identifier
, otpKey
);
418 it('failure', async
function () {
421 lastInsertRowid: undefined,
423 sinon
.stub(db
.statement
.authenticationUpdateOtpKey
, 'run').returns(dbResult
);
425 await db
.authenticationUpdateOTPKey(dbCtx
, identifier
, otpKey
);
426 assert
.fail(noExpectedException
);
428 assert(e
instanceof DBErrors
.UnexpectedResult
);
431 }); // authenticationUpsert
433 describe('subscriptionsByTopicId', function () {
434 it('success', async
function () {
435 const expected
= [{ id: 3 }];
436 sinon
.stub(db
.statement
.subscriptionsByTopicId
, 'all').returns(expected
);
437 const result
= await db
.subscriptionsByTopicId(dbCtx
, topicUrl
);
438 assert
.deepStrictEqual(result
, expected
);
440 it('failure', async
function () {
441 const expected
= new Error();
442 sinon
.stub(db
.statement
.subscriptionsByTopicId
, 'all').throws(expected
);
444 await db
.subscriptionsByTopicId(dbCtx
, topicUrl
);
445 assert
.fail(noExpectedException
);
447 assert
.deepStrictEqual(e
, expected
);
450 }); // subscriptionsByTopicId
452 describe('subscriptionCountByTopicUrl', function () {
453 it('success', async
function () {
454 const expected
= { count: 3 };
455 sinon
.stub(db
.statement
.subscriptionCountByTopicUrl
, 'get').returns(expected
);
456 const result
= await db
.subscriptionCountByTopicUrl(dbCtx
, topicUrl
);
457 assert
.deepStrictEqual(result
, expected
);
459 it('failure', async
function () {
460 const expected
= new Error();
461 sinon
.stub(db
.statement
.subscriptionCountByTopicUrl
, 'get').throws(expected
);
463 await db
.subscriptionCountByTopicUrl(dbCtx
, topicUrl
);
464 assert
.fail(noExpectedException
);
466 assert
.deepStrictEqual(e
, expected
);
469 }); // subscriptionCountByTopicUrl
471 describe('subscriptionDelete', function () {
472 it('success', async
function() {
475 lastInsertRowid: undefined,
479 lastInsertRowid: undefined,
481 sinon
.stub(db
.statement
.subscriptionDelete
, 'run').returns(dbResult
);
482 const result
= await db
.subscriptionDelete(dbCtx
, callback
, topicId
);
483 assert
.deepStrictEqual(result
, expected
);
485 it('failure', async
function () {
488 lastInsertRowid: undefined,
490 sinon
.stub(db
.statement
.subscriptionDelete
, 'run').returns(dbResult
);
492 await db
.subscriptionDelete(dbCtx
, callback
, topicId
);
493 assert
.fail(noExpectedException
);
495 assert(e
instanceof DBErrors
.UnexpectedResult
);
498 }); // subscriptionDelete
500 describe('subscriptionDeleteExpired', function () {
501 it('success', async
function () {
504 lastInsertRowid: undefined,
508 lastInsertRowid: undefined,
510 sinon
.stub(db
.statement
.subscriptionDeleteExpired
, 'run').returns(dbResult
);
511 const result
= await db
.subscriptionDeleteExpired(dbCtx
, topicId
);
512 assert
.deepStrictEqual(result
, expected
);
514 it('failure', async
function () {
515 const expected
= new Error();
516 sinon
.stub(db
.statement
.subscriptionDeleteExpired
, 'run').throws(expected
);
518 await db
.subscriptionDeleteExpired(dbCtx
, topicId
);
519 assert
.fail(noExpectedException
);
521 assert
.deepStrictEqual(e
, expected
);
524 }); // subscriptionDeleteExpired
526 describe('subscriptionDeliveryClaim', function () {
527 it('success', async
function () {
528 const dbAllResult
= [
530 id: 'c2e254c5-aa6e-4a8f-b1a1-e474b07392bb',
533 const dbRunResult
= {
535 lastInsertRowid: undefined,
537 const expected
= ['c2e254c5-aa6e-4a8f-b1a1-e474b07392bb'];
538 sinon
.stub(db
.statement
.subscriptionDeliveryNeeded
, 'all').returns(dbAllResult
);
539 sinon
.stub(db
.statement
.subscriptionDeliveryClaimById
, 'run').returns(dbRunResult
);
540 const result
= await db
.subscriptionDeliveryClaim(dbCtx
, wanted
, claimTimeoutSeconds
, claimant
);
541 assert
.deepStrictEqual(result
, expected
);
543 it('failure', async
function () {
544 const dbAllResult
= [
546 id: 'c2e254c5-aa6e-4a8f-b1a1-e474b07392bb',
549 const dbRunResult
= {
551 lastInsertRowid: undefined,
553 sinon
.stub(db
.statement
.subscriptionDeliveryNeeded
, 'all').returns(dbAllResult
);
554 sinon
.stub(db
.statement
.subscriptionDeliveryClaimById
, 'run').returns(dbRunResult
);
556 await db
.subscriptionDeliveryClaim(dbCtx
, wanted
, claimTimeoutSeconds
, claimant
);
557 assert
.fail(noExpectedException
);
559 assert(e
instanceof DBErrors
.UnexpectedResult
);
562 }); // subscriptionDeliveryClaim
564 describe('subscriptionDeliveryClaimById', function () {
565 it('success', async
function() {
568 lastInsertRowid: undefined,
570 sinon
.stub(db
.statement
.subscriptionDeliveryClaimById
, 'run').returns(dbResult
);
571 const result
= await db
.subscriptionDeliveryClaimById(dbCtx
, subscriptionId
, claimTimeoutSeconds
, claimant
);
572 assert
.deepStrictEqual(result
, dbResult
);
574 it('failure', async
function () {
577 lastInsertRowid: undefined,
579 sinon
.stub(db
.statement
.subscriptionDeliveryClaimById
, 'run').returns(dbResult
);
581 await db
.subscriptionDeliveryClaimById(dbCtx
, subscriptionId
, claimTimeoutSeconds
, claimant
);
582 assert
.fail(noExpectedException
);
584 assert(e
instanceof DBErrors
.UnexpectedResult
);
587 }); // subscriptionDeliveryClaimById
589 describe('subscriptionDeliveryComplete', function () {
590 let topicContentUpdated
;
592 topicContentUpdated
= new Date();
594 it('success', async
function() {
598 sinon
.stub(db
.statement
.subscriptionDeliverySuccess
, 'run').returns(dbResult
);
599 sinon
.stub(db
.statement
.subscriptionDeliveryDone
, 'run').returns(dbResult
);
600 await db
.subscriptionDeliveryComplete(dbCtx
, callback
, topicId
, topicContentUpdated
);
602 it('failure', async
function () {
606 sinon
.stub(db
.statement
.subscriptionDeliverySuccess
, 'run').returns(dbResult
);
607 sinon
.stub(db
.statement
.subscriptionDeliveryDone
, 'run').returns(dbResult
);
609 await db
.subscriptionDeliveryComplete(dbCtx
, callback
, topicId
, topicContentUpdated
);
610 assert
.fail(noExpectedException
);
612 assert(e
instanceof DBErrors
.UnexpectedResult
);
615 it('second failure', async
function () {
622 sinon
.stub(db
.statement
.subscriptionDeliverySuccess
, 'run').returns(dbResult0
);
623 sinon
.stub(db
.statement
.subscriptionDeliveryDone
, 'run').returns(dbResult1
);
625 await db
.subscriptionDeliveryComplete(dbCtx
, callback
, topicId
, topicContentUpdated
);
626 assert
.fail(noExpectedException
);
628 assert(e
instanceof DBErrors
.UnexpectedResult
);
631 }); // subscriptionDeliveryComplete
633 describe('subscriptionDeliveryGone', function () {
634 it('success', async
function() {
638 sinon
.stub(db
.statement
.subscriptionDelete
, 'run').returns(dbResult
);
639 await db
.subscriptionDeliveryGone(dbCtx
, callback
, topicId
);
641 it('failure', async
function () {
645 sinon
.stub(db
.statement
.subscriptionDelete
, 'run').returns(dbResult
);
647 await db
.subscriptionDeliveryGone(dbCtx
, callback
, topicId
);
648 assert
.fail(noExpectedException
);
650 assert(e
instanceof DBErrors
.UnexpectedResult
);
653 }); // subscriptionDeliveryGone
655 describe('subscriptionDeliveryIncomplete', function () {
656 it('success', async
function() {
657 const dbGet
= { deliveryAttemptsSinceSuccess: 0 };
661 sinon
.stub(db
.statement
.subscriptionDeliveryAttempts
, 'get').returns(dbGet
);
662 sinon
.stub(db
.statement
.subscriptionDeliveryFailure
, 'run').returns(dbResult
);
663 sinon
.stub(db
.statement
.subscriptionDeliveryDone
, 'run').returns(dbResult
);
664 await db
.subscriptionDeliveryIncomplete(dbCtx
, callback
, topicId
, retryDelays
);
666 it('success covers default', async
function() {
667 const dbGet
= { deliveryAttemptsSinceSuccess: 0 };
671 sinon
.stub(db
.statement
.subscriptionDeliveryAttempts
, 'get').returns(dbGet
);
672 sinon
.stub(db
.statement
.subscriptionDeliveryFailure
, 'run').returns(dbResult
);
673 sinon
.stub(db
.statement
.subscriptionDeliveryDone
, 'run').returns(dbResult
);
674 await db
.subscriptionDeliveryIncomplete(dbCtx
, callback
, topicId
);
676 it('failure', async
function () {
677 const dbGet
= { deliveryAttemptsSinceSuccess: 0 };
681 sinon
.stub(db
.statement
.subscriptionDeliveryAttempts
, 'get').returns(dbGet
);
682 sinon
.stub(db
.statement
.subscriptionDeliveryFailure
, 'run').returns(dbResult
);
683 sinon
.stub(db
.statement
.subscriptionDeliveryDone
, 'run').returns(dbResult
);
685 await db
.subscriptionDeliveryIncomplete(dbCtx
, callback
, topicId
, retryDelays
);
686 assert
.fail(noExpectedException
);
688 assert(e
instanceof DBErrors
.UnexpectedResult
);
691 it('second failure', async
function () {
692 const dbGet
= { deliveryAttemptsSinceSuccess: 0 };
699 sinon
.stub(db
.statement
.subscriptionDeliveryAttempts
, 'get').returns(dbGet
);
700 sinon
.stub(db
.statement
.subscriptionDeliveryFailure
, 'run').returns(dbResult0
);
701 sinon
.stub(db
.statement
.subscriptionDeliveryDone
, 'run').returns(dbResult1
);
703 await db
.subscriptionDeliveryIncomplete(dbCtx
, callback
, topicId
, retryDelays
);
704 assert
.fail(noExpectedException
);
706 assert(e
instanceof DBErrors
.UnexpectedResult
);
709 }); // subscriptionDeliveryIncomplete
711 describe('subscriptionGet', function () {
712 it('success', async
function() {
716 sinon
.stub(db
.statement
.subscriptionGet
, 'get').returns(expected
);
717 const result
= await db
.subscriptionGet(dbCtx
, callback
, topicId
);
718 assert
.deepStrictEqual(result
, expected
);
720 it('failure', async
function () {
721 const expected
= new Error();
722 sinon
.stub(db
.statement
.subscriptionGet
, 'get').throws(expected
);
724 await db
.subscriptionGet(dbCtx
, callback
, topicId
);
725 assert
.fail(noExpectedException
);
727 assert
.deepStrictEqual(e
, expected
);
730 }); // subscriptionGet
732 describe('subscriptionGetById', function () {
733 it('success', async
function() {
737 sinon
.stub(db
.statement
.subscriptionGetById
, 'get').returns(expected
);
738 const result
= await db
.subscriptionGetById(dbCtx
, subscriptionId
);
739 assert
.deepStrictEqual(result
, expected
);
741 it('failure', async
function () {
742 const expected
= new Error();
743 sinon
.stub(db
.statement
.subscriptionGetById
, 'get').throws(expected
);
745 await db
.subscriptionGetById(dbCtx
, subscriptionId
);
746 assert
.fail(noExpectedException
);
748 assert
.deepStrictEqual(e
, expected
);
751 }); // subscriptionGetById
753 describe('subscriptionUpdate', function () {
755 beforeEach(function () {
758 signatureAlgorithm: 'sha256',
761 it('success', async
function() {
764 lastInsertRowid: subscriptionId
,
766 sinon
.stub(db
.statement
.subscriptionUpdate
, 'run').returns(dbResult
);
767 await db
.subscriptionUpdate(dbCtx
, data
);
769 it('failure', async
function () {
773 sinon
.stub(db
.statement
.subscriptionUpdate
, 'run').returns(dbResult
);
775 await db
.subscriptionUpdate(dbCtx
, data
);
776 assert
.fail(noExpectedException
);
778 assert(e
instanceof DBErrors
.UnexpectedResult
, e
);
781 }); // subscriptionUpdate
783 describe('subscriptionUpsert', function () {
785 beforeEach(function () {
795 it('success', async
function() {
798 lastInsertRowid: subscriptionId
,
802 lastInsertRowid: subscriptionId
,
804 sinon
.stub(db
.statement
.subscriptionUpsert
, 'run').returns(dbResult
);
805 const result
= await db
.subscriptionUpsert(dbCtx
, data
);
806 assert
.deepStrictEqual(result
, expected
);
808 it('failure', async
function () {
812 sinon
.stub(db
.statement
.subscriptionUpsert
, 'run').returns(dbResult
);
814 await db
.subscriptionUpsert(dbCtx
, data
);
815 assert
.fail(noExpectedException
);
817 assert(e
instanceof DBErrors
.UnexpectedResult
);
820 }); // subscriptionUpsert
822 describe('topicDeleted', function () {
823 it('success', async
function () {
824 sinon
.stub(db
.statement
.topicDeleted
, 'run').returns({ changes: 1 });
825 await db
.topicDeleted(dbCtx
, { topicId
});
827 it('failure', async
function () {
828 sinon
.stub(db
.statement
.topicDeleted
, 'run').returns({ changes: 0 });
830 await db
.topicDeleted(dbCtx
, { topicId
});
831 assert
.fail(noExpectedException
);
833 assert(e
instanceof DBErrors
.UnexpectedResult
);
838 describe('topicFetchClaim', function () {
839 it('success', async
function() {
840 const dbAll
= [{ id: topicId
}];
844 const expected
= [topicId
];
845 sinon
.stub(db
.statement
.topicContentFetchNeeded
, 'all').returns(dbAll
);
846 sinon
.stub(db
.statement
.topicContentFetchClaimById
, 'run').returns(dbResult
);
847 const result
= await db
.topicFetchClaim(dbCtx
, wanted
, claimTimeoutSeconds
, claimant
);
848 assert
.deepStrictEqual(result
, expected
);
850 it('failure', async
function () {
851 const dbAll
= [{ id: topicId
}];
855 sinon
.stub(db
.statement
.topicContentFetchNeeded
, 'all').returns(dbAll
);
856 sinon
.stub(db
.statement
.topicContentFetchClaimById
, 'run').returns(dbResult
);
858 await db
.topicFetchClaim(dbCtx
, wanted
, claimTimeoutSeconds
, claimant
);
859 assert
.fail(noExpectedException
);
861 assert(e
instanceof DBErrors
.UnexpectedResult
);
864 }); // topicFetchClaim
866 describe('topicFetchClaimById', function () {
867 it('success', async
function() {
870 lastInsertRowid: undefined,
872 sinon
.stub(db
.statement
.topicContentFetchClaimById
, 'run').returns(expected
);
873 const result
= await db
.topicFetchClaimById(dbCtx
, topicId
, claimTimeoutSeconds
, claimant
);
874 assert
.deepStrictEqual(result
, expected
);
876 it('failure', async
function () {
879 lastInsertRowid: undefined,
881 sinon
.stub(db
.statement
.topicContentFetchClaimById
, 'run').returns(expected
);
883 await db
.topicFetchClaimById(dbCtx
, topicId
, claimTimeoutSeconds
, claimant
);
884 assert
.fail(noExpectedException
);
886 assert(e
instanceof DBErrors
.UnexpectedResult
);
889 }); // topicFetchClaimById
891 describe('topicFetchComplete', function () {
892 it('success', async
function() {
895 lastInsertRowid: undefined,
897 sinon
.stub(db
.statement
.topicAttemptsReset
, 'run').returns(dbResult
);
898 sinon
.stub(db
.statement
.topicContentFetchDone
, 'run').returns(dbResult
);
899 await db
.topicFetchComplete(dbCtx
, topicId
);
901 it('failure', async
function () {
904 lastInsertRowid: undefined,
906 sinon
.stub(db
.statement
.topicAttemptsReset
, 'run').returns(dbResult
);
907 sinon
.stub(db
.statement
.topicContentFetchDone
, 'run').returns(dbResult
);
909 await db
.topicFetchComplete(dbCtx
, topicId
);
910 assert
.fail(noExpectedException
);
912 assert(e
instanceof DBErrors
.UnexpectedResult
);
915 it('second failure', async
function () {
918 lastInsertRowid: undefined,
922 lastInsertRowid: undefined,
924 sinon
.stub(db
.statement
.topicAttemptsReset
, 'run').returns(dbResult0
);
925 sinon
.stub(db
.statement
.topicContentFetchDone
, 'run').returns(dbResult1
);
927 await db
.topicFetchComplete(dbCtx
, topicId
);
928 assert
.fail(noExpectedException
);
930 assert(e
instanceof DBErrors
.UnexpectedResult
);
933 }); // topicFetchComplete
935 describe('topicFetchIncomplete', function () {
936 it('success', async
function() {
937 const dbGet
= { currentAttempt: 0 };
940 lastInsertRowid: undefined,
944 lastInsertRowid: undefined,
948 lastInsertRowid: undefined,
950 sinon
.stub(db
.statement
.topicAttempts
, 'get').returns(dbGet
);
951 sinon
.stub(db
.statement
.topicAttemptsIncrement
, 'run').returns(dbResult0
);
952 sinon
.stub(db
.statement
.topicContentFetchDone
, 'run').returns(dbResult1
);
953 const result
= await db
.topicFetchIncomplete(dbCtx
, topicId
, retryDelays
);
954 assert
.deepStrictEqual(result
, expected
);
956 it('covers defaults', async
function() {
957 const dbGet
= { currentAttempt: 0 };
960 lastInsertRowid: undefined,
964 lastInsertRowid: undefined,
968 lastInsertRowid: undefined,
970 sinon
.stub(db
.statement
.topicAttempts
, 'get').returns(dbGet
);
971 sinon
.stub(db
.statement
.topicAttemptsIncrement
, 'run').returns(dbResult0
);
972 sinon
.stub(db
.statement
.topicContentFetchDone
, 'run').returns(dbResult1
);
973 const result
= await db
.topicFetchIncomplete(dbCtx
, topicId
);
974 assert
.deepStrictEqual(result
, expected
);
976 it('failure', async
function () {
977 const dbGet
= { currentAttempt: 0 };
980 lastInsertRowid: undefined,
984 lastInsertRowid: undefined,
986 sinon
.stub(db
.statement
.topicAttempts
, 'get').returns(dbGet
);
987 sinon
.stub(db
.statement
.topicAttemptsIncrement
, 'run').returns(dbResult0
);
988 sinon
.stub(db
.statement
.topicContentFetchDone
, 'run').returns(dbResult1
);
990 await db
.topicFetchIncomplete(dbCtx
, topicId
, retryDelays
);
991 assert
.fail(noExpectedException
);
993 assert(e
instanceof DBErrors
.UnexpectedResult
);
996 it('second failure', async
function () {
997 const dbGet
= { currentAttempt: 0 };
1000 lastInsertRowid: undefined,
1004 lastInsertRowid: undefined,
1006 sinon
.stub(db
.statement
.topicAttempts
, 'get').returns(dbGet
);
1007 sinon
.stub(db
.statement
.topicAttemptsIncrement
, 'run').returns(dbResult0
);
1008 sinon
.stub(db
.statement
.topicContentFetchDone
, 'run').returns(dbResult1
);
1010 await db
.topicFetchIncomplete(dbCtx
, topicId
, retryDelays
);
1011 assert
.fail(noExpectedException
);
1013 assert(e
instanceof DBErrors
.UnexpectedResult
);
1016 }); // topicFetchIncomplete
1018 describe('topicFetchRequested', function () {
1019 it('success', async
function() {
1022 lastInsertRowid: undefined,
1026 lastInsertRowid: undefined,
1028 sinon
.stub(db
.statement
.topicContentFetchRequested
, 'run').returns(dbResult
);
1029 const result
= await db
.topicFetchRequested(dbCtx
, topicId
);
1030 assert
.deepStrictEqual(result
, expected
);
1032 it('failure', async
function () {
1035 lastInsertRowid: undefined,
1037 sinon
.stub(db
.statement
.topicContentFetchRequested
, 'run').returns(dbResult
);
1039 await db
.topicFetchRequested(dbCtx
, topicId
);
1040 assert
.fail(noExpectedException
);
1042 assert(e
instanceof DBErrors
.UnexpectedResult
);
1045 }); // topicFetchRequested
1047 describe('topicGetAll', function () {
1048 it('success', async
function() {
1049 const expected
= [{ id: topicId
}];
1050 sinon
.stub(db
.statement
.topicGetInfoAll
, 'all').returns(expected
);
1051 const result
= await db
.topicGetAll(dbCtx
);
1052 assert
.deepStrictEqual(result
, expected
);
1054 it('covers none', async
function() {
1055 const expected
= undefined;
1056 sinon
.stub(db
.statement
.topicGetInfoAll
, 'all').returns(expected
);
1057 const result
= await db
.topicGetAll(dbCtx
);
1058 assert
.deepStrictEqual(result
, expected
);
1060 it('failure', async
function () {
1061 const expected
= new Error();
1062 sinon
.stub(db
.statement
.topicGetInfoAll
, 'all').throws(expected
);
1064 await db
.topicGetAll(dbCtx
);
1065 assert
.fail(noExpectedException
);
1067 assert
.deepStrictEqual(e
, expected
);
1072 describe('topicGetById', function () {
1073 it('success', async
function() {
1074 const expected
= { id: topicId
};
1075 sinon
.stub(db
.statement
.topicGetById
, 'get').returns(expected
);
1076 const result
= await db
.topicGetById(dbCtx
, topicId
);
1077 assert
.deepStrictEqual(result
, expected
);
1079 it('covers no defaults', async
function () {
1080 const expected
= { id: topicId
};
1081 sinon
.stub(db
.statement
.topicGetById
, 'get').returns(expected
);
1082 const result
= await db
.topicGetById(dbCtx
, topicId
, false);
1083 assert
.deepStrictEqual(result
, expected
);
1085 it('covers default', async
function() {
1086 const expected
= undefined;
1087 sinon
.stub(db
.statement
.topicGetById
, 'get').returns(expected
);
1088 const result
= await db
.topicGetById(dbCtx
, topicId
);
1089 assert
.deepStrictEqual(result
, expected
);
1091 it('failure', async
function () {
1092 const expected
= new Error();
1093 sinon
.stub(db
.statement
.topicGetById
, 'get').throws(expected
);
1095 await db
.topicGetById(dbCtx
, topicId
);
1096 assert
.fail(noExpectedException
);
1098 assert
.deepStrictEqual(e
, expected
);
1103 describe('topicGetByUrl', function () {
1104 it('success', async
function() {
1105 const expected
= [];
1106 sinon
.stub(db
.statement
.topicGetByUrl
, 'get').returns(expected
);
1107 const result
= await db
.topicGetByUrl(dbCtx
, topicUrl
);
1108 assert
.deepStrictEqual(result
, expected
);
1110 it('success, no defaults', async
function() {
1111 const expected
= [];
1112 sinon
.stub(db
.statement
.topicGetByUrl
, 'get').returns(expected
);
1113 const result
= await db
.topicGetByUrl(dbCtx
, topicUrl
, false);
1114 assert
.deepStrictEqual(result
, expected
);
1116 it('failure', async
function () {
1117 const expected
= new Error();
1118 sinon
.stub(db
.statement
.topicGetByUrl
, 'get').throws(expected
);
1120 await db
.topicGetByUrl(dbCtx
, topicUrl
);
1121 assert
.fail(noExpectedException
);
1123 assert
.deepStrictEqual(e
, expected
);
1126 }); // topicGetByUrl
1128 describe('topicGetContentById', function () {
1129 it('success', async
function() {
1130 const expected
= { id: topicId
};
1131 sinon
.stub(db
.statement
.topicGetContentById
, 'get').returns(expected
);
1132 const result
= await db
.topicGetContentById(dbCtx
, topicId
);
1133 assert
.deepStrictEqual(result
, expected
);
1135 it('covers default', async
function() {
1136 const expected
= undefined;
1137 sinon
.stub(db
.statement
.topicGetContentById
, 'get').returns(expected
);
1138 const result
= await db
.topicGetContentById(dbCtx
, topicId
);
1139 assert
.deepStrictEqual(result
, expected
);
1141 it('failure', async
function () {
1142 const expected
= new Error();
1143 sinon
.stub(db
.statement
.topicGetContentById
, 'get').throws(expected
);
1145 await db
.topicGetContentById(dbCtx
, topicId
);
1146 assert
.fail(noExpectedException
);
1148 assert
.deepStrictEqual(e
, expected
);
1151 }); // topicGetContentById
1153 describe('topicPendingDelete', function () {
1154 beforeEach(function () {
1155 sinon
.stub(db
.statement
.topicGetById
, 'get');
1156 sinon
.stub(db
.statement
.subscriptionCountByTopicUrl
, 'get');
1157 sinon
.stub(db
.statement
.topicDeleteById
, 'run');
1159 it('success', async
function () {
1160 db
.statement
.topicGetById
.get.returns({
1164 db
.statement
.subscriptionCountByTopicUrl
.get.returns({
1167 db
.statement
.topicDeleteById
.run
.returns({
1170 db
.topicPendingDelete(dbCtx
, topicId
);
1171 assert(db
.statement
.topicDeleteById
.run
.called
);
1173 it('does not delete non-deleted topic', async
function () {
1174 db
.statement
.topicGetById
.get.returns({
1178 db
.statement
.subscriptionCountByTopicUrl
.get.returns({
1181 db
.statement
.topicDeleteById
.run
.returns({
1184 db
.topicPendingDelete(dbCtx
, topicId
);
1185 assert(!db
.statement
.topicDeleteById
.run
.called
);
1187 it('does not delete topic with active subscriptions', async
function () {
1188 db
.statement
.topicGetById
.get.returns({
1192 db
.statement
.subscriptionCountByTopicUrl
.get.returns({
1195 db
.statement
.topicDeleteById
.run
.returns({
1198 db
.topicPendingDelete(dbCtx
, topicId
);
1199 assert(!db
.statement
.topicDeleteById
.run
.called
);
1201 it('covers no deletion', async
function () {
1202 db
.statement
.topicGetById
.get.returns({
1206 db
.statement
.subscriptionCountByTopicUrl
.get.returns({
1209 db
.statement
.topicDeleteById
.run
.returns({
1213 db
.topicPendingDelete(dbCtx
, topicId
);
1214 assert
.fail(noExpectedException
);
1217 assert(e
instanceof DBErrors
.UnexpectedResult
);
1219 assert(db
.statement
.topicDeleteById
.run
.called
);
1221 }); // topicPendingDelete
1223 describe('topicPublishHistory', function () {
1224 beforeEach(function () {
1225 sinon
.stub(db
.statement
.topicPublishHistory
, 'all');
1227 it('success', function () {
1228 db
.statement
.topicPublishHistory
.all
.returns([
1229 { daysAgo: 1, contentUpdates: 1 },
1230 { daysAgo: 3, contentUpdates: 2 },
1232 const result
= db
.topicPublishHistory(dbCtx
, topicId
, 7);
1233 const expected
= [0, 1, 0, 2, 0, 0, 0];
1234 assert
.deepStrictEqual(result
, expected
);
1236 }); // topicPublishHistory
1238 describe('topicSet', function () {
1240 beforeEach(function () {
1245 it('success', async
function() {
1248 lastInsertRowid: topicId
,
1252 lastInsertRowid: topicId
,
1254 sinon
.stub(db
.statement
.topicUpsert
, 'run').returns(dbResult
);
1255 const result
= await db
.topicSet(dbCtx
, data
);
1256 assert
.deepStrictEqual(result
, expected
);
1258 it('failure', async
function () {
1261 lastInsertRowid: undefined,
1263 sinon
.stub(db
.statement
.topicUpsert
, 'run').returns(dbResult
);
1265 await db
.topicSet(dbCtx
, data
);
1266 assert
.fail(noExpectedException
);
1268 assert(e
instanceof DBErrors
.UnexpectedResult
);
1271 it('fails invalid value', async
function () {
1272 sinon
.stub(db
.statement
.topicUpsert
, 'run');
1274 data
.leaseSecondsPreferred
= -100;
1275 await db
.topicSet(dbCtx
, data
);
1276 assert
.fail(noExpectedException
);
1278 assert(e
instanceof DBErrors
.DataValidation
);
1280 assert(!db
.statement
.topicUpsert
.run
.called
);
1282 it('fails invalid values', async
function () {
1283 sinon
.stub(db
.statement
.topicUpsert
, 'run');
1285 data
.leaseSecondsPreferred
= 10;
1286 data
.leaseSecondsMax
= 100;
1287 data
.leaseSecondsMin
= 50;
1288 await db
.topicSet(dbCtx
, data
);
1289 assert
.fail(noExpectedException
);
1291 assert(e
instanceof DBErrors
.DataValidation
);
1293 assert(!db
.statement
.topicUpsert
.run
.called
);
1297 describe('topicSetContent', function () {
1299 beforeEach(function () {
1302 contentType: 'text/plain',
1303 contentHash: 'abc123',
1305 sinon
.stub(db
.statement
.topicSetContent
, 'run');
1306 sinon
.stub(db
.statement
.topicSetContentHistory
, 'run');
1308 it('success', async
function() {
1311 lastInsertRowid: undefined,
1315 lastInsertRowid: undefined,
1317 db
.statement
.topicSetContent
.run
.returns(dbResult
);
1318 db
.statement
.topicSetContentHistory
.run
.returns(dbResult
);
1319 const result
= await db
.topicSetContent(dbCtx
, data
);
1320 assert
.deepStrictEqual(result
, expected
);
1322 it('failure', async
function () {
1325 lastInsertRowid: undefined,
1327 db
.statement
.topicSetContent
.run
.returns(dbResult
);
1329 await db
.topicSetContent(dbCtx
, data
);
1330 assert
.fail(noExpectedException
);
1332 assert(e
instanceof DBErrors
.UnexpectedResult
);
1335 it('failure 2', async
function () {
1336 const dbResultSuccess
= {
1338 lastInsertRowid: undefined,
1340 const dbResultFail
= {
1342 lastInsertRowid: undefined,
1344 db
.statement
.topicSetContent
.run
.returns(dbResultSuccess
);
1345 db
.statement
.topicSetContentHistory
.run
.returns(dbResultFail
);
1347 await db
.topicSetContent(dbCtx
, data
);
1348 assert
.fail(noExpectedException
);
1350 assert(e
instanceof DBErrors
.UnexpectedResult
);
1353 }); // topicSetContent
1355 describe('topicUpdate', function () {
1357 beforeEach(function () {
1360 leaseSecondsPreferred: 9999,
1361 leaseSecondsMax: 99999,
1362 leaseSecondsMin: 999,
1363 publisherValidationUrl: null,
1364 contentHashAlgorithm: 'sha256',
1367 it('success', async
function() {
1370 lastInsertRowid: topicId
,
1372 sinon
.stub(db
.statement
.topicUpdate
, 'run').returns(dbResult
);
1373 await db
.topicUpdate(dbCtx
, data
);
1375 it('failure', async
function () {
1378 lastInsertRowid: undefined,
1380 sinon
.stub(db
.statement
.topicUpdate
, 'run').returns(dbResult
);
1382 await db
.topicUpdate(dbCtx
, data
);
1383 assert
.fail(noExpectedException
);
1385 assert(e
instanceof DBErrors
.UnexpectedResult
, e
);
1388 it('fails invalid value', async
function () {
1389 sinon
.stub(db
.statement
.topicUpdate
, 'run');
1391 data
.leaseSecondsPreferred
= -100;
1392 await db
.topicUpdate(dbCtx
, data
);
1393 assert
.fail(noExpectedException
);
1395 assert(e
instanceof DBErrors
.DataValidation
, e
);
1397 assert(!db
.statement
.topicUpdate
.run
.called
);
1399 it('fails invalid values', async
function () {
1400 sinon
.stub(db
.statement
.topicUpdate
, 'run');
1402 data
.leaseSecondsPreferred
= 10;
1403 data
.leaseSecondsMax
= 100;
1404 data
.leaseSecondsMin
= 50;
1405 await db
.topicUpdate(dbCtx
, data
);
1406 assert
.fail(noExpectedException
);
1408 assert(e
instanceof DBErrors
.DataValidation
, e
);
1410 assert(!db
.statement
.topicUpdate
.run
.called
);
1414 describe('verificationClaim', function () {
1415 it('success', async
function() {
1416 const dbAll
= [{ id: verificationId
}];
1419 lastInsertRowid: undefined,
1421 const expected
= [verificationId
];
1422 sinon
.stub(db
.statement
.verificationNeeded
, 'all').returns(dbAll
);
1423 sinon
.stub(db
.statement
.verificationClaimById
, 'run').returns(dbRun
);
1424 const result
= await db
.verificationClaim(dbCtx
, wanted
, claimTimeoutSeconds
, claimant
);
1425 assert
.deepStrictEqual(result
, expected
);
1427 it('failure', async
function () {
1428 const dbAll
= [{ id: verificationId
}];
1431 lastInsertRowid: undefined,
1433 sinon
.stub(db
.statement
.verificationNeeded
, 'all').returns(dbAll
);
1434 sinon
.stub(db
.statement
.verificationClaimById
, 'run').returns(dbRun
);
1436 await db
.verificationClaim(dbCtx
, wanted
, claimTimeoutSeconds
, claimant
);
1437 assert
.fail(noExpectedException
);
1439 assert(e
instanceof DBErrors
.UnexpectedResult
);
1442 }); // verificationClaim
1444 describe('verificationClaimById', function () {
1445 it('success', async
function() {
1448 lastInsertRowid: undefined,
1450 sinon
.stub(db
.statement
.verificationClaimById
, 'run').returns(dbRun
);
1451 const result
= await db
.verificationClaimById(dbCtx
, verificationId
, claimTimeoutSeconds
, claimant
);
1452 assert
.deepStrictEqual(result
, dbRun
);
1454 it('failure', async
function () {
1457 lastInsertRowid: undefined,
1459 sinon
.stub(db
.statement
.verificationClaimById
, 'run').returns(dbRun
);
1461 await db
.verificationClaimById(dbCtx
, verificationId
, claimTimeoutSeconds
, claimant
);
1462 assert
.fail(noExpectedException
);
1464 assert(e
instanceof DBErrors
.UnexpectedResult
);
1467 }); // verificationClaimById
1469 describe('verificationComplete', function () {
1470 it('success', async
function() {
1473 lastInsertRowid: undefined,
1475 sinon
.stub(db
.statement
.verificationScrub
, 'run').returns(dbResult
);
1476 await db
.verificationComplete(dbCtx
, verificationId
, callback
, topicId
);
1478 it('failure', async
function () {
1481 lastInsertRowid: undefined,
1483 sinon
.stub(db
.statement
.verificationScrub
, 'run').returns(dbResult
);
1485 await db
.verificationComplete(dbCtx
, verificationId
, callback
, topicId
);
1486 assert
.fail(noExpectedException
);
1488 assert(e
instanceof DBErrors
.UnexpectedResult
);
1491 }); // verificationComplete
1493 describe('verificationGetById', function () {
1494 it('success', async
function() {
1495 const dbOneOrNone
= { id: verificationId
, isPublisherValidated: 1 };
1496 const expected
= { id: verificationId
, isPublisherValidated: true };
1497 sinon
.stub(db
.statement
.verificationGetById
, 'get').returns(dbOneOrNone
);
1498 const result
= await db
.verificationGetById(dbCtx
, verificationId
);
1499 assert
.deepStrictEqual(result
, expected
);
1501 it('failure', async
function () {
1502 const expected
= new Error();
1503 sinon
.stub(db
.statement
.verificationGetById
, 'get').throws(expected
);
1505 await db
.verificationGetById(dbCtx
, verificationId
);
1506 assert
.fail(noExpectedException
);
1508 assert
.deepStrictEqual(e
, expected
);
1511 }); // verificationGetById
1513 describe('verificationIncomplete', function () {
1514 it('success', async
function() {
1515 const dbOne
= { attempts: 0 };
1518 lastInsertRowid: undefined,
1522 lastInsertRowid: undefined,
1524 sinon
.stub(db
.statement
.verificationAttempts
, 'get').returns(dbOne
);
1525 sinon
.stub(db
.statement
.verificationAttemptsIncrement
, 'run').returns(dbResult0
);
1526 sinon
.stub(db
.statement
.verificationDone
, 'run').returns(dbResult1
);
1527 await db
.verificationIncomplete(dbCtx
, verificationId
, retryDelays
);
1529 it('covers defaults', async
function() {
1530 const dbOne
= { attempts: 0 };
1533 lastInsertRowid: undefined,
1537 lastInsertRowid: undefined,
1539 sinon
.stub(db
.statement
.verificationAttempts
, 'get').returns(dbOne
);
1540 sinon
.stub(db
.statement
.verificationAttemptsIncrement
, 'run').returns(dbResult0
);
1541 sinon
.stub(db
.statement
.verificationDone
, 'run').returns(dbResult1
);
1542 await db
.verificationIncomplete(dbCtx
, verificationId
);
1544 it('failure', async
function () {
1545 const dbOne
= { attempts: 0 };
1548 lastInsertRowid: undefined,
1552 lastInsertRowid: undefined,
1554 sinon
.stub(db
.statement
.verificationAttempts
, 'get').returns(dbOne
);
1555 sinon
.stub(db
.statement
.verificationAttemptsIncrement
, 'run').returns(dbResult0
);
1556 sinon
.stub(db
.statement
.verificationDone
, 'run').returns(dbResult1
);
1558 await db
.verificationIncomplete(dbCtx
, verificationId
, retryDelays
);
1559 assert
.fail(noExpectedException
);
1561 assert(e
instanceof DBErrors
.UnexpectedResult
);
1564 it('second failure', async
function () {
1565 const dbOne
= { attempts: 0 };
1568 lastInsertRowid: undefined,
1572 lastInsertRowid: undefined,
1574 sinon
.stub(db
.statement
.verificationAttempts
, 'get').returns(dbOne
);
1575 sinon
.stub(db
.statement
.verificationAttemptsIncrement
, 'run').returns(dbResult0
);
1576 sinon
.stub(db
.statement
.verificationDone
, 'run').returns(dbResult1
);
1578 await db
.verificationIncomplete(dbCtx
, verificationId
, retryDelays
);
1579 assert
.fail(noExpectedException
);
1581 assert(e
instanceof DBErrors
.UnexpectedResult
);
1584 }); // verificationIncomplete
1586 describe('_verificationDataToEngine', function () {
1587 it('covers no data', function () {
1588 DB
._verificationDataToEngine();
1590 it('covers true', function () {
1592 isPublisherValidated: true,
1594 DB
._verificationDataToEngine(data
);
1595 assert
.strictEqual(data
.isPublisherValidated
, 1);
1597 it('covers false', function () {
1599 isPublisherValidated: false,
1601 DB
._verificationDataToEngine(data
);
1602 assert
.strictEqual(data
.isPublisherValidated
, 0);
1604 }); // _verificationDataToEngine
1606 describe('verificationInsert', function () {
1608 beforeEach(function () {
1613 isPublisherValidated: true,
1614 leaseSeconds: 86400,
1617 it('success', async
function() {
1620 lastInsertRowid: verificationId
,
1622 const expected
= verificationId
;
1623 sinon
.stub(db
.statement
.verificationInsert
, 'run').returns(dbResult
);
1624 const result
= await db
.verificationInsert(dbCtx
, verification
);
1625 assert
.deepStrictEqual(result
, expected
);
1627 it('failure', async
function () {
1630 lastInsertRowid: undefined,
1632 sinon
.stub(db
.statement
.verificationInsert
, 'run').returns(dbResult
);
1634 await db
.verificationInsert(dbCtx
, verification
);
1635 assert
.fail(noExpectedException
);
1637 assert(e
instanceof DBErrors
.UnexpectedResult
);
1640 it('fails validation', async
function () {
1641 delete verification
.leaseSeconds
;
1643 await db
.verificationInsert(dbCtx
, verification
);
1644 assert
.fail(noExpectedException
);
1646 assert(e
instanceof DBErrors
.DataValidation
);
1649 }); // verificationInsert
1651 describe('verificationRelease', function () {
1652 it('success', async
function() {
1655 lastInsertRowid: undefined,
1657 sinon
.stub(db
.statement
.verificationDone
, 'run').returns(dbResult
);
1658 await db
.verificationRelease(dbCtx
, verificationId
);
1660 it('failure', async
function () {
1663 lastInsertRowid: undefined,
1665 sinon
.stub(db
.statement
.verificationDone
, 'run').returns(dbResult
);
1667 await db
.verificationRelease(dbCtx
, verificationId
);
1668 assert
.fail(noExpectedException
);
1670 assert(e
instanceof DBErrors
.UnexpectedResult
);
1673 }); // verificationRelease
1675 describe('verificationUpdate', function () {
1677 beforeEach(function () {
1680 isPublisherValidated: true,
1683 it('success', async
function() {
1686 lastInsertRowid: undefined,
1688 sinon
.stub(db
.statement
.verificationUpdate
, 'run').returns(dbResult
);
1689 await db
.verificationUpdate(dbCtx
, verificationId
, data
);
1691 it('failure', async
function () {
1694 lastInsertRowid: undefined,
1696 sinon
.stub(db
.statement
.verificationUpdate
, 'run').returns(dbResult
);
1698 await db
.verificationUpdate(dbCtx
, verificationId
, data
);
1699 assert
.fail(noExpectedException
);
1701 assert(e
instanceof DBErrors
.UnexpectedResult
, e
.name
);
1704 it('fails validation', async
function () {
1707 await db
.verificationUpdate(dbCtx
, data
);
1708 assert
.fail(noExpectedException
);
1710 assert(e
instanceof DBErrors
.DataValidation
);
1713 }); // verificationUpdate
1715 describe('verificationValidated', function () {
1716 it('success', async
function() {
1719 lastInsertRowid: undefined,
1721 sinon
.stub(db
.statement
.verificationValidate
, 'run').returns(dbResult
);
1722 await db
.verificationValidated(dbCtx
, verificationId
);
1724 it('failure', async
function () {
1727 lastInsertRowid: undefined,
1729 sinon
.stub(db
.statement
.verificationValidate
, 'run').returns(dbResult
);
1731 await db
.verificationValidated(dbCtx
, verificationId
);
1732 assert
.fail(noExpectedException
);
1734 assert(e
instanceof DBErrors
.UnexpectedResult
);
1737 }); // verificationValidated
1739 }); // DatabaseSQLite