mirror of
https://github.com/prymitive/karma
synced 2026-05-21 04:33:07 +00:00
573 lines
17 KiB
JavaScript
573 lines
17 KiB
JavaScript
import React from "react";
|
|
import { act } from "react-dom/test-utils";
|
|
|
|
import { mount, shallow } from "enzyme";
|
|
|
|
import { advanceTo, clear } from "jest-date-mock";
|
|
|
|
import toDiffableHtml from "diffable-html";
|
|
|
|
import moment from "moment";
|
|
|
|
import { SilenceFormStore } from "Stores/SilenceFormStore";
|
|
import {
|
|
DateTimeSelect,
|
|
TabContentStart,
|
|
TabContentEnd,
|
|
TabContentDuration,
|
|
} from ".";
|
|
|
|
let silenceFormStore;
|
|
|
|
beforeEach(() => {
|
|
silenceFormStore = new SilenceFormStore();
|
|
silenceFormStore.data.startsAt = moment([2060, 1, 1, 0, 0, 0]);
|
|
silenceFormStore.data.endsAt = moment([2061, 1, 1, 0, 0, 0]);
|
|
});
|
|
|
|
afterEach(() => {
|
|
clear();
|
|
});
|
|
|
|
const ShallowDateTimeSelect = () => {
|
|
return shallow(<DateTimeSelect silenceFormStore={silenceFormStore} />);
|
|
};
|
|
|
|
const MountedDateTimeSelect = () => {
|
|
return mount(<DateTimeSelect silenceFormStore={silenceFormStore} />);
|
|
};
|
|
|
|
describe("<DateTimeSelect />", () => {
|
|
it("renders 3 tabs", () => {
|
|
const tree = ShallowDateTimeSelect();
|
|
const tabs = tree.find("Tab");
|
|
expect(tabs).toHaveLength(3);
|
|
});
|
|
|
|
it("renders 'Duration' tab by default", () => {
|
|
const tree = MountedDateTimeSelect();
|
|
const tab = tree.find(".nav-link.active");
|
|
expect(tab).toHaveLength(1);
|
|
// check tab title
|
|
expect(tab.text()).toMatch(/Duration/);
|
|
// check tab content
|
|
expect(tree.find(".tab-content").text()).toBe("366days0hours0minutes");
|
|
});
|
|
|
|
it("'Duration' tab matches snapshot", () => {
|
|
advanceTo(new Date(2060, 1, 1, 0, 0, 0));
|
|
const tree = MountedDateTimeSelect();
|
|
expect(toDiffableHtml(tree.html())).toMatchSnapshot();
|
|
});
|
|
|
|
it("'Duration' tab unmounts without crashing", () => {
|
|
const tree = MountedDateTimeSelect();
|
|
tree.unmount();
|
|
});
|
|
|
|
it("clicking on the 'Starts' tab switches content to 'startsAt' selection", () => {
|
|
const tree = MountedDateTimeSelect();
|
|
const tab = tree.find(".nav-link").at(0);
|
|
expect(tab.text()).toMatch(/Starts/);
|
|
tab.simulate("click");
|
|
expect(tree.find(".tab-content").text()).toMatch(/2060/);
|
|
});
|
|
|
|
it("'Starts' tab matches snapshot", () => {
|
|
advanceTo(new Date(2060, 1, 1, 0, 0, 0));
|
|
const tree = MountedDateTimeSelect();
|
|
tree.find(".nav-link").at(0).simulate("click");
|
|
expect(toDiffableHtml(tree.html())).toMatchSnapshot();
|
|
});
|
|
|
|
it("'Starts' tab unmounts without crashing", () => {
|
|
const tree = MountedDateTimeSelect();
|
|
tree.find(".nav-link").at(0).simulate("click");
|
|
tree.unmount();
|
|
});
|
|
|
|
it("clicking on the 'Ends' tab switches content to 'endsAt' selection", () => {
|
|
const tree = MountedDateTimeSelect();
|
|
const tab = tree.find(".nav-link").at(1);
|
|
expect(tab.text()).toMatch(/Ends/);
|
|
tab.simulate("click");
|
|
expect(tree.find(".tab-content").text()).toMatch(/2061/);
|
|
});
|
|
|
|
it("'Ends' tab matches snapshot", () => {
|
|
advanceTo(new Date(2060, 1, 1, 0, 0, 0));
|
|
const tree = MountedDateTimeSelect();
|
|
tree.find(".nav-link").at(1).simulate("click");
|
|
expect(toDiffableHtml(tree.html())).toMatchSnapshot();
|
|
});
|
|
|
|
it("'Ends' tab unmounts without crashing", () => {
|
|
const tree = MountedDateTimeSelect();
|
|
tree.find(".nav-link").at(1).simulate("click");
|
|
tree.unmount();
|
|
});
|
|
|
|
it("clicking on the 'Duration' tabs switches content to duration selection", () => {
|
|
const tree = MountedDateTimeSelect();
|
|
// first switch to 'Starts'
|
|
tree.find(".nav-link").at(0).simulate("click");
|
|
// then switch back to 'Duration'
|
|
const tab = tree.find(".nav-link").at(2);
|
|
expect(tab.text()).toMatch(/Duration/);
|
|
tab.simulate("click");
|
|
expect(tree.find(".tab-content").text()).toBe("366days0hours0minutes");
|
|
});
|
|
|
|
it("'Ends' tab offset badge is updated after 1 minute", () => {
|
|
jest.useFakeTimers();
|
|
advanceTo(new Date(2060, 1, 1, 12, 0, 0));
|
|
silenceFormStore.data.startsAt = moment([2060, 1, 1, 12, 0, 0]);
|
|
silenceFormStore.data.endsAt = moment([2060, 1, 1, 13, 0, 0]);
|
|
|
|
const tree = MountedDateTimeSelect();
|
|
expect(tree.find(".nav-link").at(1).text()).toBe("Endsin 1h ");
|
|
|
|
advanceTo(new Date(2060, 1, 1, 12, 1, 0));
|
|
act(() => jest.runOnlyPendingTimers());
|
|
|
|
expect(tree.find(".nav-link").at(1).text()).toBe("Endsin 59m ");
|
|
});
|
|
|
|
it("unmounts cleanly", () => {
|
|
const tree = MountedDateTimeSelect();
|
|
tree.unmount();
|
|
});
|
|
});
|
|
|
|
const ValidateTimeButton = (
|
|
tab,
|
|
storeKey,
|
|
elemIndex,
|
|
iconMatch,
|
|
expectedDiff
|
|
) => {
|
|
const button = tab.find("td > span").at(elemIndex);
|
|
expect(button.html()).toMatch(iconMatch);
|
|
|
|
const oldTimeValue = moment(silenceFormStore.data[storeKey]);
|
|
button.simulate("click");
|
|
expect(silenceFormStore.data[storeKey].toISOString()).not.toBe(
|
|
oldTimeValue.toISOString()
|
|
);
|
|
const diffMS = silenceFormStore.data[storeKey].diff(oldTimeValue);
|
|
expect(diffMS).toBe(expectedDiff);
|
|
};
|
|
|
|
const ValidateTimeWheel = (tab, storeKey, className, deltaY, expectedDiff) => {
|
|
const elem = tab.find(className);
|
|
|
|
const oldTimeValue = moment(silenceFormStore.data[storeKey]);
|
|
|
|
elem.simulate("wheel", { deltaY: deltaY });
|
|
// fire real event so cancel listener will trigger
|
|
const event = new Event("wheel", { deltaY: deltaY });
|
|
tab
|
|
.find("div.components-hour-minute")
|
|
.at(0)
|
|
.getDOMNode()
|
|
.dispatchEvent(event);
|
|
|
|
expect(silenceFormStore.data[storeKey].toISOString()).not.toBe(
|
|
oldTimeValue.toISOString()
|
|
);
|
|
const diffMS = silenceFormStore.data[storeKey].diff(oldTimeValue);
|
|
expect(diffMS).toBe(expectedDiff);
|
|
};
|
|
|
|
const MountedTabContentStart = () => {
|
|
return mount(<TabContentStart silenceFormStore={silenceFormStore} />);
|
|
};
|
|
|
|
describe("<TabContentStart />", () => {
|
|
it("selecting date on DatePicker updates startsAt", () => {
|
|
const tree = MountedTabContentStart();
|
|
expect(silenceFormStore.data.startsAt.toISOString()).toBe(
|
|
moment([2060, 1, 1, 0, 0, 0]).toISOString()
|
|
);
|
|
tree.find("div.react-datepicker__day--018").simulate("click");
|
|
expect(silenceFormStore.data.startsAt.toISOString()).toBe(
|
|
moment([2060, 1, 18, 0, 0, 0]).toISOString()
|
|
);
|
|
});
|
|
|
|
it("clicking on the hour inc button adds 1h to startsAt", () => {
|
|
const tree = MountedTabContentStart();
|
|
ValidateTimeButton(tree, "startsAt", 0, /angle-up/, 3600 * 1000);
|
|
});
|
|
|
|
it("scrolling up on the hour button adds 1h to startsAt", () => {
|
|
const tree = MountedTabContentStart();
|
|
ValidateTimeWheel(
|
|
tree,
|
|
"startsAt",
|
|
"td.components-hour-up",
|
|
-1,
|
|
3600 * 1000
|
|
);
|
|
});
|
|
|
|
it("clicking on the minute inc button adds 1m to startsAt", () => {
|
|
const tree = MountedTabContentStart();
|
|
ValidateTimeButton(tree, "startsAt", 1, /angle-up/, 60 * 1000);
|
|
});
|
|
|
|
it("scrolling up on the minute button adds 1m to startsAt", () => {
|
|
const tree = MountedTabContentStart();
|
|
ValidateTimeWheel(
|
|
tree,
|
|
"startsAt",
|
|
"td.components-minute-up",
|
|
-2,
|
|
60 * 1000
|
|
);
|
|
});
|
|
|
|
it("clicking on the hour dec button subtracts 1h from startsAt", () => {
|
|
const tree = MountedTabContentStart();
|
|
ValidateTimeButton(tree, "startsAt", 2, /angle-down/, -1 * 3600 * 1000);
|
|
});
|
|
|
|
it("scrolling down on the hour button subtracts 1h from startsAt", () => {
|
|
const tree = MountedTabContentStart();
|
|
ValidateTimeWheel(
|
|
tree,
|
|
"startsAt",
|
|
"td.components-hour-down",
|
|
1,
|
|
-1 * 3600 * 1000
|
|
);
|
|
});
|
|
|
|
it("scrolling up on the minute adds 1m to startsAt", () => {
|
|
const tree = MountedTabContentStart();
|
|
ValidateTimeWheel(tree, "startsAt", "td.components-minute", -2, 60 * 1000);
|
|
});
|
|
|
|
it("scrolling down on the minute subtracts 1m from startsAt", () => {
|
|
const tree = MountedTabContentStart();
|
|
ValidateTimeWheel(
|
|
tree,
|
|
"startsAt",
|
|
"td.components-minute",
|
|
1,
|
|
-1 * 60 * 1000
|
|
);
|
|
});
|
|
|
|
it("clicking on the minute dec button subtracts 1m from startsAt", () => {
|
|
const tree = MountedTabContentStart();
|
|
ValidateTimeButton(tree, "startsAt", 3, /angle-down/, -1 * 60 * 1000);
|
|
});
|
|
|
|
it("scrolling down on the minute button subtracts 1m from startsAt", () => {
|
|
const tree = MountedTabContentStart();
|
|
ValidateTimeWheel(
|
|
tree,
|
|
"startsAt",
|
|
"td.components-minute-down",
|
|
2,
|
|
-1 * 60 * 1000
|
|
);
|
|
});
|
|
|
|
it("scrolling up on the minute subtracts 1m from startsAt", () => {
|
|
const tree = MountedTabContentStart();
|
|
ValidateTimeWheel(tree, "startsAt", "td.components-minute", -50, 60 * 1000);
|
|
});
|
|
|
|
it("scrolling down on the minute subtracts 1m from startsAt", () => {
|
|
const tree = MountedTabContentStart();
|
|
ValidateTimeWheel(
|
|
tree,
|
|
"startsAt",
|
|
"td.components-minute",
|
|
1,
|
|
-1 * 60 * 1000
|
|
);
|
|
});
|
|
});
|
|
|
|
const MountedTabContentEnd = () => {
|
|
return mount(<TabContentEnd silenceFormStore={silenceFormStore} />);
|
|
};
|
|
|
|
describe("<TabContentEnd />", () => {
|
|
it("Selecting date on DatePicker updates endsAt", () => {
|
|
const tree = MountedTabContentEnd();
|
|
expect(silenceFormStore.data.endsAt.toISOString()).toBe(
|
|
moment([2061, 1, 1, 0, 0, 0]).toISOString()
|
|
);
|
|
tree.find("div.react-datepicker__day--024").simulate("click");
|
|
expect(silenceFormStore.data.endsAt.toISOString()).toBe(
|
|
moment([2061, 1, 24, 0, 0, 0]).toISOString()
|
|
);
|
|
});
|
|
|
|
it("clicking on the hour inc button adds 1h to endsAt", () => {
|
|
const tree = MountedTabContentEnd();
|
|
ValidateTimeButton(tree, "endsAt", 0, /angle-up/, 3600 * 1000);
|
|
});
|
|
|
|
it("scrolling up on the hour button adds 1h to endsAt", () => {
|
|
const tree = MountedTabContentEnd();
|
|
ValidateTimeWheel(tree, "endsAt", "td.components-hour-up", -1, 3600 * 1000);
|
|
});
|
|
|
|
it("scrolling up on the hour adds 1h to endsAt", () => {
|
|
const tree = MountedTabContentEnd();
|
|
ValidateTimeWheel(tree, "endsAt", "td.components-hour", -1, 3600 * 1000);
|
|
});
|
|
|
|
it("scrolling down on the hour subtracts 1h from endsAt", () => {
|
|
const tree = MountedTabContentEnd();
|
|
ValidateTimeWheel(
|
|
tree,
|
|
"endsAt",
|
|
"td.components-hour",
|
|
1,
|
|
-1 * 3600 * 1000
|
|
);
|
|
});
|
|
|
|
it("clicking on the minute inc button adds 1m to endsAt", () => {
|
|
const tree = MountedTabContentEnd();
|
|
ValidateTimeButton(tree, "endsAt", 1, /angle-up/, 60 * 1000);
|
|
});
|
|
|
|
it("scrolling up on the minute button adds 1m to endsAt", () => {
|
|
const tree = MountedTabContentEnd();
|
|
ValidateTimeWheel(
|
|
tree,
|
|
"endsAt",
|
|
"td.components-minute-up",
|
|
-10,
|
|
60 * 1000
|
|
);
|
|
});
|
|
|
|
it("clicking on the hour dec button subtracts 1h from endsAt", () => {
|
|
const tree = MountedTabContentEnd();
|
|
ValidateTimeButton(tree, "endsAt", 2, /angle-down/, -1 * 3600 * 1000);
|
|
});
|
|
|
|
it("scrolling down on the hour button subtracts 1h from endsAt", () => {
|
|
const tree = MountedTabContentEnd();
|
|
ValidateTimeWheel(
|
|
tree,
|
|
"endsAt",
|
|
"td.components-hour-down",
|
|
1,
|
|
-1 * 3600 * 1000
|
|
);
|
|
});
|
|
|
|
it("clicking on the minute dec button subtracts 1m from endsAt", () => {
|
|
const tree = MountedTabContentEnd();
|
|
ValidateTimeButton(tree, "endsAt", 3, /angle-down/, -1 * 60 * 1000);
|
|
});
|
|
|
|
it("scrolling down on the minute button subtracts 1m from endsAt", () => {
|
|
const tree = MountedTabContentEnd();
|
|
ValidateTimeWheel(
|
|
tree,
|
|
"endsAt",
|
|
"td.components-minute-down",
|
|
50,
|
|
-1 * 60 * 1000
|
|
);
|
|
});
|
|
|
|
it("scrolling up on the minute adds 1m to endsAt", () => {
|
|
const tree = MountedTabContentEnd();
|
|
ValidateTimeWheel(tree, "endsAt", "td.components-minute", -10, 60 * 1000);
|
|
});
|
|
|
|
it("scrolling down on the minute subtracts 1m from endsAt", () => {
|
|
const tree = MountedTabContentEnd();
|
|
ValidateTimeWheel(
|
|
tree,
|
|
"endsAt",
|
|
"td.components-minute",
|
|
15,
|
|
-1 * 60 * 1000
|
|
);
|
|
});
|
|
});
|
|
|
|
const ValidateDurationButton = (elemIndex, iconMatch, expectedDiff) => {
|
|
const tree = mount(
|
|
<TabContentDuration silenceFormStore={silenceFormStore} />
|
|
);
|
|
const button = tree.find("td > span").at(elemIndex);
|
|
expect(button.html()).toMatch(iconMatch);
|
|
|
|
const oldEndsAt = moment(silenceFormStore.data.endsAt);
|
|
button.simulate("click");
|
|
expect(silenceFormStore.data.endsAt.toISOString()).not.toBe(
|
|
oldEndsAt.toISOString()
|
|
);
|
|
const diffMS = silenceFormStore.data.endsAt.diff(oldEndsAt);
|
|
expect(diffMS).toBe(expectedDiff);
|
|
};
|
|
|
|
const ValidateDurationWheel = (elemIndex, deltaY, expectedDiff) => {
|
|
const tree = mount(
|
|
<TabContentDuration silenceFormStore={silenceFormStore} />
|
|
);
|
|
const elem = tree.find(".components-duration").at(elemIndex);
|
|
|
|
const oldEndsAt = moment(silenceFormStore.data.endsAt);
|
|
|
|
elem.simulate("wheel", { deltaY: deltaY });
|
|
// fire real event so cancel listener will trigger
|
|
const event = new Event("wheel", { deltaY: deltaY });
|
|
elem.getDOMNode().dispatchEvent(event);
|
|
|
|
expect(silenceFormStore.data.endsAt.toISOString()).not.toBe(
|
|
oldEndsAt.toISOString()
|
|
);
|
|
const diffMS = silenceFormStore.data.endsAt.diff(oldEndsAt);
|
|
expect(diffMS).toBe(expectedDiff);
|
|
};
|
|
|
|
describe("<TabContentDuration />", () => {
|
|
it("clicking on the day inc button adds 1d to endsAt", () => {
|
|
ValidateDurationButton(0, /angle-up/, 24 * 3600 * 1000);
|
|
});
|
|
|
|
it("scrolling up on the day button adds 1d to endsAt", () => {
|
|
ValidateDurationWheel(0, -1, 24 * 3600 * 1000);
|
|
});
|
|
|
|
it("clicking on the day dec button subtracts 1d from endsAt", () => {
|
|
ValidateDurationButton(2, /angle-down/, -1 * 24 * 3600 * 1000);
|
|
});
|
|
|
|
it("scrolling down on the day button subtracts 1d from endsAt", () => {
|
|
ValidateDurationWheel(0, 1, -1 * 24 * 3600 * 1000);
|
|
});
|
|
|
|
it("clicking on the hour inc button adds 1h to endsAt", () => {
|
|
ValidateDurationButton(3, /angle-up/, 3600 * 1000);
|
|
});
|
|
|
|
it("scrolling up on the hour inc button adds 1h to endsAt", () => {
|
|
ValidateDurationWheel(1, -2, 3600 * 1000);
|
|
});
|
|
|
|
it("clicking on the hour dec button subtracts 1h from endsAt", () => {
|
|
ValidateDurationButton(5, /angle-down/, -1 * 3600 * 1000);
|
|
});
|
|
|
|
it("scrolling down on the hour dec button subtracts 1h from endsAt", () => {
|
|
ValidateDurationWheel(1, 2, -1 * 3600 * 1000);
|
|
});
|
|
|
|
it("clicking on the minute inc button adds 5m to endsAt", () => {
|
|
ValidateDurationButton(6, /angle-up/, 5 * 60 * 1000);
|
|
});
|
|
|
|
it("scrolling up on the minute inc button adds 5m to endsAt", () => {
|
|
ValidateDurationWheel(2, -1, 5 * 60 * 1000);
|
|
});
|
|
|
|
it("clicking on the minute dec button subtracts 5m from endsAt", () => {
|
|
ValidateDurationButton(8, /angle-down/, -1 * 5 * 60 * 1000);
|
|
});
|
|
|
|
it("scrolling down on the minute dec button subtracts 5m from endsAt", () => {
|
|
ValidateDurationWheel(2, 1, -1 * 5 * 60 * 1000);
|
|
});
|
|
});
|
|
|
|
const SetDurationTo = (hours, minutes) => {
|
|
const startsAt = moment([2060, 1, 1, 0, 0, 0]);
|
|
const endsAt = moment(startsAt).add(hours, "hours").add(minutes, "minutes");
|
|
silenceFormStore.data.startsAt = startsAt;
|
|
silenceFormStore.data.endsAt = endsAt;
|
|
};
|
|
|
|
describe("<TabContentDuration /> inc minute CalculateChangeValue", () => {
|
|
it("inc on 0:1:0 duration sets 0:1:5", () => {
|
|
SetDurationTo(1, 0);
|
|
ValidateDurationButton(6, /angle-up/, 5 * 60 * 1000);
|
|
});
|
|
|
|
it("inc on 0:1:1 duration sets 0:1:2", () => {
|
|
SetDurationTo(1, 1);
|
|
ValidateDurationButton(6, /angle-up/, 60 * 1000);
|
|
});
|
|
|
|
it("inc on 0:1:4 duration sets 0:1:5", () => {
|
|
SetDurationTo(1, 4);
|
|
ValidateDurationButton(6, /angle-up/, 60 * 1000);
|
|
});
|
|
|
|
it("inc on 0:1:5 duration sets 0:1:10", () => {
|
|
SetDurationTo(1, 5);
|
|
ValidateDurationButton(6, /angle-up/, 5 * 60 * 1000);
|
|
});
|
|
|
|
it("inc on 0:1:6 duration sets 0:1:10", () => {
|
|
SetDurationTo(1, 6);
|
|
ValidateDurationButton(6, /angle-up/, 4 * 60 * 1000);
|
|
});
|
|
|
|
it("inc on 0:0:55 duration sets 0:1:0", () => {
|
|
SetDurationTo(0, 55);
|
|
ValidateDurationButton(6, /angle-up/, 5 * 60 * 1000);
|
|
});
|
|
});
|
|
|
|
describe("<TabContentDuration /> dec minute CalculateChangeValue", () => {
|
|
it("inc on 0:1:0 duration sets 0:0:55", () => {
|
|
SetDurationTo(1, 0);
|
|
ValidateDurationButton(8, /angle-down/, -5 * 60 * 1000);
|
|
});
|
|
|
|
it("inc on 0:0:59 duration sets 0:0:55", () => {
|
|
SetDurationTo(0, 59);
|
|
ValidateDurationButton(8, /angle-down/, -4 * 60 * 1000);
|
|
});
|
|
|
|
it("inc on 0:0:56 duration sets 0:0:55", () => {
|
|
SetDurationTo(0, 56);
|
|
ValidateDurationButton(8, /angle-down/, -1 * 60 * 1000);
|
|
});
|
|
|
|
it("inc on 0:0:55 duration sets 0:0:50", () => {
|
|
SetDurationTo(1, 0);
|
|
ValidateDurationButton(8, /angle-down/, -5 * 60 * 1000);
|
|
});
|
|
|
|
it("inc on 0:1:10 duration sets 0:1:5", () => {
|
|
SetDurationTo(1, 10);
|
|
ValidateDurationButton(8, /angle-down/, -5 * 60 * 1000);
|
|
});
|
|
|
|
it("inc on 0:1:6 duration sets 0:1:5", () => {
|
|
SetDurationTo(1, 6);
|
|
ValidateDurationButton(8, /angle-down/, -1 * 60 * 1000);
|
|
});
|
|
|
|
it("inc on 0:1:5 duration sets 0:1:0", () => {
|
|
SetDurationTo(1, 5);
|
|
ValidateDurationButton(8, /angle-down/, -5 * 60 * 1000);
|
|
});
|
|
|
|
it("inc on 0:1:4 duration sets 0:1:3", () => {
|
|
SetDurationTo(1, 4);
|
|
ValidateDurationButton(8, /angle-down/, -1 * 60 * 1000);
|
|
});
|
|
|
|
it("inc on 0:1:1 duration sets 0:1:0", () => {
|
|
SetDurationTo(1, 1);
|
|
ValidateDurationButton(8, /angle-down/, -1 * 60 * 1000);
|
|
});
|
|
});
|