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/ node_modules/
.DS_Store npm-debug.log
Pods/ yarn-debug.log
*.iml yarn-error.log
# Build output
dist/
build/
*.tsbuildinfo
# IDE
.idea/ .idea/
.vscode/ .vscode/
build/ *.swp
*.tgz *.swo
# Ignore Gradle project-specific cache directory # OS
.gradle .DS_Store
Thumbs.db
# Ignore Gradle build output directory # Android
build 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 ## Features
- Schedule daily notifications with custom time and content - Schedule daily notifications with precise timing
- Support for different priority levels - Handle system state changes (battery, power, etc.)
- Timezone-aware scheduling - Support for adaptive scheduling based on device state
- Offline support with caching - Background task management
- Comprehensive permission handling - Battery optimization support
- Automatic retry logic - Rich logging system
- Detailed notification status tracking - Comprehensive error handling
- Configurable settings management
## Installation ## Installation
```bash ```bash
npm install daily-notification-plugin npm install @timesafari/daily-notification-plugin
npx cap sync
``` ```
## iOS Setup
No additional setup required for iOS. The plugin automatically handles all necessary configurations.
## Usage ## Usage
### Basic Usage
```typescript ```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 // Schedule a daily notification
await DailyNotification.scheduleDailyNotification({ await dailyNotification.scheduleDailyNotification({
url: 'https://api.example.com/updates', sound: true,
time: '09:00', priority: 'default',
title: 'Daily Update', timezone: 'UTC'
body: 'Your daily update is ready'
}); });
```
### Advanced Features // Get notification status
const status = await dailyNotification.getNotificationStatus();
#### Custom Priority // Update settings
await dailyNotification.updateSettings({
```typescript sound: false,
await DailyNotification.scheduleDailyNotification({
url: 'https://api.example.com/updates',
time: '09:00',
priority: 'high' 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 ### Android
await DailyNotification.scheduleDailyNotification({
url: 'https://api.example.com/updates', Add the following permissions to your `AndroidManifest.xml`:
time: '09:00',
timezone: 'America/New_York' ```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 ### Prerequisites
const status = await DailyNotification.getNotificationStatus();
console.log('Notification status:', status); - 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'
});
``` ```
daily-notification-plugin/
## API Documentation ├── android/ # Android implementation
│ ├── app/ # Main application module
### Methods │ └── build.gradle # Root build configuration
├── src/ # TypeScript source
#### scheduleDailyNotification(options: ScheduleOptions) ├── tests/ # Test files
Schedule a new daily notification. ├── package.json # Package configuration
└── README.md # This file
#### 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;
}
``` ```
## 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 ## 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 ## 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: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'jacoco'
android { android {
namespace "com.timesafari.dailynotification" namespace "com.timesafari.dailynotification"
compileSdkVersion 33 compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion "33.0.2"
defaultConfig { defaultConfig {
applicationId "com.timesafari.dailynotification" applicationId "com.timesafari.dailynotification"
minSdkVersion 22 minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion 33 targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -22,98 +19,27 @@ android {
buildTypes { buildTypes {
release { release {
minifyEnabled false minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
testOptions {
unitTests.all {
useJUnitPlatform()
} }
} }
} }
repositories { repositories {
google() flatDir{
mavenCentral() dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs'
maven {
url "${project.rootDir}/capacitor-cordova-android-plugins/src/main/libs"
}
maven {
url "${project.rootDir}/libs"
} }
} }
dependencies { dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs') 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') 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') 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' apply from: 'capacitor.build.gradle'
@@ -124,5 +50,5 @@ try {
apply plugin: 'com.google.gms.google-services' apply plugin: 'com.google.gms.google-services'
} }
} catch(Exception e) { } 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" apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
dependencies { 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