Skip to content
Snippets Groups Projects
Commit 40697e63 authored by OZGCloud's avatar OZGCloud
Browse files

OZG-209 OZG-246 create command-shared; create command.service/command.repository

parent 5ed29c32
No related branches found
No related tags found
No related merge requests found
Showing
with 468 additions and 20 deletions
......@@ -389,6 +389,32 @@
"style": "scss"
}
}
},
"command-shared": {
"projectType": "library",
"root": "libs/command-shared",
"sourceRoot": "libs/command-shared/src",
"prefix": "goofy-client",
"architect": {
"lint": {
"builder": "@nrwl/linter:eslint",
"options": {
"lintFilePatterns": ["libs/command-shared/src/**/*.ts"]
}
},
"test": {
"builder": "@nrwl/jest:jest",
"options": {
"jestConfig": "libs/command-shared/jest.config.js",
"passWithNoTests": true
}
}
},
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
}
}
},
"cli": {
......
......@@ -11,5 +11,6 @@ module.exports = {
'<rootDir>/libs/test-utils',
'<rootDir>/libs/app-shared',
'<rootDir>/libs/vorgang-detail',
'<rootDir>/libs/command-shared',
],
};
{ "extends": "../../.eslintrc.json", "ignorePatterns": ["!**/*"], "rules": {} }
# command-shared
This library was generated with [Nx](https://nx.dev).
## Running unit tests
Run `nx test command-shared` to execute the unit tests.
module.exports = {
displayName: 'command-shared',
preset: '../../jest.preset.js',
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
globals: {
'ts-jest': {
tsConfig: '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\\.(html|svg)$',
astTransformers: {
before: [
'jest-preset-angular/build/InlineFilesTransformer',
'jest-preset-angular/build/StripStylesTransformer',
],
},
},
},
coverageDirectory: '../../coverage/libs/command-shared',
snapshotSerializers: [
'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js',
'jest-preset-angular/build/AngularSnapshotSerializer.js',
'jest-preset-angular/build/HTMLCommentSerializer.js',
],
};
export * from './lib/command-shared.module';
import { TestBed } from '@angular/core/testing';
import { CommandSharedModule } from './command-shared.module';
describe('CommandSharedModule', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [CommandSharedModule],
}).compileComponents();
});
it('should create', () => {
expect(CommandSharedModule).toBeDefined();
});
});
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
@NgModule({
imports: [CommonModule],
})
export class CommandSharedModule {}
export enum CommandLinkRel {
UPDATE = 'update',
DELETE = 'delete'
}
\ No newline at end of file
import { Resource } from '@ngxp/rest';
export interface Command {
payload: string
// bspw. vorgang-annehmen
//TODO: Geeigneten Namen finden
}
export interface CommandResource extends Command, Resource { }
\ No newline at end of file
import { mock, useFromMock } from '@goofy-client/test-utils';
import { getUrl, Resource, ResourceFactory } from "@ngxp/rest";
import { ResourceWrapper } from "@ngxp/rest/lib/resource-wrapper";
import * as faker from 'faker';
import { createCommand, createCommandResource } from 'libs/command-shared/test/command';
import { toResource } from "libs/tech-shared/test/resource";
import { CommandLinkRel } from './command.linkrel';
import { Command, CommandResource } from './command.model';
import { CommandRepository } from './command.repository';
describe('CommandRepository', () => {
let repository: CommandRepository;
let resourceFactory = mock(ResourceFactory);
let resourceWrapper: ResourceWrapper = <any>{ post: jest.fn(), get: jest.fn(), delete: jest.fn() };
beforeEach(() => {
repository = new CommandRepository(useFromMock(resourceFactory));
(<any>resourceFactory).from.mockReturnValue(resourceWrapper);
})
describe('create command', () => {
const command: Command = createCommand();
const linkRel: string = faker.random.word();
const resource: Resource = toResource({}, [linkRel]);
const commandResource: CommandResource = createCommandResource();
beforeEach(() => {
(<any>resourceWrapper).post.mockReturnValue(commandResource);
})
it('should call resourceFactory with resource', () => {
repository.createCommand(resource, linkRel, command);
expect(resourceFactory.from).toHaveBeenCalledWith(resource);
})
it('should call resourceWrapper with linkel and payload', () => {
repository.createCommand(resource, linkRel, command);
expect(resourceWrapper.post).toHaveBeenCalledWith(linkRel, command);
})
it('should return value', () => {
const result = repository.createCommand(resource, linkRel, command);
expect(result).toBe(commandResource);
})
})
describe('get updated command', () => {
const commandResource: CommandResource = createCommandResource();
const returnResourceValue: CommandResource = createCommandResource();
beforeEach(() => {
(<any>resourceWrapper).get.mockReturnValue(returnResourceValue);
})
it('should call resourceFactory with resource', () => {
repository.getUpdatedCommand(commandResource);
expect(resourceFactory.from).toHaveBeenCalledWith(commandResource);
})
it('should call resourceWrapper with selfLink', () => {
repository.getUpdatedCommand(commandResource);
expect(resourceWrapper.get).toHaveBeenCalledWith(getUrl(commandResource));
})
it('should return value', () => {
const result = repository.getUpdatedCommand(commandResource);
expect(result).toBe(returnResourceValue);
})
})
describe('delete command', () => {
const commandResource: CommandResource = createCommandResource();
const returnValue: any = {};
beforeEach(() => {
(<any>resourceWrapper).delete.mockReturnValue(returnValue);
})
it('should call resourceFactory with Resource', () => {
repository.deleteCommand(commandResource);
expect(resourceFactory.from).toHaveBeenCalledWith(commandResource);
})
it('should call resourceWrapper with deleteLink', () => {
repository.deleteCommand(commandResource);
expect(resourceWrapper.delete).toHaveBeenCalledWith(CommandLinkRel.DELETE)
})
it('should return value', () => {
const result = repository.deleteCommand(commandResource);
expect(result).toBe(returnValue);
})
})
})
\ No newline at end of file
import { getUrl, Resource, ResourceFactory } from "@ngxp/rest";
import { Observable } from "rxjs";
import { CommandLinkRel } from "./command.linkrel";
import { Command, CommandResource } from "./command.model";
export class CommandRepository {
constructor(private resourceFacotry: ResourceFactory) { }
public createCommand(resource: Resource, linkrel: string, command: Command): Observable<CommandResource> {
return this.resourceFacotry.from(resource).post(linkrel, command);
}
public getUpdatedCommand(resource: CommandResource): Observable<CommandResource> {
return this.resourceFacotry.from(resource).get(getUrl(resource));
}
public deleteCommand(resource: CommandResource): Observable<any> {
return this.resourceFacotry.from(resource).delete(CommandLinkRel.DELETE);
}
}
\ No newline at end of file
import { createStateResource, StateResource } from '@goofy-client/tech-shared';
import { mock, Mock, useFromMock } from '@goofy-client/test-utils';
import { Resource } from '@ngxp/rest';
import * as faker from 'faker';
import { cold, hot } from 'jest-marbles';
import { createCommand, createCommandResource } from 'libs/command-shared/test/command';
import { toResource } from 'libs/tech-shared/test/resource';
import { CommandLinkRel } from './command.linkrel';
import { Command, CommandResource } from './command.model';
import { CommandRepository } from './command.repository';
import { CommandService } from './command.service';
describe('CommandService', () => {
let service: CommandService;
let repository: Mock<CommandRepository>;
const command: Command = createCommand();
const commandPayload: string = command.payload;
const commandResource: CommandResource = createCommandResource();
beforeEach(() => {
repository = mock(CommandRepository);
service = new CommandService(useFromMock(repository));
})
describe('create command', () => {
const resource: Resource = toResource({});
const linkRel: string = faker.random.word();
beforeEach(() => {
repository.createCommand.mockReturnValue(cold('a', { a: commandResource }));
})
it('should call repository with resource, linkrel and payload', () => {
service.createCommand(resource, linkRel, commandPayload);
expect(repository.createCommand).toHaveBeenCalledWith(resource, linkRel, command);
})
describe('process command with status in progress(with update link)', () => {
const commandResourceWithUpdateLink: CommandResource = createCommandResource([CommandLinkRel.UPDATE]);
const expectedResult: StateResource<CommandResource> = createStateResource(commandResourceWithUpdateLink, true);
beforeEach(() => {
repository.createCommand.mockReturnValue(cold('a', { a: commandResourceWithUpdateLink }));
})
it('should return value with loading true', () => {
const result = service.createCommand(resource, linkRel, commandPayload);
expect(result).toBeObservable(hot('a', { a: expectedResult }));
})
})
describe('process command with status done(no update link)', () => {
const expectedResult: StateResource<CommandResource> = createStateResource(commandResource);
it('should return value with loading false', () => {
const result = service.createCommand(resource, linkRel, commandPayload);
expect(result).toBeObservable(hot('a', { a: expectedResult }));
})
})
})
describe('get updated command', () => {
beforeEach(() => {
repository.getUpdatedCommand.mockReturnValue(commandResource);
})
it('should call repository with resource', () => {
service.getUpdatedCommand(commandResource);
expect(repository.getUpdatedCommand).toHaveBeenCalledWith(commandResource);
})
it('should return value', () => {
const result = service.getUpdatedCommand(commandResource);
expect(result).toBe(commandResource);
})
})
describe('delete command', () => {
const commandResource: CommandResource = createCommandResource();
const returnValue: any = {};
beforeEach(() => {
repository.deleteCommand.mockReturnValue(returnValue);
})
it('should call repository with resource', () => {
service.deleteCommand(commandResource);
expect(repository.deleteCommand).toBeCalledWith(commandResource);
})
it('should return value', () => {
const result = service.deleteCommand(commandResource);
expect(result).toBe(returnValue);
})
})
})
\ No newline at end of file
import { createStateResource, StateResource } from '@goofy-client/tech-shared';
import { hasLink, Resource } from '@ngxp/rest';
import { BehaviorSubject, Observable } from 'rxjs';
import { map, mergeMap, tap } from 'rxjs/operators';
import { CommandLinkRel } from './command.linkrel';
import { Command, CommandResource } from './command.model';
import { CommandRepository } from './command.repository';
export class CommandService {
private readonly interval: number = 500;
private checkIfCommandIsDoneInterval: number;
constructor(private repository: CommandRepository) { }
public createCommand(resource: Resource, linkRel: string, payload: string): Observable<StateResource<CommandResource>> {
return this.repository.createCommand(resource, linkRel, <Command>{ payload })
.pipe(
map(commandResource => createStateResource(commandResource, true)),
mergeMap(commandStateResource => this.processWithStateResource(commandStateResource))
);
}
private processWithStateResource(stateResource: StateResource<CommandResource>): Observable<StateResource<CommandResource>> {
return !this.isCommandDone(stateResource.resource)
? this.startIntervalUpdate(stateResource)
: new BehaviorSubject(createStateResource(stateResource.resource));
}
startIntervalUpdate(stateResource: StateResource<CommandResource>): Observable<StateResource<CommandResource>> {
let updatedCommand: BehaviorSubject<StateResource<CommandResource>> = new BehaviorSubject(stateResource);
this.checkIfCommandIsDoneInterval = window.setInterval(() => {
this.getUpdatedCommand(stateResource.resource).pipe(
tap(updatedResource => {
if (this.isCommandDone(updatedResource)) {
updatedCommand.next(createStateResource(updatedResource));
this.clearInterval();
};
})
)
}, this.interval);
return updatedCommand;
}
getUpdatedCommand(resource: CommandResource): Observable<CommandResource> {
return this.repository.getUpdatedCommand(resource);
}
private isCommandDone(resource: Resource): boolean {
return !hasLink(resource, CommandLinkRel.UPDATE);
}
private clearInterval(): void {
window.clearInterval(this.checkIfCommandIsDoneInterval);
}
public deleteCommand(resource: CommandResource): Observable<any> {
return this.repository.deleteCommand(resource);
}
}
\ No newline at end of file
import 'jest-preset-angular';
import * as faker from 'faker';
import { toResource } from '../../tech-shared/test/resource';
import { Command, CommandResource } from '../src/lib/command.model';
export function createCommand(): Command {
return {
payload: faker.internet.url()
}
}
export function createCommandResource(linkRel: string[] = []): CommandResource {
return toResource(createCommand(), linkRel);
}
\ No newline at end of file
{
"extends": "../../tsconfig.base.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"target": "es2015",
"declaration": true,
"declarationMap": true,
"inlineSources": true,
"types": [],
"lib": ["dom", "es2018"]
},
"angularCompilerOptions": {
"skipTemplateCodegen": true,
"strictMetadataEmit": true,
"enableResourceInlining": true
},
"exclude": ["src/test-setup.ts", "**/*.spec.ts"],
"include": ["**/*.ts"]
}
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"files": ["src/test-setup.ts"],
"include": ["**/*.spec.ts", "**/*.d.ts"]
}
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AntragstellerComponent } from './antragsteller.component';
import { createAntragsteller } from 'libs/vorgang-shared/test/vorgang';
import { AntragstellerComponent } from './antragsteller.component';
describe.only('AntragstellerComponent', () => {
describe('AntragstellerComponent', () => {
let component: AntragstellerComponent;
let fixture: ComponentFixture<AntragstellerComponent>;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment