Skip to content
Snippets Groups Projects
Commit 289d0c62 authored by OZGCloud's avatar OZGCloud
Browse files

OZG-5012 fix imports; split save/delete

parent 40ca81fa
No related branches found
No related tags found
No related merge requests found
Showing
with 143 additions and 33 deletions
...@@ -123,14 +123,13 @@ export class BescheidService { ...@@ -123,14 +123,13 @@ export class BescheidService {
return { return {
resource: this.vorgangService.getVorgangWithEingang(), resource: this.vorgangService.getVorgangWithEingang(),
getLinkRel: VorgangWithEingangLinkRel.BESCHEID_DRAFT, getLinkRel: VorgangWithEingangLinkRel.BESCHEID_DRAFT,
editLinkRel: null, delete: { linkRel: BescheidLinkRel.DELETE, order: CommandOrder.DELETE_BESCHEID },
}; };
} }
buildBescheidListServiceConfig(): ListResourceServiceConfig<VorgangWithEingangResource> { buildBescheidListServiceConfig(): ListResourceServiceConfig<VorgangWithEingangResource> {
return { return {
baseResource: this.vorgangService.getVorgangWithEingang(), baseResource: this.vorgangService.getVorgangWithEingang(),
createLinkRel: null,
listLinkRel: VorgangWithEingangLinkRel.BESCHEIDE, listLinkRel: VorgangWithEingangLinkRel.BESCHEIDE,
}; };
} }
......
import { CommandResource, CreateCommand } from '@alfa-client/command-shared';
import { import {
ApiError, ApiError,
createEmptyStateResource, createEmptyStateResource,
...@@ -8,14 +7,15 @@ import { ...@@ -8,14 +7,15 @@ import {
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { Action } from '@ngrx/store'; import { Action } from '@ngrx/store';
import { Resource, ResourceUri } from '@ngxp/rest'; import { Resource, ResourceUri } from '@ngxp/rest';
import { createCommandResource, createCreateCommand } from 'libs/command-shared/test/command'; import { createApiError, createHttpErrorResponse } from '../../../../tech-shared/test/error';
import { createApiError, createHttpErrorResponse } from 'libs/tech-shared/test/error'; import { createDummyResource } from '../../../../tech-shared/test/resource';
import { createDummyResource } from 'libs/tech-shared/test/resource'; import { createCommandResource, createCreateCommand } from '../../../test/command';
import { CommandResource, CreateCommand } from '../command.model';
import { CommandState, initialState, reducer } from './command.reducer'; import { CommandState, initialState, reducer } from './command.reducer';
import faker from '@faker-js/faker'; import faker from '@faker-js/faker';
import * as CommandActions from '@alfa-client/command-shared'; import * as CommandActions from '../+state/command.actions';
describe('Command Reducer', () => { describe('Command Reducer', () => {
describe('unknown action', () => { describe('unknown action', () => {
......
import { CommandOrder } from '@alfa-client/command-shared';
import { createEmptyStateResource } from '@alfa-client/tech-shared'; import { createEmptyStateResource } from '@alfa-client/tech-shared';
import { MemoizedSelector, createFeatureSelector, createSelector } from '@ngrx/store'; import { MemoizedSelector, createFeatureSelector, createSelector } from '@ngrx/store';
import { isUndefined } from 'lodash-es'; import { isUndefined } from 'lodash-es';
import { CommandOrder } from '../command.model';
import { COMMAND_FEATURE_KEY, CommandState } from './command.reducer'; import { COMMAND_FEATURE_KEY, CommandState } from './command.reducer';
const getCommandState: MemoizedSelector<object, CommandState> = const getCommandState: MemoizedSelector<object, CommandState> =
......
...@@ -36,7 +36,7 @@ describe('CommandResourceService', () => { ...@@ -36,7 +36,7 @@ describe('CommandResourceService', () => {
config = { config = {
resource: configStateResource$, resource: configStateResource$,
getLinkRel, getLinkRel,
editLinkRel, edit: { linkRel: editLinkRel },
delete: { order: deleteOrder, linkRel: deleteLinkRel }, delete: { order: deleteOrder, linkRel: deleteLinkRel },
}; };
repository = mock(ResourceRepository); repository = mock(ResourceRepository);
......
...@@ -27,6 +27,10 @@ export class CommandResourceService<B extends Resource, T extends Resource> exte ...@@ -27,6 +27,10 @@ export class CommandResourceService<B extends Resource, T extends Resource> exte
super(config, repository); super(config, repository);
} }
doSave(resource: T, toSave: unknown): Observable<T> {
throw new Error('Method not implemented.');
}
public delete(): Observable<StateResource<CommandResource>> { public delete(): Observable<StateResource<CommandResource>> {
this.verifyDeleteLinkRel(); this.verifyDeleteLinkRel();
return this.commandService.createCommandByProps(this.buildDeleteCommandProps()); return this.commandService.createCommandByProps(this.buildDeleteCommandProps());
......
import { EMPTY_STRING } from '../lib/tech.util';
import { createAriaLabelForIconButton } from './assistive-technologies.util'; import { createAriaLabelForIconButton } from './assistive-technologies.util';
import { EMPTY_STRING } from '@alfa-client/tech-shared';
describe('createAriaLabelForIconButton', () => { describe('createAriaLabelForIconButton', () => {
const tooltip = 'Tooltip text'; const tooltip = 'Tooltip text';
......
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
* Die sprachspezifischen Genehmigungen und Beschränkungen * Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen. * unter der Lizenz sind dem Lizenztext zu entnehmen.
*/ */
import { CatchHttpError } from '@alfa-client/tech-shared';
import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; import { Mock, mock, useFromMock } from '@alfa-client/test-utils';
import { CatchHttpError } from '../decorator/catch-http-error.decorator';
import { HttpErrorHandler } from '../error/error.handler'; import { HttpErrorHandler } from '../error/error.handler';
import { import {
catchHttpErrorHandleErrorResponse, catchHttpErrorHandleErrorResponse,
......
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
* Die sprachspezifischen Genehmigungen und Beschränkungen * Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen. * unter der Lizenz sind dem Lizenztext zu entnehmen.
*/ */
import { HttpErrorHandler } from '@alfa-client/tech-shared';
import { finalize } from 'rxjs/operators'; import { finalize } from 'rxjs/operators';
import { HttpErrorHandler } from '../error/error.handler';
import { import {
disableInterceptorDefaultHandling, disableInterceptorDefaultHandling,
enableInterceptorDefaultHandling, enableInterceptorDefaultHandling,
......
...@@ -29,9 +29,9 @@ import { ...@@ -29,9 +29,9 @@ import {
HttpXsrfTokenExtractor, HttpXsrfTokenExtractor,
} from '@angular/common/http'; } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { addRequestHeader, isNotNull } from '@alfa-client/tech-shared';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { existRequestHeader, isChangingDataRequest } from '../http.util'; import { addRequestHeader, existRequestHeader, isChangingDataRequest } from '../http.util';
import { isNotNull } from '../tech.util';
@Injectable() @Injectable()
export class HttpXsrfInterceptor implements HttpInterceptor { export class HttpXsrfInterceptor implements HttpInterceptor {
......
import { Mock, mock, useFromMock } from '@alfa-client/test-utils'; import { Mock, mock, useFromMock } from '@alfa-client/test-utils';
import { Observable, of } from 'rxjs'; import { fakeAsync, tick } from '@angular/core/testing';
import { Resource } from '@ngxp/rest'; import { Resource } from '@ngxp/rest';
import { createDummyResource } from 'libs/tech-shared/test/resource'; import { createProblemDetail } from 'libs/tech-shared/test/error';
import { Observable, of, throwError } from 'rxjs';
import { singleCold, singleHot } from '../../../test//marbles';
import { createDummyResource } from '../../../test/resource';
import { HttpError, ProblemDetail } from '../tech.model';
import { ApiResourceService } from './api-resource.service'; import { ApiResourceService } from './api-resource.service';
import { LinkRelationName, ResourceServiceConfig } from './resource.model'; import { LinkRelationName, ResourceServiceConfig, SaveResourceData } from './resource.model';
import { ResourceRepository } from './resource.repository'; import { ResourceRepository } from './resource.repository';
import { StateResource, createStateResource } from './resource.util'; import { StateResource, createStateResource } from './resource.util';
...@@ -18,12 +22,14 @@ describe('ApiResourceService', () => { ...@@ -18,12 +22,14 @@ describe('ApiResourceService', () => {
const editLinkRel: string = 'dummyEditLinkRel'; const editLinkRel: string = 'dummyEditLinkRel';
const getLinkRel: LinkRelationName = 'dummyGetLinkRel'; const getLinkRel: LinkRelationName = 'dummyGetLinkRel';
const deleteLinkRel: LinkRelationName = 'dummyDeleteLinkRel';
beforeEach(() => { beforeEach(() => {
config = { config = {
resource: configStateResource$, resource: configStateResource$,
getLinkRel, getLinkRel,
editLinkRel, edit: { linkRel: editLinkRel },
delete: { linkRel: deleteLinkRel },
}; };
repository = mock(ResourceRepository); repository = mock(ResourceRepository);
...@@ -33,4 +39,97 @@ describe('ApiResourceService', () => { ...@@ -33,4 +39,97 @@ describe('ApiResourceService', () => {
it('should be created', () => { it('should be created', () => {
expect(service).toBeTruthy(); expect(service).toBeTruthy();
}); });
describe('save', () => {
const dummyToSave: unknown = {};
const loadedResource: Resource = createDummyResource();
const resourceWithEditLinkRel: Resource = createDummyResource([editLinkRel]);
it('should throw error if edit link not exists', () => {
service.stateResource.next(createStateResource(createDummyResource()));
expect(() => service.save(dummyToSave)).toThrowError(
'No edit link exists on current stateresource.',
);
});
it('should call repository', fakeAsync(() => {
service.stateResource.next(createStateResource(resourceWithEditLinkRel));
repository.save.mockReturnValue(of(loadedResource));
service.save(dummyToSave).subscribe();
tick();
const expectedSaveResourceData: SaveResourceData<Resource> = {
resource: resourceWithEditLinkRel,
linkRel: editLinkRel,
toSave: dummyToSave,
};
expect(repository.save).toHaveBeenCalledWith(expectedSaveResourceData);
}));
it('should return saved object', () => {
service.stateResource.next(createStateResource(resourceWithEditLinkRel));
repository.save.mockReturnValue(singleHot(loadedResource));
const saved: Observable<StateResource<Resource | HttpError>> = service.save(dummyToSave);
expect(saved).toBeObservable(singleCold(createStateResource(loadedResource)));
});
it('should call handleError', () => {
service.stateResource.next(createStateResource(createDummyResource([config.edit.linkRel])));
const errorResponse: ProblemDetail = createProblemDetail();
repository.save.mockReturnValue(throwError(() => errorResponse));
service.handleError = jest.fn();
service.save(<any>{}).subscribe();
expect(service.handleError).toHaveBeenCalledWith(errorResponse);
});
it('should update state resource subject', fakeAsync(() => {
service.stateResource.next(createStateResource(resourceWithEditLinkRel));
repository.save.mockReturnValue(of(loadedResource));
service.save(dummyToSave).subscribe();
tick();
expect(service.stateResource.value).toEqual(createStateResource(loadedResource));
}));
});
describe('delete', () => {
const resourceWithDeleteLinkRel: Resource = createDummyResource([deleteLinkRel]);
const stateResourceWithDeleteLink: StateResource<Resource> =
createStateResource(resourceWithDeleteLinkRel);
beforeEach(() => {
service.stateResource.next(stateResourceWithDeleteLink);
});
it('should throw error if delete linkRel not exists on current stateresource', () => {
service.stateResource.next(createStateResource(createDummyResource()));
expect(() => service.delete()).toThrowError(
'No delete link exists on current stateresource.',
);
});
it('should call repository', () => {
service.delete();
expect(repository.delete).toHaveBeenCalledWith(resourceWithDeleteLinkRel, deleteLinkRel);
});
it('should return value', () => {
const deleteResource: Resource = createDummyResource();
repository.delete.mockReturnValue(singleHot(deleteResource));
const deletedResource: Observable<Resource> = service.delete();
expect(deletedResource).toBeObservable(singleCold(deleteResource));
});
});
}); });
import { Resource } from '@ngxp/rest'; import { Resource } from '@ngxp/rest';
import { Observable } from 'rxjs';
import { ResourceServiceConfig } from './resource.model'; import { ResourceServiceConfig } from './resource.model';
import { ResourceRepository } from './resource.repository'; import { ResourceRepository } from './resource.repository';
import { ResourceService } from './resource.service'; import { ResourceService } from './resource.service';
...@@ -13,4 +14,17 @@ export class ApiResourceService<B extends Resource, T extends Resource> extends ...@@ -13,4 +14,17 @@ export class ApiResourceService<B extends Resource, T extends Resource> extends
) { ) {
super(config, repository); super(config, repository);
} }
doSave(resource: T, toSave: unknown): Observable<T> {
return <Observable<T>>this.repository.save({
resource,
linkRel: this.config.edit.linkRel,
toSave,
});
}
public delete(): Observable<Resource> {
this.verifyDeleteLinkRel();
return this.repository.delete(this.getResource(), this.config.delete.linkRel);
}
} }
...@@ -5,7 +5,7 @@ import { StateResource } from './resource.util'; ...@@ -5,7 +5,7 @@ import { StateResource } from './resource.util';
export interface ListResourceServiceConfig<B> { export interface ListResourceServiceConfig<B> {
baseResource: Observable<StateResource<B>>; baseResource: Observable<StateResource<B>>;
listLinkRel: LinkRelationName; listLinkRel: LinkRelationName;
createLinkRel: LinkRelationName; createLinkRel?: LinkRelationName;
} }
export interface CreateResourceData<T> { export interface CreateResourceData<T> {
...@@ -26,6 +26,6 @@ export declare type LinkRelationName = string; ...@@ -26,6 +26,6 @@ export declare type LinkRelationName = string;
export interface ResourceServiceConfig<B> { export interface ResourceServiceConfig<B> {
resource: Observable<StateResource<B>>; resource: Observable<StateResource<B>>;
getLinkRel: LinkRelationName; getLinkRel: LinkRelationName;
editLinkRel: LinkRelationName; delete?: { linkRel: LinkRelationName; order?: string };
delete?: { order: string; linkRel: string }; edit?: { linkRel: LinkRelationName; order?: string };
} }
...@@ -22,25 +22,19 @@ ...@@ -22,25 +22,19 @@
* unter der Lizenz sind dem Lizenztext zu entnehmen. * unter der Lizenz sind dem Lizenztext zu entnehmen.
*/ */
import {
containsLoading,
createErrorStateResource,
EMPTY_ARRAY,
getSuccessfullyLoaded,
StateResource,
} from '@alfa-client/tech-shared';
import { Resource } from '@ngxp/rest'; import { Resource } from '@ngxp/rest';
import {
createDummyListResource,
createDummyResource,
toResource,
} from 'libs/tech-shared/test/resource';
import { DummyListLinkRel } from '../../../test/dummy'; import { DummyListLinkRel } from '../../../test/dummy';
import { createApiError } from '../../../test/error'; import { createApiError } from '../../../test/error';
import { createDummyListResource, createDummyResource, toResource } from '../../../test/resource';
import { EMPTY_ARRAY } from '../tech.util';
import { import {
StateResource,
containsLoading,
createEmptyStateResource, createEmptyStateResource,
createErrorStateResource,
createStateResource, createStateResource,
getEmbeddedResources, getEmbeddedResources,
getSuccessfullyLoaded,
isInvalidResourceCombination, isInvalidResourceCombination,
isLoaded, isLoaded,
isLoadingRequired, isLoadingRequired,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment