refactor(plugin): modernize plugin architecture and improve type definitions

- Update package.json with modern build tooling and dependencies
- Streamline and enhance TypeScript definitions for better type safety
- Reorganize plugin structure for better maintainability
- Add comprehensive interface definitions for notification features
- Implement proper build configuration with rollup
- Update tsconfig.json for stricter type checking and ES2020 modules

Breaking Changes:
- Changed module structure to use ES modules
- Updated interface definitions with stricter typing
- Removed redundant notification options
- Simplified API surface while maintaining core functionality

Dependencies:
- Upgrade @capacitor dependencies to v5.7.8
- Add rollup and typescript build tools
- Update test framework configuration
This commit is contained in:
Matthew Raymer
2025-03-28 12:47:10 +00:00
parent a54ba34cb9
commit a336b39754
133 changed files with 928 additions and 4260 deletions

19
.eslintrc.json Normal file
View File

@@ -0,0 +1,19 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"env": {
"node": true,
"jest": true
},
"rules": {
"@typescript-eslint/explicit-function-return-type": "warn",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
"no-console": ["warn", { "allow": ["warn", "error"] }]
}
}

66
.gitignore vendored
View File

@@ -1,15 +1,61 @@
dist/
# Dependencies
node_modules/
.DS_Store
Pods/
*.iml
npm-debug.log
yarn-debug.log
yarn-error.log
# Build output
dist/
build/
*.tsbuildinfo
# IDE
.idea/
.vscode/
build/
*.tgz
*.swp
*.swo
# Ignore Gradle project-specific cache directory
.gradle
# OS
.DS_Store
Thumbs.db
# Ignore Gradle build output directory
build
# Android
android/app/build/
android/build/
android/gradle/
android/gradlew
android/gradlew.bat
android/.gradle/
android/local.properties
android/.idea/
android/*.iml
# iOS
ios/Pods/
ios/build/
ios/Podfile.lock
ios/.xcode.env.local
ios/DerivedData/
ios/*.xcworkspace/
ios/*.xcodeproj/*
!ios/*.xcodeproj/project.pbxproj
!ios/*.xcodeproj/xcshareddata/
!ios/*.xcworkspace/contents.xcworkspacedata
# Testing
coverage/
.nyc_output/
# Logs
logs/
*.log
# Environment
.env
.env.local
.env.*.local
# Temporary files
*.tmp
*.temp
.cache/

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

Binary file not shown.

View File

@@ -0,0 +1,2 @@
#Fri Mar 28 09:01:29 UTC 2025
gradle.version=8.13

Binary file not shown.

View File

@@ -0,0 +1 @@
_{<7B><>=lLg͒<67><CD92><EFBFBD>w<EFBFBD>xD=<3D><1E>H<1A><><EFBFBD><EFBFBD>z<>QbK6<>E<EFBFBD>+Il/b<><62>zj<1B><><0F><>B4<42><34><EFBFBD><EFBFBD>`S<><53>8<EFBFBD>Oo}]<5D><>y<EFBFBD>~<17><>u<EFBFBD>\<5C>t<EFBFBD>ĞqT<71>DVEq<45>G<EFBFBD>5<EFBFBD>b<EFBFBD>*r<><72>D<EFBFBD> <09>L<EFBFBD><4C>-d<64><7F>C<EFBFBD><43>1<EFBFBD><31>'<1C><07>K<EFBFBD><10><>%<25>e<EFBFBD><65>A'p<><70><EFBFBD><EFBFBD>9<>]jPor<6F>z<EFBFBD>T<EFBFBD><54>b_<62>OūxٙW<D999>6-<2D><17>V<>i<EFBFBD>y<EFBFBD>?<3F>ؐAB'<27><>z'<27><><EFBFBD><EFBFBD>P:<3A>B<EFBFBD><42><02>c<1B><><EFBFBD>\Q<>*<2A>2<EFBFBD><32>[<5B><>+ pTvmo<6D><07>ٿ<0E>AJ<41><14><><EFBFBD>yG<79>ؒ<EFBFBD>P@f<>k<EFBFBD><6B><18><>`%w <0F><>Wh<>\ӻn?<3F><>D⏭<44><E28FAD><EFBFBD>ł˂<C582><CB82><EFBFBD><EFBFBD><EFBFBD>ټD<D9BC>r]<5D><>9<EFBFBD><l<>X<>7<EFBFBD>4o<><0F><><EFBFBD>q?ξ<>e-<2D><>J<><4A>?<3F><>*

View File

@@ -0,0 +1 @@
6c6d7154-1c12-44da-bab9-788cea5132b<32>

View File

@@ -0,0 +1 @@
T<EFBFBD>lX卆^)~c<><63><EFBFBD><EFBFBD><13>D

View File

@@ -0,0 +1 @@
^<5E><EFBFBD>e v<>a<EFBFBD>r<EFBFBD><72><EFBFBD><EFBFBD>+׽

View File

@@ -0,0 +1 @@
96e7369f-9457-47f1-8304-05bf876b89f<39>

View File

@@ -0,0 +1 @@
102cc785-1d0d-4dbb-a688-2153e21cdbf<62>

View File

@@ -0,0 +1 @@
5dbbc9a7-8a29-4ae7-b3f0-33b5a5e5203<30>

View File

@@ -0,0 +1 @@
f93c619e-5608-44c0-ae77-793c324d124<32>

View File

@@ -0,0 +1 @@
0809f6f5-185b-4807-b8df-47cb0fd7076<37>

View File

@@ -0,0 +1,3 @@
M<EFBFBD>4<EFBFBD>YG<EFBFBD>4#<23><><EFBFBD><EFBFBD>
1z<>


View File

@@ -0,0 +1 @@
<02>U2 C<17><>'<27><><EFBFBD>?<3F><>s<EFBFBD><73>9Т<39>

View File

@@ -0,0 +1 @@
6277d4cb-02d2-4a97-aa8b-c333720dfd7<64>

Binary file not shown.

View File

@@ -0,0 +1 @@
da5353e4-2da1-4b2a-8d76-9f7a80dfac3<63>

View File

@@ -0,0 +1 @@
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>6<EFBFBD>ԩ&U<><55><EFBFBD>,<2C>bj<62><0E>a\<5C><><EFBFBD>JLne<6E><65><EFBFBD>kh<06>?<3F><10><>b<EFBFBD>

View File

@@ -0,0 +1,4 @@
E[<5B>$<24><>qQ<><51><EFBFBD><14>>b<>Ԃ<EFBFBD>X<>^C<>RK<18><> <09><>U<EFBFBD>pY<16><>hΖ<68><CE96> p<><70><EFBFBD><EFBFBD>*<2A>R<EFBFBD>ze <0B><>@dV<>e_WKy=T$<24><>_Wf<57><66>n<><1D><>!|<7C>R<EFBFBD><52>_<> <20>ɘ7<C998> <0B><><EFBFBD>2<EFBFBD>w<EFBFBD>4|<7C>\<5C><>:<3A>}<7D>H<EFBFBD>-<><7F><EFBFBD><EFBFBD>y@2Q<><51>K<EFBFBD>Ȑ<EFBFBD>B@YT<59>
yh<EFBFBD>G<EFBFBD>l<EFBFBD><EFBFBD>s<EFBFBD>e<13>,
p<EFBFBD><EFBFBD><EFBFBD>e<EFBFBD>.<2E>Έ <0B><><<3C><>b<EFBFBD><62>
T<EFBFBD><EFBFBD><EFBFBD>`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.@<40><>";<3B>6<EFBFBD><36><<3C><><EFBFBD><EFBFBD><EFBFBD>Hܿ<48>z M1P}<7D><><EFBFBD>9s?<3F><>ו,<2C>'tG<><47>W<EFBFBD><57>:w<><77><EFBFBD>|ɪ<08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><15><><EFBFBD><EFBFBD><EFBFBD>=e<>2<>|<7C><>74<37>]<5D>C  <0B><><EFBFBD><EFBFBD>]<5D><>dT)Bh<42><68><EFBFBD>Ufa<66>⌐5<E28C90><35><EFBFBD><EFBFBD>R)r<><72>)<29><><EFBFBD>KR<4B><52>F<EFBFBD><1F><><EFBFBD>cC<63>.h(ڹ<>A<EFBFBD><41>׭

View File

@@ -0,0 +1 @@
f64db575-a480-4fdc-82c4-6fc81d961b4<62>

View File

@@ -0,0 +1 @@
<EFBFBD><EFBFBD> <0B><>R<08>P<-Op2<70>0<1C>X<EFBFBD>|

View File

@@ -0,0 +1 @@
o<><6F><EFBFBD>m<EFBFBD>c-<02><><EFBFBD><EFBFBD><EFBFBD>u1<75>G

BIN
.gradle/file-system.probe Normal file

Binary file not shown.

View File

10
.prettierrc Normal file
View File

@@ -0,0 +1,10 @@
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true,
"arrowParens": "avoid"
}

215
README.md
View File

@@ -1,143 +1,146 @@
# Daily Notification Plugin for Capacitor
# Daily Notification Plugin
A Capacitor plugin for scheduling and managing daily notifications with advanced features and robust error handling.
A Capacitor plugin for scheduling and managing daily notifications on Android devices.
## Features
- Schedule daily notifications with custom time and content
- Support for different priority levels
- Timezone-aware scheduling
- Offline support with caching
- Comprehensive permission handling
- Automatic retry logic
- Detailed notification status tracking
- Configurable settings management
- Schedule daily notifications with precise timing
- Handle system state changes (battery, power, etc.)
- Support for adaptive scheduling based on device state
- Background task management
- Battery optimization support
- Rich logging system
- Comprehensive error handling
## Installation
```bash
npm install daily-notification-plugin
npx cap sync
npm install @timesafari/daily-notification-plugin
```
## iOS Setup
No additional setup required for iOS. The plugin automatically handles all necessary configurations.
## Usage
### Basic Usage
```typescript
import { DailyNotification } from 'daily-notification-plugin';
import { DailyNotification } from '@timesafari/daily-notification-plugin';
// Initialize the plugin
const dailyNotification = new DailyNotification();
// Schedule a daily notification
await DailyNotification.scheduleDailyNotification({
url: 'https://api.example.com/updates',
time: '09:00',
title: 'Daily Update',
body: 'Your daily update is ready'
await dailyNotification.scheduleDailyNotification({
sound: true,
priority: 'default',
timezone: 'UTC'
});
```
### Advanced Features
// Get notification status
const status = await dailyNotification.getNotificationStatus();
#### Custom Priority
```typescript
await DailyNotification.scheduleDailyNotification({
url: 'https://api.example.com/updates',
time: '09:00',
// Update settings
await dailyNotification.updateSettings({
sound: false,
priority: 'high'
});
// Cancel all notifications
await dailyNotification.cancelAllNotifications();
// Get battery status
const batteryStatus = await dailyNotification.getBatteryStatus();
// Request battery optimization exemption
await dailyNotification.requestBatteryOptimizationExemption();
```
#### Timezone Support
## Configuration
```typescript
await DailyNotification.scheduleDailyNotification({
url: 'https://api.example.com/updates',
time: '09:00',
timezone: 'America/New_York'
});
### Android
Add the following permissions to your `AndroidManifest.xml`:
```xml
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
```
#### Check Notification Status
## Development
```typescript
const status = await DailyNotification.getNotificationStatus();
console.log('Notification status:', status);
### Prerequisites
- Node.js 14 or later
- Android Studio
- Android SDK
- Gradle
### Building
```bash
# Install dependencies
npm install
# Build the plugin
npm run build
# Run tests
npm test
```
#### Update Settings
### Project Structure
```typescript
await DailyNotification.updateSettings({
sound: true,
priority: 'high',
timezone: 'America/Los_Angeles'
});
```
## API Documentation
### Methods
#### scheduleDailyNotification(options: ScheduleOptions)
Schedule a new daily notification.
#### getLastNotification()
Get information about the last delivered notification.
#### cancelAllNotifications()
Cancel all pending notifications.
#### getNotificationStatus()
Get current notification status and settings.
#### updateSettings(settings: NotificationSettings)
Update notification settings.
#### checkPermissions()
Check current notification permissions.
#### requestPermissions()
Request notification permissions.
### Types
```typescript
interface ScheduleOptions {
url: string;
time: string;
title?: string;
body?: string;
sound?: boolean;
priority?: 'high' | 'default' | 'low';
timezone?: string;
}
interface NotificationSettings {
sound?: boolean;
priority?: string;
timezone?: string;
}
daily-notification-plugin/
├── android/ # Android implementation
│ ├── app/ # Main application module
│ └── build.gradle # Root build configuration
├── src/ # TypeScript source
├── tests/ # Test files
├── package.json # Package configuration
└── README.md # This file
```
## Error Handling
The plugin provides detailed error messages for various scenarios:
- Invalid parameters
- Permission issues
- Scheduling failures
- Invalid time formats
- Invalid timezone identifiers
- Invalid priority values
## Contributing
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our GitHub repository.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## License
MIT License - see LICENSE file for details
This project is licensed under the MIT License - see the LICENSE file for details.
## Author
Matthew Raymer
## Security
This plugin follows security best practices:
- Uses AndroidX for modern security features
- Implements proper permission handling
- Follows Android security guidelines
- Uses secure storage for sensitive data
- Implements proper error handling
- Logs security-relevant events
- Uses secure communication channels
- Implements proper access control
- Follows Android's security model
- Uses secure defaults
## Changelog
### 1.0.0
- Initial release
- Basic notification scheduling
- System state handling
- Battery optimization support
- Background task management
- Rich logging system

0
android/Configure Normal file
View File

View File

@@ -1,15 +1,12 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'jacoco'
android {
namespace "com.timesafari.dailynotification"
compileSdkVersion 33
buildToolsVersion "33.0.2"
compileSdkVersion rootProject.ext.compileSdkVersion
defaultConfig {
applicationId "com.timesafari.dailynotification"
minSdkVersion 22
targetSdkVersion 33
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -22,98 +19,27 @@ android {
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
testOptions {
unitTests.all {
useJUnitPlatform()
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
repositories {
google()
mavenCentral()
maven {
url "${project.rootDir}/capacitor-cordova-android-plugins/src/main/libs"
}
maven {
url "${project.rootDir}/libs"
flatDir{
dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs'
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"
implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion"
implementation project(':capacitor-android')
testImplementation "junit:junit:$junitVersion"
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
implementation project(':capacitor-cordova-android-plugins')
// Android SDK
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
// AndroidX Core
implementation 'androidx.core:core:1.9.0'
implementation 'androidx.core:core-ktx:1.12.0'
// AndroidX AppCompat
implementation 'androidx.appcompat:appcompat:1.6.1'
// AndroidX Test
testImplementation 'androidx.test:core:1.5.0'
testImplementation 'androidx.test:runner:1.5.2'
testImplementation 'androidx.test.ext:junit:1.1.5'
testImplementation 'androidx.test.espresso:espresso-core:3.5.1'
testImplementation 'androidx.test:rules:1.5.0'
testImplementation 'androidx.test:core-ktx:1.5.0'
// JUnit
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.2'
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.2'
// Mockito
testImplementation 'org.mockito:mockito-core:4.5.1'
testImplementation 'org.mockito:mockito-inline:4.5.1'
// AndroidX WorkManager
implementation 'androidx.work:work-runtime:2.8.1'
// AndroidX Room (for local storage)
implementation 'androidx.room:room-runtime:2.6.1'
annotationProcessor 'androidx.room:room-compiler:2.6.1'
// AndroidX Lifecycle
implementation 'androidx.lifecycle:lifecycle-runtime:2.7.0'
implementation 'androidx.lifecycle:lifecycle-common-java8:2.7.0'
// AndroidX Security
implementation 'androidx.security:security-crypto:1.1.0-alpha06'
// AndroidX Notification
implementation 'androidx.media:media:1.7.0'
// AndroidX Broadcast
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0'
// Capacitor dependencies
implementation 'com.getcapacitor:capacitor:5.0.0'
implementation 'com.getcapacitor:capacitor-android:5.0.0'
// Testing dependencies
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation 'androidx.test:runner:1.5.2'
androidTestImplementation 'androidx.test:rules:1.5.0'
androidTestImplementation 'org.mockito:mockito-android:4.5.1'
}
apply from: 'capacitor.build.gradle'
@@ -124,5 +50,5 @@ try {
apply plugin: 'com.google.gms.google-services'
}
} catch(Exception e) {
logger.warn("google-services.json not found, google-services plugin not applied. Push Notifications won't work")
logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work")
}

View File

@@ -9,6 +9,11 @@ android {
apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
dependencies {
implementation project(':capacitor-android')
implementation project(':capacitor-cordova-android-plugins')
}
}
if (hasProperty('postBuildExtras')) {
postBuildExtras()
}

View File

@@ -1 +0,0 @@
/home/matthew/projects/timesafari/daily-notification-plugin/android/app/src/androidTest/java/com/timesafari/dailynotification/DailyNotificationPluginTest.java

View File

@@ -1,104 +0,0 @@
/**
* DailyNotificationConfigTest.java
* Daily Notification Plugin for Capacitor
*
* Tests for the DailyNotificationConfig
*
* Features:
* - Unit tests
* - Singleton pattern
* - Configuration management
* - Default values
*
* @author Matthew Raymer
*/
package com.timesafari.dailynotification;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.TimeZone;
import static org.junit.Assert.*;
@RunWith(MockitoJUnitRunner.class)
public class DailyNotificationConfigTest {
private DailyNotificationConfig config;
@Before
public void setUp() {
config = DailyNotificationConfig.getInstance();
}
@Test
public void testSingletonPattern() {
DailyNotificationConfig config2 = DailyNotificationConfig.getInstance();
assertSame("Config instances should be the same", config, config2);
}
@Test
public void testDefaultValues() {
assertEquals("Default max notifications should be 10", 10,
config.getMaxNotificationsPerDay());
assertEquals("Default timezone should be system default",
TimeZone.getDefault(), config.getDefaultTimeZone());
assertTrue("Default logging should be enabled", config.isLoggingEnabled());
assertEquals("Default retention days should be 7", 7,
config.getRetentionDays());
}
@Test
public void testMaxNotificationsPerDay() {
config.setMaxNotificationsPerDay(5);
assertEquals("Max notifications should be 5", 5,
config.getMaxNotificationsPerDay());
}
@Test
public void testDefaultTimeZone() {
TimeZone newTimeZone = TimeZone.getTimeZone("America/New_York");
config.setDefaultTimeZone(newTimeZone);
assertEquals("Default timezone should be America/New_York",
newTimeZone, config.getDefaultTimeZone());
}
@Test
public void testLoggingEnabled() {
config.setLoggingEnabled(false);
assertFalse("Logging should be disabled", config.isLoggingEnabled());
config.setLoggingEnabled(true);
assertTrue("Logging should be enabled", config.isLoggingEnabled());
}
@Test
public void testRetentionDays() {
config.setRetentionDays(14);
assertEquals("Retention days should be 14", 14,
config.getRetentionDays());
}
@Test
public void testResetToDefaults() {
// Change values
config.setMaxNotificationsPerDay(5);
config.setDefaultTimeZone(TimeZone.getTimeZone("America/New_York"));
config.setLoggingEnabled(false);
config.setRetentionDays(14);
// Reset to defaults
config.resetToDefaults();
// Verify defaults
assertEquals("Max notifications should be reset to 10", 10,
config.getMaxNotificationsPerDay());
assertEquals("Default timezone should be reset to system default",
TimeZone.getDefault(), config.getDefaultTimeZone());
assertTrue("Logging should be reset to enabled", config.isLoggingEnabled());
assertEquals("Retention days should be reset to 7", 7,
config.getRetentionDays());
}
}

View File

@@ -1,126 +0,0 @@
/**
* DailyNotificationConstantsTest.java
* Daily Notification Plugin for Capacitor
*
* Tests for the DailyNotificationConstants
*
* Features:
* - Unit tests
* - Constant validation
* - Default values
* - Error messages
*
* @author Matthew Raymer
*/
package com.timesafari.dailynotification;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import static org.junit.Assert.*;
@RunWith(MockitoJUnitRunner.class)
public class DailyNotificationConstantsTest {
@Test
public void testDefaultValues() {
assertEquals("Default title should be 'Daily Notification'",
"Daily Notification", DailyNotificationConstants.DEFAULT_TITLE);
assertEquals("Default body should be 'Your daily update is ready'",
"Your daily update is ready", DailyNotificationConstants.DEFAULT_BODY);
}
@Test
public void testNotificationIdentifiers() {
assertTrue("Notification ID prefix should start with 'daily-notification-'",
DailyNotificationConstants.NOTIFICATION_ID_PREFIX.startsWith("daily-notification-"));
assertEquals("Event name should be 'notification'",
"notification", DailyNotificationConstants.EVENT_NAME);
}
@Test
public void testSettingsKeys() {
assertEquals("Sound setting key should be 'sound'",
"sound", DailyNotificationConstants.Settings.SOUND);
assertEquals("Priority setting key should be 'priority'",
"priority", DailyNotificationConstants.Settings.PRIORITY);
assertEquals("Timezone setting key should be 'timezone'",
"timezone", DailyNotificationConstants.Settings.TIMEZONE);
assertEquals("Retry count setting key should be 'retryCount'",
"retryCount", DailyNotificationConstants.Settings.RETRY_COUNT);
assertEquals("Retry interval setting key should be 'retryInterval'",
"retryInterval", DailyNotificationConstants.Settings.RETRY_INTERVAL);
}
@Test
public void testSettingsDefaultValues() {
assertTrue("Default sound should be true",
DailyNotificationConstants.Settings.DEFAULT_SOUND);
assertEquals("Default priority should be 'default'",
"default", DailyNotificationConstants.Settings.DEFAULT_PRIORITY);
assertEquals("Default retry count should be 3",
3, DailyNotificationConstants.Settings.DEFAULT_RETRY_COUNT);
assertEquals("Default retry interval should be 1000",
1000, DailyNotificationConstants.Settings.DEFAULT_RETRY_INTERVAL);
}
@Test
public void testPluginMethodKeys() {
assertEquals("URL key should be 'url'",
"url", DailyNotificationConstants.Keys.URL);
assertEquals("Time key should be 'time'",
"time", DailyNotificationConstants.Keys.TIME);
assertEquals("Title key should be 'title'",
"title", DailyNotificationConstants.Keys.TITLE);
assertEquals("Body key should be 'body'",
"body", DailyNotificationConstants.Keys.BODY);
assertEquals("Sound key should be 'sound'",
"sound", DailyNotificationConstants.Keys.SOUND);
assertEquals("Priority key should be 'priority'",
"priority", DailyNotificationConstants.Keys.PRIORITY);
assertEquals("Timezone key should be 'timezone'",
"timezone", DailyNotificationConstants.Keys.TIMEZONE);
}
@Test
public void testChannelSettings() {
assertEquals("Channel ID should be 'daily_notification_channel'",
"daily_notification_channel", DailyNotificationConstants.Channel.ID);
assertEquals("Channel name should be 'Daily Notifications'",
"Daily Notifications", DailyNotificationConstants.Channel.NAME);
assertEquals("Channel description should be 'Daily notification updates'",
"Daily notification updates", DailyNotificationConstants.Channel.DESCRIPTION);
assertTrue("Channel should enable vibration",
DailyNotificationConstants.Channel.ENABLE_VIBRATION);
assertTrue("Channel should enable lights",
DailyNotificationConstants.Channel.ENABLE_LIGHTS);
}
@Test
public void testTimeConstants() {
assertEquals("Milliseconds per day should be 86400000",
86400000, DailyNotificationConstants.Time.MILLIS_PER_DAY);
assertEquals("Maximum hours should be 24",
24, DailyNotificationConstants.Time.MAX_HOURS);
assertEquals("Maximum minutes should be 60",
60, DailyNotificationConstants.Time.MAX_MINUTES);
}
@Test
public void testErrorMessages() {
assertEquals("Missing parameters error message should be correct",
"Missing required parameters", DailyNotificationConstants.Errors.MISSING_PARAMS);
assertEquals("Invalid time error message should be correct",
"Invalid time format", DailyNotificationConstants.Errors.INVALID_TIME);
assertEquals("Invalid timezone error message should be correct",
"Invalid timezone", DailyNotificationConstants.Errors.INVALID_TIMEZONE);
assertEquals("Invalid priority error message should be correct",
"Invalid priority value", DailyNotificationConstants.Errors.INVALID_PRIORITY);
assertEquals("Scheduling failed error message should be correct",
"Failed to schedule notification", DailyNotificationConstants.Errors.SCHEDULING_FAILED);
assertEquals("Permission denied error message should be correct",
"Notification permission denied", DailyNotificationConstants.Errors.PERMISSION_DENIED);
}
}

Some files were not shown because too many files have changed in this diff Show More