185 lines
6 KiB
JavaScript
185 lines
6 KiB
JavaScript
/**
|
|
* Copyright (c) HashiCorp, Inc.
|
|
* SPDX-License-Identifier: MPL-2.0
|
|
*/
|
|
|
|
import { click, currentURL } from '@ember/test-helpers';
|
|
import percySnapshot from '@percy/ember';
|
|
import { module, test } from 'qunit';
|
|
import { setupApplicationTest } from 'ember-qunit';
|
|
import { setupMirage } from 'ember-cli-mirage/test-support';
|
|
import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
|
|
import setupCodeMirror from 'nomad-ui/tests/helpers/codemirror';
|
|
import Definition from 'nomad-ui/tests/pages/jobs/job/definition';
|
|
import { JOB_JSON } from 'nomad-ui/tests/utils/generate-raw-json-job';
|
|
|
|
let job;
|
|
|
|
module('Acceptance | job definition', function (hooks) {
|
|
setupApplicationTest(hooks);
|
|
setupMirage(hooks);
|
|
setupCodeMirror(hooks);
|
|
|
|
hooks.beforeEach(async function () {
|
|
server.create('node');
|
|
server.create('job');
|
|
job = server.db.jobs[0];
|
|
await Definition.visit({ id: job.id });
|
|
});
|
|
|
|
test('it passes an accessibility audit', async function (assert) {
|
|
assert.expect(1);
|
|
|
|
await a11yAudit(assert, 'scrollable-region-focusable');
|
|
});
|
|
|
|
test('visiting /jobs/:job_id/definition', async function (assert) {
|
|
assert.equal(currentURL(), `/jobs/${job.id}/definition`);
|
|
assert.equal(document.title, `Job ${job.name} definition - Nomad`);
|
|
});
|
|
|
|
test('the job definition page starts in read-only view', async function (assert) {
|
|
assert.dom('[data-test-job-spec-view]').exists('Read-only Editor appears.');
|
|
});
|
|
|
|
test('the job definition page requests the job to display in an unmutated form', async function (assert) {
|
|
const jobURL = `/v1/job/${job.id}`;
|
|
const jobRequests = server.pretender.handledRequests
|
|
.map((req) => req.url.split('?')[0])
|
|
.filter((url) => url === jobURL);
|
|
assert.strictEqual(
|
|
jobRequests.length,
|
|
2,
|
|
'Two requests for the job were made'
|
|
);
|
|
});
|
|
|
|
test('the job definition can be edited', async function (assert) {
|
|
assert
|
|
.dom('[data-test-job-editor]')
|
|
.doesNotExist('Editor not shown on load.');
|
|
|
|
await Definition.edit();
|
|
|
|
assert.ok(
|
|
Definition.editor.isPresent,
|
|
'Editor is shown after clicking edit'
|
|
);
|
|
assert.notOk(Definition.jsonViewer, 'Editor replaces the JSON viewer');
|
|
});
|
|
|
|
test('when in editing mode, the action can be canceled, showing the read-only definition again', async function (assert) {
|
|
await Definition.edit();
|
|
|
|
await Definition.editor.cancelEditing();
|
|
assert.dom('[data-test-job-spec-view]').exists('Read-only Editor appears.');
|
|
assert.dom('[data-test-job-editor]').doesNotExist('The editor is gone');
|
|
});
|
|
|
|
test('when in editing mode, the editor is prepopulated with the job definition', async function (assert) {
|
|
assert.expect(1);
|
|
|
|
const requests = server.pretender.handledRequests;
|
|
const jobSubmission = requests.findBy(
|
|
'url',
|
|
`/v1/job/${job.id}/submission?version=1`
|
|
).responseText;
|
|
const formattedJobDefinition = JSON.parse(jobSubmission).Source;
|
|
|
|
await Definition.edit();
|
|
await percySnapshot(assert);
|
|
|
|
assert.equal(
|
|
Definition.editor.editor.contents,
|
|
formattedJobDefinition,
|
|
'The editor already has the job definition in it'
|
|
);
|
|
});
|
|
|
|
test('when changes are submitted, the site redirects to the job overview page', async function (assert) {
|
|
await Definition.edit();
|
|
|
|
const cm = getCodeMirrorInstance(['data-test-editor']);
|
|
cm.setValue(`{}`);
|
|
|
|
await click('[data-test-plan]');
|
|
await Definition.editor.run();
|
|
assert.equal(
|
|
currentURL(),
|
|
`/jobs/${job.id}@default`,
|
|
'Now on the job overview page'
|
|
);
|
|
});
|
|
|
|
test('when the job for the definition is not found, an error message is shown, but the URL persists', async function (assert) {
|
|
assert.expect(4);
|
|
await Definition.visit({ id: 'not-a-real-job' });
|
|
await percySnapshot(assert);
|
|
|
|
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/definition',
|
|
'The URL persists'
|
|
);
|
|
assert.ok(Definition.error.isPresent, 'Error message is shown');
|
|
assert.equal(
|
|
Definition.error.title,
|
|
'Not Found',
|
|
'Error message is for 404'
|
|
);
|
|
});
|
|
});
|
|
|
|
module('display and edit using full specification', function (hooks) {
|
|
setupApplicationTest(hooks);
|
|
setupMirage(hooks);
|
|
setupCodeMirror(hooks);
|
|
|
|
hooks.beforeEach(async function () {
|
|
server.create('node');
|
|
server.create('job');
|
|
job = server.db.jobs[0];
|
|
});
|
|
|
|
test('it allows users to select between full specification and JSON definition', async function (assert) {
|
|
assert.expect(3);
|
|
const specification_response = {
|
|
Format: 'hcl2',
|
|
JobID: 'example',
|
|
JobIndex: 223,
|
|
Namespace: 'default',
|
|
Source:
|
|
'variable "datacenter" {\n description = "The datacenter to run the job in"\n type = string\n default = "dc1"\n}\n\njob "example" {\n datacenters = [var.datacenter]\n\n group "example-group" {\n task "example-task" {\n driver = "docker"\n\n config {\n image = "redis:3.2"\n }\n\n resources {\n cpu = 500\n memory = 256\n }\n }\n }\n}\n',
|
|
VariableFlags: { datacenter: 'dc2' },
|
|
Variables: '',
|
|
Version: 0,
|
|
};
|
|
server.get('/job/:id', () => JOB_JSON);
|
|
server.get('/job/:id/submission', () => specification_response);
|
|
|
|
await Definition.visit({ id: job.id });
|
|
await percySnapshot(assert);
|
|
|
|
assert
|
|
.dom('[data-test-select="job-spec"]')
|
|
.exists('A select button exists and defaults to full definition');
|
|
let codeMirror = getCodeMirrorInstance('[data-test-editor]');
|
|
assert.equal(
|
|
codeMirror.getValue(),
|
|
specification_response.Source,
|
|
'Shows the full definition as written by the user'
|
|
);
|
|
|
|
await click('[data-test-select-full]');
|
|
codeMirror = getCodeMirrorInstance('[data-test-editor]');
|
|
assert.propContains(JSON.parse(codeMirror.getValue()), JOB_JSON);
|
|
});
|
|
});
|