2023-03-01 09:39:41 -06:00
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
2021-08-16 10:18:46 -07:00
import { module , test } from 'qunit' ;
2022-11-30 14:01:23 -08:00
import { visit , currentURL , click , fillIn } from '@ember/test-helpers' ;
2021-08-16 10:18:46 -07:00
import { setupApplicationTest } from 'ember-qunit' ;
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage' ;
import { Response } from 'miragejs' ;
import {
authenticateSession ,
// These are left here intentionally for future reference.
//currentSession,
//invalidateSession,
} from 'ember-simple-auth/test-support' ;
2021-08-16 16:58:25 -07:00
module ( 'Acceptance | targets | update' , function ( hooks ) {
2021-08-16 10:18:46 -07:00
setupApplicationTest ( hooks );
setupMirage ( hooks );
2023-01-11 15:46:47 -06:00
let featuresService ;
2021-08-16 10:18:46 -07:00
const instances = {
scopes : {
global : null ,
org : null ,
project : null ,
},
2022-11-30 14:01:23 -08:00
target : null ,
2021-08-16 10:18:46 -07:00
};
const urls = {
orgScope : null ,
projectScope : null ,
targets : null ,
target : null ,
newTarget : null ,
};
hooks . beforeEach ( function () {
2023-01-11 15:46:47 -06:00
featuresService = this . owner . lookup ( 'service:features' );
2021-08-16 10:18:46 -07:00
// 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 . target = this . server . create ( 'target' , {
scope : instances . scopes . project ,
});
// Generate route URLs for resources
urls . orgScope = `/scopes/ ${ instances . scopes . org . id } /scopes` ;
urls . projectScope = `/scopes/ ${ instances . scopes . project . id } ` ;
urls . targets = ` ${ urls . projectScope } /targets` ;
urls . target = ` ${ urls . targets } / ${ instances . target . id } ` ;
urls . unknownTarget = ` ${ urls . targets } /foo` ;
urls . newTarget = ` ${ urls . targets } /new` ;
2022-11-30 14:01:23 -08:00
authenticateSession ({});
2021-08-16 10:18:46 -07:00
});
test ( 'can save changes to existing target' , async function ( assert ) {
2022-04-15 13:52:31 -05:00
assert . expect ( 5 );
2022-11-30 14:01:23 -08:00
await visit ( urls . targets );
2021-08-16 10:18:46 -07:00
assert . notEqual ( instances . target . name , 'random string' );
2022-04-15 13:52:31 -05:00
assert . notEqual ( instances . target . worker_filter , 'random filter' );
2022-11-30 14:01:23 -08:00
await click ( `[href=" ${ urls . target } "]` );
2023-01-23 14:28:37 -08:00
await click ( '.rose-form-actions [type="button"]' , 'Activate edit mode' );
2021-08-16 10:18:46 -07:00
await fillIn ( '[name="name"]' , 'random string' );
2022-04-15 13:52:31 -05:00
await fillIn ( '[name="worker_filter"]' , 'random filter' );
2021-08-16 10:18:46 -07:00
await click ( '.rose-form-actions [type="submit"]' );
2022-11-30 14:01:23 -08:00
2022-07-07 11:18:51 -07:00
assert . strictEqual ( currentURL (), urls . target );
assert . strictEqual (
2022-11-30 14:01:23 -08:00
this . server . schema . targets . first (). name ,
2021-08-16 10:18:46 -07:00
'random string'
);
2022-07-07 11:18:51 -07:00
assert . strictEqual (
2022-11-30 14:01:23 -08:00
this . server . schema . targets . first (). workerFilter ,
2022-04-15 13:52:31 -05:00
'random filter'
);
2021-08-16 10:18:46 -07:00
});
2023-01-11 15:46:47 -06:00
test ( 'updating a target shows the worker_filter deprecation message when "target-worker-filters-v2" is enabled' , async function ( assert ) {
featuresService . enable ( 'target-worker-filters-v2' );
assert . expect ( 1 );
await visit ( urls . target );
assert . dom ( '.hds-alert' ). isVisible ();
});
test ( 'updating a target does not show the worker_filter deprecation message when "target-worker-filters-v2" is disabled' , async function ( assert ) {
2023-04-03 20:28:31 -07:00
assert . expect ( 2 );
2023-01-11 15:46:47 -06:00
await visit ( urls . target );
2023-04-03 20:28:31 -07:00
assert . false ( featuresService . isEnabled ( 'target-worker-filters-v2' ));
2023-01-11 15:46:47 -06:00
assert . dom ( '.hds-alert' ). doesNotExist ();
});
test ( 'cannot edit worker_filter when "target-worker-filters-v2" is enabled' , async function ( assert ) {
featuresService . enable ( 'target-worker-filters-v2' );
assert . expect ( 1 );
await visit ( urls . target );
assert . dom ( '[name=worker_filter]' ). isDisabled ();
});
2023-02-09 16:00:19 -06:00
test ( 'show update filter button when the old worker filter field is has value' , async function ( assert ) {
2023-01-23 14:48:29 -08:00
featuresService . enable ( 'target-worker-filters-v2' );
assert . expect ( 2 );
await visit ( urls . target );
assert . dom ( '[name=worker_filter]' ). isVisible ();
await click ( '.rose-form-actions [type="button"]' , 'Activate edit mode' );
assert . dom ( '.hds-button' ). hasText ( 'Update Filter' );
});
test ( 'onClick update filter should select the egress toggle and the worker_filter value is copied into egress_worker_filter' , async function ( assert ) {
featuresService . enable ( 'target-worker-filters-v2' );
assert . expect ( 2 );
await visit ( urls . target );
assert . dom ( '[name=worker_filter]' ). isVisible ();
const worker_filter_value = this . server . schema . targets . first (). workerFilter ;
await click ( '.rose-form-actions [type="button"]' , 'Activate edit mode' );
await click ( '.hds-button[type="button"]' , 'Update Filter' );
assert . strictEqual (
this . server . schema . targets . first (). egressWorkerFilter ,
worker_filter_value
);
});
2023-02-09 16:00:19 -06:00
test ( 'onClick update filter should select the egress and ingress toggle and the worker_filter value is copied into egress_worker_filter and ingress_worker_filter' , async function ( assert ) {
featuresService . enable ( 'target-worker-filters-v2' );
featuresService . enable ( 'target-worker-filters-v2-ingress' );
assert . expect ( 3 );
await visit ( urls . target );
assert . dom ( '[name=worker_filter]' ). isVisible ();
const worker_filter_value = this . server . schema . targets . first (). workerFilter ;
await click ( '.rose-form-actions [type="button"]' , 'Activate edit mode' );
await click ( '.hds-button[type="button"]' , 'Update Filter' );
assert . strictEqual (
this . server . schema . targets . first (). egressWorkerFilter ,
worker_filter_value
);
assert . strictEqual (
this . server . schema . targets . first (). ingressWorkerFilter ,
worker_filter_value
);
});
2023-01-23 14:48:29 -08:00
test ( 'show filter input field when the `egress_worker_filter` toggle is on' , async function ( assert ) {
featuresService . enable ( 'target-worker-filters-v2' );
assert . expect ( 1 );
await visit ( urls . target );
await click ( '.rose-form-actions [type="button"]' , 'Activate edit mode' );
await click ( '.hds-button[type="button"]' , 'Update Filter' );
assert . dom ( '[name=egress_worker_filter]' ). isVisible ();
});
test ( 'hide filter input field when the `egress_worker_filter` toggled is off' , async function ( assert ) {
featuresService . enable ( 'target-worker-filters-v2' );
2023-03-17 14:34:37 -07:00
featuresService . enable ( 'target-worker-filters-v2-ingress' );
2023-01-23 14:48:29 -08:00
assert . expect ( 1 );
await visit ( urls . target );
await click ( '.rose-form-actions [type="button"]' , 'Activate edit mode' );
await click ( '.hds-button[type="button"]' , 'Update Filter' );
2023-03-17 14:34:37 -07:00
await click (
'[name="target-worker-filter-toggle-egress_worker_filter"]' ,
'Egress toggle'
);
2023-01-23 14:48:29 -08:00
assert . dom ( '[name=egress_worker_filter]' ). isNotVisible ();
});
test ( 'clear `egress_worker_field` value from a target when the toggle is off and form is saved' , async function ( assert ) {
featuresService . enable ( 'target-worker-filters-v2' );
2023-03-17 14:34:37 -07:00
featuresService . enable ( 'target-worker-filters-v2-ingress' );
2023-01-23 14:48:29 -08:00
assert . expect ( 5 );
await visit ( urls . target );
await click ( '.rose-form-actions [type="button"]' , 'Activate edit mode' );
await click ( '.hds-button[type="button"]' , 'Update Filter' );
await fillIn ( '[name=egress_worker_filter]' , 'random filter string' );
await click ( '.rose-form-actions [type="submit"]' );
assert . strictEqual ( currentURL (), urls . target );
assert . strictEqual (
this . server . schema . targets . first (). egressWorkerFilter ,
'random filter string'
);
await click ( '.rose-form-actions [type="button"]' , 'Activate edit mode' );
2023-03-17 14:34:37 -07:00
await click (
'[name="target-worker-filter-toggle-egress_worker_filter"]' ,
'Egress toggle'
);
2023-01-23 14:48:29 -08:00
await click ( '.rose-form-actions [type="submit"]' );
//clear egress_worker_filter when the toggle is off
assert . strictEqual ( currentURL (), urls . target );
assert . dom ( '[name=egress_worker_filter]' ). doesNotExist ();
assert . strictEqual (
this . server . schema . targets . first (). egressWorkerFilter ,
null
);
});
2023-02-09 16:00:19 -06:00
test ( 'show filter input field when the `ingress_worker_filter` toggle is on' , async function ( assert ) {
featuresService . enable ( 'target-worker-filters-v2' );
featuresService . enable ( 'target-worker-filters-v2-ingress' );
assert . expect ( 1 );
await visit ( urls . target );
await click ( '.rose-form-actions [type="button"]' , 'Activate edit mode' );
await click ( '.hds-button[type="button"]' , 'Update Filter' );
assert . dom ( '[name=ingress_worker_filter]' ). isVisible ();
});
test ( 'hide filter input field when the `ingress_worker_filter` toggled is off' , async function ( assert ) {
featuresService . enable ( 'target-worker-filters-v2' );
featuresService . enable ( 'target-worker-filters-v2-ingress' );
assert . expect ( 1 );
await visit ( urls . target );
await click ( '.rose-form-actions [type="button"]' , 'Activate edit mode' );
await click ( '.hds-button[type="button"]' , 'Update Filter' );
await click ( '.hds-form-toggle__control' , 'Ingress worker filter' );
assert . dom ( '[name=ingress_worker_filter]' ). isNotVisible ();
});
test ( 'clear `ingress_worker_field` value from a target when the toggle is off and form is saved' , async function ( assert ) {
featuresService . enable ( 'target-worker-filters-v2' );
featuresService . enable ( 'target-worker-filters-v2-ingress' );
assert . expect ( 5 );
await visit ( urls . target );
await click ( '.rose-form-actions [type="button"]' , 'Activate edit mode' );
await click ( '.hds-button[type="button"]' , 'Update Filter' );
await fillIn ( '[name=ingress_worker_filter]' , 'random filter string' );
await click ( '.rose-form-actions [type="submit"]' );
assert . strictEqual ( currentURL (), urls . target );
assert . strictEqual (
this . server . schema . targets . first (). ingressWorkerFilter ,
'random filter string'
);
await click ( '.rose-form-actions [type="button"]' , 'Activate edit mode' );
await click ( '.hds-form-toggle__control' , 'Ingress worker filter' );
await click ( '.rose-form-actions [type="submit"]' );
//clear egress_worker_filter when the toggle is off
assert . strictEqual ( currentURL (), urls . target );
assert . dom ( '[name=ingress_worker_filter]' ). doesNotExist ();
assert . strictEqual (
this . server . schema . targets . first (). ingressWorkerFilter ,
null
);
});
2021-08-16 10:18:46 -07:00
test ( 'can cancel changes to existing target' , async function ( assert ) {
assert . expect ( 2 );
2022-11-30 14:01:23 -08:00
await visit ( urls . targets );
await click ( `[href=" ${ urls . target } "]` );
2023-01-23 14:28:37 -08:00
await click ( '.rose-form-actions [type="button"]' , 'Activate edit mode' );
2021-08-16 10:18:46 -07:00
await fillIn ( '[name="name"]' , 'random string' );
await click ( '.rose-form-actions [type="button"]' );
2022-11-30 14:01:23 -08:00
2021-08-16 10:18:46 -07:00
assert . notEqual ( instances . target . name , 'random string' );
2022-11-30 14:01:23 -08:00
assert . dom ( '[name="name"]' ). hasValue ( instances . target . name );
2021-08-16 10:18:46 -07:00
});
test ( 'saving an existing target with invalid fields displays error messages' , async function ( assert ) {
assert . expect ( 2 );
2022-11-30 14:01:23 -08:00
await visit ( urls . targets );
2021-08-16 10:18:46 -07:00
this . server . patch ( '/targets/:id' , () => {
return new Response (
400 ,
{},
{
status : 400 ,
code : 'invalid_argument' ,
message : 'The request was invalid.' ,
details : {
request_fields : [
{
name : 'name' ,
description : 'Name is required.' ,
},
],
},
}
);
});
2022-11-30 14:01:23 -08:00
await click ( `[href=" ${ urls . target } "]` );
2023-01-23 14:28:37 -08:00
await click ( '.rose-form-actions [type="button"]' , 'Activate edit mode' );
2021-08-16 10:18:46 -07:00
await fillIn ( '[name="name"]' , 'random string' );
await click ( '[type="submit"]' );
2022-11-30 14:01:23 -08:00
assert . dom ( '[role="alert"] div' ). hasText ( 'The request was invalid.' );
2023-01-10 16:18:28 -06:00
assert . dom ( '.hds-form-error__message' ). hasText ( 'Name is required.' );
2021-08-16 10:18:46 -07:00
});
test ( 'can discard unsaved target changes via dialog' , async function ( assert ) {
2023-01-23 14:48:29 -08:00
featuresService . enable ( 'target-worker-filters-v2' );
assert . expect ( 7 );
2021-08-16 10:18:46 -07:00
const confirmService = this . owner . lookup ( 'service:confirm' );
confirmService . enabled = true ;
assert . notEqual ( instances . target . name , 'random string' );
2023-01-23 14:48:29 -08:00
assert . notEqual (
instances . target . egressWorkerFilter ,
'random worker string'
);
2022-11-30 14:01:23 -08:00
await visit ( urls . targets );
await click ( `[href=" ${ urls . target } "]` );
2023-01-23 14:28:37 -08:00
await click ( '.rose-form-actions [type="button"]' , 'Activate edit mode' );
2021-08-16 10:18:46 -07:00
await fillIn ( '[name="name"]' , 'random string' );
2023-01-23 14:48:29 -08:00
await click ( '.hds-button[type="button"]' , 'Update Filter' );
await fillIn ( '[name="egress_worker_filter"]' , 'random worker string' );
2022-07-07 11:18:51 -07:00
assert . strictEqual ( currentURL (), urls . target );
2022-11-30 14:01:23 -08:00
await click ( `[href=" ${ urls . targets } "]` );
assert . dom ( '.rose-dialog' ). exists ();
await click ( '.rose-dialog-footer button:first-child' , 'Click Discard' );
assert . strictEqual ( currentURL (), urls . targets );
assert . notEqual ( this . server . schema . targets . first (). name , 'random string' );
2023-01-23 14:48:29 -08:00
assert . notEqual (
this . server . schema . targets . first (). egressWorkerFilter ,
'random worker string'
);
2021-08-16 10:18:46 -07:00
});
2022-11-30 14:01:23 -08:00
test ( 'can click cancel on discard dialog box for unsaved target changes' , async function ( assert ) {
2023-01-23 14:48:29 -08:00
featuresService . enable ( 'target-worker-filters-v2' );
assert . expect ( 6 );
2021-08-16 10:18:46 -07:00
const confirmService = this . owner . lookup ( 'service:confirm' );
confirmService . enabled = true ;
assert . notEqual ( instances . target . name , 'random string' );
2022-11-30 14:01:23 -08:00
await visit ( urls . targets );
await click ( `[href=" ${ urls . target } "]` );
2023-01-23 14:28:37 -08:00
await click ( '.rose-form-actions [type="button"]' , 'Activate edit mode' );
2021-08-16 10:18:46 -07:00
await fillIn ( '[name="name"]' , 'random string' );
2023-01-23 14:48:29 -08:00
await click ( '.hds-button[type="button"]' , 'Update Filter' );
await fillIn ( '[name="egress_worker_filter"]' , 'random filter' );
2022-07-07 11:18:51 -07:00
assert . strictEqual ( currentURL (), urls . target );
2022-11-30 14:01:23 -08:00
await click ( `[href=" ${ urls . targets } "]` );
assert . dom ( '.rose-dialog' ). exists ();
await click ( '.rose-dialog-footer button:last-child' , 'Click Cancel' );
assert . strictEqual ( currentURL (), urls . target );
assert . notEqual ( this . server . schema . targets . first (). name , 'random string' );
2023-01-23 14:48:29 -08:00
assert . notEqual (
this . server . schema . targets . first (). egressWorkerFilter ,
'random string'
);
2021-08-16 10:18:46 -07:00
});
test ( 'cannot make changes to an existing target without proper authorization' , async function ( assert ) {
assert . expect ( 1 );
2022-11-30 14:01:23 -08:00
await visit ( urls . targets );
2021-08-16 10:18:46 -07:00
instances . target . authorized_actions =
instances . target . authorized_actions . filter (( item ) => item !== 'update' );
2022-11-30 14:01:23 -08:00
await click ( `[href=" ${ urls . target } "]` );
2023-01-23 14:28:37 -08:00
assert . dom ( '.rose-form-actions [type="button"]' ). doesNotExist ();
2021-08-16 10:18:46 -07:00
});
2023-01-17 15:00:43 -05:00
test ( 'saving address with existing host sources brings up confirmation modal and removes host sources' , async function ( assert ) {
assert . expect ( 4 );
2023-04-03 20:28:31 -07:00
featuresService . enable ( 'ssh-target' );
featuresService . enable ( 'target-network-address' );
2023-01-17 15:00:43 -05:00
const confirmService = this . owner . lookup ( 'service:confirm' );
confirmService . enabled = true ;
this . server . createList (
'host-catalog' ,
8 ,
{ scope : instances . scopes . project },
'withChildren'
);
this . server . createList (
'credential-store' ,
3 ,
{ scope : instances . scopes . project },
'withAssociations'
);
const target = this . server . create (
'target' ,
{ scope : instances . scopes . project },
'withAssociations'
);
assert . true ( this . server . schema . targets . find ( target . id ). hostSets . length > 0 );
const url = ` ${ urls . targets } / ${ target . id } ` ;
await visit ( urls . targets );
await click ( `[href=" ${ url } "]` );
await click ( 'form [type="button"]' , 'Activate edit mode' );
await fillIn ( '[name="address"]' , '0.0.0.0' );
await click ( '[type="submit"]' );
assert . dom ( '.rose-dialog' ). isVisible ();
await click ( '.rose-dialog-footer .rose-button-primary' , 'Remove resources' );
assert . strictEqual (
this . server . schema . targets . find ( target . id ). address ,
'0.0.0.0'
);
assert . strictEqual (
this . server . schema . targets . find ( target . id ). hostSets . length ,
0
);
});
test ( 'saving address with existing host sources brings up confirmation modal and can cancel' , async function ( assert ) {
assert . expect ( 4 );
2023-04-03 20:28:31 -07:00
featuresService . enable ( 'ssh-target' );
featuresService . enable ( 'target-network-address' );
2023-01-17 15:00:43 -05:00
const confirmService = this . owner . lookup ( 'service:confirm' );
confirmService . enabled = true ;
this . server . createList (
'host-catalog' ,
8 ,
{ scope : instances . scopes . project },
'withChildren'
);
this . server . createList (
'credential-store' ,
3 ,
{ scope : instances . scopes . project },
'withAssociations'
);
const target = this . server . create (
'target' ,
{ scope : instances . scopes . project },
'withAssociations'
);
assert . true ( this . server . schema . targets . find ( target . id ). hostSets . length > 0 );
const url = ` ${ urls . targets } / ${ target . id } ` ;
await visit ( urls . targets );
await click ( `[href=" ${ url } "]` );
await click ( 'form [type="button"]' , 'Activate edit mode' );
await fillIn ( '[name="address"]' , '0.0.0.0' );
await click ( '[type="submit"]' );
assert . dom ( '.rose-dialog' ). isVisible ();
await click ( '.rose-dialog-footer .rose-button-secondary' , 'Cancel' );
assert . strictEqual (
this . server . schema . targets . find ( target . id ). address ,
undefined
);
assert . true ( this . server . schema . targets . find ( target . id ). hostSets . length > 0 );
});
2021-08-16 10:18:46 -07:00
});