Refactor origin to cluster (#1210)
This commit is contained in:
1 parent
40ba4286d3
commit
4fcb005a1f
43 files changed
+492
-609
No files matched your search
@@ -159,7 +159,7 @@ You will need to turn `off` mirage and run it: `$ ENABLE_MIRAGE=false yarn start
|
||||
|
||||
In login screen, authenticate using generated admin login name and password.
|
||||
|
||||
Enter the origin of your Boundary dev instance, by default is: `http://localhost:9200`.
|
||||
Enter the cluster URL of your Boundary dev instance, by default is: `http://localhost:9200`.
|
||||
|
||||
### Committing
|
||||
|
||||
|
||||
@@ -15,19 +15,19 @@ export default function initializeMockIPC(server, config) {
|
||||
return await this[method](payload);
|
||||
}
|
||||
|
||||
origin = null;
|
||||
clusterUrl = null;
|
||||
|
||||
getOrigin() {
|
||||
return this.origin;
|
||||
getClusterUrl() {
|
||||
return this.clusterUrl;
|
||||
}
|
||||
|
||||
setOrigin(origin) {
|
||||
this.origin = origin;
|
||||
return this.origin;
|
||||
setClusterUrl(clusterUrl) {
|
||||
this.clusterUrl = clusterUrl;
|
||||
return this.clusterUrl;
|
||||
}
|
||||
|
||||
resetOrigin() {
|
||||
this.origin = null;
|
||||
resetClusterUrl() {
|
||||
this.clusterUrl = null;
|
||||
}
|
||||
|
||||
openExternal(href) {
|
||||
|
||||
@@ -31,7 +31,7 @@ add-hosts: Add Hosts
|
||||
set-password: Set Password
|
||||
change-password: Change Password
|
||||
edit-form: Edit Form
|
||||
change-origin: Change Origin URL
|
||||
change-cluster-url: Change Cluster URL
|
||||
change-state: Change State
|
||||
close: Close
|
||||
toggle-secret: Toggle secret visibility
|
||||
|
||||
@@ -9,7 +9,7 @@ auth:
|
||||
authenticating-with-org: "Scope: You are authenticating with organization \"{name}\""
|
||||
flow-success: You've successfully authenticated. You may now close this window and return to the client.
|
||||
flow-error: Something went wrong while authenticating. Please close this window and try again. If the problem persists, notify your administrator.
|
||||
origin:
|
||||
cluster-url:
|
||||
connected-to: Connected to
|
||||
titles:
|
||||
home: Home
|
||||
@@ -36,7 +36,7 @@ titles:
|
||||
create-resources: Create Resources
|
||||
descriptions:
|
||||
empty-set: There are no items to display yet. You may be able to add items or try back later.
|
||||
origin-initialization: To get started, please enter your origin URL
|
||||
cluster-url-initialization: To get started, please enter your cluster URL
|
||||
create-but-not-list: You do not have permission to list {resource}, but you can create new instances.
|
||||
neither-list-nor-create: You do not have permission to list or create {resource}.
|
||||
no-results: We found no matching records.
|
||||
|
||||
@@ -17,7 +17,7 @@ generic:
|
||||
title: Error
|
||||
authentication-failed:
|
||||
title: Authentication Failed
|
||||
origin-verification-failed:
|
||||
description: Unable to connect to the specified origin. Please check the URL and try again.
|
||||
cluster-url-verification-failed:
|
||||
description: Unable to connect to the specified cluster URL. Please check the URL and try again.
|
||||
quick-setup-failed:
|
||||
description: We're sorry, quick setup was unable to generate all resources.
|
||||
@@ -49,8 +49,8 @@ host_set:
|
||||
grant_scope:
|
||||
label: Grant Scope
|
||||
help: Specify the scope to which this role applies.
|
||||
origin:
|
||||
label: Origin URL
|
||||
cluster-url:
|
||||
label: Cluster URL
|
||||
description: The Boundary URL to which to connect (e.g. protocol://host:port)
|
||||
proxy:
|
||||
label: Proxy
|
||||
@@ -148,4 +148,4 @@ ip_addresses:
|
||||
label: Latest IP Addresses
|
||||
sync-interval:
|
||||
label: Sync Interval
|
||||
help: Number of seconds between the time Boundary syncs hosts in this set.
|
||||
help: Number of seconds between the time Boundary syncs hosts in this set.
|
||||
@@ -23,7 +23,7 @@ export default class OnboardingQuickSetupCreateResourcesSuccessRoute extends Rou
|
||||
const model = this.modelFor('onboarding.quick-setup.create-resources');
|
||||
return {
|
||||
...model,
|
||||
origin: this.window.location.origin,
|
||||
clusterUrl: this.window.location.origin,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -48,11 +48,11 @@
|
||||
<p>{{t 'onboarding.success.descriptions.controller'}}</p>
|
||||
<div class='onboarding-quick-setup-success-controller-url'>
|
||||
<Copyable
|
||||
@text={{this.model.origin}}
|
||||
@text={{this.model.clusterUrl}}
|
||||
@buttonText={{t 'actions.copy-to-clipboard'}}
|
||||
@acknowledgeText={{t 'states.copied'}}
|
||||
>
|
||||
<code>{{this.model.origin}}</code>
|
||||
<code>{{this.model.clusterUrl}}</code>
|
||||
</Copyable>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -15,98 +15,6 @@
|
||||
|
||||
<dialog.body>
|
||||
{{yield to='body'}}
|
||||
{{!--
|
||||
<Rose::Separator />
|
||||
<h3>Credentials</h3>
|
||||
<div class="credentials-card">
|
||||
<div class="credentials-card-header">
|
||||
<div><Rose::Icon @name="key" /> Credentials</div>
|
||||
<div>
|
||||
<Rose::Button
|
||||
@disabled={{false}}
|
||||
@style={{style}}
|
||||
@iconRight={{iconRight}}
|
||||
{{on "click" onClick}}
|
||||
>
|
||||
Credential library details
|
||||
</Rose::Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Rose::Separator />
|
||||
|
||||
<div class="credentials-card-body">
|
||||
<Rose::Table @style="condensed" as |table|>
|
||||
<table.header as |header|>
|
||||
<header.row as |row|>
|
||||
<row.headerCell @shrink={{true}}>Key</row.headerCell>
|
||||
<row.headerCell colspan="2">Value</row.headerCell>
|
||||
</header.row>
|
||||
</table.header>
|
||||
<table.body as |body|>
|
||||
<body.row as |row|>
|
||||
<row.cell>Foo</row.cell>
|
||||
<row.cell> </row.cell>
|
||||
</body.row>
|
||||
<body.row as |row|>
|
||||
<row.cell>ttl</row.cell>
|
||||
<row.cell> </row.cell>
|
||||
</body.row>
|
||||
</table.body>
|
||||
</Rose::Table>
|
||||
</div>
|
||||
|
||||
<div class="credentials-card-footer">
|
||||
<p><LinkTo @route='index'>View raw API output</LinkTo></p>
|
||||
<Rose::Separator />
|
||||
<div>Code</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="credentials-card">
|
||||
<div class="credentials-card-header">
|
||||
<div><Rose::Icon @name="key" /> Credentials</div>
|
||||
<div>
|
||||
<Rose::Button
|
||||
@disabled={{false}}
|
||||
@style={{style}}
|
||||
@iconRight={{iconRight}}
|
||||
{{on "click" onClick}}
|
||||
>
|
||||
Credential library details
|
||||
</Rose::Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Rose::Separator />
|
||||
|
||||
<div class="credentials-card-body">
|
||||
<Rose::Table @style="condensed" as |table|>
|
||||
<table.header as |header|>
|
||||
<header.row as |row|>
|
||||
<row.headerCell @shrink={{true}}>Key</row.headerCell>
|
||||
<row.headerCell colspan="2">Value</row.headerCell>
|
||||
</header.row>
|
||||
</table.header>
|
||||
<table.body as |body|>
|
||||
<body.row as |row|>
|
||||
<row.cell>Foo</row.cell>
|
||||
<row.cell> </row.cell>
|
||||
</body.row>
|
||||
<body.row as |row|>
|
||||
<row.cell>ttl</row.cell>
|
||||
<row.cell> </row.cell>
|
||||
</body.row>
|
||||
</table.body>
|
||||
</Rose::Table>
|
||||
</div>
|
||||
|
||||
<div class="credentials-card-footer">
|
||||
<p><LinkTo @route='index'>View raw API output</LinkTo></p>
|
||||
<Rose::Separator />
|
||||
<div>Code</div>
|
||||
</div>
|
||||
</div>--}}
|
||||
</dialog.body>
|
||||
<dialog.footer>
|
||||
{{yield to='footer'}}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { inject as service } from '@ember/service';
|
||||
export default class ScopesScopeAuthenticateController extends Controller {
|
||||
// =services
|
||||
|
||||
@service origin;
|
||||
@service clusterUrl;
|
||||
|
||||
// =attributes
|
||||
|
||||
|
||||
@@ -11,10 +11,10 @@ export function initialize(registry) {
|
||||
this._super(...arguments);
|
||||
const originalBeforeModel = this.beforeModel;
|
||||
|
||||
// Override the beforeModel hook and initialize the origin
|
||||
// Override the beforeModel hook and initialize the clusterUrl
|
||||
this.beforeModel = async function () {
|
||||
const origin = getOwner(this).lookup('service:origin');
|
||||
return origin.updateOrigin().then(
|
||||
const clusterUrl = getOwner(this).lookup('service:clusterUrl');
|
||||
return clusterUrl.updateClusterUrl().then(
|
||||
() => originalBeforeModel.apply(this, arguments),
|
||||
() => originalBeforeModel.apply(this, arguments)
|
||||
);
|
||||
@@ -25,5 +25,5 @@ Router.map(function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
this.route('origin');
|
||||
this.route('cluster-url');
|
||||
});
|
||||
@@ -9,7 +9,7 @@ export default class ApplicationRoute extends Route {
|
||||
// =services
|
||||
|
||||
@service session;
|
||||
@service origin;
|
||||
@service clusterUrl;
|
||||
@service ipc;
|
||||
|
||||
// =attributes
|
||||
@@ -20,14 +20,14 @@ export default class ApplicationRoute extends Route {
|
||||
routeIfUnauthenticated = 'index';
|
||||
|
||||
/**
|
||||
* Check that the origin specified in the renderer matches the origin
|
||||
* Check that the clusterUrl specified in the renderer matches the clusterUrl
|
||||
* reported by the main process. If they differ, update the main process
|
||||
* origin so that the renderer's CSP can be rewritten to allow requests.
|
||||
* clusterUrl so that the renderer's CSP can be rewritten to allow requests.
|
||||
*/
|
||||
beforeModel() {
|
||||
const theme = this.session.get('data.theme');
|
||||
this.toggleTheme(theme);
|
||||
return this.origin.updateOrigin();
|
||||
return this.clusterUrl.updateClusterUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,12 +52,12 @@ export default class ApplicationRoute extends Route {
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects from origin and invalidates session, thereby resetting
|
||||
* the client and reloading to the onboarding origin screen.
|
||||
* Disconnects from clusterUrl and invalidates session, thereby resetting
|
||||
* the client and reloading to the onboarding clusterUrl screen.
|
||||
*/
|
||||
@action
|
||||
disconnect() {
|
||||
this.origin.resetOrigin();
|
||||
this.clusterUrl.resetClusterUrl();
|
||||
this.invalidateSession();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ import { action } from '@ember/object';
|
||||
import { loading } from 'ember-loading';
|
||||
import config from '../config/environment';
|
||||
|
||||
export default class OriginRoute extends Route {
|
||||
export default class ClusterUrlRoute extends Route {
|
||||
// =services
|
||||
|
||||
@service session;
|
||||
@service origin;
|
||||
@service clusterUrl;
|
||||
@service intl;
|
||||
@service notify;
|
||||
@service router;
|
||||
@@ -38,45 +38,45 @@ export default class OriginRoute extends Route {
|
||||
|
||||
/**
|
||||
* If arriving here already authenticated, redirect to index for further
|
||||
* processing. User must be logged out before changing the origin.
|
||||
* processing. User must be logged out before changing the clusterUrl.
|
||||
*/
|
||||
beforeModel() {
|
||||
if (this.session.isAuthenticated) this.router.replaceWith('index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the existing origin, if any, to the controller scope.
|
||||
* Adds the existing clusterUrl, if any, to the controller scope.
|
||||
* @param {Controller} controller
|
||||
*/
|
||||
setupController(controller) {
|
||||
super.setupController(...arguments);
|
||||
let origin = this.origin.rendererOrigin;
|
||||
// If origin is unset and this is a development environment,
|
||||
// autoset the origin field of the UI for better DX.
|
||||
let clusterUrl = this.clusterUrl.rendererClusterUrl;
|
||||
// If clusterUrl is unset and this is a development environment,
|
||||
// autoset the clusterUrl field of the UI for better DX.
|
||||
// The controller URL is almost always the same as the current window when
|
||||
// using mocks, and this makes development more rapid since developers
|
||||
// do not need to fill an origin on every session.
|
||||
if (!origin && config.autoOrigin) {
|
||||
origin = this.window.location.origin;
|
||||
// do not need to fill a clusterUrl on every session.
|
||||
if (!clusterUrl && config.autoOrigin) {
|
||||
clusterUrl = this.window.location.origin;
|
||||
}
|
||||
controller.setProperties({ origin });
|
||||
controller.setProperties({ clusterUrl: clusterUrl });
|
||||
}
|
||||
|
||||
/**
|
||||
* Points the API to the specified origin. When the main process receives
|
||||
* the origin, it is expected that the renderer will be restarted.
|
||||
* @param {string} origin
|
||||
* Points the API to the specified clusterUrl. When the main process receives
|
||||
* the clusterUrl, it is expected that the renderer will be restarted.
|
||||
* @param {string} clusterUrl
|
||||
*/
|
||||
@action
|
||||
@loading
|
||||
async setOrigin(origin) {
|
||||
async setClusterUrl(clusterUrl) {
|
||||
try {
|
||||
await this.origin.setOrigin(origin);
|
||||
await this.clusterUrl.setClusterUrl(clusterUrl);
|
||||
this.router.replaceWith('index');
|
||||
} catch (e) {
|
||||
// If scopes do not load, we assume this is not a Boundary API
|
||||
const errorMessage = this.intl.t(
|
||||
'errors.origin-verification-failed.description'
|
||||
'errors.cluster-url-verification-failed.description'
|
||||
);
|
||||
this.notify.error(errorMessage, { closeAfter: null });
|
||||
}
|
||||
@@ -4,18 +4,18 @@ import { inject as service } from '@ember/service';
|
||||
export default class IndexRoute extends Route {
|
||||
// =services
|
||||
|
||||
@service origin;
|
||||
@service clusterUrl;
|
||||
@service router;
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* If no origin is specified yet, redirects to origin, otherwise scopes.
|
||||
* If no clusterUrl is specified yet, redirects to cluster-url, otherwise scopes.
|
||||
*/
|
||||
redirect() {
|
||||
const rendererOrigin = this.origin.rendererOrigin;
|
||||
if (!rendererOrigin) {
|
||||
this.router.replaceWith('origin');
|
||||
const rendererClusterUrl = this.clusterUrl.rendererClusterUrl;
|
||||
if (!rendererClusterUrl) {
|
||||
this.router.replaceWith('cluster-url');
|
||||
} else {
|
||||
this.router.replaceWith('scopes');
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ export default class ScopesScopeAuthenticateRoute extends Route {
|
||||
// =services
|
||||
|
||||
@service session;
|
||||
@service origin;
|
||||
@service clusterUrl;
|
||||
@service router;
|
||||
|
||||
// =methods
|
||||
@@ -31,16 +31,16 @@ export default class ScopesScopeAuthenticateRoute extends Route {
|
||||
}
|
||||
|
||||
redirect() {
|
||||
if (!this.origin.rendererOrigin) this.router.replaceWith('index');
|
||||
if (!this.clusterUrl.rendererClusterUrl) this.router.replaceWith('index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the existing origin, if any, to the controller scope.
|
||||
* Adds the existing clusterUrl, if any, to the controller scope.
|
||||
* @param {Controller} controller
|
||||
*/
|
||||
setupController(controller) {
|
||||
super.setupController(...arguments);
|
||||
const origin = this.origin.rendererOrigin;
|
||||
controller.setProperties({ origin });
|
||||
const clusterUrl = this.clusterUrl.rendererClusterUrl;
|
||||
controller.setProperties({ clusterUrl });
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ export default class ScopesScopeProjectsTargetsRoute extends Route {
|
||||
|
||||
@service ipc;
|
||||
@service session;
|
||||
@service origin;
|
||||
@service clusterUrl;
|
||||
@service notify;
|
||||
@service confirm;
|
||||
@service resourceFilterStore;
|
||||
|
||||
@@ -7,7 +7,7 @@ export default class ScopesScopeProjectsTargetsTargetHostsRoute extends Route {
|
||||
|
||||
@service ipc;
|
||||
@service session;
|
||||
@service origin;
|
||||
@service clusterUrl;
|
||||
@service notify;
|
||||
@service confirm;
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
import Service from '@ember/service';
|
||||
import { assert } from '@ember/debug';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { notifyError } from 'core/decorators/notify';
|
||||
|
||||
export default class ClusterUrlService extends Service {
|
||||
// =services
|
||||
|
||||
@service ipc;
|
||||
@service store;
|
||||
@service storage;
|
||||
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* @type {ApplicationAdapter}
|
||||
*/
|
||||
get adapter() {
|
||||
return this.store.adapterFor('application');
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {?string}
|
||||
*/
|
||||
get rendererClusterUrl() {
|
||||
return this.storage.getItem('cluster-url');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {?string} clusterUrl
|
||||
*/
|
||||
set rendererClusterUrl(clusterUrl) {
|
||||
this.storage.setItem('cluster-url', clusterUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {Promise{?string}}
|
||||
*/
|
||||
get mainClusterUrl() {
|
||||
return this.ipc.invoke('getClusterUrl');
|
||||
}
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Sets the main clusterUrl equal to the current renderer clusterUrl (if any).
|
||||
*/
|
||||
async updateClusterUrl() {
|
||||
const rendererClusterUrl = this.rendererClusterUrl;
|
||||
if (rendererClusterUrl) await this.setClusterUrl(rendererClusterUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that the specified clusterUrl is a Boundary API. If so, the app is
|
||||
* updated to use the clusterUrl. If it is not a Boundary API, or an clusterUrl
|
||||
* wasn't specified, throws an error.
|
||||
* @param {string} clusterUrl - protocol://host:port
|
||||
*/
|
||||
async setClusterUrl(clusterUrl) {
|
||||
const originalHost = this.adapter.host;
|
||||
assert(
|
||||
`setClusterUrl expects a string, you passed ${clusterUrl}`,
|
||||
typeof clusterUrl === 'string'
|
||||
);
|
||||
try {
|
||||
// Trim whitespaces and silently drop trailing slashes if present.
|
||||
// This is important since API paths that will be appended to the clusterUrl
|
||||
// will include preceeding slashes already.
|
||||
clusterUrl = clusterUrl.trim();
|
||||
clusterUrl = clusterUrl.replace(/\/*$/, '');
|
||||
this.adapter.host = clusterUrl;
|
||||
this.rendererClusterUrl = clusterUrl;
|
||||
if (clusterUrl !== (await this.mainClusterUrl)) {
|
||||
await this.ipc.invoke('setClusterUrl', clusterUrl);
|
||||
}
|
||||
} catch (e) {
|
||||
this.adapter.host = originalHost;
|
||||
this.rendererClusterUrl = null;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the clusterUrl.
|
||||
*/
|
||||
@notifyError(({ message }) => message, { catch: true })
|
||||
async resetClusterUrl() {
|
||||
this.rendererClusterUrl = null;
|
||||
await this.ipc.invoke('resetClusterUrl');
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
import Service from '@ember/service';
|
||||
import { assert } from '@ember/debug';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { notifyError } from 'core/decorators/notify';
|
||||
|
||||
export default class OriginService extends Service {
|
||||
// =services
|
||||
|
||||
@service ipc;
|
||||
@service store;
|
||||
@service storage;
|
||||
|
||||
// =attributes
|
||||
|
||||
/**
|
||||
* @type {ApplicationAdapter}
|
||||
*/
|
||||
get adapter() {
|
||||
return this.store.adapterFor('application');
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {?string}
|
||||
*/
|
||||
get rendererOrigin() {
|
||||
return this.storage.getItem('origin');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {?string} origin
|
||||
*/
|
||||
set rendererOrigin(origin) {
|
||||
this.storage.setItem('origin', origin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {Promise{?string}}
|
||||
*/
|
||||
get mainOrigin() {
|
||||
return this.ipc.invoke('getOrigin');
|
||||
}
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Sets the main origin equal to the current renderer origin (if any).
|
||||
*/
|
||||
async updateOrigin() {
|
||||
const rendererOrigin = this.rendererOrigin;
|
||||
if (rendererOrigin) await this.setOrigin(rendererOrigin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that the specified origin is a Boundary API. If so, the app is
|
||||
* updated to use the origin. If it is not a Boundary API, or an origin
|
||||
* wasn't specified, throws an error.
|
||||
* @param {string} origin - protocol://host:port
|
||||
*/
|
||||
async setOrigin(origin) {
|
||||
const originalHost = this.adapter.host;
|
||||
assert(
|
||||
`setOrigin expects a string, you passed ${origin}`,
|
||||
typeof origin === 'string'
|
||||
);
|
||||
try {
|
||||
// Trim whitespaces and silently drop trailing slashes if present.
|
||||
// This is important since API paths that will be appended to the origin
|
||||
// will include preceeding slashes already.
|
||||
origin = origin.trim();
|
||||
origin = origin.replace(/\/*$/, '');
|
||||
this.adapter.host = origin;
|
||||
this.rendererOrigin = origin;
|
||||
if (origin !== (await this.mainOrigin)) {
|
||||
await this.ipc.invoke('setOrigin', origin);
|
||||
}
|
||||
} catch (e) {
|
||||
this.adapter.host = originalHost;
|
||||
this.rendererOrigin = null;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the origin.
|
||||
*/
|
||||
@notifyError(({ message }) => message, { catch: true })
|
||||
async resetOrigin() {
|
||||
this.rendererOrigin = null;
|
||||
await this.ipc.invoke('resetOrigin');
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
<main>
|
||||
<BrandedCard
|
||||
@title={{t 'titles.welcome-to-boundary'}}
|
||||
@description={{t 'descriptions.origin-initialization'}}
|
||||
@description={{t 'descriptions.cluster-url-initialization'}}
|
||||
>
|
||||
<Rose::Form
|
||||
class='full-width'
|
||||
@onSubmit={{route-action 'setOrigin' this.origin}}
|
||||
@onSubmit={{route-action 'setClusterUrl' this.clusterUrl}}
|
||||
@cancel={{false}}
|
||||
@disabled={{(is-loading)}}
|
||||
as |form|
|
||||
@@ -13,9 +13,9 @@
|
||||
<form.input
|
||||
@name='host'
|
||||
@type='text'
|
||||
@value={{this.origin}}
|
||||
@label={{t 'form.origin.label'}}
|
||||
@helperText={{t 'form.origin.description'}}
|
||||
@value={{this.clusterUrl}}
|
||||
@label={{t 'form.cluster-url.label'}}
|
||||
@helperText={{t 'form.cluster-url.description'}}
|
||||
{{autofocus}}
|
||||
/>
|
||||
<form.actions @submitText={{t 'actions.submit'}} @showCancel={{false}} />
|
||||
@@ -62,11 +62,11 @@
|
||||
{{outlet}}
|
||||
|
||||
<p class='change-origin'>
|
||||
{{t 'origin.connected-to'}}:
|
||||
<code>{{this.origin}}</code>
|
||||
{{t 'cluster-url.connected-to'}}:
|
||||
<code>{{this.clusterUrl}}</code>
|
||||
<br />
|
||||
<LinkTo @route='origin'>
|
||||
{{t 'actions.change-origin'}}
|
||||
<LinkTo @route='cluster-url'>
|
||||
{{t 'actions.change-cluster-url'}}
|
||||
</LinkTo>
|
||||
</p>
|
||||
|
||||
|
||||
@@ -27,10 +27,10 @@ const enableDevCSP = () => {
|
||||
const generateCSPHeader = () => {
|
||||
const policy = Object.assign({}, csp);
|
||||
|
||||
// If an origin is specified, add it to the connect-src directive
|
||||
if (runtimeSettings.origin) {
|
||||
// If a clusterUrl is specified, add it to the connect-src directive
|
||||
if (runtimeSettings.clusterUrl) {
|
||||
policy['connect-src'] = policy['connect-src'].slice();
|
||||
policy['connect-src'].push(runtimeSettings.origin);
|
||||
policy['connect-src'].push(runtimeSettings.clusterUrl);
|
||||
}
|
||||
|
||||
return Object.keys(policy)
|
||||
|
||||
@@ -83,9 +83,9 @@ const createWindow = (partition, closeWindowCB) => {
|
||||
|
||||
const browserWindow = new BrowserWindow(browserWindowOptions);
|
||||
|
||||
// If the user-specified origin changes, reload the page so that
|
||||
// If the user-specified cluster URL changes, reload the page so that
|
||||
// the CSP can be refreshed with the this source allowed
|
||||
runtimeSettings.onOriginChange(() => browserWindow.loadURL(emberAppURL));
|
||||
runtimeSettings.onClusterUrlChange(() => browserWindow.loadURL(emberAppURL));
|
||||
|
||||
// Load the ember application
|
||||
browserWindow.loadURL(emberAppURL);
|
||||
|
||||
@@ -8,25 +8,25 @@ const sanitizer = require('../utils/sanitizer.js');
|
||||
const { isMac } = require('../helpers/platform.js');
|
||||
|
||||
/**
|
||||
* Returns the current runtime origin, which is used by the main thread to
|
||||
* Returns the current runtime clusterUrl, which is used by the main thread to
|
||||
* rewrite the CSP to allow requests.
|
||||
*/
|
||||
handle('getOrigin', () => runtimeSettings.origin);
|
||||
handle('getClusterUrl', () => runtimeSettings.clusterUrl);
|
||||
|
||||
/**
|
||||
* Sets the origin to be used in the content security policy and triggers
|
||||
* Sets the clusterUrl to be used in the content security policy and triggers
|
||||
* a main window reload.
|
||||
*/
|
||||
handle('setOrigin', async (requestOrigin) => {
|
||||
const origin = sanitizer.urlValidate(requestOrigin);
|
||||
await runtimeSettings.validateOrigin(origin);
|
||||
runtimeSettings.origin = origin;
|
||||
handle('setClusterUrl', async (requestOrigin) => {
|
||||
const clusterUrl = sanitizer.urlValidate(requestOrigin);
|
||||
await runtimeSettings.validateClusterUrl(clusterUrl);
|
||||
runtimeSettings.clusterUrl = clusterUrl;
|
||||
});
|
||||
|
||||
/**
|
||||
* Resets the origin.
|
||||
* Resets the clusterUrl.
|
||||
*/
|
||||
handle('resetOrigin', async () => runtimeSettings.resetOrigin());
|
||||
handle('resetClusterUrl', async () => runtimeSettings.resetClusterUrl());
|
||||
|
||||
/**
|
||||
* Opens the specified URL in an external browser. Only secure HTTPs URLs are
|
||||
@@ -60,7 +60,7 @@ handle('cliExists', () => boundaryCli.exists());
|
||||
* Establishes a boundary session and returns session details.
|
||||
*/
|
||||
handle('connect', ({ target_id, token, host_id }) =>
|
||||
sessionManager.start(runtimeSettings.origin, target_id, token, host_id)
|
||||
sessionManager.start(runtimeSettings.clusterUrl, target_id, token, host_id)
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
const netRequestPromise = require('../helpers/net-request-promise.js');
|
||||
|
||||
// Runtime settings are any configuration, especially user-specified,
|
||||
// set up at runtime. For example, the Boundary origin is a runtime setting.
|
||||
// set up at runtime. For example, the Boundary clusterUrl is a runtime setting.
|
||||
class RuntimeSettings {
|
||||
// Internal private origin is exposed via getter/setter below.
|
||||
#origin = undefined;
|
||||
// Internal private clusterUrl is exposed via getter/setter below.
|
||||
#clusterUrl = undefined;
|
||||
|
||||
/**
|
||||
* The user-specified Boundary origin, which should be allowed by CSP.
|
||||
* The user-specified Boundary clusterUrl, which should be allowed by CSP.
|
||||
* @type {?string}
|
||||
*/
|
||||
get origin() {
|
||||
return this.#origin;
|
||||
get clusterUrl() {
|
||||
return this.#clusterUrl;
|
||||
}
|
||||
set origin(origin) {
|
||||
if (this.#origin !== origin) {
|
||||
this.#origin = origin;
|
||||
this.triggerOriginChanged();
|
||||
set clusterUrl(clusterUrl) {
|
||||
if (this.#clusterUrl !== clusterUrl) {
|
||||
this.#clusterUrl = clusterUrl;
|
||||
this.triggerClusterUrlChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the origin is reachable and has a scopes endpoint.
|
||||
* Validates the clusterUrl is reachable and has a scopes endpoint.
|
||||
*/
|
||||
async validateOrigin(origin) {
|
||||
// If the origin is the Electron origin, it is automatically valid.
|
||||
if (origin === 'serve://boundary') return true;
|
||||
// Otherwise, check if scopes can be loaded from the specified origin.
|
||||
async validateClusterUrl(clusterUrl) {
|
||||
// If the clusterUrl is the Electron clusterUrl, it is automatically valid.
|
||||
if (clusterUrl === 'serve://boundary') return true;
|
||||
// Otherwise, check if scopes can be loaded from the specified clusterUrl.
|
||||
// Scopes are required by the desktop client, so this is a simple smoke
|
||||
// test to see if the origin is API-compatible with the desktop client.
|
||||
const scopesEndpoint = `${origin}/v1/scopes`;
|
||||
// test to see if the clusterUrl is API-compatible with the desktop client.
|
||||
const scopesEndpoint = `${clusterUrl}/v1/scopes`;
|
||||
try {
|
||||
const result = await netRequestPromise(scopesEndpoint);
|
||||
// Redirects (3xx) are handled in the netRequest Promise, so we only
|
||||
@@ -38,27 +38,27 @@ class RuntimeSettings {
|
||||
throw new Error();
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error(`Origin ${origin} could not be validated.`);
|
||||
throw new Error(`Cluster URL ${clusterUrl} could not be validated.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the origin to null.
|
||||
* Sets the clusterUrl to null.
|
||||
*/
|
||||
async resetOrigin() {
|
||||
this.origin = null;
|
||||
async resetClusterUrl() {
|
||||
this.#clusterUrl = null;
|
||||
}
|
||||
|
||||
// Quick and dirty event handler pattern to enable the application to respond
|
||||
// when the origin is changed.
|
||||
#originWatchers = [];
|
||||
// when the clusterUrl is changed.
|
||||
#clusterUrlWatchers = [];
|
||||
|
||||
onOriginChange(fn) {
|
||||
this.#originWatchers.push(fn);
|
||||
onClusterUrlChange(fn) {
|
||||
this.#clusterUrlWatchers.push(fn);
|
||||
}
|
||||
|
||||
triggerOriginChanged() {
|
||||
this.#originWatchers.forEach((fn) => fn(this.#origin));
|
||||
triggerClusterUrlChanged() {
|
||||
this.#clusterUrlWatchers.forEach((fn) => fn(this.#clusterUrl));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,27 +1,12 @@
|
||||
import { module, test } from 'qunit';
|
||||
import {
|
||||
visit,
|
||||
// currentURL,
|
||||
// fillIn,
|
||||
// click,
|
||||
find,
|
||||
//findAll,
|
||||
//getRootElement
|
||||
//setupOnerror,
|
||||
} from '@ember/test-helpers';
|
||||
import { visit, find } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
// import { Response } from 'miragejs';
|
||||
// import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
import sinon from 'sinon';
|
||||
import {
|
||||
// currentSession,
|
||||
// authenticateSession,
|
||||
invalidateSession,
|
||||
} from 'ember-simple-auth/test-support';
|
||||
import { invalidateSession } from 'ember-simple-auth/test-support';
|
||||
import { setupBrowserFakes } from 'ember-browser-services/test-support';
|
||||
|
||||
module('Acceptance | origin', function (hooks) {
|
||||
module('Acceptance | index', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupBrowserFakes(hooks, { window: true });
|
||||
setupMirage(hooks);
|
||||
@@ -31,13 +16,13 @@ module('Acceptance | origin', function (hooks) {
|
||||
};
|
||||
|
||||
const urls = {
|
||||
origin: null,
|
||||
clusterUrl: null,
|
||||
};
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
invalidateSession();
|
||||
|
||||
urls.origin = '/origin';
|
||||
urls.clusterUrl = '/cluster-url';
|
||||
|
||||
const ipcService = this.owner.lookup('service:ipc');
|
||||
stubs.ipcService = sinon.stub(ipcService, 'invoke');
|
||||
@@ -50,7 +35,7 @@ module('Acceptance | origin', function (hooks) {
|
||||
test('visiting index with chrome disabled hides custom window actions', async function (assert) {
|
||||
assert.expect(3);
|
||||
stubs.ipcService.withArgs('showWindowActions').returns(false);
|
||||
await visit(urls.origin);
|
||||
await visit(urls.clusterUrl);
|
||||
assert.notOk(find('.button-window-close'), 'Window close button');
|
||||
assert.notOk(find('.button-window-minimize'), 'Window minimize button');
|
||||
assert.notOk(find('.button-window-fullscreen'), 'Window fullscreen button');
|
||||
@@ -59,7 +44,7 @@ module('Acceptance | origin', function (hooks) {
|
||||
test('visiting index with chrome enabled shows custom window actions', async function (assert) {
|
||||
assert.expect(3);
|
||||
stubs.ipcService.withArgs('showWindowActions').returns(true);
|
||||
await visit(urls.origin);
|
||||
await visit(urls.clusterUrl);
|
||||
assert.ok(find('.button-window-close'), 'Window close button');
|
||||
assert.ok(find('.button-window-minimize'), 'Window minimize button');
|
||||
assert.ok(find('.button-window-fullscreen'), 'Window fullscreen button');
|
||||
@@ -68,7 +53,7 @@ module('Acceptance | origin', function (hooks) {
|
||||
test('visiting index with MacOS chrome enabled', async function (assert) {
|
||||
assert.expect(1);
|
||||
stubs.ipcService.withArgs('hasMacOSChrome').returns(true);
|
||||
await visit(urls.origin);
|
||||
await visit(urls.clusterUrl);
|
||||
assert.ok(
|
||||
find('.rose-header.header-cushion'),
|
||||
'Adds header padding around native window actions'
|
||||
@@ -78,7 +63,7 @@ module('Acceptance | origin', function (hooks) {
|
||||
test('visiting index with MacOS chrome disabled', async function (assert) {
|
||||
assert.expect(1);
|
||||
stubs.ipcService.withArgs('hasMacOSChrome').returns(false);
|
||||
await visit(urls.origin);
|
||||
await visit(urls.clusterUrl);
|
||||
assert.notOk(
|
||||
find('.rose-header.header-cushion'),
|
||||
'Does not add header padding around native window actions'
|
||||
|
||||
@@ -5,9 +5,7 @@ import {
|
||||
fillIn,
|
||||
click,
|
||||
find,
|
||||
//findAll,
|
||||
getRootElement,
|
||||
//setupOnerror,
|
||||
} from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
@@ -46,7 +44,7 @@ module('Acceptance | authentication', function (hooks) {
|
||||
|
||||
const urls = {
|
||||
index: '/',
|
||||
origin: '/origin',
|
||||
clusterUrl: '/cluster-url',
|
||||
scopes: {
|
||||
global: null,
|
||||
org: null,
|
||||
@@ -61,10 +59,10 @@ module('Acceptance | authentication', function (hooks) {
|
||||
sessions: null,
|
||||
};
|
||||
|
||||
const setDefaultOrigin = (test) => {
|
||||
const setDefaultClusterUrl = (test) => {
|
||||
const windowOrigin = window.location.origin;
|
||||
const origin = test.owner.lookup('service:origin');
|
||||
origin.rendererOrigin = windowOrigin;
|
||||
const clusterUrl = test.owner.lookup('service:clusterUrl');
|
||||
clusterUrl.rendererClusterUrl = windowOrigin;
|
||||
};
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
@@ -124,7 +122,7 @@ module('Acceptance | authentication', function (hooks) {
|
||||
|
||||
// Mock the postMessage interface used by IPC.
|
||||
this.owner.register('service:browser/window', WindowMockIPC);
|
||||
setDefaultOrigin(this);
|
||||
setDefaultClusterUrl(this);
|
||||
});
|
||||
|
||||
test('visiting index while unauthenticated redirects to global authenticate method', async function (assert) {
|
||||
@@ -144,12 +142,12 @@ module('Acceptance | authentication', function (hooks) {
|
||||
assert.ok(find('.rose-message'));
|
||||
});
|
||||
|
||||
test('visiting authenticate route without origin redirects to origin index', async function (assert) {
|
||||
test('visiting authenticate route without clusterUrl redirects to clusterUrl index', async function (assert) {
|
||||
assert.expect(1);
|
||||
this.owner.lookup('service:origin').rendererOrigin = null;
|
||||
this.owner.lookup('service:clusterUrl').rendererClusterUrl = null;
|
||||
await visit(urls.authenticate.global);
|
||||
await a11yAudit();
|
||||
assert.strictEqual(currentURL(), urls.origin);
|
||||
assert.strictEqual(currentURL(), urls.clusterUrl);
|
||||
});
|
||||
|
||||
test('visiting authenticate route when the scope cannot be loaded is allowed', async function (assert) {
|
||||
@@ -172,11 +170,11 @@ module('Acceptance | authentication', function (hooks) {
|
||||
assert.notOk(currentSession().isAuthenticated);
|
||||
});
|
||||
|
||||
test('can reset origin before authentication', async function (assert) {
|
||||
test('can reset clusterUrl before authentication', async function (assert) {
|
||||
assert.expect(1);
|
||||
await visit(urls.authenticate.methods.global);
|
||||
await click('.change-origin a');
|
||||
assert.strictEqual(currentURL(), urls.origin);
|
||||
assert.strictEqual(currentURL(), urls.clusterUrl);
|
||||
});
|
||||
|
||||
test('signing out redirects to first global authenticate method', async function (assert) {
|
||||
|
||||
+26
-41
@@ -1,29 +1,15 @@
|
||||
import { module, test } from 'qunit';
|
||||
import {
|
||||
visit,
|
||||
currentURL,
|
||||
fillIn,
|
||||
click,
|
||||
find,
|
||||
//findAll,
|
||||
//getRootElement
|
||||
//setupOnerror,
|
||||
} from '@ember/test-helpers';
|
||||
import { visit, currentURL, fillIn, click, find } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
// import { Response } from 'miragejs';
|
||||
import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
import sinon from 'sinon';
|
||||
import {
|
||||
// currentSession,
|
||||
// authenticateSession,
|
||||
invalidateSession,
|
||||
} from 'ember-simple-auth/test-support';
|
||||
import { invalidateSession } from 'ember-simple-auth/test-support';
|
||||
import { setupBrowserFakes } from 'ember-browser-services/test-support';
|
||||
import WindowMockIPC from '../helpers/window-mock-ipc';
|
||||
import config from '../../config/environment';
|
||||
|
||||
module('Acceptance | origin', function (hooks) {
|
||||
module('Acceptance | clusterUrl', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupBrowserFakes(hooks, { window: true });
|
||||
setupMirage(hooks);
|
||||
@@ -53,7 +39,7 @@ module('Acceptance | origin', function (hooks) {
|
||||
|
||||
const urls = {
|
||||
index: '/',
|
||||
origin: '/origin',
|
||||
clusterUrl: '/cluster-url',
|
||||
scopes: {
|
||||
global: null,
|
||||
org: null,
|
||||
@@ -117,64 +103,63 @@ module('Acceptance | origin', function (hooks) {
|
||||
|
||||
test('visiting index', async function (assert) {
|
||||
assert.expect(1);
|
||||
await visit(urls.origin);
|
||||
await visit(urls.clusterUrl);
|
||||
await a11yAudit();
|
||||
assert.strictEqual(currentURL(), urls.origin);
|
||||
assert.strictEqual(currentURL(), urls.clusterUrl);
|
||||
});
|
||||
|
||||
test('visiting index without an origin specified redirects to origin route', async function (assert) {
|
||||
test('visiting index without a clusterUrl specified redirects to clusterUrl route', async function (assert) {
|
||||
assert.expect(2);
|
||||
await visit(urls.index);
|
||||
await a11yAudit();
|
||||
assert.notOk(mockIPC.origin);
|
||||
assert.strictEqual(currentURL(), urls.origin);
|
||||
assert.notOk(mockIPC.clusterUrl);
|
||||
assert.strictEqual(currentURL(), urls.clusterUrl);
|
||||
});
|
||||
|
||||
test('can set origin', async function (assert) {
|
||||
test('can set clusterUrl', async function (assert) {
|
||||
assert.expect(3);
|
||||
assert.notOk(mockIPC.origin);
|
||||
await visit(urls.origin);
|
||||
assert.notOk(mockIPC.clusterUrl);
|
||||
await visit(urls.clusterUrl);
|
||||
await fillIn('[name="host"]', currentOrigin);
|
||||
await click('[type="submit"]');
|
||||
assert.strictEqual(currentURL(), urls.authenticate.methods.global);
|
||||
assert.strictEqual(mockIPC.origin, currentOrigin);
|
||||
assert.strictEqual(mockIPC.clusterUrl, currentOrigin);
|
||||
});
|
||||
|
||||
test('can reset origin before authentication', async function (assert) {
|
||||
test('can reset clusterUrl before authentication', async function (assert) {
|
||||
assert.expect(4);
|
||||
assert.notOk(mockIPC.origin);
|
||||
await visit(urls.origin);
|
||||
assert.notOk(mockIPC.clusterUrl);
|
||||
await visit(urls.clusterUrl);
|
||||
await fillIn('[name="host"]', currentOrigin);
|
||||
await click('[type="submit"]');
|
||||
assert.strictEqual(currentURL(), urls.authenticate.methods.global);
|
||||
assert.strictEqual(mockIPC.origin, currentOrigin);
|
||||
assert.strictEqual(mockIPC.clusterUrl, currentOrigin);
|
||||
await click('.change-origin a');
|
||||
assert.strictEqual(currentURL(), urls.origin);
|
||||
assert.strictEqual(currentURL(), urls.clusterUrl);
|
||||
});
|
||||
|
||||
test('captures error on origin update', async function (assert) {
|
||||
test('captures error on clusterUrl update', async function (assert) {
|
||||
assert.expect(2);
|
||||
assert.notOk(mockIPC.origin);
|
||||
sinon.stub(this.owner.lookup('service:origin'), 'setOrigin').throws();
|
||||
await visit(urls.origin);
|
||||
assert.notOk(mockIPC.clusterUrl);
|
||||
sinon.stub(this.owner.lookup('service:clusterUrl'), 'setClusterUrl').throws();
|
||||
await visit(urls.clusterUrl);
|
||||
await fillIn('[name="host"]', currentOrigin);
|
||||
await click('[type="submit"]');
|
||||
assert.ok(find('.rose-notification.is-error'));
|
||||
});
|
||||
|
||||
test('origin set automatically when autoOrigin is true', async function (assert) {
|
||||
test('clusterUrl set automatically when autoOrigin is true', async function (assert) {
|
||||
assert.expect(1);
|
||||
config.autoOrigin = true;
|
||||
await visit(urls.origin);
|
||||
await visit(urls.clusterUrl);
|
||||
assert.strictEqual(find('[name="host"]').value, currentOrigin);
|
||||
config.autoOrigin = false;
|
||||
});
|
||||
|
||||
test('origin is *not* set automatically when autoOrigin is false', async function (assert) {
|
||||
test('clusterUrl is *not* set automatically when autoOrigin is false', async function (assert) {
|
||||
assert.expect(2);
|
||||
assert.notOk(config.autoOrigin, 'autoOrigin is disabled');
|
||||
await visit(urls.origin);
|
||||
await visit(urls.clusterUrl);
|
||||
assert.notOk(find('[name="host"]').value, 'Origin field is empty');
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,17 +1,7 @@
|
||||
import { module, test } from 'qunit';
|
||||
import {
|
||||
visit,
|
||||
currentURL,
|
||||
//fillIn,
|
||||
//click,
|
||||
//find,
|
||||
//findAll,
|
||||
//getRootElement
|
||||
//setupOnerror,
|
||||
} from '@ember/test-helpers';
|
||||
import { visit, currentURL } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
//import { Response } from 'miragejs';
|
||||
import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
import {
|
||||
currentSession,
|
||||
@@ -43,7 +33,7 @@ module('Acceptance | projects', function (hooks) {
|
||||
|
||||
const urls = {
|
||||
index: '/',
|
||||
origin: '/origin',
|
||||
clusterUrl: '/cluster-url',
|
||||
scopes: {
|
||||
global: null,
|
||||
org: null,
|
||||
@@ -57,10 +47,10 @@ module('Acceptance | projects', function (hooks) {
|
||||
projects: null,
|
||||
};
|
||||
|
||||
const setDefaultOrigin = (test) => {
|
||||
const setDefaultClusterUrl = (test) => {
|
||||
const windowOrigin = window.location.origin;
|
||||
const origin = test.owner.lookup('service:origin');
|
||||
origin.rendererOrigin = windowOrigin;
|
||||
const clusterUrl = test.owner.lookup('service:clusterUrl');
|
||||
clusterUrl.rendererClusterUrl = windowOrigin;
|
||||
};
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
@@ -103,7 +93,7 @@ module('Acceptance | projects', function (hooks) {
|
||||
|
||||
// Mock the postMessage interface used by IPC.
|
||||
this.owner.register('service:browser/window', WindowMockIPC);
|
||||
setDefaultOrigin(this);
|
||||
setDefaultClusterUrl(this);
|
||||
});
|
||||
|
||||
test('visiting index while unauthenticated redirects to global authenticate method', async function (assert) {
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
import { module, test } from 'qunit';
|
||||
import {
|
||||
visit,
|
||||
currentURL,
|
||||
//fillIn,
|
||||
click,
|
||||
find,
|
||||
findAll,
|
||||
//getRootElement
|
||||
//setupOnerror,
|
||||
} from '@ember/test-helpers';
|
||||
import { visit, currentURL, click, find, findAll } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { Response } from 'miragejs';
|
||||
@@ -48,7 +39,7 @@ module('Acceptance | projects | sessions', function (hooks) {
|
||||
|
||||
const urls = {
|
||||
index: '/',
|
||||
origin: '/origin',
|
||||
clusterUrl: '/cluster-url',
|
||||
scopes: {
|
||||
global: null,
|
||||
org: null,
|
||||
@@ -63,10 +54,10 @@ module('Acceptance | projects | sessions', function (hooks) {
|
||||
sessions: null,
|
||||
};
|
||||
|
||||
const setDefaultOrigin = (test) => {
|
||||
const setDefaultClusterUrl = (test) => {
|
||||
const windowOrigin = window.location.origin;
|
||||
const origin = test.owner.lookup('service:origin');
|
||||
origin.rendererOrigin = windowOrigin;
|
||||
const clusterUrl = test.owner.lookup('service:clusterUrl');
|
||||
clusterUrl.rendererClusterUrl = windowOrigin;
|
||||
};
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
@@ -117,19 +108,19 @@ module('Acceptance | projects | sessions', function (hooks) {
|
||||
urls.sessions = `${urls.projects}/sessions`;
|
||||
|
||||
class MockIPC {
|
||||
origin = null;
|
||||
clusterUrl = null;
|
||||
|
||||
invoke(method, payload) {
|
||||
return this[method](payload);
|
||||
}
|
||||
|
||||
getOrigin() {
|
||||
return this.origin;
|
||||
getClusterUrl() {
|
||||
return this.clusterUrl;
|
||||
}
|
||||
|
||||
setOrigin(origin) {
|
||||
this.origin = origin;
|
||||
return this.origin;
|
||||
setClusterUrl(clusterUrl) {
|
||||
this.clusterUrl = clusterUrl;
|
||||
return this.clusterUrl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +135,7 @@ module('Acceptance | projects | sessions', function (hooks) {
|
||||
};
|
||||
|
||||
window.addEventListener('message', messageHandler);
|
||||
setDefaultOrigin(this);
|
||||
setDefaultClusterUrl(this);
|
||||
|
||||
const ipcService = this.owner.lookup('service:ipc');
|
||||
stubs.ipcService = sinon.stub(ipcService, 'invoke');
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
import { module, test } from 'qunit';
|
||||
import {
|
||||
visit,
|
||||
currentURL,
|
||||
//fillIn,
|
||||
click,
|
||||
find,
|
||||
findAll,
|
||||
//getRootElement
|
||||
//setupOnerror,
|
||||
} from '@ember/test-helpers';
|
||||
import { visit, currentURL, click, find, findAll } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { Response } from 'miragejs';
|
||||
@@ -48,7 +39,7 @@ module('Acceptance | projects | targets', function (hooks) {
|
||||
|
||||
const urls = {
|
||||
index: '/',
|
||||
origin: '/origin',
|
||||
clusterUrl: '/cluster-url',
|
||||
scopes: {
|
||||
global: null,
|
||||
org: null,
|
||||
@@ -65,10 +56,10 @@ module('Acceptance | projects | targets', function (hooks) {
|
||||
sessions: null,
|
||||
};
|
||||
|
||||
const setDefaultOrigin = (test) => {
|
||||
const setDefaultClusterUrl = (test) => {
|
||||
const windowOrigin = window.location.origin;
|
||||
const origin = test.owner.lookup('service:origin');
|
||||
origin.rendererOrigin = windowOrigin;
|
||||
const clusterUrl = test.owner.lookup('service:clusterUrl');
|
||||
clusterUrl.rendererClusterUrl = windowOrigin;
|
||||
};
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
@@ -124,19 +115,19 @@ module('Acceptance | projects | targets', function (hooks) {
|
||||
urls.sessions = `${urls.target}/sessions`;
|
||||
|
||||
class MockIPC {
|
||||
origin = null;
|
||||
clusterUrl = null;
|
||||
|
||||
invoke(method, payload) {
|
||||
return this[method](payload);
|
||||
}
|
||||
|
||||
getOrigin() {
|
||||
return this.origin;
|
||||
getClusterUrl() {
|
||||
return this.clusterUrl;
|
||||
}
|
||||
|
||||
setOrigin(origin) {
|
||||
this.origin = origin;
|
||||
return this.origin;
|
||||
setClusterUrl(clusterUrl) {
|
||||
this.clusterUrl = clusterUrl;
|
||||
return this.clusterUrl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +142,7 @@ module('Acceptance | projects | targets', function (hooks) {
|
||||
};
|
||||
|
||||
window.addEventListener('message', messageHandler);
|
||||
setDefaultOrigin(this);
|
||||
setDefaultClusterUrl(this);
|
||||
|
||||
const ipcService = this.owner.lookup('service:ipc');
|
||||
stubs.ipcService = sinon.stub(ipcService, 'invoke');
|
||||
@@ -308,8 +299,16 @@ module('Acceptance | projects | targets', function (hooks) {
|
||||
assert.ok(find('.rose-dialog-error'), 'Error dialog');
|
||||
const dialogButtons = findAll('.rose-dialog-footer button');
|
||||
assert.strictEqual(dialogButtons.length, 2);
|
||||
assert.strictEqual(dialogButtons[0].textContent.trim(), 'Retry', 'Can retry');
|
||||
assert.strictEqual(dialogButtons[1].textContent.trim(), 'Cancel', 'Can cancel');
|
||||
assert.strictEqual(
|
||||
dialogButtons[0].textContent.trim(),
|
||||
'Retry',
|
||||
'Can retry'
|
||||
);
|
||||
assert.strictEqual(
|
||||
dialogButtons[1].textContent.trim(),
|
||||
'Cancel',
|
||||
'Can cancel'
|
||||
);
|
||||
});
|
||||
|
||||
test('handles connect error', async function (assert) {
|
||||
@@ -326,8 +325,16 @@ module('Acceptance | projects | targets', function (hooks) {
|
||||
assert.ok(find('.rose-dialog-error'), 'Error dialog');
|
||||
const dialogButtons = findAll('.rose-dialog-footer button');
|
||||
assert.strictEqual(dialogButtons.length, 2);
|
||||
assert.strictEqual(dialogButtons[0].textContent.trim(), 'Retry', 'Can retry');
|
||||
assert.strictEqual(dialogButtons[1].textContent.trim(), 'Cancel', 'Can cancel');
|
||||
assert.strictEqual(
|
||||
dialogButtons[0].textContent.trim(),
|
||||
'Retry',
|
||||
'Can retry'
|
||||
);
|
||||
assert.strictEqual(
|
||||
dialogButtons[1].textContent.trim(),
|
||||
'Cancel',
|
||||
'Can cancel'
|
||||
);
|
||||
});
|
||||
|
||||
test('can retry on error', async function (assert) {
|
||||
|
||||
@@ -1,18 +1,8 @@
|
||||
import { module, test } from 'qunit';
|
||||
import {
|
||||
visit,
|
||||
currentURL,
|
||||
//fillIn,
|
||||
click,
|
||||
find,
|
||||
findAll,
|
||||
//getRootElement
|
||||
//setupOnerror,
|
||||
} from '@ember/test-helpers';
|
||||
import { visit, currentURL, click, find, findAll } from '@ember/test-helpers';
|
||||
import { run, later } from '@ember/runloop';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
// import { Response } from 'miragejs';
|
||||
import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
import sinon from 'sinon';
|
||||
import {
|
||||
@@ -50,7 +40,7 @@ module('Acceptance | projects | targets | hosts', function (hooks) {
|
||||
|
||||
const urls = {
|
||||
index: '/',
|
||||
origin: '/origin',
|
||||
clusterUrl: '/cluster-url',
|
||||
scopes: {
|
||||
global: null,
|
||||
org: null,
|
||||
@@ -67,10 +57,10 @@ module('Acceptance | projects | targets | hosts', function (hooks) {
|
||||
hosts: null,
|
||||
};
|
||||
|
||||
const setDefaultOrigin = (test) => {
|
||||
const setDefaultClusterUrl = (test) => {
|
||||
const windowOrigin = window.location.origin;
|
||||
const origin = test.owner.lookup('service:origin');
|
||||
origin.rendererOrigin = windowOrigin;
|
||||
const clusterUrl = test.owner.lookup('service:clusterUrl');
|
||||
clusterUrl.rendererClusterUrl = windowOrigin;
|
||||
};
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
@@ -125,19 +115,19 @@ module('Acceptance | projects | targets | hosts', function (hooks) {
|
||||
urls.hosts = `${urls.target}/hosts`;
|
||||
|
||||
class MockIPC {
|
||||
origin = null;
|
||||
clusterUrl = null;
|
||||
|
||||
invoke(method, payload) {
|
||||
return this[method](payload);
|
||||
}
|
||||
|
||||
getOrigin() {
|
||||
return this.origin;
|
||||
getClusterUrl() {
|
||||
return this.clusterUrl;
|
||||
}
|
||||
|
||||
setOrigin(origin) {
|
||||
this.origin = origin;
|
||||
return this.origin;
|
||||
setClusterUrl(clusterUrl) {
|
||||
this.clusterUrl = clusterUrl;
|
||||
return this.clusterUrl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +142,7 @@ module('Acceptance | projects | targets | hosts', function (hooks) {
|
||||
};
|
||||
|
||||
window.addEventListener('message', messageHandler);
|
||||
setDefaultOrigin(this);
|
||||
setDefaultClusterUrl(this);
|
||||
|
||||
const ipcService = this.owner.lookup('service:ipc');
|
||||
stubs.ipcService = sinon.stub(ipcService, 'invoke');
|
||||
@@ -248,8 +238,16 @@ module('Acceptance | projects | targets | hosts', function (hooks) {
|
||||
assert.ok(find('.rose-dialog-error'), 'Error dialog');
|
||||
const dialogButtons = findAll('.rose-dialog-footer button');
|
||||
assert.strictEqual(dialogButtons.length, 2);
|
||||
assert.strictEqual(dialogButtons[0].textContent.trim(), 'Retry', 'Can retry');
|
||||
assert.strictEqual(dialogButtons[1].textContent.trim(), 'Cancel', 'Can cancel');
|
||||
assert.strictEqual(
|
||||
dialogButtons[0].textContent.trim(),
|
||||
'Retry',
|
||||
'Can retry'
|
||||
);
|
||||
assert.strictEqual(
|
||||
dialogButtons[1].textContent.trim(),
|
||||
'Cancel',
|
||||
'Can cancel'
|
||||
);
|
||||
}, 750);
|
||||
await visit(urls.hosts);
|
||||
});
|
||||
@@ -270,8 +268,16 @@ module('Acceptance | projects | targets | hosts', function (hooks) {
|
||||
assert.ok(find('.rose-dialog-error'), 'Error dialog');
|
||||
const dialogButtons = findAll('.rose-dialog-footer button');
|
||||
assert.strictEqual(dialogButtons.length, 2);
|
||||
assert.strictEqual(dialogButtons[0].textContent.trim(), 'Retry', 'Can retry');
|
||||
assert.strictEqual(dialogButtons[1].textContent.trim(), 'Cancel', 'Can cancel');
|
||||
assert.strictEqual(
|
||||
dialogButtons[0].textContent.trim(),
|
||||
'Retry',
|
||||
'Can retry'
|
||||
);
|
||||
assert.strictEqual(
|
||||
dialogButtons[1].textContent.trim(),
|
||||
'Cancel',
|
||||
'Can cancel'
|
||||
);
|
||||
}, 750);
|
||||
await visit(urls.hosts);
|
||||
});
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
import { module, test } from 'qunit';
|
||||
import {
|
||||
visit,
|
||||
currentURL,
|
||||
//fillIn,
|
||||
click,
|
||||
find,
|
||||
findAll,
|
||||
//getRootElement
|
||||
//setupOnerror,
|
||||
} from '@ember/test-helpers';
|
||||
import { visit, currentURL, click, find, findAll } from '@ember/test-helpers';
|
||||
import { run, later } from '@ember/runloop';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
@@ -50,7 +41,7 @@ module('Acceptance | projects | targets | sessions', function (hooks) {
|
||||
|
||||
const urls = {
|
||||
index: '/',
|
||||
origin: '/origin',
|
||||
clusterUrl: '/cluster-url',
|
||||
scopes: {
|
||||
global: null,
|
||||
org: null,
|
||||
@@ -67,10 +58,10 @@ module('Acceptance | projects | targets | sessions', function (hooks) {
|
||||
sessions: null,
|
||||
};
|
||||
|
||||
const setDefaultOrigin = (test) => {
|
||||
const setDefaultClusterUrl = (test) => {
|
||||
const windowOrigin = window.location.origin;
|
||||
const origin = test.owner.lookup('service:origin');
|
||||
origin.rendererOrigin = windowOrigin;
|
||||
const clusterUrl = test.owner.lookup('service:clusterUrl');
|
||||
clusterUrl.rendererClusterUrl = windowOrigin;
|
||||
};
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
@@ -130,19 +121,19 @@ module('Acceptance | projects | targets | sessions', function (hooks) {
|
||||
urls.sessions = `${urls.target}/sessions`;
|
||||
|
||||
class MockIPC {
|
||||
origin = null;
|
||||
clusterUrl = null;
|
||||
|
||||
invoke(method, payload) {
|
||||
return this[method](payload);
|
||||
}
|
||||
|
||||
getOrigin() {
|
||||
return this.origin;
|
||||
getClusterUrl() {
|
||||
return this.clusterUrl;
|
||||
}
|
||||
|
||||
setOrigin(origin) {
|
||||
this.origin = origin;
|
||||
return this.origin;
|
||||
setClusterUrl(clusterUrl) {
|
||||
this.clusterUrl = clusterUrl;
|
||||
return this.clusterUrl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +148,7 @@ module('Acceptance | projects | targets | sessions', function (hooks) {
|
||||
};
|
||||
|
||||
window.addEventListener('message', messageHandler);
|
||||
setDefaultOrigin(this);
|
||||
setDefaultClusterUrl(this);
|
||||
|
||||
const ipcService = this.owner.lookup('service:ipc');
|
||||
stubs.ipcService = sinon.stub(ipcService, 'invoke');
|
||||
@@ -349,8 +340,16 @@ module('Acceptance | projects | targets | sessions', function (hooks) {
|
||||
assert.ok(find('.rose-dialog-error'), 'Error dialog');
|
||||
const dialogButtons = findAll('.rose-dialog-footer button');
|
||||
assert.strictEqual(dialogButtons.length, 2);
|
||||
assert.strictEqual(dialogButtons[0].textContent.trim(), 'Retry', 'Can retry');
|
||||
assert.strictEqual(dialogButtons[1].textContent.trim(), 'Cancel', 'Can cancel');
|
||||
assert.strictEqual(
|
||||
dialogButtons[0].textContent.trim(),
|
||||
'Retry',
|
||||
'Can retry'
|
||||
);
|
||||
assert.strictEqual(
|
||||
dialogButtons[1].textContent.trim(),
|
||||
'Cancel',
|
||||
'Can cancel'
|
||||
);
|
||||
}, 750);
|
||||
await visit(urls.sessions);
|
||||
});
|
||||
@@ -368,8 +367,16 @@ module('Acceptance | projects | targets | sessions', function (hooks) {
|
||||
assert.ok(find('.rose-dialog-error'), 'Error dialog');
|
||||
const dialogButtons = findAll('.rose-dialog-footer button');
|
||||
assert.strictEqual(dialogButtons.length, 2);
|
||||
assert.strictEqual(dialogButtons[0].textContent.trim(), 'Retry', 'Can retry');
|
||||
assert.strictEqual(dialogButtons[1].textContent.trim(), 'Cancel', 'Can cancel');
|
||||
assert.strictEqual(
|
||||
dialogButtons[0].textContent.trim(),
|
||||
'Retry',
|
||||
'Can retry'
|
||||
);
|
||||
assert.strictEqual(
|
||||
dialogButtons[1].textContent.trim(),
|
||||
'Cancel',
|
||||
'Can cancel'
|
||||
);
|
||||
}, 750);
|
||||
await visit(urls.sessions);
|
||||
});
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
import { module, test } from 'qunit';
|
||||
import {
|
||||
visit,
|
||||
currentURL,
|
||||
//fillIn,
|
||||
click,
|
||||
find,
|
||||
findAll,
|
||||
//getRootElement
|
||||
//setupOnerror,
|
||||
} from '@ember/test-helpers';
|
||||
import { visit, currentURL, click, find, findAll } from '@ember/test-helpers';
|
||||
import { run, later } from '@ember/runloop';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
@@ -49,7 +40,7 @@ module('Acceptance | scopes', function (hooks) {
|
||||
|
||||
const urls = {
|
||||
index: '/',
|
||||
origin: '/origin',
|
||||
clusterUrl: '/cluster-url',
|
||||
scopes: {
|
||||
global: null,
|
||||
org: null,
|
||||
@@ -71,10 +62,10 @@ module('Acceptance | scopes', function (hooks) {
|
||||
targetSessions: null,
|
||||
};
|
||||
|
||||
const setDefaultOrigin = (test) => {
|
||||
const setDefaultClusterUrl = (test) => {
|
||||
const windowOrigin = window.location.origin;
|
||||
const origin = test.owner.lookup('service:origin');
|
||||
origin.rendererOrigin = windowOrigin;
|
||||
const clusterUrl = test.owner.lookup('service:clusterUrl');
|
||||
clusterUrl.rendererClusterUrl = windowOrigin;
|
||||
};
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
@@ -137,19 +128,19 @@ module('Acceptance | scopes', function (hooks) {
|
||||
urls.targetSessions = `${urls.target}/sessions`;
|
||||
|
||||
class MockIPC {
|
||||
origin = null;
|
||||
clusterUrl = null;
|
||||
|
||||
invoke(method, payload) {
|
||||
return this[method](payload);
|
||||
}
|
||||
|
||||
getOrigin() {
|
||||
return this.origin;
|
||||
getClusterUrl() {
|
||||
return this.clusterUrl;
|
||||
}
|
||||
|
||||
setOrigin(origin) {
|
||||
this.origin = origin;
|
||||
return this.origin;
|
||||
setClusterUrl(clusterUrl) {
|
||||
this.clusterUrl = clusterUrl;
|
||||
return this.clusterUrl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +155,7 @@ module('Acceptance | scopes', function (hooks) {
|
||||
};
|
||||
|
||||
window.addEventListener('message', messageHandler);
|
||||
setDefaultOrigin(this);
|
||||
setDefaultClusterUrl(this);
|
||||
|
||||
const ipcService = this.owner.lookup('service:ipc');
|
||||
stubs.ipcService = sinon.stub(ipcService, 'invoke');
|
||||
@@ -234,11 +225,20 @@ module('Acceptance | scopes', function (hooks) {
|
||||
assert.expect(3);
|
||||
await later(async () => run.cancelTimers(), 750);
|
||||
await visit(urls.targets);
|
||||
await later(async () => assert.strictEqual(currentURL(), urls.targets), 750);
|
||||
await later(
|
||||
async () => assert.strictEqual(currentURL(), urls.targets),
|
||||
750
|
||||
);
|
||||
await click('.rose-header-nav .rose-dropdown a:nth-of-type(2)');
|
||||
await later(async () => assert.strictEqual(currentURL(), urls.org2Targets), 750);
|
||||
await later(
|
||||
async () => assert.strictEqual(currentURL(), urls.org2Targets),
|
||||
750
|
||||
);
|
||||
await click('.rose-header-nav .rose-dropdown a:nth-of-type(3)');
|
||||
later(async () => assert.strictEqual(currentURL(), urls.globalTargets), 750);
|
||||
later(
|
||||
async () => assert.strictEqual(currentURL(), urls.globalTargets),
|
||||
750
|
||||
);
|
||||
await click('.rose-header-nav .rose-dropdown a:nth-of-type(1)');
|
||||
});
|
||||
|
||||
@@ -318,8 +318,16 @@ module('Acceptance | scopes', function (hooks) {
|
||||
assert.ok(find('.rose-dialog-error'), 'Error dialog');
|
||||
const dialogButtons = findAll('.rose-dialog-footer button');
|
||||
assert.strictEqual(dialogButtons.length, 2);
|
||||
assert.strictEqual(dialogButtons[0].textContent.trim(), 'Retry', 'Can retry');
|
||||
assert.strictEqual(dialogButtons[1].textContent.trim(), 'Cancel', 'Can cancel');
|
||||
assert.strictEqual(
|
||||
dialogButtons[0].textContent.trim(),
|
||||
'Retry',
|
||||
'Can retry'
|
||||
);
|
||||
assert.strictEqual(
|
||||
dialogButtons[1].textContent.trim(),
|
||||
'Cancel',
|
||||
'Can cancel'
|
||||
);
|
||||
}, 750);
|
||||
await visit(urls.scopes.global);
|
||||
});
|
||||
@@ -340,8 +348,16 @@ module('Acceptance | scopes', function (hooks) {
|
||||
assert.ok(find('.rose-dialog-error'), 'Error dialog');
|
||||
const dialogButtons = findAll('.rose-dialog-footer button');
|
||||
assert.strictEqual(dialogButtons.length, 2);
|
||||
assert.strictEqual(dialogButtons[0].textContent.trim(), 'Retry', 'Can retry');
|
||||
assert.strictEqual(dialogButtons[1].textContent.trim(), 'Cancel', 'Can cancel');
|
||||
assert.strictEqual(
|
||||
dialogButtons[0].textContent.trim(),
|
||||
'Retry',
|
||||
'Can retry'
|
||||
);
|
||||
assert.strictEqual(
|
||||
dialogButtons[1].textContent.trim(),
|
||||
'Cancel',
|
||||
'Can cancel'
|
||||
);
|
||||
}, 750);
|
||||
await visit(urls.targets);
|
||||
});
|
||||
|
||||
@@ -1,18 +1,8 @@
|
||||
import { module, test } from 'qunit';
|
||||
import {
|
||||
visit,
|
||||
currentURL,
|
||||
//fillIn,
|
||||
//click,
|
||||
//find,
|
||||
//findAll,
|
||||
//getRootElement
|
||||
//setupOnerror,
|
||||
} from '@ember/test-helpers';
|
||||
import { visit, currentURL } from '@ember/test-helpers';
|
||||
import { run, later } from '@ember/runloop';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
// import { Response } from 'miragejs';
|
||||
import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
import {
|
||||
currentSession,
|
||||
@@ -57,10 +47,10 @@ module('Acceptance | targets', function (hooks) {
|
||||
targets: null,
|
||||
};
|
||||
|
||||
const setDefaultOrigin = (test) => {
|
||||
const setDefaultClusterUrl = (test) => {
|
||||
const windowOrigin = window.location.origin;
|
||||
const origin = test.owner.lookup('service:origin');
|
||||
origin.rendererOrigin = windowOrigin;
|
||||
const clusterUrl = test.owner.lookup('service:clusterUrl');
|
||||
clusterUrl.rendererClusterUrl = windowOrigin;
|
||||
};
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
@@ -104,7 +94,7 @@ module('Acceptance | targets', function (hooks) {
|
||||
|
||||
// Mock the postMessage interface used by IPC.
|
||||
this.owner.register('service:browser/window', WindowMockIPC);
|
||||
setDefaultOrigin(this);
|
||||
setDefaultClusterUrl(this);
|
||||
});
|
||||
|
||||
test('visiting index while unauthenticated redirects to global authenticate method', async function (assert) {
|
||||
|
||||
@@ -13,7 +13,7 @@ const executablePath = helpers.returnExecutablePath(
|
||||
);
|
||||
|
||||
// Set login variables
|
||||
const originValue = 'http://localhost:9200';
|
||||
const clusterUrlValue = 'http://localhost:9200';
|
||||
const loginUsername = 'admin';
|
||||
const loginPassword = 'password';
|
||||
|
||||
@@ -37,15 +37,15 @@ test.describe('Authentication end to end test suite', async () => {
|
||||
test('Authenticates using user and password method and deauthenticates ', async () => {
|
||||
const boundaryWindow = await electronApp.firstWindow(); // The window that contains the app.
|
||||
|
||||
// Override local storage origin
|
||||
// Override local storage cluster URL
|
||||
await boundaryWindow.evaluate(() =>
|
||||
window.localStorage.setItem('desktop:origin', null)
|
||||
window.localStorage.setItem('desktop:clusterUrl', null)
|
||||
);
|
||||
|
||||
// Perform login
|
||||
await helpers.login(
|
||||
boundaryWindow,
|
||||
originValue,
|
||||
clusterUrlValue,
|
||||
loginUsername,
|
||||
loginPassword
|
||||
);
|
||||
@@ -115,14 +115,14 @@ test.describe('Authentication end to end test suite', async () => {
|
||||
|
||||
test('Authenticates using user and wrong password, it can not authenticate', async () => {
|
||||
const boundaryWindow = await electronApp.firstWindow(); // The window that contains the app.
|
||||
// Override local storage origin
|
||||
// Override local storage cluster URL
|
||||
await boundaryWindow.evaluate(() =>
|
||||
window.localStorage.setItem('desktop:origin', null)
|
||||
window.localStorage.setItem('desktop:clusterUrl', null)
|
||||
);
|
||||
// Perform login
|
||||
await helpers.login(
|
||||
boundaryWindow,
|
||||
originValue,
|
||||
clusterUrlValue,
|
||||
loginUsername,
|
||||
'123456789'
|
||||
);
|
||||
@@ -158,15 +158,15 @@ test.describe('Authentication end to end test suite', async () => {
|
||||
});
|
||||
});
|
||||
|
||||
// Override local storage origin
|
||||
// Override local storage cluster URL
|
||||
await boundaryWindow.evaluate(() =>
|
||||
window.localStorage.setItem('desktop:origin', null)
|
||||
window.localStorage.setItem('desktop:clusterUrl', null)
|
||||
);
|
||||
const originValue = 'http://localhost:9200';
|
||||
const clusterUrlValue = 'http://localhost:9200';
|
||||
|
||||
// Fill the origin input
|
||||
// Fill the cluster URL input
|
||||
await boundaryWindow.waitForSelector('[name=host]');
|
||||
await boundaryWindow.fill('[name=host]', originValue);
|
||||
await boundaryWindow.fill('[name=host]', clusterUrlValue);
|
||||
|
||||
// Click the submit button
|
||||
// Due to an error with await boundaryWindow.click('button[type="submit"]'); we are using a workaround.
|
||||
|
||||
@@ -13,7 +13,7 @@ const executablePath = helpers.returnExecutablePath(
|
||||
);
|
||||
|
||||
// Set login variables
|
||||
const originValue = 'http://localhost:9200';
|
||||
const clusterUrlValue = 'http://localhost:9200';
|
||||
const loginUsername = 'admin';
|
||||
const loginPassword = 'password';
|
||||
|
||||
@@ -36,15 +36,15 @@ test.describe('Targets end to end test suite', async () => {
|
||||
test('Connects to a target', async () => {
|
||||
const boundaryWindow = await electronApp.firstWindow(); // The window that contains the app.
|
||||
|
||||
// Override local storage origin
|
||||
// Override local storage cluster URL
|
||||
await boundaryWindow.evaluate(() =>
|
||||
window.localStorage.setItem('desktop:origin', null)
|
||||
window.localStorage.setItem('desktop:clusterURL', null)
|
||||
);
|
||||
|
||||
// Perform the login
|
||||
await helpers.login(
|
||||
boundaryWindow,
|
||||
originValue,
|
||||
clusterUrlValue,
|
||||
loginUsername,
|
||||
loginPassword
|
||||
);
|
||||
|
||||
@@ -56,16 +56,16 @@ exports.click = async (appWindow, selector) => {
|
||||
/**
|
||||
* Performs login on the app window provided with the credentials provided.
|
||||
* @param {object} appWindow The electron window to perform the action.
|
||||
* @param {string} origin URL origin to set.
|
||||
* @param {string} clusterUrl Cluster URL to set.
|
||||
* @param {string} username Username to login.
|
||||
* @param {string} password Password to login.
|
||||
*/
|
||||
exports.login = async (appWindow, origin, username, password) => {
|
||||
// Fill the origin input
|
||||
exports.login = async (appWindow, clusterUrl, username, password) => {
|
||||
// Fill the clusterUrl input
|
||||
await appWindow.waitForSelector('[name=host]');
|
||||
await appWindow.fill('[name=host]', origin);
|
||||
await appWindow.fill('[name=host]', clusterUrl);
|
||||
|
||||
// Click the set origin submit button
|
||||
// Click the set clusterUrl submit button
|
||||
await appWindow.waitForSelector('button[type="submit"]');
|
||||
await this.click(appWindow, 'button[type="submit"]');
|
||||
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import Service from '@ember/service';
|
||||
|
||||
class MockIPC {
|
||||
origin = null;
|
||||
clusterUrl = null;
|
||||
|
||||
invoke(method, payload) {
|
||||
return this[method](payload);
|
||||
}
|
||||
|
||||
getOrigin() {
|
||||
return this.origin;
|
||||
getClusterUrl() {
|
||||
return this.clusterUrl;
|
||||
}
|
||||
|
||||
setOrigin(origin) {
|
||||
this.origin = origin;
|
||||
return this.origin;
|
||||
setClusterUrl(clusterUrl) {
|
||||
this.clusterUrl = clusterUrl;
|
||||
return this.clusterUrl;
|
||||
}
|
||||
|
||||
resetOrigin() {}
|
||||
resetClusterUrl() {}
|
||||
hasMacOSChrome() {}
|
||||
showWindowActions() {}
|
||||
}
|
||||
@@ -57,8 +57,8 @@ export default class extends Service {
|
||||
|
||||
// =methods
|
||||
|
||||
postMessage(data, origin, ports) {
|
||||
if (origin !== window.location.origin) return;
|
||||
postMessage(data, clusterUrl, ports) {
|
||||
if (clusterUrl !== window.location.origin) return;
|
||||
const { method, payload } = data;
|
||||
if (method) {
|
||||
const response = this.mockIPC.invoke(method, payload);
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Route | origin', function (hooks) {
|
||||
module('Unit | Route | ClusterUrl', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function (assert) {
|
||||
let route = this.owner.lookup('route:origin');
|
||||
let route = this.owner.lookup('route:cluster-url');
|
||||
assert.ok(route);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,49 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import sinon from 'sinon';
|
||||
|
||||
module('Unit | Service | clusterUrl', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
let service, ipcService;
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
service = this.owner.lookup('service:clusterUrl');
|
||||
ipcService = this.owner.lookup('service:ipc');
|
||||
});
|
||||
|
||||
test('resets clusterUrl on error', async function (assert) {
|
||||
assert.expect(4);
|
||||
const ipcServiceStubbed = sinon.stub(ipcService, 'invoke');
|
||||
await service.setClusterUrl(window.location.origin);
|
||||
assert.strictEqual(service.rendererClusterUrl, window.location.origin);
|
||||
assert.strictEqual(service.adapter.host, window.location.origin);
|
||||
ipcServiceStubbed.withArgs('setClusterUrl').rejects();
|
||||
service.setClusterUrl('invalid-origin').catch(() => {
|
||||
assert.notOk(service.rendererClusterUrl);
|
||||
assert.strictEqual(service.adapter.host, window.location.origin);
|
||||
});
|
||||
});
|
||||
|
||||
test('drops trailing slashes from clusterUrl on setClusterUrl', async function (assert) {
|
||||
assert.expect(4);
|
||||
sinon.stub(ipcService, 'invoke');
|
||||
await service.setClusterUrl(`${window.location.origin}/`);
|
||||
assert.strictEqual(service.rendererClusterUrl, window.location.origin);
|
||||
assert.strictEqual(service.adapter.host, window.location.origin);
|
||||
await service.setClusterUrl(`${window.location.origin}//////`);
|
||||
assert.strictEqual(service.rendererClusterUrl, window.location.origin);
|
||||
assert.strictEqual(service.adapter.host, window.location.origin);
|
||||
});
|
||||
|
||||
test('trim spaces from clusterUrl on setClusterUrl', async function (assert) {
|
||||
assert.expect(4);
|
||||
sinon.stub(ipcService, 'invoke');
|
||||
await service.setClusterUrl(` ${window.location.origin}/ `);
|
||||
assert.strictEqual(service.rendererClusterUrl, window.location.origin);
|
||||
assert.strictEqual(service.adapter.host, window.location.origin);
|
||||
await service.setClusterUrl(` ${window.location.origin} `);
|
||||
assert.strictEqual(service.rendererClusterUrl, window.location.origin);
|
||||
assert.strictEqual(service.adapter.host, window.location.origin);
|
||||
});
|
||||
});
|
||||
@@ -1,49 +0,0 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import sinon from 'sinon';
|
||||
|
||||
module('Unit | Service | origin', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
let service, ipcService;
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
service = this.owner.lookup('service:origin');
|
||||
ipcService = this.owner.lookup('service:ipc');
|
||||
});
|
||||
|
||||
test('resets origin on error', async function (assert) {
|
||||
assert.expect(4);
|
||||
const ipcServiceStubbed = sinon.stub(ipcService, 'invoke');
|
||||
await service.setOrigin(window.location.origin);
|
||||
assert.strictEqual(service.rendererOrigin, window.location.origin);
|
||||
assert.strictEqual(service.adapter.host, window.location.origin);
|
||||
ipcServiceStubbed.withArgs('setOrigin').rejects();
|
||||
service.setOrigin('invalid-origin').catch(() => {
|
||||
assert.notOk(service.rendererOrigin);
|
||||
assert.strictEqual(service.adapter.host, window.location.origin);
|
||||
});
|
||||
});
|
||||
|
||||
test('drops trailing slashes from origin on setOrigin', async function (assert) {
|
||||
assert.expect(4);
|
||||
sinon.stub(ipcService, 'invoke');
|
||||
await service.setOrigin(`${window.location.origin}/`);
|
||||
assert.strictEqual(service.rendererOrigin, window.location.origin);
|
||||
assert.strictEqual(service.adapter.host, window.location.origin);
|
||||
await service.setOrigin(`${window.location.origin}//////`);
|
||||
assert.strictEqual(service.rendererOrigin, window.location.origin);
|
||||
assert.strictEqual(service.adapter.host, window.location.origin);
|
||||
});
|
||||
|
||||
test('trim spaces from origin on setOrigin', async function (assert) {
|
||||
assert.expect(4);
|
||||
sinon.stub(ipcService, 'invoke');
|
||||
await service.setOrigin(` ${window.location.origin}/ `);
|
||||
assert.strictEqual(service.rendererOrigin, window.location.origin);
|
||||
assert.strictEqual(service.adapter.host, window.location.origin);
|
||||
await service.setOrigin(` ${window.location.origin} `);
|
||||
assert.strictEqual(service.rendererOrigin, window.location.origin);
|
||||
assert.strictEqual(service.adapter.host, window.location.origin);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user