Skip to content

Commit

Permalink
test(notifications): Add notification services e2e mocks (#25065)
Browse files Browse the repository at this point in the history
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

This adds mocks for the notification services when running e2e tests.

This also unblocks the notifications team from starting e2e tests for
our flows.

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/25065?quickstart=1)

## **Related issues**

Fixes:

## **Manual testing steps**

1. Go to this page...
2.
3.

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
  • Loading branch information
Prithpal-Sooriya authored Jun 6, 2024
1 parent b1eeaf7 commit 8a08568
Show file tree
Hide file tree
Showing 23 changed files with 546 additions and 227 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ import AuthenticationController, {
AuthenticationControllerState,
} from './authentication-controller';
import {
MOCK_ACCESS_TOKEN,
MOCK_LOGIN_RESPONSE,
mockEndpointAccessToken,
mockEndpointGetNonce,
mockEndpointLogin,
} from './mocks/mockServices';
import { MOCK_ACCESS_TOKEN, MOCK_LOGIN_RESPONSE } from './mocks/mockResponses';

const mockSignedInState = (): AuthenticationControllerState => ({
isSignedIn: true,
Expand Down
60 changes: 60 additions & 0 deletions app/scripts/controllers/authentication/mocks/mockResponses.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import {
AUTH_LOGIN_ENDPOINT,
AUTH_NONCE_ENDPOINT,
LoginResponse,
NonceResponse,
OAuthTokenResponse,
OIDC_TOKENS_ENDPOINT,
} from '../services';

type MockResponse = {
url: string;
requestMethod: 'GET' | 'POST' | 'PUT';
response: unknown;
};

export const MOCK_NONCE = '4cbfqzoQpcNxVImGv';
export const MOCK_NONCE_RESPONSE: NonceResponse = {
nonce: MOCK_NONCE,
};

export function getMockAuthNonceResponse() {
return {
url: AUTH_NONCE_ENDPOINT,
requestMethod: 'GET',
response: MOCK_NONCE_RESPONSE,
} satisfies MockResponse;
}

export const MOCK_JWT =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
export const MOCK_LOGIN_RESPONSE: LoginResponse = {
token: MOCK_JWT,
expires_in: new Date().toString(),
profile: {
identifier_id: 'MOCK_IDENTIFIER',
profile_id: 'MOCK_PROFILE_ID',
},
};

export function getMockAuthLoginResponse() {
return {
url: AUTH_LOGIN_ENDPOINT,
requestMethod: 'POST',
response: MOCK_LOGIN_RESPONSE,
} satisfies MockResponse;
}

export const MOCK_ACCESS_TOKEN = `MOCK_ACCESS_TOKEN-${MOCK_JWT}`;
export const MOCK_OATH_TOKEN_RESPONSE: OAuthTokenResponse = {
access_token: MOCK_ACCESS_TOKEN,
expires_in: new Date().getTime(),
};

export function getMockAuthAccessTokenResponse() {
return {
url: OIDC_TOKENS_ENDPOINT,
requestMethod: 'POST',
response: MOCK_OATH_TOKEN_RESPONSE,
} satisfies MockResponse;
}
45 changes: 13 additions & 32 deletions app/scripts/controllers/authentication/mocks/mockServices.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,40 @@
import nock from 'nock';
import {
AUTH_LOGIN_ENDPOINT,
AUTH_NONCE_ENDPOINT,
LoginResponse,
NonceResponse,
OAuthTokenResponse,
OIDC_TOKENS_ENDPOINT,
} from '../services';
getMockAuthAccessTokenResponse,
getMockAuthLoginResponse,
getMockAuthNonceResponse,
} from './mockResponses';

type MockReply = {
status: nock.StatusCode;
body?: nock.Body;
};

export const MOCK_NONCE = '4cbfqzoQpcNxVImGv';
const MOCK_NONCE_RESPONSE: NonceResponse = {
nonce: MOCK_NONCE,
};
export function mockEndpointGetNonce(mockReply?: MockReply) {
const reply = mockReply ?? { status: 200, body: MOCK_NONCE_RESPONSE };
const mockNonceEndpoint = nock(AUTH_NONCE_ENDPOINT)
const mockResponse = getMockAuthNonceResponse();
const reply = mockReply ?? { status: 200, body: mockResponse.response };
const mockNonceEndpoint = nock(mockResponse.url)
.get('')
.query(true)
.reply(reply.status, reply.body);

return mockNonceEndpoint;
}

export const MOCK_JWT =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
export const MOCK_LOGIN_RESPONSE: LoginResponse = {
token: MOCK_JWT,
expires_in: new Date().toString(),
profile: {
identifier_id: 'MOCK_IDENTIFIER',
profile_id: 'MOCK_PROFILE_ID',
},
};
export function mockEndpointLogin(mockReply?: MockReply) {
const reply = mockReply ?? { status: 200, body: MOCK_LOGIN_RESPONSE };
const mockLoginEndpoint = nock(AUTH_LOGIN_ENDPOINT)
const mockResponse = getMockAuthLoginResponse();
const reply = mockReply ?? { status: 200, body: mockResponse.response };
const mockLoginEndpoint = nock(mockResponse.url)
.post('')
.reply(reply.status, reply.body);

return mockLoginEndpoint;
}

export const MOCK_ACCESS_TOKEN = `MOCK_ACCESS_TOKEN-${MOCK_JWT}`;
const MOCK_OATH_TOKEN_RESPONSE: OAuthTokenResponse = {
access_token: MOCK_ACCESS_TOKEN,
expires_in: new Date().getTime(),
};
export function mockEndpointAccessToken(mockReply?: MockReply) {
const reply = mockReply ?? { status: 200, body: MOCK_OATH_TOKEN_RESPONSE };
const mockOidcTokensEndpoint = nock(OIDC_TOKENS_ENDPOINT)
const mockResponse = getMockAuthAccessTokenResponse();
const reply = mockReply ?? { status: 200, body: mockResponse.response };
const mockOidcTokensEndpoint = nock(mockResponse.url)
.post('')
.reply(reply.status, reply.body);

Expand Down
4 changes: 1 addition & 3 deletions app/scripts/controllers/authentication/services.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { MOCK_ACCESS_TOKEN, MOCK_JWT, MOCK_NONCE } from './mocks/mockResponses';
import {
MOCK_ACCESS_TOKEN,
MOCK_JWT,
MOCK_NONCE,
mockEndpointAccessToken,
mockEndpointGetNonce,
mockEndpointLogin,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
AuthenticationControllerGetBearerToken,
AuthenticationControllerIsSignedIn,
} from '../authentication/authentication-controller';
import { MOCK_ACCESS_TOKEN } from '../authentication/mocks/mockServices';
import { MOCK_ACCESS_TOKEN } from '../authentication/mocks/mockResponses';
import {
UserStorageControllerGetStorageKey,
UserStorageControllerPerformGetStorage,
Expand All @@ -31,19 +31,19 @@ import {
import {
createMockFeatureAnnouncementAPIResult,
createMockFeatureAnnouncementRaw,
mockFetchFeatureAnnouncementNotifications,
} from './mocks/mock-feature-announcements';
import {
MOCK_USER_STORAGE_ACCOUNT,
createMockFullUserStorage,
createMockUserStorageWithTriggers,
} from './mocks/mock-notification-user-storage';
import {
mockFetchFeatureAnnouncementNotifications,
mockBatchCreateTriggers,
mockBatchDeleteTriggers,
mockListNotifications,
mockMarkNotificationsAsRead,
} from './mocks/mock-onchain-notifications';
} from './mocks/mockServices';
import { createMockNotificationEthSent } from './mocks/mock-raw-notifications';
import { processNotification } from './processors/process-notifications';
import * as OnChainNotifications from './services/onchain-notifications';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,7 @@
import nock from 'nock';
import {
ContentfulResult,
FEATURE_ANNOUNCEMENT_URL,
} from '../services/feature-announcements';
import { ContentfulResult } from '../services/feature-announcements';
import { FeatureAnnouncementRawNotification } from '../types/feature-announcement/feature-announcement';
import { TRIGGER_TYPES } from '../constants/notification-schema';

type MockReply = {
status: nock.StatusCode;
body?: nock.Body;
};

export function mockFetchFeatureAnnouncementNotifications(
mockReply?: MockReply,
) {
const reply = mockReply ?? { status: 200, body: { items: [] } };
const mockEndpoint = nock(FEATURE_ANNOUNCEMENT_URL)
.get('')
.query(true)
.reply(reply.status, reply.body);

return mockEndpoint;
}

export function createMockFeatureAnnouncementAPIResult(): ContentfulResult {
return {
sys: {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ export function createMockNotificationERC721Sent() {
data: {
to: '0xf47f628fe3bd2595e9ab384bfffc3859b448e451',
nft: {
// This is not a hex color
// eslint-disable-next-line @metamask/design-tokens/color-no-hex
name: 'Captainz #8680',
image:
'https://i.seadn.io/s/raw/files/ae0fc06714ff7fb40217340d8a242c0e.gif?w=500&auto=format',
Expand Down Expand Up @@ -184,6 +186,8 @@ export function createMockNotificationERC721Received() {
data: {
to: '0xba7f3daa8adfdad686574406ab9bd5d2f0a49d2e',
nft: {
// This is not a hex color
// eslint-disable-next-line @metamask/design-tokens/color-no-hex
name: 'The Plague #2722',
image:
'https://i.seadn.io/s/raw/files/a96f90ec8ebf55a2300c66a0c46d6a16.png?w=500&auto=format',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { FEATURE_ANNOUNCEMENT_API } from '../services/feature-announcements';
import {
NOTIFICATION_API_LIST_ENDPOINT,
NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT,
TRIGGER_API_BATCH_ENDPOINT,
} from '../services/onchain-notifications';
import { createMockFeatureAnnouncementAPIResult } from './mock-feature-announcements';
import { createMockRawOnChainNotifications } from './mock-raw-notifications';

type MockResponse = {
url: string;
requestMethod: 'GET' | 'POST' | 'PUT' | 'DELETE';
response: unknown;
};

export const CONTENTFUL_RESPONSE = createMockFeatureAnnouncementAPIResult();

export function getMockFeatureAnnouncementResponse() {
return {
url: FEATURE_ANNOUNCEMENT_API,
requestMethod: 'GET',
response: CONTENTFUL_RESPONSE,
} satisfies MockResponse;
}

export function getMockBatchCreateTriggersResponse() {
return {
url: TRIGGER_API_BATCH_ENDPOINT,
requestMethod: 'POST',
response: null,
} satisfies MockResponse;
}

export function getMockBatchDeleteTriggersResponse() {
return {
url: TRIGGER_API_BATCH_ENDPOINT,
requestMethod: 'DELETE',
response: null,
} satisfies MockResponse;
}

export const MOCK_RAW_ON_CHAIN_NOTIFICATIONS =
createMockRawOnChainNotifications();

export function getMockListNotificationsResponse() {
return {
url: NOTIFICATION_API_LIST_ENDPOINT,
requestMethod: 'POST',
response: MOCK_RAW_ON_CHAIN_NOTIFICATIONS,
} satisfies MockResponse;
}

export function getMockMarkNotificationsAsReadResponse() {
return {
url: NOTIFICATION_API_MARK_ALL_AS_READ_ENDPOINT,
requestMethod: 'POST',
response: null,
} satisfies MockResponse;
}
Loading

0 comments on commit 8a08568

Please sign in to comment.