jeudi 27 août 2015

testing angular API calls with mocked backend and interceptor which adds necessary headers

I have a controller which when instantiated on route navigation fetches data from API if there is an id in ui-router's stateParams. If there is no id in stateParams then just create a new object and assign it to a model rate. I have a Rate factory which fetches data from the API.

I want to test this functionality with jasmine and karma. activate function is called every time the controller is instantiated on route navigation. I would like to check if an API call is made and the appropriate values are set in models.

There is a gotcha. I have an interceptor which adds headers to the request.
The relevant code is below.

controller:

RatesCtrl.$inject = ['$state', '$stateParams', 'Rate', 'toastr', 'appConstants'];

function RatesCtrl($state, $stateParams, Rate, toastr, appConstants){
var vm = this;

activate();

function activate(){
  if($stateParams.id){
    Rate.get({id: $stateParams.id})
      .$promise
      .then(function(response){
        vm.rate = response.data.rate;

        vm.formHeader = 'Edit Rate';
        vm.submitBtn = 'Update';
      })
  }
  else{
    var start = new Date();
    start.setHours(0,0,0,0);

    vm.rate = {
      effective_from: start,
      effective_upto: start
    }

    vm.formHeader = 'Add New Rate';
    vm.submitBtn = 'Add';
  }
}

interceptor:

angular.module('demo')
    .factory('SessionInjector', SessionInjector);

    SessionInjector.$inject = ['ipCookie', 'CookieHandler', '$location', 'toastr', '$q', '$rootScope'];
    function SessionInjector(ipCookie, CookieHandler, $location, toastr, $q, $rootScope){
      return {
        request: function(config) {
          var user = CookieHandler.get();
          config.headers['Accept'] = 'application/vnd.botsworth.v1+json';
          if (user !== undefined) {
            config.headers['Authorization'] = user.auth_token;
          }
          return config;
        },
        responseError: function(response){
          switch(response.status){
            case 401:                 
                $rootScope.loggedIn = false;
                CookieHandler.delete();
                $location.path('/sign_in');
              }
              break;
            case 0:
              break;
            case 500:
              console.log(response);
              // server error which returns status 500
              toastr.error('Something went wrong. Please refresh your page.', 'Error');
              break;
            default:
              // other error scenarios like 422(unprocessable entity)
              toastr.error(response.data.message, 'Error');
          }
          return $q.reject(response);
        }
      }
    }

I'm not sure how I can test this code as I am not calling it explicitly and the model values are set when the promise resolves.

Also to mock the the CookieHandler I have this code.

beforeEach(module(function($provide){
    $provide.factory("CookieHandler", function(){
      var user = { name: "Test", auth_token: "123" };
      var cookieHandler = {
        set: function(user){ user = user;},
        get: function(){
          return(user);
        },
        delete: function(){}
      }
      return cookieHandler;
    });
  }));

I have created 2 different describe. One for when $stateParams has an id and one where id is not present.

Aucun commentaire:

Enregistrer un commentaire