/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at . */ // @flow import React from "react"; import { mount, shallow } from "enzyme"; import { ProjectSearch } from "../ProjectSearch"; import { statusType } from "../../reducers/project-text-search"; import { mockcx } from "../../utils/test-mockup"; const hooks = { on: [], off: [] }; const shortcuts = { dispatch(eventName) { hooks.on.forEach(hook => { if (hook.event === eventName) { hook.cb(); } }); hooks.off.forEach(hook => { if (hook.event === eventName) { hook.cb(); } }); }, on: jest.fn((event, cb) => hooks.on.push({ event, cb })), off: jest.fn((event, cb) => hooks.off.push({ event, cb })) }; const context = { shortcuts }; const testResults = [ { filepath: "testFilePath1", type: "RESULT", matches: [ { match: "match1", value: "some thing match1", column: 30, type: "MATCH" }, { match: "match2", value: "some thing match2", column: 60, type: "MATCH" }, { match: "match3", value: "some thing match3", column: 90, type: "MATCH" } ] }, { filepath: "testFilePath2", type: "RESULT", matches: [ { match: "match4", value: "some thing match4", column: 80, type: "MATCH" }, { match: "match5", value: "some thing match5", column: 40, type: "MATCH" } ] } ]; const testMatch = { type: "MATCH", match: "match1", value: "some thing match1", sourceId: "some-target/source42", line: 3, column: 30 }; function render(overrides = {}, mounted = false) { const props = { cx: mockcx, status: "DONE", sources: {}, results: [], query: "foo", activeSearch: "project", closeProjectSearch: jest.fn(), searchSources: jest.fn(), clearSearch: jest.fn(), updateSearchStatus: jest.fn(), selectSpecificLocation: jest.fn(), doSearchForHighlight: jest.fn(), setActiveSearch: jest.fn(), ...overrides }; return mounted ? mount(, { context }) : shallow(, { context }); } describe("ProjectSearch", () => { beforeEach(() => { context.shortcuts.on.mockClear(); context.shortcuts.off.mockClear(); }); it("renders nothing when disabled", () => { const component = render({ activeSearch: "" }); expect(component).toMatchSnapshot(); }); it("where has not been pressed", () => { const component = render({ query: "" }); expect(component).toMatchSnapshot(); }); it("found no search results", () => { const component = render(); expect(component).toMatchSnapshot(); }); it("should display loading message while search is in progress", () => { const component = render({ query: "match", status: statusType.fetching }); expect(component).toMatchSnapshot(); }); it("found search results", () => { const component = render( { query: "match", results: testResults }, true ); expect(component).toMatchSnapshot(); }); it("turns off shortcuts on unmount", () => { const component = render({ query: "" }); expect(component).toMatchSnapshot(); component.unmount(); expect(context.shortcuts.off).toHaveBeenCalled(); }); it("calls inputOnChange", () => { const component = render( { results: testResults }, true ); component .find("SearchInput input") .simulate("change", { target: { value: "bar" } }); expect(component.state().inputValue).toEqual("bar"); }); it("onKeyDown Escape/Other", () => { const searchSources = jest.fn(); const component = render( { results: testResults, searchSources }, true ); component.find("SearchInput input").simulate("keydown", { key: "Escape" }); expect(searchSources).not.toHaveBeenCalled(); searchSources.mockClear(); component .find("SearchInput input") .simulate("keydown", { key: "Other", stopPropagation: jest.fn() }); expect(searchSources).not.toHaveBeenCalled(); }); it("onKeyDown Enter", () => { const searchSources = jest.fn(); const component = render( { results: testResults, searchSources }, true ); component .find("SearchInput input") .simulate("keydown", { key: "Enter", stopPropagation: jest.fn() }); expect(searchSources).toHaveBeenCalledWith(mockcx, "foo"); }); it("onEnterPress shortcut no match or setExpanded", () => { const selectSpecificLocation = jest.fn(); const component = render( { results: testResults, selectSpecificLocation }, true ); component.instance().state.focusedItem = null; shortcuts.dispatch("Enter"); expect(selectSpecificLocation).not.toHaveBeenCalled(); }); it("onEnterPress shortcut match", () => { const selectSpecificLocation = jest.fn(); const component = render( { results: testResults, selectSpecificLocation }, true ); component.instance().state.focusedItem = { ...testMatch }; shortcuts.dispatch("Enter"); expect(selectSpecificLocation).toHaveBeenCalledWith(mockcx, { sourceId: "some-target/source42", line: 3, column: 30 }); }); it("state.inputValue responds to prop.query changes", () => { const component = render({ query: "foo" }); expect(component.state().inputValue).toEqual("foo"); component.setProps({ query: "" }); expect(component.state().inputValue).toEqual(""); }); describe("showErrorEmoji", () => { it("false if not done & results", () => { const component = render({ status: statusType.fetching, results: testResults }); expect(component).toMatchSnapshot(); }); it("false if not done & no results", () => { const component = render({ status: statusType.fetching }); expect(component).toMatchSnapshot(); }); // "false if done & has results" // is the same test as "found search results" // "true if done & has no results" // is the same test as "found no search results" }); });