Experimental filters: add unit tests for left operands and container state (#4053)
This commit is contained in:
parent
ae813a406e
commit
504cfaac6e
5 changed files with 260 additions and 56 deletions
5
.changeset/violet-planes-nail.md
Normal file
5
.changeset/violet-planes-nail.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"saleor-dashboard": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Experimental filters: add unit tests for left operands and container state
|
|
@ -4,37 +4,6 @@ import { ConditionSelected } from "./FilterElement/ConditionSelected";
|
||||||
import { ExpressionValue } from "./FilterElement/FilterElement";
|
import { ExpressionValue } from "./FilterElement/FilterElement";
|
||||||
import { createProductQueryVariables } from "./queryVariables";
|
import { createProductQueryVariables } from "./queryVariables";
|
||||||
|
|
||||||
const createConditionValue = (
|
|
||||||
label: string,
|
|
||||||
slug: string,
|
|
||||||
value: string,
|
|
||||||
originalSlug?: string,
|
|
||||||
) => ({
|
|
||||||
label,
|
|
||||||
slug,
|
|
||||||
value,
|
|
||||||
originalSlug,
|
|
||||||
});
|
|
||||||
const createConditionItem = (type: string, value: string, label: string) => ({
|
|
||||||
type,
|
|
||||||
value,
|
|
||||||
label,
|
|
||||||
});
|
|
||||||
|
|
||||||
const createConditionOptions = (
|
|
||||||
label: string,
|
|
||||||
slug: string,
|
|
||||||
value: string,
|
|
||||||
originalSlug: string,
|
|
||||||
) => [
|
|
||||||
{
|
|
||||||
label,
|
|
||||||
slug,
|
|
||||||
value,
|
|
||||||
originalSlug,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
describe("ConditionalFilter / queryVariables / createProductQueryVariables", () => {
|
describe("ConditionalFilter / queryVariables / createProductQueryVariables", () => {
|
||||||
it("should return empty variables for empty filters", () => {
|
it("should return empty variables for empty filters", () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
|
@ -56,8 +25,8 @@ describe("ConditionalFilter / queryVariables / createProductQueryVariables", ()
|
||||||
new Condition(
|
new Condition(
|
||||||
ConditionOptions.fromStaticElementName("price"),
|
ConditionOptions.fromStaticElementName("price"),
|
||||||
new ConditionSelected(
|
new ConditionSelected(
|
||||||
createConditionValue("price", "price", "123"),
|
{ label: "price", slug: "price", value: "123" },
|
||||||
createConditionItem("price", "123", "Price"),
|
{ type: "price", value: "123", label: "Price" },
|
||||||
[],
|
[],
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
|
@ -71,19 +40,25 @@ describe("ConditionalFilter / queryVariables / createProductQueryVariables", ()
|
||||||
new Condition(
|
new Condition(
|
||||||
ConditionOptions.fromAttributeType("DROPDOWN"),
|
ConditionOptions.fromAttributeType("DROPDOWN"),
|
||||||
new ConditionSelected(
|
new ConditionSelected(
|
||||||
createConditionValue(
|
{
|
||||||
"bottle-size",
|
label: "bottle-size",
|
||||||
"bottle-id",
|
slug: "bottle-id",
|
||||||
"bottle-id",
|
value: "bottle-id",
|
||||||
"0-5l",
|
originalSlug: "0-5l",
|
||||||
),
|
},
|
||||||
createConditionItem("DROPDOWN", "bottle-id", "Bottle size"),
|
{
|
||||||
createConditionOptions(
|
type: "DROPDOWN",
|
||||||
"bottle-size",
|
value: "bottle-id",
|
||||||
"bottle-id",
|
label: "Bottle size",
|
||||||
"bottle-id",
|
},
|
||||||
"0-5l",
|
[
|
||||||
),
|
{
|
||||||
|
label: "bottle-size",
|
||||||
|
slug: "bottle-id",
|
||||||
|
value: "bottle-id",
|
||||||
|
originalSlug: "0-5l",
|
||||||
|
},
|
||||||
|
],
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
false,
|
false,
|
||||||
|
|
166
src/components/ConditionalFilter/useContainerState.test.ts
Normal file
166
src/components/ConditionalFilter/useContainerState.test.ts
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
import { act, renderHook } from "@testing-library/react-hooks";
|
||||||
|
|
||||||
|
import { Condition, FilterElement } from "./FilterElement";
|
||||||
|
import { ConditionOptions } from "./FilterElement/ConditionOptions";
|
||||||
|
import { ConditionSelected } from "./FilterElement/ConditionSelected";
|
||||||
|
import { ExpressionValue } from "./FilterElement/FilterElement";
|
||||||
|
import { FilterValueProvider } from "./FilterValueProvider";
|
||||||
|
import { useContainerState } from "./useContainerState";
|
||||||
|
|
||||||
|
describe("useContainerState", () => {
|
||||||
|
const valueProvider: FilterValueProvider = {
|
||||||
|
loading: false,
|
||||||
|
value: [],
|
||||||
|
persist: () => {},
|
||||||
|
isPersisted: () => true,
|
||||||
|
clear: () => {},
|
||||||
|
count: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
it("should set initial value from value provider", () => {
|
||||||
|
// Act
|
||||||
|
const { result } = renderHook(() => useContainerState(valueProvider));
|
||||||
|
// Assert
|
||||||
|
expect(result.current.value).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should create new empty row", () => {
|
||||||
|
// Arrange
|
||||||
|
const { result } = renderHook(() => useContainerState(valueProvider));
|
||||||
|
// Act
|
||||||
|
act(() => {
|
||||||
|
result.current.createEmpty();
|
||||||
|
});
|
||||||
|
// Assert
|
||||||
|
expect(result.current.value).toEqual([FilterElement.createEmpty()]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should add new row", () => {
|
||||||
|
// Arrange
|
||||||
|
const { result } = renderHook(() => useContainerState(valueProvider));
|
||||||
|
const staticPriceElement = new FilterElement(
|
||||||
|
new ExpressionValue("price", "Price", "price"),
|
||||||
|
new Condition(
|
||||||
|
ConditionOptions.fromStaticElementName("price"),
|
||||||
|
new ConditionSelected(
|
||||||
|
{ label: "price", slug: "price", value: "123" },
|
||||||
|
{ type: "price", value: "123", label: "Price" },
|
||||||
|
[],
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
// Act
|
||||||
|
act(() => {
|
||||||
|
result.current.createEmpty();
|
||||||
|
});
|
||||||
|
act(() => {
|
||||||
|
result.current.create(staticPriceElement);
|
||||||
|
});
|
||||||
|
// Assert
|
||||||
|
expect(result.current.value).toEqual([
|
||||||
|
FilterElement.createEmpty(),
|
||||||
|
"AND",
|
||||||
|
staticPriceElement,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should update row", () => {
|
||||||
|
// Arrange
|
||||||
|
const { result } = renderHook(() => useContainerState(valueProvider));
|
||||||
|
const staticPriceElement = new FilterElement(
|
||||||
|
new ExpressionValue("price", "Price", "price"),
|
||||||
|
new Condition(
|
||||||
|
ConditionOptions.fromStaticElementName("price"),
|
||||||
|
new ConditionSelected(
|
||||||
|
{ label: "price", slug: "price", value: "123" },
|
||||||
|
{ type: "price", value: "123", label: "Price" },
|
||||||
|
[],
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
// Act
|
||||||
|
act(() => {
|
||||||
|
result.current.create(staticPriceElement);
|
||||||
|
});
|
||||||
|
act(() => {
|
||||||
|
result.current.updateAt("0", el => {
|
||||||
|
el.updateLeftOperator({
|
||||||
|
type: "category",
|
||||||
|
label: "Category",
|
||||||
|
slug: "category",
|
||||||
|
value: "category",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// Assert
|
||||||
|
expect(result.current.value).toEqual([staticPriceElement]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should remove row", () => {
|
||||||
|
// Arrange
|
||||||
|
const { result } = renderHook(() => useContainerState(valueProvider));
|
||||||
|
const staticPriceElement = new FilterElement(
|
||||||
|
new ExpressionValue("price", "Price", "price"),
|
||||||
|
new Condition(
|
||||||
|
ConditionOptions.fromStaticElementName("price"),
|
||||||
|
new ConditionSelected(
|
||||||
|
{ label: "price", slug: "price", value: "123" },
|
||||||
|
{ type: "price", value: "123", label: "Price" },
|
||||||
|
[],
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
// Act
|
||||||
|
act(() => {
|
||||||
|
result.current.createEmpty();
|
||||||
|
});
|
||||||
|
act(() => {
|
||||||
|
result.current.create(staticPriceElement);
|
||||||
|
});
|
||||||
|
act(() => {
|
||||||
|
result.current.removeAt("0");
|
||||||
|
});
|
||||||
|
// Assert
|
||||||
|
expect(result.current.value).toEqual([staticPriceElement]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should clear not filled rows", () => {
|
||||||
|
// Arrange
|
||||||
|
const { result } = renderHook(() => useContainerState(valueProvider));
|
||||||
|
const staticPriceElement = new FilterElement(
|
||||||
|
new ExpressionValue("price", "Price", "price"),
|
||||||
|
new Condition(
|
||||||
|
ConditionOptions.fromStaticElementName("price"),
|
||||||
|
new ConditionSelected(
|
||||||
|
{ label: "price", slug: "price", value: "123" },
|
||||||
|
{ type: "price", value: "123", label: "Price" },
|
||||||
|
[],
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
// Act
|
||||||
|
act(() => {
|
||||||
|
result.current.createEmpty();
|
||||||
|
});
|
||||||
|
act(() => {
|
||||||
|
result.current.create(staticPriceElement);
|
||||||
|
});
|
||||||
|
act(() => {
|
||||||
|
result.current.clearEmpty();
|
||||||
|
});
|
||||||
|
// Assert
|
||||||
|
expect(result.current.value).toEqual([staticPriceElement]);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,44 @@
|
||||||
|
import { AttributeInputTypeEnum } from "@dashboard/graphql";
|
||||||
|
import { act,renderHook } from "@testing-library/react-hooks";
|
||||||
|
|
||||||
|
import { STATIC_OPTIONS } from "./constants";
|
||||||
|
import { useFilterLeftOperandsProvider } from "./useFilterLeftOperands";
|
||||||
|
|
||||||
|
describe("useFilterLeftOperandsProvider", () => {
|
||||||
|
it("should set unique operands", () => {
|
||||||
|
// Arrange
|
||||||
|
const { result } = renderHook(() => useFilterLeftOperandsProvider());
|
||||||
|
// Act
|
||||||
|
act(() => {
|
||||||
|
result.current.setOperands([
|
||||||
|
{
|
||||||
|
label: "SKU",
|
||||||
|
value: "sku",
|
||||||
|
type: AttributeInputTypeEnum.DROPDOWN,
|
||||||
|
slug: "sku",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
// Assert
|
||||||
|
expect(result.current.operands).toEqual([
|
||||||
|
...STATIC_OPTIONS,
|
||||||
|
{ label: "SKU", value: "sku", type: "DROPDOWN", slug: "sku" },
|
||||||
|
]);
|
||||||
|
// Act
|
||||||
|
act(() => {
|
||||||
|
result.current.setOperands([
|
||||||
|
{
|
||||||
|
label: "SKU",
|
||||||
|
value: "sku",
|
||||||
|
type: AttributeInputTypeEnum.DROPDOWN,
|
||||||
|
slug: "sku",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
// Assert
|
||||||
|
expect(result.current.operands).toEqual([
|
||||||
|
...STATIC_OPTIONS,
|
||||||
|
{ label: "SKU", value: "sku", type: "DROPDOWN", slug: "sku" },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,4 +1,4 @@
|
||||||
import { renderHook } from "@testing-library/react-hooks";
|
import { act, renderHook } from "@testing-library/react-hooks";
|
||||||
|
|
||||||
import { useFilterPresets } from "./useFilterPresets";
|
import { useFilterPresets } from "./useFilterPresets";
|
||||||
|
|
||||||
|
@ -94,7 +94,9 @@ describe("useFilterPresets", () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
act(() => {
|
||||||
result.current.onPresetChange(1);
|
result.current.onPresetChange(1);
|
||||||
|
});
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(mockNavigate).toHaveBeenCalledWith(
|
expect(mockNavigate).toHaveBeenCalledWith(
|
||||||
|
@ -124,9 +126,13 @@ describe("useFilterPresets", () => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Act(
|
// Act
|
||||||
|
act(() => {
|
||||||
result.current.setPresetIdToDelete(1);
|
result.current.setPresetIdToDelete(1);
|
||||||
|
});
|
||||||
|
act(() => {
|
||||||
result.current.onPresetDelete();
|
result.current.onPresetDelete();
|
||||||
|
});
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(mockDeleteStorage).toHaveBeenCalledWith(1);
|
expect(mockDeleteStorage).toHaveBeenCalledWith(1);
|
||||||
|
@ -156,9 +162,13 @@ describe("useFilterPresets", () => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Act(
|
// Act
|
||||||
|
act(() => {
|
||||||
result.current.setPresetIdToDelete(1);
|
result.current.setPresetIdToDelete(1);
|
||||||
|
});
|
||||||
|
act(() => {
|
||||||
result.current.onPresetDelete();
|
result.current.onPresetDelete();
|
||||||
|
});
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(mockDeleteStorage).toHaveBeenCalledWith(1);
|
expect(mockDeleteStorage).toHaveBeenCalledWith(1);
|
||||||
|
@ -186,7 +196,9 @@ describe("useFilterPresets", () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
act(() => {
|
||||||
result.current.onPresetSave({ name: "new-preset" });
|
result.current.onPresetSave({ name: "new-preset" });
|
||||||
|
});
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(mockSaveStorage).toHaveBeenCalledWith("new-preset", "query=John");
|
expect(mockSaveStorage).toHaveBeenCalledWith("new-preset", "query=John");
|
||||||
|
@ -218,7 +230,9 @@ describe("useFilterPresets", () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
act(() => {
|
||||||
result.current.onPresetUpdate("current-preset");
|
result.current.onPresetUpdate("current-preset");
|
||||||
|
});
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(mockUpdateStorage).toHaveBeenCalledWith(
|
expect(mockUpdateStorage).toHaveBeenCalledWith(
|
||||||
|
|
Loading…
Reference in a new issue