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.
253 lines
7.5 KiB
253 lines
7.5 KiB
/**
|
|
* Tests for the Daily Notification plugin
|
|
*
|
|
* @author Matthew Raymer
|
|
*/
|
|
|
|
import { DailyNotification } from '../src/daily-notification';
|
|
import { DailyNotificationPlugin, NotificationOptions, NotificationStatus, NotificationResponse, NotificationSettings } from '../src/definitions';
|
|
import { describe, it, expect, beforeEach, jest } from '@jest/globals';
|
|
|
|
describe('DailyNotification Plugin', () => {
|
|
let plugin: DailyNotification;
|
|
let mockPlugin: jest.Mocked<DailyNotificationPlugin>;
|
|
|
|
const mockOptions: NotificationOptions = {
|
|
url: 'https://api.example.com/daily-content',
|
|
time: '08:00',
|
|
title: 'Test Notification',
|
|
body: 'This is a test notification'
|
|
};
|
|
|
|
beforeEach(() => {
|
|
// Create mock plugin with all required methods
|
|
mockPlugin = {
|
|
scheduleDailyNotification: jest.fn(),
|
|
getLastNotification: jest.fn(),
|
|
cancelAllNotifications: jest.fn(),
|
|
getNotificationStatus: jest.fn(),
|
|
updateSettings: jest.fn(),
|
|
getBatteryStatus: jest.fn(),
|
|
requestBatteryOptimizationExemption: jest.fn(),
|
|
setAdaptiveScheduling: jest.fn(),
|
|
getPowerState: jest.fn(),
|
|
checkPermissions: jest.fn(),
|
|
requestPermissions: jest.fn(),
|
|
};
|
|
|
|
// Create plugin instance with mock
|
|
plugin = new DailyNotification(mockPlugin);
|
|
|
|
// Reset mocks before each test
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
describe('scheduleDailyNotification', () => {
|
|
it('should schedule a basic notification', async () => {
|
|
await plugin.scheduleDailyNotification(mockOptions);
|
|
// Verify the mock was called with correct parameters
|
|
expect(mockPlugin.scheduleDailyNotification).toHaveBeenCalledWith(mockOptions);
|
|
});
|
|
|
|
it('should handle network errors gracefully', async () => {
|
|
mockPlugin.scheduleDailyNotification.mockRejectedValueOnce(
|
|
new Error('Network error')
|
|
);
|
|
|
|
const errorOptions: NotificationOptions = {
|
|
...mockOptions,
|
|
url: 'https://invalid-url.com'
|
|
};
|
|
|
|
await expect(plugin.scheduleDailyNotification(errorOptions))
|
|
.rejects
|
|
.toThrow('Network error');
|
|
});
|
|
|
|
it('should validate required parameters', async () => {
|
|
const invalidOptions = {
|
|
time: '08:00'
|
|
} as NotificationOptions;
|
|
|
|
await expect(plugin.scheduleDailyNotification(invalidOptions))
|
|
.rejects
|
|
.toThrow('URL is required');
|
|
});
|
|
});
|
|
|
|
describe('getLastNotification', () => {
|
|
it('should return the last notification', async () => {
|
|
const mockResponse: NotificationResponse = {
|
|
id: 'test-notification',
|
|
title: 'Last Notification',
|
|
body: 'This was the last notification',
|
|
timestamp: Date.now()
|
|
};
|
|
|
|
mockPlugin.getLastNotification.mockResolvedValueOnce(mockResponse);
|
|
|
|
const result = await plugin.getLastNotification();
|
|
expect(result).toEqual(mockResponse);
|
|
});
|
|
|
|
it('should return null when no notifications exist', async () => {
|
|
mockPlugin.getLastNotification.mockResolvedValueOnce(null);
|
|
|
|
const result = await plugin.getLastNotification();
|
|
expect(result).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('cancelAllNotifications', () => {
|
|
it('should cancel all scheduled notifications', async () => {
|
|
await plugin.cancelAllNotifications();
|
|
// Verify the mock was called
|
|
expect(mockPlugin.cancelAllNotifications).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('getNotificationStatus', () => {
|
|
it('should return current notification status', async () => {
|
|
const mockStatus: NotificationStatus = {
|
|
isScheduled: true,
|
|
nextNotificationTime: Date.now() + 86400000, // 24 hours from now
|
|
lastNotificationTime: Date.now(),
|
|
settings: {}
|
|
};
|
|
|
|
mockPlugin.getNotificationStatus.mockResolvedValueOnce(mockStatus);
|
|
|
|
const result = await plugin.getNotificationStatus();
|
|
expect(result).toEqual(mockStatus);
|
|
});
|
|
|
|
it('should handle error status', async () => {
|
|
const mockErrorStatus: NotificationStatus = {
|
|
isScheduled: false,
|
|
error: 'Failed to schedule notification',
|
|
lastNotificationTime: 0,
|
|
nextNotificationTime: 0,
|
|
settings: {}
|
|
};
|
|
|
|
mockPlugin.getNotificationStatus.mockResolvedValueOnce(mockErrorStatus);
|
|
|
|
const result = await plugin.getNotificationStatus();
|
|
expect(result).toEqual(mockErrorStatus);
|
|
});
|
|
});
|
|
|
|
describe('updateSettings', () => {
|
|
it('should update notification settings', async () => {
|
|
const settings: NotificationSettings = {
|
|
sound: false,
|
|
priority: 'high',
|
|
timezone: 'UTC'
|
|
};
|
|
|
|
await plugin.updateSettings(settings);
|
|
expect(mockPlugin.updateSettings).toHaveBeenCalledWith(settings);
|
|
});
|
|
});
|
|
|
|
describe('getBatteryStatus', () => {
|
|
it('should return battery status', async () => {
|
|
const mockBatteryStatus = {
|
|
level: 85,
|
|
isCharging: false,
|
|
powerState: 1,
|
|
isOptimizationExempt: false
|
|
};
|
|
|
|
mockPlugin.getBatteryStatus.mockResolvedValueOnce(mockBatteryStatus);
|
|
|
|
const result = await plugin.getBatteryStatus();
|
|
expect(result).toEqual(mockBatteryStatus);
|
|
});
|
|
});
|
|
|
|
describe('requestBatteryOptimizationExemption', () => {
|
|
it('should request battery optimization exemption', async () => {
|
|
await plugin.requestBatteryOptimizationExemption();
|
|
expect(mockPlugin.requestBatteryOptimizationExemption).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('setAdaptiveScheduling', () => {
|
|
it('should set adaptive scheduling', async () => {
|
|
await plugin.setAdaptiveScheduling({ enabled: true });
|
|
expect(mockPlugin.setAdaptiveScheduling).toHaveBeenCalledWith({ enabled: true });
|
|
});
|
|
});
|
|
|
|
describe('getPowerState', () => {
|
|
it('should return power state', async () => {
|
|
const mockPowerState = {
|
|
powerState: 1,
|
|
isOptimizationExempt: false
|
|
};
|
|
|
|
mockPlugin.getPowerState.mockResolvedValueOnce(mockPowerState);
|
|
|
|
const result = await plugin.getPowerState();
|
|
expect(result).toEqual(mockPowerState);
|
|
});
|
|
});
|
|
|
|
describe('validation', () => {
|
|
it('should validate URL format', async () => {
|
|
const invalidOptions = {
|
|
...mockOptions,
|
|
url: 'invalid-url'
|
|
};
|
|
|
|
await expect(plugin.scheduleDailyNotification(invalidOptions))
|
|
.rejects
|
|
.toThrow('Invalid URL format');
|
|
});
|
|
|
|
it('should validate time format', async () => {
|
|
const invalidOptions = {
|
|
...mockOptions,
|
|
time: '25:00'
|
|
};
|
|
|
|
await expect(plugin.scheduleDailyNotification(invalidOptions))
|
|
.rejects
|
|
.toThrow('Invalid time format');
|
|
});
|
|
|
|
it('should validate timezone format', async () => {
|
|
const invalidOptions = {
|
|
...mockOptions,
|
|
timezone: 'Invalid/Timezone'
|
|
};
|
|
|
|
await expect(plugin.scheduleDailyNotification(invalidOptions))
|
|
.rejects
|
|
.toThrow('Invalid timezone');
|
|
});
|
|
|
|
it('should validate retry count range', async () => {
|
|
const invalidOptions = {
|
|
...mockOptions,
|
|
retryCount: 15
|
|
};
|
|
|
|
await expect(plugin.scheduleDailyNotification(invalidOptions))
|
|
.rejects
|
|
.toThrow('Retry count must be between 0 and 10');
|
|
});
|
|
|
|
it('should validate retry interval range', async () => {
|
|
const invalidOptions = {
|
|
...mockOptions,
|
|
retryInterval: 50
|
|
};
|
|
|
|
await expect(plugin.scheduleDailyNotification(invalidOptions))
|
|
.rejects
|
|
.toThrow('Retry interval must be between 100ms and 60s');
|
|
});
|
|
});
|
|
});
|