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.
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):
-
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
-
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):
- 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-runmust not contain forbidden filespackage.json.fileswhitelist 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.shis 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.gradleto 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.gradletest configuration updated- Test dependencies added (JUnit, Robolectric if needed)
./gradlew testruns successfully (even if no tests yet)- CI can run tests (
./ci/run.shincludes 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:
-
P2.3.1 First — Enable test infrastructure
- Establishes foundation for tests
- Verifies CI compatibility
- Low risk, enables subsequent work
-
P2.3.2 Second — Create test helpers
- Provides utilities for test scenarios
- Enables isolated, repeatable tests
- Medium complexity
-
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:
- All P2.3 items completed (P2.3.1, P2.3.2, P2.3.3)
- All invariants preserved (verified by CI)
- All acceptance criteria met (per item)
- Documentation updated (progress docs, parity matrix, changelog)
- 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.shcan 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)
- Review this design — Ensure scope and constraints are correct
- Approve test framework choice — Robolectric vs pure unit tests
- Begin P2.3.1 — Enable test infrastructure first
- 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