open-nomad/ui/tests/acceptance/job-versions-test.js

225 lines
7.5 KiB
JavaScript
Raw Normal View History

2019-03-13 00:08:16 +00:00
import { currentURL } from '@ember/test-helpers';
2019-03-13 00:04:16 +00:00
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
2019-09-26 18:47:07 +00:00
import { setupMirage } from 'ember-cli-mirage/test-support';
import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
2018-07-11 16:45:30 +00:00
import Versions from 'nomad-ui/tests/pages/jobs/job/versions';
import Layout from 'nomad-ui/tests/pages/layout';
2017-09-19 14:47:10 +00:00
import moment from 'moment';
let job;
let namespace;
2017-09-19 14:47:10 +00:00
let versions;
2019-03-13 00:04:16 +00:00
module('Acceptance | job versions', function(hooks) {
setupApplicationTest(hooks);
2019-03-13 01:09:19 +00:00
setupMirage(hooks);
2019-03-13 00:04:16 +00:00
hooks.beforeEach(async function() {
server.create('namespace');
namespace = server.create('namespace');
job = server.create('job', { namespaceId: namespace.id, createAllocations: false });
2017-09-19 14:47:10 +00:00
versions = server.db.jobVersions.where({ jobId: job.id });
const managementToken = server.create('token');
window.localStorage.nomadTokenSecret = managementToken.secretId;
await Versions.visit({ id: job.id, namespace: namespace.id });
2019-03-13 00:04:16 +00:00
});
2017-09-19 14:47:10 +00:00
test('it passes an accessibility audit', async function(assert) {
await a11yAudit(assert);
});
test('/jobs/:id/versions should list all job versions', async function(assert) {
2019-03-13 00:04:16 +00:00
assert.ok(Versions.versions.length, versions.length, 'Each version gets a row in the timeline');
assert.equal(document.title, `Job ${job.name} versions - Nomad`);
2019-03-13 00:04:16 +00:00
});
2017-09-19 14:47:10 +00:00
test('each version mentions the version number, the stability, and the submitted time', async function(assert) {
2019-03-13 00:04:16 +00:00
const version = versions.sortBy('submitTime').reverse()[0];
const formattedSubmitTime = moment(version.submitTime / 1000000).format(
"MMM DD, 'YY HH:mm:ss ZZ"
);
const versionRow = Versions.versions.objectAt(0);
2017-09-19 14:47:10 +00:00
2019-03-13 00:04:16 +00:00
assert.ok(versionRow.text.includes(`Version #${version.version}`), 'Version #');
assert.equal(versionRow.stability, version.stable.toString(), 'Stability');
assert.equal(versionRow.submitTime, formattedSubmitTime, 'Submit time');
});
test('all versions but the current one have a button to revert to that version', async function(assert) {
let versionRowToRevertTo;
Versions.versions.forEach(versionRow => {
if (versionRow.number === job.version) {
assert.ok(versionRow.revertToButton.isHidden);
} else {
assert.ok(versionRow.revertToButton.isPresent);
versionRowToRevertTo = versionRow;
}
});
if (versionRowToRevertTo) {
const versionNumberRevertingTo = versionRowToRevertTo.number;
await versionRowToRevertTo.revertToButton.idle();
await versionRowToRevertTo.revertToButton.confirm();
const revertRequest = this.server.pretender.handledRequests.find(request =>
request.url.includes('revert')
);
assert.equal(revertRequest.url, `/v1/job/${job.id}/revert?namespace=${namespace.id}`);
assert.deepEqual(JSON.parse(revertRequest.requestBody), {
JobID: job.id,
JobVersion: versionNumberRevertingTo,
});
assert.equal(currentURL(), `/jobs/${job.id}?namespace=${namespace.id}`);
}
});
test('when reversion fails, the error message from the API is piped through to the alert', async function(assert) {
const versionRowToRevertTo = Versions.versions.filter(
versionRow => versionRow.revertToButton.isPresent
)[0];
if (versionRowToRevertTo) {
const message = 'A plaintext error message';
server.pretender.post('/v1/job/:id/revert', () => [500, {}, message]);
await versionRowToRevertTo.revertToButton.idle();
await versionRowToRevertTo.revertToButton.confirm();
assert.ok(Layout.inlineError.isShown);
assert.ok(Layout.inlineError.isDanger);
assert.ok(Layout.inlineError.title.includes('Could Not Revert'));
assert.equal(Layout.inlineError.message, message);
await Layout.inlineError.dismiss();
assert.notOk(Layout.inlineError.isShown);
} else {
assert.expect(0);
}
});
test('when reversion has no effect, the error message explains', async function(assert) {
const versionRowToRevertTo = Versions.versions.filter(
versionRow => versionRow.revertToButton.isPresent
)[0];
if (versionRowToRevertTo) {
// The default Mirage implementation updates the job version as passed in, this does nothing
server.pretender.post('/v1/job/:id/revert', () => [200, {}, '']);
await versionRowToRevertTo.revertToButton.idle();
await versionRowToRevertTo.revertToButton.confirm();
assert.ok(Layout.inlineError.isShown);
assert.ok(Layout.inlineError.isWarning);
assert.ok(Layout.inlineError.title.includes('Reversion Had No Effect'));
assert.equal(
Layout.inlineError.message,
'Reverting to an identical older version doesnt produce a new version'
);
} else {
assert.expect(0);
}
});
test('when the job for the versions is not found, an error message is shown, but the URL persists', async function(assert) {
await Versions.visit({ id: 'not-a-real-job' });
assert.equal(
server.pretender.handledRequests
.filter(request => !request.url.includes('policy'))
.findBy('status', 404).url,
'/v1/job/not-a-real-job',
'A request to the nonexistent job is made'
);
assert.equal(currentURL(), '/jobs/not-a-real-job/versions', 'The URL persists');
assert.ok(Versions.error.isPresent, 'Error message is shown');
assert.equal(Versions.error.title, 'Not Found', 'Error message is for 404');
});
});
module('Acceptance | job versions (with client token)', function(hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
hooks.beforeEach(async function() {
job = server.create('job', { createAllocations: false });
versions = server.db.jobVersions.where({ jobId: job.id });
server.create('token');
const clientToken = server.create('token');
window.localStorage.nomadTokenSecret = clientToken.secretId;
await Versions.visit({ id: job.id });
});
test('reversion buttons are disabled when the token lacks permissions', async function(assert) {
const versionRowWithReversion = Versions.versions.filter(
versionRow => versionRow.revertToButton.isPresent
)[0];
if (versionRowWithReversion) {
assert.ok(versionRowWithReversion.revertToButtonIsDisabled);
} else {
assert.expect(0);
}
window.localStorage.clear();
});
test('reversion buttons are available when the client token has permissions', async function(assert) {
const REVERT_NAMESPACE = 'revert-namespace';
window.localStorage.clear();
const clientToken = server.create('token');
server.create('namespace', { id: REVERT_NAMESPACE });
const job = server.create('job', {
groupCount: 0,
createAllocations: false,
shallow: true,
noActiveDeployment: true,
namespaceId: REVERT_NAMESPACE,
});
const policy = server.create('policy', {
id: 'something',
name: 'something',
rulesJSON: {
Namespaces: [
{
Name: REVERT_NAMESPACE,
Capabilities: ['submit-job'],
},
],
},
});
clientToken.policyIds = [policy.id];
clientToken.save();
window.localStorage.nomadTokenSecret = clientToken.secretId;
versions = server.db.jobVersions.where({ jobId: job.id });
await Versions.visit({ id: job.id, namespace: REVERT_NAMESPACE });
const versionRowWithReversion = Versions.versions.filter(
versionRow => versionRow.revertToButton.isPresent
)[0];
if (versionRowWithReversion) {
assert.ok(versionRowWithReversion.revertToButtonIsDisabled);
} else {
assert.expect(0);
}
});
});