UI: Remove ember-native-dom-helpers (#5959)
This also includes migration of some tests to async.
This commit is contained in:
parent
cc20b3169c
commit
354b4c830f
|
@ -75,7 +75,6 @@
|
|||
"ember-load-initializers": "^1.1.0",
|
||||
"ember-maybe-import-regenerator": "^0.1.6",
|
||||
"ember-moment": "^7.8.1",
|
||||
"ember-native-dom-helpers": "^0.5.4",
|
||||
"ember-page-title": "^5.0.2",
|
||||
"ember-power-select": "^2.2.3",
|
||||
"ember-qunit-nice-errors": "^1.2.0",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { find } from 'ember-native-dom-helpers';
|
||||
import { find } from '@ember/test-helpers';
|
||||
import { module, skip, test } from 'qunit';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, settled } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import generateResources from '../../mirage/data/generate-resources';
|
||||
import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage';
|
||||
import { find } from 'ember-native-dom-helpers';
|
||||
import { find, render } from '@ember/test-helpers';
|
||||
import Response from 'ember-cli-mirage/response';
|
||||
import { initialize as fragmentSerializerInitializer } from 'nomad-ui/initializers/fragment-serializer';
|
||||
import { Promise, resolve } from 'rsvp';
|
||||
|
||||
module('Integration | Component | allocation row', function(hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
@ -25,7 +23,7 @@ module('Integration | Component | allocation row', function(hooks) {
|
|||
this.server.shutdown();
|
||||
});
|
||||
|
||||
test('Allocation row polls for stats, even when it errors or has an invalid response', function(assert) {
|
||||
test('Allocation row polls for stats, even when it errors or has an invalid response', async function(assert) {
|
||||
const component = this;
|
||||
|
||||
let currentFrame = 0;
|
||||
|
@ -52,13 +50,9 @@ module('Integration | Component | allocation row', function(hooks) {
|
|||
});
|
||||
|
||||
this.server.create('allocation', { clientStatus: 'running' });
|
||||
this.store.findAll('allocation');
|
||||
await this.store.findAll('allocation');
|
||||
|
||||
let allocation;
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
allocation = this.store.peekAll('allocation').get('firstObject');
|
||||
const allocation = this.store.peekAll('allocation').get('firstObject');
|
||||
|
||||
this.setProperties({
|
||||
allocation,
|
||||
|
@ -72,9 +66,7 @@ module('Integration | Component | allocation row', function(hooks) {
|
|||
context=context
|
||||
enablePolling=enablePolling}}
|
||||
`);
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
|
||||
assert.equal(
|
||||
this.server.pretender.handledRequests.filterBy(
|
||||
'url',
|
||||
|
@ -84,9 +76,8 @@ module('Integration | Component | allocation row', function(hooks) {
|
|||
'Requests continue to be made after malformed responses and server errors'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('Allocation row shows warning when it requires drivers that are unhealthy on the node it is running on', function(assert) {
|
||||
test('Allocation row shows warning when it requires drivers that are unhealthy on the node it is running on', async function(assert) {
|
||||
const node = this.server.schema.nodes.first();
|
||||
const drivers = node.drivers;
|
||||
Object.values(drivers).forEach(driver => {
|
||||
|
@ -96,15 +87,11 @@ module('Integration | Component | allocation row', function(hooks) {
|
|||
node.update({ drivers });
|
||||
|
||||
this.server.create('allocation', { clientStatus: 'running' });
|
||||
this.store.findAll('job');
|
||||
this.store.findAll('node');
|
||||
this.store.findAll('allocation');
|
||||
await this.store.findAll('job');
|
||||
await this.store.findAll('node');
|
||||
await this.store.findAll('allocation');
|
||||
|
||||
let allocation;
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
allocation = this.store.peekAll('allocation').get('firstObject');
|
||||
const allocation = this.store.peekAll('allocation').get('firstObject');
|
||||
|
||||
this.setProperties({
|
||||
allocation,
|
||||
|
@ -116,18 +103,13 @@ module('Integration | Component | allocation row', function(hooks) {
|
|||
allocation=allocation
|
||||
context=context}}
|
||||
`);
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
|
||||
assert.ok(find('[data-test-icon="unhealthy-driver"]'), 'Unhealthy driver icon is shown');
|
||||
});
|
||||
});
|
||||
|
||||
test('Allocation row shows an icon indicator when it was preempted', async function(assert) {
|
||||
const allocId = this.server.create('allocation', 'preempted').id;
|
||||
|
||||
const allocation = await this.store.findRecord('allocation', allocId);
|
||||
await settled();
|
||||
|
||||
this.setProperties({ allocation, context: 'job' });
|
||||
await render(hbs`
|
||||
|
@ -135,12 +117,11 @@ module('Integration | Component | allocation row', function(hooks) {
|
|||
allocation=allocation
|
||||
context=context}}
|
||||
`);
|
||||
await settled();
|
||||
|
||||
assert.ok(find('[data-test-icon="preemption"]'), 'Preempted icon is shown');
|
||||
});
|
||||
|
||||
test('when an allocation is not running, the utilization graphs are omitted', function(assert) {
|
||||
test('when an allocation is not running, the utilization graphs are omitted', async function(assert) {
|
||||
this.setProperties({
|
||||
context: 'job',
|
||||
enablePolling: false,
|
||||
|
@ -151,56 +132,22 @@ module('Integration | Component | allocation row', function(hooks) {
|
|||
this.server.create('allocation', { clientStatus })
|
||||
);
|
||||
|
||||
this.store.findAll('allocation');
|
||||
await this.store.findAll('allocation');
|
||||
|
||||
return settled().then(() => {
|
||||
const allocations = this.store.peekAll('allocation');
|
||||
return waitForEach(
|
||||
allocations.map(allocation => async () => {
|
||||
|
||||
for (const allocation of allocations.toArray()) {
|
||||
this.set('allocation', allocation);
|
||||
await render(hbs`
|
||||
await this.render(hbs`
|
||||
{{allocation-row
|
||||
allocation=allocation
|
||||
context=context
|
||||
enablePolling=enablePolling}}
|
||||
`);
|
||||
return settled().then(() => {
|
||||
|
||||
const status = allocation.get('clientStatus');
|
||||
assert.notOk(find('[data-test-cpu] .inline-chart'), `No CPU chart for ${status}`);
|
||||
assert.notOk(find('[data-test-mem] .inline-chart'), `No Mem chart for ${status}`);
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// A way to loop over asynchronous code. Can be replaced by async/await in the future.
|
||||
const waitForEach = fns => {
|
||||
let i = 0;
|
||||
let done = () => {};
|
||||
|
||||
// This function is asynchronous and needs to return a promise
|
||||
const pending = new Promise(resolve => {
|
||||
done = resolve;
|
||||
});
|
||||
|
||||
const step = () => {
|
||||
// The waitForEach promise and this recursive loop are done once
|
||||
// all functions have been called.
|
||||
if (i >= fns.length) {
|
||||
done();
|
||||
return;
|
||||
}
|
||||
// Call the current function
|
||||
const promise = fns[i]() || resolve(true);
|
||||
// Increment the function position
|
||||
i++;
|
||||
// Wait for async behaviors to settle and repeat
|
||||
promise.then(() => settled()).then(step);
|
||||
};
|
||||
|
||||
step();
|
||||
|
||||
return pending;
|
||||
};
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,8 +2,7 @@ import Service from '@ember/service';
|
|||
import RSVP from 'rsvp';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, settled } from '@ember/test-helpers';
|
||||
import { findAll } from 'ember-native-dom-helpers';
|
||||
import { findAll, render, settled } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import PromiseObject from 'nomad-ui/utils/classes/promise-object';
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { find, findAll } from 'ember-native-dom-helpers';
|
||||
import { find, findAll, render } from '@ember/test-helpers';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import flat from 'flat';
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { findAll, find } from 'ember-native-dom-helpers';
|
||||
import { findAll, find, render } from '@ember/test-helpers';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import cleanWhitespace from '../utils/clean-whitespace';
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import { assign } from '@ember/polyfills';
|
||||
import { run } from '@ember/runloop';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { settled } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import { create } from 'ember-cli-page-object';
|
||||
import sinon from 'sinon';
|
||||
|
@ -95,8 +93,7 @@ module('Integration | Component | job-editor', function(hooks) {
|
|||
|
||||
const renderNewJob = async (component, job) => {
|
||||
component.setProperties({ job, onSubmit: sinon.spy(), context: 'new' });
|
||||
component.render(commonTemplate);
|
||||
await settled();
|
||||
await component.render(commonTemplate);
|
||||
};
|
||||
|
||||
const renderEditJob = async (component, job) => {
|
||||
|
@ -106,33 +103,22 @@ module('Integration | Component | job-editor', function(hooks) {
|
|||
|
||||
const planJob = async spec => {
|
||||
await Editor.editor.fillIn(spec);
|
||||
await settled();
|
||||
await Editor.plan();
|
||||
await settled();
|
||||
};
|
||||
|
||||
test('the default state is an editor with an explanation popup', async function(assert) {
|
||||
let job;
|
||||
run(() => {
|
||||
job = this.store.createRecord('job');
|
||||
});
|
||||
const job = await this.store.createRecord('job');
|
||||
|
||||
await settled();
|
||||
await renderNewJob(this, job);
|
||||
assert.ok(Editor.editorHelp.isPresent, 'Editor explanation popup is present');
|
||||
assert.ok(Editor.editor.isPresent, 'Editor is present');
|
||||
});
|
||||
|
||||
test('the explanation popup can be dismissed', async function(assert) {
|
||||
let job;
|
||||
run(() => {
|
||||
job = this.store.createRecord('job');
|
||||
});
|
||||
const job = await this.store.createRecord('job');
|
||||
|
||||
await settled();
|
||||
await renderNewJob(this, job);
|
||||
await Editor.editorHelp.dismiss();
|
||||
await settled();
|
||||
assert.notOk(Editor.editorHelp.isPresent, 'Editor explanation popup is gone');
|
||||
assert.equal(
|
||||
window.localStorage.nomadMessageJobEditor,
|
||||
|
@ -144,24 +130,16 @@ module('Integration | Component | job-editor', function(hooks) {
|
|||
test('the explanation popup is not shown once the dismissal state is set in localStorage', async function(assert) {
|
||||
window.localStorage.nomadMessageJobEditor = 'false';
|
||||
|
||||
let job;
|
||||
run(() => {
|
||||
job = this.store.createRecord('job');
|
||||
});
|
||||
const job = await this.store.createRecord('job');
|
||||
|
||||
await settled();
|
||||
await renderNewJob(this, job);
|
||||
assert.notOk(Editor.editorHelp.isPresent, 'Editor explanation popup is gone');
|
||||
});
|
||||
|
||||
test('submitting a json job skips the parse endpoint', async function(assert) {
|
||||
const spec = jsonJob();
|
||||
let job;
|
||||
run(() => {
|
||||
job = this.store.createRecord('job');
|
||||
});
|
||||
const job = await this.store.createRecord('job');
|
||||
|
||||
await settled();
|
||||
await renderNewJob(this, job);
|
||||
await planJob(spec);
|
||||
const requests = this.server.pretender.handledRequests.mapBy('url');
|
||||
|
@ -171,12 +149,8 @@ module('Integration | Component | job-editor', function(hooks) {
|
|||
|
||||
test('submitting an hcl job requires the parse endpoint', async function(assert) {
|
||||
const spec = hclJob();
|
||||
let job;
|
||||
run(() => {
|
||||
job = this.store.createRecord('job');
|
||||
});
|
||||
const job = await this.store.createRecord('job');
|
||||
|
||||
await settled();
|
||||
await renderNewJob(this, job);
|
||||
await planJob(spec);
|
||||
const requests = this.server.pretender.handledRequests.mapBy('url');
|
||||
|
@ -190,12 +164,8 @@ module('Integration | Component | job-editor', function(hooks) {
|
|||
|
||||
test('when a job is successfully parsed and planned, the plan is shown to the user', async function(assert) {
|
||||
const spec = hclJob();
|
||||
let job;
|
||||
run(() => {
|
||||
job = this.store.createRecord('job');
|
||||
});
|
||||
const job = await this.store.createRecord('job');
|
||||
|
||||
await settled();
|
||||
await renderNewJob(this, job);
|
||||
await planJob(spec);
|
||||
assert.ok(Editor.planOutput, 'The plan is outputted');
|
||||
|
@ -205,16 +175,11 @@ module('Integration | Component | job-editor', function(hooks) {
|
|||
|
||||
test('from the plan screen, the cancel button goes back to the editor with the job still in tact', async function(assert) {
|
||||
const spec = hclJob();
|
||||
let job;
|
||||
run(() => {
|
||||
job = this.store.createRecord('job');
|
||||
});
|
||||
const job = await this.store.createRecord('job');
|
||||
|
||||
await settled();
|
||||
await renderNewJob(this, job);
|
||||
await planJob(spec);
|
||||
await Editor.cancel();
|
||||
await settled();
|
||||
assert.ok(Editor.editor.isPresent, 'The editor is shown again');
|
||||
assert.equal(Editor.editor.contents, spec, 'The spec that was planned is still in the editor');
|
||||
});
|
||||
|
@ -222,15 +187,10 @@ module('Integration | Component | job-editor', function(hooks) {
|
|||
test('when parse fails, the parse error message is shown', async function(assert) {
|
||||
const spec = hclJob();
|
||||
const errorMessage = 'Parse Failed!! :o';
|
||||
|
||||
let job;
|
||||
run(() => {
|
||||
job = this.store.createRecord('job');
|
||||
});
|
||||
const job = await this.store.createRecord('job');
|
||||
|
||||
this.server.pretender.post('/v1/jobs/parse', () => [400, {}, errorMessage]);
|
||||
|
||||
await settled();
|
||||
await renderNewJob(this, job);
|
||||
await planJob(spec);
|
||||
assert.notOk(Editor.planError.isPresent, 'Plan error is not shown');
|
||||
|
@ -247,15 +207,10 @@ module('Integration | Component | job-editor', function(hooks) {
|
|||
test('when plan fails, the plan error message is shown', async function(assert) {
|
||||
const spec = hclJob();
|
||||
const errorMessage = 'Plan Failed!! :o';
|
||||
|
||||
let job;
|
||||
run(() => {
|
||||
job = this.store.createRecord('job');
|
||||
});
|
||||
const job = await this.store.createRecord('job');
|
||||
|
||||
this.server.pretender.post(`/v1/job/${newJobName}/plan`, () => [400, {}, errorMessage]);
|
||||
|
||||
await settled();
|
||||
await renderNewJob(this, job);
|
||||
await planJob(spec);
|
||||
assert.notOk(Editor.parseError.isPresent, 'Parse error is not shown');
|
||||
|
@ -272,19 +227,13 @@ module('Integration | Component | job-editor', function(hooks) {
|
|||
test('when run fails, the run error message is shown', async function(assert) {
|
||||
const spec = hclJob();
|
||||
const errorMessage = 'Run Failed!! :o';
|
||||
|
||||
let job;
|
||||
run(() => {
|
||||
job = this.store.createRecord('job');
|
||||
});
|
||||
const job = await this.store.createRecord('job');
|
||||
|
||||
this.server.pretender.post('/v1/jobs', () => [400, {}, errorMessage]);
|
||||
|
||||
await settled();
|
||||
await renderNewJob(this, job);
|
||||
await planJob(spec);
|
||||
await Editor.run();
|
||||
await settled();
|
||||
assert.notOk(Editor.planError.isPresent, 'Plan error is not shown');
|
||||
assert.notOk(Editor.parseError.isPresent, 'Parse error is not shown');
|
||||
|
||||
|
@ -298,12 +247,8 @@ module('Integration | Component | job-editor', function(hooks) {
|
|||
|
||||
test('when the scheduler dry-run has warnings, the warnings are shown to the user', async function(assert) {
|
||||
const spec = jsonJob({ Unschedulable: true });
|
||||
let job;
|
||||
run(() => {
|
||||
job = this.store.createRecord('job');
|
||||
});
|
||||
const job = await this.store.createRecord('job');
|
||||
|
||||
await settled();
|
||||
await renderNewJob(this, job);
|
||||
await planJob(spec);
|
||||
assert.ok(
|
||||
|
@ -322,12 +267,8 @@ module('Integration | Component | job-editor', function(hooks) {
|
|||
|
||||
test('when the scheduler dry-run has no warnings, a success message is shown to the user', async function(assert) {
|
||||
const spec = hclJob();
|
||||
let job;
|
||||
run(() => {
|
||||
job = this.store.createRecord('job');
|
||||
});
|
||||
const job = await this.store.createRecord('job');
|
||||
|
||||
await settled();
|
||||
await renderNewJob(this, job);
|
||||
await planJob(spec);
|
||||
assert.ok(
|
||||
|
@ -342,12 +283,8 @@ module('Integration | Component | job-editor', function(hooks) {
|
|||
|
||||
test('when a job is submitted in the edit context, a POST request is made to the update job endpoint', async function(assert) {
|
||||
const spec = hclJob();
|
||||
let job;
|
||||
run(() => {
|
||||
job = this.store.createRecord('job');
|
||||
});
|
||||
const job = await this.store.createRecord('job');
|
||||
|
||||
await settled();
|
||||
await renderEditJob(this, job);
|
||||
await planJob(spec);
|
||||
await Editor.run();
|
||||
|
@ -358,12 +295,8 @@ module('Integration | Component | job-editor', function(hooks) {
|
|||
|
||||
test('when a job is submitted in the new context, a POST request is made to the create job endpoint', async function(assert) {
|
||||
const spec = hclJob();
|
||||
let job;
|
||||
run(() => {
|
||||
job = this.store.createRecord('job');
|
||||
});
|
||||
const job = await this.store.createRecord('job');
|
||||
|
||||
await settled();
|
||||
await renderNewJob(this, job);
|
||||
await planJob(spec);
|
||||
await Editor.run();
|
||||
|
@ -377,16 +310,11 @@ module('Integration | Component | job-editor', function(hooks) {
|
|||
|
||||
test('when a job is successfully submitted, the onSubmit hook is called', async function(assert) {
|
||||
const spec = hclJob();
|
||||
let job;
|
||||
run(() => {
|
||||
job = this.store.createRecord('job');
|
||||
});
|
||||
const job = await this.store.createRecord('job');
|
||||
|
||||
await settled();
|
||||
await renderNewJob(this, job);
|
||||
await planJob(spec);
|
||||
await Editor.run();
|
||||
await settled();
|
||||
assert.ok(
|
||||
this.get('onSubmit').calledWith(newJobName, 'default'),
|
||||
'The onSubmit hook was called with the correct arguments'
|
||||
|
@ -394,34 +322,22 @@ module('Integration | Component | job-editor', function(hooks) {
|
|||
});
|
||||
|
||||
test('when the job-editor cancelable flag is false, there is no cancel button in the header', async function(assert) {
|
||||
let job;
|
||||
run(() => {
|
||||
job = this.store.createRecord('job');
|
||||
});
|
||||
const job = await this.store.createRecord('job');
|
||||
|
||||
await settled();
|
||||
await renderNewJob(this, job);
|
||||
assert.notOk(Editor.cancelEditingIsAvailable, 'No way to cancel editing');
|
||||
});
|
||||
|
||||
test('when the job-editor cancelable flag is true, there is a cancel button in the header', async function(assert) {
|
||||
let job;
|
||||
run(() => {
|
||||
job = this.store.createRecord('job');
|
||||
});
|
||||
const job = await this.store.createRecord('job');
|
||||
|
||||
await settled();
|
||||
await renderEditJob(this, job);
|
||||
assert.ok(Editor.cancelEditingIsAvailable, 'Cancel editing button exists');
|
||||
});
|
||||
|
||||
test('when the job-editor cancel button is clicked, the onCancel hook is called', async function(assert) {
|
||||
let job;
|
||||
run(() => {
|
||||
job = this.store.createRecord('job');
|
||||
});
|
||||
const job = await this.store.createRecord('job');
|
||||
|
||||
await settled();
|
||||
await renderEditJob(this, job);
|
||||
await Editor.cancelEditing();
|
||||
assert.ok(this.get('onCancel').calledOnce, 'The onCancel hook was called');
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { click, find } from 'ember-native-dom-helpers';
|
||||
import { settled } from '@ember/test-helpers';
|
||||
import { click, find } from '@ember/test-helpers';
|
||||
|
||||
export function jobURL(job, path = '') {
|
||||
const id = job.get('plainId');
|
||||
|
@ -11,20 +10,14 @@ export function jobURL(job, path = '') {
|
|||
return expectedURL;
|
||||
}
|
||||
|
||||
export function stopJob() {
|
||||
click('[data-test-stop] [data-test-idle-button]');
|
||||
return settled().then(() => {
|
||||
click('[data-test-stop] [data-test-confirm-button]');
|
||||
return settled();
|
||||
});
|
||||
export async function stopJob() {
|
||||
await click('[data-test-stop] [data-test-idle-button]');
|
||||
await click('[data-test-stop] [data-test-confirm-button]');
|
||||
}
|
||||
|
||||
export function startJob() {
|
||||
click('[data-test-start] [data-test-idle-button]');
|
||||
return settled().then(() => {
|
||||
click('[data-test-start] [data-test-confirm-button]');
|
||||
return settled();
|
||||
});
|
||||
export async function startJob() {
|
||||
await click('[data-test-start] [data-test-idle-button]');
|
||||
await click('[data-test-start] [data-test-confirm-button]');
|
||||
}
|
||||
|
||||
export function expectStartRequest(assert, server, job) {
|
||||
|
@ -39,8 +32,7 @@ export function expectStartRequest(assert, server, job) {
|
|||
assert.ok(requestPayload.Stop == null, 'The Stop signal is not sent in the POST request');
|
||||
}
|
||||
|
||||
export function expectError(assert, title) {
|
||||
return () => {
|
||||
export async function expectError(assert, title) {
|
||||
assert.equal(
|
||||
find('[data-test-job-error-title]').textContent,
|
||||
title,
|
||||
|
@ -51,10 +43,8 @@ export function expectError(assert, title) {
|
|||
'The error message mentions ACLs'
|
||||
);
|
||||
|
||||
click('[data-test-job-error-close]');
|
||||
await click('[data-test-job-error-close]');
|
||||
assert.notOk(find('[data-test-job-error-title]'), 'Error message is dismissable');
|
||||
return settled();
|
||||
};
|
||||
}
|
||||
|
||||
export function expectDeleteRequest(assert, server, job) {
|
||||
|
@ -66,6 +56,4 @@ export function expectDeleteRequest(assert, server, job) {
|
|||
.find(req => req.url === expectedURL),
|
||||
'DELETE URL was made correctly'
|
||||
);
|
||||
|
||||
return settled();
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import { run } from '@ember/runloop';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, settled } from '@ember/test-helpers';
|
||||
import { find, findAll } from 'ember-native-dom-helpers';
|
||||
import { find, findAll, render } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage';
|
||||
|
||||
|
@ -29,20 +27,15 @@ module('Integration | Component | job-page/parts/body', function(hooks) {
|
|||
{{/job-page/parts/body}}
|
||||
`);
|
||||
|
||||
await settled();
|
||||
assert.ok(find('[data-test-subnav="job"]'), 'Job subnav is rendered');
|
||||
});
|
||||
|
||||
test('the subnav includes the deployments link when the job is a service', async function(assert) {
|
||||
const store = this.owner.lookup('service:store');
|
||||
let job;
|
||||
|
||||
run(() => {
|
||||
job = store.createRecord('job', {
|
||||
const job = await store.createRecord('job', {
|
||||
id: 'service-job',
|
||||
type: 'service',
|
||||
});
|
||||
});
|
||||
|
||||
this.set('job', job);
|
||||
|
||||
|
@ -52,7 +45,6 @@ module('Integration | Component | job-page/parts/body', function(hooks) {
|
|||
{{/job-page/parts/body}}
|
||||
`);
|
||||
|
||||
await settled();
|
||||
const subnavLabels = findAll('[data-test-tab]').map(anchor => anchor.textContent);
|
||||
assert.ok(subnavLabels.some(label => label === 'Definition'), 'Definition link');
|
||||
assert.ok(subnavLabels.some(label => label === 'Versions'), 'Versions link');
|
||||
|
@ -61,14 +53,10 @@ module('Integration | Component | job-page/parts/body', function(hooks) {
|
|||
|
||||
test('the subnav does not include the deployments link when the job is not a service', async function(assert) {
|
||||
const store = this.owner.lookup('service:store');
|
||||
let job;
|
||||
|
||||
run(() => {
|
||||
job = store.createRecord('job', {
|
||||
const job = await store.createRecord('job', {
|
||||
id: 'batch-job',
|
||||
type: 'batch',
|
||||
});
|
||||
});
|
||||
|
||||
this.set('job', job);
|
||||
|
||||
|
@ -78,7 +66,6 @@ module('Integration | Component | job-page/parts/body', function(hooks) {
|
|||
{{/job-page/parts/body}}
|
||||
`);
|
||||
|
||||
await settled();
|
||||
const subnavLabels = findAll('[data-test-tab]').map(anchor => anchor.textContent);
|
||||
assert.ok(subnavLabels.some(label => label === 'Definition'), 'Definition link');
|
||||
assert.ok(subnavLabels.some(label => label === 'Versions'), 'Versions link');
|
||||
|
@ -94,7 +81,6 @@ module('Integration | Component | job-page/parts/body', function(hooks) {
|
|||
{{/job-page/parts/body}}
|
||||
`);
|
||||
|
||||
await settled();
|
||||
assert.ok(
|
||||
find('[data-test-subnav="job"] + .section > .inner-content'),
|
||||
'Content is rendered immediately after the subnav'
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import { assign } from '@ember/polyfills';
|
||||
import { run } from '@ember/runloop';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import { findAll, find, click } from 'ember-native-dom-helpers';
|
||||
import { findAll, find, click, render } from '@ember/test-helpers';
|
||||
import sinon from 'sinon';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, settled } from '@ember/test-helpers';
|
||||
import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage';
|
||||
|
||||
module('Integration | Component | job-page/parts/children', function(hooks) {
|
||||
|
@ -35,21 +33,16 @@ module('Integration | Component | job-page/parts/children', function(hooks) {
|
|||
options
|
||||
);
|
||||
|
||||
test('lists each child', function(assert) {
|
||||
let parent;
|
||||
|
||||
test('lists each child', async function(assert) {
|
||||
this.server.create('job', 'periodic', {
|
||||
id: 'parent',
|
||||
childrenCount: 3,
|
||||
createAllocations: false,
|
||||
});
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled().then(async () => {
|
||||
run(() => {
|
||||
parent = this.store.peekAll('job').findBy('plainId', 'parent');
|
||||
});
|
||||
const parent = this.store.peekAll('job').findBy('plainId', 'parent');
|
||||
|
||||
this.setProperties(props(parent));
|
||||
|
||||
|
@ -62,31 +55,23 @@ module('Integration | Component | job-page/parts/children', function(hooks) {
|
|||
gotoJob=gotoJob}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
assert.equal(
|
||||
findAll('[data-test-job-name]').length,
|
||||
parent.get('children.length'),
|
||||
'A row for each child'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('eventually paginates', function(assert) {
|
||||
let parent;
|
||||
|
||||
test('eventually paginates', async function(assert) {
|
||||
this.server.create('job', 'periodic', {
|
||||
id: 'parent',
|
||||
childrenCount: 11,
|
||||
createAllocations: false,
|
||||
});
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled().then(async () => {
|
||||
run(() => {
|
||||
parent = this.store.peekAll('job').findBy('plainId', 'parent');
|
||||
});
|
||||
const parent = this.store.peekAll('job').findBy('plainId', 'parent');
|
||||
|
||||
this.setProperties(props(parent));
|
||||
|
||||
|
@ -99,7 +84,6 @@ module('Integration | Component | job-page/parts/children', function(hooks) {
|
|||
gotoJob=gotoJob}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
const childrenCount = parent.get('children.length');
|
||||
assert.ok(childrenCount > 10, 'Parent has more children than one page size');
|
||||
assert.equal(findAll('[data-test-job-name]').length, 10, 'Table length maxes out at 10');
|
||||
|
@ -109,24 +93,17 @@ module('Integration | Component | job-page/parts/children', function(hooks) {
|
|||
new RegExp(`1.10.+?${childrenCount}`).test(find('.pagination-numbers').textContent.trim())
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('is sorted based on the sortProperty and sortDescending properties', function(assert) {
|
||||
let parent;
|
||||
|
||||
test('is sorted based on the sortProperty and sortDescending properties', async function(assert) {
|
||||
this.server.create('job', 'periodic', {
|
||||
id: 'parent',
|
||||
childrenCount: 3,
|
||||
createAllocations: false,
|
||||
});
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled().then(async () => {
|
||||
run(() => {
|
||||
parent = this.store.peekAll('job').findBy('plainId', 'parent');
|
||||
});
|
||||
const parent = this.store.peekAll('job').findBy('plainId', 'parent');
|
||||
|
||||
this.setProperties(props(parent));
|
||||
|
||||
|
@ -139,7 +116,6 @@ module('Integration | Component | job-page/parts/children', function(hooks) {
|
|||
gotoJob=gotoJob}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
const sortedChildren = parent.get('children').sortBy('name');
|
||||
const childRows = findAll('[data-test-job-name]');
|
||||
|
||||
|
@ -151,7 +127,7 @@ module('Integration | Component | job-page/parts/children', function(hooks) {
|
|||
);
|
||||
});
|
||||
|
||||
this.set('sortDescending', false);
|
||||
await this.set('sortDescending', false);
|
||||
|
||||
sortedChildren.forEach((child, index) => {
|
||||
assert.equal(
|
||||
|
@ -160,14 +136,9 @@ module('Integration | Component | job-page/parts/children', function(hooks) {
|
|||
`Child ${index} is ${child.get('name')}`
|
||||
);
|
||||
});
|
||||
|
||||
return settled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('gotoJob is called when a job row is clicked', function(assert) {
|
||||
let parent;
|
||||
test('gotoJob is called when a job row is clicked', async function(assert) {
|
||||
const gotoJobSpy = sinon.spy();
|
||||
|
||||
this.server.create('job', 'periodic', {
|
||||
|
@ -176,12 +147,9 @@ module('Integration | Component | job-page/parts/children', function(hooks) {
|
|||
createAllocations: false,
|
||||
});
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled().then(async () => {
|
||||
run(() => {
|
||||
parent = this.store.peekAll('job').findBy('plainId', 'parent');
|
||||
});
|
||||
const parent = this.store.peekAll('job').findBy('plainId', 'parent');
|
||||
|
||||
this.setProperties(
|
||||
props(parent, {
|
||||
|
@ -198,13 +166,11 @@ module('Integration | Component | job-page/parts/children', function(hooks) {
|
|||
gotoJob=gotoJob}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
click('tr.job-row');
|
||||
await click('tr.job-row');
|
||||
|
||||
assert.ok(
|
||||
gotoJobSpy.withArgs(parent.get('children.firstObject')).calledOnce,
|
||||
'Clicking the job row calls the gotoJob action'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, settled } from '@ember/test-helpers';
|
||||
import { click, find } from 'ember-native-dom-helpers';
|
||||
import { click, find, render } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import moment from 'moment';
|
||||
import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage';
|
||||
|
@ -23,45 +22,39 @@ module('Integration | Component | job-page/parts/latest-deployment', function(ho
|
|||
window.localStorage.clear();
|
||||
});
|
||||
|
||||
test('there is no latest deployment section when the job has no deployments', function(assert) {
|
||||
test('there is no latest deployment section when the job has no deployments', async function(assert) {
|
||||
this.server.create('job', {
|
||||
type: 'service',
|
||||
noDeployments: true,
|
||||
createAllocations: false,
|
||||
});
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled().then(async () => {
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
await render(hbs`
|
||||
{{job-page/parts/latest-deployment job=job}})
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
assert.notOk(find('[data-test-active-deployment]'), 'No active deployment');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('the latest deployment section shows up for the currently running deployment', function(assert) {
|
||||
test('the latest deployment section shows up for the currently running deployment', async function(assert) {
|
||||
this.server.create('job', {
|
||||
type: 'service',
|
||||
createAllocations: false,
|
||||
activeDeployment: true,
|
||||
});
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled().then(async () => {
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
await render(hbs`
|
||||
{{job-page/parts/latest-deployment job=job}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
const deployment = this.get('job.latestDeployment');
|
||||
const version = deployment.get('version');
|
||||
const deployment = await this.get('job.latestDeployment');
|
||||
const version = await deployment.get('version');
|
||||
|
||||
assert.ok(find('[data-test-active-deployment]'), 'Active deployment');
|
||||
assert.ok(
|
||||
|
@ -116,67 +109,54 @@ module('Integration | Component | job-page/parts/latest-deployment', function(ho
|
|||
'Status description is in the metrics block'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('when there is no running deployment, the latest deployment section shows up for the last deployment', function(assert) {
|
||||
test('when there is no running deployment, the latest deployment section shows up for the last deployment', async function(assert) {
|
||||
this.server.create('job', {
|
||||
type: 'service',
|
||||
createAllocations: false,
|
||||
noActiveDeployment: true,
|
||||
});
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled().then(async () => {
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
await render(hbs`
|
||||
{{job-page/parts/latest-deployment job=job}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
assert.ok(find('[data-test-active-deployment]'), 'Active deployment');
|
||||
assert.notOk(
|
||||
find('[data-test-active-deployment]').classList.contains('is-info'),
|
||||
'Non-running deployment does not get the is-info class'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('the latest deployment section can be expanded to show task groups and allocations', function(assert) {
|
||||
test('the latest deployment section can be expanded to show task groups and allocations', async function(assert) {
|
||||
this.server.create('node');
|
||||
this.server.create('job', { type: 'service', activeDeployment: true });
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled().then(async () => {
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
await render(hbs`
|
||||
{{job-page/parts/latest-deployment job=job}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
assert.notOk(find('[data-test-deployment-task-groups]'), 'Task groups not found');
|
||||
assert.notOk(find('[data-test-deployment-allocations]'), 'Allocations not found');
|
||||
|
||||
click('[data-test-deployment-toggle-details]');
|
||||
await click('[data-test-deployment-toggle-details]');
|
||||
|
||||
return settled().then(() => {
|
||||
assert.ok(find('[data-test-deployment-task-groups]'), 'Task groups found');
|
||||
assert.ok(find('[data-test-deployment-allocations]'), 'Allocations found');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('each task group in the expanded task group section shows task group details', function(assert) {
|
||||
test('each task group in the expanded task group section shows task group details', async function(assert) {
|
||||
this.server.create('node');
|
||||
this.server.create('job', { type: 'service', activeDeployment: true });
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled().then(async () => {
|
||||
const job = this.store.peekAll('job').get('firstObject');
|
||||
|
||||
this.set('job', job);
|
||||
|
@ -184,15 +164,10 @@ module('Integration | Component | job-page/parts/latest-deployment', function(ho
|
|||
{{job-page/parts/latest-deployment job=job}}
|
||||
`);
|
||||
|
||||
return settled()
|
||||
.then(() => {
|
||||
click('[data-test-deployment-toggle-details]');
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
await click('[data-test-deployment-toggle-details]');
|
||||
|
||||
const task = job.get('runningDeployment.taskGroupSummaries.firstObject');
|
||||
const findForTaskGroup = selector =>
|
||||
find(`[data-test-deployment-task-group-${selector}]`);
|
||||
const findForTaskGroup = selector => find(`[data-test-deployment-task-group-${selector}]`);
|
||||
assert.equal(findForTaskGroup('name').textContent.trim(), task.get('name'));
|
||||
assert.equal(
|
||||
findForTaskGroup('progress-deadline').textContent.trim(),
|
||||
|
@ -200,5 +175,3 @@ module('Integration | Component | job-page/parts/latest-deployment', function(ho
|
|||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
import { run } from '@ember/runloop';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import { findAll, find } from 'ember-native-dom-helpers';
|
||||
import { findAll, find, render } from '@ember/test-helpers';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, settled } from '@ember/test-helpers';
|
||||
import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage';
|
||||
import { initialize as fragmentSerializerInitializer } from 'nomad-ui/initializers/fragment-serializer';
|
||||
|
||||
|
@ -23,22 +21,19 @@ module('Integration | Component | job-page/parts/placement-failures', function(h
|
|||
window.localStorage.clear();
|
||||
});
|
||||
|
||||
test('when the job has placement failures, they are called out', function(assert) {
|
||||
test('when the job has placement failures, they are called out', async function(assert) {
|
||||
this.server.create('job', { failedPlacements: true, createAllocations: false });
|
||||
this.store.findAll('job').then(jobs => {
|
||||
jobs.forEach(job => job.reload());
|
||||
});
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled().then(async () => {
|
||||
run(() => {
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
});
|
||||
const job = this.store.peekAll('job').get('firstObject');
|
||||
await job.reload();
|
||||
|
||||
this.set('job', job);
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/placement-failures job=job}})
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
const failedEvaluation = this.get('job.evaluations')
|
||||
.filterBy('hasPlacementFailures')
|
||||
.sortBy('modifyIndex')
|
||||
|
@ -64,28 +59,20 @@ module('Integration | Component | job-page/parts/placement-failures', function(h
|
|||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('when the job has no placement failures, the placement failures section is gone', function(assert) {
|
||||
test('when the job has no placement failures, the placement failures section is gone', async function(assert) {
|
||||
this.server.create('job', { noFailedPlacements: true, createAllocations: false });
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled().then(async () => {
|
||||
run(() => {
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
});
|
||||
const job = this.store.peekAll('job').get('firstObject');
|
||||
await job.reload();
|
||||
|
||||
this.set('job', job);
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/placement-failures job=job}})
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
assert.notOk(
|
||||
find('[data-test-placement-failures]'),
|
||||
'Placement failures section not found'
|
||||
);
|
||||
});
|
||||
});
|
||||
assert.notOk(find('[data-test-placement-failures]'), 'Placement failures section not found');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import hbs from 'htmlbars-inline-precompile';
|
||||
import { find, click } from 'ember-native-dom-helpers';
|
||||
import { find, click, render } from '@ember/test-helpers';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, settled } from '@ember/test-helpers';
|
||||
import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage';
|
||||
import { initialize as fragmentSerializerInitializer } from 'nomad-ui/initializers/fragment-serializer';
|
||||
|
||||
|
@ -22,63 +21,53 @@ module('Integration | Component | job-page/parts/summary', function(hooks) {
|
|||
window.localStorage.clear();
|
||||
});
|
||||
|
||||
test('jobs with children use the children diagram', function(assert) {
|
||||
test('jobs with children use the children diagram', async function(assert) {
|
||||
this.server.create('job', 'periodic', {
|
||||
createAllocations: false,
|
||||
});
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled().then(async () => {
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/summary job=job}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
assert.ok(find('[data-test-children-status-bar]'), 'Children status bar found');
|
||||
assert.notOk(find('[data-test-allocation-status-bar]'), 'Allocation status bar not found');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('jobs without children use the allocations diagram', function(assert) {
|
||||
test('jobs without children use the allocations diagram', async function(assert) {
|
||||
this.server.create('job', {
|
||||
createAllocations: false,
|
||||
});
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled().then(async () => {
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/summary job=job}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
assert.ok(find('[data-test-allocation-status-bar]'), 'Allocation status bar found');
|
||||
assert.notOk(find('[data-test-children-status-bar]'), 'Children status bar not found');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('the allocations diagram lists all allocation status figures', function(assert) {
|
||||
test('the allocations diagram lists all allocation status figures', async function(assert) {
|
||||
this.server.create('job', {
|
||||
createAllocations: false,
|
||||
});
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled().then(async () => {
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/summary job=job}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
assert.equal(
|
||||
find('[data-test-legend-value="queued"]').textContent,
|
||||
this.get('job.queuedAllocs'),
|
||||
|
@ -115,24 +104,20 @@ module('Integration | Component | job-page/parts/summary', function(hooks) {
|
|||
`${this.get('job.lostAllocs')} are lost`
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('the children diagram lists all children status figures', function(assert) {
|
||||
test('the children diagram lists all children status figures', async function(assert) {
|
||||
this.server.create('job', 'periodic', {
|
||||
createAllocations: false,
|
||||
});
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled().then(async () => {
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/summary job=job}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
assert.equal(
|
||||
find('[data-test-legend-value="queued"]').textContent,
|
||||
this.get('job.pendingChildren'),
|
||||
|
@ -151,127 +136,94 @@ module('Integration | Component | job-page/parts/summary', function(hooks) {
|
|||
`${this.get('job.deadChildren')} are dead`
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('the summary block can be collapsed', function(assert) {
|
||||
test('the summary block can be collapsed', async function(assert) {
|
||||
this.server.create('job', {
|
||||
createAllocations: false,
|
||||
});
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/summary job=job}}
|
||||
`);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
click('[data-test-accordion-toggle]');
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
await click('[data-test-accordion-toggle]');
|
||||
|
||||
assert.notOk(find('[data-test-accordion-body]'), 'No accordion body');
|
||||
assert.notOk(find('[data-test-legend]'), 'No legend');
|
||||
});
|
||||
});
|
||||
|
||||
test('when collapsed, the summary block includes an inline version of the chart', function(assert) {
|
||||
test('when collapsed, the summary block includes an inline version of the chart', async function(assert) {
|
||||
this.server.create('job', {
|
||||
createAllocations: false,
|
||||
});
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
await this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/summary job=job}}
|
||||
`);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
click('[data-test-accordion-toggle]');
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
await click('[data-test-accordion-toggle]');
|
||||
|
||||
assert.ok(find('[data-test-allocation-status-bar]'), 'Allocation bar still existed');
|
||||
assert.ok(
|
||||
find('.inline-chart [data-test-allocation-status-bar]'),
|
||||
'Allocation bar is rendered in an inline-chart container'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('the collapsed/expanded state is persisted to localStorage', function(assert) {
|
||||
test('the collapsed/expanded state is persisted to localStorage', async function(assert) {
|
||||
this.server.create('job', {
|
||||
createAllocations: false,
|
||||
});
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/summary job=job}}
|
||||
`);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
assert.notOk(window.localStorage.nomadExpandJobSummary, 'No value in localStorage yet');
|
||||
click('[data-test-accordion-toggle]');
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
await click('[data-test-accordion-toggle]');
|
||||
|
||||
assert.equal(
|
||||
window.localStorage.nomadExpandJobSummary,
|
||||
'false',
|
||||
'Value is stored for the collapsed state'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('the collapsed/expanded state from localStorage is used for the initial state when available', function(assert) {
|
||||
test('the collapsed/expanded state from localStorage is used for the initial state when available', async function(assert) {
|
||||
this.server.create('job', {
|
||||
createAllocations: false,
|
||||
});
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
window.localStorage.nomadExpandJobSummary = 'false';
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/summary job=job}}
|
||||
`);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
assert.ok(find('[data-test-allocation-status-bar]'), 'Allocation bar still existed');
|
||||
assert.ok(
|
||||
find('.inline-chart [data-test-allocation-status-bar]'),
|
||||
'Allocation bar is rendered in an inline-chart container'
|
||||
);
|
||||
|
||||
click('[data-test-accordion-toggle]');
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
await click('[data-test-accordion-toggle]');
|
||||
|
||||
assert.equal(
|
||||
window.localStorage.nomadExpandJobSummary,
|
||||
'true',
|
||||
|
@ -280,4 +232,3 @@ module('Integration | Component | job-page/parts/summary', function(hooks) {
|
|||
assert.ok(find('[data-test-accordion-body]'), 'Summary still expands');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
import { assign } from '@ember/polyfills';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import { click, findAll, find } from 'ember-native-dom-helpers';
|
||||
import { click, findAll, find } from '@ember/test-helpers';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, settled } from '@ember/test-helpers';
|
||||
import sinon from 'sinon';
|
||||
import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage';
|
||||
import { initialize as fragmentSerializerInitializer } from 'nomad-ui/initializers/fragment-serializer';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
|
||||
module('Integration | Component | job-page/parts/task-groups', function(hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
hooks.beforeEach(function() {
|
||||
fragmentSerializerInitializer(this.owner);
|
||||
window.localStorage.clear();
|
||||
this.store = this.owner.lookup('service:store');
|
||||
this.server = startMirage();
|
||||
|
@ -34,20 +31,19 @@ module('Integration | Component | job-page/parts/task-groups', function(hooks) {
|
|||
options
|
||||
);
|
||||
|
||||
test('the job detail page should list all task groups', function(assert) {
|
||||
test('the job detail page should list all task groups', async function(assert) {
|
||||
this.server.create('job', {
|
||||
createAllocations: false,
|
||||
});
|
||||
|
||||
this.store.findAll('job').then(jobs => {
|
||||
await this.store.findAll('job').then(jobs => {
|
||||
jobs.forEach(job => job.reload());
|
||||
});
|
||||
|
||||
return settled().then(async () => {
|
||||
const job = this.store.peekAll('job').get('firstObject');
|
||||
this.setProperties(props(job));
|
||||
|
||||
await render(hbs`
|
||||
await this.render(hbs`
|
||||
{{job-page/parts/task-groups
|
||||
job=job
|
||||
sortProperty=sortProperty
|
||||
|
@ -55,36 +51,31 @@ module('Integration | Component | job-page/parts/task-groups', function(hooks) {
|
|||
gotoTaskGroup=gotoTaskGroup}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
assert.equal(
|
||||
findAll('[data-test-task-group]').length,
|
||||
job.get('taskGroups.length'),
|
||||
'One row per task group'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('each row in the task group table should show basic information about the task group', function(assert) {
|
||||
test('each row in the task group table should show basic information about the task group', async function(assert) {
|
||||
this.server.create('job', {
|
||||
createAllocations: false,
|
||||
});
|
||||
|
||||
this.store.findAll('job').then(jobs => {
|
||||
jobs.forEach(job => job.reload());
|
||||
const job = await this.store.findAll('job').then(async jobs => {
|
||||
return await jobs.get('firstObject').reload();
|
||||
});
|
||||
|
||||
return settled().then(async () => {
|
||||
const job = this.store.peekAll('job').get('firstObject');
|
||||
const taskGroup = job
|
||||
.get('taskGroups')
|
||||
const taskGroups = await job.get('taskGroups');
|
||||
const taskGroup = taskGroups
|
||||
.sortBy('name')
|
||||
.reverse()
|
||||
.get('firstObject');
|
||||
|
||||
this.setProperties(props(job));
|
||||
|
||||
await render(hbs`
|
||||
await this.render(hbs`
|
||||
{{job-page/parts/task-groups
|
||||
job=job
|
||||
sortProperty=sortProperty
|
||||
|
@ -92,7 +83,6 @@ module('Integration | Component | job-page/parts/task-groups', function(hooks) {
|
|||
gotoTaskGroup=gotoTaskGroup}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
const taskGroupRow = find('[data-test-task-group]');
|
||||
|
||||
assert.equal(
|
||||
|
@ -121,23 +111,20 @@ module('Integration | Component | job-page/parts/task-groups', function(hooks) {
|
|||
'Reserved Disk'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('gotoTaskGroup is called when task group rows are clicked', function(assert) {
|
||||
test('gotoTaskGroup is called when task group rows are clicked', async function(assert) {
|
||||
this.server.create('job', {
|
||||
createAllocations: false,
|
||||
});
|
||||
|
||||
this.store.findAll('job').then(jobs => {
|
||||
jobs.forEach(job => job.reload());
|
||||
const job = await this.store.findAll('job').then(async jobs => {
|
||||
return await jobs.get('firstObject').reload();
|
||||
});
|
||||
|
||||
return settled().then(async () => {
|
||||
const taskGroupSpy = sinon.spy();
|
||||
const job = this.store.peekAll('job').get('firstObject');
|
||||
const taskGroup = job
|
||||
.get('taskGroups')
|
||||
|
||||
const taskGroups = await job.get('taskGroups');
|
||||
const taskGroup = taskGroups
|
||||
.sortBy('name')
|
||||
.reverse()
|
||||
.get('firstObject');
|
||||
|
@ -148,7 +135,7 @@ module('Integration | Component | job-page/parts/task-groups', function(hooks) {
|
|||
})
|
||||
);
|
||||
|
||||
await render(hbs`
|
||||
await this.render(hbs`
|
||||
{{job-page/parts/task-groups
|
||||
job=job
|
||||
sortProperty=sortProperty
|
||||
|
@ -156,13 +143,11 @@ module('Integration | Component | job-page/parts/task-groups', function(hooks) {
|
|||
gotoTaskGroup=gotoTaskGroup}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
click('[data-test-task-group]');
|
||||
await click('[data-test-task-group]');
|
||||
|
||||
assert.ok(
|
||||
taskGroupSpy.withArgs(taskGroup).calledOnce,
|
||||
'Clicking the task group row calls the gotoTaskGroup action'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, settled } from '@ember/test-helpers';
|
||||
import { click, find, findAll } from 'ember-native-dom-helpers';
|
||||
import { click, find, findAll, render } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage';
|
||||
import {
|
||||
|
@ -45,7 +44,7 @@ module('Integration | Component | job-page/periodic', function(hooks) {
|
|||
gotoJob: () => {},
|
||||
});
|
||||
|
||||
test('Clicking Force Launch launches a new periodic child job', function(assert) {
|
||||
test('Clicking Force Launch launches a new periodic child job', async function(assert) {
|
||||
const childrenCount = 3;
|
||||
|
||||
this.server.create('job', 'periodic', {
|
||||
|
@ -54,15 +53,13 @@ module('Integration | Component | job-page/periodic', function(hooks) {
|
|||
createAllocations: false,
|
||||
});
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled().then(async () => {
|
||||
const job = this.store.peekAll('job').findBy('plainId', 'parent');
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
await this.render(commonTemplate);
|
||||
|
||||
return settled().then(() => {
|
||||
const currentJobCount = server.db.jobs.length;
|
||||
|
||||
assert.equal(
|
||||
|
@ -71,9 +68,8 @@ module('Integration | Component | job-page/periodic', function(hooks) {
|
|||
'The new periodic job launch is in the children list'
|
||||
);
|
||||
|
||||
click('[data-test-force-launch]');
|
||||
await click('[data-test-force-launch]');
|
||||
|
||||
return settled().then(() => {
|
||||
const expectedURL = jobURL(job, '/periodic/force');
|
||||
|
||||
assert.ok(
|
||||
|
@ -85,11 +81,8 @@ module('Integration | Component | job-page/periodic', function(hooks) {
|
|||
|
||||
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) {
|
||||
test('Clicking force launch without proper permissions shows an error message', async function(assert) {
|
||||
this.server.pretender.post('/v1/job/:id/periodic/force', () => [403, {}, null]);
|
||||
|
||||
this.server.create('job', 'periodic', {
|
||||
|
@ -99,20 +92,17 @@ module('Integration | Component | job-page/periodic', function(hooks) {
|
|||
status: 'running',
|
||||
});
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled().then(async () => {
|
||||
const job = this.store.peekAll('job').findBy('plainId', 'parent');
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
await this.render(commonTemplate);
|
||||
|
||||
return settled().then(() => {
|
||||
assert.notOk(find('[data-test-job-error-title]'), 'No error message yet');
|
||||
|
||||
click('[data-test-force-launch]');
|
||||
await click('[data-test-force-launch]');
|
||||
|
||||
return settled().then(() => {
|
||||
assert.equal(
|
||||
find('[data-test-job-error-title]').textContent,
|
||||
'Could Not Force Launch',
|
||||
|
@ -123,15 +113,12 @@ module('Integration | Component | job-page/periodic', function(hooks) {
|
|||
'The error message mentions ACLs'
|
||||
);
|
||||
|
||||
click('[data-test-job-error-close]');
|
||||
await click('[data-test-job-error-close]');
|
||||
|
||||
assert.notOk(find('[data-test-job-error-title]'), 'Error message is dismissable');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('Stopping a job sends a delete request for the job', function(assert) {
|
||||
test('Stopping a job sends a delete request for the job', async function(assert) {
|
||||
const mirageJob = this.server.create('job', 'periodic', {
|
||||
childrenCount: 0,
|
||||
createAllocations: false,
|
||||
|
@ -139,22 +126,18 @@ module('Integration | Component | job-page/periodic', function(hooks) {
|
|||
});
|
||||
|
||||
let job;
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
await stopJob();
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(stopJob)
|
||||
.then(() => expectDeleteRequest(assert, this.server, job));
|
||||
expectDeleteRequest(assert, this.server, job);
|
||||
});
|
||||
|
||||
test('Stopping a job without proper permissions shows an error message', function(assert) {
|
||||
test('Stopping a job without proper permissions shows an error message', async function(assert) {
|
||||
this.server.pretender.delete('/v1/job/:id', () => [403, {}, null]);
|
||||
|
||||
const mirageJob = this.server.create('job', 'periodic', {
|
||||
|
@ -163,45 +146,35 @@ module('Integration | Component | job-page/periodic', function(hooks) {
|
|||
status: 'running',
|
||||
});
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
const job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(stopJob)
|
||||
.then(expectError(assert, 'Could Not Stop Job'));
|
||||
await stopJob();
|
||||
expectError(assert, 'Could Not Stop Job');
|
||||
});
|
||||
|
||||
test('Starting a job sends a post request for the job using the current definition', function(assert) {
|
||||
let job;
|
||||
|
||||
test('Starting a job sends a post request for the job using the current definition', async function(assert) {
|
||||
const mirageJob = this.server.create('job', 'periodic', {
|
||||
childrenCount: 0,
|
||||
createAllocations: false,
|
||||
status: 'dead',
|
||||
});
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
const job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(startJob)
|
||||
.then(() => expectStartRequest(assert, this.server, job));
|
||||
await startJob();
|
||||
expectStartRequest(assert, this.server, job);
|
||||
});
|
||||
|
||||
test('Starting a job without proper permissions shows an error message', function(assert) {
|
||||
test('Starting a job without proper permissions shows an error message', async function(assert) {
|
||||
this.server.pretender.post('/v1/job/:id', () => [403, {}, null]);
|
||||
|
||||
const mirageJob = this.server.create('job', 'periodic', {
|
||||
|
@ -209,18 +182,14 @@ module('Integration | Component | job-page/periodic', function(hooks) {
|
|||
createAllocations: false,
|
||||
status: 'dead',
|
||||
});
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
const job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(startJob)
|
||||
.then(expectError(assert, 'Could Not Start Job'));
|
||||
await startJob();
|
||||
expectError(assert, 'Could Not Start Job');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { assign } from '@ember/polyfills';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, settled } from '@ember/test-helpers';
|
||||
import { click, find } from 'ember-native-dom-helpers';
|
||||
import { click, find, render } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage';
|
||||
import { startJob, stopJob, expectError, expectDeleteRequest, expectStartRequest } from './helpers';
|
||||
|
@ -57,182 +56,131 @@ module('Integration | Component | job-page/service', function(hooks) {
|
|||
)
|
||||
);
|
||||
|
||||
test('Stopping a job sends a delete request for the job', function(assert) {
|
||||
let job;
|
||||
|
||||
test('Stopping a job sends a delete request for the job', async function(assert) {
|
||||
const mirageJob = makeMirageJob(this.server);
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
const job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(stopJob)
|
||||
.then(() => expectDeleteRequest(assert, this.server, job));
|
||||
await stopJob();
|
||||
expectDeleteRequest(assert, this.server, job);
|
||||
});
|
||||
|
||||
test('Stopping a job without proper permissions shows an error message', function(assert) {
|
||||
test('Stopping a job without proper permissions shows an error message', async function(assert) {
|
||||
this.server.pretender.delete('/v1/job/:id', () => [403, {}, null]);
|
||||
|
||||
const mirageJob = makeMirageJob(this.server);
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
const job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(stopJob)
|
||||
.then(expectError(assert, 'Could Not Stop Job'));
|
||||
await stopJob();
|
||||
expectError(assert, 'Could Not Stop Job');
|
||||
});
|
||||
|
||||
test('Starting a job sends a post request for the job using the current definition', function(assert) {
|
||||
let job;
|
||||
|
||||
test('Starting a job sends a post request for the job using the current definition', async function(assert) {
|
||||
const mirageJob = makeMirageJob(this.server, { status: 'dead' });
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
const job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(startJob)
|
||||
.then(() => expectStartRequest(assert, this.server, job));
|
||||
await startJob();
|
||||
expectStartRequest(assert, this.server, job);
|
||||
});
|
||||
|
||||
test('Starting a job without proper permissions shows an error message', function(assert) {
|
||||
test('Starting a job without proper permissions shows an error message', async function(assert) {
|
||||
this.server.pretender.post('/v1/job/:id', () => [403, {}, null]);
|
||||
|
||||
const mirageJob = makeMirageJob(this.server, { status: 'dead' });
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
const job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(startJob)
|
||||
.then(expectError(assert, 'Could Not Start Job'));
|
||||
await startJob();
|
||||
expectError(assert, 'Could Not Start Job');
|
||||
});
|
||||
|
||||
test('Recent allocations shows allocations in the job context', function(assert) {
|
||||
let job;
|
||||
|
||||
test('Recent allocations shows allocations in the job context', async function(assert) {
|
||||
this.server.create('node');
|
||||
const mirageJob = makeMirageJob(this.server, { createAllocations: true });
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
const job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
const allocation = this.server.db.allocations.sortBy('modifyIndex').reverse()[0];
|
||||
const allocationRow = Job.allocations.objectAt(0);
|
||||
|
||||
assert.equal(allocationRow.shortId, allocation.id.split('-')[0], 'ID');
|
||||
assert.equal(allocationRow.taskGroup, allocation.taskGroup, 'Task Group name');
|
||||
});
|
||||
});
|
||||
|
||||
test('Recent allocations caps out at five', function(assert) {
|
||||
let job;
|
||||
|
||||
test('Recent allocations caps out at five', async function(assert) {
|
||||
this.server.create('node');
|
||||
const mirageJob = makeMirageJob(this.server);
|
||||
this.server.createList('allocation', 10);
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled().then(async () => {
|
||||
job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
const job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled().then(() => {
|
||||
assert.equal(Job.allocations.length, 5, 'Capped at 5 allocations');
|
||||
assert.ok(
|
||||
Job.viewAllAllocations.includes(job.get('allocations.length') + ''),
|
||||
`View link mentions ${job.get('allocations.length')} allocations`
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('Recent allocations shows an empty message when the job has no allocations', function(assert) {
|
||||
let job;
|
||||
|
||||
test('Recent allocations shows an empty message when the job has no allocations', async function(assert) {
|
||||
this.server.create('node');
|
||||
const mirageJob = makeMirageJob(this.server);
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
const job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
assert.ok(
|
||||
Job.recentAllocationsEmptyState.headline.includes('No Allocations'),
|
||||
'No allocations empty message'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('Active deployment can be promoted', function(assert) {
|
||||
let job;
|
||||
let deployment;
|
||||
|
||||
test('Active deployment can be promoted', async function(assert) {
|
||||
this.server.create('node');
|
||||
const mirageJob = makeMirageJob(this.server, { activeDeployment: true });
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
deployment = job.get('latestDeployment');
|
||||
const job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
const deployment = await job.get('latestDeployment');
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
click('[data-test-promote-canary]');
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
await click('[data-test-promote-canary]');
|
||||
|
||||
const requests = this.server.pretender.handledRequests;
|
||||
|
||||
assert.ok(
|
||||
requests
|
||||
.filterBy('method', 'POST')
|
||||
|
@ -240,32 +188,22 @@ module('Integration | Component | job-page/service', function(hooks) {
|
|||
'A promote POST request was made'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('When promoting the active deployment fails, an error is shown', function(assert) {
|
||||
test('When promoting the active deployment fails, an error is shown', async function(assert) {
|
||||
this.server.pretender.post('/v1/deployment/promote/:id', () => [403, {}, null]);
|
||||
|
||||
let job;
|
||||
|
||||
this.server.create('node');
|
||||
const mirageJob = makeMirageJob(this.server, { activeDeployment: true });
|
||||
|
||||
this.store.findAll('job');
|
||||
await this.store.findAll('job');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
const job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
click('[data-test-promote-canary]');
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
await click('[data-test-promote-canary]');
|
||||
|
||||
assert.equal(
|
||||
find('[data-test-job-error-title]').textContent,
|
||||
'Could Not Promote Deployment',
|
||||
|
@ -276,9 +214,8 @@ module('Integration | Component | job-page/service', function(hooks) {
|
|||
'The error message mentions ACLs'
|
||||
);
|
||||
|
||||
click('[data-test-job-error-close]');
|
||||
await click('[data-test-job-error-close]');
|
||||
|
||||
assert.notOk(find('[data-test-job-error-title]'), 'Error message is dismissable');
|
||||
return settled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { findAll, find } from 'ember-native-dom-helpers';
|
||||
import { findAll, find, render } from '@ember/test-helpers';
|
||||
import { module, skip, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
module('Integration | Component | list pagination', function(hooks) {
|
||||
|
@ -240,7 +239,8 @@ module('Integration | Component | list pagination', function(hooks) {
|
|||
assert.equal(
|
||||
findAll('.item')[item].textContent,
|
||||
item + (currentPage - 1) * size,
|
||||
`Rendered items are in the current page, ${currentPage} (${item + (currentPage - 1) * size})`
|
||||
`Rendered items are in the current page, ${currentPage} (${item +
|
||||
(currentPage - 1) * size})`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { findAll, find } from 'ember-native-dom-helpers';
|
||||
import { findAll, find, render } from '@ember/test-helpers';
|
||||
import { module, skip, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { faker } from 'ember-cli-mirage';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { findAll, find, click, focus, keyEvent } from 'ember-native-dom-helpers';
|
||||
import { findAll, find, click, focus, render, triggerKeyEvent } from '@ember/test-helpers';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, settled } from '@ember/test-helpers';
|
||||
import sinon from 'sinon';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
|
@ -55,27 +54,21 @@ module('Integration | Component | multi-select dropdown', function(hooks) {
|
|||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
click('[data-test-dropdown-trigger]');
|
||||
await click('[data-test-dropdown-trigger]');
|
||||
|
||||
await assert.ok(find('[data-test-dropdown-options]'), 'Options are shown now');
|
||||
await click('[data-test-dropdown-trigger]');
|
||||
|
||||
return settled()
|
||||
.then(() => {
|
||||
assert.ok(find('[data-test-dropdown-options]'), 'Options are shown now');
|
||||
click('[data-test-dropdown-trigger]');
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
assert.notOk(find('[data-test-dropdown-options]'), 'Options are hidden after clicking again');
|
||||
});
|
||||
});
|
||||
|
||||
test('all options are shown in the options dropdown, each with a checkbox input', async function(assert) {
|
||||
const props = commonProperties();
|
||||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
click('[data-test-dropdown-trigger]');
|
||||
await click('[data-test-dropdown-trigger]');
|
||||
|
||||
return settled().then(() => {
|
||||
assert.equal(
|
||||
findAll('[data-test-dropdown-option]').length,
|
||||
props.options.length,
|
||||
|
@ -87,21 +80,15 @@ module('Integration | Component | multi-select dropdown', function(hooks) {
|
|||
assert.ok(optionEl.querySelector('input[type="checkbox"]'), 'Option contains a checkbox');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('onSelect gets called when an option is clicked', async function(assert) {
|
||||
const props = commonProperties();
|
||||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
click('[data-test-dropdown-trigger]');
|
||||
await click('[data-test-dropdown-trigger]');
|
||||
await click('[data-test-dropdown-option] label');
|
||||
|
||||
return settled()
|
||||
.then(() => {
|
||||
click('[data-test-dropdown-option] label');
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
assert.ok(props.onSelect.called, 'onSelect was called');
|
||||
const newSelection = props.onSelect.getCall(0).args[0];
|
||||
assert.deepEqual(
|
||||
|
@ -110,7 +97,6 @@ module('Integration | Component | multi-select dropdown', function(hooks) {
|
|||
'onSelect was called with the first option key'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('the component trigger shows the selection count when there is a selection', async function(assert) {
|
||||
const props = commonProperties();
|
||||
|
@ -118,31 +104,32 @@ module('Integration | Component | multi-select dropdown', function(hooks) {
|
|||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
assert.ok(find('[data-test-dropdown-trigger] [data-test-dropdown-count]'), 'The count is shown');
|
||||
assert.ok(
|
||||
find('[data-test-dropdown-trigger] [data-test-dropdown-count]'),
|
||||
'The count is shown'
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-dropdown-trigger] [data-test-dropdown-count]').textContent,
|
||||
props.selection.length,
|
||||
'The count is accurate'
|
||||
);
|
||||
|
||||
this.set('selection', []);
|
||||
await this.set('selection', []);
|
||||
|
||||
return settled().then(() => {
|
||||
assert.notOk(
|
||||
find('[data-test-dropdown-trigger] [data-test-dropdown-count]'),
|
||||
'The count is no longer shown when the selection is empty'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('pressing DOWN when the trigger has focus opens the options list', async function(assert) {
|
||||
const props = commonProperties();
|
||||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
focus('[data-test-dropdown-trigger]');
|
||||
await focus('[data-test-dropdown-trigger]');
|
||||
assert.notOk(find('[data-test-dropdown-options]'), 'Options are not shown on focus');
|
||||
keyEvent('[data-test-dropdown-trigger]', 'keydown', ARROW_DOWN);
|
||||
await triggerKeyEvent('[data-test-dropdown-trigger]', 'keydown', ARROW_DOWN);
|
||||
assert.ok(find('[data-test-dropdown-options]'), 'Options are now shown');
|
||||
assert.equal(
|
||||
document.activeElement,
|
||||
|
@ -156,9 +143,9 @@ module('Integration | Component | multi-select dropdown', function(hooks) {
|
|||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
focus('[data-test-dropdown-trigger]');
|
||||
keyEvent('[data-test-dropdown-trigger]', 'keydown', ARROW_DOWN);
|
||||
keyEvent('[data-test-dropdown-trigger]', 'keydown', ARROW_DOWN);
|
||||
await focus('[data-test-dropdown-trigger]');
|
||||
await triggerKeyEvent('[data-test-dropdown-trigger]', 'keydown', ARROW_DOWN);
|
||||
await triggerKeyEvent('[data-test-dropdown-trigger]', 'keydown', ARROW_DOWN);
|
||||
assert.equal(
|
||||
document.activeElement,
|
||||
find('[data-test-dropdown-option]'),
|
||||
|
@ -171,9 +158,9 @@ module('Integration | Component | multi-select dropdown', function(hooks) {
|
|||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
focus('[data-test-dropdown-trigger]');
|
||||
keyEvent('[data-test-dropdown-trigger]', 'keydown', ARROW_DOWN);
|
||||
keyEvent('[data-test-dropdown-trigger]', 'keydown', TAB);
|
||||
await focus('[data-test-dropdown-trigger]');
|
||||
await triggerKeyEvent('[data-test-dropdown-trigger]', 'keydown', ARROW_DOWN);
|
||||
await triggerKeyEvent('[data-test-dropdown-trigger]', 'keydown', TAB);
|
||||
assert.equal(
|
||||
document.activeElement,
|
||||
find('[data-test-dropdown-option]'),
|
||||
|
@ -186,10 +173,10 @@ module('Integration | Component | multi-select dropdown', function(hooks) {
|
|||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
click('[data-test-dropdown-trigger]');
|
||||
await click('[data-test-dropdown-trigger]');
|
||||
|
||||
focus('[data-test-dropdown-option]');
|
||||
keyEvent('[data-test-dropdown-option]', 'keydown', ARROW_UP);
|
||||
await focus('[data-test-dropdown-option]');
|
||||
await triggerKeyEvent('[data-test-dropdown-option]', 'keydown', ARROW_UP);
|
||||
assert.equal(
|
||||
document.activeElement,
|
||||
find('[data-test-dropdown-option]'),
|
||||
|
@ -202,10 +189,10 @@ module('Integration | Component | multi-select dropdown', function(hooks) {
|
|||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
click('[data-test-dropdown-trigger]');
|
||||
await click('[data-test-dropdown-trigger]');
|
||||
|
||||
focus('[data-test-dropdown-option]');
|
||||
keyEvent('[data-test-dropdown-option]', 'keydown', ARROW_DOWN);
|
||||
await focus('[data-test-dropdown-option]');
|
||||
await triggerKeyEvent('[data-test-dropdown-option]', 'keydown', ARROW_DOWN);
|
||||
assert.equal(
|
||||
document.activeElement,
|
||||
findAll('[data-test-dropdown-option]')[1],
|
||||
|
@ -218,20 +205,26 @@ module('Integration | Component | multi-select dropdown', function(hooks) {
|
|||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
click('[data-test-dropdown-trigger]');
|
||||
await click('[data-test-dropdown-trigger]');
|
||||
|
||||
focus('[data-test-dropdown-option]');
|
||||
await focus('[data-test-dropdown-option]');
|
||||
const optionEls = findAll('[data-test-dropdown-option]');
|
||||
const lastIndex = optionEls.length - 1;
|
||||
optionEls.forEach((option, index) => {
|
||||
keyEvent(option, 'keydown', ARROW_DOWN);
|
||||
|
||||
for (const [index, option] of optionEls.entries()) {
|
||||
await triggerKeyEvent(option, 'keydown', ARROW_DOWN);
|
||||
|
||||
if (index < lastIndex) {
|
||||
assert.equal(document.activeElement, optionEls[index + 1], `Option ${index + 1} has focus`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
keyEvent(optionEls[lastIndex], 'keydown', ARROW_DOWN);
|
||||
assert.equal(document.activeElement, optionEls[lastIndex], `Option ${lastIndex} still has focus`);
|
||||
await triggerKeyEvent(optionEls[lastIndex], 'keydown', ARROW_DOWN);
|
||||
assert.equal(
|
||||
document.activeElement,
|
||||
optionEls[lastIndex],
|
||||
`Option ${lastIndex} still has focus`
|
||||
);
|
||||
});
|
||||
|
||||
test('onSelect gets called when pressing SPACE when a list option is focused', async function(assert) {
|
||||
|
@ -239,10 +232,10 @@ module('Integration | Component | multi-select dropdown', function(hooks) {
|
|||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
click('[data-test-dropdown-trigger]');
|
||||
await click('[data-test-dropdown-trigger]');
|
||||
|
||||
focus('[data-test-dropdown-option]');
|
||||
keyEvent('[data-test-dropdown-option]', 'keydown', SPACE);
|
||||
await focus('[data-test-dropdown-option]');
|
||||
await triggerKeyEvent('[data-test-dropdown-option]', 'keydown', SPACE);
|
||||
|
||||
assert.ok(props.onSelect.called, 'onSelect was called');
|
||||
const newSelection = props.onSelect.getCall(0).args[0];
|
||||
|
@ -258,7 +251,7 @@ module('Integration | Component | multi-select dropdown', function(hooks) {
|
|||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
click('[data-test-dropdown-trigger]');
|
||||
await click('[data-test-dropdown-trigger]');
|
||||
|
||||
findAll('[data-test-dropdown-option]').forEach(option => {
|
||||
assert.ok(parseInt(option.getAttribute('tabindex'), 10) > 0, 'tabindex is a positive value');
|
||||
|
@ -270,7 +263,7 @@ module('Integration | Component | multi-select dropdown', function(hooks) {
|
|||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
click('[data-test-dropdown-trigger]');
|
||||
await click('[data-test-dropdown-trigger]');
|
||||
|
||||
findAll('[data-test-dropdown-option]').forEach(option => {
|
||||
assert.ok(
|
||||
|
@ -285,10 +278,10 @@ module('Integration | Component | multi-select dropdown', function(hooks) {
|
|||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
focus('[data-test-dropdown-trigger]');
|
||||
keyEvent('[data-test-dropdown-trigger]', 'keydown', ARROW_DOWN);
|
||||
keyEvent('[data-test-dropdown-trigger]', 'keydown', ARROW_DOWN);
|
||||
keyEvent('[data-test-dropdown-option]', 'keydown', ESC);
|
||||
await focus('[data-test-dropdown-trigger]');
|
||||
await triggerKeyEvent('[data-test-dropdown-trigger]', 'keydown', ARROW_DOWN);
|
||||
await triggerKeyEvent('[data-test-dropdown-trigger]', 'keydown', ARROW_DOWN);
|
||||
await triggerKeyEvent('[data-test-dropdown-option]', 'keydown', ESC);
|
||||
|
||||
assert.notOk(find('[data-test-dropdown-options]'), 'The options list is hidden once more');
|
||||
assert.equal(
|
||||
|
@ -304,7 +297,7 @@ module('Integration | Component | multi-select dropdown', function(hooks) {
|
|||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
click('[data-test-dropdown-trigger]');
|
||||
await click('[data-test-dropdown-trigger]');
|
||||
assert.ok(find('[data-test-dropdown-options]'), 'The dropdown is still shown');
|
||||
assert.ok(find('[data-test-dropdown-empty]'), 'The empty state is shown');
|
||||
assert.notOk(find('[data-test-dropdown-option]'), 'No options are shown');
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, settled } from '@ember/test-helpers';
|
||||
import { find, click } from 'ember-native-dom-helpers';
|
||||
import { find, click, render } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage';
|
||||
|
||||
|
@ -23,54 +22,36 @@ module('Integration | Component | page layout', function(hooks) {
|
|||
find('[data-test-gutter-menu]').classList.contains('is-open'),
|
||||
'Gutter menu is not open'
|
||||
);
|
||||
click('[data-test-header-gutter-toggle]');
|
||||
await click('[data-test-header-gutter-toggle]');
|
||||
|
||||
return settled().then(() => {
|
||||
assert.ok(find('[data-test-gutter-menu]').classList.contains('is-open'), 'Gutter menu is open');
|
||||
});
|
||||
});
|
||||
|
||||
test('the gutter-menu hamburger menu closes the gutter menu', async function(assert) {
|
||||
await render(hbs`{{page-layout}}`);
|
||||
|
||||
click('[data-test-header-gutter-toggle]');
|
||||
await click('[data-test-header-gutter-toggle]');
|
||||
|
||||
assert.ok(find('[data-test-gutter-menu]').classList.contains('is-open'), 'Gutter menu is open');
|
||||
await click('[data-test-gutter-gutter-toggle]');
|
||||
|
||||
return settled()
|
||||
.then(() => {
|
||||
assert.ok(
|
||||
find('[data-test-gutter-menu]').classList.contains('is-open'),
|
||||
'Gutter menu is open'
|
||||
);
|
||||
click('[data-test-gutter-gutter-toggle]');
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
assert.notOk(
|
||||
find('[data-test-gutter-menu]').classList.contains('is-open'),
|
||||
'Gutter menu is not open'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('the gutter-menu backdrop closes the gutter menu', async function(assert) {
|
||||
await render(hbs`{{page-layout}}`);
|
||||
|
||||
click('[data-test-header-gutter-toggle]');
|
||||
await click('[data-test-header-gutter-toggle]');
|
||||
|
||||
assert.ok(find('[data-test-gutter-menu]').classList.contains('is-open'), 'Gutter menu is open');
|
||||
await click('[data-test-gutter-backdrop]');
|
||||
|
||||
return settled()
|
||||
.then(() => {
|
||||
assert.ok(
|
||||
find('[data-test-gutter-menu]').classList.contains('is-open'),
|
||||
'Gutter menu is open'
|
||||
);
|
||||
click('[data-test-gutter-backdrop]');
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
assert.notOk(
|
||||
find('[data-test-gutter-menu]').classList.contains('is-open'),
|
||||
'Gutter menu is not open'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { find, findAll } from 'ember-native-dom-helpers';
|
||||
import { find, findAll, render } from '@ember/test-helpers';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { assign } from '@ember/polyfills';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import cleanWhitespace from '../utils/clean-whitespace';
|
||||
|
|
|
@ -2,9 +2,8 @@ import EmberObject, { computed } from '@ember/object';
|
|||
import Service from '@ember/service';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, settled } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import { find } from 'ember-native-dom-helpers';
|
||||
import { find, render } from '@ember/test-helpers';
|
||||
import { task } from 'ember-concurrency';
|
||||
import sinon from 'sinon';
|
||||
import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage';
|
||||
|
@ -57,125 +56,93 @@ module('Integration | Component | primary metric', function(hooks) {
|
|||
metric=metric}}
|
||||
`;
|
||||
|
||||
test('Contains a line chart, a percentage bar, a percentage figure, and an absolute usage figure', function(assert) {
|
||||
test('Contains a line chart, a percentage bar, a percentage figure, and an absolute usage figure', async function(assert) {
|
||||
let resource;
|
||||
const metric = 'cpu';
|
||||
|
||||
this.store.findAll('node');
|
||||
await this.store.findAll('node');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
resource = this.store.peekAll('node').get('firstObject');
|
||||
this.setProperties({ resource, metric });
|
||||
|
||||
await render(commonTemplate);
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
|
||||
assert.ok(find('[data-test-line-chart]'), 'Line chart');
|
||||
assert.ok(find('[data-test-percentage-bar]'), 'Percentage bar');
|
||||
assert.ok(find('[data-test-percentage]'), 'Percentage figure');
|
||||
assert.ok(find('[data-test-absolute-value]'), 'Absolute usage figure');
|
||||
});
|
||||
});
|
||||
|
||||
test('The CPU metric maps to is-info', function(assert) {
|
||||
let resource;
|
||||
test('The CPU metric maps to is-info', async function(assert) {
|
||||
const metric = 'cpu';
|
||||
|
||||
this.store.findAll('node');
|
||||
await this.store.findAll('node');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
resource = this.store.peekAll('node').get('firstObject');
|
||||
const resource = this.store.peekAll('node').get('firstObject');
|
||||
this.setProperties({ resource, metric });
|
||||
|
||||
await render(commonTemplate);
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
|
||||
assert.ok(
|
||||
find('[data-test-line-chart] .canvas').classList.contains('is-info'),
|
||||
'Info class for CPU metric'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('The Memory metric maps to is-danger', function(assert) {
|
||||
let resource;
|
||||
test('The Memory metric maps to is-danger', async function(assert) {
|
||||
const metric = 'memory';
|
||||
|
||||
this.store.findAll('node');
|
||||
await this.store.findAll('node');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
resource = this.store.peekAll('node').get('firstObject');
|
||||
const resource = this.store.peekAll('node').get('firstObject');
|
||||
this.setProperties({ resource, metric });
|
||||
|
||||
await render(commonTemplate);
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
|
||||
assert.ok(
|
||||
find('[data-test-line-chart] .canvas').classList.contains('is-danger'),
|
||||
'Danger class for Memory metric'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('Gets the tracker from the tracker registry', function(assert) {
|
||||
let resource;
|
||||
test('Gets the tracker from the tracker registry', async function(assert) {
|
||||
const metric = 'cpu';
|
||||
|
||||
this.store.findAll('node');
|
||||
await this.store.findAll('node');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
resource = this.store.peekAll('node').get('firstObject');
|
||||
const resource = this.store.peekAll('node').get('firstObject');
|
||||
this.setProperties({ resource, metric });
|
||||
|
||||
await render(commonTemplate);
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
|
||||
assert.ok(
|
||||
this.getTrackerSpy.calledWith(resource),
|
||||
'Uses the tracker registry to get the tracker for the provided resource'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('Immediately polls the tracker', function(assert) {
|
||||
let resource;
|
||||
test('Immediately polls the tracker', async function(assert) {
|
||||
const metric = 'cpu';
|
||||
|
||||
this.store.findAll('node');
|
||||
await this.store.findAll('node');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
resource = this.store.peekAll('node').get('firstObject');
|
||||
const resource = this.store.peekAll('node').get('firstObject');
|
||||
this.setProperties({ resource, metric });
|
||||
|
||||
await render(commonTemplate);
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
|
||||
assert.ok(this.trackerPollSpy.calledOnce, 'The tracker is polled immediately');
|
||||
});
|
||||
});
|
||||
|
||||
test('A pause signal is sent to the tracker when the component is destroyed', function(assert) {
|
||||
let resource;
|
||||
test('A pause signal is sent to the tracker when the component is destroyed', async function(assert) {
|
||||
const metric = 'cpu';
|
||||
|
||||
// Capture a reference to the spy before the component is destroyed
|
||||
const trackerSignalPauseSpy = this.trackerSignalPauseSpy;
|
||||
|
||||
this.store.findAll('node');
|
||||
await this.store.findAll('node');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
resource = this.store.peekAll('node').get('firstObject');
|
||||
const resource = this.store.peekAll('node').get('firstObject');
|
||||
this.setProperties({ resource, metric, showComponent: true });
|
||||
await render(hbs`
|
||||
{{#if showComponent}}
|
||||
|
@ -185,16 +152,11 @@ module('Integration | Component | primary metric', function(hooks) {
|
|||
}}
|
||||
{{/if}}
|
||||
`);
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
|
||||
assert.notOk(trackerSignalPauseSpy.called, 'No pause signal has been sent yet');
|
||||
// This will toggle the if statement, resulting the primary-metric component being destroyed.
|
||||
this.set('showComponent', false);
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
|
||||
assert.ok(trackerSignalPauseSpy.calledOnce, 'A pause signal is sent to the tracker');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, settled } from '@ember/test-helpers';
|
||||
import { find, findAll } from 'ember-native-dom-helpers';
|
||||
import { find, findAll, render } from '@ember/test-helpers';
|
||||
import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import moment from 'moment';
|
||||
|
@ -25,7 +24,7 @@ module('Integration | Component | reschedule event timeline', function(hooks) {
|
|||
{{reschedule-event-timeline allocation=allocation}}
|
||||
`;
|
||||
|
||||
test('when the allocation is running, the timeline shows past allocations', function(assert) {
|
||||
test('when the allocation is running, the timeline shows past allocations', async function(assert) {
|
||||
const attempts = 2;
|
||||
|
||||
this.server.create('allocation', 'rescheduled', {
|
||||
|
@ -33,21 +32,15 @@ module('Integration | Component | reschedule event timeline', function(hooks) {
|
|||
rescheduleSuccess: true,
|
||||
});
|
||||
|
||||
this.store.findAll('allocation');
|
||||
let allocation;
|
||||
await this.store.findAll('allocation');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
allocation = this.store
|
||||
const allocation = this.store
|
||||
.peekAll('allocation')
|
||||
.find(alloc => !alloc.get('nextAllocation.content'));
|
||||
|
||||
this.set('allocation', allocation);
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
assert.equal(
|
||||
findAll('[data-test-allocation]').length,
|
||||
attempts + 1,
|
||||
|
@ -77,9 +70,8 @@ module('Integration | Component | reschedule event timeline', function(hooks) {
|
|||
'Allocation shows the status'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('when the allocation has failed and there is a follow up evaluation, a note with a time is shown', function(assert) {
|
||||
test('when the allocation has failed and there is a follow up evaluation, a note with a time is shown', async function(assert) {
|
||||
const attempts = 2;
|
||||
|
||||
this.server.create('allocation', 'rescheduled', {
|
||||
|
@ -87,28 +79,21 @@ module('Integration | Component | reschedule event timeline', function(hooks) {
|
|||
rescheduleSuccess: false,
|
||||
});
|
||||
|
||||
this.store.findAll('allocation');
|
||||
let allocation;
|
||||
await this.store.findAll('allocation');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
allocation = this.store
|
||||
const allocation = this.store
|
||||
.peekAll('allocation')
|
||||
.find(alloc => !alloc.get('nextAllocation.content'));
|
||||
|
||||
this.set('allocation', allocation);
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
assert.ok(
|
||||
find('[data-test-stop-warning]'),
|
||||
'Stop warning is shown since the last allocation failed'
|
||||
);
|
||||
assert.notOk(find('[data-test-attempt-notice]'), 'Reschdule attempt notice is not shown');
|
||||
});
|
||||
});
|
||||
|
||||
test('when the allocation has failed and there is no follow up evaluation, a warning is shown', async function(assert) {
|
||||
const attempts = 2;
|
||||
|
@ -128,7 +113,6 @@ module('Integration | Component | reschedule event timeline', function(hooks) {
|
|||
});
|
||||
|
||||
await this.store.findAll('allocation');
|
||||
await settled();
|
||||
|
||||
let allocation = this.store
|
||||
.peekAll('allocation')
|
||||
|
@ -136,7 +120,6 @@ module('Integration | Component | reschedule event timeline', function(hooks) {
|
|||
this.set('allocation', allocation);
|
||||
|
||||
await render(commonTemplate);
|
||||
await settled();
|
||||
|
||||
assert.ok(
|
||||
find('[data-test-attempt-notice]'),
|
||||
|
@ -145,7 +128,7 @@ module('Integration | Component | reschedule event timeline', function(hooks) {
|
|||
assert.notOk(find('[data-test-stop-warning]'), 'Stop warning is not shown');
|
||||
});
|
||||
|
||||
test('when the allocation has a next allocation already, it is shown in the timeline', function(assert) {
|
||||
test('when the allocation has a next allocation already, it is shown in the timeline', async function(assert) {
|
||||
const attempts = 2;
|
||||
|
||||
const originalAllocation = this.server.create('allocation', 'rescheduled', {
|
||||
|
@ -153,19 +136,13 @@ module('Integration | Component | reschedule event timeline', function(hooks) {
|
|||
rescheduleSuccess: true,
|
||||
});
|
||||
|
||||
this.store.findAll('allocation');
|
||||
let allocation;
|
||||
await this.store.findAll('allocation');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
allocation = this.store.peekAll('allocation').findBy('id', originalAllocation.id);
|
||||
const allocation = this.store.peekAll('allocation').findBy('id', originalAllocation.id);
|
||||
|
||||
this.set('allocation', allocation);
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
assert.ok(
|
||||
find('[data-test-reschedule-label]').textContent.trim(),
|
||||
'Next Allocation',
|
||||
|
@ -188,4 +165,3 @@ module('Integration | Component | reschedule event timeline', function(hooks) {
|
|||
assert.notOk(find('[data-test-attempt-notice]'), 'No attempt notice');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { run } from '@ember/runloop';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, settled } from '@ember/test-helpers';
|
||||
import { find, click } from 'ember-native-dom-helpers';
|
||||
import { find, click, render, settled } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import Pretender from 'pretender';
|
||||
import { logEncode } from '../../mirage/data/logs';
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { find, click } from 'ember-native-dom-helpers';
|
||||
import { find, click, render } from '@ember/test-helpers';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, settled } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import sinon from 'sinon';
|
||||
import { create } from 'ember-cli-page-object';
|
||||
|
@ -53,9 +52,8 @@ module('Integration | Component | two step button', function(hooks) {
|
|||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
TwoStepButton.idle();
|
||||
await TwoStepButton.idle();
|
||||
|
||||
return settled().then(() => {
|
||||
assert.ok(find('[data-test-cancel-button]'), 'Cancel button is rendered');
|
||||
assert.equal(TwoStepButton.cancelText, props.cancelText, 'Button is labeled correctly');
|
||||
|
||||
|
@ -70,41 +68,32 @@ module('Integration | Component | two step button', function(hooks) {
|
|||
|
||||
assert.notOk(find('[data-test-idle-button]'), 'No more idle button');
|
||||
});
|
||||
});
|
||||
|
||||
test('canceling in the promptForConfirmation state calls the onCancel hook and resets to the idle state', async function(assert) {
|
||||
const props = commonProperties();
|
||||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
TwoStepButton.idle();
|
||||
await TwoStepButton.idle();
|
||||
|
||||
return settled().then(() => {
|
||||
TwoStepButton.cancel();
|
||||
await TwoStepButton.cancel();
|
||||
|
||||
return settled().then(() => {
|
||||
assert.ok(props.onCancel.calledOnce, 'The onCancel hook fired');
|
||||
assert.ok(find('[data-test-idle-button]'), 'Idle button is back');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('confirming the promptForConfirmation state calls the onConfirm hook and resets to the idle state', async function(assert) {
|
||||
const props = commonProperties();
|
||||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
TwoStepButton.idle();
|
||||
await TwoStepButton.idle();
|
||||
|
||||
return settled().then(() => {
|
||||
TwoStepButton.confirm();
|
||||
await TwoStepButton.confirm();
|
||||
|
||||
return settled().then(() => {
|
||||
assert.ok(props.onConfirm.calledOnce, 'The onConfirm hook fired');
|
||||
assert.ok(find('[data-test-idle-button]'), 'Idle button is back');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('when awaitingConfirmation is true, the cancel and submit buttons are disabled and the submit button is loading', async function(assert) {
|
||||
const props = commonProperties();
|
||||
|
@ -112,27 +101,23 @@ module('Integration | Component | two step button', function(hooks) {
|
|||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
TwoStepButton.idle();
|
||||
await TwoStepButton.idle();
|
||||
|
||||
return settled().then(() => {
|
||||
assert.ok(TwoStepButton.cancelIsDisabled, 'The cancel button is disabled');
|
||||
assert.ok(TwoStepButton.confirmIsDisabled, 'The confirm button is disabled');
|
||||
assert.ok(TwoStepButton.isRunning, 'The confirm button is in a loading state');
|
||||
});
|
||||
});
|
||||
|
||||
test('when in the prompt state, clicking outside will reset state back to idle', async function(assert) {
|
||||
const props = commonProperties();
|
||||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
TwoStepButton.idle();
|
||||
await settled();
|
||||
await TwoStepButton.idle();
|
||||
|
||||
assert.ok(find('[data-test-cancel-button]'), 'In the prompt state');
|
||||
|
||||
click(document.body);
|
||||
await settled();
|
||||
await click(document.body);
|
||||
|
||||
assert.ok(find('[data-test-idle-button]'), 'Back in the idle state');
|
||||
});
|
||||
|
@ -142,13 +127,11 @@ module('Integration | Component | two step button', function(hooks) {
|
|||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
TwoStepButton.idle();
|
||||
await settled();
|
||||
await TwoStepButton.idle();
|
||||
|
||||
assert.ok(find('[data-test-cancel-button]'), 'In the prompt state');
|
||||
|
||||
click('[data-test-confirmation-message]');
|
||||
await settled();
|
||||
await click('[data-test-confirmation-message]');
|
||||
|
||||
assert.notOk(find('[data-test-idle-button]'), 'Still in the prompt state');
|
||||
});
|
||||
|
@ -159,13 +142,11 @@ module('Integration | Component | two step button', function(hooks) {
|
|||
this.setProperties(props);
|
||||
await render(commonTemplate);
|
||||
|
||||
TwoStepButton.idle();
|
||||
await settled();
|
||||
await TwoStepButton.idle();
|
||||
|
||||
assert.ok(find('[data-test-cancel-button]'), 'In the prompt state');
|
||||
|
||||
click(document.body);
|
||||
await settled();
|
||||
await click(document.body);
|
||||
|
||||
assert.notOk(find('[data-test-idle-button]'), 'Still in the prompt state');
|
||||
});
|
||||
|
@ -178,7 +159,7 @@ module('Integration | Component | two step button', function(hooks) {
|
|||
|
||||
assert.ok(TwoStepButton.isDisabled, 'The idle button is disabled');
|
||||
|
||||
TwoStepButton.idle();
|
||||
await TwoStepButton.idle();
|
||||
assert.ok(find('[data-test-idle-button]'), 'Still in the idle state after clicking');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4824,7 +4824,7 @@ ember-moment@^7.8.1:
|
|||
ember-getowner-polyfill "^2.2.0"
|
||||
ember-macro-helpers "^2.1.0"
|
||||
|
||||
ember-native-dom-helpers@^0.5.3, ember-native-dom-helpers@^0.5.4:
|
||||
ember-native-dom-helpers@^0.5.3:
|
||||
version "0.5.10"
|
||||
resolved "https://registry.yarnpkg.com/ember-native-dom-helpers/-/ember-native-dom-helpers-0.5.10.tgz#9c7172e4ddfa5dd86830c46a936e2f8eca3e5896"
|
||||
integrity sha512-bPJX49vlgnBGwFn/3WJPPJjjyd7/atvzW5j01u1dbyFf3bXvHg9Rs1qaZJdk8js0qZ1FINadIEC9vWtgN3w7tg==
|
||||
|
|
Loading…
Reference in a new issue