feat(tests): filter input tests

This commit is contained in:
Łukasz Mierzwa
2018-08-24 18:44:54 +01:00
parent 13b364a0d4
commit 26fac070b2
5 changed files with 233 additions and 0 deletions

11
ui/__mocks__/lodash.js Normal file
View File

@@ -0,0 +1,11 @@
// https://github.com/facebook/jest/issues/3465
function debounce(wrapped) {
return wrapped;
}
function throttle(wrapped) {
return wrapped;
}
export { debounce, throttle };

9
ui/package-lock.json generated
View File

@@ -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",

View File

@@ -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"
]
}
}

View File

@@ -0,0 +1,95 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<FilterInput /> matches snapshot on default render 1`] = `
<form
class="form-inline mw-100"
data-filters=""
>
<div
aria-expanded="false"
aria-haspopup="listbox"
aria-owns="react-autowhatever-1"
class="autosuggest d-inline-block w-100"
role="combobox"
>
<div
class="input-group mr-2"
>
<div
class="input-group-prepend"
>
<span
class="input-group-text px-2"
>
<svg
aria-hidden="true"
class="svg-inline--fa fa-search fa-w-16 "
data-icon="search"
data-prefix="fas"
role="img"
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"
fill="currentColor"
>
</path>
</svg>
</span>
</div>
<div
class="form-control p-1 components-filterinput"
>
<input
aria-autocomplete="list"
aria-controls="react-autowhatever-1"
autocomplete="off"
class="components-filterinput-wrapper"
placeholder=""
type="text"
value=""
>
</input>
</div>
<div
class="input-group-append"
>
<button
aria-expanded="true"
aria-haspopup="true"
class="input-group-text rounded-right cursor-pointer components-navbar-history px-2"
data-toggle="dropdown"
type="button"
>
<svg
aria-hidden="true"
class="svg-inline--fa fa-caret-down fa-w-10 "
data-icon="caret-down"
data-prefix="fas"
role="img"
viewBox="0 0 320 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"
fill="currentColor"
>
</path>
</svg>
</button>
</div>
</div>
<div
class="dropdown"
id="react-autowhatever-1"
role="listbox"
>
</div>
</div>
</form>
`;

View File

@@ -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(
<FilterInput alertStore={alertStore} settingsStore={settingsStore} />
);
};
describe("<FilterInput />", () => {
it("matches snapshot on default render", () => {
const tree = render(
<FilterInput alertStore={alertStore} settingsStore={settingsStore} />
);
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("<FilterInput Autosuggest />", () => {
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);
});
});