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 {dingus} from 'dingusjs'; 16 17import {Actions, DeferredAction} from '../common/actions'; 18 19import {Router} from './router'; 20 21const mockComponent = { 22 view() {} 23}; 24 25const fakeDispatch = () => {}; 26 27beforeEach(() => { 28 window.onhashchange = null; 29 window.location.hash = ''; 30}); 31 32test('Default route must be defined', () => { 33 expect(() => new Router('/a', {'/b': mockComponent}, fakeDispatch)).toThrow(); 34}); 35 36test('Resolves empty route to default component', () => { 37 const router = new Router('/a', {'/a': mockComponent}, fakeDispatch); 38 expect(router.resolve('')).toBe(mockComponent); 39 expect(router.resolve(null)).toBe(mockComponent); 40}); 41 42test('Parse route from hash', () => { 43 const router = new Router('/', {'/': mockComponent}, fakeDispatch); 44 window.location.hash = '#!/foobar?s=42'; 45 expect(router.getRouteFromHash()).toBe('/foobar'); 46 47 window.location.hash = '/foobar'; // Invalid prefix. 48 expect(router.getRouteFromHash()).toBe(''); 49}); 50 51test('Set valid route on hash', () => { 52 const dispatch = dingus<(a: DeferredAction) => void>(); 53 const router = new Router( 54 '/', 55 { 56 '/': mockComponent, 57 '/a': mockComponent, 58 }, 59 dispatch); 60 const prevHistoryLength = window.history.length; 61 62 router.setRouteOnHash('/a'); 63 expect(window.location.hash).toBe('#!/a'); 64 expect(window.history.length).toBe(prevHistoryLength + 1); 65 // No navigation action should be dispatched. 66 expect(dispatch.calls.length).toBe(0); 67}); 68 69test('Redirects to default for invalid route in setRouteOnHash ', () => { 70 const dispatch = dingus<(a: DeferredAction) => void>(); 71 // const dispatch = () => {console.log("action received")}; 72 73 const router = new Router('/', {'/': mockComponent}, dispatch); 74 router.setRouteOnHash('foo'); 75 expect(dispatch.calls.length).toBe(1); 76 expect(dispatch.calls[0][1].length).toBeGreaterThanOrEqual(1); 77 expect(dispatch.calls[0][1][0]).toEqual(Actions.navigate({route: '/'})); 78}); 79 80test('Navigate on hash change', done => { 81 const mockDispatch = (a: DeferredAction) => { 82 expect(a).toEqual(Actions.navigate({route: '/viewer'})); 83 done(); 84 }; 85 new Router( 86 '/', 87 { 88 '/': mockComponent, 89 '/viewer': mockComponent, 90 }, 91 mockDispatch); 92 window.location.hash = '#!/viewer'; 93}); 94 95test('Redirects to default when invalid route set in window location', done => { 96 const mockDispatch = (a: DeferredAction) => { 97 expect(a).toEqual(Actions.navigate({route: '/'})); 98 done(); 99 }; 100 101 new Router( 102 '/', 103 { 104 '/': mockComponent, 105 '/viewer': mockComponent, 106 }, 107 mockDispatch); 108 109 window.location.hash = '#invalid'; 110}); 111 112test('navigateToCurrentHash with valid current route', () => { 113 const dispatch = dingus<(a: DeferredAction) => void>(); 114 window.location.hash = '#!/b'; 115 const router = 116 new Router('/', {'/': mockComponent, '/b': mockComponent}, dispatch); 117 router.navigateToCurrentHash(); 118 expect(dispatch.calls[0][1][0]).toEqual(Actions.navigate({route: '/b'})); 119}); 120 121test('navigateToCurrentHash with invalid current route', () => { 122 const dispatch = dingus<(a: DeferredAction) => void>(); 123 window.location.hash = '#!/invalid'; 124 const router = new Router('/', {'/': mockComponent}, dispatch); 125 router.navigateToCurrentHash(); 126 expect(dispatch.calls[0][1][0]).toEqual(Actions.navigate({route: '/'})); 127}); 128 129test('Params parsing', () => { 130 window.location.hash = '#!/foo?a=123&b=42&c=a?b?c'; 131 expect(Router.param('a')).toBe('123'); 132 expect(Router.param('b')).toBe('42'); 133 expect(Router.param('c')).toBe('a?b?c'); 134}); 135