X-Git-Url: https://git.squeep.com/?a=blobdiff_plain;f=test%2Fsrc%2Fdb%2Fsqlite.js;h=33f00282d9d80ff9b1e1d2278afe4e8cebdf4481;hb=3ca7fccb306d0b23626befc3791ffa360b3db1e7;hp=370d559909cfdfaa1bb2eb7020584e3f8e0eb7d1;hpb=9812213260e952ae601f94ab0915c680e8c80495;p=websub-hub diff --git a/test/src/db/sqlite.js b/test/src/db/sqlite.js index 370d559..33f0028 100644 --- a/test/src/db/sqlite.js +++ b/test/src/db/sqlite.js @@ -1,12 +1,8 @@ -/* eslint-disable sonarjs/no-identical-functions */ -/* eslint-env mocha */ -/* eslint-disable sonarjs/no-duplicate-string */ 'use strict'; /* This provides implementation coverage, stubbing parts of better-sqlite3. */ -const assert = require('assert'); -// eslint-disable-next-line node/no-unpublished-require +const assert = require('node:assert'); const sinon = require('sinon'); const DBStub = require('../../stub-db'); const stubLogger = require('../../stub-logger'); @@ -47,6 +43,12 @@ describe('DatabaseSQLite', function () { sinon.restore(); }); + it('covers options', function () { + const xoptions = new Config('test'); + delete xoptions.db.connectionString; + db = new DB(stubLogger, xoptions); + }); + // Ensure all interface methods are implemented describe('Implementation', function () { it('implements interface', async function () { @@ -66,6 +68,38 @@ describe('DatabaseSQLite', function () { }); }); // Implementation + describe('_initTables', function () { + let preparedGet; + beforeEach(function () { + preparedGet = sinon.stub(); + sinon.stub(db.db, 'prepare').returns({ + pluck: () => ({ + bind: () => ({ + get: preparedGet, + }), + }), + }); + sinon.stub(db, '_currentSchema').returns(db.schemaVersionsSupported.min); + sinon.stub(db.db, 'exec'); + }); + it('covers migration', async function() { + preparedGet.returns({}); + await db._initTables(); + assert(db.db.exec.called); + }); + it('covers migration failure', async function() { + const expected = new Error('oh no'); + preparedGet.returns({}); + db.db.exec.throws(expected); + try { + await db._initTables(); + assert.fail(noExpectedException); + } catch (e) { + assert.deepStrictEqual(e, expected); + } + }); + }); // _initTables + describe('_currentSchema', function () { it('covers', async function () { const version = { major: 1, minor: 0, patch: 0 }; @@ -205,7 +239,7 @@ describe('DatabaseSQLite', function () { contentFetchNextAttempt: now, contentUpdated: now, url: topic.url, - } + }; const result = DB._topicDataToNative(topic); assert.deepStrictEqual(result, expected); }); @@ -309,10 +343,11 @@ describe('DatabaseSQLite', function () { }); // authenticationGet describe('authenticationUpsert', function () { - let identifier, credential; + let identifier, credential, otpKey; beforeEach(function () { identifier = 'username'; credential = '$z$foo'; + otpKey = '12345678901234567890123456789012'; }); it('success', async function() { const dbResult = { @@ -320,7 +355,7 @@ describe('DatabaseSQLite', function () { lastInsertRowid: undefined, }; sinon.stub(db.statement.authenticationUpsert, 'run').returns(dbResult); - await db.authenticationUpsert(dbCtx, identifier, credential); + await db.authenticationUpsert(dbCtx, identifier, credential, otpKey); }); it('failure', async function () { const dbResult = { @@ -329,7 +364,65 @@ describe('DatabaseSQLite', function () { }; sinon.stub(db.statement.authenticationUpsert, 'run').returns(dbResult); try { - await db.authenticationUpsert(dbCtx, identifier, credential); + await db.authenticationUpsert(dbCtx, identifier, credential, otpKey); + assert.fail(noExpectedException); + } catch (e) { + assert(e instanceof DBErrors.UnexpectedResult); + } + }); + }); // authenticationUpsert + + describe('authenticationUpdateCredential', function () { + let identifier, credential; + beforeEach(function () { + identifier = 'username'; + credential = '$z$foo'; + }); + it('success', async function() { + const dbResult = { + changes: 1, + lastInsertRowid: undefined, + }; + sinon.stub(db.statement.authenticationUpdateCredential, 'run').returns(dbResult); + await db.authenticationUpdateCredential(dbCtx, identifier, credential); + }); + it('failure', async function () { + const dbResult = { + changes: 0, + lastInsertRowid: undefined, + }; + sinon.stub(db.statement.authenticationUpdateCredential, 'run').returns(dbResult); + try { + await db.authenticationUpdateCredential(dbCtx, identifier, credential); + assert.fail(noExpectedException); + } catch (e) { + assert(e instanceof DBErrors.UnexpectedResult); + } + }); + }); // authenticationUpdateCredential + + describe('authenticationUpdateOTPKey', function () { + let identifier, otpKey; + beforeEach(function () { + identifier = 'username'; + otpKey = '12345678901234567890123456789012'; + }); + it('success', async function() { + const dbResult = { + changes: 1, + lastInsertRowid: undefined, + }; + sinon.stub(db.statement.authenticationUpdateOtpKey, 'run').returns(dbResult); + await db.authenticationUpdateOTPKey(dbCtx, identifier, otpKey); + }); + it('failure', async function () { + const dbResult = { + changes: 0, + lastInsertRowid: undefined, + }; + sinon.stub(db.statement.authenticationUpdateOtpKey, 'run').returns(dbResult); + try { + await db.authenticationUpdateOTPKey(dbCtx, identifier, otpKey); assert.fail(noExpectedException); } catch (e) { assert(e instanceof DBErrors.UnexpectedResult); @@ -428,7 +521,7 @@ describe('DatabaseSQLite', function () { assert.deepStrictEqual(e, expected); } }); - }); + }); // subscriptionDeleteExpired describe('subscriptionDeliveryClaim', function () { it('success', async function () { @@ -494,13 +587,17 @@ describe('DatabaseSQLite', function () { }); // subscriptionDeliveryClaimById describe('subscriptionDeliveryComplete', function () { + let topicContentUpdated; + before(function () { + topicContentUpdated = new Date(); + }); it('success', async function() { const dbResult = { changes: 1, }; sinon.stub(db.statement.subscriptionDeliverySuccess, 'run').returns(dbResult); sinon.stub(db.statement.subscriptionDeliveryDone, 'run').returns(dbResult); - await db.subscriptionDeliveryComplete(dbCtx, callback, topicId); + await db.subscriptionDeliveryComplete(dbCtx, callback, topicId, topicContentUpdated); }); it('failure', async function () { const dbResult = { @@ -509,7 +606,7 @@ describe('DatabaseSQLite', function () { sinon.stub(db.statement.subscriptionDeliverySuccess, 'run').returns(dbResult); sinon.stub(db.statement.subscriptionDeliveryDone, 'run').returns(dbResult); try { - await db.subscriptionDeliveryComplete(dbCtx, callback, topicId); + await db.subscriptionDeliveryComplete(dbCtx, callback, topicId, topicContentUpdated); assert.fail(noExpectedException); } catch (e) { assert(e instanceof DBErrors.UnexpectedResult); @@ -525,7 +622,7 @@ describe('DatabaseSQLite', function () { sinon.stub(db.statement.subscriptionDeliverySuccess, 'run').returns(dbResult0); sinon.stub(db.statement.subscriptionDeliveryDone, 'run').returns(dbResult1); try { - await db.subscriptionDeliveryComplete(dbCtx, callback, topicId); + await db.subscriptionDeliveryComplete(dbCtx, callback, topicId, topicContentUpdated); assert.fail(noExpectedException); } catch (e) { assert(e instanceof DBErrors.UnexpectedResult); @@ -845,7 +942,7 @@ describe('DatabaseSQLite', function () { const dbResult1 = { changes: 1, lastInsertRowid: undefined, - } + }; const expected = { changes: 1, lastInsertRowid: undefined, @@ -865,7 +962,7 @@ describe('DatabaseSQLite', function () { const dbResult1 = { changes: 1, lastInsertRowid: undefined, - } + }; const expected = { changes: 1, lastInsertRowid: undefined, @@ -885,7 +982,7 @@ describe('DatabaseSQLite', function () { const dbResult1 = { changes: 0, lastInsertRowid: undefined, - } + }; sinon.stub(db.statement.topicAttempts, 'get').returns(dbGet); sinon.stub(db.statement.topicAttemptsIncrement, 'run').returns(dbResult0); sinon.stub(db.statement.topicContentFetchDone, 'run').returns(dbResult1); @@ -905,7 +1002,7 @@ describe('DatabaseSQLite', function () { const dbResult1 = { changes: 0, lastInsertRowid: undefined, - } + }; sinon.stub(db.statement.topicAttempts, 'get').returns(dbGet); sinon.stub(db.statement.topicAttemptsIncrement, 'run').returns(dbResult0); sinon.stub(db.statement.topicContentFetchDone, 'run').returns(dbResult1); @@ -1010,6 +1107,12 @@ describe('DatabaseSQLite', function () { const result = await db.topicGetByUrl(dbCtx, topicUrl); assert.deepStrictEqual(result, expected); }); + it('success, no defaults', async function() { + const expected = []; + sinon.stub(db.statement.topicGetByUrl, 'get').returns(expected); + const result = await db.topicGetByUrl(dbCtx, topicUrl, false); + assert.deepStrictEqual(result, expected); + }); it('failure', async function () { const expected = new Error(); sinon.stub(db.statement.topicGetByUrl, 'get').throws(expected); @@ -1115,7 +1218,22 @@ describe('DatabaseSQLite', function () { } assert(db.statement.topicDeleteById.run.called); }); - }); + }); // topicPendingDelete + + describe('topicPublishHistory', function () { + beforeEach(function () { + sinon.stub(db.statement.topicPublishHistory, 'all'); + }); + it('success', function () { + db.statement.topicPublishHistory.all.returns([ + { daysAgo: 1, contentUpdates: 1 }, + { daysAgo: 3, contentUpdates: 2 }, + ]); + const result = db.topicPublishHistory(dbCtx, topicId, 7); + const expected = [0, 1, 0, 2, 0, 0, 0]; + assert.deepStrictEqual(result, expected); + }); + }); // topicPublishHistory describe('topicSet', function () { let data; @@ -1184,6 +1302,8 @@ describe('DatabaseSQLite', function () { contentType: 'text/plain', contentHash: 'abc123', }; + sinon.stub(db.statement.topicSetContent, 'run'); + sinon.stub(db.statement.topicSetContentHistory, 'run'); }); it('success', async function() { const dbResult = { @@ -1194,7 +1314,8 @@ describe('DatabaseSQLite', function () { changes: 1, lastInsertRowid: undefined, }; - sinon.stub(db.statement.topicSetContent, 'run').returns(dbResult); + db.statement.topicSetContent.run.returns(dbResult); + db.statement.topicSetContentHistory.run.returns(dbResult); const result = await db.topicSetContent(dbCtx, data); assert.deepStrictEqual(result, expected); }); @@ -1203,7 +1324,25 @@ describe('DatabaseSQLite', function () { changes: 0, lastInsertRowid: undefined, }; - sinon.stub(db.statement.topicSetContent, 'run').returns(dbResult); + db.statement.topicSetContent.run.returns(dbResult); + try { + await db.topicSetContent(dbCtx, data); + assert.fail(noExpectedException); + } catch (e) { + assert(e instanceof DBErrors.UnexpectedResult); + } + }); + it('failure 2', async function () { + const dbResultSuccess = { + changes: 1, + lastInsertRowid: undefined, + }; + const dbResultFail = { + changes: 0, + lastInsertRowid: undefined, + }; + db.statement.topicSetContent.run.returns(dbResultSuccess); + db.statement.topicSetContentHistory.run.returns(dbResultFail); try { await db.topicSetContent(dbCtx, data); assert.fail(noExpectedException); @@ -1462,7 +1601,7 @@ describe('DatabaseSQLite', function () { DB._verificationDataToEngine(data); assert.strictEqual(data.isPublisherValidated, 0); }); - }) // _verificationDataToEngine + }); // _verificationDataToEngine describe('verificationInsert', function () { let verification; @@ -1553,7 +1692,7 @@ describe('DatabaseSQLite', function () { const dbResult = { changes: 0, lastInsertRowid: undefined, - } + }; sinon.stub(db.statement.verificationUpdate, 'run').returns(dbResult); try { await db.verificationUpdate(dbCtx, verificationId, data); @@ -1578,7 +1717,7 @@ describe('DatabaseSQLite', function () { const dbResult = { changes: 1, lastInsertRowid: undefined, - } + }; sinon.stub(db.statement.verificationValidate, 'run').returns(dbResult); await db.verificationValidated(dbCtx, verificationId); }); @@ -1586,7 +1725,7 @@ describe('DatabaseSQLite', function () { const dbResult = { changes: 0, lastInsertRowid: undefined, - } + }; sinon.stub(db.statement.verificationValidate, 'run').returns(dbResult); try { await db.verificationValidated(dbCtx, verificationId); @@ -1597,4 +1736,4 @@ describe('DatabaseSQLite', function () { }); }); // verificationValidated -}); // DatabasePostgres +}); // DatabaseSQLite