github.com/zoomfoo/nomad@v0.8.5-0.20180907175415-f28fd3a1a056/ui/tests/unit/services/breadcrumbs-test.js (about) 1 import Service from '@ember/service'; 2 import Route from '@ember/routing/route'; 3 import Controller from '@ember/controller'; 4 import { get } from '@ember/object'; 5 import { alias } from '@ember/object/computed'; 6 import { getOwner } from '@ember/application'; 7 import RSVP from 'rsvp'; 8 import { moduleFor, test } from 'ember-qunit'; 9 import PromiseObject from 'nomad-ui/utils/classes/promise-object'; 10 11 const makeRoute = (crumbs, controller = {}) => 12 Route.extend({ 13 breadcrumbs: crumbs, 14 controller: Controller.extend(controller).create(), 15 }); 16 17 moduleFor('service:breadcrumbs', 'Unit | Service | Breadcrumbs', { 18 beforeEach() { 19 const mockRouter = Service.extend({ 20 currentRouteName: 'application', 21 currentURL: '/', 22 }); 23 24 this.register('service:router', mockRouter); 25 this.router = getOwner(this).lookup('service:router'); 26 27 const none = makeRoute(); 28 const fixed = makeRoute([{ label: 'Static', args: ['static.index'] }]); 29 const manyFixed = makeRoute([ 30 { label: 'Static 1', args: ['static.index', 1] }, 31 { label: 'Static 2', args: ['static.index', 2] }, 32 ]); 33 const dynamic = makeRoute(model => [{ label: model, args: ['dynamic.index', model] }], { 34 model: 'Label of the Crumb', 35 }); 36 const manyDynamic = makeRoute( 37 model => [ 38 { label: get(model, 'fishOne'), args: ['dynamic.index', get(model, 'fishOne')] }, 39 { label: get(model, 'fishTwo'), args: ['dynamic.index', get(model, 'fishTwo')] }, 40 ], 41 { 42 model: { 43 fishOne: 'red', 44 fishTwo: 'blue', 45 }, 46 } 47 ); 48 const promise = makeRoute([ 49 PromiseObject.create({ 50 promise: RSVP.Promise.resolve({ 51 label: 'delayed', 52 args: ['wait.for.it'], 53 }), 54 }), 55 ]); 56 const fromURL = makeRoute(model => [{ label: model, args: ['url'] }], { 57 router: getOwner(this).lookup('service:router'), 58 model: alias('router.currentURL'), 59 }); 60 61 this.register('route:none', none); 62 this.register('route:none.more-none', none); 63 this.register('route:static', fixed); 64 this.register('route:static.many', manyFixed); 65 this.register('route:dynamic', dynamic); 66 this.register('route:dynamic.many', manyDynamic); 67 this.register('route:promise', promise); 68 this.register('route:url', fromURL); 69 }, 70 71 subject() { 72 return getOwner(this) 73 .factoryFor('service:breadcrumbs') 74 .create(); 75 }, 76 }); 77 78 test('when the route hierarchy has no breadcrumbs', function(assert) { 79 this.router.set('currentRouteName', 'none'); 80 81 const service = this.subject(); 82 assert.deepEqual(service.get('breadcrumbs'), []); 83 }); 84 85 test('when the route hierarchy has one segment with static crumbs', function(assert) { 86 this.router.set('currentRouteName', 'static'); 87 88 const service = this.subject(); 89 assert.deepEqual(service.get('breadcrumbs'), [{ label: 'Static', args: ['static.index'] }]); 90 }); 91 92 test('when the route hierarchy has multiple segments with static crumbs', function(assert) { 93 this.router.set('currentRouteName', 'static.many'); 94 95 const service = this.subject(); 96 assert.deepEqual(service.get('breadcrumbs'), [ 97 { label: 'Static', args: ['static.index'] }, 98 { label: 'Static 1', args: ['static.index', 1] }, 99 { label: 'Static 2', args: ['static.index', 2] }, 100 ]); 101 }); 102 103 test('when the route hierarchy has a function as its breadcrumbs property', function(assert) { 104 this.router.set('currentRouteName', 'dynamic'); 105 106 const service = this.subject(); 107 assert.deepEqual(service.get('breadcrumbs'), [ 108 { label: 'Label of the Crumb', args: ['dynamic.index', 'Label of the Crumb'] }, 109 ]); 110 }); 111 112 test('when the route hierarchy has multiple segments with dynamic crumbs', function(assert) { 113 this.router.set('currentRouteName', 'dynamic.many'); 114 115 const service = this.subject(); 116 assert.deepEqual(service.get('breadcrumbs'), [ 117 { label: 'Label of the Crumb', args: ['dynamic.index', 'Label of the Crumb'] }, 118 { label: 'red', args: ['dynamic.index', 'red'] }, 119 { label: 'blue', args: ['dynamic.index', 'blue'] }, 120 ]); 121 }); 122 123 test('when a route provides a breadcrumb that is a promise, it gets passed through to the template', function(assert) { 124 this.router.set('currentRouteName', 'promise'); 125 126 const service = this.subject(); 127 assert.ok(service.get('breadcrumbs.firstObject') instanceof PromiseObject); 128 }); 129 130 // This happens when transitioning to the current route but with a different model 131 // jobs.job.index --> jobs.job.index 132 // /jobs/one --> /jobs/two 133 test('when the route stays the same but the url changes, breadcrumbs get recomputed', function(assert) { 134 this.router.set('currentRouteName', 'url'); 135 136 const service = this.subject(); 137 assert.deepEqual( 138 service.get('breadcrumbs'), 139 [{ label: '/', args: ['url'] }], 140 'The label is initially / as is the router currentURL' 141 ); 142 143 this.router.set('currentURL', '/somewhere/else'); 144 assert.deepEqual( 145 service.get('breadcrumbs'), 146 [{ label: '/somewhere/else', args: ['url'] }], 147 'The label changes with currentURL since it is an alias and a change to currentURL recomputes breadcrumbs' 148 ); 149 });