Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

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

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

Comments

@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
Copy link
Contributor

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
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
Copy link
Contributor

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
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
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
Copy link
Member

gkalpak commented Feb 17, 2016

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

gkalpak added a commit that referenced this issue Feb 17, 2016
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
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 subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants