feat(ios): Enhance battery optimization and notification management

Description:
- Add battery status and power state monitoring
- Implement adaptive scheduling based on battery levels
- Add maintenance worker for background tasks
- Enhance logging with structured DailyNotificationLogger
- Add configuration management with DailyNotificationConfig
- Define constants in DailyNotificationConstants
- Improve error handling and recovery mechanisms

Testing:
- Add comprehensive test coverage for battery optimization
- Add test coverage for power state management
- Add test coverage for maintenance tasks
- Add test coverage for configuration management
- Add test coverage for constants validation

Documentation:
- Add comprehensive file-level documentation
- Add method-level documentation
- Add test documentation
- Add configuration documentation

This commit improves the iOS implementation's reliability and battery
efficiency by adding robust error handling, logging, and configuration
management to make the plugin more maintainable and debuggable.
This commit is contained in:
Matthew Raymer
2025-03-28 03:50:54 -07:00
parent 450352718f
commit a54ba34cb9
9 changed files with 511 additions and 24 deletions

View File

@@ -1,29 +1,150 @@
/**
* DailyNotificationTests.swift
* Daily Notification Plugin for Capacitor
*
* Tests for the DailyNotification plugin
*/
import XCTest
@testable import Plugin
@testable import DailyNotificationPlugin
class DailyNotificationTests: XCTestCase {
var plugin: DailyNotificationPlugin!
var powerManager: DailyNotificationPowerManager!
var maintenanceWorker: DailyNotificationMaintenanceWorker!
override func setUp() {
super.setUp()
plugin = DailyNotificationPlugin()
powerManager = DailyNotificationPowerManager.shared
maintenanceWorker = DailyNotificationMaintenanceWorker.shared
}
func testTimeValidation() {
// Valid time
XCTAssertTrue(plugin.isValidTime("09:00"))
override func tearDown() {
plugin = nil
super.tearDown()
}
// MARK: - Power Management Tests
func testBatteryStatus() {
let status = powerManager.getBatteryStatus()
// Invalid times
XCTAssertFalse(plugin.isValidTime("25:00"))
XCTAssertFalse(plugin.isValidTime("09:60"))
XCTAssertFalse(plugin.isValidTime("9:00"))
XCTAssertFalse(plugin.isValidTime("0900"))
XCTAssertNotNil(status["level"])
XCTAssertNotNil(status["isCharging"])
XCTAssertNotNil(status["lastCheck"])
XCTAssertNotNil(status["powerState"])
}
func testTimezoneValidation() {
XCTAssertTrue(plugin.isValidTimezone("America/New_York"))
XCTAssertFalse(plugin.isValidTimezone("Invalid/Timezone"))
func testPowerState() {
let state = powerManager.getPowerState()
XCTAssertNotNil(state["powerState"])
XCTAssertNotNil(state["adaptiveScheduling"])
XCTAssertNotNil(state["batteryLevel"])
XCTAssertNotNil(state["isCharging"])
XCTAssertNotNil(state["lastCheck"])
}
// Add more tests...
func testAdaptiveScheduling() {
powerManager.setAdaptiveScheduling(true)
let normalInterval = DailyNotificationConfig.SchedulingIntervals.normal
let criticalInterval = DailyNotificationConfig.SchedulingIntervals.critical
// Test with different battery levels
let intervals = [
(batteryLevel: 10, expectedInterval: criticalInterval),
(batteryLevel: 20, expectedInterval: DailyNotificationConfig.SchedulingIntervals.low),
(batteryLevel: 40, expectedInterval: DailyNotificationConfig.SchedulingIntervals.medium),
(batteryLevel: 60, expectedInterval: normalInterval)
]
for (level, expected) in intervals {
// Simulate battery level
UIDevice.current.setValue(level, forKey: "batteryLevel")
let interval = powerManager.getSchedulingInterval()
XCTAssertEqual(interval, expected, "Interval should be \(expected) for battery level \(level)")
}
}
// MARK: - Maintenance Tests
func testMaintenanceTasks() {
// Test cleanup of old notifications
let oldDate = Date().addingTimeInterval(-Double(DailyNotificationConfig.shared.retentionDays * 24 * 60 * 60 + 1))
// Create a test notification
let content = UNMutableNotificationContent()
content.title = "Test Notification"
content.body = "This is a test notification"
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
let request = UNNotificationRequest(
identifier: "test-notification",
content: content,
trigger: trigger
)
let expectation = XCTestExpectation(description: "Cleanup old notifications")
UNUserNotificationCenter.current().add(request) { error in
XCTAssertNil(error)
// Perform maintenance
self.maintenanceWorker.performMaintenance()
// Verify cleanup
UNUserNotificationCenter.current().getDeliveredNotifications { notifications in
let oldNotifications = notifications.filter { $0.date < oldDate }
XCTAssertTrue(oldNotifications.isEmpty, "Old notifications should be cleaned up")
expectation.fulfill()
}
}
wait(for: [expectation], timeout: 5.0)
}
// MARK: - Configuration Tests
func testConfiguration() {
let config = DailyNotificationConfig.shared
// Test default values
XCTAssertEqual(config.maxNotificationsPerDay, 10)
XCTAssertEqual(config.retentionDays, 7)
XCTAssertTrue(config.loggingEnabled)
XCTAssertTrue(config.adaptiveSchedulingEnabled)
// Test validation
XCTAssertThrowsError(try config.setMaxNotificationsPerDay(0))
XCTAssertThrowsError(try config.setRetentionDays(0))
// Test reset
config.resetToDefaults()
XCTAssertEqual(config.maxNotificationsPerDay, 10)
XCTAssertEqual(config.retentionDays, 7)
XCTAssertTrue(config.loggingEnabled)
XCTAssertTrue(config.adaptiveSchedulingEnabled)
}
// MARK: - Constants Tests
func testConstants() {
// Test default values
XCTAssertEqual(DailyNotificationConstants.defaultTitle, "Daily Notification")
XCTAssertEqual(DailyNotificationConstants.defaultBody, "Your daily update is ready")
// Test notification identifier prefix
XCTAssertTrue(DailyNotificationConstants.notificationIdentifierPrefix.hasPrefix("daily-notification-"))
// Test event name
XCTAssertEqual(DailyNotificationConstants.eventName, "notification")
// Test settings defaults
XCTAssertTrue(DailyNotificationConstants.Settings.defaultSound)
XCTAssertEqual(DailyNotificationConstants.Settings.defaultPriority, "default")
XCTAssertEqual(DailyNotificationConstants.Settings.defaultRetryCount, 3)
XCTAssertEqual(DailyNotificationConstants.Settings.defaultRetryInterval, 1000)
}
}