mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
Updated gh-uploader to work with new /images/upload/ endpoint
This commit is contained in:
parent
a0a0c50ff5
commit
72d9732958
6 changed files with 57 additions and 23 deletions
|
@ -3,7 +3,7 @@ import EmberObject from '@ember/object';
|
|||
import ghostPaths from 'ghost-admin/utils/ghost-paths';
|
||||
import {all, task} from 'ember-concurrency';
|
||||
import {get} from '@ember/object';
|
||||
import {isArray as isEmberArray} from '@ember/array';
|
||||
import {isArray} from '@ember/array';
|
||||
import {isEmpty} from '@ember/utils';
|
||||
import {run} from '@ember/runloop';
|
||||
import {inject as service} from '@ember/service';
|
||||
|
@ -51,7 +51,9 @@ export default Component.extend({
|
|||
accept: '',
|
||||
extensions: '',
|
||||
files: null,
|
||||
paramName: 'uploadimage', // TODO: is this the best default?
|
||||
paramName: 'file',
|
||||
paramsHash: null,
|
||||
resourceName: 'images',
|
||||
uploadUrl: null,
|
||||
|
||||
// Interal attributes
|
||||
|
@ -62,7 +64,7 @@ export default Component.extend({
|
|||
uploadUrls: null, // [{filename: 'x', url: 'y'}],
|
||||
|
||||
// Private
|
||||
_defaultUploadUrl: '/images/',
|
||||
_defaultUploadUrl: '/images/upload/',
|
||||
_files: null,
|
||||
_uploadTrackers: null,
|
||||
|
||||
|
@ -83,6 +85,10 @@ export default Component.extend({
|
|||
this.set('errors', []);
|
||||
this.set('uploadUrls', []);
|
||||
this._uploadTrackers = [];
|
||||
|
||||
if (!this.paramsHash) {
|
||||
this.set('paramsHash', {purpose: 'image'});
|
||||
}
|
||||
},
|
||||
|
||||
didReceiveAttrs() {
|
||||
|
@ -169,7 +175,7 @@ export default Component.extend({
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!isEmberArray(extensions)) {
|
||||
if (!isArray(extensions)) {
|
||||
extensions = extensions.split(',');
|
||||
}
|
||||
|
||||
|
@ -240,10 +246,27 @@ export default Component.extend({
|
|||
tracker.update({loaded: file.size, total: file.size});
|
||||
this._updateProgress();
|
||||
|
||||
let uploadResponse = JSON.parse(response);
|
||||
let uploadResponse;
|
||||
let responseUrl;
|
||||
|
||||
try {
|
||||
uploadResponse = JSON.parse(response);
|
||||
} catch (e) {
|
||||
if (!(e instanceof SyntaxError)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (uploadResponse) {
|
||||
let resource = get(uploadResponse, this.resourceName);
|
||||
if (resource && isArray(resource) && resource[0]) {
|
||||
responseUrl = get(resource[0], 'url');
|
||||
}
|
||||
}
|
||||
|
||||
let result = {
|
||||
fileName: file.name,
|
||||
url: get(uploadResponse, 'url')
|
||||
url: responseUrl,
|
||||
fileName: file.name
|
||||
};
|
||||
|
||||
this.get('uploadUrls')[index] = result;
|
||||
|
@ -274,6 +297,11 @@ export default Component.extend({
|
|||
_getFormData(file) {
|
||||
let formData = new FormData();
|
||||
formData.append(this.get('paramName'), file, file.name);
|
||||
|
||||
Object.keys(this.paramsHash || {}).forEach((key) => {
|
||||
formData.append(key, this.paramsHash[key]);
|
||||
});
|
||||
|
||||
return formData;
|
||||
},
|
||||
|
||||
|
|
|
@ -95,7 +95,8 @@
|
|||
<div class="gh-setting" data-test-setting="icon">
|
||||
{{#gh-uploader
|
||||
extensions=iconExtensions
|
||||
uploadUrl="/images/icon/"
|
||||
uploadUrl="/images/upload/"
|
||||
paramsHash=(hash purpose="icon")
|
||||
onComplete=(action "imageUploaded" "icon")
|
||||
as |uploader|
|
||||
}}
|
||||
|
|
|
@ -51,7 +51,7 @@ export function testConfig() {
|
|||
// this.urlPrefix = ''; // make this `http://localhost:8080`, for example, if your API is on a different server
|
||||
this.namespace = '/ghost/api/v2/admin'; // make this `api`, for example, if your API is namespaced
|
||||
// this.timing = 400; // delay for each request, automatically set to 0 during testing
|
||||
this.logging = false;
|
||||
this.logging = true;
|
||||
|
||||
mockApiKeys(this);
|
||||
mockAuthentication(this);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
const fileUploadResponse = function (db, {requestBody}) {
|
||||
let [file] = requestBody.getAll('uploadimage');
|
||||
// let [ref] = requestBody.getAll('ref');
|
||||
let [purpose] = requestBody.getAll('purpose');
|
||||
let [file] = requestBody.getAll('file');
|
||||
let now = new Date();
|
||||
let year = now.getFullYear();
|
||||
let month = `${now.getMonth()}`;
|
||||
|
@ -8,12 +10,15 @@ const fileUploadResponse = function (db, {requestBody}) {
|
|||
month = `0${month}`;
|
||||
}
|
||||
|
||||
return {
|
||||
url: `/content/images/${year}/${month}/${file.name}`
|
||||
};
|
||||
if (['image', 'profile_image', 'icon'].includes(purpose)) {
|
||||
return {
|
||||
images: [{
|
||||
url: `/content/images/${year}/${month}/${file.name}`
|
||||
}]
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export default function mockUploads(server) {
|
||||
server.post('/images/', fileUploadResponse, 200, {timing: 100});
|
||||
server.post('/images/icon/', fileUploadResponse, 200, {timing: 100});
|
||||
server.post('/images/upload/', fileUploadResponse, 200, {timing: 100});
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ describe('Acceptance: Settings - General', function () {
|
|||
).to.not.exist;
|
||||
|
||||
// failed upload shows error
|
||||
this.server.post('/images/icon/', function () {
|
||||
this.server.post('/images/upload/', function () {
|
||||
return {
|
||||
errors: [{
|
||||
errorType: 'ValidationError',
|
||||
|
|
|
@ -9,13 +9,13 @@ import {run} from '@ember/runloop';
|
|||
import {setupRenderingTest} from 'ember-mocha';
|
||||
|
||||
const stubSuccessfulUpload = function (server, delay = 0) {
|
||||
server.post('/ghost/api/v2/admin/images/', function () {
|
||||
return [200, {'Content-Type': 'application/json'}, '{"url": "/content/images/test.png"}'];
|
||||
server.post('/ghost/api/v2/admin/images/upload/', function () {
|
||||
return [200, {'Content-Type': 'application/json'}, '{"images": [{"url": "/content/images/test.png"}]}'];
|
||||
}, delay);
|
||||
};
|
||||
|
||||
const stubFailedUpload = function (server, code, error, delay = 0) {
|
||||
server.post('/ghost/api/v2/admin/images/', function () {
|
||||
server.post('/ghost/api/v2/admin/images/upload/', function () {
|
||||
return [code, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||
errors: [{
|
||||
errorType: error,
|
||||
|
@ -51,11 +51,11 @@ describe('Integration: Component: gh-uploader', function () {
|
|||
|
||||
let [lastRequest] = server.handledRequests;
|
||||
expect(server.handledRequests.length).to.equal(1);
|
||||
expect(lastRequest.url).to.equal('/ghost/api/v2/admin/images/');
|
||||
expect(lastRequest.url).to.equal('/ghost/api/v2/admin/images/upload/');
|
||||
// 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;
|
||||
expect(lastRequest.requestBody.has('file')).to.be.true;
|
||||
});
|
||||
|
||||
it('triggers multiple uploads', async function () {
|
||||
|
@ -136,7 +136,7 @@ describe('Integration: Component: gh-uploader', function () {
|
|||
|
||||
it('onComplete returns results in same order as selected', async function () {
|
||||
// first request has a delay to simulate larger file
|
||||
server.post('/ghost/api/v2/admin/images/', function () {
|
||||
server.post('/ghost/api/v2/admin/images/upload/', function () {
|
||||
// second request has no delay to simulate small file
|
||||
stubSuccessfulUpload(server, 0);
|
||||
|
||||
|
@ -266,7 +266,7 @@ describe('Integration: Component: gh-uploader', function () {
|
|||
|
||||
it('uploads to supplied `uploadUrl`', async function () {
|
||||
server.post('/ghost/api/v2/admin/images/', function () {
|
||||
return [200, {'Content-Type': 'application/json'}, '"/content/images/test.png"'];
|
||||
return [200, {'Content-Type': 'application/json'}, '{"images": [{"url": "/content/images/test.png"}]'];
|
||||
});
|
||||
|
||||
await render(hbs`{{#gh-uploader files=files uploadUrl="/images/"}}{{/gh-uploader}}`);
|
||||
|
|
Loading…
Add table
Reference in a new issue