Squash and merge of version-0.1 Co-authored-by: James Wampler <james@wamp.dev> Co-committed-by: James Wampler <james@wamp.dev>
78 lines
3.3 KiB
Markdown
Executable File
78 lines
3.3 KiB
Markdown
Executable File
# MicCheck.Api ASP.NET Project — Implementation Output
|
|
|
|
All source files have been created. The `dotnet` CLI is not on the PATH in the current shell session, so the build and tests could not be run. See setup instructions below.
|
|
|
|
## Getting Started
|
|
|
|
```bash
|
|
# If dotnet is not on your PATH, install the SDK:
|
|
wget https://dot.net/v1/dotnet-install.sh && bash dotnet-install.sh --channel 10.0
|
|
source ~/.bashrc
|
|
|
|
# Then from the repo root:
|
|
cd /home/james/src/mic-check
|
|
dotnet build MicCheck.slnx # 0 errors expected
|
|
dotnet test MicCheck.slnx # 7 tests expected to pass
|
|
```
|
|
|
|
---
|
|
|
|
## Files Created
|
|
|
|
### Solution (`/`)
|
|
- `MicCheck.slnx` — XML solution file with `/src/` and `/tests/` solution folders
|
|
|
|
### API Project (`src/api/MicCheck.Api/`)
|
|
- `MicCheck.Api.csproj` — `net10.0`, nullable enabled, LangVersion latest
|
|
- `Program.cs` — OpenAPI + Scalar UI + JWT bearer auth + `ITokenService` DI registration
|
|
- `appsettings.json` — JWT config (`SecretKey`, `Issuer`, `Audience`, `ExpiryMinutes`)
|
|
- `appsettings.Development.json` — debug-level logging for development
|
|
- `Auth/TokenRequest.cs` — `record TokenRequest(string Username, string Password)`
|
|
- `Auth/TokenResponse.cs` — `record TokenResponse(string Token, DateTime ExpiresAt)`
|
|
- `Auth/ITokenService.cs` — service interface
|
|
- `Auth/TokenService.cs` — JWT generation using `System.IdentityModel.Tokens.Jwt`
|
|
- `Auth/AuthEndpoints.cs` — `POST /auth/token`, 400 on empty credentials, 200 + token on success
|
|
|
|
### Test Project (`tests/api/MicCheck.Api.Tests.Unit/`)
|
|
- `MicCheck.Api.Tests.Unit.csproj` — NUnit 4.5.1 + Moq 4.20.72 + `Microsoft.AspNetCore.Mvc.Testing`
|
|
- `Auth/TokenServiceTests.cs` — 4 BDD tests directly against `TokenService`
|
|
- `Auth/AuthEndpointsTests.cs` — 3 BDD tests via `WebApplicationFactory<Program>` with mocked `ITokenService`
|
|
|
|
---
|
|
|
|
## Stack
|
|
|
|
| Concern | Technology |
|
|
|---|---|
|
|
| Framework | .NET 10 (`net10.0`) |
|
|
| API style | ASP.NET Minimal API |
|
|
| OpenAPI document | `Microsoft.AspNetCore.OpenApi` 10.0.5 |
|
|
| OpenAPI UI | `Scalar.AspNetCore` 2.5.14 (available at `/scalar/v1` in Development) |
|
|
| JWT | `System.IdentityModel.Tokens.Jwt` 8.16.0 + `Microsoft.AspNetCore.Authentication.JwtBearer` 10.0.5 |
|
|
| Test framework | NUnit 4.5.1 + NUnit3TestAdapter 6.2.0 + Microsoft.NET.Test.Sdk 18.3.0 |
|
|
| Mocking | Moq 4.20.72 |
|
|
|
|
---
|
|
|
|
## Endpoints
|
|
|
|
| Method | Path | Description |
|
|
|---|---|---|
|
|
| `POST` | `/auth/token` | Returns a JWT for the provided username/password |
|
|
| `GET` | `/openapi/v1.json` | OpenAPI document (Development only) |
|
|
| `GET` | `/scalar/v1` | Scalar API UI (Development only) |
|
|
|
|
---
|
|
|
|
## Test Cases
|
|
|
|
| Class | Test | Coverage |
|
|
|---|---|---|
|
|
| `TokenServiceTests` | `WhenAUsernameIsProvided_ThenATokenIsReturned` | Token is non-empty |
|
|
| `TokenServiceTests` | `WhenATokenIsGenerated_ThenItContainsTheUsernameAsSubjectClaim` | JWT `sub` claim |
|
|
| `TokenServiceTests` | `WhenATokenIsGenerated_ThenItHasAFutureExpiry` | Expiry is in the future |
|
|
| `TokenServiceTests` | `WhenATokenIsGenerated_ThenItHasTheConfiguredIssuer` | JWT `iss` claim |
|
|
| `AuthEndpointsTests` | `WhenUsernameIsEmpty_ThenBadRequestIsReturned` | 400 on empty username |
|
|
| `AuthEndpointsTests` | `WhenPasswordIsEmpty_ThenBadRequestIsReturned` | 400 on empty password |
|
|
| `AuthEndpointsTests` | `WhenValidCredentialsAreProvided_ThenOkIsReturnedWithToken` | 200 + token body |
|