This document summarizes the order in which tests were introduced to the CalendarNotification project, based on commit history and documentation. This is intended to help understand the test suite one file at a time.
The test suite was developed incrementally, starting with basic backup/restore tests and evolving into a comprehensive testing infrastructure with fixtures and mock providers. The tests focus on being faithful to the real code while only mocking out core Android APIs that the instrumentation test suite doesn't work well with.
Commit: feat: reassociate after backup restore (#60) - March 24, 2025
Files Introduced:
android/app/src/androidTest/java/com/github/quarck/calnotify/calendar/CalendarBackupRestoreTest.kt
Purpose: First test file introduced to verify backup and restore functionality related to calendar data. Tests:
- Retrieving backup information for a calendar
- Finding a matching calendar on a "restored" device based on backup info
- Restoring an event alert record into local storage
Key Learning: Use unique identifiers (UUID suffix) for calendar names and accounts during setup to prevent intermittent failures due to calendar ID drift or conflicts with pre-existing data.
Commit: test: core feature test harness setup (#62) - April 3, 2025
Files Introduced:
android/app/src/androidTest/java/com/github/quarck/calnotify/deprecated_raw_calendarmonitor/CalendarMonitorServiceTest.ktandroid/app/src/androidTest/java/com/github/quarck/calnotify/deprecated_raw_calendarmonitor/CalendarMonitorServiceEventReminderTest.kt
Purpose: First comprehensive test harness for CalendarMonitorService. These tests verify:
- Calendar event monitoring
- Event processing
- Delayed event handling functionality
Key Achievements:
- First tests using mock objects to simulate calendar provider interactions
- Established the pattern of using MockK for mocking
- Created the initial documentation in
docs/architecture/calendar_monitoring.md
Commit: test: Clocks Refactor and More Testing Of Calendar Monitoring Code (#71) - April 5, 2025
Files Introduced:
android/app/src/androidTest/java/com/github/quarck/calnotify/deprecated_raw_calendarmonitor/CalendarMonitorServiceTestFirstScanEver.kt
Infrastructure Added:
CNPlusClockInterface- Interface for time operationsCNPlusSystemClock- Production implementationCNPlusTestClock- Test implementation with time control
Purpose: Refactored the codebase to use injectable clocks, making time-dependent code much easier to test. Key improvements:
- Replaced direct
System.currentTimeMillis()calls - Enabled deterministic testing of time-dependent behavior
- Added
advanceAndExecuteTasks()andexecuteAllPendingTasks()methods
Documentation Added: docs/architecture/clock_implementation.md
Commit: test: suite refactor all the repeated mock stuff out of everything (#72) - April 7, 2025
Files Introduced:
android/app/src/androidTest/java/com/github/quarck/calnotify/testutils/BaseCalendarTestFixture.ktandroid/app/src/androidTest/java/com/github/quarck/calnotify/testutils/MockContextProvider.ktandroid/app/src/androidTest/java/com/github/quarck/calnotify/testutils/MockTimeProvider.ktandroid/app/src/androidTest/java/com/github/quarck/calnotify/testutils/MockCalendarProvider.ktandroid/app/src/androidTest/java/com/github/quarck/calnotify/testutils/MockApplicationComponents.ktandroid/app/src/androidTest/java/com/github/quarck/calnotify/calendar/CalendarProviderBasicTest.ktandroid/app/src/androidTest/java/com/github/quarck/calnotify/calendar/CalendarProviderEventTest.ktandroid/app/src/androidTest/java/com/github/quarck/calnotify/calendar/CalendarProviderReminderTest.ktandroid/app/src/androidTest/java/com/github/quarck/calnotify/calendarmonitor/ComponentIsolationTest.kt
Purpose: Major refactoring to extract repeated mock setup into reusable fixtures. Created a modular, extensible test infrastructure.
Documentation Added: docs/testing/test_fixture_refactoring.md
Commit: test: use real calendar provider where possible (#74) - April 23, 2025
Files Introduced:
android/app/src/androidTest/java/com/github/quarck/calnotify/testutils/CalendarProviderTestFixture.ktandroid/app/src/androidTest/java/com/github/quarck/calnotify/testutils/CalendarMonitorTestFixture.ktandroid/app/src/androidTest/java/com/github/quarck/calnotify/testutils/DirectReminderTestFixture.ktandroid/app/src/androidTest/java/com/github/quarck/calnotify/calendarmonitor/FixturedCalendarMonitorServiceTest.ktandroid/app/src/androidTest/java/com/github/quarck/calnotify/calendarmonitor/SimpleCalendarMonitoringTest.ktandroid/app/src/androidTest/java/com/github/quarck/calnotify/calendarmonitor/CalendarTestFixtureExampleTest.kt
Purpose: Refactored MockCalendarProvider to delegate to real CalendarProvider implementation. Tests now use real code wherever possible, only mocking out heavy external dependencies.
Key Insight: CalendarProvider is part of the codebase (not Android API), so it should be tested with real implementation.
Documentation Added: docs/dev_completed/mock_calendar_provider_refactor.md
Commit: feat!: dismiss from reschedule confirmations (#73) - April 25, 2025
Commit: fix: safeDismissEventsFromRescheduleConfirmations fast follows (#82) - April 28, 2025
Files Introduced:
android/app/src/androidTest/java/com/github/quarck/calnotify/dismissedeventsstorage/EventDismissTest.ktandroid/app/src/androidTest/java/com/github/quarck/calnotify/dismissedeventsstorage/OriginalEventDismissTest.kt
Purpose: Comprehensive event dismissal testing covering:
- Single event dismissal (valid and non-existent cases)
- Multiple event dismissal (valid, mixed, and all invalid)
- Deletion warnings (when DB deletion fails)
- Storage errors (when dismissed events storage fails)
- Dismissal by event IDs
- Dismissal from reschedule confirmations
Documentation Added:
docs/dev_completed/event_dismissal_testing_notes.mddocs/dev_completed/constructor-mocking-android.md
android/app/src/androidTest/java/com/github/quarck/calnotify/
├── calendar/
│ ├── CalendarBackupRestoreTest.kt # Phase 1 - First test file
│ ├── CalendarProviderBasicTest.kt # Phase 4 - Basic provider tests
│ ├── CalendarProviderEventTest.kt # Phase 4 - Event operations
│ └── CalendarProviderReminderTest.kt # Phase 4 - Reminder tests
├── calendarmonitor/
│ ├── FixturedCalendarMonitorServiceTest.kt # Phase 5 - Fixtured tests
│ ├── SimpleCalendarMonitoringTest.kt # Phase 5 - Simple examples
│ ├── CalendarTestFixtureExampleTest.kt # Phase 5 - Example usage
│ └── ComponentIsolationTest.kt # Phase 4 - Isolation tests
├── deprecated_raw_calendarmonitor/
│ ├── CalendarMonitorServiceTest.kt # Phase 2 - Original tests
│ ├── CalendarMonitorServiceEventReminderTest.kt # Phase 2 - Reminder flow
│ └── CalendarMonitorServiceTestFirstScanEver.kt # Phase 3 - First scan
├── dismissedeventsstorage/
│ ├── EventDismissTest.kt # Phase 6 - Safe dismiss
│ └── OriginalEventDismissTest.kt # Phase 6 - Original dismiss
├── testutils/
│ ├── BaseCalendarTestFixture.kt # Phase 4 - Base fixture
│ ├── MockContextProvider.kt # Phase 4 - Context mocking
│ ├── MockTimeProvider.kt # Phase 4 - Time mocking
│ ├── MockCalendarProvider.kt # Phase 4 - Calendar mocking
│ ├── MockApplicationComponents.kt # Phase 4 - App components
│ ├── CalendarProviderTestFixture.kt # Phase 5 - Provider fixture
│ ├── CalendarMonitorTestFixture.kt # Phase 5 - Monitor fixture
│ └── DirectReminderTestFixture.kt # Phase 5 - Reminder fixture
└── utils/
└── (utility tests)
For understanding the test suite one file at a time, follow this order:
docs/architecture/calendar_monitoring.md- Understand the flows being testeddocs/architecture/clock_implementation.md- Understand time control in testsdocs/dev_completed/constructor-mocking-android.md- Key mocking limitations
testutils/MockTimeProvider.kt- Time controltestutils/MockContextProvider.kt- Context mockingtestutils/MockCalendarProvider.kt- Calendar operationstestutils/MockApplicationComponents.kt- App-level mockingtestutils/BaseCalendarTestFixture.kt- Base fixture class
testutils/CalendarProviderTestFixture.kttestutils/CalendarMonitorTestFixture.kttestutils/DirectReminderTestFixture.kt
calendar/CalendarProviderBasicTest.kt- Simple provider testscalendar/CalendarProviderEventTest.kt- Event operationscalendar/CalendarProviderReminderTest.kt- Reminder testscalendar/CalendarBackupRestoreTest.kt- Backup/restorecalendarmonitor/SimpleCalendarMonitoringTest.kt- Simple monitoringcalendarmonitor/FixturedCalendarMonitorServiceTest.kt- Complex monitoringdismissedeventsstorage/EventDismissTest.kt- Dismissal logic
deprecated_raw_calendarmonitor/CalendarMonitorServiceTest.ktdeprecated_raw_calendarmonitor/CalendarMonitorServiceEventReminderTest.ktdeprecated_raw_calendarmonitor/CalendarMonitorServiceTestFirstScanEver.kt
From the documentation and commit history, these principles emerged:
-
Faithful Testing: Use real code wherever possible, only mock out core Android APIs that instrumentation tests don't work well with (e.g., push notifications)
-
No Constructor Mocking: MockK's
mockkConstructorandmockkStaticalmost always fail in Android instrumentation tests. Use dependency injection patterns instead. -
Manual Dependency Injection: See Dependency Injection Patterns for the full guide. TL;DR: default to optional parameters, fall back to companion object providers for Activities/BroadcastReceivers.
-
Time Control: Use
CNPlusTestClockfor deterministic time-based testing. -
Unique Identifiers: Use UUIDs or unique suffixes for test data to prevent conflicts between test runs.
-
Incremental Development: Build tests one file at a time, verify they pass, then move on.