105 lines
3.7 KiB
JavaScript
105 lines
3.7 KiB
JavaScript
const ADDRESS = "0x66133E8ea0f5D1d612D2502a968757D1048c214a";
|
|
|
|
function oneWallet() {
|
|
return [{ name: "Wallet 1", type: "hd", addresses: [ADDRESS] }];
|
|
}
|
|
|
|
// state.js resolves the storage API at require time, so the stub has to exist
|
|
// before the module is loaded, and the module registry has to be reset between
|
|
// cases because `state` is a module-level singleton.
|
|
function loadModuleWith(persisted) {
|
|
jest.resetModules();
|
|
const set = jest.fn(async () => {});
|
|
global.chrome = {
|
|
storage: {
|
|
local: {
|
|
get: jest.fn(async () =>
|
|
persisted ? { autistmask: persisted } : {},
|
|
),
|
|
set,
|
|
},
|
|
},
|
|
};
|
|
return { mod: require("../src/shared/state"), set };
|
|
}
|
|
|
|
afterEach(() => {
|
|
delete global.chrome;
|
|
});
|
|
|
|
describe("loadState hasWallet reconciliation", () => {
|
|
// A profile that deleted its last wallet on a build predating the write
|
|
// path fix keeps hasWallet: true forever. It must load as no wallet, which
|
|
// is what sends the popup to the welcome view.
|
|
test("stored hasWallet true with zero wallets loads as no wallet", async () => {
|
|
const { mod } = loadModuleWith({ hasWallet: true, wallets: [] });
|
|
await mod.loadState();
|
|
expect(mod.state.hasWallet).toBe(false);
|
|
});
|
|
|
|
test("stored hasWallet true with a missing wallets key loads as no wallet", async () => {
|
|
const { mod } = loadModuleWith({ hasWallet: true });
|
|
await mod.loadState();
|
|
expect(mod.state.wallets).toEqual([]);
|
|
expect(mod.state.hasWallet).toBe(false);
|
|
});
|
|
|
|
test("stored hasWallet false with one wallet loads as having a wallet", async () => {
|
|
const { mod } = loadModuleWith({
|
|
hasWallet: false,
|
|
wallets: oneWallet(),
|
|
});
|
|
await mod.loadState();
|
|
expect(mod.state.hasWallet).toBe(true);
|
|
});
|
|
|
|
test("absent hasWallet with wallets present loads as having a wallet", async () => {
|
|
const { mod } = loadModuleWith({ wallets: oneWallet() });
|
|
await mod.loadState();
|
|
expect(mod.state.hasWallet).toBe(true);
|
|
});
|
|
|
|
test("consistent stored states are preserved", async () => {
|
|
const withWallet = loadModuleWith({
|
|
hasWallet: true,
|
|
wallets: oneWallet(),
|
|
});
|
|
await withWallet.mod.loadState();
|
|
expect(withWallet.mod.state.hasWallet).toBe(true);
|
|
|
|
const without = loadModuleWith({ hasWallet: false, wallets: [] });
|
|
await without.mod.loadState();
|
|
expect(without.mod.state.hasWallet).toBe(false);
|
|
});
|
|
|
|
test("empty storage leaves the default no-wallet state", async () => {
|
|
const { mod } = loadModuleWith(null);
|
|
await mod.loadState();
|
|
expect(mod.state.hasWallet).toBe(false);
|
|
expect(mod.state.wallets).toEqual([]);
|
|
});
|
|
|
|
// The correction is derived on every load rather than written back, so a
|
|
// load never has a storage side effect.
|
|
test("loadState does not write to storage", async () => {
|
|
const { mod, set } = loadModuleWith({ hasWallet: true, wallets: [] });
|
|
await mod.loadState();
|
|
expect(set).not.toHaveBeenCalled();
|
|
});
|
|
|
|
// Deriving must not disturb the rest of the load.
|
|
test("other persisted fields still load", async () => {
|
|
const { mod } = loadModuleWith({
|
|
hasWallet: false,
|
|
wallets: oneWallet(),
|
|
networkId: "sepolia",
|
|
theme: "dark",
|
|
activeAddress: ADDRESS,
|
|
});
|
|
await mod.loadState();
|
|
expect(mod.state.networkId).toBe("sepolia");
|
|
expect(mod.state.theme).toBe("dark");
|
|
expect(mod.state.activeAddress).toBe(ADDRESS);
|
|
});
|
|
});
|