1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React from "react";
6 import { mount, configure } from "enzyme";
7 import { SearchInput, DEFAULT_SEARCH_DEBOUNCE } from "./search-input";
8 import Adapter from 'enzyme-adapter-react-16';
10 configure({ adapter: new Adapter() });
12 describe("<SearchInput />", () => {
14 let onSearch: () => void;
21 describe("on submit", () => {
22 it("calls onSearch with initial value passed via props", () => {
23 const searchInput = mount(<SearchInput selfClearProp="" value="initial value" onSearch={onSearch} />);
24 searchInput.find("form").simulate("submit");
25 expect(onSearch).toBeCalledWith("initial value");
28 it("calls onSearch with current value", () => {
29 const searchInput = mount(<SearchInput selfClearProp="" value="" onSearch={onSearch} />);
30 searchInput.find("input").simulate("change", { target: { value: "current value" } });
31 searchInput.find("form").simulate("submit");
32 expect(onSearch).toBeCalledWith("current value");
35 it("calls onSearch with new value passed via props", () => {
36 const searchInput = mount(<SearchInput selfClearProp="" value="" onSearch={onSearch} />);
37 searchInput.find("input").simulate("change", { target: { value: "current value" } });
38 searchInput.setProps({value: "new value"});
39 searchInput.find("form").simulate("submit");
40 expect(onSearch).toBeCalledWith("new value");
43 it("cancels timeout set on input value change", () => {
44 const searchInput = mount(<SearchInput selfClearProp="" value="" onSearch={onSearch} debounce={1000} />);
45 searchInput.find("input").simulate("change", { target: { value: "current value" } });
46 searchInput.find("form").simulate("submit");
47 jest.runTimersToTime(1000);
48 expect(onSearch).toHaveBeenCalledTimes(1);
49 expect(onSearch).toBeCalledWith("current value");
54 describe("on input value change", () => {
55 it("calls onSearch after default timeout", () => {
56 const searchInput = mount(<SearchInput selfClearProp="" value="" onSearch={onSearch} />);
57 searchInput.find("input").simulate("change", { target: { value: "current value" } });
58 expect(onSearch).not.toBeCalled();
59 jest.runTimersToTime(DEFAULT_SEARCH_DEBOUNCE);
60 expect(onSearch).toBeCalledWith("current value");
63 it("calls onSearch after the time specified in props has passed", () => {
64 const searchInput = mount(<SearchInput selfClearProp="" value="" onSearch={onSearch} debounce={2000}/>);
65 searchInput.find("input").simulate("change", { target: { value: "current value" } });
66 jest.runTimersToTime(1000);
67 expect(onSearch).not.toBeCalled();
68 jest.runTimersToTime(1000);
69 expect(onSearch).toBeCalledWith("current value");
72 it("calls onSearch only once after no change happened during the specified time", () => {
73 const searchInput = mount(<SearchInput selfClearProp="" value="" onSearch={onSearch} debounce={1000}/>);
74 searchInput.find("input").simulate("change", { target: { value: "current value" } });
75 jest.runTimersToTime(500);
76 searchInput.find("input").simulate("change", { target: { value: "changed value" } });
77 jest.runTimersToTime(1000);
78 expect(onSearch).toHaveBeenCalledTimes(1);
81 it("calls onSearch again after the specified time has passed since previous call", () => {
82 const searchInput = mount(<SearchInput selfClearProp="" value="" onSearch={onSearch} debounce={1000}/>);
83 searchInput.find("input").simulate("change", { target: { value: "current value" } });
84 jest.runTimersToTime(500);
85 searchInput.find("input").simulate("change", { target: { value: "intermediate value" } });
86 jest.runTimersToTime(1000);
87 expect(onSearch).toBeCalledWith("intermediate value");
88 searchInput.find("input").simulate("change", { target: { value: "latest value" } });
89 jest.runTimersToTime(1000);
90 expect(onSearch).toBeCalledWith("latest value");
91 expect(onSearch).toHaveBeenCalledTimes(2);
97 describe("on input target change", () => {
98 it("clears the input value on selfClearProp change", () => {
99 const searchInput = mount(<SearchInput selfClearProp="abc" value="123" onSearch={onSearch} debounce={1000}/>);
101 // component should clear value upon creation
102 jest.runTimersToTime(1000);
103 expect(onSearch).toBeCalledWith("");
104 expect(onSearch).toHaveBeenCalledTimes(1);
106 // component should not clear on same selfClearProp
107 searchInput.setProps({ selfClearProp: 'abc' });
108 jest.runTimersToTime(1000);
109 expect(onSearch).toHaveBeenCalledTimes(1);
111 // component should clear on selfClearProp change
112 searchInput.setProps({ selfClearProp: '111' });
113 jest.runTimersToTime(1000);
114 expect(onSearch).toBeCalledWith("");
115 expect(onSearch).toHaveBeenCalledTimes(2);