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:
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:
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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));
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user