diff --git a/lib/__tests__/settings-shared-store.test.ts b/lib/__tests__/settings-shared-store.test.ts index 970f006cd..3716f3a60 100644 --- a/lib/__tests__/settings-shared-store.test.ts +++ b/lib/__tests__/settings-shared-store.test.ts @@ -1,5 +1,5 @@ // @vitest-environment node -import { mkdtempSync, rmSync } from 'node:fs'; +import { mkdtempSync, readdirSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import path from 'node:path'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; @@ -120,13 +120,20 @@ describe('settings with a shared store', () => { expect((await (await fetchSettings()).json()).settings).toBeNull(); }); - it('answers 503 to a save over a stored document that does not decrypt and leaves its bytes alone', async () => { + it('moves a stored document that does not decrypt aside in the store before a save, keeping its bytes', async () => { const garbage = Buffer.alloc(64, 7); - await store.collection('settings', SETTINGS_COLLECTION).put(settingsId(USER, SERVER), garbage); + const id = settingsId(USER, SERVER); + await store.collection('settings', SETTINGS_COLLECTION).put(id, garbage); - expect((await push({ theme: 'light' })).status).toBe(503); - expect((await fetchSettings()).status).toBe(503); - expect((await storedDoc())?.data.equals(garbage)).toBe(true); + expect((await (await fetchSettings()).json()).settings).toBeNull(); + expect((await push({ theme: 'light' })).status).toBe(200); + expect((await (await fetchSettings()).json()).settings).toEqual({ theme: 'light' }); + + // In the store, not on this replica's disk. + const aside = readdirSync(path.join(store.root, 'settings')).filter((f) => f.startsWith(`${id}.unreadable-`)); + expect(aside).toHaveLength(1); + const asideId = aside[0].slice(0, -'.enc'.length); + expect((await store.collection('settings', SETTINGS_COLLECTION).get(asideId))?.data.equals(garbage)).toBe(true); }); it('answers 503 and writes nothing while the store is down', async () => { diff --git a/lib/__tests__/stored-data-unreadable.test.ts b/lib/__tests__/stored-data-unreadable.test.ts index db9948f7a..d709f8366 100644 --- a/lib/__tests__/stored-data-unreadable.test.ts +++ b/lib/__tests__/stored-data-unreadable.test.ts @@ -1,14 +1,16 @@ // @vitest-environment node -import { mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; +import { mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; import { tmpdir } from 'node:os'; import path from 'node:path'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { NextRequest } from 'next/server'; // A settings file or plugin vault that exists but doesn't decrypt (written -// with another session secret, or cut short) used to read as "nothing -// stored". The next save then merged into nothing and overwrote the user's -// real data. Now the read throws, and the routes answer 503 and write nothing. +// with another session secret) used to read as "nothing stored", and the +// next save wrote over it: the user's real data was gone for good. Now the +// save first moves it aside (`.unreadable-