31 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	Comprehensive Testing Guide v2.0 - P0 Production-Grade Features
Overview
This document provides comprehensive testing procedures for the DailyNotification Capacitor plugin with all P0 production-grade improvements implemented. The current version includes:
- ✅ P0 Priority 1: Channel Management (ChannelManager)
 - ✅ P0 Priority 2: PendingIntent & Exact Alarms (PendingIntentManager)
 - ✅ P0 Priority 3: JIT Freshness Re-check (Soft TTL)
 - ✅ P0 Priority 4: Recovery Coexistence (RecoveryManager)
 
Table of Contents
- P0 Feature Testing
 - Reboot Testing Procedures
 - Automated Test Suites
 - Edge Case Testing
 - Performance Testing
 - Troubleshooting Guide
 
P0 Feature Testing
Test Suite 1: Channel Management (P0 Priority 1)
Test 1.1: Channel Creation and Status
Objective: Verify ChannelManager creates and manages notification channels correctly
Steps:
# 1. Launch app and check channel status
adb shell am start -n com.timesafari.dailynotification/.MainActivity
# 2. In app UI, tap "Check Channel Status"
# 3. Verify channel exists and is enabled
Expected Results:
- Channel ID: 
daily_default - Channel Name: 
Daily Notifications - Channel Importance: 
IMPORTANCE_HIGH(3) - Channel Enabled: 
true 
Verification Commands:
# Check channel in system
adb shell "dumpsys notification | grep -A10 -B5 daily_default"
# Check channel importance
adb shell "dumpsys notification | grep -A5 'daily_default'"
Test 1.2: Channel Blocking Detection
Objective: Test detection and handling of blocked notification channels
Steps:
# 1. Block the notification channel manually
adb shell "am start -a android.settings.CHANNEL_NOTIFICATION_SETTINGS -e android.provider.extra.APP_PACKAGE com.timesafari.dailynotification -e android.provider.extra.CHANNEL_ID daily_default"
# 2. In system settings, disable the channel
# 3. Return to app and tap "Check Channel Status"
Expected Results:
- Channel Importance: 
IMPORTANCE_NONE(0) - Channel Enabled: 
false - Status shows blocked channel warning
 
Test 1.3: Channel Settings Deep Link
Objective: Test deep linking to channel settings
Steps:
# 1. In app UI, tap "Open Channel Settings"
# 2. Verify system settings open to correct channel
Expected Results:
- System settings open
 - Correct app package selected
 - Correct channel ID selected
 
Test Suite 2: PendingIntent & Exact Alarms (P0 Priority 2)
Test 2.1: Exact Alarm Permission Check
Objective: Verify exact alarm permission detection and handling
Steps:
# 1. In app UI, tap "Comprehensive Status"
# 2. Check exact alarm status
Expected Results:
exactAlarmsSupported:true(Android 12+)exactAlarmsGranted:trueorfalsecanScheduleNow: Depends on all permissions
Verification Commands:
# Check exact alarm permission
adb shell "dumpsys alarm | grep SCHEDULE_EXACT_ALARM"
# Check alarm manager status
adb shell "dumpsys alarm | grep -A5 -B5 timesafari"
Test 2.2: Modern PendingIntent Flags
Objective: Verify PendingIntent uses modern flags
Steps:
# 1. Schedule a notification
# 2. Check alarm details
Verification Commands:
# Check PendingIntent flags in alarm
adb shell "dumpsys alarm | grep -A10 -B5 timesafari"
# Look for FLAG_IMMUTABLE in alarm details
Expected Results:
- PendingIntent uses 
FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE - No security warnings in logs
 
Test 2.3: Exact Alarm Settings Deep Link
Objective: Test deep linking to exact alarm settings
Steps:
# 1. In app UI, tap "Exact Alarm Settings"
# 2. Verify system settings open
Expected Results:
- System settings open to exact alarm settings
 - Correct app package selected
 
Test Suite 3: JIT Freshness Re-check (P0 Priority 3)
Test 3.1: Fresh Content Check
Objective: Verify JIT freshness check for recent content
Steps:
# 1. Schedule a notification
# 2. Wait for it to fire (should be fresh)
# 3. Check logs for JIT behavior
Verification Commands:
# Monitor JIT freshness logs
adb logcat | grep -i "jit\|freshness\|stale"
# Look for: "Content is fresh (age: X minutes), skipping JIT refresh"
Expected Results:
- Content age < 6 hours: JIT refresh skipped
 - Log shows: "Content is fresh, skipping JIT refresh"
 
Test 3.2: Stale Content Refresh
Objective: Test JIT refresh for stale content
Steps:
# 1. Schedule a notification
# 2. Wait 6+ hours (or modify code to use shorter threshold for testing)
# 3. Wait for notification to fire
# 4. Check logs for refresh attempt
Verification Commands:
# Monitor JIT refresh logs
adb logcat | grep -i "stale.*minutes.*attempting.*refresh"
# Look for: "Content is stale (age: X minutes), attempting JIT refresh"
Expected Results:
- Content age > 6 hours: JIT refresh attempted
 - Log shows: "Content is stale, attempting JIT refresh"
 - Either: "JIT refresh succeeded" or "JIT refresh failed, using original content"
 
Test 3.3: JIT Refresh Fallback
Objective: Test graceful fallback when refresh fails
Steps:
# 1. Disable network connectivity
# 2. Schedule notification with stale content
# 3. Wait for notification to fire
# 4. Check logs for fallback behavior
Expected Results:
- JIT refresh attempted
 - Refresh fails due to network
 - Original content used as fallback
 - Log shows: "JIT refresh failed, using original content"
 
Test Suite 4: Recovery Coexistence (P0 Priority 4)
Test 4.1: App Startup Recovery
Objective: Test idempotent app startup recovery
Steps:
# 1. Schedule notifications
# 2. Close app normally
# 3. Launch app multiple times quickly
# 4. Check recovery logs
Verification Commands:
# Check recovery manager logs
adb logcat | grep -i "recovery.*requested.*app_startup"
# Look for cooldown behavior
adb logcat | grep -i "recovery.*performed.*recently.*skipping"
Expected Results:
- First launch: Recovery performed
 - Subsequent launches: Recovery skipped due to cooldown
 - Log shows: "Recovery performed recently (Xs ago), skipping"
 
Test 4.2: Boot Recovery Integration
Objective: Test boot recovery with app startup recovery
Steps:
# 1. Schedule notifications
# 2. Reboot device
# 3. Check boot recovery logs
# 4. Launch app and check startup recovery
Verification Commands:
# Check boot recovery
adb logcat -d | grep -i "boot.*completed.*restoring"
# Check startup recovery cooldown
adb logcat -d | grep -i "recovery.*requested.*app_startup"
Expected Results:
- Boot recovery: "Recovery requested from: BOOT_COMPLETED"
 - App startup: "Recovery performed recently, skipping"
 - No duplicate recovery operations
 
Test 4.3: Recovery Statistics
Objective: Test recovery statistics tracking
Steps:
# 1. Perform multiple recovery operations
# 2. Check recovery stats
Verification Commands:
# Check recovery stats (if implemented in UI)
# Or check logs for recovery count
adb logcat -d | grep -i "recovery.*count"
Expected Results:
- Recovery count increments correctly
 - Last recovery time tracked
 - Success status tracked
 
Reboot Testing Procedures
Enhanced Reboot Test Suite
Test R1: Boot Receiver with RecoveryManager
Objective: Test new RecoveryManager-based boot recovery
Steps:
# 1. Schedule notification
adb shell am start -n com.timesafari.dailynotification/.MainActivity
# Tap "Test Notification" in UI
# 2. Verify initial scheduling
adb shell "dumpsys alarm | grep timesafari"
# 3. Reboot device
adb reboot
# 4. Wait for boot completion
adb wait-for-device
sleep 30
# 5. Check recovery logs
adb logcat -d | grep -i "recovery.*requested.*boot_completed"
Expected Results:
- Boot recovery triggered: "Recovery requested from: BOOT_COMPLETED"
 - Recovery performed or skipped based on cooldown
 - Alarms restored correctly
 
Test R2: App Update Recovery
Objective: Test MY_PACKAGE_REPLACED recovery
Steps:
# 1. Schedule notification
# 2. Update app
cd android && ./gradlew assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk
# 3. Check recovery logs
adb logcat -d | grep -i "recovery.*requested.*my_package_replaced"
Expected Results:
- Package replacement recovery triggered
 - Notifications restored after update
 
Test R3: Recovery Coexistence Test
Objective: Test boot recovery + app startup recovery coexistence
Steps:
# 1. Schedule notification
# 2. Reboot device
# 3. Immediately launch app after boot
# 4. Check both recovery logs
Verification Commands:
# Check both recovery sources
adb logcat -d | grep -i "recovery.*requested.*\(boot_completed\|app_startup\)"
# Verify cooldown prevents duplicate recovery
adb logcat -d | grep -i "recovery.*performed.*recently.*skipping"
Expected Results:
- Boot recovery performed
 - App startup recovery skipped due to cooldown
 - No duplicate operations
 
Automated Test Suites
Comprehensive Test Script v2.0
#!/bin/bash
# comprehensive-test-v2.sh
set -e
APP_PACKAGE="com.timesafari.dailynotification"
APP_ACTIVITY=".MainActivity"
TEST_TIMEOUT=300  # 5 minutes
echo "🧪 DailyNotification Plugin Comprehensive Test Suite v2.0"
echo "========================================================"
echo "Testing P0 Production-Grade Features:"
echo "✅ Channel Management (P0 Priority 1)"
echo "✅ PendingIntent & Exact Alarms (P0 Priority 2)"
echo "✅ JIT Freshness Re-check (P0 Priority 3)"
echo "✅ Recovery Coexistence (P0 Priority 4)"
echo ""
# Test results tracking
declare -A test_results
# Function to run test and track result
run_test() {
    local test_name="$1"
    local test_function="$2"
    
    echo "🧪 Running: $test_name"
    echo "----------------------------------------"
    
    if $test_function; then
        echo "✅ PASS: $test_name"
        test_results["$test_name"]="PASS"
    else
        echo "❌ FAIL: $test_name"
        test_results["$test_name"]="FAIL"
    fi
    echo ""
}
# Test 1: Channel Management
test_channel_management() {
    echo "📢 Testing Channel Management..."
    
    # Launch app
    adb shell am start -n $APP_PACKAGE/$APP_ACTIVITY
    sleep 3
    
    # Check channel exists
    if adb shell "dumpsys notification | grep -q daily_default"; then
        echo "✅ Channel exists"
    else
        echo "❌ Channel not found"
        return 1
    fi
    
    # Check channel importance
    local importance=$(adb shell "dumpsys notification | grep -A5 daily_default | grep importance" | head -1)
    if [[ "$importance" == *"3"* ]]; then
        echo "✅ Channel importance correct (HIGH)"
    else
        echo "❌ Channel importance incorrect: $importance"
        return 1
    fi
    
    return 0
}
# Test 2: PendingIntent & Exact Alarms
test_pendingintent_alarms() {
    echo "⏰ Testing PendingIntent & Exact Alarms..."
    
    # Check exact alarm support
    if adb shell "dumpsys alarm | grep -q SCHEDULE_EXACT_ALARM"; then
        echo "✅ Exact alarm permission system available"
    else
        echo "⚠️  Exact alarm permission system not available (pre-Android 12)"
    fi
    
    # Schedule notification and check alarm
    echo "📅 Scheduling test notification..."
    echo "⚠️  Manual step: Schedule notification in app UI"
    read -p "Press Enter when notification is scheduled..."
    
    # Check alarm scheduled
    if adb shell "dumpsys alarm | grep -q timesafari"; then
        echo "✅ Alarm scheduled successfully"
    else
        echo "❌ No alarm found"
        return 1
    fi
    
    return 0
}
# Test 3: JIT Freshness Re-check
test_jit_freshness() {
    echo "🔄 Testing JIT Freshness Re-check..."
    
    # Clear logs
    adb logcat -c
    
    # Schedule notification
    echo "📅 Scheduling notification for JIT test..."
    echo "⚠️  Manual step: Schedule notification in app UI"
    read -p "Press Enter when notification is scheduled..."
    
    # Wait for notification to fire
    echo "⏰ Waiting for notification to fire..."
    timeout 60 bash -c '
    while true; do
        if adb logcat -d | grep -q "Content is fresh.*skipping JIT refresh"; then
            echo "✅ JIT freshness check working (fresh content)"
            exit 0
        elif adb logcat -d | grep -q "Content is stale.*attempting JIT refresh"; then
            echo "✅ JIT freshness check working (stale content)"
            exit 0
        fi
        sleep 5
    done
    '
    
    if [ $? -eq 0 ]; then
        echo "✅ JIT freshness re-check working"
        return 0
    else
        echo "❌ JIT freshness re-check not working"
        return 1
    fi
}
# Test 4: Recovery Coexistence
test_recovery_coexistence() {
    echo "🔄 Testing Recovery Coexistence..."
    
    # Clear logs
    adb logcat -c
    
    # Schedule notification
    echo "📅 Scheduling notification for recovery test..."
    echo "⚠️  Manual step: Schedule notification in app UI"
    read -p "Press Enter when notification is scheduled..."
    
    # Launch app multiple times to test cooldown
    echo "🚀 Testing app startup recovery cooldown..."
    adb shell am start -n $APP_PACKAGE/$APP_ACTIVITY
    sleep 2
    adb shell am start -n $APP_PACKAGE/$APP_ACTIVITY
    sleep 2
    adb shell am start -n $APP_PACKAGE/$APP_ACTIVITY
    sleep 2
    
    # Check recovery logs
    local recovery_count=$(adb logcat -d | grep -c "Recovery requested from: APP_STARTUP")
    local cooldown_count=$(adb logcat -d | grep -c "Recovery performed recently.*skipping")
    
    if [ $recovery_count -eq 1 ] && [ $cooldown_count -gt 0 ]; then
        echo "✅ Recovery cooldown working correctly"
        echo "   - Recovery performed: $recovery_count times"
        echo "   - Cooldown skips: $cooldown_count times"
        return 0
    else
        echo "❌ Recovery cooldown not working"
        echo "   - Recovery performed: $recovery_count times"
        echo "   - Cooldown skips: $cooldown_count times"
        return 1
    fi
}
# Test 5: Reboot Recovery
test_reboot_recovery() {
    echo "🔄 Testing Reboot Recovery..."
    
    # Schedule notification
    echo "📅 Scheduling notification for reboot test..."
    echo "⚠️  Manual step: Schedule notification in app UI"
    read -p "Press Enter when notification is scheduled..."
    
    # Verify initial scheduling
    if ! adb shell "dumpsys alarm | grep -q timesafari"; then
        echo "❌ No alarm scheduled before reboot"
        return 1
    fi
    
    echo "🔄 Rebooting device..."
    adb reboot
    
    echo "⏳ Waiting for device to boot..."
    adb wait-for-device
    sleep 30
    
    # Check recovery logs
    if adb logcat -d | grep -q "Recovery requested from: BOOT_COMPLETED"; then
        echo "✅ Boot recovery triggered"
    else
        echo "❌ Boot recovery not triggered"
        return 1
    fi
    
    # Check alarms restored
    if adb shell "dumpsys alarm | grep -q timesafari"; then
        echo "✅ Alarms restored after reboot"
        return 0
    else
        echo "❌ Alarms not restored after reboot"
        return 1
    fi
}
# Main test execution
main() {
    echo "🚀 Starting comprehensive test suite..."
    echo ""
    
    # Run all tests
    run_test "Channel Management" test_channel_management
    run_test "PendingIntent & Exact Alarms" test_pendingintent_alarms
    run_test "JIT Freshness Re-check" test_jit_freshness
    run_test "Recovery Coexistence" test_recovery_coexistence
    run_test "Reboot Recovery" test_reboot_recovery
    
    # Print results summary
    echo "📊 Test Results Summary"
    echo "======================"
    local pass_count=0
    local total_count=0
    
    for test_name in "${!test_results[@]}"; do
        local result="${test_results[$test_name]}"
        echo "$test_name: $result"
        if [ "$result" = "PASS" ]; then
            ((pass_count++))
        fi
        ((total_count++))
    done
    
    echo ""
    echo "Overall: $pass_count/$total_count tests passed"
    
    if [ $pass_count -eq $total_count ]; then
        echo "🎉 All tests passed! P0 features working correctly."
        exit 0
    else
        echo "❌ Some tests failed. Check logs for details."
        exit 1
    fi
}
# Run main function
main
Python Test Suite v2.0
#!/usr/bin/env python3
"""
DailyNotification Plugin Comprehensive Test Suite v2.0
Tests all P0 production-grade features
"""
import subprocess
import time
import sys
import json
from typing import Dict, List, Optional, Tuple
class DailyNotificationTesterV2:
    def __init__(self, package: str = "com.timesafari.dailynotification"):
        self.package = package
        self.activity = f"{package}/.MainActivity"
        self.test_results: Dict[str, bool] = {}
        
    def run_adb_command(self, command: str) -> subprocess.CompletedProcess:
        """Run ADB command and return result"""
        return subprocess.run(
            f"adb {command}", 
            shell=True, 
            capture_output=True, 
            text=True
        )
    
    def is_app_running(self) -> bool:
        """Check if app is currently running"""
        result = self.run_adb_command(f'shell "ps | grep {self.package}"')
        return result.returncode == 0 and self.package in result.stdout
    
    def launch_app(self) -> bool:
        """Launch the app"""
        result = self.run_adb_command(f"shell am start -n {self.activity}")
        time.sleep(3)
        return self.is_app_running()
    
    def test_channel_management(self) -> bool:
        """Test P0 Priority 1: Channel Management"""
        print("📢 Testing Channel Management...")
        
        # Launch app
        if not self.launch_app():
            print("❌ Failed to launch app")
            return False
        
        # Check channel exists
        result = self.run_adb_command('shell "dumpsys notification | grep daily_default"')
        if result.returncode != 0:
            print("❌ Channel not found")
            return False
        
        # Check channel importance
        result = self.run_adb_command('shell "dumpsys notification | grep -A5 daily_default"')
        if "3" not in result.stdout:  # IMPORTANCE_HIGH = 3
            print("❌ Channel importance incorrect")
            return False
        
        print("✅ Channel management working")
        return True
    
    def test_pendingintent_alarms(self) -> bool:
        """Test P0 Priority 2: PendingIntent & Exact Alarms"""
        print("⏰ Testing PendingIntent & Exact Alarms...")
        
        # Check exact alarm support
        result = self.run_adb_command('shell "dumpsys alarm | grep SCHEDULE_EXACT_ALARM"')
        if result.returncode == 0:
            print("✅ Exact alarm permission system available")
        else:
            print("⚠️  Exact alarm permission system not available (pre-Android 12)")
        
        # Manual step: Schedule notification
        print("⚠️  Manual step: Schedule notification in app UI")
        input("Press Enter when notification is scheduled...")
        
        # Check alarm scheduled
        result = self.run_adb_command('shell "dumpsys alarm | grep timesafari"')
        if result.returncode != 0:
            print("❌ No alarm found")
            return False
        
        print("✅ PendingIntent & Exact Alarms working")
        return True
    
    def test_jit_freshness(self) -> bool:
        """Test P0 Priority 3: JIT Freshness Re-check"""
        print("🔄 Testing JIT Freshness Re-check...")
        
        # Clear logs
        self.run_adb_command("logcat -c")
        
        # Manual step: Schedule notification
        print("⚠️  Manual step: Schedule notification in app UI")
        input("Press Enter when notification is scheduled...")
        
        # Wait for notification to fire and check logs
        print("⏰ Waiting for notification to fire...")
        start_time = time.time()
        timeout = 60
        
        while time.time() - start_time < timeout:
            result = self.run_adb_command("logcat -d")
            if "Content is fresh" in result.stdout and "skipping JIT refresh" in result.stdout:
                print("✅ JIT freshness check working (fresh content)")
                return True
            elif "Content is stale" in result.stdout and "attempting JIT refresh" in result.stdout:
                print("✅ JIT freshness check working (stale content)")
                return True
            time.sleep(5)
        
        print("❌ JIT freshness re-check not working")
        return False
    
    def test_recovery_coexistence(self) -> bool:
        """Test P0 Priority 4: Recovery Coexistence"""
        print("🔄 Testing Recovery Coexistence...")
        
        # Clear logs
        self.run_adb_command("logcat -c")
        
        # Manual step: Schedule notification
        print("⚠️  Manual step: Schedule notification in app UI")
        input("Press Enter when notification is scheduled...")
        
        # Launch app multiple times to test cooldown
        print("🚀 Testing app startup recovery cooldown...")
        for i in range(3):
            self.run_adb_command(f"shell am start -n {self.activity}")
            time.sleep(2)
        
        # Check recovery logs
        result = self.run_adb_command("logcat -d")
        recovery_count = result.stdout.count("Recovery requested from: APP_STARTUP")
        cooldown_count = result.stdout.count("Recovery performed recently")
        
        if recovery_count == 1 and cooldown_count > 0:
            print(f"✅ Recovery cooldown working correctly")
            print(f"   - Recovery performed: {recovery_count} times")
            print(f"   - Cooldown skips: {cooldown_count} times")
            return True
        else:
            print(f"❌ Recovery cooldown not working")
            print(f"   - Recovery performed: {recovery_count} times")
            print(f"   - Cooldown skips: {cooldown_count} times")
            return False
    
    def test_reboot_recovery(self) -> bool:
        """Test Reboot Recovery with RecoveryManager"""
        print("🔄 Testing Reboot Recovery...")
        
        # Manual step: Schedule notification
        print("⚠️  Manual step: Schedule notification in app UI")
        input("Press Enter when notification is scheduled...")
        
        # Verify initial scheduling
        result = self.run_adb_command('shell "dumpsys alarm | grep timesafari"')
        if result.returncode != 0:
            print("❌ No alarm scheduled before reboot")
            return False
        
        print("🔄 Rebooting device...")
        self.run_adb_command("reboot")
        
        print("⏳ Waiting for device to boot...")
        self.run_adb_command("wait-for-device")
        time.sleep(30)
        
        # Check recovery logs
        result = self.run_adb_command("logcat -d")
        if "Recovery requested from: BOOT_COMPLETED" not in result.stdout:
            print("❌ Boot recovery not triggered")
            return False
        
        # Check alarms restored
        result = self.run_adb_command('shell "dumpsys alarm | grep timesafari"')
        if result.returncode != 0:
            print("❌ Alarms not restored after reboot")
            return False
        
        print("✅ Reboot recovery working")
        return True
    
    def run_comprehensive_test_suite(self) -> Dict[str, bool]:
        """Run complete test suite for all P0 features"""
        print("🧪 DailyNotification Plugin Comprehensive Test Suite v2.0")
        print("=" * 60)
        print("Testing P0 Production-Grade Features:")
        print("✅ Channel Management (P0 Priority 1)")
        print("✅ PendingIntent & Exact Alarms (P0 Priority 2)")
        print("✅ JIT Freshness Re-check (P0 Priority 3)")
        print("✅ Recovery Coexistence (P0 Priority 4)")
        print("")
        
        # Run all tests
        self.test_results["Channel Management"] = self.test_channel_management()
        self.test_results["PendingIntent & Exact Alarms"] = self.test_pendingintent_alarms()
        self.test_results["JIT Freshness Re-check"] = self.test_jit_freshness()
        self.test_results["Recovery Coexistence"] = self.test_recovery_coexistence()
        self.test_results["Reboot Recovery"] = self.test_reboot_recovery()
        
        return self.test_results
    
    def print_results_summary(self):
        """Print test results summary"""
        print("\n📊 Test Results Summary")
        print("=" * 30)
        
        pass_count = 0
        total_count = len(self.test_results)
        
        for test_name, passed in self.test_results.items():
            status = "✅ PASS" if passed else "❌ FAIL"
            print(f"{test_name}: {status}")
            if passed:
                pass_count += 1
        
        print(f"\nOverall: {pass_count}/{total_count} tests passed")
        
        if pass_count == total_count:
            print("🎉 All tests passed! P0 features working correctly.")
            return True
        else:
            print("❌ Some tests failed. Check logs for details.")
            return False
def main():
    tester = DailyNotificationTesterV2()
    tester.run_comprehensive_test_suite()
    
    if tester.print_results_summary():
        sys.exit(0)
    else:
        sys.exit(1)
if __name__ == "__main__":
    main()
Edge Case Testing
Test Suite E: Edge Cases
Test E1: Network Connectivity Issues
Objective: Test behavior with poor/no network connectivity
Steps:
# 1. Disable network connectivity
adb shell "svc wifi disable"
adb shell "svc data disable"
# 2. Schedule notification
# 3. Wait for JIT refresh attempt
# 4. Check fallback behavior
Expected Results:
- JIT refresh attempted
 - Refresh fails gracefully
 - Original content used as fallback
 
Test E2: Battery Optimization
Objective: Test behavior with battery optimization enabled
Steps:
# 1. Enable battery optimization for app
adb shell "dumpsys deviceidle whitelist -com.timesafari.dailynotification"
# 2. Schedule notification
# 3. Wait for notification
# 4. Check if notification appears
Expected Results:
- Notification appears despite battery optimization
 - Logs show proper alarm scheduling
 
Test E3: Multiple Rapid Scheduling
Objective: Test rapid notification scheduling
Steps:
# 1. Schedule multiple notifications rapidly
# 2. Check alarm manager state
# 3. Verify all notifications fire
Expected Results:
- All notifications scheduled correctly
 - No conflicts or errors
 - All notifications fire at correct times
 
Performance Testing
Test Suite P: Performance
Test P1: Memory Usage
Objective: Monitor memory usage during operation
Steps:
# 1. Check initial memory usage
adb shell "dumpsys meminfo com.timesafari.dailynotification"
# 2. Schedule multiple notifications
# 3. Check memory usage again
# 4. Wait for notifications to fire
# 5. Check final memory usage
Expected Results:
- Memory usage remains stable
 - No memory leaks detected
 - Proper cleanup after notifications
 
Test P2: CPU Usage
Objective: Monitor CPU usage during recovery operations
Steps:
# 1. Monitor CPU usage during app startup
adb shell "top -n 1 | grep timesafari"
# 2. Monitor CPU usage during recovery
# 3. Check CPU usage during JIT refresh
Expected Results:
- CPU usage remains reasonable
 - No excessive CPU usage during recovery
 - Efficient JIT refresh operations
 
Troubleshooting Guide
Common Issues and Solutions
Issue 1: Channel Not Created
Symptoms: Channel status shows "not found"
Solutions:
# Check channel creation logs
adb logcat -d | grep -i "channel.*created"
# Verify ChannelManager initialization
adb logcat -d | grep -i "channelmanager"
Issue 2: Exact Alarm Permission Denied
Symptoms: exactAlarmsGranted: false
Solutions:
# Check exact alarm permission
adb shell "dumpsys alarm | grep SCHEDULE_EXACT_ALARM"
# Open exact alarm settings
adb shell "am start -a android.settings.REQUEST_SCHEDULE_EXACT_ALARM -d package:com.timesafari.dailynotification"
Issue 3: JIT Refresh Not Working
Symptoms: No JIT refresh logs
Solutions:
# Check JIT refresh logs
adb logcat -d | grep -i "jit\|freshness"
# Verify content age calculation
adb logcat -d | grep -i "age.*minutes"
Issue 4: Recovery Not Working
Symptoms: No recovery logs after reboot
Solutions:
# Check RecoveryManager logs
adb logcat -d | grep -i "recovery.*requested"
# Check recovery state
adb logcat -d | grep -i "recovery.*performed.*recently"
Debug Commands
# Comprehensive status check
adb shell "dumpsys notification | grep -A10 daily_default"
adb shell "dumpsys alarm | grep -A5 timesafari"
adb shell "dumpsys package com.timesafari.dailynotification | grep -A5 receiver"
# Recovery state check
adb shell "run-as com.timesafari.dailynotification ls -la /data/data/com.timesafari.dailynotification/shared_prefs/"
# Channel status check
adb shell "cmd notification list | grep daily_default"
# Alarm manager state
adb shell "dumpsys alarm | head -20"
Success Criteria
✅ All Tests Pass When:
- 
Channel Management:
- Channel created with correct ID and importance
 - Channel blocking detection works
 - Settings deep linking works
 
 - 
PendingIntent & Exact Alarms:
- Modern PendingIntent flags used
 - Exact alarm permission detection works
 - Settings deep linking works
 
 - 
JIT Freshness Re-check:
- Fresh content skips refresh
 - Stale content attempts refresh
 - Graceful fallback on failure
 
 - 
Recovery Coexistence:
- App startup recovery works
 - Boot recovery works
 - Cooldown prevents duplicate recovery
 - Statistics tracking works
 
 - 
Reboot Recovery:
- Boot receiver triggered
 - Notifications restored
 - Alarms rescheduled correctly
 
 
❌ Tests Fail When:
- Any P0 feature doesn't work as expected
 - Recovery operations conflict
 - Memory leaks detected
 - Performance issues observed
 - Error logs show critical failures
 
Conclusion
This comprehensive testing guide ensures all P0 production-grade features work correctly. The test suite covers:
- Channel Management: Notification channel creation and management
 - PendingIntent & Exact Alarms: Modern Android compatibility
 - JIT Freshness Re-check: Content freshness validation
 - Recovery Coexistence: Idempotent recovery operations
 - Reboot Recovery: Robust persistence across reboots
 
Regular testing with this guide ensures the DailyNotification plugin maintains production-grade reliability and performance.
For questions or issues, refer to the troubleshooting section or check the plugin logs using the provided ADB commands.