Icu-11111 don't display empty modal when a target has no target address and no host sources (#1909)

* fix: 🐛 disable connect buttons & add message

✅ Closes: ICU-11111

* test: 💍 add test cases

* fix: 🐛 buttons on list view & add getter to target model

* refactor: 💡 use can ability instead and remove Promise.all

* test: 💍 fix expect number
This commit is contained in:
Lisbet Alvarez authored and Zhihe Li committed 2023-09-22 18:58:15 -04:00
1 parent 3d0a57d459
commit 3740bb079a
5 files changed
+121 -24

No files matched your search

@@ -551,6 +551,9 @@ target:
connect-more-info:
title: Connect for more info
description: Additional information for this target will be provided here after your session is established.
cannot-connect:
title: Cannot connect to {targetDisplayName}
description: No host sources and no target address found. Please update target with address information to connect directly. Otherwise, add at least one host to connect using host sources.
titles:
new: New Target
actions:
+16
View File
@@ -0,0 +1,16 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
import TargetAbility from 'api/abilities/target';
export default class OverrideTargetAbility extends TargetAbility {
/**
*
* @type {boolean}
*/
get canInitiateConnection() {
return this.model.address || this.model.host_sources?.length;
}
}
@@ -15,34 +15,51 @@
</page.header>
<page.actions>
<Hds::Button
data-test-target-detail-connect-button
@text={{t 'resources.session.actions.connect'}}
@icon='entry-point'
@iconPosition='trailing'
{{on 'click' (route-action 'preConnect' @model this.toggle)}}
/>
{{#if (can 'connect target' @model.target)}}
<Hds::Button
data-test-target-detail-connect-button
@text={{t 'resources.session.actions.connect'}}
@icon='entry-point'
@iconPosition='trailing'
disabled={{not (can 'initiateConnection target' @model.target)}}
{{on 'click' (route-action 'preConnect' @model this.toggle)}}
/>
{{/if}}
</page.actions>
<page.body class='details-screen-body'>
<Rose::Layout::BodyContent as |bc|>
<Target::HostModal
@showModal={{this.isConnecting}}
@toggle={{this.toggle}}
@connect={{route-action 'connect'}}
@hosts={{@model.hosts}}
@target={{@model.target}}
/>
{{#if (can 'initiateConnection target' @model.target)}}
<Target::HostModal
@showModal={{this.isConnecting}}
@toggle={{this.toggle}}
@connect={{route-action 'connect'}}
@hosts={{@model.hosts}}
@target={{@model.target}}
/>
{{/if}}
<bc.Body class='target-details-body'>
<Hds::ApplicationState as |A|>
<A.Header
@title={{t 'resources.target.messages.connect-more-info.title'}}
/>
<A.Body
@text={{t
'resources.target.messages.connect-more-info.description'
}}
/>
{{#if (can 'initiateConnection target' @model.target)}}
<A.Header
@title={{t 'resources.target.messages.connect-more-info.title'}}
/>
<A.Body
@text={{t
'resources.target.messages.connect-more-info.description'
}}
/>
{{else}}
<A.Header
@title={{t
'resources.target.messages.cannot-connect.title'
targetDisplayName=@model.target.displayName
}}
/>
<A.Body
@text={{t 'resources.target.messages.cannot-connect.description'}}
/>
{{/if}}
</Hds::ApplicationState>
</bc.Body>
<bc.Sidebar>
+33 -2
View File
@@ -4,7 +4,7 @@
*/
import { module, test } from 'qunit';
import { visit, currentURL } 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 a11yAudit from 'ember-a11y-testing/test-support/audit';
@@ -19,6 +19,9 @@ module('Acceptance | targets', function (hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
const TARGET_CONNECT_BUTTON = '[data-test-target-detail-connect-button]';
const APP_STATE_TITLE = '.hds-application-state__title';
const instances = {
scopes: {
global: null,
@@ -29,6 +32,7 @@ module('Acceptance | targets', function (hooks) {
global: null,
},
target: null,
emptyTarget: null,
};
const stubs = {
@@ -49,6 +53,8 @@ module('Acceptance | targets', function (hooks) {
},
projects: null,
targets: null,
target: null,
emptyTarget: null,
};
const setDefaultClusterUrl = (test) => {
@@ -85,9 +91,12 @@ module('Acceptance | targets', function (hooks) {
);
instances.target = this.server.create(
'target',
{ scope: instances.scopes.project },
{ scope: instances.scopes.project, address: '127.0.0.1' },
'withAssociations'
);
instances.emptyTarget = this.server.create('target', {
scope: instances.scopes.project,
});
urls.scopes.global = `/scopes/${instances.scopes.global.id}`;
urls.scopes.org = `/scopes/${instances.scopes.org.id}`;
@@ -95,6 +104,8 @@ module('Acceptance | targets', function (hooks) {
urls.authenticate.methods.global = `${urls.authenticate.global}/${instances.authMethods.global.id}`;
urls.projects = `${urls.scopes.org}/projects`;
urls.targets = `${urls.projects}/targets`;
urls.target = `${urls.targets}/${instances.target.id}`;
urls.emptyTarget = `${urls.targets}/${instances.emptyTarget.id}`;
// Mock the postMessage interface used by IPC.
this.owner.register('service:browser/window', WindowMockIPC);
@@ -115,4 +126,24 @@ module('Acceptance | targets', function (hooks) {
await visit(urls.targets);
assert.strictEqual(currentURL(), urls.targets);
});
test('cannot connect to a target without an address and no host sources', async function (assert) {
assert.expect(2);
await visit(urls.targets);
await click(`[href="${urls.emptyTarget}"]`);
assert.dom(TARGET_CONNECT_BUTTON).isDisabled();
assert.dom(APP_STATE_TITLE).includesText('Cannot connect');
});
test('can connect to a target with an address', async function (assert) {
assert.expect(2);
await visit(urls.targets);
await click(`[href="${urls.target}"]`);
assert.dom(TARGET_CONNECT_BUTTON).isEnabled();
assert.dom(APP_STATE_TITLE).includesText('Connect for more info');
});
});
@@ -0,0 +1,30 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Abilities | target', function (hooks) {
setupTest(hooks);
test('it reflects when a target can initiate connection or not', function (assert) {
assert.expect(5);
const service = this.owner.lookup('service:can');
const model = {
address: '',
};
assert.false(service.can('initiateConnection target', model));
model.host_sources = [];
assert.false(service.can('initiateConnection target', model));
model.address = 'localhost';
assert.true(service.can('initiateConnection target', model));
model.address = '';
model.host_sources = ['host_123'];
assert.true(service.can('initiateConnection target', model));
model.address = 'localhost';
model.host_sources = ['host_123'];
assert.true(service.can('initiateConnection target', model));
});
});