diff --git a/alfa-client/apps/admin/src/main.ts b/alfa-client/apps/admin/src/main.ts index e52cca37a4bb2ba62708e875a8a122f13548a2f9..bc43c6b29165f379489415815e05864069349131 100644 --- a/alfa-client/apps/admin/src/main.ts +++ b/alfa-client/apps/admin/src/main.ts @@ -21,15 +21,11 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { AggregationMappingProvider } from '@admin-client/reporting-shared'; -import { ApiRootModule } from '@alfa-client/api-root-shared'; -import { EnvironmentModule, loadEnvironment } from '@alfa-client/environment-shared'; -import { enableProdMode, importProvidersFrom } from '@angular/core'; -import { isNil } from 'lodash-es'; - import { CONFIGURATION_FEATURE_KEY, configurationReducer } from '@admin-client/configuration-shared'; import { POSTFACH_FEATURE_KEY, postfachReducer } from '@admin-client/postfach-shared'; +import { AggregationMappingProvider } from '@admin-client/reporting-shared'; import { ApiRootModule } from '@alfa-client/api-root-shared'; +import { EnvironmentModule, loadEnvironment } from '@alfa-client/environment-shared'; import { NavigationSharedModule } from '@alfa-client/navigation-shared'; import { registerLocaleData } from '@angular/common'; import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; @@ -54,10 +50,6 @@ import { ConfigurationsProviders } from 'libs/admin/configuration-shared/src/lib import { PostfachProviders } from 'libs/admin/postfach-shared/src/lib/postfach.providers'; import { SettingsProviders } from 'libs/admin/settings-shared/src/lib/settings.providers'; import { UserProviders } from 'libs/admin/user/src/lib/user.providers'; -import { - ORGANISATIONS_EINHEIT_FEATURE_KEY, - organisationsEinheitReducer, -} from '../../../libs/admin/organisations-einheit-shared/src/lib/organisations-einheit-resource.service'; import { isNil } from 'lodash-es'; import { HttpBinaryFileInterceptor } from '../../../libs/tech-shared/src/lib/interceptor/http-binary-file.interceptor'; import { HttpXsrfInterceptor } from '../../../libs/tech-shared/src/lib/interceptor/http-xsrf.interceptor'; @@ -117,7 +109,6 @@ loadEnvironment(environment.environmentUrl).then((env) => { StoreModule.forRoot({}), StoreModule.forFeature(CONFIGURATION_FEATURE_KEY, configurationReducer), StoreModule.forFeature(POSTFACH_FEATURE_KEY, postfachReducer), - StoreModule.forFeature(ORGANISATIONS_EINHEIT_FEATURE_KEY, organisationsEinheitReducer), EffectsModule.forRoot(), StoreRouterConnectingModule.forRoot(), OAuthModule.forRoot({ diff --git a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping-resource.service.ts b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping-resource.service.ts index b35ace76f241fc664783a82db59ae071bd4d9b25..8f96d053a24b8d10c4878d99dc75ce7fae2506a9 100644 --- a/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping-resource.service.ts +++ b/alfa-client/libs/admin/reporting-shared/src/lib/aggregation-mapping-resource.service.ts @@ -1,14 +1,9 @@ import { ConfigurationLinkRel, ConfigurationResource, ConfigurationService } from '@admin-client/configuration-shared'; -import { - ApiListResourceService, - ListResourceServiceConfig, - ResourceListService, - ResourceRepository, -} from '@alfa-client/tech-shared'; +import { ApiListResourceService, ListResourceServiceConfig, ResourceRepository } from '@alfa-client/tech-shared'; import { AggregationMappingListLinkRel } from './aggregation-mapping.linkrel'; import { AggregationMappingListResource, AggregationMappingResource } from './aggregation-mapping.model'; -export class AggregationMappingListResourceService extends ResourceListService< +export class AggregationMappingListResourceService extends ApiListResourceService< ConfigurationResource, AggregationMappingListResource, AggregationMappingResource diff --git a/alfa-client/libs/command-shared/src/lib/command-resource.service.spec.ts b/alfa-client/libs/command-shared/src/lib/command-resource.service.spec.ts index 99e8e1433bc00c9de2f086a1bfbfc1314cc5ae71..4eb48bcd8351237ee55966c890df0522071ca148 100644 --- a/alfa-client/libs/command-shared/src/lib/command-resource.service.spec.ts +++ b/alfa-client/libs/command-shared/src/lib/command-resource.service.spec.ts @@ -34,21 +34,12 @@ import { import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; import { Resource } from '@ngxp/rest'; import { Observable, of, take } from 'rxjs'; -import { - createCommandResource, - createCreateCommandProps, - createDoneCommandResource, -} from '../../../command-shared/test/command'; -import { multiCold, singleCold } from '../../../tech-shared/test/marbles'; +import { createCommandResource, createCreateCommandProps, createDoneCommandResource } from '../../../command-shared/test/command'; +import { multipleCold, singleCold } from '../../../tech-shared/test/marbles'; import { createDummyResource } from '../../../tech-shared/test/resource'; import { CommandResourceService } from './command-resource.service'; import { CommandLinkRel } from './command.linkrel'; -import { - CommandResource, - CreateCommandProps, - DeleteCommandProps, - SaveCommandProps, -} from './command.model'; +import { CommandResource, CreateCommandProps, DeleteCommandProps, SaveCommandProps } from './command.model'; import { CommandService } from './command.service'; import { getEffectedResourceUrl } from './command.util'; @@ -82,9 +73,7 @@ describe('CommandResourceService', () => { delete: { order: deleteOrder, linkRel: deleteLinkRel }, }; stateService = mock(StateService); - stateService.createSingleResourceService = jest - .fn() - .mockReturnValue(mock(SingleResourceStateService)); + stateService.createSingleResourceService = jest.fn().mockReturnValue(mock(SingleResourceStateService)); commandService = mock(CommandService); service = new CommandResourceService(config, useFromMock(stateService), useFromMock(commandService)); @@ -99,17 +88,12 @@ describe('CommandResourceService', () => { const dummyToSave: unknown = {}; - const commandResource: CommandResource = createCommandResource([ - CommandLinkRel.EFFECTED_RESOURCE, - ]); - const commandStateResource: StateResource<CommandResource> = - createStateResource(commandResource); + const commandResource: CommandResource = createCommandResource([CommandLinkRel.EFFECTED_RESOURCE]); + const commandStateResource: StateResource<CommandResource> = createStateResource(commandResource); beforeEach(() => { service.doSave = jest.fn().mockReturnValue(of(commandStateResource)); - service.resourceStateService.selectResource = jest - .fn() - .mockReturnValue(of(dummyStateResource)); + service.resourceStateService.selectResource = jest.fn().mockReturnValue(of(dummyStateResource)); service.loadByResourceUri = jest.fn(); }); @@ -124,20 +108,15 @@ describe('CommandResourceService', () => { it('should loadByResourceUri on sucessfully done command', () => { service.save(dummyToSave).pipe(take(FIRST_EMIT_AFTER_INITIAL_START_EMIT)).subscribe(); - expect(service.loadByResourceUri).toHaveBeenCalledWith( - getEffectedResourceUrl(commandResource), - ); + expect(service.loadByResourceUri).toHaveBeenCalledWith(getEffectedResourceUrl(commandResource)); }); it('should return initial value', () => { service.doSave = jest.fn().mockReturnValue(singleCold(commandStateResource, '-a')); - const initialResponse$: Observable<StateResource<CommandResource>> = - service.save(dummyToSave); + const initialResponse$: Observable<StateResource<CommandResource>> = service.save(dummyToSave); - expect(initialResponse$).toBeObservable( - multiCold({ a: createEmptyStateResource(true), b: commandStateResource }), - ); + expect(initialResponse$).toBeObservable(multipleCold(createEmptyStateResource(true), commandStateResource)); }); }); @@ -150,9 +129,7 @@ describe('CommandResourceService', () => { let buildSaveCommandPropsSpy: jest.SpyInstance; beforeEach(() => { - buildSaveCommandPropsSpy = service.buildSaveCommandProps = jest - .fn() - .mockReturnValue(createCommandProps); + buildSaveCommandPropsSpy = service.buildSaveCommandProps = jest.fn().mockReturnValue(createCommandProps); }); it('should call command service', () => { @@ -164,11 +141,7 @@ describe('CommandResourceService', () => { it('should build command', () => { service.doSave(dummyResource, dummyToSave, saveCommandProps); - expect(buildSaveCommandPropsSpy).toHaveBeenCalledWith( - dummyResource, - dummyToSave, - saveCommandProps, - ); + expect(buildSaveCommandPropsSpy).toHaveBeenCalledWith(dummyResource, dummyToSave, saveCommandProps); }); }); @@ -224,14 +197,11 @@ describe('CommandResourceService', () => { const FIRST_EMIT_AFTER_INITIAL_START_EMIT: number = 2; const commandResource: CommandResource = createDoneCommandResource(); - const commandStateResource: StateResource<CommandResource> = - createStateResource(commandResource); + const commandStateResource: StateResource<CommandResource> = createStateResource(commandResource); beforeEach(() => { service.doDelete = jest.fn().mockReturnValue(of(commandStateResource)); - service.resourceStateService.selectResource = jest - .fn() - .mockReturnValue(of(dummyStateResource)); + service.resourceStateService.selectResource = jest.fn().mockReturnValue(of(dummyStateResource)); service.clearResource = jest.fn(); }); @@ -254,9 +224,7 @@ describe('CommandResourceService', () => { const initialResponse$: Observable<StateResource<CommandResource>> = service.delete(); - expect(initialResponse$).toBeObservable( - multiCold({ a: createEmptyStateResource(true), b: commandStateResource }), - ); + expect(initialResponse$).toBeObservable(multipleCold(createEmptyStateResource(true), commandStateResource)); }); }); @@ -268,9 +236,7 @@ describe('CommandResourceService', () => { let buildDeleteCommandPropsSpy: jest.SpyInstance; beforeEach(() => { - buildDeleteCommandPropsSpy = service.buildDeleteCommandProps = jest - .fn() - .mockReturnValue(createCommandProps); + buildDeleteCommandPropsSpy = service.buildDeleteCommandProps = jest.fn().mockReturnValue(createCommandProps); }); it('should call command service', () => { @@ -291,48 +257,33 @@ describe('CommandResourceService', () => { const deleteCommandProps: SaveCommandProps = { snackBarMessage: EMPTY_STRING }; it('should have resource', () => { - const props: CreateCommandProps = service.buildDeleteCommandProps( - resource, - deleteCommandProps, - ); + const props: CreateCommandProps = service.buildDeleteCommandProps(resource, deleteCommandProps); expect(props.resource).toBe(resource); }); it('should have linkRel', () => { - const props: CreateCommandProps = service.buildDeleteCommandProps( - resource, - deleteCommandProps, - ); + const props: CreateCommandProps = service.buildDeleteCommandProps(resource, deleteCommandProps); expect(props.linkRel).toBe(deleteLinkRel); }); describe('command', () => { it('should have order', () => { - const props: CreateCommandProps = service.buildDeleteCommandProps( - resource, - deleteCommandProps, - ); + const props: CreateCommandProps = service.buildDeleteCommandProps(resource, deleteCommandProps); expect(props.command.order).toBe(deleteOrder); }); it('should have body', () => { - const props: CreateCommandProps = service.buildDeleteCommandProps( - resource, - deleteCommandProps, - ); + const props: CreateCommandProps = service.buildDeleteCommandProps(resource, deleteCommandProps); expect(props.command.body).toBeNull(); }); }); it('should have snackBarMessage', () => { - const props: CreateCommandProps = service.buildDeleteCommandProps( - resource, - deleteCommandProps, - ); + const props: CreateCommandProps = service.buildDeleteCommandProps(resource, deleteCommandProps); expect(props.snackBarMessage).toBe(deleteCommandProps.snackBarMessage); }); diff --git a/alfa-client/libs/tech-shared/src/lib/resource/api-list-resource.service.spec.ts b/alfa-client/libs/tech-shared/src/lib/resource/api-list-resource.service.spec.ts index c32be68df5eba0d5728116ccd8da3a616132fb8c..87451e3301ee1530a3e6a5ecda5dac37d179d979 100644 --- a/alfa-client/libs/tech-shared/src/lib/resource/api-list-resource.service.spec.ts +++ b/alfa-client/libs/tech-shared/src/lib/resource/api-list-resource.service.spec.ts @@ -2,22 +2,12 @@ import { mock, Mock, useFromMock } from '@alfa-client/test-utils'; import { Resource } from '@ngxp/rest'; import { BehaviorSubject, Observable } from 'rxjs'; import { DummyLinkRel, DummyListLinkRel } from '../../../test/dummy'; -import { singleCold, singleHot } from '../../../test/marbles'; +import { multipleCold, singleCold } from '../../../test/marbles'; import { createDummyListResource, createDummyResource } from '../../../test/resource'; import { ApiListResourceService } from './api-list-resource.service'; -import { - CreateResourceData, - LinkRelationName, - ListItemResource, - ListResourceServiceConfig, -} from './resource.model'; +import { CreateResourceData, LinkRelationName, ListItemResource, ListResourceServiceConfig } from './resource.model'; import { ResourceRepository } from './resource.repository'; -import { - createEmptyStateResource, - createStateResource, - ListResource, - StateResource, -} from './resource.util'; +import { createEmptyStateResource, createStateResource, ListResource, StateResource } from './resource.util'; describe('ListResourceService', () => { let service: ApiListResourceService<Resource, ListResource, ListItemResource>; @@ -31,9 +21,9 @@ describe('ListResourceService', () => { const baseResource: Resource = createDummyResource(); const baseStateResource: StateResource<Resource> = createStateResource(baseResource); - const baseResourceSubj: BehaviorSubject<StateResource<Resource>> = new BehaviorSubject< - StateResource<Resource> - >(baseStateResource); + const baseResourceSubj: BehaviorSubject<StateResource<Resource>> = new BehaviorSubject<StateResource<Resource>>( + baseStateResource, + ); beforeEach(() => { config = { baseResource: baseResourceSubj, @@ -82,11 +72,14 @@ describe('ListResourceService', () => { it('should return value', () => { const returnResource: Resource = createDummyResource(); - resourceRepository.createResource.mockReturnValue(singleHot(returnResource)); - const createdResource: Observable<Resource> = service.create(toCreate); + resourceRepository.createResource.mockReturnValue(singleCold(returnResource, '-a')); - expect(createdResource).toBeObservable(singleCold(returnResource)); + const createdStateResource$: Observable<StateResource<Resource>> = service.create(toCreate); + + expect(createdStateResource$).toBeObservable( + multipleCold(createEmptyStateResource(true), createStateResource(returnResource)), + ); }); }); }); diff --git a/alfa-client/libs/tech-shared/src/lib/resource/api-list-resource.service.ts b/alfa-client/libs/tech-shared/src/lib/resource/api-list-resource.service.ts index 4fd970d0011d9f05d1977beec3021c27ece66edc..03d1d46175587de5bc958432a570c4e6d32c3081 100644 --- a/alfa-client/libs/tech-shared/src/lib/resource/api-list-resource.service.ts +++ b/alfa-client/libs/tech-shared/src/lib/resource/api-list-resource.service.ts @@ -1,9 +1,9 @@ import { Resource } from '@ngxp/rest'; -import { first, Observable, switchMap } from 'rxjs'; +import { first, map, Observable, startWith, switchMap } from 'rxjs'; import { ResourceListService } from './list-resource.service'; import { CreateResourceData, ListItemResource, ListResourceServiceConfig } from './resource.model'; import { ResourceRepository } from './resource.repository'; -import { ListResource, StateResource } from './resource.util'; +import { createEmptyStateResource, createStateResource, ListResource, StateResource } from './resource.util'; export class ApiListResourceService< B extends Resource, @@ -17,13 +17,15 @@ export class ApiListResourceService< super(config, repository); } - public create(toCreate: unknown): Observable<Resource> { + public create(toCreate: unknown): Observable<StateResource<I>> { this.verifyBeforeCreation(); return this.getListResourceAsObservable().pipe( first(), switchMap((listResource: StateResource<T>) => this.repository.createResource(this.buildCreateResourceData(toCreate, this.config.create.linkRel, listResource.resource)), ), + map((listItemResource: I) => createStateResource(listItemResource)), + startWith(createEmptyStateResource<I>(true)), ); } diff --git a/alfa-client/libs/tech-shared/src/lib/resource/api-resource.service.spec.ts b/alfa-client/libs/tech-shared/src/lib/resource/api-resource.service.spec.ts index 9de7cebb347ca8fcafca82a488ba3aefd28f7f1b..49ab4f50dfcf4c49712640d825b303224b3e1682 100644 --- a/alfa-client/libs/tech-shared/src/lib/resource/api-resource.service.spec.ts +++ b/alfa-client/libs/tech-shared/src/lib/resource/api-resource.service.spec.ts @@ -26,7 +26,7 @@ import { HttpErrorResponse } from '@angular/common/http'; import { fakeAsync, tick } from '@angular/core/testing'; import { Resource } from '@ngxp/rest'; import { lastValueFrom, Observable, of, throwError } from 'rxjs'; -import { multiCold, singleCold } from '../../../test//marbles'; +import { multipleCold, singleCold } from '../../../test//marbles'; import { createProblemDetail } from '../../../test/error'; import { createDummyResource } from '../../../test/resource'; import { SingleResourceStateService, StateService } from '../ngrx/state.service'; @@ -100,7 +100,7 @@ describe('ApiResourceService', () => { const saved$: Observable<StateResource<Resource | HttpError>> = service.save(dummyToSave); - expect(saved$).toBeObservable(multiCold({ a: createEmptyStateResource(true), b: createStateResource(loadedResource) })); + expect(saved$).toBeObservable(multipleCold(createEmptyStateResource(true), createStateResource(loadedResource))); }); it('should call handleError', () => { @@ -144,7 +144,7 @@ describe('ApiResourceService', () => { const patchd$: Observable<StateResource<Resource | HttpError>> = service.patch(dummyToSave); - expect(patchd$).toBeObservable(multiCold({ a: createEmptyStateResource(true), b: createStateResource(loadedResource) })); + expect(patchd$).toBeObservable(multipleCold(createEmptyStateResource(true), createStateResource(loadedResource))); }); it('should call handleError', () => { diff --git a/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.spec.ts b/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.spec.ts index f3d2812811186696aae4bfc0529d4fe9f81b8ae3..e3fddaee393189b9f81f8c0d0ee0a4a5c3f5ecf2 100644 --- a/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.spec.ts +++ b/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.spec.ts @@ -28,7 +28,6 @@ import { Resource, ResourceUri } from '@ngxp/rest'; import { DummyLinkRel, DummyListLinkRel } from 'libs/tech-shared/test/dummy'; import { createDummyListResource, createDummyResource, createFilledDummyListResource } from 'libs/tech-shared/test/resource'; import { BehaviorSubject, of } from 'rxjs'; -import { EMPTY_ARRAY } from '../tech.util'; import { ResourceListService } from './list-resource.service'; import { LinkRelationName, ListItemResource, ListResourceServiceConfig } from './resource.model'; import { ResourceRepository } from './resource.repository'; @@ -83,14 +82,14 @@ describe('ListResourceService', () => { it('should handle config resource changed', fakeAsync(() => { service.getList().subscribe(); - tick(); + tick(50); expect(service.handleChanges).toHaveBeenCalledWith(listStateResource, baseResource); })); it('should call isInvalidResourceCombinationSpy', fakeAsync(() => { service.getList().subscribe(); - tick(); + tick(50); expect(isInvalidResourceCombinationSpy).toHaveBeenCalled(); })); @@ -488,7 +487,7 @@ describe('ListResourceService', () => { service.getList = jest.fn().mockReturnValue(of(createEmptyStateResource())); service.getItems().subscribe((items) => { - expect(items).toEqual(EMPTY_ARRAY); + expect(items).toEqual([]); done(); }); }); @@ -518,7 +517,7 @@ class DummyListResourceService< > extends ResourceListService<B, T, I> { constructor( protected config: ListResourceServiceConfig<B>, - protected repository: ResourceRepository, + protected repository: ResourceRepository<I>, ) { super(config, repository); }