1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00
metamask-extension/app/scripts/controllers/app-state.test.js

350 lines
11 KiB
JavaScript
Raw Normal View History

import { ObservableStore } from '@metamask/obs-store';
import log from 'loglevel';
import { ORIGIN_METAMASK } from '../../../shared/constants/app';
import AppStateController from './app-state';
jest.mock('loglevel');
let appStateController, mockStore;
describe('AppStateController', () => {
mockStore = new ObservableStore();
const createAppStateController = (initState = {}) => {
return new AppStateController({
addUnlockListener: jest.fn(),
isUnlocked: jest.fn(() => true),
initState,
onInactiveTimeout: jest.fn(),
showUnlockRequest: jest.fn(),
preferencesStore: {
subscribe: jest.fn(),
getState: jest.fn(() => ({
preferences: {
autoLockTimeLimit: 0,
},
})),
},
qrHardwareStore: {
subscribe: jest.fn(),
},
messenger: {
call: jest.fn(() => ({
catch: jest.fn(),
})),
},
});
};
beforeEach(() => {
appStateController = createAppStateController({ store: mockStore });
});
describe('setOutdatedBrowserWarningLastShown', () => {
it('sets the last shown time', () => {
appStateController = createAppStateController();
const date = new Date();
appStateController.setOutdatedBrowserWarningLastShown(date);
expect(
appStateController.store.getState().outdatedBrowserWarningLastShown,
).toStrictEqual(date);
});
it('sets outdated browser warning last shown timestamp', () => {
const lastShownTimestamp = Date.now();
appStateController = createAppStateController();
const updateStateSpy = jest.spyOn(
appStateController.store,
'updateState',
);
appStateController.setOutdatedBrowserWarningLastShown(lastShownTimestamp);
expect(updateStateSpy).toHaveBeenCalledTimes(1);
expect(updateStateSpy).toHaveBeenCalledWith({
outdatedBrowserWarningLastShown: lastShownTimestamp,
});
updateStateSpy.mockRestore();
});
});
describe('getUnlockPromise', () => {
it('waits for unlock if the extension is locked', async () => {
appStateController = createAppStateController();
const isUnlockedMock = jest
.spyOn(appStateController, 'isUnlocked')
.mockReturnValue(false);
const waitForUnlockSpy = jest.spyOn(appStateController, 'waitForUnlock');
appStateController.getUnlockPromise(true);
expect(isUnlockedMock).toHaveBeenCalled();
expect(waitForUnlockSpy).toHaveBeenCalledWith(expect.any(Function), true);
});
it('resolves immediately if the extension is already unlocked', async () => {
appStateController = createAppStateController();
const isUnlockedMock = jest
.spyOn(appStateController, 'isUnlocked')
.mockReturnValue(true);
await expect(
appStateController.getUnlockPromise(false),
).resolves.toBeUndefined();
expect(isUnlockedMock).toHaveBeenCalled();
});
});
describe('waitForUnlock', () => {
it('resolves immediately if already unlocked', async () => {
const emitSpy = jest.spyOn(appStateController, 'emit');
const resolveFn = jest.fn();
appStateController.waitForUnlock(resolveFn, false);
expect(emitSpy).toHaveBeenCalledWith('updateBadge');
expect(appStateController.messagingSystem.call).toHaveBeenCalledTimes(0);
});
it('creates approval request when waitForUnlock is called with shouldShowUnlockRequest as true', async () => {
jest.spyOn(appStateController, 'isUnlocked').mockReturnValue(false);
const resolveFn = jest.fn();
appStateController.waitForUnlock(resolveFn, true);
expect(appStateController.messagingSystem.call).toHaveBeenCalledTimes(1);
expect(appStateController.messagingSystem.call).toHaveBeenCalledWith(
'ApprovalController:addRequest',
expect.objectContaining({
id: expect.any(String),
origin: ORIGIN_METAMASK,
type: 'unlock',
}),
true,
);
});
});
describe('handleUnlock', () => {
beforeEach(() => {
jest.spyOn(appStateController, 'isUnlocked').mockReturnValue(false);
});
afterEach(() => {
jest.clearAllMocks();
});
it('accepts approval request revolving all the related promises', async () => {
const emitSpy = jest.spyOn(appStateController, 'emit');
const resolveFn = jest.fn();
appStateController.waitForUnlock(resolveFn, true);
appStateController.handleUnlock();
expect(emitSpy).toHaveBeenCalled();
expect(emitSpy).toHaveBeenCalledWith('updateBadge');
expect(appStateController.messagingSystem.call).toHaveBeenCalled();
expect(appStateController.messagingSystem.call).toHaveBeenCalledWith(
'ApprovalController:acceptRequest',
expect.any(String),
);
});
it('logs if rejecting approval request throws', async () => {
appStateController._approvalRequestId = 'mock-approval-request-id';
appStateController = new AppStateController({
addUnlockListener: jest.fn(),
isUnlocked: jest.fn(() => true),
onInactiveTimeout: jest.fn(),
showUnlockRequest: jest.fn(),
preferencesStore: {
subscribe: jest.fn(),
getState: jest.fn(() => ({
preferences: {
autoLockTimeLimit: 0,
},
})),
},
qrHardwareStore: {
subscribe: jest.fn(),
},
messenger: {
call: jest.fn(() => {
throw new Error('mock error');
}),
},
});
appStateController.handleUnlock();
expect(log.error).toHaveBeenCalledTimes(1);
expect(log.error).toHaveBeenCalledWith(
'Attempted to accept missing unlock approval request',
);
});
it('returns without call messenger if no approval request in pending', async () => {
const emitSpy = jest.spyOn(appStateController, 'emit');
appStateController.handleUnlock();
expect(emitSpy).toHaveBeenCalledTimes(0);
expect(appStateController.messagingSystem.call).toHaveBeenCalledTimes(0);
expect(log.error).toHaveBeenCalledTimes(1);
expect(log.error).toHaveBeenCalledWith(
'Attempted to accept missing unlock approval request',
);
});
});
describe('setDefaultHomeActiveTabName', () => {
it('sets the default home tab name', () => {
appStateController.setDefaultHomeActiveTabName('testTabName');
expect(appStateController.store.getState().defaultHomeActiveTabName).toBe(
'testTabName',
);
});
});
describe('setConnectedStatusPopoverHasBeenShown', () => {
it('sets connected status popover as shown', () => {
appStateController.setConnectedStatusPopoverHasBeenShown();
expect(
appStateController.store.getState().connectedStatusPopoverHasBeenShown,
).toBe(true);
});
});
describe('setRecoveryPhraseReminderHasBeenShown', () => {
it('sets recovery phrase reminder as shown', () => {
appStateController.setRecoveryPhraseReminderHasBeenShown();
expect(
appStateController.store.getState().recoveryPhraseReminderHasBeenShown,
).toBe(true);
});
});
describe('setRecoveryPhraseReminderLastShown', () => {
it('sets the last shown time of recovery phrase reminder', () => {
const timestamp = Date.now();
appStateController.setRecoveryPhraseReminderLastShown(timestamp);
expect(
appStateController.store.getState().recoveryPhraseReminderLastShown,
).toBe(timestamp);
});
});
describe('setLastActiveTime', () => {
it('sets the last active time to the current time', () => {
const spy = jest.spyOn(appStateController, '_resetTimer');
appStateController.setLastActiveTime();
expect(spy).toHaveBeenCalled();
});
});
describe('setBrowserEnvironment', () => {
it('sets the current browser and OS environment', () => {
appStateController.setBrowserEnvironment('Windows', 'Chrome');
expect(
appStateController.store.getState().browserEnvironment,
).toStrictEqual({
os: 'Windows',
browser: 'Chrome',
});
});
});
describe('addPollingToken', () => {
it('adds a pollingToken for a given environmentType', () => {
const pollingTokenType = 'popupGasPollTokens';
appStateController.addPollingToken('token1', pollingTokenType);
expect(appStateController.store.getState()[pollingTokenType]).toContain(
'token1',
);
});
});
describe('removePollingToken', () => {
it('removes a pollingToken for a given environmentType', () => {
const pollingTokenType = 'popupGasPollTokens';
appStateController.addPollingToken('token1', pollingTokenType);
appStateController.removePollingToken('token1', pollingTokenType);
expect(
appStateController.store.getState()[pollingTokenType],
).not.toContain('token1');
});
});
describe('clearPollingTokens', () => {
it('clears all pollingTokens', () => {
appStateController.addPollingToken('token1', 'popupGasPollTokens');
appStateController.addPollingToken('token2', 'notificationGasPollTokens');
appStateController.addPollingToken('token3', 'fullScreenGasPollTokens');
appStateController.clearPollingTokens();
expect(
appStateController.store.getState().popupGasPollTokens,
).toStrictEqual([]);
expect(
appStateController.store.getState().notificationGasPollTokens,
).toStrictEqual([]);
expect(
appStateController.store.getState().fullScreenGasPollTokens,
).toStrictEqual([]);
});
});
describe('setShowTestnetMessageInDropdown', () => {
it('sets whether the testnet dismissal link should be shown in the network dropdown', () => {
appStateController.setShowTestnetMessageInDropdown(true);
expect(
appStateController.store.getState().showTestnetMessageInDropdown,
).toBe(true);
appStateController.setShowTestnetMessageInDropdown(false);
expect(
appStateController.store.getState().showTestnetMessageInDropdown,
).toBe(false);
});
});
describe('setShowBetaHeader', () => {
it('sets whether the beta notification heading on the home page', () => {
appStateController.setShowBetaHeader(true);
expect(appStateController.store.getState().showBetaHeader).toBe(true);
appStateController.setShowBetaHeader(false);
expect(appStateController.store.getState().showBetaHeader).toBe(false);
});
});
describe('setCurrentPopupId', () => {
it('sets the currentPopupId in the appState', () => {
const popupId = 'popup1';
appStateController.setCurrentPopupId(popupId);
expect(appStateController.store.getState().currentPopupId).toBe(popupId);
});
});
describe('getCurrentPopupId', () => {
it('retrieves the currentPopupId saved in the appState', () => {
const popupId = 'popup1';
appStateController.setCurrentPopupId(popupId);
expect(appStateController.getCurrentPopupId()).toBe(popupId);
});
});
describe('setFirstTimeUsedNetwork', () => {
it('updates the array of the first time used networks', () => {
const chainId = '0x1';
appStateController.setFirstTimeUsedNetwork(chainId);
expect(appStateController.store.getState().usedNetworks[chainId]).toBe(
true,
);
});
});
});