From 21a9862432f65f4093dfb4f1ab49189bf7bd8a59 Mon Sep 17 00:00:00 2001 From: alxndrsn Date: Tue, 26 Nov 2024 08:48:56 +0000 Subject: [PATCH 1/4] Add test for /backup Closes #1305 --- test/integration/api/backup.js | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/test/integration/api/backup.js b/test/integration/api/backup.js index 4ac07b829..a5ce26afe 100644 --- a/test/integration/api/backup.js +++ b/test/integration/api/backup.js @@ -1,11 +1,38 @@ +const { omit } = require('ramda'); const { testService } = require('../setup'); - +const { httpZipResponseToFiles } = require('../../util/zip'); describe('api: /backup', () => { - describe('POST', () => { + describe('POST', function () { + this.timeout(10000); it('should reject if the user cannot backup', testService((service) => service.login('chelsea', (asChelsea) => asChelsea.post('/v1/backup').expect(403)))); + + it('should return a valid zip file if the user can backup @slow', testService((service) => + service.login('alice', (asAlice) => + httpZipResponseToFiles(asAlice.post('/v1/backup').expect(200)) + .then(res => { + const constantProps = ['filenames', 'keepalive', 'keys.json', 'toc.dat']; + res.should.have.properties(constantProps); + + const datFiles = Object.keys(omit(constantProps, res)); + // Because /backup ALWAYS uses config('default.database'), this list + // may be empty in some environments, including CI. + datFiles.should.matchEvery(/\.dat\.gz$/); + + res.should.only.have.keys(...constantProps, ...datFiles); + + const keysJson = JSON.parse(res['keys.json']); + keysJson.should.only.have.keys('iv', 'local', 'privkey', 'pubkey', 'salt'); + keysJson.iv.should.be.a.String(); + keysJson.privkey.should.be.a.String(); + keysJson.pubkey.should.be.a.String(); + keysJson.salt.should.be.a.String(); + keysJson.local.should.only.have.keys('key', 'ivs'); + keysJson.local.key.should.be.a.String(); + keysJson.local.ivs.should.only.have.keys('toc.dat', ...datFiles); + })))); }); }); From 79b83903b47c1e93e26a3f6a0020383395b7ff4b Mon Sep 17 00:00:00 2001 From: alxndrsn Date: Wed, 27 Nov 2024 07:05:48 +0000 Subject: [PATCH 2/4] implement improved understanding of zip results --- test/integration/api/backup.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/test/integration/api/backup.js b/test/integration/api/backup.js index a5ce26afe..d01ffab23 100644 --- a/test/integration/api/backup.js +++ b/test/integration/api/backup.js @@ -1,4 +1,4 @@ -const { omit } = require('ramda'); +const { without } = require('ramda'); const { testService } = require('../setup'); const { httpZipResponseToFiles } = require('../../util/zip'); @@ -12,18 +12,16 @@ describe('api: /backup', () => { it('should return a valid zip file if the user can backup @slow', testService((service) => service.login('alice', (asAlice) => httpZipResponseToFiles(asAlice.post('/v1/backup').expect(200)) - .then(res => { - const constantProps = ['filenames', 'keepalive', 'keys.json', 'toc.dat']; - res.should.have.properties(constantProps); + .then(({ filenames, ...files }) => { + const constantFiles = ['keepalive', 'keys.json', 'toc.dat']; + files.should.have.properties(constantFiles); - const datFiles = Object.keys(omit(constantProps, res)); + const datFiles = without(constantFiles, filenames); // Because /backup ALWAYS uses config('default.database'), this list // may be empty in some environments, including CI. datFiles.should.matchEvery(/\.dat\.gz$/); - res.should.only.have.keys(...constantProps, ...datFiles); - - const keysJson = JSON.parse(res['keys.json']); + const keysJson = JSON.parse(files['keys.json']); keysJson.should.only.have.keys('iv', 'local', 'privkey', 'pubkey', 'salt'); keysJson.iv.should.be.a.String(); keysJson.privkey.should.be.a.String(); From 8c648e1d1fb195d571e658232e15a831f24b4db1 Mon Sep 17 00:00:00 2001 From: alxndrsn Date: Tue, 10 Dec 2024 06:20:45 +0000 Subject: [PATCH 3/4] fix? --- test/integration/api/backup.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/integration/api/backup.js b/test/integration/api/backup.js index d01ffab23..700004713 100644 --- a/test/integration/api/backup.js +++ b/test/integration/api/backup.js @@ -5,6 +5,7 @@ const { httpZipResponseToFiles } = require('../../util/zip'); describe('api: /backup', () => { describe('POST', function () { this.timeout(10000); + it('should reject if the user cannot backup', testService((service) => service.login('chelsea', (asChelsea) => asChelsea.post('/v1/backup').expect(403)))); @@ -12,16 +13,16 @@ describe('api: /backup', () => { it('should return a valid zip file if the user can backup @slow', testService((service) => service.login('alice', (asAlice) => httpZipResponseToFiles(asAlice.post('/v1/backup').expect(200)) - .then(({ filenames, ...files }) => { + .then(({ filenames, files }) => { const constantFiles = ['keepalive', 'keys.json', 'toc.dat']; - files.should.have.properties(constantFiles); + [ ...files.keys() ].should.eqlInAnyOrder(constantFiles); const datFiles = without(constantFiles, filenames); // Because /backup ALWAYS uses config('default.database'), this list // may be empty in some environments, including CI. datFiles.should.matchEvery(/\.dat\.gz$/); - const keysJson = JSON.parse(files['keys.json']); + const keysJson = JSON.parse(files.get('keys.json')); keysJson.should.only.have.keys('iv', 'local', 'privkey', 'pubkey', 'salt'); keysJson.iv.should.be.a.String(); keysJson.privkey.should.be.a.String(); From 467d36cc1f294fbf1473b0d5ea1e00119f85d159 Mon Sep 17 00:00:00 2001 From: alxndrsn Date: Tue, 10 Dec 2024 06:23:12 +0000 Subject: [PATCH 4/4] containDeep --- test/integration/api/backup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/api/backup.js b/test/integration/api/backup.js index 700004713..b8899f873 100644 --- a/test/integration/api/backup.js +++ b/test/integration/api/backup.js @@ -15,7 +15,7 @@ describe('api: /backup', () => { httpZipResponseToFiles(asAlice.post('/v1/backup').expect(200)) .then(({ filenames, files }) => { const constantFiles = ['keepalive', 'keys.json', 'toc.dat']; - [ ...files.keys() ].should.eqlInAnyOrder(constantFiles); + [ ...files.keys() ].should.containDeep(constantFiles); const datFiles = without(constantFiles, filenames); // Because /backup ALWAYS uses config('default.database'), this list