Skip to content

Commit

Permalink
Migrate CurrencyRateController to BaseControllerV2
Browse files Browse the repository at this point in the history
The CurrencyRateController has been migrated to the new base
controller. The configuration can now only be set during construction,
as it was never changed at runtime in practice with the old controller.
Similarly, the `disable` function was removed as it wasn't relied upon
in practice.

The TokenRatesController has been detached temporarily from the
CurrencyRateController, just to get this to compile and to get tests
running. This can't be merged as-is, because now the
TokenRatesController doesn't get currency rate updates anymore.
  • Loading branch information
Gudahtt committed Apr 19, 2021
1 parent c38021a commit cd60734
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 221 deletions.
32 changes: 0 additions & 32 deletions src/ComposableController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ import {
RestrictedControllerMessenger,
} from './ControllerMessenger';
import PreferencesController from './user/PreferencesController';
import TokenRatesController from './assets/TokenRatesController';
import { AssetsController } from './assets/AssetsController';
import {
NetworkController,
NetworksChainId,
} from './network/NetworkController';
import { AssetsContractController } from './assets/AssetsContractController';
import CurrencyRateController from './assets/CurrencyRateController';

// Mock BaseControllerV2 classes

Expand Down Expand Up @@ -107,21 +105,13 @@ describe('ComposableController', () => {
assetContractController,
),
});
const currencyRateController = new CurrencyRateController();
const controller = new ComposableController([
new AddressBookController(),
assetController,
assetContractController,
new EnsController(),
currencyRateController,
networkController,
preferencesController,
new TokenRatesController({
onAssetsStateChange: (listener) =>
assetController.subscribe(listener),
onCurrencyRateStateChange: (listener) =>
currencyRateController.subscribe(listener),
}),
]);
expect(controller.state).toStrictEqual({
AddressBookController: { addressBook: {} },
Expand All @@ -137,13 +127,6 @@ describe('ComposableController', () => {
suggestedAssets: [],
tokens: [],
},
CurrencyRateController: {
conversionDate: 0,
conversionRate: 0,
currentCurrency: 'usd',
nativeCurrency: 'ETH',
usdConversionRate: 0,
},
EnsController: {
ensEntries: {},
},
Expand All @@ -159,7 +142,6 @@ describe('ComposableController', () => {
lostIdentities: {},
selectedAddress: '',
},
TokenRatesController: { contractExchangeRates: {} },
});
});

Expand All @@ -182,21 +164,13 @@ describe('ComposableController', () => {
assetContractController,
),
});
const currencyRateController = new CurrencyRateController();
const controller = new ComposableController([
new AddressBookController(),
assetController,
assetContractController,
new EnsController(),
currencyRateController,
networkController,
preferencesController,
new TokenRatesController({
onAssetsStateChange: (listener) =>
assetController.subscribe(listener),
onCurrencyRateStateChange: (listener) =>
currencyRateController.subscribe(listener),
}),
]);
expect(controller.flatState).toStrictEqual({
addressBook: {},
Expand All @@ -205,10 +179,6 @@ describe('ComposableController', () => {
allTokens: {},
collectibleContracts: [],
collectibles: [],
contractExchangeRates: {},
conversionDate: 0,
conversionRate: 0,
currentCurrency: 'usd',
ensEntries: {},
featureFlags: {},
frequentRpcList: [],
Expand All @@ -217,13 +187,11 @@ describe('ComposableController', () => {
ignoredTokens: [],
ipfsGateway: 'https://ipfs.io/ipfs/',
lostIdentities: {},
nativeCurrency: 'ETH',
network: 'loading',
provider: { type: 'mainnet', chainId: NetworksChainId.mainnet },
selectedAddress: '',
suggestedAssets: [],
tokens: [],
usdConversionRate: 0,
});
});

Expand Down
148 changes: 86 additions & 62 deletions src/assets/CurrencyRateController.test.ts
Original file line number Diff line number Diff line change
@@ -1,68 +1,75 @@
import 'isomorphic-fetch';
import { stub } from 'sinon';
import CurrencyRateController from './CurrencyRateController';
import { ControllerMessenger } from '../ControllerMessenger';
import {
CurrencyRateController,
CurrencyRateStateChange,
} from './CurrencyRateController';

const name = 'CurrencyRateController';

function getRestrictedMessenger() {
const controllerMessenger = new ControllerMessenger<
any,
CurrencyRateStateChange
>();
const messenger = controllerMessenger.getRestricted<
'CurrencyRateController',
never,
never
>({
name,
});
return messenger;
}

describe('CurrencyRateController', () => {
it('should set default state', () => {
const fetchExchangeRateStub = stub();
const messenger = getRestrictedMessenger();
const controller = new CurrencyRateController(
{},
{},
{ messenger },
fetchExchangeRateStub,
);
expect(controller.state).toStrictEqual({
conversionDate: 0,
conversionRate: 0,
currentCurrency: 'usd',
nativeCurrency: 'ETH',
usdConversionRate: 0,
});

controller.disabled = true;
});

it('should initialize with the default config', () => {
const fetchExchangeRateStub = stub();
const controller = new CurrencyRateController(
{},
{},
fetchExchangeRateStub,
);
expect(controller.config).toStrictEqual({
currentCurrency: 'usd',
disabled: false,
interval: 180000,
nativeCurrency: 'ETH',
includeUSDRate: false,
pendingCurrentCurrency: null,
pendingNativeCurrency: null,
usdConversionRate: null,
});

controller.disabled = true;
controller.destroy();
});

it('should initialize with the currency in state', () => {
it('should initialize with initial state', () => {
const fetchExchangeRateStub = stub();
const messenger = getRestrictedMessenger();
const existingState = { currentCurrency: 'rep' };
const controller = new CurrencyRateController(
{},
existingState,
{ messenger, state: existingState },
fetchExchangeRateStub,
);
expect(controller.config).toStrictEqual({
expect(controller.state).toStrictEqual({
conversionDate: 0,
conversionRate: 0,
currentCurrency: 'rep',
disabled: false,
interval: 180000,
nativeCurrency: 'ETH',
includeUSDRate: false,
pendingCurrentCurrency: null,
pendingNativeCurrency: null,
usdConversionRate: null,
});

controller.disabled = true;
controller.destroy();
});

it('should throw when currentCurrency property is accessed', () => {
const fetchExchangeRateStub = stub();
const messenger = getRestrictedMessenger();
const controller = new CurrencyRateController(
{},
{},
{ messenger },
fetchExchangeRateStub,
);
expect(() => console.log(controller.currentCurrency)).toThrow(
Expand All @@ -72,9 +79,9 @@ describe('CurrencyRateController', () => {

it('should throw when nativeCurrency property is accessed', () => {
const fetchExchangeRateStub = stub();
const messenger = getRestrictedMessenger();
const controller = new CurrencyRateController(
{},
{},
{ messenger },
fetchExchangeRateStub,
);
expect(() => console.log(controller.nativeCurrency)).toThrow(
Expand All @@ -84,9 +91,9 @@ describe('CurrencyRateController', () => {

it('should poll and update rate in the right interval', async () => {
const fetchExchangeRateStub = stub();
const messenger = getRestrictedMessenger();
const controller = new CurrencyRateController(
{ interval: 100 },
{},
{ interval: 100, messenger },
fetchExchangeRateStub,
);

Expand All @@ -96,61 +103,76 @@ describe('CurrencyRateController', () => {
await new Promise<void>((resolve) => setTimeout(() => resolve(), 150));
expect(fetchExchangeRateStub.calledTwice).toBe(true);

controller.disabled = true;
});

it('should not update rates if disabled', async () => {
const fetchExchangeRateStub = stub().resolves({});
const controller = new CurrencyRateController(
{ interval: 10 },
{},
fetchExchangeRateStub,
);
controller.disabled = true;

await controller.updateExchangeRate();
expect(fetchExchangeRateStub.called).toBe(false);
controller.destroy();
});

it('should clear previous interval', async () => {
const fetchExchangeRateStub = stub();
const messenger = getRestrictedMessenger();
const mock = stub(global, 'clearTimeout');
const controller = new CurrencyRateController(
{ interval: 1337 },
{},
{ interval: 1337, messenger },
fetchExchangeRateStub,
);
await new Promise<void>((resolve) => {
setTimeout(() => {
controller.poll(1338);
controller.poll();
expect(mock.called).toBe(true);
mock.restore();

controller.disabled = true;
controller.destroy();
resolve();
}, 100);
});
});

it('should update currency', async () => {
it('should update exchange rate', async () => {
const fetchExchangeRateStub = stub().resolves({ conversionRate: 10 });
const messenger = getRestrictedMessenger();
const controller = new CurrencyRateController(
{ interval: 10 },
{},
{ interval: 10, messenger },
fetchExchangeRateStub,
);
expect(controller.state.conversionRate).toStrictEqual(0);
await controller.updateExchangeRate();
expect(controller.state.conversionRate).toStrictEqual(10);

controller.disabled = true;
controller.destroy();
});

it('should update current currency', async () => {
const fetchExchangeRateStub = stub().resolves({ conversionRate: 10 });
const messenger = getRestrictedMessenger();
const controller = new CurrencyRateController(
{ interval: 10, messenger },
fetchExchangeRateStub,
);
expect(controller.state.conversionRate).toStrictEqual(0);
await controller.setCurrentCurrency('CAD');
expect(controller.state.conversionRate).toStrictEqual(10);

controller.destroy();
});

it('should add usd rate to state when includeUSDRate is configured true', async () => {
it('should update native currency', async () => {
const fetchExchangeRateStub = stub().resolves({ conversionRate: 10 });
const messenger = getRestrictedMessenger();
const controller = new CurrencyRateController(
{ interval: 10, messenger },
fetchExchangeRateStub,
);
expect(controller.state.conversionRate).toStrictEqual(0);
await controller.setNativeCurrency('xDAI');
expect(controller.state.conversionRate).toStrictEqual(10);

controller.destroy();
});

it('should add usd rate to state when includeUsdRate is configured true', async () => {
const fetchExchangeRateStub = stub().resolves({});
const messenger = getRestrictedMessenger();
const controller = new CurrencyRateController(
{ includeUSDRate: true, currentCurrency: 'xyz' },
{},
{ includeUsdRate: true, messenger, state: { currentCurrency: 'xyz' } },
fetchExchangeRateStub,
);

Expand All @@ -159,5 +181,7 @@ describe('CurrencyRateController', () => {
expect(
fetchExchangeRateStub.alwaysCalledWithExactly('xyz', 'ETH', true),
).toBe(true);

controller.destroy();
});
});
Loading

0 comments on commit cd60734

Please sign in to comment.