chore: 🤖 alias target route (#2228)
This commit is contained in:
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}
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
});
|
||||
},
|
||||
);
|
||||
Reference in new issue
Block a user