# Test Generation: Coverage Requirements & Categories

> Referenced from `steps/step-07-tests.md` — Test coverage minimums and category definitions.

---

## Minimum Test Coverage Per Category

| Category | Minimum Tests | Focus Areas |
|----------|---------------|------------|
| Controller (mock) | 10 | CRUD routing, auth/tenant handling, error responses |
| Controller (real integration) | 8 | CRUD with actual DB persistence, tenant isolation, 404/409 cases |
| Service | 8 | Business logic, CRUD, error handling, edge cases |
| Entity | 5 | Factory method, property updates, validation, soft delete |
| Validator | 8 | Code validation, name validation, security rules |
| Repository | 8 | CRUD, tenant filtering, pagination, indexes |
| Security | 10 | Auth bypass attempts, injection attacks, header validation |

**Total minimum:** ~67 tests per entity

---

## Real Integration Test Coverage

Integration tests (with actual DB):
- GET all → 200 with list
- GET by ID → 200 when exists, 404 when not
- POST → 201/200 when valid, persist to DB, read back to verify
- POST → 400 when invalid data
- POST → 409 when duplicate code
- PUT → 200 when valid, persist changes, read back to verify
- PUT → 404 when not exists
- DELETE → 204 when exists
- DELETE → 404 when not exists
- Tenant isolation → create in tenant A, invisible in tenant B (REAL DB)
- Authorization → 401 when not authenticated

---

## Test Naming Convention (BLOCKING)

All test methods MUST follow: `{Method}_When{Condition}_Should{Result}`

**FORBIDDEN patterns:**
- `Test1`, `Test2`, `TestMethod`, `MyTest`
- `Should_Return_OK`, `test_get_all`

**REQUIRED pattern:**
```csharp
GetAll_WhenCalled_ShouldReturn200WithList
Create_WhenDuplicateCode_ShouldThrowException
Delete_WhenNotAuthenticated_ShouldReturn401
```

---

## Test Structure (BLOCKING)

All tests MUST follow Arrange-Act-Assert:

```csharp
// CORRECT
[Fact]
public async Task GetById_WhenExists_ShouldReturn200()
{
    // Arrange
    var id = Guid.NewGuid();
    // ... setup

    // Act
    var response = await _client.GetAsync($"/api/{entityCode}/{id}");

    // Assert
    response.StatusCode.Should().Be(HttpStatusCode.OK);
}

// FORBIDDEN - No structure
[Fact]
public void TestGetById()
{
    var response = _client.GetAsync("/api/product/1");
    Assert.Equal(200, response.StatusCode);
}
```

---

## Dependencies Check (BLOCKING)

Verify test project uses:
- `FluentAssertions` (NOT `Assert.Equal`)
- `Moq` (NOT manual fakes)
- `xunit` (NOT NUnit or MSTest)

---

## Test Categories

### 1. Controller Mock Tests

Unit tests with mocked dependencies:
- Routing validation
- Authentication/Authorization
- Error response formatting
- Input validation

```csharp
[Fact]
public async Task GetAll_WhenCalled_ShouldReturn200WithList()
{
    // Mock service
    _mockService.Setup(s => s.GetAllAsync(It.IsAny<CancellationToken>()))
        .ReturnsAsync(new List<ProductDto>());

    // Act & Assert
    ...
}
```

### 2. Controller Integration Tests

REAL tests with actual DB (via WebApplicationFactory):
- Full HTTP flow
- Database persistence
- Tenant isolation
- Query validation

### 3. Service Tests

Unit tests for business logic:
- CRUD operations
- Error handling
- Validation logic

### 4. Entity Tests

Domain model tests:
- Factory methods
- Property validation
- State transitions
- Soft delete

### 5. Validator Tests

Input validation:
- Code format validation
- Name constraints
- Security rules (XSS, SQL injection detection)

### 6. Repository Tests

Data access tests:
- Query correctness
- Tenant filtering
- Pagination
- Indexes

### 7. Security Tests

OWASP coverage:
- Authentication bypass attempts
- Authorization bypass attempts
- SQL injection attempts
- XSS payload handling
- CSRF token validation
- Tenant isolation breach attempts
- Header injection attempts

---

## Build & Run Checks (BLOCKING)

```bash
# Build
dotnet build tests/{SolutionName}.Tests/{SolutionName}.Tests.csproj

# Run
dotnet test tests/{SolutionName}.Tests/{SolutionName}.Tests.csproj --no-build --verbosity normal
```

**ALL tests MUST pass.** If tests fail:
1. Read the failure output carefully
2. Fix the failing tests or the code they test
3. Re-run until all tests pass
4. Do NOT proceed to the next step until all tests are green

---

## Frontend Test Categories

| File | Category | Focus |
|------|----------|-------|
| `{EntityName}Page.test.tsx` | Page | Loading, error, render with data |
| `{EntityName}ListView.test.tsx` | List | Pagination, filtering, view toggle |
| `{EntityName}DetailPage.test.tsx` | Detail | Tab switching, back navigation |
| `use{EntityName}Preferences.test.ts` | Hooks | State persistence, local storage |
| `{entityName}Api.test.ts` | API Client | MSW mocking, HTTP methods |

---

## Validation Checklist

- [ ] All test methods follow `{Method}_When{Condition}_Should{Result}` naming
- [ ] All tests use Arrange-Act-Assert structure
- [ ] FluentAssertions used throughout (not Assert.Equal)
- [ ] Moq used for mock-based tests only
- [ ] Minimum test count met per category
- [ ] Real integration tests verify DB persistence
- [ ] Security tests cover OWASP top 10 issues
- [ ] Backend tests build successfully
- [ ] **ALL backend tests pass**
- [ ] Frontend tests build successfully
- [ ] **ALL frontend tests pass**
