- HERENCIA-SIMCO.md actualizado con directivas v3.7 y v3.8 - Actualizaciones de configuracion Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
565 lines
26 KiB
JavaScript
565 lines
26 KiB
JavaScript
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
}
|
|
Object.defineProperty(o, k2, desc);
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || (function () {
|
|
var ownKeys = function(o) {
|
|
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
var ar = [];
|
|
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
return ar;
|
|
};
|
|
return ownKeys(o);
|
|
};
|
|
return function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
})();
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const testing_1 = require("@nestjs/testing");
|
|
const typeorm_1 = require("@nestjs/typeorm");
|
|
const config_1 = require("@nestjs/config");
|
|
const push_notification_service_1 = require("../services/push-notification.service");
|
|
const entities_1 = require("../entities");
|
|
const webpush = __importStar(require("web-push"));
|
|
describe('PushNotificationService', () => {
|
|
let service;
|
|
let deviceRepository;
|
|
let logRepository;
|
|
let configService;
|
|
const mockDevice = {
|
|
id: 'device-1',
|
|
tenant_id: 'tenant-1',
|
|
user_id: 'user-1',
|
|
device_type: 'web',
|
|
device_token: JSON.stringify({
|
|
endpoint: 'https://fcm.googleapis.com/fcm/send/test',
|
|
keys: { p256dh: 'test-key', auth: 'test-auth' },
|
|
}),
|
|
device_name: 'Chrome on Windows',
|
|
browser: 'Chrome',
|
|
browser_version: '120',
|
|
os: 'Windows',
|
|
os_version: '11',
|
|
is_active: true,
|
|
last_used_at: new Date(),
|
|
created_at: new Date(),
|
|
};
|
|
const mockDeviceRepository = {
|
|
find: jest.fn(),
|
|
save: jest.fn(),
|
|
};
|
|
const mockLogRepository = {
|
|
save: jest.fn(),
|
|
};
|
|
const createMockConfigService = () => ({
|
|
get: jest.fn((key, defaultValue) => {
|
|
const config = {
|
|
VAPID_PUBLIC_KEY: 'BN4GvZtEZiZuqFJiLNpT1234567890',
|
|
VAPID_PRIVATE_KEY: 'aB3cDefGh4IjKlM5nOpQr6StUvWxYz',
|
|
VAPID_SUBJECT: 'mailto:admin@example.com',
|
|
};
|
|
return config[key] || defaultValue;
|
|
}),
|
|
});
|
|
let mockConfigService;
|
|
beforeEach(async () => {
|
|
jest.clearAllMocks();
|
|
mockConfigService = createMockConfigService();
|
|
const module = await testing_1.Test.createTestingModule({
|
|
providers: [
|
|
push_notification_service_1.PushNotificationService,
|
|
{
|
|
provide: (0, typeorm_1.getRepositoryToken)(entities_1.UserDevice),
|
|
useValue: mockDeviceRepository,
|
|
},
|
|
{
|
|
provide: (0, typeorm_1.getRepositoryToken)(entities_1.NotificationLog),
|
|
useValue: mockLogRepository,
|
|
},
|
|
{
|
|
provide: config_1.ConfigService,
|
|
useValue: mockConfigService,
|
|
},
|
|
],
|
|
}).compile();
|
|
service = module.get(push_notification_service_1.PushNotificationService);
|
|
deviceRepository = module.get((0, typeorm_1.getRepositoryToken)(entities_1.UserDevice));
|
|
logRepository = module.get((0, typeorm_1.getRepositoryToken)(entities_1.NotificationLog));
|
|
configService = module.get(config_1.ConfigService);
|
|
service.onModuleInit();
|
|
});
|
|
describe('onModuleInit', () => {
|
|
it('should configure VAPID if keys are provided', () => {
|
|
expect(webpush.setVapidDetails).toHaveBeenCalledWith('mailto:admin@example.com', 'BN4GvZtEZiZuqFJiLNpT1234567890', 'aB3cDefGh4IjKlM5nOpQr6StUvWxYz');
|
|
expect(service.isEnabled()).toBe(true);
|
|
});
|
|
it('should not configure if keys are missing', async () => {
|
|
jest.clearAllMocks();
|
|
mockConfigService.get.mockReturnValue(undefined);
|
|
const module = await testing_1.Test.createTestingModule({
|
|
providers: [
|
|
push_notification_service_1.PushNotificationService,
|
|
{
|
|
provide: (0, typeorm_1.getRepositoryToken)(entities_1.UserDevice),
|
|
useValue: mockDeviceRepository,
|
|
},
|
|
{
|
|
provide: (0, typeorm_1.getRepositoryToken)(entities_1.NotificationLog),
|
|
useValue: mockLogRepository,
|
|
},
|
|
{
|
|
provide: config_1.ConfigService,
|
|
useValue: { get: () => undefined },
|
|
},
|
|
],
|
|
}).compile();
|
|
const unconfiguredService = module.get(push_notification_service_1.PushNotificationService);
|
|
unconfiguredService.onModuleInit();
|
|
expect(unconfiguredService.isEnabled()).toBe(false);
|
|
});
|
|
});
|
|
describe('getVapidPublicKey', () => {
|
|
it('should return VAPID public key when configured', () => {
|
|
const key = service.getVapidPublicKey();
|
|
expect(key).toBe('BN4GvZtEZiZuqFJiLNpT1234567890');
|
|
});
|
|
});
|
|
describe('sendToUser', () => {
|
|
const payload = {
|
|
title: 'Test Notification',
|
|
body: 'This is a test',
|
|
url: '/test',
|
|
};
|
|
it('should send to all active devices', async () => {
|
|
mockDeviceRepository.find.mockResolvedValue([mockDevice]);
|
|
webpush.sendNotification.mockResolvedValue({});
|
|
mockDeviceRepository.save.mockResolvedValue(mockDevice);
|
|
const results = await service.sendToUser('user-1', 'tenant-1', payload);
|
|
expect(results).toHaveLength(1);
|
|
expect(results[0].success).toBe(true);
|
|
expect(webpush.sendNotification).toHaveBeenCalled();
|
|
});
|
|
it('should return empty array if no devices', async () => {
|
|
mockDeviceRepository.find.mockResolvedValue([]);
|
|
const results = await service.sendToUser('user-1', 'tenant-1', payload);
|
|
expect(results).toHaveLength(0);
|
|
});
|
|
it('should handle expired subscription (410)', async () => {
|
|
mockDeviceRepository.find.mockResolvedValue([mockDevice]);
|
|
webpush.sendNotification.mockRejectedValue({
|
|
statusCode: 410,
|
|
message: 'Subscription expired',
|
|
});
|
|
mockDeviceRepository.save.mockResolvedValue({
|
|
...mockDevice,
|
|
is_active: false,
|
|
});
|
|
const results = await service.sendToUser('user-1', 'tenant-1', payload);
|
|
expect(results).toHaveLength(1);
|
|
expect(results[0].success).toBe(false);
|
|
expect(results[0].statusCode).toBe(410);
|
|
expect(mockDeviceRepository.save).toHaveBeenCalledWith(expect.objectContaining({ is_active: false }));
|
|
});
|
|
it('should create log on success with notificationId', async () => {
|
|
mockDeviceRepository.find.mockResolvedValue([mockDevice]);
|
|
webpush.sendNotification.mockResolvedValue({});
|
|
mockDeviceRepository.save.mockResolvedValue(mockDevice);
|
|
mockLogRepository.save.mockResolvedValue({});
|
|
await service.sendToUser('user-1', 'tenant-1', payload, 'notification-1');
|
|
expect(mockLogRepository.save).toHaveBeenCalledWith(expect.objectContaining({
|
|
notification_id: 'notification-1',
|
|
channel: 'push',
|
|
status: 'sent',
|
|
provider: 'web-push',
|
|
}));
|
|
});
|
|
});
|
|
describe('validateSubscription', () => {
|
|
it('should return true for valid subscription', () => {
|
|
const validSubscription = JSON.stringify({
|
|
endpoint: 'https://fcm.googleapis.com/fcm/send/test',
|
|
keys: { p256dh: 'test-key', auth: 'test-auth' },
|
|
});
|
|
expect(service.validateSubscription(validSubscription)).toBe(true);
|
|
});
|
|
it('should return false for missing endpoint', () => {
|
|
const invalidSubscription = JSON.stringify({
|
|
keys: { p256dh: 'test-key', auth: 'test-auth' },
|
|
});
|
|
expect(service.validateSubscription(invalidSubscription)).toBe(false);
|
|
});
|
|
it('should return false for missing keys', () => {
|
|
const invalidSubscription = JSON.stringify({
|
|
endpoint: 'https://fcm.googleapis.com/fcm/send/test',
|
|
});
|
|
expect(service.validateSubscription(invalidSubscription)).toBe(false);
|
|
});
|
|
it('should return false for invalid JSON', () => {
|
|
expect(service.validateSubscription('invalid-json')).toBe(false);
|
|
});
|
|
});
|
|
describe('sendBroadcast', () => {
|
|
const payload = {
|
|
title: 'Broadcast Test',
|
|
body: 'This is a broadcast',
|
|
};
|
|
it('should send to all tenant devices', async () => {
|
|
mockDeviceRepository.find.mockResolvedValue([mockDevice, mockDevice]);
|
|
webpush.sendNotification.mockResolvedValue({});
|
|
mockDeviceRepository.save.mockResolvedValue(mockDevice);
|
|
const result = await service.sendBroadcast('tenant-1', payload);
|
|
expect(result.total).toBe(2);
|
|
expect(result.successful).toBe(2);
|
|
expect(result.failed).toBe(0);
|
|
});
|
|
it('should count failures correctly', async () => {
|
|
mockDeviceRepository.find.mockResolvedValue([mockDevice, mockDevice]);
|
|
webpush.sendNotification
|
|
.mockResolvedValueOnce({})
|
|
.mockRejectedValueOnce(new Error('Failed'));
|
|
mockDeviceRepository.save.mockResolvedValue(mockDevice);
|
|
const result = await service.sendBroadcast('tenant-1', payload);
|
|
expect(result.total).toBe(2);
|
|
expect(result.successful).toBe(1);
|
|
expect(result.failed).toBe(1);
|
|
});
|
|
it('should return zeros when not configured', async () => {
|
|
const module = await testing_1.Test.createTestingModule({
|
|
providers: [
|
|
push_notification_service_1.PushNotificationService,
|
|
{
|
|
provide: (0, typeorm_1.getRepositoryToken)(entities_1.UserDevice),
|
|
useValue: mockDeviceRepository,
|
|
},
|
|
{
|
|
provide: (0, typeorm_1.getRepositoryToken)(entities_1.NotificationLog),
|
|
useValue: mockLogRepository,
|
|
},
|
|
{
|
|
provide: config_1.ConfigService,
|
|
useValue: { get: () => undefined },
|
|
},
|
|
],
|
|
}).compile();
|
|
const unconfiguredService = module.get(push_notification_service_1.PushNotificationService);
|
|
unconfiguredService.onModuleInit();
|
|
const result = await unconfiguredService.sendBroadcast('tenant-1', payload);
|
|
expect(result).toEqual({ total: 0, successful: 0, failed: 0 });
|
|
expect(mockDeviceRepository.find).not.toHaveBeenCalled();
|
|
});
|
|
it('should return zeros when no devices in tenant', async () => {
|
|
mockDeviceRepository.find.mockResolvedValue([]);
|
|
const result = await service.sendBroadcast('tenant-1', payload);
|
|
expect(result.total).toBe(0);
|
|
expect(result.successful).toBe(0);
|
|
expect(result.failed).toBe(0);
|
|
});
|
|
});
|
|
describe('sendToDevice', () => {
|
|
const testPayload = JSON.stringify({
|
|
title: 'Direct Device Test',
|
|
body: 'Testing direct send',
|
|
});
|
|
it('should send push to valid device', async () => {
|
|
webpush.sendNotification.mockResolvedValue({});
|
|
mockDeviceRepository.save.mockResolvedValue(mockDevice);
|
|
const result = await service.sendToDevice(mockDevice, testPayload);
|
|
expect(result.success).toBe(true);
|
|
expect(result.deviceId).toBe('device-1');
|
|
expect(webpush.sendNotification).toHaveBeenCalledWith(JSON.parse(mockDevice.device_token), testPayload);
|
|
});
|
|
it('should update last_used_at on success', async () => {
|
|
webpush.sendNotification.mockResolvedValue({});
|
|
mockDeviceRepository.save.mockResolvedValue(mockDevice);
|
|
await service.sendToDevice(mockDevice, testPayload);
|
|
expect(mockDeviceRepository.save).toHaveBeenCalledWith(expect.objectContaining({
|
|
last_used_at: expect.any(Date),
|
|
}));
|
|
});
|
|
it('should create log on success with notificationId', async () => {
|
|
webpush.sendNotification.mockResolvedValue({});
|
|
mockDeviceRepository.save.mockResolvedValue(mockDevice);
|
|
mockLogRepository.save.mockResolvedValue({});
|
|
await service.sendToDevice(mockDevice, testPayload, 'notif-123');
|
|
expect(mockLogRepository.save).toHaveBeenCalledWith(expect.objectContaining({
|
|
notification_id: 'notif-123',
|
|
channel: 'push',
|
|
status: 'sent',
|
|
provider: 'web-push',
|
|
device_id: 'device-1',
|
|
delivered_at: expect.any(Date),
|
|
}));
|
|
});
|
|
it('should not create log when notificationId is not provided', async () => {
|
|
webpush.sendNotification.mockResolvedValue({});
|
|
mockDeviceRepository.save.mockResolvedValue(mockDevice);
|
|
await service.sendToDevice(mockDevice, testPayload);
|
|
expect(mockLogRepository.save).not.toHaveBeenCalled();
|
|
});
|
|
it('should handle invalid device (404)', async () => {
|
|
webpush.sendNotification.mockRejectedValue({
|
|
statusCode: 404,
|
|
message: 'Subscription not found',
|
|
});
|
|
mockDeviceRepository.save.mockResolvedValue({
|
|
...mockDevice,
|
|
is_active: false,
|
|
});
|
|
const result = await service.sendToDevice(mockDevice, testPayload);
|
|
expect(result.success).toBe(false);
|
|
expect(result.statusCode).toBe(404);
|
|
expect(mockDeviceRepository.save).toHaveBeenCalledWith(expect.objectContaining({ is_active: false }));
|
|
});
|
|
it('should handle generic send error', async () => {
|
|
webpush.sendNotification.mockRejectedValue({
|
|
statusCode: 500,
|
|
message: 'Internal server error',
|
|
});
|
|
const result = await service.sendToDevice(mockDevice, testPayload);
|
|
expect(result.success).toBe(false);
|
|
expect(result.statusCode).toBe(500);
|
|
expect(result.error).toBe('Internal server error');
|
|
});
|
|
it('should create failure log with notificationId', async () => {
|
|
webpush.sendNotification.mockRejectedValue({
|
|
statusCode: 500,
|
|
message: 'Server error',
|
|
});
|
|
mockLogRepository.save.mockResolvedValue({});
|
|
await service.sendToDevice(mockDevice, testPayload, 'notif-456');
|
|
expect(mockLogRepository.save).toHaveBeenCalledWith(expect.objectContaining({
|
|
notification_id: 'notif-456',
|
|
channel: 'push',
|
|
status: 'failed',
|
|
provider: 'web-push',
|
|
device_id: 'device-1',
|
|
error_code: '500',
|
|
error_message: 'Server error',
|
|
}));
|
|
});
|
|
it('should not create failure log without notificationId', async () => {
|
|
webpush.sendNotification.mockRejectedValue({
|
|
statusCode: 500,
|
|
message: 'Server error',
|
|
});
|
|
await service.sendToDevice(mockDevice, testPayload);
|
|
expect(mockLogRepository.save).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
describe('sendToUser - additional cases', () => {
|
|
const payload = {
|
|
title: 'Test Notification',
|
|
body: 'This is a test',
|
|
};
|
|
it('should return empty array when service not configured', async () => {
|
|
const module = await testing_1.Test.createTestingModule({
|
|
providers: [
|
|
push_notification_service_1.PushNotificationService,
|
|
{
|
|
provide: (0, typeorm_1.getRepositoryToken)(entities_1.UserDevice),
|
|
useValue: mockDeviceRepository,
|
|
},
|
|
{
|
|
provide: (0, typeorm_1.getRepositoryToken)(entities_1.NotificationLog),
|
|
useValue: mockLogRepository,
|
|
},
|
|
{
|
|
provide: config_1.ConfigService,
|
|
useValue: { get: () => undefined },
|
|
},
|
|
],
|
|
}).compile();
|
|
const unconfiguredService = module.get(push_notification_service_1.PushNotificationService);
|
|
unconfiguredService.onModuleInit();
|
|
const results = await unconfiguredService.sendToUser('user-1', 'tenant-1', payload);
|
|
expect(results).toHaveLength(0);
|
|
expect(mockDeviceRepository.find).not.toHaveBeenCalled();
|
|
});
|
|
it('should send to multiple devices and aggregate results', async () => {
|
|
const device2 = {
|
|
...mockDevice,
|
|
id: 'device-2',
|
|
device_name: 'Firefox on Linux',
|
|
};
|
|
mockDeviceRepository.find.mockResolvedValue([mockDevice, device2]);
|
|
webpush.sendNotification.mockResolvedValue({});
|
|
mockDeviceRepository.save.mockResolvedValue(mockDevice);
|
|
const results = await service.sendToUser('user-1', 'tenant-1', payload);
|
|
expect(results).toHaveLength(2);
|
|
expect(results.every((r) => r.success)).toBe(true);
|
|
expect(webpush.sendNotification).toHaveBeenCalledTimes(2);
|
|
});
|
|
it('should continue sending to other devices after one fails', async () => {
|
|
const device2 = {
|
|
...mockDevice,
|
|
id: 'device-2',
|
|
};
|
|
mockDeviceRepository.find.mockResolvedValue([mockDevice, device2]);
|
|
webpush.sendNotification
|
|
.mockRejectedValueOnce({ statusCode: 500, message: 'Error' })
|
|
.mockResolvedValueOnce({});
|
|
mockDeviceRepository.save.mockResolvedValue(mockDevice);
|
|
const results = await service.sendToUser('user-1', 'tenant-1', payload);
|
|
expect(results).toHaveLength(2);
|
|
expect(results[0].success).toBe(false);
|
|
expect(results[1].success).toBe(true);
|
|
});
|
|
it('should include custom payload data and actions', async () => {
|
|
const customPayload = {
|
|
title: 'Test',
|
|
body: 'Test body',
|
|
icon: '/custom-icon.png',
|
|
badge: '/custom-badge.png',
|
|
url: '/custom-url',
|
|
data: { orderId: '123' },
|
|
actions: [{ action: 'open', title: 'Open' }],
|
|
};
|
|
mockDeviceRepository.find.mockResolvedValue([mockDevice]);
|
|
webpush.sendNotification.mockResolvedValue({});
|
|
mockDeviceRepository.save.mockResolvedValue(mockDevice);
|
|
await service.sendToUser('user-1', 'tenant-1', customPayload);
|
|
const sentPayload = JSON.parse(webpush.sendNotification.mock.calls[0][1]);
|
|
expect(sentPayload.icon).toBe('/custom-icon.png');
|
|
expect(sentPayload.badge).toBe('/custom-badge.png');
|
|
expect(sentPayload.url).toBe('/custom-url');
|
|
expect(sentPayload.data).toEqual({ orderId: '123' });
|
|
expect(sentPayload.actions).toEqual([{ action: 'open', title: 'Open' }]);
|
|
});
|
|
});
|
|
describe('getVapidPublicKey - additional cases', () => {
|
|
it('should return null when not configured', async () => {
|
|
const module = await testing_1.Test.createTestingModule({
|
|
providers: [
|
|
push_notification_service_1.PushNotificationService,
|
|
{
|
|
provide: (0, typeorm_1.getRepositoryToken)(entities_1.UserDevice),
|
|
useValue: mockDeviceRepository,
|
|
},
|
|
{
|
|
provide: (0, typeorm_1.getRepositoryToken)(entities_1.NotificationLog),
|
|
useValue: mockLogRepository,
|
|
},
|
|
{
|
|
provide: config_1.ConfigService,
|
|
useValue: { get: () => undefined },
|
|
},
|
|
],
|
|
}).compile();
|
|
const unconfiguredService = module.get(push_notification_service_1.PushNotificationService);
|
|
unconfiguredService.onModuleInit();
|
|
expect(unconfiguredService.getVapidPublicKey()).toBeNull();
|
|
});
|
|
});
|
|
describe('validateSubscription - additional cases', () => {
|
|
it('should return false for missing p256dh key', () => {
|
|
const invalidSubscription = JSON.stringify({
|
|
endpoint: 'https://fcm.googleapis.com/fcm/send/test',
|
|
keys: { auth: 'test-auth' },
|
|
});
|
|
expect(service.validateSubscription(invalidSubscription)).toBe(false);
|
|
});
|
|
it('should return false for missing auth key', () => {
|
|
const invalidSubscription = JSON.stringify({
|
|
endpoint: 'https://fcm.googleapis.com/fcm/send/test',
|
|
keys: { p256dh: 'test-key' },
|
|
});
|
|
expect(service.validateSubscription(invalidSubscription)).toBe(false);
|
|
});
|
|
it('should return false for empty keys object', () => {
|
|
const invalidSubscription = JSON.stringify({
|
|
endpoint: 'https://fcm.googleapis.com/fcm/send/test',
|
|
keys: {},
|
|
});
|
|
expect(service.validateSubscription(invalidSubscription)).toBe(false);
|
|
});
|
|
it('should return false for null keys', () => {
|
|
const invalidSubscription = JSON.stringify({
|
|
endpoint: 'https://fcm.googleapis.com/fcm/send/test',
|
|
keys: null,
|
|
});
|
|
expect(service.validateSubscription(invalidSubscription)).toBe(false);
|
|
});
|
|
it('should return false for empty string', () => {
|
|
expect(service.validateSubscription('')).toBe(false);
|
|
});
|
|
});
|
|
describe('onModuleInit - additional cases', () => {
|
|
it('should handle setVapidDetails error gracefully', async () => {
|
|
jest.clearAllMocks();
|
|
webpush.setVapidDetails.mockImplementation(() => {
|
|
throw new Error('Invalid VAPID keys');
|
|
});
|
|
const module = await testing_1.Test.createTestingModule({
|
|
providers: [
|
|
push_notification_service_1.PushNotificationService,
|
|
{
|
|
provide: (0, typeorm_1.getRepositoryToken)(entities_1.UserDevice),
|
|
useValue: mockDeviceRepository,
|
|
},
|
|
{
|
|
provide: (0, typeorm_1.getRepositoryToken)(entities_1.NotificationLog),
|
|
useValue: mockLogRepository,
|
|
},
|
|
{
|
|
provide: config_1.ConfigService,
|
|
useValue: mockConfigService,
|
|
},
|
|
],
|
|
}).compile();
|
|
const errorService = module.get(push_notification_service_1.PushNotificationService);
|
|
expect(() => errorService.onModuleInit()).not.toThrow();
|
|
expect(errorService.isEnabled()).toBe(false);
|
|
});
|
|
it('should use default VAPID subject when not provided', async () => {
|
|
jest.clearAllMocks();
|
|
const configWithoutSubject = {
|
|
get: jest.fn((key, defaultValue) => {
|
|
const config = {
|
|
VAPID_PUBLIC_KEY: 'BN4GvZtEZiZuqFJiLNpT1234567890',
|
|
VAPID_PRIVATE_KEY: 'aB3cDefGh4IjKlM5nOpQr6StUvWxYz',
|
|
};
|
|
return config[key] || defaultValue;
|
|
}),
|
|
};
|
|
const module = await testing_1.Test.createTestingModule({
|
|
providers: [
|
|
push_notification_service_1.PushNotificationService,
|
|
{
|
|
provide: (0, typeorm_1.getRepositoryToken)(entities_1.UserDevice),
|
|
useValue: mockDeviceRepository,
|
|
},
|
|
{
|
|
provide: (0, typeorm_1.getRepositoryToken)(entities_1.NotificationLog),
|
|
useValue: mockLogRepository,
|
|
},
|
|
{
|
|
provide: config_1.ConfigService,
|
|
useValue: configWithoutSubject,
|
|
},
|
|
],
|
|
}).compile();
|
|
const serviceWithDefault = module.get(push_notification_service_1.PushNotificationService);
|
|
serviceWithDefault.onModuleInit();
|
|
expect(webpush.setVapidDetails).toHaveBeenCalledWith('mailto:admin@example.com', 'BN4GvZtEZiZuqFJiLNpT1234567890', 'aB3cDefGh4IjKlM5nOpQr6StUvWxYz');
|
|
});
|
|
});
|
|
});
|
|
//# sourceMappingURL=push-notification.service.spec.js.map
|