refactor: Refactor tests to not use module mocks, so bun test can be used
Some checks failed
CodeQL Scan / Analyze (javascript-typescript) (push) Failing after 45s
Build Docker Images / lint (push) Successful in 27s
Build Docker Images / check (push) Successful in 1m7s
Build Docker Images / tests (push) Failing after 6s
Build Docker Images / build (server, Dockerfile, ${{ github.repository_owner }}/server) (push) Has been skipped
Build Docker Images / build (worker, Worker.Dockerfile, ${{ github.repository_owner }}/worker) (push) Has been skipped
Deploy Docs to GitHub Pages / build (push) Failing after 12s
Mirror to Codeberg / Mirror (push) Failing after 0s
Deploy Docs to GitHub Pages / Deploy (push) Has been skipped
Nix Build / check (push) Failing after 32m31s

This commit is contained in:
Jesse Wierzbinski 2025-03-23 04:12:28 +01:00
parent ec506241f0
commit 7112a66e4c
No known key found for this signature in database
10 changed files with 71 additions and 527 deletions

View file

@ -1,5 +1,6 @@
import { describe, expect, it, mock } from "bun:test";
import { describe, expect, it } from "bun:test";
import sharp from "sharp";
import { mockModule } from "~/tests/utils.ts";
import { calculateBlurhash } from "./blurhash.ts";
describe("BlurhashPreprocessor", () => {
@ -49,7 +50,7 @@ describe("BlurhashPreprocessor", () => {
type: "image/png",
});
mock.module("blurhash", () => ({
using __ = await mockModule("blurhash", () => ({
encode: (): void => {
throw new Error("Test error");
},

View file

@ -1,27 +1,8 @@
import { beforeEach, describe, expect, it, mock } from "bun:test";
import { describe, expect, it } from "bun:test";
import sharp from "sharp";
import type { config } from "~/config.ts";
import { convertImage } from "./image-conversion.ts";
describe("ImageConversionPreprocessor", () => {
let mockConfig: typeof config;
beforeEach(() => {
mockConfig = {
media: {
conversion: {
convert_images: true,
convert_to: "image/webp",
convert_vector: false,
},
},
} as unknown as typeof config;
mock.module("~/config.ts", () => ({
config: mockConfig,
}));
});
it("should convert a JPEG image to WebP", async () => {
const inputBuffer = await sharp({
create: {
@ -37,7 +18,7 @@ describe("ImageConversionPreprocessor", () => {
const inputFile = new File([inputBuffer], "test.jpg", {
type: "image/jpeg",
});
const result = await convertImage(inputFile);
const result = await convertImage(inputFile, "image/webp");
expect(result.type).toBe("image/webp");
expect(result.name).toBe("test.webp");
@ -53,20 +34,20 @@ describe("ImageConversionPreprocessor", () => {
const inputFile = new File([svgContent], "test.svg", {
type: "image/svg+xml",
});
const result = await convertImage(inputFile);
const result = await convertImage(inputFile, "image/webp");
expect(result).toBe(inputFile);
});
it("should convert SVG when convert_vector is true", async () => {
mockConfig.media.conversion.convert_vectors = true;
const svgContent =
'<svg xmlns="http://www.w3.org/2000/svg"><rect width="100" height="100" fill="red"/></svg>';
const inputFile = new File([svgContent], "test.svg", {
type: "image/svg+xml",
});
const result = await convertImage(inputFile);
const result = await convertImage(inputFile, "image/webp", {
convertVectors: true,
});
expect(result.type).toBe("image/webp");
expect(result.name).toBe("test.webp");
@ -76,14 +57,12 @@ describe("ImageConversionPreprocessor", () => {
const inputFile = new File(["test content"], "test.txt", {
type: "text/plain",
});
const result = await convertImage(inputFile);
const result = await convertImage(inputFile, "image/webp");
expect(result).toBe(inputFile);
});
it("should throw an error for unsupported output format", async () => {
mockConfig.media.conversion.convert_to = "image/bmp";
const inputBuffer = await sharp({
create: {
width: 100,
@ -99,7 +78,7 @@ describe("ImageConversionPreprocessor", () => {
type: "image/png",
});
await expect(convertImage(inputFile)).rejects.toThrow(
await expect(convertImage(inputFile, "image/bmp")).rejects.toThrow(
"Unsupported output format: image/bmp",
);
});
@ -120,7 +99,7 @@ describe("ImageConversionPreprocessor", () => {
const inputFile = new File([inputBuffer], "animated.gif", {
type: "image/gif",
});
const result = await convertImage(inputFile);
const result = await convertImage(inputFile, "image/webp");
expect(result.type).toBe("image/webp");
expect(result.name).toBe("animated.webp");
@ -147,7 +126,7 @@ describe("ImageConversionPreprocessor", () => {
"test image with spaces.png",
{ type: "image/png" },
);
const result = await convertImage(inputFile);
const result = await convertImage(inputFile, "image/webp");
expect(result.type).toBe("image/webp");
expect(result.name).toBe("test image with spaces.webp");

View file

@ -4,7 +4,6 @@
*/
import sharp from "sharp";
import { config } from "~/config.ts";
/**
* Supported input media formats.
@ -36,11 +35,11 @@ const supportedOutputFormats = [
* @param file - The file to check.
* @returns True if the file is convertible, false otherwise.
*/
const isConvertible = (file: File): boolean => {
if (
file.type === "image/svg+xml" &&
!config.media.conversion.convert_vectors
) {
const isConvertible = (
file: File,
options?: { convertVectors?: boolean },
): boolean => {
if (file.type === "image/svg+xml" && !options?.convertVectors) {
return false;
}
return supportedInputFormats.includes(file.type);
@ -69,14 +68,20 @@ const getReplacedFileName = (fileName: string, newExtension: string): string =>
* Converts an image file to the format specified in the configuration.
*
* @param file - The image file to convert.
* @param targetFormat - The target format to convert to.
* @returns The converted image file.
*/
export const convertImage = async (file: File): Promise<File> => {
if (!isConvertible(file)) {
export const convertImage = async (
file: File,
targetFormat: string,
options?: {
convertVectors?: boolean;
},
): Promise<File> => {
if (!isConvertible(file, options)) {
return file;
}
const targetFormat = config.media.conversion.convert_to;
if (!supportedOutputFormats.includes(targetFormat)) {
throw new Error(`Unsupported output format: ${targetFormat}`);
}