74 lines
2.7 KiB
TypeScript
74 lines
2.7 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
// Mock the runtime package so tests don't need a real remote.
|
|
vi.mock("@module-federation/enhanced/runtime", () => {
|
|
return {
|
|
init: vi.fn(),
|
|
loadRemote: vi.fn(),
|
|
registerRemotes: vi.fn(),
|
|
};
|
|
});
|
|
|
|
import { init, loadRemote, registerRemotes } from "@module-federation/enhanced/runtime";
|
|
|
|
describe("remote-loader", () => {
|
|
beforeEach(async () => {
|
|
const mod = await import("./remote-loader.js");
|
|
mod.__resetRemoteLoaderForTests();
|
|
vi.mocked(init).mockClear();
|
|
vi.mocked(loadRemote).mockClear();
|
|
vi.mocked(registerRemotes).mockClear();
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.resetModules();
|
|
});
|
|
|
|
it("registerRemote calls init once for the first remote, then registerRemotes for subsequent", async () => {
|
|
const { registerRemote } = await import("./remote-loader.js");
|
|
registerRemote({ name: "customer-ui", entry: "https://host.example/mf-manifest.json" });
|
|
expect(init).toHaveBeenCalledTimes(1);
|
|
expect(init).toHaveBeenCalledWith({
|
|
name: "aeroflot_flights_host",
|
|
remotes: [{ name: "customer-ui", entry: "https://host.example/mf-manifest.json" }],
|
|
});
|
|
|
|
registerRemote({ name: "customer-analytics", entry: "https://host.example/analytics/mf-manifest.json" });
|
|
expect(init).toHaveBeenCalledTimes(1); // still only once
|
|
expect(registerRemotes).toHaveBeenCalledTimes(1);
|
|
expect(registerRemotes).toHaveBeenCalledWith([
|
|
{ name: "customer-analytics", entry: "https://host.example/analytics/mf-manifest.json" },
|
|
]);
|
|
});
|
|
|
|
it("loadRemoteModule delegates to loadRemote with the concatenated key", async () => {
|
|
const fakeModule = { default: "hello" };
|
|
vi.mocked(loadRemote).mockResolvedValueOnce(fakeModule);
|
|
|
|
const { loadRemoteModule } = await import("./remote-loader.js");
|
|
const result = await loadRemoteModule<{ default: string }>({
|
|
name: "customer-ui",
|
|
module: "./Header",
|
|
});
|
|
|
|
expect(loadRemote).toHaveBeenCalledWith("customer-ui/Header");
|
|
expect(result).toBe(fakeModule);
|
|
});
|
|
|
|
it("loadRemoteModule rejects with a typed error if the module returns null/undefined", async () => {
|
|
vi.mocked(loadRemote).mockResolvedValueOnce(null);
|
|
const { loadRemoteModule } = await import("./remote-loader.js");
|
|
await expect(
|
|
loadRemoteModule({ name: "customer-ui", module: "./NonExistent" }),
|
|
).rejects.toThrow(/customer-ui\/NonExistent/);
|
|
});
|
|
|
|
it("loadRemoteModule propagates errors from loadRemote", async () => {
|
|
vi.mocked(loadRemote).mockRejectedValueOnce(new Error("boom"));
|
|
const { loadRemoteModule } = await import("./remote-loader.js");
|
|
await expect(
|
|
loadRemoteModule({ name: "customer-ui", module: "./Broken" }),
|
|
).rejects.toThrow("boom");
|
|
});
|
|
});
|