refactor: 💡 add custom sort to resources (#2860)
* refactor: 💡 add custom sort * test: 💍 fix tests * test: 💍 fix more tests * refactor: 💡 use reusable sort function for name * refactor: 💡 use sort util in all resources w/ optional name * Add missing copyright headers * test: 💍 fix broken tests & add tests for new util * refactor: 💡 add name custom sort to users * test: 💍 fix import in tests * refactor: 💡 add custom name sort to scopes * test: 💍 pr feedback on util test cases * refactor: 💡 move sort function into object (pr feedback)
This commit is contained in:
1 parent
4c959ab297
commit
738fa1f15f
27 files changed
+331
-41
No files matched your search
@@ -42,7 +42,7 @@ export const sortResults = (results, { querySort, schema }) => {
|
||||
|
||||
// Default sort direction is ascending unless we are sorting by `created_time` (default sort attribute)
|
||||
const defaultSortDirection =
|
||||
sortAttribute === SORT_DEFAULT_ATTRIBUTE
|
||||
sortAttribute === SORT_DEFAULT_ATTRIBUTE && !querySort.sortFunction
|
||||
? SORT_DIRECTION_DESCENDING
|
||||
: SORT_DIRECTION_ASCENDING;
|
||||
const sortDirection = querySort.direction || defaultSortDirection;
|
||||
@@ -55,6 +55,17 @@ export const sortResults = (results, { querySort, schema }) => {
|
||||
throw new Error('Invalid sort direction');
|
||||
}
|
||||
|
||||
// Execute custom sort function if one is provided.
|
||||
if (querySort.sortFunction) {
|
||||
return results.toSorted((a, b) => {
|
||||
const sortResult = querySort.sortFunction(a, b);
|
||||
|
||||
return sortDirection === SORT_DIRECTION_ASCENDING
|
||||
? sortResult
|
||||
: -1 * sortResult;
|
||||
});
|
||||
}
|
||||
|
||||
const sortAttributeDataType = schema.attributes.get(sortAttribute)?.type;
|
||||
|
||||
const sortFunction =
|
||||
|
||||
@@ -306,6 +306,54 @@ module('Unit | Handler | indexed-db-handler', function (hooks) {
|
||||
['Alias 001', 'Alias 002', 'Alias 003', 'Alias 004'],
|
||||
);
|
||||
});
|
||||
|
||||
test('it sorts by descending, then ascending `name` using custom string sorting', async function (assert) {
|
||||
const alias1 = this.server.create('alias', { name: 'alias1' });
|
||||
const alias2 = this.server.create('alias', { name: 'alias2' });
|
||||
const alias3 = this.server.create('alias', { name: 'alias3' });
|
||||
const alias4 = this.server.create('alias', { name: 'alias4' });
|
||||
|
||||
const sortName = (recordA, recordB) => {
|
||||
const nameMap = {
|
||||
alias3: 'Alpha',
|
||||
alias4: 'Beta',
|
||||
alias1: 'Delta',
|
||||
alias2: 'Epsilon',
|
||||
};
|
||||
return String(nameMap[recordA.attributes.name]).localeCompare(
|
||||
String(nameMap[recordB.attributes.name]),
|
||||
);
|
||||
};
|
||||
|
||||
const shuffledAliases = faker.helpers.shuffle([
|
||||
alias1,
|
||||
alias2,
|
||||
alias3,
|
||||
alias4,
|
||||
]);
|
||||
|
||||
this.server.get(
|
||||
'aliases',
|
||||
createPaginatedResponseHandler(shuffledAliases, {
|
||||
pageSize: 1,
|
||||
}),
|
||||
);
|
||||
|
||||
const resultsDesc = await store.query('alias', {
|
||||
query: { sort: { sortFunction: sortName, direction: 'desc' } },
|
||||
});
|
||||
const resultsAsc = await store.query('alias', {
|
||||
query: { sort: { sortFunction: sortName, direction: 'asc' } },
|
||||
});
|
||||
assert.deepEqual(
|
||||
resultsDesc.map(({ name }) => name),
|
||||
['alias2', 'alias1', 'alias4', 'alias3'],
|
||||
);
|
||||
assert.deepEqual(
|
||||
resultsAsc.map(({ name }) => name),
|
||||
['alias3', 'alias4', 'alias1', 'alias2'],
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
module('option: pushToStore', function (hooks) {
|
||||
|
||||
@@ -421,4 +421,68 @@ module('Unit | Utility | sortResults', function (hooks) {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
module('custom function sorting', function () {
|
||||
const result01 = createJsonApiMockRecord('id_01', 'target', {
|
||||
name: 'target1',
|
||||
});
|
||||
const result02 = createJsonApiMockRecord('id_02', 'target', {
|
||||
name: 'target2',
|
||||
});
|
||||
const result03 = createJsonApiMockRecord('id_03', 'target', {
|
||||
name: 'target3',
|
||||
});
|
||||
const result04 = createJsonApiMockRecord('id_04', 'target', {
|
||||
name: 'target4',
|
||||
});
|
||||
|
||||
const sortFunction = (recordA, recordB) => {
|
||||
const nameMap = {
|
||||
target3: 'Alpha',
|
||||
target4: 'Beta',
|
||||
target1: 'Delta',
|
||||
target2: 'Epsilon',
|
||||
};
|
||||
return String(nameMap[recordA.attributes.name]).localeCompare(
|
||||
String(nameMap[recordB.attributes.name]),
|
||||
);
|
||||
};
|
||||
const schema = { attributes: new Map() };
|
||||
|
||||
test.each(
|
||||
'it sorts by `name` using custom sorting function',
|
||||
{
|
||||
'ascending (default)': {
|
||||
querySort: { sortFunction },
|
||||
expectedResults: ['target3', 'target4', 'target1', 'target2'],
|
||||
},
|
||||
descending: {
|
||||
querySort: { sortFunction, direction: 'desc' },
|
||||
expectedResults: ['target2', 'target1', 'target4', 'target3'],
|
||||
},
|
||||
ascending: {
|
||||
querySort: { sortFunction, direction: 'asc' },
|
||||
expectedResults: ['target3', 'target4', 'target1', 'target2'],
|
||||
},
|
||||
},
|
||||
function (assert, input) {
|
||||
const shuffledResults = faker.helpers.shuffle([
|
||||
result01,
|
||||
result02,
|
||||
result03,
|
||||
result04,
|
||||
]);
|
||||
schema.attributes.set('name', { type: 'string' });
|
||||
const sortedResults = sortResults(shuffledResults, {
|
||||
querySort: input.querySort,
|
||||
schema,
|
||||
});
|
||||
|
||||
assert.deepEqual(
|
||||
sortedResults.map(({ attributes: { name } }) => name),
|
||||
input.expectedResults,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -6,6 +6,7 @@
|
||||
import Route from '@ember/routing/route';
|
||||
import { service } from '@ember/service';
|
||||
import { restartableTask, timeout } from 'ember-concurrency';
|
||||
import { sortNameWithIdFallback } from 'admin/utils/sort-name-with-id-fallback';
|
||||
|
||||
export default class ScopesScopeCredentialStoresIndexRoute extends Route {
|
||||
// =services
|
||||
@@ -77,10 +78,10 @@ export default class ScopesScopeCredentialStoresIndexRoute extends Route {
|
||||
filters.type.push({ equals: type });
|
||||
});
|
||||
|
||||
const sort = {
|
||||
attribute: sortAttribute,
|
||||
direction: sortDirection,
|
||||
};
|
||||
const sort =
|
||||
sortAttribute === 'name'
|
||||
? { sortFunction: sortNameWithIdFallback, direction: sortDirection }
|
||||
: { attribute: sortAttribute, direction: sortDirection };
|
||||
|
||||
let credentialStores;
|
||||
let totalItems = 0;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import Route from '@ember/routing/route';
|
||||
import { service } from '@ember/service';
|
||||
import { restartableTask, timeout } from 'ember-concurrency';
|
||||
import { sortNameWithIdFallback } from 'admin/utils/sort-name-with-id-fallback';
|
||||
|
||||
export default class ScopesScopeGroupsIndexRoute extends Route {
|
||||
// =services
|
||||
@@ -63,15 +64,16 @@ export default class ScopesScopeGroupsIndexRoute extends Route {
|
||||
|
||||
const scope = this.modelFor('scopes.scope');
|
||||
const { id: scope_id } = scope;
|
||||
const filters = { scope_id: [{ equals: scope_id }] };
|
||||
|
||||
const sort =
|
||||
sortAttribute === 'name'
|
||||
? { sortFunction: sortNameWithIdFallback, direction: sortDirection }
|
||||
: { attribute: sortAttribute, direction: sortDirection };
|
||||
|
||||
let groups = [];
|
||||
let totalItems = 0;
|
||||
let doGroupsExist = false;
|
||||
const filters = { scope_id: [{ equals: scope_id }] };
|
||||
const sort = {
|
||||
attribute: sortAttribute,
|
||||
direction: sortDirection,
|
||||
};
|
||||
|
||||
if (this.can.can('list model', scope, { collection: 'groups' })) {
|
||||
groups = await this.store.query('group', {
|
||||
scope_id,
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import Route from '@ember/routing/route';
|
||||
import { service } from '@ember/service';
|
||||
import { restartableTask, timeout } from 'ember-concurrency';
|
||||
import { sortNameWithIdFallback } from 'admin/utils/sort-name-with-id-fallback';
|
||||
|
||||
export default class ScopesScopeHostCatalogsIndexRoute extends Route {
|
||||
// =services
|
||||
@@ -70,10 +71,10 @@ export default class ScopesScopeHostCatalogsIndexRoute extends Route {
|
||||
'plugin.name': [],
|
||||
};
|
||||
|
||||
const sort = {
|
||||
attribute: sortAttribute,
|
||||
direction: sortDirection,
|
||||
};
|
||||
const sort =
|
||||
sortAttribute === 'name'
|
||||
? { sortFunction: sortNameWithIdFallback, direction: sortDirection }
|
||||
: { attribute: sortAttribute, direction: sortDirection };
|
||||
|
||||
let hostCatalogs;
|
||||
let totalItems = 0;
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
import Route from '@ember/routing/route';
|
||||
import { service } from '@ember/service';
|
||||
import { restartableTask, timeout } from 'ember-concurrency';
|
||||
import { sortNameWithIdFallback } from 'admin/utils/sort-name-with-id-fallback';
|
||||
import { GRANT_SCOPE_THIS } from 'api/models/role';
|
||||
|
||||
export default class ScopesScopeRolesIndexRoute extends Route {
|
||||
// =attributes
|
||||
@@ -31,6 +33,21 @@ export default class ScopesScopeRolesIndexRoute extends Route {
|
||||
},
|
||||
};
|
||||
|
||||
customSortFunction = {
|
||||
name: sortNameWithIdFallback,
|
||||
grant_scope_ids: (recordA, recordB) => {
|
||||
const a = recordA.attributes?.grant_scope_ids.includes(GRANT_SCOPE_THIS);
|
||||
const b = recordB.attributes?.grant_scope_ids.includes(GRANT_SCOPE_THIS);
|
||||
if (a === b) {
|
||||
return 0;
|
||||
} else if (a) {
|
||||
return 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// =services
|
||||
|
||||
@service can;
|
||||
@@ -66,10 +83,11 @@ export default class ScopesScopeRolesIndexRoute extends Route {
|
||||
const filters = {
|
||||
scope_id: [{ equals: scope_id }],
|
||||
};
|
||||
const sort = {
|
||||
attribute: sortAttribute,
|
||||
direction: sortDirection,
|
||||
};
|
||||
|
||||
const sortFunction = this.customSortFunction[sortAttribute];
|
||||
const sort = sortFunction
|
||||
? { sortFunction, direction: sortDirection }
|
||||
: { attribute: sortAttribute, direction: sortDirection };
|
||||
|
||||
let roles;
|
||||
let totalItems = 0;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import Route from '@ember/routing/route';
|
||||
import { service } from '@ember/service';
|
||||
import { restartableTask, timeout } from 'ember-concurrency';
|
||||
import { sortNameWithIdFallback } from 'admin/utils/sort-name-with-id-fallback';
|
||||
|
||||
export default class ScopesScopeScopesIndexRoute extends Route {
|
||||
// =attributes
|
||||
@@ -67,10 +68,10 @@ export default class ScopesScopeScopesIndexRoute extends Route {
|
||||
scope_id: [{ equals: scope_id }],
|
||||
};
|
||||
|
||||
const sort = {
|
||||
attribute: sortAttribute,
|
||||
direction: sortDirection,
|
||||
};
|
||||
const sort =
|
||||
sortAttribute === 'name'
|
||||
? { sortFunction: sortNameWithIdFallback, direction: sortDirection }
|
||||
: { attribute: sortAttribute, direction: sortDirection };
|
||||
|
||||
const subScopes = await this.store.query('scope', {
|
||||
scope_id,
|
||||
|
||||
@@ -7,12 +7,18 @@ import Route from '@ember/routing/route';
|
||||
import { service } from '@ember/service';
|
||||
import { action } from '@ember/object';
|
||||
import { restartableTask, timeout } from 'ember-concurrency';
|
||||
import {
|
||||
STATE_SESSION_RECORDING_STARTED,
|
||||
STATE_SESSION_RECORDING_AVAILABLE,
|
||||
STATE_SESSION_RECORDING_UNKNOWN,
|
||||
} from 'api/models/session-recording';
|
||||
|
||||
export default class ScopesScopeSessionRecordingsIndexRoute extends Route {
|
||||
// =services
|
||||
@service store;
|
||||
@service router;
|
||||
@service can;
|
||||
@service intl;
|
||||
|
||||
// =attributes
|
||||
|
||||
@@ -65,6 +71,17 @@ export default class ScopesScopeSessionRecordingsIndexRoute extends Route {
|
||||
return this.retrieveData.perform({ ...params, useDebounce });
|
||||
}
|
||||
|
||||
sortState = (recordA, recordB) => {
|
||||
const stateMap = {
|
||||
[STATE_SESSION_RECORDING_AVAILABLE]: this.intl.t('states.completed'),
|
||||
[STATE_SESSION_RECORDING_STARTED]: this.intl.t('states.recording'),
|
||||
[STATE_SESSION_RECORDING_UNKNOWN]: this.intl.t('states.failed'),
|
||||
};
|
||||
return String(stateMap[recordA.attributes.state]).localeCompare(
|
||||
String(stateMap[recordB.attributes.state]),
|
||||
);
|
||||
};
|
||||
|
||||
retrieveData = restartableTask(
|
||||
async ({
|
||||
search,
|
||||
@@ -105,15 +122,16 @@ export default class ScopesScopeSessionRecordingsIndexRoute extends Route {
|
||||
filters['create_time_values.target.id'].push({ equals: target });
|
||||
});
|
||||
|
||||
const sort =
|
||||
sortAttribute === 'state'
|
||||
? { sortFunction: this.sortState, direction: sortDirection }
|
||||
: { attribute: sortAttribute, direction: sortDirection };
|
||||
|
||||
if (
|
||||
this.can.can('list scope', scope, {
|
||||
collection: 'session-recordings',
|
||||
})
|
||||
) {
|
||||
const sort = {
|
||||
attribute: sortAttribute,
|
||||
direction: sortDirection,
|
||||
};
|
||||
const queryOptions = {
|
||||
scope_id,
|
||||
recursive: true,
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
|
||||
import Route from '@ember/routing/route';
|
||||
import { service } from '@ember/service';
|
||||
import { restartableTask, timeout } from 'ember-concurrency';
|
||||
import {
|
||||
STATUS_SESSION_ACTIVE,
|
||||
STATUS_SESSION_PENDING,
|
||||
} from 'api/models/session';
|
||||
import { restartableTask, timeout } from 'ember-concurrency';
|
||||
import { TYPE_TARGET_SSH, TYPE_TARGET_TCP } from 'api/models/target';
|
||||
|
||||
export default class ScopesScopeTargetsIndexRoute extends Route {
|
||||
// =services
|
||||
@@ -17,6 +18,7 @@ export default class ScopesScopeTargetsIndexRoute extends Route {
|
||||
@service can;
|
||||
@service store;
|
||||
@service session;
|
||||
@service intl;
|
||||
|
||||
// =attributes
|
||||
|
||||
@@ -62,6 +64,16 @@ export default class ScopesScopeTargetsIndexRoute extends Route {
|
||||
return this.retrieveData.perform({ ...params, useDebounce });
|
||||
}
|
||||
|
||||
sortType = (recordA, recordB) => {
|
||||
const typeMap = {
|
||||
[TYPE_TARGET_SSH]: this.intl.t('resources.target.types.ssh'),
|
||||
[TYPE_TARGET_TCP]: this.intl.t('resources.target.types.tcp'),
|
||||
};
|
||||
return String(typeMap[recordA.attributes.type]).localeCompare(
|
||||
String(typeMap[recordB.attributes.type]),
|
||||
);
|
||||
};
|
||||
|
||||
retrieveData = restartableTask(
|
||||
async ({
|
||||
search,
|
||||
@@ -105,14 +117,15 @@ export default class ScopesScopeTargetsIndexRoute extends Route {
|
||||
this.addActiveSessionFilters(filters, availableSessions, sessions);
|
||||
}
|
||||
|
||||
const sort =
|
||||
sortAttribute === 'type'
|
||||
? { sortFunction: this.sortType, direction: sortDirection }
|
||||
: { attribute: sortAttribute, direction: sortDirection };
|
||||
|
||||
let targets;
|
||||
let totalItems = 0;
|
||||
let doTargetsExist = false;
|
||||
if (this.can.can('list model', scope, { collection: 'targets' })) {
|
||||
const sort = {
|
||||
attribute: sortAttribute,
|
||||
direction: sortDirection,
|
||||
};
|
||||
targets = await this.store.query('target', {
|
||||
scope_id,
|
||||
query: { search, filters, sort },
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import Route from '@ember/routing/route';
|
||||
import { service } from '@ember/service';
|
||||
import { restartableTask, timeout } from 'ember-concurrency';
|
||||
import { sortNameWithIdFallback } from 'admin/utils/sort-name-with-id-fallback';
|
||||
|
||||
export default class ScopesScopeUsersIndexRoute extends Route {
|
||||
// =attributes
|
||||
@@ -68,10 +69,10 @@ export default class ScopesScopeUsersIndexRoute extends Route {
|
||||
scope_id: [{ equals: scope_id }],
|
||||
};
|
||||
|
||||
const sort = {
|
||||
attribute: sortAttribute,
|
||||
direction: sortDirection,
|
||||
};
|
||||
const sort =
|
||||
sortAttribute === 'name'
|
||||
? { sortFunction: sortNameWithIdFallback, direction: sortDirection }
|
||||
: { attribute: sortAttribute, direction: sortDirection };
|
||||
|
||||
let users;
|
||||
let totalItems = 0;
|
||||
|
||||
@@ -59,9 +59,10 @@
|
||||
>
|
||||
{{t 'form.name.label'}}
|
||||
</H.ThSort>
|
||||
<H.Th>
|
||||
{{t 'resources.role.titles.grants-applied'}}
|
||||
</H.Th>
|
||||
<H.ThSort
|
||||
@onClickSort={{fn H.setSortBy 'grant_scope_ids'}}
|
||||
@sortOrder={{if (eq 'grant_scope_ids' H.sortBy) H.sortOrder}}
|
||||
>{{t 'resources.role.titles.grants-applied'}}</H.ThSort>
|
||||
<H.ThSort
|
||||
@onClickSort={{fn H.setSortBy 'id'}}
|
||||
@sortOrder={{if (eq 'id' H.sortBy) H.sortOrder}}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
export function sortNameWithIdFallback(recordA, recordB) {
|
||||
let a = recordA.attributes.name;
|
||||
let b = recordB.attributes.name;
|
||||
a = a ? a : recordA.id;
|
||||
b = b ? b : recordB.id;
|
||||
return String(a).localeCompare(String(b));
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
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 { setupIntl } from 'ember-intl/test-support';
|
||||
import { Response } from 'miragejs';
|
||||
import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
import {
|
||||
@@ -32,6 +33,7 @@ module('Acceptance | authentication', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
setupIntl(hooks, 'en-us');
|
||||
|
||||
let indexURL;
|
||||
let globalScope;
|
||||
|
||||
@@ -187,6 +187,14 @@ module('Acceptance | roles | list', function (hooks) {
|
||||
expectedAscendingSort: ['Alpha', 'Beta', 'Delta', 'Epsilon', 'Gamma'],
|
||||
column: 1,
|
||||
},
|
||||
'on grants applied': {
|
||||
attribute: {
|
||||
key: 'grant_scope_ids',
|
||||
values: [[GRANT_SCOPE_THIS], [GRANT_SCOPE_THIS], [], [], []],
|
||||
},
|
||||
expectedAscendingSort: ['No', 'No', 'No', 'Yes', 'Yes'],
|
||||
column: 2,
|
||||
},
|
||||
'on id': {
|
||||
attribute: {
|
||||
key: 'id',
|
||||
|
||||
@@ -8,6 +8,7 @@ import { visit, currentURL, click, fillIn, waitFor } 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 { setupIntl } from 'ember-intl/test-support';
|
||||
import { authenticateSession } from 'ember-simple-auth/test-support';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import * as commonSelectors from 'admin/tests/helpers/selectors';
|
||||
@@ -22,6 +23,7 @@ module('Acceptance | session recordings | list', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
setupIntl(hooks, 'en-us');
|
||||
|
||||
const CREATED_TIME_VALUES_ARRAY = [
|
||||
'2020-01-01T00:00:00.010Z',
|
||||
@@ -288,7 +290,7 @@ module('Acceptance | session recordings | list', function (hooks) {
|
||||
STATE_SESSION_RECORDING_STARTED,
|
||||
],
|
||||
},
|
||||
expectedAscendingSort: ['Completed', 'Recording', 'Failed'],
|
||||
expectedAscendingSort: ['Completed', 'Failed', 'Recording'],
|
||||
column: 2,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -10,6 +10,7 @@ import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
|
||||
import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
import { authenticateSession } from 'ember-simple-auth/test-support';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import { setupIntl } from 'ember-intl/test-support';
|
||||
import * as commonSelectors from 'admin/tests/helpers/selectors';
|
||||
import * as selectors from './selectors';
|
||||
|
||||
@@ -17,6 +18,7 @@ module('Acceptance | session-recordings | read', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
setupIntl(hooks, 'en-us');
|
||||
|
||||
let featuresService;
|
||||
|
||||
|
||||
+2
@@ -11,6 +11,7 @@ import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
import { authenticateSession } from 'ember-simple-auth/test-support';
|
||||
import { Response } from 'miragejs';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import { setupIntl } from 'ember-intl/test-support';
|
||||
import * as commonSelectors from 'admin/tests/helpers/selectors';
|
||||
import * as selectors from '../../selectors';
|
||||
|
||||
@@ -20,6 +21,7 @@ module(
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
setupIntl(hooks, 'en-us');
|
||||
|
||||
let featuresService;
|
||||
let getRecordingCount;
|
||||
|
||||
@@ -11,6 +11,7 @@ import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
import { Response } from 'miragejs';
|
||||
import { authenticateSession } from 'ember-simple-auth/test-support';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import { setupIntl } from 'ember-intl/test-support';
|
||||
import * as commonSelectors from 'admin/tests/helpers/selectors';
|
||||
|
||||
import { TYPE_TARGET_TCP, TYPE_TARGET_SSH } from 'api/models/target';
|
||||
@@ -19,6 +20,7 @@ module('Acceptance | targets | create-alias', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
setupIntl(hooks, 'en-us');
|
||||
|
||||
let getAliasCount;
|
||||
let featuresService;
|
||||
|
||||
@@ -17,6 +17,7 @@ import { Response } from 'miragejs';
|
||||
import { authenticateSession } from 'ember-simple-auth/test-support';
|
||||
import { TYPE_TARGET_TCP, TYPE_TARGET_SSH } from 'api/models/target';
|
||||
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
|
||||
import { setupIntl } from 'ember-intl/test-support';
|
||||
import * as commonSelectors from 'admin/tests/helpers/selectors';
|
||||
import * as selectors from './selectors';
|
||||
|
||||
@@ -24,6 +25,7 @@ module('Acceptance | targets | create', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
setupIntl(hooks, 'en-us');
|
||||
|
||||
let getTargetCount;
|
||||
let getTCPTargetCount;
|
||||
|
||||
@@ -8,6 +8,7 @@ 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 { setupIntl } from 'ember-intl/test-support';
|
||||
import { Response } from 'miragejs';
|
||||
import { authenticateSession } from 'ember-simple-auth/test-support';
|
||||
import * as commonSelectors from 'admin/tests/helpers/selectors';
|
||||
@@ -17,6 +18,7 @@ module('Acceptance | targets | delete', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
setupIntl(hooks, 'en-us');
|
||||
|
||||
let getTargetCount;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
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 { setupIntl } from 'ember-intl/test-support';
|
||||
import { authenticateSession } from 'ember-simple-auth/test-support';
|
||||
import { TYPE_TARGET_TCP, TYPE_TARGET_SSH } from 'api/models/target';
|
||||
import { STATUS_SESSION_ACTIVE } from 'api/models/session';
|
||||
@@ -26,6 +27,7 @@ module('Acceptance | targets | list', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
setupIntl(hooks, 'en-us');
|
||||
|
||||
const NAME_VALUES_ARRAY = ['Alpha', 'Beta', 'Delta', 'Epsilon', 'Gamma'];
|
||||
const ID_VALUES_ARRAY = ['i_0001', 'i_0010', 'i_0100', 'i_1000', 'i_10000'];
|
||||
@@ -307,7 +309,7 @@ module('Acceptance | targets | list', function (hooks) {
|
||||
key: 'type',
|
||||
values: [TYPE_TARGET_SSH, TYPE_TARGET_TCP, TYPE_TARGET_SSH],
|
||||
},
|
||||
expectedAscendingSort: ['SSH', 'SSH', 'Generic TCP'],
|
||||
expectedAscendingSort: ['Generic TCP', 'SSH', 'SSH'],
|
||||
column: 2,
|
||||
},
|
||||
'on id': {
|
||||
|
||||
@@ -8,6 +8,7 @@ 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 { setupIntl } from 'ember-intl/test-support';
|
||||
import a11yAudit from 'ember-a11y-testing/test-support/audit';
|
||||
import { authenticateSession } from 'ember-simple-auth/test-support';
|
||||
import { TYPE_TARGET_TCP, TYPE_TARGET_SSH } from 'api/models/target';
|
||||
@@ -18,6 +19,7 @@ module('Acceptance | targets | read', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
setupIntl(hooks, 'en-us');
|
||||
|
||||
let featuresService;
|
||||
let aliasResource;
|
||||
|
||||
@@ -8,6 +8,7 @@ import { visit, currentURL, click, fillIn } 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 { setupIntl } from 'ember-intl/test-support';
|
||||
import { Response } from 'miragejs';
|
||||
import { authenticateSession } from 'ember-simple-auth/test-support';
|
||||
import * as commonSelectors from 'admin/tests/helpers/selectors';
|
||||
@@ -17,6 +18,7 @@ module('Acceptance | targets | update', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
setupMirage(hooks);
|
||||
setupIndexedDb(hooks);
|
||||
setupIntl(hooks, 'en-us');
|
||||
|
||||
let featuresService;
|
||||
|
||||
|
||||
@@ -5,11 +5,13 @@
|
||||
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'admin/tests/helpers';
|
||||
import { setupIntl } from 'ember-intl/test-support';
|
||||
|
||||
module(
|
||||
'Unit | Route | scopes/scope/session-recordings/index',
|
||||
function (hooks) {
|
||||
setupTest(hooks);
|
||||
setupIntl(hooks, 'en-us');
|
||||
|
||||
test('it exists', function (assert) {
|
||||
let route = this.owner.lookup(
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import { setupIntl } from 'ember-intl/test-support';
|
||||
|
||||
module('Unit | Route | scopes/scope/targets/index', function (hooks) {
|
||||
setupTest(hooks);
|
||||
setupIntl(hooks, 'en-us');
|
||||
|
||||
test('it exists', function (assert) {
|
||||
let route = this.owner.lookup('route:scopes/scope/targets/index');
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { sortNameWithIdFallback } from 'admin/utils/sort-name-with-id-fallback';
|
||||
import { module, test } from 'qunit';
|
||||
|
||||
function createMockRecord(id, attributes = {}) {
|
||||
return {
|
||||
id,
|
||||
attributes,
|
||||
};
|
||||
}
|
||||
|
||||
module('Unit | Utility | sort-name-with-id-fallback', function () {
|
||||
test.each(
|
||||
'sort on name with id fallback',
|
||||
[
|
||||
{
|
||||
recordA: createMockRecord('id_01'),
|
||||
recordB: createMockRecord('id_01'),
|
||||
expectedResult: 0,
|
||||
},
|
||||
{
|
||||
recordA: createMockRecord('id_02'),
|
||||
recordB: createMockRecord('id_01'),
|
||||
expectedResult: 1,
|
||||
},
|
||||
{
|
||||
recordA: createMockRecord('id_01'),
|
||||
recordB: createMockRecord('id_02'),
|
||||
expectedResult: -1,
|
||||
},
|
||||
{
|
||||
recordA: createMockRecord('id_01', { name: 'Alpha' }),
|
||||
recordB: createMockRecord('id_02'),
|
||||
expectedResult: -1,
|
||||
},
|
||||
{
|
||||
recordA: createMockRecord('id_01'),
|
||||
recordB: createMockRecord('id_02', { name: 'Alpha' }),
|
||||
expectedResult: 1,
|
||||
},
|
||||
{
|
||||
recordA: createMockRecord('id_01', { name: 'Alpha' }),
|
||||
recordB: createMockRecord('id_02', { name: 'Beta' }),
|
||||
expectedResult: -1,
|
||||
},
|
||||
{
|
||||
recordA: createMockRecord('id_01', { name: 'Beta' }),
|
||||
recordB: createMockRecord('id_02', { name: 'Alpha' }),
|
||||
expectedResult: 1,
|
||||
},
|
||||
{
|
||||
recordA: createMockRecord('id_01', { name: 'Alpha' }),
|
||||
recordB: createMockRecord('id_02', { name: 'Alpha' }),
|
||||
expectedResult: 0,
|
||||
},
|
||||
],
|
||||
function (assert, input) {
|
||||
const result = sortNameWithIdFallback(input.recordA, input.recordB);
|
||||
|
||||
assert.strictEqual(result, input.expectedResult);
|
||||
},
|
||||
);
|
||||
});
|
||||
Reference in new issue
Block a user