forked from ReactiveX/rxjs
/
navigation.service.spec.ts
250 lines (205 loc) · 7.5 KB
/
navigation.service.spec.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { Injector } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import {
CurrentNodes,
NavigationService,
NavigationViews,
NavigationNode,
VersionInfo,
} from 'app/navigation/navigation.service';
import { LocationService } from 'app/shared/location.service';
import { MockLocationService } from 'testing/location.service';
describe('NavigationService', () => {
let injector: Injector;
let navService: NavigationService;
let httpMock: HttpTestingController;
beforeEach(() => {
injector = TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [NavigationService, { provide: LocationService, useFactory: () => new MockLocationService('a') }],
});
navService = injector.get(NavigationService);
httpMock = injector.get(HttpTestingController);
});
afterEach(() => httpMock.verify());
describe('navigationViews', () => {
it('should make a single connection to the server', () => {
const req = httpMock.expectOne({});
expect(req.request.url).toBe('generated/navigation.json');
});
it('should expose the server response', () => {
const viewsEvents: NavigationViews[] = [];
navService.navigationViews.subscribe(views => viewsEvents.push(views));
expect(viewsEvents).toEqual([]);
httpMock.expectOne({}).flush({ TopBar: [{ url: 'a' }] });
expect(viewsEvents).toEqual([{ TopBar: [{ url: 'a' }] }]);
});
it('navigationViews observable should complete', () => {
navService.navigationViews.subscribe();
// Stop `$httpMock.verify()` from complaining.
httpMock.expectOne({});
});
it('should return the same object to all subscribers', () => {
let views1: NavigationViews | undefined;
navService.navigationViews.subscribe(views => (views1 = views));
let views2: NavigationViews | undefined;
navService.navigationViews.subscribe(views => (views2 = views));
httpMock.expectOne({}).flush({ TopBar: [{ url: 'a' }] });
let views3: NavigationViews | undefined;
navService.navigationViews.subscribe(views => (views3 = views));
expect(views2).toBe(views1);
expect(views3).toBe(views1);
// Verify that subsequent subscriptions did not trigger another request.
httpMock.expectNone({});
});
it('should do WHAT(?) if the request fails');
});
describe('node.tooltip', () => {
let view: NavigationNode[];
const sideNav: NavigationNode[] = [
{ title: 'a', tooltip: 'a tip' },
{ title: 'b' },
{ title: 'c!' },
{ url: 'foo' },
];
beforeEach(() => {
navService.navigationViews.subscribe(views => (view = views['sideNav']));
httpMock.expectOne({}).flush({ sideNav });
});
it('should have the supplied tooltip', () => {
expect(view[0].tooltip).toEqual('a tip');
});
it('should create a tooltip from title + period', () => {
expect(view[1].tooltip).toEqual('b.');
});
it('should create a tooltip from title, keeping its trailing punctuation', () => {
expect(view[2].tooltip).toEqual('c!');
});
it('should not create a tooltip if there is no title', () => {
expect(view[3].tooltip).toBeUndefined();
});
});
describe('currentNode', () => {
let currentNodes: CurrentNodes;
let locationService: MockLocationService;
const topBarNodes: NavigationNode[] = [{ url: 'features', title: 'Features', tooltip: 'tip' }];
const sideNavNodes: NavigationNode[] = [
{
title: 'a',
tooltip: 'tip',
children: [
{
url: 'b',
title: 'b',
tooltip: 'tip',
children: [{ url: 'c', title: 'c', tooltip: 'tip' }, { url: 'd', title: 'd', tooltip: 'tip' }],
},
{ url: 'e', title: 'e', tooltip: 'tip' },
],
},
{ url: 'f', title: 'f', tooltip: 'tip' },
];
const navJson = {
TopBar: topBarNodes,
SideNav: sideNavNodes,
__versionInfo: {},
};
beforeEach(() => {
locationService = (injector.get(LocationService) as any) as MockLocationService;
navService.currentNodes.subscribe(selected => (currentNodes = selected));
httpMock.expectOne({}).flush(navJson);
});
it('should list the side navigation node that matches the current location, and all its ancestors', () => {
locationService.go('b');
expect(currentNodes).toEqual({
SideNav: {
url: 'b',
view: 'SideNav',
nodes: [sideNavNodes[0].children![0], sideNavNodes[0]],
},
});
locationService.go('d');
expect(currentNodes).toEqual({
SideNav: {
url: 'd',
view: 'SideNav',
nodes: [sideNavNodes[0].children![0].children![1], sideNavNodes[0].children![0], sideNavNodes[0]],
},
});
locationService.go('f');
expect(currentNodes).toEqual({
SideNav: {
url: 'f',
view: 'SideNav',
nodes: [sideNavNodes[1]],
},
});
});
it('should be a TopBar selected node if the current location is a top menu node', () => {
locationService.go('features');
expect(currentNodes).toEqual({
TopBar: {
url: 'features',
view: 'TopBar',
nodes: [topBarNodes[0]],
},
});
});
it('should be a plain object if no navigation node matches the current location', () => {
locationService.go('g?search=moo#anchor-1');
expect(currentNodes).toEqual({
'': {
url: 'g',
view: '',
nodes: [],
},
});
});
it('should ignore trailing slashes, hashes, and search params on URLs in the navmap', () => {
const cnode: CurrentNodes = {
SideNav: {
url: 'c',
view: 'SideNav',
nodes: [sideNavNodes[0].children![0].children![0], sideNavNodes[0].children![0], sideNavNodes[0]],
},
};
locationService.go('c');
expect(currentNodes).toEqual(cnode, 'location: c');
locationService.go('c#foo');
expect(currentNodes).toEqual(cnode, 'location: c#foo');
locationService.go('c?foo=1');
expect(currentNodes).toEqual(cnode, 'location: c?foo=1');
locationService.go('c#foo?bar=1&baz=2');
expect(currentNodes).toEqual(cnode, 'location: c#foo?bar=1&baz=2');
});
});
describe('versionInfo', () => {
const expectedVersionInfo = { raw: '4.0.0' } as VersionInfo;
let versionInfo: VersionInfo;
beforeEach(() => {
navService.versionInfo.subscribe(info => (versionInfo = info));
httpMock.expectOne({}).flush({
__versionInfo: expectedVersionInfo,
});
});
it('should extract the version info', () => {
expect(versionInfo).toEqual(expectedVersionInfo);
});
});
describe('docVersions', () => {
let actualDocVersions: NavigationNode[];
let docVersions: NavigationNode[];
let expectedDocVersions: NavigationNode[];
beforeEach(() => {
actualDocVersions = [];
docVersions = [{ title: 'v4.0.0' }, { title: 'v2', url: 'https://v2.angular.io' }];
expectedDocVersions = docVersions.map(v => ({ ...v, ...{ tooltip: v.title + '.' } }));
navService.navigationViews.subscribe(views => (actualDocVersions = views['docVersions']));
});
it('should extract the docVersions', () => {
httpMock.expectOne({}).flush({ docVersions });
expect(actualDocVersions).toEqual(expectedDocVersions);
});
});
});