Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions packages/notification-services-controller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@
"default": "./dist/NotificationServicesPushController/index.cjs"
}
},
"./push-services/web": {
"import": {
"types": "./dist/NotificationServicesPushController/web/index.d.mts",
"default": "./dist/NotificationServicesPushController/web/index.mjs"
},
"require": {
"types": "./dist/NotificationServicesPushController/web/index.d.cts",
"default": "./dist/NotificationServicesPushController/web/index.cjs"
}
},
"./push-services/mocks": {
"import": {
"types": "./dist/NotificationServicesPushController/__fixtures__/index.d.mts",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"version": "1.0.0",
"private": true,
"description": "",
"license": "MIT",
"sideEffects": false,
"main": "../../dist/NotificationServicesPushController/web/index.cjs",
"types": "../../dist/NotificationServicesPushController/web/index.d.cts"
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,8 @@ import NotificationServicesController, {
import type {
AllowedActions,
AllowedEvents,
NotificationServicesPushControllerEnablePushNotifications,
NotificationServicesPushControllerDisablePushNotifications,
NotificationServicesPushControllerUpdateTriggerPushNotifications,
NotificationServicesControllerMessenger,
NotificationServicesControllerState,
NotificationServicesPushControllerSubscribeToNotifications,
} from './NotificationServicesController';
import { processFeatureAnnouncement } from './processors';
import { processNotification } from './processors/process-notifications';
Expand All @@ -50,6 +46,12 @@ import * as OnChainNotifications from './services/onchain-notifications';
import type { INotification } from './types';
import type { UserStorage } from './types/user-storage/user-storage';
import * as Utils from './utils/utils';
import type {
NotificationServicesPushControllerDisablePushNotificationsAction,
NotificationServicesPushControllerEnablePushNotificationsAction,
NotificationServicesPushControllerSubscribeToNotificationsAction,
NotificationServicesPushControllerUpdateTriggerPushNotificationsAction,
} from '../NotificationServicesPushController';

// Mock type used for testing purposes
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down Expand Up @@ -206,7 +208,7 @@ describe('metamask-notifications - constructor()', () => {
return mocks;
};

it('initializes push notifications', async () => {
it('initialises push notifications', async () => {
const { mockEnablePushNotifications } =
arrangeActInitialisePushNotifications();

Expand Down Expand Up @@ -471,7 +473,7 @@ describe('metamask-notifications - deleteOnChainTriggersByAccount', () => {
const {
messenger,
nockMockDeleteTriggersAPI,
mockDisablePushNotifications,
mockUpdateTriggerPushNotifications,
} = arrangeMocks();
const controller = new NotificationServicesController({
messenger,
Expand All @@ -482,7 +484,7 @@ describe('metamask-notifications - deleteOnChainTriggersByAccount', () => {
]);
expect(Utils.traverseUserStorageTriggers(result)).toHaveLength(0);
expect(nockMockDeleteTriggersAPI.isDone()).toBe(true);
expect(mockDisablePushNotifications).toHaveBeenCalled();
expect(mockUpdateTriggerPushNotifications).toHaveBeenCalled();
});

it('does nothing if account does not exist in storage', async () => {
Expand Down Expand Up @@ -1017,6 +1019,7 @@ describe('metamask-notifications - disableMetamaskNotifications()', () => {
// Act - final state
expect(controller.state.isUpdatingMetamaskNotifications).toBe(false);
expect(controller.state.isNotificationServicesEnabled).toBe(false);
expect(controller.state.isFeatureAnnouncementsEnabled).toBe(false);
expect(controller.state.metamaskNotificationsList).toStrictEqual([
createMockSnapNotification(),
]);
Expand Down Expand Up @@ -1065,6 +1068,73 @@ describe('metamask-notifications - updateMetamaskNotificationsList', () => {
});
});

describe('metamask-notifications - enablePushNotifications', () => {
const arrangeMocks = () => {
const messengerMocks = mockNotificationMessenger();
return messengerMocks;
};

it('calls push controller and enables notifications for accounts that have subscribed to notifications', async () => {
const { messenger, mockPerformGetStorage, mockEnablePushNotifications } =
arrangeMocks();
const controller = new NotificationServicesController({
messenger,
env: { featureAnnouncements: featureAnnouncementsEnv },
state: { isNotificationServicesEnabled: true },
});

// Act
await controller.enablePushNotifications();

// Assert
expect(mockPerformGetStorage).toHaveBeenCalled();
expect(mockEnablePushNotifications).toHaveBeenCalled();
});

it('throws error if fails to get notification triggers', async () => {
const { messenger, mockPerformGetStorage, mockEnablePushNotifications } =
arrangeMocks();

// Mock no storage
mockPerformGetStorage.mockResolvedValue(null);

const controller = new NotificationServicesController({
messenger,
env: { featureAnnouncements: featureAnnouncementsEnv },
state: { isNotificationServicesEnabled: true },
});

// Act
await expect(() => controller.enablePushNotifications()).rejects.toThrow(
expect.any(Error),
);

expect(mockEnablePushNotifications).not.toHaveBeenCalled();
});
});

describe('metamask-notifications - disablePushNotifications', () => {
const arrangeMocks = () => {
const messengerMocks = mockNotificationMessenger();
return messengerMocks;
};

it('calls push controller and enables notifications for accounts that have subscribed to notifications', async () => {
const { messenger, mockDisablePushNotifications } = arrangeMocks();
const controller = new NotificationServicesController({
messenger,
env: { featureAnnouncements: featureAnnouncementsEnv },
state: { isNotificationServicesEnabled: true },
});

// Act
await controller.disablePushNotifications();

// Assert
expect(mockDisablePushNotifications).toHaveBeenCalled();
});
});

// Type-Computation - we are extracting args and parameters from a generic type utility
// Thus this `AnyFunc` can be used to help constrain the generic parameters correctly
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down Expand Up @@ -1101,6 +1171,7 @@ function mockNotificationMessenger() {
'KeyringController:lock',
'KeyringController:unlock',
'NotificationServicesPushController:onNewNotifications',
'NotificationServicesPushController:stateChange',
],
});

Expand All @@ -1123,16 +1194,16 @@ function mockNotificationMessenger() {
);

const mockDisablePushNotifications =
typedMockAction<NotificationServicesPushControllerDisablePushNotifications>();
typedMockAction<NotificationServicesPushControllerDisablePushNotificationsAction>();

const mockEnablePushNotifications =
typedMockAction<NotificationServicesPushControllerEnablePushNotifications>();
typedMockAction<NotificationServicesPushControllerEnablePushNotificationsAction>();

const mockUpdateTriggerPushNotifications =
typedMockAction<NotificationServicesPushControllerUpdateTriggerPushNotifications>();
typedMockAction<NotificationServicesPushControllerUpdateTriggerPushNotificationsAction>();

const mockSubscribeToPushNotifications =
typedMockAction<NotificationServicesPushControllerSubscribeToNotifications>();
typedMockAction<NotificationServicesPushControllerSubscribeToNotificationsAction>();

const mockGetStorageKey =
typedMockAction<UserStorageController.UserStorageControllerGetStorageKey>().mockResolvedValue(
Expand Down Expand Up @@ -1184,7 +1255,7 @@ function mockNotificationMessenger() {
actionType ===
'NotificationServicesPushController:disablePushNotifications'
) {
return mockDisablePushNotifications(params[0]);
return mockDisablePushNotifications();
}

if (
Expand Down
Loading
Loading