1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-26 20:39:08 +01:00
metamask-extension/app/scripts/lib/ComposableObservableStore.test.js
Elliot Winkler 51cffa15dd
Migrate to new controller packages (#16547)
* Migrate to new controller packages

`@metamask/controllers` is deprecated, and most of the controllers that
lived here are now located in their own package ([1]). This commit
replaces `@metamask/controllers` in `package.json` with references to
these packages and updates `import` lines to match.

[1]: https://github.com/MetaMask/controllers/pull/831

* Support GitHub registry for draft PRs (#16549)

* Add additional allowed host to lockfile linter

* Update LavaMoat policies

* Add policy exception for nanoid

* Add additional nanoid overrides

* Update LavaMoat policies again

* Bump controller packages

* Update lavamoat

* Bump controller packages

* Update packages to v1.0.0

* Expand gitignore comment

* Unpin controller dependencies, using ^ range instead

Co-authored-by: Mark Stacey <markjstacey@gmail.com>
2022-11-24 16:29:07 -03:30

195 lines
6.1 KiB
JavaScript

import { ObservableStore } from '@metamask/obs-store';
import {
BaseController,
BaseControllerV2,
ControllerMessenger,
} from '@metamask/base-controller';
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', () => {
it('should register initial state', () => {
const controllerMessenger = new ControllerMessenger();
const store = new ComposableObservableStore({
controllerMessenger,
state: 'state',
});
expect(store.getState()).toStrictEqual('state');
});
it('should register initial structure', () => {
const controllerMessenger = new ControllerMessenger();
const testStore = new ObservableStore();
const store = new ComposableObservableStore({
config: { TestStore: testStore },
controllerMessenger,
});
testStore.putState('state');
expect(store.getState()).toStrictEqual({ TestStore: 'state' });
});
it('should update structure with observable store', () => {
const controllerMessenger = new ControllerMessenger();
const testStore = new ObservableStore();
const store = new ComposableObservableStore({ controllerMessenger });
store.updateStructure({ TestStore: testStore });
testStore.putState('state');
expect(store.getState()).toStrictEqual({ TestStore: 'state' });
});
it('should update structure with BaseController-based controller', () => {
const controllerMessenger = new ControllerMessenger();
const oldExampleController = new OldExampleController();
const store = new ComposableObservableStore({ controllerMessenger });
store.updateStructure({ OldExample: oldExampleController });
oldExampleController.updateBaz('state');
expect(store.getState()).toStrictEqual({ OldExample: { baz: 'state' } });
});
it('should update structure with BaseControllerV2-based controller', () => {
const controllerMessenger = new ControllerMessenger();
const exampleController = new ExampleController({
messenger: controllerMessenger,
});
const store = new ComposableObservableStore({ controllerMessenger });
store.updateStructure({ Example: exampleController });
exampleController.updateBar('state');
expect(store.getState()).toStrictEqual({ Example: { bar: 'state' } });
});
it('should update structure with all three types of stores', () => {
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');
expect(store.getState()).toStrictEqual({
Example: { bar: 'state' },
OldExample: { baz: 'state' },
Store: 'state',
});
});
it('should return flattened state', () => {
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,
},
});
expect(store.getFlatState()).toStrictEqual({
foo: 'foo',
bar: 'bar',
baz: 'baz',
});
});
it('should return empty flattened state when not configured', () => {
const controllerMessenger = new ControllerMessenger();
const store = new ComposableObservableStore({ controllerMessenger });
expect(store.getFlatState()).toStrictEqual({});
});
it('should throw if the controller messenger is omitted and the config includes a BaseControllerV2 controller', () => {
const controllerMessenger = new ControllerMessenger();
const exampleController = new ExampleController({
messenger: controllerMessenger,
});
expect(
() =>
new ComposableObservableStore({
config: {
Example: exampleController,
},
}),
).toThrow(`Cannot read properties of undefined (reading 'subscribe')`);
});
it('should throw if the controller messenger is omitted and updateStructure called with a BaseControllerV2 controller', () => {
const controllerMessenger = new ControllerMessenger();
const exampleController = new ExampleController({
messenger: controllerMessenger,
});
const store = new ComposableObservableStore({});
expect(() => store.updateStructure({ Example: exampleController })).toThrow(
`Cannot read properties of undefined (reading 'subscribe')`,
);
});
it('should throw if initialized with undefined config entry', () => {
const controllerMessenger = new ControllerMessenger();
expect(
() =>
new ComposableObservableStore({
config: {
Example: undefined,
},
controllerMessenger,
}),
).toThrow(`Undefined 'Example'`);
});
});