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

Multichain API E2E Test: wallet_revokeSession #29639

Open
wants to merge 9 commits into
base: jl/caip-multichain-migrate-core
Choose a base branch
from
170 changes: 170 additions & 0 deletions test/e2e/flask/multichain-api/wallet_revokeSession.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import { strict as assert } from 'assert';
import {
ACCOUNT_1,
ACCOUNT_2,
largeDelayMs,
WINDOW_TITLES,
withFixtures,
} from '../../helpers';
import { Driver } from '../../webdriver/driver';
import FixtureBuilder from '../../fixture-builder';
import {
initCreateSessionScopes,
DEFAULT_MULTICHAIN_TEST_DAPP_FIXTURE_OPTIONS,
openMultichainDappAndConnectWalletWithExternallyConnectable,
addAccountInWalletAndAuthorize,
getSessionScopes,
} from './testHelpers';

describe('Initializing a session w/ several scopes and accounts, then calling `wallet_revokeSession`', function () {
const GANACHE_SCOPES = ['eip155:1337', 'eip155:1338', 'eip155:1000'];
const ACCOUNTS = [ACCOUNT_1, ACCOUNT_2];
it('Should return empty object from `wallet_getSession` call', async function () {
await withFixtures(
{
title: this.test?.fullTitle(),
fixtures: new FixtureBuilder()
.withNetworkControllerTripleGanache()
.build(),
...DEFAULT_MULTICHAIN_TEST_DAPP_FIXTURE_OPTIONS,
},
async ({
driver,
extensionId,
}: {
driver: Driver;
extensionId: string;
}) => {
await openMultichainDappAndConnectWalletWithExternallyConnectable(
driver,
extensionId,
);
await initCreateSessionScopes(driver, GANACHE_SCOPES, ACCOUNTS);
await addAccountInWalletAndAuthorize(driver);
await driver.clickElement({ text: 'Connect', tag: 'button' });
await driver.delay(largeDelayMs);
await driver.switchToWindowWithTitle(WINDOW_TITLES.MultichainTestDApp);

/**
* We verify that scopes are not empty before calling `wallet_revokeSession`
*/
const { sessionScopes } = await getSessionScopes(driver);
for (const scope of GANACHE_SCOPES) {
assert.notStrictEqual(
sessionScopes[scope],
undefined,
`scope ${scope} should not be empty.`,
);
}

await driver.clickElement({
text: 'wallet_revokeSession',
tag: 'span',
});

const parsedResult = await getSessionScopes(driver);
const resultSessionScopes = parsedResult.sessionScopes;
assert.deepStrictEqual(
resultSessionScopes,
{},
'Should receive an empty session scope after calling `wallet_getSession`',
);
},
);
});

it('Should throw an error if `wallet_invokeMethod` is called afterwards', async function () {
await withFixtures(
{
title: this.test?.fullTitle(),
fixtures: new FixtureBuilder()
.withNetworkControllerTripleGanache()
.build(),
...DEFAULT_MULTICHAIN_TEST_DAPP_FIXTURE_OPTIONS,
},
async ({
driver,
extensionId,
}: {
driver: Driver;
extensionId: string;
}) => {
await openMultichainDappAndConnectWalletWithExternallyConnectable(
driver,
extensionId,
);
const expectedError = {
code: 4100,
message:
'The requested account and/or method has not been authorized by the user.',
};

await initCreateSessionScopes(driver, GANACHE_SCOPES, ACCOUNTS);
await addAccountInWalletAndAuthorize(driver);
await driver.clickElement({ text: 'Connect', tag: 'button' });
await driver.delay(largeDelayMs);
await driver.switchToWindowWithTitle(WINDOW_TITLES.MultichainTestDApp);

await driver.clickElement({
text: 'wallet_revokeSession',
tag: 'span',
});

for (const scope of GANACHE_SCOPES) {
const id = 1999133338649204;
const data = JSON.stringify({
id,
jsonrpc: '2.0',
method: 'wallet_invokeMethod',
params: {
scope,
request: {
method: 'eth_getBalance',
params: [ACCOUNT_1, 'latest'],
},
},
});

const script = `
const port = chrome.runtime.connect('${extensionId}');
const data = ${data};
const result = new Promise((resolve) => {
port.onMessage.addListener((msg) => {
if (msg.type !== 'caip-x') {
return;
}
if (msg.data?.id !== ${id}) {
return;
}

if (msg.data.id || msg.data.error) {
resolve(msg)
}
})
})
port.postMessage({ type: 'caip-x', data });
return result;`;

/**
* We call `executeScript` to attempt JSON rpc call directly through the injected provider object since when session is revoked,
* webapp does not provide UI to make call.
*/
const actualError = await driver
.executeScript(script)
.then((res) => res.data?.error);

/**
* We make sure it's the expected error by comparing expected error code and message (we ignore `stack` property)
*/
Object.entries(expectedError).forEach(([key, value]) => {
assert.deepEqual(
value,
actualError[key],
`calling wallet_invokeMethod should throw an error with ${key} ${value} for scope ${scope}`,
);
});
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally in this section I'd prefer something along the lines of

expect(actualError).toBeEqual(expect.objectContaining(expectedError))

Which jest's API allows me to do, but node's strict doesn't seem to have a similar feature. Open to suggestion on a cleaner way of asserting here.

}
},
);
});
});
Loading