From 1a57c186aa704ba062604b5f96e16df1fcba3c9f Mon Sep 17 00:00:00 2001 From: meriadec Date: Fri, 3 Aug 2018 15:21:16 +0200 Subject: [PATCH] Improve robustness of first migration --- src/migrations/migrations.js | 18 ++++++--- src/migrations/migrations.spec.js | 35 ++++++++++++++++++ .../userdata_v1.0.5_mock-03-missing-file.zip | Bin 0 -> 4039 bytes ...erdata_v1.0.5_mock-04-app-json-present.zip | Bin 0 -> 6066 bytes 4 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 src/migrations/mocks/userdata_v1.0.5_mock-03-missing-file.zip create mode 100644 src/migrations/mocks/userdata_v1.0.5_mock-04-app-json-present.zip diff --git a/src/migrations/migrations.js b/src/migrations/migrations.js index ed7fc04d..185798ea 100644 --- a/src/migrations/migrations.js +++ b/src/migrations/migrations.js @@ -18,7 +18,7 @@ const migrations: Migration[] = [ const dbPath = db.getDBPath() const legacyKeys = ['accounts', 'countervalues', 'settings', 'user'] const [accounts, countervalues, settings, user] = await Promise.all( - legacyKeys.map(key => getLegacyData(path.join(dbPath, `${key}.json`))), + legacyKeys.map(key => getFileData(dbPath, key)), ) const appData = { user, settings, accounts, countervalues } await db.setNamespace('app', appData) @@ -28,15 +28,22 @@ const migrations: Migration[] = [ const windowParams = await db.getKey('app', 'settings.window') await db.setKey('app', 'settings.window', undefined) await db.setNamespace('windowParams', windowParams) - await Promise.all(legacyKeys.map(key => fsUnlink(path.join(dbPath, `${key}.json`)))) + await Promise.all( + legacyKeys.map(async key => { + try { + await fsUnlink(path.join(dbPath, `${key}.json`)) + } catch (err) {} // eslint-disable-line + }), + ) }, }, ] -async function getLegacyData(filePath) { +async function getFileData(dbPath, fileName) { + const filePath = path.join(dbPath, `${fileName}.json`) let finalData - const fileContent = await fsReadfile(filePath, 'utf-8') try { + const fileContent = await fsReadfile(filePath, 'utf-8') const { data } = JSON.parse(fileContent) finalData = data } catch (err) { @@ -45,7 +52,8 @@ async function getLegacyData(filePath) { const buf = await fsReadfile(filePath) return buf.toString('base64') } - throw err + // will be stripped down by JSON.stringify + return undefined } return finalData } diff --git a/src/migrations/migrations.spec.js b/src/migrations/migrations.spec.js index 5898cab8..0791326c 100644 --- a/src/migrations/migrations.spec.js +++ b/src/migrations/migrations.spec.js @@ -50,6 +50,41 @@ describe('migration 1', () => { }, }) }) + + test('handle missing file without crash', async () => { + const dir = await extractMock('userdata_v1.0.5_mock-03-missing-file') + let files + files = await fsReaddir(dir) + expect(files).toEqual(['countervalues.json', 'migrations.json', 'settings.json', 'user.json']) + db.init(dir) + let err + try { + await runMigrations() + } catch (e) { + err = e + } + expect(err).toBeUndefined() + files = await fsReaddir(dir) + expect(files).toEqual(['app.json', 'migrations.json', 'windowParams.json']) + }) + + test('handle where app.json is already present', async () => { + const dir = await extractMock('userdata_v1.0.5_mock-04-app-json-present') + let files + files = await fsReaddir(dir) + expect(files).toEqual([ + 'accounts.json', + 'app.json', + 'countervalues.json', + 'migrations.json', + 'settings.json', + 'user.json', + ]) + db.init(dir) + await runMigrations() + files = await fsReaddir(dir) + expect(files).toEqual(['app.json', 'migrations.json', 'windowParams.json']) + }) }) describe('with encryption', () => { diff --git a/src/migrations/mocks/userdata_v1.0.5_mock-03-missing-file.zip b/src/migrations/mocks/userdata_v1.0.5_mock-03-missing-file.zip new file mode 100644 index 0000000000000000000000000000000000000000..b390d1b00d2368c8010bfa596796b4e5ec0ee3c6 GIT binary patch literal 4039 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 literal 0 HcmV?d00001 diff --git a/src/migrations/mocks/userdata_v1.0.5_mock-04-app-json-present.zip b/src/migrations/mocks/userdata_v1.0.5_mock-04-app-json-present.zip new file mode 100644 index 0000000000000000000000000000000000000000..eebdc20c4c971ac1368aba956d5825c1665086df GIT binary patch literal 6066 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 Kt-1RN0QfJ