import { OnInit, } from '@angular/core'; import { MemoizedSelector, Store, } from '@ngrx/store'; import { of, } from 'rxjs'; /** * Often our components (mostly organisms) use a similar structure when we * initialize them. This is provides an easy way to test a component that * just pulls data from the store when running ngOnInit. * * An example of how this might be useful if is a component has an ngOnInit * function that looks like this: * public ngOnInit() { * this.isCurrentSidebarTabEdit$ = * this._store.select(selectIsCurrentSidebarTabEdit); * } * * In which case we could easily test that the store select is called and that * the property is set to the matching value. * * An example of this would be: * storeConnectOnInitTests< * MyComponentClass, * StateInterface, * >({ * initComponentFunction: (store) => new MyComponentClass(store), * initStoreFunction: initMockStore, * propertyName: 'isCurrentSidebarTabEdit$', * selector: selectIsCurrentSidebarTabEdit, * }); * * Which would test that isCurrentSidebarTabEdit$ is set to the value from the * store and that the store is called with the selectIsCurrentSidebarTabEdit * selector. */ export const storeConnectOnInitTests = < ComponentType extends OnInit, State >({ initComponentFunction, initStoreFunction, propertyName, selector, }: { initComponentFunction: (store: Store) => ComponentType, initStoreFunction: () => Store, propertyName: keyof ComponentType, selector: MemoizedSelector, }) => { const initData = () => { const mockReturnValue = of('some value'); const store = initStoreFunction(); store.select = jest.fn((arg) => arg === selector ? mockReturnValue : of(null), ); const component = initComponentFunction(store); return { component, mockReturnValue, store, }; }; test(`Calls store.select with ${selector.name}`, () => { const { component, store, } = initData(); component.ngOnInit(); expect(store.select).toHaveBeenCalledWith(selector); }); test(`Sets ${propertyName} to the value from the store`, () => { const { component, mockReturnValue, } = initData(); component.ngOnInit(); expect(component[propertyName]).toBe(mockReturnValue); }); };