import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; import { fakeAsync, tick } from '@angular/core/testing'; import faker from '@faker-js/faker'; import { Resource } from '@ngxp/rest'; import { DummyLinkRel } from 'libs/tech-shared/test/dummy'; import { createDummyListResource, createDummyResource } from 'libs/tech-shared/test/resource'; import { BehaviorSubject, Observable, of } from 'rxjs'; import { singleColdCompleted } from '../../../test/marbles'; import { EMPTY_STRING } from '../tech.util'; import { ResourceSearchService } from './resource-search.service'; import { LinkRelationName, ListItemResource, SearchResourceServiceConfig } from './resource.model'; import { ResourceRepository } from './resource.repository'; import { ListResource, StateResource, createEmptyStateResource, createStateResource, } from './resource.util'; describe('ResourceSearchService', () => { let service: ResourceSearchService<Resource, ListResource, ListItemResource>; let config: SearchResourceServiceConfig<Resource>; let repository: Mock<ResourceRepository>; const baseResource: Resource = createDummyResource(); const baseResourceSubj: BehaviorSubject<Resource> = new BehaviorSubject<Resource>(baseResource); const searchLinkRel: LinkRelationName = DummyLinkRel.DUMMY; const listResource: ListResource = createDummyListResource(); const stateListResource: StateResource<ListResource> = createStateResource(listResource); const searchBy: string = faker.random.words(2); beforeEach(() => { config = { baseResource: baseResourceSubj, searchLinkRel, }; repository = mock(ResourceRepository); service = new ResourceSearchService(config, useFromMock(repository)); }); it('should be created', () => { expect(service).toBeTruthy(); }); describe('get result list', () => { beforeEach(() => { service.handleChanges = jest.fn(); service.listResource.next(stateListResource); service.searchBy.next(searchBy); }); it('should call handleChanges', fakeAsync(() => { service.getResultList().subscribe(); tick(); expect(service.handleChanges).toHaveBeenCalledWith(stateListResource, searchBy, baseResource); })); it('should return value', (done) => { service.getResultList().subscribe((resultList) => { expect(resultList).toBe(stateListResource); done(); }); }); }); describe('handle changes', () => { it('should call doSearch on loading flag', () => { service.doSearch = jest.fn(); service.handleChanges({ ...stateListResource, loading: true }, searchBy, baseResource); expect(service.doSearch).toHaveBeenCalledWith(searchBy, baseResource); }); it('should NOT call doSearch on loading flag false', () => { service.doSearch = jest.fn(); service.handleChanges({ ...stateListResource, loading: false }, searchBy, baseResource); expect(service.doSearch).not.toHaveBeenCalled(); }); }); describe('do search', () => { beforeEach(() => { service.dispatchSearch = jest.fn(); }); describe('on existing searchBy', () => { it('should call dispatchSearch', () => { service.doSearch(searchBy, baseResource); expect(service.dispatchSearch).toHaveBeenCalledWith(baseResource, searchLinkRel, searchBy); }); it('should NOT clear list resource', () => { service.listResource.next(stateListResource); service.doSearch(searchBy, baseResource); expect(service.listResource.value).toBe(stateListResource); }); }); describe('on empty searchBy', () => { it('should clear list resource', () => { service.listResource.next(stateListResource); service.doSearch(EMPTY_STRING, baseResource); expect(service.listResource.value).toEqual(createEmptyStateResource()); }); it('should NOT call dispatchSearch', () => { service.doSearch(EMPTY_STRING, baseResource); expect(service.dispatchSearch).not.toHaveBeenCalled(); }); }); }); describe('dispatch search', () => { beforeEach(() => { repository.search.mockReturnValue(of(listResource)); }); it('should call respository', () => { service.dispatchSearch(baseResource, searchLinkRel, searchBy); expect(repository.search).toHaveBeenCalledWith(baseResource, searchLinkRel, searchBy); }); it('should update list resource', () => { service.listResource.next(createEmptyStateResource()); service.dispatchSearch(baseResource, searchLinkRel, searchBy); expect(service.listResource.value).toEqual(createStateResource(listResource)); }); }); describe('clear search list', () => { it('should call dispatchClearSearch listResource by given result', () => { service.listResource.next(stateListResource); service.clearResultList(); expect(service.listResource.value).toEqual(createEmptyStateResource()); }); }); describe('saerch', () => { it('should set searchBy', () => { service.search(searchBy); expect(service.searchBy.value).toEqual(searchBy); }); it('should set list resource loading', () => { service.listResource.next(stateListResource); service.search(searchBy); expect(service.listResource.value).toEqual({ ...stateListResource, loading: true }); }); }); describe('get selected', () => { const dummyResource: Resource = createDummyResource(); it('should return selected resource', () => { service.getSelectedResult = jest.fn().mockReturnValue(of(dummyResource)); const selectedResult$: Observable<Resource> = service.getSelectedResult(); expect(selectedResult$).toBeObservable(singleColdCompleted(dummyResource)); }); }); describe('select result', () => { const dummyResource: Resource = createDummyResource(); it('should update selected resource', () => { service.selectedResource.next(null); service.selectResult(dummyResource); expect(service.selectedResource.value).toEqual(dummyResource); }); }); describe('clear select result', () => { const dummyResource: Resource = createDummyResource(); it('should update selected resource to null', () => { service.selectedResource.next(dummyResource); service.clearSelectedResult(); expect(service.selectedResource.value).toBeNull(); }); }); });