mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2026-09-03 05:10:16 +03:00
Compare commits
13
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d27cd26a6 | ||
|
|
be24bcc759 | ||
|
|
6e39e25905 | ||
|
|
c5f7ebc2f1 | ||
|
|
e50f18ca7c | ||
|
|
31827c4405 | ||
|
|
9a8ee5a84d | ||
|
|
b4ef003689 | ||
|
|
c01d402323 | ||
|
|
ec19f0c8ac | ||
|
|
92889fce92 | ||
|
|
61ed03477b | ||
|
|
345a9d37b1 |
+11
-2
@@ -523,6 +523,7 @@ tasks:
|
||||
deps: [prepare]
|
||||
vars:
|
||||
COVERAGE: '{{.COVERAGE | default .CI | default "false"}}'
|
||||
TEST_TIMEOUT: '{{.TEST_TIMEOUT | default "5000"}}'
|
||||
cmds:
|
||||
- >
|
||||
npx vitest run --root editor
|
||||
@@ -531,7 +532,9 @@ tasks:
|
||||
--coverage.reporter=text-summary
|
||||
--coverage.reporter=json-summary
|
||||
--coverage.reporter=html
|
||||
--coverage.reportsDirectory=./coverage{{end}}
|
||||
--coverage.reportsDirectory=./coverage
|
||||
{{if .TEST_TIMEOUT}}--testTimeout={{.TEST_TIMEOUT}}
|
||||
--hookTimeout={{.TEST_TIMEOUT}}{{end}}{{end}}
|
||||
|
||||
test:watch:
|
||||
desc: "Run tests in watch mode"
|
||||
@@ -541,9 +544,15 @@ tasks:
|
||||
|
||||
test:coverage:
|
||||
desc: "Run tests with coverage (one-shot; CI-friendly)."
|
||||
vars:
|
||||
TEST_TIMEOUT: '{{.TEST_TIMEOUT | default "5000"}}'
|
||||
env:
|
||||
TEST_TIMEOUT: '{{.TEST_TIMEOUT}}'
|
||||
cmds:
|
||||
- task: test:editor
|
||||
vars: { COVERAGE: "true" }
|
||||
vars:
|
||||
COVERAGE: "true"
|
||||
TEST_TIMEOUT: '{{.TEST_TIMEOUT}}'
|
||||
|
||||
# ============================================================
|
||||
# Code Generation
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/editor/coverage
|
||||
/coverage
|
||||
|
||||
# production
|
||||
@@ -50,3 +51,4 @@ test-results
|
||||
/editor/src-tauri/tauri.conf.dev-update.json
|
||||
.a11y-scan/
|
||||
.a11y-acc/
|
||||
/editor/src-tauri/*
|
||||
|
||||
@@ -212,6 +212,3 @@ if (typeof globalThis.DOMMatrix === "undefined") {
|
||||
configurable: true,
|
||||
});
|
||||
}
|
||||
|
||||
// Set global test timeout to prevent hangs
|
||||
vi.setConfig({ testTimeout: 5000, hookTimeout: 5000 });
|
||||
|
||||
@@ -33,6 +33,8 @@ export function formatMinor(
|
||||
minor: number,
|
||||
currency: string | null | undefined,
|
||||
): string {
|
||||
// Money strings use a stable decimal separator because the compact symbol is
|
||||
// already supplied separately and backend/test contracts expect dot decimals.
|
||||
const num = new Intl.NumberFormat("en-US", {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 3,
|
||||
|
||||
+17
-23
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||
import { renderHook, act } from "@testing-library/react";
|
||||
import { renderHook, waitFor } from "@testing-library/react";
|
||||
import type { ClassificationConfidence } from "@app/types/fileContext";
|
||||
|
||||
/**
|
||||
@@ -8,7 +8,7 @@ import type { ClassificationConfidence } from "@app/types/fileContext";
|
||||
*/
|
||||
|
||||
const FILE_COUNT = 61;
|
||||
|
||||
const TEST_TIMEOUT_MS = Number(process.env.TEST_TIMEOUT ?? 10000);
|
||||
// A tiny mutable "workspace" the mocks share: the list of file stubs currently in
|
||||
// the workbench, mirrored into useAllFiles. consumeFiles mutates it in place
|
||||
// (input id → output id) exactly as the real silent reducer would.
|
||||
@@ -240,15 +240,13 @@ beforeEach(() => {
|
||||
/** Drive the hook until the store shows the expected number of imported runs. */
|
||||
async function runUntilSettled(expectedRuns: number) {
|
||||
renderHook(() => Harness());
|
||||
await act(async () => {
|
||||
await vi.waitFor(
|
||||
() => {
|
||||
const imported = latestRuns.filter((r) => r.imported).length;
|
||||
expect(imported).toBe(expectedRuns);
|
||||
},
|
||||
{ timeout: 8000, interval: 20 },
|
||||
);
|
||||
});
|
||||
await waitFor(
|
||||
() => {
|
||||
const imported = latestRuns.filter((r) => r.imported).length;
|
||||
expect(imported).toBe(expectedRuns);
|
||||
},
|
||||
{ timeout: TEST_TIMEOUT_MS, interval: 20 },
|
||||
);
|
||||
}
|
||||
|
||||
describe("policy auto-run — 61-file batch through a Security → Classification chain", () => {
|
||||
@@ -296,19 +294,15 @@ describe("policy auto-run — 61-file batch through a Security → Classificatio
|
||||
id: "storage",
|
||||
versionNumber: 1,
|
||||
});
|
||||
act(() => {
|
||||
mocks.workspace = [];
|
||||
});
|
||||
mocks.workspace = [];
|
||||
|
||||
await act(async () => {
|
||||
await vi.waitFor(
|
||||
() => {
|
||||
const imported = latestRuns.filter((r) => r.imported).length;
|
||||
expect(imported).toBe(FILE_COUNT * 2);
|
||||
},
|
||||
{ timeout: 8000, interval: 20 },
|
||||
);
|
||||
});
|
||||
await waitFor(
|
||||
() => {
|
||||
const imported = latestRuns.filter((r) => r.imported).length;
|
||||
expect(imported).toBe(FILE_COUNT * 2);
|
||||
},
|
||||
{ timeout: TEST_TIMEOUT_MS, interval: 20 },
|
||||
);
|
||||
|
||||
// Still fully processed (chain intact), but Security's versions went to
|
||||
// STORAGE, never re-added to the workbench — the workspace stays empty.
|
||||
|
||||
@@ -416,6 +416,7 @@ describe("Login", () => {
|
||||
options: { redirectTo: "/auth/callback" },
|
||||
});
|
||||
});
|
||||
await waitFor(() => expect(oauthButton).not.toBeDisabled());
|
||||
});
|
||||
|
||||
it("should use actual provider ID for OAuth login (custom provider)", async () => {
|
||||
@@ -463,6 +464,10 @@ describe("Login", () => {
|
||||
options: { redirectTo: "/auth/callback" },
|
||||
});
|
||||
});
|
||||
|
||||
// The async handler clears isSubmitting after the OAuth mock resolves. Wait
|
||||
// for that final render so Mantine's transition cannot update after teardown.
|
||||
await waitFor(() => expect(oauthButton).not.toBeDisabled());
|
||||
});
|
||||
|
||||
it("should use oidc provider ID when explicitly configured", async () => {
|
||||
@@ -509,6 +514,7 @@ describe("Login", () => {
|
||||
options: { redirectTo: "/auth/callback" },
|
||||
});
|
||||
});
|
||||
await waitFor(() => expect(oauthButton).not.toBeDisabled());
|
||||
});
|
||||
|
||||
it("should show error on failed login", async () => {
|
||||
@@ -845,6 +851,9 @@ describe("Login", () => {
|
||||
await waitFor(() => {
|
||||
expect(springAuth.signInWithOAuth).toHaveBeenCalled();
|
||||
});
|
||||
await waitFor(() =>
|
||||
expect(screen.getByText(/Authentik/)).not.toBeDisabled(),
|
||||
);
|
||||
|
||||
// Must be stashed before the cross-origin SSO redirect wipes location.state.
|
||||
expect(sessionStorage.getItem("stirling_post_login_path")).toBe(
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
import react from "@vitejs/plugin-react-swc";
|
||||
import tsconfigPaths from "vite-tsconfig-paths";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const editorDir = dirname(fileURLToPath(import.meta.url));
|
||||
const tsconfig = (name: string) => resolve(editorDir, name);
|
||||
|
||||
// Projects do NOT inherit the root test.testTimeout, so every project silently
|
||||
// ran at vitest's 5s default. Spread this into each one instead.
|
||||
const TIMEOUTS = { testTimeout: 10000, hookTimeout: 10000 };
|
||||
|
||||
export default defineConfig({
|
||||
root: editorDir,
|
||||
test: {
|
||||
globals: true,
|
||||
environment: "jsdom",
|
||||
@@ -22,13 +28,21 @@ export default defineConfig({
|
||||
reporter: ["text", "json", "html"],
|
||||
exclude: [
|
||||
"node_modules/",
|
||||
"dist/**",
|
||||
"coverage/**",
|
||||
"src/core/setupTests.ts",
|
||||
"src/proprietary/setupTests.ts",
|
||||
"src/portal/setupTests.ts",
|
||||
"src/saas/setupTests.ts",
|
||||
"**/*.d.ts",
|
||||
"src/tests/test-fixtures/**",
|
||||
"src/**/*.spec.ts",
|
||||
],
|
||||
thresholds: {
|
||||
lines: 13,
|
||||
functions: 40,
|
||||
branches: 63,
|
||||
statements: 13,
|
||||
},
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
@@ -43,7 +57,8 @@ export default defineConfig({
|
||||
plugins: [
|
||||
react(),
|
||||
tsconfigPaths({
|
||||
projects: ["./tsconfig.core.vite.json"],
|
||||
root: editorDir,
|
||||
projects: [tsconfig("tsconfig.core.vite.json")],
|
||||
}),
|
||||
],
|
||||
esbuild: {
|
||||
@@ -62,9 +77,10 @@ export default defineConfig({
|
||||
plugins: [
|
||||
react(),
|
||||
tsconfigPaths({
|
||||
root: editorDir,
|
||||
// Broad project so @app/@portal resolve in every editor file the
|
||||
// portal tests pull in (core/ui, core, ...).
|
||||
projects: ["./tsconfig.portal.vite.json"],
|
||||
projects: [tsconfig("tsconfig.portal.vite.json")],
|
||||
}),
|
||||
],
|
||||
esbuild: {
|
||||
@@ -83,7 +99,8 @@ export default defineConfig({
|
||||
plugins: [
|
||||
react(),
|
||||
tsconfigPaths({
|
||||
projects: ["./tsconfig.proprietary.vite.json"],
|
||||
root: editorDir,
|
||||
projects: [tsconfig("tsconfig.proprietary.vite.json")],
|
||||
}),
|
||||
],
|
||||
esbuild: {
|
||||
@@ -102,7 +119,8 @@ export default defineConfig({
|
||||
plugins: [
|
||||
react(),
|
||||
tsconfigPaths({
|
||||
projects: ["./tsconfig.desktop.vite.json"],
|
||||
root: editorDir,
|
||||
projects: [tsconfig("tsconfig.desktop.vite.json")],
|
||||
}),
|
||||
],
|
||||
esbuild: {
|
||||
@@ -127,7 +145,8 @@ export default defineConfig({
|
||||
plugins: [
|
||||
react(),
|
||||
tsconfigPaths({
|
||||
projects: ["./tsconfig.saas.vite.json"],
|
||||
root: editorDir,
|
||||
projects: [tsconfig("tsconfig.saas.vite.json")],
|
||||
}),
|
||||
],
|
||||
esbuild: {
|
||||
@@ -146,7 +165,8 @@ export default defineConfig({
|
||||
plugins: [
|
||||
react(),
|
||||
tsconfigPaths({
|
||||
projects: ["./tsconfig.prototypes.vite.json"],
|
||||
root: editorDir,
|
||||
projects: [tsconfig("tsconfig.prototypes.vite.json")],
|
||||
}),
|
||||
],
|
||||
esbuild: {
|
||||
|
||||
Reference in New Issue
Block a user