mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
* Gallery allows picking stuff * Small fixes * added sentinel templates * Can set enforcement level on policies * Working on the interactive sentinel dev mode * Very rough development flow on FE * Changed position in gutter menu * More sentinel stuff * PR cleanup: removed testmode, removed unneeded mixins and deps * Heliosification * Index-level sentinel policy deletion and page title fixes * Makes the Canaries sentinel policy real and then comments out the unfinished ones * rename Access Control to Administration in prep for moving Sentinel Policies and Node Pool admin there * Sentinel policies moved within the Administration section * Mirage fixture for sentinel policy endpoints * Description length check and 500 prevention * Sync review PR feedback addressed, implied butons on radio cards * Cull un-used sentinel policies --------- Co-authored-by: Mike Nomitch <mail@mikenomitch.com>
253 lines
9.4 KiB
JavaScript
253 lines
9.4 KiB
JavaScript
/**
|
|
* Copyright (c) HashiCorp, Inc.
|
|
* SPDX-License-Identifier: BUSL-1.1
|
|
*/
|
|
|
|
import { module, test } from 'qunit';
|
|
import {
|
|
visit,
|
|
currentURL,
|
|
click,
|
|
typeIn,
|
|
findAll,
|
|
find,
|
|
} from '@ember/test-helpers';
|
|
import { setupApplicationTest } from 'ember-qunit';
|
|
import { allScenarios } from '../../mirage/scenarios/default';
|
|
import { setupMirage } from 'ember-cli-mirage/test-support';
|
|
import percySnapshot from '@percy/ember';
|
|
import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
|
|
|
|
module('Acceptance | namespaces', function (hooks) {
|
|
setupApplicationTest(hooks);
|
|
setupMirage(hooks);
|
|
|
|
test('Namespaces index, general', async function (assert) {
|
|
assert.expect(4);
|
|
allScenarios.namespacesTestCluster(server);
|
|
window.localStorage.nomadTokenSecret = server.db.tokens[0].secretId;
|
|
await visit('/administration/namespaces');
|
|
assert.dom('[data-test-gutter-link="administration"]').exists();
|
|
assert.equal(currentURL(), '/administration/namespaces');
|
|
assert
|
|
.dom('[data-test-namespace-row]')
|
|
.exists({ count: server.db.namespaces.length });
|
|
await a11yAudit(assert);
|
|
await percySnapshot(assert);
|
|
// Reset Token
|
|
window.localStorage.nomadTokenSecret = null;
|
|
});
|
|
|
|
test('Prevents namespaes access if you lack a management token', async function (assert) {
|
|
allScenarios.namespacesTestCluster(server);
|
|
window.localStorage.nomadTokenSecret = server.db.tokens[1].secretId;
|
|
await visit('/administration/namespaces');
|
|
assert.equal(currentURL(), '/jobs');
|
|
assert.dom('[data-test-gutter-link="administration"]').doesNotExist();
|
|
// Reset Token
|
|
window.localStorage.nomadTokenSecret = null;
|
|
});
|
|
|
|
test('Creating a new namespace', async function (assert) {
|
|
assert.expect(7);
|
|
allScenarios.namespacesTestCluster(server);
|
|
window.localStorage.nomadTokenSecret = server.db.tokens[0].secretId;
|
|
await visit('/administration/namespaces');
|
|
await click('[data-test-create-namespace]');
|
|
assert.equal(currentURL(), '/administration/namespaces/new');
|
|
await typeIn('[data-test-namespace-name-input]', 'My New Namespace');
|
|
await click('button[data-test-save-namespace]');
|
|
assert
|
|
.dom('.flash-message.alert-critical')
|
|
.exists('Doesnt let you save a bad name');
|
|
assert.equal(currentURL(), '/administration/namespaces/new');
|
|
document.querySelector('[data-test-namespace-name-input]').value = ''; // clear
|
|
await typeIn('[data-test-namespace-name-input]', 'My-New-Namespace');
|
|
await click('button[data-test-save-namespace]');
|
|
assert.dom('.flash-message.alert-success').exists();
|
|
|
|
assert.equal(
|
|
currentURL(),
|
|
'/administration/namespaces/My-New-Namespace',
|
|
'redirected to the now-created namespace'
|
|
);
|
|
await visit('/administration/namespaces');
|
|
const newNs = [...findAll('[data-test-namespace-name]')].filter((a) =>
|
|
a.textContent.includes('My-New-Namespace')
|
|
)[0];
|
|
assert.ok(newNs, 'Namespace is in the list');
|
|
await click(newNs);
|
|
assert.equal(currentURL(), '/administration/namespaces/My-New-Namespace');
|
|
await percySnapshot(assert);
|
|
// Reset Token
|
|
window.localStorage.nomadTokenSecret = null;
|
|
});
|
|
|
|
test('New namespaces have quotas and node_pool properties if Ent', async function (assert) {
|
|
assert.expect(2);
|
|
allScenarios.namespacesTestCluster(server, { enterprise: true });
|
|
window.localStorage.nomadTokenSecret = server.db.tokens[0].secretId;
|
|
await visit('/administration/namespaces');
|
|
await click('[data-test-create-namespace]');
|
|
|
|
// Get the dom node text for the description
|
|
const descriptionText = document.querySelector(
|
|
'[data-test-namespace-editor]'
|
|
).textContent;
|
|
|
|
assert.ok(
|
|
descriptionText.includes('Quota'),
|
|
'Includes Quotas in namespace description'
|
|
);
|
|
assert.ok(
|
|
descriptionText.includes(
|
|
'NodePoolConfiguration',
|
|
'Includes NodePoolConfiguration in namespace description'
|
|
)
|
|
);
|
|
|
|
// Reset Token
|
|
window.localStorage.nomadTokenSecret = null;
|
|
});
|
|
|
|
test('New namespaces hide quotas and node_pool properties if CE', async function (assert) {
|
|
assert.expect(2);
|
|
allScenarios.namespacesTestCluster(server, { enterprise: false });
|
|
window.localStorage.nomadTokenSecret = server.db.tokens[0].secretId;
|
|
await visit('/administration/namespaces');
|
|
await click('[data-test-create-namespace]');
|
|
|
|
// Get the dom node text for the description
|
|
const descriptionText = document.querySelector(
|
|
'[data-test-namespace-editor]'
|
|
).textContent;
|
|
|
|
assert.notOk(descriptionText.includes('Quotas'));
|
|
assert.notOk(descriptionText.includes('NodePoolConfiguration'));
|
|
|
|
// Reset Token
|
|
window.localStorage.nomadTokenSecret = null;
|
|
});
|
|
|
|
test('Modifying an existing namespace', async function (assert) {
|
|
allScenarios.namespacesTestCluster(server);
|
|
window.localStorage.nomadTokenSecret = server.db.tokens[0].secretId;
|
|
await visit('/administration/namespaces');
|
|
await click('[data-test-namespace-row]:first-child a');
|
|
// Table sorts by name by default
|
|
let firstNamespace = server.db.namespaces.sort((a, b) => {
|
|
return a.name.localeCompare(b.name);
|
|
})[0];
|
|
assert.equal(
|
|
currentURL(),
|
|
`/administration/namespaces/${firstNamespace.name}`
|
|
);
|
|
assert.dom('[data-test-namespace-editor]').exists();
|
|
assert.dom('[data-test-title]').includesText(firstNamespace.name);
|
|
await click('button[data-test-save-namespace]');
|
|
assert.dom('.flash-message.alert-success').exists();
|
|
assert.equal(
|
|
currentURL(),
|
|
`/administration/namespaces/${firstNamespace.name}`,
|
|
'remain on page after save'
|
|
);
|
|
// Reset Token
|
|
window.localStorage.nomadTokenSecret = null;
|
|
});
|
|
|
|
test('Deleting a namespace', async function (assert) {
|
|
assert.expect(11);
|
|
allScenarios.namespacesTestCluster(server);
|
|
window.localStorage.nomadTokenSecret = server.db.tokens[0].secretId;
|
|
await visit('/administration/namespaces');
|
|
|
|
// Default namespace hides delete button
|
|
const defaultNamespaceLink = [
|
|
...findAll('[data-test-namespace-name]'),
|
|
].filter((row) => row.textContent.includes('default'))[0];
|
|
await click(defaultNamespaceLink);
|
|
|
|
assert.equal(currentURL(), `/administration/namespaces/default`);
|
|
let deleteButton = find('[data-test-delete-namespace] button');
|
|
assert
|
|
.dom(deleteButton)
|
|
.doesNotExist('delete button is not present for default');
|
|
|
|
// Standard namespace properly deletes
|
|
await visit('/administration/namespaces');
|
|
|
|
let nonDefaultNamespace = server.db.namespaces.findBy(
|
|
(ns) => ns.name != 'default'
|
|
);
|
|
const nonDefaultNsLink = [...findAll('[data-test-namespace-name]')].filter(
|
|
(row) => row.textContent.includes(nonDefaultNamespace.name)
|
|
)[0];
|
|
await click(nonDefaultNsLink);
|
|
assert.equal(
|
|
currentURL(),
|
|
`/administration/namespaces/${nonDefaultNamespace.name}`
|
|
);
|
|
deleteButton = find('[data-test-delete-namespace] button');
|
|
assert.dom(deleteButton).exists('delete button is present for non-default');
|
|
await click(deleteButton);
|
|
assert
|
|
.dom('[data-test-confirmation-message]')
|
|
.exists('confirmation message is present');
|
|
await click(find('[data-test-confirm-button]'));
|
|
assert.dom('.flash-message.alert-success').exists();
|
|
assert.equal(currentURL(), '/administration/namespaces');
|
|
assert
|
|
.dom(`[data-test-namespace-name="${nonDefaultNamespace.name}"]`)
|
|
.doesNotExist();
|
|
|
|
// Namespace with variables errors properly
|
|
// "with-variables" hard-coded into scenario to be a NS with variables attached
|
|
await visit('/administration/namespaces/with-variables');
|
|
assert.equal(currentURL(), '/administration/namespaces/with-variables');
|
|
deleteButton = find('[data-test-delete-namespace] button');
|
|
await click(deleteButton);
|
|
await click(find('[data-test-confirm-button]'));
|
|
assert
|
|
.dom('.flash-message.alert-critical')
|
|
.exists('Doesnt let you delete a namespace with variables');
|
|
|
|
assert.equal(currentURL(), '/administration/namespaces/with-variables');
|
|
|
|
// Reset Token
|
|
window.localStorage.nomadTokenSecret = null;
|
|
});
|
|
|
|
test('Deleting a namespace failure and return', async function (assert) {
|
|
// This is an indirect test of rollbackWithoutChangedAttrs
|
|
// which allows deletes to fail and rolls back attributes
|
|
// It was added because this path was throwing an error when
|
|
// reloading the Ember model that was attempted to be deleted
|
|
|
|
assert.expect(3);
|
|
allScenarios.namespacesTestCluster(server);
|
|
window.localStorage.nomadTokenSecret = server.db.tokens[0].secretId;
|
|
|
|
// Attempt a delete on an un-deletable namespace
|
|
await visit('/administration/namespaces/with-variables');
|
|
let deleteButton = find('[data-test-delete-namespace] button');
|
|
await click(deleteButton);
|
|
await click(find('[data-test-confirm-button]'));
|
|
|
|
assert
|
|
.dom('.flash-message.alert-critical')
|
|
.exists('Doesnt let you delete a namespace with variables');
|
|
assert.equal(currentURL(), '/administration/namespaces/with-variables');
|
|
|
|
// Navigate back to the page via the index
|
|
await visit('/administration/namespaces');
|
|
|
|
// Default namespace hides delete button
|
|
const notDeletedNSLink = [...findAll('[data-test-namespace-name]')].filter(
|
|
(row) => row.textContent.includes('with-variables')
|
|
)[0];
|
|
await click(notDeletedNSLink);
|
|
|
|
assert.equal(currentURL(), `/administration/namespaces/with-variables`);
|
|
});
|
|
});
|