Jasmine how to mock http request (for fetch and XMLXtthpRequest) - http

I want to test some ajax function that makes a request to the some url. I tried to use nock to mock http but it it's working because I use Karma runner and it throws to me an error about "can't find module 'fs'". It is because karma run tests on the browser.
How I can do that ? Thanks (I tried jasmine-ajax but it's also isn't working somehow).
As I understand an issue appears because karma works in the browser. But how I can fight with that.
Thanks for any help!

jasmine-ajax surely does work. here is a sample from working code (jasmine over karma):
describe('RequesterTest', function(){
beforeEach(function(){
jasmine.Ajax.install(); // this enables interception
});
afterEach(function(){
jasmine.Ajax.uninstall(); // disables interceptions
})
it('makes $.ajax', function(){
spyOn($, 'ajax');
$.ajax({url: 'http://example.com'});
expect($.ajax).toHaveBeenCalled();
});
it('assert success callback for ajax', function(){
spyOn($, 'ajax');
var myCallback = function(){};
$.ajax({url: 'http://example.com', success: myCallback});
var actualAjaxOptions = $.ajax.calls.mostRecent().args[0];
expect(actualAjaxOptions).toEqual(jasmine.objectContaining({
success: myCallback,
}));
});
});
exapmle assumes jquery defined globally and no modules/AMD usage.

Related

AngularJS $httpBackend asynchronous response

I'm trying to mock the back-end for an AngularJS(1.3.8)-app with ngMockE2E as replacement until the back-end code has been written.
I'm using already existing services that also query other data, however they return a promise. I am aware that ngMockE2E is supposed to be synchronous, however I wanted to see if there's a way to do it asynchronously first.
Looking around the web I found this and put the mocking-related code into its own seperate module to see if this approach works.
$httpBackend.whenAsync('projects/').respond(function (promise, headers, status) {
var deferred = $q.defer();
_getProjectIndex().then(function (result) {
deferred.resolve(result);
},
function (statusCode) {
console.log(statusCode);
deferred.reject(statusCode);
});
return deferred.promise;
});
When I try to run $httpBackend.whenAsync() the request just seems to 404. Checking the same request with $httpBackend.whenGET() I receive the promise containing the data I requested.
What am I doing wrong?

Meteor [Error: Can't wait without a fiber] after a call to Email.send

I've created a very simple server using Meteor, to send an email after a timeout. When I use a timeout, the message is successfully sent but an error is thrown: [Error: Can't wait without a fiber].
Here's my code:
if (Meteor.isServer) {
Meteor.startup(function () {
// <DUMMY VALUES: PLEASE CHANGE>
process.env.MAIL_URL = 'smtp://me%40example.com:PASSWORD#smtp.example.com:25';
var to = 'you#example.com'
var from = 'me#example.com'
// </DUMMY>
//
var subject = 'Message'
var message = "Hello Meteor"
var eta_ms = 10000
var timeout = setTimeout(sendMail, eta_ms);
console.log(eta_ms)
function sendMail() {
console.log("Sending...")
try {
Email.send({
to: to,
from: from,
subject: subject,
text: message
})
} catch (error) {
console.log("Email.send error:", error)
}
}
})
}
I understand that I could use Meteor.wrapAsync to create a fiber. But wrapAsync expects there to be a callback to call, and Email.send doesn't use a callback.
What should I do to get rid of the error?
This happens because while your Meteor.startup function runs inside a Fiber (like almost all other Meteor callbacks), the setTimeout you use does not! Due to the nature of setTimeout it will run on the top scope, outside the fiber in which you defined and/or called the function.
To solve, you could use something like Meteor.bindEnvironment:
setTimeout(Meteor.bindEnvironment(sendMail), eta_ms);
And then do so for every single call to setTimeout, which is a painfully hard fact.
Good thing it's not actually true. Simply use Meteor.setTimeout instead of the native one:
Meteor.setTimeout(sendMail, eta_ms);
From the docs:
These functions work just like their native JavaScript equivalents. If you call the native function, you'll get an error stating that Meteor code must always run within a Fiber, and advising to use Meteor.bindEnvironment
Meteor timers just bindEnvironment then delay the call as you wanted.

node.js, css validation, w3c banned me?

I apologize in advance for what I write through a translator, I am very bad at English.
I was faced with the following problem: I need to perform validation css files. To this end, I decided to use the NPM package w3c-css, first it worked, but then start giving "connected etimedout", in the course of research, I noticed that through the browser and the validator stops working.
Sniffer log at start of my script: link (<10 rep :( )
My code:
gulp.task('css', function() {
gulp.src('dev/sass/*.scss')
.pipe(through2.obj(function(file, enc, cb){
w3c_css.validate({text: file.contents.toString('utf8')}, function(err, data) {
if(err) {
// an error happened
console.error(err);
} else {
// validation errors
console.log('validation errors', data.errors);
// validation warnings
console.log('validation warnings', data.warnings);
}
});
cb(null, file);
}))
.pipe(gulp.dest('build/'));
});
What is the reason? It must be some mistake, or I block due to too frequent requests and it does not change? Maybe there is some other way to check the css files?
Thx!
From the "About" page of the CSS validation service of the W3C:
Can I build an application upon this validator? Is there an API?
Yes, and yes. The CSS Validator has a (RESTful) SOAP interface which should make it reasonably easy to build applications (Web or otherwise) upon it. Good manners and respectful usage of shared resources are of course customary: make sure your applications sleep() between calls to the validator, or install and run your own instance of the validator.
So yes, it seems you have been banned.
I don't know how to make a gulp task to be called from time to time. You may mount a local version of the CSS Validator webservice and editing the w3c-css package to point to your own server.
Make sure that your script will sleep for at least 1 second between requests.
From the manual:
Note: If you wish to call the validator programmatically for a batch
of documents, please make sure that your script will sleep for at
least 1 second between requests. The CSS Validation service is a free,
public service for all, your respect is appreciated. thanks.
To validate multiple links, use async + setTimeout or any related way to pause between the requests:
'use strict';
var async = require('async');
var validator = require('w3c-css');
var hrefs = [
'http://google.com',
'https://developer.mozilla.org',
'http://www.microsoft.com/'];
async.eachSeries(hrefs, function(href, next) {
validator.validate(href, function(err, data) {
// { process err, data.errors & data.warnings }
// sleep for 1.5 seconds between the requests
setTimeout(function() { next(err); }, 1500);
});
}, function(err) {
if(err) {
console.log('Failed to process an url', err);
} else {
console.log('All urls have been processed successfully');
}
});
EDIT:
To mitigate this issue:
Added some comments and an example.
Placed setTimeout right into the gulp-w3c-css plugin.

Protractor, Cucumber and chai as promised: When chai assertion fails

I am using protractor to run my cucumber tests. Inside my test I have the following assertion:
label.getText().then(
function(labelText){
labelText = labelText.trim();
console.log('label text: ' + labelText);
chai.expect(labelText).to.equal(arg1);
callback();
},
function() {
callback.fail('Could not get page label text');
});
When the Assertion is correct there is no problem. However when my labelText is different from arg1 I would like to still keep running it but I don't know how to add the exception or a fail callback in that. At the moment my application just exits. I know that is because I am not using a fail callback (I would like to know where I should have it).
I am also not sure if I should put the callback(); where it is now.
I am looking for solutions online and all I can find are examples using Mocha. I am not using Mocha or Jasmine. I am just using Cucumber framework with protractor. Since Cucumberjs does not have an assertion library, I added chai-as-promised for that. Thanks!
Cucumber.js seems to have issues when expect() calls fail in a callback. Since you have chai-as-promised installed, try doing this:
var labelText = label.getText().then(
function(labelText){
labelText = labelText.trim();
console.log('label text: ' + labelText);
return labelText;
});
chai.expect(labelText).to.eventually.equal(arg1).then(callback);
I got this workaround from this comment and it worked well for me.
If you have chai-as-promised then you can assert async code like this:
this.When(/^I assert async code$/, function(callback) {
expect(asyncMethod()).to.eventually.equal(true).and.notify(callback);
});

Writing an async test with Intern

I am trying to write an Integration test which calls my real service (that returns JSON) and makes sure the format of the JSON is OK.
I get an error
Error: Unable to load http://localhost:7200/users/signoff status: 0
ErrorCtor#http://localhost:9000/resources/www/tests/lib/dojo/errors/create.js:29
onError#http://localhost:9000/resources/www/tests/lib/dojo/request/xhr.js:133
I've got a service that has the actual functions to interact with the server and it returns promises from every function. My test looks like this.
define([
'intern!bdd',
'intern/chai!expect',
'app/services/myService'
], function (bdd, expect, MyService) {
with (bdd) {
describe('Service Tests', function () {
var service;
before(function () {
service = MyService.getInstance();
});
it('should sign user off', function(){
var dfd = this.async(2000);
service.signUserOff().then(dfd.callback(function (data) {
expect(data).to.exist;
expect(data.status).to.exist;
}), dfd.reject.bind(dfd));
});
});
}
});
service.signOff() makes a call to the real service and then returns a promise. I have tried this with Firefox and PhantomJS both and I keep getting this error. The weird thing is, the URL in the error works fine if loaded manually in the browser.
I wonder if this is something to do with Intern not being able to load the request/xhr.js and therefore throwing this error?
The request that you are making is considered a cross-site request, so you need to either make sure your server correctly responds with the appropriate CORS headers for such a request, or you need to set up a reverse proxy that ensures that the XHR requests are occurring through the same origin.

Resources