UNPKG

@netdata/charts

Version:

Netdata frontend SDK and chart utilities

438 lines 13.5 kB
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } import hoverX from "./hoverX"; import { makeTestChart } from "@jest/testUtilities"; describe("hoverX", function () { var chart, chartUI, hoverXInstance; beforeEach(function () { var testChart = makeTestChart({ attributes: { chartType: "line", overlays: {} } }); chart = testChart.chart; chart.trigger = jest.fn(); chart.updateAttribute = jest.fn(); chartUI = { on: jest.fn().mockReturnThis(), off: jest.fn().mockReturnThis(), getDygraph: jest.fn(function () { return { getArea: jest.fn(function () { return { h: 200 }; }), findStackedPoint: jest.fn(function () { return { point: { canvasy: 100 }, row: 0, seriesName: "test" }; }), findClosestPoint: jest.fn(function () { return { seriesName: "test" }; }), getPropertiesForSeries: jest.fn(function () { return { column: 1 }; }), toDomXCoord: jest.fn(function (x) { return x; }) }; }), sdk: { trigger: jest.fn() }, chart: chart }; hoverXInstance = hoverX(chartUI); }); it("creates hoverX handler", function () { expect(_typeof(hoverX)).toBe("function"); expect(hoverXInstance).toHaveProperty("toggle"); expect(hoverXInstance).toHaveProperty("destroy"); }); it("registers event listeners when toggled on", function () { hoverXInstance.toggle(true); expect(chartUI.on).toHaveBeenCalledWith("highlightCallback", expect.any(Function)); expect(chartUI.on).toHaveBeenCalledWith("mousemove", expect.any(Function)); expect(chartUI.on).toHaveBeenCalledWith("mouseout", expect.any(Function)); expect(chartUI.on).toHaveBeenCalledWith("click", expect.any(Function)); }); it("handles highlight event with valid data", function () { hoverXInstance.toggle(true); var highlightHandler = chartUI.on.mock.calls.find(function (call) { return call[0] === "highlightCallback"; })[1]; var mockEvent = { offsetX: 100, offsetY: 100, stopImmediatePropagation: jest.fn(), preventDefault: jest.fn(), target: { getBoundingClientRect: function getBoundingClientRect() { return { left: 0, top: 0 }; } } }; var xValue = 1640995200000; var points = [{ xval: xValue, yval: 100, idx: 0, name: "test" }]; chart.getPayloadDimensionIds = jest.fn(function () { return ["test"]; }); highlightHandler(mockEvent, xValue, points); expect(chartUI.sdk.trigger).toHaveBeenCalledWith("highlightHover", chart, xValue, "test"); expect(chart.trigger).toHaveBeenCalledWith("highlightHover", xValue, "test"); }); it("handles mouseout event", function () { hoverXInstance.toggle(true); var mouseoutHandler = chartUI.on.mock.calls.find(function (call) { return call[0] === "mouseout"; })[1]; mouseoutHandler(); expect(chartUI.sdk.trigger).toHaveBeenCalledWith("highlightBlur", chart); expect(chart.trigger).toHaveBeenCalledWith("highlightBlur"); }); it("handles annotations area hover", function () { hoverXInstance.toggle(true); var highlightHandler = chartUI.on.mock.calls.find(function (call) { return call[0] === "highlightCallback"; })[1]; var mockEvent = { offsetX: 100, offsetY: 195, target: { getBoundingClientRect: function getBoundingClientRect() { return { left: 0, top: 0 }; } } }; highlightHandler(mockEvent, 1640995200000, []); expect(chartUI.sdk.trigger).not.toHaveBeenCalled(); expect(chart.trigger).not.toHaveBeenCalled(); }); it("handles anomaly rate area hover", function () { hoverXInstance.toggle(true); var highlightHandler = chartUI.on.mock.calls.find(function (call) { return call[0] === "highlightCallback"; })[1]; var mockEvent = { offsetX: 100, offsetY: 10, target: { getBoundingClientRect: function getBoundingClientRect() { return { left: 0, top: 0 }; } } }; highlightHandler(mockEvent, 1640995200000, []); expect(chartUI.sdk.trigger).not.toHaveBeenCalled(); expect(chart.trigger).not.toHaveBeenCalled(); }); it("handles stacked chart type", function () { chart.getAttribute = jest.fn(function (key) { if (key === "chartType") return "stacked"; if (key === "overlays") return {}; return null; }); hoverXInstance.toggle(true); var highlightHandler = chartUI.on.mock.calls.find(function (call) { return call[0] === "highlightCallback"; })[1]; var mockEvent = { offsetX: 100, offsetY: 100, target: { getBoundingClientRect: function getBoundingClientRect() { return { left: 0, top: 0 }; } } }; var points = [{ yval: 10, idx: 0, name: "cpu" }, { yval: 20, idx: 0, name: "memory" }]; chart.getPayloadDimensionIds = jest.fn(function () { return ["cpu", "memory"]; }); highlightHandler(mockEvent, 1640995200000, points); expect(chartUI.sdk.trigger).toHaveBeenCalled(); }); it("triggers SDK hover event", function () { hoverXInstance.toggle(true); var highlightHandler = chartUI.on.mock.calls.find(function (call) { return call[0] === "highlightCallback"; })[1]; var mockEvent = { offsetX: 100, offsetY: 100, target: { getBoundingClientRect: function getBoundingClientRect() { return { left: 0, top: 0 }; } } }; chart.getPayloadDimensionIds = jest.fn(function () { return ["test"]; }); highlightHandler(mockEvent, 1640995200000, []); expect(chartUI.sdk.trigger).toHaveBeenCalledWith("highlightHover", chart, 1640995200000, "test"); }); it("selects heatmap bucket from cursor y instead of dygraph nearest point", function () { var visibleHeatmapIds = ["low", "mid", "high"]; var findClosestPoint = jest.fn(function () { return { seriesName: "low", row: 0 }; }); chart.getAttribute = jest.fn(function (key) { if (key === "chartType") return "heatmap"; if (key === "overlays") return {}; return null; }); chart.getVisibleHeatmapIds = jest.fn(function () { return visibleHeatmapIds; }); chart.getPayloadDimensionIds = jest.fn(function () { return visibleHeatmapIds; }); chartUI.getDygraph = jest.fn(function () { return { getArea: jest.fn(function () { return { h: 200 }; }), findClosestPoint: findClosestPoint, getPropertiesForSeries: jest.fn(function (seriesName) { return { column: visibleHeatmapIds.findIndex(function (id) { return id === seriesName; }) + 1 }; }), toDomYCoord: jest.fn(function (index) { var positions = [150, 100, 50]; return positions[index]; }) }; }); hoverXInstance.toggle(true); var highlightHandler = chartUI.on.mock.calls.find(function (call) { return call[0] === "highlightCallback"; })[1]; highlightHandler({ clientX: 100, clientY: 100, target: { getBoundingClientRect: function getBoundingClientRect() { return { left: 0, top: 0 }; } } }, 1640995200000, []); expect(findClosestPoint).not.toHaveBeenCalled(); expect(chartUI.sdk.trigger).toHaveBeenCalledWith("highlightHover", chart, 1640995200000, "mid"); }); it("handles destroy method", function () { hoverXInstance.toggle(true); hoverXInstance.destroy(); expect(chartUI.off).toHaveBeenCalledWith("highlightCallback", expect.any(Function)); expect(chartUI.off).toHaveBeenCalledWith("mousemove", expect.any(Function)); expect(chartUI.off).toHaveBeenCalledWith("mouseout", expect.any(Function)); expect(chartUI.off).toHaveBeenCalledWith("click", expect.any(Function)); }); it("deduplicates repeated hover events at same position", function () { hoverXInstance.toggle(true); var highlightHandler = chartUI.on.mock.calls.find(function (call) { return call[0] === "highlightCallback"; })[1]; var mockEvent = { offsetX: 100, offsetY: 100, stopImmediatePropagation: jest.fn(), preventDefault: jest.fn(), target: { getBoundingClientRect: function getBoundingClientRect() { return { left: 0, top: 0 }; } } }; var xValue = 1640995200000; var points = [{ idx: 0, name: "test" }]; chart.getPayloadDimensionIds = jest.fn(function () { return ["test"]; }); highlightHandler(mockEvent, xValue, points); expect(chartUI.sdk.trigger).toHaveBeenCalledTimes(1); highlightHandler(mockEvent, xValue, points); expect(chartUI.sdk.trigger).toHaveBeenCalledTimes(1); highlightHandler(mockEvent, xValue + 60000, points); expect(chartUI.sdk.trigger).toHaveBeenCalledTimes(2); }); it("handles click event for annotations", function () { hoverXInstance.toggle(true); var clickHandler = chartUI.on.mock.calls.find(function (call) { return call[0] === "click"; })[1]; var mockEvent = { offsetX: 100, offsetY: 100, target: { getBoundingClientRect: function getBoundingClientRect() { return { left: 0, top: 0 }; } } }; chart.getPayloadDimensionIds = jest.fn(function () { return ["test"]; }); clickHandler(mockEvent, 1640995200000, []); expect(chart.updateAttribute).toHaveBeenCalledWith("draftAnnotation", expect.objectContaining({ timestamp: 1640995200, status: "draft" })); expect(chart.trigger).toHaveBeenCalledWith("annotationCreate", 1640995200); expect(chartUI.sdk.trigger).toHaveBeenCalledWith("annotationCreate", expect.objectContaining({ trigger: chart.trigger, getAttribute: chart.getAttribute }), 1640995200); }); it("skips annotation creation near existing annotations", function () { chart.getAttribute = jest.fn(function (key) { if (key === "overlays") return { 1: { type: "annotation", timestamp: 1640995200 } }; return null; }); chartUI.getDygraph = jest.fn(function () { return { getArea: jest.fn(function () { return { h: 200 }; }), findClosestPoint: jest.fn(function () { return { seriesName: "test" }; }), getPropertiesForSeries: jest.fn(function () { return { column: 1 }; }), toDomXCoord: jest.fn(function (timestamp) { if (timestamp === 1640995200 * 1000) return 105; return timestamp; }) }; }); hoverXInstance.toggle(true); var clickHandler = chartUI.on.mock.calls.find(function (call) { return call[0] === "click"; })[1]; var mockEvent = { clientX: 105, clientY: 100, target: { getBoundingClientRect: function getBoundingClientRect() { return { left: 0, top: 0 }; } } }; chart.getPayloadDimensionIds = jest.fn(function () { return ["test"]; }); clickHandler(mockEvent, 1640995200000, []); expect(chart.updateAttribute).not.toHaveBeenCalledWith("draftAnnotation", expect.anything()); }); it("handles mousemove event", function () { hoverXInstance.toggle(true); var highlightHandler = chartUI.on.mock.calls.find(function (call) { return call[0] === "highlightCallback"; })[1]; var mousemoveHandler = chartUI.on.mock.calls.find(function (call) { return call[0] === "mousemove"; })[1]; chart.getPayloadDimensionIds = jest.fn(function () { return ["test"]; }); highlightHandler({ offsetX: 100, offsetY: 100, target: { getBoundingClientRect: function getBoundingClientRect() { return { left: 0, top: 0 }; } } }, 1640995200000, []); var mockEvent = { offsetX: 200, offsetY: 150, target: { getBoundingClientRect: function getBoundingClientRect() { return { left: 0, top: 0 }; } } }; mousemoveHandler(mockEvent); expect(chartUI.sdk.trigger).toHaveBeenCalledWith("highlightHover", chart, 1640995200000, "test"); }); });