The Jasmine test encounters a failure when attempting to make an $httpBackend call because the Angular mock is receiving JSON data in

I've run into a snag while trying to write what should be a straightforward unit test. Here's the controller I'm working with:

 (function(){ 'use strict';
    var LoginController = function($scope, $state, RestService){
        var _user = {};
        var _message = 'hello';

        var _login = function(username, password){
            var _success = function(response){
                _message = response.success;
                _user = response.user;
            };

            var _error = function(response){
                _message = response.success;
            };

            RestService.postData('/api/login', {username: username, password: password}, _success,  _error, {showLoader: true});
        };

        $scope.model = {
            login: _login,
            user: _user,
            message: _message
        };
    };

    angular.module('danny').controller('LoginController',['$scope', '$state', 'RestService',LoginController]);
})();

Here is the spec:

describe('LoginController', function(){
    var scope, $httpBackend, controller, restService;
    beforeEach(function(){
        module('danny');
    });

    beforeEach(inject(function(_$controller_, _$rootScope_, _$httpBackend_, _RestService_){
        $httpBackend = _$httpBackend_;
        restService = _RestService_;
        scope = _$rootScope_.$new();
        controller = _$controller_('LoginController', {
            $scope: scope,
            RestService: restService
        });
    }));

    afterEach(function() {
        $httpBackend.verifyNoOutstandingExpectation();
        $httpBackend.verifyNoOutstandingRequest();
    });

    describe('successfully logging in', function(){

       it('should redirect to /blog when authenticated', function(){

           var user = {"username":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="395d58575740794b584f5c57584b4d545c5d5058175a5654">[email protected]</a>", "password":"test"};
            expect(user.username).toEqual('<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d4b0b5babaad94a6b5a2b1bab5a6a0b9b1b0bdb5fab7bbb9">[email protected]</a>');

           $httpBackend.expectPOST('/api/login', user);

           scope.model.login(user);
           $httpBackend.flush();
           expect(scope.model.user).not.toBe(undefined);
       });
    });
});

During testing, I encountered this error in the karma output:

    C:\Program Files (x86)\JetBrains\WebStorm 9.0.1\bin\runnerw.exe" C:\nodejs\node.exe c:\Users\danny_000\AppData\Roaming\npm\node_modules\grunt-cli\bin\grunt test
Running "karma:development" (karma) task
INFO [karma]: Karma v0.12.16 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9.8 (Windows 8)]: Connected on socket SWVDLzehlqv2Z3J0C2Av with id 62852294
PhantomJS 1.9.8 (Windows 8): Executed 0 of 1 SUCCESS (0 secs / 0 secs)
PhantomJS 1.9.8 (Windows 8) LoginController successfully logging in should redirect to /blog when authenticated FAILED
    SyntaxError: Unable to parse JSON string
        at fromJson (c:/Projects/dannyschreiber/public/vendors/angular/angular.js:1066)
        at c:/Projects/dannyschreiber/public/vendors/angular-mocks/angular-mocks.js:1646
        at $httpBackend (c:/Projects/dannyschreiber/public/vendors/angular-mocks/angular-mocks.js:1194)
        at sendReq (c:/Projects/dannyschreiber/public/vendors/angular/angular.js:9616)
        at c:/Projects/dannyschreiber/public/vendors/angular/angular.js:9331
        at processQueue (c:/Projects/dannyschreiber/public/vendors/angular/angular.js:13171)
        at c:/Projects/dannyschreiber/public/vendors/angular/angular.js:13187
        at c:/Projects/dannyschreiber/public/vendors/angular/angular.js:14384
        at c:/Projects/dannyschreiber/public/vendors/angular/angular.js:14200
        at c:/Projects/dannyschreiber/public/vendors/angular-mocks/angular-mocks.js:1525
        at c:/Projects/dannyschreiber/public/src/core/security/login-controller.spec.js:6
    Error: [$rootScope:inprog] $digest already in progress
    http://errors.angularjs.org/1.3.9/$rootScope/inprog?p0=%24digest
        at beginPhase (c:/Projects/dannyschreiber/public/vendors/angular/angular.js:14738)
        at c:/Projects/dannyschreiber/public/vendors/angular/angular.js:14180
        at c:/Projects/dannyschreiber/public/vendors/angular-moc...

Continued in next comment...

Answer №1

Your custom function is defined as

function(url, params, data, successFunction,  errorFunction, config)
, with data being the third parameter. Consider this in comparison to how you are calling it:

RestService.postData('/api/login', null, null, {username: username, password: password}, _success, 'Invalid login, please try again', _error, {showLoader: true});

In your method invocation, the data is passed as the fourth parameter. It seems like one of the null values may be unnecessary. Unfortunately, JavaScript does not give warnings for incorrect numbers of parameters, it simply ignores them.

Update: I see that you have made changes to your initial question, but your usage of postData still appears to be incorrect. I've created a demo using your provided code: http://jsfiddle.net/qwteyak3/1/

The first call to postData treats the data as the params parameter, resulting in $http sending it as form data. The second call passes the data within the data field; hence, $http recognizes the object and sends it as a JSON body.

In running the demo, I observed Chrome's network tab showing requests to

http://fiddle.jshell.net/echo/json?password=123&username=test
for the first call and
http://fiddle.jshell.net/echo/json
(with data in the body) for the second.

I trust this clears things up.

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

Guide on positioning the canvas using p5.js

With just an hour of HTML and CSS experience under my belt, I have a much deeper understanding of programming languages like JavaScript. So please bear with me as I navigate through creating a p5 canvas that follows my CSS styling. How can I achieve this? ...

I'm looking to convert a Selenium webdriver test script from node.js to phantomjs - ghostdriver. Any tips on how to do this?

Recently, I started using Selenium and utilized node to run my scripts visually for easier testing. Now, I face the challenge of converting these tests into headless mode. Most resources I found only cover phantomjs and ghostdriver in conjunction with Java ...

The TypeScript error reads: "An element is implicitly assigned the 'any' type because an expression of type 'any' cannot be used to index a specific type."

[Hey there!][1] Encountering this TypeScript error message: { "Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{ 0: { image: string; title: string; text: string; }; 1: { ...

What is the best way to build the foundation of a web app using the Flatiron Node framework?

While browsing through the documentation on , I came across instructions for creating an app skeleton using the command: flatiron create <type> <app-name> However, I couldn't find any specific values to use for the "type" parameter. I tr ...

Unable to invoke array functions on undefined after utilizing Promise.all to generate an array within TypeScript

For more information, you can check out this post on Stack Overflow: How to use Promise.all() with Typescript In my TypeScript project, I am trying to implement Promise.all(). I have an array of promises that I pass to Promise.all(), then use .then() to ...

Deliver the react package loaded with redux dependencies via ship

In the process of developing an NPM package containing React components from a different company. The components include both pure UI components following the UI/Container pattern, as well as components that are integrated with redux functionality. The ai ...

The functionality of the wysiwyg-editor within a jQuery dialog is experiencing issues

As a website editor, I decided to test out various editing tools such as tinyEditor, wysihtml5, and jHTMLArea. Initially, everything seemed to work fine when I only had a textarea-element on my site. However, when I tried integrating the editor into a jQue ...

Incorporating a specific div element using AngularJS in my primary HTML document

As I dive into AngularJS, I've been exploring how to embed specific parts of an HTML document within another. While I've had experience doing this with jQuery in the past, I'm uncertain if the approach is the same in AngularJS and how to pre ...

Issues encountered while trying to update the database using Jquery.Ajax

Currently developing a website and seeking to update a field in a database table upon clicking a specific div. Came across some code example on stack, which can be found here, but for some reason it is not working even though it was accepted. Using C# ASP. ...

RXJS - distinguishing between values based on multiple keys

I am looking to trigger .subscribe() for my observable when any one of three object keys has been changed. The method works if I manually duplicate it for each key: this.myService.loadData(this.dataContainer.id, true) .distinctUntilChanged((updated ...

Having trouble getting the templateUrl to work properly with AngularUI-Router?

Can you please explain the flow of how a URL is processed when visited and provide insights on why Angular's templateUrl may not be working? When a user clicks on a URL in their browser, it first checks the cache to see if the URL is saved from the $ ...

How to convert SVG paths to canvas shapes

I'm curious about combining SVG paths and div elements into one image. How can this be achieved? For example: <div class="objects ui-droppable ui-sortable"> <div class="b_s _jsPlumb_endpoint_anchor _jsPlumb_connected" id="start_bloc ...

How to Determine the Length of a Subarray in JavaScript

I am working with a JSON element that contains nested arrays: json = [ { "category": "Electronic", "param": "param1", "subMenu": [ { "subCategory": "Audio & Hifi", ...

The auto-refresh feature of DataTables is not functioning as expected

Having trouble with the reload feature of DataTables. This is the code I'm using to load and reload the table on the server-side: $( document ).ready(function() { $('#dienst_tabelle').DataTable( { "ajax": "getData ...

Using AngularJS to create clickable divs that reveal child records through ng-repeat

$scope.webAppsDepartment = [ { AppName: 'Unlock Case', Colour: '#AF1A3F', Apps: null }, { AppName: 'Route Rec', Colour: '#00ABA9', Apps: null }, { AppName: 'RW Database', Colour: '#AF1A3F&a ...

Could you lend a hand in figuring out the root cause of why this Express server is constantly serving up error

I am encountering a 404 error while running this test. I can't seem to identify the issue on my own and could really use another set of eyes to help me out. The test involves mocking a request to the Microsoft Graph API in order to remove a member fro ...

Troubleshooting the Safari Height Problem with md-autocomplete Input

Using AngularJS v1.5.6 and AngularJS Material Design v1.1.8, I have encountered an issue with md-autocomplete not displaying correctly in Safari browser. The input search box's height is not filling 100% as expected. Here is a reference image for furt ...

Transmitting an "array with key-value pairs" through POST method in AngularJS

Currently, I have a filter object that looks like this: { name: 'text', value: 'xxx', field: 'firstname' } This object represents a filter for a specific field and is updated whenever input field values change. I am at ...

Every time I attempt to log into my app, I encounter a persistent 401 error message

I've implemented a user/login route that retrieves a user, compares their password with a hashed version, creates a token, and sends it to the front end. However, I encountered a persistent 401 error in the console on the front end, leading to the fin ...

The attempt to convert an array into an array of objects using the map function was

var array = ["x","y","z"] array.map(object => {object.key: object}) I thought array would transform into [{key:"x"},{key:"y"},{key:"z"}] but I encountered an error at object.key in my map function. Where did I go wrong? ...