// The unit tests must exercise the libsodium backend that actually ships
// (#182). Before this, they could not: node compiles WebAssembly happily,
// the extension CSP refused it, and so the browser silently ran the
// wasm2js translation while every test ran the WASM build.
//
// With 'wasm-unsafe-eval' in both manifests the two agree, and these tests
// hold that agreement in place from the node side. tests/manifest.test.js
// holds up the CSP end of it, and the end-to-end suite observes the real
// popup.

const { cryptoBackend } = require("../src/shared/vault");

// The module libsodium-wrappers-sumo itself requires and drives. Not a new
// dependency: it is inspected here, never used to perform crypto, because
// it is the only thing that can say which backend is loaded.
const SODIUM_CORE = "libsodium-sumo";

describe("libsodium backend", () => {
    test("this realm compiles WebAssembly, so the tests run the WASM build", async () => {
        await expect(cryptoBackend()).resolves.toBe("wasm");
    });

    test("libsodium did not swap in the wasm2js fallback", async () => {
        const core = require(SODIUM_CORE);
        await require("libsodium-wrappers-sumo").ready;
        // useBackupModule is the entry point to the fallback; taking it
        // replaces the module's exports with the translation's, and the
        // entry point goes with them. Still present after ready means the
        // WASM module is the one in place. The test below is what keeps
        // that inference honest.
        expect(typeof core.useBackupModule).toBe("function");
    });

    // Deliberately last, and deliberately destructive: it takes the
    // fallback, which replaces the loaded module for the rest of this
    // file. Jest gives each test file its own module registry, so nothing
    // outside sees it.
    //
    // Without this, the check above would be a claim about libsodium's
    // internals with nothing holding it to account: if a future version
    // kept useBackupModule on the fallback module too, the marker would
    // quietly become true in both backends and the test would pass while
    // measuring nothing. Forcing the fallback and watching the marker
    // disappear is what makes its presence mean something.
    test("the fallback marker distinguishes the two backends", async () => {
        const core = require(SODIUM_CORE);
        await require("libsodium-wrappers-sumo").ready;
        expect(typeof core.useBackupModule).toBe("function");
        await core.useBackupModule();
        expect(typeof core.useBackupModule).toBe("undefined");
    });
});
