From 26fac070b2bb69e5d35597f17b96e2b1bbaff32d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Fri, 24 Aug 2018 18:44:54 +0100 Subject: [PATCH] feat(tests): filter input tests --- ui/__mocks__/lodash.js | 11 ++ ui/package-lock.json | 9 ++ ui/package.json | 6 + .../__snapshots__/index.test.js.snap | 95 +++++++++++++++ .../NavBar/FilterInput/index.test.js | 112 ++++++++++++++++++ 5 files changed, 233 insertions(+) create mode 100644 ui/__mocks__/lodash.js create mode 100644 ui/src/Components/NavBar/FilterInput/__snapshots__/index.test.js.snap create mode 100644 ui/src/Components/NavBar/FilterInput/index.test.js diff --git a/ui/__mocks__/lodash.js b/ui/__mocks__/lodash.js new file mode 100644 index 000000000..6d9fc6447 --- /dev/null +++ b/ui/__mocks__/lodash.js @@ -0,0 +1,11 @@ +// https://github.com/facebook/jest/issues/3465 + +function debounce(wrapped) { + return wrapped; +} + +function throttle(wrapped) { + return wrapped; +} + +export { debounce, throttle }; diff --git a/ui/package-lock.json b/ui/package-lock.json index 60d423e5d..12abbf3a5 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -3386,6 +3386,15 @@ "prop-types": "15.6.2" } }, + "enzyme-to-json": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/enzyme-to-json/-/enzyme-to-json-3.3.4.tgz", + "integrity": "sha1-Z8YEDpMRgvGDQYry659DIyWKp38=", + "dev": true, + "requires": { + "lodash": "4.17.10" + } + }, "errno": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", diff --git a/ui/package.json b/ui/package.json index c04a1fb51..28473c973 100644 --- a/ui/package.json +++ b/ui/package.json @@ -53,6 +53,7 @@ "devDependencies": { "enzyme": "3.4.4", "enzyme-adapter-react-16": "1.2.0", + "enzyme-to-json": "3.3.4", "eslint-plugin-react": "7.11.1", "jest-fetch-mock": "1.6.5", "jest-localstorage-mock": "2.2.0", @@ -60,5 +61,10 @@ "markdownlint-cli": "0.13.0", "node-sass-chokidar": "1.3.3", "onchange": "4.1.0" + }, + "jest": { + "snapshotSerializers": [ + "enzyme-to-json/serializer" + ] } } diff --git a/ui/src/Components/NavBar/FilterInput/__snapshots__/index.test.js.snap b/ui/src/Components/NavBar/FilterInput/__snapshots__/index.test.js.snap new file mode 100644 index 000000000..ad75ddc7e --- /dev/null +++ b/ui/src/Components/NavBar/FilterInput/__snapshots__/index.test.js.snap @@ -0,0 +1,95 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` matches snapshot on default render 1`] = ` +
+ +
+`; diff --git a/ui/src/Components/NavBar/FilterInput/index.test.js b/ui/src/Components/NavBar/FilterInput/index.test.js new file mode 100644 index 000000000..f06b0dd73 --- /dev/null +++ b/ui/src/Components/NavBar/FilterInput/index.test.js @@ -0,0 +1,112 @@ +import React from "react"; + +import { mount, render } from "enzyme"; + +import { AlertStore, NewUnappliedFilter } from "Stores/AlertStore"; +import { Settings } from "Stores/Settings"; +import { FilterInput } from "."; + +let alertStore; +let settingsStore; + +beforeEach(() => { + alertStore = new AlertStore([]); + settingsStore = new Settings(); + + fetch.resetMocks(); +}); + +const MountedInput = () => { + return mount( + + ); +}; + +describe("", () => { + it("matches snapshot on default render", () => { + const tree = render( + + ); + expect(tree).toMatchSnapshot(); + }); + + it("inputStore.ref should be != null after mount", () => { + const tree = MountedInput(); + const instance = tree.instance(); + expect(instance.inputStore.ref).not.toBeNull(); + }); + + it("onChange should modify inputStore.value", () => { + fetch.mockResponseOnce(JSON.stringify([])); + + const tree = MountedInput(); + tree.find("input").simulate("change", { target: { value: "foo=bar" } }); + const instance = tree.instance(); + expect(instance.inputStore.value).toBe("foo=bar"); + }); + + it("submit should modify alertStore.filters", () => { + const tree = MountedInput(); + const instance = tree.instance(); + instance.inputStore.value = "foo=bar"; + expect(alertStore.filters.values).toHaveLength(0); + tree.find("form").simulate("submit"); + expect(alertStore.filters.values).toHaveLength(1); + expect(alertStore.filters.values[0]).toMatchObject( + NewUnappliedFilter("foo=bar") + ); + }); + + it("Clicking on form-control div focuses input", () => { + const tree = MountedInput(); + const instance = tree.instance(); + const inputSpy = jest.spyOn(instance.inputStore.ref.input, "focus"); + const formControl = tree.find(".form-control"); + formControl.simulate("click"); + expect(inputSpy).toHaveBeenCalledTimes(1); + }); +}); + +describe("", () => { + it("fetches suggestions on input change", done => { + fetch.mockResponseOnce(JSON.stringify(["foo=bar", "foo=~bar"])); + + const tree = MountedInput(); + const instance = tree.instance(); + tree.find("input").simulate("change", { target: { value: "foo" } }); + + // need to wait on fetch to resolve, but can't find any better way here + setTimeout(() => { + expect(fetch.mock.calls).toHaveLength(1); + expect(fetch.mock.calls[0]).toContain("./autocomplete.json?term=foo"); + expect(instance.inputStore.suggestions).toHaveLength(2); + expect(instance.inputStore.suggestions).toContain("foo=bar"); + expect(instance.inputStore.suggestions).toContain("foo=~bar"); + done(); + }, 1000); + }); + + it("handles failed suggestion fetches", done => { + fetch.mockRejectOnce("Fetch error"); + + const tree = MountedInput(); + const instance = tree.instance(); + tree.find("input").simulate("change", { target: { value: "bar" } }); + + // need to wait on fetch to resolve, but can't find any better way here + setTimeout(() => { + expect(fetch.mock.calls).toHaveLength(1); + expect(fetch.mock.calls[0]).toContain("./autocomplete.json?term=bar"); + expect(instance.inputStore.suggestions).toHaveLength(0); + done(); + }, 1000); + }); + + it("clearing input clears suggestions", () => { + const tree = MountedInput(); + const instance = tree.instance(); + instance.inputStore.suggestions = ["foo", "bar"]; + tree.find("input").simulate("change", { target: { value: "" } }); + expect(instance.inputStore.suggestions).toHaveLength(0); + }); +});