Open taras opened 7 years ago
I'm down. I'd personally design this in an "adapter" style, with the default adapter being "Browser" or maybe "XMLHttpRequest"
Great. We'll start experimenting with it. I'll create a WIP PR and we'll go from there.
@taras did you make any progress?
I believe we use for fastboot: https://github.com/najaxjs/najax/blob/master/lib/najax.js
@stefanpenner We didn't end up getting round to it. I got busy and we didn't pick it up.
Ok.
i wonder if we can just provide our own XMLHTTPRequest global in fastboot, and then most of this stuff would "just work".
That's an interesting idea. We might be able to use this https://www.npmjs.com/package/xmlhttprequest
some trickier will be required to deal with najax or ember datas stuff.
Hi @stefanpenner, I'm able to simulate and run pretender in node by using the packages below:
require('jsdom-global')();
window.FakeXMLHttpRequest = require('fake-xml-http-request');
window.RouteRecognizer = require('route-recognizer');
window.$ = require("jquery");
require('pretender');
var PHOTOS = {
"10": {
id: 10,
src: 'http://media.giphy.com/media/UdqUo8xvEcvgA/giphy.gif'
},
"42": {
id: 42,
src: 'http://media0.giphy.com/media/Ko2pyD26RdYRi/giphy.gif'
}
};
var server = new window.Pretender(function(){
this.get('/photos', function(request){
var all = JSON.stringify(Object.keys(PHOTOS).map((k) => PHOTOS[k]));
return [200, {"Content-Type": "application/json"}, all];
});
this.get('/photos/:id', function(request){
return [200, {"Content-Type": "application/json"}, JSON.stringify(PHOTOS[request.params.id])];
});
});
server.handledRequest = function(verb, path, request) {
console.log("a request was responded to", verb, path, request);
}
server.unhandledRequest = function(verb, path, request) {
console.log("what is this I don't even...");
}
window.$.getJSON('/photos/12', (a) => {
console.log(a);
}).done(function() {
console.log('second success');
}).fail(function() {
console.log('error');
});
Pretender is able to intercept the requests, however the request.params are not parsed correctly, therefore server responds with empty body/error. I believe there is a problem with route-recognizer addon.
This is an important issue because, I was trying to run ember-fastboot with mirage and I get 404s during the broccoli/node environment, while the browser environment of the mirage server runs correctly. Considering the fact that most serious ember projects use mirage during development, enabling pretender in node.js should open new possibilities for ember fastboot.
I've found a problem with the parseURL() function:
parseURL('/photos/12').fullpath returns '/' for the node environment above..
Also the parseURL function seems to be very hard to read/maintain and probably quirky.
I found a hacky way to fix this, however the whole thing was an ordeal:
const JSDOM = require('jsdom').JSDOM;
const dom = new JSDOM(`<p>Hello</p>`, { url: 'http://localhost' });
global.window = dom.window;
global.document = window.document;
window.FakeXMLHttpRequest = require('fake-xml-http-request');
window.RouteRecognizer = require('route-recognizer');
window.$ = require("jquery");
window.self = window;
global.self = window.self;
require('pretender');
let PHOTOS = {
'10': {
id: 10,
src: 'http://media.giphy.com/media/UdqUo8xvEcvgA/giphy.gif'
},
'42': {
id: 42,
src: 'http://media0.giphy.com/media/Ko2pyD26RdYRi/giphy.gif'
}
};
let server = new window.Pretender(function(){
this.get('/photos', (request) => {
var all = JSON.stringify(Object.keys(PHOTOS).map((k) => PHOTOS[k]));
return [200, {'Content-Type': 'application/json'}, all];
});
this.get('/photos/:id', (request) => {
return [200, {'Content-Type': 'application/json'}, JSON.stringify(PHOTOS[request.params.id])];
});
});
server.handledRequest = function(verb, path, request) {
console.log('a request was responded to', verb, path);
}
server.unhandledRequest = function(verb, path, request) {
console.log('[UNHANDLED REQUEST]', verb, path);
console.log('REQUEST:');
console.log(request);
}
window.$.getJSON('/photos/10', (a) => {
console.log(a);
}).done(function() {
console.log('second success');
}).fail(function() {
console.log('error');
});
So the actual fix was this line:
const dom = new JSDOM(`<p>Hello</p>`, { url: 'http://localhost' });
when JSDOM receives no url, then window.location.host is ''
and the parseURL() function breaks.
ember-ajax
team is looking for a way to test the addon on node.js. We're using Pretender to stub XMLHttpRequest in the browser. In node.js, there is no XMLHttpRequest.nock
stubshttp.ClientRequest
to provide behaviour similar to what Pretender offers in the browser.If it was possible to use Pretender on node, then we could use Pretender to test app in Fastboot mode.
What are your thoughts about node.js support for this library?