Add sorting foundation as util and using it within indexed-db-handler (#2773)
This commit is contained in:
1 parent
e96131a933
commit
b0d26fe1e6
5 files changed
+594
-26
No files matched your search
@@ -0,0 +1,424 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { assert, module, test } from 'qunit';
|
||||
import { sortResults } from 'api/utils/sort-results';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
function createJsonApiMockRecord(id, type, attributes) {
|
||||
return {
|
||||
id,
|
||||
type,
|
||||
attributes,
|
||||
};
|
||||
}
|
||||
|
||||
module('Unit | Utility | sortResults', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
module('Defaults', function () {
|
||||
test("throws an error when an attribute is not id, created_time or defined as a schema attribute, even when it exists on the record's attribute object", function (assert) {
|
||||
const result01 = createJsonApiMockRecord('id_01', 'target', {
|
||||
name: 'Result 01',
|
||||
});
|
||||
const result02 = createJsonApiMockRecord('id_02', 'target', {
|
||||
name: 'Result 02',
|
||||
});
|
||||
const result03 = createJsonApiMockRecord('id_03', 'target', {
|
||||
name: 'Result 03',
|
||||
});
|
||||
|
||||
const shuffledResults = faker.helpers.shuffle([
|
||||
result01,
|
||||
result02,
|
||||
result03,
|
||||
]);
|
||||
|
||||
const querySort = { attribute: 'name' };
|
||||
|
||||
// Note: `name` is not defined as a schema attribute but exists on the record
|
||||
const schema = { attributes: new Map() };
|
||||
schema.attributes.set('date', { type: 'date' });
|
||||
|
||||
assert.throws(
|
||||
() => sortResults(shuffledResults, { querySort, schema }),
|
||||
/Error: The attribute "name" does not map to the model definition of type "target". Supported sortable attributes are 'id', 'created_time', or 'date'/,
|
||||
);
|
||||
});
|
||||
|
||||
test('throws an error when results do not contain a valid sort direction', function (assert) {
|
||||
const result01 = createJsonApiMockRecord('id_01', 'target', {
|
||||
name: 'Result 01',
|
||||
});
|
||||
|
||||
const querySort = {
|
||||
attribute: 'name',
|
||||
direction: 'invalid sort direction',
|
||||
};
|
||||
const schema = { attributes: new Map() };
|
||||
schema.attributes.set('name', { type: 'string' });
|
||||
assert.throws(
|
||||
() => sortResults([result01], { querySort, schema }),
|
||||
/Error: Invalid sort direction/,
|
||||
);
|
||||
});
|
||||
|
||||
test('when passing no querySort, sorts using default created_time, descending order and string sorting', async function (assert) {
|
||||
const result01 = createJsonApiMockRecord('id_01', 'target', {
|
||||
created_time: '2021',
|
||||
});
|
||||
const result02 = createJsonApiMockRecord('id_02', 'target', {
|
||||
created_time: '2022',
|
||||
});
|
||||
const result03 = createJsonApiMockRecord('id_03', 'target', {
|
||||
created_time: '2023',
|
||||
});
|
||||
const result04 = createJsonApiMockRecord('id_04', 'target', {
|
||||
created_time: '2024',
|
||||
});
|
||||
|
||||
const shuffledResults = faker.helpers.shuffle([
|
||||
result01,
|
||||
result02,
|
||||
result03,
|
||||
result04,
|
||||
]);
|
||||
const querySort = {};
|
||||
const schema = { attributes: new Map() };
|
||||
schema.attributes.set('created_time', { type: 'string' });
|
||||
const sortedResults = sortResults(shuffledResults, {
|
||||
querySort,
|
||||
schema,
|
||||
});
|
||||
assert.deepEqual(
|
||||
sortedResults.map(({ attributes: { created_time } }) => created_time),
|
||||
['2024', '2023', '2022', '2021'],
|
||||
);
|
||||
});
|
||||
|
||||
test('when sorting by id, without being on the results attributes it sorts as expected ', function () {
|
||||
const result01 = createJsonApiMockRecord('id_01', 'target', {
|
||||
name: 'Result 01',
|
||||
});
|
||||
const result02 = createJsonApiMockRecord('id_02', 'target', {
|
||||
name: 'Result 02',
|
||||
});
|
||||
const result03 = createJsonApiMockRecord('id_03', 'target', {
|
||||
name: 'Result 03',
|
||||
});
|
||||
const result04 = createJsonApiMockRecord('id_04', 'target', {
|
||||
name: 'Result 04',
|
||||
});
|
||||
|
||||
const shuffledResults = faker.helpers.shuffle([
|
||||
result01,
|
||||
result02,
|
||||
result03,
|
||||
result04,
|
||||
]);
|
||||
const querySort = { attribute: 'id' };
|
||||
const schema = { attributes: new Map() };
|
||||
schema.attributes.set('id', { type: 'string' });
|
||||
const sortedResults = sortResults(shuffledResults, { querySort, schema });
|
||||
|
||||
assert.deepEqual(
|
||||
sortedResults.map(({ id }) => id),
|
||||
['id_01', 'id_02', 'id_03', 'id_04'],
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
module('string sorting', function () {
|
||||
test('it sorts by ascending (default) `name` using string sorting', async function (assert) {
|
||||
const result01 = createJsonApiMockRecord('id_01', 'target', {
|
||||
name: 'Result 01',
|
||||
});
|
||||
const result02 = createJsonApiMockRecord('id_02', 'target', {
|
||||
name: 'Result 02',
|
||||
});
|
||||
const result03 = createJsonApiMockRecord('id_03', 'target', {
|
||||
name: 'Result 03',
|
||||
});
|
||||
const result04 = createJsonApiMockRecord('id_04', 'target', {
|
||||
name: 'Result 04',
|
||||
});
|
||||
|
||||
const shuffledResults = faker.helpers.shuffle([
|
||||
result01,
|
||||
result02,
|
||||
result03,
|
||||
result04,
|
||||
]);
|
||||
const querySort = { attribute: 'name' };
|
||||
const schema = { attributes: new Map() };
|
||||
schema.attributes.set('name', { type: 'string' });
|
||||
const sortedResults = sortResults(shuffledResults, { querySort, schema });
|
||||
assert.deepEqual(
|
||||
sortedResults.map(({ attributes: { name } }) => name),
|
||||
['Result 01', 'Result 02', 'Result 03', 'Result 04'],
|
||||
);
|
||||
});
|
||||
|
||||
test('it sorts by ascending then descending `name` using string sorting', async function (assert) {
|
||||
const result01 = createJsonApiMockRecord('id_01', 'target', {
|
||||
name: 'Result 01',
|
||||
});
|
||||
const result02 = createJsonApiMockRecord('id_02', 'target', {
|
||||
name: 'Result 02',
|
||||
});
|
||||
const result03 = createJsonApiMockRecord('id_03', 'target', {
|
||||
name: 'Result 03',
|
||||
});
|
||||
const result04 = createJsonApiMockRecord('id_04', 'target', {
|
||||
name: 'Result 04',
|
||||
});
|
||||
|
||||
const shuffledResults = faker.helpers.shuffle([
|
||||
result01,
|
||||
result02,
|
||||
result03,
|
||||
result04,
|
||||
]);
|
||||
const querySortAsc = { attribute: 'name', direction: 'asc' };
|
||||
const querySortDesc = { attribute: 'name', direction: 'desc' };
|
||||
const schema = { attributes: new Map() };
|
||||
schema.attributes.set('name', { type: 'string' });
|
||||
const sortedResultsAsc = sortResults(shuffledResults, {
|
||||
querySort: querySortAsc,
|
||||
schema,
|
||||
});
|
||||
const sortedResultsDesc = sortResults(shuffledResults, {
|
||||
querySort: querySortDesc,
|
||||
schema,
|
||||
});
|
||||
assert.deepEqual(
|
||||
sortedResultsAsc.map(({ attributes: { name } }) => name),
|
||||
['Result 01', 'Result 02', 'Result 03', 'Result 04'],
|
||||
);
|
||||
assert.deepEqual(
|
||||
sortedResultsDesc.map(({ attributes: { name } }) => name),
|
||||
['Result 04', 'Result 03', 'Result 02', 'Result 01'],
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
module('date sorting', function () {
|
||||
test('it sorts by ascending (default) `date` using date sorting', function (assert) {
|
||||
const result01 = createJsonApiMockRecord('id_01', 'target', {
|
||||
date: '2021',
|
||||
});
|
||||
const result02 = createJsonApiMockRecord('id_02', 'target', {
|
||||
date: '2022',
|
||||
});
|
||||
const result03 = createJsonApiMockRecord('id_03', 'target', {
|
||||
date: '2023',
|
||||
});
|
||||
const result04 = createJsonApiMockRecord('id_04', 'target', {
|
||||
date: '2024',
|
||||
});
|
||||
|
||||
const shuffledResults = faker.helpers.shuffle([
|
||||
result01,
|
||||
result02,
|
||||
result03,
|
||||
result04,
|
||||
]);
|
||||
const querySort = { attribute: 'date' };
|
||||
const schema = { attributes: new Map() };
|
||||
schema.attributes.set('date', { type: 'date' });
|
||||
|
||||
const sortedResults = sortResults(shuffledResults, { querySort, schema });
|
||||
|
||||
assert.deepEqual(
|
||||
sortedResults.map(({ attributes: { date } }) => date),
|
||||
['2021', '2022', '2023', '2024'],
|
||||
);
|
||||
});
|
||||
|
||||
test('it sorts by ascending then descending `date` using date sorting', function (assert) {
|
||||
const result01 = createJsonApiMockRecord('id_01', 'target', {
|
||||
date: '2021',
|
||||
});
|
||||
const result02 = createJsonApiMockRecord('id_02', 'target', {
|
||||
date: '2022',
|
||||
});
|
||||
const result03 = createJsonApiMockRecord('id_03', 'target', {
|
||||
date: '2023',
|
||||
});
|
||||
const result04 = createJsonApiMockRecord('id_04', 'target', {
|
||||
date: '2024',
|
||||
});
|
||||
|
||||
const shuffledResults = faker.helpers.shuffle([
|
||||
result01,
|
||||
result02,
|
||||
result03,
|
||||
result04,
|
||||
]);
|
||||
const querySortAsc = { attribute: 'date', direction: 'asc' };
|
||||
const querySortDesc = { attribute: 'date', direction: 'desc' };
|
||||
const schema = { attributes: new Map() };
|
||||
schema.attributes.set('date', { type: 'date' });
|
||||
|
||||
const sortedResultsAsc = sortResults(shuffledResults, {
|
||||
querySort: querySortAsc,
|
||||
schema,
|
||||
});
|
||||
const sortedResultsDesc = sortResults(shuffledResults, {
|
||||
querySort: querySortDesc,
|
||||
schema,
|
||||
});
|
||||
|
||||
assert.deepEqual(
|
||||
sortedResultsAsc.map(({ attributes: { date } }) => date),
|
||||
['2021', '2022', '2023', '2024'],
|
||||
);
|
||||
assert.deepEqual(
|
||||
sortedResultsDesc.map(({ attributes: { date } }) => date),
|
||||
['2024', '2023', '2022', '2021'],
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
module('number sorting', function () {
|
||||
test('it sorts by ascending (default) `sessions`', function (assert) {
|
||||
const result01 = createJsonApiMockRecord('id_01', 'target', {
|
||||
sessions: 10,
|
||||
});
|
||||
const result02 = createJsonApiMockRecord('id_01', 'target', {
|
||||
sessions: 200,
|
||||
});
|
||||
const result03 = createJsonApiMockRecord('id_01', 'target', {
|
||||
sessions: 3333,
|
||||
});
|
||||
const result04 = createJsonApiMockRecord('id_01', 'target', {
|
||||
sessions: 40444,
|
||||
});
|
||||
|
||||
const shuffledResults = faker.helpers.shuffle([
|
||||
result01,
|
||||
result02,
|
||||
result03,
|
||||
result04,
|
||||
]);
|
||||
const querySort = { attribute: 'sessions' };
|
||||
const schema = { attributes: new Map() };
|
||||
schema.attributes.set('sessions', { type: 'number' });
|
||||
|
||||
const sortedResults = sortResults(shuffledResults, { querySort, schema });
|
||||
|
||||
assert.deepEqual(
|
||||
sortedResults.map(({ attributes: { sessions } }) => sessions),
|
||||
[10, 200, 3333, 40444],
|
||||
);
|
||||
});
|
||||
|
||||
test('it sorts by ascending then descending `sessions`', function (assert) {
|
||||
const result01 = createJsonApiMockRecord('id_01', 'target', {
|
||||
sessions: 10,
|
||||
});
|
||||
const result02 = createJsonApiMockRecord('id_01', 'target', {
|
||||
sessions: 200,
|
||||
});
|
||||
const result03 = createJsonApiMockRecord('id_01', 'target', {
|
||||
sessions: 3333,
|
||||
});
|
||||
const result04 = createJsonApiMockRecord('id_01', 'target', {
|
||||
sessions: 40444,
|
||||
});
|
||||
|
||||
const shuffledResults = faker.helpers.shuffle([
|
||||
result01,
|
||||
result02,
|
||||
result03,
|
||||
result04,
|
||||
]);
|
||||
const querySortAsc = { attribute: 'sessions', direction: 'asc' };
|
||||
const querySortDesc = { attribute: 'sessions', direction: 'desc' };
|
||||
const schema = { attributes: new Map() };
|
||||
schema.attributes.set('sessions', { type: 'number' });
|
||||
|
||||
const sortedResultsAsc = sortResults(shuffledResults, {
|
||||
querySort: querySortAsc,
|
||||
schema,
|
||||
});
|
||||
const sortedResultsDesc = sortResults(shuffledResults, {
|
||||
querySort: querySortDesc,
|
||||
schema,
|
||||
});
|
||||
|
||||
assert.deepEqual(
|
||||
sortedResultsAsc.map(({ attributes: { sessions } }) => sessions),
|
||||
[10, 200, 3333, 40444],
|
||||
);
|
||||
assert.deepEqual(
|
||||
sortedResultsDesc.map(({ attributes: { sessions } }) => sessions),
|
||||
[40444, 3333, 200, 10],
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
module('boolean sorting', function () {
|
||||
test('it sorts by ascending (default) `active`', function (assert) {
|
||||
const result01 = { attributes: { active: true } };
|
||||
const result02 = { attributes: { active: false } };
|
||||
const result03 = { attributes: { active: false } };
|
||||
const result04 = { attributes: { active: true } };
|
||||
const shuffledResults = faker.helpers.shuffle([
|
||||
result01,
|
||||
result02,
|
||||
result03,
|
||||
result04,
|
||||
]);
|
||||
const querySort = { attribute: 'active' };
|
||||
const schema = { attributes: new Map() };
|
||||
schema.attributes.set('active', { type: 'boolean' });
|
||||
|
||||
const sortedResults = sortResults(shuffledResults, { querySort, schema });
|
||||
|
||||
assert.deepEqual(
|
||||
sortedResults.map(({ attributes: { active } }) => active),
|
||||
[false, false, true, true],
|
||||
);
|
||||
});
|
||||
|
||||
test('it sorts by ascending then descending `active`', function (assert) {
|
||||
const result01 = { attributes: { active: true } };
|
||||
const result02 = { attributes: { active: false } };
|
||||
const result03 = { attributes: { active: false } };
|
||||
const result04 = { attributes: { active: true } };
|
||||
const shuffledResults = faker.helpers.shuffle([
|
||||
result01,
|
||||
result02,
|
||||
result03,
|
||||
result04,
|
||||
]);
|
||||
const querySortAsc = { attribute: 'active', direction: 'asc' };
|
||||
const querySortDesc = { attribute: 'active', direction: 'desc' };
|
||||
const schema = { attributes: new Map() };
|
||||
schema.attributes.set('active', { type: 'boolean' });
|
||||
|
||||
const sortedResultsAsc = sortResults(shuffledResults, {
|
||||
querySort: querySortAsc,
|
||||
schema,
|
||||
});
|
||||
const sortedResultsDesc = sortResults(shuffledResults, {
|
||||
querySort: querySortDesc,
|
||||
schema,
|
||||
});
|
||||
|
||||
assert.deepEqual(
|
||||
sortedResultsAsc.map(({ attributes: { active } }) => active),
|
||||
[false, false, true, true],
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
sortedResultsDesc.map(({ attributes: { active } }) => active),
|
||||
[true, true, false, false],
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user