mirror of https://github.com/Squidex/squidex.git
11 changed files with 290 additions and 205 deletions
@ -0,0 +1,99 @@ |
|||
/* |
|||
* Squidex Headless CMS |
|||
* |
|||
* @license |
|||
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
|||
*/ |
|||
|
|||
import { Observable } from 'rxjs'; |
|||
import { IMock, Mock } from 'typemoq'; |
|||
|
|||
import { |
|||
AppsState, |
|||
AppPatternDto, |
|||
AppPatternsDto, |
|||
AppPatternsService, |
|||
PatternsState, |
|||
DialogService, |
|||
EditAppPatternDto, |
|||
Version, |
|||
Versioned |
|||
} from '@app/shared'; |
|||
|
|||
describe('PatternsState', () => { |
|||
const app = 'my-app'; |
|||
const version = new Version('1'); |
|||
const newVersion = new Version('2'); |
|||
|
|||
const oldPatterns = [ |
|||
new AppPatternDto('id1', 'name1', 'pattern1', ''), |
|||
new AppPatternDto('id2', 'name2', 'pattern2', '') |
|||
]; |
|||
|
|||
let dialogs: IMock<DialogService>; |
|||
let appsState: IMock<AppsState>; |
|||
let patternsService: IMock<AppPatternsService>; |
|||
let patternsState: PatternsState; |
|||
|
|||
beforeEach(() => { |
|||
dialogs = Mock.ofType<DialogService>(); |
|||
|
|||
appsState = Mock.ofType<AppsState>(); |
|||
|
|||
appsState.setup(x => x.appName) |
|||
.returns(() => app); |
|||
|
|||
patternsService = Mock.ofType<AppPatternsService>(); |
|||
|
|||
patternsService.setup(x => x.getPatterns(app)) |
|||
.returns(() => Observable.of(new AppPatternsDto(oldPatterns, version))); |
|||
|
|||
patternsState = new PatternsState(patternsService.object, appsState.object, dialogs.object); |
|||
patternsState.load().subscribe(); |
|||
}); |
|||
|
|||
it('should load patterns', () => { |
|||
expect(patternsState.snapshot.patterns.values).toEqual(oldPatterns); |
|||
expect(patternsState.snapshot.version).toEqual(version); |
|||
}); |
|||
|
|||
it('should add pattern to snapshot', () => { |
|||
const newPattern = new AppPatternDto('id3', 'name3', 'pattern3', ''); |
|||
|
|||
const request = new EditAppPatternDto('name3', 'pattern3', ''); |
|||
|
|||
patternsService.setup(x => x.postPattern(app, request, version)) |
|||
.returns(() => Observable.of(new Versioned<AppPatternDto>(newVersion, newPattern))); |
|||
|
|||
patternsState.create(request).subscribe(); |
|||
|
|||
expect(patternsState.snapshot.patterns.values).toEqual([...oldPatterns, newPattern]); |
|||
expect(patternsState.snapshot.version).toEqual(newVersion); |
|||
}); |
|||
|
|||
it('should update pattern in snapshot', () => { |
|||
const request = new EditAppPatternDto('a_name2', 'a_pattern2', 'a_message2'); |
|||
|
|||
patternsService.setup(x => x.putPattern(app, oldPatterns[1].id, request, version)) |
|||
.returns(() => Observable.of(new Versioned<any>(newVersion, {}))); |
|||
|
|||
patternsState.update(oldPatterns[1], request).subscribe(); |
|||
|
|||
const pattern_1 = patternsState.snapshot.patterns.at(0); |
|||
|
|||
expect(pattern_1.name).toBe('a_name2'); |
|||
expect(pattern_1.pattern).toBe('a_pattern2'); |
|||
expect(pattern_1.message).toBe('a_message2'); |
|||
expect(patternsState.snapshot.version).toEqual(newVersion); |
|||
}); |
|||
|
|||
it('should remove pattern from snapshot', () => { |
|||
patternsService.setup(x => x.deletePattern(app, oldPatterns[0].id, version)) |
|||
.returns(() => Observable.of(new Versioned<any>(newVersion, {}))); |
|||
|
|||
patternsState.delete(oldPatterns[0]).subscribe(); |
|||
|
|||
expect(patternsState.snapshot.patterns.values).toEqual([oldPatterns[1]]); |
|||
expect(patternsState.snapshot.version).toEqual(newVersion); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,131 @@ |
|||
/* |
|||
* Squidex Headless CMS |
|||
* |
|||
* @license |
|||
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
|||
*/ |
|||
|
|||
import { Injectable } from '@angular/core'; |
|||
import { FormBuilder, Validators, FormGroup } from '@angular/forms'; |
|||
import { Observable } from 'rxjs'; |
|||
|
|||
import '@app/framework/utils/rxjs-extensions'; |
|||
|
|||
import { |
|||
DialogService, |
|||
ImmutableArray, |
|||
Form, |
|||
State, |
|||
ValidatorsEx, |
|||
Version |
|||
} from '@app/framework'; |
|||
|
|||
import { AppsState } from './apps.state'; |
|||
|
|||
import { |
|||
AppPatternDto, |
|||
AppPatternsService, |
|||
EditAppPatternDto |
|||
} from './../services/app-patterns.service'; |
|||
|
|||
export class EditPatternForm extends Form<FormGroup> { |
|||
constructor(formBuilder: FormBuilder) { |
|||
super(formBuilder.group({ |
|||
name: ['', |
|||
[ |
|||
Validators.required, |
|||
Validators.maxLength(100), |
|||
ValidatorsEx.pattern('[A-z0-9]+[A-z0-9\- ]*[A-z0-9]', 'Name can only contain letters, numbers, dashes and spaces.') |
|||
] |
|||
], |
|||
pattern: ['', |
|||
[ |
|||
Validators.required |
|||
] |
|||
], |
|||
message: ['', |
|||
[ |
|||
Validators.maxLength(1000) |
|||
] |
|||
] |
|||
})); |
|||
} |
|||
} |
|||
|
|||
interface Snapshot { |
|||
patterns: ImmutableArray<AppPatternDto>; |
|||
|
|||
isLoaded: boolean; |
|||
|
|||
version: Version; |
|||
} |
|||
|
|||
@Injectable() |
|||
export class PatternsState extends State<Snapshot> { |
|||
public patterns = |
|||
this.changes.map(x => x.patterns); |
|||
|
|||
public isLoaded = |
|||
this.changes.map(x => x.isLoaded); |
|||
|
|||
constructor( |
|||
private readonly appPatternsService: AppPatternsService, |
|||
private readonly appsState: AppsState, |
|||
private readonly dialogs: DialogService |
|||
) { |
|||
super({ patterns: ImmutableArray.empty(), version: new Version(''), isLoaded: false }); |
|||
} |
|||
|
|||
public load(): Observable<any> { |
|||
return this.appPatternsService.getPatterns(this.appName) |
|||
.do(dtos => { |
|||
this.next(s => { |
|||
return { patterns: ImmutableArray.of(dtos.patterns), isLoaded: true, version: dtos.version }; |
|||
}); |
|||
}) |
|||
.notify(this.dialogs); |
|||
} |
|||
|
|||
public create(request: EditAppPatternDto): Observable<any> { |
|||
return this.appPatternsService.postPattern(this.appName, request, this.snapshot.version) |
|||
.do(dto => { |
|||
this.next(s => { |
|||
const patterns = s.patterns.push(dto.payload).sortByStringAsc(x => x.name); |
|||
|
|||
return { ...s, patterns, version: dto.version }; |
|||
}); |
|||
}) |
|||
.notify(this.dialogs); |
|||
} |
|||
|
|||
public update(pattern: AppPatternDto, request: EditAppPatternDto): Observable<any> { |
|||
return this.appPatternsService.putPattern(this.appName, pattern.id, request, this.snapshot.version) |
|||
.do(dto => { |
|||
this.next(s => { |
|||
const patterns = s.patterns.replaceBy('id', update(pattern, request)).sortByStringAsc(x => x.name); |
|||
|
|||
return { ...s, patterns, version: dto.version }; |
|||
}); |
|||
}) |
|||
.notify(this.dialogs); |
|||
} |
|||
|
|||
public delete(pattern: AppPatternDto): Observable<any> { |
|||
return this.appPatternsService.deletePattern(this.appName, pattern.id, this.snapshot.version) |
|||
.do(dto => { |
|||
this.next(s => { |
|||
const patterns = s.patterns.filter(c => c.id !== pattern.id); |
|||
|
|||
return { ...s, patterns, version: dto.version }; |
|||
}); |
|||
}) |
|||
.notify(this.dialogs); |
|||
} |
|||
|
|||
private get appName() { |
|||
return this.appsState.appName; |
|||
} |
|||
} |
|||
|
|||
const update = (pattern: AppPatternDto, request: EditAppPatternDto) => |
|||
new AppPatternDto(pattern.id, request.name, request.pattern, request.message); |
|||
Loading…
Reference in new issue