Files
daily-notification-plugin/docs/progress/P2.3-DESIGN.md
Matthew Raymer 6b5b886951 feat(ios): complete P2.1 schema versioning and P2.2 combined edge case tests
P2.1: iOS Schema Versioning Strategy
- Added SCHEMA_VERSION constant and checkSchemaVersion() method in PersistenceController
- Version stored in NSPersistentStore metadata (observability contract, not migration gate)
- CoreData auto-migration remains authoritative; version mismatches logged, not blocked
- Documentation added to ios/Plugin/README.md with migration contract

P2.2: Combined Edge Case Tests
- Added 3 resilience test scenarios to DailyNotificationRecoveryTests.swift:
  - test_combined_dst_boundary_duplicate_delivery_cold_start()
  - test_combined_rollover_duplicate_delivery_cold_start()
  - test_combined_schema_version_cold_start_recovery()
- All tests labeled with @resilience @combined-scenarios comments
- Tests verify idempotency and correctness under combined stressors

P2.3: Android Combined Tests Design
- Created P2.3-DESIGN.md with scope, invariants, and acceptance criteria
- Created P2.3-IMPLEMENTATION-CHECKLIST.md with step-by-step execution plan
- Design ready for implementation to achieve parity with iOS P2.2

Documentation Updates
- Fixed parity matrix: iOS invalid data handling now correctly shows " Recovery tested" with test references
- Updated progress docs (00-STATUS.md, 01-CHANGELOG-WORK.md, 03-TEST-RUNS.md, 04-PARITY-MATRIX.md)
- Updated P2-DESIGN.md to reflect P2.3 scope (Android combined tests)
- Updated SYSTEM_INVARIANTS.md baseline tag references

Baseline Tag
- Created and pushed v1.0.11-p2-complete tag
- Tag represents P2.x completion (schema versioning + combined resilience tests)

All invariants preserved. CI passes. Tests runnable via xcodebuild on macOS.
2025-12-22 12:59:40 +00:00

12 KiB

P2.3 Design: Android Combined Edge Case Tests

Purpose: Defines scope, boundaries, and acceptance criteria for Android combined resilience tests to achieve parity with iOS P2.2.
Owner: Development Team
Last Updated: 2025-12-22
Status: design-only (no implementation)
Baseline: v1.0.11-p2-complete


Purpose

This document defines the scope, boundaries, and acceptance criteria for P2.3 work before any implementation begins. It ensures P2.3:

  • Achieves parity with iOS combined edge case tests (P2.2)
  • Uses CI-compatible testing approach (JUnit + Robolectric or pure unit tests)
  • Maintains all established invariants
  • Can be executed incrementally

P2.3 Scope Definition

What P2.3 Includes

Android Combined Edge Case Tests

  • Add automated resilience tests mirroring iOS P2.2 scenarios
  • Enable Android test infrastructure (currently disabled in build.gradle)
  • Use CI-compatible testing framework (JUnit + Robolectric or pure unit tests)
  • Validate idempotency and correctness under combined stressors

Test Scenarios (Must-Have):

  1. DST boundary + duplicate delivery + cold start

    • Validate recovery idempotency under DST transitions
    • Verify only one logical delivery recorded after dedupe
    • Validate next scheduled time is DST-consistent
    • Test cold start recovery after duplicate delivery
  2. Rollover + duplicate delivery + cold start

    • Test rollover idempotency under re-entry
    • Verify duplicate delivery doesn't double-apply state transitions
    • Validate cold start reconciliation produces correct state

Test Scenarios (Optional):

  1. Schema version + cold start recovery (if Android has explicit version tracking)
    • Confirm Room database version is observable
    • Verify version doesn't interfere with recovery

What P2.3 Excludes

  • No emulator/instrumentation tests in CI — Use JVM-compatible tests (Robolectric or pure unit tests)
  • No new features — Tests only, no production code changes
  • No architectural changes — Core structure remains unchanged
  • No breaking changes — Backward compatibility required
  • No new dependencies — Use existing AndroidX test libraries

Current State Analysis

Android Test Infrastructure

Current Status:

  • Tests are disabled in android/build.gradle (lines 48-63)
  • Comment: "tests reference deprecated/removed code"
  • TODO: "Rewrite tests to use modern AndroidX testing framework"
  • Test source directory exists but is empty/placeholder

Existing Test Infrastructure:

  • Manual emulator scripts: test-phase1.sh, test-phase2.sh, test-phase3.sh
  • These validate recovery scenarios but are not automated/CI-compatible
  • No automated unit/integration tests in android/src/test/

iOS Comparison (P2.2)

iOS State:

  • Automated combined edge case tests in ios/Tests/DailyNotificationRecoveryTests.swift
  • 3 combined scenarios with direct references in parity matrix
  • Tests runnable via xcodebuild (skipped on Linux CI, documented)

Parity Gap:

  • Android has manual scripts but no automated combined scenarios
  • Need to close this gap with CI-compatible automated tests

Invariants That Must Not Be Violated

1. Packaging Invariants (P0)

Enforced by: verify.shcheck_package()

  • npm pack --dry-run must not contain forbidden files
  • package.json.files whitelist must remain authoritative

P2.3 Constraint: Test files must not be included in published package (already excluded via package.json.files).


2. Core Module Purity (P1.4)

Enforced by: verify.shcheck_core_source() + check_core_artifacts()

  • src/core/ must not import platform-specific modules

P2.3 Constraint: Tests are Android-only, no impact on core module.


3. CI Authority (P0)

Enforced by: ci/README.md (policy-as-code contract)

  • ./ci/run.sh is the only supported CI entrypoint
  • All gates must call ./ci/run.sh

P2.3 Constraint: Tests must be runnable via ./ci/run.sh (or clearly documented as manual if platform-specific).


4. Export Correctness (P0)

Enforced by: verify.shcheck_build()

  • All exported paths must match actual build artifacts

P2.3 Constraint: Test files don't affect exports.


5. Documentation Structure (P1.5)

Enforced by: docs/00-INDEX.md (index-first rule)

  • New docs must be linked from index or placed in _archive//_reference/

P2.3 Constraint: Test documentation must follow existing patterns.


6. Baseline Tag Integrity

Baseline: v1.0.11-p2-complete

  • This tag represents a known-good state
  • P2.3 work must not invalidate the baseline

P2.3 Constraint: Tests must not break existing functionality.


P2.3 Work Items (Detailed)

P2.3.1: Enable Android Test Infrastructure

Goal: Re-enable Android tests with modern AndroidX testing framework.

Scope:

  • Update android/build.gradle to enable unit tests
  • Add AndroidX test dependencies (JUnit, Robolectric if needed)
  • Create test directory structure
  • Verify tests can compile and run (even if initially empty)

Constraints:

  • Must use modern AndroidX testing framework (not deprecated APIs)
  • Must be runnable on Linux CI (JVM-compatible, no emulator required)
  • Must not break existing build

Acceptance Criteria:

  • android/build.gradle test configuration updated
  • Test dependencies added (JUnit, Robolectric if needed)
  • ./gradlew test runs successfully (even if no tests yet)
  • CI can run tests (./ci/run.sh includes Android test step or documents manual requirement)

P2.3.2: Create Test Infrastructure Helpers

Goal: Create test helpers similar to iOS TestDBFactory.swift.

Scope:

  • Create test database factory (in-memory Room database)
  • Create test data injection helpers (invalid data, duplicate scenarios)
  • Create mock context/component helpers if needed

Constraints:

  • Must use in-memory databases for isolation
  • Must not require real Android device/emulator
  • Must follow existing test patterns where possible

Acceptance Criteria:

  • Test database factory created (in-memory Room)
  • Test data injection helpers created
  • Helpers support invalid data scenarios
  • Helpers support duplicate delivery scenarios

P2.3.3: Implement Combined Test Scenarios

Goal: Add 2-3 combined edge case tests mirroring iOS P2.2.

Scope:

Scenario A: DST boundary + duplicate delivery + cold start

  • Create notification scheduled at DST boundary
  • Simulate duplicate delivery events (rapid succession)
  • Trigger cold start recovery
  • Verify: idempotency, deduplication, DST-consistent next time

Scenario B: Rollover + duplicate delivery + cold start

  • Create notification that was just delivered (past time)
  • Trigger rollover (first delivery)
  • Simulate duplicate delivery immediately
  • Trigger cold start recovery
  • Verify: rollover idempotency, no double-apply, correct state

Scenario C: Schema version + cold start recovery (optional)

  • Verify Room database version is observable
  • Test recovery with version metadata present
  • Verify version doesn't interfere with recovery

Constraints:

  • Must use Robolectric or pure unit tests (no emulator)
  • Must test core logic, not platform-specific AlarmManager (mock if needed)
  • Must be deterministic and CI-runnable

Acceptance Criteria:

  • At least 2 combined test scenarios implemented
  • Tests verify idempotency in combined scenarios
  • Tests labeled explicitly as resilience/combined-scenarios
  • Tests pass in CI (or clearly documented as manual if platform-specific)
  • Test results logged in docs/progress/03-TEST-RUNS.md
  • Parity matrix updated with direct test references

P2.3 Execution Strategy

Phase Ordering

Recommended sequence:

  1. P2.3.1 First — Enable test infrastructure

    • Establishes foundation for tests
    • Verifies CI compatibility
    • Low risk, enables subsequent work
  2. P2.3.2 Second — Create test helpers

    • Provides utilities for test scenarios
    • Enables isolated, repeatable tests
    • Medium complexity
  3. P2.3.3 Third — Implement combined scenarios

    • Builds on infrastructure and helpers
    • Validates resilience under combined stressors
    • Higher complexity, benefits from previous phases

Incremental Approach

  • Each P2.3 item can be completed independently
  • Can pause/resume at any item boundary
  • Each item has its own acceptance criteria

Testing Strategy

  • P2.3.1: Verify test infrastructure works (./gradlew test)
  • P2.3.2: Verify helpers work in isolation
  • P2.3.3: New tests required, existing functionality must pass

P2.3 "Done" Criteria

Overall P2.3 Completion

P2.3 is complete when:

  1. All P2.3 items completed (P2.3.1, P2.3.2, P2.3.3)
  2. All invariants preserved (verified by CI)
  3. All acceptance criteria met (per item)
  4. Documentation updated (progress docs, parity matrix, changelog)
  5. Parity achieved (Android has automated combined tests matching iOS)

Individual Item Completion

Each P2.3 item is complete when:

  • Acceptance criteria met
  • CI passes (./ci/run.sh)
  • No invariant violations
  • Documentation updated (if applicable)
  • Progress docs updated

Risk Mitigation

Risk: Android Tests Currently Disabled

Mitigation:

  • Start with minimal test infrastructure (one simple test)
  • Verify CI compatibility before adding complex scenarios
  • Use Robolectric for Android framework mocking (no emulator needed)

Risk: CI Incompatibility

Mitigation:

  • Use JVM-compatible tests (Robolectric or pure unit tests)
  • Document manual test requirements clearly if any
  • Ensure ./ci/run.sh can run tests or skip gracefully

Risk: Breaking Existing Functionality

Mitigation:

  • Tests only, no production code changes
  • Incremental approach (one scenario at a time)
  • CI gates prevent regressions

Risk: Scope Creep

Mitigation:

  • Clear "what P2.3 excludes" section
  • Acceptance criteria defined upfront
  • Can pause/resume at item boundaries

Success Metrics

Quantitative

  • P2.3.1: Test infrastructure enabled and CI-compatible
  • P2.3.2: Test helpers created (database factory, data injection)
  • P2.3.3: At least 2 combined test scenarios (3 if time permits)

Qualitative

  • Parity: Android has automated combined tests matching iOS intent
  • CI Compatibility: Tests runnable in CI or clearly documented as manual
  • Maintainability: Tests follow existing patterns and are well-documented

Dependencies

External Dependencies

  • Robolectric (if used) — Must be compatible with existing AndroidX versions
  • JUnit — Standard Android testing framework

Internal Dependencies

  • P2.3.1 → P2.3.2 → P2.3.3: Sequential dependency (infrastructure → helpers → scenarios)

Blocking Dependencies

  • None — P2.3 can start immediately after P2.x completion

Timeline Estimate

P2.3.1: 2-4 hours (test infrastructure setup)
P2.3.2: 4-6 hours (test helpers creation)
P2.3.3: 6-10 hours (combined scenarios implementation)

Total: 12-20 hours (can be spread over multiple sessions)

Note: These are estimates. Actual time depends on Android test framework complexity and Robolectric setup.


Next Steps (After Design Approval)

  1. Review this design — Ensure scope and constraints are correct
  2. Approve test framework choice — Robolectric vs pure unit tests
  3. Begin P2.3.1 — Enable test infrastructure first
  4. Execute incrementally — One item at a time, pause/resume as needed

Last Updated: 2025-12-22
Status: Design-Only (No Implementation)
Next Action: Review and approve design before proceeding