diff --git a/test/bin/jar.spec.ts b/test/bin/jar.spec.ts deleted file mode 100644 index 65cf57f3..00000000 --- a/test/bin/jar.spec.ts +++ /dev/null @@ -1,131 +0,0 @@ -import jar, { jarStream, type ZipEntryGenerator } from "keycloakify/bin/tools/jar"; -import { fromBuffer, Entry, ZipFile } from "yauzl"; -import { it, describe, assert, afterAll } from "vitest"; -import { Readable } from "stream"; -import { tmpdir } from "os"; -import { mkdtemp, cp, mkdir, rm, writeFile } from "fs/promises"; -import path from "path"; -import { createReadStream } from "fs"; -import walk from "keycloakify/bin/tools/walk"; - -type AsyncIterable = { - [Symbol.asyncIterator](): AsyncIterableIterator; -}; - -async function arrayFromAsync(asyncIterable: AsyncIterable) { - const chunks: T[] = []; - for await (const chunk of asyncIterable) chunks.push(chunk); - return chunks; -} - -async function readToBuffer(stream: NodeJS.ReadableStream) { - return Buffer.concat(await arrayFromAsync(stream as AsyncIterable)); -} - -function unzipBuffer(buffer: Buffer) { - return new Promise((resolve, reject) => - fromBuffer(buffer, { lazyEntries: true }, (err, zipFile) => { - if (err !== null) { - reject(err); - } else { - resolve(zipFile); - } - }) - ); -} - -function readEntry(zipFile: ZipFile, entry: Entry): Promise { - return new Promise((resolve, reject) => { - zipFile.openReadStream(entry, (err, stream) => { - if (err !== null) { - reject(err); - } else { - resolve(stream); - } - }); - }); -} - -function readAll(zipFile: ZipFile): Promise> { - return new Promise>((resolve, reject) => { - const entries1: Map = new Map(); - zipFile.on("entry", async (entry: Entry) => { - const stream = await readEntry(zipFile, entry); - const buffer = await readToBuffer(stream); - entries1.set(entry.fileName, buffer); - zipFile.readEntry(); - }); - zipFile.on("end", () => resolve(entries1)); - zipFile.on("error", e => reject(e)); - zipFile.readEntry(); - }); -} - -describe("jar", () => { - const coords = { artifactId: "someArtifactId", groupId: "someGroupId", version: "1.2.3" }; - - const tmpDirs: string[] = []; - - afterAll(async () => { - await Promise.all(tmpDirs.map(dir => rm(dir, { force: true, recursive: true }))); - }); - - it("creates jar artifacts without error", async () => { - async function* mockFiles(): ZipEntryGenerator { - yield { zipPath: "foo", buffer: Buffer.from("foo") }; - } - - const zipped = await jarStream({ ...coords, asyncPathGeneratorFn: mockFiles }); - const buffered = await readToBuffer(zipped.outputStream); - const unzipped = await unzipBuffer(buffered); - const entries = await readAll(unzipped); - - assert.equal(entries.size, 3); - assert.isOk(entries.has("foo")); - assert.isOk(entries.has("META-INF/MANIFEST.MF")); - assert.isOk(entries.has("META-INF/maven/someGroupId/someArtifactId/pom.properties")); - - assert.equal("foo", entries.get("foo")?.toString("utf-8")); - - const manifest = entries.get("META-INF/MANIFEST.MF")?.toString("utf-8"); - const pomProperties = entries.get("META-INF/maven/someGroupId/someArtifactId/pom.properties")?.toString("utf-8"); - - assert.isOk(manifest?.includes("Created-By: Keycloakify")); - assert.isOk(pomProperties?.includes("1.2.3")); - assert.isOk(pomProperties?.includes("someGroupId")); - assert.isOk(pomProperties?.includes("someArtifactId")); - }); - - it("creates a jar from _real_ files without error", async () => { - const tmp = await mkdtemp(path.join(tmpdir(), "kc-jar-test-")); - - tmpDirs.push(tmp); - - const rootPath = path.join(tmp, "root"); - const resourcesPath = path.join(tmp, "root", "src", "main", "resources"); - const targetPath = path.join(tmp, "jar.jar"); - - await mkdir(resourcesPath, { recursive: true }); - await writeFile(path.join(rootPath, "pom.xml"), "foo", "utf-8"); - - await cp(path.dirname(__dirname), resourcesPath, { recursive: true }); - - await jar({ ...coords, rootPath, targetPath }); - - const buffered = await readToBuffer(createReadStream(targetPath)); - const unzipped = await unzipBuffer(buffered); - const entries = await readAll(unzipped); - const zipPaths = Array.from(entries.keys()); - - assert.isOk(entries.has("META-INF/MANIFEST.MF")); - assert.isOk(entries.has("META-INF/maven/someGroupId/someArtifactId/pom.properties")); - assert.isOk(entries.has("META-INF/maven/someGroupId/someArtifactId/pom.xml")); - - for await (const fsPath of walk(resourcesPath)) { - if (!fsPath.endsWith(path.sep)) { - const rel = path.relative(resourcesPath, fsPath).replace(path.sep === "/" ? /\//g : /\\/g, "/"); - assert.isOk(zipPaths.includes(rel), `missing '${rel}' (${rel}, '${zipPaths.join("', '")}')`); - } - } - }); -}); diff --git a/test/bin/setupSampleReactProject.spec.ts b/test/bin/setupSampleReactProject.spec.ts index 1995b49e..98b6966f 100644 --- a/test/bin/setupSampleReactProject.spec.ts +++ b/test/bin/setupSampleReactProject.spec.ts @@ -24,7 +24,7 @@ vi.mock("keycloakify/bin/keycloakify/parsed-package-json", async () => ({ vi.mock("keycloakify/bin/promptKeycloakVersion", async () => ({ ...((await vi.importActual("keycloakify/bin/promptKeycloakVersion")) as Record), - promptKeycloakVersion: () => ({ keycloakVersion: "11.0.3" }) + promptKeycloakVersion: () => ({ "keycloakVersion": "11.0.3" }) })); const nativeCwd = process.cwd; @@ -52,19 +52,25 @@ describe("Sample Project", () => { await setupSampleReactProject(sampleReactProjectDirPath); await initializeEmailTheme(); - const projectDirPath = process.cwd(); + const reactAppRootDirPath = process.cwd(); const destDirPath = pathJoin( readBuildOptions({ "processArgv": ["--silent"], - projectDirPath + reactAppRootDirPath }).keycloakifyBuildDirPath, "src", "main", "resources", "theme" ); - await downloadBuiltinKeycloakTheme({ destDirPath, "keycloakVersion": "11.0.3", projectDirPath }); + await downloadBuiltinKeycloakTheme({ + destDirPath, + "keycloakVersion": "11.0.3", + "buildOptions": { + "cacheDirPath": pathJoin(reactAppRootDirPath, "node_modules", ".cache", "keycloakify") + } + }); }, { timeout: 90000 } ); @@ -80,19 +86,25 @@ describe("Sample Project", () => { await setupSampleReactProject(pathJoin(sampleReactProjectDirPath, "custom_input")); await initializeEmailTheme(); - const projectDirPath = process.cwd(); + const reactAppRootDirPath = process.cwd(); const destDirPath = pathJoin( readBuildOptions({ "processArgv": ["--silent"], - projectDirPath + reactAppRootDirPath }).keycloakifyBuildDirPath, "src", "main", "resources", "theme" ); - await downloadBuiltinKeycloakTheme({ destDirPath, "keycloakVersion": "11.0.3", projectDirPath }); + await downloadBuiltinKeycloakTheme({ + destDirPath, + "keycloakVersion": "11.0.3", + buildOptions: { + "cacheDirPath": pathJoin(reactAppRootDirPath, "node_modules", ".cache", "keycloakify") + } + }); }, { timeout: 90000 } ); diff --git a/test/bin/tools/trimIndet.spec.ts b/test/bin/tools/trimIndet.spec.ts deleted file mode 100644 index cad19a39..00000000 --- a/test/bin/tools/trimIndet.spec.ts +++ /dev/null @@ -1,65 +0,0 @@ -import trimIndent from "keycloakify/bin/tools/trimIndent"; -import { it, describe, assert } from "vitest"; - -describe("trimIndent", () => { - it("does not change a left-aligned string as expected", () => { - const txt = trimIndent`lorem -ipsum`; - assert.equal(txt, ["lorem", "ipsum"].join("\n")); - }); - - it("removes leading and trailing empty lines from a left-aligned string", () => { - const txt = trimIndent` -lorem -ipsum -`; - assert.equal(txt, ["lorem", "ipsum"].join("\n")); - }); - - it("removes indent from an aligned string", () => { - const txt = trimIndent` - lorem - ipsum - `; - assert.equal(txt, ["lorem", "ipsum"].join("\n")); - }); - - it("removes indent from unaligned string", () => { - const txt = trimIndent` - lorem - ipsum - `; - assert.equal(txt, ["lorem", " ipsum"].join("\n")); - }); - - it("removes only first and last empty line", () => { - const txt = trimIndent` - - lorem - ipsum - - `; - - assert.equal(txt, ["", "lorem", "ipsum", ""].join("\n")); - }); - - it("interpolates non-strings", () => { - const d = new Date(); - const txt = trimIndent` - lorem - ${d} - ipsum`; - - assert.equal(txt, ["lorem", String(d), "ipsum"].join("\n")); - }); - - it("inderpolates preserving new-lines in the interpolated bits", () => { - const a = ["ipsum", "dolor", "sit"].join("\n"); - const txt = trimIndent` - lorem - ${a} - amet - `; - assert.equal(txt, ["lorem", "ipsum", "dolor", "sit", "amet"].join("\n")); - }); -});