Skip to content

Commit

Permalink
Regression coverage for incorrect loaded & progress stats (#1005)
Browse files Browse the repository at this point in the history
An attempt to prove and model #1001 with a failing regression test

Unfortunately to do so I've also had to modify some internals...

Mirage upload handler 🌴
Adjusted this route handler to more accurately model a real upload request.

It now fires onloadstart, onprogress and onloadend rather then onprogress only.

The total value of the onloadend ProgressEvent is intentionally set to an arbitrary value.

⚠️ I don't think this is a breaking change, and I'd be surprised if it affected users of the mirage handler as it's a specific implementation detail of something this addon handles for users. No guarantees, though.

HTTPRequest 🌐
Setup so that onloadstart and onloadend may be called from the Mirage handler.

Shouldn't affect addon users.
  • Loading branch information
gilest authored Oct 21, 2023
1 parent 613d2b5 commit d511150
Show file tree
Hide file tree
Showing 10 changed files with 4,511 additions and 154 deletions.
20 changes: 17 additions & 3 deletions ember-file-upload/src/mirage/upload-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ const NETWORK = {
interface FakeRequest {
requestBody: FormData | object; // Replaced with an object by this handler
upload: {
onloadstart: (event: ProgressEvent<EventTarget>) => void;
onprogress: (event: ProgressEvent<EventTarget>) => void;
onloadend: (event: ProgressEvent<EventTarget>) => void;
};
}

Expand Down Expand Up @@ -50,14 +52,26 @@ export function uploadHandler(
return new RSVP.Promise((resolve) => {
const start = new Date().getTime();

request.upload.onloadstart(
new ProgressEvent('loadstart', {
lengthComputable: true,
total,
loaded: Math.min(loaded, total),
}),
);

const upload = async () => {
const timedOut =
options.timeout && new Date().getTime() - start > options.timeout;
if (timedOut || loaded >= total) {
request.upload.onprogress(
new ProgressEvent('progress', {
request.upload.onloadend(
new ProgressEvent('loadend', {
lengthComputable: true,
total,
// For the loadend event the `total` value may be sourced from the `Content-Length` response header of the upload endpoint.
// In which case it may represent the size of the response rather than the number of uploaded bytes.
// So we set it to an arbitrary value to make sure this doesn't influence file upload and queue progress stats.
// See: https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent/total
total: 300,
loaded: Math.min(loaded, total),
}),
);
Expand Down
17 changes: 11 additions & 6 deletions ember-file-upload/src/system/http-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,20 @@ export default class HTTPRequest {
aborted.resolve();
});

this.request.onloadstart =
this.request.onprogress =
this.request.onloadend =
bind(this, function (evt) {
this.onprogress?.(evt);
});
this.request.onloadstart = bind(this, function (evt) {
this.onprogress?.(evt);
});
this.request.onprogress = bind(this, function (evt) {
this.onprogress?.(evt);
});
this.request.onloadend = bind(this, function (evt) {
this.onprogress?.(evt);
});

if (this.request.upload) {
this.request.upload.onloadstart = this.request.onprogress;
this.request.upload.onprogress = this.request.onprogress;
this.request.upload.onloadend = this.request.onprogress;
}

this.request.onload = bind(this, function () {
Expand Down
Loading

0 comments on commit d511150

Please sign in to comment.