Files
api/plugin/builder/__tests__/cli/setup-plugin-environment.spec.ts
Eli Bosley d63e54bdbc feat: split plugin builds
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced containerized plugin deployment support with updated Docker
Compose configurations.
- Added continuous build watch modes for API, web, and UI components for
smoother development iterations.
  - Added a new job for API testing in the CI/CD workflow.
- Added a new shell script to determine the local host's IP address for
Docker configurations.
- Introduced a new entry point and HTTP server setup in the plugin's
Docker environment.
- Added new scripts for building and watching plugin changes in
real-time.
- Added a new script for building the project in watch mode for the API
and UI components.

- **Improvements**
- Streamlined the plugin installation process and refined release
workflows for a more reliable user experience.
- Enhanced overall CI/CD pipelines to ensure efficient, production-ready
deployments.
- Updated artifact upload paths and job definitions for clarity and
efficiency.
- Implemented new utility functions for better URL management and
changelog generation.
- Modified the `.dockerignore` file to ignore all contents within the
`node_modules` directory.
- Added new constants and functions for managing plugin paths and
configurations.
- Updated the build process in the Dockerfile to focus on release
operations.

- **Tests**
- Expanded automated testing to validate environment setups and build
stability, ensuring higher reliability during updates.
- Introduced new test suites for validating plugin environment setups
and configurations.
- Added tests for validating environment variables and handling of
manifest files.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Datelle <mdatelle@icloud.com>
Co-authored-by: mdatelle <mike@datelle.net>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Pujit Mehrotra <pujit@lime-technology.com>
2025-03-04 15:18:04 -05:00

173 lines
4.7 KiB
TypeScript

import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import {
validatePluginEnv,
setupPluginEnv,
} from "../../cli/setup-plugin-environment";
import { access, readFile } from "node:fs/promises";
// Mock fs/promises
vi.mock("node:fs/promises", () => ({
access: vi.fn(),
readFile: vi.fn(),
constants: {
F_OK: 0,
},
}));
beforeEach(() => {
vi.resetAllMocks();
vi.mocked(readFile).mockImplementation((path, encoding) => {
console.log("Mock readFile called with:", path, encoding);
// If called with encoding parameter (for release notes)
if (encoding === "utf8") {
if (path.toString().includes("valid-release-notes.txt")) {
return Promise.resolve("Release notes content");
}
}
// If called without encoding (for txz file)
if (path.toString().includes("test.txz")) {
return Promise.resolve(Buffer.from("test content"));
}
return Promise.reject(new Error(`File not found: ${path}`));
});
vi.mocked(access).mockResolvedValue(undefined);
});
describe("validatePluginEnv", () => {
afterEach(() => {
vi.clearAllMocks();
});
it("validates required fields", async () => {
const validEnv = {
baseUrl: "https://example.com",
txzPath: "./test.txz",
pluginVersion: "2024.05.05.1232",
};
const result = await validatePluginEnv(validEnv);
expect(result).toMatchObject(validEnv);
});
it("throws on invalid URL", async () => {
const invalidEnv = {
baseUrl: "not-a-url",
txzPath: "./test.txz",
pluginVersion: "2024.05.05.1232",
};
await expect(validatePluginEnv(invalidEnv)).rejects.toThrow();
});
it("handles tag option in non-CI mode", async () => {
const envWithTag = {
baseUrl: "https://example.com",
txzPath: "./test.txz",
pluginVersion: "2024.05.05.1232",
tag: "v1.0.0",
};
const result = await validatePluginEnv(envWithTag);
expect(result.releaseNotes).toBe("FAST_TEST_CHANGELOG");
expect(result.tag).toBe("v1.0.0");
});
it("reads release notes when release-notes-path is provided", async () => {
const envWithNotes = {
baseUrl: "https://example.com",
txzPath: "./test.txz",
pluginVersion: "2024.05.05.1232",
releaseNotesPath: "valid-release-notes.txt",
};
const result = await validatePluginEnv(envWithNotes);
expect(access).toHaveBeenCalledWith("valid-release-notes.txt", 0);
expect(readFile).toHaveBeenCalledWith("valid-release-notes.txt", "utf8");
expect(result.releaseNotes).toBe("Release notes content");
});
it("throws when release notes file is empty", async () => {
// Instead of overwriting the entire mock, just mock this specific case
vi.mocked(readFile).mockImplementationOnce((path, encoding) => {
if (path === "/path/to/notes.md" && encoding === "utf8") {
return Promise.resolve("");
}
return Promise.reject(new Error("Unexpected mock call"));
});
const envWithEmptyNotes = {
baseUrl: "https://example.com",
txzPath: "./test.txz",
pluginVersion: "2024.05.05.1232",
releaseNotesPath: "/path/to/notes.md",
};
await expect(validatePluginEnv(envWithEmptyNotes)).rejects.toThrow(
"Release notes file is empty: /path/to/notes.md"
);
});
});
describe("setupPluginEnv", () => {
it("sets up environment from CLI arguments", async () => {
const argv = [
"node",
"script.js",
"--plugin-version",
"2024.05.05.1232",
"--txz-path",
"./test.txz",
"--base-url",
"https://example.com",
];
const result = await setupPluginEnv(argv);
expect(result).toMatchObject({
pluginVersion: "2024.05.05.1232",
txzPath: "./test.txz",
baseUrl: "https://example.com",
});
});
it("throws when required options are missing", async () => {
const argv = ["node", "script.js"]; // Missing required options
await expect(setupPluginEnv(argv)).rejects.toThrow();
});
it("handles optional CLI arguments", async () => {
const argv = [
"node",
"script.js",
"--txz-path",
"./test.txz",
"--base-url",
"https://example.com",
"--tag",
"PR1203",
"--ci",
"--plugin-version",
"2024.05.05.1232",
];
try {
const result = await setupPluginEnv(argv);
expect(result).toMatchObject({
pluginVersion: "2024.05.05.1232",
txzPath: "./test.txz",
txzSha256:
"6ae8a75555209fd6c44157c0aed8016e763ff435a19cf186f76863140143ff72",
baseUrl: "https://example.com",
tag: "PR1203",
ci: true,
});
} catch (error) {
console.error("Error:", error);
throw error;
}
});
});