Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$httpBackend cannot mock binary blob responses at IE11 (InvalidStateError) #9669

Closed
yneves opened this Issue Oct 17, 2014 · 4 comments

Comments

Projects
None yet
4 participants
@yneves
Copy link

yneves commented Oct 17, 2014

I found this issue running tests with karma at IE11 / Win8.1.

When i try to mock a blob response with $httpBackend.expect, i got InvalidStateError.

I dig and found that this happens because of the angular.copy which clones fake response data.

If i hack angular.copy with something like this the error stops.

if (isBlob(source)) {
    destination = new Blob([source]);
} else if (isArray(source)) {
@jurko-gospodnetic

This comment has been minimized.

Copy link
Contributor

jurko-gospodnetic commented Feb 6, 2016

This is not browser specific. And pretty much prevents your from mocking HTTP requests with Blob responses. :-(

And it's related to the issue in pull request #5415, but where that one is only concerned with using the ng-mocks in pass-through mode for e2e testing.

@gkalpak

This comment has been minimized.

Copy link
Member

gkalpak commented Feb 6, 2016

@jurko-gospodnetic, I couldn't reprocude it just by angular.copying and Blob. Could you create a live demo of the issue (e.g. using CodePen, Plnkr etc) ?

#5415, although about $httpBackend and Blobs, is about a totally different problem.

@jurko-gospodnetic

This comment has been minimized.

Copy link
Contributor

jurko-gospodnetic commented Feb 6, 2016

The shortest way to reproduce the problem is to just use the following one-liner:

angular.copy(new Blob(['bright side of life'])).slice();

And here's a plnkr reproducing the error: http://plnkr.co/xenwdKodooTrYO7VG2P2

It shows that you can't treat the almost-blob API response object you get from ng-mock as a true blob, while you can do so with the original blob given to ng-mock in its expectation. It also shows how you can not do so with an almost-blob object you get by calling angular.copy() on an actual blob object.

And if calling .slice() on it does not faze you, try using the FileReader interface to get at the blob's content, e.g. by using fileReader.readAsText() and hooking its onload (for success) & error/onloadend (for error) events.

When calling slice() on an angular.copy() produced almost-blob using PhantomJS, you get an impossible to debug error stack:

    TypeError: Type error in /your/project/path/here.js (line 42)
        at slice ([native code])

Chrome is not much better:

TypeError: Illegal invocation
    at Object.<anonymous> (http://run.plnkr.co/plunks/xenwdKodooTrYO7VG2P2/:41:20)

while FireFox seems to play a bit nicer and says:

TypeError: 'slice' called on an object that does not implement interface Blob. in http://run.plnkr.co/plunks/xenwdKodooTrYO7VG2P2/ (line 41)
@http://run.plnkr.co/plunks/xenwdKodooTrYO7VG2P2/:41:11

and IE11 seems as uninformative as Chrome:

TypeError: Invalid calling object
   at Anonymous function (http://run.plnkr.co/plunks/xenwdKodooTrYO7VG2P2/:41:11)

gkalpak added a commit to gkalpak/angular.js that referenced this issue Feb 17, 2016

fix(copy): add support for copying `Blob` objects
Although `copy()` does not need to (and never will) support all kinds of objects, there is a
(not uncommon) usecase for supporting `Blob` objects:

`ngMock`'s `$httpBackend` will return a copy of the response data (so that changes in one test
won't affect others). Since returning `Blob` objects in response to HTTP requests and since
`ngMocks`'s `$httpBackend` will use `copy()` to create a copy of that data, it is reasonable to
support `Blob` objects.
(I didn't run any benchmarks, but the additional check for the type of the copied element should
have negligible impact, cmpared to the other stuff that `copy()` is going.)

Fixes angular#9669

gkalpak added a commit to gkalpak/angular.js that referenced this issue Feb 17, 2016

fix(copy): add support for copying `Blob` objects
Although `copy()` does not need to (and never will) support all kinds of objects, there is a
(not uncommon) usecase for supporting `Blob` objects:

`ngMock`'s `$httpBackend` will return a copy of the response data (so that changes in one test won't
affect others). Since returning `Blob` objects in response to HTTP requests is a valid usecase and
since `ngMocks`'s `$httpBackend` will use `copy()` to create a copy of that data, it is reasonable
to support `Blob` objects.
(I didn't run any benchmarks, but the additional check for the type of the copied element should
have negligible impact, compared to the other stuff that `copy()` is doing.)

Fixes angular#9669
@gkalpak

This comment has been minimized.

Copy link
Member

gkalpak commented Feb 17, 2016

@jurko-gospodnetic, thx for the reproduction. I have submitted a fix in #14064.

@gkalpak gkalpak closed this in 0b1b911 Feb 17, 2016

gkalpak added a commit that referenced this issue Feb 17, 2016

fix(copy): add support for copying `Blob` objects
Although `copy()` does not need to (and never will) support all kinds of objects, there is a
(not uncommon) usecase for supporting `Blob` objects:

`ngMock`'s `$httpBackend` will return a copy of the response data (so that changes in one test won't
affect others). Since returning `Blob` objects in response to HTTP requests is a valid usecase and
since `ngMocks`'s `$httpBackend` will use `copy()` to create a copy of that data, it is reasonable
to support `Blob` objects.
(I didn't run any benchmarks, but the additional check for the type of the copied element should
have negligible impact, compared to the other stuff that `copy()` is doing.)

Fixes #9669

Closes #14064

gkalpak added a commit that referenced this issue Feb 17, 2016

fix(copy): add support for copying `Blob` objects
Although `copy()` does not need to (and never will) support all kinds of objects, there is a
(not uncommon) usecase for supporting `Blob` objects:

`ngMock`'s `$httpBackend` will return a copy of the response data (so that changes in one test won't
affect others). Since returning `Blob` objects in response to HTTP requests is a valid usecase and
since `ngMocks`'s `$httpBackend` will use `copy()` to create a copy of that data, it is reasonable
to support `Blob` objects.
(I didn't run any benchmarks, but the additional check for the type of the copied element should
have negligible impact, compared to the other stuff that `copy()` is doing.)

Fixes #9669

Closes #14064
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.