Commit Graph
13 Commits
Author SHA1 Message Date
SnapOtter 492da820f8 fix(web): resolve feature install status sync and mutual exclusivity (#214) 2026-06-13 13:44:37 +08:00
SnapOtterandGitHub 436576fe15 fix: resolve features-store test timeouts and dynamic icon-map test (#151)
- Fix installAll tests timing out by returning installed status from
  refreshBundles mock (prevents infinite retry loop) and increasing
  waitFor/test timeouts to accommodate the 2s inter-install delay
- Fix zustand-stores installAll test with same refreshBundles mock fix
- Icon-map test already fixed to derive from shared constants
2026-05-18 17:24:36 +08:00
SnapOtter e1ca06cd95 fix: update unit tests for DecodedPreview return type and outpaint tier arg 2026-05-13 15:53:09 +08:00
SnapOtter a0556772e8 test: expand coverage across all layers -- 1,268 new tests, fix replace-color div-by-zero
14-agent parallel test expansion covering integration, unit, E2E, E2E-Docker,
cross-format matrix, adversarial, GUI navigation/tools/settings/visual/a11y/perf.

- Integration: expand 23 tool test files with HEIC, stress, batch, edge cases
- Unit: close coverage gaps in image-engine, stores, lib (metadata, auto-enhance,
  connection-store, lazy-with-retry, collage/file-store HEIC preview)
- AI bridge: 141 new tests for dispatcher buffering, crash recovery, OOM/segfault
- Cross-format: 794 parameterized tests (16 formats x 12 tools + no-crash matrix)
- Adversarial: memory stress (50x large file), zero-byte, corrupted headers, unicode
- E2E-Docker: expand 8 spec files with dimension verification, pipeline chains
- GUI E2E: tool UI settings/interactions for all 47 tools, remove all test.skip,
  RBAC per-role verification, visual screenshot naming, cross-browser smoke tests,
  a11y ARIA/focus/contrast, performance budgets, 15-tool stability test
- Fix: replace-color.ts tolerance=0 caused division-by-zero producing NaN pixels

Total: 8,958 tests passing across 202 files. Zero failures, zero skips.
2026-05-09 18:02:58 +08:00
SnapOtter 649ad5db9e test: massive test coverage expansion (+1,437 tests, 22 new files)
Expand test coverage across all layers via 14 parallel agents:

Unit tests (3,378 total, +534):
- First-ever AI sidecar tests (157 tests covering bridge lifecycle, all 12 tool modules)
- API route infrastructure (auth, pipeline, batch, settings, teams, roles, audit, api-keys, files, docs)
- Lib coverage improvements (audit 7%->95%, worker-pool 33%->100%)
- Web store/lib gap fills (features-store, tool-registry)

Integration tests (4,403 total, +903):
- Expanded 19 tool test files with parameter variations, format edge cases, boundary values
- Cross-format matrix: 290 tests covering 14 tools x 17 formats
- Adversarial/edge cases: 63 tests for extreme inputs, concurrent requests, corrupted files

E2E-Docker (125 new tests):
- Expanded 8 spec files + 1 new file covering all 49 tools
- Added HEIC/format handling, auth failures, download verification

GUI E2E (expanded 28 spec files):
- Navigation, responsive layout, keyboard shortcuts
- All 51 tool UIs with settings, processing, display modes
- Batch/pipeline workflows, settings/RBAC, visual regression
- Resilience, accessibility (ARIA, contrast, focus), performance budgets
2026-05-09 09:02:29 +08:00
SnapOtter 8f9ba701be fix: QR code logo causes preview to vanish and become unrecoverable
The QR code generator's logo feature was broken in production (Docker)
due to three interacting issues:

1. The CSP connect-src directive did not include data:, so the
   qr-code-styling library's internal XHR to convert logo data URLs to
   blobs was silently blocked. The library has no onerror handler, so the
   render promise hung forever after the container was already cleared.

2. crossOrigin: "anonymous" was unnecessarily set on imageOptions for
   data URLs, which can cause canvas taint issues.

3. The logo options used a conditional spread that omitted the image key
   when no logo was set. The library's update() deep-merges options, so
   removing the logo preserved the stale data URL and the QR stayed
   broken even after logo removal.

Closes #121
2026-05-06 21:38:12 +08:00
SnapOtter e358634f8b fix: production CSP blocking PostHog/Sentry/Scalar and silent failure hardening
The production CSP had connect-src/script-src/font-src set to 'self' only,
silently blocking all analytics and error reporting in production while
working fine in dev (where CSP is not applied).

CSP fixes:
- Add PostHog ingest + assets origins to connect-src and script-src
- Add Sentry ingest origin to connect-src
- Add Scalar fonts origin to font-src for API docs pages
- Extract CSP construction into testable buildCsp() function

Silent failure hardening:
- Settings/features stores now set loadError flag and allow retry on
  subsequent fetch() calls instead of permanently caching failed state
- Analytics init no longer sets initialized=true before the try block,
  allowing retry on failure
- Settings dialog Tools section disables save button when settings
  failed to load, preventing accidental config wipe
- Branding logo storage moved from process.cwd() to FILES_STORAGE_PATH
  so logos persist across Docker container recreation

Test coverage:
- 16 CSP directive tests covering all external service domains
- Store retry-on-error behavior tests for settings and features stores
- Analytics init retry-after-failure test
2026-05-05 17:16:19 +08:00
SnapOtter 4f81b29fbc fix: AI feature install failures — missing rembg session and Fastify 415 (#102, #103)
Register custom BiRefNet-matting ONNX session in install_feature.py so
rembg.new_session("birefnet-matting") no longer raises ValueError during
on-demand installs. The session was already registered in remove_bg.py
(runtime) and download_models.py (build-time) but was missed in the
install path, causing background-removal bundle installs to always fail.

Send JSON body on install/uninstall POST requests to avoid Fastify 5's
strict content-type parser rejecting body-less POSTs with 415.

Fix error message extraction to preserve structured {"error": ...} JSON
from the Python script and filter out pthread_setaffinity_np noise.
2026-04-27 02:38:17 +08:00
SnapOtter 733ebe8010 test: major coverage expansion — 18 new test files, ~830 new tests
Unit tests: 1354 → 1781 (+427)
- 11 new AI bridge module tests (packages/ai/ from 2/13 → 13/13 files)
- files-page-store (0% → full), pdf-to-image-store, features-store expanded
- saturation and edit-metadata image-engine operations
- analytics route, features route, web analytics lib, api-extended

Integration tests: ~2070 → 2320 (+250)
- 31 integration files expanded with branch-coverage-targeted tests
- progress.ts SSE endpoints (28% → comprehensive, +18 tests)
- gif-tools all modes (+18), pdf-to-image format variants (+13)
- Cross-format matrix expanded to 17 tools × 17 formats (467 tests)
- Adversarial: concurrent, memory pressure, unicode filenames, pipeline limits

E2E-Docker: +1020 lines across 6 spec files
- Info, colors, sharpening, base64, QR read, JXL/ICO/SVG formats
- Strip-metadata, image-enhancement, content-aware-resize expanded
- Batch pipelines, multi-format batches, HEIC input coverage
2026-04-26 12:03:08 +08:00
SnapOtter c061ad13ce fix: default theme setting not persisting across sessions (#98)
Three disconnected systems caused the theme to never apply from server
settings: the DEFAULT_THEME env var was parsed but never seeded to the
database, the settings store ignored defaultTheme from the API, and the
settings dialog wrote to the DB without updating the active theme store.

- Seed DEFAULT_THEME and DEFAULT_LOCALE env vars into the settings table
  on first startup (ensureDefaultSettings in index.ts)
- Add applyServerDefault() to theme store that applies the server's
  default theme only when the user hasn't made an explicit choice
- Extract defaultTheme from the settings API response and apply it on
  fresh sessions (no localStorage preference)
- Apply theme immediately when admin saves settings
- Allow "system" as a valid DEFAULT_THEME env var value
2026-04-25 22:39:18 +08:00
SnapOtter 7f62bc32db test: expand coverage to 3,382 tests across all layers
- Unit: 1,353 tests (42 files) — +256 new tests covering AI bridge
  modules, image-engine sharpen/optimize-for-web, Zustand stores, and
  icon-map validation
- Integration: 1,640 tests (57 files) — +826 new tests across all
  tool routes, pipeline/progress/batch infrastructure, user-files,
  edit-metadata, and a 321-test cross-format matrix
- E2E-Docker: 389 passing (20 spec files) — 6 new spec files for
  batch processing, format conversion, layout, optimization,
  watermark/overlay, and pipeline chains. Tests verified against fresh
  Docker container with all 6 AI bundles installed.

Bug fixes discovered during testing:
- fix(compress): SVG/BMP/exotic formats crashed Sharp encoder — added
  format-safety fallback to PNG
- fix(rate-limit): increase default login attempt limit from 10 to 500
  per minute — previous value caused false test failures and is too
  restrictive for a self-hosted app
- fix(auth.setup): wait for consent button visibility before clicking
  to prevent flaky E2E-Docker auth setup
2026-04-24 22:43:14 +08:00
SnapOtter 0309e0f680 chore: deploy to Cloudflare Pages and update branding
- Add Cloudflare Pages deployment for landing page (snapotter.com) and
  docs (docs.snapotter.com)
- Create deploy-landing.yml and update deploy-docs.yml workflows
- Update CI to ignore apps/landing/** paths
- Fix logo transparency (remove white background) across all apps
- Recreate social-preview.png with SnapOtter branding
- Update all docs URLs from GitHub Pages to docs.snapotter.com
- Update VitePress config: light theme default, fix llms.txt paths
- Add .vitepress/cache/ and .env.* to gitignore
2026-04-24 18:06:29 +08:00
ashim-hq babca4cf97 test: comprehensive test coverage expansion (+965 tests)
Add 42 new test files covering all untested tool routes, image engine
internals, AI sidecar bridge, Zustand stores, and cross-format
compatibility. Expand e2e-docker suite with 7 spec files covering all
48 tools against a real Docker container.

Unit tests:
- Image engine: format detection, MIME mapping, metadata parsing, pipeline
- AI bridge: sidecar lifecycle, all 11 tool functions (mocked)
- Web stores: 14 Zustand stores (collage, settings, features, analytics, etc.)
- API helpers: format decoders, page range, file validation

Integration tests:
- 25 tool routes that had zero dedicated tests
- Cross-format matrix: 17 input formats x 3 tools
- Edge cases: zero-byte files, corrupted headers, path traversal, XSS, SQL injection
- Concurrent request handling and pipeline edge cases

E2E-Docker (Playwright against real container):
- 7 spec files: essential, adjustment, conversion, creative, utility, AI, pipeline
- Custom buildMultipart helper for multi-file tool uploads
- AI tools gracefully skip when sidecar not installed

Fixtures:
- Organized test media: formats/ (18 formats) + content/ (17 content types)
- Reduced from 3.1 GB unorganized samples to 33 MB structured fixtures

Bug fix:
- color-adjustments: gamma exposure used invalid single-param gamma() for
  positive values; fixed to use two-param gamma(gammaIn, gammaOut) form
2026-04-23 17:12:02 +08:00