mirror of https://github.com/Squidex/squidex.git
25 changed files with 247 additions and 27 deletions
@ -0,0 +1,100 @@ |
|||
/* |
|||
* Squidex Headless CMS |
|||
* |
|||
* @license |
|||
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
|||
*/ |
|||
|
|||
import { of } from 'rxjs'; |
|||
import { IMock, It, Mock, Times } from 'typemoq'; |
|||
|
|||
import { |
|||
DialogService, |
|||
versioned, |
|||
WorkflowPayload, |
|||
WorkflowsService, |
|||
WorkflowsState |
|||
} from '@app/shared/internal'; |
|||
|
|||
import { createWorkflow } from '../services/workflows.service.spec'; |
|||
|
|||
import { TestValues } from './_test-helpers'; |
|||
|
|||
describe('WorkflowsState', () => { |
|||
const { |
|||
app, |
|||
appsState, |
|||
newVersion, |
|||
version |
|||
} = TestValues; |
|||
|
|||
const oldWorkflow = createWorkflow('test'); |
|||
|
|||
let dialogs: IMock<DialogService>; |
|||
let workflowsService: IMock<WorkflowsService>; |
|||
let workflowsState: WorkflowsState; |
|||
|
|||
beforeEach(() => { |
|||
dialogs = Mock.ofType<DialogService>(); |
|||
|
|||
workflowsService = Mock.ofType<WorkflowsService>(); |
|||
workflowsState = new WorkflowsState(workflowsService.object, appsState.object, dialogs.object); |
|||
}); |
|||
|
|||
afterEach(() => { |
|||
workflowsService.verifyAll(); |
|||
}); |
|||
|
|||
describe('Loading', () => { |
|||
it('should load workflow', () => { |
|||
workflowsService.setup(x => x.getWorkflow(app)) |
|||
.returns(() => of(versioned(version, oldWorkflow))).verifiable(); |
|||
|
|||
workflowsState.load().subscribe(); |
|||
|
|||
expect(workflowsState.snapshot.workflow).toEqual(oldWorkflow.workflow); |
|||
expect(workflowsState.snapshot.isLoaded).toBeTruthy(); |
|||
expect(workflowsState.snapshot.version).toEqual(version); |
|||
|
|||
dialogs.verify(x => x.notifyInfo(It.isAnyString()), Times.never()); |
|||
}); |
|||
|
|||
it('should show notification on load when reload is true', () => { |
|||
workflowsService.setup(x => x.getWorkflow(app)) |
|||
.returns(() => of(versioned(version, oldWorkflow))).verifiable(); |
|||
|
|||
workflowsState.load(true).subscribe(); |
|||
|
|||
expect().nothing(); |
|||
|
|||
dialogs.verify(x => x.notifyInfo(It.isAnyString()), Times.once()); |
|||
}); |
|||
}); |
|||
|
|||
describe('Updates', () => { |
|||
beforeEach(() => { |
|||
workflowsService.setup(x => x.getWorkflow(app)) |
|||
.returns(() => of(versioned(version, oldWorkflow))).verifiable(); |
|||
|
|||
workflowsState.load().subscribe(); |
|||
}); |
|||
|
|||
it('should update workflows when saved', () => { |
|||
const updated = createWorkflow('updated'); |
|||
|
|||
const request = oldWorkflow.workflow.serialize(); |
|||
|
|||
workflowsService.setup(x => x.putWorkflow(app, oldWorkflow, request, version)) |
|||
.returns(() => of(versioned(newVersion, updated))).verifiable(); |
|||
|
|||
workflowsState.save().subscribe(); |
|||
|
|||
expectNewWorkflows(updated); |
|||
}); |
|||
|
|||
function expectNewWorkflows(updated: WorkflowPayload) { |
|||
expect(workflowsState.snapshot.workflow).toEqual(updated.workflow); |
|||
expect(workflowsState.snapshot.version).toEqual(newVersion); |
|||
} |
|||
}); |
|||
}); |
|||
@ -0,0 +1,97 @@ |
|||
/* |
|||
* Squidex Headless CMS |
|||
* |
|||
* @license |
|||
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
|||
*/ |
|||
|
|||
// tslint:disable: no-shadowed-variable
|
|||
|
|||
import { Injectable } from '@angular/core'; |
|||
import { Observable } from 'rxjs'; |
|||
import { tap } from 'rxjs/operators'; |
|||
|
|||
import { |
|||
DialogService, |
|||
shareSubscribed, |
|||
State, |
|||
Version |
|||
} from '@app/framework'; |
|||
|
|||
import { AppsState } from './apps.state'; |
|||
|
|||
import { |
|||
WorkflowDto, |
|||
WorkflowPayload, |
|||
WorkflowsService |
|||
} from './../services/workflows.service'; |
|||
|
|||
interface Snapshot { |
|||
// The current workflow.
|
|||
workflow?: WorkflowDto; |
|||
|
|||
// The app version.
|
|||
version: Version; |
|||
|
|||
// Indicates if the workflows are loaded.
|
|||
isLoaded?: boolean; |
|||
} |
|||
|
|||
@Injectable() |
|||
export class WorkflowsState extends State<Snapshot> { |
|||
public workflow = |
|||
this.project(x => x.workflow); |
|||
|
|||
public isLoaded = |
|||
this.project(x => !!x.isLoaded); |
|||
|
|||
constructor( |
|||
private readonly workflowsService: WorkflowsService, |
|||
private readonly appsState: AppsState, |
|||
private readonly dialogs: DialogService |
|||
) { |
|||
super({ version: Version.EMPTY }); |
|||
} |
|||
|
|||
public load(isReload = false): Observable<any> { |
|||
if (!isReload) { |
|||
this.resetState(); |
|||
} |
|||
|
|||
return this.workflowsService.getWorkflow(this.appName).pipe( |
|||
tap(({ version, payload }) => { |
|||
if (isReload) { |
|||
this.dialogs.notifyInfo('Workflow reloaded.'); |
|||
} |
|||
|
|||
this.replaceWorkflow(payload, version); |
|||
}), |
|||
shareSubscribed(this.dialogs)); |
|||
} |
|||
|
|||
public save(): Observable<any> { |
|||
const workflow = this.snapshot.workflow!; |
|||
|
|||
return this.workflowsService.putWorkflow(this.appName, workflow, workflow.serialize(), this.version).pipe( |
|||
tap(({ version, payload }) => { |
|||
this.replaceWorkflow(payload, version); |
|||
}), |
|||
shareSubscribed(this.dialogs)); |
|||
} |
|||
|
|||
private replaceWorkflow(payload: WorkflowPayload, version: Version) { |
|||
const { workflow } = payload; |
|||
|
|||
this.next(s => { |
|||
return { ...s, workflow, isLoaded: true, version }; |
|||
}); |
|||
} |
|||
|
|||
private get appName() { |
|||
return this.appsState.appName; |
|||
} |
|||
|
|||
private get version() { |
|||
return this.snapshot.version; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue