Having a simulated service dependency that returns a promise is causing challenges when testing

I provide three essential services. The RequestAuthorizationService reaches out to the OAuthAuthorizationDataService for token-based authorization credentials, which are then securely stored in session storage by the sessionStorageManagerService.

The focus of the test lies on verifying the invocation of the sessionStorageManagerService.set() method. I am having trouble ensuring that this method is indeed being called.

Despite reviewing numerous resources, I am unable to pinpoint the issue when trying to confirm the method call within the 'then' block. Every time I run the test, it claims that the method was not executed. Any insights or guidance on this matter would be greatly appreciated!

Below you can find the corresponding code snippets:

RequestAuthorizationService

(function () {
    'use strict';

    var serviceId = 'requestAuthorizationService';

    angular
        .module('dilib')
        .service(serviceId, requestAuthorizationService);

    requestAuthorizationService.$inject = ['$q', 'Restangular', 'cryptoService', 'OAuthAuthenticationDataService', 'sessionStorageManagerService'];

    function requestAuthorizationService($q, Restangular, cryptoService, OAuthAuthenticationDataService, sessionStorageManagerService) {

        //API
        var service = {

            requestAuthorization: requestAuthorization,
        }

        return service;

        /////////////////////////////////////////////////////////////////////

        function requestAuthorization(user) {

            var defer = $q.defer();

            var userLocal = undefined;

            if (typeof user === "undefined") {

                userLocal = {
                    username: 'visitor',
                    password: cryptoService.getMD5('qwe123')
                };
            } else {

                userLocal = user;

            }

            OAuthAuthenticationDataService.authenticate(userLocal).then(function (result) {

                //To be tested
                sessionStorageManagerService.set('authorizationData',
                {
                    token: result.access_token,
                    username: user.username
                });

                defer.resolve(userdata.username);

            }, function (msg) {

                defer.reject(msg);

            });

            return defer.promise;
        }

    }
})();

OAuthAuthenticationDataService

(function () {
    'use strict';

    var serviceId = 'OAuthAuthenticationDataService';

    angular
        .module('dilib')
        .service(serviceId, OAuthAuthenticationDataService);

    OAuthAuthenticationDataService.$inject = ['Restangular'];

    function OAuthAuthenticationDataService(Restangular) {

        var OAuthHttpHeader = {
            "Content-Type": 'application/x-www-form-urlencoded'
        };

        var oAuthEndpointResource = Restangular.all('/token');

        var service = {

            authenticate : authenticate

        }

        return service;


        function authenticate(user) {

            return oAuthEndpointResource.post('grant_type=password&username=' + user.username + '&password=' + user.password, {}, OAuthHttpHeader);

        }
    }
})();

sessionStorageManagerService

(function () {
    'use strict';

    var serviceId = 'sessionStorageManagerService';

    angular
        .module('dilib')
        .service(serviceId, sessionStorageManagerService);

    sessionStorageManagerService.$inject = ['localStorageService'];

    function sessionStorageManagerService(localStorageService) {

        var service = {

            get: get,
            set: set

        };

        return service;

        function set(key, val) {

            localStorageService.set(key, val);

        }

        function get(key) {

            return localStorageService.get(key);

        }

    }
})();

Test

describe('requestAuthorizationService', function () {

    var RestangularProvider,
        localStorageServiceProvider,
        cryptoServiceMockSvc,
        OAuthAuthenticationDataServiceMockSvc,
        sessionStorageManagerServiceMockSvc,
        requestAuthorizationService,
        $q,
        $rootScope;

    beforeEach(function () {

        angular.module('ngAnimate', []);
        angular.module('ngRoute', []);
        angular.module('dilib.layout', []);
        //angular.module('LocalStorageModule', []);
        angular.module('http-auth-interceptor', []);
        //angular.module('restangular', []);

    });

    beforeEach(function () {

        module('dilib', function (_RestangularProvider_, _localStorageServiceProvider_) {

            RestangularProvider = _RestangularProvider_;
            localStorageServiceProvider = _localStorageServiceProvider_;

        });

    });

    //beforeEach(inject());

    beforeEach(function () {

        module(function ($provide) {

            $provide.service('cryptoService', function () {
                this.getMD5 = jasmine.createSpy('getMD5').and.callFake(function (param) {

                    var returnVal;

                    if (param == 'qwe123') {

                        returnVal = '200820e3227815ed1756a6b531e7e0d2';
                    }

                    if (param == 'qwe321') {

                        returnVal = 'blabla';
                    }

                    return returnVal;
                });
            });

            $provide.service('OAuthAuthenticationDataService', function () {
                this.authenticate = jasmine.createSpy('authenticate').and.callFake(function (userObject) {

                    var defer = $q.defer();
                    defer.resolve({ access_token: '1234' });
                    return defer.promise;

                });
            });

            $provide.service('sessionStorageManagerService', function () {

                this.get = jasmine.createSpy('get').and.callFake(function(param) {
                    return param;
                });
                this.set = jasmine.createSpy('set').and.callFake(function(param) {
                    return param;
                });

            });

        });

    });

    beforeEach(inject(function (cryptoService,
                                OAuthAuthenticationDataService,
                                sessionStorageManagerService,
                                _requestAuthorizationService_,
                                _$q_,
                                _$rootScope_) {

        cryptoServiceMockSvc = cryptoService;
        OAuthAuthenticationDataServiceMockSvc = OAuthAuthenticationDataService;
        sessionStorageManagerServiceMockSvc = sessionStorageManagerService;
        requestAuthorizationService = _requestAuthorizationService_;
        $q = _$q_;
        $rootScope = _$rootScope_;

    }));

    describe('requestAuthorization method', function () {

        describe('OAuth authentication result will be passed through sessionStorageManager', function () {

            it('default value result will be passed through', function () {

                //try 1
                // OAuthAuthenticationDataServiceMockSvc.authenticate().then(function(result) {

                    // console.log('result', result);

                    // expect(sessionStorageManagerServiceMockSvc.set).toHaveBeenCalled();

                // });

                // $rootScope.$digest();

                //try 2
                // OAuthAuthenticationDataServiceMockSvc.authenticate();

                // expect(sessionStorageManagerServiceMockSvc.set).toHaveBeenCalled();

                //-----------------

                // $rootScope.$digest();

            });

        });

    });

});

Answer №1

The authentication function has a simulated implementation that does not interact with the sessionStorageManagerService.

Upon reviewing your code, I did not find any instances of sessionStorageManagerService.set being called.

Answer №2

I believe this solution will be beneficial

var $scope;
var $q;
var deferred;
var sessionStorageManagerService;
var requestAuthorizationService;
var OAuthAuthenticationDataService;

/* Mocking other necessary modules */

beforeEach(function() {
    angular.mock.module(function($provide) {
        sessionStorageManagerService = jasmine.createSpyObj('sessionStorageManagerService', ['set', 'get']);

        $provide.value('sessionStorageManagerService', sessionStorageManagerService);
    });
});

beforeEach(function() {
    angular.mock.module(function($provide) {
        OAuthAuthenticationDataService = jasmine.createSpyObj('OAuthAuthenticationDataService', ['authenticate']);

        $provide.value('OAuthAuthenticationDataService', OAuthAuthenticationDataService);
    });
});

beforeEach(function() {
    angular.mock.module(function($provide) {
        requestAuthorizationService = jasmine.createSpyObj('requestAuthorizationService', ['requestAuthorization']);

        $provide.value('requestAuthorizationService', requestAuthorizationService);
    });
});

beforeEach(inject(function(_$rootScope_, _$q_, _sessionStorageManagerService_, _requestAuthorizationService_, _OAuthAuthenticationDataService_) {
    $scope = _$rootScope_.$new();
    $q = _$q_;
    sessionStorageManagerService = _sessionStorageManagerService_;
    requestAuthorizationService = _requestAuthorizationService_;
    OAuthAuthenticationDataService = _OAuthAuthenticationDataService_;
    deferred = $q.defer();

requestAuthorization.requestAuthorization.and.returnValue(deferred.promise);
OAuthAuthenticationDataService.authenticate.and,returnValue(deferred.promise);

    $scope.$digest();
}));

it('', function() {
    var user = {};

    requestAuthorizationService.requestAuthorization(user);
    deferred.resolve({});
    $scope.$digest();

    expect(OAuthAuthenticationDataService.authenticate).toHaveBeenCalledWith(...);
    expect(sessionStorageManagerService.set).toHaveBeenCalledWith(...);
});

it('', function() {
    var user = {};

    requestAuthorizationService.requestAuthorization(user);
    deferred.reject({});
    $scope.$digest();

    expect(...);
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Remove an array object in React Redux

I recently started using Redux and I’ve encountered a major issue. Whenever I try to remove an object from an array, the map function stops working. Do you have any tips or suggestions? reducer.js: const initialState = { storeState: { name: ...

The promise from NodeJS connected to MySQL is causing an issue by

Currently, I am attempting to create a command for my Discord bot that fetches an integer from a MySQL table. I've experimented with using async/await, promises, and callbacks in the past, but unfortunately, I haven't had much success. Although ...

The style from '<URL>' was not applied as it has a MIME type of 'text/html', which is not a compatible stylesheet MIME type

After attempting to run the angular application with the home component, an error appeared stating that styles were refused and images could not be found. It's puzzling because the CSS and image folder are located in the /src/assets folder. I have tr ...

Issues with retrieving data from nested nodes while parsing NOAA weather information using Javascript XML

Seeking assistance with my Javascript code, which is designed to extract weather data from NOAA xml files (obtained from this link: ). Currently, I have included a snippet of the XML as a string: var xmlDoc = $.parseXML("<data>\ <weather tim ...

Bug causing horizontal lines to glitch

In my Voxel.js project, which is based on Three.js, I have noticed a strange rendering issue specifically on Macbook Airs with Intel HD Graphics 3000. Interestingly, this problem does not occur on other Macbooks like those with GeForce 320Ms. I have gathe ...

Is there a way to use Javascript to launch a new page on my website?

I'll do my best to provide a clear explanation of what I need. Take a look at this: My website is filled with a plethora of news articles, all retrieved from the MySQL database using select * from table_name. Displaying so much news on one page can ...

What is the best way to transform an Object into an Array?

[ { id: '5b3a223296fb381a29cf6fd9', number: 1, name: 'Tablet White EliteBook Revolve 810 G2', dprice: '0', image: '' } ] This message is generated by the angular application. Upon inspecting its type, it was identi ...

Retrieve the item within the nested array that is contained within the outer object

I have a collection of objects, each containing nested arrays. My goal is to access the specific object inside one of those arrays. How can I achieve this? For instance, take a look at my function below where I currently log each array to the console. Wha ...

Using Symfony2 to send AJAX request data to a form rendering controller

I am facing an issue with a Symfony Form that I need to prefill based on the previously viewed record. The goal is to provide a way to modify the record data. I reach the form page through javascript and send an ajax request to the controller responsible f ...

How can I employ Single Sign-On (SSO) for my-website's account across various websites?

I'm looking to create a gaming platform similar to Epic Games, which we'll call "AB." I'd like game developers to be able to connect their games with my website and offer a "Login With AB" option on their login pages. Is this feasible? Thank ...

What is the recommended Vue js lifecycle method for initializing the materialize dropdown menu?

https://i.stack.imgur.com/cjGvh.png Upon examining the materialize documentation, it is evident that implementing this on a basic HTML file is straightforward: simply paste the HTML code into the body and add the JavaScript initializer within a script tag ...

What is the best way to handle waiting for a request and user input simultaneously?

Imagine a scenario where a component loads and initiates an asynchronous request. This component also includes a submit button that, when clicked by the user, triggers a function that depends on the result of the initial request. How can I ensure that this ...

The button's color cannot be modified due to a malfunctioning event script that is not

Seeking an explanation for why my current implementation isn't working. I'm attempting to create a quiz with a multiple choice section where the correct answer turns green when clicked, and incorrect answers turn red. Despite validating the code ...

The data from the Ajax request failed to display in the table

JavaScript Code</p> $(function (){ $.ajax({ type : 'GET', url : 'order/orders.json', dataType : 'JSON', success: function(data) { /*var trHTML = ''; $.each(orders, function (i, it ...

Retrieve a photo from a website address and determine its dimensions

When grabbing an image from a URL using this function: const fetch = require("node-fetch"); function getImageFromUrl(url) { return fetch(url).then((response) => response.blob()); } To determine the dimensions of the images, I am utilizing ...

Issue encountered when setting a background image in Angular

When trying to add a background image and set it to cover the entire browser window, I encountered an issue where the image appeared very small and did not fully cover the background. As someone new to Angular, my understanding of how this process works i ...

The smartcard node encounters an SCardConnect error when attempting to scan the card, followed by an SCardListReaders error upon disconnect

I am currently utilizing both angular and electron, and everything was functioning properly in the past. However, I am now encountering this error: Error: SCardConnect error: SCardConnect error: The smart card cannot be accessed because of other connecti ...

Completing tasks in groups, with the possibility of some not succeeding

My goal is to efficiently create users in batches of 20. I have organized the necessary functions within an array called "promises" along with a counter. The process goes smoothly until one of the functions encounters an error, causing the entire code exec ...

Having trouble with the checkbox functionality. Attempting to dynamically toggle gridlines in a flot chart

First, I'll share the code and then provide an explanation. Below is a snippet of the relevant HTML: <div id='gridButton'> <form> <input type="checkbox" id="gridCheck" value="showGrid">Show Grid </form ...

Is there a way to divide the array based on a specific letter in the alphabet using Angular?

I am trying to create something similar to this: "ABCDEF", "GHIJK", "LMNO", "PRSTU", "VYZXWQ", "0123456789" I have a list in alphabetical order; I want names starting with "ABCDEF" to be in one a ...