import { describe, expect, it, vi } from "vitest"; import { finalizeAccountMigration } from "../../lib/flows/migration-shared.ts"; describe("migration/finalizeAccountMigration", () => { it("activates the destination only after deactivating the source", async () => { const calls: string[] = []; const sourceClient = { deactivateAccount: vi.fn(async () => { calls.push("deactivate-source"); }), }; const destinationClient = { activateAccount: vi.fn(async () => { calls.push("activate-destination"); }), }; await finalizeAccountMigration(sourceClient, destinationClient); expect(calls).toEqual(["deactivate-source", "activate-destination"]); }); it("activates the destination when source deactivation fails", async () => { const sourceError = new Error("source unavailable"); const sourceClient = { deactivateAccount: vi.fn().mockRejectedValue(sourceError), }; const destinationClient = { activateAccount: vi.fn(), }; const onSourceDeactivated = vi.fn(); const onSourceDeactivationFailed = vi.fn(); await finalizeAccountMigration(sourceClient, destinationClient, { onSourceDeactivated, onSourceDeactivationFailed, sourceDeactivationRetryDelayMs: 0, }); expect(onSourceDeactivated).not.toHaveBeenCalled(); expect(onSourceDeactivationFailed).toHaveBeenCalledWith(sourceError); expect(sourceClient.deactivateAccount).toHaveBeenCalledTimes(3); expect(destinationClient.activateAccount).toHaveBeenCalledOnce(); }); it("retries source deactivation before activating the destination", async () => { const calls: string[] = []; const sourceClient = { deactivateAccount: vi .fn() .mockRejectedValueOnce(new Error("source unavailable")) .mockRejectedValueOnce(new Error("source unavailable")) .mockImplementation(async () => { calls.push("deactivate-source"); }), }; const destinationClient = { activateAccount: vi.fn(async () => { calls.push("activate-destination"); }), }; await finalizeAccountMigration(sourceClient, destinationClient, { sourceDeactivationRetryDelayMs: 0, }); expect(sourceClient.deactivateAccount).toHaveBeenCalledTimes(3); expect(calls).toEqual(["deactivate-source", "activate-destination"]); }); it("retries activation without deactivating the source again", async () => { const sourceClient = { deactivateAccount: vi.fn(), }; const destinationClient = { activateAccount: vi.fn(), }; await finalizeAccountMigration(sourceClient, destinationClient, { sourceAlreadyDeactivated: true, }); expect(sourceClient.deactivateAccount).not.toHaveBeenCalled(); expect(destinationClient.activateAccount).toHaveBeenCalledOnce(); }); it("records source deactivation before destination activation", async () => { const sourceClient = { deactivateAccount: vi.fn(), }; const destinationClient = { activateAccount: vi.fn().mockRejectedValue(new Error("not propagated")), }; const onSourceDeactivated = vi.fn(); await expect( finalizeAccountMigration(sourceClient, destinationClient, { onSourceDeactivated, }), ).rejects.toThrow("not propagated"); expect(onSourceDeactivated).toHaveBeenCalledOnce(); }); });