import { describe, expect, it } from "vitest"; import type { PasskeyData, VaultEntry } from "../../shared/types"; import { filterAndSortVaultEntries } from "./vault-search"; function basePasskey(overrides: Partial = {}): PasskeyData { return { rpId: "example.com", rpName: "Example", credentialId: "cred-1", publicKeyCose: "cose", userHandle: "handle", userName: "passkey-user", userDisplayName: "Passkey User", algorithm: -7, signCount: 0, aaguid: "", backupEligible: false, backupState: false, createdAt: 1, ...overrides, }; } function entry(overrides: Partial = {}): VaultEntry { return { id: "entry-1", title: "Example", type: "login", createdAt: 1, modifiedAt: 1, ...overrides, }; } describe("vault-search", () => { it("sorts recent entries by last-used timestamps", () => { const entries = [ entry({ id: "created-only", title: "Created only", modifiedAt: 10 }), entry({ id: "login-used", title: "Login used", lastUsedAt: 300, modifiedAt: 20 }), entry({ id: "passkey-used", title: "Passkey used", passkey: basePasskey({ lastUsedAt: 200 }) }), ]; const sorted = filterAndSortVaultEntries(entries, { notesOnly: false, selectedTags: new Set(), query: "", searchScope: "both", sortOrder: "recent", }); expect(sorted.map((candidate) => candidate.id)).toEqual([ "login-used", "passkey-used", "created-only", ]); }); it("respects the email and username search scope toggle", () => { const sample = entry({ id: "identity", title: "Mailbox", username: "june-user", email: "billing@example.com", url: "https://mail.example.com", }); const emailsOnly = filterAndSortVaultEntries([sample], { notesOnly: false, selectedTags: new Set(), query: "june-user", searchScope: "emails", sortOrder: "recent", }); const usernamesOnly = filterAndSortVaultEntries([sample], { notesOnly: false, selectedTags: new Set(), query: "june-user", searchScope: "usernames", sortOrder: "recent", }); const both = filterAndSortVaultEntries([sample], { notesOnly: false, selectedTags: new Set(), query: "june-user", searchScope: "both", sortOrder: "recent", }); expect(emailsOnly).toHaveLength(0); expect(usernamesOnly).toHaveLength(1); expect(both).toHaveLength(1); }); it("uses recent usage as the tie-breaker for matching search results", () => { const entries = [ entry({ id: "older", title: "Alpha", username: "alpha-user", modifiedAt: 10, lastUsedAt: 100, }), entry({ id: "newer", title: "Alpha", username: "alpha-user", modifiedAt: 20, lastUsedAt: 200, }), entry({ id: "fallback", title: "Alpha", username: "alpha-user", modifiedAt: 30, }), ]; const sorted = filterAndSortVaultEntries(entries, { notesOnly: false, selectedTags: new Set(), query: "alpha", searchScope: "usernames", sortOrder: "recent", }); expect(sorted.map((candidate) => candidate.id)).toEqual([ "newer", "older", "fallback", ]); }); });