Icu 13302 add filtering pagination support for scopes (#2216)
* feat: 🎸 add filtering and pagination to scopes ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-13302
This commit is contained in:
1 parent
ece9c9b0c8
commit
1d7892230c
36 files changed
+521
-157
No files matched your search
@@ -4,13 +4,15 @@
|
||||
*/
|
||||
|
||||
import GeneratedScopeModel from '../generated/models/scope';
|
||||
import { computed } from '@ember/object';
|
||||
|
||||
export const scopeTypes = {
|
||||
global: 'global',
|
||||
org: 'org',
|
||||
project: 'project',
|
||||
};
|
||||
export const TYPE_SCOPE_GLOBAL = 'global';
|
||||
export const TYPE_SCOPE_ORG = 'org';
|
||||
export const TYPE_SCOPE_PROJECT = 'project';
|
||||
export const TYPES_SCOPE = Object.freeze([
|
||||
TYPE_SCOPE_GLOBAL,
|
||||
TYPE_SCOPE_ORG,
|
||||
TYPE_SCOPE_PROJECT,
|
||||
]);
|
||||
|
||||
export default class ScopeModel extends GeneratedScopeModel {
|
||||
// =attributes
|
||||
@@ -18,9 +20,8 @@ export default class ScopeModel extends GeneratedScopeModel {
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
@computed('type')
|
||||
get isGlobal() {
|
||||
return this.type === scopeTypes.global;
|
||||
return this.type === TYPE_SCOPE_GLOBAL;
|
||||
}
|
||||
// There is only one global scope and it cannot be created by clients,
|
||||
// thus no set.
|
||||
@@ -28,23 +29,21 @@ export default class ScopeModel extends GeneratedScopeModel {
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
@computed('type')
|
||||
get isOrg() {
|
||||
return this.type === scopeTypes.org;
|
||||
return this.type === TYPE_SCOPE_ORG;
|
||||
}
|
||||
set isOrg(value) {
|
||||
if (value) this.type = scopeTypes.org;
|
||||
if (value) this.type = TYPE_SCOPE_ORG;
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
@computed('type')
|
||||
get isProject() {
|
||||
return this.type === scopeTypes.project;
|
||||
return this.type === TYPE_SCOPE_PROJECT;
|
||||
}
|
||||
set isProject(value) {
|
||||
if (value) this.type = scopeTypes.project;
|
||||
if (value) this.type = TYPE_SCOPE_PROJECT;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,8 @@ export const modelIndexes = {
|
||||
group:
|
||||
'&id, attributes.created_time, attributes.name, attributes.description, attributes.scope.scope_id',
|
||||
role: '&id, attributes.created_time, attributes.name, attributes.description, attributes.scope.scope_id',
|
||||
scope:
|
||||
'&id, attributes.created_time, attributes.type, attributes.name, attributes.description, attributes.scope.scope_id',
|
||||
'credential-store':
|
||||
'&id, attributes.created_time, attributes.name, attributes.description, attributes.type, attributes.scope.scope_id',
|
||||
'host-catalog':
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
{{#if (can 'addBrokeredCredentialSources target' @model)}}
|
||||
<dropdown.link
|
||||
@route='scopes.scope.targets.target.add-brokered-credential-sources'
|
||||
data-test-add-brokered-cred-sources-action
|
||||
>
|
||||
{{t 'resources.target.actions.add-brokered-credential-sources'}}
|
||||
</dropdown.link>
|
||||
@@ -24,6 +25,7 @@
|
||||
{{#if (can 'addInjectedApplicationCredentialSources target' @model)}}
|
||||
<dropdown.link
|
||||
@route='scopes.scope.targets.target.add-injected-application-credential-sources'
|
||||
data-test-add-injected-cred-sources-action
|
||||
>
|
||||
{{t
|
||||
'resources.target.actions.add-injected-application-credential-sources'
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import Controller from '@ember/controller';
|
||||
import { action } from '@ember/object';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { debounce } from 'core/decorators/debounce';
|
||||
|
||||
export default class ScopesScopeScopesIndexController extends Controller {
|
||||
// =attributes
|
||||
|
||||
queryParams = ['search', 'page', 'pageSize'];
|
||||
|
||||
@tracked search = '';
|
||||
@tracked page = 1;
|
||||
@tracked pageSize = 10;
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Handles input on each keystroke and the search queryParam
|
||||
* @param {object} event
|
||||
*/
|
||||
@action
|
||||
@debounce(250)
|
||||
handleSearchInput(event) {
|
||||
const { value } = event.target;
|
||||
this.search = value;
|
||||
this.page = 1;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import { action } from '@ember/object';
|
||||
import { loading } from 'ember-loading';
|
||||
import { notifyError } from 'core/decorators/notify';
|
||||
import { TYPE_TARGET_TCP } from 'api/models/target';
|
||||
|
||||
export default class OnboardingRoute extends Route {
|
||||
// =services
|
||||
|
||||
@@ -25,6 +26,7 @@ export default class OnboardingRoute extends Route {
|
||||
async beforeModel() {
|
||||
const orgs = await this.store.query('scope', {
|
||||
scope_id: 'global',
|
||||
query: { filters: { scope_id: [{ equals: 'global' }] } },
|
||||
});
|
||||
if (!this.session.isAuthenticated || orgs.length)
|
||||
this.router.transitionTo('index');
|
||||
|
||||
@@ -33,9 +33,13 @@ export default class ScopesRoute extends Route {
|
||||
await this.store.findRecord('scope', 'global').catch(() => {
|
||||
/* no op */
|
||||
});
|
||||
// NOTE: In the absence of a `scope_id` query parameter, this endpoint is
|
||||
// expected to default to the global scope, thus returning org scopes.
|
||||
return this.store.query('scope', {}).catch(() => A([]));
|
||||
// Return all org scopes.
|
||||
return this.store
|
||||
.query('scope', {
|
||||
scope_id: 'global',
|
||||
query: { filters: { scope_id: [{ equals: 'global' }] } },
|
||||
})
|
||||
.catch(() => A([]));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,6 +11,7 @@ import { next } from '@ember/runloop';
|
||||
import { loading } from 'ember-loading';
|
||||
import { confirm } from 'core/decorators/confirm';
|
||||
import { notifySuccess, notifyError } from 'core/decorators/notify';
|
||||
import { TYPE_SCOPE_GLOBAL, TYPE_SCOPE_ORG } from 'api/models/scope';
|
||||
|
||||
export default class ScopesScopeRoute extends Route {
|
||||
// =services
|
||||
@@ -36,7 +37,7 @@ export default class ScopesScopeRoute extends Route {
|
||||
async model({ scope_id: id }) {
|
||||
// Since only global and org scopes are authenticatable, we can infer type
|
||||
// from ID because global has a fixed ID.
|
||||
const type = id === 'global' ? 'global' : 'org';
|
||||
const type = id === 'global' ? TYPE_SCOPE_GLOBAL : TYPE_SCOPE_ORG;
|
||||
return this.store.findRecord('scope', id).catch(() => {
|
||||
const maybeExistingScope = this.store.peekRecord('scope', id);
|
||||
const scopeOptions = { id, type };
|
||||
@@ -55,11 +56,17 @@ export default class ScopesScopeRoute extends Route {
|
||||
// First, load orgs and, if necessary, projects
|
||||
let orgs, projects;
|
||||
orgs = await this.store
|
||||
.query('scope', { scope_id: 'global' })
|
||||
.query('scope', {
|
||||
scope_id: 'global',
|
||||
query: { filters: { scope_id: [{ equals: 'global' }] } },
|
||||
})
|
||||
.catch(() => A([]));
|
||||
|
||||
if (model.isProject) {
|
||||
projects = await this.store.query('scope', { scope_id: model.scopeID });
|
||||
projects = await this.store.query('scope', {
|
||||
scope_id: model.scopeID,
|
||||
query: { filters: { scope_id: [{ equals: model.scopeID }] } },
|
||||
});
|
||||
}
|
||||
// Then pull out the "selected" scopes, if relevant
|
||||
let selectedOrg, selectedProject;
|
||||
@@ -144,7 +151,6 @@ export default class ScopesScopeRoute extends Route {
|
||||
async delete(scope) {
|
||||
const { scopeID } = scope;
|
||||
await scope.destroyRecord();
|
||||
await this.router.replaceWith('scopes.scope.scopes', scopeID);
|
||||
//this.refresh();
|
||||
this.router.replaceWith('scopes.scope.scopes', scopeID);
|
||||
}
|
||||
}
|
||||
@@ -22,12 +22,16 @@ export default class ScopesScopeRolesRoleIndexRoute extends Route {
|
||||
if (!currentScope.isProject) {
|
||||
const scopes = await this.store.query('scope', {
|
||||
scope_id: currentScope.id,
|
||||
query: { filters: { scope_id: [{ equals: currentScope.id }] } },
|
||||
});
|
||||
subScopes = await Promise.all(
|
||||
scopes.map(async (scope) => ({
|
||||
model: scope,
|
||||
subScopes: !scope.isProject
|
||||
? await this.store.query('scope', { scope_id: scope.id })
|
||||
? await this.store.query('scope', {
|
||||
scope_id: scope.id,
|
||||
query: { filters: { scope_id: [{ equals: scope.id }] } },
|
||||
})
|
||||
: [],
|
||||
})),
|
||||
);
|
||||
|
||||
@@ -14,7 +14,6 @@ import { inject as service } from '@ember/service';
|
||||
export default class ScopesScopeScopesRoute extends Route {
|
||||
// =services
|
||||
|
||||
@service store;
|
||||
@service session;
|
||||
@service router;
|
||||
|
||||
@@ -26,23 +25,4 @@ export default class ScopesScopeScopesRoute extends Route {
|
||||
beforeModel() {
|
||||
if (!this.session.isAuthenticated) this.router.transitionTo('index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads sub scopes for the current scope.
|
||||
* @return {Promise}
|
||||
*/
|
||||
async model() {
|
||||
const currentScope = this.modelFor('scopes.scope');
|
||||
const parentScope = !currentScope.isGlobal
|
||||
? await this.store.findRecord('scope', currentScope.scopeID)
|
||||
: null;
|
||||
const subScopes = await this.store.query('scope', {
|
||||
scope_id: currentScope.id,
|
||||
});
|
||||
return {
|
||||
currentScope,
|
||||
parentScope,
|
||||
subScopes,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -4,5 +4,84 @@
|
||||
*/
|
||||
|
||||
import Route from '@ember/routing/route';
|
||||
import { inject as service } from '@ember/service';
|
||||
|
||||
export default class ScopesScopeScopesIndexRoute extends Route {}
|
||||
export default class ScopesScopeScopesIndexRoute extends Route {
|
||||
// =attributes
|
||||
|
||||
queryParams = {
|
||||
search: {
|
||||
refreshModel: true,
|
||||
replace: true,
|
||||
},
|
||||
page: {
|
||||
refreshModel: true,
|
||||
},
|
||||
pageSize: {
|
||||
refreshModel: true,
|
||||
},
|
||||
};
|
||||
|
||||
// =services
|
||||
|
||||
@service can;
|
||||
@service store;
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Loads sub scopes for the current scope.
|
||||
* @returns {Promise<{totalItems: number, currentScope: ScopeModel, subScopes: [ScopeModel], scopesExist: boolean }> }
|
||||
*/
|
||||
async model({ search, page, pageSize }) {
|
||||
const currentScope = this.modelFor('scopes.scope');
|
||||
const { id: scope_id } = currentScope;
|
||||
const filters = {
|
||||
scope_id: [{ equals: scope_id }],
|
||||
};
|
||||
|
||||
const subScopes = await this.store.query('scope', {
|
||||
scope_id,
|
||||
query: { search, filters },
|
||||
page,
|
||||
pageSize,
|
||||
});
|
||||
const totalItems = subScopes.meta?.totalItems;
|
||||
const scopesExist = await this.getScopesExist(scope_id, totalItems);
|
||||
|
||||
return {
|
||||
currentScope,
|
||||
subScopes,
|
||||
scopesExist,
|
||||
totalItems,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets scopesExist to true if there exists any scopes.
|
||||
* @param {string} scope_id
|
||||
* @param {number} totalItems
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async getScopesExist(scope_id, totalItems) {
|
||||
if (totalItems > 0) {
|
||||
return true;
|
||||
}
|
||||
const options = { pushToStore: false };
|
||||
const scopes = await this.store.query(
|
||||
'scope',
|
||||
{
|
||||
scope_id,
|
||||
query: {
|
||||
filters: {
|
||||
scope_id: [{ equals: scope_id }],
|
||||
},
|
||||
},
|
||||
page: 1,
|
||||
pageSize: 1,
|
||||
},
|
||||
options,
|
||||
);
|
||||
return scopes.length > 0;
|
||||
}
|
||||
}
|
||||
@@ -78,7 +78,10 @@ export default class ScopesScopeStorageBucketsNewRoute extends Route {
|
||||
async afterModel() {
|
||||
let scopes;
|
||||
const orgScopes = (
|
||||
await this.store.query('scope', { scope_id: 'global' })
|
||||
await this.store.query('scope', {
|
||||
scope_id: 'global',
|
||||
query: { filters: { scope_id: [{ equals: 'global' }] } },
|
||||
})
|
||||
).map((scope) => ({ model: scope }));
|
||||
scopes = [
|
||||
{ model: this.store.peekRecord('scope', 'global') },
|
||||
|
||||
@@ -16,7 +16,10 @@ export default class ScopesScopeStorageBucketsStorageBucketIndexRoute extends Ro
|
||||
async afterModel() {
|
||||
let scopes;
|
||||
const orgScopes = (
|
||||
await this.store.query('scope', { scope_id: 'global' })
|
||||
await this.store.query('scope', {
|
||||
scope_id: 'global',
|
||||
query: { filters: { scope_id: [{ equals: 'global' }] } },
|
||||
})
|
||||
).map((scope) => ({ model: scope }));
|
||||
scopes = [
|
||||
{ model: this.store.peekRecord('scope', 'global') },
|
||||
|
||||
+7
-4
@@ -5,13 +5,13 @@
|
||||
|
||||
import Route from '@ember/routing/route';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { action } from '@ember/object';
|
||||
import { notifySuccess, notifyError } from 'core/decorators/notify';
|
||||
import { loading } from 'ember-loading';
|
||||
import {
|
||||
TYPE_STORAGE_BUCKET_PLUGIN,
|
||||
TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3,
|
||||
} from 'api/models/storage-bucket';
|
||||
import { action } from '@ember/object';
|
||||
import { notifySuccess, notifyError } from 'core/decorators/notify';
|
||||
import { loading } from 'ember-loading';
|
||||
|
||||
export default class ScopesScopeTargetsTargetEnableSessionRecordingCreateStorageBucketRoute extends Route {
|
||||
// =services
|
||||
@@ -37,7 +37,10 @@ export default class ScopesScopeTargetsTargetEnableSessionRecordingCreateStorage
|
||||
async afterModel() {
|
||||
let scopes;
|
||||
const orgScopes = (
|
||||
await this.store.query('scope', { scope_id: 'global' })
|
||||
await this.store.query('scope', {
|
||||
scope_id: 'global',
|
||||
query: { filters: { scope_id: [{ equals: 'global' }] } },
|
||||
})
|
||||
).map((scope) => ({ model: scope }));
|
||||
scopes = [
|
||||
{ model: this.store.peekRecord('scope', 'global') },
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
{{t 'resources.org.title_plural'}}
|
||||
<DocLink @doc='org' @iconSize='large' />
|
||||
</h2>
|
||||
{{#if @model.subScopes}}
|
||||
{{#if @model.scopesExist}}
|
||||
<p>{{t 'resources.org.description'}}</p>
|
||||
{{/if}}
|
||||
{{else if @model.currentScope.isOrg}}
|
||||
@@ -23,7 +23,7 @@
|
||||
{{t 'resources.project.title_plural'}}
|
||||
<DocLink @doc='project' @iconSize='large' />
|
||||
</h2>
|
||||
{{#if @model.subScopes}}
|
||||
{{#if @model.scopesExist}}
|
||||
<p>{{t 'resources.project.description'}}</p>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
@@ -31,79 +31,115 @@
|
||||
|
||||
<page.actions>
|
||||
{{#if (can 'create model' @model.currentScope collection='scopes')}}
|
||||
{{#if @model.subScopes}}
|
||||
<Rose::LinkButton @route='scopes.scope.scopes.new' @style='primary'>
|
||||
{{#if @model.currentScope.isGlobal}}
|
||||
{{t 'resources.org.titles.new'}}
|
||||
{{else if @model.currentScope.isOrg}}
|
||||
{{t 'resources.project.titles.new'}}
|
||||
{{/if}}
|
||||
</Rose::LinkButton>
|
||||
{{#if @model.scopesExist}}
|
||||
<Hds::Button
|
||||
@route='scopes.scope.scopes.new'
|
||||
@text={{t
|
||||
(if
|
||||
@model.currentScope.isGlobal
|
||||
'resources.org.titles.new'
|
||||
'resources.project.titles.new'
|
||||
)
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</page.actions>
|
||||
|
||||
<page.body>
|
||||
<page.body class='search-filtering'>
|
||||
|
||||
{{#if @model.subScopes}}
|
||||
|
||||
<Rose::Cards as |cards|>
|
||||
{{#each @model.subScopes as |scope|}}
|
||||
<cards.link
|
||||
@title={{scope.name}}
|
||||
@description={{scope.description}}
|
||||
@id={{scope.id}}
|
||||
@icon={{if
|
||||
scope.isOrg
|
||||
'flight-icons/svg/org-16'
|
||||
'flight-icons/svg/grid-16'
|
||||
{{#if @model.scopesExist}}
|
||||
<Hds::SegmentedGroup as |S|>
|
||||
<S.TextInput
|
||||
@value={{this.search}}
|
||||
@type='search'
|
||||
placeholder={{t 'actions.search'}}
|
||||
aria-label={{t 'actions.search'}}
|
||||
{{on 'input' this.handleSearchInput}}
|
||||
/>
|
||||
</Hds::SegmentedGroup>
|
||||
{{#if @model.subScopes}}
|
||||
<Hds::Table
|
||||
@columns={{array
|
||||
(hash label=(t 'form.name.label'))
|
||||
(hash label=(t 'form.id.label'))
|
||||
}}
|
||||
@model={{@model.subScopes}}
|
||||
@valign='middle'
|
||||
>
|
||||
<:body as |B|>
|
||||
<B.Tr data-test-scopes-table-row={{B.data.id}}>
|
||||
<B.Td>
|
||||
{{#if (can 'read model' B.data)}}
|
||||
<LinkTo @route='scopes.scope' @model={{B.data.id}}>
|
||||
{{B.data.displayName}}
|
||||
</LinkTo>
|
||||
{{else}}
|
||||
<Hds::Text::Body @tag='p'>
|
||||
{{B.data.displayName}}
|
||||
</Hds::Text::Body>
|
||||
{{/if}}
|
||||
<Hds::Text::Body @tag='p'>
|
||||
{{B.data.description}}
|
||||
</Hds::Text::Body>
|
||||
</B.Td>
|
||||
<B.Td>
|
||||
<Hds::Copy::Snippet
|
||||
@textToCopy={{B.data.id}}
|
||||
@color='secondary'
|
||||
/>
|
||||
</B.Td>
|
||||
</B.Tr>
|
||||
</:body>
|
||||
</Hds::Table>
|
||||
<Rose::Pagination
|
||||
@totalItems={{@model.totalItems}}
|
||||
@currentPage={{this.page}}
|
||||
@currentPageSize={{this.pageSize}}
|
||||
/>
|
||||
{{else}}
|
||||
<Hds::ApplicationState data-test-no-scope-results as |A|>
|
||||
<A.Header @title={{t 'titles.no-results-found'}} />
|
||||
<A.Body
|
||||
@text={{t
|
||||
'descriptions.no-search-results'
|
||||
query=this.search
|
||||
resource=(t 'resources.scope.title_plural')
|
||||
}}
|
||||
@route='scopes.scope'
|
||||
@model={{scope.id}}
|
||||
/>
|
||||
{{/each}}
|
||||
</Rose::Cards>
|
||||
</Hds::ApplicationState>
|
||||
{{/if}}
|
||||
|
||||
{{else}}
|
||||
|
||||
{{#if @model.currentScope.isGlobal}}
|
||||
<Rose::Layout::Centered>
|
||||
<Rose::Message
|
||||
@title={{t 'resources.org.messages.welcome.title'}}
|
||||
as |message|
|
||||
>
|
||||
<message.description>
|
||||
{{t 'resources.org.description'}}
|
||||
</message.description>
|
||||
{{#if (can 'create model' @model.currentScope collection='scopes')}}
|
||||
<message.link @route='scopes.scope.scopes.new'>
|
||||
<Rose::Icon @name='flight-icons/svg/plus-circle-16' />
|
||||
{{t 'titles.new'}}
|
||||
</message.link>
|
||||
{{/if}}
|
||||
</Rose::Message>
|
||||
</Rose::Layout::Centered>
|
||||
{{/if}}
|
||||
|
||||
{{#if @model.currentScope.isOrg}}
|
||||
<Rose::Layout::Centered>
|
||||
<Rose::Message
|
||||
@title={{t 'resources.project.messages.welcome.title'}}
|
||||
as |message|
|
||||
>
|
||||
<message.description>
|
||||
{{t 'resources.project.description'}}
|
||||
</message.description>
|
||||
{{#if (can 'create model' @model.currentScope collection='scopes')}}
|
||||
<message.link @route='scopes.scope.scopes.new'>
|
||||
<Rose::Icon @name='flight-icons/svg/plus-circle-16' />
|
||||
{{t 'titles.new'}}
|
||||
</message.link>
|
||||
{{/if}}
|
||||
</Rose::Message>
|
||||
</Rose::Layout::Centered>
|
||||
{{/if}}
|
||||
|
||||
<Hds::ApplicationState as |A|>
|
||||
<A.Header
|
||||
@title={{t
|
||||
(if
|
||||
@model.currentScope.isGlobal
|
||||
'resources.org.messages.welcome.title'
|
||||
'resources.project.messages.welcome.title'
|
||||
)
|
||||
}}
|
||||
/>
|
||||
<A.Body
|
||||
@text={{t
|
||||
(if
|
||||
@model.currentScope.isGlobal
|
||||
'resources.org.description'
|
||||
'resources.project.description'
|
||||
)
|
||||
}}
|
||||
/>
|
||||
{{#if (can 'create model' @model.currentScope collection='scopes')}}
|
||||
<A.Footer as |F|>
|
||||
<F.Link::Standalone
|
||||
@icon='plus-circle'
|
||||
@text={{t 'titles.new'}}
|
||||
@route='scopes.scope.scopes.new'
|
||||
/>
|
||||
</A.Footer>
|
||||
{{/if}}
|
||||
</Hds::ApplicationState>
|
||||
{{/if}}
|
||||
|
||||
</page.body>
|
||||
|
||||
@@ -7,6 +7,7 @@ import { module, test } from 'qunit';
|
||||
import { visit, currentURL, click, find, fillIn } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
import { Response } from 'miragejs';
|
||||
import {
|
||||
@@ -19,6 +20,7 @@ import {
|
||||
module('Acceptance | accounts | change password', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
const instances = {
|
||||
scopes: {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { module, test } from 'qunit';
|
||||
import { visit, currentURL, click, fillIn, select } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import { Response } from 'miragejs';
|
||||
import {
|
||||
authenticateSession,
|
||||
@@ -18,6 +19,8 @@ import {
|
||||
module('Acceptance | auth-methods | create', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
const DROPDOWN_SELECTOR_ICON =
|
||||
'tbody .hds-table__tr:nth-child(1) .hds-table__td:last-child .hds-dropdown-toggle-icon';
|
||||
const DROPDOWN_SELECTOR_OPTION =
|
||||
|
||||
@@ -7,6 +7,7 @@ import { module, test } from 'qunit';
|
||||
import { visit, find } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import {
|
||||
authenticateSession,
|
||||
// These are left here intentionally for future reference.
|
||||
@@ -17,6 +18,7 @@ import {
|
||||
module('Acceptance | auth-methods | list', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
const instances = {
|
||||
scopes: {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { module, test } from 'qunit';
|
||||
import { visit, currentURL, click } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
import { authenticateSession } from 'ember-simple-auth/test-support';
|
||||
import {
|
||||
@@ -18,6 +19,8 @@ import {
|
||||
module('Acceptance | auth-methods | read', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
const AUTH_LINK_SELECTOR = 'main tbody .hds-table__td:nth-child(1) a';
|
||||
const AUTH_TYPE_SELECTOR =
|
||||
'tbody .hds-table__tr:nth-child(1) .hds-table__td:nth-child(2)';
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
} from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import { Response } from 'miragejs';
|
||||
import { runAllJobs } from 'ember-pollster/test-support';
|
||||
import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
@@ -32,6 +33,7 @@ import {
|
||||
module('Acceptance | authentication', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
let indexURL;
|
||||
let globalScope;
|
||||
|
||||
@@ -7,11 +7,13 @@ import { module, test } from 'qunit';
|
||||
import { visit, click } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'admin/tests/helpers';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import { authenticateSession } from 'ember-simple-auth/test-support';
|
||||
|
||||
module('Acceptance | policies | delete', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
let featuresService;
|
||||
let policyCount;
|
||||
|
||||
@@ -7,11 +7,13 @@ import { module, test } from 'qunit';
|
||||
import { visit, click, currentURL, find } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'admin/tests/helpers';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import { authenticateSession } from 'ember-simple-auth/test-support';
|
||||
|
||||
module('Acceptance | policies | list', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
let featuresService;
|
||||
let intl;
|
||||
|
||||
@@ -7,12 +7,14 @@ import { module, test } from 'qunit';
|
||||
import { visit, currentURL, click } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'admin/tests/helpers';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
import { authenticateSession } from 'ember-simple-auth/test-support';
|
||||
|
||||
module('Acceptance | policies | read', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
let features;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import { module, test } from 'qunit';
|
||||
import { visit, currentURL, click, fillIn } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
import { Response } from 'miragejs';
|
||||
import {
|
||||
@@ -19,6 +20,15 @@ import {
|
||||
module('Acceptance | scopes', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
const ORG_SCOPES_DROPDOWN_SELECTOR = (url) =>
|
||||
`.rose-header-nav .rose-dropdown [href="${url}"]`;
|
||||
const PROJECT_SCOPES_DROPDOWN_SELECTOR = (url) =>
|
||||
`.rose-header-nav .rose-dropdown + .rose-dropdown [href="${url}"]`;
|
||||
const SAVE_BUTTON_SELECTOR = '[type="submit"]';
|
||||
const CANCEL_BUTTON_SELECTOR = '.rose-form-actions [type="button"]';
|
||||
const NAME_FIELD_SELECTOR = '[name="name"]';
|
||||
|
||||
let getScopeCount;
|
||||
|
||||
@@ -34,10 +44,14 @@ module('Acceptance | scopes', function (hooks) {
|
||||
const urls = {
|
||||
globalScope: null,
|
||||
orgScope: null,
|
||||
orgScopes: null,
|
||||
newOrgScope: null,
|
||||
org2Scope: null,
|
||||
org2Scopes: null,
|
||||
orgScopeEdit: null,
|
||||
org2ScopeEdit: null,
|
||||
projectScope: null,
|
||||
newProjectScope: null,
|
||||
project2Scope: null,
|
||||
projectScopeEdit: null,
|
||||
project2ScopeEdit: null,
|
||||
@@ -64,19 +78,21 @@ module('Acceptance | scopes', function (hooks) {
|
||||
});
|
||||
// Generate route URLs for resources
|
||||
urls.globalScope = `/scopes/global/scopes`;
|
||||
urls.newOrgScope = `/scopes/global/scopes/new`;
|
||||
urls.orgScope = `/scopes/${instances.scopes.org.id}/scopes`;
|
||||
urls.org2Scope = `/scopes/${instances.scopes.org2.id}/scopes`;
|
||||
urls.orgScopeEdit = `/scopes/${instances.scopes.org.id}/edit`;
|
||||
urls.org2ScopeEdit = `/scopes/${instances.scopes.org2.id}/edit`;
|
||||
urls.newProjectScope = `/scopes/${instances.scopes.org.id}/scopes/new`;
|
||||
urls.newOrgScope = `${urls.globalScope}/new`;
|
||||
urls.orgScope = `/scopes/${instances.scopes.org.id}`;
|
||||
urls.orgScopes = `${urls.orgScope}/scopes`;
|
||||
urls.org2Scope = `/scopes/${instances.scopes.org2.id}`;
|
||||
urls.org2Scopes = `${urls.org2Scope}/scopes`;
|
||||
urls.orgScopeEdit = `${urls.orgScope}/edit`;
|
||||
urls.org2ScopeEdit = `${urls.org2Scope}/edit`;
|
||||
urls.newProjectScope = `${urls.orgScopes}/new`;
|
||||
urls.projectScope = `/scopes/${instances.scopes.project.id}`;
|
||||
urls.project2Scope = `/scopes/${instances.scopes.project2.id}`;
|
||||
urls.projectScopeEdit = `/scopes/${instances.scopes.project.id}/edit`;
|
||||
urls.project2ScopeEdit = `/scopes/${instances.scopes.project2.id}/edit`;
|
||||
// Generate resource couner
|
||||
urls.projectScopeEdit = `${urls.projectScope}/edit`;
|
||||
urls.project2ScopeEdit = `${urls.project2Scope}/edit`;
|
||||
// Generate resource counter
|
||||
getScopeCount = (type) => this.server.schema.scopes.where({ type }).length;
|
||||
authenticateSession({});
|
||||
authenticateSession({ isGlobal: true });
|
||||
});
|
||||
|
||||
test('visiting global scope', async function (assert) {
|
||||
@@ -100,67 +116,79 @@ module('Acceptance | scopes', function (hooks) {
|
||||
});
|
||||
|
||||
test('visiting org scope', async function (assert) {
|
||||
await visit(urls.orgScope);
|
||||
await visit(urls.orgScopes);
|
||||
await a11yAudit();
|
||||
assert.strictEqual(currentURL(), urls.orgScope);
|
||||
|
||||
assert.strictEqual(currentURL(), urls.orgScopes);
|
||||
});
|
||||
|
||||
// NOTE: In reality, we'd have a third "Global" item listed in the org
|
||||
// dropdown. But since the mock test authenticator bypasses the auth
|
||||
// normalization step, the UI doesn't know it's authenticated with global
|
||||
// and thus doesn't display the "Global" item in the org nav dropdown.
|
||||
test('can navigate among org scopes via header navigation', async function (assert) {
|
||||
await visit(urls.globalScope);
|
||||
await a11yAudit();
|
||||
|
||||
assert.strictEqual(currentURL(), urls.globalScope);
|
||||
await click('.rose-header-nav .rose-dropdown a:nth-child(1)');
|
||||
assert.strictEqual(currentURL(), urls.orgScope);
|
||||
// In reality, there would be a third item in the list
|
||||
await click('.rose-header-nav .rose-dropdown a:nth-child(2)');
|
||||
assert.strictEqual(currentURL(), urls.org2Scope);
|
||||
|
||||
await click(ORG_SCOPES_DROPDOWN_SELECTOR(urls.orgScope));
|
||||
assert.strictEqual(currentURL(), urls.orgScopes);
|
||||
|
||||
await click(ORG_SCOPES_DROPDOWN_SELECTOR(urls.org2Scope));
|
||||
assert.strictEqual(currentURL(), urls.org2Scopes);
|
||||
});
|
||||
|
||||
test('can navigate among project scopes via header navigation', async function (assert) {
|
||||
await visit(urls.projectScope);
|
||||
await a11yAudit();
|
||||
|
||||
assert.strictEqual(currentURL(), urls.projectScopeEdit);
|
||||
await click(
|
||||
'.rose-header-nav .rose-dropdown + .rose-dropdown a:nth-child(2)',
|
||||
);
|
||||
|
||||
await click(PROJECT_SCOPES_DROPDOWN_SELECTOR(urls.project2Scope));
|
||||
|
||||
assert.strictEqual(currentURL(), urls.project2ScopeEdit);
|
||||
});
|
||||
|
||||
test('can create new org scopes', async function (assert) {
|
||||
const orgScopeCount = getScopeCount('org');
|
||||
await visit(urls.newOrgScope);
|
||||
await fillIn('[name="name"]', 'random string');
|
||||
await click('[type="submit"]');
|
||||
await visit(urls.globalScope);
|
||||
|
||||
await click(`[href="${urls.newOrgScope}"]`);
|
||||
await fillIn(NAME_FIELD_SELECTOR, 'random string');
|
||||
await click(SAVE_BUTTON_SELECTOR);
|
||||
|
||||
assert.strictEqual(getScopeCount('org'), orgScopeCount + 1);
|
||||
});
|
||||
|
||||
test('can create new project scopes', async function (assert) {
|
||||
const orgScopeCount = getScopeCount('project');
|
||||
await visit(urls.newProjectScope);
|
||||
await fillIn('[name="name"]', 'random string');
|
||||
await click('[type="submit"]');
|
||||
await visit(urls.orgScopes);
|
||||
|
||||
await click(`[href="${urls.newProjectScope}"]`);
|
||||
await fillIn(NAME_FIELD_SELECTOR, 'random string');
|
||||
await click(SAVE_BUTTON_SELECTOR);
|
||||
|
||||
assert.strictEqual(getScopeCount('project'), orgScopeCount + 1);
|
||||
});
|
||||
|
||||
test('can cancel create new org scopes', async function (assert) {
|
||||
const orgScopeCount = getScopeCount('org');
|
||||
await visit(urls.newOrgScope);
|
||||
await fillIn('[name="name"]', 'random string');
|
||||
await click('.rose-form-actions [type="button"]');
|
||||
await visit(urls.globalScope);
|
||||
|
||||
await click(`[href="${urls.newOrgScope}"]`);
|
||||
await fillIn(NAME_FIELD_SELECTOR, 'random string');
|
||||
await click(CANCEL_BUTTON_SELECTOR);
|
||||
|
||||
assert.strictEqual(currentURL(), urls.globalScope);
|
||||
assert.strictEqual(getScopeCount('org'), orgScopeCount);
|
||||
});
|
||||
|
||||
test('can cancel create new project scopes', async function (assert) {
|
||||
const projectScopeCount = getScopeCount('project');
|
||||
await visit(urls.newProjectScope);
|
||||
await fillIn('[name="name"]', 'random string');
|
||||
await click('.rose-form-actions [type="button"]');
|
||||
assert.strictEqual(currentURL(), urls.orgScope);
|
||||
await visit(urls.orgScopes);
|
||||
|
||||
await click(`[href="${urls.newProjectScope}"]`);
|
||||
await fillIn(NAME_FIELD_SELECTOR, 'random string');
|
||||
await click(CANCEL_BUTTON_SELECTOR);
|
||||
|
||||
assert.strictEqual(currentURL(), urls.orgScopes);
|
||||
assert.strictEqual(getScopeCount('project'), projectScopeCount);
|
||||
});
|
||||
|
||||
@@ -184,8 +212,11 @@ module('Acceptance | scopes', function (hooks) {
|
||||
},
|
||||
);
|
||||
});
|
||||
await visit(urls.newOrgScope);
|
||||
await click('[type="submit"]');
|
||||
await visit(urls.globalScope);
|
||||
|
||||
await click(`[href="${urls.newOrgScope}"]`);
|
||||
await click(SAVE_BUTTON_SELECTOR);
|
||||
|
||||
assert.dom('.rose-notification-body').hasText('The request was invalid.');
|
||||
assert.dom('.hds-form-error__message').hasText('Name is required.');
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ import { module, test } from 'qunit';
|
||||
import { visit, click, currentURL } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import { Response } from 'miragejs';
|
||||
import {
|
||||
authenticateSession,
|
||||
@@ -18,6 +19,7 @@ import {
|
||||
module('Acceptance | scopes | delete', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
let getScopeCount;
|
||||
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { visit, fillIn, waitFor } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import {
|
||||
authenticateSession,
|
||||
// These are left here intentionally for future reference.
|
||||
//currentSession,
|
||||
//invalidateSession,
|
||||
} from 'ember-simple-auth/test-support';
|
||||
|
||||
module('Acceptance | scopes | list', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
const SEARCH_INPUT_SELECTOR = '.search-filtering [type="search"]';
|
||||
const NO_RESULTS_MSG_SELECTOR = '[data-test-no-scope-results]';
|
||||
const SCOPE_LINK_SELECTOR = (id) =>
|
||||
`tbody [data-test-scopes-table-row="${id}"] a`;
|
||||
|
||||
const instances = {
|
||||
scopes: {
|
||||
global: null,
|
||||
org1: null,
|
||||
org2: null,
|
||||
project1: null,
|
||||
project2: null,
|
||||
},
|
||||
};
|
||||
|
||||
const urls = {
|
||||
globalScope: null,
|
||||
orgScope: null,
|
||||
};
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
instances.scopes.global = this.server.create('scope', { id: 'global' });
|
||||
instances.scopes.org1 = this.server.create('scope', {
|
||||
type: 'org',
|
||||
scope: { id: 'global', type: 'global' },
|
||||
});
|
||||
instances.scopes.org2 = this.server.create('scope', {
|
||||
type: 'org',
|
||||
scope: { id: 'global', type: 'global' },
|
||||
});
|
||||
instances.scopes.project1 = this.server.create('scope', {
|
||||
type: 'project',
|
||||
scope: { id: instances.scopes.org1.id, type: 'org' },
|
||||
});
|
||||
instances.scopes.project2 = this.server.create('scope', {
|
||||
type: 'project',
|
||||
scope: { id: instances.scopes.org1.id, type: 'org' },
|
||||
});
|
||||
urls.globalScope = `/scopes/global/scopes`;
|
||||
urls.orgScope = `/scopes/${instances.scopes.org1.id}/scopes`;
|
||||
authenticateSession({});
|
||||
});
|
||||
|
||||
test('user can search for a specifc org scope by id', async function (assert) {
|
||||
await visit(urls.globalScope);
|
||||
|
||||
assert.dom(SCOPE_LINK_SELECTOR(instances.scopes.org1.id)).exists();
|
||||
assert.dom(SCOPE_LINK_SELECTOR(instances.scopes.org2.id)).exists();
|
||||
|
||||
await fillIn(SEARCH_INPUT_SELECTOR, instances.scopes.org1.id);
|
||||
await waitFor(SCOPE_LINK_SELECTOR(instances.scopes.org2.id), { count: 0 });
|
||||
|
||||
assert.dom(SCOPE_LINK_SELECTOR(instances.scopes.org1.id)).exists();
|
||||
assert.dom(SCOPE_LINK_SELECTOR(instances.scopes.org2.id)).doesNotExist();
|
||||
});
|
||||
|
||||
test('user can search for org scopes and get no results', async function (assert) {
|
||||
await visit(urls.globalScope);
|
||||
|
||||
assert.dom(SCOPE_LINK_SELECTOR(instances.scopes.org1.id)).exists();
|
||||
assert.dom(SCOPE_LINK_SELECTOR(instances.scopes.org2.id)).exists();
|
||||
|
||||
await fillIn(SEARCH_INPUT_SELECTOR, 'fake org scope that does not exist');
|
||||
await waitFor(NO_RESULTS_MSG_SELECTOR, { count: 1 });
|
||||
|
||||
assert.dom(SCOPE_LINK_SELECTOR(instances.scopes.org1.id)).doesNotExist();
|
||||
assert.dom(SCOPE_LINK_SELECTOR(instances.scopes.org2.id)).doesNotExist();
|
||||
});
|
||||
|
||||
test('user can search for a specifc project scope by id', async function (assert) {
|
||||
await visit(urls.orgScope);
|
||||
|
||||
assert.dom(SCOPE_LINK_SELECTOR(instances.scopes.project1.id)).exists();
|
||||
assert.dom(SCOPE_LINK_SELECTOR(instances.scopes.project2.id)).exists();
|
||||
|
||||
await fillIn(SEARCH_INPUT_SELECTOR, instances.scopes.project1.id);
|
||||
await waitFor(SCOPE_LINK_SELECTOR(instances.scopes.project2.id), {
|
||||
count: 0,
|
||||
});
|
||||
|
||||
assert.dom(SCOPE_LINK_SELECTOR(instances.scopes.project1.id)).exists();
|
||||
assert
|
||||
.dom(SCOPE_LINK_SELECTOR(instances.scopes.project2.id))
|
||||
.doesNotExist();
|
||||
});
|
||||
|
||||
test('user can search for project scopes and get no results', async function (assert) {
|
||||
await visit(urls.orgScope);
|
||||
|
||||
assert.dom(SCOPE_LINK_SELECTOR(instances.scopes.project1.id)).exists();
|
||||
assert.dom(SCOPE_LINK_SELECTOR(instances.scopes.project2.id)).exists();
|
||||
|
||||
await fillIn(SEARCH_INPUT_SELECTOR, 'fake org scope that does not exist');
|
||||
await waitFor(NO_RESULTS_MSG_SELECTOR, { count: 1 });
|
||||
|
||||
assert
|
||||
.dom(SCOPE_LINK_SELECTOR(instances.scopes.project1.id))
|
||||
.doesNotExist();
|
||||
assert
|
||||
.dom(SCOPE_LINK_SELECTOR(instances.scopes.project2.id))
|
||||
.doesNotExist();
|
||||
});
|
||||
});
|
||||
@@ -7,6 +7,7 @@ import { module, test } from 'qunit';
|
||||
import { visit, currentURL, click } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
import {
|
||||
authenticateSession,
|
||||
@@ -18,6 +19,7 @@ import {
|
||||
module('Acceptance | scopes | read', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
let features;
|
||||
let featureEdition;
|
||||
|
||||
@@ -7,6 +7,7 @@ import { module, test } from 'qunit';
|
||||
import { visit, currentURL, click, fillIn } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import { Response } from 'miragejs';
|
||||
import {
|
||||
authenticateSession,
|
||||
@@ -18,6 +19,7 @@ import {
|
||||
module('Acceptance | scopes | update', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
const instances = {
|
||||
scopes: {
|
||||
|
||||
@@ -7,11 +7,13 @@ import { module, test } from 'qunit';
|
||||
import { visit, currentURL, click } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'admin/tests/helpers';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import { authenticateSession } from 'ember-simple-auth/test-support';
|
||||
|
||||
module('Acceptance | session recordings | list', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
let featuresService;
|
||||
|
||||
|
||||
@@ -7,11 +7,13 @@ import { module, test } from 'qunit';
|
||||
import { visit, click, currentURL } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'admin/tests/helpers';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import { authenticateSession } from 'ember-simple-auth/test-support';
|
||||
|
||||
module('Acceptance | storage-buckets | list', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
let featuresService;
|
||||
let intl;
|
||||
|
||||
@@ -7,12 +7,14 @@ import { module, test } from 'qunit';
|
||||
import { visit, currentURL, click } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'admin/tests/helpers';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
import { authenticateSession } from 'ember-simple-auth/test-support';
|
||||
|
||||
module('Acceptance | storage-buckets | read', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
let features;
|
||||
|
||||
|
||||
@@ -246,7 +246,7 @@ module('Acceptance | targets | brokered credential sources', function (hooks) {
|
||||
(item) => item !== 'add-credential-sources',
|
||||
);
|
||||
await visit(urls.brokeredCredentialSources);
|
||||
assert.dom('.rose-dropdown-content a:nth-child(2)').doesNotExist();
|
||||
assert.dom('[data-test-add-brokered-cred-sources-action]').doesNotExist();
|
||||
});
|
||||
|
||||
test('can select and cancel credential sources to add', async function (assert) {
|
||||
|
||||
@@ -261,7 +261,7 @@ module(
|
||||
);
|
||||
await visit(urls.injectedApplicationCredentialSources);
|
||||
|
||||
assert.dom('.rose-dropdown-content a:nth-child(2)').doesNotExist();
|
||||
assert.dom('[data-test-add-injected-cred-sources-action]').doesNotExist();
|
||||
});
|
||||
|
||||
test('can select and cancel credential sources to add', async function (assert) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { module, test } from 'qunit';
|
||||
import { visit, currentURL, click, fillIn } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import { Response } from 'miragejs';
|
||||
import {
|
||||
authenticateSession,
|
||||
@@ -18,6 +19,7 @@ import {
|
||||
module('Acceptance | users | create', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
let getUsersCount;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import { module, test } from 'qunit';
|
||||
import { visit } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import {
|
||||
authenticateSession,
|
||||
// These are left here intentionally for future reference.
|
||||
@@ -17,6 +18,7 @@ import {
|
||||
module('Acceptance | workers | list', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
let featuresService;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import { module, test } from 'qunit';
|
||||
import { visit, currentURL, click } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
import {
|
||||
authenticateSession,
|
||||
@@ -18,6 +19,7 @@ import {
|
||||
module('Acceptance | workers | read', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
|
||||
let featuresService;
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import { waitUntil } from '@ember/test-helpers';
|
||||
|
||||
module('Unit | Controller | scopes/scope/scopes/index', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
let controller;
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
controller = this.owner.lookup('controller:scopes/scope/scopes/index');
|
||||
});
|
||||
|
||||
test('it exists', function (assert) {
|
||||
assert.ok(controller);
|
||||
});
|
||||
|
||||
test('handleSearchInput action sets expected values correctly', async function (assert) {
|
||||
const searchValue = 'test';
|
||||
controller.handleSearchInput({ target: { value: searchValue } });
|
||||
await waitUntil(() => controller.search === searchValue);
|
||||
|
||||
assert.strictEqual(controller.page, 1);
|
||||
assert.strictEqual(controller.search, searchValue);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user