[AZ-284] Autodev baseline + testability refactor

Phase A baseline outputs from /autodev (Steps 1-5):
- Problem & solution docs (_docs/00_problem, _docs/01_solution)
- Codebase documentation (_docs/02_document) incl. architecture,
  module-layout, glossary, system-flows, baseline compliance scan
- Test specs (blackbox, performance, resilience, security, resource,
  traceability matrix)
- Test task decomposition (_docs/02_tasks/todo): AZ-285..AZ-290
- Testability refactor (_docs/04_refactoring/01-testability-refactoring):
  - TC-01 Move DownloadedTileInfoV2 + new ExistingTileInfo to Common.DTO
  - TC-02 Replace dead ISatelliteDownloader API with real signatures
  - TC-03 GoogleMapsDownloaderV2 implements ISatelliteDownloader
  - TC-04 TileService depends on ISatelliteDownloader (mockable)
  - TC-05 DI + endpoints use ISatelliteDownloader
- Test runner scripts (scripts/run-tests.sh, run-performance-tests.sh)
- Autodev state pointer (_docs/_autodev_state.md)

Prepares the codebase for AZ-285..AZ-290 unit/integration test work.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-10 04:44:08 +03:00
parent 25a644a9bf
commit b0fffa6d42
68 changed files with 4192 additions and 11 deletions
@@ -0,0 +1,30 @@
# Test Infrastructure
**Task**: AZ-285_test_infrastructure
**Name**: Test Infrastructure: scaffold unit test project with mocks
**Description**: Scaffold the unit test project with proper mocking infrastructure for ISatelliteDownloader and all repository interfaces
**Complexity**: 3 points
**Dependencies**: None
**Component**: Blackbox Tests
**Tracker**: AZ-285
**Epic**: AZ-284
## Scope
- Replace DummyTest with actual test infrastructure in `SatelliteProvider.Tests`
- Add Moq package for interface mocking (ISatelliteDownloader, ITileRepository, IRegionRepository, IRouteRepository, IRegionRequestQueue)
- Add shared test fixtures with standard test coordinates (47.461747, 37.647063 for tiles; 48.276067, 37.384458 for routes)
- Verify existing docker-compose.tests.yml works as integration test environment
- Ensure FluentAssertions is available (already in project)
## Test Project Layout
Existing structure is sufficient — enhance `SatelliteProvider.Tests/`:
- Add `Fixtures/` for shared test data
- Add test classes per service (TileServiceTests, RegionServiceTests, RouteServiceTests)
## Acceptance Criteria
**AC-1**: Unit test project builds and all mock interfaces resolve
**AC-2**: `docker-compose -f docker-compose.yml -f docker-compose.tests.yml up --build --abort-on-container-exit` succeeds
**AC-3**: Test runner discovers and executes test classes
@@ -0,0 +1,30 @@
# Unit Tests: TileService
**Task**: AZ-286_tile_service_tests
**Name**: Unit tests: TileService (download, cache, dedup)
**Complexity**: 3 points
**Dependencies**: AZ-285
**Component**: Blackbox Tests
**Tracker**: AZ-286
**Epic**: AZ-284
## Scenarios
- BT-01: Tile download — mock ISatelliteDownloader.DownloadSingleTileAsync returns tile info; verify TileService stores it via ITileRepository.InsertAsync
- BT-02: Cache reuse — mock ITileRepository.GetTilesByRegionAsync returns existing tile; verify ISatelliteDownloader receives existing tiles to skip
- BT-N01: Invalid coordinates — verify appropriate error handling for out-of-range lat/lon
- BT-N02: Invalid zoom level — verify GoogleMapsDownloaderV2 rejects zoom levels outside allowed range
## Test Data
Coordinates from `input_data/test_coordinates.md`: lat=47.461747, lon=37.647063, zoom=18
## Expected Results
Per `input_data/expected_results/results_report.md`: tile with zoomLevel=18, tileSizePixels=256, imageType="jpg", non-empty filePath
## Acceptance Criteria
AC-1: All 4 scenarios have passing tests
AC-2: ISatelliteDownloader is mocked (no real Google Maps calls)
AC-3: Tests verify both happy path and error paths
@@ -0,0 +1,30 @@
# Unit Tests: RegionService
**Task**: AZ-287_region_service_tests
**Name**: Unit tests: RegionService (request, process, stitch)
**Complexity**: 3 points
**Dependencies**: AZ-285
**Component**: Blackbox Tests
**Tracker**: AZ-287
**Epic**: AZ-284
## Scenarios
- BT-03: Region 200m zoom 18 — verify request queuing and status="completed" after processing
- BT-04: Region 400m zoom 17 — same flow, different parameters
- BT-05: Region 500m zoom 18 with stitching — verify stitched image path is set
## Test Data
Coordinates: lat=47.461747, lon=37.647063. Sizes: 200m, 400m, 500m.
## Expected Results
Per results_report.md: status="completed", csvFilePath non-empty, summaryFilePath non-empty
## Acceptance Criteria
AC-1: RegionService.RequestRegionAsync creates entity and queues request
AC-2: RegionService.ProcessRegionAsync transitions status pending→processing→completed
AC-3: CSV and summary files are generated
AC-4: Stitch path is set when stitchTiles=true
@@ -0,0 +1,30 @@
# Unit Tests: RouteService
**Task**: AZ-288_route_service_tests
**Name**: Unit tests: RouteService (interpolation, geofence, distance)
**Complexity**: 3 points
**Dependencies**: AZ-285
**Component**: Blackbox Tests
**Tracker**: AZ-288
**Epic**: AZ-284
## Scenarios
- BT-06: Simple 2-point route — verify intermediate points at ≤200m spacing, point types correct
- BT-07: Route retrieval — verify GET returns same route with all points
- BT-10: Complex 10-point route — verify point distribution (1 first-original, 1 last-original, 8 intermediate)
- BT-11: Geofenced route — verify geofence region creation
- BT-12: Extended 20-point route — verify point distribution (1 first-original, 1 last-original, 18 intermediate)
- BT-N03: Route with <2 points — verify validation error
- BT-N04/N05: Invalid geofences — verify validation errors
## Test Data
Route points from test_coordinates.md (ROUTE-01 through ROUTE-06)
## Acceptance Criteria
AC-1: Point interpolation produces spacing ≤200m between all consecutive points
AC-2: Point type assignment is correct (original/intermediate)
AC-3: Total distance is calculated via Haversine
AC-4: Negative cases return appropriate errors
@@ -0,0 +1,31 @@
# Integration Tests: Route Map Processing + ZIP
**Task**: AZ-289_integration_route_maps
**Name**: Integration tests: route map processing + ZIP
**Complexity**: 2 points
**Dependencies**: AZ-285
**Component**: Blackbox Tests
**Tracker**: AZ-289
**Epic**: AZ-284
## Scenarios
- BT-08: Route with requestMaps=true — verify mapsReady=true, stitchedImagePath, csvFilePath
- BT-09: Route with createTilesZip=true — verify ZIP contents match CSV tile count, directory structure preserved
## System Under Test Boundary
Tests drive the API via HTTP endpoints. No internal module stubs — all services run in Docker as production.
## Test Data
Route points from test_coordinates.md (ROUTE-02, ROUTE-03)
## Notes
BT-10/11/12 are already covered by existing integration tests (ComplexRouteTests, ExtendedRouteTests).
## Acceptance Criteria
AC-1: Route map processing completes within 180s
AC-2: ZIP file structure is validated (entry count matches CSV, path prefix "tiles/")
@@ -0,0 +1,50 @@
# Non-Functional Tests
**Task**: AZ-290_nonfunctional_tests
**Name**: Non-functional tests: perf, resilience, security, limits
**Complexity**: 3 points
**Dependencies**: AZ-285
**Component**: Blackbox Tests
**Tracker**: AZ-290
**Epic**: AZ-284
## Performance Scenarios (PT-01 through PT-06)
- PT-01: Tile download latency <30s
- PT-02: Cached tile retrieval <500ms
- PT-03/04: Region processing throughput
- PT-05: 5 concurrent regions all complete
- PT-06: Route interpolation <5s
## Resilience Scenarios (RS-01 through RS-06)
- RS-01: API starts with database ready
- RS-02: Migrations run on fresh DB
- RS-03: Region processing handles tile failures
- RS-04: Queue rejects overflow (capacity 1000)
- RS-05: Max 4 concurrent downloads
- RS-06: Route processing completes all regions
## Security Scenarios (SEC-01 through SEC-04)
- SEC-01: SQL injection via coordinates
- SEC-02: Path traversal in tile serving
- SEC-03: Oversized region request
- SEC-04: Malformed JSON
## Resource Limit Scenarios (RL-01 through RL-04)
- RL-01: ZIP ≤ 50MB
- RL-02: Queue capacity 1000
- RL-03: Concurrent download semaphore (4)
- RL-04: Concurrent region processing (20)
## System Under Test Boundary
All tests drive the system via HTTP API or observe Docker container behavior.
## Acceptance Criteria
AC-1: Performance scripts (scripts/run-performance-tests.sh) pass thresholds
AC-2: Resilience tests verify state transitions and resource limits
AC-3: Security tests confirm no injection or traversal vulnerabilities