stitch-ui
Version:
238 lines (211 loc) • 6.93 kB
JavaScript
/* global it, describe, beforeAll, afterEach, expect */
import React from "react"; // eslint-disable-line no-unused-vars
import { Provider } from "react-redux";
import { JSDOM } from "jsdom";
import { mount } from "enzyme";
import JSON5 from "json5";
import {
testSetup,
changeInput,
noConsoleErrorsAllowed,
stubConfirmation,
braceCompatShim
} from "../../testutil";
import * as homeActions from "../../home/actions";
import * as actions from "../actions";
import Values from "../components/Values";
global.navigator = {
userAgent: "node.js"
};
const doc = new JSDOM("<!doctype html><html><body></body></html>");
global.document = doc;
global.window = doc.defaultView;
braceCompatShim(global.window);
describe("values", () => {
noConsoleErrorsAllowed();
let store;
let testApp;
let vdisplay;
let actionSub;
beforeAll(async () => {
const testHarness = await testSetup();
store = testHarness.store;
actionSub = testHarness.actionSub;
testApp = await store.dispatch(
homeActions.createApp(testHarness.groupId, "my-test-app")
);
return new Promise(resolve => {
actionSub.subscribe(actions.loadValuesActions.rcv.getType(), resolve);
vdisplay = mount(
<Provider store={store}>
<Values app={testApp} />
</Provider>
);
});
});
afterEach(() => {
actionSub.reset();
});
const validTestValue = {
name: "my-new-name",
value: '{"foo":"my-new-value"}',
private: false
};
it('renders the "add value" form correctly', async () => {
expect(vdisplay.find("input")).toHaveLength(2);
expect(vdisplay.find("input[type='text']")).toHaveLength(1);
expect(vdisplay.find("input[type='checkbox']")).toHaveLength(1);
expect(vdisplay.find("ReactAce")).toHaveLength(1);
expect(
vdisplay.find("button").findWhere(x => x.text() === "Save")
).toHaveLength(1);
});
it("cannot create value with a blank name (synchronous validation)", async () => {
expect.assertions(1);
changeInput(vdisplay, "name", "");
vdisplay.find("ReactAce").props().onChange(validTestValue.value);
await vdisplay
.find("button")
.findWhere(x => x.text() === "Save")
.props()
.onClick();
expect(vdisplay.find(".banner-error").text()).toMatch(
"Name must not be blank"
);
});
it("cannot create value with an invalid name", async () => {
expect.assertions(1);
changeInput(vdisplay, "name", "invalid name");
vdisplay.find("ReactAce").props().onChange(validTestValue.value);
await vdisplay
.find("button")
.findWhere(x => x.text() === "Save")
.props()
.onClick();
expect(vdisplay.find(".banner-error").text()).toMatch("invalid value name");
});
it("can create a new value", async () => {
expect.assertions(3);
changeInput(vdisplay, "name", validTestValue.name);
vdisplay.find("ReactAce").props().onChange(validTestValue.value);
await vdisplay
.find("button")
.findWhere(x => x.text() === "Save")
.props()
.onClick();
expect(vdisplay.find("h3").text()).toBe(validTestValue.name);
expect(vdisplay.find("ReactAce").at(0).props().value).toEqual(
JSON.stringify(JSON.parse(validTestValue.value), null, 2)
);
expect(vdisplay.find("input").at(0).node.value).toBe("");
});
it("can change the value", async () => {
expect.assertions(1);
const newValue = '{"a":"blahhhh"}';
vdisplay.find("ReactAce").at(0).props().onChange(newValue);
await vdisplay
.find("button")
.findWhere(x => x.text() === "Save")
.at(0)
.props()
.onClick();
expect(vdisplay.find("ReactAce").at(0).props().value).toBe(
JSON.stringify(JSON5.parse(newValue), null, 2)
);
});
it("triggers an error if the json is invalid", async () => {
expect.assertions(1);
const newValue = "{foo";
vdisplay.find("ReactAce").at(0).props().onChange(newValue);
vdisplay
.find("button")
.findWhere(x => x.text() === "Save")
.at(0)
.props()
.onClick();
expect(vdisplay.find(".banner-error").text()).toBe("Invalid JSON");
});
describe("private checkbox", () => {
const e = {
target: {
checked: true
}
};
const flipSavedPrivate = async () => {
e.target.checked = !e.target.checked;
expect.assertions(1);
vdisplay.find("input[type='checkbox']").at(0).props().onChange(e);
await vdisplay
.find("button")
.findWhere(x => x.text() === "Save")
.at(0)
.props()
.onClick();
expect(
vdisplay.find("input[type='checkbox']").at(0).props().checked
).toEqual(e.target.checked);
};
it("can change the private checkbox on previously saved value", async () => {
await flipSavedPrivate();
});
it("can uncheck the private checkbox on previously saved value", async () => {
await flipSavedPrivate();
});
it("checkbox resets to false after new value is added", async () => {
e.target.checked = true;
expect.assertions(1);
changeInput(vdisplay, "name", validTestValue.name);
vdisplay.find("ReactAce").at(1).props().onChange(validTestValue.value);
vdisplay.find("input[type='checkbox']").at(1).props().onChange(e);
await vdisplay
.find("button")
.findWhere(x => x.text() === "Save")
.at(1)
.props()
.onClick();
expect(
vdisplay.find("input[type='checkbox']").at(1).props().checked
).toEqual(!e.target.checked);
});
});
it("dirty values can be reset", async () => {
const checkDirtyAndDiscard = () => {
expect(
store.getState().values.values.get(validTestValue.name).dirty
).toBe(true);
expect(
vdisplay.find("button").findWhere(x => x.text() === "Discard Changes")
).toHaveLength(1);
vdisplay
.find("button")
.findWhere(x => x.text() === "Discard Changes")
.props()
.onClick();
expect(
store.getState().values.values.get(validTestValue.name).dirty
).toBe(false);
expect(
vdisplay.find("button").findWhere(x => x.text() === "Discard Changes")
).toHaveLength(0);
};
// Trigger dirty via the value form
vdisplay.find("ReactAce").at(0).props().onChange("{hello}");
checkDirtyAndDiscard();
const checkbox = vdisplay.find("input[type='checkbox']").at(0);
// trigger dirty via private checkbox
checkbox
.props()
.onChange({ target: { checked: !checkbox.props().checked } });
checkDirtyAndDiscard();
});
it("can delete the value", async () => {
stubConfirmation(true);
expect.assertions(1);
await vdisplay
.find("button")
.findWhere(b => b.text() === "Delete")
.props()
.onClick();
expect(vdisplay.find("h3").exists()).toBe(false);
});
});