1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 01:39:44 +01:00

Robustify permissions controller requestUserApproval tests (#9064)

* convert requestUserApproval mock to wrapper
This commit is contained in:
Erik Marks 2020-07-27 14:35:09 -07:00 committed by GitHub
parent d9f07a796d
commit f6f8e5cc4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 77 additions and 38 deletions

View File

@ -19,25 +19,44 @@ export function grantPermissions (permController, origin, permissions) {
} }
/** /**
* Sets the underlying rpc-cap requestUserApproval function, and returns * Returns a wrapper for the given permissions controller's requestUserApproval
* a promise that's resolved once it has been set. * function, so we don't have to worry about its internals.
* *
* This function must be called on the given permissions controller every * @param {PermissionsController} permController - The permissions controller.
* time you want such a Promise. As of writing, it's only called once per test. * @return {Function} A convenient wrapper for the requestUserApproval function.
*/
export function getRequestUserApprovalHelper (permController) {
/**
* Returns a request object that can be passed to requestUserApproval.
*
* @param {string} id - The internal permissions request ID (not the RPC request ID).
* @param {string} [origin] - The origin of the request, if necessary.
* @returns {Object} The corresponding request object.
*/
return (id, origin = 'defaultOrigin') => {
return permController.permissions.requestUserApproval({ metadata: { id, origin } })
}
}
/**
* Returns a Promise that resolves once a pending user approval has been set.
* Calls the underlying requestUserApproval function as normal, and restores it
* once the Promise is resolved.
*
* This function must be called on the permissions controller for each request.
* *
* @param {PermissionsController} - A permissions controller. * @param {PermissionsController} - A permissions controller.
* @returns {Promise<void>} A Promise that resolves once a pending approval * @returns {Promise<void>} A Promise that resolves once a pending approval
* has been set. * has been set.
*/ */
export function getUserApprovalPromise (permController) { export function getUserApprovalPromise (permController) {
return new Promise((resolveForCaller) => { const originalFunction = permController.permissions.requestUserApproval
permController.permissions.requestUserApproval = async (req) => { return new Promise((resolveHelperPromise) => {
const { origin, metadata: { id } } = req permController.permissions.requestUserApproval = (req) => {
const userApprovalPromise = originalFunction(req)
return new Promise((resolve, reject) => { permController.permissions.requestUserApproval = originalFunction
permController.pendingApprovals.set(id, { origin, resolve, reject }) resolveHelperPromise()
resolveForCaller() return userApprovalPromise
})
} }
}) })
} }

View File

@ -15,6 +15,7 @@ import {
} from '../../../../../app/scripts/controllers/permissions' } from '../../../../../app/scripts/controllers/permissions'
import { import {
getRequestUserApprovalHelper,
grantPermissions, grantPermissions,
} from './helpers' } from './helpers'
@ -58,12 +59,6 @@ const initPermController = (notifications = initNotifications()) => {
}) })
} }
const getMockRequestUserApprovalFunction = (permController) => (id, origin) => {
return new Promise((resolve, reject) => {
permController.pendingApprovals.set(id, { origin, resolve, reject })
})
}
describe('permissions controller', function () { describe('permissions controller', function () {
describe('getAccounts', function () { describe('getAccounts', function () {
@ -951,13 +946,11 @@ describe('permissions controller', function () {
describe('approvePermissionsRequest', function () { describe('approvePermissionsRequest', function () {
let permController, mockRequestUserApproval let permController, requestUserApproval
beforeEach(function () { beforeEach(function () {
permController = initPermController() permController = initPermController()
mockRequestUserApproval = getMockRequestUserApprovalFunction( requestUserApproval = getRequestUserApprovalHelper(permController)
permController,
)
}) })
it('does nothing if called on non-existing request', async function () { it('does nothing if called on non-existing request', async function () {
@ -994,14 +987,14 @@ describe('permissions controller', function () {
PERMS.requests.eth_accounts(), PERMS.requests.eth_accounts(),
) )
const requestRejection = assert.rejects( const rejectionPromise = assert.rejects(
mockRequestUserApproval(REQUEST_IDS.a), requestUserApproval(REQUEST_IDS.a),
ERRORS.validatePermittedAccounts.invalidParam(), ERRORS.validatePermittedAccounts.invalidParam(),
'should reject bad accounts', 'should reject with "null" accounts',
) )
await permController.approvePermissionsRequest(request, null) await permController.approvePermissionsRequest(request, null)
await requestRejection await rejectionPromise
assert.equal( assert.equal(
permController.pendingApprovals.size, 0, permController.pendingApprovals.size, 0,
@ -1014,7 +1007,7 @@ describe('permissions controller', function () {
const request = PERMS.approvedRequest(REQUEST_IDS.a, {}) const request = PERMS.approvedRequest(REQUEST_IDS.a, {})
const requestRejection = assert.rejects( const requestRejection = assert.rejects(
mockRequestUserApproval(REQUEST_IDS.a), requestUserApproval(REQUEST_IDS.a),
ERRORS.approvePermissionsRequest.noPermsRequested(), ERRORS.approvePermissionsRequest.noPermsRequested(),
'should reject if no permissions in request', 'should reject if no permissions in request',
) )
@ -1036,7 +1029,7 @@ describe('permissions controller', function () {
const requestApproval = assert.doesNotReject( const requestApproval = assert.doesNotReject(
async () => { async () => {
perms = await mockRequestUserApproval(REQUEST_IDS.a) perms = await requestUserApproval(REQUEST_IDS.a)
}, },
'should not reject single valid request', 'should not reject single valid request',
) )
@ -1065,14 +1058,14 @@ describe('permissions controller', function () {
const approval1 = assert.doesNotReject( const approval1 = assert.doesNotReject(
async () => { async () => {
perms1 = await mockRequestUserApproval(REQUEST_IDS.a) perms1 = await requestUserApproval(REQUEST_IDS.a, DOMAINS.a.origin)
}, },
'should not reject request', 'should not reject request',
) )
const approval2 = assert.doesNotReject( const approval2 = assert.doesNotReject(
async () => { async () => {
perms2 = await mockRequestUserApproval(REQUEST_IDS.b) perms2 = await requestUserApproval(REQUEST_IDS.b, DOMAINS.b.origin)
}, },
'should not reject request', 'should not reject request',
) )
@ -1105,13 +1098,11 @@ describe('permissions controller', function () {
describe('rejectPermissionsRequest', function () { describe('rejectPermissionsRequest', function () {
let permController, mockRequestUserApproval let permController, requestUserApproval
beforeEach(async function () { beforeEach(async function () {
permController = initPermController() permController = initPermController()
mockRequestUserApproval = getMockRequestUserApprovalFunction( requestUserApproval = getRequestUserApprovalHelper(permController)
permController,
)
}) })
it('does nothing if called on non-existing request', async function () { it('does nothing if called on non-existing request', async function () {
@ -1135,7 +1126,7 @@ describe('permissions controller', function () {
it('rejects single existing request', async function () { it('rejects single existing request', async function () {
const requestRejection = assert.rejects( const requestRejection = assert.rejects(
mockRequestUserApproval(REQUEST_IDS.a), requestUserApproval(REQUEST_IDS.a),
ERRORS.rejectPermissionsRequest.rejection(), ERRORS.rejectPermissionsRequest.rejection(),
'should reject with expected error', 'should reject with expected error',
) )
@ -1152,13 +1143,13 @@ describe('permissions controller', function () {
it('rejects requests regardless of order', async function () { it('rejects requests regardless of order', async function () {
const requestRejection1 = assert.rejects( const requestRejection1 = assert.rejects(
mockRequestUserApproval(REQUEST_IDS.b), requestUserApproval(REQUEST_IDS.b, DOMAINS.b.origin),
ERRORS.rejectPermissionsRequest.rejection(), ERRORS.rejectPermissionsRequest.rejection(),
'should reject with expected error', 'should reject with expected error',
) )
const requestRejection2 = assert.rejects( const requestRejection2 = assert.rejects(
mockRequestUserApproval(REQUEST_IDS.c), requestUserApproval(REQUEST_IDS.c, DOMAINS.c.origin),
ERRORS.rejectPermissionsRequest.rejection(), ERRORS.rejectPermissionsRequest.rejection(),
'should reject with expected error', 'should reject with expected error',
) )

View File

@ -70,11 +70,15 @@ describe('permissions middleware', function () {
) )
const res = {} const res = {}
const userApprovalPromise = getUserApprovalPromise(permController)
const pendingApproval = assert.doesNotReject( const pendingApproval = assert.doesNotReject(
aMiddleware(req, res), aMiddleware(req, res),
'should not reject permissions request', 'should not reject permissions request',
) )
await userApprovalPromise
assert.equal( assert.equal(
permController.pendingApprovals.size, 1, permController.pendingApprovals.size, 1,
'perm controller should have single pending approval', 'perm controller should have single pending approval',
@ -131,11 +135,15 @@ describe('permissions middleware', function () {
// send, approve, and validate first request // send, approve, and validate first request
// note use of ACCOUNTS.a.permitted // note use of ACCOUNTS.a.permitted
let userApprovalPromise = getUserApprovalPromise(permController)
const pendingApproval1 = assert.doesNotReject( const pendingApproval1 = assert.doesNotReject(
aMiddleware(req1, res1), aMiddleware(req1, res1),
'should not reject permissions request', 'should not reject permissions request',
) )
await userApprovalPromise
const id1 = permController.pendingApprovals.keys().next().value const id1 = permController.pendingApprovals.keys().next().value
const approvedReq1 = PERMS.approvedRequest(id1, PERMS.requests.eth_accounts()) const approvedReq1 = PERMS.approvedRequest(id1, PERMS.requests.eth_accounts())
@ -187,11 +195,15 @@ describe('permissions middleware', function () {
// send, approve, and validate second request // send, approve, and validate second request
// note use of ACCOUNTS.b.permitted // note use of ACCOUNTS.b.permitted
userApprovalPromise = getUserApprovalPromise(permController)
const pendingApproval2 = assert.doesNotReject( const pendingApproval2 = assert.doesNotReject(
aMiddleware(req2, res2), aMiddleware(req2, res2),
'should not reject permissions request', 'should not reject permissions request',
) )
await userApprovalPromise
const id2 = permController.pendingApprovals.keys().next().value const id2 = permController.pendingApprovals.keys().next().value
const approvedReq2 = PERMS.approvedRequest(id2, { ...requestedPerms2 }) const approvedReq2 = PERMS.approvedRequest(id2, { ...requestedPerms2 })
@ -251,12 +263,16 @@ describe('permissions middleware', function () {
const expectedError = ERRORS.rejectPermissionsRequest.rejection() const expectedError = ERRORS.rejectPermissionsRequest.rejection()
const userApprovalPromise = getUserApprovalPromise(permController)
const requestRejection = assert.rejects( const requestRejection = assert.rejects(
aMiddleware(req, res), aMiddleware(req, res),
expectedError, expectedError,
'request should be rejected with correct error', 'request should be rejected with correct error',
) )
await userApprovalPromise
assert.equal( assert.equal(
permController.pendingApprovals.size, 1, permController.pendingApprovals.size, 1,
'perm controller should have single pending approval', 'perm controller should have single pending approval',
@ -343,11 +359,15 @@ describe('permissions middleware', function () {
) )
const resA1 = {} const resA1 = {}
let userApprovalPromise = getUserApprovalPromise(permController)
const requestApproval1 = assert.doesNotReject( const requestApproval1 = assert.doesNotReject(
aMiddleware(reqA1, resA1), aMiddleware(reqA1, resA1),
'should not reject permissions request', 'should not reject permissions request',
) )
await userApprovalPromise
// create and start processing first request for second origin // create and start processing first request for second origin
const reqB1 = RPC_REQUESTS.requestPermission( const reqB1 = RPC_REQUESTS.requestPermission(
@ -355,11 +375,15 @@ describe('permissions middleware', function () {
) )
const resB1 = {} const resB1 = {}
userApprovalPromise = getUserApprovalPromise(permController)
const requestApproval2 = assert.doesNotReject( const requestApproval2 = assert.doesNotReject(
bMiddleware(reqB1, resB1), bMiddleware(reqB1, resB1),
'should not reject permissions request', 'should not reject permissions request',
) )
await userApprovalPromise
assert.equal( assert.equal(
permController.pendingApprovals.size, 2, permController.pendingApprovals.size, 2,
'perm controller should have expected number of pending approvals', 'perm controller should have expected number of pending approvals',
@ -373,12 +397,17 @@ describe('permissions middleware', function () {
) )
const resA2 = {} const resA2 = {}
await assert.rejects( userApprovalPromise = getUserApprovalPromise(permController)
const requestApprovalFail = assert.rejects(
aMiddleware(reqA2, resA2), aMiddleware(reqA2, resA2),
expectedError, expectedError,
'request should be rejected with correct error', 'request should be rejected with correct error',
) )
await userApprovalPromise
await requestApprovalFail
assert.ok( assert.ok(
( (
!resA2.result && resA2.error && !resA2.result && resA2.error &&