chore: 🤖 alias target route (#2228)

This commit is contained in:
Dharini Jeeva authored and GitHub committed 2024-04-12 16:36:17 -07:00
1 parent c550faddb4
commit bd65c91ff9
21 files changed
+745 -17

No files matched your search

@@ -37,6 +37,13 @@ export default class ScopesScopeTargetsTargetIndexController extends Controller
return this.model.aliases.length > 3;
}
/**
* Decides when to show the flyout component
* @returns {boolean}
*/
get showFlyOutComponent() {
return this.showFlyout && this.model.aliases.length > 3;
}
/**
* Returns only the first three items in the aliases array if there are more than 3
* @returns {array}
+2
View File
@@ -88,6 +88,8 @@ Router.map(function () {
this.route('injected-application-credential-sources');
this.route('add-brokered-credential-sources');
this.route('add-injected-application-credential-sources');
this.route('create-alias');
this.route('manage-alias', { path: ':alias_id' }, function () {});
this.route('enable-session-recording', function () {
this.route('create-storage-bucket');
});
@@ -140,4 +140,33 @@ export default class ScopesScopeTargetsRoute extends Route {
this.router.replaceWith('scopes.scope.targets');
this.refresh();
}
/**
* Delete an alias
* @param {AliasModel} alias
*/
@action
@loading
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.delete-success')
async deleteAlias(alias) {
await alias.destroyRecord();
await this.router.replaceWith('scopes.scope.targets.target');
this.router.refresh();
}
/**
* Remove destaination_id from alias
* @param {AliasModel} alias
*/
@action
@loading
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.clear-success')
async clearAlias(alias) {
alias.destination_id = '';
await alias.save();
this.router.refresh('scopes.scope.targets.target');
await this.router.transitionTo('scopes.scope.targets.target');
}
}
@@ -0,0 +1,58 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { notifySuccess, notifyError } from 'core/decorators/notify';
import { loading } from 'ember-loading';
import { TYPE_ALIAS_TARGET } from 'api/models/alias';
export default class ScopesScopeTargetsTargetCreateAliasRoute extends Route {
// =services
@service store;
@service router;
// =methods
/**
* Creates a new unsaved alias.
* @return {AliasModel}
*/
model() {
const scopeModel = this.store.peekRecord('scope', 'global');
const record = this.store.createRecord('alias', {
type: TYPE_ALIAS_TARGET,
});
record.scopeModel = scopeModel;
return record;
}
// =actions
/**
* Handle save
* @param {AliasModel} alias
*/
@action
@loading
@notifyError(({ message }) => message)
@notifySuccess('notifications.save-success')
async save(alias) {
await alias.save();
await this.router.transitionTo('scopes.scope.targets.target');
this.router.refresh();
}
/**
* Rollback changes on alias.
* @param {AliasModel} alias
*/
@action
cancel(alias) {
alias.rollbackAttributes();
this.router.transitionTo('scopes.scope.targets.target');
}
}
@@ -0,0 +1,54 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { notifySuccess, notifyError } from 'core/decorators/notify';
import { loading } from 'ember-loading';
export default class ScopesScopeTargetsTargetManageAliasRoute extends Route {
// =services
@service store;
@service router;
// =methods
/**
* Creates a new unsaved alias.
* @return {AliasModel}
*/
async model({ alias_id }) {
return this.store.findRecord('alias', alias_id, {
reload: true,
});
}
// =actions
/**
* Handle save
* @param {AliasModel} alias
*/
@action
@loading
@notifyError(({ message }) => message)
@notifySuccess('notifications.save-success')
async save(alias) {
await alias.save();
await this.router.refresh('scopes.scope.targets.target');
this.router.transitionTo('scopes.scope.targets.target');
}
/**
* Rollback changes on alias.
* @param {AliasModel} alias
*/
@action
async cancel(alias) {
alias.rollbackAttributes();
await this.router.transitionTo('scopes.scope.targets.target');
}
}
+21
View File
@@ -625,6 +625,7 @@
.target-sidebar-aliases {
margin-bottom: 3rem;
width: 300px;
.description {
color: var(--token-form-helper-text-color);
@@ -636,8 +637,28 @@
margin-top: 1rem;
}
.link-list-item:first-of-type {
width: 90%;
}
.link-list-item {
margin-bottom: 0.5rem;
word-break: break-word;
}
/* stylelint-disable selector-class-pattern */
.hds-card__container > ul {
display: flex;
margin-bottom: 0.5rem;
}
.hds-link-standalone__text {
margin: 1rem 0;
}
/* stylelint-enable selector-class-pattern */
.hds-dropdown .hds-dropdown-toggle-icon {
color: var(--stark);
}
}
@@ -0,0 +1,33 @@
{{!
Copyright (c) HashiCorp, Inc.
SPDX-License-Identifier: MPL-2.0
}}
{{page-title (t 'titles.new')}}
<Breadcrumbs::Item
@text={{t 'resources.alias.titles.new'}}
@route='scopes.scope.aliases.new'
/>
<Rose::Layout::Page as |page|>
<page.breadcrumbs>
<Breadcrumbs::Container />
</page.breadcrumbs>
<page.header>
<h2>
{{t 'resources.alias.titles.new'}}
{{! TODO: Add doc link for alias }}
</h2>
<p>{{t 'resources.alias.description'}}</p>
</page.header>
<page.body>
<Form::Alias
@model={{@model}}
@submit={{route-action 'save' @model}}
@cancel={{route-action 'cancel' @model}}
/>
</page.body>
</Rose::Layout::Page>
@@ -38,16 +38,28 @@
{{t 'resources.alias.form.sidebar.help'}}
</p>
{{#if @model.aliases}}
{{#each this.aliases as |alias|}}
<LinkListPanel as |P|>
<P.Item
@icon='at-sign'
@color='boundary'
@text={{alias.value}}
{{! @route=' ' }}
@model={{alias.id}}
/>
<P.Item>
<Hds::Dropdown as |dd|>
<dd.ToggleIcon
@icon='more-horizontal'
@text={{t 'actions.manage'}}
@hasChevron={{false}}
@size='small'
/>
<dd.Interactive
@route='scopes.scope.targets.target.manage-alias'
@model={{alias.id}}
@text={{t 'actions.manage'}}
/>
</Hds::Dropdown>
</P.Item>
</LinkListPanel>
{{/each}}
@@ -59,7 +71,7 @@
{{on 'click' this.targets.toggleFlyout}}
/>
{{/if}}
{{#if this.showFlyout}}
{{#if this.showFlyOutComponent}}
<Hds::Flyout
data-test-flyout
@onClose={{this.toggleFlyout}}
@@ -79,9 +91,22 @@
@icon='at-sign'
@color='boundary'
@text={{alias.value}}
{{! @route='' }}
@model={{alias.id}}
/>
<P.Item>
<Hds::Dropdown as |dd|>
<dd.ToggleIcon
@icon='more-horizontal'
@text={{t 'actions.manage'}}
@hasChevron={{false}}
@size='small'
/>
<dd.Interactive
@route='scopes.scope.targets.target.manage-alias'
@model={{alias.id}}
@text={{t 'actions.manage'}}
/>
</Hds::Dropdown>
</P.Item>
</LinkListPanel>
{{/each}}
</M.Body>
@@ -92,7 +117,7 @@
@icon='plus'
@text={{t 'resources.target.actions.add-an-alias'}}
@color='secondary'
{{! @route='' }}
@route='scopes.scope.targets.target.create-alias'
/>
{{/if}}
</div>
@@ -0,0 +1,55 @@
{{!
Copyright (c) HashiCorp, Inc.
SPDX-License-Identifier: MPL-2.0
}}
<Breadcrumbs::Item
@text={{t 'resources.alias.title'}}
@route='scopes.scope.targets.target.manage-alias'
/>
<Rose::Layout::Page as |page|>
<page.breadcrumbs>
<Breadcrumbs::Container />
</page.breadcrumbs>
<page.header>
<h2>
{{t 'resources.alias.title'}}
{{! TODO: DOC LINK }}
</h2>
<p>{{t 'resources.alias.description'}}</p>
<Hds::Copy::Snippet @color='secondary' @textToCopy={{@model.id}} />
</page.header>
<page.actions>
<Hds::Dropdown as |dd|>
<dd.ToggleButton
data-test-manage-dropdown
@text={{t 'actions.manage'}}
@color='secondary'
/>
<dd.Interactive
@text={{t 'actions.clear'}}
{{on 'click' (route-action 'clearAlias' @model)}}
/>
{{#if (can 'delete model' @model)}}
<dd.Separator />
<dd.Interactive
data-test-manage-alias-dropdown-delete
@color='critical'
@text={{t 'actions.delete'}}
{{on 'click' (route-action 'deleteAlias' @model)}}
/>
{{/if}}
</Hds::Dropdown>
</page.actions>
<page.body>
<Form::Alias
@model={{@model}}
@submit={{route-action 'save' @model}}
@cancel={{route-action 'cancel' @model}}
/>
</page.body>
</Rose::Layout::Page>
@@ -14,7 +14,6 @@ import { authenticateSession } from 'ember-simple-auth/test-support';
module('Acceptance | aliases | create', function (hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
let features;
let getAliasCount;
@@ -0,0 +1,169 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
import { module, test } from 'qunit';
import { visit, click, fillIn } from '@ember/test-helpers';
import { setupApplicationTest } from 'admin/tests/helpers';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import a11yAudit from 'ember-a11y-testing/test-support/audit';
import { Response } from 'miragejs';
import { authenticateSession } from 'ember-simple-auth/test-support';
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
import { TYPE_TARGET_TCP, TYPE_TARGET_SSH } from 'api/models/target';
module('Acceptance | targets | create-alias', function (hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
setupIndexedDb(hooks);
let getAliasCount;
const SAVE_BTN_SELECTOR = '[type="submit"]';
const CANCEL_BTN_SELECTOR = '.rose-form-actions [type="button"]';
const NAME_FIELD_SELECTOR = '[name="name"]';
const ALIAS_FIELD_SELECTOR = '[name="value"]';
const DEST_FIELD_SELECTOR = '[name="destination_id"]';
const ALERT_TEXT_SELECTOR = '[role="alert"] div';
const FIELD_ERROR_TEXT_SELECTOR = '.hds-form-error__message';
const NAME_FIELD_TEXT = 'random string';
const ALIAS_VALUE_TEXT = 'www.target1.com';
const ADD_AN_ALIAS_SELECTOR = '.target-sidebar-aliases .hds-button';
const instances = {
scopes: {
global: null,
org: null,
},
};
const urls = {
globalScope: null,
projectScope: null,
targets: null,
target: null,
};
hooks.beforeEach(function () {
instances.scopes.global = this.server.create('scope', { id: 'global' });
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.scopes.org.id, type: 'org' },
});
instances.target = this.server.create('target', {
scope: instances.scopes.project,
type: TYPE_TARGET_TCP,
});
urls.globalScope = `/scopes/global`;
urls.projectScope = `/scopes/${instances.scopes.project.id}`;
urls.targets = `${urls.projectScope}/targets`;
urls.target = `${urls.targets}/${instances.target.id}`;
getAliasCount = () => this.server.schema.aliases.all().models.length;
authenticateSession({});
});
test('users can create a new alias for a target of TCP type', async function (assert) {
const aliasCount = getAliasCount();
await visit(urls.targets);
await click(`[href="${urls.target}"]`);
await click(ADD_AN_ALIAS_SELECTOR);
await fillIn(NAME_FIELD_SELECTOR, NAME_FIELD_TEXT);
await fillIn(ALIAS_FIELD_SELECTOR, ALIAS_VALUE_TEXT);
await fillIn(DEST_FIELD_SELECTOR, instances.target.id);
await click(SAVE_BTN_SELECTOR);
const alias = this.server.schema.aliases.findBy({
name: NAME_FIELD_TEXT,
});
assert.strictEqual(alias.name, NAME_FIELD_TEXT);
assert.strictEqual(alias.scopeId, 'global');
assert.strictEqual(getAliasCount(), aliasCount + 1);
});
test('users can create a new alias for a target of SSH type', async function (assert) {
instances.target = this.server.create('target', {
scope: instances.scopes.project,
type: TYPE_TARGET_SSH,
});
const aliasCount = getAliasCount();
await visit(urls.targets);
await click(`[href="${urls.target}"]`);
await click(ADD_AN_ALIAS_SELECTOR);
await fillIn(NAME_FIELD_SELECTOR, NAME_FIELD_TEXT);
await fillIn(ALIAS_FIELD_SELECTOR, ALIAS_VALUE_TEXT);
await fillIn(DEST_FIELD_SELECTOR, instances.target.id);
await click(SAVE_BTN_SELECTOR);
const alias = this.server.schema.aliases.findBy({
name: NAME_FIELD_TEXT,
});
assert.strictEqual(alias.name, NAME_FIELD_TEXT);
assert.strictEqual(alias.scopeId, 'global');
assert.strictEqual(getAliasCount(), aliasCount + 1);
});
test('user can cancel new alias creation', async function (assert) {
const aliasCount = getAliasCount();
instances.target = this.server.create('target', {
scope: instances.scopes.project,
type: TYPE_TARGET_SSH,
});
await visit(urls.targets);
await click(`[href="${urls.target}"]`);
await click(ADD_AN_ALIAS_SELECTOR);
await fillIn(NAME_FIELD_SELECTOR, NAME_FIELD_TEXT);
await click(CANCEL_BTN_SELECTOR);
assert.strictEqual(getAliasCount(), aliasCount);
});
test('saving a new alias with invalid fields displays error messages', async function (assert) {
this.server.post('/aliases', () => {
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.targets);
await click(`[href="${urls.target}"]`);
await click(ADD_AN_ALIAS_SELECTOR);
await click(SAVE_BTN_SELECTOR);
await a11yAudit();
assert.dom(ALERT_TEXT_SELECTOR).hasText('The request was invalid.');
assert.dom(FIELD_ERROR_TEXT_SELECTOR).hasText('Name is required.');
});
});
@@ -0,0 +1,164 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
import { module, test } from 'qunit';
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';
import { authenticateSession } from 'ember-simple-auth/test-support';
import { TYPE_TARGET_TCP, TYPE_TARGET_SSH } from 'api/models/target';
module('Acceptance | targets | manage-alias', function (hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
let aliasResourceTwo, aliasResourceOne, getAliasCount;
const ALIASES_SIDEBAR = '.target-sidebar-aliases';
const ALIASES_SIDEBAR_LIST = '.link-list-item';
const DROPDOWN_BUTTON_SELECTOR = '.hds-dropdown-toggle-icon';
const DROPDOWN_ITEM_SELECTOR = '.hds-dropdown-list-item a';
const DROPDOWN_ACTION = '.hds-dropdown-toggle-button__text';
const CLEAR_BTN_SELECTOR = '.hds-dropdown-list-item--color-action button';
const DELETE_BTN_SELECTOR = '.hds-dropdown-list-item--color-critical button';
const LINK_TO_NEW_ALIAS = '.target-sidebar-aliases .hds-button';
const instances = {
scopes: {
global: null,
org: null,
project: null,
},
sshTarget: null,
tcpTarget: null,
};
const urls = {
globalScope: null,
orgScope: null,
projectScope: null,
targets: null,
sshTarget: null,
tcpTarget: null,
tcpAlias: null,
aliases: null,
};
hooks.beforeEach(function () {
// Generate resources
instances.scopes.global = this.server.create('scope', { id: 'global' });
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.scopes.org.id, type: 'org' },
});
instances.alias = this.server.createList('alias', 2, {
scope: instances.scopes.global,
});
aliasResourceOne = instances.alias[0];
aliasResourceTwo = instances.alias[1];
instances.sshTarget = this.server.create('target', {
type: TYPE_TARGET_SSH,
scope: instances.scopes.project,
aliases: [
{ id: aliasResourceOne.id, value: aliasResourceOne.value },
{ id: aliasResourceTwo.id, value: aliasResourceTwo.value },
],
});
instances.tcpTarget = this.server.create('target', {
type: TYPE_TARGET_TCP,
scope: instances.scopes.project,
aliases: [{ id: aliasResourceOne.id, value: aliasResourceOne.value }],
});
// Generate route URLs for resources
urls.globalScope = `/scopes/global`;
urls.orgScope = `/scopes/${instances.scopes.org.id}/scopes`;
urls.projectScope = `/scopes/${instances.scopes.project.id}`;
urls.targets = `${urls.projectScope}/targets`;
urls.tcpTarget = `${urls.targets}/${instances.tcpTarget.id}`;
urls.sshTarget = `${urls.targets}/${instances.sshTarget.id}`;
urls.unknownTarget = `${urls.targets}/foo`;
urls.tcpAlias = `${urls.tcpTarget}/${aliasResourceOne.id}`;
getAliasCount = () => this.server.schema.aliases.all().models.length;
authenticateSession({});
});
test('clicking on manage should take you to manage page', async function (assert) {
await visit(urls.tcpTarget);
assert.dom(ALIASES_SIDEBAR).exists();
assert.dom(ALIASES_SIDEBAR_LIST).exists();
await click(DROPDOWN_BUTTON_SELECTOR);
assert.dom(DROPDOWN_ITEM_SELECTOR).exists();
assert.dom(DROPDOWN_ITEM_SELECTOR).hasText('Manage');
await click(DROPDOWN_ITEM_SELECTOR);
assert.strictEqual(currentURL(), urls.tcpAlias);
await a11yAudit();
});
test('clicking on `clear alias` from the dropdown should remove the destination ID and alias should disapper from the target sidebar', async function (assert) {
aliasResourceOne.update({
destination_id: instances.tcpTarget.id,
});
await visit(urls.tcpTarget);
assert.dom(ALIASES_SIDEBAR).exists();
assert.dom(ALIASES_SIDEBAR_LIST).exists();
await click(DROPDOWN_BUTTON_SELECTOR);
assert.dom(DROPDOWN_ITEM_SELECTOR).exists();
assert.dom(DROPDOWN_ITEM_SELECTOR).hasText('Manage');
await click(DROPDOWN_ITEM_SELECTOR);
assert.strictEqual(currentURL(), urls.tcpAlias);
await click(DROPDOWN_ACTION);
await click(CLEAR_BTN_SELECTOR);
const id = aliasResourceOne.id;
const associatedAlias = this.server.schema.aliases.findBy({ id });
assert.strictEqual(associatedAlias.destinationId, null);
assert.strictEqual(currentURL(), urls.tcpTarget);
assert.dom(ALIASES_SIDEBAR_LIST).doesNotExist();
assert.dom(LINK_TO_NEW_ALIAS).exists;
});
test('clicking on `delete alias` from the dropdown should remove the destination ID and alias should disapper from the target sidebar and deleted from aliases list', async function (assert) {
const aliasCount = getAliasCount();
aliasResourceOne.update({
destination_id: instances.tcpTarget.id,
});
await visit(urls.tcpTarget);
assert.dom(ALIASES_SIDEBAR).exists();
assert.dom(ALIASES_SIDEBAR_LIST).exists();
await click(DROPDOWN_BUTTON_SELECTOR);
assert.dom(DROPDOWN_ITEM_SELECTOR).exists();
assert.dom(DROPDOWN_ITEM_SELECTOR).hasText('Manage');
await click(DROPDOWN_ITEM_SELECTOR);
assert.strictEqual(currentURL(), urls.tcpAlias);
await click(DROPDOWN_ACTION);
await click(DELETE_BTN_SELECTOR);
assert.strictEqual(getAliasCount(), aliasCount - 1);
assert.strictEqual(currentURL(), urls.tcpTarget);
assert.dom(ALIASES_SIDEBAR_LIST).doesNotExist();
assert.dom(LINK_TO_NEW_ALIAS).exists;
});
});
+38 -8
View File
@@ -23,11 +23,15 @@ module('Acceptance | targets | read', function (hooks) {
setupIndexedDb(hooks);
let featuresService;
let aliasResource;
const ALIASES_SIDEBAR = '.target-sidebar-aliases';
const ALIASES_SIDEBAR_LIST = '.target-sidebar-aliases .link-list-item';
const LINK_TO_NEW_ALIAS = '.target-sidebar-aliases button';
const ALIASES_SIDEBAR_LIST = '.link-list-item';
const LINK_TO_NEW_ALIAS = '.target-sidebar-aliases .hds-button';
const VIEW_MORE_BTN = '[data-test-view-more]';
const FLYOUT_COMPONENT = '[data-test-flyout]';
const DROPDOWN_BUTTON_SELECTOR = '.hds-dropdown-toggle-icon';
const DROPDOWN_ITEM_SELECTOR = '.hds-dropdown-list-item a';
const instances = {
scopes: {
global: null,
@@ -44,6 +48,8 @@ module('Acceptance | targets | read', function (hooks) {
targets: null,
sshTarget: null,
tcpTarget: null,
alias: null,
aliases: null,
};
hooks.beforeEach(function () {
@@ -67,14 +73,23 @@ module('Acceptance | targets | read', function (hooks) {
scope: instances.scopes.project,
});
instances.alias = this.server.createList('alias', 1, {
scope: instances.scopes.global,
});
aliasResource = instances.alias[0];
// Generate route URLs for resources
urls.globalScope = `/scopes/global/scopes`;
urls.globalScope = `/scopes/global`;
urls.orgScope = `/scopes/${instances.scopes.org.id}/scopes`;
urls.projectScope = `/scopes/${instances.scopes.project.id}`;
urls.targets = `${urls.projectScope}/targets`;
urls.sshTarget = `${urls.targets}/${instances.sshTarget.id}`;
urls.tcpTarget = `${urls.targets}/${instances.tcpTarget.id}`;
urls.unknownTarget = `${urls.targets}/foo`;
urls.aliases = `${urls.globalScope}/aliases`;
urls.alias = `${urls.tcpTarget}/${aliasResource.id}`;
authenticateSession({});
});
@@ -198,7 +213,7 @@ module('Acceptance | targets | read', function (hooks) {
test('can view aliases on the right sidebar', async function (assert) {
instances.tcpTarget.update({
aliases: [{ id: 'alt_123', value: 'alias 1' }],
aliases: [{ id: aliasResource.id, value: 'alias 1' }],
});
await visit(urls.tcpTarget);
assert.dom(ALIASES_SIDEBAR).exists();
@@ -219,10 +234,10 @@ module('Acceptance | targets | read', function (hooks) {
test('can click `view more aliases` to see the remaining associated aliases if there are more than 3', async function (assert) {
instances.tcpTarget.update({
aliases: [
{ id: 'alt_123', value: 'alias 1' },
{ id: 'alt_125', value: 'alias 5' },
{ id: 'alt_122', value: 'alias 2' },
{ id: 'alt_124', value: 'alias 4' },
{ id: aliasResource.id, value: 'alias 1' },
{ id: aliasResource.id, value: 'alias 5' },
{ id: aliasResource.id, value: 'alias 2' },
{ id: aliasResource.id, value: 'alias 4' },
],
});
await visit(urls.tcpTarget);
@@ -232,4 +247,19 @@ module('Acceptance | targets | read', function (hooks) {
await click(VIEW_MORE_BTN);
assert.dom(FLYOUT_COMPONENT).exists();
});
test('users can click on associated alias card on the right sidebar', async function (assert) {
instances.tcpTarget.update({
aliases: [{ id: aliasResource.id, value: aliasResource.value }],
});
await visit(urls.tcpTarget);
assert.dom(ALIASES_SIDEBAR_LIST).exists();
await click(DROPDOWN_BUTTON_SELECTOR);
assert.dom(DROPDOWN_ITEM_SELECTOR).exists();
assert.dom(DROPDOWN_ITEM_SELECTOR).hasText('Manage');
await click(DROPDOWN_ITEM_SELECTOR);
assert.strictEqual(currentURL(), urls.alias);
});
});
@@ -0,0 +1,21 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module(
'Unit | Route | scopes/scope/targets/target/create-alias',
function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let route = this.owner.lookup(
'route:scopes/scope/targets/target/create-alias',
);
assert.ok(route);
});
},
);
@@ -0,0 +1,21 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module(
'Unit | Route | scopes/scope/targets/target/manage-alias',
function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let route = this.owner.lookup(
'route:scopes/scope/targets/target/manage-alias',
);
assert.ok(route);
});
},
);