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');
});
});
});