mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-11-09 07:23:14 +00:00
245 lines
8.2 KiB
JavaScript
245 lines
8.2 KiB
JavaScript
import { cp, mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
import { createRequire } from "node:module";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { afterEach, describe, expect, it } from "vitest";
|
|
import { prepareDistributionNotices } from "../scripts/prepare-distribution-notices.mjs";
|
|
|
|
const require = createRequire(import.meta.url);
|
|
const JSON5 = require("json5");
|
|
const storeConfiguration = require("../electron-builder.store.cjs");
|
|
const root = fileURLToPath(new URL("../", import.meta.url));
|
|
const directories = [];
|
|
|
|
async function put(directory, name, content) {
|
|
const file = path.join(directory, name);
|
|
await mkdir(path.dirname(file), { recursive: true });
|
|
await writeFile(file, content);
|
|
}
|
|
|
|
async function fixture() {
|
|
const directory = await mkdtemp(path.join(os.tmpdir(), "recordly-notices-"));
|
|
directories.push(directory);
|
|
for (const name of [
|
|
"LICENSE.md",
|
|
"THIRD_PARTY_NOTICES.md",
|
|
"build/legal",
|
|
"src/assets/cursors/community",
|
|
"src/assets/cursors/pixel-glove",
|
|
"src/assets/fonts/dm-sans",
|
|
"src/assets/fonts/tiktok-sans",
|
|
"src/assets/liquid-glass",
|
|
]) {
|
|
await mkdir(path.dirname(path.join(directory, name)), { recursive: true });
|
|
await cp(path.join(root, name), path.join(directory, name), { recursive: true });
|
|
}
|
|
await put(
|
|
directory,
|
|
"package.json",
|
|
JSON.stringify({
|
|
name: "fixture",
|
|
version: "2.0.0",
|
|
dependencies: { "demo-runtime": "1.0.0" },
|
|
devDependencies: {
|
|
"@scope/renderer": "1.0.0",
|
|
"@scope/styles": "1.0.0",
|
|
"test-only": "1.0.0",
|
|
},
|
|
}),
|
|
);
|
|
await put(
|
|
directory,
|
|
"node_modules/demo-runtime/package.json",
|
|
JSON.stringify({
|
|
name: "demo-runtime",
|
|
version: "1.0.0",
|
|
license: "MIT",
|
|
dependencies: { "nested-runtime": "1.0.0" },
|
|
}),
|
|
);
|
|
await put(
|
|
directory,
|
|
"node_modules/demo-runtime/LICENSE",
|
|
"Runtime attribution\nMIT license fixture\n",
|
|
);
|
|
await put(
|
|
directory,
|
|
"node_modules/demo-runtime/node_modules/nested-runtime/package.json",
|
|
JSON.stringify({ name: "nested-runtime", version: "1.0.0", license: "BSD-3-Clause" }),
|
|
);
|
|
await put(
|
|
directory,
|
|
"node_modules/demo-runtime/node_modules/nested-runtime/NOTICE",
|
|
"Nested runtime attribution\n",
|
|
);
|
|
await put(
|
|
directory,
|
|
"node_modules/@scope/renderer/package.json",
|
|
JSON.stringify({ name: "@scope/renderer", version: "1.0.0", license: "Apache-2.0" }),
|
|
);
|
|
await put(directory, "node_modules/@scope/renderer/LICENSE", "Renderer license fixture\n");
|
|
await put(
|
|
directory,
|
|
"node_modules/@scope/styles/package.json",
|
|
JSON.stringify({ name: "@scope/styles", version: "1.0.0", license: "MIT" }),
|
|
);
|
|
await put(
|
|
directory,
|
|
"build/legal/packages/@scope__styles@1.0.0/LICENSE",
|
|
"Styles license fixture\n",
|
|
);
|
|
await put(
|
|
directory,
|
|
"build/legal/packages/@scope__styles@1.0.0/PROVENANCE.json",
|
|
'{"licenseUrl":"https://example.invalid/pinned/LICENSE"}\n',
|
|
);
|
|
await put(
|
|
directory,
|
|
"src/entry.tsx",
|
|
'import { renderer } from "@scope/renderer/submodule";\n',
|
|
);
|
|
await put(directory, "src/style.css", '@import "@scope/styles";\n');
|
|
await put(directory, "src/ignored.test.ts", 'import "test-only";\n');
|
|
for (const extension of [".distribution.json", ".LICENSE", ".README"]) {
|
|
await put(directory, `node_modules/ffmpeg-static/ffmpeg${extension}`, "FFmpeg fixture\n");
|
|
await put(
|
|
directory,
|
|
`node_modules/ffmpeg-static/ffmpeg.exe${extension}`,
|
|
"FFmpeg fixture\n",
|
|
);
|
|
await put(
|
|
directory,
|
|
`node_modules/ffprobe-static/bin/win32/x64/ffprobe.exe${extension}`,
|
|
"FFprobe fixture\n",
|
|
);
|
|
}
|
|
await put(
|
|
directory,
|
|
"node_modules/ffmpeg-static/ffmpeg.sources/source.tar.xz",
|
|
"Source archive fixture\n",
|
|
);
|
|
return directory;
|
|
}
|
|
|
|
afterEach(async () => {
|
|
await Promise.all(
|
|
directories.splice(0).map((directory) => rm(directory, { recursive: true, force: true })),
|
|
);
|
|
});
|
|
|
|
describe("desktop distribution notices", () => {
|
|
it("includes editable cursor source, full licenses, font notices and native dependency notices", async () => {
|
|
const projectDir = await fixture();
|
|
const { outputDir, manifest } = await prepareDistributionNotices({
|
|
projectDir,
|
|
platform: "darwin",
|
|
arch: "arm64",
|
|
});
|
|
expect(outputDir).toBe(path.join(projectDir, ".tmp/distribution-notices/mac-arm64"));
|
|
for (const [source, target] of [
|
|
["LICENSE.md", "LICENSE.md"],
|
|
["THIRD_PARTY_NOTICES.md", "THIRD_PARTY_NOTICES.md"],
|
|
[
|
|
"src/assets/cursors/community/bee/arrow.svg",
|
|
"assets/cursors/community/bee/arrow.svg",
|
|
],
|
|
[
|
|
"src/assets/cursors/community/catppuccin-pink/AUTHORS",
|
|
"assets/cursors/community/catppuccin-pink/AUTHORS",
|
|
],
|
|
["src/assets/cursors/pixel-glove/COPYING", "assets/cursors/pixel-glove/COPYING"],
|
|
[
|
|
"src/assets/cursors/pixel-glove/LICENSE.GPL",
|
|
"assets/cursors/pixel-glove/LICENSE.GPL",
|
|
],
|
|
["src/assets/cursors/pixel-glove/arrow.svg", "assets/cursors/pixel-glove/arrow.svg"],
|
|
["src/assets/fonts/dm-sans/OFL.txt", "assets/fonts/dm-sans/OFL.txt"],
|
|
["src/assets/fonts/tiktok-sans/OFL.txt", "assets/fonts/tiktok-sans/OFL.txt"],
|
|
[
|
|
"build/legal/onnxruntime/ThirdPartyNotices.txt",
|
|
"native/onnxruntime/ThirdPartyNotices.txt",
|
|
],
|
|
[
|
|
"node_modules/ffmpeg-static/ffmpeg.sources/source.tar.xz",
|
|
"ffmpeg/sources/source.tar.xz",
|
|
],
|
|
])
|
|
expect(await readFile(path.join(outputDir, target))).toEqual(
|
|
await readFile(path.join(projectDir, source)),
|
|
);
|
|
expect(manifest.packages.map((pkg) => pkg.name)).toEqual([
|
|
"@scope/renderer",
|
|
"@scope/styles",
|
|
"demo-runtime",
|
|
"nested-runtime",
|
|
]);
|
|
const runtime = manifest.packages.find((pkg) => pkg.name === "demo-runtime");
|
|
expect(
|
|
await readFile(path.join(outputDir, runtime.noticeDirectory, "LICENSE"), "utf8"),
|
|
).toContain("Runtime attribution");
|
|
const styles = manifest.packages.find((pkg) => pkg.name === "@scope/styles");
|
|
expect(
|
|
await readFile(
|
|
path.join(outputDir, styles.noticeDirectory, "upstream/LICENSE"),
|
|
"utf8",
|
|
),
|
|
).toContain("Styles license fixture");
|
|
expect(styles.legalFiles).toContain("upstream/LICENSE");
|
|
expect(JSON.stringify(manifest)).not.toContain(projectDir);
|
|
expect(await readFile(path.join(outputDir, "SOURCE_CODE.txt"), "utf8")).toContain(
|
|
"not the complete source for this binary",
|
|
);
|
|
});
|
|
|
|
it("fails instead of producing a package with a missing cursor GPL notice", async () => {
|
|
const projectDir = await fixture();
|
|
await rm(path.join(projectDir, "src/assets/cursors/pixel-glove/LICENSE.GPL"));
|
|
await expect(
|
|
prepareDistributionNotices({ projectDir, platform: "darwin", arch: "arm64" }),
|
|
).rejects.toThrow(
|
|
"Missing required distribution notice: src/assets/cursors/pixel-glove/LICENSE.GPL",
|
|
);
|
|
});
|
|
|
|
it("includes the Windows FFprobe distribution provenance alongside the separately packaged executable", async () => {
|
|
const projectDir = await fixture();
|
|
const { outputDir } = await prepareDistributionNotices({
|
|
projectDir,
|
|
platform: "win32",
|
|
arch: "x64",
|
|
});
|
|
for (const extension of [".distribution.json", ".LICENSE", ".README"]) {
|
|
expect(
|
|
await readFile(path.join(outputDir, "ffprobe", `ffprobe${extension}`), "utf8"),
|
|
).toBe("FFprobe fixture\n");
|
|
}
|
|
});
|
|
|
|
it("fails when a declared runtime dependency is unavailable for notice collection", async () => {
|
|
const projectDir = await fixture();
|
|
await rm(path.join(projectDir, "node_modules/demo-runtime"), { recursive: true });
|
|
await expect(
|
|
prepareDistributionNotices({ projectDir, platform: "darwin", arch: "arm64" }),
|
|
).rejects.toThrow("demo-runtime is not installed");
|
|
});
|
|
|
|
it("runs notice preparation and adds an external license resource in desktop and Store configurations", async () => {
|
|
const base = JSON5.parse(await readFile(path.join(root, "electron-builder.json5"), "utf8"));
|
|
const store = storeConfiguration(undefined, {
|
|
RECORDLY_STORE_IDENTITY_NAME: "12345.TestRecordly",
|
|
RECORDLY_STORE_PUBLISHER: "CN=00000000-0000-0000-0000-000000000000",
|
|
RECORDLY_STORE_PUBLISHER_DISPLAY_NAME: "Test",
|
|
RECORDLY_STORE_VERSION: "2.0.1",
|
|
});
|
|
for (const config of [base, store]) {
|
|
expect(config.beforePack).toBe("./scripts/prepare-distribution-notices.mjs");
|
|
expect(config.extraResources).toContainEqual({
|
|
from: ".tmp/distribution-notices/${os}-${arch}",
|
|
to: "licenses",
|
|
filter: ["**/*"],
|
|
});
|
|
}
|
|
});
|
|
});
|