initial commit
[urlittler] / test / src / db / sqlite / index.js
1 /* eslint-disable capitalized-comments */
2 /* eslint-env mocha */
3
4 'use strict';
5
6 const assert = require('assert');
7 const sinon = require('sinon'); // eslint-disable-line node/no-unpublished-require
8 const DBErrors = require('../../../../src/db/errors');
9
10 const noExpectedException = 'did not get expected exception';
11
12 describe('SQLiteDatabase', function () {
13 const SQLiteDatabase = require('../../../../src/db/sqlite');
14 let db, logger, options, dbCtx;
15
16 beforeEach(function () {
17 logger = {
18 debug: sinon.stub(),
19 info: sinon.stub(),
20 error: sinon.stub(),
21 };
22 options = {};
23 db = new SQLiteDatabase(logger, options);
24 dbCtx = undefined;
25 });
26
27 describe('context', function () {
28 it('covers', async function () {
29 const fn = sinon.stub();
30 await db.context(fn);
31 assert(fn.called);
32 });
33 }); // context
34
35 describe('transaction', function () {
36 it('covers', async function () {
37 const fn = sinon.stub();
38 await db.transaction(dbCtx, fn);
39 assert(fn.called);
40 });
41 }); // transaction
42
43 describe('getAuthById', function () {
44 let id;
45 beforeEach(function () {
46 sinon.stub(db.statement.getAuthById, 'get');
47 });
48
49 it('stubbed success', async function () {
50 const expected = {
51 id: 'id',
52 secret: 'secret',
53 password: 'password',
54 };
55 id = 'id';
56 db.statement.getAuthById.get.returns(expected);
57 const result = await db.getAuthById(dbCtx, id);
58 assert.deepStrictEqual(result, expected);
59 });
60 it('stubbed failure', async function () {
61 const expectedExeption = new Error('blah');
62 id = 'id';
63 db.statement.getAuthById.get.throws(expectedExeption);
64 try {
65 await db.getAuthById(dbCtx, id);
66 assert.fail(noExpectedException);
67 } catch (e) {
68 assert.deepStrictEqual(e, expectedExeption, noExpectedException);
69 }
70 });
71 }); // getAuthById
72
73 describe('insertLink', function () {
74 let id, url, authToken;
75 beforeEach(function () {
76 sinon.stub(db.statement.insertLink, 'run');
77 sinon.stub(db.statement.updateLink, 'run');
78 });
79
80 it('stubbed insert success', async function () {
81 const info = {
82 changes: BigInt(1),
83 lastInsertRowid: BigInt(123),
84 };
85 id = 'id';
86 db.statement.insertLink.run.returns(info);
87 const expected = {
88 changes: 1,
89 lastInsertRowid: 123,
90 };
91 const result = await db.insertLink(dbCtx, id, url, authToken);
92 assert.deepStrictEqual(result, expected);
93 });
94 it('stubbed update success', async function () {
95 const info = {
96 changes: BigInt(1),
97 lastInsertRowid: BigInt(123),
98 };
99 id = 'id';
100 db.statement.insertLink.run.throws({ code: 'SQLITE_CONSTRAINT_UNIQUE' });
101 db.statement.updateLink.run.returns(info);
102 const expected = {
103 changes: 1,
104 lastInsertRowid: 123,
105 };
106 const result = await db.insertLink(dbCtx, id, url, authToken);
107 assert.deepStrictEqual(result, expected);
108 });
109 it('stubbed failure', async function () {
110 const expectedExeption = new Error('blah');
111 id = 'id';
112 db.statement.insertLink.run.throws(expectedExeption);
113 try {
114 await db.insertLink(dbCtx, id, url, authToken);
115 assert.fail(noExpectedException);
116 } catch (e) {
117 assert.deepStrictEqual(e, expectedExeption, noExpectedException);
118 }
119 });
120 it('stubbed unexpected failure', async function () {
121 const expectedException = DBErrors.UnexpectedResult;
122 const returns = {
123 changes: 0,
124 lastInsertRowid: undefined,
125 };
126 id = 'id';
127 db.statement.insertLink.run.returns(returns);
128 try {
129 await db.insertLink(dbCtx, id, url, authToken);
130 assert.fail(noExpectedException);
131 } catch (e) {
132 assert(e instanceof expectedException);
133 }
134 });
135 }); // insertLink
136
137 describe('getLinkById', function () {
138 let id;
139
140 beforeEach(function () {
141 sinon.stub(db.statement.getLinkById, 'get');
142 });
143
144 it('stubbed success', async function () {
145 const returns = {
146 id: 'id',
147 url: 'url',
148 created: 0,
149 expires: 0,
150 'auth_token': 'abc',
151 'last_access': 0,
152 accesses: 0,
153 };
154 const expected = {
155 id: 'id',
156 url: 'url',
157 created: 0,
158 expires: 0,
159 authToken: 'abc',
160 lastAccess: 0,
161 accesses: 0,
162 };
163 id = 'id';
164 db.statement.getLinkById.get.returns(returns);
165 const result = await db.getLinkById(dbCtx, id);
166 assert.deepStrictEqual(result, expected);
167 });
168 it('stubbed failure', async function () {
169 const expectedExeption = new Error('blah');
170 id = 'id';
171 db.statement.getLinkById.get.throws(expectedExeption);
172 try {
173 await db.getLinkById(dbCtx, id);
174 assert.fail(noExpectedException);
175 } catch (e) {
176 assert.deepStrictEqual(e, expectedExeption, noExpectedException);
177 }
178 });
179 }); // getLinkById
180
181 describe('getLinkByUrl', function () {
182 let url;
183
184 beforeEach(function () {
185 sinon.stub(db.statement.getLinkByUrl, 'get');
186 });
187
188 it('stubbed success', async function () {
189 const returns = {
190 id: 'id',
191 url: 'url',
192 created: 0,
193 expires: 123,
194 'auth_token': 'abc',
195 'last_access': 0,
196 accesses: 0,
197 };
198 const expected = {
199 id: 'id',
200 url: 'url',
201 created: 0,
202 expires: 123,
203 authToken: 'abc',
204 lastAccess: 0,
205 accesses: 0,
206 };
207 url = 'url';
208 db.statement.getLinkByUrl.get.returns(returns);
209 const result = await db.getLinkByUrl(dbCtx, url);
210 assert.deepStrictEqual(result, expected);
211 });
212 it('stubbed failure', async function () {
213 const expectedExeption = new Error('blah');
214 url = 'url';
215 db.statement.getLinkByUrl.get.throws(expectedExeption);
216 try {
217 await db.getLinkByUrl(dbCtx, url);
218 assert.fail(noExpectedException);
219 } catch (e) {
220 assert.deepStrictEqual(e, expectedExeption, noExpectedException);
221 }
222 });
223 }); // getLinkByUrl
224
225 describe('accessLink', function () {
226 let id;
227
228 beforeEach(function () {
229 sinon.stub(db.statement.getLinkById, 'get');
230 sinon.stub(db.statement.incrementLinkAccess, 'run');
231 });
232
233 it('stubbed exists success', async function () {
234 const returns = {
235 id: 'id',
236 url: 'url',
237 created: 0,
238 expires: 0,
239 'auth_token': 'abc',
240 'last_access': 0,
241 accesses: 0,
242 };
243 const expected = {
244 id: 'id',
245 url: 'url',
246 created: 0,
247 expires: 0,
248 authToken: 'abc',
249 lastAccess: 0,
250 accesses: 0,
251 };
252 id = 'id';
253 db.statement.getLinkById.get.returns(returns);
254 db.statement.incrementLinkAccess.run.returns({ changes: 1 });
255 const result = await db.accessLink(dbCtx, id);
256 assert.deepStrictEqual(result, expected);
257 });
258 it('stubbed missing success', async function () {
259 const returns = undefined;
260 const expected = undefined;
261 id = 'id';
262 db.statement.getLinkById.get.returns(returns);
263 db.statement.incrementLinkAccess.run.returns({ changes: 0 });
264 const result = await db.accessLink(dbCtx, id);
265 assert.deepStrictEqual(result, expected);
266 });
267 it('stubbed increment failure', async function () {
268 const expectedExeption = DBErrors.UnexpectedResult;
269 const returns = {
270 id: 'id',
271 url: 'url',
272 created: 0,
273 expires: 0,
274 'auth_token': 'abc',
275 'last_access': 0,
276 accesses: 0,
277 };
278 id = 'id';
279 db.statement.getLinkById.get.returns(returns);
280 db.statement.incrementLinkAccess.run.returns({ changes: 0 });
281 try {
282 await db.accessLink(dbCtx, id);
283 assert.fail(noExpectedException);
284 } catch (e) {
285 assert(e instanceof expectedExeption, noExpectedException);
286 }
287 });
288 it('stubbed failure', async function () {
289 const expectedExeption = new Error('blah');
290 id = 'id';
291 db.statement.getLinkById.get.throws(expectedExeption);
292 try {
293 await db.accessLink(dbCtx, id);
294 assert.fail(noExpectedException);
295 } catch (e) {
296 assert.deepStrictEqual(e, expectedExeption, noExpectedException);
297 }
298 });
299 }); // accessLink
300
301 describe('expireLink', function () {
302 let id, expires;
303
304 beforeEach(function () {
305 sinon.stub(db.statement.expireLink, 'run');
306 });
307
308 it('stubbed success', async function () {
309 const returns = {
310 changes: 1,
311 lastInsertRowid: 123,
312 };
313 const expected = {
314 changes: 1,
315 lastInsertRowid: 123,
316 };
317 id = 'id';
318 expires = null;
319 db.statement.expireLink.run.returns(returns);
320 const result = await db.expireLink(dbCtx, id, expires);
321 assert.deepStrictEqual(result, expected);
322 });
323 it('stubbed change failure', async function () {
324 const expectedExeption = DBErrors.UnexpectedResult;
325 const returns = {
326 changes: 0,
327 lastInsertRowid: undefined,
328 };
329 id = 'id';
330 db.statement.expireLink.run.returns(returns);
331 try {
332 await db.expireLink(dbCtx, id);
333 assert.fail(noExpectedException);
334 } catch (e) {
335 assert(e instanceof expectedExeption, noExpectedException);
336 }
337 });
338 it('stubbed failure', async function () {
339 const expectedExeption = new Error('blah');
340 id = 'id';
341 expires = null;
342 db.statement.expireLink.run.throws(expectedExeption);
343 try {
344 await db.expireLink(dbCtx, id, expires);
345 assert.fail(noExpectedException);
346 } catch (e) {
347 assert.deepStrictEqual(e, expectedExeption, noExpectedException);
348 }
349 });
350 }); // expireLink
351
352 describe('updateLink', function () {
353 let id, expires;
354
355 beforeEach(function () {
356 sinon.stub(db.statement.updateLink, 'run');
357 });
358
359 it('stubbed success', async function () {
360 const returns = {
361 changes: 1,
362 lastInsertRowid: 1,
363 };
364 const expected = {
365 changes: 1,
366 lastInsertRowid: 1,
367 };
368 id = 'id';
369 expires = null;
370 db.statement.updateLink.run.returns(returns);
371 const result = await db.updateLink(dbCtx, id, expires);
372 assert.deepStrictEqual(result, expected);
373 });
374 it('stubbed change failure', async function () {
375 const expectedExeption = DBErrors.UnexpectedResult;
376 const returns = {
377 changes: 0,
378 lastInsertRowid: undefined,
379 };
380 id = 'id';
381 db.statement.updateLink.run.returns(returns);
382 try {
383 await db.updateLink(dbCtx, id);
384 assert.fail(noExpectedException);
385 } catch (e) {
386 assert(e instanceof expectedExeption, noExpectedException);
387 }
388 });
389 it('stubbed failure', async function () {
390 const expectedExeption = new Error('blah');
391 id = 'id';
392 expires = null;
393 db.statement.updateLink.run.throws(expectedExeption);
394 try {
395 await db.updateLink(dbCtx, id, expires);
396 assert.fail(noExpectedException);
397 } catch (e) {
398 assert.deepStrictEqual(e, expectedExeption, noExpectedException);
399 }
400 });
401 }); // updateLink
402
403 describe('getAllLinks', function () {
404 beforeEach(function () {
405 sinon.stub(db.statement.linkGetAll, 'all');
406 });
407
408 it('stubbed success', async function () {
409 const returns = [
410 {
411 id: 'id',
412 url: 'url',
413 created: 0,
414 expires: 0,
415 'auth_token': 'abc',
416 'last_access': 0,
417 accesses: 0,
418 },
419 ];
420 const expected = [
421 {
422 id: 'id',
423 url: 'url',
424 created: 0,
425 expires: 0,
426 authToken: 'abc',
427 lastAccess: 0,
428 accesses: 0,
429 },
430 ];
431 db.statement.linkGetAll.all.returns(returns);
432 const result = await db.getAllLinks(dbCtx);
433 assert.deepStrictEqual(result, expected);
434 });
435 it('stubbed failure', async function () {
436 const expectedExeption = new Error('blah');
437 db.statement.linkGetAll.all.throws(expectedExeption);
438 try {
439 await db.getAllLinks(dbCtx);
440 assert.fail(noExpectedException);
441 } catch (e) {
442 assert.deepStrictEqual(e, expectedExeption, noExpectedException);
443 }
444 });
445 }); // getAllLinks
446
447 describe('_optimize', function () {
448 let cslo, oac;
449 beforeEach(function () {
450 cslo = db.changesSinceLastOptimize;
451 oac = db.optimizeAfterChanges;
452 sinon.stub(db.db, 'prepare').returns({
453 all: sinon.stub(),
454 });
455 sinon.stub(db.db, 'pragma');
456 });
457 afterEach(function () {
458 db.changesSinceLastOptimize = cslo;
459 db.optimizeAfterChanges = oac;
460 });
461 it('covers', function () {
462 db._optimize();
463 assert(db.db.pragma.called);
464 });
465 it('_maybeOptimize', function () {
466 db.changesSinceLastOptimize = BigInt(1000);
467 db.optimizeAfterChanges = BigInt(10);
468 sinon.stub(db, '_optimize');
469 db._maybeOptimize();
470 assert(db._optimize.called);
471 });
472 });
473
474 });