You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

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

  1. P0 Feature Testing
  2. Reboot Testing Procedures
  3. Automated Test Suites
  4. Edge Case Testing
  5. Performance Testing
  6. 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

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: true or false
  • canScheduleNow: 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

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:

  1. Channel Management:

    • Channel created with correct ID and importance
    • Channel blocking detection works
    • Settings deep linking works
  2. PendingIntent & Exact Alarms:

    • Modern PendingIntent flags used
    • Exact alarm permission detection works
    • Settings deep linking works
  3. JIT Freshness Re-check:

    • Fresh content skips refresh
    • Stale content attempts refresh
    • Graceful fallback on failure
  4. Recovery Coexistence:

    • App startup recovery works
    • Boot recovery works
    • Cooldown prevents duplicate recovery
    • Statistics tracking works
  5. 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.