Giter VIP home page Giter VIP logo

nise's People

Contributors

43081j avatar betalb avatar boidolr avatar codejedi365 avatar darrennolan avatar davidwood avatar dependabot-preview[bot] avatar dependabot[bot] avatar evan-007 avatar fatso83 avatar fearphage avatar flovogt avatar gordoncl avatar griest024 avatar harelm avatar johnmiroki avatar josephschmitt avatar justinbeckwith avatar m90 avatar maadhattah avatar mantoni avatar maoberlehner avatar mnahkies avatar mroderick avatar mtharrison avatar offirgolan avatar rgeerts avatar sebcanonica avatar serbanghita avatar tzrh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nise's Issues

Expose a way of choosing an alternate target

As sinonjs/sinon#2218 (comment) showed, we have a bit of a feature disparity between this project and the fake timers: When using projects such as JSDOM it would be useful to explicitly state which target we want to install the fake XHR into to avoid issues such as the one in #2218, where the "global detection" will fail tests in "mixed environments", such as Node+JSDOM.

Not sure about the API, but perhaps something like

fakeXhr.useFakeXMLHttpRequest({target});

There are more methods that would need this, of course.

Alternatively, do like fake-timers and wrap everything in a factory method to do nise.withGlobal(target).useFakeXMLHttpRequest(), etc.

Timeout isn't working as expected

Expected behaviour:

  1. xhr.ontimeout is called after xhr.timeout
  2. xhr.triggerTimeout is called after xhr.timeout

Actual behaviour:

  1. xhr.ontimeout is NOT called after xhr.timeout
  2. xhr.triggerTimeout is NOT called after xhr.timeout

Code:

import { expect } from 'chai';
import { createSandbox, fakeServer, FakeXMLHttpRequest } from 'sinon';

const sleep = (duration: number): Promise<void> =>
    new Promise((resolve) => {
        setTimeout(resolve, duration);
    });

describe('send', () => {
    it('should be timeout', async () => {
        const sandboxInstance = createSandbox();

        const xhr = new FakeXMLHttpRequest();
        (xhr as any).open('GET', '/');
        (xhr as any).timeout = 1_000;
        (xhr as any).triggerTimeout = sandboxInstance.spy();
        (xhr as any).send();

        let isTimeout = false;
        (xhr as any).ontimeout = () => {
            isTimeout = true;
        };

        await sleep(2_000);

        (fakeServer as any).respond();

        expect((xhr as any).triggerTimeout.getCalls().length).to.eq(1);
        expect(isTimeout).to.eq(true);
    });
});

Additional data

  1. Versions:
  • "nise": "1.4.3",
  • "chai": "4.2.0",
  • "@types/chai": "4.1.7",
  1. Might be connected to issue and PR
  2. If I replace it with XMLHttpRequest and use latency=5s in Chrome, the test will pass
  3. If I update nise to version 4.0.3, it doesn't change anything

FakeXHR and Event Targets

The test below fails for me, but I think it should work. It is possible that i don't correctly understand what i am doing.
I think that FakeXMLHttpRequest.dispatchEvent ought to set the target of the event, but it does not.

import { fakeXhr } from 'nise';

let xhrControl;
beforeEach(() => {
    xhrControl = fakeXhr.useFakeXMLHttpRequest();
});
afterEach(() => {
    xhrControl.restore();
});
test('Event target should be set', (done) => {
    const xhr = new XMLHttpRequest();
    xhr.addEventListener('error', (evt) => {
        expect(evt.target).toBe(xhr);
        done();
    }, false);
    const err = new ErrorEvent('error');
    xhr.dispatchEvent(err);
});

Error: Cannot find module 'text-encoding'

Hello,

Since the latest release 1.4.9 I'm getting the following error:

Error: Cannot find module 'text-encoding'

Apparently the fix is already committed but not yet released:
fb3b595

Any plan to release it quickly?
Many thanks!

"Defaked" fake XHR does not propagate properties to actual XHR after triggering `open`

Related to #49.

Minimal repro: https://github.com/pswai/nise-defake-issue

Considering this case:

sinon.FakeXMLHttpRequest.useFilters = true;
sinon.FakeXMLHttpRequest.addFilter(() => true);

const server = sinon.fakeServer.create();

const xhr = new XMLHttpRequest();
xhr.open("GET", "http://www.mocky.io/v2/5e8aa67e2d00003c1a1a473e", true);

// Setting `withCredentials` applies only to the FakeXhr instance.
// The `workingXHR` in `defake` does not receive this.
xhr.withCredentials = true;
xhr.send();

xhr.send() calls the send function defined in the defake function. Since defake is called during open, any modification to the fake XHR does not reflect on the actual XHR. In this example, if we put a breakpoint in send, we can see that withCredentials is false for the actual XHR.

I think we can either utilise Proxy to setup trap for setting properties after defake, or do copyAttrs again in send.

This was discovered when I was trying to use unsafeHeadersEnabled: false with fake server and noticed that withCredentials didn't work ๐Ÿ˜…

FakeXMLHttpRequest falsly sets responseXML


Migrated from sinonjs/sinon#1678
Originally created by @Ninerian on Fri, 26 Jan 2018 14:41:19 GMT


  • Sinon version : 4.2.1
  • Environment: Node 9.4.0, Chrome, Firefox, Safari
  • Other libraries you are using: karma, chai, mocha

What did you expect to happen?
When a invalid xml file is loaded with XMLHttpRequest, the responseXML is null.

What actually happens
The FakeXMLHttpRequest fills the responseXML with the parsed xml document with included parseErrors.

How to reproduce

const invalidXMLData = `!!!<?xml version="1.0" encoding="UTF-8"?><start>`;

function testXMLRequest(options) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', options.url, true);

  // If specified, responseType must be empty string or "document"
  xhr.responseType = 'document';

  // overrideMimeType() can be used to force the response to be parsed as XML
  xhr.overrideMimeType('text/xml');

  xhr.onload = function() {
    if (xhr.readyState === xhr.DONE) {
      if (xhr.status === 200) {
        if (xhr.responseXML) {
          options.onSuccess();
        } else {
          options.onErrorCallback();
        }
      }
    }
  };

  xhr.send(null);
}

let xhr, requests, requestor;

before(() => {
  xhr = sinon.useFakeXMLHttpRequest();
  requests = [];
  xhr.onCreate = function(xhr) {
    requests.push(xhr);
  };
});

after(() => {
  xhr.restore();
});

it('Should throw an error, when the xml is invalid', () => {
  let successCallback = sinon.spy();
  let errorCallback = sinon.spy();

  const reqSettings = {
    url: '/xml',
    onSuccess: successCallback,
    onErrorCallback: errorCallback,
  };

  testXMLRequest(reqSettings);

  requests[0].respond(200, { 'Content-Type': 'text/text' }, invalidXMLData);

  expect(successCallback.notCalled, 'Success callback is not called').to.be.true;
  expect(errorCallback.calledOnce, 'Error callback is called').to.be.true;
});

Solution
After parsing the response, you should check for parseerrors and return null.

readystatechange OPENED event triggered on send()

Hi there!

I noticed that nise is sending the readystatechange event with an "OPENED" readystate when calling the xhr.send() function, while the native XHR doesn't.

As it's pretty hard to explain, here is an example of what the native XHR triggers and what nise does: https://jsfiddle.net/1djoqatw/2/

We can see that nise triggers an "OPENED" event for both xhr.open() and xhr.send(), while the native XHR only triggers it once when xhr.open() is being called.

It's pretty problematic for us as we are doing some actions on the readystatechange event listener which gets called too many times in our unit tests.

Is there a particular reason for "OPENED" to be triggered when send() is called?

Thank you very much,

Have a nice day!

Error: Cannot find module './event'

After an update up to 1.2.1 version I found that error message:

Error: Cannot find module './event'
    at Function.Module._resolveFilename (module.js:469:15)
    at Function.Module._load (module.js:417:25)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/home/kantora.pro/node-backend-skeleton/node_modules/.registry.npmjs.org/nise/1.2.1/node_modules/nise/lib/event/index.js:4:12)

Believe that happens because directory lib/event doesn't contain 'event.js' module

fakeServer should enable triggering progress events.

Hi, AFAIK there is no way to get the fake server to trigger progress events during an upload.

It would be very useful this was possible in a simple way. Maybe:

    server = sinon.fakeServer.create()
    server.responWith((r) => {...})
// this fires for all requests - not ideal but very accessable and would solve 80% of all usecases
    server.updateProgress({lengthComputable: true, loaded: 100, total: 200 })
  • Sinon version : 4.0
  • Other libraries you are using: Mocha, Karma

**What did you expect to happen?

I would expect the progress event to fire for all requests.

Fake XHR XML document parser fails to parse.

It looks like there is an error attempting to determine what a parse error may look like.

https://github.com/sinonjs/nise/blob/master/lib/fake-xhr/index.js#L345

I have a situation running with a DOMParser stub in node where the document INVALID does not return any elements with a parseerror tag name. In this situation my XML is failing to parse even though my XML is valid. The check for getElementsByTagName("parsererror") should verify that it got a result prior to checking the item at index 0. In my situation I have valid XML but no parsererror for the "INVALID" document.

Out of Date dependencies.

Can you please update all of your dependencies to resolve some security issues?

  • just-extend should go from 3.0.0 to 4.0.2
  • lolex should go from 2.7.5 to 3.0.0
  • path-to-regexp should go from 1.7.0 to the latest 2.4.0
  • text-encoding should be completely replaced or, at least, be moved from 0.6.4 to 0.7.0

Version 1.2.1 is missing code on npm

Version 1.2.1 of nise is broken - there are missing files in the package on npm, eg. all contents of lib/events is missing, except for index.js.

unmaintained 'text-encoding'

the dependency 'text-encoding' of 'nise' is no longer maintained:

gms@orion:~/work/RESEARCH/loopback4-example-todo$ npm i
npm WARN deprecated [email protected]: no longer maintained
npm notice created a lockfile as package-lock.json. You should commit this file.
added 623 packages from 1418 contributors and audited 3053 packages in 19.523s
found 1 low severity vulnerability
  run `npm audit fix` to fix them, or `npm audit` for details

gms@orion:~/work/RESEARCH/loopback4-example-todo$ npm ls text-encoding
@loopback/[email protected] /home/gms/work/RESEARCH/loopback4-example-todo
โ””โ”€โ”ฌ @loopback/[email protected]
  โ””โ”€โ”ฌ [email protected]
    โ””โ”€โ”ฌ [email protected]
      โ””โ”€โ”€ [email protected] 

URLs with port fail to match & respond on fake-server

When registering a response with a fake-server instance and the URL specifies port number, the corresponding requests receive a HTTP 404 Not Found error even though the URLs match.

Error Reproduction:

this.server.respondWith("GET", "http://localhost:5000/ping", "Pong");

var xhr = new FakeXMLHttpRequest();
xhr.open("GET", "http://localhost:5000/ping", true);
xhr.send();
// HTTP 404 Not Found

Expected behavior: HTTP 200 OK, "Pong"

Context
This error comes up when testing a Vue.js app which is a Web UI that is communicating back to a API server. The API server is running on the same host on the separate port (ie same domain/origin, different port). For the purpose of unit testing, the API server is being abstracted by the Sinon fake-server which is how the issue arose.

Library version: [email protected]
Environment: Node v12.16.2, Vue.js v4.3.1, [email protected], [email protected], [email protected]

Regression in v5.0.8+ fakeServer when $.ajax() XHR includes headers

From @scottohara on May 31, 2018 7:10

Describe the bug
In [email protected], using jQuery's $.ajax() to fetch a non-existent URL from fakeServer returns a 404 Not Found response, as expected.

In [email protected] and later, the same fetch now returns a 0 status.

To Reproduce

  1. npm install [email protected], and run the tests below
  2. npm install [email protected], and re-run the tests again
describe.only("404 Not Found", () => {
  let fakeServer;

  beforeEach(() => (fakeServer = sinon.fakeServer.create({respondImmediately: true})));

  it("should work without headers", done => {
    $.ajax({
      url: "/bad",
      headers: {},
      error(response) {
        response.status.should.equal(404);
        response.statusText.should.equal("Not Found");
        done();
      }
    });
  });

  it("should work with headers", done => {
    $.ajax({
      url: "/bad",
      headers: {"X-FOO": 1},
      error(response) {
        response.status.should.equal(404);
        response.statusText.should.equal("Not Found");
        done();
      }
    });
  });

  afterEach(() => fakeServer.restore());
});

Expected behavior
The specs above create a fakeServer and then attempt to fetch a non-existant URL (/bad).
The only difference between the two specs is the second includes a request header, X-FOO: 1.
The specs assert the response returned from fakeServer is a 404 Not Found

In [email protected], both specs pass.
In [email protected] and later, the spec with the X-FOO request header fails

Screenshots
Results from [email protected]:
5_0_7

Results from [email protected]:
5_0_8

Context (please complete the following information):

Copied from original issue: sinonjs/sinon#1817

Missing Request headers for requests pass through via fakeServer

The headers like Cookie are missing for the requests which pass though the fakeServer and filter.
This is causing the requests to lose the sessions.

const server = sinon.fakeServer.create({ logger: console.log, unsafeHeadersEnabled: true });
server.autoRespond = true;
server.xhr.filters = [];
server.xhr.useFilters = true;

//If the filter returns true, the request will not be faked - leave original
server.xhr.addFilter(function(method, url, async, username, password) {
  // have some condition to allow some requests to pass through
});

server.respondWith((xhr, id) => {
  xhr.respond(200, { "Content-Type": "application/text" },"Hello World");
});

Intercept Requests

Hey,

First of all: I really like the nise fake server.

Is it possible to intercept and manipulate a request? I tried several approaches.

My last approach was to intercept a request, make the same call with the fetch api and return the result from the fetch api as mock. Please see the following code snippet:

const server = nise.fakeServer.create({
  autoRespond: true,
  autoRespondAfter: 100,
});

// devices
server.respondWith(
  'GET',
  /.*(rest\/devices)/,
  async (xhr) => {
    const devices = await fetch(xhr.url)
      .then(function(response) {
        return response.json();
      });

    xhr.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify(devices));
  },
);

But I get the following error: Error: INVALID_STATE_ERR - 4.
I get the same error if I try to use the setTimeout method in the callback function.

Is there any possibility to intercept requests with nise?

Thank you in advance!

Cheers,
Stefan

Regression when $.ajax() XHR includes headers

From @scottohara on May 31, 2018 7:10

Describe the bug
In [email protected], using jQuery's $.ajax() to fetch a non-existent URL from fakeServer returns a 404 Not Found response, as expected.

In [email protected] and later, the same fetch now returns a 0 status.

To Reproduce

  1. npm install [email protected], and run the tests below
  2. npm install [email protected], and re-run the tests again
describe.only("404 Not Found", () => {
  let fakeServer;

  beforeEach(() => (fakeServer = sinon.fakeServer.create({respondImmediately: true})));

  it("should work without headers", done => {
    $.ajax({
      url: "/bad",
      headers: {},
      error(response) {
        response.status.should.equal(404);
        response.statusText.should.equal("Not Found");
        done();
      }
    });
  });

  it("should work with headers", done => {
    $.ajax({
      url: "/bad",
      headers: {"X-FOO": 1},
      error(response) {
        response.status.should.equal(404);
        response.statusText.should.equal("Not Found");
        done();
      }
    });
  });

  afterEach(() => fakeServer.restore());
});

Expected behavior
The specs above create a fakeServer and then attempt to fetch a non-existant URL (/bad).
The only difference between the two specs is the second includes a request header, X-FOO: 1.
The specs assert the response returned from fakeServer is a 404 Not Found

In [email protected], both specs pass.
In [email protected] and later, the spec with the X-FOO request header fails

Screenshots
Results from [email protected]:
5_0_7

Results from [email protected]:
5_0_8

Context (please complete the following information):

Copied from original issue: sinonjs/sinon#1817

Tests are not executing in a browser

Given that this is the only sinonjs/* library that exclusively deals with browsers, it's perplexing that it's the only one not running tests in a browser ๐Ÿ˜ฎ That makes it hard to verify run-time issues in browsers, such as #61 (and the fix in #67).

We should add mochito (running Puppeteer) like in the other projects.

readyState in onreadystatechange listeners will never equal to 4 after defake request

Hi.

var xhr = nise.fakeXhr.useFakeXMLHttpRequest();

xhr.useFilters = true;
xhr.addFilter(function () {
                    return true;
                });

xhr.addEventListener('readystatechange', () => {
    console.log(xhr.readyState) // will never been 4
});
....
xhr.open("GET", "http://example.com");

readyState in defaked request is being setted in stateChange handler
https://github.com/sinonjs/nise/blob/master/lib/fake-xhr/index.js#L225
that fires after other handlers.

General question: Nise vs Sinon.JS fakeserver

Hi team,
I've some general questions to this project which I can not answer by the documentation.
What is the way to go to use fakeServer in a JS project. Should I use sinon.js fakeserver or nise?
Is there a future roadmap to remove fakeServer from Sinon.js?
Thanks a lot for your work! FakeServer helped me so lot.

Filtered synchronous FakeXMLHttpRequest throw Exception


Migrated from sinonjs/sinon#1873
Originally created by @sebcanonica on Wed, 01 Aug 2018 17:16:00 GMT


Symptom
Using a fake server, if I try to filter a request (to let it go through normally) which is sent synchronously, then sinon throw an exception:

In Chrome
Uncaught DOMException: Failed to set the 'responseType' property on 'XMLHttpRequest': The response type cannot be changed for synchronous requests made from a document.
at y.u.send (https://cdnjs.cloudflare.com/ajax/libs/sinon.js/6.1.4/sinon.min.js:1:113357)
at window.onload (https://fiddle.jshell.net/_display/:36:9)

In Firefox
InvalidAccessError: synchronous XMLHttpRequests do not support timeout and responseType. sinon.min.js:1
[61]</</y.defake/u.send
https://cdnjs.cloudflare.com/ajax/libs/sinon.js/6.1.4/sinon.min.js:1:113343
window.onload
https://fiddle.jshell.net/_display/:36:1

To Reproduce
Steps to reproduce the behavior:

  1. Go to https://jsfiddle.net/sebcano/czmhLrqf/7/
  2. Open the console
  3. Click on Run
  4. See error
const server = sinon.fakeServer.create();
server.xhr.useFilters = true;
server.xhr.addFilter(() => true);
const request = new XMLHttpRequest();
request.open('GET', 'anything.html', false);
request.send();
console.log('Not reached');

Expected behavior
The request should be served normally and no exception should be thrown

Context

Additional context
The defake method put in place a send method which modify the responseType of the real xhr, which is forbidden for synchronous xhr not in a worker context.
If I comment out this line, the behavior is Ok.

The same handler registered twice with addEventListener should be discarded

According to documentation from MDN https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener, if listener is registered more than once it should be discarded. I haven't found any specific details on how to translate with the same parameters in regards to XHR. Event type and listener are definitely part of this, and seems that options.once should be added to equality comparison, as it works as expected for XHR.

XHR.timeout not implemented.

There was a ticket on sinon from a while back: sinonjs/sinon#431. I attempted to fix this with the following PR: https://github.com/sinonjs/sinon/pull/1495/files.

It'd be pretty easy for me to port the PR, since the files haven't changed much.

My thought was to only set the timeout functionality if an instance of global XMLHttpRequest has the timeout variable and if send is called while fake timers are activated. I've taken into account quirks like fakeServerWithClocks forcing a tick for the longest timeout.

If this sounds reason let me know and I would be happy to create a PR for review.

Header composition in setRequestHeader should ignore header name case

Currently if setRequestHeader is called twice with the same header name, value will be combined into one comma delimited list. But if header names passed to setRequestHeader differ in case, it will produce 2 separate headers being set.

According to spec composition process should ignore case of header name:

Also value should be trimmed

Wait for mocked XHR to fulfil all requests

I'm having the following situation:

function reloadApp() {
   $.ajax({url: "first/url"}).then(() => {

       $.ajax({url: "second/url"}).then(() => updateSomeDOMAttributes());

   }).then((r1) => addSomeDOMAttributes());

   renderDOMComponent();
}

There are two ajax requests nested but not chained to one another.
I'm using Sinon.js (which uses nise).

I have no way of waiting for the second request to fulfil unless I chain the Promise which is something I cannot do without breaking compatibility (let's assume that it cannot be done).

    beforeEach(() => {
        server = sinon.createFakeServer({respondImmediately: true});
        spy = sinon.spy(tracking, "trackEvent");
    });

    afterEach(() => {
        server.restore();
        spy.restore();
    });

    it('ajax mocking works #1', (done) => {
    
         server.respondWith("GET", 'first/url', [ 200, { "Content-Type": "text/html" }, `mocked1` ]);
         server.respondWith("GET", 'second/url', [ 200, { "Content-Type": "text/html" }, `mocked2` ]);
    
         reloadApp().then((r1) => {
             expect(r1).to.equal(`mocked1`);
             expect(spy.callCount).to.equal(2); <------- fails
             done();
         });
    
         // server.respond();
    
     });

I tried both strategies with respondImmediately and with the server.respond().

My solution is to make a helper:

/**
 * Wait for the Sinon.js nise XHR mocks to finish their registered
 * responses.
 *
 * @param server Server created with sinon.createFakeServer
 * @param timeout Optional, how much to wait before failing.
 * @returns {Promise<any>}
 */
function waitForServerToFulfillRequests(server, timeout) {
    timeout = timeout || 100;
    return new Promise((resolve, reject) => {
        let checkCount = 0;
        const i = setInterval(() => {
            if (server.requests.length === server.responses.length) {
                clearInterval(i);
                resolve();
            }
            if (checkCount === 100) {
                clearInterval(i);
                reject(`Maximum waiting count of ${checkCount * 16} has passed.`);
            }
            checkCount++;
        }, 16);
    });
}

This is obviously an edge case but my goal is to test the final outcome of the code and wait for all the requests to finish because they modify the HTML component that I'm testing.

Working example: https://github.com/serbanghita/karma-mocha-chai-sinon ;

Let me know your thoughts on the situation and waitForServerToFulfillRequests

Proposal: remove `text-encoding` dependency

Although this package is most likely only rarely used in the browser, and it is (hopefully) never used on a live site, I'm still concerned by the huge overhead the text-encoding dependency adds. The package size is about 500kb with text-encoding and 40kb without.

I'm using this package to fake XHR requests in automated acceptance tests with Nightwatch.js and although loading is not too much of an issue when the file isn't sent over the network, parsing it in the browser is a significant burden on the performance of the test system.

As a quick workaround, I've just forked this package and removed everything text-encoding related (maoberlehner@64db34e).

Is there any chance to get rid of this dependency? Maybe it is possible to make it optional, so people who actually need ArrayBuffers and Blobs, can add it manually?

respondWith with a function

I tried passing a function into server.respondWith() but i think there is a bug in processing response results.

here's my call:

var server = sinon.fakeServer.create();
server.respondWith("POST", "/foo/api", function(request) {
   var req = JSON.parse(request.requestBody);
   return [200, {"Content-Type": "application/json"},JSON.stringify({ req.bar === 'hello world' ? 'yes' : 'no'})}];
});

The problem seems to be here:
node_modules/nise/lib/fake-server/index.js:261
request.respond(response[0], response[1], response[2]);

Instead it should do something like this:

if (typeof response.response === "function") {
  response = response();
} 
return request.respond(response[0], response[1], response[2]);

Default route matched in addition to more specific route

Moved from sinonjs/sinon#1528.

Running the test case where only the /foo route should be matched results in both being matched. To reproduce:

$ npm i -g phantomic phantomjs-prebuilt browserify 
$ npm i babelify babel-preset-es2015 

$ browserify test.js  -t [ babelify --presets [ es2015  ] ] -o bundle.js && phantomic bundle.js
requesting foo
foo requested
default requested
INVALID_STATE_ERR - 4 Error: INVALID_STATE_ERR - 4
status == 200? true
test.js
// when testing locally in the repo: const nise = require('./lib/')
const nise = require('nise');

const server = nise.fakeServer.create();

// each response should be triggered exactly once
let fooResponded = false;
let defaultResponded = false;

// default responder
server.respondWith(xhr=>{
    console.log('default requested')
    if (defaultResponded)
        console.log("default requested more than once!");
    defaultResponded = true;
    try {
    xhr.respond(404, {}, '');
    }catch(err) {
        console.log(err);
    }
});

// foo responder
server.respondWith('/foo', xhr=>{
    console.log('foo requested')
    if (fooResponded)
        console.log("foo requested more than once!");
    fooResponded = true;
    return xhr.respond(200, {}, '');
});


// request foo
let r = new XMLHttpRequest();
console.log('requesting foo');
r.open('GET', '/foo', false);
r.send();
console.log('status == 200?', r.status === 200);

Missing documentation on how to create a fake server for Node.js applications

From @bennyn on March 26, 2017 15:34

Sinon version: Sinon v2.1.0

Environment: Node.js v7.7.3

Other libraries you are using:

I always used Sinon in combination with Jasmine and a Karma test runner (to execute Browser tests). Now I want to use Sinon in a Node.js environment and I want to mock server responses.

In my Node.js application I don't use jQuery, so I cannot make use of sinon.spy(jQuery, 'ajax');. In your documentation I read that I can fake the XMLHttpRequest object (if not using jQuery), but it also looks like Node.js doesn't make use of the standard XMLHttpRequest.

So do I need a wrapping module for Node.js requests like node-XMLHttpRequest to make it work?

Here is the code I have written so far:

const sinon = require('sinon');
const EndpointValidator = require('./../src/EndpointValidator');

let server = undefined;
let validator = undefined;

beforeAll(() => {
  server = sinon.fakeServer.create();
  server.autoRespond = true;
  server.respondWith('GET', 'http://www.mypage.com/online', [
    200, {
      'Content-Type': 'application/json'
    }, JSON.stringify({
      "status": "online"
    })
  ]);
});

beforeEach(() => {
  validator = new EndpointValidator();
});

afterEach(() => {
  server.restore();
});

describe('EndpointValidator', () => {
  it('checks for a valid endpoint', (done) => {
    validator.isValidEndpoint('http://www.mypage.com/online')
      .then((data) => {
        const json = JSON.parse(data);
        expect(json.status).toBe('online');
        done();
      })
      .catch(done.fail);
  });
});

EndpointValidator.js

const request = require('request');

class EndpointValidator {
  constructor() {
  }

  isValidEndpoint(url, minimumBodyLength = 0) {
    return new Promise((resolve, reject) => {
      request.get(url, function(error, response, body) {
        if (response.statusCode !== 200) {
          reject(new Error('Service is temporarily unavailable.'));
        } else {
          if (response.body.length > minimumBodyLength) {
            resolve(body);
          } else {
            resolve(false);
          }
        }
      });
    });
  }
}

module.exports = EndpointValidator;

Copied from original issue: sinonjs/sinon#1367

XHR: Content-Type clobbered


Migrated from sinonjs/sinon#607
Originally created by @terinjokes on Thu, 20 Nov 2014 00:47:58 GMT


FakeXMLHttpRequest's send method currently clobbers the "Content-Type" header if set, by removing anything after the first ";" and forcibly appending ";charset=utf-8".

A real XHR object allows sending binary data via TypedArrays, ArrayBuffers, and Blobs. They also correctly form encode when sent with FormData values. As "Content-Type" might have application-specific behavior, blindingly clobbering them makes it difficult for developers to properly test the functionality.

Bind to different Window context?

Wondering if it is posable to bind this library to use a different window / global context programatically ?

Experimenting with PollyJs and CypressJs. Need to bind this lib to a different window to get this to work.

Happy to fo the work needed, just wondering if this is something this lib will embrace?

Thx

Publish version 1.1.0

I wanted to report the same issue as #5 but I found out it is already fixed. Could you please do NPM publish of 1.0.2?

I'd love to know which mocked/stubbed responses didn't get sent

I've got some non-trivial unit tests that may trigger multiple AJAX requests. I usually mock out the various responses I should handle in my tests and then call the function that will trigger those requests.

At the end of the test I'd like to be able to know if any or a particular response didn't get sent. Similar to https://github.com/node-nock/nock#pendingmocks

This would be useful to test not only that all the relevant requests were made, but also to validate that a particular request wasn't made, if its conditional.

[HELP] can't respond to xhr: INVALID_STATE_ERR - 4

Im writing a chrome extension that is essentially a proxy. I'm getting an invalid state error when trying to respond to a fake xhr request. When the proxyRequest method executes I'm seeing in the console that onload is triggered before I call respond. Thank you in advance for any help.

import { fakeXhr, FakeXMLHttpRequest, fakeServer, FakeServer } from 'nise'
import { isM3u8Url, isTsUrl, PROXY_REQUEST, Message, PROXY_RESPONSE } from './common'
import { generateId } from 'utils-and-helpers/helpers'
import { HttpMethod } from 'utils-and-helpers/enums'
import axios from 'axios'

let server: FakeServer
function createShim() {
    fakeXhr.FakeXMLHttpRequest.useFilters = true
    fakeXhr.FakeXMLHttpRequest.addFilter(xhrFilter)
    server = fakeServer.create({
        autoRespond: true
    })
    server.respondWith(proxyRequest)
}

function xhrFilter(method: string, url: string): boolean {
    if((method.toLocaleUpperCase() == HttpMethod.GET) && (isM3u8Url(url) || isTsUrl(url))) return false
    else return true
}

function proxyRequest(xhr: FakeXMLHttpRequest) {
    let id = generateId(25)
    let message: Message = {
        id,
        action: PROXY_REQUEST,
        async: xhr.async,
        method: xhr.method,
        requestBody: xhr.requestBody,
        requestHeaders: xhr.requestHeaders,
        url: xhr.url,
        username: xhr.username,
        withCredentials: xhr.withCredentials
    }
    xhr.onload = () => console.log(`${id}: load start`)
    chrome.runtime.sendMessage(message, response => {
        switch(response.action) {
            case PROXY_RESPONSE:
                console.log(`${id}: trying to respond`)
                xhr.respond(response.status, response.responseHeaders, response.responseBody)
                break
            default:
                xhr.error()
        }
    })
}

createShim()

//test
setInterval(() => {
    axios.get('https://5g9s179kfgx9wn8tqwj9-cul47i.p5cdn.com/dlive/transcode-93-29/dlive-47692714/1583938810/src/live.m3u8')
    .then(res => console.log('res: ' + res))
    .catch(error => console.error('error: ' + error))
}, 3000)

filters are not cleared on restore

Hi!

If you add a filter, call .restore() on fakeXhr and call useFakeXMLHttpRequest(), previously added filters are not cleared. Is that a bug or a desired behaviour?

TypeError: GlobalTextEncoder is not a constructor

We use sinon with jsdom and recently updated sinon to 8.0.1 and starts to fail with

        Mozilla/5.0 (darwin) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/15.2.1
      Fake server request processing threw exception: GlobalTextEncoder is not a constructor
      TypeError: GlobalTextEncoder is not a constructor
          at convertToArrayBuffer (webpack:///./node_modules/nise/nise.js?:756:12)
          at convertResponseBody (webpack:///./node_modules/nise/nise.js?:960:30)
          at FakeXMLHttpRequest.setResponseBody (webpack:///./node_modules/nise/nise.js?:1317:29)
          at FakeXMLHttpRequest.respond (webpack:///./node_modules/nise/nise.js?:1333:18)
          at Object.processRequest (webpack:///./node_modules/nise/nise.js?:584:25)
          at eval (webpack:///./node_modules/nise/nise.js?:547:18)
          at Array.forEach (<anonymous>)
          at Object.respond (webpack:///./node_modules/nise/nise.js?:546:18)

jsdom does not implement TextEncoder (ref) and in ./node_modules/nise/nise.js @sinonjs/text-encoding is embed as empty module.

},{"./create-matcher":32,"./deep-equal":41,"./identical":43,"./is-arguments":44,"./is-element":46,"./is-map":47,"./is-neg-zero":49,"./is-set":51,"./match":54}],56:[function(require,module,exports){
  // empty!
},{}],57:[function(require,module,exports){

// abbrev...

module.exports = extend(fakeXMLHttpRequestFor(globalObject), {
    fakeXMLHttpRequestFor: fakeXMLHttpRequestFor
});

},{"../configure-logger":1,"../event":5,"./blob":10,"@sinonjs/commons":19,"@sinonjs/text-encoding":56,"just-extend":58}],12:[function(require,module,exports){ // the number is 56

I expect nise loads sinonjs/text-encoding properly. How can I use sinon with jsdom?

FakeXMLHttpRequest.defake doesn't reflect enough of a real event

Hi,

Recently come across a need to use xhr.useFilters = true; where we allow real requests to go through, and only mock parts that shouldn't be allowed.

However I've tracked down an issue where when we are "defaking" a request, we're missing some more of the real-ish type properties on the event.

Specifically for us, currentTarget is not beside target.

fakeXhr.onreadystatechange.call(fakeXhr, { target: fakeXhr }); currently needs currentTarget: fakeXhr added.

Is this something that other people are seeing, or kind of an edge case for us?

Happy to present a PR, but at this stage all we need in addition to target, is currentTarget, but there's still a lot of other native-ish properties that are dropped when un-faking it, it may be better to not fake the request before checking filters (and thus remove the need to recreate the original event).

Thoughts?

unable to install nise version 1.4.4

When i am trying to install nise version 1.4.4 i am getting the below error
Tried commands
npm install -g nise
npm install -g [email protected]

Error
npm ERR! code ETARGET
npm ERR! notarget No matching version found for just-extend@^3.0.0
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.
npm ERR! notarget

But when i am trying to install nise version 1.4.3 then it doesnt throw any error

npm install -g [email protected]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.