Karma+Jasmine: ajax call with real(not mocked) response - jasmine

I'd like getting real response from server when send XmlHttpRequest in karma env + Jasmine. Test case
it('get data from server', function (done) {
var request = new XMLHttpRequest();
request.open('GET', 'my_working_backPoint');
request.onload = function (resp) {
console.log(resp);
done();
};
request.send();
});
But I get this:
Error: Timeout - Async callback was not invoked within timeout
specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
I couldn't find any helpful answers. Please explain me how I could test real ajax call.

Related

Mocha Chai HTTP post request not working

The following test is not working with mocha-chai, it is able to to get the input request but throws the error message.
it('/hb : ', function (done) {
return chai.request(app)
.post('/hb')
.send({"a":1 })
.then(function (res) {
expect(err).to.be.null;
expect(res).to.have.status(200);
// { ah: { rt: [Object] }, ad: { mojo: 1 } } }
//console.log("CAlling DOne ........... +");
done();
}, function (err) {
//console.log(err);
throw err;
});
});
Output:
Web Requests : /hb : :
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
The functions that chai-http adds to chai return promises. In your code you return the promise, which is good. However, you also declare your test to take the a parameter: function (done). This would be fine if you did not return the promise, but returning the promise is really the better mechanism here. When you declare your test to take a parameter, Mocha ignores the return value from the test, and so the promise is ignored. So just remove your use of done.
Here's an example that reproduces the error you had in your original code with err being undefined in the function you pass to then.
'use strict';
var app = require('./server');
var chai = require('chai');
chai.use(require('chai-http'));
var expect = chai.expect;
it('/hb', function () {
return chai.request(app)
.post('/hb')
.send({a: 1})
.then(function (res) {
expect(err).to.be.null;
expect(res).to.have.status(200);
});
});
If the server returns a 200 status, then you'll get this on the console:
1) /hb
0 passing (26ms)
1 failing
1) /hb:
ReferenceError: err is not defined
at test.js:13:20
If the server returns a 400 status, the output would be:
1) /hb
0 passing (24ms)
1 failing
1) /hb:
Error: Bad Request
at Test.Request.callback (node_modules/superagent/lib/node/index.js:792:17)
at IncomingMessage.<anonymous> (node_modules/superagent/lib/node/index.js:990:12)
at endReadableNT (_stream_readable.js:913:12)
you need to add following:
.set('content-type', 'application/x-www-form-urlencoded')
you can reference this question over Post request via Chai

Cannot submit form with supertest and mocha

I am using supertest and mocha to test a nodejs application. One of the things users can do is to submit a very simple form, which is picked up by the node server and parsed using formidable.
Here is the mocha test code:
var should = require('should'),
express = require('express'),
app = require('../app.js'),
request = require('supertest'),
csrfToken,
sessionId,
cookies = [];
describe('Post Handler', function(){
it('Uploads new post', function(done){
var req = request(app).post('/post?_csrf=' + csrfToken);
req.cookies = cookies;
req
.type('form')
.send({fieldTitle: 'autopost'})
.send({fieldContent: 'autocontent'})
.send({contentType: 'image/png'})
.send({blobId: 'icon_23943.png'})
.expect(200)
.end(function(error, res){
console.log('here');
done();
});
});
csrfToken retrieves a csrf token from the server, since I am using the csurf module and every POST method requires a csrf token. cookies stores the session cookie that is provided by the node server so I can persist the session between requests.
The form is processed by the following code:
//Takes HTTP form posted by client and creates a new post in the Db
exports.postPostUpload = function (req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
console.log(err);
if (err) res.redirect(303, '/error');
else {
var new_post = new post_model.Post().createNewPost(fields);
new_post.setUserId(req.session.passport.user.userId);
new_post.uploadPostToDb(function (error, result) {
if (error) return res.status(500).end();
else {
if (new_post.media.contentType.indexOf('video') !== -1) {
addMessageToEncodingQueue(new_post, function (error, result, response) {
if (error) {
errorHelper.reportError({
stack: new Error().stack,
error: error
});
res.status(500).end();
}
else res.status(200).send(new_post.cuid);
});
}
else return res.status(200).send(new_post.cuid);
}
});
}
});
}
My current problem is, that once the form handler executes the line form.parse(req, function (err, fields, files) {, nothing happens. Formidable does not return error, it just does not return anything. Consequently, the mocha test never receives a reply from the server, and eventually the socket hangs and the test crashes. Needless to say, the form is successfully submit if you do it manually via the website.
There must be an error in the way supertest/mocha are executing this test, but I have not been able to find it. Any pointers are highly appreciated.

Angular Js - Test POST request that returns an object with Jasmine

I have a service set up which makes all my AJAX calls. I want to test my login method, which sends an AJAX POST $http.post to a particular URL, which returns an objects with the result (login passed or failed). This result is an object. I have not return the code exactly to test the service, but I'm trying to test the URL first. This is how it looks right now:
'use strict';
describe('Service: Ajax', function () {
var service, httpBackend;
// load the service's module
beforeEach(module('mySampleApp'));
// instantiate service
beforeEach(inject(function (Ajax, _$httpBackend_) {
httpBackend = _$httpBackend_;
service = Ajax;
}));
it('Test AJAX call', function () {
httpBackend.expect('POST', 'http://myloginurl', {u: 'xyz', p: 'pass'}, { withCredentials: true})
.respond(201, 'success');
});
});
This passes. Now I tried putting a wrong URL, wrong username/password, but it still passes! How do I test this?
UPDATE:
Better written now:
//Ajax is my AJAX service
it('should test the login AJAX call', inject(function (Ajax) {
httpBackend.expect('POST', 'http://myloginurl')
.respond(200, "[{ status: 200, //some more data }]");
httpBackend.flush();
Ajax.authenticate({u: 'xyz', password: 'pass' })
.then(function(data){
expect(data.status).toBe(200);
});
}));
I get this:
PhantomJS 1.9.7 (Linux) Service: Ajax should test the login AJAX call FAILED
Error: No pending request to flush !
blah blah...
You need to put a
httpBackend.flush();
in that will throw an exception if the expected url wasn't called - thereby failing your test.
Also, I can't see that you're calling the code that does the Ajax request anywhere - you need to do that before calling flush().
So something like:
it('Test AJAX call', function () {
httpBackend.expect('POST', 'http://myloginurl', {u: 'xyz', p: 'pass'}, { withCredentials: true})
.respond(201, 'success');
service.functionThatMakesCallToServer();
httpBackend.flush();
});
If functionThatMakesCallToServer() calls the url in the httpBackend.expect(...) line, everything will be ok. If it doesn't httpBackend.flush() will throw an error as a call that was expected did not happen. The error will cause your test to fail.

Intern ajax testing with node.js

I'm using intern with node.js, trying to set up intern for ajax testing. The server code below serves direct GET requests, but XHR request by Intern doesn't seem to reach to it. I suspect the problem is something to do with proxyUrl setup for the Node.
server/main.js: Node/express
...
app.get('/data', function(request, response, next){
if(request.xhr)
{
var data = dfs.readFileSync("src/server/data.json");
response.render(data, {
root: root,
error: new Error('Cant read file')
});
}
else
next();
});
...
app.listen(8001);
http_proxy.createServer(function(req,res, proxy){
proxy.proxyRequest(req,res, {host:'localhost', port:8001});
}).listen(9000);
intern.hello.js: (unit test code)
...
'async test': function () {
var dfd = this.async(1000);
request('/data').then(dfd.callback(function (data) {
assert.strictEqual(data, 'hello world');
}, dfd.reject.bind(dfd)));
}
intern config:
...
proxyPort:9000,
proxyUrl: 'http://localhost:8001/',
...
intern error:
Warning: FAIL: async test (1015ms)
Error: Timeout reached on main - wait - async test
at Error (<anonymous>)
at new ErrorCtor (.../node_modules/intern/node_modules/dojo/errors/create.js:13:21)
at null._onTimeout (.../node_modules/intern/lib/Test.js:164:21)
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
2/3 tests passed
2/3 tests passed Use --force to continue.

simultaneous ajax requests django

I have multiple ajax calls firing on page load.
From request1 I expect response1, and from request2 I expect response2. But I receive response1 for both request1 and request2.
When I move request2 to fire after response1 has been recieved then I recieve request2 as expected.
How can I do multiple ajax calls safely?
some code:
//avoids problem
this.update = function(){
$.post('/ws/newsfeed/', {'action':'6'}).done( function(response){
...
_this.get_alert_count()
})
}
this.get_alert_count = function(){
$.post('/ws/newsfeed/', {'action':'2'}).done(function(count) {
...
})
}
_this.update()
//causes problem
this.update = function(){
$.post('/ws/newsfeed/', {'action':'6'}).done( function(response){
...
})
}
this.get_alert_count = function(){
$.post('/ws/newsfeed/', {'action':'2'}).done(function(count) {
...
})
}
_this.update()
_this.get_alert_count()
You may want to investigate AjaxQ (http://code.google.com/p/jquery-ajaxq/), it lets you chain ajax calls without overlapping in a given time.
Hope it helps

Resources