Skip to content

Commit 3cfa87d

Browse files
committed
test: harden exisiting tests for js/widgets/statistics.js
1 parent 36ac918 commit 3cfa87d

File tree

1 file changed

+82
-5
lines changed

1 file changed

+82
-5
lines changed

js/widgets/statistics.test.js

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
const StatsWindow = require("./statistics.js");
2424

2525
describe("StatsWindow", () => {
26-
let activity, widgetWin, body, capturedCb;
26+
let activity, widgetWin, body, capturedCb, myChartMock, radarMock;
2727

2828
beforeEach(() => {
2929
capturedCb = null;
@@ -58,7 +58,8 @@ describe("StatsWindow", () => {
5858
windowFor: jest.fn().mockReturnValue(widgetWin)
5959
};
6060

61-
global.docById = jest.fn().mockReturnValue({ getContext: jest.fn().mockReturnValue({}) });
61+
myChartMock = { getContext: jest.fn().mockReturnValue({}) };
62+
global.docById = jest.fn().mockReturnValue(myChartMock);
6263

6364
global.analyzeProject = jest.fn().mockReturnValue({});
6465
global.runAnalytics = jest.fn();
@@ -68,10 +69,11 @@ describe("StatsWindow", () => {
6869
return {};
6970
});
7071

72+
radarMock = {
73+
toBase64Image: jest.fn().mockReturnValue("data:image/png;base64,fakedata")
74+
};
7175
global.Chart = jest.fn().mockImplementation(() => ({
72-
Radar: jest.fn().mockReturnValue({
73-
toBase64Image: jest.fn().mockReturnValue("data:image/png;base64,fakedata")
74-
})
76+
Radar: jest.fn().mockReturnValue(radarMock)
7577
}));
7678
});
7779

@@ -118,6 +120,22 @@ describe("StatsWindow", () => {
118120
expect(body.style.padding).toBe("0px 0px");
119121
});
120122

123+
test("onmaximize clears existing body content before rerender", () => {
124+
const sw = new StatsWindow(activity);
125+
const staleNode = document.createElement("p");
126+
staleNode.textContent = "stale";
127+
body.appendChild(staleNode);
128+
const previousJsonObject = sw.jsonObject;
129+
global.analyzeProject.mockClear();
130+
131+
widgetWin.isMaximized.mockReturnValue(false);
132+
widgetWin.onmaximize();
133+
134+
expect(body.textContent).not.toContain("stale");
135+
expect(sw.jsonObject).not.toBe(previousJsonObject);
136+
expect(global.analyzeProject).toHaveBeenCalledTimes(1);
137+
});
138+
121139
test("chart callback sets img width to 200 when not maximized", () => {
122140
widgetWin.isMaximized.mockReturnValue(false);
123141
const sw = new StatsWindow(activity);
@@ -143,6 +161,65 @@ describe("StatsWindow", () => {
143161
expect(imgs[imgs.length - 1].width).toBe(420); // 500 - 80
144162
});
145163

164+
test("doAnalytics initializes chart with canvas context and analytics data", () => {
165+
const chartData = { labels: ["a"] };
166+
const chartOptions = { responsive: true };
167+
global.scoreToChartData.mockReturnValue(chartData);
168+
global.getChartOptions.mockImplementation(cb => {
169+
capturedCb = cb;
170+
return chartOptions;
171+
});
172+
173+
const sw = new StatsWindow(activity);
174+
175+
expect(global.docById).toHaveBeenCalledWith("myChart");
176+
expect(myChartMock.getContext).toHaveBeenCalledWith("2d");
177+
expect(global.scoreToChartData).toHaveBeenCalledWith({});
178+
expect(global.getChartOptions).toHaveBeenCalledWith(expect.any(Function));
179+
expect(global.Chart).toHaveBeenCalledWith(myChartMock.getContext.mock.results[0].value);
180+
expect(activity.blocks.activeBlock).toBeNull();
181+
expect(document.body.style.cursor).toBe("wait");
182+
expect(activity.loading).toBe(true);
183+
});
184+
185+
test("doAnalytics appends json list container with left float style", () => {
186+
const sw = new StatsWindow(activity);
187+
188+
expect(sw.jsonObject).toBeInstanceOf(HTMLUListElement);
189+
expect(sw.jsonObject.style.float).toBe("left");
190+
expect(body.lastChild).toBe(sw.jsonObject);
191+
});
192+
193+
test("chart callback reads base64 image from radar chart", () => {
194+
const sw = new StatsWindow(activity);
195+
196+
capturedCb();
197+
198+
expect(radarMock.toBase64Image).toHaveBeenCalled();
199+
const imgs = body.querySelectorAll("img");
200+
expect(imgs[imgs.length - 1].src).toContain("data:image/png;base64,fakedata");
201+
});
202+
203+
test("chart callback appends chart image after stats list", () => {
204+
const sw = new StatsWindow(activity);
205+
206+
capturedCb();
207+
208+
expect(body.children[0]).toBe(sw.jsonObject);
209+
expect(body.children[body.children.length - 1].tagName).toBe("IMG");
210+
});
211+
212+
test("onmaximize reruns analytics and updates chart callback reference", () => {
213+
const sw = new StatsWindow(activity);
214+
const firstCb = capturedCb;
215+
global.getChartOptions.mockClear();
216+
217+
widgetWin.onmaximize();
218+
219+
expect(global.getChartOptions).toHaveBeenCalledTimes(1);
220+
expect(capturedCb).not.toBe(firstCb);
221+
});
222+
146223
test("displayInfo renders all stats fields with correct Hz", () => {
147224
const sw = new StatsWindow(activity);
148225

0 commit comments

Comments
 (0)