@embeddable.com/sdk-core
Version:
Core Embeddable SDK module responsible for web-components bundling and publishing.
140 lines (110 loc) • 3.55 kB
text/typescript
import { server } from "./../../../mocks/server";
import login, { resolveFiles, getToken } from "./login";
import { vi } from "vitest";
import { pathToFileURL } from "node:url";
import { existsSync } from "node:fs";
import { PathLike } from "node:fs";
import { mkdir, access, writeFile, readFile } from "fs/promises";
import { CREDENTIALS_DIR, CREDENTIALS_FILE } from "./credentials";
import { http, HttpResponse } from "msw";
import { AxiosError } from "axios";
vi.mock("./logger", () => ({
initLogger: vi.fn(),
logError: vi.fn(),
}));
vi.mock("fs/promises", () => ({
readFile: vi.fn(),
writeFile: vi.fn(),
access: vi.fn(),
mkdir: vi.fn(),
}));
const startMock = {
succeed: vi.fn(),
fail: vi.fn(),
};
vi.mock("ora", () => ({
default: () => ({
start: vi.fn().mockImplementation(() => startMock),
info: vi.fn(),
}),
}));
vi.mock("./rollbar.mjs", () => ({
default: vi.fn(),
}));
vi.mock("open", () => ({
default: vi.fn(),
}));
vi.mock("node:fs", () => ({
existsSync: vi.fn(),
}));
vi.mock("node:url", () => ({
pathToFileURL: vi.fn(),
}));
// Create a mock module factory
const mockConfigModule = {
default: {
authDomain: "test-domain.com",
},
};
// Mock both possible config paths
vi.mock(`${process.cwd()}/embeddable.config.js`, () => mockConfigModule);
vi.mock(`${process.cwd()}/embeddable.config.ts`, () => mockConfigModule);
describe("login", () => {
beforeEach(async () => {
vi.resetModules();
vi.mocked(readFile).mockImplementation(async () =>
Buffer.from(`{"access_token":"mocked-token"}`),
);
vi.mocked(access).mockImplementation(async () => {
throw new Error();
});
vi.mocked(mkdir).mockImplementation(async () => "mocked");
vi.mocked(writeFile).mockImplementation(async () => undefined);
// Mock that only the TS config exists
vi.mocked(existsSync).mockImplementation((path: PathLike) =>
path.toString().endsWith("embeddable.config.ts"),
);
// Mock URL creation
vi.mocked(pathToFileURL).mockImplementation(
(path) => new URL(`file://${path}`),
);
});
vi.mock("./reportErrorToRollbar", () => vi.fn());
vi.mock("./sleep", () => vi.fn());
it("should resolve files", async () => {
await resolveFiles();
expect(access).toHaveBeenCalledWith(CREDENTIALS_DIR);
expect(mkdir).toHaveBeenCalledWith(CREDENTIALS_DIR);
expect(writeFile).toHaveBeenCalledWith(CREDENTIALS_FILE, "");
});
it("should get token", async () => {
const token = await getToken();
expect(token).toBe("mocked-token");
});
it("should login by saving token in the credentials file", async () => {
await login();
expect(startMock.succeed).toHaveBeenCalledWith(
"You are successfully authenticated now!",
);
expect(writeFile).toHaveBeenCalledWith(
CREDENTIALS_FILE,
JSON.stringify({ access_token: "mocked-token " }),
);
});
it("should fail to login when the response returns 500 error", async () => {
vi.spyOn(console, "log").mockImplementation(() => undefined);
vi.spyOn(process, "exit").mockImplementation(() => undefined as never);
server.use(
http.post("**/oauth/device/code", () => {
return new HttpResponse(null, { status: 500 });
}),
);
await login();
expect(startMock.fail).toHaveBeenCalledWith(
"Authentication failed. Please try again.",
);
expect((console.log as any).mock.calls[0][0]).toMatchInlineSnapshot(
`[AxiosError: Request failed with status code 500]`,
);
});
});