# 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):** 3. **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.sh` → `check_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.sh` → `check_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.sh` → `check_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