150 lines
5 KiB
JavaScript
150 lines
5 KiB
JavaScript
import Service from '@ember/service';
|
|
import Route from '@ember/routing/route';
|
|
import Controller from '@ember/controller';
|
|
import { get } from '@ember/object';
|
|
import { alias } from '@ember/object/computed';
|
|
import { getOwner } from '@ember/application';
|
|
import RSVP from 'rsvp';
|
|
import { moduleFor, test } from 'ember-qunit';
|
|
import PromiseObject from 'nomad-ui/utils/classes/promise-object';
|
|
|
|
const makeRoute = (crumbs, controller = {}) =>
|
|
Route.extend({
|
|
breadcrumbs: crumbs,
|
|
controller: Controller.extend(controller).create(),
|
|
});
|
|
|
|
moduleFor('service:breadcrumbs', 'Unit | Service | Breadcrumbs', {
|
|
beforeEach() {
|
|
const mockRouter = Service.extend({
|
|
currentRouteName: 'application',
|
|
currentURL: '/',
|
|
});
|
|
|
|
this.register('service:router', mockRouter);
|
|
this.router = getOwner(this).lookup('service:router');
|
|
|
|
const none = makeRoute();
|
|
const fixed = makeRoute([{ label: 'Static', args: ['static.index'] }]);
|
|
const manyFixed = makeRoute([
|
|
{ label: 'Static 1', args: ['static.index', 1] },
|
|
{ label: 'Static 2', args: ['static.index', 2] },
|
|
]);
|
|
const dynamic = makeRoute(model => [{ label: model, args: ['dynamic.index', model] }], {
|
|
model: 'Label of the Crumb',
|
|
});
|
|
const manyDynamic = makeRoute(
|
|
model => [
|
|
{ label: get(model, 'fishOne'), args: ['dynamic.index', get(model, 'fishOne')] },
|
|
{ label: get(model, 'fishTwo'), args: ['dynamic.index', get(model, 'fishTwo')] },
|
|
],
|
|
{
|
|
model: {
|
|
fishOne: 'red',
|
|
fishTwo: 'blue',
|
|
},
|
|
}
|
|
);
|
|
const promise = makeRoute([
|
|
PromiseObject.create({
|
|
promise: RSVP.Promise.resolve({
|
|
label: 'delayed',
|
|
args: ['wait.for.it'],
|
|
}),
|
|
}),
|
|
]);
|
|
const fromURL = makeRoute(model => [{ label: model, args: ['url'] }], {
|
|
router: getOwner(this).lookup('service:router'),
|
|
model: alias('router.currentURL'),
|
|
});
|
|
|
|
this.register('route:none', none);
|
|
this.register('route:none.more-none', none);
|
|
this.register('route:static', fixed);
|
|
this.register('route:static.many', manyFixed);
|
|
this.register('route:dynamic', dynamic);
|
|
this.register('route:dynamic.many', manyDynamic);
|
|
this.register('route:promise', promise);
|
|
this.register('route:url', fromURL);
|
|
},
|
|
|
|
subject() {
|
|
return getOwner(this)
|
|
.factoryFor('service:breadcrumbs')
|
|
.create();
|
|
},
|
|
});
|
|
|
|
test('when the route hierarchy has no breadcrumbs', function(assert) {
|
|
this.router.set('currentRouteName', 'none');
|
|
|
|
const service = this.subject();
|
|
assert.deepEqual(service.get('breadcrumbs'), []);
|
|
});
|
|
|
|
test('when the route hierarchy has one segment with static crumbs', function(assert) {
|
|
this.router.set('currentRouteName', 'static');
|
|
|
|
const service = this.subject();
|
|
assert.deepEqual(service.get('breadcrumbs'), [{ label: 'Static', args: ['static.index'] }]);
|
|
});
|
|
|
|
test('when the route hierarchy has multiple segments with static crumbs', function(assert) {
|
|
this.router.set('currentRouteName', 'static.many');
|
|
|
|
const service = this.subject();
|
|
assert.deepEqual(service.get('breadcrumbs'), [
|
|
{ label: 'Static', args: ['static.index'] },
|
|
{ label: 'Static 1', args: ['static.index', 1] },
|
|
{ label: 'Static 2', args: ['static.index', 2] },
|
|
]);
|
|
});
|
|
|
|
test('when the route hierarchy has a function as its breadcrumbs property', function(assert) {
|
|
this.router.set('currentRouteName', 'dynamic');
|
|
|
|
const service = this.subject();
|
|
assert.deepEqual(service.get('breadcrumbs'), [
|
|
{ label: 'Label of the Crumb', args: ['dynamic.index', 'Label of the Crumb'] },
|
|
]);
|
|
});
|
|
|
|
test('when the route hierarchy has multiple segments with dynamic crumbs', function(assert) {
|
|
this.router.set('currentRouteName', 'dynamic.many');
|
|
|
|
const service = this.subject();
|
|
assert.deepEqual(service.get('breadcrumbs'), [
|
|
{ label: 'Label of the Crumb', args: ['dynamic.index', 'Label of the Crumb'] },
|
|
{ label: 'red', args: ['dynamic.index', 'red'] },
|
|
{ label: 'blue', args: ['dynamic.index', 'blue'] },
|
|
]);
|
|
});
|
|
|
|
test('when a route provides a breadcrumb that is a promise, it gets passed through to the template', function(assert) {
|
|
this.router.set('currentRouteName', 'promise');
|
|
|
|
const service = this.subject();
|
|
assert.ok(service.get('breadcrumbs.firstObject') instanceof PromiseObject);
|
|
});
|
|
|
|
// This happens when transitioning to the current route but with a different model
|
|
// jobs.job.index --> jobs.job.index
|
|
// /jobs/one --> /jobs/two
|
|
test('when the route stays the same but the url changes, breadcrumbs get recomputed', function(assert) {
|
|
this.router.set('currentRouteName', 'url');
|
|
|
|
const service = this.subject();
|
|
assert.deepEqual(
|
|
service.get('breadcrumbs'),
|
|
[{ label: '/', args: ['url'] }],
|
|
'The label is initially / as is the router currentURL'
|
|
);
|
|
|
|
this.router.set('currentURL', '/somewhere/else');
|
|
assert.deepEqual(
|
|
service.get('breadcrumbs'),
|
|
[{ label: '/somewhere/else', args: ['url'] }],
|
|
'The label changes with currentURL since it is an alias and a change to currentURL recomputes breadcrumbs'
|
|
);
|
|
});
|