mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-21 17:37:01 +01:00
MV3: add retry logic to actions (#15337)
This commit is contained in:
parent
ece5901b40
commit
99ed42b3dc
@ -11,7 +11,7 @@ import MetaMetricsProviderStorybook from './metametrics';
|
||||
import testData from './test-data.js';
|
||||
import { Router } from 'react-router-dom';
|
||||
import { createBrowserHistory } from 'history';
|
||||
import { _setBackgroundConnection } from '../ui/store/actions';
|
||||
import { _setBackgroundConnection } from '../ui/store/action-queue';
|
||||
import MetaMaskStorybookTheme from './metamask-storybook-theme';
|
||||
import addons from '@storybook/addons';
|
||||
|
||||
|
@ -71,6 +71,8 @@ async function start() {
|
||||
const messageListener = (message) => {
|
||||
if (message?.name === 'CONNECTION_READY') {
|
||||
if (isUIInitialised) {
|
||||
// Currently when service worker is revived we create new streams
|
||||
// in later version we might try to improve it by reviving same streams.
|
||||
updateUiStreams();
|
||||
} else {
|
||||
initializeUiWithTab(activeTab);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as actions from '../../ui/store/actions';
|
||||
import { _setBackgroundConnection } from '../../ui/store/action-queue';
|
||||
|
||||
export const setBackgroundConnection = (backgroundConnection = {}) => {
|
||||
actions._setBackgroundConnection(backgroundConnection);
|
||||
_setBackgroundConnection(backgroundConnection);
|
||||
};
|
||||
|
@ -28,6 +28,7 @@ import {
|
||||
} from './ducks/metamask/metamask';
|
||||
import Root from './pages';
|
||||
import txHelper from './helpers/utils/tx-helper';
|
||||
import { _setBackgroundConnection } from './store/action-queue';
|
||||
|
||||
log.setLevel(global.METAMASK_DEBUG ? 'debug' : 'warn');
|
||||
|
||||
@ -39,7 +40,7 @@ let reduxStore;
|
||||
* @param backgroundConnection - connection object to background
|
||||
*/
|
||||
export const updateBackgroundConnection = (backgroundConnection) => {
|
||||
actions._setBackgroundConnection(backgroundConnection);
|
||||
_setBackgroundConnection(backgroundConnection);
|
||||
backgroundConnection.onNotification((data) => {
|
||||
if (data.method === 'sendUpdate') {
|
||||
reduxStore.dispatch(actions.updateMetamaskState(data.params[0]));
|
||||
|
200
ui/store/action-queue/index.js
Normal file
200
ui/store/action-queue/index.js
Normal file
@ -0,0 +1,200 @@
|
||||
import pify from 'pify';
|
||||
import { isManifestV3 } from '../../../shared/modules/mv3.utils';
|
||||
|
||||
// // A simplified pify maybe?
|
||||
// function pify(apiObject) {
|
||||
// return Object.keys(apiObject).reduce((promisifiedAPI, key) => {
|
||||
// if (apiObject[key].apply) { // depending on our browser support we might use a nicer check for functions here
|
||||
// promisifiedAPI[key] = function (...args) {
|
||||
// return new Promise((resolve, reject) => {
|
||||
// return apiObject[key](
|
||||
// ...args,
|
||||
// (err, result) => {
|
||||
// if (err) {
|
||||
// reject(err);
|
||||
// } else {
|
||||
// resolve(result);
|
||||
// }
|
||||
// },
|
||||
// );
|
||||
// });
|
||||
// };
|
||||
// }
|
||||
// return promisifiedAPI;
|
||||
// }, {});
|
||||
// }
|
||||
|
||||
let background = null;
|
||||
let promisifiedBackground = null;
|
||||
|
||||
const actionRetryQueue = [];
|
||||
|
||||
function failQueue() {
|
||||
actionRetryQueue.forEach(({ reject }) =>
|
||||
reject(
|
||||
Error('Background operation cancelled while waiting for connection.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops the entire actions queue. Rejects all actions in the queue unless silently==true
|
||||
* Does not affect the single action that is currently being processed.
|
||||
*
|
||||
* @param {boolean} [silently]
|
||||
*/
|
||||
export function dropQueue(silently) {
|
||||
if (!silently) {
|
||||
failQueue();
|
||||
}
|
||||
actionRetryQueue.length = 0;
|
||||
}
|
||||
|
||||
// add action to queue
|
||||
const executeActionOrAddToRetryQueue = (item) => {
|
||||
if (actionRetryQueue.some((act) => act.actionId === item.actionId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (background.connectionStream.readable) {
|
||||
executeAction({
|
||||
action: item,
|
||||
disconnectSideeffect: () => actionRetryQueue.push(item),
|
||||
});
|
||||
} else {
|
||||
actionRetryQueue.push(item);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Promise-style call to background method
|
||||
* In MV2: invokes promisifiedBackground method directly.
|
||||
* In MV3: action is added to retry queue, along with resolve handler to be executed on completion,
|
||||
* the queue is then immediately processed if background connection is available.
|
||||
* On completion (successful or error) the action is removed from the retry queue.
|
||||
*
|
||||
* @param {string} method - name of the background method
|
||||
* @param {Array} [args] - arguments to that method, if any
|
||||
* @param {any} [actionId] - if an action with the === same id is submitted, it'll be ignored if already in queue waiting for a retry.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function submitRequestToBackground(
|
||||
method,
|
||||
args = [],
|
||||
actionId = Date.now() + Math.random(), // current date is not guaranteed to be unique
|
||||
) {
|
||||
if (isManifestV3) {
|
||||
return new Promise((resolve, reject) => {
|
||||
executeActionOrAddToRetryQueue({
|
||||
actionId,
|
||||
request: { method, args },
|
||||
resolve,
|
||||
reject,
|
||||
});
|
||||
});
|
||||
}
|
||||
return promisifiedBackground[method](...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback-style call to background method
|
||||
* In MV2: invokes promisifiedBackground method directly.
|
||||
* In MV3: action is added to retry queue, along with resolve handler to be executed on completion,
|
||||
* the queue is then immediately processed if background connection is available.
|
||||
* On completion (successful or error) the action is removed from the retry queue.
|
||||
*
|
||||
* @param {string} method - name of the background method
|
||||
* @param {Array} [args] - arguments to that method, if any
|
||||
* @param callback - Node style (error, result) callback for finishing the operation
|
||||
* @param {any} [actionId] - if an action with the === same id is submitted, it'll be ignored if already in queue.
|
||||
*/
|
||||
export const callBackgroundMethod = (
|
||||
method,
|
||||
args = [],
|
||||
callback,
|
||||
actionId = Date.now() + Math.random(), // current date is not guaranteed to be unique
|
||||
) => {
|
||||
if (isManifestV3) {
|
||||
const resolve = (value) => callback(null, value);
|
||||
const reject = (err) => callback(err);
|
||||
executeActionOrAddToRetryQueue({
|
||||
actionId,
|
||||
request: { method, args },
|
||||
resolve,
|
||||
reject,
|
||||
});
|
||||
} else {
|
||||
background[method](...args, callback);
|
||||
}
|
||||
};
|
||||
|
||||
async function executeAction({ action, disconnectSideeffect }) {
|
||||
const {
|
||||
request: { method, args },
|
||||
resolve,
|
||||
reject,
|
||||
} = action;
|
||||
try {
|
||||
resolve(await promisifiedBackground[method](...args));
|
||||
} catch (err) {
|
||||
if (
|
||||
background.DisconnectError && // necessary to not break compatibility with background stubs or non-default implementations
|
||||
err instanceof background.DisconnectError
|
||||
) {
|
||||
disconnectSideeffect(action);
|
||||
} else {
|
||||
reject(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let processingQueue = false;
|
||||
|
||||
// Clears list of pending action in actionRetryQueue
|
||||
// The results of background calls are wired up to the original promises that's been returned
|
||||
// The first method on the queue gets called synchronously to make testing and reasoning about
|
||||
// a single request to an open connection easier.
|
||||
async function processActionRetryQueue() {
|
||||
if (processingQueue) {
|
||||
return;
|
||||
}
|
||||
processingQueue = true;
|
||||
try {
|
||||
while (
|
||||
background.connectionStream.readable &&
|
||||
actionRetryQueue.length > 0
|
||||
) {
|
||||
// If background disconnects and fails the action, the next one will not be taken off the queue.
|
||||
// Retrying an action that failed because of connection loss while it was processing is not supported.
|
||||
const item = actionRetryQueue.shift();
|
||||
await executeAction({
|
||||
action: item,
|
||||
disconnectSideeffect: () => actionRetryQueue.unshift(item),
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
// error in the queue mechanism itself, the action was malformed
|
||||
console.error(e);
|
||||
}
|
||||
processingQueue = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets/replaces the background connection reference
|
||||
* Under MV3 it also triggers queue processing if the new background is connected
|
||||
*
|
||||
* @param {*} backgroundConnection
|
||||
*/
|
||||
export async function _setBackgroundConnection(backgroundConnection) {
|
||||
background = backgroundConnection;
|
||||
promisifiedBackground = pify(background);
|
||||
if (isManifestV3) {
|
||||
if (processingQueue) {
|
||||
console.warn(
|
||||
'_setBackgroundConnection called while a queue was processing and not disconnected yet',
|
||||
);
|
||||
}
|
||||
// Process all actions collected while connection stream was not available.
|
||||
processActionRetryQueue();
|
||||
}
|
||||
}
|
358
ui/store/action-queue/index.test.js
Normal file
358
ui/store/action-queue/index.test.js
Normal file
@ -0,0 +1,358 @@
|
||||
import sinon from 'sinon';
|
||||
|
||||
import {
|
||||
dropQueue,
|
||||
callBackgroundMethod,
|
||||
submitRequestToBackground,
|
||||
_setBackgroundConnection,
|
||||
} from '.';
|
||||
|
||||
// This file tests only MV3 queue scenario
|
||||
// MV2 tests are already covered by '../actions.test.js'
|
||||
|
||||
jest.mock('../../../shared/modules/mv3.utils', () => {
|
||||
return {
|
||||
isManifestV3: () => true,
|
||||
};
|
||||
});
|
||||
|
||||
describe('ActionQueue', () => {
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
dropQueue(true);
|
||||
});
|
||||
|
||||
describe('dropQueue', () => {
|
||||
it('rejects all pending actions by default', async () => {
|
||||
const background = {
|
||||
connectionStream: {
|
||||
readable: false,
|
||||
},
|
||||
backgroundFunction: sinon.stub().yields(),
|
||||
};
|
||||
|
||||
_setBackgroundConnection(background);
|
||||
const result = submitRequestToBackground('backgroundFunction');
|
||||
dropQueue();
|
||||
|
||||
await expect(result).rejects.toThrow(
|
||||
'Background operation cancelled while waiting for connection.',
|
||||
);
|
||||
expect(background.backgroundFunction.called).toStrictEqual(false);
|
||||
});
|
||||
});
|
||||
describe('submitRequestToBackground', () => {
|
||||
it('calls promisified background method if the stream is connected', async () => {
|
||||
const background = {
|
||||
connectionStream: {
|
||||
readable: true,
|
||||
},
|
||||
backgroundFunction1: sinon.stub().yields(),
|
||||
};
|
||||
|
||||
_setBackgroundConnection(background);
|
||||
submitRequestToBackground('backgroundFunction1');
|
||||
expect(background.backgroundFunction1.called).toStrictEqual(true);
|
||||
});
|
||||
|
||||
it('does not calls promisified background method if the stream is not connected', async () => {
|
||||
const background = {
|
||||
connectionStream: {
|
||||
readable: false,
|
||||
},
|
||||
backgroundFunction2: sinon.stub().yields(),
|
||||
};
|
||||
|
||||
_setBackgroundConnection(background);
|
||||
submitRequestToBackground('backgroundFunction2');
|
||||
expect(background.backgroundFunction2.called).toStrictEqual(false);
|
||||
});
|
||||
|
||||
it('calls promisified background method on stream reconnection', async () => {
|
||||
const background = {
|
||||
connectionStream: {
|
||||
readable: false,
|
||||
},
|
||||
backgroundFunction3: sinon.stub().yields(),
|
||||
};
|
||||
_setBackgroundConnection(background);
|
||||
const requestPromise = submitRequestToBackground('backgroundFunction3');
|
||||
|
||||
background.connectionStream = {
|
||||
readable: true,
|
||||
};
|
||||
_setBackgroundConnection(background);
|
||||
await requestPromise;
|
||||
expect(background.backgroundFunction3.calledOnce).toStrictEqual(true);
|
||||
});
|
||||
|
||||
it('resolves if backgroundFunction resolves', async () => {
|
||||
const background = {
|
||||
connectionStream: {
|
||||
readable: true,
|
||||
},
|
||||
backgroundFunction4: (cb) => {
|
||||
return cb(null, 'test');
|
||||
},
|
||||
};
|
||||
_setBackgroundConnection(background);
|
||||
await expect(
|
||||
submitRequestToBackground('backgroundFunction4'),
|
||||
).resolves.toStrictEqual('test');
|
||||
});
|
||||
|
||||
it('rejects if backgroundFunction throws exception', async () => {
|
||||
expect.assertions(1);
|
||||
const background = {
|
||||
connectionStream: {
|
||||
readable: true,
|
||||
},
|
||||
backgroundFunction: () => {
|
||||
throw Error('test');
|
||||
},
|
||||
};
|
||||
_setBackgroundConnection(background);
|
||||
await expect(
|
||||
submitRequestToBackground('backgroundFunction'),
|
||||
).rejects.toThrow('test');
|
||||
});
|
||||
|
||||
it('calls methods in parallel when connection available', async () => {
|
||||
const trace = {};
|
||||
const background = {
|
||||
connectionStream: {
|
||||
readable: true,
|
||||
},
|
||||
first: (cb) => {
|
||||
setTimeout(() => {
|
||||
trace.firstDone = Date.now();
|
||||
cb(null, 'first');
|
||||
}, 5);
|
||||
},
|
||||
second: (cb) => {
|
||||
trace.secondStarted = Date.now();
|
||||
setTimeout(() => cb(null, 'second'), 10);
|
||||
},
|
||||
};
|
||||
_setBackgroundConnection(background);
|
||||
const scheduled = Promise.all([
|
||||
submitRequestToBackground('first'),
|
||||
submitRequestToBackground('second'),
|
||||
]);
|
||||
await scheduled;
|
||||
expect(trace.firstDone).toBeGreaterThan(trace.secondStarted);
|
||||
});
|
||||
|
||||
it('processes the queue sequentially when connection is restored', async () => {
|
||||
const trace = {};
|
||||
const background = {
|
||||
connectionStream: {
|
||||
readable: false,
|
||||
},
|
||||
first: (cb) => {
|
||||
setTimeout(() => {
|
||||
trace.firstDone = Date.now();
|
||||
cb(null, 'first');
|
||||
}, 5);
|
||||
},
|
||||
second: (cb) => {
|
||||
trace.secondStarted = Date.now();
|
||||
setTimeout(() => cb(null, 'second'), 10);
|
||||
},
|
||||
};
|
||||
_setBackgroundConnection(background);
|
||||
const scheduled = Promise.all([
|
||||
submitRequestToBackground('first'),
|
||||
submitRequestToBackground('second'),
|
||||
]);
|
||||
background.connectionStream.readable = true;
|
||||
_setBackgroundConnection(background);
|
||||
await scheduled;
|
||||
expect(trace.firstDone).toBeLessThanOrEqual(trace.secondStarted);
|
||||
});
|
||||
|
||||
it('ensures actions in queue will not repeat once finished', async () => {
|
||||
const trace = { calls: 0 };
|
||||
const background = {
|
||||
connectionStream: {
|
||||
readable: false,
|
||||
},
|
||||
first: (cb) => {
|
||||
trace.calls += 1;
|
||||
setTimeout(() => {
|
||||
trace.firstDone = Date.now();
|
||||
cb(null, 'first');
|
||||
}, 5);
|
||||
},
|
||||
second: (cb) => {
|
||||
trace.calls += 1;
|
||||
trace.secondStarted = Date.now();
|
||||
setTimeout(() => cb(null, 'second'), 10);
|
||||
},
|
||||
};
|
||||
_setBackgroundConnection(background);
|
||||
const scheduled = Promise.all([
|
||||
submitRequestToBackground('first'),
|
||||
submitRequestToBackground('second'),
|
||||
]);
|
||||
background.connectionStream.readable = true;
|
||||
_setBackgroundConnection(background);
|
||||
await scheduled;
|
||||
_setBackgroundConnection(background); // once all actions finished, this triggers draining the queue again
|
||||
expect(trace.firstDone).toBeLessThanOrEqual(trace.secondStarted);
|
||||
expect(trace.calls).toStrictEqual(2);
|
||||
});
|
||||
|
||||
it('stops processng the queue if connection is lost', async () => {
|
||||
const trace = {};
|
||||
const background = {
|
||||
connectionStream: {
|
||||
readable: false,
|
||||
},
|
||||
first: (cb) => {
|
||||
setTimeout(() => {
|
||||
trace.firstDone = true;
|
||||
background.connectionStream.readable = false;
|
||||
cb(Error('lost connection'));
|
||||
}, 5);
|
||||
},
|
||||
second: sinon.stub().yields(),
|
||||
};
|
||||
_setBackgroundConnection(background);
|
||||
const scheduled = Promise.race([
|
||||
submitRequestToBackground('first').catch(() => ({})),
|
||||
submitRequestToBackground('second'),
|
||||
]);
|
||||
background.connectionStream.readable = true;
|
||||
_setBackgroundConnection(background);
|
||||
await scheduled;
|
||||
await Promise.resolve('one more tick'); // One asynchronous tick to avoid depending on implementation details
|
||||
expect(trace.firstDone).toStrictEqual(true);
|
||||
expect(background.second.called).toStrictEqual(false);
|
||||
});
|
||||
|
||||
// Failing test for a race condition related to how items are removed from queue
|
||||
it('avoids race conditions', async () => {
|
||||
const trace = { first: 0, second: 0 };
|
||||
const flowControl = {};
|
||||
const background = {
|
||||
connectionStream: {
|
||||
readable: false,
|
||||
},
|
||||
first: (cb) => {
|
||||
trace.first += 1;
|
||||
setTimeout(() => {
|
||||
flowControl.triggerRaceCondition();
|
||||
cb(null, 'first');
|
||||
}, 5);
|
||||
},
|
||||
second: (cb) => {
|
||||
trace.second += 1;
|
||||
setTimeout(() => cb(null, 'second'), 10);
|
||||
},
|
||||
third: sinon.stub().yields(),
|
||||
};
|
||||
flowControl.triggerRaceCondition = () => {
|
||||
flowControl.waitFor = submitRequestToBackground('third');
|
||||
};
|
||||
_setBackgroundConnection(background);
|
||||
const scheduled = Promise.all([
|
||||
submitRequestToBackground('first'),
|
||||
submitRequestToBackground('second'),
|
||||
]);
|
||||
background.connectionStream.readable = true;
|
||||
_setBackgroundConnection(background);
|
||||
await scheduled;
|
||||
await flowControl.waitFor;
|
||||
expect(trace.first).toStrictEqual(1);
|
||||
expect(trace.second).toStrictEqual(1);
|
||||
expect(background.third.calledOnce).toStrictEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('callBackgroundMethod', () => {
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
it('calls background method if the stream is connected', async () => {
|
||||
const background = {
|
||||
connectionStream: {
|
||||
readable: true,
|
||||
},
|
||||
backgroundFunction: sinon.stub().yields(),
|
||||
};
|
||||
|
||||
_setBackgroundConnection(background);
|
||||
callBackgroundMethod('backgroundFunction', [], () => ({}));
|
||||
expect(background.backgroundFunction.called).toStrictEqual(true);
|
||||
});
|
||||
|
||||
it('does not call background method if the stream is not connected', async () => {
|
||||
const background = {
|
||||
connectionStream: {
|
||||
readable: false,
|
||||
},
|
||||
backgroundFunction: sinon.stub(),
|
||||
};
|
||||
|
||||
_setBackgroundConnection(background);
|
||||
callBackgroundMethod('backgroundFunction', [], () => ({}));
|
||||
expect(background.backgroundFunction.called).toStrictEqual(false);
|
||||
});
|
||||
|
||||
it('calls background method on stream reconnection', async () => {
|
||||
const background = {
|
||||
connectionStream: {
|
||||
readable: false,
|
||||
},
|
||||
backgroundFunction: sinon.stub().yields(),
|
||||
};
|
||||
_setBackgroundConnection(background);
|
||||
callBackgroundMethod('backgroundFunction', [], () => ({}));
|
||||
expect(background.backgroundFunction.called).toStrictEqual(false);
|
||||
|
||||
background.connectionStream = {
|
||||
readable: true,
|
||||
};
|
||||
_setBackgroundConnection(background);
|
||||
expect(background.backgroundFunction.calledOnce).toStrictEqual(true);
|
||||
});
|
||||
|
||||
it('resolves if backgroundFunction called resolves', async () => {
|
||||
const background = {
|
||||
connectionStream: {
|
||||
readable: true,
|
||||
},
|
||||
backgroundFunction: (cb) => {
|
||||
return cb(null, 'successViaCallback');
|
||||
},
|
||||
};
|
||||
_setBackgroundConnection(background);
|
||||
const value = await new Promise((resolve) => {
|
||||
callBackgroundMethod('backgroundFunction', [], (_err, result) => {
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
expect(value).toStrictEqual('successViaCallback');
|
||||
});
|
||||
it('rejects if backgroundFunction called rejects', async () => {
|
||||
const errorViaCallback = Error('errorViaCallback');
|
||||
const background = {
|
||||
connectionStream: {
|
||||
readable: true,
|
||||
},
|
||||
backgroundFunction: (cb) => {
|
||||
return cb(errorViaCallback);
|
||||
},
|
||||
};
|
||||
_setBackgroundConnection(background);
|
||||
const value = await new Promise((resolve) => {
|
||||
callBackgroundMethod('backgroundFunction', [], (err) => {
|
||||
resolve(err);
|
||||
});
|
||||
});
|
||||
expect(value).toStrictEqual(errorViaCallback);
|
||||
});
|
||||
});
|
||||
});
|
66
ui/store/action-queue/queue.integration.test.js
Normal file
66
ui/store/action-queue/queue.integration.test.js
Normal file
@ -0,0 +1,66 @@
|
||||
import sinon from 'sinon';
|
||||
import PortStream from 'extension-port-stream';
|
||||
import { setupMultiplex } from '../../../app/scripts/lib/stream-utils';
|
||||
import metaRPCClientFactory from '../../../app/scripts/lib/metaRPCClientFactory';
|
||||
|
||||
import {
|
||||
dropQueue,
|
||||
submitRequestToBackground,
|
||||
_setBackgroundConnection,
|
||||
} from '.';
|
||||
|
||||
jest.mock('../../../shared/modules/mv3.utils', () => {
|
||||
return {
|
||||
isManifestV3: () => true,
|
||||
};
|
||||
});
|
||||
|
||||
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
describe('queue integration test', () => {
|
||||
afterEach(() => {
|
||||
dropQueue(true);
|
||||
});
|
||||
it('schedules a retry if background method failed because of a disconnect', async () => {
|
||||
let disconnectListener;
|
||||
const extensionPort = {
|
||||
onMessage: {
|
||||
addListener: sinon.stub(),
|
||||
},
|
||||
onDisconnect: {
|
||||
addListener(cb) {
|
||||
disconnectListener = cb;
|
||||
},
|
||||
},
|
||||
postMessage: sinon.stub().callsFake(() => {
|
||||
disconnectListener();
|
||||
}),
|
||||
};
|
||||
|
||||
const connectionStream = new PortStream(extensionPort);
|
||||
const mx = setupMultiplex(connectionStream);
|
||||
const multiplexStream1 = mx.createStream('controller');
|
||||
const background = metaRPCClientFactory(multiplexStream1);
|
||||
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
// disconnect will happen on the attempt to send the message
|
||||
const finished = submitRequestToBackground('backgroundFunction').catch(
|
||||
(error) => {
|
||||
// disconnect error should not get propagated, we retry.
|
||||
// eslint-disable-next-line jest/no-conditional-expect
|
||||
expect(error).not.toBeInstanceOf(background.DisconnectError);
|
||||
// eslint-disable-next-line jest/no-conditional-expect
|
||||
expect(error.message).toContain('cancelled');
|
||||
},
|
||||
);
|
||||
// We want to make sure we disconnect in the middle of processing, so we have to wait for the control flow to reach postMessage
|
||||
// undetermined number of asynchronous jumps withing the stream implementation leaves no other option
|
||||
await wait(3);
|
||||
// we drop the queue because we're expecting the action to have been returned to the queue and this is the simplest way to check that
|
||||
dropQueue();
|
||||
|
||||
expect(extensionPort.postMessage.calledOnce).toStrictEqual(true);
|
||||
await finished;
|
||||
});
|
||||
});
|
File diff suppressed because it is too large
Load Diff
@ -7,6 +7,7 @@ import { TRANSACTION_STATUSES } from '../../shared/constants/transaction';
|
||||
import { DEVICE_NAMES } from '../../shared/constants/hardware-wallets';
|
||||
import { GAS_LIMITS } from '../../shared/constants/gas';
|
||||
import * as actions from './actions';
|
||||
import { _setBackgroundConnection } from './action-queue';
|
||||
|
||||
const middleware = [thunk];
|
||||
const defaultState = {
|
||||
@ -56,7 +57,7 @@ describe('Actions', () => {
|
||||
cb(),
|
||||
);
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -81,7 +82,7 @@ describe('Actions', () => {
|
||||
|
||||
background.submitPassword.callsFake((_, cb) => cb(new Error('error')));
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -111,7 +112,7 @@ describe('Actions', () => {
|
||||
|
||||
background.unMarkPasswordForgotten.callsFake((cb) => cb());
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
await store.dispatch(
|
||||
actions.createNewVaultAndRestore('password', 'test'),
|
||||
@ -125,7 +126,7 @@ describe('Actions', () => {
|
||||
background.createNewVaultAndRestore.callsFake((_, __, cb) => cb());
|
||||
background.unMarkPasswordForgotten.callsFake((cb) => cb());
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -152,7 +153,7 @@ describe('Actions', () => {
|
||||
cb(new Error('error')),
|
||||
);
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -183,7 +184,7 @@ describe('Actions', () => {
|
||||
cb(null, Array.from(Buffer.from('test').values())),
|
||||
);
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
await store.dispatch(actions.requestRevealSeedWords());
|
||||
expect(verifyPassword.callCount).toStrictEqual(1);
|
||||
@ -198,7 +199,7 @@ describe('Actions', () => {
|
||||
cb(new Error('error'));
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -244,7 +245,7 @@ describe('Actions', () => {
|
||||
|
||||
const removeAccount = background.removeAccount.callsFake((_, cb) => cb());
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
'SHOW_LOADING_INDICATION',
|
||||
@ -271,7 +272,7 @@ describe('Actions', () => {
|
||||
cb(new Error('error'));
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -299,7 +300,7 @@ describe('Actions', () => {
|
||||
|
||||
const resetAccount = background.resetAccount.callsFake((cb) => cb());
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -319,7 +320,7 @@ describe('Actions', () => {
|
||||
cb(new Error('error'));
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -348,7 +349,7 @@ describe('Actions', () => {
|
||||
cb();
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
await store.dispatch(
|
||||
actions.importNewAccount('Private Key', [
|
||||
@ -365,7 +366,7 @@ describe('Actions', () => {
|
||||
cb(new Error('error')),
|
||||
);
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{
|
||||
@ -396,7 +397,7 @@ describe('Actions', () => {
|
||||
}),
|
||||
);
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
await store.dispatch(actions.addNewAccount(1));
|
||||
expect(addNewAccount.callCount).toStrictEqual(1);
|
||||
@ -409,7 +410,7 @@ describe('Actions', () => {
|
||||
cb(new Error('error'));
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -439,7 +440,7 @@ describe('Actions', () => {
|
||||
},
|
||||
);
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
await store.dispatch(
|
||||
actions.checkHardwareStatus(DEVICE_NAMES.LEDGER, `m/44'/60'/0'/0`),
|
||||
@ -454,7 +455,7 @@ describe('Actions', () => {
|
||||
cb(new Error('error')),
|
||||
);
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -480,7 +481,7 @@ describe('Actions', () => {
|
||||
|
||||
const forgetDevice = background.forgetDevice.callsFake((_, cb) => cb());
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
await store.dispatch(actions.forgetDevice(DEVICE_NAMES.LEDGER));
|
||||
expect(forgetDevice.callCount).toStrictEqual(1);
|
||||
@ -491,7 +492,7 @@ describe('Actions', () => {
|
||||
|
||||
background.forgetDevice.callsFake((_, cb) => cb(new Error('error')));
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -521,7 +522,7 @@ describe('Actions', () => {
|
||||
|
||||
background.establishLedgerTransportPreference.callsFake((cb) => cb());
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
await store.dispatch(
|
||||
actions.connectHardware(DEVICE_NAMES.LEDGER, 0, `m/44'/60'/0'/0`),
|
||||
@ -538,7 +539,7 @@ describe('Actions', () => {
|
||||
|
||||
background.establishLedgerTransportPreference.callsFake((cb) => cb());
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{
|
||||
@ -569,7 +570,7 @@ describe('Actions', () => {
|
||||
(_, __, ___, ____, cb) => cb(),
|
||||
);
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
await store.dispatch(
|
||||
actions.unlockHardwareWalletAccounts(
|
||||
@ -589,7 +590,7 @@ describe('Actions', () => {
|
||||
cb(new Error('error')),
|
||||
);
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -613,7 +614,7 @@ describe('Actions', () => {
|
||||
it('calls setCurrentCurrency', async () => {
|
||||
const store = mockStore();
|
||||
background.setCurrentCurrency = sinon.stub().callsFake((_, cb) => cb());
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
await store.dispatch(actions.setCurrentCurrency('jpy'));
|
||||
expect(background.setCurrentCurrency.callCount).toStrictEqual(1);
|
||||
@ -624,7 +625,7 @@ describe('Actions', () => {
|
||||
background.setCurrentCurrency = sinon
|
||||
.stub()
|
||||
.callsFake((_, cb) => cb(new Error('error')));
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -655,7 +656,7 @@ describe('Actions', () => {
|
||||
cb(null, defaultState.metamask),
|
||||
);
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
await store.dispatch(actions.signMsg(msgParams));
|
||||
expect(signMessage.callCount).toStrictEqual(1);
|
||||
@ -666,7 +667,7 @@ describe('Actions', () => {
|
||||
|
||||
background.signMessage.callsFake((_, cb) => cb(new Error('error')));
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -699,7 +700,7 @@ describe('Actions', () => {
|
||||
(_, cb) => cb(null, defaultState.metamask),
|
||||
);
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
await store.dispatch(actions.signPersonalMsg(msgParams));
|
||||
expect(signPersonalMessage.callCount).toStrictEqual(1);
|
||||
@ -712,7 +713,7 @@ describe('Actions', () => {
|
||||
cb(new Error('error'));
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -780,7 +781,7 @@ describe('Actions', () => {
|
||||
cb(null, defaultState.metamask),
|
||||
);
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
await store.dispatch(actions.signTypedMsg(msgParamsV3));
|
||||
expect(signTypedMsg.callCount).toStrictEqual(1);
|
||||
@ -791,7 +792,7 @@ describe('Actions', () => {
|
||||
|
||||
background.signTypedMessage.callsFake((_, cb) => cb(new Error('error')));
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -837,7 +838,7 @@ describe('Actions', () => {
|
||||
getState: sinon.stub().callsFake((cb) => cb(null, baseMockState)),
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
await store.dispatch(actions.updateTransaction(txData));
|
||||
|
||||
@ -865,7 +866,7 @@ describe('Actions', () => {
|
||||
),
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -903,7 +904,7 @@ describe('Actions', () => {
|
||||
|
||||
const backgroundSetLocked = background.setLocked.callsFake((cb) => cb());
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
await store.dispatch(actions.lockMetamask());
|
||||
expect(backgroundSetLocked.callCount).toStrictEqual(1);
|
||||
@ -916,7 +917,7 @@ describe('Actions', () => {
|
||||
cb(new Error('error'));
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -945,7 +946,7 @@ describe('Actions', () => {
|
||||
setSelectedAddress: setSelectedAddressSpy,
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
await store.dispatch(
|
||||
actions.setSelectedAddress(
|
||||
@ -966,7 +967,7 @@ describe('Actions', () => {
|
||||
setSelectedAddress: setSelectedAddressSpy,
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -996,7 +997,7 @@ describe('Actions', () => {
|
||||
setSelectedAddress: setSelectedAddressSpy,
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
await store.dispatch(actions.showAccountDetail());
|
||||
expect(setSelectedAddressSpy.callCount).toStrictEqual(1);
|
||||
@ -1016,7 +1017,7 @@ describe('Actions', () => {
|
||||
setSelectedAddress: setSelectedAddressSpy,
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -1046,7 +1047,7 @@ describe('Actions', () => {
|
||||
getState: sinon.stub().callsFake((cb) => cb(null, baseMockState)),
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
await store.dispatch(
|
||||
actions.addToken({
|
||||
@ -1076,7 +1077,7 @@ describe('Actions', () => {
|
||||
getState: sinon.stub().callsFake((cb) => cb(null, baseMockState)),
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -1114,7 +1115,7 @@ describe('Actions', () => {
|
||||
getState: sinon.stub().callsFake((cb) => cb(null, baseMockState)),
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
await store.dispatch(
|
||||
actions.ignoreTokens({ tokensToIgnore: '0x0000001' }),
|
||||
@ -1130,7 +1131,7 @@ describe('Actions', () => {
|
||||
getState: sinon.stub().callsFake((cb) => cb(null, baseMockState)),
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -1164,7 +1165,7 @@ describe('Actions', () => {
|
||||
setProviderType: setProviderTypeStub,
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
await store.dispatch(actions.setProviderType());
|
||||
expect(setProviderTypeStub.callCount).toStrictEqual(1);
|
||||
@ -1179,7 +1180,7 @@ describe('Actions', () => {
|
||||
.callsFake((_, cb) => cb(new Error('error'))),
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'DISPLAY_WARNING', value: 'Had a problem changing networks!' },
|
||||
@ -1200,7 +1201,7 @@ describe('Actions', () => {
|
||||
|
||||
background.setCustomRpc.callsFake((_, __, ___, ____, cb) => cb());
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
await store.dispatch(actions.setRpcTarget('http://localhost:8545'));
|
||||
expect(background.setCustomRpc.callCount).toStrictEqual(1);
|
||||
@ -1213,7 +1214,7 @@ describe('Actions', () => {
|
||||
cb(new Error('error')),
|
||||
);
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'DISPLAY_WARNING', value: 'Had a problem changing networks!' },
|
||||
@ -1236,7 +1237,7 @@ describe('Actions', () => {
|
||||
setAddressBook: setAddressBookStub,
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
await store.dispatch(actions.addToAddressBook('0x0000'));
|
||||
expect(setAddressBookStub.callCount).toStrictEqual(1);
|
||||
@ -1265,7 +1266,7 @@ describe('Actions', () => {
|
||||
exportAccount: exportAccountStub,
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -1295,7 +1296,7 @@ describe('Actions', () => {
|
||||
verifyPassword: verifyPasswordStub,
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -1324,7 +1325,7 @@ describe('Actions', () => {
|
||||
exportAccount: exportAccountStub,
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -1357,7 +1358,7 @@ describe('Actions', () => {
|
||||
setAccountLabel: setAccountLabelStub,
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
await store.dispatch(
|
||||
actions.setAccountLabel(
|
||||
@ -1377,7 +1378,7 @@ describe('Actions', () => {
|
||||
.callsFake((_, __, cb) => cb(new Error('error'))),
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -1412,7 +1413,7 @@ describe('Actions', () => {
|
||||
setFeatureFlag: setFeatureFlagStub,
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
await store.dispatch(actions.setFeatureFlag());
|
||||
expect(setFeatureFlagStub.callCount).toStrictEqual(1);
|
||||
@ -1427,7 +1428,7 @@ describe('Actions', () => {
|
||||
.callsFake((_, __, cb) => cb(new Error('error'))),
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -1456,7 +1457,7 @@ describe('Actions', () => {
|
||||
completeOnboarding: completeOnboardingStub,
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
await store.dispatch(actions.setCompletedOnboarding());
|
||||
expect(completeOnboardingStub.callCount).toStrictEqual(1);
|
||||
@ -1471,7 +1472,7 @@ describe('Actions', () => {
|
||||
.callsFake((cb) => cb(new Error('error'))),
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -1495,7 +1496,7 @@ describe('Actions', () => {
|
||||
it('calls setUseBlockie in background', async () => {
|
||||
const store = mockStore();
|
||||
const setUseBlockieStub = sinon.stub().callsFake((_, cb) => cb());
|
||||
actions._setBackgroundConnection({ setUseBlockie: setUseBlockieStub });
|
||||
_setBackgroundConnection({ setUseBlockie: setUseBlockieStub });
|
||||
|
||||
await store.dispatch(actions.setUseBlockie());
|
||||
expect(setUseBlockieStub.callCount).toStrictEqual(1);
|
||||
@ -1507,7 +1508,7 @@ describe('Actions', () => {
|
||||
cb(new Error('error'));
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection({ setUseBlockie: setUseBlockieStub });
|
||||
_setBackgroundConnection({ setUseBlockie: setUseBlockieStub });
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'SHOW_LOADING_INDICATION', value: undefined },
|
||||
@ -1535,7 +1536,7 @@ describe('Actions', () => {
|
||||
it('calls expected actions', async () => {
|
||||
const store = mockStore();
|
||||
const setCurrentLocaleStub = sinon.stub().callsFake((_, cb) => cb());
|
||||
actions._setBackgroundConnection({
|
||||
_setBackgroundConnection({
|
||||
setCurrentLocale: setCurrentLocaleStub,
|
||||
});
|
||||
|
||||
@ -1558,7 +1559,7 @@ describe('Actions', () => {
|
||||
const setCurrentLocaleStub = sinon
|
||||
.stub()
|
||||
.callsFake((_, cb) => cb(new Error('error')));
|
||||
actions._setBackgroundConnection({
|
||||
_setBackgroundConnection({
|
||||
setCurrentLocale: setCurrentLocaleStub,
|
||||
});
|
||||
|
||||
@ -1584,7 +1585,7 @@ describe('Actions', () => {
|
||||
|
||||
background.markPasswordForgotten.callsFake((cb) => cb());
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
await store.dispatch(actions.markPasswordForgotten());
|
||||
|
||||
@ -1603,7 +1604,7 @@ describe('Actions', () => {
|
||||
cb(new Error('error')),
|
||||
);
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: 'HIDE_LOADING_INDICATION' },
|
||||
@ -1628,7 +1629,7 @@ describe('Actions', () => {
|
||||
|
||||
background.unMarkPasswordForgotten.callsFake((cb) => cb());
|
||||
|
||||
actions._setBackgroundConnection(background);
|
||||
_setBackgroundConnection(background);
|
||||
|
||||
store.dispatch(actions.unMarkPasswordForgotten());
|
||||
|
||||
@ -1687,7 +1688,7 @@ describe('Actions', () => {
|
||||
),
|
||||
});
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
const txId = 1457634084250832;
|
||||
|
||||
@ -1742,7 +1743,7 @@ describe('Actions', () => {
|
||||
},
|
||||
];
|
||||
|
||||
actions._setBackgroundConnection(background.getApi());
|
||||
_setBackgroundConnection(background.getApi());
|
||||
|
||||
await store.dispatch(actions.cancelMsgs(msgsList));
|
||||
const resultantActions = store.getActions();
|
||||
|
Loading…
Reference in New Issue
Block a user