Generate integration tests for a concrete API controller derived from UmbrellaGenericRepositoryDataServiceApiController (Pattern 2, backing controller service), covering every testable response status code per endpoint including ExistsById and TotalCount. Resolves enablement and authorization flags on the backing data service. Use after integration test infrastructure exists.
Scanned 9/22/2026
Install to Claude Code
npx -y skills add umbrella-libraries/Umbrella --skill umbrella-dotnet-generate-api-data-service-controller-tests --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Umbrella Dotnet Generate Api Data Service Controller Tests?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/umbrella-libraries-umbrella-dotnet-generate-api-data-service-controll)More formats (shields.io, HTML) on the badges page.
---
name: umbrella-dotnet-generate-api-data-service-controller-tests
description: 'Generate integration tests for a concrete API controller derived from UmbrellaGenericRepositoryDataServiceApiController (Pattern 2, backing controller service), covering every testable response status code per endpoint including ExistsById and TotalCount. Resolves enablement and authorization flags on the backing data service. Use after integration test infrastructure exists.'
---
# Generate Data Service Controller Integration Tests
## Purpose
Generate a complete integration test class for a concrete controller derived from `UmbrellaGenericRepositoryDataServiceApiController`, with one or more tests per testable status code per endpoint. The critical Pattern 2 difference: endpoint-enablement flags, authorization-check flags, and all lifecycle hooks live on the **backing data service** (the `TRepositoryDataService` generic argument, typically derived from `UmbrellaRepositoryDataService`), not on the controller. Always locate and read the data service implementation.
The authoritative contract is `docs\api-base-controller-endpoint-map.md` in the Umbrella repository — read it when available.
## Required inputs
As for `umbrella-dotnet-generate-api-repo-controller-tests`:
1. `umbrella-dotnet-audit-api-controller-response-contract` output for the target controller **and its data service**.
2. Working integration test infrastructure via `umbrella-dotnet-audit-aspnetcore-integration-test-readiness` / `umbrella-dotnet-scaffold-aspnetcore-integration-tests`, satisfying the response contract host requirements (claims propagation, configured `validationFailureStatusCode`, non-`Development` environment for `500` shapes, policies/handlers).
3. Anonymous, passing, and denying test identities.
## Endpoint contract
| Endpoint | Statuses |
| --- | --- |
| `GET SearchSlim` | `200`, `401`, `403`, `405`, `422`, `500` |
| `GET` | `200`, `401`, `403`, `404`, `405`, `422`, `500` |
| `POST` | `201`, `400`, `401`, `403`, `405`, `409`, `422`, `500` |
| `PUT` | `200`, `400`, `401`, `403`, `404`, `405`, `409`, `422`, `500` |
| `DELETE` | `204`, `401`, `403`, `404`, `405`, `409`, `422`, `500` |
| `GET ExistsById` | `200`, `401`, `403`, `405`, `422`, `500` |
| `GET TotalCount` | `200`, `401`, `403`, `405`, `500` |
Strike codes the audit marked untestable and never generate tests for them.
## Pattern 2 differences from Pattern 1
Apply the recipes from `umbrella-dotnet-generate-api-repo-controller-tests` with these deltas:
- **Flag resolution**: `SlimReadEndpointEnabled`, `ReadEndpointEnabled`, `CreateEndpointEnabled`, `UpdateEndpointEnabled`, `DeleteEndpointEnabled`, `ExistsByIdEndpointEnabled`, `TotalCountEndpointEnabled` and the five `AuthorizationXxxChecksEnabled` flags are read from the **data service** class. A disabled endpoint returns `405` via a `NotAllowed` operation result.
- **`ExistsById`**: assert `200` with body `true` for a seeded id and `200` with body `false` for a non-existent id. **Never** generate a `404` test — the service maps not-found to `false`. There is no imperative auth check on the default path, so `403` is declarative-policy-only.
- **`TotalCount`**: seed N entities, assert the body equals N. No `422` exists — the endpoint binds no input. `403` is declarative-policy-only.
- **Sorters/filters**: `SearchSlim` binds `SortExpressionDescriptor`/`FilterExpressionDescriptor` collections. Descriptors that cannot be converted to typed expressions are **silently skipped** — do not generate 4xx tests for invalid filter property names; assert they are ignored instead.
- **Hooks**: `Before*`/`After*` conflict and validation hooks live on the data service; the audit's extension-point findings come from there. `POST`/`DELETE` `409` remains extension-point-only.
- **Concurrency**: the `PUT` `409` stamp-rotation recipe is unchanged (create → `GET` stamp A → `PUT` rotates to B → `PUT` with A → `409` with `code = ConcurrencyStampMismatch`), because the data service routes through the same `UmbrellaRepositoryCoreDataService`.
## Test class template
```csharp
[Collection(IndyRecordsSqlServerIntegrationTestCollection.Name)]
public sealed class ArtistsControllerTests
{
private const string ApiUrl = "/api/artists";
private readonly IndyRecordsSqlServerWebApplicationFactory _factory;
public ArtistsControllerTests(IndyRecordsSqlServerWebApplicationFactory factory)
{
_factory = factory;
}
[Fact]
public async Task ExistsByIdAsync_ExistingId_Returns200True()
{
Artist artist = await SeedArtistAsync();
using HttpClient client = _factory.CreateClient();
using HttpResponseMessage response = await client.GetAsync($"{ApiUrl}/ExistsById?id={artist.Id}", TestContext.Current.CancellationToken);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.True(await response.Content.ReadFromJsonAsync<bool>(TestContext.Current.CancellationToken));
}
}
```
Seed through a scoped `DbContext` from the factory, use the `Umbrella.Testing.AspNetCore.Http` problem-details assertion extensions described by the repository-controller generator (including the plain ASP.NET validation helper when Umbrella behavior options are absent), and follow the shared naming convention `<Method>Async_<Scenario>_Returns<Status>`. Capture returned problem details when asserting their fields; otherwise assign the awaited result to `_` for analyzer-clean code.
## Rules
- Generate tests only for codes the contract audit marked testable; document exclusions in a comment block at the top of the test class.
- Assert the validation failure status and body per the host state resolved by the contract audit (Umbrella behavior options default → `422` + `UmbrellaValidationProblemDetails`; explicit `validationFailureStatusCode` → that code; not configured → `400` + plain ASP.NET `ValidationProblemDetails`, no separate malformed-JSON-root test). Never hard-code `422` without checking.
- Satisfy earlier pipeline gates when targeting later ones (existing id + current stamp + valid model for a `PUT` `403`).
- Derive create/update result assertions from the audited data-service hooks and mappers. If they populate a Dynamic Image URL/version-token pair, assert both values and the retained/replaced file behavior; do not expect output-only properties to remain empty simply because the request omitted them.
- Keep tests independent with uniquely seeded data.
- Put every created or mutated resource behind `try`/`finally`, and use `CancellationToken.None` for cleanup/restoration so test cancellation cannot contaminate later tests.
- Reuse application-local test-data builders for repeated domain graphs while keeping response assertions, identity requests, and feature-specific request construction separate.
- Do not weaken production authorization; use the denying identity.
## Validation
```powershell
dotnet build "<TestProject>"
dotnet test "<TestProject>" --no-restore --no-build --verbosity minimal
```
## Analyzer compatibility
Before finishing, read `.ai-shared\bundles\umbrella\analyzer-compatibility.md` and build the affected projects with their installed analyzers enabled. Treat diagnostics introduced by the generated or changed code as defects in this workflow.
## Output
Report: endpoints covered, status codes tested per endpoint, codes excluded with reasons, the data service class audited, shared assertion APIs used or compatibility fallbacks added, and test run results.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!