Skip to content

Tests against a real PostgreSQL, specs for the untested views and map layers, and a compact trip format for the map - #522

Merged
joszz merged 4 commits into
mainfrom
claude/gallant-rubin-ihbf2v
Oct 19, 2026
Merged

joszz merged 4 commits into
mainfrom
claude/gallant-rubin-ihbf2v

Conversation

@joszz

@joszz joszz commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

Pull Request

Summary

P5 from the project review (the gaps in the tests), and #15 from P2 (the map's trip download).

  • test: the repositories against a real PostgreSQL. 17 tests for what the in-memory provider cannot answer: every migration on an empty database, unique and filtered indexes, concurrency tokens, ExecuteUpdate/ExecuteDelete, the SQL the trip, telemetry, settings, climate schedule, housekeeping and notification queries become, and NOTIFY. Each test gets a copy of a template the migrations build once per run, dropped afterwards. They need GARAGESTACK_TEST_POSTGRES: without it they skip locally and fail in CI (CI=true), so they cannot pass there by not running. The backend-test job now starts a postgres:18-alpine service for them. CONTRIBUTING.md and ARCHITECTURE.md say how to run them.
  • test(frontend): the views and composables that had no spec. DashboardView, StatisticsView, TripLogView and MapView (what each loads, when it loads again, empty and error states, hiding and joining trips, the parking map, the month table, Find car, the snapped pill), and useTripLayers and usePoiLayers, with Leaflet and the tile layers replaced by recorders (line and marker drawing, selection, speed and speed limit colours, layer applicability per drivetrain, the power, brand and fuel-type filters, popups). Each mount gets the test's pinia as a plugin and every store the test reads names it: relying on the active pinia made the dashboard's "reload after a trip" test fail about one full run in four, because the active one had changed between the mount and the assertion (0 failures in 15 full runs since).
  • feat(map): an opt-in compact trip format. GET .../trips?format=compact (CompactTripDto) serves the same trips with their fixes as an encoded polyline at six decimals (PolylineCodec, about 10 cm), the milliseconds from each fix to the next, and the speeds. On a synthetic month of driving (6,000 fixes) that is 39 KB gzipped instead of 82 KB. The intervals are taken between rounded offsets from the start, so every fix's time stays within half a millisecond however long the trip. The map asks for it and vehicleApi.trips unpacks it into the plain Trip shape, so nothing past the client changes. The plain format stays the default, so scripts reading /trips with an API token are not affected; any other format value is a 400 trip.unknownFormat.

Type of Change

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Documentation
  • Dependency update
  • Other (tests and CI)

Related Issues

Follows #521.

Checklist

  • Tests added or updated (17 PostgreSQL, 55 frontend view and composable tests; the compact format packed and unpacked in TripDtoTests and vehicleApi.spec.ts against an independently encoded polyline, and compared fix by fix with the plain format through the demo stack)
  • Linting passes: vue-tsc, oxlint, eslint, prettier, dotnet format --verify-no-changes; 1478 backend tests (PostgreSQL ones included) and 1197 frontend tests locally
  • No secrets or personal data committed
  • Responsive on mobile: no UI change
  • i18n keys added for any new UI strings: none added
  • If unraid/garagestack.xml changed: not changed

The PostgreSQL service in CI is new: this PR's run is its first. Not checked here: the map against the compact format in a browser (the client unpacks into the same shape the map already draws).

🤖 Generated with Claude Code

https://claude.ai/code/session_01L6DtW2eHhipteRopmy3cif

Most backend tests use EF's in-memory database, which has no indexes,
transactions, concurrency tokens or bulk updates, so what only PostgreSQL decides
went untested. GarageStack.Tests/Postgres runs it against a real server: every
migration from an empty database (and back three and forward), the unique trip
index and its transaction, hidden trips and joins in SQL, the partial telemetry
UPDATE and NOTIFY, the model-derived filters behind the merged status and the
daily statistics, concurrent settings saves, the climate schedule version
token, and the bulk deletes and updates of housekeeping and notifications.

Each test gets a database copied from a template migrated once per run. The
server comes from GARAGESTACK_TEST_POSTGRES; without it the tests skip locally
and fail in CI, whose backend job now runs a postgres:18 service.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L6DtW2eHhipteRopmy3cif
…ws and the map layers

Specs for the four views that had none (what each loads, when it loads again,
its empty and error states, hiding and joining trips) and for useTripLayers and
usePoiLayers, with Leaflet and the tile layers replaced by recorders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L6DtW2eHhipteRopmy3cif
@joszz
joszz enabled auto-merge October 19, 2026 20:43
Under a full test run the active pinia was sometimes another one by the time
a test read its store, so the dashboard spec saw no reload after a trip ended
about one run in four. Each mount now gets the test's pinia as a plugin, and
every store the test reads names it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L6DtW2eHhipteRopmy3cif
GET .../trips?format=compact serves the same trips with their fixes as an
encoded polyline (six decimals), the milliseconds from each fix to the next and
the speeds: a month of driving is about half the download. The map asks for it
and unpacks it in vehicleApi.trips, so nothing past the client changes. The
plain format stays the default, for scripts reading it with an API token.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L6DtW2eHhipteRopmy3cif
@joszz joszz changed the title Tests against a real PostgreSQL, and specs for the untested views and map layers Tests against a real PostgreSQL, specs for the untested views and map layers, and a compact trip format for the map Oct 19, 2026
@joszz
joszz merged commit e895c92 into main Oct 19, 2026
21 checks passed
@joszz
joszz deleted the claude/gallant-rubin-ihbf2v branch October 19, 2026 21:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants