From 7807b7a280b7be77576ff9af6cbfbb184ae7e851 Mon Sep 17 00:00:00 2001 From: Cameron Perera Date: Mon, 10 Feb 2025 17:41:37 -0600 Subject: [PATCH] Icu 15471 credential store tests (#2663) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test: 💍 update cred store read tests to use selectors ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-15471 * test: 💍 update cred store update to use selectors ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-15471 * test: 💍 update cred store delete to use selectors ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-15471 * test: 💍 update cred store list to use selectors ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-15471 * chore: 🤖 remove refactored selector ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-15471 --- .../credential-store/create-test.js | 8 - .../credential-store/delete-test.js | 80 ++++---- .../acceptance/credential-store/list-test.js | 82 ++++---- .../acceptance/credential-store/read-test.js | 28 +-- .../acceptance/credential-store/selectors.js | 8 +- .../credential-store/update-test.js | 185 ++++++++++-------- ui/admin/tests/helpers/selectors.js | 2 + 7 files changed, 215 insertions(+), 178 deletions(-) diff --git a/ui/admin/tests/acceptance/credential-store/create-test.js b/ui/admin/tests/acceptance/credential-store/create-test.js index 0088fe715..953dd07ed 100644 --- a/ui/admin/tests/acceptance/credential-store/create-test.js +++ b/ui/admin/tests/acceptance/credential-store/create-test.js @@ -143,14 +143,6 @@ module('Acceptance | credential-stores | create', function (hooks) { status: 400, code: 'invalid_argument', message: errorMsg, - details: { - request_fields: [ - { - name: 'name', - description: 'Name is required.', - }, - ], - }, }, ); }); diff --git a/ui/admin/tests/acceptance/credential-store/delete-test.js b/ui/admin/tests/acceptance/credential-store/delete-test.js index a4d234d84..e5532689d 100644 --- a/ui/admin/tests/acceptance/credential-store/delete-test.js +++ b/ui/admin/tests/acceptance/credential-store/delete-test.js @@ -12,6 +12,8 @@ import { authenticateSession } from 'ember-simple-auth/test-support'; import { Response } from 'miragejs'; import { resolve, reject } from 'rsvp'; import sinon from 'sinon'; +import * as selectors from './selectors'; +import * as commonSelectors from 'admin/tests/helpers/selectors'; module('Acceptance | credential-stores | delete', function (hooks) { setupApplicationTest(hooks); @@ -20,10 +22,6 @@ module('Acceptance | credential-stores | delete', function (hooks) { let getStaticCredentialStoresCount; let getVaultCredentialStoresCount; - const MANAGE_DROPDOWN_SELECTOR = - '[data-test-manage-credential-stores-dropdown] button:first-child'; - const DELETE_ACTION_SELECTOR = - '[data-test-manage-credential-stores-dropdown] ul li button'; const instances = { scopes: { @@ -34,9 +32,6 @@ module('Acceptance | credential-stores | delete', function (hooks) { }; const urls = { - globalScope: null, - orgScope: null, - projectScope: null, credentialStores: null, staticCredentialStore: null, vaultCredentialStore: null, @@ -62,10 +57,7 @@ module('Acceptance | credential-stores | delete', function (hooks) { type: 'vault', }); // Generate route URLs for resources - urls.globalScope = `/scopes/global/scopes`; - urls.orgScope = `/scopes/${instances.scopes.org.id}/scopes`; - urls.projectScope = `/scopes/${instances.scopes.project.id}`; - urls.credentialStores = `${urls.projectScope}/credential-stores`; + urls.credentialStores = `/scopes/${instances.scopes.project.id}/credential-stores`; urls.staticCredentialStore = `${urls.credentialStores}/${instances.staticCredentialStore.id}`; urls.vaultCredentialStore = `${urls.credentialStores}/${instances.vaultCredentialStore.id}`; // Generate resource counter @@ -83,16 +75,20 @@ module('Acceptance | credential-stores | delete', function (hooks) { test('can delete credential store of type vault', async function (assert) { const count = getVaultCredentialStoresCount(); await visit(urls.vaultCredentialStore); - await click(MANAGE_DROPDOWN_SELECTOR); - await click(DELETE_ACTION_SELECTOR); + + await click(selectors.MANAGE_DROPDOWN); + await click(selectors.DELETE_ACTION); + assert.strictEqual(getVaultCredentialStoresCount(), count - 1); }); test('can delete credential store of type static', async function (assert) { const count = getStaticCredentialStoresCount(); await visit(urls.staticCredentialStore); - await click(MANAGE_DROPDOWN_SELECTOR); - await click(DELETE_ACTION_SELECTOR); + + await click(selectors.MANAGE_DROPDOWN); + await click(selectors.DELETE_ACTION); + assert.strictEqual(getStaticCredentialStoresCount(), count - 1); }); @@ -102,9 +98,10 @@ module('Acceptance | credential-stores | delete', function (hooks) { (item) => item !== 'delete', ); await visit(urls.vaultCredentialStore); - await click(MANAGE_DROPDOWN_SELECTOR); - assert.dom(DELETE_ACTION_SELECTOR).doesNotExist(); + await click(selectors.MANAGE_DROPDOWN); + + assert.dom(selectors.DELETE_ACTION).doesNotExist(); }); test('cannot delete a static credential store without proper authorization', async function (assert) { @@ -113,9 +110,10 @@ module('Acceptance | credential-stores | delete', function (hooks) { (item) => item !== 'delete', ); await visit(urls.staticCredentialStore); - await click(MANAGE_DROPDOWN_SELECTOR); - assert.dom(DELETE_ACTION_SELECTOR).doesNotExist(); + await click(selectors.MANAGE_DROPDOWN); + + assert.dom(selectors.DELETE_ACTION).doesNotExist(); }); test('can accept delete static credential store via dialog', async function (assert) { @@ -124,8 +122,10 @@ module('Acceptance | credential-stores | delete', function (hooks) { confirmService.confirm = sinon.fake.returns(resolve()); const count = getStaticCredentialStoresCount(); await visit(urls.staticCredentialStore); - await click(MANAGE_DROPDOWN_SELECTOR); - await click(DELETE_ACTION_SELECTOR); + + await click(selectors.MANAGE_DROPDOWN); + await click(selectors.DELETE_ACTION); + assert.strictEqual(getStaticCredentialStoresCount(), count - 1); assert.ok(confirmService.confirm.calledOnce); }); @@ -136,8 +136,10 @@ module('Acceptance | credential-stores | delete', function (hooks) { confirmService.confirm = sinon.fake.returns(resolve()); const count = getVaultCredentialStoresCount(); await visit(urls.vaultCredentialStore); - await click(MANAGE_DROPDOWN_SELECTOR); - await click(DELETE_ACTION_SELECTOR); + + await click(selectors.MANAGE_DROPDOWN); + await click(selectors.DELETE_ACTION); + assert.strictEqual(getVaultCredentialStoresCount(), count - 1); assert.ok(confirmService.confirm.calledOnce); }); @@ -148,8 +150,10 @@ module('Acceptance | credential-stores | delete', function (hooks) { confirmService.confirm = sinon.fake.returns(reject()); const count = getStaticCredentialStoresCount(); await visit(urls.staticCredentialStore); - await click(MANAGE_DROPDOWN_SELECTOR); - await click(DELETE_ACTION_SELECTOR); + + await click(selectors.MANAGE_DROPDOWN); + await click(selectors.DELETE_ACTION); + assert.strictEqual(getStaticCredentialStoresCount(), count); assert.ok(confirmService.confirm.calledOnce); }); @@ -160,8 +164,10 @@ module('Acceptance | credential-stores | delete', function (hooks) { confirmService.confirm = sinon.fake.returns(reject()); const count = getVaultCredentialStoresCount(); await visit(urls.vaultCredentialStore); - await click(MANAGE_DROPDOWN_SELECTOR); - await click(DELETE_ACTION_SELECTOR); + + await click(selectors.MANAGE_DROPDOWN); + await click(selectors.DELETE_ACTION); + assert.strictEqual(getVaultCredentialStoresCount(), count); assert.ok(confirmService.confirm.calledOnce); }); @@ -179,11 +185,11 @@ module('Acceptance | credential-stores | delete', function (hooks) { ); }); await visit(urls.staticCredentialStore); - await click(MANAGE_DROPDOWN_SELECTOR); - await click(DELETE_ACTION_SELECTOR); - assert - .dom('[data-test-toast-notification] .hds-alert__description') - .hasText('Oops.'); + + await click(selectors.MANAGE_DROPDOWN); + await click(selectors.DELETE_ACTION); + + assert.dom(commonSelectors.ALERT_TOAST_BODY).hasText('Oops.'); }); test('deleting a vault credential store which errors displays error messages', async function (assert) { @@ -199,10 +205,10 @@ module('Acceptance | credential-stores | delete', function (hooks) { ); }); await visit(urls.vaultCredentialStore); - await click(MANAGE_DROPDOWN_SELECTOR); - await click(DELETE_ACTION_SELECTOR); - assert - .dom('[data-test-toast-notification] .hds-alert__description') - .hasText('Oops.'); + + await click(selectors.MANAGE_DROPDOWN); + await click(selectors.DELETE_ACTION); + + assert.dom(commonSelectors.ALERT_TOAST_BODY).hasText('Oops.'); }); }); diff --git a/ui/admin/tests/acceptance/credential-store/list-test.js b/ui/admin/tests/acceptance/credential-store/list-test.js index 521c36d1b..24ba8b4a7 100644 --- a/ui/admin/tests/acceptance/credential-store/list-test.js +++ b/ui/admin/tests/acceptance/credential-store/list-test.js @@ -13,19 +13,14 @@ import { TYPE_CREDENTIAL_STORE_STATIC, TYPE_CREDENTIAL_STORE_VAULT, } from 'api/models/credential-store'; +import * as selectors from './selectors'; +import * as commonSelectors from 'admin/tests/helpers/selectors'; module('Acceptance | credential-stores | list', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); setupIndexedDb(hooks); - const SEARCH_INPUT_SELECTOR = '.search-filtering [type="search"]'; - const NO_RESULTS_MSG_SELECTOR = '[data-test-no-credential-store-results]'; - const FILTER_DROPDOWN_SELECTOR = (name) => - `.search-filtering [name="${name}"] button`; - const FILTER_APPLY_BUTTON_SELECTOR = - '.search-filtering [data-test-dropdown-apply-button]'; - const instances = { scopes: { global: null, @@ -76,14 +71,14 @@ module('Acceptance | credential-stores | list', function (hooks) { test('users can navigate to credential-stores with proper authorization', async function (assert) { await visit(urls.orgScope); - await click(`[href="${urls.projectScope}"]`); + await click(commonSelectors.HREF(urls.projectScope)); assert.true( instances.scopes.project.authorized_collection_actions[ 'credential-stores' ].includes('list'), ); - assert.dom(`[href="${urls.credentialStores}"]`).exists(); + assert.dom(commonSelectors.HREF(urls.credentialStores)).isVisible(); }); test('users cannot navigate to index without either list or create actions', async function (assert) { @@ -92,7 +87,7 @@ module('Acceptance | credential-stores | list', function (hooks) { ] = []; await visit(urls.orgScope); - await click(`[href="${urls.projectScope}"]`); + await click(commonSelectors.HREF(urls.projectScope)); assert.false( instances.scopes.project.authorized_collection_actions[ @@ -104,7 +99,7 @@ module('Acceptance | credential-stores | list', function (hooks) { 'credential-stores' ].includes('create'), ); - assert.dom(`[href="${urls.credentialStores}"]`).doesNotExist(); + assert.dom(commonSelectors.HREF(urls.credentialStores)).doesNotExist(); }); test('users can navigate to index with only create action', async function (assert) { @@ -113,67 +108,78 @@ module('Acceptance | credential-stores | list', function (hooks) { ] = ['create']; await visit(urls.orgScope); - await click(`[href="${urls.projectScope}"]`); + await click(commonSelectors.HREF(urls.projectScope)); - assert.dom(`[href="${urls.credentialStores}"]`).exists(); + assert.dom(commonSelectors.HREF(urls.credentialStores)).isVisible(); }); test('users can link to docs page for credential stores', async function (assert) { await visit(urls.projectScope); - await click(`[href="${urls.credentialStores}"]`); + await click(commonSelectors.HREF(urls.credentialStores)); assert .dom( `[href="https://developer.hashicorp.com/boundary/docs/concepts/domain-model/credential-stores"]`, ) - .exists(); + .isVisible(); }); test('user can search for a specific credential-store by id', async function (assert) { await visit(urls.projectScope); - await click(`[href="${urls.credentialStores}"]`); + await click(commonSelectors.HREF(urls.credentialStores)); - assert.dom(`[href="${urls.staticCredentialStore}"]`).exists(); - assert.dom(`[href="${urls.vaultCredentialStore}"]`).exists(); + assert.dom(commonSelectors.HREF(urls.staticCredentialStore)).isVisible(); + assert.dom(commonSelectors.HREF(urls.vaultCredentialStore)).isVisible(); - await fillIn(SEARCH_INPUT_SELECTOR, instances.staticCredentialStore.id); - await waitFor(`[href="${urls.vaultCredentialStore}"]`, { count: 0 }); + await fillIn( + commonSelectors.SEARCH_INPUT, + instances.staticCredentialStore.id, + ); + await waitFor(commonSelectors.HREF(urls.vaultCredentialStore), { + count: 0, + }); - assert.dom(`[href="${urls.staticCredentialStore}"]`).exists(); - assert.dom(`[href="${urls.vaultCredentialStore}"]`).doesNotExist(); + assert.dom(commonSelectors.HREF(urls.staticCredentialStore)).isVisible(); + assert.dom(commonSelectors.HREF(urls.vaultCredentialStore)).doesNotExist(); }); test('user can search for credential-stores and get no results', async function (assert) { await visit(urls.projectScope); - await click(`[href="${urls.credentialStores}"]`); + await click(commonSelectors.HREF(urls.credentialStores)); - assert.dom(`[href="${urls.staticCredentialStore}"]`).exists(); - assert.dom(`[href="${urls.vaultCredentialStore}"]`).exists(); + assert.dom(commonSelectors.HREF(urls.staticCredentialStore)).isVisible(); + assert.dom(commonSelectors.HREF(urls.vaultCredentialStore)).isVisible(); - await fillIn(SEARCH_INPUT_SELECTOR, 'fake cred store that does not exist'); - await waitFor(NO_RESULTS_MSG_SELECTOR, { count: 1 }); + await fillIn( + commonSelectors.SEARCH_INPUT, + 'fake cred store that does not exist', + ); + await waitFor(selectors.NO_RESULTS_MSG, { count: 1 }); - assert.dom(`[href="${urls.staticCredentialStore}"]`).doesNotExist(); - assert.dom(`[href="${urls.vaultCredentialStore}"]`).doesNotExist(); - assert.dom(NO_RESULTS_MSG_SELECTOR).includesText('No results found'); + assert.dom(commonSelectors.HREF(urls.staticCredentialStore)).doesNotExist(); + assert.dom(commonSelectors.HREF(urls.vaultCredentialStore)).doesNotExist(); + assert.dom(selectors.NO_RESULTS_MSG).includesText('No results found'); }); test('user can filter for credential-stores by type', async function (assert) { await visit(urls.projectScope); - await click(`[href="${urls.credentialStores}"]`); + await click(commonSelectors.HREF(urls.credentialStores)); - assert.dom(`[href="${urls.staticCredentialStore}"]`).exists(); - assert.dom(`[href="${urls.vaultCredentialStore}"]`).exists(); + assert.dom(commonSelectors.HREF(urls.staticCredentialStore)).isVisible(); + assert.dom(commonSelectors.HREF(urls.vaultCredentialStore)).isVisible(); - await click(FILTER_DROPDOWN_SELECTOR('type')); - await click(`input[value="${TYPE_CREDENTIAL_STORE_VAULT}"]`); - await click(FILTER_APPLY_BUTTON_SELECTOR); + await click(commonSelectors.FILTER_DROPDOWN('type')); - assert.dom(`[href="${urls.staticCredentialStore}"]`).doesNotExist(); - assert.dom(`[href="${urls.vaultCredentialStore}"]`).exists(); + await click( + commonSelectors.FILTER_DROPDOWN_ITEM(TYPE_CREDENTIAL_STORE_VAULT), + ); + await click(commonSelectors.FILTER_DROPDOWN_ITEM_APPLY_BTN('type')); + + assert.dom(commonSelectors.HREF(urls.staticCredentialStore)).doesNotExist(); + assert.dom(commonSelectors.HREF(urls.vaultCredentialStore)).isVisible(); }); }); diff --git a/ui/admin/tests/acceptance/credential-store/read-test.js b/ui/admin/tests/acceptance/credential-store/read-test.js index 19e2d4198..a1239b0ec 100644 --- a/ui/admin/tests/acceptance/credential-store/read-test.js +++ b/ui/admin/tests/acceptance/credential-store/read-test.js @@ -30,8 +30,6 @@ module('Acceptance | credential-stores | read', function (hooks) { }; const urls = { - globalScope: null, - orgScope: null, projectScope: null, credentialStores: null, staticCredentialStore: null, @@ -59,8 +57,6 @@ module('Acceptance | credential-stores | read', function (hooks) { type: 'vault', }); // Generate route URLs for resources - urls.globalScope = `/scopes/global/scopes`; - urls.orgScope = `/scopes/${instances.scopes.org.id}/scopes`; urls.projectScope = `/scopes/${instances.scopes.project.id}`; urls.credentialStores = `${urls.projectScope}/credential-stores`; urls.staticCredentialStore = `${urls.credentialStores}/${instances.staticCredentialStore.id}`; @@ -74,22 +70,24 @@ module('Acceptance | credential-stores | read', function (hooks) { test('visiting static credential store', async function (assert) { featuresService.enable('static-credentials'); await visit(urls.credentialStores); + await a11yAudit(); assert.strictEqual(currentURL(), urls.credentialStores); - await click(`[href="${urls.staticCredentialStore}"]`); - await a11yAudit(); + await click(commonSelectors.HREF(urls.staticCredentialStore)); + await a11yAudit(); assert.strictEqual(currentURL(), urls.staticCredentialStore); }); test('visiting vault credential store', async function (assert) { await visit(urls.credentialStores); + assert.strictEqual(currentURL(), urls.credentialStores); - await click(`[href="${urls.vaultCredentialStore}"]`); - await a11yAudit(); + await click(commonSelectors.HREF(urls.vaultCredentialStore)); + await a11yAudit(); assert.strictEqual(currentURL(), urls.vaultCredentialStore); }); @@ -100,7 +98,7 @@ module('Acceptance | credential-stores | read', function (hooks) { (item) => item !== 'read', ); - await click(`[href="${urls.credentialStores}"]`); + await click(commonSelectors.HREF(urls.credentialStores)); assert .dom(commonSelectors.TABLE_RESOURCE_LINK(urls.vaultCredentialStore)) @@ -118,7 +116,7 @@ module('Acceptance | credential-stores | read', function (hooks) { (item) => item !== 'read', ); - await click(`[href="${urls.credentialStores}"]`); + await click(commonSelectors.HREF(urls.credentialStores)); assert .dom(commonSelectors.TABLE_RESOURCE_LINK(urls.staticCredentialStore)) @@ -130,8 +128,8 @@ module('Acceptance | credential-stores | read', function (hooks) { test('visiting an unknown credential store displays 404 message', async function (assert) { await visit(urls.unknownCredentialStore); - await a11yAudit(); + await a11yAudit(); assert .dom(commonSelectors.RESOURCE_NOT_FOUND_SUBTITLE) .hasText(commonSelectors.RESOURCE_NOT_FOUND_VALUE); @@ -140,13 +138,15 @@ module('Acceptance | credential-stores | read', function (hooks) { test('users can link to docs page for credential store', async function (assert) { await visit(urls.projectScope); - await click(`[href="${urls.credentialStores}"]`); + await click(commonSelectors.HREF(urls.credentialStores)); assert .dom( - `[href="https://developer.hashicorp.com/boundary/docs/concepts/domain-model/credential-stores"]`, + commonSelectors.HREF( + 'https://developer.hashicorp.com/boundary/docs/concepts/domain-model/credential-stores', + ), ) - .exists(); + .isVisible(); }); test('users can navigate to credential store and incorrect url auto-corrects', async function (assert) { diff --git a/ui/admin/tests/acceptance/credential-store/selectors.js b/ui/admin/tests/acceptance/credential-store/selectors.js index 828d15529..9c9ee6cba 100644 --- a/ui/admin/tests/acceptance/credential-store/selectors.js +++ b/ui/admin/tests/acceptance/credential-store/selectors.js @@ -6,8 +6,13 @@ // Manage actions dropdown selectors export const MANAGE_DROPDOWN = '[data-test-manage-credential-stores-dropdown] button:first-child'; -export const EDIT_ACTION = +export const EDIT_WORKER_FILTER_ACTION = '[data-test-manage-credential-stores-dropdown] ul li:nth-child(2) a'; +export const DELETE_ACTION = + '[data-test-manage-credential-stores-dropdown] ul li:last-child button'; + +// Search filtering selectors +export const NO_RESULTS_MSG = '[data-test-no-credential-store-results]'; export const CODE_EDITOR_BODY = '[data-test-code-editor-field-editor] textarea'; export const CODE_BLOCK_BODY = '.hds-code-block__code'; @@ -15,5 +20,6 @@ export const EDITOR_WORKER_FILTER_VALUE = '"dev" in "/tags/env"'; export const TYPE_VAULT = '[value="vault"]'; +export const FIELD_VAULT_ADDRESS = '[name="address"]'; export const FIELD_VAULT_ADDRESS_ERROR = '[data-test-error-message-vault-address]'; diff --git a/ui/admin/tests/acceptance/credential-store/update-test.js b/ui/admin/tests/acceptance/credential-store/update-test.js index 08587005b..0e6797f65 100644 --- a/ui/admin/tests/acceptance/credential-store/update-test.js +++ b/ui/admin/tests/acceptance/credential-store/update-test.js @@ -4,7 +4,7 @@ */ import { module, test } from 'qunit'; -import { visit, currentURL, find, click, fillIn } from '@ember/test-helpers'; +import { visit, currentURL, click, fillIn } from '@ember/test-helpers'; import { setupApplicationTest } from 'admin/tests/helpers'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; import { setupIndexedDb } from 'api/test-support/helpers/indexed-db'; @@ -27,8 +27,6 @@ module('Acceptance | credential-stores | update', function (hooks) { }; const urls = { - globalScope: null, - orgScope: null, projectScope: null, credentialStores: null, staticCredentialStore: null, @@ -55,8 +53,6 @@ module('Acceptance | credential-stores | update', function (hooks) { type: 'vault', }); // Generate route URLs for resources - urls.globalScope = `/scopes/global/scopes`; - urls.orgScope = `/scopes/${instances.scopes.org.id}/scopes`; urls.projectScope = `/scopes/${instances.scopes.project.id}`; urls.credentialStores = `${urls.projectScope}/credential-stores`; urls.vaultCredentialStore = `${urls.credentialStores}/${instances.vaultCredentialStore.id}`; @@ -72,29 +68,35 @@ module('Acceptance | credential-stores | update', function (hooks) { test('can save changes to existing static credential store', async function (assert) { assert.notEqual(instances.staticCredentialStore.name, 'random string'); + await visit(urls.staticCredentialStore); - await click('form [type="button"]', 'Activate edit mode'); - await fillIn('[name="name"]', 'random string'); - await click('.rose-form-actions [type="submit"]'); + + await click(commonSelectors.EDIT_BTN); + await fillIn(commonSelectors.FIELD_NAME, commonSelectors.FIELD_NAME_VALUE); + await click(commonSelectors.SAVE_BTN); + assert.strictEqual(currentURL(), urls.staticCredentialStore); assert.strictEqual( this.server.schema.credentialStores.where({ type: 'static' }).models[0] .name, - 'random string', + commonSelectors.FIELD_NAME_VALUE, ); }); test('can save changes to existing vault credential store', async function (assert) { assert.notEqual(instances.vaultCredentialStore.name, 'random string'); + await visit(urls.vaultCredentialStore); - await click('form [type="button"]', 'Activate edit mode'); - await fillIn('[name="name"]', 'random string'); - await click('.rose-form-actions [type="submit"]'); + + await click(commonSelectors.EDIT_BTN); + await fillIn(commonSelectors.FIELD_NAME, commonSelectors.FIELD_NAME_VALUE); + await click(commonSelectors.SAVE_BTN); + assert.strictEqual(currentURL(), urls.vaultCredentialStore); assert.strictEqual( this.server.schema.credentialStores.where({ type: 'vault' }).models[0] .name, - 'random string', + commonSelectors.FIELD_NAME_VALUE, ); }); @@ -103,8 +105,10 @@ module('Acceptance | credential-stores | update', function (hooks) { instances.staticCredentialStore.authorized_actions.filter( (item) => item !== 'update', ); + await visit(urls.staticCredentialStore); - assert.notOk(find('.rose-layout-page-actions .rose-button-secondary')); + + assert.dom(commonSelectors.EDIT_BTN).doesNotExist(); }); test('cannot make changes to an existing vault credential store without proper authorization', async function (assert) { @@ -112,35 +116,47 @@ module('Acceptance | credential-stores | update', function (hooks) { instances.vaultCredentialStore.authorized_actions.filter( (item) => item !== 'update', ); + await visit(urls.vaultCredentialStore); - assert.notOk(find('.rose-layout-page-actions .rose-button-secondary')); + + assert.dom(commonSelectors.EDIT_BTN).doesNotExist(); }); test('can cancel changes to existing static credential store', async function (assert) { await visit(urls.staticCredentialStore); - await click('form [type="button"]', 'Activate edit mode'); - await fillIn('[name="name"]', 'random string'); - await click('.rose-form-actions [type="button"]'); - assert.notEqual(instances.staticCredentialStore.name, 'random string'); - assert.strictEqual( - find('[name="name"]').value, + + await click(commonSelectors.EDIT_BTN); + await fillIn(commonSelectors.FIELD_NAME, commonSelectors.FIELD_NAME_VALUE); + await click(commonSelectors.CANCEL_BTN); + + assert.notEqual( instances.staticCredentialStore.name, + commonSelectors.FIELD_NAME_VALUE, ); + assert + .dom(commonSelectors.FIELD_NAME) + .hasValue(instances.staticCredentialStore.name); }); test('can cancel changes to existing vault credential store', async function (assert) { await visit(urls.vaultCredentialStore); - await click('form [type="button"]', 'Activate edit mode'); - await fillIn('[name="name"]', 'random string'); - await click('.rose-form-actions [type="button"]'); - assert.notEqual(instances.vaultCredentialStore.name, 'random string'); - assert.strictEqual( - find('[name="name"]').value, + + await click(commonSelectors.EDIT_BTN); + await fillIn(commonSelectors.FIELD_NAME, commonSelectors.FIELD_NAME_VALUE); + await click(commonSelectors.CANCEL_BTN); + + assert.notEqual( instances.vaultCredentialStore.name, + commonSelectors.FIELD_NAME_VALUE, ); + assert + .dom(commonSelectors.FIELD_NAME) + .hasValue(instances.vaultCredentialStore.name); }); test('saving an existing static credential store with invalid fields displays error messages', async function (assert) { + const errorMsg = + 'Invalid request. Request attempted to make second resource with the same field value that must be unique.'; this.server.patch('/credential-stores/:id', () => { return new Response( 400, @@ -148,32 +164,22 @@ module('Acceptance | credential-stores | update', function (hooks) { { status: 400, code: 'invalid_argument', - message: 'The request was invalid.', - details: { - request_fields: [ - { - name: 'name', - description: 'Name is required.', - }, - ], - }, + message: errorMsg, }, ); }); await visit(urls.staticCredentialStore); - await click('form [type="button"]', 'Activate edit mode'); - await fillIn('[name="name"]', 'random string'); - await click('[type="submit"]'); - assert - .dom('[data-test-toast-notification] .hds-alert__description') - .hasText('The request was invalid.'); - assert.ok( - find('[data-test-error-message-name]').textContent.trim(), - 'Name is required.', - ); + + await click(commonSelectors.EDIT_BTN); + await fillIn(commonSelectors.FIELD_NAME, commonSelectors.FIELD_NAME_VALUE); + await click(commonSelectors.SAVE_BTN); + + assert.dom(commonSelectors.ALERT_TOAST_BODY).hasText(errorMsg); }); test('saving an existing vault credential store with invalid fields displays error messages', async function (assert) { + const desc = 'Field required for creating a vault credential store.'; + const msg = 'The request was invalid'; this.server.patch('/credential-stores/:id', () => { return new Response( 400, @@ -181,12 +187,12 @@ module('Acceptance | credential-stores | update', function (hooks) { { status: 400, code: 'invalid_argument', - message: 'The request was invalid.', + message: msg, details: { request_fields: [ { - name: 'name', - description: 'Name is required.', + name: 'attributes.address', + description: desc, }, ], }, @@ -194,34 +200,39 @@ module('Acceptance | credential-stores | update', function (hooks) { ); }); await visit(urls.vaultCredentialStore); - await click('form [type="button"]', 'Activate edit mode'); - await fillIn('[name="name"]', 'random string'); - await click('[type="submit"]'); - assert - .dom('[data-test-toast-notification] .hds-alert__description') - .hasText('The request was invalid.'); - assert.ok( - find('[data-test-error-message-name]').textContent.trim(), - 'Name is required.', - ); + + await click(commonSelectors.EDIT_BTN); + await fillIn(selectors.FIELD_VAULT_ADDRESS, 'random string'); + await click(commonSelectors.SAVE_BTN); + + assert.dom(commonSelectors.ALERT_TOAST_BODY).hasText(msg); + assert.dom(selectors.FIELD_VAULT_ADDRESS_ERROR).hasText(desc); }); test('can discard unsaved static credential store changes via dialog', async function (assert) { assert.expect(5); const confirmService = this.owner.lookup('service:confirm'); confirmService.enabled = true; - assert.notEqual(instances.staticCredentialStore.name, 'random string'); + + assert.notEqual( + instances.staticCredentialStore.name, + commonSelectors.FIELD_NAME_VALUE, + ); await visit(urls.staticCredentialStore); - await click('form [type="button"]', 'Activate edit mode'); - await fillIn('[name="name"]', 'random string'); + + await click(commonSelectors.EDIT_BTN); + await fillIn(commonSelectors.FIELD_NAME, commonSelectors.FIELD_NAME_VALUE); + assert.strictEqual(currentURL(), urls.staticCredentialStore); try { await visit(urls.credentialStores); } catch (e) { - assert.ok(find(commonSelectors.MODAL_WARNING)); + assert.dom(commonSelectors.MODAL_WARNING).isVisible(); + await click(commonSelectors.MODAL_WARNING_CONFIRM_BTN, 'Click Discard'); + assert.strictEqual(currentURL(), urls.credentialStores); assert.notEqual( this.server.schema.credentialStores.where({ type: 'static' }).models[0] @@ -238,15 +249,19 @@ module('Acceptance | credential-stores | update', function (hooks) { assert.notEqual(instances.vaultCredentialStore.name, 'random string'); await visit(urls.vaultCredentialStore); - await click('form [type="button"]', 'Activate edit mode'); - await fillIn('[name="name"]', 'random string'); + + await click(commonSelectors.EDIT_BTN); + await fillIn(commonSelectors.FIELD_NAME, commonSelectors.FIELD_NAME_VALUE); + assert.strictEqual(currentURL(), urls.vaultCredentialStore); try { await visit(urls.credentialStores); } catch (e) { - assert.ok(find(commonSelectors.MODAL_WARNING)); + assert.dom(commonSelectors.MODAL_WARNING).isVisible(); + await click(commonSelectors.MODAL_WARNING_CONFIRM_BTN, 'Click Discard'); + assert.strictEqual(currentURL(), urls.credentialStores); assert.notEqual( this.server.schema.credentialStores.where({ type: 'vault' }).models[0] @@ -260,17 +275,23 @@ module('Acceptance | credential-stores | update', function (hooks) { assert.expect(5); const confirmService = this.owner.lookup('service:confirm'); confirmService.enabled = true; + assert.notEqual(instances.staticCredentialStore.name, 'random string'); + await visit(urls.staticCredentialStore); - await click('form [type="button"]', 'Activate edit mode'); - await fillIn('[name="name"]', 'random string'); + + await click(commonSelectors.EDIT_BTN); + await fillIn(commonSelectors.FIELD_NAME, commonSelectors.FIELD_NAME_VALUE); + assert.strictEqual(currentURL(), urls.staticCredentialStore); try { await visit(urls.credentialStores); } catch (e) { - assert.ok(find(commonSelectors.MODAL_WARNING)); + assert.dom(commonSelectors.MODAL_WARNING).isVisible(); + await click(commonSelectors.MODAL_WARNING_CANCEL_BTN); + assert.strictEqual(currentURL(), urls.staticCredentialStore); assert.notEqual( this.server.schema.credentialStores.where({ type: 'static' }).models[0] @@ -284,17 +305,23 @@ module('Acceptance | credential-stores | update', function (hooks) { assert.expect(5); const confirmService = this.owner.lookup('service:confirm'); confirmService.enabled = true; + assert.notEqual(instances.vaultCredentialStore.name, 'random string'); + await visit(urls.vaultCredentialStore); - await click('form [type="button"]', 'Activate edit mode'); - await fillIn('[name="name"]', 'random string'); + + await click(commonSelectors.EDIT_BTN); + await fillIn(commonSelectors.FIELD_NAME, commonSelectors.FIELD_NAME_VALUE); + assert.strictEqual(currentURL(), urls.vaultCredentialStore); try { await visit(urls.credentialStores); } catch (e) { - assert.ok(find(commonSelectors.MODAL_WARNING)); + assert.dom(commonSelectors.MODAL_WARNING).isVisible(); + await click(commonSelectors.MODAL_WARNING_CANCEL_BTN); + assert.strictEqual(currentURL(), urls.vaultCredentialStore); assert.notEqual( this.server.schema.credentialStores.where({ type: 'vault' }).models[0] @@ -313,7 +340,7 @@ module('Acceptance | credential-stores | update', function (hooks) { test('user can click vault credential store worker filter tab and be rerouted to correct url', async function (assert) { await visit(urls.vaultCredentialStore); - assert.dom(commonSelectors.HREF(urls.workerFilter)).exists(); + assert.dom(commonSelectors.HREF(urls.workerFilter)).isVisible(); await click(commonSelectors.HREF(urls.workerFilter)); @@ -325,7 +352,7 @@ module('Acceptance | credential-stores | update', function (hooks) { await click(commonSelectors.HREF(urls.workerFilter)); await click(selectors.MANAGE_DROPDOWN); - await click(selectors.EDIT_ACTION); + await click(selectors.EDIT_WORKER_FILTER_ACTION); assert.strictEqual(currentURL(), urls.editWorkerFilter); }); @@ -338,12 +365,10 @@ module('Acceptance | credential-stores | update', function (hooks) { await click(commonSelectors.HREF(urls.workerFilter)); - assert.dom('.hds-application-state').exists(); assert - .dom('.hds-application-state') - .hasText( - `No worker filter added You haven't added a worker filter yet. Add Worker Filter`, - ); + .dom(commonSelectors.PAGE_MESSAGE_DESCRIPTION) + .hasText("You haven't added a worker filter yet."); + assert.dom(commonSelectors.PAGE_MESSAGE_LINK).hasText('Add Worker Filter'); }); test('when worker filter exists, readonly code block displays the filter text', async function (assert) { @@ -355,7 +380,7 @@ module('Acceptance | credential-stores | update', function (hooks) { await click(commonSelectors.HREF(urls.workerFilter)); await click(selectors.MANAGE_DROPDOWN); - await click(selectors.EDIT_ACTION); + await click(selectors.EDIT_WORKER_FILTER_ACTION); await fillIn(selectors.CODE_EDITOR_BODY, '"bar" in "/tags/foo"'); await click(commonSelectors.SAVE_BTN); diff --git a/ui/admin/tests/helpers/selectors.js b/ui/admin/tests/helpers/selectors.js index ab0448489..38772a907 100644 --- a/ui/admin/tests/helpers/selectors.js +++ b/ui/admin/tests/helpers/selectors.js @@ -43,6 +43,8 @@ export const MODAL_WARNING_CANCEL_BTN = export const MODAL_WARNING_TITLE = '.hds-modal__header'; export const MODAL_WARNING_MESSAGE = '.hds-modal__body'; +// Search filtering selectors +export const SEARCH_INPUT = '.search-filtering [type="search"]'; export const FILTER_DROPDOWN = (filterName) => `.search-filtering [name="${filterName}"] button`; export const FILTER_DROPDOWN_ITEM = (itemList) => `input[value="${itemList}"]`;