Commit Graph

430 Commits

Author SHA1 Message Date
jubnl f594cbc21b fix(tests): target window.URL instead of URL for createObjectURL mocking
In jsdom, source modules resolve bare 'URL' identifiers through
window.URL (the jsdom window object), not through globalThis.URL (Node's
URL class). On GitHub Actions these are distinct objects, so all prior
attempts (Object.defineProperty, direct assignment, vi.stubGlobal) were
patching the wrong object and failing silently.

Changes:
- setup.ts: Object.defineProperty targets window.URL so the vi.fn mock
  is visible to authUrl.ts at call time
- authUrl.test.ts: drop vi.stubGlobal approach; add vi.clearAllMocks()
  to reset accumulated call counts on the setup.ts vi.fn between tests;
  fix vi.spyOn target to window.URL in test 012
2026-04-07 23:32:33 +02:00
jubnl e991f834e2 fix(tests): replace URL.createObjectURL mocking with vi.stubGlobal
Direct property assignment and Object.defineProperty both fail
silently on CI when jsdom marks URL.createObjectURL as non-writable
and non-configurable. vi.stubGlobal('URL', ...) replaces globalThis.URL
entirely — which always succeeds — while extending the real URL class
so all URL parsing behaviour is preserved. vi.unstubAllGlobals() is
called at the start of beforeEach to reset cleanly between tests.
2026-04-07 23:18:43 +02:00
jubnl b0633b1d36 fix(tests): fix remaining CI failures for URL.createObjectURL and Response mocking
Two root causes:

1. authUrl.test.ts (007, 011, 012): Object.defineProperty in setup.ts
   fails silently on CI when jsdom's URL.createObjectURL is
   non-configurable. vi.restoreAllMocks() in beforeEach then restores
   the property to jsdom's native implementation (returns '').
   Fix: assign URL.createObjectURL = vi.fn(() => 'blob:mock') directly
   in authUrl.test.ts's beforeEach, after restoreAllMocks(), so every
   test in the file gets a fresh, reliable mock. Remove the now-
   unnecessary mockClear() from test 012.

2. client.test.ts (013): MSW patches the global Response constructor and
   calls blob.stream() on the body — a method not implemented by jsdom's
   Blob. Fix: replace new Response(blob) with a plain-object duck-type
   ({ ok: true, blob: () => Promise.resolve(blob) }) to bypass the
   patched constructor entirely.
2026-04-07 23:10:41 +02:00
jubnl d8da0fffa5 fix(tests): resolve URL.createObjectURL and fetch mocking failures on CI
Three interrelated issues caused 4 tests to pass locally but fail on CI:

1. setup.ts only applied the URL.createObjectURL stub when it was
   undefined, but jsdom already defines it (returning ''). Changed to
   always override with configurable:true so the predictable 'blob:mock'
   value is set in every environment.

2. FE-API-013 used Object.defineProperty (non-configurable in jsdom) and
   MSW to handle a native fetch call. Replaced with vi.spyOn for both
   URL.createObjectURL/revokeObjectURL and a direct fetch mock, which is
   more reliable across environments.

3. FE-COMP-AUTHURL-012's vi.spyOn(URL, 'createObjectURL') returned the
   same vi.fn() instance set in setup.ts, accumulating calls from all
   prior tests in the file (1+8+7+6=22 instead of 6). Added mockClear()
   immediately after the spy setup to reset the count.
2026-04-07 22:51:38 +02:00
jubnl 9e23766b51 fix(client): resolve esbuild version conflict for CI
Add npm overrides to force esbuild@^0.28.0, resolving the conflict
between vite@5.x (which installs 0.21.5) and vitest@4.x's internal
vite@8.x (which requires ^0.27.0 || ^0.28.0). Without this,
npm ci fails on a clean install.
2026-04-07 22:40:08 +02:00
jubnl fd48169219 test(client): expand frontend test suite to 69.1% coverage
Add and extend tests across 32 files (+10 595 lines) covering Admin
panels (AuditLog, Backup, DevNotifications, GitHub), Collab (Chat,
Notes, Panel, Polls), Planner (DayDetailPanel, DayPlanSidebar),
Settings (DisplaySettings, Integrations, MapSettings), Files
(FileManager, FilesPage), Map, Layout (DemoBanner,
InAppNotificationBell), shared pickers (CustomDateTimePicker,
CustomTimePicker), Vacay holidays, pages (Dashboard, Login), unit
stores (authStore, inAppNotificationStore), API (authUrl, client
integration), and i18n. Also updates sonar-project.properties and
MSW trip handlers to support the new cases.
2026-04-07 21:56:08 +02:00
Julien G. 9390a2e9c6 Merge pull request #501 from mauriceboe/dev
get backend tests
2026-04-07 18:57:16 +02:00
github-actions[bot] 504195a324 chore: bump version to 2.9.11 [skip ci] 2026-04-07 11:18:45 +00:00
jubnl 47b880221d fix(oidc): resolve login/logout loop in OIDC-only mode
Three distinct bugs caused infinite OIDC redirect loops:

1. After logout, navigating to /login with no signal to suppress the
   auto-redirect caused the login page to immediately re-trigger the
   OIDC flow. Fixed by passing `{ state: { noRedirect: true } }` via
   React Router's navigation state (not URL params, which were fragile
   due to async cleanup timing) from all logout call sites.

2. On the OIDC callback page (/login?oidc_code=...), App.tsx's
   mount-level loadUser() fired concurrently with the LoginPage's
   exchange fetch. The App-level call had no cookie yet and got a 401,
   which (if it resolved after the successful exchange loadUser()) would
   overwrite isAuthenticated back to false. Fixed by skipping loadUser()
   in App.tsx when the initial path is /login.

3. React 18 StrictMode double-invokes useEffect. The first run called
   window.history.replaceState to clean the oidc_code from the URL
   before starting the async exchange, so the second run saw no
   oidc_code and fell through to the getAppConfig auto-redirect, firing
   window.location.href = '/api/auth/oidc/login' before the exchange
   could complete. Fixed by adding a useRef guard to prevent
   double-execution and moving replaceState into the fetch callbacks so
   the URL is only cleaned after the exchange resolves.

Also adds login.oidcLoggedOut translation key in all 14 languages to
show "You have been logged out" instead of the generic OIDC-only
message when landing on /login after an intentional logout.

Closes #491
2026-04-07 13:18:24 +02:00
jubnl 3c31902885 test(front): add test suite frontend (WIP) 2026-04-07 12:31:09 +02:00
github-actions[bot] a6ea73eab6 chore: bump version to 2.9.10 [skip ci] 2026-04-06 10:57:06 +00:00
Maurice 4ba6005ca3 fix(dayplan): resolve duplicate reservation display, date off-by-one, and missing day_id on edit
- Exclude place-assigned reservations from timeline to prevent duplicate display
- Use selected day's date instead of today when entering time without date
- Pass day_id when updating reservations, not only when creating
2026-04-06 12:56:54 +02:00
github-actions[bot] 09ab829b17 chore: bump version to 2.9.9 [skip ci] 2026-04-06 09:32:20 +00:00
Maurice 66a057a070 fix(bookings): resolve date handling and file auth bugs
- Clear reservation_time fields when switching booking type to hotel (#459)
- Parse date-only reservation_end_time correctly on edit (#455)
- Show end date on booking cards for date-only values (#455)
- Add auth token to file download links in bookings (#454)
- Account for timezone offsets in flight time validation (#456)
2026-04-06 11:32:06 +02:00
github-actions[bot] f2ffea5ba4 chore: bump version to 2.9.8 [skip ci] 2026-04-05 22:09:41 +00:00
github-actions[bot] beb48af8ed chore: bump version to 2.9.7 [skip ci] 2026-04-05 21:38:56 +00:00
jubnl e2be3ec191 fix(atlas): replace fuzzy region matching with exact name_en check
Bidirectional substring matching in isVisitedFeature caused unrelated
regions to be highlighted as visited (e.g. selecting Nordrhein-Westfalen
also marked Nord France due to "nord" being a substring match).

Replace the fuzzy loop with an additional exact check against the Natural
Earth name_en property to cover English-vs-native name mismatches.
Also fix Nominatim field priority to prefer state over county so
reverse-geocoded places resolve to the correct admin-1 level.

Adds integration tests ATLAS-009 through ATLAS-011 covering mark/unmark
region endpoints and user isolation.

Fixes #446
2026-04-05 23:38:34 +02:00
github-actions[bot] 68a1f9683e chore: bump version to 2.9.6 [skip ci] 2026-04-05 21:26:44 +00:00
Maurice 5c57116a68 fix(dayplan): restore time-based auto-sort for places and free reorder for untimed
Timed places now auto-sort chronologically when a time is set.
Untimed places can be freely dragged between timed items.
Transports are inserted by time with per-day position override.
Fixes regression from multi-day spanning PR that removed timed/untimed split.
2026-04-05 23:26:35 +02:00
github-actions[bot] 48508b9df4 chore: bump version to 2.9.5 [skip ci] 2026-04-05 21:12:19 +00:00
github-actions[bot] 6491e1f986 chore: bump version to 2.9.4 [skip ci] 2026-04-05 21:02:53 +00:00
Maurice 03757ed0af fix(dayplan): per-day transport positions for multi-day reservations
Reordering places on one day of a multi-day reservation no longer
affects the order on other days. Transport positions are now stored
per-day in a new reservation_day_positions table instead of a single
global day_plan_position on the reservation.
2026-04-05 23:02:42 +02:00
github-actions[bot] a676dbe881 chore: bump version to 2.9.3 [skip ci] 2026-04-05 20:46:34 +00:00
jubnl 411d8620ba fix(reservations): reset stale budget category when it no longer exists
If the budget category stored in reservation metadata was deleted, the
form would re-submit it on next save, resurrecting the deleted category.
Now validates against live budget items on form init and falls back to
auto-generation when the stored category is gone.

Closes #442
2026-04-05 22:46:16 +02:00
github-actions[bot] f45f56318a chore: bump version to 2.9.2 [skip ci] 2026-04-05 20:36:00 +00:00
jubnl 3ae0f3f819 Merge remote-tracking branch 'origin/main' 2026-04-05 22:35:41 +02:00
jubnl 306626ee1c fix(trip): redirect to plan tab when active tab's addon is disabled
If a user's last visited tab belongs to an addon that gets disabled while
they are away, re-opening the trip now resets the active tab to 'plan'
instead of rendering the inaccessible addon page.

Closes #441
2026-04-05 22:30:22 +02:00
jubnl 7e0fe3b1b9 fix(reservations): hide price/budget fields when budget addon is disabled
Closes #440
2026-04-05 22:30:13 +02:00
jubnl fdbc015dbf fix(memories): re-fetch EXIF info when navigating between lightbox photos
The navigateTo function was clearing lightboxInfo without re-fetching it,
causing the EXIF sidebar to disappear and nav button placement to break.
Mirrors the fetch logic already present in the thumbnail click handler.

Fixes #439
2026-04-05 22:30:05 +02:00
github-actions[bot] 7d8e3912b4 chore: bump version to 2.9.1 [skip ci] 2026-04-05 20:20:56 +00:00
github-actions[bot] 9718187490 chore: bump version to 2.9.0 [skip ci] 2026-04-05 19:38:21 +00:00
jubnl 955776b492 fix(LF): Normalize file to LF 2026-04-05 21:30:32 +02:00
Julien G. 9b11abbf4a Merge pull request #434 from jerryhuangyu/feat/support-zh
feat(i18n): add Traditional Chinese (zh-TW) language support
2026-04-05 21:18:02 +02:00
Maurice 48bf149d01 feat(packing): item quantity, bag rename, multi-user bags, save as template
- Add quantity field to packing items (persisted, visible per item)
- Bags are now renamable (click to edit in sidebar)
- Bags support multiple user assignments with avatar display
- New packing_bag_members table for multi-user bag ownership
- Save current packing list as reusable template
- Add bag members API endpoint (PUT /bags/:bagId/members)
- Migration 74: quantity on packing_items, user_id on packing_bags, packing_bag_members table
2026-04-05 19:28:33 +02:00
Maurice f3679739d8 fix(reservations): format check-in/out times with user's time format setting
Respects 12h/24h preference for hotel check-in and check-out display.
2026-04-05 18:19:46 +02:00
Maurice 38206883ff feat(budget): bidirectional sync between reservations and budget items
- Link budget items to reservations via reservation_id column
- Update budget entry when reservation price changes (not create duplicate)
- Delete budget entry when reservation price is cleared
- Sync price back to reservation when edited in budget panel
- Lock budget item name when linked to a reservation
- Add migration 73 for reservation_id on budget_items
2026-04-05 18:16:02 +02:00
jerryhuangyu dd21074c27 feat: Add Traditional Chinese (zh-TW) translations support 2026-04-05 23:53:26 +08:00
Maurice cd5a6c7491 ui(settings): add about text, community links and bug/feature/wiki cards
- Add TREK description and "Made with heart" text to About tab (all 13 languages)
- Add Report Bug, Feature Request and Wiki cards to About tab and Admin GitHub panel
- Version shown as inline badge
2026-04-05 17:53:15 +02:00
Maurice 6e6e0a370e ui(settings): add Ko-fi, Buy Me a Coffee and Discord cards to About tab 2026-04-05 17:33:16 +02:00
Maurice 83bac11173 ui(trip): replace plane loading animation with TREK logo GIF
- Use animated TREK logo instead of plane SVG on trip loading screen
- Dark/light mode aware (switches GIF based on theme)
2026-04-05 17:28:04 +02:00
jubnl c6148ba4f2 fix(mfa): generate SVG QR code
Replace the rasterized 180px PNG QR code with a crisp 250px SVG
2026-04-05 17:15:19 +02:00
Maurice d5cc2432c4 fix(i18n): escape apostrophes in French dayCountHint translation 2026-04-05 16:25:32 +02:00
Maurice 7f077d949d feat(trips): add configurable day count for trips without dates
- Show day count input in trip form when no start/end date is set
- Backend accepts day_count param for create and update
- Remove forced date assignment for dateless trips (was always setting tomorrow + 7)
- Fix off-by-one: single-date fallback now creates 7 days instead of 8
- Add dayCount/dayCountHint translations for all 13 languages
2026-04-05 16:25:09 +02:00
Maurice a9d6ce87c1 Merge pull request #336 from tiquis0290/test
Adding support for SynologyPhoto (immich like) and adding support to use more photo proiders not just immich
2026-04-05 15:08:50 +02:00
Maurice 67b21d5fe3 i18n(admin): rename tabs and merge notification panels
- Configuration → Personalization (all 13 languages)
- Merge Notification Channels + Admin Notifications into single Notifications tab
- Audit Log → Audit (all 13 languages)
2026-04-05 14:46:36 +02:00
Marek Maslowski 4a0d586768 fix for not calling api route on fetch 2026-04-05 11:54:51 +02:00
Marek Maslowski 079964bec8 making helper functions for building urls 2026-04-05 11:50:34 +02:00
Marek Maslowski b0b85fff3a fix for settings page 2026-04-05 11:08:58 +02:00
Marek Maslowski b8c3d5b3d1 Merge branch 'dev' into test 2026-04-05 10:26:09 +02:00
jubnl 959015928f feat(security): mask saved webhook URLs instead of returning encrypted values
Encrypted webhook URLs are no longer returned to the frontend. Both user
and admin webhook fields now show '••••••••' as a placeholder when a URL
is already saved, and the sentinel value is skipped on save/test so the
stored secret is never exposed or accidentally overwritten.
2026-04-05 06:08:44 +02:00