Added routes.yaml upload to Labs screen

refs https://github.com/TryGhost/Ghost/issues/9744
- adds `routes.yaml` upload using the same UI as the `redirects.json` upload
  - upload: `POST /settings/routes/yaml/`
  - download: `GET /settings/routes/yaml/`
This commit is contained in:
Kevin Ansfield 2018-07-24 12:20:53 +01:00
parent 512d6d8262
commit 02f45c2a3a
3 changed files with 180 additions and 0 deletions

View File

@ -25,6 +25,14 @@ const IMPORT_MIME_TYPES = [
const JSON_EXTENSION = ['json'];
const JSON_MIME_TYPE = ['application/json'];
const YAML_EXTENSION = ['yml', 'yaml'];
const YAML_MIME_TYPE = [
'text/vnd.yaml',
'application/vnd.yaml',
'text/x-yaml',
'application/x-yaml'
];
export default Controller.extend({
ajax: service(),
config: service(),
@ -43,12 +51,16 @@ export default Controller.extend({
importMimeType: null,
jsonExtension: null,
jsonMimeType: null,
yamlExtension: null,
yamlMimeType: null,
init() {
this._super(...arguments);
this.importMimeType = IMPORT_MIME_TYPES;
this.jsonExtension = JSON_EXTENSION;
this.jsonMimeType = JSON_MIME_TYPE;
this.yamlExtension = YAML_EXTENSION;
this.yamlMimeType = YAML_MIME_TYPE;
},
actions: {
@ -214,6 +226,17 @@ export default Controller.extend({
return true;
}).drop(),
routesUploadResult: task(function* (success) {
this.set('routesSuccess', success);
this.set('routesFailure', !success);
yield timeout(config.environment === 'test' ? 100 : 5000);
this.set('routesSuccess', null);
this.set('routesFailure', null);
return true;
}).drop(),
reset() {
this.set('importErrors', null);
this.set('importSuccessful', false);

View File

@ -163,7 +163,51 @@
</div>
{{/gh-uploader}}
</div>
<div class="gh-setting">
{{#gh-uploader
extensions=yamlExtension
uploadUrl="/settings/routes/yaml/"
paramName="routes"
onUploadSuccess=(perform routesUploadResult true)
onUploadFailure=(perform routesUploadResult false)
as |uploader|
}}
<div class="gh-setting-content">
<div class="gh-setting-title">Routes</div>
<div class="gh-setting-desc">Configure dynamic routing by modifying the routes.yaml file</div>
{{#each uploader.errors as |error|}}
<div class="gh-setting-error" data-test-error="routes">{{error.message}}</div>
{{/each}}
</div>
<div class="gh-setting-action" style="display: flex; flex-direction: column">
{{#if uploader.isUploading}}
{{uploader.progressBar}}
{{else}}
<button
type="button"
class="gh-btn gh-btn-icon {{if routesSuccess "gh-btn-green"}} {{if routesFailure "gh-btn-red"}}"
onclick={{action "triggerFileDialog"}}
data-test-button="upload-routes"
>
<span>
{{#if routesSuccess}}
{{svg-jar "check-circle"}} Uploaded
{{else if routesFailure}}
{{svg-jar "retry"}} Upload Failed
{{else}}
Upload routes YAML
{{/if}}
</span>
</button>
<span><a href="#" {{action "downloadFile" "settings/routes/yaml"}} data-test-link="download-routes">Download current routes.yml</a></span>
{{/if}}
<div style="display:none">
{{gh-file-input multiple=false action=uploader.setFiles accept=yamlMimeType data-test-file-input="routes"}}
</div>
</div>
{{/gh-uploader}}
</div>
</section>
</section>

View File

@ -195,5 +195,118 @@ describe('Acceptance: Settings - Labs', function () {
let iframe = $('#iframeDownload');
expect(iframe.attr('src')).to.have.string('/redirects/json/');
});
it('can upload/download routes.yaml', async function () {
await visit('/settings/labs');
// successful upload
server.post('/settings/routes/yaml/', {}, 200);
await fileUpload(
'[data-test-file-input="routes"]',
['test'],
{name: 'routes.yaml', type: 'application/x-yaml'}
);
// TODO: tests for the temporary success/failure state have been
// disabled because they were randomly failing
// this should be half-way through button reset timeout
// await timeout(50);
//
// // shows success button
// let button = find('[data-test-button="upload-routes"]');
// expect(button.length, 'no of success buttons').to.equal(1);
// expect(
// button.hasClass('gh-btn-green'),
// 'success button is green'
// ).to.be.true;
// expect(
// button.text().trim(),
// 'success button text'
// ).to.have.string('Uploaded');
//
// await wait();
// returned to normal button
let button = find('[data-test-button="upload-routes"]');
expect(button.length, 'no of post-success buttons').to.equal(1);
expect(
button.hasClass('gh-btn-green'),
'routes post-success button doesn\'t have success class'
).to.be.false;
expect(
button.text().trim(),
'routes post-success button text'
).to.have.string('Upload routes YAML');
// failed upload
server.post('/settings/routes/yaml/', {
errors: [{
errorType: 'BadRequestError',
message: 'Test failure message'
}]
}, 400);
await fileUpload(
'[data-test-file-input="routes"]',
['test'],
{name: 'routes-bad.yaml', type: 'application/x-yaml'}
);
// TODO: tests for the temporary success/failure state have been
// disabled because they were randomly failing
// this should be half-way through button reset timeout
// await timeout(50);
//
// shows failure button
// button = find('[data-test-button="upload-routes"]');
// expect(button.length, 'no of failure buttons').to.equal(1);
// expect(
// button.hasClass('gh-btn-red'),
// 'failure button is red'
// ).to.be.true;
// expect(
// button.text().trim(),
// 'failure button text'
// ).to.have.string('Upload Failed');
//
// await wait();
// shows error message
expect(
find('[data-test-error="routes"]').text().trim(),
'routes upload error text'
).to.have.string('Test failure message');
// returned to normal button
button = find('[data-test-button="upload-routes"]');
expect(button.length, 'no of post-failure buttons').to.equal(1);
expect(
button.hasClass('gh-btn-red'),
'routes post-failure button doesn\'t have failure class'
).to.be.false;
expect(
button.text().trim(),
'routes post-failure button text'
).to.have.string('Upload routes YAML');
// successful upload clears error
server.post('/settings/routes/yaml/', {}, 200);
await fileUpload(
'[data-test-file-input="routes"]',
['test'],
{name: 'routes-good.yaml', type: 'application/x-yaml'}
);
expect(find('[data-test-error="routes"]')).to.not.exist;
// can download redirects.json
await click('[data-test-link="download-routes"]');
let iframe = $('#iframeDownload');
expect(iframe.attr('src')).to.have.string('/settings/routes/yaml/');
});
});
});