From 9c93ff6c131d531c640da3e6f02e2ba28833841d Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Fri, 16 Jul 2021 13:55:33 -0700 Subject: [PATCH 1/4] =?UTF-8?q?test:=20=F0=9F=92=8D=20Add=20test=20cases?= =?UTF-8?q?=20to=20credential=20stores=20route?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add new test cases to credential stores route --- .../acceptance/credential-stores-test.js | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/ui/admin/tests/acceptance/credential-stores-test.js b/ui/admin/tests/acceptance/credential-stores-test.js index b62c0f3fe..4a8f46177 100644 --- a/ui/admin/tests/acceptance/credential-stores-test.js +++ b/ui/admin/tests/acceptance/credential-stores-test.js @@ -1,13 +1,16 @@ import { module, test } from 'qunit'; -import { visit, currentURL } 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 a11yAudit from 'ember-a11y-testing/test-support/audit'; +import { authenticateSession } from 'ember-simple-auth/test-support'; module('Acceptance | credential-stores', function (hooks) { setupApplicationTest(hooks); setupMirage(hooks); + let getCredentialStoresCount; + const instances = { scopes: { global: null, @@ -32,17 +35,40 @@ module('Acceptance | credential-stores', function (hooks) { type: 'project', scope: { id: instances.scopes.org.id, type: 'org' }, }); + instances.credentialStore = this.server.create('credential-store', { + 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.credentialStores = `${urls.projectScope}/credential-stores`; + urls.credentialStore = `${urls.credentialStores}/${instances.credentialStore.id}`; + urls.unknownCredentialStore = `${urls.credentialStores}/foo`; + urls.newCredentialStore = `${urls.credentialStores}/new`; + // Generate resource counter + getCredentialStoresCount = () => { + return this.server.schema.credentialStores.all().models.length; + }; + authenticateSession({}); }); test('visiting /credential-stores', async function (assert) { - assert.expect(1); + assert.expect(2); await visit(urls.credentialStores); await a11yAudit(); assert.equal(currentURL(), urls.credentialStores); + await visit(urls.credentialStore); + await a11yAudit(); + assert.equal(currentURL(), urls.credentialStore); + }); + + test('can create a new credential store', async function (assert) { + assert.expect(1); + const count = getCredentialStoresCount(); + await visit(urls.newCredentialStore); + await fillIn('[name="name"]', 'random string'); + await click('[type="submit"]'); + assert.equal(getCredentialStoresCount(), count + 1); }); }); From 44510ea8d4d601e1bff600ac4a43cf32fb397605 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Mon, 19 Jul 2021 14:16:40 -0700 Subject: [PATCH 2/4] =?UTF-8?q?test:=20=F0=9F=92=8D=20Adding=20integration?= =?UTF-8?q?=20test=20for=20credential=20stores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding more integration test cases for credential stores --- .../acceptance/credential-stores-test.js | 145 +++++++++++++++++- 1 file changed, 143 insertions(+), 2 deletions(-) diff --git a/ui/admin/tests/acceptance/credential-stores-test.js b/ui/admin/tests/acceptance/credential-stores-test.js index 4a8f46177..1a79f6bc5 100644 --- a/ui/admin/tests/acceptance/credential-stores-test.js +++ b/ui/admin/tests/acceptance/credential-stores-test.js @@ -1,5 +1,5 @@ import { module, test } from 'qunit'; -import { visit, currentURL, click, fillIn } from '@ember/test-helpers'; +import { visit, currentURL, find, click, fillIn } 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'; @@ -21,7 +21,12 @@ module('Acceptance | credential-stores', function (hooks) { const urls = { globalScope: null, + orgScope: null, + projectScope: null, credentialStores: null, + credentialStore: null, + unknownCredentialStore: null, + newCredentialStore: null, }; hooks.beforeEach(function () { @@ -63,7 +68,14 @@ module('Acceptance | credential-stores', function (hooks) { assert.equal(currentURL(), urls.credentialStore); }); - test('can create a new credential store', async function (assert) { + test.skip('visiting an unknown credential store display 404 message', async function (assert) { + assert.expect(1); + await visit(urls.unknownCredentialStore); + await a11yAudit(); + assert.ok(find('.rose-message-subtitle').textContent.trim(), 'Error 404'); + }); + + test('can create a new credential stores', async function (assert) { assert.expect(1); const count = getCredentialStoresCount(); await visit(urls.newCredentialStore); @@ -71,4 +83,133 @@ module('Acceptance | credential-stores', function (hooks) { await click('[type="submit"]'); assert.equal(getCredentialStoresCount(), count + 1); }); + + test('can cancel create new credential stores', async function (assert) { + assert.expect(2); + const count = getCredentialStoresCount(); + await visit(urls.newCredentialStore); + await fillIn('[name="name"]', 'random string'); + await click('.rose-form-actions [type="button"]'); + assert.equal(currentURL(), urls.credentialStores); + assert.equal(getCredentialStoresCount(), count); + }); + + // Skip this test for now. The request is successful + // but we are expecting to not be. + test.skip('saving a new credential store with invalid fields displays error messages', async function (assert) { + assert.expect(2); + this.server.post('/credential-stores', () => { + 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.newCredentialStore); + await click('form [type="submit"]', 'Click new'); // Issue starts here + assert.ok( + find('[role="alert"]').textContent.trim(), + 'The request was invalid.' + ); + assert.ok( + find('.rose-form-error-message').textContent.trim(), + 'Name is required.' + ); + }); + + test('can save changes to existing credential store', async function (assert) { + assert.expect(3); + assert.notEqual(instances.credentialStore.name, 'random string'); + await visit(urls.credentialStore); + await click('form [type="button"]', 'Activate edit mode'); + await fillIn('[name="name"]', 'random string'); + await click('.rose-form-actions [type="submit"]'); + assert.equal(currentURL(), urls.credentialStore); + assert.equal( + this.server.schema.credentialStores.all().models[0].name, + 'random string' + ); + }); + + test('can cancel changes to existing credential store', async function (assert) { + assert.expect(2); + await visit(urls.credentialStore); + await click('form [type="button"]', 'Activate edit mode'); + await fillIn('[name="name"]', 'random string'); + await click('.rose-form-actions [type="button"]'); + assert.notEqual(instances.credentialStore.name, 'random string'); + assert.equal(find('[name="name"]').value, instances.credentialStore.name); + }); + + // Skip this test for now. The request is successful + // but we are expecting to not be. + test.skip('saving an existing credential store with invalid fields displays error messages', async function (assert) { + assert.expect(2); + this.server.patch('/credential-stores/:id', () => { + 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.credentialStore); + 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.' + ); + }); + + test.skip('can discard unsaved credential store changes via dialog', async function (assert) { + assert.expect(5); + const confirmService = this.owner.lookup('service:confirm'); + confirmService.enabled = true; + assert.notEqual(instances.credentialStore.name, 'random string'); + + await visit(urls.credentialStore); + await click('form [type="button"]', 'Activate edit mode'); + assert.equal(currentURL(), urls.credentialStore); + + try { + await visit(urls.credentialStores); + } catch (e) { + assert.ok(find('.rose-dialog')); + await click('.rose-dialog-footer button:first-child'); + assert.equal(currentURL(), urls.credentialStores); + assert.notEqual( + this.server.schema.credentialStores.all().models[0].name, + 'random string' + ); + } + }); }); From f69477e55647b80b2f8017f71519149d5c7b5555 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Tue, 20 Jul 2021 10:36:34 -0700 Subject: [PATCH 3/4] =?UTF-8?q?test:=20=F0=9F=92=8D=20Add=20credential=20s?= =?UTF-8?q?tores=20create=20and=20edit=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add credential store create and edit acceptance tests --- .../form/credential-store/index.hbs | 27 +++++++++++- .../acceptance/credential-stores-test.js | 41 +++++++++++++++---- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/ui/admin/app/components/form/credential-store/index.hbs b/ui/admin/app/components/form/credential-store/index.hbs index f972854c1..b70183ed3 100644 --- a/ui/admin/app/components/form/credential-store/index.hbs +++ b/ui/admin/app/components/form/credential-store/index.hbs @@ -2,6 +2,7 @@ @onSubmit={{@submit}} @cancel={{@cancel}} @disabled={{@model.isSaving}} + @error={{@model.errors.base}} @showEditToggle={{if @model.isNew false true}} as |form| > @@ -18,16 +19,38 @@ @value={{@model.name}} @label={{t 'form.name.label'}} @helperText={{t 'form.name.help'}} + @error={{@model.errors.name}} readonly={{false}} - /> + as |field| + > + {{#if @model.errors.name}} + + {{#each @model.errors.name as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + disabled={{@model.isSaving}} + readonly={{false}} + as |field| + > + {{#if @model.errors.description}} + + {{#each @model.errors.description as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + { return new Response( @@ -118,7 +119,7 @@ module('Acceptance | credential-stores', function (hooks) { ); }); await visit(urls.newCredentialStore); - await click('form [type="submit"]', 'Click new'); // Issue starts here + await click('[type="submit"]'); assert.ok( find('[role="alert"]').textContent.trim(), 'The request was invalid.' @@ -153,9 +154,7 @@ module('Acceptance | credential-stores', function (hooks) { assert.equal(find('[name="name"]').value, instances.credentialStore.name); }); - // Skip this test for now. The request is successful - // but we are expecting to not be. - test.skip('saving an existing credential store with invalid fields displays error messages', async function (assert) { + test('saving an existing credential store with invalid fields displays error messages', async function (assert) { assert.expect(2); this.server.patch('/credential-stores/:id', () => { return new Response( @@ -190,7 +189,7 @@ module('Acceptance | credential-stores', function (hooks) { ); }); - test.skip('can discard unsaved credential store changes via dialog', async function (assert) { + test('can discard unsaved credential store changes via dialog', async function (assert) { assert.expect(5); const confirmService = this.owner.lookup('service:confirm'); confirmService.enabled = true; @@ -198,13 +197,14 @@ module('Acceptance | credential-stores', function (hooks) { await visit(urls.credentialStore); await click('form [type="button"]', 'Activate edit mode'); + await fillIn('[name="name"]', 'random string'); assert.equal(currentURL(), urls.credentialStore); try { await visit(urls.credentialStores); } catch (e) { assert.ok(find('.rose-dialog')); - await click('.rose-dialog-footer button:first-child'); + await click('.rose-dialog-footer button:first-child', 'Click Discard'); assert.equal(currentURL(), urls.credentialStores); assert.notEqual( this.server.schema.credentialStores.all().models[0].name, @@ -212,4 +212,27 @@ module('Acceptance | credential-stores', function (hooks) { ); } }); + + test('can cancel discard unsaved credential store via dialog', async function (assert) { + assert.expect(5); + const confirmService = this.owner.lookup('service:confirm'); + confirmService.enabled = true; + assert.notEqual(instances.credentialStore.name, 'random string'); + await visit(urls.credentialStore); + await click('form [type="button"]', 'Activate edit mode'); + await fillIn('[name="name"]', 'random string'); + assert.equal(currentURL(), urls.credentialStore); + + try { + await visit(urls.credentialStores); + } catch (e) { + assert.ok(find('.rose-dialog')); + await click('.rose-dialog-footer button:last-child'); + assert.equal(currentURL(), urls.credentialStore); + assert.notEqual( + this.server.schema.credentialStores.all().models[0].name, + 'random string' + ); + } + }); }); From d96d7425f8d91f949f4aec20594c7ccc15c185bf Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Wed, 21 Jul 2021 10:36:16 -0700 Subject: [PATCH 4/4] Fix skip test with false positive --- ui/admin/tests/acceptance/credential-stores-test.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ui/admin/tests/acceptance/credential-stores-test.js b/ui/admin/tests/acceptance/credential-stores-test.js index 7507f5ba8..f41d31a12 100644 --- a/ui/admin/tests/acceptance/credential-stores-test.js +++ b/ui/admin/tests/acceptance/credential-stores-test.js @@ -69,13 +69,14 @@ module('Acceptance | credential-stores', function (hooks) { assert.equal(currentURL(), urls.credentialStore); }); - // This test is returning an issue regarding not finding resource. - // It is a false positive. - test.skip('visiting an unknown credential store display 404 message', async function (assert) { + test('visiting an unknown credential store display 404 message', async function (assert) { assert.expect(1); await visit(urls.unknownCredentialStore); await a11yAudit(); - assert.ok(find('.rose-message-subtitle').textContent.trim(), 'Error 404'); + assert.equal( + find('.rose-message-subtitle').textContent.trim(), + 'Error 404' + ); }); test('can create a new credential stores', async function (assert) {