@gooddata/react-components
Version:
GoodData.UI - A powerful JavaScript library for building analytical applications
345 lines (324 loc) • 12.7 kB
text/typescript
// (C) 2020 GoodData Corporation
import { AFM } from "@gooddata/typings";
import {
adaptReferencePointSortItemsToPivotTable,
addDefaultSort,
isSortItemVisible,
} from "../sortItemsHelpers";
import * as referencePointMocks from "../../../../mocks/referencePointMocks";
import {
IBucketItem,
IExtendedReferencePoint,
IBucketFilterElement,
IBucketFilter,
} from "../../../../interfaces/Visualization";
import {
invalidAttributeSort,
invalidMeasureSortInvalidMeasure,
invalidMeasureSortInvalidAttribute,
invalidMeasureSortLocatorsTooShort,
invalidMeasureSortTooManyLocators,
validAttributeSort,
validMeasureSort,
partiallyValidMeasureSort,
} from "./sortItemsMock";
import { getMockReferencePoint } from "./testHelper";
describe("adaptReferencePointSortItemsToPivotTable", () => {
const sourceReferencePoint = referencePointMocks.simpleStackedReferencePoint;
const mockPivotTableReferencePoint: IExtendedReferencePoint = getMockReferencePoint(
sourceReferencePoint.buckets[0].items,
sourceReferencePoint.buckets[1].items,
sourceReferencePoint.buckets[2].items,
[],
[],
true,
);
const sourceSortItems: AFM.SortItem[] = [
invalidAttributeSort,
invalidMeasureSortInvalidMeasure,
invalidMeasureSortInvalidAttribute,
invalidMeasureSortLocatorsTooShort,
invalidMeasureSortTooManyLocators,
validAttributeSort,
validMeasureSort,
];
const measures: IBucketItem[] = mockPivotTableReferencePoint.buckets[0].items;
const rowAttributes: IBucketItem[] = mockPivotTableReferencePoint.buckets[1].items;
const columnAttributes: IBucketItem[] = mockPivotTableReferencePoint.buckets[2].items;
it("should remove invalid sort items", async () => {
const expectedSortItems: AFM.SortItem[] = [validAttributeSort, validMeasureSort];
expect(
adaptReferencePointSortItemsToPivotTable(
sourceSortItems,
measures,
rowAttributes,
columnAttributes,
),
).toEqual(expectedSortItems);
});
it("should keep modified measure sort item with column attribute removed", async () => {
const expectedSortItems: AFM.SortItem[] = [validMeasureSort];
expect(
adaptReferencePointSortItemsToPivotTable(
[partiallyValidMeasureSort],
measures,
rowAttributes,
columnAttributes,
),
).toEqual(expectedSortItems);
});
});
describe("addDefaultSort", () => {
const rowFor = (localIdentifier: string, attributeName: string): IBucketItem => ({
aggregation: null,
showInPercent: null,
operator: null,
operandLocalIdentifiers: null,
granularity: null,
masterLocalIdentifier: null,
localIdentifier,
showOnSecondaryAxis: null,
type: "attribute",
filters: [],
attribute: attributeName,
});
const accountRowId = "d0f1043a2eec42daac004a10c41afdd5";
const accountRow = rowFor(accountRowId, "attr.account");
const countryRowId = "6d523113ca754409a8b685736e7fe32b";
const countryRow = rowFor(countryRowId, "attr.country");
const productRowId = "38f1d87b8b7c42c1b9a37395a24f7313";
const productRow = rowFor(productRowId, "attr.product");
const sortFor = (localId: string, direction: AFM.SortDirection): AFM.SortItem => ({
attributeSortItem: {
attributeIdentifier: localId,
direction,
},
});
const defaultSortFor = (localId: string): AFM.SortItem => sortFor(localId, "asc");
describe("with no filters specified", () => {
it("should not add the default sort if no row is specified", () => {
const expected: AFM.SortItem[] = [];
const actual = addDefaultSort([], [], [], []);
expect(actual).toEqual(expected);
});
it("should add the default sort for the first row added", () => {
const expected = [defaultSortFor(accountRowId)];
const actual = addDefaultSort([], [], [accountRow], []);
expect(actual).toEqual(expected);
});
it("should add the default sort when a row is added to the first place", () => {
const expected = [defaultSortFor(accountRowId)];
const actual = addDefaultSort(
[defaultSortFor(countryRowId)],
[],
[accountRow, countryRow],
[countryRow],
);
expect(actual).toEqual(expected);
});
it("should not change the default sort when a row is added to the second place", () => {
const expected = [defaultSortFor(countryRowId)];
const actual = addDefaultSort(
[defaultSortFor(countryRowId)],
[],
[countryRow, accountRow],
[countryRow],
);
expect(actual).toEqual(expected);
});
it("should not change sorts when there is a desc sort on the first item", () => {
const expected = [sortFor(countryRowId, "desc")];
const actual = addDefaultSort(
[sortFor(countryRowId, "desc")],
[],
[countryRow, accountRow],
[countryRow],
);
expect(actual).toEqual(expected);
});
it("should not change sorts when there is a desc sort on the second item", () => {
const expected = [sortFor(countryRowId, "desc")];
const actual = addDefaultSort(
[sortFor(countryRowId, "desc")],
[],
[accountRow, countryRow, productRow],
[accountRow, countryRow],
);
expect(actual).toEqual(expected);
});
it("should not change sorts when there is an asc sort on the second item", () => {
const expected = [sortFor(countryRowId, "asc")];
const actual = addDefaultSort(
[sortFor(countryRowId, "asc")],
[],
[accountRow, countryRow, productRow],
[accountRow, countryRow],
);
expect(actual).toEqual(expected);
});
it("should not change sorts when there is a measure sort", () => {
const measureSort: AFM.IMeasureSortItem = {
measureSortItem: {
direction: "asc",
locators: [],
},
};
const expected = [measureSort];
const actual = addDefaultSort(
[measureSort],
[],
[accountRow, countryRow, productRow],
[accountRow, countryRow],
);
expect(actual).toEqual(expected);
});
});
it("should add default sort if existing measure sort is not visible due to filters (RAIL-1275)", () => {
const expected = [sortFor(accountRowId, "asc")];
const uri = "/gdc/md/mockproject/obj/attr.country/elements?id=1";
const measureSort: AFM.IMeasureSortItem = {
measureSortItem: {
direction: "asc",
locators: [
{
attributeLocatorItem: {
attributeIdentifier: "attr.country",
element: uri,
},
},
],
},
};
const filterElement: IBucketFilterElement = {
title: "Matching",
uri,
};
const actual = addDefaultSort(
[measureSort],
[
{
attribute: "irrelevant",
isInverted: true,
selectedElements: [filterElement],
totalElementsCount: 4,
},
],
[accountRow, countryRow, productRow],
[accountRow, countryRow],
);
expect(actual).toEqual(expected);
});
});
describe("isSortItemVisible", () => {
describe("given attribute sort item", () => {
it("should always return true", () => {
const actual = isSortItemVisible(
{
attributeSortItem: {
attributeIdentifier: "foo",
direction: "asc",
},
},
[],
);
const expected = true;
expect(actual).toEqual(expected);
});
});
describe("given measure sort item", () => {
const createFilterBucketItem = (
selectedElements: IBucketFilterElement[],
isInverted: boolean,
): IBucketFilter => ({
attribute: "irrelevant",
isInverted,
totalElementsCount: 5,
selectedElements,
});
const matchingUri = "/gdc/md/mockproject/obj/attr.movie_genre/elements?id=1";
const notMatchingUri = "/gdc/md/mockproject/obj/attr.movie_genre/elements?id=123";
const sortItem: AFM.IMeasureSortItem = {
measureSortItem: {
direction: "asc",
locators: [
{
attributeLocatorItem: {
attributeIdentifier: "foo",
element: matchingUri,
},
},
{
measureLocatorItem: {
measureIdentifier: "bar",
},
},
],
},
};
const matchingFilterElement: IBucketFilterElement = {
title: "Matching",
uri: matchingUri,
};
const notMatchingFilterElement: IBucketFilterElement = {
title: "Not Matching",
uri: notMatchingUri,
};
const measureValueFilter: IBucketFilter = {
measureLocalIdentifier: "id",
condition: {
range: {
operator: "BETWEEN",
from: 0,
to: 0,
},
},
};
it("should return true when no filters are specified", () => {
const actual = isSortItemVisible(sortItem, []);
const expected = true;
expect(actual).toEqual(expected);
});
it('should return true when empty "notIn" filter is specified', () => {
const actual = isSortItemVisible(sortItem, [createFilterBucketItem([], true)]);
const expected = true;
expect(actual).toEqual(expected);
});
it('should return false when "notIn" filter with matching element is specified', () => {
const actual = isSortItemVisible(sortItem, [
createFilterBucketItem([matchingFilterElement], true),
]);
const expected = false;
expect(actual).toEqual(expected);
});
it('should return true when "notIn" filter without matching element is specified', () => {
const actual = isSortItemVisible(sortItem, [
createFilterBucketItem([notMatchingFilterElement], true),
]);
const expected = true;
expect(actual).toEqual(expected);
});
it('should return false when empty "in" filter is specified', () => {
const actual = isSortItemVisible(sortItem, [createFilterBucketItem([], false)]);
const expected = false;
expect(actual).toEqual(expected);
});
it('should return true when "in" filter with matching element is specified', () => {
const actual = isSortItemVisible(sortItem, [
createFilterBucketItem([matchingFilterElement], false),
]);
const expected = true;
expect(actual).toEqual(expected);
});
it('should return false when "in" filter without matching element is specified', () => {
const actual = isSortItemVisible(sortItem, [
createFilterBucketItem([notMatchingFilterElement], false),
]);
const expected = false;
expect(actual).toEqual(expected);
});
it("should return true when filter is MVF", () => {
const actual = isSortItemVisible(sortItem, [measureValueFilter]);
expect(actual).toEqual(true);
});
});
});