mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
250 lines
7.8 KiB
TypeScript
250 lines
7.8 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.dev/license
|
|
*/
|
|
|
|
import {Component} from '@angular/core';
|
|
import {TestBed} from '@angular/core/testing';
|
|
import {ActivatedRouteSnapshot, provideRouter, Router} from '../../index';
|
|
import {RouterTestingHarness} from '../../testing';
|
|
import {EMPTY, interval, NEVER, of} from 'rxjs';
|
|
import {useAutoTick} from '@angular/private/testing';
|
|
|
|
describe('resolveData operator', () => {
|
|
useAutoTick();
|
|
it('should take only the first emitted value of every resolver', async () => {
|
|
TestBed.configureTestingModule({
|
|
providers: [provideRouter([{path: '**', children: [], resolve: {e1: () => interval()}}])],
|
|
});
|
|
await RouterTestingHarness.create('/');
|
|
expect(TestBed.inject(Router).routerState.root.firstChild?.snapshot.data).toEqual({e1: 0});
|
|
});
|
|
|
|
it('should cancel navigation if a resolver does not complete', async () => {
|
|
TestBed.configureTestingModule({
|
|
providers: [provideRouter([{path: '**', children: [], resolve: {e1: () => EMPTY}}])],
|
|
});
|
|
await RouterTestingHarness.create('/a');
|
|
expect(TestBed.inject(Router).url).toEqual('/');
|
|
});
|
|
|
|
it('should cancel navigation if 1 of 2 resolvers does not emit', async () => {
|
|
TestBed.configureTestingModule({
|
|
providers: [
|
|
provideRouter([{path: '**', children: [], resolve: {e0: () => of(0), e1: () => EMPTY}}]),
|
|
],
|
|
});
|
|
await RouterTestingHarness.create('/a');
|
|
expect(TestBed.inject(Router).url).toEqual('/');
|
|
});
|
|
|
|
it("should complete instantly if at least one resolver doesn't emit", async () => {
|
|
TestBed.configureTestingModule({
|
|
providers: [
|
|
provideRouter([{path: '**', children: [], resolve: {e0: () => EMPTY, e1: () => NEVER}}]),
|
|
],
|
|
});
|
|
await RouterTestingHarness.create('/a');
|
|
expect(TestBed.inject(Router).url).toEqual('/');
|
|
});
|
|
|
|
it('should run resolvers in different parts of the tree', async () => {
|
|
let value = 0;
|
|
let bValue = 0;
|
|
TestBed.configureTestingModule({
|
|
providers: [
|
|
provideRouter([
|
|
{
|
|
path: 'a',
|
|
runGuardsAndResolvers: () => false,
|
|
children: [
|
|
{
|
|
path: '',
|
|
resolve: {d0: () => ++value},
|
|
runGuardsAndResolvers: 'always',
|
|
children: [],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
path: 'b',
|
|
outlet: 'aux',
|
|
runGuardsAndResolvers: () => false,
|
|
children: [
|
|
{
|
|
path: '',
|
|
resolve: {d1: () => ++bValue},
|
|
runGuardsAndResolvers: 'always',
|
|
children: [],
|
|
},
|
|
],
|
|
},
|
|
]),
|
|
],
|
|
});
|
|
const router = TestBed.inject(Router);
|
|
const harness = await RouterTestingHarness.create('/a(aux:b)');
|
|
expect(router.routerState.root.children[0]?.firstChild?.snapshot.data).toEqual({d0: 1});
|
|
expect(router.routerState.root.children[1]?.firstChild?.snapshot.data).toEqual({d1: 1});
|
|
|
|
await harness.navigateByUrl('/a(aux:b)#new');
|
|
expect(router.routerState.root.children[0]?.firstChild?.snapshot.data).toEqual({d0: 2});
|
|
expect(router.routerState.root.children[1]?.firstChild?.snapshot.data).toEqual({d1: 2});
|
|
});
|
|
|
|
it('should update children inherited data when resolvers run', async () => {
|
|
let value = 0;
|
|
TestBed.configureTestingModule({
|
|
providers: [
|
|
provideRouter([
|
|
{
|
|
path: 'a',
|
|
children: [{path: 'b', children: []}],
|
|
resolve: {d0: () => ++value},
|
|
runGuardsAndResolvers: 'always',
|
|
},
|
|
]),
|
|
],
|
|
});
|
|
const harness = await RouterTestingHarness.create('/a/b');
|
|
expect(TestBed.inject(Router).routerState.root.firstChild?.snapshot.data).toEqual({d0: 1});
|
|
expect(TestBed.inject(Router).routerState.root.firstChild?.firstChild?.snapshot.data).toEqual({
|
|
d0: 1,
|
|
});
|
|
|
|
await harness.navigateByUrl('/a/b#new');
|
|
expect(TestBed.inject(Router).routerState.root.firstChild?.snapshot.data).toEqual({d0: 2});
|
|
expect(TestBed.inject(Router).routerState.root.firstChild?.firstChild?.snapshot.data).toEqual({
|
|
d0: 2,
|
|
});
|
|
});
|
|
|
|
it('should have correct data when parent resolver runs but data is not inherited', async () => {
|
|
@Component({
|
|
template: '',
|
|
standalone: false,
|
|
})
|
|
class Empty {}
|
|
|
|
TestBed.configureTestingModule({
|
|
providers: [
|
|
provideRouter([
|
|
{
|
|
path: 'a',
|
|
component: Empty,
|
|
data: {parent: 'parent'},
|
|
resolve: {other: () => 'other'},
|
|
children: [
|
|
{
|
|
path: 'b',
|
|
data: {child: 'child'},
|
|
component: Empty,
|
|
},
|
|
],
|
|
},
|
|
]),
|
|
],
|
|
});
|
|
await RouterTestingHarness.create('/a/b');
|
|
const rootSnapshot = TestBed.inject(Router).routerState.root.firstChild!.snapshot;
|
|
expect(rootSnapshot.data).toEqual({parent: 'parent', other: 'other'});
|
|
expect(rootSnapshot.firstChild!.data).toEqual({child: 'child'});
|
|
});
|
|
|
|
it('should have static title when there is a resolver', async () => {
|
|
@Component({
|
|
template: '',
|
|
standalone: false,
|
|
})
|
|
class Empty {}
|
|
|
|
TestBed.configureTestingModule({
|
|
providers: [
|
|
provideRouter([
|
|
{
|
|
path: 'a',
|
|
title: 'a title',
|
|
component: Empty,
|
|
resolve: {other: () => 'other'},
|
|
children: [
|
|
{
|
|
path: 'b',
|
|
title: 'b title',
|
|
component: Empty,
|
|
resolve: {otherb: () => 'other b'},
|
|
},
|
|
],
|
|
},
|
|
]),
|
|
],
|
|
});
|
|
await RouterTestingHarness.create('/a/b');
|
|
const rootSnapshot = TestBed.inject(Router).routerState.root.firstChild!.snapshot;
|
|
expect(rootSnapshot.title).toBe('a title');
|
|
expect(rootSnapshot.firstChild!.title).toBe('b title');
|
|
});
|
|
|
|
it('can used parent data in child resolver', async () => {
|
|
@Component({
|
|
template: '',
|
|
})
|
|
class Empty {}
|
|
|
|
TestBed.configureTestingModule({
|
|
providers: [
|
|
provideRouter([
|
|
{
|
|
path: 'a',
|
|
resolve: {
|
|
aResolve: () => new Promise<string>((resolve) => setTimeout(() => resolve('a'), 5)),
|
|
},
|
|
children: [
|
|
{
|
|
path: 'b',
|
|
resolve: {
|
|
bResolve: (route: ActivatedRouteSnapshot) => route.data['aResolve'] + 'b',
|
|
},
|
|
children: [{path: 'c', component: Empty}],
|
|
},
|
|
],
|
|
},
|
|
]),
|
|
],
|
|
});
|
|
await RouterTestingHarness.create('/a/b/c');
|
|
const rootSnapshot = TestBed.inject(Router).routerState.root.firstChild!.snapshot;
|
|
expect(rootSnapshot.firstChild!.firstChild!.data).toEqual({bResolve: 'ab', aResolve: 'a'});
|
|
});
|
|
|
|
it('should inherit resolved data from parent of parent route', async () => {
|
|
@Component({
|
|
template: '',
|
|
standalone: false,
|
|
})
|
|
class Empty {}
|
|
|
|
TestBed.configureTestingModule({
|
|
providers: [
|
|
provideRouter([
|
|
{
|
|
path: 'a',
|
|
resolve: {aResolve: () => 'a'},
|
|
children: [
|
|
{
|
|
path: 'b',
|
|
resolve: {bResolve: () => 'b'},
|
|
children: [{path: 'c', component: Empty}],
|
|
},
|
|
],
|
|
},
|
|
]),
|
|
],
|
|
});
|
|
await RouterTestingHarness.create('/a/b/c');
|
|
const rootSnapshot = TestBed.inject(Router).routerState.root.firstChild!.snapshot;
|
|
expect(rootSnapshot.firstChild!.firstChild!.data).toEqual({bResolve: 'b', aResolve: 'a'});
|
|
});
|
|
});
|