Skip to content

Commit 0a4e98e

Browse files
committed
Merge branch 'feature/1.5.2-browser-automation-testing' into main
Implements Feature 1.5.2 browser automation testing infrastructure: - CoreIdent.E2E.Tests with Playwright for browser automation - Keycloak integration tests with external provider fixture - OAuth2/OIDC E2E tests for token, JWKS, passkey endpoints - KestrelTestHostFixture for real in-proc HTTP testing All 473 tests pass.
2 parents 56910de + 5c3af94 commit 0a4e98e

20 files changed

Lines changed: 3212 additions & 74 deletions

AGENTS.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# AGENTS.md — Agentic Coding Guidelines for CoreIdent
2+
3+
This file provides instructions for AI coding agents (Claude, Copilot, Cursor, etc.) working on this codebase.
4+
5+
## Build / Test Commands
6+
7+
```bash
8+
# Restore and build entire solution
9+
dotnet restore CoreIdent.sln
10+
11+
# Build (compile only)
12+
dotnet build CoreIdent.sln
13+
14+
# Run all tests
15+
dotnet test CoreIdent.sln
16+
17+
# Run tests with coverage (produces coverage.cobertura.xml)
18+
dotnet test CoreIdent.sln --collect:"XPlat Code Coverage"
19+
20+
# Run single test project
21+
dotnet test tests/CoreIdent.Core.Tests/CoreIdent.Core.Tests.csproj
22+
23+
# Run single test class
24+
dotnet test tests/CoreIdent.Integration.Tests -v n --filter "FullyQualifiedName~TokenEndpointsTests"
25+
26+
# Watch mode (during development)
27+
dotnet watch test --project tests/CoreIdent.Core.Tests
28+
29+
# Format code style
30+
dotnet format
31+
32+
# Build a specific project
33+
dotnet build src/CoreIdent.Core/CoreIdent.Core.csproj
34+
```
35+
36+
## Code Style Guidelines
37+
38+
### General Principles
39+
- **Security first** — Never log secrets, tokens, OTPs, or raw PII. Use redaction helpers for email/phone.
40+
- **Fail fast** — Validate arguments early. Throw `ArgumentNullException` for null required params.
41+
- **One responsibility per class/method** — Keep functions focused and small.
42+
- **Interface-driven design** — All services have interfaces for testability. No `new` for services; inject via constructor.
43+
44+
### C# 14 Conventions
45+
- **File-scoped namespaces**: `namespace Foo;` not `namespace Foo { }`
46+
- **Primary constructors** where appropriate
47+
- **Target-typed new**: `List<string> items = [];` not `new List<string>()`
48+
- **Extension members** for `ClaimsPrincipal` utilities
49+
- **Pattern matching** — Prefer `is` patterns over type checks + casts
50+
51+
### Naming
52+
- Meaningful names; avoid abbreviations except well-known ones (`ct` for CancellationToken is fine)
53+
- Interfaces: `I` prefix (e.g., `ITokenService`)
54+
- Records for DTOs/value objects: suffix with `Request`, `Response`, `Options`, or `Result` as appropriate
55+
56+
### Types & Nullability
57+
- **Nullable reference types enabled** — Fix nullable warnings, don't suppress with `!`
58+
- **No type coercion** (`as any`, `@ts-ignore`, `@ts-expect-error`, etc.)
59+
- Prefer `record` types for DTOs and value objects
60+
- Use `CancellationToken` with default value in async APIs
61+
62+
### Imports & Formatting
63+
- Remove unused usings before committing
64+
- Run `dotnet format` when touching many files
65+
- Follow existing style in the file you're editing
66+
67+
### NuGet Package Management
68+
- **Prefer `dotnet add package` over manual XML edits** — This ensures consistent formatting and version resolution
69+
```bash
70+
# Correct way to add a package
71+
dotnet add tests/CoreIdent.Testing/CoreIdent.Testing.csproj package Microsoft.Playwright
72+
73+
# Avoid: Manually editing .csproj XML
74+
```
75+
- When manually adding packages is unavoidable, follow the existing `<PackageReference>` formatting in the project
76+
- Never add comments inside `<ItemGroup>` blocks that describe why a package is added (commit messages serve this purpose)
77+
78+
### Error Handling
79+
- **No empty catch blocks** — Always handle or log exceptions
80+
- Use structured logging with `ILogger<T>`
81+
- Include correlation context in logs
82+
83+
### XML Documentation
84+
- **All public APIs require XML docs** (CS1591 is treated as error)
85+
- User-facing APIs (DI/extension methods/endpoints): add practical guidance in `<remarks>`
86+
87+
### Testing
88+
- **Use Shouldly** with explicit assertion messages:
89+
```csharp
90+
result.ShouldNotBeNull("Token should be issued on successful authentication");
91+
client.AllowedScopes.ShouldContain("openid", "OIDC scope must be allowed");
92+
```
93+
- **Coverage gate**: Changes to `src/CoreIdent.Core/` require **>= 90% normalized merged line coverage**
94+
- Write tests *before* or *alongside* implementation, not after
95+
- Never commit code that breaks existing tests
96+
97+
### Commit Discipline
98+
- **One feature per commit** — No multi-feature commits
99+
- **Atomic commits** — Each commit should build and pass tests independently
100+
- **Conventional commits**: `feat:`, `fix:`, `test:`, `docs:`, `chore:`, `refactor:`
101+
- **No AI co-authorship** in commit messages
102+
103+
## Essential Documentation
104+
105+
| Document | Purpose |
106+
|----------|---------|
107+
| [`CLAUDE.md`](CLAUDE.md) | **Primary** — Complete development guidelines |
108+
| [`docs/DEVPLAN.md`](docs/DEVPLAN.md) | Task-level checklist and roadmap |
109+
| [`docs/Technical_Plan.md`](docs/Technical_Plan.md) | Technical specifications and RFC links |
110+
| [`docs/Project_Overview.md`](docs/Project_Overview.md) | Architecture and vision |
111+
| [`index.md`](index.md) | Component and folder overview |
112+
113+
## Before Making Changes
114+
115+
1. Read relevant sections of `DEVPLAN.md` and `Technical_Plan.md`
116+
2. Check existing patterns in similar files
117+
3. Write or outline tests first
118+
4. Run diagnostics: `lsp_diagnostics` on changed files before completing
119+
120+
## What NOT To Do
121+
122+
- Don't commit without tests
123+
- Don't bundle multiple features in one commit
124+
- Don't skip security validation "for now"
125+
- Don't add dependencies without justification
126+
- Don't delete or weaken existing tests
127+
- Don't hardcode configuration values
128+
- Don't log sensitive data
129+
- Don't leave code in broken state

CoreIdent.sln

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoreIdent.Client.Samples",
4949
EndProject
5050
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoreIdent.Server.Samples", "samples\CoreIdent.Server.Samples\CoreIdent.Server.Samples.csproj", "{3358BBBC-5B99-415D-8113-FF763CC9DDA5}"
5151
EndProject
52+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoreIdent.E2E.Tests", "tests\CoreIdent.E2E.Tests\CoreIdent.E2E.Tests.csproj", "{6B54927B-02A8-43EC-AAD0-0749703B4F2D}"
53+
EndProject
5254
Global
5355
GlobalSection(SolutionConfigurationPlatforms) = preSolution
5456
Debug|Any CPU = Debug|Any CPU
@@ -299,6 +301,18 @@ Global
299301
{3358BBBC-5B99-415D-8113-FF763CC9DDA5}.Release|x64.Build.0 = Release|Any CPU
300302
{3358BBBC-5B99-415D-8113-FF763CC9DDA5}.Release|x86.ActiveCfg = Release|Any CPU
301303
{3358BBBC-5B99-415D-8113-FF763CC9DDA5}.Release|x86.Build.0 = Release|Any CPU
304+
{6B54927B-02A8-43EC-AAD0-0749703B4F2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
305+
{6B54927B-02A8-43EC-AAD0-0749703B4F2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
306+
{6B54927B-02A8-43EC-AAD0-0749703B4F2D}.Debug|x64.ActiveCfg = Debug|Any CPU
307+
{6B54927B-02A8-43EC-AAD0-0749703B4F2D}.Debug|x64.Build.0 = Debug|Any CPU
308+
{6B54927B-02A8-43EC-AAD0-0749703B4F2D}.Debug|x86.ActiveCfg = Debug|Any CPU
309+
{6B54927B-02A8-43EC-AAD0-0749703B4F2D}.Debug|x86.Build.0 = Debug|Any CPU
310+
{6B54927B-02A8-43EC-AAD0-0749703B4F2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
311+
{6B54927B-02A8-43EC-AAD0-0749703B4F2D}.Release|Any CPU.Build.0 = Release|Any CPU
312+
{6B54927B-02A8-43EC-AAD0-0749703B4F2D}.Release|x64.ActiveCfg = Release|Any CPU
313+
{6B54927B-02A8-43EC-AAD0-0749703B4F2D}.Release|x64.Build.0 = Release|Any CPU
314+
{6B54927B-02A8-43EC-AAD0-0749703B4F2D}.Release|x86.ActiveCfg = Release|Any CPU
315+
{6B54927B-02A8-43EC-AAD0-0749703B4F2D}.Release|x86.Build.0 = Release|Any CPU
302316
EndGlobalSection
303317
GlobalSection(SolutionProperties) = preSolution
304318
HideSolutionNode = FALSE
@@ -324,5 +338,6 @@ Global
324338
{A90B9D37-39B3-4AE4-8AE1-52E5A02CB200} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
325339
{08E5F2CA-FB60-4E61-B0B3-ADBD6743C19F} = {5D20AA90-6969-D8BD-9DCD-8634F4692FDA}
326340
{3358BBBC-5B99-415D-8113-FF763CC9DDA5} = {5D20AA90-6969-D8BD-9DCD-8634F4692FDA}
341+
{6B54927B-02A8-43EC-AAD0-0749703B4F2D} = {0AB3BF05-4346-4AA6-1389-037BE0695223}
327342
EndGlobalSection
328343
EndGlobal

0 commit comments

Comments
 (0)