mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
✅ add tests for gh-uploader
component (#701)
no issue - filled in tests ready to start work on https://github.com/TryGhost/Ghost/issues/8455
This commit is contained in:
parent
fccc04ebe1
commit
e8ff4ac1dd
4 changed files with 392 additions and 37 deletions
|
@ -5,6 +5,7 @@ import {isEmpty} from 'ember-utils';
|
||||||
import {task, all} from 'ember-concurrency';
|
import {task, all} from 'ember-concurrency';
|
||||||
import ghostPaths from 'ghost-admin/utils/ghost-paths';
|
import ghostPaths from 'ghost-admin/utils/ghost-paths';
|
||||||
import EmberObject from 'ember-object';
|
import EmberObject from 'ember-object';
|
||||||
|
import run from 'ember-runloop';
|
||||||
|
|
||||||
// TODO: this is designed to be a more re-usable/composable upload component, it
|
// TODO: this is designed to be a more re-usable/composable upload component, it
|
||||||
// should be able to replace the duplicated upload logic in:
|
// should be able to replace the duplicated upload logic in:
|
||||||
|
@ -36,11 +37,10 @@ export default Component.extend({
|
||||||
tagName: '',
|
tagName: '',
|
||||||
|
|
||||||
ajax: injectService(),
|
ajax: injectService(),
|
||||||
notifications: injectService(),
|
|
||||||
|
|
||||||
// Public attributes
|
// Public attributes
|
||||||
accept: '',
|
accept: '',
|
||||||
extensions: null,
|
extensions: '',
|
||||||
files: null,
|
files: null,
|
||||||
paramName: 'uploadimage', // TODO: is this the best default?
|
paramName: 'uploadimage', // TODO: is this the best default?
|
||||||
uploadUrl: null,
|
uploadUrl: null,
|
||||||
|
@ -55,7 +55,6 @@ export default Component.extend({
|
||||||
// Private
|
// Private
|
||||||
_defaultUploadUrl: '/uploads/',
|
_defaultUploadUrl: '/uploads/',
|
||||||
_files: null,
|
_files: null,
|
||||||
_isUploading: false,
|
|
||||||
_uploadTrackers: null,
|
_uploadTrackers: null,
|
||||||
|
|
||||||
// Closure actions
|
// Closure actions
|
||||||
|
@ -87,8 +86,9 @@ export default Component.extend({
|
||||||
// if we have new files, validate and start an upload
|
// if we have new files, validate and start an upload
|
||||||
let files = this.get('files');
|
let files = this.get('files');
|
||||||
if (files && files !== this._files) {
|
if (files && files !== this._files) {
|
||||||
if (this._isUploading) {
|
if (this.get('_uploadFiles.isRunning')) {
|
||||||
throw new Error('Adding new files whilst an upload is in progress is not supported.');
|
// eslint-disable-next-line
|
||||||
|
console.error('Adding new files whilst an upload is in progress is not supported.');
|
||||||
}
|
}
|
||||||
|
|
||||||
this._files = files;
|
this._files = files;
|
||||||
|
@ -133,6 +133,11 @@ export default Component.extend({
|
||||||
let extensions = this.get('extensions');
|
let extensions = this.get('extensions');
|
||||||
let [, extension] = (/(?:\.([^.]+))?$/).exec(file.name);
|
let [, extension] = (/(?:\.([^.]+))?$/).exec(file.name);
|
||||||
|
|
||||||
|
// if extensions is falsy exit early and accept all files
|
||||||
|
if (!extensions) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isEmberArray(extensions)) {
|
if (!isEmberArray(extensions)) {
|
||||||
extensions = extensions.split(',');
|
extensions = extensions.split(',');
|
||||||
}
|
}
|
||||||
|
@ -159,6 +164,10 @@ export default Component.extend({
|
||||||
// populates this.errors and this.uploadUrls
|
// populates this.errors and this.uploadUrls
|
||||||
yield all(uploads);
|
yield all(uploads);
|
||||||
|
|
||||||
|
if (!isEmpty(this.get('errors'))) {
|
||||||
|
this.onFailed(this.get('errors'));
|
||||||
|
}
|
||||||
|
|
||||||
this.onComplete(this.get('uploadUrls'));
|
this.onComplete(this.get('uploadUrls'));
|
||||||
}).drop(),
|
}).drop(),
|
||||||
|
|
||||||
|
@ -180,32 +189,50 @@ export default Component.extend({
|
||||||
let xhr = new window.XMLHttpRequest();
|
let xhr = new window.XMLHttpRequest();
|
||||||
|
|
||||||
xhr.upload.addEventListener('progress', (event) => {
|
xhr.upload.addEventListener('progress', (event) => {
|
||||||
tracker.update(event);
|
run(() => {
|
||||||
this._updateProgress();
|
tracker.update(event);
|
||||||
|
this._updateProgress();
|
||||||
|
});
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
return xhr;
|
return xhr;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// force tracker progress to 100% in case we didn't get a final event,
|
||||||
|
// eg. when using mirage
|
||||||
|
tracker.update({loaded: file.size, total: file.size});
|
||||||
|
this._updateProgress();
|
||||||
|
|
||||||
// TODO: is it safe to assume we'll only get a url back?
|
// TODO: is it safe to assume we'll only get a url back?
|
||||||
let uploadUrl = JSON.parse(response);
|
let uploadUrl = JSON.parse(response);
|
||||||
|
let result = {
|
||||||
this.get('uploadUrls').push({
|
|
||||||
fileName: file.name,
|
fileName: file.name,
|
||||||
url: uploadUrl
|
url: uploadUrl
|
||||||
});
|
};
|
||||||
|
|
||||||
|
this.get('uploadUrls').pushObject(result);
|
||||||
|
this.onUploadSuccess(result);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('error', error); // eslint-disable-line
|
// grab custom error message if present
|
||||||
|
let message = error.errors && error.errors[0].message;
|
||||||
|
|
||||||
// TODO: check for or expose known error types?
|
// fall back to EmberData/ember-ajax default message for error type
|
||||||
this.get('errors').push({
|
if (!message) {
|
||||||
|
message = error.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = {
|
||||||
fileName: file.name,
|
fileName: file.name,
|
||||||
message: error.errors[0].message
|
message: error.errors[0].message
|
||||||
});
|
};
|
||||||
|
|
||||||
|
// TODO: check for or expose known error types?
|
||||||
|
this.get('errors').pushObject(result);
|
||||||
|
this.onUploadFail(result);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -247,7 +274,6 @@ export default Component.extend({
|
||||||
this.set('uploadedSize', 0);
|
this.set('uploadedSize', 0);
|
||||||
this.set('uploadPercentage', 0);
|
this.set('uploadPercentage', 0);
|
||||||
this._uploadTrackers = [];
|
this._uploadTrackers = [];
|
||||||
this._isUploading = false;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="gh-progress-container">
|
<div class="gh-progress-container">
|
||||||
<div class="gh-progress-container-progress">
|
<div class="gh-progress-container-progress">
|
||||||
<div class="gh-progress-bar {{if isError "-error"}}" style={{progressStyle}}></div>
|
<div class="gh-progress-bar {{if isError "-error"}}" style={{progressStyle}} data-test-progress-bar></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
{{#if hasBlock}}
|
{{yield (hash
|
||||||
{{yield (hash
|
progressBar=(component "gh-progress-bar" percentage=uploadPercentage)
|
||||||
progressBar=(component "gh-progress-bar" percentage=uploadPercentage)
|
files=files
|
||||||
files=files
|
errors=errors
|
||||||
errors=errors
|
cancel=(action "cancel")
|
||||||
cancel=(action "cancel")
|
)}}
|
||||||
)}}
|
|
||||||
{{else}}
|
|
||||||
{{!-- TODO: default uploader interface --}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
|
@ -2,23 +2,356 @@ import {expect} from 'chai';
|
||||||
import {describe, it} from 'mocha';
|
import {describe, it} from 'mocha';
|
||||||
import {setupComponentTest} from 'ember-mocha';
|
import {setupComponentTest} from 'ember-mocha';
|
||||||
import hbs from 'htmlbars-inline-precompile';
|
import hbs from 'htmlbars-inline-precompile';
|
||||||
|
import {createFile} from '../../helpers/file-upload';
|
||||||
|
import Pretender from 'pretender';
|
||||||
|
import sinon from 'sinon';
|
||||||
|
import wait from 'ember-test-helpers/wait';
|
||||||
|
import run from 'ember-runloop';
|
||||||
|
import {click, find, findAll} from 'ember-native-dom-helpers';
|
||||||
|
import testSelector from 'ember-test-selectors';
|
||||||
|
|
||||||
|
const stubSuccessfulUpload = function (server, delay = 0) {
|
||||||
|
server.post('/ghost/api/v0.1/uploads/', function () {
|
||||||
|
return [200, {'Content-Type': 'application/json'}, '"/content/images/test.png"'];
|
||||||
|
}, delay);
|
||||||
|
};
|
||||||
|
|
||||||
|
const stubFailedUpload = function (server, code, error, delay = 0) {
|
||||||
|
server.post('/ghost/api/v0.1/uploads/', function () {
|
||||||
|
return [code, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||||
|
errors: [{
|
||||||
|
errorType: error,
|
||||||
|
message: `Error: ${error}`
|
||||||
|
}]
|
||||||
|
})];
|
||||||
|
}, delay);
|
||||||
|
};
|
||||||
|
|
||||||
describe('Integration: Component: gh-uploader', function() {
|
describe('Integration: Component: gh-uploader', function() {
|
||||||
setupComponentTest('gh-uploader', {
|
setupComponentTest('gh-uploader', {
|
||||||
integration: true
|
integration: true
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders', function() {
|
let server;
|
||||||
// Set any properties with this.set('myProperty', 'value');
|
|
||||||
// Handle any actions with this.on('myAction', function(val) { ... });
|
|
||||||
// Template block usage:
|
|
||||||
// this.render(hbs`
|
|
||||||
// {{#gh-uploader}}
|
|
||||||
// template content
|
|
||||||
// {{/gh-uploader}}
|
|
||||||
// `);
|
|
||||||
|
|
||||||
this.render(hbs`{{gh-uploader}}`);
|
beforeEach(function () {
|
||||||
expect(this.$()).to.have.length(1);
|
server = new Pretender();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
server.shutdown();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('uploads', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
stubSuccessfulUpload(server);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('triggers uploads when `files` is set', async function () {
|
||||||
|
this.render(hbs`{{#gh-uploader files=files}}{{/gh-uploader}}`);
|
||||||
|
|
||||||
|
this.set('files', [createFile()]);
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
let [lastRequest] = server.handledRequests;
|
||||||
|
expect(server.handledRequests.length).to.equal(1);
|
||||||
|
expect(lastRequest.url).to.equal('/ghost/api/v0.1/uploads/');
|
||||||
|
// requestBody is a FormData object
|
||||||
|
// this will fail in anything other than Chrome and Firefox
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/FormData#Browser_compatibility
|
||||||
|
expect(lastRequest.requestBody.has('uploadimage')).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('triggers multiple uploads', async function () {
|
||||||
|
this.render(hbs`{{#gh-uploader files=files}}{{/gh-uploader}}`);
|
||||||
|
|
||||||
|
this.set('files', [createFile(), createFile()]);
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
expect(server.handledRequests.length).to.equal(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('triggers onStart when upload starts', async function () {
|
||||||
|
this.set('uploadStarted', sinon.spy());
|
||||||
|
|
||||||
|
this.render(hbs`{{#gh-uploader files=files onStart=(action uploadStarted)}}{{/gh-uploader}}`);
|
||||||
|
this.set('files', [createFile(), createFile()]);
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
expect(this.get('uploadStarted').calledOnce).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('triggers onUploadSuccess when a file uploads', async function () {
|
||||||
|
this.set('fileUploaded', sinon.spy());
|
||||||
|
|
||||||
|
this.render(hbs`{{#gh-uploader files=files onUploadSuccess=(action fileUploaded)}}{{/gh-uploader}}`);
|
||||||
|
this.set('files', [createFile(['test'], {name: 'file1.png'}), createFile()]);
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
// triggered for each file
|
||||||
|
expect(this.get('fileUploaded').calledTwice).to.be.true;
|
||||||
|
|
||||||
|
// filename and url is passed in arg
|
||||||
|
let firstCall = this.get('fileUploaded').getCall(0);
|
||||||
|
expect(firstCall.args[0].fileName).to.equal('file1.png');
|
||||||
|
expect(firstCall.args[0].url).to.equal('/content/images/test.png');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('triggers onComplete when all files uploaded', async function () {
|
||||||
|
this.set('uploadsFinished', sinon.spy());
|
||||||
|
|
||||||
|
this.render(hbs`{{#gh-uploader files=files onComplete=(action uploadsFinished)}}{{/gh-uploader}}`);
|
||||||
|
this.set('files', [
|
||||||
|
createFile(['test'], {name: 'file1.png'}),
|
||||||
|
createFile(['test'], {name: 'file2.png'})
|
||||||
|
]);
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
expect(this.get('uploadsFinished').calledOnce).to.be.true;
|
||||||
|
|
||||||
|
// array of filenames and urls is passed in arg
|
||||||
|
let [result] = this.get('uploadsFinished').getCall(0).args;
|
||||||
|
expect(result.length).to.equal(2);
|
||||||
|
expect(result[0].fileName).to.equal('file1.png');
|
||||||
|
expect(result[0].url).to.equal('/content/images/test.png');
|
||||||
|
expect(result[1].fileName).to.equal('file2.png');
|
||||||
|
expect(result[1].url).to.equal('/content/images/test.png');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('doesn\'t allow new files to be set whilst uploading', async function () {
|
||||||
|
let errorSpy = sinon.spy(console, 'error');
|
||||||
|
stubSuccessfulUpload(server, 100);
|
||||||
|
|
||||||
|
this.render(hbs`{{#gh-uploader files=files}}{{/gh-uploader}}`);
|
||||||
|
this.set('files', [createFile()]);
|
||||||
|
|
||||||
|
// logs error because upload is in progress
|
||||||
|
run.later(() => {
|
||||||
|
this.set('files', [createFile()]);
|
||||||
|
}, 50);
|
||||||
|
|
||||||
|
// runs ok because original upload has finished
|
||||||
|
run.later(() => {
|
||||||
|
this.set('files', [createFile()]);
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
expect(server.handledRequests.length).to.equal(2);
|
||||||
|
expect(errorSpy.calledOnce).to.be.true;
|
||||||
|
errorSpy.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('yields progressBar component with total upload progress', async function () {
|
||||||
|
stubSuccessfulUpload(server, 200);
|
||||||
|
|
||||||
|
this.render(hbs`
|
||||||
|
{{#gh-uploader files=files as |uploader|}}
|
||||||
|
{{uploader.progressBar}}
|
||||||
|
{{/gh-uploader}}`);
|
||||||
|
|
||||||
|
this.set('files', [createFile(), createFile()]);
|
||||||
|
|
||||||
|
run.later(() => {
|
||||||
|
expect(find(testSelector('progress-bar'))).to.exist;
|
||||||
|
let progressWidth = parseInt(find(testSelector('progress-bar')).style.width);
|
||||||
|
expect(progressWidth).to.be.above(0);
|
||||||
|
expect(progressWidth).to.be.below(100);
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
let progressWidth = parseInt(find(testSelector('progress-bar')).style.width);
|
||||||
|
expect(progressWidth).to.equal(100);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('yields files property', function () {
|
||||||
|
this.render(hbs`
|
||||||
|
{{#gh-uploader files=files as |uploader|}}
|
||||||
|
{{#each uploader.files as |file|}}
|
||||||
|
<div class="file">{{file.name}}</div>
|
||||||
|
{{/each}}
|
||||||
|
{{/gh-uploader}}`);
|
||||||
|
|
||||||
|
this.set('files', [
|
||||||
|
createFile(['test'], {name: 'file1.png'}),
|
||||||
|
createFile(['test'], {name: 'file2.png'})
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(findAll('.file')[0].textContent).to.equal('file1.png');
|
||||||
|
expect(findAll('.file')[1].textContent).to.equal('file2.png');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can be cancelled', async function () {
|
||||||
|
stubSuccessfulUpload(server, 200);
|
||||||
|
this.set('cancelled', sinon.spy());
|
||||||
|
this.set('complete', sinon.spy());
|
||||||
|
|
||||||
|
this.render(hbs`
|
||||||
|
{{#gh-uploader files=files onCancel=(action cancelled) as |uploader|}}
|
||||||
|
<button class="cancel-button" {{action uploader.cancel}}>Cancel</button>
|
||||||
|
{{/gh-uploader}}`);
|
||||||
|
|
||||||
|
this.set('files', [createFile()]);
|
||||||
|
|
||||||
|
run.later(() => {
|
||||||
|
click('.cancel-button');
|
||||||
|
}, 50);
|
||||||
|
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
expect(this.get('cancelled').calledOnce, 'onCancel triggered').to.be.true;
|
||||||
|
expect(this.get('complete').notCalled, 'onComplete triggered').to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('uploads to supplied `uploadUrl`', async function () {
|
||||||
|
server.post('/ghost/api/v0.1/images/', function () {
|
||||||
|
return [200, {'Content-Type': 'application/json'}, '"/content/images/test.png"'];
|
||||||
|
});
|
||||||
|
|
||||||
|
this.render(hbs`{{#gh-uploader files=files uploadUrl="/images/"}}{{/gh-uploader}}`);
|
||||||
|
this.set('files', [createFile()]);
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
let [lastRequest] = server.handledRequests;
|
||||||
|
expect(lastRequest.url).to.equal('/ghost/api/v0.1/images/');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('passes supplied paramName in request', async function () {
|
||||||
|
this.render(hbs`{{#gh-uploader files=files paramName="testupload"}}{{/gh-uploader}}`);
|
||||||
|
this.set('files', [createFile()]);
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
let [lastRequest] = server.handledRequests;
|
||||||
|
// requestBody is a FormData object
|
||||||
|
// this will fail in anything other than Chrome and Firefox
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/FormData#Browser_compatibility
|
||||||
|
expect(lastRequest.requestBody.has('testupload')).to.be.true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('validation', function () {
|
||||||
|
it('validates file extensions by default', async function () {
|
||||||
|
this.set('onFailed', sinon.spy());
|
||||||
|
|
||||||
|
this.render(hbs`
|
||||||
|
{{#gh-uploader files=files extensions="jpg,jpeg" onFailed=(action onFailed)}}{{/gh-uploader}}
|
||||||
|
`);
|
||||||
|
this.set('files', [createFile(['test'], {name: 'test.png'})]);
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
let [onFailedResult] = this.get('onFailed').firstCall.args;
|
||||||
|
expect(onFailedResult.length).to.equal(1);
|
||||||
|
expect(onFailedResult[0].fileName, 'onFailed file name').to.equal('test.png');
|
||||||
|
expect(onFailedResult[0].message, 'onFailed message').to.match(/not supported/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('accepts custom validation method', async function () {
|
||||||
|
this.set('validate', function (file) {
|
||||||
|
return `${file.name} failed test validation`;
|
||||||
|
});
|
||||||
|
this.set('onFailed', sinon.spy());
|
||||||
|
|
||||||
|
this.render(hbs`
|
||||||
|
{{#gh-uploader files=files validate=(action validate) onFailed=(action onFailed)}}{{/gh-uploader}}
|
||||||
|
`);
|
||||||
|
this.set('files', [createFile(['test'], {name: 'test.png'})]);
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
let [onFailedResult] = this.get('onFailed').firstCall.args;
|
||||||
|
expect(onFailedResult.length).to.equal(1);
|
||||||
|
expect(onFailedResult[0].fileName).to.equal('test.png');
|
||||||
|
expect(onFailedResult[0].message).to.equal('test.png failed test validation');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('yields errors when validation fails', async function () {
|
||||||
|
this.render(hbs`
|
||||||
|
{{#gh-uploader files=files extensions="jpg,jpeg" as |uploader|}}
|
||||||
|
{{#each uploader.errors as |error|}}
|
||||||
|
<div class="error-fileName">{{error.fileName}}</div>
|
||||||
|
<div class="error-message">{{error.message}}</div>
|
||||||
|
{{/each}}
|
||||||
|
{{/gh-uploader}}
|
||||||
|
`);
|
||||||
|
this.set('files', [createFile(['test'], {name: 'test.png'})]);
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
expect(find('.error-fileName').textContent).to.equal('test.png');
|
||||||
|
expect(find('.error-message').textContent).to.match(/not supported/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('server errors', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
stubFailedUpload(server, 500, 'No upload for you');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('triggers onFailed when uploads complete', async function () {
|
||||||
|
this.set('uploadFailed', sinon.spy());
|
||||||
|
this.set('uploadComplete', sinon.spy());
|
||||||
|
|
||||||
|
this.render(hbs`
|
||||||
|
{{#gh-uploader
|
||||||
|
files=files
|
||||||
|
onFailed=(action uploadFailed)
|
||||||
|
onComplete=(action uploadComplete)}}
|
||||||
|
{{/gh-uploader}}
|
||||||
|
`);
|
||||||
|
this.set('files', [
|
||||||
|
createFile(['test'], {name: 'file1.png'}),
|
||||||
|
createFile(['test'], {name: 'file2.png'})
|
||||||
|
]);
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
expect(this.get('uploadFailed').calledOnce).to.be.true;
|
||||||
|
expect(this.get('uploadComplete').calledOnce).to.be.true;
|
||||||
|
|
||||||
|
let [failures] = this.get('uploadFailed').firstCall.args;
|
||||||
|
expect(failures.length).to.equal(2);
|
||||||
|
expect(failures[0].fileName).to.equal('file1.png');
|
||||||
|
expect(failures[0].message).to.equal('Error: No upload for you');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('triggers onUploadFail when each upload fails', async function () {
|
||||||
|
this.set('uploadFail', sinon.spy());
|
||||||
|
|
||||||
|
this.render(hbs`
|
||||||
|
{{#gh-uploader
|
||||||
|
files=files
|
||||||
|
onUploadFail=(action uploadFail)}}
|
||||||
|
{{/gh-uploader}}
|
||||||
|
`);
|
||||||
|
this.set('files', [
|
||||||
|
createFile(['test'], {name: 'file1.png'}),
|
||||||
|
createFile(['test'], {name: 'file2.png'})
|
||||||
|
]);
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
expect(this.get('uploadFail').calledTwice).to.be.true;
|
||||||
|
|
||||||
|
let [firstFailure] = this.get('uploadFail').firstCall.args;
|
||||||
|
expect(firstFailure.fileName).to.equal('file1.png');
|
||||||
|
expect(firstFailure.message).to.equal('Error: No upload for you');
|
||||||
|
|
||||||
|
let [secondFailure] = this.get('uploadFail').secondCall.args;
|
||||||
|
expect(secondFailure.fileName).to.equal('file2.png');
|
||||||
|
expect(secondFailure.message).to.equal('Error: No upload for you');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('yields errors when uploads fail', async function () {
|
||||||
|
this.render(hbs`
|
||||||
|
{{#gh-uploader files=files as |uploader|}}
|
||||||
|
{{#each uploader.errors as |error|}}
|
||||||
|
<div class="error-fileName">{{error.fileName}}</div>
|
||||||
|
<div class="error-message">{{error.message}}</div>
|
||||||
|
{{/each}}
|
||||||
|
{{/gh-uploader}}
|
||||||
|
`);
|
||||||
|
this.set('files', [createFile(['test'], {name: 'test.png'})]);
|
||||||
|
await wait();
|
||||||
|
|
||||||
|
expect(find('.error-fileName').textContent).to.equal('test.png');
|
||||||
|
expect(find('.error-message').textContent).to.equal('Error: No upload for you');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue