Skip to content

checksum test #14827

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

Draft
wants to merge 6 commits into
base: refactor/mock-server
Choose a base branch
from
Draft
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
4 changes: 2 additions & 2 deletions e2e/api-mocking/mock-config/mock-events.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ export const mockEvents = {
origin: 'metamask',
params: [
{
from: '0x76cf1cdd1fcc252442b50d6e97207228aa4aefc3',
to: '0x50587e46c5b96a3f6f9792922ec647f13e6efae4',
from: '0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3',
to: '0x50587E46C5B96a3F6f9792922EC647F13E6EFAE4',
value: '0x0',
},
],
Expand Down
158 changes: 118 additions & 40 deletions e2e/api-mocking/mock-server.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,38 @@
/* eslint-disable no-console */
import { getLocal } from 'mockttp';
import portfinder from 'portfinder';
import _ from 'lodash';

/**
* Utility function to handle direct fetch requests
* @param {string} url - The URL to fetch from
* @param {string} method - The HTTP method
* @param {Headers} headers - Request headers
* @param {Object} requestBody - The request body object
* @returns {Promise<{statusCode: number, body: string}>} Response object
*/
const handleDirectFetch = async (url, method, headers, requestBody) => {
try {
const response = await global.fetch(url, {
method,
headers,
body: ['POST', 'PUT', 'PATCH'].includes(method) ? requestBody : undefined,
});

const responseBody = await response.text();
return {
statusCode: response.status,
body: responseBody,
};
} catch (error) {
console.error('Error forwarding request:', url);
return {
statusCode: 500,
body: JSON.stringify({ error: 'Failed to forward request' }),
};
}
};

/**
* Starts the mock server and sets up mock events.
*
Expand All @@ -19,53 +51,99 @@ export const startMockServer = async (events, port) => {
.forGet('/health-check')
.thenReply(200, 'Mock server is running');

for (const method in events) {
const methodEvents = events[method];

console.log(`Setting up mock events for ${method} requests...`);

for (const {
urlEndpoint,
response,
requestBody,
responseCode,
} of methodEvents) {
console.log(`Mocking ${method} request to: ${urlEndpoint}`);
console.log(`Response status: ${responseCode}`);
console.log('Response:', response);
if (requestBody) {
console.log(`POST request body:`, requestBody);
}
// Handle all /proxy requests
await mockServer
.forAnyRequest()
.matching((request) => request.path.startsWith('/proxy'))
.thenCallback(async (request) => {
const urlEndpoint = new URL(request.url).searchParams.get('url');
const method = request.method;

if (method === 'GET') {
await mockServer
.forGet('/proxy')
.withQuery({ url: urlEndpoint })
.thenReply(responseCode, JSON.stringify(response));
}
// Find matching mock event
const methodEvents = events[method] || [];
const matchingEvent = methodEvents.find(
(event) => event.urlEndpoint === urlEndpoint,
);

if (matchingEvent) {
console.log(`Mocking ${method} request to: ${urlEndpoint}`);
console.log(`Response status: ${matchingEvent.responseCode}`);
console.log('Response:', matchingEvent.response);

// For POST requests, verify the request body if specified
if (method === 'POST' && matchingEvent.requestBody) {
const requestBodyJson = await request.body.getJson();

// Ensure both objects exist before comparison
if (!requestBodyJson || !matchingEvent.requestBody) {
console.log('Request body validation failed: Missing request body');
return {
statusCode: 400,
body: JSON.stringify({ error: 'Missing request body' }),
};
}

// We don't use _.isEqual because we want to ignore extra fields in the request body
const matches = _.isMatch(requestBodyJson, matchingEvent.requestBody);

if (method === 'POST') {
await mockServer
.forPost('/proxy')
.withQuery({ url: urlEndpoint })
.withJsonBodyIncluding(requestBody || {})
.thenReply(responseCode, JSON.stringify(response));
if (!matches) {
console.log('Request body validation failed:');
console.log(
'Expected:',
JSON.stringify(matchingEvent.requestBody, null, 2),
);
console.log('Received:', JSON.stringify(requestBodyJson, null, 2));
console.log(
'Differences:',
JSON.stringify(
_.differenceWith(
[requestBodyJson],
[matchingEvent.requestBody],
_.isEqual,
),
null,
2,
),
);

return {
statusCode: 404,
body: JSON.stringify({
error: 'Request body validation failed',
expected: matchingEvent.requestBody,
received: requestBodyJson,
}),
};
}
}

return {
statusCode: matchingEvent.responseCode,
body: JSON.stringify(matchingEvent.response),
};
}
}
}

await mockServer.forUnmatchedRequest().thenPassThrough({
beforeRequest: async ({ url, method }) => {
const returnUrl = new URL(url).searchParams.get('url') || url;
// If no matching mock found, pass through to actual endpoint
const updatedUrl =
device.getPlatform() === 'android'
? returnUrl.replace('localhost', '127.0.0.1')
: returnUrl;
console.log(`Mock proxy forwarding request to: ${updatedUrl}`);
return { url: updatedUrl };
},
});
? urlEndpoint.replace('localhost', '127.0.0.1')
: urlEndpoint;

return handleDirectFetch(
updatedUrl,
method,
request.headers,
method === 'POST' ? await request.body.getText() : undefined
);
});

// In case any other requests are made, pass them through to the actual endpoint
await mockServer.forUnmatchedRequest().thenCallback(async (request) => handleDirectFetch(
request.url,
request.method,
request.headers,
await request.body.getText()
));

return mockServer;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const typedSignRequestBody = {
{ type: 'string', name: 'Message', value: 'Hi, Alice!' },
{ type: 'uint32', name: 'A number', value: '1337' },
],
'0x76cf1cdd1fcc252442b50d6e97207228aa4aefc3',
'0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3',
],
origin: 'localhost',
};
Expand Down Expand Up @@ -80,7 +80,7 @@ describe(SmokeConfirmationsRedesigned('Alert System - Signature'), () => {
});
});

it.skip('should show security alert for malicious request, acknowledge and confirm the signature', async () => {
it('should show security alert for malicious request, acknowledge and confirm the signature', async () => {
const testSpecificMock = {
POST: [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ describe(SmokeConfirmations('Security Alert API - Signature'), () => {
{ type: 'string', name: 'Message', value: 'Hi, Alice!' },
{ type: 'uint32', name: 'A number', value: '1337' },
],
'0x76cf1cdd1fcc252442b50d6e97207228aa4aefc3',
'0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3',
],
origin: 'localhost',
};
Expand Down
Loading