mirror of https://github.com/Squidex/squidex.git
18 changed files with 253 additions and 65 deletions
@ -0,0 +1,93 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import { IMock, Mock } from 'typemoq'; |
||||
|
import { Observable } from 'rxjs'; |
||||
|
|
||||
|
import { ContentsService } from 'shared'; |
||||
|
|
||||
|
import { ResolveContentGuard } from './resolve-content.guard'; |
||||
|
import { RouterMockup } from './router-mockup'; |
||||
|
|
||||
|
describe('ResolveContentGuard', () => { |
||||
|
const route = { |
||||
|
params: { |
||||
|
appName: 'my-app' |
||||
|
}, |
||||
|
parent: { |
||||
|
params: { |
||||
|
schemaName: 'my-schema' |
||||
|
}, |
||||
|
parent: { |
||||
|
params: { |
||||
|
contentId: '123' |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
let appsStore: IMock<ContentsService>; |
||||
|
|
||||
|
beforeEach(() => { |
||||
|
appsStore = Mock.ofType(ContentsService); |
||||
|
}); |
||||
|
|
||||
|
it('should throw if route does not contain parameter', () => { |
||||
|
const guard = new ResolveContentGuard(appsStore.object, <any>new RouterMockup()); |
||||
|
|
||||
|
expect(() => guard.resolve(<any>{ params: {} }, <any>{})).toThrow('Route must contain app and schema name and id.'); |
||||
|
}); |
||||
|
|
||||
|
it('should navigate to 404 page if schema is not found', (done) => { |
||||
|
appsStore.setup(x => x.getContent('my-app', 'my-schema', '123')) |
||||
|
.returns(() => Observable.of(null!)); |
||||
|
const router = new RouterMockup(); |
||||
|
|
||||
|
const guard = new ResolveContentGuard(appsStore.object, <any>router); |
||||
|
|
||||
|
guard.resolve(<any>route, <any>{}) |
||||
|
.then(result => { |
||||
|
expect(result).toBeFalsy(); |
||||
|
expect(router.lastNavigation).toEqual(['/404']); |
||||
|
|
||||
|
done(); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
it('should navigate to 404 page if schema loading fails', (done) => { |
||||
|
appsStore.setup(x => x.getContent('my-app', 'my-schema', '123')) |
||||
|
.returns(() => Observable.throw(null!)); |
||||
|
const router = new RouterMockup(); |
||||
|
|
||||
|
const guard = new ResolveContentGuard(appsStore.object, <any>router); |
||||
|
|
||||
|
guard.resolve(<any>route, <any>{}) |
||||
|
.then(result => { |
||||
|
expect(result).toBeFalsy(); |
||||
|
expect(router.lastNavigation).toEqual(['/404']); |
||||
|
|
||||
|
done(); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
it('should return schema if loading succeeded', (done) => { |
||||
|
const schema = {}; |
||||
|
|
||||
|
appsStore.setup(x => x.getContent('my-app', 'my-schema', '123')) |
||||
|
.returns(() => Observable.of(schema)); |
||||
|
const router = new RouterMockup(); |
||||
|
|
||||
|
const guard = new ResolveContentGuard(appsStore.object, <any>router); |
||||
|
|
||||
|
guard.resolve(<any>route, <any>{}) |
||||
|
.then(result => { |
||||
|
expect(result).toBe(schema); |
||||
|
|
||||
|
done(); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
@ -0,0 +1,64 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import { Injectable } from '@angular/core'; |
||||
|
import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router'; |
||||
|
|
||||
|
import { ContentDto, ContentsService } from './../services/contents.service'; |
||||
|
|
||||
|
@Injectable() |
||||
|
export class ResolveContentGuard implements Resolve<ContentDto> { |
||||
|
constructor( |
||||
|
private readonly contentsService: ContentsService, |
||||
|
private readonly router: Router |
||||
|
) { |
||||
|
} |
||||
|
|
||||
|
public resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<ContentDto> { |
||||
|
const appName = this.findParameter(route, 'appName'); |
||||
|
const schemaName = this.findParameter(route, 'schemaName'); |
||||
|
const contentId = this.findParameter(route, 'contentId'); |
||||
|
|
||||
|
if (!appName || !schemaName || !contentId) { |
||||
|
throw 'Route must contain app and schema name and id.'; |
||||
|
} |
||||
|
|
||||
|
const result = |
||||
|
this.contentsService.getContent(appName, schemaName, contentId).toPromise() |
||||
|
.then(dto => { |
||||
|
if (!dto) { |
||||
|
this.router.navigate(['/404']); |
||||
|
|
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return dto; |
||||
|
}).catch(() => { |
||||
|
this.router.navigate(['/404']); |
||||
|
|
||||
|
return null; |
||||
|
}); |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
private findParameter(route: ActivatedRouteSnapshot, name: string): string | null { |
||||
|
let result: string | null = null; |
||||
|
|
||||
|
while (route) { |
||||
|
result = route.params[name]; |
||||
|
|
||||
|
if (result) { |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
route = route.parent; |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue