• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2018 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import {Router} from './router';
16
17const mockComponent = {
18  view() {},
19};
20
21describe('Router#resolve', () => {
22  beforeEach(() => {
23    window.location.hash = '';
24  });
25
26  test('Default route must be defined', () => {
27    expect(() => new Router({'/a': mockComponent})).toThrow();
28  });
29
30  test('Resolves empty route to default component', () => {
31    const router = new Router({'/': mockComponent});
32    window.location.hash = '';
33    expect(router.resolve().tag).toBe(mockComponent);
34  });
35
36  test('Resolves subpage route to component of main page', () => {
37    const nonDefaultComponent = {view() {}};
38    const router = new Router({
39      '/': mockComponent,
40      '/a': nonDefaultComponent,
41    });
42    window.location.hash = '#!/a/subpage';
43    expect(router.resolve().tag).toBe(nonDefaultComponent);
44    expect(router.resolve().attrs.subpage).toBe('/subpage');
45  });
46
47  test('Pass empty subpage if not found in URL', () => {
48    const nonDefaultComponent = {view() {}};
49    const router = new Router({
50      '/': mockComponent,
51      '/a': nonDefaultComponent,
52    });
53    window.location.hash = '#!/a';
54    expect(router.resolve().tag).toBe(nonDefaultComponent);
55    expect(router.resolve().attrs.subpage).toBe('');
56  });
57});
58
59describe('Router.parseUrl', () => {
60  // Can parse arguments from the search string.
61  test('Search parsing', () => {
62    const url = 'http://localhost?p=123&s=42&url=a?b?c';
63    const route = Router.parseUrl(url);
64    const args = route.args;
65    expect(args.p).toBe('123');
66    expect(args.s).toBe('42');
67    expect(args.url).toBe('a?b?c');
68    expect(route.fragment).toBe('');
69  });
70
71  // Or from the fragment string.
72  test('Fragment parsing', () => {
73    const url = 'http://localhost/#!/foo?p=123&s=42&url=a?b?c';
74    const route = Router.parseUrl(url);
75    const args = route.args;
76    expect(args.p).toBe('123');
77    expect(args.s).toBe('42');
78    expect(args.url).toBe('a?b?c');
79    expect(route.fragment).toBe('');
80  });
81
82  // Or both in which case fragment overrides the search.
83  test('Fragment parsing', () => {
84    const url =
85      'http://localhost/?p=1&s=2&hideSidebar=true#!/foo?s=3&url=4&hideSidebar=false';
86    const route = Router.parseUrl(url);
87    const args = route.args;
88    expect(args.p).toBe('1');
89    expect(args.s).toBe('3');
90    expect(args.url).toBe('4');
91    expect(args.hideSidebar).toBe(false);
92    expect(route.fragment).toBe('');
93  });
94
95  // + is also space
96  test('plus is space query', () => {
97    const url = 'http://localhost?query=(foo+%2B+bar),';
98    const route = Router.parseUrl(url);
99    const args = route.args;
100    expect(args.query).toBe('(foo + bar),');
101  });
102
103  // + is also space
104  test('plus is space hash', () => {
105    const url = 'http://localhost#!/foo?query=(foo+%2B+bar),';
106    const route = Router.parseUrl(url);
107    const args = route.args;
108    expect(args.query).toBe('(foo + bar),');
109  });
110
111  test('Nested fragment', () => {
112    const url =
113      'http://localhost/?p=1&s=2&hideSidebar=true#!/foo?s=3&url=4&hideSidebar=false#myfragment';
114    const route = Router.parseUrl(url);
115    expect(route.fragment).toBe('myfragment');
116  });
117});
118
119describe('Router.parseFragment', () => {
120  test('empty route broken into empty components', () => {
121    const {page, subpage, args} = Router.parseFragment('');
122    expect(page).toBe('');
123    expect(subpage).toBe('');
124    expect(args.mode).toBe(undefined);
125  });
126
127  test('by default args are undefined', () => {
128    // This prevents the url from becoming messy.
129    const {args} = Router.parseFragment('');
130    expect(args).toEqual({});
131  });
132
133  test('invalid route broken into empty components', () => {
134    const {page, subpage} = Router.parseFragment('/bla');
135    expect(page).toBe('');
136    expect(subpage).toBe('');
137  });
138
139  test('simple route has page defined', () => {
140    const {page, subpage} = Router.parseFragment('#!/record');
141    expect(page).toBe('/record');
142    expect(subpage).toBe('');
143  });
144
145  test('simple route has both components defined', () => {
146    const {page, subpage} = Router.parseFragment('#!/record/memory');
147    expect(page).toBe('/record');
148    expect(subpage).toBe('/memory');
149  });
150
151  test('route broken at first slash', () => {
152    const {page, subpage} = Router.parseFragment('#!/record/memory/stuff');
153    expect(page).toBe('/record');
154    expect(subpage).toBe('/memory/stuff');
155  });
156
157  test('parameters separated from route', () => {
158    const {page, subpage, args} = Router.parseFragment(
159      '#!/record/memory?url=http://localhost:1234/aaaa',
160    );
161    expect(page).toBe('/record');
162    expect(subpage).toBe('/memory');
163    expect(args.url).toEqual('http://localhost:1234/aaaa');
164  });
165
166  test('openFromAndroidBugTool can be false', () => {
167    const {args} = Router.parseFragment('#!/?openFromAndroidBugTool=false');
168    expect(args.openFromAndroidBugTool).toEqual(false);
169  });
170
171  test('openFromAndroidBugTool can be true', () => {
172    const {args} = Router.parseFragment('#!/?openFromAndroidBugTool=true');
173    expect(args.openFromAndroidBugTool).toEqual(true);
174  });
175
176  test('bad modes are coerced to default', () => {
177    const {args} = Router.parseFragment('#!/?mode=1234');
178    expect(args.mode).toEqual(undefined);
179  });
180
181  test('bad hideSidebar is coerced to default', () => {
182    const {args} = Router.parseFragment('#!/?hideSidebar=helloworld!');
183    expect(args.hideSidebar).toEqual(undefined);
184  });
185});
186