canjs / can-fixture

Intercept and simulate AJAX requests. Works without CanJS.

Home Page:https://canjs.com/doc/can-fixture.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

can-fixture shouldn't copy all properties if type is arraybuffer

alexisabril opened this issue · comments

responseText and responseXML shouldn't be copied to the mockXHR if the xhr type is arraybuffer. Currently we have an excludes parameter, but it is singular in context(you can only skip one thing).

Note for a future implementation: We should probably have a type of matching algorithm to configure what properties to skip in which scenarios.

Sample test below for this behavior. I'm not sure how to assert/catch responseText & responseXML being set. Inside xhr.js there is a new XHR that is created, to which we try to assign these properties. Any thoughts are appreciated!

asyncTest('responseText & responseXML should not be set for arraybuffer types (#38)', function() {
    fixture('/onload', '/test/fixtures/foo.json');

    var xhr = new XMLHttpRequest();

    xhr.addEventListener('load', function() {
        fixture('/onload', null);
        start();
    });

    xhr.open('GET', '/onload');
    xhr.responseType = 'arraybuffer';
    xhr.send();
});

@alexisabril can you walk me through this a bit more?

What should be the expected behavior? Should we see that responseType is "arraybuffer" and convert the content of '/test/fixtures/foo.json' to an arraybuffer?

When you say mockXHR, that is the same object as xhr in your example right? We overwrite XMLHttpRequest object to return mockXHR objects. We use real XHR objects to fetch foo.json.

Where is the excludes parameter?

Finally, does it need to assert/catch those being set? Can it simply have the test never call start() and timeout?

A crazy like a fox way of testing this would be to use dependency injection to re-load xhr.js. Before re-loading it, you could put your own, custom XHR object on the window with getter/setters on those properties. @phillipskevin might be able to show you how to do this.

accidentally closed

What should be the expected behavior? Should we see that responseType is "arraybuffer" and convert the content of '/test/fixtures/foo.json' to an arraybuffer?

No, I'm setting responseType='arraybuffer' to verify that this error gets thrown:

image

Using a file path for the fixture is arbitrary. I actually don't use /test/fixtures/foo.json for anything other than forcing xhr.js to skip this condition:

if(fixtureSettings && typeof fixtureSettings.fixture === "function") {

If it skips that if statement, it'll end up calling makeXHR and subsequently assign in an attempt to copy all properties from our mockXHR to the new xhr.

When you say mockXHR, that is the same object as xhr in your example right? We overwrite XMLHttpRequest object to return mockXHR objects. We use real XHR objects to fetch foo.json.

Yes.

Where is the excludes parameter?

We don't want to exclude responseType|responseXML in all scenarios, but you're right in the sense that perhaps this condition belongs around the excludes parameter.

Finally, does it need to assert/catch those being set? Can it simply have the test never call start() and timeout?

Not sure about not calling start(), but the question I have is how to catch the thrown error illustrated above. Or rather, test that a property is being set.

A crazy like a fox way of testing this would be to use dependency injection to re-load xhr.js. Before re-loading it, you could put your own, custom XHR object on the window with getter/setters on those
properties. @phillipskevin might be able to show you how to do this.

That's true and this may be the solution. I don't understand how this is done at the moment, but would love to take a look.

I think the gist of it is:

import stealClone from 'steal-clone';
...

window.XMLHttpRequest = function() {
  // return your object with setters/getters for responseText/responseXML with 
};

var clone = stealClone({});

clone
  .import('xhr', function() {
    clone.import('can-fixture', function() {
       // run test code here
    });
  });

It's a little bit complicated because I think you need to import xhr and then can-fixture. I'd be happy to pair with you on it @alexisabril.

I added a breaking test for this issue on this branch: https://github.com/canjs/can-fixture/tree/dont-set-response-text. Let me know if you have any feedback @justinbmeyer @alexisabril @daffl.

Awesome! Thanks for the assist @phillipskevin!

Actually, we should have a fix for it in #40.

we ran in to the same issue on our project, so @daffl and I were looking into it. He actually found out my test wasn't totally working and put in a much simpler test. You can give him all the credit.

Closing this issue as #40 has been merged into master