diff --git a/ui/app/components/job-page/periodic.js b/ui/app/components/job-page/periodic.js index 705d95a2f..95be2cbb1 100644 --- a/ui/app/components/job-page/periodic.js +++ b/ui/app/components/job-page/periodic.js @@ -3,13 +3,19 @@ import { inject as service } from '@ember/service'; export default AbstractJobPage.extend({ store: service(), + + errorMessage: '', + actions: { forceLaunch() { this.get('job') .forcePeriodic() - .then(() => { - this.get('store').findAll('job'); + .catch(error => { + this.set('errorMessage', `Could not force launch: ${error}`); }); }, + clearErrorMessage() { + this.set('errorMessage', ''); + }, }, }); diff --git a/ui/app/templates/components/job-page/periodic.hbs b/ui/app/templates/components/job-page/periodic.hbs index 6a815b332..25fcdc102 100644 --- a/ui/app/templates/components/job-page/periodic.hbs +++ b/ui/app/templates/components/job-page/periodic.hbs @@ -6,6 +6,19 @@ {{/each}} {{/global-header}} {{#job-page/parts/body job=job onNamespaceChange=onNamespaceChange}} + {{#if errorMessage}} +
+
+
+

Could Not Force Launch

+

Your ACL token does not grant permission to submit jobs.

+
+
+ +
+
+
+ {{/if}}

{{job.name}} {{job.status}} diff --git a/ui/tests/integration/job-page/periodic-test.js b/ui/tests/integration/job-page/periodic-test.js index 6ea79bd18..a9dd30bf7 100644 --- a/ui/tests/integration/job-page/periodic-test.js +++ b/ui/tests/integration/job-page/periodic-test.js @@ -1,6 +1,6 @@ import { getOwner } from '@ember/application'; import { test, moduleForComponent } from 'ember-qunit'; -import { click, findAll } from 'ember-native-dom-helpers'; +import { click, find, findAll } from 'ember-native-dom-helpers'; import wait from 'ember-test-helpers/wait'; import hbs from 'htmlbars-inline-precompile'; import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage'; @@ -75,15 +75,61 @@ test('Clicking Force Launch launches a new periodic child job', function(assert) 'POST URL was correct' ); - assert.ok(server.db.jobs.length, currentJobCount + 1, 'POST request was made'); - - return wait().then(() => { - assert.equal( - findAll('[data-test-job-name]').length, - childrenCount + 1, - 'The new periodic job launch is in the children list' - ); - }); + assert.equal(server.db.jobs.length, currentJobCount + 1, 'POST request was made'); + }); + }); + }); +}); + +test('Clicking force launch without proper permissions shows an error message', function(assert) { + server.pretender.post('/v1/job/:id/periodic/force', () => [403, {}, null]); + + this.server.create('job', 'periodic', { + id: 'parent', + childrenCount: 1, + createAllocations: false, + }); + + this.store.findAll('job'); + + return wait().then(() => { + const job = this.store.peekAll('job').findBy('plainId', 'parent'); + this.setProperties({ + job, + sortProperty: 'name', + sortDescending: true, + currentPage: 1, + gotoJob: () => {}, + }); + + this.render(hbs` + {{job-page/periodic + job=job + sortProperty=sortProperty + sortDescending=sortDescending + currentPage=currentPage + gotoJob=gotoJob}} + `); + + return wait().then(() => { + assert.notOk(find('[data-test-force-error-title]'), 'No error message yet'); + + click('[data-test-force-launch]'); + + return wait().then(() => { + assert.equal( + find('[data-test-force-error-title]').textContent, + 'Could Not Force Launch', + 'Appropriate error is shown' + ); + assert.ok( + find('[data-test-force-error-body]').textContent.includes('ACL'), + 'The error message mentions ACLs' + ); + + click('[data-test-force-error-close]'); + + assert.notOk(find('[data-test-force-error-title]'), 'Error message is dismissable'); }); }); });