mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-28 14:03:48 +03:00
🔥 remove URL input option from image upload components
refs https://github.com/TryGhost/Ghost/issues/8032 - `fileStorage: false` config is going away, it predates storage engines and will simplify future image optimisation work - simplifies UI, it can be brought back in the future in a more robust fashion if required
This commit is contained in:
parent
0366bde545
commit
ea58dc6f85
@ -9,12 +9,6 @@ export default Component.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onInput() {
|
|
||||||
if (typeof this.attrs.onInput === 'function') {
|
|
||||||
this.attrs.onInput(...arguments);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
uploadStarted() {
|
uploadStarted() {
|
||||||
if (typeof this.attrs.uploadStarted === 'function') {
|
if (typeof this.attrs.uploadStarted === 'function') {
|
||||||
this.attrs.uploadStarted(...arguments);
|
this.attrs.uploadStarted(...arguments);
|
||||||
@ -27,12 +21,6 @@ export default Component.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
formChanged() {
|
|
||||||
if (typeof this.attrs.formChanged === 'function') {
|
|
||||||
this.attrs.formChanged(...arguments);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
remove() {
|
remove() {
|
||||||
invokeAction(this, 'remove');
|
invokeAction(this, 'remove');
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import {htmlSafe} from 'ember-string';
|
|||||||
import {isBlank} from 'ember-utils';
|
import {isBlank} from 'ember-utils';
|
||||||
import {isEmberArray} from 'ember-array/utils';
|
import {isEmberArray} from 'ember-array/utils';
|
||||||
import run from 'ember-runloop';
|
import run from 'ember-runloop';
|
||||||
|
|
||||||
import {invokeAction} from 'ember-invoke-action';
|
import {invokeAction} from 'ember-invoke-action';
|
||||||
import ghostPaths from 'ghost-admin/utils/ghost-paths';
|
import ghostPaths from 'ghost-admin/utils/ghost-paths';
|
||||||
import {
|
import {
|
||||||
@ -27,18 +26,15 @@ export default Component.extend({
|
|||||||
accept: null,
|
accept: null,
|
||||||
extensions: null,
|
extensions: null,
|
||||||
uploadUrl: null,
|
uploadUrl: null,
|
||||||
allowUrlInput: true,
|
|
||||||
validate: null,
|
validate: null,
|
||||||
|
|
||||||
dragClass: null,
|
dragClass: null,
|
||||||
failureMessage: null,
|
failureMessage: null,
|
||||||
file: null,
|
file: null,
|
||||||
formType: 'upload',
|
|
||||||
url: null,
|
url: null,
|
||||||
uploadPercentage: 0,
|
uploadPercentage: 0,
|
||||||
|
|
||||||
ajax: injectService(),
|
ajax: injectService(),
|
||||||
config: injectService(),
|
|
||||||
notifications: injectService(),
|
notifications: injectService(),
|
||||||
|
|
||||||
_defaultAccept: 'image/gif,image/jpg,image/jpeg,image/png,image/svg+xml',
|
_defaultAccept: 'image/gif,image/jpg,image/jpeg,image/png,image/svg+xml',
|
||||||
@ -75,17 +71,6 @@ export default Component.extend({
|
|||||||
return htmlSafe(`width: ${width}`);
|
return htmlSafe(`width: ${width}`);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
canShowUploadForm: computed('config.fileStorage', function () {
|
|
||||||
return this.get('config.fileStorage') !== false;
|
|
||||||
}),
|
|
||||||
|
|
||||||
showUploadForm: computed('formType', function () {
|
|
||||||
let canShowUploadForm = this.get('canShowUploadForm');
|
|
||||||
let formType = this.get('formType');
|
|
||||||
|
|
||||||
return formType === 'upload' && canShowUploadForm;
|
|
||||||
}),
|
|
||||||
|
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
let image = this.get('image');
|
let image = this.get('image');
|
||||||
this.set('url', image);
|
this.set('url', image);
|
||||||
@ -102,8 +87,6 @@ export default Component.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
dragOver(event) {
|
dragOver(event) {
|
||||||
let showUploadForm = this.get('showUploadForm');
|
|
||||||
|
|
||||||
if (!event.dataTransfer) {
|
if (!event.dataTransfer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -116,32 +99,21 @@ export default Component.extend({
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
if (showUploadForm) {
|
this.set('dragClass', '-drag-over');
|
||||||
this.set('dragClass', '-drag-over');
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
dragLeave(event) {
|
dragLeave(event) {
|
||||||
let showUploadForm = this.get('showUploadForm');
|
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
this.set('dragClass', null);
|
||||||
if (showUploadForm) {
|
|
||||||
this.set('dragClass', null);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
drop(event) {
|
drop(event) {
|
||||||
let showUploadForm = this.get('showUploadForm');
|
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
this.set('dragClass', null);
|
this.set('dragClass', null);
|
||||||
|
|
||||||
if (showUploadForm) {
|
if (event.dataTransfer.files) {
|
||||||
if (event.dataTransfer.files) {
|
this.send('fileSelected', event.dataTransfer.files);
|
||||||
this.send('fileSelected', event.dataTransfer.files);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -269,24 +241,11 @@ export default Component.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onInput(url) {
|
|
||||||
this.set('url', url);
|
|
||||||
invokeAction(this, 'onInput', url);
|
|
||||||
},
|
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.set('file', null);
|
this.set('file', null);
|
||||||
this.set('uploadPercentage', 0);
|
this.set('uploadPercentage', 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
switchForm(formType) {
|
|
||||||
this.set('formType', formType);
|
|
||||||
|
|
||||||
run.scheduleOnce('afterRender', this, function () {
|
|
||||||
invokeAction(this, 'formChanged', formType);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
saveUrl() {
|
saveUrl() {
|
||||||
let url = this.get('url');
|
let url = this.get('url');
|
||||||
invokeAction(this, 'update', url);
|
invokeAction(this, 'update', url);
|
||||||
|
@ -29,7 +29,6 @@ export default Component.extend({
|
|||||||
|
|
||||||
validEmail: '',
|
validEmail: '',
|
||||||
hasUploadedImage: false,
|
hasUploadedImage: false,
|
||||||
fileStorage: true,
|
|
||||||
ajax: AjaxService.create(),
|
ajax: AjaxService.create(),
|
||||||
|
|
||||||
config: injectService(),
|
config: injectService(),
|
||||||
|
@ -73,51 +73,6 @@
|
|||||||
font-size: 1.6rem;
|
font-size: 1.6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gh-image-uploader .image-upload,
|
|
||||||
.gh-image-uploader .image-url {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
display: block;
|
|
||||||
padding: 10px;
|
|
||||||
color: var(--midgrey);
|
|
||||||
text-decoration: none;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gh-image-uploader a {
|
|
||||||
color: var(--midgrey);
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gh-image-uploader a:hover {
|
|
||||||
color: var(--darkgrey);
|
|
||||||
}
|
|
||||||
.gh-image-uploader .image-upload:hover,
|
|
||||||
.gh-image-uploader .image-url:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gh-image-uploader form {
|
|
||||||
padding: 55px 60px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gh-image-uploader input.url {
|
|
||||||
margin: 0 0 10px 0;
|
|
||||||
padding: 9px 7px;
|
|
||||||
outline: 0;
|
|
||||||
background: #fff;
|
|
||||||
vertical-align: middle;
|
|
||||||
font: -webkit-small-control;
|
|
||||||
font-size: 1.4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gh-image-uploader input.url + .gh-btn.gh-btn-blue {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gh-image-uploader .image-cancel:hover {
|
.gh-image-uploader .image-cancel:hover {
|
||||||
background: var(--red);
|
background: var(--red);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
update=(action "updateImageSrc" uploader.index)
|
update=(action "updateImageSrc" uploader.index)
|
||||||
remove=(action "updateImageSrc" uploader.index "")
|
remove=(action "updateImageSrc" uploader.index "")
|
||||||
uploadStarted=uploadStarted
|
uploadStarted=uploadStarted
|
||||||
uploadFinished=uploadFinished
|
uploadFinished=uploadFinished}}
|
||||||
formChanged=(action "updateHeight")}}
|
|
||||||
{{/ember-wormhole}}
|
{{/ember-wormhole}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
@ -10,9 +10,7 @@
|
|||||||
text=text
|
text=text
|
||||||
altText=altText
|
altText=altText
|
||||||
update=(action 'update')
|
update=(action 'update')
|
||||||
onInput=(action 'onInput')
|
|
||||||
uploadStarted=(action 'uploadStarted')
|
uploadStarted=(action 'uploadStarted')
|
||||||
uploadFinished=(action 'uploadFinished')
|
uploadFinished=(action 'uploadFinished')
|
||||||
formChanged=(action 'formChanged')
|
|
||||||
}}
|
}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -12,33 +12,10 @@
|
|||||||
<button class="gh-btn gh-btn-green" {{action "reset"}}><span>Try Again</span></button>
|
<button class="gh-btn gh-btn-green" {{action "reset"}}><span>Try Again</span></button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if showUploadForm}}
|
{{!-- file selection/drag-n-drop --}}
|
||||||
{{!-- file selection/drag-n-drop --}}
|
<div class="upload-form">
|
||||||
<div class="upload-form">
|
{{#gh-file-input multiple=false alt=description action=(action "fileSelected") accept=accept}}
|
||||||
{{#gh-file-input multiple=false alt=description action=(action "fileSelected") accept=accept}}
|
<div class="description">{{description}}</div>
|
||||||
<div class="description">{{description}}</div>
|
{{/gh-file-input}}
|
||||||
{{/gh-file-input}}
|
</div>
|
||||||
</div>
|
|
||||||
{{#if allowUrlInput}}
|
|
||||||
<a class="image-url" {{action "switchForm" "url-input"}}>
|
|
||||||
<i class="icon-link"><span class="hidden">URL</span></i>
|
|
||||||
</a>
|
|
||||||
{{/if}}
|
|
||||||
{{else}}
|
|
||||||
{{!-- URL input --}}
|
|
||||||
<form class="url-form">
|
|
||||||
{{gh-input url class="url" placeholder="http://" update=(action "onInput") onenter=(action "saveUrl")}}
|
|
||||||
{{#if saveButton}}
|
|
||||||
<button class="gh-btn gh-btn-blue gh-input" {{action "saveUrl"}}><span>Save</span></button>
|
|
||||||
{{else}}
|
|
||||||
<div class="description">{{description}}</div>
|
|
||||||
{{/if}}
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{{#if canShowUploadForm}}
|
|
||||||
<a class="image-upload icon-photos" title="Add image" {{action "switchForm" "upload"}}>
|
|
||||||
<span class="hidden">Upload</span>
|
|
||||||
</a>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -13,5 +13,5 @@
|
|||||||
<span class="sr-only">Upload an image</span>
|
<span class="sr-only">Upload an image</span>
|
||||||
</i>
|
</i>
|
||||||
</span>
|
</span>
|
||||||
{{#if fileStorage}}<input type="file" class="file-uploader js-file-input" name="uploadimage">{{/if}}
|
<input type="file" class="file-uploader js-file-input" name="uploadimage">
|
||||||
</figure>
|
</figure>
|
||||||
|
@ -11,10 +11,8 @@
|
|||||||
image=newUrl
|
image=newUrl
|
||||||
saveButton=false
|
saveButton=false
|
||||||
update=(action 'fileUploaded')
|
update=(action 'fileUploaded')
|
||||||
onInput=(action (mut newUrl))
|
|
||||||
accept=model.accept
|
accept=model.accept
|
||||||
extensions=model.extensions
|
extensions=model.extensions
|
||||||
allowUrlInput=model.allowUrlInput
|
|
||||||
uploadUrl=model.uploadUrl
|
uploadUrl=model.uploadUrl
|
||||||
}}
|
}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -66,7 +66,7 @@
|
|||||||
|
|
||||||
{{#if showUploadIconModal}}
|
{{#if showUploadIconModal}}
|
||||||
{{gh-fullscreen-modal "upload-image"
|
{{gh-fullscreen-modal "upload-image"
|
||||||
model=(hash model=model imageProperty="icon" accept=iconMimeTypes extensions=iconExtensions allowUrlInput=false uploadUrl="/uploads/icon/")
|
model=(hash model=model imageProperty="icon" accept=iconMimeTypes extensions=iconExtensions uploadUrl="/uploads/icon/")
|
||||||
close=(action "toggleUploadIconModal")
|
close=(action "toggleUploadIconModal")
|
||||||
modifier="action wide"}}
|
modifier="action wide"}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
@ -86,7 +86,7 @@
|
|||||||
|
|
||||||
{{#if showUploadLogoModal}}
|
{{#if showUploadLogoModal}}
|
||||||
{{gh-fullscreen-modal "upload-image"
|
{{gh-fullscreen-modal "upload-image"
|
||||||
model=(hash model=model imageProperty="logo" allowUrlInput=true)
|
model=(hash model=model imageProperty="logo")
|
||||||
close=(action "toggleUploadLogoModal")
|
close=(action "toggleUploadLogoModal")
|
||||||
modifier="action wide"}}
|
modifier="action wide"}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
@ -106,7 +106,7 @@
|
|||||||
|
|
||||||
{{#if showUploadCoverModal}}
|
{{#if showUploadCoverModal}}
|
||||||
{{gh-fullscreen-modal "upload-image"
|
{{gh-fullscreen-modal "upload-image"
|
||||||
model=(hash model=model imageProperty="cover" allowUrlInput=true)
|
model=(hash model=model imageProperty="cover")
|
||||||
close=(action "toggleUploadCoverModal")
|
close=(action "toggleUploadCoverModal")
|
||||||
modifier="action wide"}}
|
modifier="action wide"}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
<input style="display:none;" type="text" name="fakeusernameremembered"/>
|
<input style="display:none;" type="text" name="fakeusernameremembered"/>
|
||||||
<input style="display:none;" type="password" name="fakepasswordremembered"/>
|
<input style="display:none;" type="password" name="fakepasswordremembered"/>
|
||||||
|
|
||||||
{{gh-profile-image fileStorage=config.fileStorage email=email setImage="setImage"}}
|
{{gh-profile-image email=email setImage="setImage"}}
|
||||||
{{#gh-form-group errors=errors hasValidated=hasValidated property="email"}}
|
{{#gh-form-group errors=errors hasValidated=hasValidated property="email"}}
|
||||||
<label for="email-address">Email address</label>
|
<label for="email-address">Email address</label>
|
||||||
<span class="input-icon icon-mail">
|
<span class="input-icon icon-mail">
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
<input style="display:none;" type="text" name="fakeusernameremembered"/>
|
<input style="display:none;" type="text" name="fakeusernameremembered"/>
|
||||||
<input style="display:none;" type="password" name="fakepasswordremembered"/>
|
<input style="display:none;" type="password" name="fakepasswordremembered"/>
|
||||||
|
|
||||||
{{gh-profile-image fileStorage=config.fileStorage email=model.email setImage="setImage"}}
|
{{gh-profile-image email=model.email setImage="setImage"}}
|
||||||
|
|
||||||
{{#gh-form-group}}
|
{{#gh-form-group}}
|
||||||
<label for="email-address">Email address</label>
|
<label for="email-address">Email address</label>
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
<button class="gh-btn gh-btn-default user-cover-edit" {{action "toggleUploadCoverModal"}}><span>Change Cover</span></button>
|
<button class="gh-btn gh-btn-default user-cover-edit" {{action "toggleUploadCoverModal"}}><span>Change Cover</span></button>
|
||||||
{{#if showUploadCoverModal}}
|
{{#if showUploadCoverModal}}
|
||||||
{{gh-fullscreen-modal "upload-image"
|
{{gh-fullscreen-modal "upload-image"
|
||||||
model=(hash model=user imageProperty="cover" allowUrlInput=true)
|
model=(hash model=user imageProperty="cover")
|
||||||
close=(action "toggleUploadCoverModal")
|
close=(action "toggleUploadCoverModal")
|
||||||
modifier="action wide"}}
|
modifier="action wide"}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
@ -74,7 +74,7 @@
|
|||||||
<button type="button" {{action "toggleUploadImageModal"}} class="edit-user-image">Edit Picture</button>
|
<button type="button" {{action "toggleUploadImageModal"}} class="edit-user-image">Edit Picture</button>
|
||||||
{{#if showUploadImageModal}}
|
{{#if showUploadImageModal}}
|
||||||
{{gh-fullscreen-modal "upload-image"
|
{{gh-fullscreen-modal "upload-image"
|
||||||
model=(hash model=user imageProperty="image" allowUrlInput=true)
|
model=(hash model=user imageProperty="image")
|
||||||
close=(action "toggleUploadImageModal")
|
close=(action "toggleUploadImageModal")
|
||||||
modifier="action wide"}}
|
modifier="action wide"}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -33,12 +33,10 @@ export default Component.extend({
|
|||||||
dragClass: null,
|
dragClass: null,
|
||||||
failureMessage: null,
|
failureMessage: null,
|
||||||
file: null,
|
file: null,
|
||||||
formType: 'upload',
|
|
||||||
url: null,
|
url: null,
|
||||||
uploadPercentage: 0,
|
uploadPercentage: 0,
|
||||||
|
|
||||||
ajax: injectService(),
|
ajax: injectService(),
|
||||||
config: injectService(),
|
|
||||||
notifications: injectService(),
|
notifications: injectService(),
|
||||||
|
|
||||||
// TODO: this wouldn't be necessary if the server could accept direct
|
// TODO: this wouldn't be necessary if the server could accept direct
|
||||||
@ -70,17 +68,6 @@ export default Component.extend({
|
|||||||
return htmlSafe(`width: ${width}`);
|
return htmlSafe(`width: ${width}`);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
canShowUploadForm: computed('config.fileStorage', function () {
|
|
||||||
return this.get('config.fileStorage') !== false;
|
|
||||||
}),
|
|
||||||
|
|
||||||
showUploadForm: computed('formType', function () {
|
|
||||||
let canShowUploadForm = this.get('canShowUploadForm');
|
|
||||||
let formType = this.get('formType');
|
|
||||||
|
|
||||||
return formType === 'upload' && canShowUploadForm;
|
|
||||||
}),
|
|
||||||
|
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
let image = this.get('payload');
|
let image = this.get('payload');
|
||||||
if (image.img) {
|
if (image.img) {
|
||||||
@ -93,8 +80,6 @@ export default Component.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
dragOver(event) {
|
dragOver(event) {
|
||||||
let showUploadForm = this.get('showUploadForm');
|
|
||||||
|
|
||||||
if (!event.dataTransfer) {
|
if (!event.dataTransfer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -107,32 +92,21 @@ export default Component.extend({
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
if (showUploadForm) {
|
this.set('dragClass', '-drag-over');
|
||||||
this.set('dragClass', '-drag-over');
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
dragLeave(event) {
|
dragLeave(event) {
|
||||||
let showUploadForm = this.get('showUploadForm');
|
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
this.set('dragClass', null);
|
||||||
if (showUploadForm) {
|
|
||||||
this.set('dragClass', null);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
drop(event) {
|
drop(event) {
|
||||||
let showUploadForm = this.get('showUploadForm');
|
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
this.set('dragClass', null);
|
this.set('dragClass', null);
|
||||||
|
|
||||||
if (showUploadForm) {
|
if (event.dataTransfer.files) {
|
||||||
if (event.dataTransfer.files) {
|
this.send('fileSelected', event.dataTransfer.files);
|
||||||
this.send('fileSelected', event.dataTransfer.files);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -272,24 +246,11 @@ export default Component.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onInput(url) {
|
|
||||||
this.set('url', url);
|
|
||||||
invokeAction(this, 'onInput', url);
|
|
||||||
},
|
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.set('file', null);
|
this.set('file', null);
|
||||||
this.set('uploadPercentage', 0);
|
this.set('uploadPercentage', 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
switchForm(formType) {
|
|
||||||
this.set('formType', formType);
|
|
||||||
|
|
||||||
run.scheduleOnce('afterRender', this, function () {
|
|
||||||
invokeAction(this, 'formChanged', formType);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
saveUrl() {
|
saveUrl() {
|
||||||
let url = this.get('url');
|
let url = this.get('url');
|
||||||
invokeAction(this, 'update', url);
|
invokeAction(this, 'update', url);
|
||||||
|
@ -15,32 +15,10 @@
|
|||||||
<button class="btn btn-green" {{action "reset"}}>Try Again</button>
|
<button class="btn btn-green" {{action "reset"}}>Try Again</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if showUploadForm}}
|
|
||||||
{{!-- file selection/drag-n-drop --}}
|
{{!-- file selection/drag-n-drop --}}
|
||||||
<div class="upload-form">
|
<div class="upload-form">
|
||||||
{{#gh-file-input multiple=false alt=description action=(action 'fileSelected') accept=accept}}
|
{{#gh-file-input multiple=false alt=description action=(action 'fileSelected') accept=accept}}
|
||||||
<div class="description">{{description}}</div>
|
<div class="description">{{description}}</div>
|
||||||
{{/gh-file-input}}
|
{{/gh-file-input}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a class="image-url" {{action 'switchForm' 'url-input'}}>
|
|
||||||
<i class="icon-link"><span class="hidden">URL</span></i>
|
|
||||||
</a>
|
|
||||||
{{else}}
|
|
||||||
{{!-- URL input --}}
|
|
||||||
<form class="url-form">
|
|
||||||
{{gh-input url class="url" placeholder="http://" update=(action "onInput") onenter=(action "saveUrl")}}
|
|
||||||
{{#if saveButton}}
|
|
||||||
<button class="btn btn-blue gh-input" {{action 'saveUrl'}}>Save</button>
|
|
||||||
{{else}}
|
|
||||||
<div class="description">{{description}}</div>
|
|
||||||
{{/if}}
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{{#if canShowUploadForm}}
|
|
||||||
<a class="image-upload icon-photos" title="Add image" {{action 'switchForm' 'upload'}}>
|
|
||||||
<span class="hidden">Upload</span>
|
|
||||||
</a>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -101,7 +101,6 @@ describe('Acceptance: Settings - General', function () {
|
|||||||
|
|
||||||
andThen(() => {
|
andThen(() => {
|
||||||
expect(find('.fullscreen-modal .modal-content .gh-image-uploader .description').text()).to.equal('Upload an image');
|
expect(find('.fullscreen-modal .modal-content .gh-image-uploader .description').text()).to.equal('Upload an image');
|
||||||
expect(find('.fullscreen-modal .modal-content .gh-image-uploader .image-url').length, 'url upload').to.equal(1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// click cancel button
|
// click cancel button
|
||||||
@ -121,7 +120,6 @@ describe('Acceptance: Settings - General', function () {
|
|||||||
|
|
||||||
andThen(() => {
|
andThen(() => {
|
||||||
expect(find('.fullscreen-modal .modal-content .gh-image-uploader .description').text()).to.equal('Upload an image');
|
expect(find('.fullscreen-modal .modal-content .gh-image-uploader .description').text()).to.equal('Upload an image');
|
||||||
expect(find('.fullscreen-modal .modal-content .gh-image-uploader .image-url').length, 'url upload').to.equal(0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// click cancel button
|
// click cancel button
|
||||||
|
@ -12,14 +12,6 @@ import run from 'ember-runloop';
|
|||||||
import Service from 'ember-service';
|
import Service from 'ember-service';
|
||||||
import {UnsupportedMediaTypeError} from 'ghost-admin/services/ajax';
|
import {UnsupportedMediaTypeError} from 'ghost-admin/services/ajax';
|
||||||
|
|
||||||
const keyCodes = {
|
|
||||||
enter: 13
|
|
||||||
};
|
|
||||||
|
|
||||||
const configStub = Service.extend({
|
|
||||||
fileStorage: true
|
|
||||||
});
|
|
||||||
|
|
||||||
const notificationsStub = Service.extend({
|
const notificationsStub = Service.extend({
|
||||||
showAPIError(/* error, options */) {
|
showAPIError(/* error, options */) {
|
||||||
// noop - to be stubbed
|
// noop - to be stubbed
|
||||||
@ -60,10 +52,8 @@ describe('Integration: Component: gh-image-uploader', function() {
|
|||||||
let server;
|
let server;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
this.register('service:config', configStub);
|
|
||||||
this.register('service:session', sessionStub);
|
this.register('service:session', sessionStub);
|
||||||
this.register('service:notifications', notificationsStub);
|
this.register('service:notifications', notificationsStub);
|
||||||
this.inject.service('config', {as: 'configService'});
|
|
||||||
this.inject.service('session', {as: 'sessionService'});
|
this.inject.service('session', {as: 'sessionService'});
|
||||||
this.inject.service('notifications', {as: 'notifications'});
|
this.inject.service('notifications', {as: 'notifications'});
|
||||||
this.set('update', function () {});
|
this.set('update', function () {});
|
||||||
@ -80,498 +70,387 @@ describe('Integration: Component: gh-image-uploader', function() {
|
|||||||
expect(this.$()).to.have.length(1);
|
expect(this.$()).to.have.length(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('defaults to upload form', function () {
|
it('renders form with supplied alt text', function () {
|
||||||
this.render(hbs`{{gh-image-uploader image=image}}`);
|
this.render(hbs`{{gh-image-uploader image=image altText="text test"}}`);
|
||||||
expect(this.$('input[type="file"]').length).to.equal(1);
|
expect(this.$('.description').text().trim()).to.equal('Upload image of "text test"');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('defaults to url form with no filestorage config', function () {
|
it('renders form with supplied text', function () {
|
||||||
this.set('configService.fileStorage', false);
|
this.render(hbs`{{gh-image-uploader image=image text="text test"}}`);
|
||||||
this.render(hbs`{{gh-image-uploader image=image}}`);
|
expect(this.$('.description').text().trim()).to.equal('text test');
|
||||||
expect(this.$('input[type="file"]').length).to.equal(0);
|
|
||||||
expect(this.$('input[type="text"].url').length).to.equal(1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can switch between form types', function () {
|
it('generates request to correct endpoint', function (done) {
|
||||||
this.render(hbs`{{gh-image-uploader image=image}}`);
|
stubSuccessfulUpload(server);
|
||||||
expect(this.$('input[type="file"]').length).to.equal(1);
|
|
||||||
expect(this.$('input[type="text"].url').length).to.equal(0);
|
|
||||||
|
|
||||||
this.$('a.image-url').click();
|
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
||||||
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
||||||
|
|
||||||
expect(this.$('input[type="file"]').length, 'upload form is visible after switch to url form')
|
wait().then(() => {
|
||||||
.to.equal(0);
|
expect(server.handledRequests.length).to.equal(1);
|
||||||
expect(this.$('input[type="text"].url').length, 'url form is visible after switch to url form')
|
expect(server.handledRequests[0].url).to.equal('/ghost/api/v0.1/uploads/');
|
||||||
.to.equal(1);
|
expect(server.handledRequests[0].requestHeaders.Authorization).to.be.undefined;
|
||||||
|
done();
|
||||||
this.$('a.image-upload').click();
|
});
|
||||||
|
|
||||||
expect(this.$('input[type="file"]').length, 'upload form is visible after switch to upload form')
|
|
||||||
.to.equal(1);
|
|
||||||
expect(this.$('input[type="text"].url').length, 'url form is visible after switch to upload form')
|
|
||||||
.to.equal(0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('triggers formChanged action when switching between forms', function () {
|
it('adds authentication headers to request', function (done) {
|
||||||
let formChanged = sinon.spy();
|
stubSuccessfulUpload(server);
|
||||||
this.set('formChanged', formChanged);
|
|
||||||
|
|
||||||
this.render(hbs`{{gh-image-uploader image=image formChanged=(action formChanged)}}`);
|
this.get('sessionService').set('isAuthenticated', true);
|
||||||
|
|
||||||
this.$('a.image-url').click();
|
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
||||||
this.$('a.image-upload').click();
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
||||||
|
|
||||||
expect(formChanged.calledTwice).to.be.true;
|
wait().then(() => {
|
||||||
expect(formChanged.firstCall.args[0]).to.equal('url-input');
|
let [request] = server.handledRequests;
|
||||||
expect(formChanged.secondCall.args[0]).to.equal('upload');
|
expect(request.requestHeaders.Authorization).to.equal('Bearer token');
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('file upload form', function () {
|
it('fires update action on successful upload', function (done) {
|
||||||
it('renders form with supplied alt text', function () {
|
let update = sinon.spy();
|
||||||
this.render(hbs`{{gh-image-uploader image=image altText="text test"}}`);
|
this.set('update', update);
|
||||||
expect(this.$('.description').text().trim()).to.equal('Upload image of "text test"');
|
|
||||||
|
stubSuccessfulUpload(server);
|
||||||
|
|
||||||
|
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
||||||
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
||||||
|
|
||||||
|
wait().then(() => {
|
||||||
|
expect(update.calledOnce).to.be.true;
|
||||||
|
expect(update.firstCall.args[0]).to.equal('/content/images/test.png');
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('renders form with supplied text', function () {
|
it('doesn\'t fire update action on failed upload', function (done) {
|
||||||
this.render(hbs`{{gh-image-uploader image=image text="text test"}}`);
|
let update = sinon.spy();
|
||||||
expect(this.$('.description').text().trim()).to.equal('text test');
|
this.set('update', update);
|
||||||
|
|
||||||
|
stubFailedUpload(server, 500);
|
||||||
|
|
||||||
|
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
||||||
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
||||||
|
|
||||||
|
wait().then(() => {
|
||||||
|
expect(update.calledOnce).to.be.false;
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('generates request to correct endpoint', function (done) {
|
it('fires fileSelected action on file selection', function (done) {
|
||||||
stubSuccessfulUpload(server);
|
let fileSelected = sinon.spy();
|
||||||
|
this.set('fileSelected', fileSelected);
|
||||||
|
|
||||||
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
stubSuccessfulUpload(server);
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
|
||||||
|
|
||||||
wait().then(() => {
|
this.render(hbs`{{gh-image-uploader image=image fileSelected=(action fileSelected) update=(action update)}}`);
|
||||||
expect(server.handledRequests.length).to.equal(1);
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
||||||
expect(server.handledRequests[0].url).to.equal('/ghost/api/v0.1/uploads/');
|
|
||||||
expect(server.handledRequests[0].requestHeaders.Authorization).to.be.undefined;
|
wait().then(() => {
|
||||||
done();
|
expect(fileSelected.calledOnce).to.be.true;
|
||||||
});
|
expect(fileSelected.args[0]).to.not.be.blank;
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('adds authentication headers to request', function (done) {
|
it('fires uploadStarted action on upload start', function (done) {
|
||||||
stubSuccessfulUpload(server);
|
let uploadStarted = sinon.spy();
|
||||||
|
this.set('uploadStarted', uploadStarted);
|
||||||
|
|
||||||
this.get('sessionService').set('isAuthenticated', true);
|
stubSuccessfulUpload(server);
|
||||||
|
|
||||||
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
this.render(hbs`{{gh-image-uploader image=image uploadStarted=(action uploadStarted) update=(action update)}}`);
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
||||||
|
|
||||||
wait().then(() => {
|
wait().then(() => {
|
||||||
let [request] = server.handledRequests;
|
expect(uploadStarted.calledOnce).to.be.true;
|
||||||
expect(request.requestHeaders.Authorization).to.equal('Bearer token');
|
done();
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('fires update action on successful upload', function (done) {
|
it('fires uploadFinished action on successful upload', function (done) {
|
||||||
let update = sinon.spy();
|
let uploadFinished = sinon.spy();
|
||||||
this.set('update', update);
|
this.set('uploadFinished', uploadFinished);
|
||||||
|
|
||||||
stubSuccessfulUpload(server);
|
stubSuccessfulUpload(server);
|
||||||
|
|
||||||
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
this.render(hbs`{{gh-image-uploader image=image uploadFinished=(action uploadFinished) update=(action update)}}`);
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
||||||
|
|
||||||
wait().then(() => {
|
wait().then(() => {
|
||||||
expect(update.calledOnce).to.be.true;
|
expect(uploadFinished.calledOnce).to.be.true;
|
||||||
expect(update.firstCall.args[0]).to.equal('/content/images/test.png');
|
done();
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('doesn\'t fire update action on failed upload', function (done) {
|
it('fires uploadFinished action on failed upload', function (done) {
|
||||||
let update = sinon.spy();
|
let uploadFinished = sinon.spy();
|
||||||
this.set('update', update);
|
this.set('uploadFinished', uploadFinished);
|
||||||
|
|
||||||
stubFailedUpload(server, 500);
|
stubFailedUpload(server);
|
||||||
|
|
||||||
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
this.render(hbs`{{gh-image-uploader image=image uploadFinished=(action uploadFinished) update=(action update)}}`);
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
||||||
|
|
||||||
wait().then(() => {
|
wait().then(() => {
|
||||||
expect(update.calledOnce).to.be.false;
|
expect(uploadFinished.calledOnce).to.be.true;
|
||||||
done();
|
done();
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('fires fileSelected action on file selection', function (done) {
|
it('displays invalid file type error', function (done) {
|
||||||
let fileSelected = sinon.spy();
|
stubFailedUpload(server, 415, 'UnsupportedMediaTypeError');
|
||||||
this.set('fileSelected', fileSelected);
|
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
||||||
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
||||||
|
|
||||||
stubSuccessfulUpload(server);
|
wait().then(() => {
|
||||||
|
expect(this.$('.failed').length, 'error message is displayed').to.equal(1);
|
||||||
this.render(hbs`{{gh-image-uploader image=image fileSelected=(action fileSelected) update=(action update)}}`);
|
expect(this.$('.failed').text()).to.match(/The image type you uploaded is not supported/);
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
expect(this.$('.gh-btn-green').length, 'reset button is displayed').to.equal(1);
|
||||||
|
expect(this.$('.gh-btn-green').text()).to.equal('Try Again');
|
||||||
wait().then(() => {
|
done();
|
||||||
expect(fileSelected.calledOnce).to.be.true;
|
|
||||||
expect(fileSelected.args[0]).to.not.be.blank;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('fires uploadStarted action on upload start', function (done) {
|
it('displays file too large for server error', function (done) {
|
||||||
let uploadStarted = sinon.spy();
|
stubFailedUpload(server, 413, 'RequestEntityTooLargeError');
|
||||||
this.set('uploadStarted', uploadStarted);
|
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
||||||
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
||||||
|
|
||||||
stubSuccessfulUpload(server);
|
wait().then(() => {
|
||||||
|
expect(this.$('.failed').length, 'error message is displayed').to.equal(1);
|
||||||
this.render(hbs`{{gh-image-uploader image=image uploadStarted=(action uploadStarted) update=(action update)}}`);
|
expect(this.$('.failed').text()).to.match(/The image you uploaded was larger/);
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
done();
|
||||||
|
|
||||||
wait().then(() => {
|
|
||||||
expect(uploadStarted.calledOnce).to.be.true;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('fires uploadFinished action on successful upload', function (done) {
|
it('handles file too large error directly from the web server', function (done) {
|
||||||
let uploadFinished = sinon.spy();
|
server.post('/ghost/api/v0.1/uploads/', function () {
|
||||||
this.set('uploadFinished', uploadFinished);
|
return [413, {}, ''];
|
||||||
|
|
||||||
stubSuccessfulUpload(server);
|
|
||||||
|
|
||||||
this.render(hbs`{{gh-image-uploader image=image uploadFinished=(action uploadFinished) update=(action update)}}`);
|
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
|
||||||
|
|
||||||
wait().then(() => {
|
|
||||||
expect(uploadFinished.calledOnce).to.be.true;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
||||||
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
||||||
|
|
||||||
it('fires uploadFinished action on failed upload', function (done) {
|
wait().then(() => {
|
||||||
let uploadFinished = sinon.spy();
|
expect(this.$('.failed').length, 'error message is displayed').to.equal(1);
|
||||||
this.set('uploadFinished', uploadFinished);
|
expect(this.$('.failed').text()).to.match(/The image you uploaded was larger/);
|
||||||
|
done();
|
||||||
stubFailedUpload(server);
|
|
||||||
|
|
||||||
this.render(hbs`{{gh-image-uploader image=image uploadFinished=(action uploadFinished) update=(action update)}}`);
|
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
|
||||||
|
|
||||||
wait().then(() => {
|
|
||||||
expect(uploadFinished.calledOnce).to.be.true;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('displays invalid file type error', function (done) {
|
it('displays other server-side error with message', function (done) {
|
||||||
stubFailedUpload(server, 415, 'UnsupportedMediaTypeError');
|
stubFailedUpload(server, 400, 'UnknownError');
|
||||||
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
||||||
|
|
||||||
wait().then(() => {
|
wait().then(() => {
|
||||||
expect(this.$('.failed').length, 'error message is displayed').to.equal(1);
|
expect(this.$('.failed').length, 'error message is displayed').to.equal(1);
|
||||||
expect(this.$('.failed').text()).to.match(/The image type you uploaded is not supported/);
|
expect(this.$('.failed').text()).to.match(/Error: UnknownError/);
|
||||||
expect(this.$('.gh-btn-green').length, 'reset button is displayed').to.equal(1);
|
done();
|
||||||
expect(this.$('.gh-btn-green').text()).to.equal('Try Again');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('displays file too large for server error', function (done) {
|
it('handles unknown failure', function (done) {
|
||||||
stubFailedUpload(server, 413, 'RequestEntityTooLargeError');
|
server.post('/ghost/api/v0.1/uploads/', function () {
|
||||||
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
return [500, {'Content-Type': 'application/json'}, ''];
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
|
||||||
|
|
||||||
wait().then(() => {
|
|
||||||
expect(this.$('.failed').length, 'error message is displayed').to.equal(1);
|
|
||||||
expect(this.$('.failed').text()).to.match(/The image you uploaded was larger/);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
||||||
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
||||||
|
|
||||||
it('handles file too large error directly from the web server', function (done) {
|
wait().then(() => {
|
||||||
server.post('/ghost/api/v0.1/uploads/', function () {
|
expect(this.$('.failed').length, 'error message is displayed').to.equal(1);
|
||||||
return [413, {}, ''];
|
expect(this.$('.failed').text()).to.match(/Something went wrong/);
|
||||||
});
|
done();
|
||||||
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
|
||||||
|
|
||||||
wait().then(() => {
|
|
||||||
expect(this.$('.failed').length, 'error message is displayed').to.equal(1);
|
|
||||||
expect(this.$('.failed').text()).to.match(/The image you uploaded was larger/);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('displays other server-side error with message', function (done) {
|
it('triggers notifications.showAPIError for VersionMismatchError', function (done) {
|
||||||
stubFailedUpload(server, 400, 'UnknownError');
|
let showAPIError = sinon.spy();
|
||||||
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
this.set('notifications.showAPIError', showAPIError);
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
|
||||||
|
|
||||||
wait().then(() => {
|
stubFailedUpload(server, 400, 'VersionMismatchError');
|
||||||
expect(this.$('.failed').length, 'error message is displayed').to.equal(1);
|
|
||||||
expect(this.$('.failed').text()).to.match(/Error: UnknownError/);
|
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
||||||
done();
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
||||||
});
|
|
||||||
|
wait().then(() => {
|
||||||
|
expect(showAPIError.calledOnce).to.be.true;
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('handles unknown failure', function (done) {
|
it('doesn\'t trigger notifications.showAPIError for other errors', function (done) {
|
||||||
server.post('/ghost/api/v0.1/uploads/', function () {
|
let showAPIError = sinon.spy();
|
||||||
return [500, {'Content-Type': 'application/json'}, ''];
|
this.set('notifications.showAPIError', showAPIError);
|
||||||
});
|
|
||||||
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
|
||||||
|
|
||||||
wait().then(() => {
|
stubFailedUpload(server, 400, 'UnknownError');
|
||||||
expect(this.$('.failed').length, 'error message is displayed').to.equal(1);
|
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
||||||
expect(this.$('.failed').text()).to.match(/Something went wrong/);
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
||||||
done();
|
|
||||||
});
|
wait().then(() => {
|
||||||
|
expect(showAPIError.called).to.be.false;
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('triggers notifications.showAPIError for VersionMismatchError', function (done) {
|
it('can be reset after a failed upload', function (done) {
|
||||||
let showAPIError = sinon.spy();
|
stubFailedUpload(server, 400, 'UnknownError');
|
||||||
this.set('notifications.showAPIError', showAPIError);
|
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
||||||
|
fileUpload(this.$('input[type="file"]'), ['test'], {type: 'test.png'});
|
||||||
stubFailedUpload(server, 400, 'VersionMismatchError');
|
|
||||||
|
|
||||||
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
|
||||||
|
|
||||||
wait().then(() => {
|
|
||||||
expect(showAPIError.calledOnce).to.be.true;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('doesn\'t trigger notifications.showAPIError for other errors', function (done) {
|
|
||||||
let showAPIError = sinon.spy();
|
|
||||||
this.set('notifications.showAPIError', showAPIError);
|
|
||||||
|
|
||||||
stubFailedUpload(server, 400, 'UnknownError');
|
|
||||||
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
|
||||||
|
|
||||||
wait().then(() => {
|
|
||||||
expect(showAPIError.called).to.be.false;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can be reset after a failed upload', function (done) {
|
|
||||||
stubFailedUpload(server, 400, 'UnknownError');
|
|
||||||
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {type: 'test.png'});
|
|
||||||
|
|
||||||
wait().then(() => {
|
|
||||||
run(() => {
|
|
||||||
this.$('.gh-btn-green').click();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
wait().then(() => {
|
|
||||||
expect(this.$('input[type="file"]').length).to.equal(1);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('displays upload progress', function (done) {
|
|
||||||
this.set('done', done);
|
|
||||||
|
|
||||||
// pretender fires a progress event every 50ms
|
|
||||||
stubSuccessfulUpload(server, 150);
|
|
||||||
|
|
||||||
this.render(hbs`{{gh-image-uploader image=image uploadFinished=(action done) update=(action update)}}`);
|
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
|
||||||
|
|
||||||
// after 75ms we should have had one progress event
|
|
||||||
run.later(this, function () {
|
|
||||||
expect(this.$('.progress .bar').length).to.equal(1);
|
|
||||||
let [, percentageWidth] = this.$('.progress .bar').attr('style').match(/width: (\d+)%?/);
|
|
||||||
expect(percentageWidth).to.be.above(0);
|
|
||||||
expect(percentageWidth).to.be.below(100);
|
|
||||||
}, 75);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('handles drag over/leave', function () {
|
|
||||||
stubSuccessfulUpload(server);
|
|
||||||
|
|
||||||
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
|
||||||
|
|
||||||
|
wait().then(() => {
|
||||||
run(() => {
|
run(() => {
|
||||||
// eslint-disable-next-line new-cap
|
this.$('.gh-btn-green').click();
|
||||||
let dragover = $.Event('dragover', {
|
|
||||||
dataTransfer: {
|
|
||||||
files: []
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.$('.gh-image-uploader').trigger(dragover);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(this.$('.gh-image-uploader').hasClass('-drag-over'), 'has drag-over class').to.be.true;
|
|
||||||
|
|
||||||
run(() => {
|
|
||||||
this.$('.gh-image-uploader').trigger('dragleave');
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(this.$('.gh-image-uploader').hasClass('-drag-over'), 'has drag-over class').to.be.false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('triggers file upload on file drop', function (done) {
|
wait().then(() => {
|
||||||
let uploadSuccess = sinon.spy();
|
expect(this.$('input[type="file"]').length).to.equal(1);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('displays upload progress', function (done) {
|
||||||
|
this.set('done', done);
|
||||||
|
|
||||||
|
// pretender fires a progress event every 50ms
|
||||||
|
stubSuccessfulUpload(server, 150);
|
||||||
|
|
||||||
|
this.render(hbs`{{gh-image-uploader image=image uploadFinished=(action done) update=(action update)}}`);
|
||||||
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
||||||
|
|
||||||
|
// after 75ms we should have had one progress event
|
||||||
|
run.later(this, function () {
|
||||||
|
expect(this.$('.progress .bar').length).to.equal(1);
|
||||||
|
let [, percentageWidth] = this.$('.progress .bar').attr('style').match(/width: (\d+)%?/);
|
||||||
|
expect(percentageWidth).to.be.above(0);
|
||||||
|
expect(percentageWidth).to.be.below(100);
|
||||||
|
}, 75);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles drag over/leave', function () {
|
||||||
|
stubSuccessfulUpload(server);
|
||||||
|
|
||||||
|
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
||||||
|
|
||||||
|
run(() => {
|
||||||
// eslint-disable-next-line new-cap
|
// eslint-disable-next-line new-cap
|
||||||
let drop = $.Event('drop', {
|
let dragover = $.Event('dragover', {
|
||||||
dataTransfer: {
|
dataTransfer: {
|
||||||
files: [createFile(['test'], {name: 'test.png'})]
|
files: []
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.$('.gh-image-uploader').trigger(dragover);
|
||||||
this.set('uploadSuccess', uploadSuccess);
|
|
||||||
|
|
||||||
stubSuccessfulUpload(server);
|
|
||||||
this.render(hbs`{{gh-image-uploader uploadSuccess=(action uploadSuccess)}}`);
|
|
||||||
|
|
||||||
run(() => {
|
|
||||||
this.$('.gh-image-uploader').trigger(drop);
|
|
||||||
});
|
|
||||||
|
|
||||||
wait().then(() => {
|
|
||||||
expect(uploadSuccess.calledOnce).to.be.true;
|
|
||||||
expect(uploadSuccess.firstCall.args[0]).to.equal('/content/images/test.png');
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('validates extension by default', function (done) {
|
expect(this.$('.gh-image-uploader').hasClass('-drag-over'), 'has drag-over class').to.be.true;
|
||||||
let uploadSuccess = sinon.spy();
|
|
||||||
let uploadFailed = sinon.spy();
|
|
||||||
|
|
||||||
this.set('uploadSuccess', uploadSuccess);
|
run(() => {
|
||||||
this.set('uploadFailed', uploadFailed);
|
this.$('.gh-image-uploader').trigger('dragleave');
|
||||||
|
|
||||||
stubSuccessfulUpload(server);
|
|
||||||
|
|
||||||
this.render(hbs`{{gh-image-uploader
|
|
||||||
uploadSuccess=(action uploadSuccess)
|
|
||||||
uploadFailed=(action uploadFailed)}}`);
|
|
||||||
|
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.json'});
|
|
||||||
|
|
||||||
wait().then(() => {
|
|
||||||
expect(uploadSuccess.called).to.be.false;
|
|
||||||
expect(uploadFailed.calledOnce).to.be.true;
|
|
||||||
expect(this.$('.failed').length, 'error message is displayed').to.equal(1);
|
|
||||||
expect(this.$('.failed').text()).to.match(/The image type you uploaded is not supported/);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uploads if validate action supplied and returns true', function (done) {
|
expect(this.$('.gh-image-uploader').hasClass('-drag-over'), 'has drag-over class').to.be.false;
|
||||||
let validate = sinon.stub().returns(true);
|
});
|
||||||
let uploadSuccess = sinon.spy();
|
|
||||||
|
|
||||||
this.set('validate', validate);
|
it('triggers file upload on file drop', function (done) {
|
||||||
this.set('uploadSuccess', uploadSuccess);
|
let uploadSuccess = sinon.spy();
|
||||||
|
// eslint-disable-next-line new-cap
|
||||||
stubSuccessfulUpload(server);
|
let drop = $.Event('drop', {
|
||||||
|
dataTransfer: {
|
||||||
this.render(hbs`{{gh-image-uploader
|
files: [createFile(['test'], {name: 'test.png'})]
|
||||||
uploadSuccess=(action uploadSuccess)
|
}
|
||||||
validate=(action validate)}}`);
|
|
||||||
|
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.txt'});
|
|
||||||
|
|
||||||
wait().then(() => {
|
|
||||||
expect(validate.calledOnce).to.be.true;
|
|
||||||
expect(uploadSuccess.calledOnce).to.be.true;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('skips upload and displays error if validate action supplied and doesn\'t return true', function (done) {
|
this.set('uploadSuccess', uploadSuccess);
|
||||||
let validate = sinon.stub().returns(new UnsupportedMediaTypeError());
|
|
||||||
let uploadSuccess = sinon.spy();
|
|
||||||
let uploadFailed = sinon.spy();
|
|
||||||
|
|
||||||
this.set('validate', validate);
|
stubSuccessfulUpload(server);
|
||||||
this.set('uploadSuccess', uploadSuccess);
|
this.render(hbs`{{gh-image-uploader uploadSuccess=(action uploadSuccess)}}`);
|
||||||
this.set('uploadFailed', uploadFailed);
|
|
||||||
|
|
||||||
stubSuccessfulUpload(server);
|
run(() => {
|
||||||
|
this.$('.gh-image-uploader').trigger(drop);
|
||||||
|
});
|
||||||
|
|
||||||
this.render(hbs`{{gh-image-uploader
|
wait().then(() => {
|
||||||
uploadSuccess=(action uploadSuccess)
|
expect(uploadSuccess.calledOnce).to.be.true;
|
||||||
uploadFailed=(action uploadFailed)
|
expect(uploadSuccess.firstCall.args[0]).to.equal('/content/images/test.png');
|
||||||
validate=(action validate)}}`);
|
done();
|
||||||
|
|
||||||
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
|
||||||
|
|
||||||
wait().then(() => {
|
|
||||||
expect(validate.calledOnce).to.be.true;
|
|
||||||
expect(uploadSuccess.called).to.be.false;
|
|
||||||
expect(uploadFailed.calledOnce).to.be.true;
|
|
||||||
expect(this.$('.failed').length, 'error message is displayed').to.equal(1);
|
|
||||||
expect(this.$('.failed').text()).to.match(/The image type you uploaded is not supported/);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('URL input form', function () {
|
it('validates extension by default', function (done) {
|
||||||
beforeEach(function () {
|
let uploadSuccess = sinon.spy();
|
||||||
this.set('configService.fileStorage', false);
|
let uploadFailed = sinon.spy();
|
||||||
|
|
||||||
|
this.set('uploadSuccess', uploadSuccess);
|
||||||
|
this.set('uploadFailed', uploadFailed);
|
||||||
|
|
||||||
|
stubSuccessfulUpload(server);
|
||||||
|
|
||||||
|
this.render(hbs`{{gh-image-uploader
|
||||||
|
uploadSuccess=(action uploadSuccess)
|
||||||
|
uploadFailed=(action uploadFailed)}}`);
|
||||||
|
|
||||||
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.json'});
|
||||||
|
|
||||||
|
wait().then(() => {
|
||||||
|
expect(uploadSuccess.called).to.be.false;
|
||||||
|
expect(uploadFailed.calledOnce).to.be.true;
|
||||||
|
expect(this.$('.failed').length, 'error message is displayed').to.equal(1);
|
||||||
|
expect(this.$('.failed').text()).to.match(/The image type you uploaded is not supported/);
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('displays save button by default', function () {
|
it('uploads if validate action supplied and returns true', function (done) {
|
||||||
this.set('image', 'http://example.com/test.png');
|
let validate = sinon.stub().returns(true);
|
||||||
this.render(hbs`{{gh-image-uploader image=image text="text test"}}`);
|
let uploadSuccess = sinon.spy();
|
||||||
expect(this.$('button').length).to.equal(1);
|
|
||||||
expect(this.$('input[type="text"]').val()).to.equal('http://example.com/test.png');
|
this.set('validate', validate);
|
||||||
|
this.set('uploadSuccess', uploadSuccess);
|
||||||
|
|
||||||
|
stubSuccessfulUpload(server);
|
||||||
|
|
||||||
|
this.render(hbs`{{gh-image-uploader
|
||||||
|
uploadSuccess=(action uploadSuccess)
|
||||||
|
validate=(action validate)}}`);
|
||||||
|
|
||||||
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.txt'});
|
||||||
|
|
||||||
|
wait().then(() => {
|
||||||
|
expect(validate.calledOnce).to.be.true;
|
||||||
|
expect(uploadSuccess.calledOnce).to.be.true;
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('can render without a save button', function () {
|
it('skips upload and displays error if validate action supplied and doesn\'t return true', function (done) {
|
||||||
this.render(hbs`{{gh-image-uploader image=image saveButton=false text="text test"}}`);
|
let validate = sinon.stub().returns(new UnsupportedMediaTypeError());
|
||||||
expect(this.$('button').length).to.equal(0);
|
let uploadSuccess = sinon.spy();
|
||||||
expect(this.$('.description').text().trim()).to.equal('text test');
|
let uploadFailed = sinon.spy();
|
||||||
});
|
|
||||||
|
|
||||||
it('fires update action when save button clicked', function () {
|
this.set('validate', validate);
|
||||||
let update = sinon.spy();
|
this.set('uploadSuccess', uploadSuccess);
|
||||||
this.set('update', update);
|
this.set('uploadFailed', uploadFailed);
|
||||||
|
|
||||||
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
stubSuccessfulUpload(server);
|
||||||
|
|
||||||
this.$('input[type="text"]').val('saved url');
|
this.render(hbs`{{gh-image-uploader
|
||||||
this.$('input[type="text"]').change();
|
uploadSuccess=(action uploadSuccess)
|
||||||
this.$('button.gh-btn-blue').click();
|
uploadFailed=(action uploadFailed)
|
||||||
|
validate=(action validate)}}`);
|
||||||
|
|
||||||
expect(update.calledOnce).to.be.true;
|
fileUpload(this.$('input[type="file"]'), ['test'], {name: 'test.png'});
|
||||||
expect(update.firstCall.args[0]).to.equal('saved url');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('fires onInput action when typing URL', function () {
|
wait().then(() => {
|
||||||
let onInput = sinon.spy();
|
expect(validate.calledOnce).to.be.true;
|
||||||
this.set('onInput', onInput);
|
expect(uploadSuccess.called).to.be.false;
|
||||||
|
expect(uploadFailed.calledOnce).to.be.true;
|
||||||
this.render(hbs`{{gh-image-uploader image=image onInput=(action onInput)}}`);
|
expect(this.$('.failed').length, 'error message is displayed').to.equal(1);
|
||||||
|
expect(this.$('.failed').text()).to.match(/The image type you uploaded is not supported/);
|
||||||
this.$('input[type="text"]').val('input url');
|
done();
|
||||||
this.$('input[type="text"]').change();
|
|
||||||
|
|
||||||
expect(onInput.calledOnce).to.be.true;
|
|
||||||
expect(onInput.firstCall.args[0]).to.equal('input url');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('saves on enter key', function () {
|
|
||||||
let update = sinon.spy();
|
|
||||||
this.set('update', update);
|
|
||||||
|
|
||||||
this.render(hbs`{{gh-image-uploader image=image update=(action update)}}`);
|
|
||||||
|
|
||||||
this.$('input[type="text"]').val('saved url');
|
|
||||||
this.$('input[type="text"]').change();
|
|
||||||
this.$('input[type="text"]').trigger(
|
|
||||||
// eslint-disable-next-line new-cap
|
|
||||||
$.Event('keyup', {keyCode: keyCodes.enter, which: keyCodes.enter})
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(update.calledOnce).to.be.true;
|
|
||||||
expect(update.firstCall.args[0]).to.equal('saved url');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -61,17 +61,6 @@ describe('Integration: Component: gh-profile-image', function () {
|
|||||||
expect(this.$()).to.have.length(1);
|
expect(this.$()).to.have.length(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders and tears down ok with fileStorage:false', function () {
|
|
||||||
this.set('fileStorage', false);
|
|
||||||
|
|
||||||
this.render(hbs`
|
|
||||||
{{gh-profile-image fileStorage=fileStorage}}
|
|
||||||
`);
|
|
||||||
|
|
||||||
expect(this.$()).to.have.length(1);
|
|
||||||
expect(this.$('input')).to.have.length(0);
|
|
||||||
}),
|
|
||||||
|
|
||||||
it('renders default image if no email supplied', function () {
|
it('renders default image if no email supplied', function () {
|
||||||
this.set('email', null);
|
this.set('email', null);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user