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,41 +50,34 @@ module('Integration | Component | allocation row', function(hooks) {
|
|||
});
|
||||
|
||||
this.server.create('allocation', { clientStatus: 'running' });
|
||||
this.store.findAll('allocation');
|
||||
await this.store.findAll('allocation');
|
||||
|
||||
let allocation;
|
||||
const allocation = this.store.peekAll('allocation').get('firstObject');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
allocation = this.store.peekAll('allocation').get('firstObject');
|
||||
this.setProperties({
|
||||
allocation,
|
||||
context: 'job',
|
||||
enablePolling: true,
|
||||
});
|
||||
|
||||
this.setProperties({
|
||||
allocation,
|
||||
context: 'job',
|
||||
enablePolling: true,
|
||||
});
|
||||
await render(hbs`
|
||||
{{allocation-row
|
||||
allocation=allocation
|
||||
context=context
|
||||
enablePolling=enablePolling}}
|
||||
`);
|
||||
|
||||
await render(hbs`
|
||||
{{allocation-row
|
||||
allocation=allocation
|
||||
context=context
|
||||
enablePolling=enablePolling}}
|
||||
`);
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
assert.equal(
|
||||
this.server.pretender.handledRequests.filterBy(
|
||||
'url',
|
||||
`/v1/client/allocation/${allocation.get('id')}/stats`
|
||||
).length,
|
||||
frames.length,
|
||||
'Requests continue to be made after malformed responses and server errors'
|
||||
);
|
||||
});
|
||||
assert.equal(
|
||||
this.server.pretender.handledRequests.filterBy(
|
||||
'url',
|
||||
`/v1/client/allocation/${allocation.get('id')}/stats`
|
||||
).length,
|
||||
frames.length,
|
||||
'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,38 +87,29 @@ 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;
|
||||
const allocation = this.store.peekAll('allocation').get('firstObject');
|
||||
|
||||
return settled()
|
||||
.then(async () => {
|
||||
allocation = this.store.peekAll('allocation').get('firstObject');
|
||||
this.setProperties({
|
||||
allocation,
|
||||
context: 'job',
|
||||
});
|
||||
|
||||
this.setProperties({
|
||||
allocation,
|
||||
context: 'job',
|
||||
});
|
||||
await render(hbs`
|
||||
{{allocation-row
|
||||
allocation=allocation
|
||||
context=context}}
|
||||
`);
|
||||
|
||||
await render(hbs`
|
||||
{{allocation-row
|
||||
allocation=allocation
|
||||
context=context}}
|
||||
`);
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
assert.ok(find('[data-test-icon="unhealthy-driver"]'), 'Unhealthy driver icon is shown');
|
||||
});
|
||||
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 () => {
|
||||
this.set('allocation', allocation);
|
||||
await 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}`);
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
const allocations = this.store.peekAll('allocation');
|
||||
|
||||
for (const allocation of allocations.toArray()) {
|
||||
this.set('allocation', allocation);
|
||||
await this.render(hbs`
|
||||
{{allocation-row
|
||||
allocation=allocation
|
||||
context=context
|
||||
enablePolling=enablePolling}}
|
||||
`);
|
||||
|
||||
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,22 +32,19 @@ 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 () => {
|
||||
assert.equal(
|
||||
find('[data-test-job-error-title]').textContent,
|
||||
title,
|
||||
'Appropriate error is shown'
|
||||
);
|
||||
assert.ok(
|
||||
find('[data-test-job-error-body]').textContent.includes('ACL'),
|
||||
'The error message mentions ACLs'
|
||||
);
|
||||
export async function expectError(assert, title) {
|
||||
assert.equal(
|
||||
find('[data-test-job-error-title]').textContent,
|
||||
title,
|
||||
'Appropriate error is shown'
|
||||
);
|
||||
assert.ok(
|
||||
find('[data-test-job-error-body]').textContent.includes('ACL'),
|
||||
'The error message mentions ACLs'
|
||||
);
|
||||
|
||||
click('[data-test-job-error-close]');
|
||||
assert.notOk(find('[data-test-job-error-title]'), 'Error message is dismissable');
|
||||
return settled();
|
||||
};
|
||||
await click('[data-test-job-error-close]');
|
||||
assert.notOk(find('[data-test-job-error-title]'), 'Error message is dismissable');
|
||||
}
|
||||
|
||||
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,19 +27,14 @@ 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', {
|
||||
id: 'service-job',
|
||||
type: 'service',
|
||||
});
|
||||
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,13 +53,9 @@ 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', {
|
||||
id: 'batch-job',
|
||||
type: 'batch',
|
||||
});
|
||||
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,139 +33,112 @@ 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));
|
||||
this.setProperties(props(parent));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/children
|
||||
job=job
|
||||
sortProperty=sortProperty
|
||||
sortDescending=sortDescending
|
||||
currentPage=currentPage
|
||||
gotoJob=gotoJob}}
|
||||
`);
|
||||
await render(hbs`
|
||||
{{job-page/parts/children
|
||||
job=job
|
||||
sortProperty=sortProperty
|
||||
sortDescending=sortDescending
|
||||
currentPage=currentPage
|
||||
gotoJob=gotoJob}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
assert.equal(
|
||||
findAll('[data-test-job-name]').length,
|
||||
parent.get('children.length'),
|
||||
'A row for each child'
|
||||
);
|
||||
});
|
||||
});
|
||||
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));
|
||||
this.setProperties(props(parent));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/children
|
||||
job=job
|
||||
sortProperty=sortProperty
|
||||
sortDescending=sortDescending
|
||||
currentPage=currentPage
|
||||
gotoJob=gotoJob}}
|
||||
`);
|
||||
await render(hbs`
|
||||
{{job-page/parts/children
|
||||
job=job
|
||||
sortProperty=sortProperty
|
||||
sortDescending=sortDescending
|
||||
currentPage=currentPage
|
||||
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');
|
||||
assert.ok(find('.pagination-next'), 'Next button is rendered');
|
||||
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');
|
||||
assert.ok(find('.pagination-next'), 'Next button is rendered');
|
||||
|
||||
assert.ok(
|
||||
new RegExp(`1.10.+?${childrenCount}`).test(find('.pagination-numbers').textContent.trim())
|
||||
);
|
||||
});
|
||||
});
|
||||
assert.ok(
|
||||
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));
|
||||
this.setProperties(props(parent));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/children
|
||||
job=job
|
||||
sortProperty=sortProperty
|
||||
sortDescending=sortDescending
|
||||
currentPage=currentPage
|
||||
gotoJob=gotoJob}}
|
||||
`);
|
||||
await render(hbs`
|
||||
{{job-page/parts/children
|
||||
job=job
|
||||
sortProperty=sortProperty
|
||||
sortDescending=sortDescending
|
||||
currentPage=currentPage
|
||||
gotoJob=gotoJob}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
const sortedChildren = parent.get('children').sortBy('name');
|
||||
const childRows = findAll('[data-test-job-name]');
|
||||
const sortedChildren = parent.get('children').sortBy('name');
|
||||
const childRows = findAll('[data-test-job-name]');
|
||||
|
||||
sortedChildren.reverse().forEach((child, index) => {
|
||||
assert.equal(
|
||||
childRows[index].textContent.trim(),
|
||||
child.get('name'),
|
||||
`Child ${index} is ${child.get('name')}`
|
||||
);
|
||||
});
|
||||
sortedChildren.reverse().forEach((child, index) => {
|
||||
assert.equal(
|
||||
childRows[index].textContent.trim(),
|
||||
child.get('name'),
|
||||
`Child ${index} is ${child.get('name')}`
|
||||
);
|
||||
});
|
||||
|
||||
this.set('sortDescending', false);
|
||||
await this.set('sortDescending', false);
|
||||
|
||||
sortedChildren.forEach((child, index) => {
|
||||
assert.equal(
|
||||
childRows[index].textContent.trim(),
|
||||
child.get('name'),
|
||||
`Child ${index} is ${child.get('name')}`
|
||||
);
|
||||
});
|
||||
|
||||
return settled();
|
||||
});
|
||||
sortedChildren.forEach((child, index) => {
|
||||
assert.equal(
|
||||
childRows[index].textContent.trim(),
|
||||
child.get('name'),
|
||||
`Child ${index} is ${child.get('name')}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
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,35 +147,30 @@ 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, {
|
||||
gotoJob: gotoJobSpy,
|
||||
})
|
||||
);
|
||||
this.setProperties(
|
||||
props(parent, {
|
||||
gotoJob: gotoJobSpy,
|
||||
})
|
||||
);
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/children
|
||||
job=job
|
||||
sortProperty=sortProperty
|
||||
sortDescending=sortDescending
|
||||
currentPage=currentPage
|
||||
gotoJob=gotoJob}}
|
||||
`);
|
||||
await render(hbs`
|
||||
{{job-page/parts/children
|
||||
job=job
|
||||
sortProperty=sortProperty
|
||||
sortDescending=sortDescending
|
||||
currentPage=currentPage
|
||||
gotoJob=gotoJob}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
click('tr.job-row');
|
||||
assert.ok(
|
||||
gotoJobSpy.withArgs(parent.get('children.firstObject')).calledOnce,
|
||||
'Clicking the job row calls the gotoJob action'
|
||||
);
|
||||
});
|
||||
});
|
||||
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,182 +22,156 @@ 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}})
|
||||
`);
|
||||
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');
|
||||
});
|
||||
});
|
||||
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}}
|
||||
`);
|
||||
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(
|
||||
find('[data-test-active-deployment]').classList.contains('is-info'),
|
||||
'Running deployment gets the is-info class'
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-active-deployment-stat="id"]').textContent.trim(),
|
||||
deployment.get('shortId'),
|
||||
'The active deployment is the most recent running deployment'
|
||||
);
|
||||
assert.ok(find('[data-test-active-deployment]'), 'Active deployment');
|
||||
assert.ok(
|
||||
find('[data-test-active-deployment]').classList.contains('is-info'),
|
||||
'Running deployment gets the is-info class'
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-active-deployment-stat="id"]').textContent.trim(),
|
||||
deployment.get('shortId'),
|
||||
'The active deployment is the most recent running deployment'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('[data-test-active-deployment-stat="submit-time"]').textContent.trim(),
|
||||
moment(version.get('submitTime')).fromNow(),
|
||||
'Time since the job was submitted is in the active deployment header'
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-active-deployment-stat="submit-time"]').textContent.trim(),
|
||||
moment(version.get('submitTime')).fromNow(),
|
||||
'Time since the job was submitted is in the active deployment header'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('[data-test-deployment-metric="canaries"]').textContent.trim(),
|
||||
`${deployment.get('placedCanaries')} / ${deployment.get('desiredCanaries')}`,
|
||||
'Canaries, both places and desired, are in the metrics'
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-deployment-metric="canaries"]').textContent.trim(),
|
||||
`${deployment.get('placedCanaries')} / ${deployment.get('desiredCanaries')}`,
|
||||
'Canaries, both places and desired, are in the metrics'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('[data-test-deployment-metric="placed"]').textContent.trim(),
|
||||
deployment.get('placedAllocs'),
|
||||
'Placed allocs aggregates across task groups'
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-deployment-metric="placed"]').textContent.trim(),
|
||||
deployment.get('placedAllocs'),
|
||||
'Placed allocs aggregates across task groups'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('[data-test-deployment-metric="desired"]').textContent.trim(),
|
||||
deployment.get('desiredTotal'),
|
||||
'Desired allocs aggregates across task groups'
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-deployment-metric="desired"]').textContent.trim(),
|
||||
deployment.get('desiredTotal'),
|
||||
'Desired allocs aggregates across task groups'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('[data-test-deployment-metric="healthy"]').textContent.trim(),
|
||||
deployment.get('healthyAllocs'),
|
||||
'Healthy allocs aggregates across task groups'
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-deployment-metric="healthy"]').textContent.trim(),
|
||||
deployment.get('healthyAllocs'),
|
||||
'Healthy allocs aggregates across task groups'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('[data-test-deployment-metric="unhealthy"]').textContent.trim(),
|
||||
deployment.get('unhealthyAllocs'),
|
||||
'Unhealthy allocs aggregates across task groups'
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-deployment-metric="unhealthy"]').textContent.trim(),
|
||||
deployment.get('unhealthyAllocs'),
|
||||
'Unhealthy allocs aggregates across task groups'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('[data-test-deployment-notification]').textContent.trim(),
|
||||
deployment.get('statusDescription'),
|
||||
'Status description is in the metrics block'
|
||||
);
|
||||
});
|
||||
});
|
||||
assert.equal(
|
||||
find('[data-test-deployment-notification]').textContent.trim(),
|
||||
deployment.get('statusDescription'),
|
||||
'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}}
|
||||
`);
|
||||
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'
|
||||
);
|
||||
});
|
||||
});
|
||||
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}}
|
||||
`);
|
||||
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');
|
||||
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');
|
||||
});
|
||||
});
|
||||
});
|
||||
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');
|
||||
const job = this.store.peekAll('job').get('firstObject');
|
||||
|
||||
this.set('job', job);
|
||||
await render(hbs`
|
||||
{{job-page/parts/latest-deployment job=job}}
|
||||
`);
|
||||
this.set('job', job);
|
||||
await render(hbs`
|
||||
{{job-page/parts/latest-deployment job=job}}
|
||||
`);
|
||||
|
||||
return settled()
|
||||
.then(() => {
|
||||
click('[data-test-deployment-toggle-details]');
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
const task = job.get('runningDeployment.taskGroupSummaries.firstObject');
|
||||
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(),
|
||||
moment(task.get('requireProgressBy')).format("MMM DD, 'YY HH:mm:ss ZZ")
|
||||
);
|
||||
});
|
||||
});
|
||||
await click('[data-test-deployment-toggle-details]');
|
||||
|
||||
const task = job.get('runningDeployment.taskGroupSummaries.firstObject');
|
||||
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(),
|
||||
moment(task.get('requireProgressBy')).format("MMM DD, 'YY HH:mm:ss ZZ")
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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,69 +21,58 @@ 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();
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/placement-failures job=job}})
|
||||
`);
|
||||
this.set('job', job);
|
||||
|
||||
return settled().then(() => {
|
||||
const failedEvaluation = this.get('job.evaluations')
|
||||
.filterBy('hasPlacementFailures')
|
||||
.sortBy('modifyIndex')
|
||||
.reverse()
|
||||
.get('firstObject');
|
||||
const failedTGAllocs = failedEvaluation.get('failedTGAllocs');
|
||||
await render(hbs`
|
||||
{{job-page/parts/placement-failures job=job}})
|
||||
`);
|
||||
|
||||
assert.ok(find('[data-test-placement-failures]'), 'Placement failures section found');
|
||||
const failedEvaluation = this.get('job.evaluations')
|
||||
.filterBy('hasPlacementFailures')
|
||||
.sortBy('modifyIndex')
|
||||
.reverse()
|
||||
.get('firstObject');
|
||||
const failedTGAllocs = failedEvaluation.get('failedTGAllocs');
|
||||
|
||||
const taskGroupLabels = findAll('[data-test-placement-failure-task-group]').map(title =>
|
||||
title.textContent.trim()
|
||||
);
|
||||
assert.ok(find('[data-test-placement-failures]'), 'Placement failures section found');
|
||||
|
||||
failedTGAllocs.forEach(alloc => {
|
||||
const name = alloc.get('name');
|
||||
assert.ok(
|
||||
taskGroupLabels.find(label => label.includes(name)),
|
||||
`${name} included in placement failures list`
|
||||
);
|
||||
assert.ok(
|
||||
taskGroupLabels.find(label => label.includes(alloc.get('coalescedFailures') + 1)),
|
||||
'The number of unplaced allocs = CoalescedFailures + 1'
|
||||
);
|
||||
});
|
||||
});
|
||||
const taskGroupLabels = findAll('[data-test-placement-failure-task-group]').map(title =>
|
||||
title.textContent.trim()
|
||||
);
|
||||
|
||||
failedTGAllocs.forEach(alloc => {
|
||||
const name = alloc.get('name');
|
||||
assert.ok(
|
||||
taskGroupLabels.find(label => label.includes(name)),
|
||||
`${name} included in placement failures list`
|
||||
);
|
||||
assert.ok(
|
||||
taskGroupLabels.find(label => label.includes(alloc.get('coalescedFailures') + 1)),
|
||||
'The number of unplaced allocs = CoalescedFailures + 1'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
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();
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/placement-failures job=job}})
|
||||
`);
|
||||
this.set('job', job);
|
||||
|
||||
return settled().then(() => {
|
||||
assert.notOk(
|
||||
find('[data-test-placement-failures]'),
|
||||
'Placement failures section not found'
|
||||
);
|
||||
});
|
||||
});
|
||||
await render(hbs`
|
||||
{{job-page/parts/placement-failures job=job}})
|
||||
`);
|
||||
|
||||
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,262 +21,214 @@ 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'));
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/summary job=job}}
|
||||
`);
|
||||
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');
|
||||
});
|
||||
});
|
||||
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'));
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/summary job=job}}
|
||||
`);
|
||||
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');
|
||||
});
|
||||
});
|
||||
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'));
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/summary job=job}}
|
||||
`);
|
||||
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'),
|
||||
`${this.get('job.queuedAllocs')} are queued`
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-legend-value="queued"]').textContent,
|
||||
this.get('job.queuedAllocs'),
|
||||
`${this.get('job.queuedAllocs')} are queued`
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('[data-test-legend-value="starting"]').textContent,
|
||||
this.get('job.startingAllocs'),
|
||||
`${this.get('job.startingAllocs')} are starting`
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-legend-value="starting"]').textContent,
|
||||
this.get('job.startingAllocs'),
|
||||
`${this.get('job.startingAllocs')} are starting`
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('[data-test-legend-value="running"]').textContent,
|
||||
this.get('job.runningAllocs'),
|
||||
`${this.get('job.runningAllocs')} are running`
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-legend-value="running"]').textContent,
|
||||
this.get('job.runningAllocs'),
|
||||
`${this.get('job.runningAllocs')} are running`
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('[data-test-legend-value="complete"]').textContent,
|
||||
this.get('job.completeAllocs'),
|
||||
`${this.get('job.completeAllocs')} are complete`
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-legend-value="complete"]').textContent,
|
||||
this.get('job.completeAllocs'),
|
||||
`${this.get('job.completeAllocs')} are complete`
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('[data-test-legend-value="failed"]').textContent,
|
||||
this.get('job.failedAllocs'),
|
||||
`${this.get('job.failedAllocs')} are failed`
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-legend-value="failed"]').textContent,
|
||||
this.get('job.failedAllocs'),
|
||||
`${this.get('job.failedAllocs')} are failed`
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('[data-test-legend-value="lost"]').textContent,
|
||||
this.get('job.lostAllocs'),
|
||||
`${this.get('job.lostAllocs')} are lost`
|
||||
);
|
||||
});
|
||||
});
|
||||
assert.equal(
|
||||
find('[data-test-legend-value="lost"]').textContent,
|
||||
this.get('job.lostAllocs'),
|
||||
`${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'));
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/summary job=job}}
|
||||
`);
|
||||
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'),
|
||||
`${this.get('job.pendingChildren')} are pending`
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-legend-value="queued"]').textContent,
|
||||
this.get('job.pendingChildren'),
|
||||
`${this.get('job.pendingChildren')} are pending`
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('[data-test-legend-value="running"]').textContent,
|
||||
this.get('job.runningChildren'),
|
||||
`${this.get('job.runningChildren')} are running`
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-legend-value="running"]').textContent,
|
||||
this.get('job.runningChildren'),
|
||||
`${this.get('job.runningChildren')} are running`
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('[data-test-legend-value="complete"]').textContent,
|
||||
this.get('job.deadChildren'),
|
||||
`${this.get('job.deadChildren')} are dead`
|
||||
);
|
||||
});
|
||||
});
|
||||
assert.equal(
|
||||
find('[data-test-legend-value="complete"]').textContent,
|
||||
this.get('job.deadChildren'),
|
||||
`${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'));
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/summary job=job}}
|
||||
`);
|
||||
await render(hbs`
|
||||
{{job-page/parts/summary job=job}}
|
||||
`);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
click('[data-test-accordion-toggle]');
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
assert.notOk(find('[data-test-accordion-body]'), 'No accordion body');
|
||||
assert.notOk(find('[data-test-legend]'), 'No legend');
|
||||
});
|
||||
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}}
|
||||
`);
|
||||
await render(hbs`
|
||||
{{job-page/parts/summary job=job}}
|
||||
`);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
click('[data-test-accordion-toggle]');
|
||||
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'
|
||||
);
|
||||
});
|
||||
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'));
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/summary job=job}}
|
||||
`);
|
||||
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(() => {
|
||||
assert.equal(
|
||||
window.localStorage.nomadExpandJobSummary,
|
||||
'false',
|
||||
'Value is stored for the collapsed state'
|
||||
);
|
||||
});
|
||||
assert.notOk(window.localStorage.nomadExpandJobSummary, 'No value in localStorage yet');
|
||||
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'));
|
||||
this.set('job', this.store.peekAll('job').get('firstObject'));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/summary job=job}}
|
||||
`);
|
||||
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'
|
||||
);
|
||||
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(() => {
|
||||
assert.equal(
|
||||
window.localStorage.nomadExpandJobSummary,
|
||||
'true',
|
||||
'localStorage value still toggles'
|
||||
);
|
||||
assert.ok(find('[data-test-accordion-body]'), 'Summary still expands');
|
||||
});
|
||||
await click('[data-test-accordion-toggle]');
|
||||
|
||||
assert.equal(
|
||||
window.localStorage.nomadExpandJobSummary,
|
||||
'true',
|
||||
'localStorage value still toggles'
|
||||
);
|
||||
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,135 +31,123 @@ 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));
|
||||
const job = this.store.peekAll('job').get('firstObject');
|
||||
this.setProperties(props(job));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/task-groups
|
||||
job=job
|
||||
sortProperty=sortProperty
|
||||
sortDescending=sortDescending
|
||||
gotoTaskGroup=gotoTaskGroup}}
|
||||
`);
|
||||
await this.render(hbs`
|
||||
{{job-page/parts/task-groups
|
||||
job=job
|
||||
sortProperty=sortProperty
|
||||
sortDescending=sortDescending
|
||||
gotoTaskGroup=gotoTaskGroup}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
assert.equal(
|
||||
findAll('[data-test-task-group]').length,
|
||||
job.get('taskGroups.length'),
|
||||
'One row per task group'
|
||||
);
|
||||
});
|
||||
});
|
||||
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')
|
||||
.sortBy('name')
|
||||
.reverse()
|
||||
.get('firstObject');
|
||||
const taskGroups = await job.get('taskGroups');
|
||||
const taskGroup = taskGroups
|
||||
.sortBy('name')
|
||||
.reverse()
|
||||
.get('firstObject');
|
||||
|
||||
this.setProperties(props(job));
|
||||
this.setProperties(props(job));
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/task-groups
|
||||
job=job
|
||||
sortProperty=sortProperty
|
||||
sortDescending=sortDescending
|
||||
gotoTaskGroup=gotoTaskGroup}}
|
||||
`);
|
||||
await this.render(hbs`
|
||||
{{job-page/parts/task-groups
|
||||
job=job
|
||||
sortProperty=sortProperty
|
||||
sortDescending=sortDescending
|
||||
gotoTaskGroup=gotoTaskGroup}}
|
||||
`);
|
||||
|
||||
return settled().then(() => {
|
||||
const taskGroupRow = find('[data-test-task-group]');
|
||||
const taskGroupRow = find('[data-test-task-group]');
|
||||
|
||||
assert.equal(
|
||||
taskGroupRow.querySelector('[data-test-task-group-name]').textContent.trim(),
|
||||
taskGroup.get('name'),
|
||||
'Name'
|
||||
);
|
||||
assert.equal(
|
||||
taskGroupRow.querySelector('[data-test-task-group-count]').textContent.trim(),
|
||||
taskGroup.get('count'),
|
||||
'Count'
|
||||
);
|
||||
assert.equal(
|
||||
taskGroupRow.querySelector('[data-test-task-group-cpu]').textContent.trim(),
|
||||
`${taskGroup.get('reservedCPU')} MHz`,
|
||||
'Reserved CPU'
|
||||
);
|
||||
assert.equal(
|
||||
taskGroupRow.querySelector('[data-test-task-group-mem]').textContent.trim(),
|
||||
`${taskGroup.get('reservedMemory')} MiB`,
|
||||
'Reserved Memory'
|
||||
);
|
||||
assert.equal(
|
||||
taskGroupRow.querySelector('[data-test-task-group-disk]').textContent.trim(),
|
||||
`${taskGroup.get('reservedEphemeralDisk')} MiB`,
|
||||
'Reserved Disk'
|
||||
);
|
||||
});
|
||||
});
|
||||
assert.equal(
|
||||
taskGroupRow.querySelector('[data-test-task-group-name]').textContent.trim(),
|
||||
taskGroup.get('name'),
|
||||
'Name'
|
||||
);
|
||||
assert.equal(
|
||||
taskGroupRow.querySelector('[data-test-task-group-count]').textContent.trim(),
|
||||
taskGroup.get('count'),
|
||||
'Count'
|
||||
);
|
||||
assert.equal(
|
||||
taskGroupRow.querySelector('[data-test-task-group-cpu]').textContent.trim(),
|
||||
`${taskGroup.get('reservedCPU')} MHz`,
|
||||
'Reserved CPU'
|
||||
);
|
||||
assert.equal(
|
||||
taskGroupRow.querySelector('[data-test-task-group-mem]').textContent.trim(),
|
||||
`${taskGroup.get('reservedMemory')} MiB`,
|
||||
'Reserved Memory'
|
||||
);
|
||||
assert.equal(
|
||||
taskGroupRow.querySelector('[data-test-task-group-disk]').textContent.trim(),
|
||||
`${taskGroup.get('reservedEphemeralDisk')} MiB`,
|
||||
'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')
|
||||
.sortBy('name')
|
||||
.reverse()
|
||||
.get('firstObject');
|
||||
const taskGroupSpy = sinon.spy();
|
||||
|
||||
this.setProperties(
|
||||
props(job, {
|
||||
gotoTaskGroup: taskGroupSpy,
|
||||
})
|
||||
);
|
||||
const taskGroups = await job.get('taskGroups');
|
||||
const taskGroup = taskGroups
|
||||
.sortBy('name')
|
||||
.reverse()
|
||||
.get('firstObject');
|
||||
|
||||
await render(hbs`
|
||||
{{job-page/parts/task-groups
|
||||
job=job
|
||||
sortProperty=sortProperty
|
||||
sortDescending=sortDescending
|
||||
gotoTaskGroup=gotoTaskGroup}}
|
||||
`);
|
||||
this.setProperties(
|
||||
props(job, {
|
||||
gotoTaskGroup: taskGroupSpy,
|
||||
})
|
||||
);
|
||||
|
||||
return settled().then(() => {
|
||||
click('[data-test-task-group]');
|
||||
assert.ok(
|
||||
taskGroupSpy.withArgs(taskGroup).calledOnce,
|
||||
'Clicking the task group row calls the gotoTaskGroup action'
|
||||
);
|
||||
});
|
||||
});
|
||||
await this.render(hbs`
|
||||
{{job-page/parts/task-groups
|
||||
job=job
|
||||
sortProperty=sortProperty
|
||||
sortDescending=sortDescending
|
||||
gotoTaskGroup=gotoTaskGroup}}
|
||||
`);
|
||||
|
||||
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,42 +53,36 @@ 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');
|
||||
const job = this.store.peekAll('job').findBy('plainId', 'parent');
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
this.setProperties(commonProperties(job));
|
||||
await this.render(commonTemplate);
|
||||
|
||||
return settled().then(() => {
|
||||
const currentJobCount = server.db.jobs.length;
|
||||
const currentJobCount = server.db.jobs.length;
|
||||
|
||||
assert.equal(
|
||||
findAll('[data-test-job-name]').length,
|
||||
childrenCount,
|
||||
'The new periodic job launch is in the children list'
|
||||
);
|
||||
assert.equal(
|
||||
findAll('[data-test-job-name]').length,
|
||||
childrenCount,
|
||||
'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');
|
||||
const expectedURL = jobURL(job, '/periodic/force');
|
||||
|
||||
assert.ok(
|
||||
this.server.pretender.handledRequests
|
||||
.filterBy('method', 'POST')
|
||||
.find(req => req.url === expectedURL),
|
||||
'POST URL was correct'
|
||||
);
|
||||
assert.ok(
|
||||
this.server.pretender.handledRequests
|
||||
.filterBy('method', 'POST')
|
||||
.find(req => req.url === expectedURL),
|
||||
'POST URL was correct'
|
||||
);
|
||||
|
||||
assert.equal(server.db.jobs.length, currentJobCount + 1, 'POST request was made');
|
||||
});
|
||||
});
|
||||
});
|
||||
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,39 +92,33 @@ 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');
|
||||
const job = this.store.peekAll('job').findBy('plainId', 'parent');
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
this.setProperties(commonProperties(job));
|
||||
await this.render(commonTemplate);
|
||||
|
||||
return settled().then(() => {
|
||||
assert.notOk(find('[data-test-job-error-title]'), 'No error message yet');
|
||||
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',
|
||||
'Appropriate error is shown'
|
||||
);
|
||||
assert.ok(
|
||||
find('[data-test-job-error-body]').textContent.includes('ACL'),
|
||||
'The error message mentions ACLs'
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-job-error-title]').textContent,
|
||||
'Could Not Force Launch',
|
||||
'Appropriate error is shown'
|
||||
);
|
||||
assert.ok(
|
||||
find('[data-test-job-error-body]').textContent.includes('ACL'),
|
||||
'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');
|
||||
});
|
||||
});
|
||||
});
|
||||
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);
|
||||
job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
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);
|
||||
const job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
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);
|
||||
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);
|
||||
const job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
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,228 +56,166 @@ 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);
|
||||
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);
|
||||
const job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
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);
|
||||
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);
|
||||
const job = this.store.peekAll('job').findBy('plainId', mirageJob.id);
|
||||
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
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);
|
||||
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);
|
||||
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');
|
||||
});
|
||||
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);
|
||||
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`
|
||||
);
|
||||
});
|
||||
});
|
||||
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);
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
assert.ok(
|
||||
Job.recentAllocationsEmptyState.headline.includes('No Allocations'),
|
||||
'No allocations empty message'
|
||||
);
|
||||
});
|
||||
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);
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
click('[data-test-promote-canary]');
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
const requests = this.server.pretender.handledRequests;
|
||||
assert.ok(
|
||||
requests
|
||||
.filterBy('method', 'POST')
|
||||
.findBy('url', `/v1/deployment/promote/${deployment.get('id')}`),
|
||||
'A promote POST request was made'
|
||||
);
|
||||
});
|
||||
await click('[data-test-promote-canary]');
|
||||
|
||||
const requests = this.server.pretender.handledRequests;
|
||||
|
||||
assert.ok(
|
||||
requests
|
||||
.filterBy('method', 'POST')
|
||||
.findBy('url', `/v1/deployment/promote/${deployment.get('id')}`),
|
||||
'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);
|
||||
this.setProperties(commonProperties(job));
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
click('[data-test-promote-canary]');
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
assert.equal(
|
||||
find('[data-test-job-error-title]').textContent,
|
||||
'Could Not Promote Deployment',
|
||||
'Appropriate error is shown'
|
||||
);
|
||||
assert.ok(
|
||||
find('[data-test-job-error-body]').textContent.includes('ACL'),
|
||||
'The error message mentions ACLs'
|
||||
);
|
||||
await click('[data-test-promote-canary]');
|
||||
|
||||
click('[data-test-job-error-close]');
|
||||
assert.notOk(find('[data-test-job-error-title]'), 'Error message is dismissable');
|
||||
return settled();
|
||||
});
|
||||
assert.equal(
|
||||
find('[data-test-job-error-title]').textContent,
|
||||
'Could Not Promote Deployment',
|
||||
'Appropriate error is shown'
|
||||
);
|
||||
assert.ok(
|
||||
find('[data-test-job-error-body]').textContent.includes('ACL'),
|
||||
'The error message mentions ACLs'
|
||||
);
|
||||
|
||||
await click('[data-test-job-error-close]');
|
||||
|
||||
assert.notOk(find('[data-test-job-error-title]'), 'Error message is dismissable');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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,17 +54,12 @@ 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]');
|
||||
|
||||
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');
|
||||
});
|
||||
await assert.ok(find('[data-test-dropdown-options]'), 'Options are shown now');
|
||||
await click('[data-test-dropdown-trigger]');
|
||||
|
||||
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) {
|
||||
|
@ -73,19 +67,17 @@ 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]');
|
||||
|
||||
return settled().then(() => {
|
||||
assert.equal(
|
||||
findAll('[data-test-dropdown-option]').length,
|
||||
props.options.length,
|
||||
'All options are shown'
|
||||
);
|
||||
findAll('[data-test-dropdown-option]').forEach((optionEl, index) => {
|
||||
const label = props.options[index].label;
|
||||
assert.equal(optionEl.textContent.trim(), label, `Correct label for ${label}`);
|
||||
assert.ok(optionEl.querySelector('input[type="checkbox"]'), 'Option contains a checkbox');
|
||||
});
|
||||
assert.equal(
|
||||
findAll('[data-test-dropdown-option]').length,
|
||||
props.options.length,
|
||||
'All options are shown'
|
||||
);
|
||||
findAll('[data-test-dropdown-option]').forEach((optionEl, index) => {
|
||||
const label = props.options[index].label;
|
||||
assert.equal(optionEl.textContent.trim(), label, `Correct label for ${label}`);
|
||||
assert.ok(optionEl.querySelector('input[type="checkbox"]'), 'Option contains a checkbox');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -94,22 +86,16 @@ 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 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(
|
||||
newSelection,
|
||||
[props.options[0].key],
|
||||
'onSelect was called with the first option key'
|
||||
);
|
||||
});
|
||||
assert.ok(props.onSelect.called, 'onSelect was called');
|
||||
const newSelection = props.onSelect.getCall(0).args[0];
|
||||
assert.deepEqual(
|
||||
newSelection,
|
||||
[props.options[0].key],
|
||||
'onSelect was called with the first option key'
|
||||
);
|
||||
});
|
||||
|
||||
test('the component trigger shows the selection count when there is a selection', async function(assert) {
|
||||
|
@ -118,21 +104,22 @@ 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'
|
||||
);
|
||||
});
|
||||
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) {
|
||||
|
@ -140,9 +127,9 @@ module('Integration | Component | multi-select dropdown', function(hooks) {
|
|||
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');
|
||||
});
|
||||
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]');
|
||||
|
||||
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'
|
||||
);
|
||||
});
|
||||
assert.ok(find('[data-test-gutter-menu]').classList.contains('is-open'), 'Gutter menu is open');
|
||||
await click('[data-test-gutter-gutter-toggle]');
|
||||
|
||||
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]');
|
||||
|
||||
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'
|
||||
);
|
||||
});
|
||||
assert.ok(find('[data-test-gutter-menu]').classList.contains('is-open'), 'Gutter menu is open');
|
||||
await click('[data-test-gutter-backdrop]');
|
||||
|
||||
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,144 +56,107 @@ 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 });
|
||||
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');
|
||||
});
|
||||
await render(commonTemplate);
|
||||
|
||||
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');
|
||||
this.setProperties({ resource, metric });
|
||||
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'
|
||||
);
|
||||
});
|
||||
await render(commonTemplate);
|
||||
|
||||
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');
|
||||
this.setProperties({ resource, metric });
|
||||
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'
|
||||
);
|
||||
});
|
||||
await render(commonTemplate);
|
||||
|
||||
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');
|
||||
this.setProperties({ resource, metric });
|
||||
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'
|
||||
);
|
||||
});
|
||||
await render(commonTemplate);
|
||||
|
||||
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');
|
||||
this.setProperties({ resource, metric });
|
||||
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');
|
||||
});
|
||||
await render(commonTemplate);
|
||||
|
||||
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');
|
||||
this.setProperties({ resource, metric, showComponent: true });
|
||||
await render(hbs`
|
||||
{{#if showComponent}}
|
||||
{{primary-metric
|
||||
resource=resource
|
||||
metric=metric}}
|
||||
}}
|
||||
{{/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');
|
||||
});
|
||||
const resource = this.store.peekAll('node').get('firstObject');
|
||||
this.setProperties({ resource, metric, showComponent: true });
|
||||
await render(hbs`
|
||||
{{#if showComponent}}
|
||||
{{primary-metric
|
||||
resource=resource
|
||||
metric=metric}}
|
||||
}}
|
||||
{{/if}}
|
||||
`);
|
||||
|
||||
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);
|
||||
|
||||
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,53 +32,46 @@ 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')
|
||||
.find(alloc => !alloc.get('nextAllocation.content'));
|
||||
const allocation = this.store
|
||||
.peekAll('allocation')
|
||||
.find(alloc => !alloc.get('nextAllocation.content'));
|
||||
|
||||
this.set('allocation', allocation);
|
||||
await render(commonTemplate);
|
||||
this.set('allocation', allocation);
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
assert.equal(
|
||||
findAll('[data-test-allocation]').length,
|
||||
attempts + 1,
|
||||
'Total allocations equals current allocation plus all past allocations'
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-allocation]'),
|
||||
find(`[data-test-allocation="${allocation.id}"]`),
|
||||
'First allocation is the current allocation'
|
||||
);
|
||||
assert.equal(
|
||||
findAll('[data-test-allocation]').length,
|
||||
attempts + 1,
|
||||
'Total allocations equals current allocation plus all past allocations'
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-allocation]'),
|
||||
find(`[data-test-allocation="${allocation.id}"]`),
|
||||
'First allocation is the current allocation'
|
||||
);
|
||||
|
||||
assert.notOk(find('[data-test-stop-warning]'), 'No stop warning');
|
||||
assert.notOk(find('[data-test-attempt-notice]'), 'No attempt notice');
|
||||
assert.notOk(find('[data-test-stop-warning]'), 'No stop warning');
|
||||
assert.notOk(find('[data-test-attempt-notice]'), 'No attempt notice');
|
||||
|
||||
assert.equal(
|
||||
find(
|
||||
`[data-test-allocation="${allocation.id}"] [data-test-allocation-link]`
|
||||
).textContent.trim(),
|
||||
allocation.get('shortId'),
|
||||
'The "this" allocation is correct'
|
||||
);
|
||||
assert.equal(
|
||||
find(
|
||||
`[data-test-allocation="${allocation.id}"] [data-test-allocation-status]`
|
||||
).textContent.trim(),
|
||||
allocation.get('clientStatus'),
|
||||
'Allocation shows the status'
|
||||
);
|
||||
});
|
||||
assert.equal(
|
||||
find(
|
||||
`[data-test-allocation="${allocation.id}"] [data-test-allocation-link]`
|
||||
).textContent.trim(),
|
||||
allocation.get('shortId'),
|
||||
'The "this" allocation is correct'
|
||||
);
|
||||
assert.equal(
|
||||
find(
|
||||
`[data-test-allocation="${allocation.id}"] [data-test-allocation-status]`
|
||||
).textContent.trim(),
|
||||
allocation.get('clientStatus'),
|
||||
'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,27 +79,20 @@ 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
|
||||
.peekAll('allocation')
|
||||
.find(alloc => !alloc.get('nextAllocation.content'));
|
||||
const allocation = this.store
|
||||
.peekAll('allocation')
|
||||
.find(alloc => !alloc.get('nextAllocation.content'));
|
||||
|
||||
this.set('allocation', allocation);
|
||||
await render(commonTemplate);
|
||||
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');
|
||||
});
|
||||
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) {
|
||||
|
@ -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,39 +136,32 @@ 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);
|
||||
this.set('allocation', allocation);
|
||||
await render(commonTemplate);
|
||||
|
||||
return settled();
|
||||
})
|
||||
.then(() => {
|
||||
assert.ok(
|
||||
find('[data-test-reschedule-label]').textContent.trim(),
|
||||
'Next Allocation',
|
||||
'The first allocation is the next allocation and labeled as such'
|
||||
);
|
||||
assert.ok(
|
||||
find('[data-test-reschedule-label]').textContent.trim(),
|
||||
'Next Allocation',
|
||||
'The first allocation is the next allocation and labeled as such'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
find('[data-test-allocation] [data-test-allocation-link]').textContent.trim(),
|
||||
allocation.get('nextAllocation.shortId'),
|
||||
'The next allocation item is for the correct allocation'
|
||||
);
|
||||
assert.equal(
|
||||
find('[data-test-allocation] [data-test-allocation-link]').textContent.trim(),
|
||||
allocation.get('nextAllocation.shortId'),
|
||||
'The next allocation item is for the correct allocation'
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
findAll('[data-test-allocation]')[1],
|
||||
find(`[data-test-allocation="${allocation.id}"]`),
|
||||
'Second allocation is the current allocation'
|
||||
);
|
||||
assert.equal(
|
||||
findAll('[data-test-allocation]')[1],
|
||||
find(`[data-test-allocation="${allocation.id}"]`),
|
||||
'Second allocation is the current allocation'
|
||||
);
|
||||
|
||||
assert.notOk(find('[data-test-stop-warning]'), 'No stop warning');
|
||||
assert.notOk(find('[data-test-attempt-notice]'), 'No attempt notice');
|
||||
});
|
||||
assert.notOk(find('[data-test-stop-warning]'), 'No stop warning');
|
||||
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,23 +52,21 @@ 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');
|
||||
assert.ok(find('[data-test-cancel-button]'), 'Cancel button is rendered');
|
||||
assert.equal(TwoStepButton.cancelText, props.cancelText, 'Button is labeled correctly');
|
||||
|
||||
assert.ok(find('[data-test-confirm-button]'), 'Confirm button is rendered');
|
||||
assert.equal(TwoStepButton.confirmText, props.confirmText, 'Button is labeled correctly');
|
||||
assert.ok(find('[data-test-confirm-button]'), 'Confirm button is rendered');
|
||||
assert.equal(TwoStepButton.confirmText, props.confirmText, 'Button is labeled correctly');
|
||||
|
||||
assert.equal(
|
||||
TwoStepButton.confirmationMessage,
|
||||
props.confirmationMessage,
|
||||
'Confirmation message is shown'
|
||||
);
|
||||
assert.equal(
|
||||
TwoStepButton.confirmationMessage,
|
||||
props.confirmationMessage,
|
||||
'Confirmation message is shown'
|
||||
);
|
||||
|
||||
assert.notOk(find('[data-test-idle-button]'), 'No more idle button');
|
||||
});
|
||||
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) {
|
||||
|
@ -77,16 +74,12 @@ module('Integration | Component | two step button', function(hooks) {
|
|||
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');
|
||||
});
|
||||
});
|
||||
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) {
|
||||
|
@ -94,16 +87,12 @@ module('Integration | Component | two step button', function(hooks) {
|
|||
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');
|
||||
});
|
||||
});
|
||||
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) {
|
||||
|
@ -112,13 +101,11 @@ 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');
|
||||
});
|
||||
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) {
|
||||
|
@ -126,13 +113,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.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