From cb526da4a465011678acafbd9e69c73601a24035 Mon Sep 17 00:00:00 2001 From: Jordan Reimer Date: Tue, 13 Dec 2022 19:36:45 -0700 Subject: [PATCH] adds acceptance tests for kubernetes secrets engine roles --- .../vault/cluster/secrets/backend/list.js | 2 +- .../addon/components/page/credentials.hbs | 6 +- .../addon/components/page/roles.hbs | 2 +- ui/mirage/handlers/kubernetes.js | 11 +- ui/mirage/scenarios/default.js | 6 +- ui/mirage/scenarios/kubernetes.js | 6 + .../secrets/backend/kubernetes/roles-test.js | 123 ++++++++++++++++++ 7 files changed, 146 insertions(+), 10 deletions(-) create mode 100644 ui/mirage/scenarios/kubernetes.js create mode 100644 ui/tests/acceptance/secrets/backend/kubernetes/roles-test.js diff --git a/ui/app/routes/vault/cluster/secrets/backend/list.js b/ui/app/routes/vault/cluster/secrets/backend/list.js index 1701d6b9c930..b753d7d56bb5 100644 --- a/ui/app/routes/vault/cluster/secrets/backend/list.js +++ b/ui/app/routes/vault/cluster/secrets/backend/list.js @@ -64,7 +64,7 @@ export default Route.extend({ const { tab } = this.paramsFor('vault.cluster.secrets.backend.list-root'); const secretEngine = this.store.peekRecord('secret-engine', backend); const type = secretEngine && secretEngine.get('engineType'); - const { engineRoute } = allEngines().findBy('type', type); + const engineRoute = allEngines().findBy('type', type)?.engineRoute; if (!type || !SUPPORTED_BACKENDS.includes(type)) { return this.router.transitionTo('vault.cluster.secrets'); diff --git a/ui/lib/kubernetes/addon/components/page/credentials.hbs b/ui/lib/kubernetes/addon/components/page/credentials.hbs index 6ac2472c8ce3..3dc19b78e300 100644 --- a/ui/lib/kubernetes/addon/components/page/credentials.hbs +++ b/ui/lib/kubernetes/addon/components/page/credentials.hbs @@ -10,7 +10,7 @@ / roles -
  • +
  • / {{@roleName}}
  • @@ -62,7 +62,7 @@
    -
    @@ -106,7 +106,7 @@ - - {{role.name}} + {{role.name}} {{#if role.rolesPath.isLoading}} diff --git a/ui/mirage/handlers/kubernetes.js b/ui/mirage/handlers/kubernetes.js index 44e2870d435d..ca24786d9cf4 100644 --- a/ui/mirage/handlers/kubernetes.js +++ b/ui/mirage/handlers/kubernetes.js @@ -24,7 +24,8 @@ export default function (server) { return new Response(204); }; const deleteRecord = (schema, req, dbKey) => { - const record = getRecord(schema, req, dbKey); + const { name } = req.params; + const record = schema.db[dbKey].findBy({ name }); if (record) { schema.db[dbKey].remove(record.id); } @@ -86,4 +87,12 @@ export default function (server) { }, }; }); + + server.get('/sys/internal/ui/mounts/kubernetes', () => ({ + data: { + accessor: 'kubernetes_9f846a87', + path: 'kubernetes/', + type: 'kubernetes', + }, + })); } diff --git a/ui/mirage/scenarios/default.js b/ui/mirage/scenarios/default.js index 1e18578bf3d3..810caf5c0d27 100644 --- a/ui/mirage/scenarios/default.js +++ b/ui/mirage/scenarios/default.js @@ -1,14 +1,12 @@ import ENV from 'vault/config/environment'; const { handler } = ENV['ember-cli-mirage']; +import kubernetesScenario from './kubernetes'; export default function (server) { server.create('clients/config'); server.create('feature', { feature_flags: ['SOME_FLAG', 'VAULT_CLOUD_ADMIN_NAMESPACE'] }); if (handler === 'kubernetes') { - server.create('kubernetes-config', { path: 'kubernetes' }); - server.create('kubernetes-role'); - server.create('kubernetes-role', 'withRoleName'); - server.create('kubernetes-role', 'withRoleRules'); + kubernetesScenario(server); } } diff --git a/ui/mirage/scenarios/kubernetes.js b/ui/mirage/scenarios/kubernetes.js new file mode 100644 index 000000000000..2751b4bf23a4 --- /dev/null +++ b/ui/mirage/scenarios/kubernetes.js @@ -0,0 +1,6 @@ +export default function (server) { + server.create('kubernetes-config', { path: 'kubernetes' }); + server.create('kubernetes-role'); + server.create('kubernetes-role', 'withRoleName'); + server.create('kubernetes-role', 'withRoleRules'); +} diff --git a/ui/tests/acceptance/secrets/backend/kubernetes/roles-test.js b/ui/tests/acceptance/secrets/backend/kubernetes/roles-test.js new file mode 100644 index 000000000000..68b2f7eea6cc --- /dev/null +++ b/ui/tests/acceptance/secrets/backend/kubernetes/roles-test.js @@ -0,0 +1,123 @@ +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; +import { setupMirage } from 'ember-cli-mirage/test-support'; +import kubernetesScenario from 'vault/mirage/scenarios/kubernetes'; +import ENV from 'vault/config/environment'; +import authPage from 'vault/tests/pages/auth'; +import { fillIn, visit, currentURL, click, currentRouteName } from '@ember/test-helpers'; + +module('Acceptance | kubernetes | roles', function (hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + + hooks.before(function () { + ENV['ember-cli-mirage'].handler = 'kubernetes'; + }); + hooks.beforeEach(function () { + kubernetesScenario(this.server); + this.visitRoles = () => { + return visit('/vault/secrets/kubernetes/kubernetes/roles'); + }; + this.validateRoute = (assert, route, message) => { + assert.strictEqual(currentRouteName(), `vault.cluster.secrets.backend.kubernetes.${route}`, message); + }; + return authPage.login(); + }); + hooks.after(function () { + ENV['ember-cli-mirage'].handler = null; + }); + + test('it should filter roles', async function (assert) { + await this.visitRoles(); + assert.dom('[data-test-list-item-link]').exists({ count: 3 }, 'Roles list renders'); + await fillIn('[data-test-comoponent="navigate-input"]', '1'); + assert.dom('[data-test-list-item-link]').exists({ count: 1 }, 'Filtered roles list renders'); + assert.ok(currentURL().includes('pageFilter=1'), 'pageFilter query param value is set'); + }); + + test('it should link to role details on list item click', async function (assert) { + assert.expect(1); + await this.visitRoles(); + await click('[data-test-list-item-link]'); + this.validateRoute(assert, 'roles.role.details', 'Transitions to details route on list item click'); + }); + + test('it should have correct breadcrumb links in role details view', async function (assert) { + assert.expect(2); + await this.visitRoles(); + await click('[data-test-list-item-link]'); + await click('[data-test-crumb="roles"] a'); + this.validateRoute(assert, 'roles.index', 'Transitions to roles route on breadcrumb click'); + await click('[data-test-list-item-link]'); + await click('[data-test-crumb="overview"] a'); + this.validateRoute(assert, 'overview', 'Transitions to overview route on breadcrumb click'); + }); + + test('it should have functional list item menu', async function (assert) { + assert.expect(3); + await this.visitRoles(); + for (const action of ['details', 'edit', 'delete']) { + await click('[data-test-list-item-popup] button'); + await click(`[data-test-${action}]`); + if (action === 'delete') { + await click('[data-test-confirm-button]'); + assert.dom('[data-test-list-item-link]').exists({ count: 2 }, 'Deleted role removed from list'); + } else { + this.validateRoute( + assert, + `roles.role.${action}`, + `Transitions to ${action} route on menu action click` + ); + const selector = action === 'details' ? '[data-test-crumb="roles"] a' : '[data-test-cancel]'; + await click(selector); + } + } + }); + + test('it should create role', async function (assert) { + assert.expect(2); + await this.visitRoles(); + await click('[data-test-toolbar-roles-action]'); + await click('[data-test-radio-card="basic"]'); + await fillIn('[data-test-input="name"]', 'new-test-role'); + await fillIn('[data-test-input="serviceAccountName"]', 'default'); + await fillIn('[data-test-input="allowedKubernetesNamespaces"]', '*'); + await click('[data-test-save]'); + this.validateRoute(assert, 'roles.role.details', 'Transitions to details route on save success'); + await click('[data-test-crumb="roles"] a'); + assert.dom('[data-test-role="new-test-role"]').exists('New role renders in list'); + }); + + test('it should have functional toolbar actions in details view', async function (assert) { + assert.expect(3); + await this.visitRoles(); + await click('[data-test-list-item-link]'); + await click('[data-test-generate-credentials]'); + this.validateRoute(assert, 'roles.role.credentials', 'Transitions to credentials route'); + await click('[data-test-crumb="details"] a'); + await click('[data-test-edit]'); + this.validateRoute(assert, 'roles.role.edit', 'Transitions to edit route'); + await click('[data-test-cancel]'); + await click('[data-test-list-item-link]'); + await click('[data-test-delete] button'); + await click('[data-test-confirm-button]'); + assert + .dom('[data-test-list-item-link]') + .exists({ count: 2 }, 'Transitions to roles route and deleted role removed from list'); + }); + + test('it should generate credentials for role', async function (assert) { + assert.expect(1); + await this.visitRoles(); + await click('[data-test-list-item-link]'); + await click('[data-test-generate-credentials]'); + await fillIn('[data-test-kubernetes-namespace]', 'test-namespace'); + await click('[data-test-generate-credentials-button]'); + await click('[data-test-generate-credentials-done]'); + this.validateRoute( + assert, + 'roles.role.details', + 'Transitions to details route when done generating credentials' + ); + }); +});