From b1f14e5c623ebb5f8d5c486242a671681c220a8d Mon Sep 17 00:00:00 2001 From: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Wed, 30 Nov 2022 14:01:23 -0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20acceptance=20tests?= =?UTF-8?q?=20in=20targets=20folder=20(#1505)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 💡 acceptance tests in targets folder ✅ Closes: ICU-6974 * refactor: 💡 update a few test cases --- .../tests/acceptance/targets/create-test.js | 122 ++++++++++------ .../tests/acceptance/targets/delete-test.js | 66 +++++---- .../acceptance/targets/host-sources-test.js | 136 +++++++++++------- .../tests/acceptance/targets/list-test.js | 112 +++++++++++---- .../tests/acceptance/targets/update-test.js | 122 ++++++---------- 5 files changed, 328 insertions(+), 230 deletions(-) diff --git a/ui/admin/tests/acceptance/targets/create-test.js b/ui/admin/tests/acceptance/targets/create-test.js index 3e3c9139b..58df58ecd 100644 --- a/ui/admin/tests/acceptance/targets/create-test.js +++ b/ui/admin/tests/acceptance/targets/create-test.js @@ -22,6 +22,8 @@ module('Acceptance | targets | create', function (hooks) { setupMirage(hooks); let getTargetCount; + let getTCPTargetCount; + let getSSHTargetCount; let featuresService; const instances = { @@ -30,13 +32,14 @@ module('Acceptance | targets | create', function (hooks) { org: null, project: null, }, + target: null, }; const urls = { - globalScope: null, orgScope: null, projectScope: null, targets: null, target: null, + newTarget: null, newTCPTarget: null, newSSHTarget: null, }; @@ -57,7 +60,6 @@ module('Acceptance | targets | create', function (hooks) { scope: instances.scopes.project, }); // 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.targets = `${urls.projectScope}/targets`; @@ -66,8 +68,12 @@ module('Acceptance | targets | create', function (hooks) { urls.newTarget = `${urls.targets}/new`; urls.newTCPTarget = `${urls.targets}/new?type=tcp`; urls.newSSHTarget = `${urls.targets}/new?type=ssh`; - // Generate resource couner + // Generate resource counter getTargetCount = () => this.server.schema.targets.all().models.length; + getSSHTargetCount = () => + this.server.schema.targets.where({ type: 'ssh' }).models.length; + getTCPTargetCount = () => + this.server.schema.targets.where({ type: 'tcp' }).models.length; authenticateSession({}); }); @@ -78,13 +84,18 @@ module('Acceptance | targets | create', function (hooks) { }); test('can create new targets of type TCP', async function (assert) { - assert.expect(3); - const count = getTargetCount(); - await visit(urls.newTCPTarget); + assert.expect(4); + const targetCount = getTargetCount(); + const tcpTargetCount = getTCPTargetCount(); + await visit(urls.targets); + + await click(`[href="${urls.newTarget}"]`); await fillIn('[name="name"]', 'random string'); await fillIn('[name="worker_filter"]', 'random filter'); await click('[type="submit"]'); - assert.strictEqual(getTargetCount(), count + 1); + + assert.strictEqual(getTargetCount(), targetCount + 1); + assert.strictEqual(getTCPTargetCount(), tcpTargetCount + 1); assert.strictEqual( this.server.schema.targets.all().models[getTargetCount() - 1].name, 'random string' @@ -97,13 +108,19 @@ module('Acceptance | targets | create', function (hooks) { }); test('can create new targets of type SSH', async function (assert) { - assert.expect(3); - const count = getTargetCount(); - await visit(urls.newSSHTarget); + assert.expect(4); + const targetCount = getTargetCount(); + const sshTargetCount = getSSHTargetCount(); + await visit(urls.targets); + + await click(`[href="${urls.newTarget}"]`); await fillIn('[name="name"]', 'random string'); + await click('[value="ssh"]'); await fillIn('[name="worker_filter"]', 'random filter'); await click('[type="submit"]'); - assert.strictEqual(getTargetCount(), count + 1); + + assert.strictEqual(getSSHTargetCount(), sshTargetCount + 1); + assert.strictEqual(getTargetCount(), targetCount + 1); assert.strictEqual( this.server.schema.targets.all().models[getTargetCount() - 1].name, 'random string' @@ -117,57 +134,81 @@ module('Acceptance | targets | create', function (hooks) { test('can navigate to new targets route with proper authorization', async function (assert) { assert.expect(2); - await visit(urls.targets); - assert.ok( + await visit(urls.projectScope); + + await click(`[href="${urls.targets}"]`); + + assert.true( instances.scopes.project.authorized_collection_actions.targets.includes( 'create' ) ); - assert.ok(find(`[href="${urls.newTarget}"]`)); + assert.dom(`[href="${urls.newTarget}"]`).exists(); }); test('cannot navigate to new targets route without proper authorization', async function (assert) { assert.expect(2); - instances.scopes.project.authorized_collection_actions.targets = []; - await visit(urls.targets); - assert.notOk( + instances.scopes.project.authorized_collection_actions.targets = + instances.scopes.project.authorized_collection_actions.targets.filter( + (item) => item !== 'create' + ); + await visit(urls.projectScope); + + await click(`[href="${urls.targets}"]`); + + assert.false( instances.scopes.project.authorized_collection_actions.targets.includes( 'create' ) ); - assert.notOk(find(`[href="${urls.newTarget}"]`)); + assert.dom('.rose-layout-page-actions a').doesNotExist(); }); test('cannot navigate to new SSH targets route when ssh feature is disabled', async function (assert) { + assert.expect(3); featuresService.disable('ssh-target'); - assert.expect(2); await visit(urls.targets); - assert.ok( + + await click(`[href="${urls.newTarget}"]`); + + assert.true( instances.scopes.project.authorized_collection_actions.targets.includes( 'create' ) ); - assert.notOk(find(`[href="${urls.newSSHTarget}"]`)); + assert.dom('.rose-form-radio-card').exists({ count: 1 }); + assert.dom('.rose-form-radio-card label').includesText('TCP'); }); test('can cancel create new TCP target', async function (assert) { - assert.expect(2); - const count = getTargetCount(); - await visit(urls.newTCPTarget); + assert.expect(3); + const targetCount = getTargetCount(); + const tcpTargetCount = getTCPTargetCount(); + await visit(urls.targets); + + await click(`[href="${urls.newTarget}"]`); await fillIn('[name="name"]', 'random string'); await click('.rose-form-actions [type="button"]'); + assert.strictEqual(currentURL(), urls.targets); - assert.strictEqual(getTargetCount(), count); + assert.strictEqual(getTargetCount(), targetCount); + assert.strictEqual(getTCPTargetCount(), tcpTargetCount); }); test('can cancel create new SSH target', async function (assert) { - assert.expect(2); - const count = getTargetCount(); - await visit(urls.newSSHTarget); + assert.expect(3); + const targetCount = getTargetCount(); + const sshTargetCount = getSSHTargetCount(); + await visit(urls.targets); + + await click(`[href="${urls.newTarget}"]`); await fillIn('[name="name"]', 'random string'); + await click('[value="ssh"]'); await click('.rose-form-actions [type="button"]'); + assert.strictEqual(currentURL(), urls.targets); - assert.strictEqual(getTargetCount(), count); + assert.strictEqual(getTargetCount(), targetCount); + assert.strictEqual(getSSHTargetCount(), sshTargetCount); }); test('saving a new TCP target with invalid fields displays error messages', async function (assert) { @@ -191,16 +232,12 @@ module('Acceptance | targets | create', function (hooks) { } ); }); + await visit(urls.newTCPTarget); await click('[type="submit"]'); - assert.ok( - find('[role="alert"]').textContent.trim(), - 'The request was invalid.' - ); - assert.ok( - find('.rose-form-error-message').textContent.trim(), - 'Name is required.' - ); + + assert.dom('[role="alert"] div').hasText('The request was invalid.'); + assert.dom('.rose-form-error-message').hasText('Name is required.'); }); test('saving a new SSH target with invalid fields displays error messages', async function (assert) { @@ -226,13 +263,8 @@ module('Acceptance | targets | create', function (hooks) { }); await visit(urls.newSSHTarget); await click('[type="submit"]'); - assert.ok( - find('[role="alert"]').textContent.trim(), - 'The request was invalid.' - ); - assert.ok( - find('.rose-form-error-message').textContent.trim(), - 'Name is required.' - ); + + assert.dom('[role="alert"] div').hasText('The request was invalid.'); + assert.dom('.rose-form-error-message').hasText('Name is required.'); }); }); diff --git a/ui/admin/tests/acceptance/targets/delete-test.js b/ui/admin/tests/acceptance/targets/delete-test.js index 0dc53423e..ef5e4d498 100644 --- a/ui/admin/tests/acceptance/targets/delete-test.js +++ b/ui/admin/tests/acceptance/targets/delete-test.js @@ -1,10 +1,8 @@ import { module, test } from 'qunit'; -import { visit, find, click } from '@ember/test-helpers'; +import { visit, click, currentURL } from '@ember/test-helpers'; import { setupApplicationTest } from 'ember-qunit'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; import { Response } from 'miragejs'; -import { resolve, reject } from 'rsvp'; -import sinon from 'sinon'; import { authenticateSession, // These are left here intentionally for future reference. @@ -24,9 +22,9 @@ module('Acceptance | targets | delete', function (hooks) { org: null, project: null, }, + target: null, }; const urls = { - globalScope: null, orgScope: null, projectScope: null, targets: null, @@ -49,62 +47,74 @@ module('Acceptance | targets | delete', function (hooks) { scope: instances.scopes.project, }); // 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.targets = `${urls.projectScope}/targets`; urls.target = `${urls.targets}/${instances.target.id}`; - urls.unknownTarget = `${urls.targets}/foo`; urls.newTarget = `${urls.targets}/new`; - // Generate resource couner + // Generate resource counter getTargetCount = () => this.server.schema.targets.all().models.length; authenticateSession({}); }); test('can delete target', async function (assert) { assert.expect(1); - const count = getTargetCount(); - await visit(urls.target); + const targetCount = getTargetCount(); + await visit(urls.targets); + + await click(`[href="${urls.target}"]`); await click('.rose-layout-page-actions .rose-dropdown-button-danger'); - assert.strictEqual(getTargetCount(), count - 1); + + assert.strictEqual(getTargetCount(), targetCount - 1); }); test('can accept delete target via dialog', async function (assert) { - assert.expect(2); + assert.expect(3); const confirmService = this.owner.lookup('service:confirm'); confirmService.enabled = true; - confirmService.confirm = sinon.fake.returns(resolve()); - const count = getTargetCount(); - await visit(urls.target); + const targetCount = getTargetCount(); + await visit(urls.targets); + + await click(`[href="${urls.target}"]`); await click('.rose-layout-page-actions .rose-dropdown-button-danger'); - assert.strictEqual(getTargetCount(), count - 1); - assert.ok(confirmService.confirm.calledOnce); + await click('.rose-dialog .rose-button-primary'); + + assert.dom('.rose-notification-body').hasText('Deleted successfully.'); + assert.strictEqual(getTargetCount(), targetCount - 1); + assert.strictEqual(currentURL(), urls.targets); }); test('cannot cancel delete target via dialog', async function (assert) { assert.expect(2); const confirmService = this.owner.lookup('service:confirm'); confirmService.enabled = true; - confirmService.confirm = sinon.fake.returns(reject()); - const count = getTargetCount(); - await visit(urls.target); + const targetCount = getTargetCount(); + await visit(urls.targets); + + await click(`[href="${urls.target}"]`); await click('.rose-layout-page-actions .rose-dropdown-button-danger'); - assert.strictEqual(getTargetCount(), count); - assert.ok(confirmService.confirm.calledOnce); + await click('.rose-dialog .rose-button-secondary'); + + assert.strictEqual(getTargetCount(), targetCount); + assert.strictEqual(currentURL(), urls.target); }); test('cannot delete target without proper authorization', async function (assert) { assert.expect(1); + await visit(urls.targets); instances.target.authorized_actions = instances.target.authorized_actions.filter((item) => item !== 'delete'); - await visit(urls.target); - assert.notOk( - find('.rose-layout-page-actions .rose-dropdown-button-danger') - ); + + await click(`[href="${urls.target}"]`); + + assert + .dom('.rose-layout-page-actions .rose-dropdown-button-danger') + .doesNotExist(); }); test('deleting a target which errors displays error messages', async function (assert) { assert.expect(1); + await visit(urls.targets); this.server.del('/targets/:id', () => { return new Response( 490, @@ -116,8 +126,10 @@ module('Acceptance | targets | delete', function (hooks) { } ); }); - await visit(urls.target); + + await click(`[href="${urls.target}"]`); await click('.rose-layout-page-actions .rose-dropdown-button-danger'); - assert.ok(find('[role="alert"]').textContent.trim(), 'Oops.'); + + assert.dom('.rose-notification-body').hasText('Oops.'); }); }); diff --git a/ui/admin/tests/acceptance/targets/host-sources-test.js b/ui/admin/tests/acceptance/targets/host-sources-test.js index 42426bc3b..1ad9982eb 100644 --- a/ui/admin/tests/acceptance/targets/host-sources-test.js +++ b/ui/admin/tests/acceptance/targets/host-sources-test.js @@ -1,5 +1,5 @@ import { module, test } from 'qunit'; -import { visit, currentURL, find, findAll, click } from '@ember/test-helpers'; +import { visit, currentURL, click } from '@ember/test-helpers'; import { setupApplicationTest } from 'ember-qunit'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; import a11yAudit from 'ember-a11y-testing/test-support/audit'; @@ -15,21 +15,26 @@ module('Acceptance | targets | host-sources', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); + let getTargetHostSetCount; + const instances = { scopes: { global: null, org: null, project: null, }, + target: null, + hostCatalog: null, + hostCatalogPlugin: null, }; + const urls = { - globalScope: null, orgScope: null, projectScope: null, targets: null, target: null, - targetHostSets: null, - targetAddHostSets: null, + targetHostSources: null, + targetAddHostSources: null, }; hooks.beforeEach(function () { @@ -50,7 +55,7 @@ module('Acceptance | targets | host-sources', function (hooks) { }, 'withChildren' ); - // creates "unknown" host-sets for target host sources + // creates "unknown" host-set for target host sources instances.hostCatalogPlugin = this.server.create( 'host-catalog', { @@ -65,35 +70,38 @@ module('Acceptance | targets | host-sources', function (hooks) { hostSets: instances.hostCatalog.hostSets, }); // 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.targets = `/scopes/${instances.scopes.project.id}/targets`; + urls.targets = `${urls.projectScope}/targets`; urls.target = `${urls.targets}/${instances.target.id}`; urls.targetHostSources = `${urls.target}/host-sources`; urls.targetAddHostSources = `${urls.target}/add-host-sources`; urls.hostSet = `${urls.projectScope}/host-catalogs/${instances.hostCatalog.id}/host-sets/${instances.hostCatalog.hostSetIds[0]}`; - urls.unknownHostSet = `${urls.projectScope}/host-catalogs/${instances.hostCatalogPlugin.id}/host-sets/${instances.hostCatalogPlugin.hostSetIds[0]}`; + // Generate resource counter + getTargetHostSetCount = () => + this.server.schema.targets.first().hostSets.models.length; authenticateSession({}); }); test('visiting target host sources', async function (assert) { - assert.expect(3); - const targetHostSetCount = instances.target.hostSets.length; - await visit(urls.targetHostSources); + assert.expect(2); + const targetHostSetCount = getTargetHostSetCount(); + await visit(urls.target); + + await click(`[href="${urls.targetHostSources}"]`); await a11yAudit(); + assert.strictEqual(currentURL(), urls.targetHostSources); - assert.ok(targetHostSetCount); - assert.strictEqual(findAll('tbody tr').length, targetHostSetCount); + assert.dom('tbody tr').exists({ count: targetHostSetCount }); }); test('can navigate to a known host set type', async function (assert) { assert.expect(1); await visit(urls.targetHostSources); - await click( - `main tbody .rose-table-header-cell:nth-child(1) a[href="${urls.hostSet}"]` - ); + + await click(`[href="${urls.hostSet}"]`); await a11yAudit(); + assert.strictEqual(currentURL(), urls.hostSet); }); @@ -102,22 +110,23 @@ module('Acceptance | targets | host-sources', function (hooks) { instances.target.update({ hostSets: instances.hostCatalogPlugin.hostSets, }); + await visit(urls.target); - await visit(urls.targetHostSources); - assert - .dom( - `main tbody .rose-table-header-cell:nth-child(1) a [href="${urls.unknownHostSet}"]` - ) - .doesNotExist(); + await click(`[href="${urls.targetHostSources}"]`); + + assert.dom('.rose-table-body tr:first-child a').doesNotExist(); }); test('can remove a host set', async function (assert) { assert.expect(2); - const targetHostSetCount = instances.target.hostSets.length; - await visit(urls.targetHostSources); - assert.strictEqual(findAll('tbody tr').length, targetHostSetCount); + const targetHostSetCount = getTargetHostSetCount(); + await visit(urls.target); + + await click(`[href="${urls.targetHostSources}"]`); await click('tbody tr .rose-dropdown-button-danger'); - assert.strictEqual(findAll('tbody tr').length, targetHostSetCount - 1); + + assert.strictEqual(getTargetHostSetCount(), targetHostSetCount - 1); + assert.dom('tbody tr').exists({ count: targetHostSetCount - 1 }); }); test('cannot remove a host set without proper authorization', async function (assert) { @@ -126,8 +135,11 @@ module('Acceptance | targets | host-sources', function (hooks) { instances.target.authorized_actions.filter( (item) => item !== 'remove-host-sources' ); - await visit(urls.targetHostSources); - assert.notOk(find('tbody tr .rose-dropdown-button-danger')); + await visit(urls.target); + + await click(`[href="${urls.targetHostSources}"]`); + + assert.dom('tbody tr .rose-dropdown-button-danger').doesNotExist(); }); test('removing a target host set which errors displays error messages', async function (assert) { @@ -144,27 +156,36 @@ module('Acceptance | targets | host-sources', function (hooks) { } ); }); - const targetHostSetCount = instances.target.hostSets.length; - await visit(urls.targetHostSources); - assert.strictEqual(findAll('tbody tr').length, targetHostSetCount); + const targetHostSetCount = getTargetHostSetCount(); + await visit(urls.target); + + await click(`[href="${urls.targetHostSources}"]`); await click('tbody tr .rose-dropdown-button-danger'); - assert.ok(find('[role="alert"]')); + + assert.dom('tbody tr').exists({ count: targetHostSetCount }); + assert.dom('[role="alert"] div').hasText('The request was invalid.'); }); test('select and save host sets to add', async function (assert) { - assert.expect(3); + assert.expect(4); instances.target.update({ hostSetIds: [] }); - await visit(urls.targetHostSources); - assert.strictEqual(findAll('tbody tr').length, 0); + await visit(urls.target); + const targetHostSetCount = getTargetHostSetCount(); + + await click(`[href="${urls.targetHostSources}"]`); + assert.dom('tbody tr').exists({ count: 0 }); await click('.rose-layout-page-actions a'); assert.strictEqual(currentURL(), urls.targetAddHostSources); + // Click three times to select, unselect, then reselect (for coverage) await click('tbody label'); await click('tbody label'); await click('tbody label'); await click('form [type="submit"]'); - await visit(urls.targetHostSources); - assert.strictEqual(findAll('tbody tr').length, 1); + await click(`[href="${urls.targetHostSources}"]`); + + assert.strictEqual(getTargetHostSetCount(), targetHostSetCount + 1); + assert.dom('tbody tr').exists({ count: targetHostSetCount + 1 }); }); test('cannot add host sources without proper authorization', async function (assert) { @@ -173,24 +194,35 @@ module('Acceptance | targets | host-sources', function (hooks) { instances.target.authorized_actions.filter( (item) => item !== 'add-host-sources' ); - await visit(urls.targetHostSources); - assert.notOk(find(`[href="${urls.addHostSources}"]`)); + await visit(urls.target); + + await click(`[href="${urls.targetHostSources}"]`); + + assert + .dom('.rose-layout-page-actions a') + .doesNotIncludeText('Add Host Sources'); }); test('select and cancel host sets to add', async function (assert) { - assert.expect(4); - const targetHostSetCount = instances.target.hostSets.length; - await visit(urls.targetHostSources); - assert.strictEqual(findAll('tbody tr').length, targetHostSetCount); + assert.expect(6); + const targetHostSetCount = getTargetHostSetCount(); + await visit(urls.target); + + await click(`[href="${urls.targetHostSources}"]`); + assert.dom('tbody tr').exists({ count: targetHostSetCount }); + // first, remove a target host set (otherwise none would be available to add) await click('tbody tr .rose-dropdown-button-danger'); - assert.strictEqual(findAll('tbody tr').length, targetHostSetCount - 1); + assert.dom('tbody tr').exists({ count: targetHostSetCount - 1 }); + await click('.rose-layout-page-actions a'); assert.strictEqual(currentURL(), urls.targetAddHostSources); await click('tbody label'); await click('form [type="button"]'); - await visit(urls.targetHostSources); - assert.strictEqual(findAll('tbody tr').length, targetHostSetCount - 1); + + assert.strictEqual(currentURL(), urls.targetHostSources); + assert.dom('tbody tr').exists({ count: targetHostSetCount - 1 }); + assert.strictEqual(getTargetHostSetCount(), targetHostSetCount - 1); }); test('adding a target host set which errors displays error messages', async function (assert) { @@ -207,13 +239,17 @@ module('Acceptance | targets | host-sources', function (hooks) { } ); }); + await visit(urls.targetHostSources); instances.target.update({ hostSetIds: [] }); - await visit(urls.targetAddHostSources); - assert.strictEqual(instances.target.hostSets.length, 0); - assert.strictEqual(currentURL(), urls.targetAddHostSources); + const targetHostSetCount = getTargetHostSetCount(); + + await click(`[href="${urls.targetAddHostSources}"]`); + assert.strictEqual(targetHostSetCount, 0); await click('tbody label'); await click('form [type="submit"]'); + assert.strictEqual(currentURL(), urls.targetAddHostSources); - assert.strictEqual(instances.target.hostSets.length, 0); + assert.strictEqual(getTargetHostSetCount(), targetHostSetCount); + assert.dom('[role="alert"] div').hasText('The request was invalid.'); }); }); diff --git a/ui/admin/tests/acceptance/targets/list-test.js b/ui/admin/tests/acceptance/targets/list-test.js index 19bd4ee64..a02241826 100644 --- a/ui/admin/tests/acceptance/targets/list-test.js +++ b/ui/admin/tests/acceptance/targets/list-test.js @@ -1,5 +1,5 @@ import { module, test } from 'qunit'; -import { visit, find } from '@ember/test-helpers'; +import { visit, click } from '@ember/test-helpers'; import { setupApplicationTest } from 'ember-qunit'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; import { @@ -17,68 +17,120 @@ module('Acceptance | targets | list', function (hooks) { scopes: { global: null, org: null, + project: null, }, - orgScope: null, + target: null, }; const urls = { - scopes: { - org: null, - project: null, - }, - targets: null, + orgScope: null, projectScope: null, + targets: null, }; hooks.beforeEach(function () { instances.scopes.global = this.server.create('scope', { id: 'global' }); - instances.orgScope = this.server.create( - 'scope', - { - type: 'org', - scope: { id: 'global', type: 'global' }, - }, - 'withChildren' - ); + instances.scopes.org = this.server.create('scope', { + type: 'org', + scope: { id: 'global', type: 'global' }, + }); instances.scopes.project = this.server.create('scope', { type: 'project', - scope: { id: instances.orgScope.id, type: 'org' }, + scope: { id: instances.scopes.org.id, type: 'org' }, }); instances.target = this.server.create('target', { scope: instances.scopes.project, }); + urls.orgScope = `/scopes/${instances.scopes.org.id}/scopes`; urls.projectScope = `/scopes/${instances.scopes.project.id}`; urls.targets = `${urls.projectScope}/targets`; authenticateSession({}); }); test('can navigate to targets with proper authorization', async function (assert) { - assert.expect(2); - await visit(urls.projectScope); - assert.ok( + assert.expect(3); + await visit(urls.orgScope); + + await click(`[href="${urls.projectScope}"]`); + + assert.true( instances.scopes.project.authorized_collection_actions.targets.includes( 'list' ) ); - assert.ok(find(`[href="${urls.targets}"]`)); + assert.true( + instances.scopes.project.authorized_collection_actions.targets.includes( + 'create' + ) + ); + assert.dom(`[href="${urls.targets}"]`).exists(); }); - test('User cannot navigate to index without either list or create actions', async function (assert) { - assert.expect(2); + test('user cannot navigate to index without either list or create actions', async function (assert) { + assert.expect(3); instances.scopes.project.authorized_collection_actions.targets = []; - await visit(urls.projectScope); - assert.notOk( + await visit(urls.orgScope); + + await click(`[href="${urls.projectScope}"]`); + + assert.false( instances.scopes.project.authorized_collection_actions.targets.includes( 'list' ) ); - assert.notOk(find(`[href="${urls.targets}"]`)); + assert.false( + instances.scopes.project.authorized_collection_actions.targets.includes( + 'create' + ) + ); + assert + .dom('[title="Resources"] a:nth-of-type(2)') + .doesNotIncludeText('Targets'); }); - test('User can navigate to index with only create action', async function (assert) { - assert.expect(1); - instances.scopes.project.authorized_collection_actions.targets = ['create']; - await visit(urls.projectScope); - assert.ok(find(`[href="${urls.targets}"]`)); + test('user can navigate to index with only create action', async function (assert) { + assert.expect(3); + instances.scopes.project.authorized_collection_actions.targets = + instances.scopes.project.authorized_collection_actions.targets.filter( + (item) => item !== 'list' + ); + await visit(urls.orgScope); + + await click(`[href="${urls.projectScope}"]`); + + assert.true( + instances.scopes.project.authorized_collection_actions.targets.includes( + 'create' + ) + ); + assert.false( + instances.scopes.project.authorized_collection_actions.targets.includes( + 'list' + ) + ); + assert.dom(`[href="${urls.targets}"]`).exists(); + }); + + test('user can navigate to index with only list action', async function (assert) { + assert.expect(3); + instances.scopes.project.authorized_collection_actions.targets = + instances.scopes.project.authorized_collection_actions.targets.filter( + (item) => item !== 'create' + ); + await visit(urls.orgScope); + + await click(`[href="${urls.projectScope}"]`); + + assert.false( + instances.scopes.project.authorized_collection_actions.targets.includes( + 'create' + ) + ); + assert.true( + instances.scopes.project.authorized_collection_actions.targets.includes( + 'list' + ) + ); + assert.dom(`[href="${urls.targets}"]`).exists(); }); }); diff --git a/ui/admin/tests/acceptance/targets/update-test.js b/ui/admin/tests/acceptance/targets/update-test.js index f034a21e6..623f42b6b 100644 --- a/ui/admin/tests/acceptance/targets/update-test.js +++ b/ui/admin/tests/acceptance/targets/update-test.js @@ -1,5 +1,5 @@ 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 'ember-qunit'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; import { Response } from 'miragejs'; @@ -20,9 +20,9 @@ module('Acceptance | targets | update', function (hooks) { org: null, project: null, }, + target: null, }; const urls = { - globalScope: null, orgScope: null, projectScope: null, targets: null, @@ -45,82 +45,55 @@ module('Acceptance | targets | update', function (hooks) { scope: instances.scopes.project, }); // 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.targets = `${urls.projectScope}/targets`; urls.target = `${urls.targets}/${instances.target.id}`; urls.unknownTarget = `${urls.targets}/foo`; urls.newTarget = `${urls.targets}/new`; - // Generate resource couner - authenticateSession({}); - }); - test('saving a new target with invalid fields displays error messages', async function (assert) { - assert.expect(2); - this.server.post('/targets', () => { - return new Response( - 400, - {}, - { - status: 400, - code: 'invalid_argument', - message: 'The request was invalid.', - details: { - request_fields: [ - { - name: 'name', - description: 'Name is required.', - }, - ], - }, - } - ); - }); - await visit(urls.newTarget); - await click('[type="submit"]'); - assert.ok( - find('[role="alert"]').textContent.trim(), - 'The request was invalid.' - ); - assert.ok( - find('.rose-form-error-message').textContent.trim(), - 'Name is required.' - ); + authenticateSession({}); }); test('can save changes to existing target', async function (assert) { assert.expect(5); + await visit(urls.targets); assert.notEqual(instances.target.name, 'random string'); assert.notEqual(instances.target.worker_filter, 'random filter'); - await visit(urls.target); + + await click(`[href="${urls.target}"]`); await click('form [type="button"]', 'Activate edit mode'); await fillIn('[name="name"]', 'random string'); await fillIn('[name="worker_filter"]', 'random filter'); await click('.rose-form-actions [type="submit"]'); + assert.strictEqual(currentURL(), urls.target); assert.strictEqual( - this.server.schema.targets.all().models[0].name, + this.server.schema.targets.first().name, 'random string' ); assert.strictEqual( - this.server.schema.targets.all().models[0].workerFilter, + this.server.schema.targets.first().workerFilter, 'random filter' ); }); test('can cancel changes to existing target', async function (assert) { assert.expect(2); - await visit(urls.target); + await visit(urls.targets); + + await click(`[href="${urls.target}"]`); await click('form [type="button"]', 'Activate edit mode'); await fillIn('[name="name"]', 'random string'); await click('.rose-form-actions [type="button"]'); + assert.notEqual(instances.target.name, 'random string'); - assert.strictEqual(find('[name="name"]').value, instances.target.name); + assert.dom('[name="name"]').hasValue(instances.target.name); }); test('saving an existing target with invalid fields displays error messages', async function (assert) { assert.expect(2); + await visit(urls.targets); this.server.patch('/targets/:id', () => { return new Response( 400, @@ -140,18 +113,14 @@ module('Acceptance | targets | update', function (hooks) { } ); }); - await visit(urls.target); + + await click(`[href="${urls.target}"]`); await click('form [type="button"]', 'Activate edit mode'); await fillIn('[name="name"]', 'random string'); await click('[type="submit"]'); - assert.ok( - find('[role="alert"]').textContent.trim(), - 'The request was invalid.' - ); - assert.ok( - find('.rose-form-error-message').textContent.trim(), - 'Name is required.' - ); + + assert.dom('[role="alert"] div').hasText('The request was invalid.'); + assert.dom('.rose-form-error-message').hasText('Name is required.'); }); test('can discard unsaved target changes via dialog', async function (assert) { @@ -159,50 +128,47 @@ module('Acceptance | targets | update', function (hooks) { const confirmService = this.owner.lookup('service:confirm'); confirmService.enabled = true; assert.notEqual(instances.target.name, 'random string'); - await visit(urls.target); + await visit(urls.targets); + + await click(`[href="${urls.target}"]`); await click('form [type="button"]', 'Activate edit mode'); await fillIn('[name="name"]', 'random string'); assert.strictEqual(currentURL(), urls.target); - try { - await visit(urls.targets); - } catch (e) { - assert.ok(find('.rose-dialog')); - await click('.rose-dialog-footer button:first-child'); - assert.strictEqual(currentURL(), urls.targets); - assert.notEqual( - this.server.schema.targets.all().models[0].name, - 'random string' - ); - } + await click(`[href="${urls.targets}"]`); + assert.dom('.rose-dialog').exists(); + await click('.rose-dialog-footer button:first-child', 'Click Discard'); + + assert.strictEqual(currentURL(), urls.targets); + assert.notEqual(this.server.schema.targets.first().name, 'random string'); }); - test('can cancel discard unsaved target changes via dialog', async function (assert) { + test('can click cancel on discard dialog box for unsaved target changes', async function (assert) { assert.expect(5); const confirmService = this.owner.lookup('service:confirm'); confirmService.enabled = true; assert.notEqual(instances.target.name, 'random string'); - await visit(urls.target); + await visit(urls.targets); + + await click(`[href="${urls.target}"]`); await click('form [type="button"]', 'Activate edit mode'); await fillIn('[name="name"]', 'random string'); assert.strictEqual(currentURL(), urls.target); - try { - await visit(urls.targets); - } catch (e) { - assert.ok(find('.rose-dialog')); - await click('.rose-dialog-footer button:last-child'); - assert.strictEqual(currentURL(), urls.target); - assert.notEqual( - this.server.schema.targets.all().models[0].name, - 'random string' - ); - } + await click(`[href="${urls.targets}"]`); + assert.dom('.rose-dialog').exists(); + await click('.rose-dialog-footer button:last-child', 'Click Cancel'); + + assert.strictEqual(currentURL(), urls.target); + assert.notEqual(this.server.schema.targets.first().name, 'random string'); }); test('cannot make changes to an existing target without proper authorization', async function (assert) { assert.expect(1); + await visit(urls.targets); instances.target.authorized_actions = instances.target.authorized_actions.filter((item) => item !== 'update'); - await visit(urls.target); - assert.notOk(find('.rose-layout-page-actions .rose-button-secondary')); + + await click(`[href="${urls.target}"]`); + + assert.dom('form [type="button"]').doesNotExist(); }); });