chore: 🤖 rdp desktop changes
This commit is contained in:
1 parent
42e32f9568
commit
4a179ac3e3
9 files changed
+452
-248
No files matched your search
@@ -369,6 +369,7 @@ session:
|
||||
proxy-url:
|
||||
address-port: Address & port
|
||||
ssh: SSH
|
||||
rdp: RDP
|
||||
shell: Shell
|
||||
global:
|
||||
title: Global
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
{{!
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
}}
|
||||
|
||||
<Rose::Layout::BodyContent data-test-session-details as |bc|>
|
||||
<bc.Body>
|
||||
{{#if @model.credentials}}
|
||||
<CredentialsPanel @credentials={{@model.credentials}} />
|
||||
{{else}}
|
||||
<Hds::ApplicationState data-test-no-credentials as |A|>
|
||||
<A.Header @title={{t 'resources.session.messages.connected.title'}} />
|
||||
<A.Body
|
||||
@text={{t
|
||||
'resources.session.messages.connected.description'
|
||||
targetDisplayName=@model.target.displayName
|
||||
}}
|
||||
/>
|
||||
</Hds::ApplicationState>
|
||||
{{/if}}
|
||||
</bc.Body>
|
||||
|
||||
{{#if (or @model.host @model.target)}}
|
||||
<bc.Sidebar>
|
||||
<div class='details-sidebar'>
|
||||
{{#if @model.host}}
|
||||
<div
|
||||
class='title hds-typography-display-200 hds-font-weight-semibold'
|
||||
>
|
||||
{{t 'resources.host.details'}}
|
||||
</div>
|
||||
<Rose::MetadataList @orientation='vertical' as |list|>
|
||||
{{! Host name }}
|
||||
{{#if @model.host.name}}
|
||||
<list.Item
|
||||
@icon='monitor'
|
||||
@color='faint'
|
||||
>{{@model.host.name}}</list.Item>
|
||||
{{/if}}
|
||||
{{! Host description }}
|
||||
{{#if @model.host.description}}
|
||||
<list.Item
|
||||
@icon='message-circle-fill'
|
||||
@color='faint'
|
||||
>{{@model.host.description}}</list.Item>
|
||||
{{/if}}
|
||||
{{! Host address }}
|
||||
{{#if @model.host.address}}
|
||||
<list.Item
|
||||
@icon='network-alt'
|
||||
@color='faint'
|
||||
>{{@model.host.address}}</list.Item>
|
||||
{{/if}}
|
||||
{{! Host ID }}
|
||||
<list.Item @icon='hash' @color='faint'>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{@model.host.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</list.Item>
|
||||
</Rose::MetadataList>
|
||||
{{/if}}
|
||||
|
||||
{{#if @model.target}}
|
||||
<div
|
||||
class='title hds-typography-display-200 hds-font-weight-semibold'
|
||||
>
|
||||
{{t 'resources.target.details'}}
|
||||
</div>
|
||||
<Rose::MetadataList @orientation='vertical' as |list|>
|
||||
{{! Target name }}
|
||||
<list.Item
|
||||
@icon='target'
|
||||
@color='faint'
|
||||
>{{@model.target.name}}</list.Item>
|
||||
{{! Project name }}
|
||||
<list.Item
|
||||
@icon='grid'
|
||||
@color='faint'
|
||||
>{{@model.target.project.displayName}}</list.Item>
|
||||
{{! Target description }}
|
||||
{{#if @model.target.description}}
|
||||
<list.Item
|
||||
@icon='message-circle-fill'
|
||||
@color='faint'
|
||||
>{{@model.target.description}}</list.Item>
|
||||
{{/if}}
|
||||
{{! Target type (SSH/RDP/TCP) }}
|
||||
<list.Item
|
||||
class='resource-type'
|
||||
@icon={{if @model.target.isRDP 'microsoft' 'terminal'}}
|
||||
@color='faint'
|
||||
>
|
||||
{{t (concat 'resources.target.types.' @model.target.type)}}
|
||||
</list.Item>
|
||||
{{! Target address }}
|
||||
{{#if @model.target.address}}
|
||||
<list.Item
|
||||
class='resource-type'
|
||||
@icon='network-alt'
|
||||
@color='faint'
|
||||
>{{@model.target.address}}</list.Item>
|
||||
{{/if}}
|
||||
{{! Target ID}}
|
||||
<list.Item @icon='hash' @color='faint'>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{@model.target.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</list.Item>
|
||||
</Rose::MetadataList>
|
||||
{{/if}}
|
||||
</div>
|
||||
</bc.Sidebar>
|
||||
{{/if}}
|
||||
</Rose::Layout::BodyContent>
|
||||
@@ -3,40 +3,31 @@
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
}}
|
||||
|
||||
<div class='proxy-url-container'>
|
||||
<div class='proxy-url-container' data-test-proxy-url>
|
||||
<Hds::Dropdown @listPosition='bottom-left' as |dd|>
|
||||
<dd.ToggleButton @color='secondary' @text={{this.selectedValue}} />
|
||||
<dd.Interactive
|
||||
{{on
|
||||
'click'
|
||||
(fn
|
||||
this.updateContent
|
||||
(t 'resources.session.proxy-url.address-port')
|
||||
dd.close
|
||||
)
|
||||
}}
|
||||
>{{t 'resources.session.proxy-url.address-port'}}</dd.Interactive>
|
||||
<dd.Interactive
|
||||
data-test-ssh-option
|
||||
{{on
|
||||
'click'
|
||||
(fn this.updateContent (t 'resources.session.proxy-url.ssh') dd.close)
|
||||
}}
|
||||
>{{t 'resources.session.proxy-url.ssh'}}</dd.Interactive>
|
||||
<dd.ToggleButton
|
||||
@color='secondary'
|
||||
@text={{t (concat 'resources.session.proxy-url.' this.currentValue)}}
|
||||
/>
|
||||
{{#each this.dropdownOptions as |optionId|}}
|
||||
<dd.Interactive
|
||||
data-test={{concat optionId '-option'}}
|
||||
{{on 'click' (fn this.handleSelect optionId dd.close)}}
|
||||
>
|
||||
{{t (concat 'resources.session.proxy-url.' optionId)}}
|
||||
</dd.Interactive>
|
||||
{{/each}}
|
||||
</Hds::Dropdown>
|
||||
{{#if this.isAddressAndPort}}
|
||||
<Hds::Copy::Snippet
|
||||
class='copy-address'
|
||||
@textToCopy={{@proxyAddress}}
|
||||
@isTruncated={{true}}
|
||||
/>
|
||||
<Hds::Copy::Snippet class='copy-port' @textToCopy={{@proxyPort}} />
|
||||
{{/if}}
|
||||
{{#unless this.isAddressAndPort}}
|
||||
<Hds::Copy::Snippet
|
||||
class='copy-ssh-command'
|
||||
@textToCopy={{this.sshCommand}}
|
||||
@isTruncated={{true}}
|
||||
/>
|
||||
{{/unless}}
|
||||
|
||||
{{#let this.copySnippetData as |snippet|}}
|
||||
{{#if snippet}}
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{snippet.address}}
|
||||
@isTruncated={{true}}
|
||||
/>
|
||||
{{#if snippet.port}}
|
||||
<Hds::Copy::Snippet @textToCopy={{snippet.port}} />
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/let}}
|
||||
</div>
|
||||
@@ -7,28 +7,85 @@ import Component from '@glimmer/component';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { action } from '@ember/object';
|
||||
import { service } from '@ember/service';
|
||||
import {
|
||||
TYPE_TARGET_RDP,
|
||||
TYPE_TARGET_SSH,
|
||||
TYPE_TARGET_TCP,
|
||||
} from 'api/models/target';
|
||||
|
||||
const ADDRESS_PORT = 'address-port';
|
||||
|
||||
export default class SessionProxyUrlComponent extends Component {
|
||||
// =services
|
||||
|
||||
@service intl;
|
||||
|
||||
@tracked selectedValue = this.args.isSSHTarget
|
||||
? this.intl.t('resources.session.proxy-url.ssh')
|
||||
: this.intl.t('resources.session.proxy-url.address-port');
|
||||
// =attributes
|
||||
|
||||
get isAddressAndPort() {
|
||||
@tracked selectedValue = null;
|
||||
|
||||
/**
|
||||
* Returns the current value to be displayed in the dropdown.
|
||||
* If a value is selected, it returns that value.
|
||||
* Otherwise, it defaults to 'address-port' for TCP targets or the targetType for others.
|
||||
*/
|
||||
get currentValue() {
|
||||
return (
|
||||
this.selectedValue ===
|
||||
this.intl.t('resources.session.proxy-url.address-port')
|
||||
this.selectedValue ??
|
||||
(this.args.targetType === TYPE_TARGET_TCP
|
||||
? ADDRESS_PORT
|
||||
: this.args.targetType)
|
||||
);
|
||||
}
|
||||
|
||||
get sshCommand() {
|
||||
return `ssh ${this.args.proxyAddress} -p ${this.args.proxyPort}`;
|
||||
/**
|
||||
* Returns the copy snippet data based on the current selected value.
|
||||
*/
|
||||
get copySnippetData() {
|
||||
const { proxyAddress, proxyPort } = this.args;
|
||||
switch (this.currentValue) {
|
||||
case ADDRESS_PORT:
|
||||
return {
|
||||
address: proxyAddress,
|
||||
port: proxyPort,
|
||||
};
|
||||
case TYPE_TARGET_SSH:
|
||||
return {
|
||||
address: `ssh ${proxyAddress} -p ${proxyPort}`,
|
||||
};
|
||||
case TYPE_TARGET_RDP:
|
||||
// TODO: This is a just a placeholder. Update this based on the design and product requirements.
|
||||
return {
|
||||
address: `rdp ${proxyAddress} -p ${proxyPort}`,
|
||||
};
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the dropdown options based on the target type.
|
||||
*/
|
||||
get dropdownOptions() {
|
||||
let options = [ADDRESS_PORT];
|
||||
|
||||
options.push(
|
||||
this.args.targetType === TYPE_TARGET_RDP
|
||||
? TYPE_TARGET_RDP
|
||||
: TYPE_TARGET_SSH,
|
||||
);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
// =actions
|
||||
|
||||
/** Updates the selected value and closes the dropdown.
|
||||
* @param {string} optionId - The selected option.
|
||||
* @param {function} closeCallback - The callback function to close the dropdown.
|
||||
*/
|
||||
@action
|
||||
updateContent(value, closeCallback) {
|
||||
this.selectedValue = value;
|
||||
handleSelect(optionId, closeCallback) {
|
||||
this.selectedValue = optionId;
|
||||
closeCallback();
|
||||
}
|
||||
}
|
||||
@@ -3,133 +3,37 @@
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
}}
|
||||
|
||||
<Hds::Tabs as |T|>
|
||||
<T.Tab>{{t 'titles.details'}} </T.Tab>
|
||||
<T.Tab @icon='terminal' {{on 'click' this.openTerminal}}>
|
||||
{{t 'resources.session.shell'}}
|
||||
</T.Tab>
|
||||
<T.Panel>
|
||||
{{#if (and @model.proxy_address @model.proxy_port)}}
|
||||
<Session::ProxyUrl
|
||||
@proxyAddress={{@model.proxy_address}}
|
||||
@proxyPort={{@model.proxy_port}}
|
||||
@isSSHTarget={{@model.target.isSSH}}
|
||||
/>
|
||||
{{/if}}
|
||||
<Rose::Layout::BodyContent as |bc|>
|
||||
<bc.Body>
|
||||
{{#if @model.credentials}}
|
||||
<CredentialsPanel @credentials={{@model.credentials}} />
|
||||
{{else}}
|
||||
<Hds::ApplicationState data-test-no-credentials as |A|>
|
||||
<A.Header
|
||||
@title={{t 'resources.session.messages.connected.title'}}
|
||||
/>
|
||||
<A.Body
|
||||
@text={{t
|
||||
'resources.session.messages.connected.description'
|
||||
targetDisplayName=@model.target.displayName
|
||||
}}
|
||||
/>
|
||||
</Hds::ApplicationState>
|
||||
{{/if}}
|
||||
</bc.Body>
|
||||
{{#if @model.target.isRDP}}
|
||||
{{! RDP: Show content directly without tabs }}
|
||||
{{#if (and @model.proxy_address @model.proxy_port)}}
|
||||
<Session::ProxyUrl
|
||||
@proxyAddress={{@model.proxy_address}}
|
||||
@proxyPort={{@model.proxy_port}}
|
||||
@targetType={{@model.target.type}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
||||
{{#if (or @model.host @model.target)}}
|
||||
<bc.Sidebar>
|
||||
<div class='details-sidebar'>
|
||||
{{#if @model.host}}
|
||||
<div
|
||||
class='title hds-typography-display-200 hds-font-weight-semibold'
|
||||
>
|
||||
{{t 'resources.host.details'}}
|
||||
</div>
|
||||
<Rose::MetadataList @orientation='vertical' as |list|>
|
||||
{{! Host name }}
|
||||
{{#if @model.host.name}}
|
||||
<list.Item @icon='monitor' @color='faint'>
|
||||
{{@model.host.name}}
|
||||
</list.Item>
|
||||
{{/if}}
|
||||
{{! Host description }}
|
||||
{{#if @model.host.description}}
|
||||
<list.Item @icon='message-circle-fill' @color='faint'>
|
||||
{{@model.host.description}}
|
||||
</list.Item>
|
||||
{{/if}}
|
||||
{{! Host address }}
|
||||
{{#if @model.host.address}}
|
||||
<list.Item @icon='network-alt' @color='faint'>
|
||||
{{@model.host.address}}
|
||||
</list.Item>
|
||||
{{/if}}
|
||||
{{! Host ID }}
|
||||
<list.Item @icon='hash' @color='faint'>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{@model.host.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</list.Item>
|
||||
</Rose::MetadataList>
|
||||
{{/if}}
|
||||
{{#if @model.target}}
|
||||
<div
|
||||
class='title hds-typography-display-200 hds-font-weight-semibold'
|
||||
>
|
||||
{{t 'resources.target.details'}}
|
||||
</div>
|
||||
<Rose::MetadataList @orientation='vertical' as |list|>
|
||||
{{! Target name }}
|
||||
<list.Item @icon='target' @color='faint'>
|
||||
{{@model.target.name}}
|
||||
</list.Item>
|
||||
{{! Project name }}
|
||||
<list.Item @icon='grid' @color='faint'>
|
||||
{{@model.target.project.displayName}}
|
||||
</list.Item>
|
||||
{{! Target description }}
|
||||
{{#if @model.target.description}}
|
||||
<list.Item @icon='message-circle-fill' @color='faint'>
|
||||
{{@model.target.description}}
|
||||
</list.Item>
|
||||
{{/if}}
|
||||
{{! Target type }}
|
||||
<list.Item
|
||||
class='resource-type'
|
||||
@icon='terminal'
|
||||
@color='faint'
|
||||
>
|
||||
{{#if @model.target.isSSH}}
|
||||
{{t 'resources.target.types.ssh'}}
|
||||
{{else}}
|
||||
{{t 'resources.target.types.tcp'}}
|
||||
{{/if}}
|
||||
</list.Item>
|
||||
{{! Target address }}
|
||||
{{#if @model.target.address}}
|
||||
<list.Item
|
||||
class='resource-type'
|
||||
@icon='network-alt'
|
||||
@color='faint'
|
||||
>
|
||||
{{@model.target.address}}
|
||||
</list.Item>
|
||||
{{/if}}
|
||||
{{! Target ID }}
|
||||
<list.Item @icon='hash' @color='faint'>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{@model.target.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</list.Item>
|
||||
</Rose::MetadataList>
|
||||
{{/if}}
|
||||
</div>
|
||||
</bc.Sidebar>
|
||||
<Session::Details @model={{@model}} />
|
||||
{{else}}
|
||||
{{! Non-RDP: Show tabbed interface }}
|
||||
<Hds::Tabs as |T|>
|
||||
<T.Tab>{{t 'titles.details'}}</T.Tab>
|
||||
<T.Tab @icon='terminal' {{on 'click' this.openTerminal}}>
|
||||
{{t 'resources.session.shell'}}
|
||||
</T.Tab>
|
||||
<T.Panel>
|
||||
{{#if (and @model.proxy_address @model.proxy_port)}}
|
||||
<Session::ProxyUrl
|
||||
@proxyAddress={{@model.proxy_address}}
|
||||
@proxyPort={{@model.proxy_port}}
|
||||
@targetType={{@model.target.type}}
|
||||
/>
|
||||
{{/if}}
|
||||
</Rose::Layout::BodyContent>
|
||||
</T.Panel>
|
||||
<T.Panel>
|
||||
<div id='terminal-container'></div>
|
||||
</T.Panel>
|
||||
</Hds::Tabs>
|
||||
|
||||
<Session::Details @model={{@model}} />
|
||||
</T.Panel>
|
||||
<T.Panel>
|
||||
<div id='terminal-container'></div>
|
||||
</T.Panel>
|
||||
</Hds::Tabs>
|
||||
{{/if}}
|
||||
@@ -300,14 +300,6 @@
|
||||
.hds-copy-snippet {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.copy-address {
|
||||
max-width: 70%;
|
||||
}
|
||||
|
||||
.copy-ssh-command {
|
||||
max-width: 90%;
|
||||
}
|
||||
}
|
||||
|
||||
// Credentials Panel
|
||||
|
||||
@@ -134,12 +134,12 @@
|
||||
</list.Item>
|
||||
{{/if}}
|
||||
{{! Target type }}
|
||||
<list.Item class='resource-type' @icon='terminal' @color='faint'>
|
||||
{{#if @model.target.isSSH}}
|
||||
{{t 'resources.target.types.ssh'}}
|
||||
{{else}}
|
||||
{{t 'resources.target.types.tcp'}}
|
||||
{{/if}}
|
||||
<list.Item
|
||||
class='resource-type'
|
||||
@icon={{if @model.target.isRDP 'microsoft' 'terminal'}}
|
||||
@color='faint'
|
||||
>
|
||||
{{t (concat 'resources.target.types.' @model.target.type)}}
|
||||
</list.Item>
|
||||
{{! Target address }}
|
||||
{{#if @model.target.address}}
|
||||
|
||||
@@ -8,90 +8,147 @@ import { setupRenderingTest } from 'desktop/tests/helpers';
|
||||
import { render, click } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import { setupIntl } from 'ember-intl/test-support';
|
||||
import {
|
||||
TYPE_TARGET_SSH,
|
||||
TYPE_TARGET_RDP,
|
||||
TYPE_TARGET_TCP,
|
||||
} from 'api/models/target';
|
||||
|
||||
module('Integration | Component | session/proxy-url', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
setupIntl(hooks, 'en-us');
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
assert.expect(2);
|
||||
this.set('proxyAddress', 'http://localhost');
|
||||
this.set('proxyPort', '1234');
|
||||
test.each(
|
||||
'shows the correct command based on the target type',
|
||||
[
|
||||
{
|
||||
targetType: TYPE_TARGET_SSH,
|
||||
expectedCommand: (address, port) => `ssh ${address} -p ${port}`,
|
||||
expectedSnippetCount: 1,
|
||||
},
|
||||
{
|
||||
targetType: TYPE_TARGET_RDP,
|
||||
expectedCommand: (address, port) => `rdp ${address} -p ${port}`,
|
||||
expectedSnippetCount: 1,
|
||||
},
|
||||
{
|
||||
targetType: TYPE_TARGET_TCP,
|
||||
expectedCommand: (address, port) => `${address}:${port}`,
|
||||
expectedSnippetCount: 2, // TCP has two copy snippets- one for address and one for port
|
||||
},
|
||||
],
|
||||
async function (
|
||||
assert,
|
||||
{ targetType, expectedCommand, expectedSnippetCount },
|
||||
) {
|
||||
this.set('proxyAddress', 'http://localhost');
|
||||
this.set('proxyPort', '1234');
|
||||
this.set('targetType', targetType);
|
||||
|
||||
await render(
|
||||
hbs`
|
||||
await render(
|
||||
hbs`
|
||||
<Session::ProxyUrl
|
||||
@proxyAddress={{this.proxyAddress}}
|
||||
@proxyPort={{this.proxyPort}}
|
||||
@isSSHTarget={{false}}
|
||||
@targetType={{this.targetType}}
|
||||
/>
|
||||
`,
|
||||
);
|
||||
);
|
||||
assert.dom('.hds-copy-snippet').exists({ count: expectedSnippetCount });
|
||||
|
||||
assert.dom('.copy-address').hasText(this.proxyAddress);
|
||||
assert.dom('.copy-port').hasText(this.proxyPort);
|
||||
});
|
||||
// Assert the content of the copy snippets
|
||||
if (targetType === TYPE_TARGET_TCP) {
|
||||
assert
|
||||
.dom('.hds-copy-snippet:nth-of-type(1)')
|
||||
.hasText(this.proxyAddress);
|
||||
assert.dom('.hds-copy-snippet:nth-of-type(2)').hasText(this.proxyPort);
|
||||
} else {
|
||||
assert
|
||||
.dom('.hds-copy-snippet')
|
||||
.hasText(expectedCommand(this.proxyAddress, this.proxyPort));
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
test('it switches to SSH command on dropdown click', async function (assert) {
|
||||
assert.expect(2);
|
||||
this.set('proxyAddress', 'http://localhost');
|
||||
this.set('proxyPort', '1234');
|
||||
test.each(
|
||||
'displays correct dropdown options based on target type',
|
||||
[
|
||||
{
|
||||
targetType: TYPE_TARGET_SSH,
|
||||
visibleOptions: [
|
||||
'[data-test="ssh-option"]',
|
||||
'[data-test="address-port-option"]',
|
||||
],
|
||||
hiddenOptions: ['[data-test="rdp-option"]'],
|
||||
},
|
||||
{
|
||||
targetType: TYPE_TARGET_RDP,
|
||||
visibleOptions: [
|
||||
'[data-test="rdp-option"]',
|
||||
'[data-test="address-port-option"]',
|
||||
],
|
||||
hiddenOptions: ['[data-test="ssh-option"]'],
|
||||
},
|
||||
{
|
||||
targetType: TYPE_TARGET_TCP,
|
||||
visibleOptions: [
|
||||
'[data-test="address-port-option"]',
|
||||
'[data-test="ssh-option"]',
|
||||
],
|
||||
hiddenOptions: ['[data-test="rdp-option"]'],
|
||||
},
|
||||
],
|
||||
async function (assert, { targetType, visibleOptions, hiddenOptions }) {
|
||||
this.set('proxyAddress', 'http://localhost');
|
||||
this.set('proxyPort', '1234');
|
||||
this.set('targetType', targetType);
|
||||
|
||||
await render(
|
||||
hbs`
|
||||
await render(
|
||||
hbs`
|
||||
<Session::ProxyUrl
|
||||
@proxyAddress={{this.proxyAddress}}
|
||||
@proxyPort={{this.proxyPort}}
|
||||
@isSSHTarget={{false}}
|
||||
@targetType={{this.targetType}}
|
||||
/>
|
||||
`,
|
||||
);
|
||||
|
||||
await click('.proxy-url-container .hds-dropdown-toggle-button');
|
||||
|
||||
// Assert visible options
|
||||
for (const option of visibleOptions) {
|
||||
assert.dom(option).isVisible();
|
||||
}
|
||||
|
||||
// Assert hidden options
|
||||
for (const option of hiddenOptions) {
|
||||
assert.dom(option).doesNotExist();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
test('updates command based on dropdown selection', async function (assert) {
|
||||
this.set('proxyAddress', 'http://localhost');
|
||||
this.set('proxyPort', '1234');
|
||||
this.set('targetType', TYPE_TARGET_SSH);
|
||||
|
||||
await render(
|
||||
hbs`
|
||||
<Session::ProxyUrl
|
||||
@proxyAddress={{this.proxyAddress}}
|
||||
@proxyPort={{this.proxyPort}}
|
||||
@targetType={{this.targetType}}
|
||||
/>
|
||||
`,
|
||||
);
|
||||
|
||||
// select address-port dropdown option
|
||||
await click('.proxy-url-container .hds-dropdown-toggle-button');
|
||||
await click('[data-test-ssh-option]');
|
||||
await click('[data-test="address-port-option"]');
|
||||
|
||||
assert.dom('.copy-ssh-command').isVisible();
|
||||
assert
|
||||
.dom('.copy-ssh-command')
|
||||
.hasText(`ssh ${this.proxyAddress} -p ${this.proxyPort}`);
|
||||
});
|
||||
|
||||
test('shows address & port info when target type is TCP', async function (assert) {
|
||||
assert.expect(2);
|
||||
this.set('proxyAddress', 'http://localhost');
|
||||
this.set('proxyPort', '1234');
|
||||
|
||||
await render(
|
||||
hbs`
|
||||
<Session::ProxyUrl
|
||||
@proxyAddress={{this.proxyAddress}}
|
||||
@proxyPort={{this.proxyPort}}
|
||||
@isSSHTarget={{false}}
|
||||
/>
|
||||
`,
|
||||
);
|
||||
|
||||
assert.dom('.copy-address').hasText(this.proxyAddress);
|
||||
assert.dom('.copy-port').hasText(this.proxyPort);
|
||||
});
|
||||
|
||||
test('shows ssh command when target type is SSH', async function (assert) {
|
||||
assert.expect(2);
|
||||
this.set('proxyAddress', 'http://localhost');
|
||||
this.set('proxyPort', '1234');
|
||||
|
||||
await render(
|
||||
hbs`
|
||||
<Session::ProxyUrl
|
||||
@proxyAddress={{this.proxyAddress}}
|
||||
@proxyPort={{this.proxyPort}}
|
||||
@isSSHTarget={{true}}
|
||||
/>
|
||||
`,
|
||||
);
|
||||
|
||||
assert.dom('.copy-ssh-command').isVisible();
|
||||
assert
|
||||
.dom('.copy-ssh-command')
|
||||
.hasText(`ssh ${this.proxyAddress} -p ${this.proxyPort}`);
|
||||
.dom('.hds-copy-snippet:nth-of-type(1)')
|
||||
.hasText(`${this.proxyAddress}`);
|
||||
assert.dom('.hds-copy-snippet:nth-of-type(2)').hasText(`${this.proxyPort}`);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import {
|
||||
TYPE_TARGET_SSH,
|
||||
TYPE_TARGET_RDP,
|
||||
TYPE_TARGET_TCP,
|
||||
} from 'api/models/target';
|
||||
import { setupIntl } from 'ember-intl/test-support';
|
||||
|
||||
module('Integration | Component | session/tabs', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
setupIntl(hooks, 'en-us');
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.store = this.owner.lookup('service:store');
|
||||
});
|
||||
|
||||
test.each(
|
||||
'it shows correct content for different target types',
|
||||
[
|
||||
{
|
||||
targetType: TYPE_TARGET_TCP,
|
||||
targetId: 'tcp-target-1',
|
||||
defaultPort: 9000,
|
||||
proxyPort: 9000,
|
||||
shouldShowTabs: true,
|
||||
},
|
||||
{
|
||||
targetType: TYPE_TARGET_SSH,
|
||||
targetId: 'ssh-target-4',
|
||||
defaultPort: 22,
|
||||
proxyPort: 9000,
|
||||
shouldShowTabs: true,
|
||||
},
|
||||
{
|
||||
targetType: TYPE_TARGET_RDP,
|
||||
targetId: 'rdp-target-2',
|
||||
defaultPort: 3389,
|
||||
proxyPort: 3389,
|
||||
shouldShowTabs: false,
|
||||
},
|
||||
],
|
||||
async function (
|
||||
assert,
|
||||
{ targetType, targetId, defaultPort, proxyPort, shouldShowTabs },
|
||||
) {
|
||||
this.store.createRecord('target', {
|
||||
id: targetId,
|
||||
type: targetType,
|
||||
address: 'example.com',
|
||||
default_port: defaultPort,
|
||||
scope: {
|
||||
scope_id: 'p_123',
|
||||
type: 'project',
|
||||
},
|
||||
});
|
||||
|
||||
const session = this.store.createRecord('session', {
|
||||
id: `session-${targetId}`,
|
||||
target_id: targetId,
|
||||
proxy_address: '127.0.0.1',
|
||||
proxy_port: proxyPort,
|
||||
});
|
||||
|
||||
this.set('model', session);
|
||||
|
||||
await render(hbs`<Session::Tabs @model={{this.model}} />`);
|
||||
|
||||
if (shouldShowTabs) {
|
||||
assert.dom('.hds-tabs').exists();
|
||||
} else {
|
||||
assert.dom('.hds-tabs').doesNotExist();
|
||||
}
|
||||
|
||||
assert.dom('[data-test-proxy-url]').exists();
|
||||
assert.dom('[data-test-session-details]').exists();
|
||||
},
|
||||
);
|
||||
});
|
||||
Reference in new issue
Block a user