backup.test.ts

2.8 KB · raw

1import { describe, expect, it } from "vitest";23import {4  exportEntriesToPeachJson,5  importEntriesFromPeachJson,6  type PeachExportEnvelope,7} from "./backup";89describe("shared backup", () => {10  const sampleEntries = [11    {12      id: "login-1",13      type: "login" as const,14      title: "GitHub",15      username: "june",16      password: "secret123",17      url: "https://github.com",18      notes: "2fa enabled",19      createdAt: 1,20      modifiedAt: 1,21    },22  ];2324  it("importEntriesFromPeachJson decrypts entries with the correct password", async () => {25    const envelope = await exportEntriesToPeachJson(sampleEntries, "export-pass");2627    await expect(28      importEntriesFromPeachJson(JSON.stringify(envelope), "export-pass")29    ).resolves.toMatchObject([30      {31        type: "login",32        title: "GitHub",33        username: "june",34        password: "secret123",35        url: "https://github.com",36      },37    ]);38  });3940  it("importEntriesFromPeachJson rejects the wrong password", async () => {41    const envelope = await exportEntriesToPeachJson(sampleEntries, "export-pass");4243    await expect(44      importEntriesFromPeachJson(JSON.stringify(envelope), "wrong-pass")45    ).rejects.toThrow("INVALID_EXPORT_PASSWORD");46  });4748  it("importEntriesFromPeachJson rejects malformed JSON", async () => {49    await expect(importEntriesFromPeachJson("{not json", "export-pass")).rejects.toThrow(50      "INVALID_PEACH_EXPORT"51    );52  });5354  it("export includes trashed entries; import preserves deletedAt", async () => {55    const trashedAt = 1_700_000_010_000;56    const entries = [57      ...sampleEntries,58      {59        id: "login-2",60        type: "login" as const,61        title: "Old Service",62        username: "june",63        password: "oldpass",64        url: "https://old.example.com",65        createdAt: 1,66        modifiedAt: 1,67        deletedAt: trashedAt,68      },69    ];7071    const envelope = await exportEntriesToPeachJson(entries, "export-pass");72    const imported = await importEntriesFromPeachJson(JSON.stringify(envelope), "export-pass");7374    expect(imported).toHaveLength(2);7576    const active = imported.filter((e) => !e.deletedAt);77    const trashed = imported.filter((e) => !!e.deletedAt);7879    expect(active).toHaveLength(1);80    expect(trashed).toHaveLength(1);81    expect(trashed[0].title).toBe("Old Service");82    expect(trashed[0].deletedAt).toBe(trashedAt);83  });8485  it("importEntriesFromPeachJson rejects envelopes with missing required fields", async () => {86    const envelope: Partial<PeachExportEnvelope> = {87      version: 2,88      type: "peach-export",89      kdf: "PBKDF2-SHA256",90      salt: "00",91      nonce: "00",92      ciphertext: "00",93    };9495    await expect(96      importEntriesFromPeachJson(JSON.stringify(envelope), "export-pass")97    ).rejects.toThrow("INVALID_PEACH_EXPORT");98  });99});