import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; import { fakeAsync, tick } from '@angular/core/testing'; import faker from '@faker-js/faker'; import { Resource, getUrl } from '@ngxp/rest'; import { BehaviorSubject, of } from 'rxjs'; import { DummyResourceService, createDummyResource } from '../../../test/resource'; import { LinkRelationName, ResourceServiceConfig } from './resource.model'; import { ResourceRepository } from './resource.repository'; import { StateResource, createEmptyStateResource, createStateResource } from './resource.util'; describe.skip('FIXME: mocking.ts issue due to module test | ResourceService ITCase', () => { let service: DummyResourceService<Resource, Resource>; let config: ResourceServiceConfig<Resource>; let repository: Mock<ResourceRepository>; const getLinkRel: LinkRelationName = faker.random.word(); const editLinkRel: LinkRelationName = faker.random.word(); const deleteLinkRel: LinkRelationName = faker.random.word(); const configResource: Resource = createDummyResource([getLinkRel, editLinkRel]); const configStateResource: StateResource<Resource> = createStateResource(configResource); const configResourceSubj: BehaviorSubject<StateResource<Resource>> = new BehaviorSubject< StateResource<Resource> >(configStateResource); const loadedResource: Resource = createDummyResource([getLinkRel, editLinkRel]); const EXPECTED_EMITTED_TIMES_FOR_GET: number = 3; beforeEach(() => { config = { resource: configResourceSubj, getLinkRel, edit: { linkRel: editLinkRel }, delete: { linkRel: deleteLinkRel }, }; repository = mock(ResourceRepository); service = new DummyResourceService<Resource, Resource>(config, useFromMock(repository)); repository.getResource.mockReturnValueOnce(of(loadedResource)); service.stateResource.next(createEmptyStateResource()); }); describe('get', () => { it('should emit initially loading stateResource', (done) => { let emittedTimes: number = 0; service.get().subscribe((response: StateResource<Resource>) => { emittedTimes++; if (emittedTimes === 1) { console.info('RESPONSE 1: ', response); expect(response.loading).toBeTruthy(); expect(response.resource).toBeNull(); done(); } }); }); it('should emit loading stateResource', (done) => { let emittedTimes: number = 0; service.get().subscribe((response: StateResource<Resource>) => { emittedTimes++; if (emittedTimes === 2) { expect(response.loading).toBeTruthy(); expect(response.resource).toBeNull(); done(); } }); }); it('should emit loaded stateResource', (done) => { let emittedTimes: number = 0; service.get().subscribe((response: StateResource<Resource>) => { emittedTimes++; if (emittedTimes === EXPECTED_EMITTED_TIMES_FOR_GET) { expect(repository.getResource).toHaveBeenCalledWith(getUrl(configResource, getLinkRel)); expect(response.resource).toBe(loadedResource); expect(response.loading).toBeFalsy(); done(); } }); }); it('should emit 3 times', async () => { let emittedTimes: number = 0; service.get().subscribe((response) => { emittedTimes++; console.info('RESPONSE ON GET: ', response); }); console.info('EMITTED TIMES: ', emittedTimes); expect(emittedTimes).toBe(EXPECTED_EMITTED_TIMES_FOR_GET); }); }); describe('get - change configResource', () => { const reloadedResource: Resource = createDummyResource(); const EXPECTED_EMITTED_TIMES: number = EXPECTED_EMITTED_TIMES_FOR_GET + 2; const newConfigResource: Resource = createDummyResource([deleteLinkRel, getLinkRel]); const newConfigStateResource: StateResource<Resource> = createStateResource(newConfigResource); beforeEach(() => { repository.getResource.mockReturnValueOnce(of(reloadedResource)); }); it('should emit loading stateResource', (done) => { let emittedTimes: number = 0; service.get().subscribe((response: StateResource<Resource>) => { emittedTimes++; doAfterGetIsDone(emittedTimes, () => configResourceSubj.next(newConfigStateResource)); if (emittedTimes === 4) { expect(response.loading).toBeTruthy(); expect(response.resource).toBeNull(); done(); } }); }); it.skip('should emit reloaded stateResource', (done) => { let emittedTimes: number = 0; service.get().subscribe((response: StateResource<Resource>) => { emittedTimes++; doAfterGetIsDone(emittedTimes, () => configResourceSubj.next(newConfigStateResource)); if (emittedTimes === EXPECTED_EMITTED_TIMES) { expect(repository.getResource).toHaveBeenCalledTimes(2); expect(repository.getResource).toHaveBeenCalledWith(getUrl(configResource, getLinkRel)); expect(repository.getResource).toHaveBeenCalledWith( getUrl(newConfigResource, getLinkRel), ); expect(response.resource).toBe(reloadedResource); expect(response.loading).toBeFalsy(); done(); } }); }); it.skip('should emit 5 times', fakeAsync(async () => { let emittedTimes: number = 0; service.get().subscribe((response) => { emittedTimes++; console.info('RESPONSE ON GET: ', response); doAfterGetIsDone(emittedTimes, () => configResourceSubj.next(newConfigStateResource)); }); tick(); console.info('EMITTED TIMES: ', emittedTimes); expect(emittedTimes).toBe(EXPECTED_EMITTED_TIMES); })); }); describe('get - change configResource to null', () => { const EXPECTED_EMITTED_TIMES_FOR_GET: number = 3; const EXPECTED_EMITTED_TIMES: number = EXPECTED_EMITTED_TIMES_FOR_GET + 1; const emptyConfigStateResource: StateResource<Resource> = createEmptyStateResource(); it('should emit empty stateResource', (done) => { let emittedTimes: number = 0; service.get().subscribe((response: StateResource<Resource>) => { emittedTimes++; doAfterGetIsDone(emittedTimes, () => configResourceSubj.next(emptyConfigStateResource)); if (emittedTimes === EXPECTED_EMITTED_TIMES) { expect(response.loading).toBeFalsy(); expect(response.resource).toBeNull(); done(); } }); }); it('should emit 4 times', fakeAsync(async () => { let emittedTimes: number = 0; service.get().subscribe(() => { emittedTimes++; doAfterGetIsDone(emittedTimes, () => configResourceSubj.next(emptyConfigStateResource)); }); tick(); expect(emittedTimes).toBe(EXPECTED_EMITTED_TIMES); })); }); describe.skip('FIXME (Funktioniert nicht mit den anderen Tests zusammen) refresh', () => { const reloadedResource: Resource = createDummyResource(); const EXPECTED_EMITTED_TIMES_FOR_GET: number = 3; const EXPECTED_EMITTED_TIMES: number = EXPECTED_EMITTED_TIMES_FOR_GET + 2; beforeEach(() => { repository.getResource.mockReturnValueOnce(of(reloadedResource)); }); it('should return loading stateResource', (done) => { let emittedTimes: number = 0; service.get().subscribe((response: StateResource<Resource>) => { emittedTimes++; doAfterGetIsDone(emittedTimes, () => service.refresh()); if (emittedTimes === 4) { expect(repository.getResource).toHaveBeenCalledWith(getUrl(configResource, getLinkRel)); expect(response.loading).toBeTruthy(); done(); } }); }); it('should return reloaded stateResource', (done) => { let emittedTimes: number = 0; service.get().subscribe((response: StateResource<Resource>) => { emittedTimes++; doAfterGetIsDone(emittedTimes, () => service.refresh()); if (emittedTimes === EXPECTED_EMITTED_TIMES) { expect(response.resource).toBe(reloadedResource); expect(response.loading).toBeFalsy(); done(); } }); }); it('should emit 5 times', fakeAsync(async () => { let emittedTimes: number = 0; service.get().subscribe(() => { emittedTimes++; doAfterGetIsDone(emittedTimes, () => service.refresh()); }); tick(); expect(emittedTimes).toBe(EXPECTED_EMITTED_TIMES); })); }); function doAfterGetIsDone(emittedTimes: number, runnable: () => void): void { if (emittedTimes === EXPECTED_EMITTED_TIMES_FOR_GET) { runnable(); } } });