TableSort.spec.tsx 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * Copyright 2021-2024 Avaiga Private Limited
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
  5. * the License. You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
  10. * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
  11. * specific language governing permissions and limitations under the License.
  12. */
  13. import React from "react";
  14. import { getByTitle, render } from "@testing-library/react";
  15. import "@testing-library/jest-dom";
  16. import userEvent from "@testing-library/user-event";
  17. import TableSort from "./TableSort";
  18. import { ColumnDesc } from "./tableUtils";
  19. const tableColumns = {
  20. StringCol: { dfid: "StringCol", type: "object", index: 0, format: "", filter: true },
  21. NumberCol: { dfid: "NumberCol", type: "int", index: 1, format: "", filter: true },
  22. BoolCol: { dfid: "BoolCol", type: "bool", index: 2, format: "", filter: true },
  23. DateCol: { dfid: "DateCol", type: "datetime", index: 3, format: "", filter: true },
  24. } as Record<string, ColumnDesc>;
  25. const colsOrder = ["StringCol", "NumberCol", "BoolCol", "DateCol"];
  26. beforeEach(() => {
  27. // add window.matchMedia
  28. // this is necessary for the date picker to be rendered in desktop mode.
  29. // if this is not provided, the mobile mode is rendered, which might lead to unexpected behavior
  30. Object.defineProperty(window, "matchMedia", {
  31. writable: true,
  32. value: (query: string): MediaQueryList => ({
  33. media: query,
  34. // this is the media query that @material-ui/pickers uses to determine if a device is a desktop device
  35. matches: query === "(pointer: fine)",
  36. onchange: () => {},
  37. addEventListener: () => {},
  38. removeEventListener: () => {},
  39. addListener: () => {},
  40. removeListener: () => {},
  41. dispatchEvent: () => false,
  42. }),
  43. });
  44. });
  45. afterEach(() => {
  46. // @ts-ignore
  47. delete window.matchMedia;
  48. });
  49. describe("Table Filter Component", () => {
  50. it("renders an icon", async () => {
  51. const { getByTestId } = render(
  52. <TableSort columns={tableColumns} colsOrder={colsOrder} onValidate={jest.fn()} />
  53. );
  54. const elt = getByTestId("SortByAlphaIcon");
  55. expect(elt.parentElement?.parentElement?.tagName).toBe("BUTTON");
  56. });
  57. it("renders popover when clicked", async () => {
  58. const { getByTestId, getAllByText, getAllByTestId } = render(
  59. <TableSort columns={tableColumns} colsOrder={colsOrder} onValidate={jest.fn()} />
  60. );
  61. const elt = getByTestId("SortByAlphaIcon");
  62. await userEvent.click(elt);
  63. expect(getAllByText("Column")).toHaveLength(2);
  64. const dropdownElts = getAllByTestId("ArrowDropDownIcon");
  65. expect(dropdownElts).toHaveLength(1);
  66. expect(getByTestId("CheckIcon").parentElement).toBeDisabled();
  67. expect(getByTestId("DeleteIcon").parentElement).toBeDisabled();
  68. });
  69. it("behaves on column", async () => {
  70. const { getByTestId, getAllByTestId, findByRole, getByText } = render(
  71. <TableSort columns={tableColumns} colsOrder={colsOrder} onValidate={jest.fn()} />
  72. );
  73. const elt = getByTestId("SortByAlphaIcon");
  74. await userEvent.click(elt);
  75. const dropdownElts = getAllByTestId("ArrowDropDownIcon");
  76. expect(dropdownElts).toHaveLength(1);
  77. await userEvent.click(dropdownElts[0].parentElement?.firstElementChild || dropdownElts[0]);
  78. await findByRole("listbox");
  79. await userEvent.click(getByText("StringCol"));
  80. await findByRole("checkbox");
  81. const validate = getByTestId("CheckIcon").parentElement;
  82. expect(validate).not.toBeDisabled();
  83. });
  84. it("adds a row on validation", async () => {
  85. const onValidate = jest.fn();
  86. const { getByTestId, getAllByTestId, findByRole, getByText } = render(
  87. <TableSort columns={tableColumns} colsOrder={colsOrder} onValidate={onValidate} />
  88. );
  89. const elt = getByTestId("SortByAlphaIcon");
  90. await userEvent.click(elt);
  91. const dropdownElts = getAllByTestId("ArrowDropDownIcon");
  92. expect(dropdownElts).toHaveLength(1);
  93. await userEvent.click(dropdownElts[0].parentElement?.firstElementChild || dropdownElts[0]);
  94. await findByRole("listbox");
  95. await userEvent.click(getByText("StringCol"));
  96. await findByRole("checkbox");
  97. const validate = getByTestId("CheckIcon");
  98. expect(validate.parentElement).not.toBeDisabled();
  99. await userEvent.click(validate);
  100. const ddElts = getAllByTestId("ArrowDropDownIcon");
  101. expect(ddElts).toHaveLength(2);
  102. getByText("1");
  103. expect(onValidate).toHaveBeenCalled();
  104. });
  105. it("delete a row", async () => {
  106. const onValidate = jest.fn();
  107. const { getByTestId, getAllByTestId, findByRole, getByText } = render(
  108. <TableSort columns={tableColumns} colsOrder={colsOrder} onValidate={onValidate} />
  109. );
  110. const elt = getByTestId("SortByAlphaIcon");
  111. await userEvent.click(elt);
  112. const dropdownElts = getAllByTestId("ArrowDropDownIcon");
  113. expect(dropdownElts).toHaveLength(1);
  114. await userEvent.click(dropdownElts[0].parentElement?.firstElementChild || dropdownElts[0]);
  115. await findByRole("listbox");
  116. await userEvent.click(getByText("StringCol"));
  117. await findByRole("checkbox");
  118. const validate = getByTestId("CheckIcon");
  119. expect(validate.parentElement).not.toBeDisabled();
  120. await userEvent.click(validate);
  121. const ddElts = getAllByTestId("ArrowDropDownIcon");
  122. expect(ddElts).toHaveLength(2);
  123. const deletes = getAllByTestId("DeleteIcon");
  124. expect(deletes).toHaveLength(2);
  125. expect(deletes[0].parentElement).not.toBeDisabled();
  126. expect(deletes[1].parentElement).toBeDisabled();
  127. await userEvent.click(deletes[0]);
  128. const ddElts2 = getAllByTestId("ArrowDropDownIcon");
  129. expect(ddElts2).toHaveLength(1);
  130. });
  131. it("reset filters", async () => {
  132. const onValidate = jest.fn();
  133. const { getAllByTestId, getByTestId } = render(
  134. <TableSort
  135. columns={tableColumns}
  136. colsOrder={colsOrder}
  137. onValidate={onValidate}
  138. appliedSorts={[{ col: "StringCol", order: true }]}
  139. />
  140. );
  141. const elt = getByTestId("SortByAlphaIcon");
  142. await userEvent.click(elt);
  143. const deletes = getAllByTestId("DeleteIcon");
  144. expect(deletes).toHaveLength(2);
  145. expect(deletes[0].parentElement).not.toBeDisabled();
  146. expect(deletes[1].parentElement).toBeDisabled();
  147. await userEvent.click(deletes[0]);
  148. expect(onValidate).toHaveBeenCalled();
  149. });
  150. it("ignores unapplicable filters", async () => {
  151. const { getAllByTestId, getByTestId } = render(
  152. <TableSort
  153. columns={tableColumns}
  154. colsOrder={colsOrder}
  155. onValidate={jest.fn()}
  156. appliedSorts={[{ col: "unknown col", order: true }]}
  157. />
  158. );
  159. const elt = getByTestId("SortByAlphaIcon");
  160. await userEvent.click(elt);
  161. const ddElts2 = getAllByTestId("ArrowDropDownIcon");
  162. expect(ddElts2).toHaveLength(1);
  163. });
  164. });