test: reorganize flat test files into purpose-based subdirectories (phase 6)

Group 245 flat integration tests and 25 loose unit tests into
discoverable subdirectories per spec section 6:

  integration/tools/{image,video,audio,document,data}/  (156 files)
  integration/platform/                                  (64 files)
  integration/generated/                                 (14 files)
  integration/security/                                  (10 files)

  unit/security/     (8 files, new subdir)
  unit/api/          (7 files moved in)
  unit/web/          (3 files moved in)
  unit/shared/       (6 files moved in)
  unit/image-engine/ (1 file moved in)

All moves via git mv (history preserved). Relative imports repaired
for both depth levels (platform/generated/security = +1, tools/ = +2):
static from-imports, dynamic import() calls, vi.mock() paths,
import.meta.dirname joins, and __dirname joins.

Vitest discovery unchanged (no test.include in config, recursive glob
matches subdirs, shard-by-hash unaffected). test-server.ts and
tool-route-drift.test.ts stay at integration root. fixtures/ untouched.

Parity gate: 13189 passing test names before = 13189 after (0 dropped).
This commit is contained in:
SnapOtter
2026-06-20 05:07:46 +08:00
parent 257f030c09
commit 1727a7a73e
269 changed files with 1553 additions and 619 deletions
@@ -17,10 +17,10 @@
import { TOOLS } from "@snapotter/shared";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { getRegisteredToolIds } from "../../apps/api/src/routes/tool-factory.js";
import { TOOL_DISPLAY_MODES } from "../../apps/web/src/lib/tool-display-modes.js";
import { toolRegistry } from "../../apps/web/src/lib/tool-registry.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { getRegisteredToolIds } from "../../../apps/api/src/routes/tool-factory.js";
import { TOOL_DISPLAY_MODES } from "../../../apps/web/src/lib/tool-display-modes.js";
import { toolRegistry } from "../../../apps/web/src/lib/tool-registry.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
/**
* Tools whose contract does not fit the single-buffer process fn (multi-file,
@@ -12,8 +12,13 @@ import { tmpdir } from "node:os";
import { join } from "node:path";
import sharp from "sharp";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
// All output formats accepted by the convert tool
const OUTPUT_FORMATS = [
@@ -20,8 +20,13 @@
import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtureDir, fixtures } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtureDir, fixtures } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
// ---------------------------------------------------------------------------
// Format sample definitions (matches format-matrix.test.ts)
@@ -28,8 +28,13 @@
import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
import { fixtureDir } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtureDir } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
vi.setConfig({ testTimeout: 60_000 });
@@ -20,8 +20,13 @@ import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import sharp from "sharp";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtureDir, fixtures } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtureDir, fixtures } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
// ---------------------------------------------------------------------------
// Format definitions
@@ -34,8 +34,13 @@
import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtureDir, fixtures } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtureDir, fixtures } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
// ---------------------------------------------------------------------------
// Format sample definitions (subset relevant to the expanded tools)
@@ -3,10 +3,18 @@ import { join } from "node:path";
import { TOOLS } from "@snapotter/shared";
import sharp from "sharp";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { getRegisteredToolIds, getToolConfig } from "../../apps/api/src/routes/tool-factory.js";
import { fixtureDir } from "../fixtures/index.js";
import { defaultSettingsFor, TOOL_SETTINGS_OVERRIDES } from "../helpers/tool-default-settings.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { getRegisteredToolIds, getToolConfig } from "../../../apps/api/src/routes/tool-factory.js";
import { fixtureDir } from "../../fixtures/index.js";
import {
defaultSettingsFor,
TOOL_SETTINGS_OVERRIDES,
} from "../../helpers/tool-default-settings.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
/**
* Registry-generated tool x format matrix.
@@ -2,9 +2,14 @@ import { existsSync, readdirSync, readFileSync } from "node:fs";
import { extname, join } from "node:path";
import { TOOL_BUNDLE_MAP, TOOLS } from "@snapotter/shared";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtureDir } from "../fixtures/index.js";
import { defaultSettingsFor } from "../helpers/tool-default-settings.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtureDir } from "../../fixtures/index.js";
import { defaultSettingsFor } from "../../helpers/tool-default-settings.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
/**
* Multi-modality tool x format matrix.
@@ -19,8 +19,13 @@
import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtureDir, fixtures } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtureDir, fixtures } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
// ---------------------------------------------------------------------------
// Format sample definitions
@@ -3,10 +3,10 @@ import fc from "fast-check";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import type { z } from "zod";
import { ZodFastCheck } from "zod-fast-check";
import { getToolConfig } from "../../apps/api/src/routes/tool-factory.js";
import { fixtures, readFixture } from "../fixtures/index.js";
import { collectRegexStringSchemas } from "../helpers/zod-pict.js";
import { buildTestApp, type TestApp } from "./test-server.js";
import { getToolConfig } from "../../../apps/api/src/routes/tool-factory.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import { collectRegexStringSchemas } from "../../helpers/zod-pict.js";
import { buildTestApp, type TestApp } from "../test-server.js";
/**
* Property-based settings fuzz: random VALID settings (derived from each
@@ -9,8 +9,13 @@
import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtureDir, fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtureDir, fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
function isAsyncFallback(res: { statusCode: number; body: string }): boolean {
if (res.statusCode !== 202) return false;
@@ -1,6 +1,11 @@
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
// ---------------------------------------------------------------------------
// Fixtures -- one canonical file per modality
@@ -1,11 +1,11 @@
import { TOOLS } from "@snapotter/shared";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { getToolConfig } from "../../apps/api/src/routes/tool-factory.js";
import { fixtures, readFixture } from "../fixtures/index.js";
import { pairwise } from "../helpers/pairwise.js";
import { defaultSettingsFor } from "../helpers/tool-default-settings.js";
import { compactCase, deriveAxes } from "../helpers/zod-pict.js";
import { buildTestApp, type TestApp } from "./test-server.js";
import { getToolConfig } from "../../../apps/api/src/routes/tool-factory.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import { pairwise } from "../../helpers/pairwise.js";
import { defaultSettingsFor } from "../../helpers/tool-default-settings.js";
import { compactCase, deriveAxes } from "../../helpers/zod-pict.js";
import { buildTestApp, type TestApp } from "../test-server.js";
/**
* Pairwise settings matrix: a covering array over each tool's settings schema
@@ -7,7 +7,7 @@
*/
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let app: TestApp["app"];
@@ -1,5 +1,5 @@
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let token: string;
@@ -1,9 +1,9 @@
import { randomUUID } from "node:crypto";
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { ensureAnonymousUser, hashPassword } from "../../apps/api/src/plugins/auth.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { ensureAnonymousUser, hashPassword } from "../../../apps/api/src/plugins/auth.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let app: TestApp["app"];
@@ -4,8 +4,8 @@
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -1,7 +1,7 @@
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -8,8 +8,13 @@
*/
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
// ---------------------------------------------------------------------------
// Fixtures
@@ -1,7 +1,7 @@
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -1,5 +1,5 @@
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -1,7 +1,7 @@
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -6,9 +6,14 @@
* is disabled (the default).
*/
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
const PNG = readFixture(fixtures.image.edge.px1);
@@ -5,8 +5,8 @@
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -12,10 +12,15 @@ import { join } from "node:path";
import { ffmpegAvailable } from "@snapotter/media-engine";
import AdmZip from "adm-zip";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { sharedRedis } from "../../apps/api/src/jobs/connection.js";
import { bullPrefix } from "../../apps/api/src/jobs/types.js";
import { fixtureDir, fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { sharedRedis } from "../../../apps/api/src/jobs/connection.js";
import { bullPrefix } from "../../../apps/api/src/jobs/types.js";
import { fixtureDir, fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
const PNG = readFixture(fixtures.image.base.png200);
const JPG = readFixture(fixtures.image.base.jpg100);
@@ -1,8 +1,8 @@
import { eq } from "drizzle-orm";
import { afterEach, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { runMigrations } from "../../apps/api/src/db/migrate.js";
import { getMaxAgeMs, shouldRunStartupCleanup } from "../../apps/api/src/lib/cleanup.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { runMigrations } from "../../../apps/api/src/db/migrate.js";
import { getMaxAgeMs, shouldRunStartupCleanup } from "../../../apps/api/src/lib/cleanup.js";
beforeAll(async () => {
await runMigrations();
@@ -6,8 +6,13 @@
*/
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
// ---------------------------------------------------------------------------
// Fixtures
@@ -1,7 +1,7 @@
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -71,9 +71,9 @@ describe("config export with enterprise license", () => {
beforeAll(async () => {
vi.resetModules();
const { mockEnterpriseFeatures } = await import("../helpers/enterprise-mock.js");
const { mockEnterpriseFeatures } = await import("../../helpers/enterprise-mock.js");
mockEnterpriseFeatures(["config_export_import"]);
const { buildTestApp, loginAsAdmin } = await import("./test-server.js");
const { buildTestApp, loginAsAdmin } = await import("../test-server.js");
licensedApp = await buildTestApp();
licensedToken = await loginAsAdmin(licensedApp.app);
}, 30_000);
@@ -154,9 +154,9 @@ describe("config import with enterprise license", () => {
beforeAll(async () => {
vi.resetModules();
const { mockEnterpriseFeatures } = await import("../helpers/enterprise-mock.js");
const { mockEnterpriseFeatures } = await import("../../helpers/enterprise-mock.js");
mockEnterpriseFeatures(["config_export_import"]);
const { buildTestApp, loginAsAdmin } = await import("./test-server.js");
const { buildTestApp, loginAsAdmin } = await import("../test-server.js");
licensedApp = await buildTestApp();
licensedToken = await loginAsAdmin(licensedApp.app);
}, 30_000);
@@ -294,9 +294,9 @@ describe("config round-trip", () => {
beforeAll(async () => {
vi.resetModules();
const { mockEnterpriseFeatures } = await import("../helpers/enterprise-mock.js");
const { mockEnterpriseFeatures } = await import("../../helpers/enterprise-mock.js");
mockEnterpriseFeatures(["config_export_import"]);
const { buildTestApp, loginAsAdmin } = await import("./test-server.js");
const { buildTestApp, loginAsAdmin } = await import("../test-server.js");
licensedApp = await buildTestApp();
licensedToken = await loginAsAdmin(licensedApp.app);
}, 30_000);
@@ -16,8 +16,13 @@
import { spawnSync } from "node:child_process";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
// ── Binary gates ──────────────────────────────────────────────────────
function hasBinary(name: string): boolean {
@@ -1,7 +1,7 @@
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -1,7 +1,7 @@
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -20,7 +20,7 @@ import {
qpdfSplitRanges,
} from "@snapotter/doc-engine";
import { describe, expect, it } from "vitest";
import { fixtures } from "../fixtures/index.js";
import { fixtures } from "../../fixtures/index.js";
const PDF = fixtures.document.pdf3;
@@ -10,7 +10,7 @@ import {
pdfcpuTextStamp,
} from "@snapotter/doc-engine";
import { describe, expect, it } from "vitest";
import { fixtures } from "../fixtures/index.js";
import { fixtures } from "../../fixtures/index.js";
const PDF = fixtures.document.pdf3;
@@ -10,7 +10,7 @@ import {
sofficeAvailable,
} from "@snapotter/doc-engine";
import { describe, expect, it } from "vitest";
import { fixtures } from "../fixtures/index.js";
import { fixtures } from "../../fixtures/index.js";
const PDF = fixtures.document.pdf3;
const DOCX = fixtures.document.tiny("docx");
@@ -10,8 +10,8 @@ import {
pdfTextPy,
} from "@snapotter/doc-engine";
import { afterAll, describe, expect, it } from "vitest";
import { fixtures } from "../fixtures/index.js";
import { hasFitz, hasPikepdf, hasPython } from "../helpers/python-gate.js";
import { fixtures } from "../../fixtures/index.js";
import { hasFitz, hasPikepdf, hasPython } from "../../helpers/python-gate.js";
// Ensure the bridge uses a reachable Python; set PYTHON_VENV_PATH before
// any import triggers a dispatcher spawn.
@@ -1,5 +1,5 @@
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { buildTestApp, type TestApp } from "./test-server";
import { buildTestApp, type TestApp } from "../test-server";
describe("API docs", () => {
let testApp: TestApp;
@@ -1,6 +1,6 @@
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { deletePrefix, putObject } from "../../apps/api/src/lib/object-storage.js";
import { buildTestApp, type TestApp } from "./test-server.js";
import { deletePrefix, putObject } from "../../../apps/api/src/lib/object-storage.js";
import { buildTestApp, type TestApp } from "../test-server.js";
describe("download endpoint (object storage + Range)", () => {
let testApp: TestApp;
@@ -6,8 +6,13 @@
*/
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
// ---------------------------------------------------------------------------
// Fixtures
@@ -1,7 +1,7 @@
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -8,16 +8,16 @@
import { TOOLS } from "@snapotter/shared";
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { createToolRoute } from "../../apps/api/src/routes/tool-factory.js";
import { fixtures, readFixture } from "../fixtures/index.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { createToolRoute } from "../../../apps/api/src/routes/tool-factory.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
preReadyHooks,
type TestApp,
} from "./test-server.js";
} from "../test-server.js";
const PNG = readFixture(fixtures.image.edge.px1);
const PNG_A = readFixture(fixtures.image.edge.px1);
@@ -47,10 +47,10 @@ const {
invalidateCache,
ImportLockError,
ImportValidationError,
} = await import("../../apps/api/src/lib/feature-status.js");
} = await import("../../../apps/api/src/lib/feature-status.js");
// Test helpers from test-server
const { createMultipartPayload, loginAsAdmin } = await import("./test-server.js");
const { createMultipartPayload, loginAsAdmin } = await import("../test-server.js");
// Use face-detection as smallest bundle from the manifest
const testBundleId = "face-detection";
@@ -347,7 +347,7 @@ describe("POST /api/v1/admin/features/import", () => {
await app.register(cookie, { secret: "test-cookie-secret", hook: "onRequest" });
const { authMiddleware, authRoutes, ensureBuiltinRoles, ensureDefaultAdmin } = await import(
"../../apps/api/src/plugins/auth.js"
"../../../apps/api/src/plugins/auth.js"
);
await authMiddleware(app);
await authRoutes(app);
@@ -355,14 +355,14 @@ describe("POST /api/v1/admin/features/import", () => {
await ensureDefaultAdmin();
// Clear mustChangePassword for admin
const { db, schema } = await import("../../apps/api/src/db/index.js");
const { db, schema } = await import("../../../apps/api/src/db/index.js");
const { eq } = await import("drizzle-orm");
await db
.update(schema.users)
.set({ mustChangePassword: false })
.where(eq(schema.users.username, "admin"));
const { registerFeatureRoutes } = await import("../../apps/api/src/routes/features.js");
const { registerFeatureRoutes } = await import("../../../apps/api/src/routes/features.js");
await registerFeatureRoutes(app);
token = await loginAsAdmin(app);
@@ -8,8 +8,8 @@
*/
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
const JPG = readFixture(fixtures.image.base.jpg100);
const TIFF = readFixture(fixtures.image.formats("tiff"));
@@ -1,7 +1,7 @@
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -1,7 +1,7 @@
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -64,9 +64,9 @@ describe("IP allowlist with enterprise license", () => {
beforeAll(async () => {
vi.resetModules();
const { mockEnterpriseFeatures } = await import("../helpers/enterprise-mock.js");
const { mockEnterpriseFeatures } = await import("../../helpers/enterprise-mock.js");
mockEnterpriseFeatures(["ip_allowlist"]);
const { buildTestApp, loginAsAdmin } = await import("./test-server.js");
const { buildTestApp, loginAsAdmin } = await import("../test-server.js");
enterpriseApp = await buildTestApp();
entAdminToken = await loginAsAdmin(enterpriseApp.app);
@@ -7,17 +7,17 @@
import { randomUUID } from "node:crypto";
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { requestCancel } from "../../apps/api/src/jobs/cancel.js";
import { sharedRedis } from "../../apps/api/src/jobs/connection.js";
import { enqueueToolJob, waitForJob } from "../../apps/api/src/jobs/enqueue.js";
import { bullPrefix, type ToolJobData } from "../../apps/api/src/jobs/types.js";
import { putObject } from "../../apps/api/src/lib/object-storage.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { requestCancel } from "../../../apps/api/src/jobs/cancel.js";
import { sharedRedis } from "../../../apps/api/src/jobs/connection.js";
import { enqueueToolJob, waitForJob } from "../../../apps/api/src/jobs/enqueue.js";
import { bullPrefix, type ToolJobData } from "../../../apps/api/src/jobs/types.js";
import { putObject } from "../../../apps/api/src/lib/object-storage.js";
import {
registerToolProcessFn,
type ToolProcessCtx,
} from "../../apps/api/src/routes/tool-factory.js";
import { buildTestApp, type TestApp } from "./test-server.js";
} from "../../../apps/api/src/routes/tool-factory.js";
import { buildTestApp, type TestApp } from "../test-server.js";
// Register test-only tools for the spine tests
registerToolProcessFn({
@@ -1,6 +1,6 @@
import { sql } from "drizzle-orm";
import { describe, expect, it } from "vitest";
import { db } from "../../apps/api/src/db/index.js";
import { db } from "../../../apps/api/src/db/index.js";
describe("jobs table (phase 2 spine)", () => {
it("has the spine columns and canceled status", async () => {
@@ -1,7 +1,7 @@
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -3,7 +3,7 @@ import { tmpdir } from "node:os";
import { join } from "node:path";
import { ffmpegAvailable, probeMedia, runFfmpeg } from "@snapotter/media-engine";
import { describe, expect, it } from "vitest";
import { fixtures } from "../fixtures/index.js";
import { fixtures } from "../../fixtures/index.js";
const FIXTURE = fixtures.video.tiny("mp4");
@@ -3,13 +3,13 @@ import * as OTPAuth from "otpauth";
import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from "vitest";
vi.resetModules();
const { mockEnterpriseFeatures } = await import("../helpers/enterprise-mock.js");
const { mockEnterpriseFeatures } = await import("../../helpers/enterprise-mock.js");
mockEnterpriseFeatures(["mfa"]);
const { buildTestApp, loginAsAdmin } = await import("./test-server.js");
const { db, schema } = await import("../../apps/api/src/db/index.js");
const { buildTestApp, loginAsAdmin } = await import("../test-server.js");
const { db, schema } = await import("../../../apps/api/src/db/index.js");
import type { TestApp } from "./test-server.js";
import type { TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -4,8 +4,8 @@ import { join } from "node:path";
import Database from "better-sqlite3";
import { sql } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db } from "../../apps/api/src/db/index.js";
import { migrateFromSqlite } from "../../apps/api/src/db/migrate-from-sqlite.js";
import { db } from "../../../apps/api/src/db/index.js";
import { migrateFromSqlite } from "../../../apps/api/src/db/migrate-from-sqlite.js";
function buildFixtureSqlite(path: string): void {
const s = new Database(path);
@@ -5,10 +5,10 @@ import { join } from "node:path";
import { qpdfAvailable } from "@snapotter/doc-engine";
import { ffmpegAvailable } from "@snapotter/media-engine";
import { afterAll, describe, expect, it } from "vitest";
import { InputValidationError } from "../../apps/api/src/modality/contract.js";
import { DocumentInputHandler } from "../../apps/api/src/modality/document-input.js";
import { MediaInputHandler } from "../../apps/api/src/modality/media-input.js";
import { fixtures, readFixture } from "../fixtures/index.js";
import { InputValidationError } from "../../../apps/api/src/modality/contract.js";
import { DocumentInputHandler } from "../../../apps/api/src/modality/document-input.js";
import { MediaInputHandler } from "../../../apps/api/src/modality/media-input.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
const scratchDir = mkdtempSync(join(tmpdir(), "modality-input-"));
afterAll(() => rmSync(scratchDir, { recursive: true, force: true }));
@@ -41,7 +41,7 @@ describe.skipIf(!ffmpegAvailable())("MediaInputHandler (requires ffmpeg)", () =>
});
it("enforces the duration cap", async () => {
const { env } = await import("../../apps/api/src/config.js");
const { env } = await import("../../../apps/api/src/config.js");
const original = env.MAX_AUDIO_DURATION_S;
(env as Record<string, unknown>).MAX_AUDIO_DURATION_S = 0.5;
try {
@@ -66,7 +66,7 @@ describe("DocumentInputHandler", () => {
const buf = readFixture(fixtures.document.pdf3);
const out = await new DocumentInputHandler().prepare(buf, "test.pdf", { scratchDir });
expect(out.buffer).toBe(buf);
const { env } = await import("../../apps/api/src/config.js");
const { env } = await import("../../../apps/api/src/config.js");
const original = env.MAX_PDF_PAGES;
(env as Record<string, unknown>).MAX_PDF_PAGES = 2;
try {
@@ -3,8 +3,8 @@ import { tmpdir } from "node:os";
import { join } from "node:path";
import { ffmpegAvailable } from "@snapotter/media-engine";
import { describe, expect, it } from "vitest";
import { MediaInputHandler } from "../../apps/api/src/modality/media-input.js";
import { fixtureRoot } from "../fixtures/index.js";
import { MediaInputHandler } from "../../../apps/api/src/modality/media-input.js";
import { fixtureRoot } from "../../fixtures/index.js";
const FIX = fixtureRoot;
const MP4 = readFileSync(join(FIX, "media", "tiny.mp4"));
@@ -4,7 +4,7 @@
* - GET/POST /api/v1/admin/log-level (runtime log level)
*/
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let app: TestApp["app"];
@@ -13,9 +13,9 @@ import { randomUUID } from "node:crypto";
import { createServer, type Server } from "node:http";
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { env } from "../../apps/api/src/config.js";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { env } from "../../../apps/api/src/config.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
// ── Helpers ──────────────────────────────────────────────────────────
@@ -440,7 +440,7 @@ describe("OIDC login redirect", () => {
(env as any).OIDC_CLIENT_SECRET = "test-client-secret";
// Clear the cached OIDC config so discovery hits our mock
const _oidcModule = await import("../../apps/api/src/plugins/oidc.js");
const _oidcModule = await import("../../../apps/api/src/plugins/oidc.js");
// The module caches config in a module-level variable; rebuild app to get fresh routes
oidcApp = await buildTestApp();
}, 30_000);
@@ -9,8 +9,13 @@ import { readFileSync } from "node:fs";
import { join } from "node:path";
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -30,7 +35,9 @@ let userAFileId: string;
let userAPipelineId: string;
// Load test fixture
const fixtureBuffer = readFileSync(join(import.meta.dirname, "..", "fixtures", "test-1x1.png"));
const fixtureBuffer = readFileSync(
join(import.meta.dirname, "..", "..", "fixtures", "test-1x1.png"),
);
/** Register a user, clear mustChangePassword, log in, return token. */
async function createAndLogin(
@@ -2,8 +2,13 @@ import { readFileSync } from "node:fs";
import { join } from "node:path";
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -249,7 +254,7 @@ describe("permission enforcement on routes", () => {
});
describe("tool and pipeline permission enforcement", () => {
const fixturePath = join(import.meta.dirname, "..", "fixtures", "test-200x150.png");
const fixturePath = join(import.meta.dirname, "..", "..", "fixtures", "test-200x150.png");
const fixtureBuffer = readFileSync(fixturePath);
it("unauthenticated user cannot use tools", async () => {
@@ -443,7 +448,9 @@ describe("file ownership scoping", () => {
it("user A cannot access user B's file by ID", async () => {
// Upload as user A
const testImage = readFileSync(join(import.meta.dirname, "..", "fixtures", "test-200x150.png"));
const testImage = readFileSync(
join(import.meta.dirname, "..", "..", "fixtures", "test-200x150.png"),
);
const { body: uploadBody, contentType } = createMultipartPayload([
{ name: "file", filename: "test.png", contentType: "image/png", content: testImage },
]);
@@ -7,8 +7,13 @@
import { ffmpegAvailable } from "@snapotter/media-engine";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
// ---------------------------------------------------------------------------
// Fixtures
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { resolveToolPool, shouldSkipSyncWindow } from "../../apps/api/src/lib/pool.js";
import { resolveToolPool, shouldSkipSyncWindow } from "../../../apps/api/src/lib/pool.js";
describe("pool routing", () => {
it("image tools stay on the image pool", () => {
@@ -2,8 +2,8 @@ import { readFile } from "node:fs/promises";
import { resolveGs } from "@snapotter/doc-engine";
import { ffmpegAvailable } from "@snapotter/media-engine";
import { describe, expect, it } from "vitest";
import { pdfFirstPagePreview, videoPosterPreview } from "../../apps/api/src/modality/preview.js";
import { fixtures, readFixture } from "../fixtures/index.js";
import { pdfFirstPagePreview, videoPosterPreview } from "../../../apps/api/src/modality/preview.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
describe.skipIf(!ffmpegAvailable())("video poster preview (requires ffmpeg)", () => {
it("renders a webp poster", async () => {
@@ -11,12 +11,12 @@ import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { enqueueToolJob, waitForJob } from "../../apps/api/src/jobs/enqueue.js";
import type { ToolJobData } from "../../apps/api/src/jobs/types.js";
import { getObjectBuffer, putObject } from "../../apps/api/src/lib/object-storage.js";
import { registerToolProcessFn } from "../../apps/api/src/routes/tool-factory.js";
import { buildTestApp, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { enqueueToolJob, waitForJob } from "../../../apps/api/src/jobs/enqueue.js";
import type { ToolJobData } from "../../../apps/api/src/jobs/types.js";
import { getObjectBuffer, putObject } from "../../../apps/api/src/lib/object-storage.js";
import { registerToolProcessFn } from "../../../apps/api/src/routes/tool-factory.js";
import { buildTestApp, type TestApp } from "../test-server.js";
// Register a native-v2 test tool that concatenates two inputs via scratchPath
registerToolProcessFn({
@@ -14,9 +14,9 @@
import { randomUUID } from "node:crypto";
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { updateSingleFileProgress } from "../../apps/api/src/routes/progress.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { updateSingleFileProgress } from "../../../apps/api/src/routes/progress.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let app: TestApp["app"];
@@ -95,7 +95,7 @@ describe("Redis progress transport", () => {
const jobId = `tp-batch-${randomUUID()}`;
// Use the updateJobProgress export (imported indirectly via the module)
const { updateJobProgress } = await import("../../apps/api/src/routes/progress.js");
const { updateJobProgress } = await import("../../../apps/api/src/routes/progress.js");
updateJobProgress({
jobId,
status: "completed",
@@ -17,10 +17,18 @@
import { randomUUID } from "node:crypto";
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { updateJobProgress, updateSingleFileProgress } from "../../apps/api/src/routes/progress.js";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import {
updateJobProgress,
updateSingleFileProgress,
} from "../../../apps/api/src/routes/progress.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
const PNG = readFixture(fixtures.image.base.png200);
const JPG = readFixture(fixtures.image.base.jpg100);
@@ -7,8 +7,8 @@
*/
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -1,7 +1,7 @@
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -19,8 +19,8 @@ import {
} from "@aws-sdk/client-s3";
import { loadS3Storage, type S3StorageModule } from "@snapotter/enterprise";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { env } from "../../apps/api/src/config.js";
import { fixtures, readFixture } from "../fixtures/index.js";
import { env } from "../../../apps/api/src/config.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
const PNG = readFixture(fixtures.image.base.png200);
@@ -108,7 +108,7 @@ describe.skipIf(!minioAvailable)("S3 storage backend", () => {
}, 15_000);
it("saveFile writes object to S3", async () => {
const { saveFile } = await import("../../apps/api/src/lib/file-storage.js");
const { saveFile } = await import("../../../apps/api/src/lib/file-storage.js");
storedName = await saveFile(PNG, "test-upload.png");
expect(storedName).toMatch(/^[a-f0-9-]+\.png$/);
@@ -116,13 +116,13 @@ describe.skipIf(!minioAvailable)("S3 storage backend", () => {
});
it("readStoredFile returns the correct buffer", async () => {
const { readStoredFile } = await import("../../apps/api/src/lib/file-storage.js");
const { readStoredFile } = await import("../../../apps/api/src/lib/file-storage.js");
const buffer = await readStoredFile(storedName);
expect(Buffer.compare(buffer, PNG)).toBe(0);
});
it("streamStoredFile returns a readable stream", async () => {
const { streamStoredFile } = await import("../../apps/api/src/lib/file-storage.js");
const { streamStoredFile } = await import("../../../apps/api/src/lib/file-storage.js");
const stream = await streamStoredFile(storedName);
const chunks: Buffer[] = [];
@@ -134,7 +134,7 @@ describe.skipIf(!minioAvailable)("S3 storage backend", () => {
it("saveThumbnail stores in S3, getCachedThumbnail retrieves it", async () => {
const { saveThumbnail, getCachedThumbnail } = await import(
"../../apps/api/src/lib/file-storage.js"
"../../../apps/api/src/lib/file-storage.js"
);
const thumbData = Buffer.from("fake-thumbnail-data");
@@ -147,29 +147,31 @@ describe.skipIf(!minioAvailable)("S3 storage backend", () => {
});
it("deleteThumbnail removes thumbnail from S3", async () => {
const { deleteThumbnail } = await import("../../apps/api/src/lib/file-storage.js");
const { deleteThumbnail } = await import("../../../apps/api/src/lib/file-storage.js");
await deleteThumbnail(storedName);
expect(await objectExists(`thumbs/${storedName}.thumb.jpg`)).toBe(false);
});
it("deleteStoredFile removes file from S3", async () => {
const { deleteStoredFile } = await import("../../apps/api/src/lib/file-storage.js");
const { deleteStoredFile } = await import("../../../apps/api/src/lib/file-storage.js");
await deleteStoredFile(storedName);
expect(await objectExists(`files/${storedName}`)).toBe(false);
});
it("deleteStoredFile is idempotent (no error for missing key)", async () => {
const { deleteStoredFile } = await import("../../apps/api/src/lib/file-storage.js");
const { deleteStoredFile } = await import("../../../apps/api/src/lib/file-storage.js");
await expect(deleteStoredFile("nonexistent-file.png")).resolves.toBeUndefined();
});
it("getCachedThumbnail returns null for missing thumbnail", async () => {
const { getCachedThumbnail } = await import("../../apps/api/src/lib/file-storage.js");
const { getCachedThumbnail } = await import("../../../apps/api/src/lib/file-storage.js");
expect(await getCachedThumbnail("nonexistent.png")).toBeNull();
});
it("S3_PREFIX scopes all object keys under a tenant prefix", async () => {
const { saveFile, deleteStoredFile } = await import("../../apps/api/src/lib/file-storage.js");
const { saveFile, deleteStoredFile } = await import(
"../../../apps/api/src/lib/file-storage.js"
);
(env as Record<string, unknown>).S3_PREFIX = "tenant-123";
s3Storage.configureS3({
@@ -1,7 +1,7 @@
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { hashPassword } from "../../apps/api/src/plugins/auth.js";
import { buildTestApp, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { hashPassword } from "../../../apps/api/src/plugins/auth.js";
import { buildTestApp, type TestApp } from "../test-server.js";
let testApp: TestApp;
const SCIM_TOKEN = "test-scim-token-abc123";
@@ -1,7 +1,7 @@
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -72,9 +72,9 @@ describe("SIEM config with enterprise license", () => {
beforeAll(async () => {
vi.resetModules();
const { mockEnterpriseFeatures } = await import("../helpers/enterprise-mock.js");
const { mockEnterpriseFeatures } = await import("../../helpers/enterprise-mock.js");
mockEnterpriseFeatures(["siem_forwarding"]);
const { buildTestApp, loginAsAdmin } = await import("./test-server.js");
const { buildTestApp, loginAsAdmin } = await import("../test-server.js");
enterpriseApp = await buildTestApp();
entAdminToken = await loginAsAdmin(enterpriseApp.app);
@@ -1,5 +1,5 @@
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -7,9 +7,9 @@
import { randomUUID } from "node:crypto";
import AdmZip from "adm-zip";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { env } from "../../apps/api/src/config.js";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { env } from "../../../apps/api/src/config.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let app: TestApp["app"];
@@ -8,18 +8,18 @@ import { join } from "node:path";
import type { Job } from "bullmq";
import { eq, sql } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
import { env } from "../../apps/api/src/config.js";
import { db, schema } from "../../apps/api/src/db/index.js";
import { runMigrations } from "../../apps/api/src/db/migrate.js";
import { closeQueues, getQueue } from "../../apps/api/src/jobs/queues.js";
import { env } from "../../../apps/api/src/config.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { runMigrations } from "../../../apps/api/src/db/migrate.js";
import { closeQueues, getQueue } from "../../../apps/api/src/jobs/queues.js";
import {
decideExpiry,
runSystemJob,
SYSTEM_JOBS,
scheduleSystemJobs,
} from "../../apps/api/src/jobs/system-jobs.js";
import type { ObjectInfo } from "../../apps/api/src/lib/object-storage.js";
import * as objectStorage from "../../apps/api/src/lib/object-storage.js";
} from "../../../apps/api/src/jobs/system-jobs.js";
import type { ObjectInfo } from "../../../apps/api/src/lib/object-storage.js";
import * as objectStorage from "../../../apps/api/src/lib/object-storage.js";
beforeAll(async () => {
await runMigrations();
@@ -8,8 +8,8 @@
import { randomUUID } from "node:crypto";
import { eq, sql } from "drizzle-orm";
import { afterAll, beforeAll, beforeEach, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let app: TestApp["app"];
@@ -7,10 +7,15 @@
*/
import sharp from "sharp";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { sharedRedis } from "../../apps/api/src/jobs/connection.js";
import { bullPrefix } from "../../apps/api/src/jobs/types.js";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { sharedRedis } from "../../../apps/api/src/jobs/connection.js";
import { bullPrefix } from "../../../apps/api/src/jobs/types.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
const PNG = readFixture(fixtures.image.base.png200);
@@ -1,7 +1,7 @@
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -80,9 +80,9 @@ describe("upgrade management - with enterprise license", () => {
beforeAll(async () => {
vi.resetModules();
const { mockEnterpriseFeatures } = await import("../helpers/enterprise-mock.js");
const { mockEnterpriseFeatures } = await import("../../helpers/enterprise-mock.js");
mockEnterpriseFeatures(["upgrade_management"]);
const { buildTestApp, loginAsAdmin } = await import("./test-server.js");
const { buildTestApp, loginAsAdmin } = await import("../test-server.js");
entApp = await buildTestApp();
entAdminToken = await loginAsAdmin(entApp.app);
}, 30_000);
@@ -7,8 +7,8 @@
import { randomUUID } from "node:crypto";
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let app: TestApp["app"];
@@ -7,8 +7,13 @@
import sharp from "sharp";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
const PNG = readFixture(fixtures.image.base.png200);
const JPG = readFixture(fixtures.image.base.jpg100);
@@ -1,7 +1,7 @@
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
describe("webhook management", () => {
describe("without enterprise license", () => {
@@ -96,9 +96,9 @@ describe("webhook management", () => {
beforeAll(async () => {
vi.resetModules();
const { mockEnterpriseFeatures } = await import("../helpers/enterprise-mock.js");
const { mockEnterpriseFeatures } = await import("../../helpers/enterprise-mock.js");
mockEnterpriseFeatures(["admin_alerts", "webhooks"]);
const testServer = await import("./test-server.js");
const testServer = await import("../test-server.js");
testApp = await testServer.buildTestApp();
adminToken = await testServer.loginAsAdmin(testApp.app);
}, 30_000);
@@ -15,17 +15,17 @@ process.env.JOB_TIMEOUT_FAST_S = "1";
// Dynamic imports so config.ts picks up the 1-second timeout.
const { eq } = await import("drizzle-orm");
const { db, schema } = await import("../../apps/api/src/db/index.js");
const { db, schema } = await import("../../../apps/api/src/db/index.js");
const { startCancelListener, stopCancelListener } = await import(
"../../apps/api/src/jobs/cancel.js"
"../../../apps/api/src/jobs/cancel.js"
);
const { sharedRedis } = await import("../../apps/api/src/jobs/connection.js");
const { enqueueToolJob } = await import("../../apps/api/src/jobs/enqueue.js");
const { bullPrefix } = await import("../../apps/api/src/jobs/types.js");
const { closeWorkers, startWorkers } = await import("../../apps/api/src/jobs/worker.js");
const { putObject } = await import("../../apps/api/src/lib/object-storage.js");
const { registerToolProcessFn } = await import("../../apps/api/src/routes/tool-factory.js");
const { env } = await import("../../apps/api/src/config.js");
const { sharedRedis } = await import("../../../apps/api/src/jobs/connection.js");
const { enqueueToolJob } = await import("../../../apps/api/src/jobs/enqueue.js");
const { bullPrefix } = await import("../../../apps/api/src/jobs/types.js");
const { closeWorkers, startWorkers } = await import("../../../apps/api/src/jobs/worker.js");
const { putObject } = await import("../../../apps/api/src/lib/object-storage.js");
const { registerToolProcessFn } = await import("../../../apps/api/src/routes/tool-factory.js");
const { env } = await import("../../../apps/api/src/config.js");
// Sanity: the env override must have taken effect.
if (env.JOB_TIMEOUT_FAST_S !== 1) {
@@ -42,7 +42,7 @@ registerToolProcessFn({
inputBuffer: Buffer,
_settings: unknown,
filename: string,
ctx?: import("../../apps/api/src/routes/tool-factory.js").ToolProcessCtx,
ctx?: import("../../../apps/api/src/routes/tool-factory.js").ToolProcessCtx,
) => {
// Loop for up to 30s, checking signal every 100ms.
for (let i = 0; i < 300; i++) {
@@ -62,7 +62,7 @@ const wsPath = process.env.WORKSPACE_PATH ?? "";
mkdirSync(wsPath, { recursive: true });
// Run migrations so the jobs table exists in this fork's DB.
const { runMigrations } = await import("../../apps/api/src/db/migrate.js");
const { runMigrations } = await import("../../../apps/api/src/db/migrate.js");
await runMigrations();
beforeAll(async () => {
@@ -18,8 +18,13 @@
import sharp from "sharp";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
// ---------------------------------------------------------------------------
// Fixtures
@@ -19,8 +19,13 @@
import sharp from "sharp";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
// ---------------------------------------------------------------------------
// Fixtures
@@ -10,8 +10,13 @@
*/
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
// ---------------------------------------------------------------------------
// Fixtures
@@ -18,8 +18,13 @@
import sharp from "sharp";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
// ---------------------------------------------------------------------------
// Fixtures
@@ -16,8 +16,13 @@
*/
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
// ---------------------------------------------------------------------------
// Fixtures
@@ -16,8 +16,13 @@
import sharp from "sharp";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
// ---------------------------------------------------------------------------
// Fixtures
@@ -8,8 +8,13 @@
import sharp from "sharp";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
// ---------------------------------------------------------------------------
// Fixtures
@@ -2,9 +2,14 @@ import { readFileSync } from "node:fs";
import { join } from "node:path";
import { TOOLS } from "@snapotter/shared";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { TOOL_DISPLAY_MODES } from "../../apps/web/src/lib/tool-display-modes.js";
import { fixtureDir } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { TOOL_DISPLAY_MODES } from "../../../apps/web/src/lib/tool-display-modes.js";
import { fixtureDir } from "../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
/**
* Hostile-input matrix: every tool route must reject malformed, truncated,
@@ -5,8 +5,8 @@
*/
import { eq } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import { buildTestApp, loginAsAdmin, type TestApp } from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -10,8 +10,13 @@
*/
import { eq, sql } from "drizzle-orm";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { db, schema } from "../../apps/api/src/db/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { db, schema } from "../../../apps/api/src/db/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../test-server.js";
let testApp: TestApp;
let adminToken: string;
@@ -3,8 +3,13 @@ import { tmpdir } from "node:os";
import { join } from "node:path";
import { ffmpegAvailable, probeMedia } from "@snapotter/media-engine";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../../test-server.js";
const STEREO = readFixture(fixtures.audio.stereo);
const MONO_MP3 = readFixture(fixtures.audio.tiny("mp3"));
@@ -3,8 +3,13 @@ import { tmpdir } from "node:os";
import { join } from "node:path";
import { ffmpegAvailable, probeMedia } from "@snapotter/media-engine";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../../test-server.js";
const MP3 = readFixture(fixtures.audio.tiny("mp3"));
@@ -3,8 +3,13 @@ import { tmpdir } from "node:os";
import { join } from "node:path";
import { ffmpegAvailable, probeMedia } from "@snapotter/media-engine";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../../test-server.js";
const MP3 = readFixture(fixtures.audio.tiny("mp3"));
@@ -1,7 +1,12 @@
import { ffmpegAvailable } from "@snapotter/media-engine";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../../test-server.js";
const WAV = readFixture(fixtures.audio.tiny("wav"));
const MP3 = readFixture(fixtures.audio.tiny("mp3"));
@@ -1,7 +1,12 @@
import { ffmpegAvailable } from "@snapotter/media-engine";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../../test-server.js";
const MP3 = readFixture(fixtures.audio.tiny("mp3"));
@@ -3,8 +3,13 @@ import { tmpdir } from "node:os";
import { join } from "node:path";
import { ffmpegAvailable, probeMedia } from "@snapotter/media-engine";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../../test-server.js";
const MP3 = readFixture(fixtures.audio.tiny("mp3"));
const WAV = readFixture(fixtures.audio.tiny("wav"));
@@ -3,8 +3,13 @@ import { tmpdir } from "node:os";
import { join } from "node:path";
import { ffmpegAvailable, probeMedia } from "@snapotter/media-engine";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../../test-server.js";
const MP3 = readFixture(fixtures.audio.tiny("mp3"));
@@ -1,7 +1,12 @@
import { ffmpegAvailable } from "@snapotter/media-engine";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../../test-server.js";
const WAV = readFixture(fixtures.audio.tiny("wav"));
@@ -3,8 +3,13 @@ import { tmpdir } from "node:os";
import { join } from "node:path";
import { ffmpegAvailable, probeMedia } from "@snapotter/media-engine";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../../test-server.js";
const MP3 = readFixture(fixtures.audio.tiny("mp3"));
@@ -3,8 +3,13 @@ import { tmpdir } from "node:os";
import { join } from "node:path";
import { ffmpegAvailable, probeMedia } from "@snapotter/media-engine";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../../test-server.js";
const MP3 = readFixture(fixtures.audio.tiny("mp3"));
@@ -1,7 +1,12 @@
import { ffmpegAvailable } from "@snapotter/media-engine";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../../test-server.js";
const MP3 = readFixture(fixtures.audio.tiny("mp3"));
@@ -3,8 +3,13 @@ import { tmpdir } from "node:os";
import { join } from "node:path";
import { ffmpegAvailable, probeMedia } from "@snapotter/media-engine";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../fixtures/index.js";
import { buildTestApp, createMultipartPayload, loginAsAdmin, type TestApp } from "./test-server.js";
import { fixtures, readFixture } from "../../../fixtures/index.js";
import {
buildTestApp,
createMultipartPayload,
loginAsAdmin,
type TestApp,
} from "../../test-server.js";
const TONE_GAP = readFixture(fixtures.audio.gap);

Some files were not shown because too many files have changed in this diff Show More