Jason
Jason

Reputation: 11363

angular ui-router test state

I'm writing up a series of unit tests for a login module. Right now, all the failures are being applied as expected. However, I'm having an issue testing a valid login because the test is returning an error Could not resolve 'models' from state '' for the valid login test.

Given an authentication service that takes in a return message from the server and transitions

angular.module('qServices').service('qsAuthentication', function($resource, qsSession, 
               REST_ROOT, $state){

    var Session = $resource(REST_ROOT + 'session');

    this.login = function(credentials, errorHandler){

        //does a POST
        Session.save({}, credentials, function(response){
            if (response.success === true){
                qsSession.refresh();
                $state.go('models'); //TODO: "default" state
            }

and the state is defined in

angular.module('qRouting', ['ui.router'])
    .config(function($stateProvider){

    $stateProvider.state('models', {
        parent: 'base',
        templateUrl: 'modules/models/models-view.html',
        controller: 'qcModels',
        url: '/models'
    })

So, basically what happens here is if response.success is true, the state transitions to the /models URL and loads the approprate template. Unfortunately, the test is returning an error Could not resolve 'models' from state '' for the test

describe("Login Test: ", function()
{
    var $httpBackend,
        rootScope,
        scope,
        qsAuthentication,
        loginError,
        REST_ROOT,
        state,
        templateCache;

    beforeEach(module("qLogin"));

    beforeEach(inject(function($injector)
    {
        $httpBackend = $injector.get("$httpBackend");
        REST_ROOT = $injector.get("REST_ROOT");
        state = $injector.get("$state");
        qsAuthentication = $injector.get("qsAuthentication");
        rootScope = $injector.get("$rootScope");
        scope = rootScope.$new();
        templateCache = $injector.get("$templateCache");

        scope.credentials = {
            username : "dummytest",
            password : "dummypass"
        };

        loginError = function(errorMessage)
        {
            scope.loginErrorMessage = errorMessage;
        };

        templateCache.put('modules/models/models-view.html');
    }));

    it("Should send a valid login request", function ()
    {
        $httpBackend.expectPOST(REST_ROOT + "session", scope.credentials)
            .respond(200, {success : true});
        qsAuthentication.login(scope.credentials, loginError);
        rootScope.$apply();
        $httpBackend.flush();

        expect(state.current.name).toBe("models");
    });
};

The error happens at

$state.go("models"); 

line in the service. How can I resolve this issue?

Upvotes: 0

Views: 569

Answers (1)

Radim Köhler
Radim Köhler

Reputation: 123861

I would guess, that we are facing "missing module dependency" here.

The point is, that module qLogin which will be tested :

// this module will be tested
beforeEach(module("qLogin"));
...

Is working with state 'models' - defined in other module 'qRouting':

angular.module('qRouting', ['ui.router'])
    .config(function($stateProvider){

        $stateProvider.state('models', {
        ...

While we cannot see the module 'qLogin' declaration (setter), I would expect, that it is missing the dependency to module 'qRouting':

// module 'qRouting' is not having access to qLogin
angular.module('qRouting', ['ui.router'])

So, solution here should be extending that module declaration

// now we have state 'models' in the test domain
angular.module('qRouting', ['ui.router', 'qLogin'])

Upvotes: 1

Related Questions