1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-12 12:47:14 +01:00
metamask-extension/app/scripts/lib/ComposableObservableStore.test.js
Mark Stacey 5009ceae53
Migrate to new CurrencyRateController (#11005)
The CurrencyRateController has been migrated to the BaseControllerV2
API, which includes various API changes. These changes include:
* The constructor now expects to be passed a
`RestrictedControllerMessenger`.
* State changes are subscribed to via the `ControllerMessenger` now,
rather than via a `subscribe` function.
* The state and configration are passed in as one "options" object,
rather than as two separate parameters
* The polling needs to be started explicitly by calling `start`. It
can be stopped and started on-demand now as well.
* Changing the current currency or native currency will now throw an
error if we fail to update the conversion rate.

The `ComposableObservableStore` has been updated to accomodate these
new types of controllers. The constructor has been updated to use an
options bag pattern as well, to make the addition of the new required
`controllerMessenger` parameter a bit less unweildly.
2021-05-20 00:27:51 -02:30

195 lines
6.1 KiB
JavaScript

import { strict as assert } from 'assert';
import { ObservableStore } from '@metamask/obs-store';
import {
BaseController,
BaseControllerV2,
ControllerMessenger,
} from '@metamask/controllers';
import ComposableObservableStore from './ComposableObservableStore';
class OldExampleController extends BaseController {
name = 'OldExampleController';
defaultState = {
baz: 'baz',
};
constructor() {
super();
this.initialize();
}
updateBaz(contents) {
this.update({ baz: contents });
}
}
class ExampleController extends BaseControllerV2 {
static defaultState = {
bar: 'bar',
};
static metadata = {
bar: { persist: true, anonymous: true },
};
constructor({ messenger }) {
super({
messenger,
name: 'ExampleController',
metadata: ExampleController.metadata,
state: ExampleController.defaultState,
});
}
updateBar(contents) {
this.update(() => {
return { bar: contents };
});
}
}
describe('ComposableObservableStore', function () {
it('should register initial state', function () {
const controllerMessenger = new ControllerMessenger();
const store = new ComposableObservableStore({
controllerMessenger,
state: 'state',
});
assert.strictEqual(store.getState(), 'state');
});
it('should register initial structure', function () {
const controllerMessenger = new ControllerMessenger();
const testStore = new ObservableStore();
const store = new ComposableObservableStore({
config: { TestStore: testStore },
controllerMessenger,
});
testStore.putState('state');
assert.deepEqual(store.getState(), { TestStore: 'state' });
});
it('should update structure with observable store', function () {
const controllerMessenger = new ControllerMessenger();
const testStore = new ObservableStore();
const store = new ComposableObservableStore({ controllerMessenger });
store.updateStructure({ TestStore: testStore });
testStore.putState('state');
assert.deepEqual(store.getState(), { TestStore: 'state' });
});
it('should update structure with BaseController-based controller', function () {
const controllerMessenger = new ControllerMessenger();
const oldExampleController = new OldExampleController();
const store = new ComposableObservableStore({ controllerMessenger });
store.updateStructure({ OldExample: oldExampleController });
oldExampleController.updateBaz('state');
assert.deepEqual(store.getState(), { OldExample: { baz: 'state' } });
});
it('should update structure with BaseControllerV2-based controller', function () {
const controllerMessenger = new ControllerMessenger();
const exampleController = new ExampleController({
messenger: controllerMessenger,
});
const store = new ComposableObservableStore({ controllerMessenger });
store.updateStructure({ Example: exampleController });
exampleController.updateBar('state');
console.log(exampleController.state);
assert.deepEqual(store.getState(), { Example: { bar: 'state' } });
});
it('should update structure with all three types of stores', function () {
const controllerMessenger = new ControllerMessenger();
const exampleStore = new ObservableStore();
const exampleController = new ExampleController({
messenger: controllerMessenger,
});
const oldExampleController = new OldExampleController();
const store = new ComposableObservableStore({ controllerMessenger });
store.updateStructure({
Example: exampleController,
OldExample: oldExampleController,
Store: exampleStore,
});
exampleStore.putState('state');
exampleController.updateBar('state');
oldExampleController.updateBaz('state');
assert.deepEqual(store.getState(), {
Example: { bar: 'state' },
OldExample: { baz: 'state' },
Store: 'state',
});
});
it('should return flattened state', function () {
const controllerMessenger = new ControllerMessenger();
const fooStore = new ObservableStore({ foo: 'foo' });
const barController = new ExampleController({
messenger: controllerMessenger,
});
const bazController = new OldExampleController();
const store = new ComposableObservableStore({
config: {
FooStore: fooStore,
BarStore: barController,
BazStore: bazController,
},
controllerMessenger,
state: {
FooStore: fooStore.getState(),
BarStore: barController.state,
BazStore: bazController.state,
},
});
assert.deepEqual(store.getFlatState(), {
foo: 'foo',
bar: 'bar',
baz: 'baz',
});
});
it('should return empty flattened state when not configured', function () {
const controllerMessenger = new ControllerMessenger();
const store = new ComposableObservableStore({ controllerMessenger });
assert.deepEqual(store.getFlatState(), {});
});
it('should throw if the controller messenger is omitted and the config includes a BaseControllerV2 controller', function () {
const controllerMessenger = new ControllerMessenger();
const exampleController = new ExampleController({
messenger: controllerMessenger,
});
assert.throws(
() =>
new ComposableObservableStore({
config: {
Example: exampleController,
},
}),
);
});
it('should throw if the controller messenger is omitted and updateStructure called with a BaseControllerV2 controller', function () {
const controllerMessenger = new ControllerMessenger();
const exampleController = new ExampleController({
messenger: controllerMessenger,
});
const store = new ComposableObservableStore({});
assert.throws(() => store.updateStructure({ Example: exampleController }));
});
it('should throw if initialized with undefined config entry', function () {
const controllerMessenger = new ControllerMessenger();
assert.throws(
() =>
new ComposableObservableStore({
config: {
Example: undefined,
},
controllerMessenger,
}),
);
});
});