# adas-core.Test — Automated Test Suite

> The **integration and unit test project** for the ADAS Core platform.  
> Provides comprehensive automated coverage across repositories, services, domain logic, and module-level behavior. Tests run against an in-process MongoDB instance (Mongo2Go), an in-memory distributed-lock provider, and mocked external dependencies.

---

## Table of Contents

1. [Overview](#overview)
2. [Responsibilities](#responsibilities)
3. [Project Structure](#project-structure)
4. [Dependencies](#dependencies)
5. [Test Architecture](#test-architecture)
6. [Test Data & Builders](#test-data--builders)
7. [Running the Tests](#running-the-tests)
8. [Design Rules](#design-rules)

---

## Overview

`adas-core.Test` is a dedicated .NET 8 test assembly that exercises the ADAS Core platform end-to-end, from domain-level calculations to repository CRUD and service orchestration. It follows a **layered test pyramid**: fast unit tests for pure logic, integration tests backed by Mongo2Go for persistence, and module-level tests for device abstractions.

Key characteristics:

- **NUnit + Moq** — Primary test framework and mocking library.
- **Mongo2Go Integration** — `IntegrationDb` spins up a real MongoDB instance in RAM for repository and migration tests, then tears it down cleanly.
- **In-Memory Locking** — `InMemoryLockProvider` enables `CacheService` and `LockManagerService` tests without Redis.
- **Shared Test Data** — `TestUtilities` provides factory methods for domain entities (`Patient`, `Admission`, `PointOfCare`, etc.) ensuring consistent, valid test fixtures.
- **Fake Logger** — `FakeLogger` implements `ILogger` to capture and assert on log output during service tests.
- **Customization Tests** — Hospital-specific calculated-observation logic is validated under `Customizations/`.
- **Fakes Framework** — `Microsoft.QualityTools.Testing.Fakes` supports shim-based isolation for static or sealed dependencies.

---

## Responsibilities

| Concern | What this project does |
|---------|----------------------|
| **Unit Tests — Domain** | Pure logic tests for domain entities, value objects, enums, and utility classes that have no external dependencies. |
| **Unit Tests — Services** | Isolated service tests using Moq for all collaborators (repositories, messaging, logging). |
| **Integration Tests — Repositories** | CRUD, filtering, pagination, and aggregation tests against a live Mongo2Go database via `IntegrationDb`. |
| **Integration Tests — Migrations** | MongoMigrations.Core-based schema-migration tests (`MongodbMigrationTest`). |
| **Module Tests** | Tests for `LightBeaconService`, `RelayService`, and cache/provider implementations using in-memory substitutes. |
| **Customisation Tests** | Hospital-specific calculated-observation formulas validated per deployment (H12O, HPAZ, HRYC, HUVH). |
| **Test Fixture Bootstrapping** | `IntegrationDb` handles one-time MongoDB startup/teardown for the entire integration test suite. |
| **Shared Factories** | `TestUtilities` generates consistently valid domain objects with deterministic `ObjectId` values. |
| **Logging Assertions** | `FakeLogger` collects log messages so tests can verify warning/error emission paths. |
| **Coverage** | `coverlet.collector` instruments the assembly during CI to produce code-coverage reports. |

---

## Project Structure

```
adas-core.Test/
├── Customizations/
│   ├── H12O/UCIN/CalculatedObservationsTest.cs      # H12O hospital computed-observation formulas
│   ├── HPAZ/CalculatedObservationsTest.cs           # HPAZ hospital computed-observation formulas
│   ├── HRYC/CalculatedObservationsTest.cs           # HRYC hospital computed-observation formulas
│   ├── HUVH/UCIA/CalculatedObservationsTest.cs      # HUVH-UCIA computed-observation formulas
│   └── HUVH/UCIN/CalculatedObservationsTest.cs      # HUVH-UCIN computed-observation formulas
│
├── Models/
│   ├── FakeLogger.cs                                # Serilog ILogger test double (captures log output)
│   └── SignalR/SubscriberGroupedTest.cs              # SignalR subscription grouping tests
│
├── Repositories/
│   ├── IntegrationDb.cs                             # One-time Mongo2Go runner setup/tear-down fixture
│   ├── MongodbMigrationTest.cs                      # MongoMigrations.Core migration validation
│   ├── AdmissionRepositoryTest.cs                   # Admission aggregate CRUD tests
│   ├── AlarmRepositoryTest.cs                       # Alarm entity CRUD tests
│   ├── AppointmentRepositoryTest.cs                 # Appointment CRUD and archive tests
│   ├── ConfigObservationRepositoryTest.cs           # Observation config CRUD tests
│   ├── ConfigPumpsRepositoryTest.cs                 # Pump config CRUD tests
│   ├── ConfigUnitsRepositoryTest.cs                 # Unit config CRUD tests
│   ├── DiagnosisRepositoryTest.cs                   # Diagnosis CRUD and archive tests
│   ├── DisplayConfigTest.cs                          # Display configuration tests
│   ├── HistoricalConfigChangesRepositoryTest.cs       # Historical config audit tests
│   ├── MasterListRepositoryTest.cs                  # Master-list CRUD tests
│   ├── MedicineRepositoryTest.cs                     # Medicine entity tests
│   ├── ObservationRepositoryTest.cs                 # Observation CRUD and archive tests
│   ├── PatientRepositoryTest.cs                     # Patient aggregate tests
│   ├── PointOfCareRepositoryTests.cs                # PoC repository tests
│   ├── PoCMappingRepositoryTest.cs                  # PoC-mapping tests
│   ├── PoCSettingsRepositoryTest.cs                 # PoC-settings tests
│   ├── Pump*RepositoryTest.cs                       # Pump state/alarm/event/archive tests
│   ├── RecordingAlertRepositoryTest.cs              # Recording alert CRUD and archive tests
│   ├── SectionRepositoryTest.cs                     # Section/ward tests
│   ├── ServiceConfigRepositoryTest.cs               # Service-config tests
│   ├── TreatmentRepositoryTest.cs                   # Treatment CRUD and archive tests
│   └── UnitRepositoryTest.cs                        # Unit aggregate tests
│
├── Services/
│   ├── AdmissionServiceTest.cs                      # Admission orchestration tests
│   ├── AlarmServiceTest.cs                          # Alarm service logic tests
│   ├── CacheDispatcherTest.cs                       # Cache dispatcher routing tests
│   ├── CacheServiceTest.cs                          # Cache hit/miss/eviction/concurrency tests
│   ├── CameraServiceTest.cs                         # Camera service tests
│   ├── ConfigObservationServiceTest.cs              # Observation config service tests
│   ├── ConfigPumpsServiceTest.cs                  # Pump config service tests
│   ├── ConfigUnitsServiceTest.cs                    # Unit config service tests
│   ├── DiagnosisServiceTest.cs                      # Diagnosis orchestration tests
│   ├── DischargeServiceTest.cs                      # Discharge workflow tests
│   ├── DisplayServiceTest.cs                        # Display configuration service tests
│   ├── GroupedObservationServiceTest.cs             # Grouped observation calculation tests
│   ├── HistoricalConfigChangesServiceTest.cs        # Historical config changes service tests
│   ├── InMemoryLockProviderTest.cs                  # In-memory distributed-lock tests
│   ├── LightBeaconServiceTest.cs                    # Light beacon module tests
│   ├── MasterListServiceTest.cs                     # Master-list service tests
│   ├── MedicineServiceTest.cs                       # Medicine service tests
│   ├── NoCacheServiceTest.cs                        # No-cache fallback tests
│   ├── ObservationServiceTest.cs                    # Observation orchestration tests
│   ├── PatientServiceTest.cs                        # Patient orchestration tests
│   ├── PointOfCareServiceTest.cs                    # PoC service tests
│   ├── PublisherServiceTest.cs                      # Event-publisher service tests
│   ├── PumpServiceTest.cs                           # Pump orchestration tests
│   ├── RecordingAlertServiceTest.cs                 # Recording alert service tests
│   ├── RecordingServiceTest.cs                      # Recording service tests
│   ├── RedisLockProviderTest.cs                     # Redis-backed lock-provider tests
│   ├── RedisServiceTest.cs                          # Redis caching service tests
│   ├── RelayServiceTest.cs                          # Relay module tests
│   ├── SchedulerServiceTest.cs                      # Background scheduler tests
│   ├── SendAlertServiceTest.cs                      # Alert-dispatch service tests
│   ├── ServiceConfigServiceTest.cs                  # Service-config orchestration tests
│   ├── TreatmentServiceTest.cs                      # Treatment orchestration tests
│   └── UnitServiceTest.cs                           # Unit orchestration tests
│
├── Utilities/
│   ├── CacheKeyClassifierTest.cs                    # Cache-key parsing and classification tests
│   └── TestUtilities.cs                             # Shared entity builders and helper methods
│
└── Usings.cs                                          # Global `using NUnit.Framework`
```

| Folder | Role |
|--------|------|
| `Customizations/` | Hospital-specific test fixtures isolating per-client business rules. Each subfolder mirrors a real deployment configuration. |
| `Models/` | Shared test doubles (`FakeLogger`) and SignalR model tests. |
| `Repositories/` | Integration tests for every concrete `MongoRepository` subclass. `IntegrationDb` bootstraps the ephemeral MongoDB instance. |
| `Services/` | Unit and integration tests for Application-layer service implementations (caching, alerting, pumping, relays, beacons, etc.). |
| `Utilities/` | Helper factories for test data (`TestUtilities`) and utility-class tests (`CacheKeyClassifierTest`). |

---

## Dependencies

### Downstream References

| Project | Role |
|---------|------|
| `adas-core.Domain` | Domain entities, enums, and exceptions exercised by unit tests. |
| `adas-core.Infrastructure` | Concrete repositories, services, and DB context exercised by integration tests. |
| `adas-core` (Host) | WebHost builder, middleware pipeline, and DI configuration tested via integration fixtures. |

### NuGet Packages

| Package | Version | Purpose |
|---------|---------|---------|
| `NUnit` | 4.6.1 | Primary test framework. |
| `NUnit3TestAdapter` | 6.2.0 | Visual Studio / `dotnet test` runner adapter. |
| `NUnit.Analyzers` | 4.13.0 | Static analysis rules for NUnit test quality. |
| `Moq` | 4.20.72 | Mocking framework for interface and logger substitution. |
| `Microsoft.NET.Test.Sdk` | 18.6.0 | MSBuild targets and test-host runtime. |
| `Microsoft.QualityTools.Testing.Fakes` | 18.1.1 | Shim-based isolation for static/sealed code. |
| `Mongo2Go` | 4.1.0 | Ephemeral MongoDB instance for integration tests. |
| `MongoMigrations.Core` | 4.0.15 | Migration script validation in integration tests. |
| `coverlet.collector` | 10.0.1 | Code-coverage instrumentation for CI pipelines. |
| `AuditLogs` | 1.0.59 | Audit logging used during service-level tests. |

---

## Test Architecture

### Layer Distribution

```
┌─────────────────────────────────────────────────────────────┐
│                      Unit Tests                             │
│  (fast, deterministic, no I/O)                            │
│  • Domain entity factories & validation                   │
│  • Service logic with Moq'd repositories                  │
│  • Utility classes (CacheKeyClassifier, etc.)              │
├─────────────────────────────────────────────────────────────┤
│                    Integration Tests                        │
│  (MongoDB-backed, startup/teardown cost)                    │
│  • Repository CRUD round-trips                             │
│  • Pagination, filtering, aggregation pipelines            │
│  • Migration script execution                             │
├─────────────────────────────────────────────────────────────┤
│                    Module Tests                             │
│  (in-memory device substitutes)                            │
│  • FakeRelay outlet control sequences                      │
│  • CacheService eviction & concurrency                      │
│  • LockManagerService deadlock prevention                 │
└─────────────────────────────────────────────────────────────┘
```

### Categorisation

| Category | Attribute | CI Inclusion |
|----------|-----------|------------|
| Unit | `[Category("Unit")]` (implicit) | Always |
| Integration | `[Category("Integration")]` | Gated / nightly |
| Customization | `[Category("Customization")]` | Deployment-specific |

### Concurrency Safety

- `[Parallelizable(ParallelScope.All)]` is applied at fixture level where tests are independent.
- `IntegrationDb` is a `[SetUpFixture]` — one MongoDB runner per test run, not per test.
- Each repository test class works on **disjoint document IDs** to avoid collisions.

---

## Test Data & Builders

### `IntegrationDb` — MongoDB Lifecycle

- `[OneTimeSetUp]` starts `MongoDbRunner`, configures BSON conventions, and opens `IntegrationTestDb`.
- `[OneTimeTearDown]` disposes runner and client connections.
- All repository fixtures implicitly share the same database but use unique collections per test class.

### `TestUtilities` — Entity Factories

Provides deterministic builders for:

- `Patient` with default demographics
- `Admission` linked to a `PointOfCare`
- `PointOfCare` with unit and section hierarchy
- `Unit`, `Section`, `DisplayConfig`
- `OptionList` master data
- `Discharge`, `Diagnosis`, `Treatment` records

Every builder assigns deterministic `ObjectId` values so assertions are reproducible.

### `FakeLogger` — Log Capture

Implements `Serilog.ILogger` with:

- `Messages` list capturing every rendered log entry.
- `IsEnabled()` returns `true` unconditionally.
- `ForContext()` returns `this` (no-op enrichment).
- Tests assert on `Messages.Contains(...)`, `Messages.Count`, or log level distribution.

---

## Running the Tests

### Full Suite

```bash
cd adas-core.Test
dotnet test --verbosity normal
```

### Unit Only (skip integration)

```bash
dotnet test --filter "Category!=Integration"
```

### Integration Only

```bash
dotnet test --filter "Category=Integration"
```

### With Coverage

```bash
dotnet test --collect:"XPlat Code Coverage"
```

> Requires `coverlet.collector` and produces `coverage.cobertura.xml` in the `TestResults/` folder.

---

## Design Rules

1. **No External Network** — All tests must run without external MongoDB, Redis, RabbitMQ, or LDAP servers. `Mongo2Go`, `InMemoryLockProvider`, and `Moq` satisfy this.
2. **Deterministic Fixtures** — `TestUtilities` builders always produce the same `ObjectId` and default values for the same inputs. No random data.
3. **One Concern per Test** — Each `[Test]` asserts a single behavior. Compound assertions are allowed only when verifying correlated outcomes of the same operation.
4. **Mock External Boundaries** — Services under test receive Moq'd `ILogger`, `IRepository`, and `IMessageService` instances. Integration tests may use real `MongoRepository` via `IntegrationDb`.
5. **Category Tags** — Every repository or migration test MUST carry `[Category("Integration")]` so CI can filter slow tests.
6. **Cleanup Guarantee** — `[OneTimeTearDown]` in `IntegrationDb` always disposes the `MongoDbRunner`. No orphaned processes.
7. **FakeLogger Over Null Logger** — Service tests must pass a `FakeLogger` (or `Mock<ILogger>`) rather than `null` to constructors expecting `ILogger`.
8. **No Production Dependencies in Tests** — The test project references `Domain`, `Infrastructure`, and `Host`, but must never be referenced **by** them. Tests are the outermost layer.
9. **Customization Isolation** — Hospital-specific tests reside exclusively in `Customizations/{Site}/`. They validate site-specific formulas without polluting generic service tests.
10. **Coverage Thresholds** — CI gates enforce minimum branch coverage on `Domain` and `Application` projects. New features without accompanying tests fail the build.

---

<p align="center">
  Back to <a href="../README.md">adas-core Root README</a>
</p>