I have an auth service that I'm trying to write a unit test for.
When there isn't a previous transition stored in the Auth service, it redirects to a specific route.
The app works as expected, however the tests for this service give the following error:
Uncaught TypeError: Cannot read property 'hasRoute' of undefined
I don't know how to debug / solve this. What's going on?
Here's my auth service:
import Ember from 'ember';
import config from '../config/environment';
export default Ember.Service.extend({
routing: Ember.inject.service('-routing'),
loginCapable: true,
localStorageKey: config.localStorageKeys.user,
checkAuth(priorTransition){
this.set('priorTransition', priorTransition);
return this.get('isLoggedIn');
},
isLoggedIn: Ember.computed('user', function(){
return !!this.get('user');
}),
init(){
this.set('user', JSON.parse(window.localStorage.getItem( this.get("localStorageKey") )) );
},
login(adID){
return Ember.$.ajax(
config.apiHost + config.apiVersion + "/getLdapInfo",{
type: 'GET',
data: "adID="+adID
}).then(json => {
this.set('user', json);
window.localStorage.setItem( this.get("localStorageKey") , JSON.stringify(json));
var priorTransition = this.get('priorTransition');
if( priorTransition )
{
priorTransition.retry();
this.set('priorTransition', null);
}else{
this.get('routing').transitionTo('index');
}
}, xhr => {
return xhr.responseJSON ? xhr.responseJSON.message : "Login failed";
});
}
});
And my router:
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('authenticated', { path: '/' }, function(){
this.route('index', { resetNamespace: true });
});
this.route('login');
});
export default Router;
Here's the test for that service:
import { moduleFor, test } from 'ember-qunit';
import Ember from 'ember';
import startApp from 'recruiter-admin/tests/helpers/start-app';
import Pretender from 'pretender';
var server,
application;
var user = [{
"adID":"uniqueID",
"first_name":"First Name",
"last_name":"Last Name",
"employee_type":"Regular",
"employee_id":"12345",
"manager":"CN=managerID,OU=Employees,OU=company Users,DC=company,DC=com",
"success":true
}];
function jsonResponse(json, status = 200) {
return [status, {"Content-Type": "application/json"}, JSON.stringify(json)];
}
moduleFor('service:auth', 'Unit | Service | auth', {
unit:true,
needs:['router:main'],
beforeEach(){
application = startApp();
server = new Pretender(function(){
this.get('/getLdapInfo', function(req){
return jsonResponse(user.findBy('adID',req.queryParams.adID));
});
});
},
afterEach(){
Ember.run(application, 'destroy');
if( server ){
server.shutdown();
}
}
});
// Replace this with your real tests.
test('it exists', function(assert) {
var service = this.subject();
assert.ok(service);
});
test('isLoggedIn Testing', function(assert){
var service = this.subject();
assert.ok(service.get('isLoggedIn') === false, 'Not logged in');
Ember.run(()=>{
service.set('user', true);
});
assert.ok(service.get('isLoggedIn') === true, 'IS logged in');
});
test('can login', function(assert){
assert.expect(0);
var service = this.subject();
Ember.run(()=>{
service.login('uniqueID');
});
andThen(()=>{
assert.ok(service.get('user'));
});
});
Using Ember 2.0.0-beta.5
You are using the private -routing
service, it expects to have a router
instance initialized and setup. This test does not do that, so you either have to mock it or setup the router.
I am not opposed to tweaking https://github.com/emberjs/ember.js/blob/master/packages/ember-routing/lib/services/routing.js#L37 a bit to prevent this error (it should ultimately return false if get(this, 'router')
is falsey) if you want to submit a PR, but using private API's in a non-supported way isn't a bug.
Closing this issue, but I'd happily review a PR.
Late for the game, but I just want to show the way I did to solve such issues.
Just override the methods.
const service = this.subject({
routing: {
transitionTo() {
return true;
}
}
})
I'm doing this because I've written tests for testing different routes itself, also trust on ember team to test ember/service/routing.js
this.owner.unregister('service:router');
this.owner.register('service:router', mocks.routerService());
One way of stubbing it without failing the test case
Most helpful comment
You are using the private
-routing
service, it expects to have arouter
instance initialized and setup. This test does not do that, so you either have to mock it or setup the router.I am not opposed to tweaking https://github.com/emberjs/ember.js/blob/master/packages/ember-routing/lib/services/routing.js#L37 a bit to prevent this error (it should ultimately return false if
get(this, 'router')
is falsey) if you want to submit a PR, but using private API's in a non-supported way isn't a bug.