Skip to content

Add API integration tests, return 400 for client errors and fix vulnerable dependencies - #3

Merged
kris7011 merged 2 commits into
mainfrom
test/api-integration-tests
Oct 16, 2026
Merged

kris7011 merged 2 commits into
mainfrom
test/api-integration-tests

Conversation

@kris7011

Copy link
Copy Markdown
Owner

Independent of #1 and #2 (targets main). The existing .NET CI runs on it.

Problem

  • The API layer had no tests. The 59 unit tests cover Domain and Application well, but nothing tested endpoints, model binding, status codes, JSON contracts, EF Core migrations or the SQLite repositories.
  • 500 on a client error. POST /api/load-analysis with assignEmployee: true for a shift whose skill the employee lacks threw InvalidOperationException in Shift.AssignEmployee. The global middleware turned that into 500 "An unexpected error occurred." I reproduced this against the running API.
  • Inconsistent error bodies. The employee and shift endpoints return 400 { "error": "..." }, while /api/schedule/generate and /api/schedule/simulate returned a bare JSON string.
  • The connection string was hard-coded (Data Source=shiftplanner.db) in AddInfrastructure, so the API could not be pointed at a test database (or any other database) without a code change.
  • Two high-severity transitive vulnerabilities: SQLitePCLRaw.lib.e_sqlite3 2.1.10 (GHSA-2m69-gcr7-jv3q) via EF Core 9.0.7, and Microsoft.OpenApi 2.4.1 (GHSA-v5pm-xwqc-g5wc) via Swashbuckle 10.1.7.

Solution

  1. Dependencies (separate commit, patch/minor updates only): EF Core 9.0.7 → 9.0.21, Microsoft.AspNetCore.OpenApi 9.0.15 → 9.0.21, Swashbuckle 10.1.7 → 10.2.3. dotnet list package --vulnerable --include-transitive is now clean for all projects.
  2. Configurable connection string: read from ConnectionStrings:ShiftPlanner (added to appsettings.json), with the old value as fallback. Default behaviour is unchanged.
  3. public partial class Program, so WebApplicationFactory<Program> can host the API.
  4. Load analysis: checks shift.CanAssign(employee) and returns 400 { error } with the skill and date. The domain rule is unchanged.
  5. Scheduling validation: the same messages, now wrapped as { error }. The frontend only checks response.ok for these calls, so nothing in the UI changes.
  6. New project tests/ShiftPlanner.Api.IntegrationTests with 20 tests. Each test gets its own API instance on an isolated in-memory SQLite database, and EF Core migrations run exactly as in production. No files are written. The tests cover:
    • demo reset/seed
    • overview skill gaps
    • generation persisting assignments, consistent with /api/shifts
    • simulation for coverable and uncoverable shifts, without persisting
    • assignment analysis, load overview, preference profiles, 404s
    • employee creation (201 + Location) and validation
    • load-analysis 400
    • enum-as-string contract

The scheduling logic is unchanged.

Test results

dotnet test
ShiftPlanner.Tests                  → 59 passed
ShiftPlanner.Api.IntegrationTests   → 20 passed

Manual smoke test of the Release build: /swagger/v1/swagger.json → 200 with the new Swashbuckle, POST /api/demo/reset → 10 employees / 14 shifts, load analysis with missing skill → 400 with message (previously 500).

Limitations / findings not changed here

  • RequiredStaff is not persisted. ShiftEntity has no column for it, and ShiftRepository always reads it back as 1. POST /api/shifts with requiredStaff: 3 responds with 3 but stores 1. The scheduling model assigns one employee per shift, so fixing this properly is a domain/migration decision. I left it unchanged and flagged it for review.
  • Repository writes are not wrapped in a transaction during schedule generation (one SaveChanges per assignment). That is fine for the demo, but worth knowing.

🤖 Generated with Claude Code

kris7011 and others added 2 commits October 16, 2026 13:45
- EF Core 9.0.7 -> 9.0.21: SQLitePCLRaw.lib.e_sqlite3 2.1.10 -> 2.1.13
  (GHSA-2m69-gcr7-jv3q, high)
- Swashbuckle.AspNetCore 10.1.7 -> 10.2.3: Microsoft.OpenApi 2.4.1 ->
  2.7.5 (GHSA-v5pm-xwqc-g5wc, high)
- Microsoft.AspNetCore.OpenApi 9.0.15 -> 9.0.21

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Read the SQLite connection string from ConnectionStrings:ShiftPlanner
  (default unchanged) so tests can use an isolated database
- Expose Program to WebApplicationFactory
- POST /api/load-analysis returned 500 when an employee lacked the
  skill for an assigned shift; return 400 with an error message
- Use { error } bodies for scheduling validation errors, matching the
  employee and shift endpoints
- Add 20 WebApplicationFactory tests on in-memory SQLite covering
  demo data, generation, simulation, analysis and validation

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kris7011
kris7011 merged commit 9807fcb into main Oct 16, 2026
1 check passed
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.

1 participant