Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uncaught TypeError: Cannot read property 'hasRoute' of undefined #12052

Closed
csprocket777 opened this issue Aug 11, 2015 · 4 comments
Closed

Uncaught TypeError: Cannot read property 'hasRoute' of undefined #12052

csprocket777 opened this issue Aug 11, 2015 · 4 comments

Comments

@csprocket777
Copy link

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

@rwjblue
Copy link
Member

rwjblue commented Aug 12, 2015

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.

@rwjblue
Copy link
Member

rwjblue commented Aug 12, 2015

Closing this issue, but I'd happily review a PR.

@rwjblue rwjblue closed this as completed Aug 12, 2015
@ldong
Copy link

ldong commented Feb 2, 2017

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

@Amerr
Copy link

Amerr commented Mar 14, 2019

this.owner.unregister('service:router');
this.owner.register('service:router', mocks.routerService());

One way of stubbing it without failing the test case

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants