Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Migrate AbstractMessageManager from BaseControllerV1 to BaseControllerV2 #5103

Merged
merged 15 commits into from
Jan 14, 2025
Merged
7 changes: 7 additions & 0 deletions packages/message-manager/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- **BREAKING:** Base class of `DecryptMessageManager` and `EncryptionPublicKeyManager`(`AbstractMessageManager`) now expects new options to initialise ([#5103](https://github.com/MetaMask/core/pull/5103))
- Bump `@metamask/base-controller` from `^7.0.0` to `^7.1.0` ([#5079](https://github.com/MetaMask/core/pull/5079))

### Removed

- **BREAKING:** Removed internal event emitter (`hub` property) from `AbstractMessageManager` ([#5103](https://github.com/MetaMask/core/pull/5103))
matthewwalsh0 marked this conversation as resolved.
Show resolved Hide resolved
- **BREAKING:** `unapprovedMessage` and `updateBadge` removed from internal events. These events are now emitted from messaging system ([#5103](https://github.com/MetaMask/core/pull/5103))
matthewwalsh0 marked this conversation as resolved.
Show resolved Hide resolved
- Controllers should now listen to `DerivedManagerName:X` event instead of using internal event emitter.

## [11.0.3]

### Changed
Expand Down
129 changes: 83 additions & 46 deletions packages/message-manager/src/AbstractMessageManager.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { RestrictedControllerMessenger } from '@metamask/base-controller';
import { ApprovalType } from '@metamask/controller-utils';

import type {
Expand All @@ -20,10 +21,15 @@ type ConcreteMessageParamsMetamask = ConcreteMessageParams & {
metamaskId?: string;
};

type ConcreteMessageManagerActions = never;
type ConcreteMessageManagerEvents = never;

class AbstractTestManager extends AbstractMessageManager<
ConcreteMessage,
ConcreteMessageParams,
ConcreteMessageParamsMetamask
ConcreteMessageParamsMetamask,
ConcreteMessageManagerActions,
ConcreteMessageManagerEvents
> {
addRequestToMessageParams<MessageParams extends AbstractMessageParams>(
messageParams: MessageParams,
Expand Down Expand Up @@ -56,6 +62,26 @@ class AbstractTestManager extends AbstractMessageManager<
}
}

const MOCK_MESSENGER = {
clearEventSubscriptions: jest.fn(),
publish: jest.fn(),
registerActionHandler: jest.fn(),
registerInitialEventPayload: jest.fn(),
} as unknown as RestrictedControllerMessenger<
'AbstractMessageManager',
never,
never,
string,
string
>;

const MOCK_INITIAL_OPTIONS = {
additionalFinishStatuses: undefined,
messenger: MOCK_MESSENGER,
name: 'AbstractMessageManager' as const,
securityProviderRequest: undefined,
};

const messageId = '1';
const messageId2 = '2';
const from = '0x0123';
Expand All @@ -78,20 +104,15 @@ const mockMessageParams = { from, test: testData };

describe('AbstractTestManager', () => {
it('should set default state', () => {
const controller = new AbstractTestManager();
const controller = new AbstractTestManager(MOCK_INITIAL_OPTIONS);
expect(controller.state).toStrictEqual({
unapprovedMessages: {},
unapprovedMessagesCount: 0,
});
});

it('should set default config', () => {
const controller = new AbstractTestManager();
expect(controller.config).toStrictEqual({});
});

it('should add a valid message', async () => {
const controller = new AbstractTestManager();
const controller = new AbstractTestManager(MOCK_INITIAL_OPTIONS);
await controller.addMessage({
id: messageId,
messageParams: {
Expand All @@ -115,7 +136,7 @@ describe('AbstractTestManager', () => {
});

it('should get all messages', async () => {
const controller = new AbstractTestManager();
const controller = new AbstractTestManager(MOCK_INITIAL_OPTIONS);
const message = {
id: messageId,
messageParams: {
Expand Down Expand Up @@ -148,11 +169,10 @@ describe('AbstractTestManager', () => {
const securityProviderRequestMock: SecurityProviderRequest = jest
.fn()
.mockResolvedValue(securityProviderResponseMock);
const controller = new AbstractTestManager(
undefined,
undefined,
securityProviderRequestMock,
);
const controller = new AbstractTestManager({
...MOCK_INITIAL_OPTIONS,
securityProviderRequest: securityProviderRequestMock,
});
await controller.addMessage({
id: messageId,
messageParams: {
Expand Down Expand Up @@ -180,7 +200,7 @@ describe('AbstractTestManager', () => {
});

it('should reject a message', async () => {
const controller = new AbstractTestManager();
const controller = new AbstractTestManager(MOCK_INITIAL_OPTIONS);
await controller.addMessage({
id: messageId,
messageParams: {
Expand All @@ -200,7 +220,7 @@ describe('AbstractTestManager', () => {
});

it('should sign a message', async () => {
const controller = new AbstractTestManager();
const controller = new AbstractTestManager(MOCK_INITIAL_OPTIONS);
await controller.addMessage({
id: messageId,
messageParams: {
Expand All @@ -221,12 +241,10 @@ describe('AbstractTestManager', () => {
});

it('sets message to one of the allowed statuses', async () => {
const controller = new AbstractTestManager(
undefined,
undefined,
undefined,
['test-status'],
);
const controller = new AbstractTestManager({
...MOCK_INITIAL_OPTIONS,
additionalFinishStatuses: ['test-status'],
});
await controller.addMessage({
id: messageId,
messageParams: {
Expand All @@ -246,12 +264,10 @@ describe('AbstractTestManager', () => {
});

it('should set a status to inProgress', async () => {
const controller = new AbstractTestManager(
undefined,
undefined,
undefined,
['test-status'],
);
const controller = new AbstractTestManager({
...MOCK_INITIAL_OPTIONS,
additionalFinishStatuses: ['test-status'],
});
await controller.addMessage({
id: messageId,
messageParams: {
Expand Down Expand Up @@ -285,7 +301,7 @@ describe('AbstractTestManager', () => {
time: 123,
type: 'eth_signTypedData',
};
const controller = new AbstractTestManager();
const controller = new AbstractTestManager(MOCK_INITIAL_OPTIONS);
await controller.addMessage(firstMessage);
await controller.addMessage(secondMessage);
expect(controller.getUnapprovedMessagesCount()).toBe(2);
Expand All @@ -296,7 +312,7 @@ describe('AbstractTestManager', () => {
});

it('should approve message', async () => {
const controller = new AbstractTestManager();
const controller = new AbstractTestManager(MOCK_INITIAL_OPTIONS);
const firstMessage = { from: '0xfoO', test: testData };
await controller.addMessage({
id: messageId,
Expand All @@ -319,7 +335,7 @@ describe('AbstractTestManager', () => {

describe('addRequestToMessageParams', () => {
it('adds original request id and origin to messageParams', () => {
const controller = new AbstractTestManager();
const controller = new AbstractTestManager(MOCK_INITIAL_OPTIONS);

const result = controller.addRequestToMessageParams(
mockMessageParams,
Expand All @@ -336,7 +352,7 @@ describe('AbstractTestManager', () => {

describe('createUnapprovedMessage', () => {
it('creates a Message object with an unapproved status', () => {
const controller = new AbstractTestManager();
const controller = new AbstractTestManager(MOCK_INITIAL_OPTIONS);

const result = controller.createUnapprovedMessage(
mockMessageParams,
Expand All @@ -361,7 +377,7 @@ describe('AbstractTestManager', () => {
emit: jest.fn(),
}));

const controller = new AbstractTestManager();
const controller = new AbstractTestManager(MOCK_INITIAL_OPTIONS);
await controller.addMessage({
id: messageId,
messageParams: { ...mockMessageParams },
Expand All @@ -379,7 +395,7 @@ describe('AbstractTestManager', () => {
});

it('throws an error if the message is not found', async () => {
const controller = new AbstractTestManager();
const controller = new AbstractTestManager(MOCK_INITIAL_OPTIONS);

expect(() => controller.setMessageStatus(messageId, 'newstatus')).toThrow(
'AbstractMessageManager: Message not found for id: 1.',
Expand All @@ -393,7 +409,7 @@ describe('AbstractTestManager', () => {
emit: jest.fn(),
}));

const controller = new AbstractTestManager();
const controller = new AbstractTestManager(MOCK_INITIAL_OPTIONS);
await controller.addMessage({
id: messageId,
messageParams: { ...mockMessageParams },
Expand All @@ -407,14 +423,13 @@ describe('AbstractTestManager', () => {
controller.setMessageStatusAndResult(messageId, 'newRawSig', 'newstatus');
const messageAfter = controller.getMessage(messageId);

// expect(controller.hub.emit).toHaveBeenNthCalledWith(1, 'updateBadge');
expect(messageAfter?.status).toBe('newstatus');
});
});

describe('setMetadata', () => {
it('should set the given message metadata', async () => {
const controller = new AbstractTestManager();
const controller = new AbstractTestManager(MOCK_INITIAL_OPTIONS);
await controller.addMessage({
id: messageId,
messageParams: { ...mockMessageParams },
Expand All @@ -432,7 +447,7 @@ describe('AbstractTestManager', () => {
});

it('should throw an error if message is not found', () => {
const controller = new AbstractTestManager();
const controller = new AbstractTestManager(MOCK_INITIAL_OPTIONS);

expect(() => controller.setMetadata(messageId, { foo: 'bar' })).toThrow(
'AbstractMessageManager: Message not found for id: 1.',
Expand All @@ -442,7 +457,7 @@ describe('AbstractTestManager', () => {

describe('waitForFinishStatus', () => {
it('signs the message when status is "signed"', async () => {
const controller = new AbstractTestManager();
const controller = new AbstractTestManager(MOCK_INITIAL_OPTIONS);
const promise = controller.waitForFinishStatus(
{
from: fromMock,
Expand All @@ -452,7 +467,7 @@ describe('AbstractTestManager', () => {
);

setTimeout(() => {
controller.hub.emit(`${messageIdMock}:finished`, {
controller.internalEvents.emit(`${messageIdMock}:finished`, {
status: 'signed',
rawSig: rawSigMock,
});
Expand All @@ -462,7 +477,7 @@ describe('AbstractTestManager', () => {
});

it('rejects with an error when status is "rejected"', async () => {
const controller = new AbstractTestManager();
const controller = new AbstractTestManager(MOCK_INITIAL_OPTIONS);
const promise = controller.waitForFinishStatus(
{
from: fromMock,
Expand All @@ -472,7 +487,7 @@ describe('AbstractTestManager', () => {
);

setTimeout(() => {
controller.hub.emit(`${messageIdMock}:finished`, {
controller.internalEvents.emit(`${messageIdMock}:finished`, {
status: 'rejected',
});
}, 100);
Expand All @@ -483,7 +498,7 @@ describe('AbstractTestManager', () => {
});

it('rejects with an error when finishes with unknown status', async () => {
const controller = new AbstractTestManager();
const controller = new AbstractTestManager(MOCK_INITIAL_OPTIONS);
const promise = controller.waitForFinishStatus(
{
from: fromMock,
Expand All @@ -493,7 +508,7 @@ describe('AbstractTestManager', () => {
);

setTimeout(() => {
controller.hub.emit(`${messageIdMock}:finished`, {
controller.internalEvents.emit(`${messageIdMock}:finished`, {
status: 'unknown',
});
}, 100);
Expand All @@ -508,7 +523,7 @@ describe('AbstractTestManager', () => {
});

it('rejects with an error when finishes with errored status', async () => {
const controller = new AbstractTestManager();
const controller = new AbstractTestManager(MOCK_INITIAL_OPTIONS);
const promise = controller.waitForFinishStatus(
{
from: fromMock,
Expand All @@ -518,7 +533,7 @@ describe('AbstractTestManager', () => {
);

setTimeout(() => {
controller.hub.emit(`${messageIdMock}:finished`, {
controller.internalEvents.emit(`${messageIdMock}:finished`, {
status: 'errored',
error: 'error message',
});
Expand All @@ -529,4 +544,26 @@ describe('AbstractTestManager', () => {
);
});
});

describe('clearUnapprovedMessages', () => {
it('clears the unapproved messages', () => {
const controller = new AbstractTestManager({
...MOCK_INITIAL_OPTIONS,
state: {
unapprovedMessages: {
'1': {
id: '1',
messageParams: { from: '0x1', test: 1 },
status: 'unapproved',
time: 10,
type: 'type',
},
},
unapprovedMessagesCount: 1,
},
});
controller.clearUnapprovedMessages();
expect(controller.getUnapprovedMessagesCount()).toBe(0);
OGPoyraz marked this conversation as resolved.
Show resolved Hide resolved
});
});
});
Loading
Loading