From 71f9051ffe5d64ed0a8d4124cf0829f42a0ec3f4 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Sun, 17 Dec 2017 14:33:06 +0100 Subject: [PATCH] Service added --- .../services/app-patterns.service.spec.ts | 172 ++++++++++++++++++ .../shared/services/app-patterns.service.ts | 127 +++++++++++++ 2 files changed, 299 insertions(+) create mode 100644 src/Squidex/app/shared/services/app-patterns.service.spec.ts create mode 100644 src/Squidex/app/shared/services/app-patterns.service.ts diff --git a/src/Squidex/app/shared/services/app-patterns.service.spec.ts b/src/Squidex/app/shared/services/app-patterns.service.spec.ts new file mode 100644 index 000000000..b5fa92f91 --- /dev/null +++ b/src/Squidex/app/shared/services/app-patterns.service.spec.ts @@ -0,0 +1,172 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Sebastian Stehle. All rights reserved + */ + +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; +import { inject, TestBed } from '@angular/core/testing'; + +import { + ApiUrlConfig, + AppPatternDto, + AppPatternsDto, + AppPatternsService, + UpdatePatternDto, + Version +} from './../'; + +describe('ApppatternsDto', () => { + const pattern1 = new AppPatternDto('1', 'Any', '.*', 'Message1'); + const pattern2 = new AppPatternDto('2', 'Number', '[0-9]', 'Message2'); + const pattern2_new = new AppPatternDto('2', 'Numbers', '[0-9]*', 'Message2_1'); + const version = new Version('1'); + const newVersion = new Version('2'); + + it('should update patterns when adding pattern', () => { + const patterns_1 = new AppPatternsDto([pattern1], version); + const patterns_2 = patterns_1.addPattern(pattern2, newVersion); + + expect(patterns_2.patterns).toEqual([pattern1, pattern2]); + expect(patterns_2.version).toEqual(newVersion); + }); + + it('should update patterns when removing pattern', () => { + const patterns_1 = new AppPatternsDto([pattern1, pattern2], version); + const patterns_2 = patterns_1.removePattern(pattern1, newVersion); + + expect(patterns_2.patterns).toEqual([pattern2]); + expect(patterns_2.version).toEqual(newVersion); + }); + + it('should update patterns when updating pattern', () => { + const patterns_1 = new AppPatternsDto([pattern1, pattern2], version); + const patterns_2 = patterns_1.updatePattern(pattern2_new, newVersion); + + expect(patterns_2.patterns).toEqual([pattern1, pattern2_new]); + expect(patterns_2.version).toEqual(newVersion); + }); +}); + +describe('AppPatternDto', () => { + it('should update properties when updating', () => { + const pattern_1 = new AppPatternDto('1', 'Number', '[0-9]', 'Message1'); + const pattern_2 = pattern_1.update(new UpdatePatternDto('Numbers', '[0-9]*', 'Message2')); + + expect(pattern_2.name).toBe('Numbers'); + expect(pattern_2.pattern).toBe('[0-9]*'); + expect(pattern_2.message).toBe('Message2'); + }); +}); + +describe('AppPatternsService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ + HttpClientTestingModule + ], + providers: [ + AppPatternsService, + { provide: ApiUrlConfig, useValue: new ApiUrlConfig('http://service/p/') } + ] + }); + }); + + afterEach(inject([HttpTestingController], (httpMock: HttpTestingController) => { + httpMock.verify(); + })); + + it('should make get request to get patterns', + inject([AppPatternsService, HttpTestingController], (patternService: AppPatternsService, httpMock: HttpTestingController) => { + + let patterns: AppPatternsDto | null = null; + + patternService.getPatterns('my-app').subscribe(result => { + patterns = result; + }); + + const req = httpMock.expectOne('http://service/p/api/apps/my-app/patterns'); + + expect(req.request.method).toEqual('GET'); + expect(req.request.headers.get('If-Match')).toBeNull(); + + req.flush([ + { + patternId: '1', + pattern: '[0-9]', + name: 'Number', + message: 'Message1' + }, { + patternId: '2', + pattern: '[0-9]*', + name: 'Numbers', + message: 'Message2' + } + ], { + headers: { + etag: '2' + } + }); + + expect(patterns).toEqual( + new AppPatternsDto([ + new AppPatternDto('1', 'Number', '[0-9]', 'Message1'), + new AppPatternDto('2', 'Numbers', '[0-9]*', 'Message2') + ], new Version('2'))); + })); + + it('should make post request to add pattern', + inject([AppPatternsService, HttpTestingController], (patternService: AppPatternsService, httpMock: HttpTestingController) => { + + const dto = new UpdatePatternDto('Number', '[0-9]', 'Message1'); + + let pattern: AppPatternDto | null = null; + + patternService.postPattern('my-app', dto, new Version()).subscribe(result => { + pattern = result; + }); + + const req = httpMock.expectOne('http://service/p/api/apps/my-app/patterns'); + + expect(req.request.method).toEqual('POST'); + expect(req.request.headers.get('E-Tag')).toBeNull(); + + req.flush({ + patternId: '1', + pattern: '[0-9]', + name: 'Number', + message: 'Message1' + }); + + expect(pattern).toEqual(new AppPatternDto('1', 'Number', '[0-9]', 'Message1')); + })); + + it('should make put request to update pattern', + inject([AppPatternsService, HttpTestingController], (patternService: AppPatternsService, httpMock: HttpTestingController) => { + + const dto = new UpdatePatternDto('Number', '[0-9]', 'Message1'); + + patternService.updatePattern('my-app', '1', dto, new Version()).subscribe(); + + const req = httpMock.expectOne('http://service/p/api/apps/my-app/patterns/1'); + + expect(req.request.method).toEqual('PUT'); + expect(req.request.headers.get('E-Tag')).toBeNull(); + + req.flush({}); + })); + + it('should make delete request to remove pattern', + inject([AppPatternsService, HttpTestingController], (patternService: AppPatternsService, httpMock: HttpTestingController) => { + + patternService.deletePattern('my-app', '1', new Version('1')).subscribe(); + + const req = httpMock.expectOne('http://service/p/api/apps/my-app/patterns/1'); + + expect(req.request.method).toEqual('DELETE'); + expect(req.request.headers.get('If-Match')).toEqual(new Version('1').value); + + req.flush({}); + })); +}); \ No newline at end of file diff --git a/src/Squidex/app/shared/services/app-patterns.service.ts b/src/Squidex/app/shared/services/app-patterns.service.ts new file mode 100644 index 000000000..9585a86c7 --- /dev/null +++ b/src/Squidex/app/shared/services/app-patterns.service.ts @@ -0,0 +1,127 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Sebastian Stehle. All rights reserved + */ + +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; + +import 'framework/angular/http-extensions'; + +import { + ApiUrlConfig, + HTTP, + Version +} from 'framework'; + +export class AppPatternsDto { + constructor( + public readonly patterns: AppPatternDto[], + public readonly version: Version + ) { + } + + public addPattern(pattern: AppPatternDto, version: Version) { + return new AppPatternsDto([...this.patterns, pattern], version); + } + + public updatePattern(pattern: AppPatternDto, version: Version) { + return new AppPatternsDto(this.patterns.map(p => p.patternId === pattern.patternId ? pattern : p), version); + } + + public removePattern(pattern: AppPatternDto, version: Version) { + return new AppPatternsDto(this.patterns.filter(c => c.patternId !== pattern.patternId), version); + } +} + +export class AppPatternDto { + constructor( + public readonly patternId: string, + public readonly name: string, + public readonly pattern: string, + public readonly message: string + ) { + } + + public update(update: UpdatePatternDto) { + return new AppPatternDto( + this.patternId, + update.name, + update.pattern, + update.message); + } +} + +export class UpdatePatternDto { + constructor( + public readonly name: string, + public readonly pattern: string, + public readonly message: string + ) { + } +} + + +@Injectable() +export class AppPatternsService { + constructor( + private readonly http: HttpClient, + private readonly apiUrl: ApiUrlConfig + ) { + } + + public getPatterns(appName: string): Observable { + const url = this.apiUrl.buildUrl(`api/apps/${appName}/patterns`); + + return HTTP.getVersioned(this.http, url) + .map(response => { + const body = response.payload.body; + + const items: any[] = body; + + return new AppPatternsDto( + items.map(item => { + return new AppPatternDto( + item.patternId, + item.name, + item.pattern, + item.message); + }), + response.version); + }) + .pretifyError('Failed to add pattern. Please reload.'); + } + + public postPattern(appName: string, pattern: UpdatePatternDto, version: Version): Observable { + const url = this.apiUrl.buildUrl(`api/apps/${appName}/patterns`); + + return HTTP.postVersioned(this.http, url, pattern, version) + .map(response => { + const body = response.payload.body; + + return new AppPatternDto( + body.patternId, + body.name, + body.pattern, + body.message); + }) + .pretifyError('Failed to add pattern. Please reload.'); + } + + public updatePattern(appName: string, id: string, pattern: UpdatePatternDto, version: Version): Observable { + const url = this.apiUrl.buildUrl(`api/apps/${appName}/patterns/${id}`); + + return HTTP.putVersioned(this.http, url, pattern, version) + .pretifyError('Failed to update pattern. Please reload.'); + } + + public deletePattern(appName: string, id: string, version: Version): Observable { + const url = this.apiUrl.buildUrl(`api/apps/${appName}/patterns/${id}`); + + return HTTP.deleteVersioned(this.http, url, version) + .pretifyError('Failed to remove pattern. Please reload.'); + } +} \ No newline at end of file