Skip to content

Commit 09601c2

Browse files
authored
Merge pull request #5 from aligneddev/tests
Add Automated Tests and CI Action
2 parents 84124ef + 24f1479 commit 09601c2

29 files changed

Lines changed: 3380 additions & 288 deletions

.github/workflows/ci.yaml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
name: ci
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- main
8+
9+
permissions:
10+
contents: read
11+
12+
concurrency:
13+
group: ci-${{ github.ref }}
14+
cancel-in-progress: true
15+
16+
jobs:
17+
verify:
18+
runs-on: ubuntu-latest
19+
timeout-minutes: 40
20+
env:
21+
CI: "true"
22+
DOTNET_NOLOGO: "true"
23+
DOTNET_CLI_TELEMETRY_OPTOUT: "1"
24+
25+
steps:
26+
- name: Checkout
27+
uses: actions/checkout@v4
28+
29+
- name: Setup .NET from global.json
30+
uses: actions/setup-dotnet@v4
31+
with:
32+
global-json-file: global.json
33+
34+
- name: Setup Node.js
35+
uses: actions/setup-node@v4
36+
with:
37+
node-version: 24
38+
cache: npm
39+
cache-dependency-path: package-lock.json
40+
41+
- name: Restore .NET dependencies
42+
run: dotnet restore BikeTracking.slnx
43+
44+
- name: Run backend tests
45+
run: dotnet test BikeTracking.slnx --configuration Release --no-restore --verbosity minimal
46+
47+
- name: Install frontend dependencies
48+
working-directory: BikeTracking.Frontend
49+
run: npm ci
50+
51+
- name: Install Playwright browser and system dependencies
52+
working-directory: BikeTracking.Frontend
53+
run: npx playwright install --with-deps chromium
54+
55+
- name: Frontend lint
56+
working-directory: BikeTracking.Frontend
57+
run: npm run lint
58+
59+
- name: Frontend build
60+
working-directory: BikeTracking.Frontend
61+
run: npm run build
62+
63+
- name: Frontend unit tests
64+
working-directory: BikeTracking.Frontend
65+
run: npm run test:unit
66+
67+
- name: Frontend end-to-end tests
68+
working-directory: BikeTracking.Frontend
69+
run: npm run test:e2e
70+
71+
- name: Upload Playwright artifacts on failure
72+
if: failure()
73+
uses: actions/upload-artifact@v4
74+
with:
75+
name: playwright-artifacts
76+
path: |
77+
playwright-report
78+
test-results
79+
if-no-files-found: ignore
80+
retention-days: 14
81+
82+
- name: Cleanup sqlite files
83+
if: always()
84+
run: |
85+
rm -f biketracking.local.db
86+
rm -f biketracking.local.db-shm
87+
rm -f biketracking.local.db-wal

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,6 @@ paket-files/
6060

6161
src/.vs/*
6262

63-
.fake
63+
.fake
64+
src/BikeTracking.Frontend/test-results/
65+
src/BikeTracking.Frontend/playwright-report/

.specify/memory/constitution.md

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
# Bike Tracking Application Constitution
2-
<!-- Sync Impact Report v1.10.1
3-
Rationale: Clarified the local deployment approach for end-user machines by standardizing SQLite local-file storage as the default profile and documenting safety expectations for storage path and upgrades.
2+
<!-- Sync Impact Report v1.10.2
3+
Rationale: Codified a mandatory post-change verification command matrix so every change runs explicit checks before merge.
44
Modified Sections:
5-
- Mission > Decision Record: Added rationale for SQLite local-file default on user machines
6-
- Technology Stack Requirements > Data & Persistence: Clarified local database default and user-machine storage profile
7-
- Guardrails: Added explicit local SQLite file safety rule for user-machine installs
8-
Status: Approved — local user-machine deployments default to SQLite local-file storage for simplicity and offline reliability
5+
- Development Workflow: Added mandatory post-change verification matrix and command requirements
6+
- Definition of Done: Requires matrix execution evidence for changed scope
7+
- Compliance Audit Checklist: Requires matrix execution and recorded evidence
8+
- Guardrails: Added non-negotiable requirement to run matrix commands after every change
9+
Status: Approved — impacted-layer checks are mandatory after any change; auth/cross-layer changes also require E2E verification
910
Previous Updates:
11+
- v1.10.1: Clarified the local deployment approach for end-user machines by standardizing SQLite local-file storage as the default profile and documenting safety expectations for storage path and upgrades.
1012
- v1.10: Added an explicit engineering mindset for small-batch experimentation, continuous learning, complexity management, mandatory change validation, and proactive security teaching/remediation.
1113
- v1.9: Replaced Blazor WebAssembly frontend direction with Aurelia 2. Updated Principle V and all frontend-related sections for consistency. Added an explicit rule to always reference official Aurelia documentation at https://docs.aurelia.io/.
1214
- v1.8: Scoped Aspire Dashboard to local development only; removed cloud Aspire Dashboard requirement. Clarified local-first deployment priority with Azure as a future target. Strengthened public GitHub repository secret safety guidance.
@@ -168,12 +170,30 @@ Example: "User records a bike ride" slice includes:
168170
- Background function listening to CES to update RideProjection
169171
- Aspire AppHost configuration for frontend + API + database orchestration; Azure CLI deployment scripts for Static Web Apps (frontend) and Container Apps (API)
170172

171-
run `csharpier format .` to enforce code formatting (document in readme.md, `dotnet tool install csharpier -g` is needed); run `dotnet format .` (built-in .NET tool) uses .editorconfig for formatting rules and supports more granular control (e.g., namespace matching, file-scoped namespaces).
173+
Run `csharpier format .` to enforce code formatting (`dotnet tool install csharpier -g` is required). Run `dotnet format .` for additional .editorconfig-driven diagnostics.
172174

173-
Best Practice: Use CSharpier for consistent formatting and dotnet format for linting and code style enforcement (e.g., dotnet_diagnostic.IDE0130.severity=error in .editorconfig).
174-
run Typescript linting and formatting via `npm run lint` and `npm run format` in the frontend directory.
175+
Best Practice: Use CSharpier for consistent formatting and dotnet format for linting/code-style enforcement (for example, dotnet_diagnostic.IDE0130.severity=error).
175176

176-
Test` to run tests; `dotnet run --project src/BikeTracking.AppHost` to start local stack; GitHub Actions for CI/CD to Azure.
177+
Run TypeScript linting and formatting via `npm run lint` and `npm run format` in the frontend directory.
178+
179+
Use `dotnet run --project src/BikeTracking.AppHost` to start the local stack; use GitHub Actions for CI/CD to Azure.
180+
181+
### Post-Change Verification Matrix (Mandatory After Any Change)
182+
183+
After **every** code change, run verification commands based on the changed scope. These checks are required before merge and before phase transitions.
184+
185+
1. **Frontend-only changes** (React/TypeScript/CSS, frontend config):
186+
- `cd src/BikeTracking.Frontend`
187+
- `npm run lint`
188+
- `npm run build`
189+
- `npm run test:unit`
190+
2. **Backend/domain-only changes** (API, F#, persistence, .NET configuration):
191+
- `dotnet test`
192+
3. **Authentication/login/cross-layer changes** (routes, auth context, identify endpoint/service, contracts, frontend+backend touches):
193+
- Run **all impacted-layer commands** above
194+
- Additionally run `cd src/BikeTracking.Frontend && npm run test:e2e`
195+
196+
Evidence from these command runs (terminal output or CI artifacts) must be attached to the work item or PR notes.
177197

178198

179199
### Vertical Slice Implementation Strategy: Minimal-First Approach
@@ -206,6 +226,7 @@ A vertical slice is **production-ready** only when all items are verified:
206226
- [ ] Implementation complete; all tests passing (green + refactor phases)
207227
- [ ] Code review: architecture compliance verified, naming conventions followed, validation discipline observed
208228
- [ ] Change validation complete: compile succeeds, coding standards checks pass, automated behavior tests pass
229+
- [ ] Post-change verification matrix executed for the impacted scope and evidence recorded
209230
- [ ] Feature branch deployed locally via `dotnet run` (entire Aspire stack: frontend, API, database)
210231
- [ ] Integration tests pass; manual E2E test via Playwright (if critical user journey)
211232
- [ ] All validation layers implemented: client-side (React validation), API (DTO DataAnnotations), database (constraints)
@@ -313,6 +334,7 @@ Tests suggested by agent must receive explicit user approval before implementati
313334
- [ ] Data validation implemented at three layers: client (React), API (Minimal API), database (constraints)
314335
- [ ] Test coverage for domain logic ≥85%; F# discriminated unions and ROP patterns tested
315336
- [ ] Every change validated: compile/build, coding standards, automated tests, and pipeline deployment checks
337+
- [ ] Post-change verification matrix executed for the changed scope (frontend, backend/domain, or auth/cross-layer) with evidence captured
316338
- [ ] Security issues recognized, explained, and remediated (or explicitly accepted by user)
317339
- [ ] All SAMPLE_/DEMO_ data removed from code before merge
318340
- [ ] Secrets NOT committed; `.gitignore` verified; pre-commit hook prevents credential leakage
@@ -348,6 +370,7 @@ Breaking these guarantees causes architectural decay and technical debt accrual:
348370
- **Event schema is append-only** — never mutate existing events. If schema changes needed, create new event type and version old events. Immutability is non-negotiable.
349371
- **F# domain types must marshal through EF Core value converters** — no raw EF entities exposed to C# API layer. C# records serve as API DTOs; converters handle F#-to-C# translation.
350372
- **Tests must pass before merge** — no exceptions, no "fix later" debt. CI/CD pipeline blocks merge if test suite fails.
373+
- **Post-change verification matrix must run after any change** — no change is complete without executing required commands for impacted scope; auth/cross-layer changes also require `npm run test:e2e`.
351374
- **Three-layer validation enforced** — if field validated in React form, also validated in API DTOs and database constraints. No single-layer validation.
352375
- **OAuth token required on all user endpoints** — anonymous access forbidden for personal data. Public data endpoints explicitly marked; separate authorization logic. (Optional for single-user local deployment; mandatory for cloud/multi-user.)
353376
- **SAMPLE_/DEMO_ data never in production** — automated linting prevents prefixed data from deploying. Merge blocked if test data detected.
@@ -437,5 +460,5 @@ Always commit before continuing to a new phase.
437460

438461
---
439462

440-
**Version**: 1.10.1 | **Ratified**: 2026-03-03 | **Last Amended**: 2026-03-16
463+
**Version**: 1.10.2 | **Ratified**: 2026-03-03 | **Last Amended**: 2026-03-18
441464

BikeTracking.slnx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<Solution>
22
<Folder Name="/src/">
33
<Project Path="src/BikeTracking.Api/BikeTracking.Api.csproj" />
4+
<Project Path="src/BikeTracking.Api.Tests/BikeTracking.Api.Tests.csproj" />
45
<Project Path="src/BikeTracking.AppHost/BikeTracking.AppHost.csproj" />
56
<Project Path="src/BikeTracking.Domain.FSharp/BikeTracking.Domain.FSharp.fsproj" />
67
<Project Path="src/BikeTracking.Frontend/BikeTracking.Frontend.esproj" />

README.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Local-first Bike Tracking application built with .NET Aspire orchestration, .NET
2121
## Prerequisites
2222

2323
- .NET SDK 10.x
24-
- Node.js 20+ and npm
24+
- Node.js 24+ and npm
2525
- CSharpier global tool (required for formatting checks):
2626

2727
```powershell
@@ -76,6 +76,15 @@ For local-first deployment to end-user machines, the default persistence model i
7676
- Before schema upgrades, create a safety backup copy of the SQLite file.
7777
- Use SQL Server LocalDB or SQL Server Express only when local multi-user requirements exceed the single-user SQLite profile.
7878

79-
## Next Step
8079

81-
Continue with task execution and verification using specs/001-user-signup-pin/tasks.md.
80+
## Automated Tests
81+
82+
frontend unit tests: `npm run test:unit` (Vitest)
83+
84+
frontend end-to-end tests: `npm run test:e2e` (Playwright)
85+
- These use the local SQLlite database, so they are more like integration tests. The values are thrown away after each test, but they do test the full stack of the API and database layers.
86+
87+
backend tests: `dotnet test` from repo root (xUnit)
88+
89+
These are ran in the .github\workflows\ci.yml pipeline on every PR
90+

0 commit comments

Comments
 (0)