Skip to content

Commit 6cc8269

Browse files
committed
test: resolve React act warnings
1 parent c5ed8a2 commit 6cc8269

3 files changed

Lines changed: 28 additions & 17 deletions

File tree

‎src/components/centre/CommitBox.test.tsx‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @vitest-environment jsdom
22
import React from "react";
3-
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
3+
import { act, fireEvent, render, screen, waitFor } from "@testing-library/react";
44
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
55
import { CommitBox } from "./CommitBox";
66
import type { CommitPrimaryAction } from "../../types";
@@ -50,7 +50,7 @@ function renderCommitBox({
5050
mergeMessage,
5151
mergeInProgress,
5252
}: RenderCommitBoxOptions = {}) {
53-
const onCommit = vi.fn();
53+
const onCommit = vi.fn(() => false);
5454
const onSelectAction = vi.fn();
5555

5656
const view = render(
@@ -79,7 +79,7 @@ describe("CommitBox", () => {
7979
vi.stubGlobal("localStorage", makeLocalStorage());
8080
localStorage.removeItem(COMMIT_BOX_RATIO_KEY);
8181
getCommitMessageRecovery.mockClear();
82-
getCommitMessageRecovery.mockResolvedValue(null);
82+
getCommitMessageRecovery.mockReturnValue(new Promise(() => {}));
8383
});
8484

8585
afterEach(() => {
@@ -259,16 +259,20 @@ describe("CommitBox", () => {
259259
});
260260

261261
it("does not offer COMMIT_EDITMSG recovery for the latest commit message", async () => {
262-
getCommitMessageRecovery.mockResolvedValue({
262+
const recovery = Promise.resolve({
263263
message: "Publish tide report\n\nNo new recovery copy.",
264264
updatedAt: 1,
265265
});
266+
getCommitMessageRecovery.mockReturnValue(recovery);
266267
renderCommitBox({
267268
repoPath,
268269
lastCommitMessage: "Publish tide report\n\nNo new recovery copy.",
269270
});
270271

271-
await waitFor(() => expect(getCommitMessageRecovery).toHaveBeenCalled());
272+
await act(async () => {
273+
await recovery;
274+
});
275+
expect(getCommitMessageRecovery).toHaveBeenCalled();
272276
expect(screen.queryByRole("button", {name: "Restore previous message"})).not.toBeInTheDocument();
273277
});
274278

‎src/components/centre/StagingView.test.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import "../../i18n";
77
import { StagingView } from "./StagingView";
88

99
vi.mock("../../api/commands", () => ({
10-
getCommitMessageRecovery: vi.fn(async () => null),
10+
getCommitMessageRecovery: vi.fn(() => new Promise(() => {})),
1111
getNumstat: vi.fn(),
1212
}));
1313

‎src/components/settings/SettingsWindow.test.tsx‎

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
// @vitest-environment jsdom
22
import React from "react";
33
import {fireEvent, render, screen, waitFor} from "@testing-library/react";
4-
import {beforeEach, describe, expect, it, vi} from "vitest";
4+
import {afterEach, beforeEach, describe, expect, it, vi} from "vitest";
55
import type {Settings} from "../../types";
66
import "../../i18n";
77

88
const mocks = vi.hoisted(() => ({
99
close: vi.fn(),
1010
emit: vi.fn(async () => {}),
11+
getAppUpdateChannel: vi.fn(async () => "SystemManaged"),
1112
openDialog: vi.fn(),
1213
openPath: vi.fn(),
1314
invoke: vi.fn(),
@@ -88,7 +89,7 @@ vi.mock("@tauri-apps/plugin-dialog", () => ({open: mocks.openDialog}));
8889
vi.mock("@tauri-apps/plugin-opener", () => ({openPath: mocks.openPath}));
8990
vi.mock("@tauri-apps/plugin-os", () => ({platform: () => "linux"}));
9091
vi.mock("../../api/commands", () => ({
91-
getAppUpdateChannel: vi.fn(async () => "SystemManaged"),
92+
getAppUpdateChannel: mocks.getAppUpdateChannel,
9293
getConfigFilePath: vi.fn(async () => "/home/conor/.config/gitmun/config.toml"),
9394
getConfigFolderPath: vi.fn(async () => "/home/conor/.config/gitmun"),
9495
getGlobalDiffToolPath: vi.fn(async () => null),
@@ -111,6 +112,8 @@ describe("SettingsWindow", () => {
111112
mocks.invoke.mockClear();
112113
mocks.invoke.mockImplementation(defaultInvoke);
113114
mocks.emit.mockClear();
115+
mocks.getAppUpdateChannel.mockClear();
116+
mocks.getAppUpdateChannel.mockResolvedValue("SystemManaged");
114117
mocks.close.mockClear();
115118
const store = new Map<string, string>();
116119
vi.stubGlobal("localStorage", {
@@ -135,14 +138,12 @@ describe("SettingsWindow", () => {
135138
});
136139
});
137140

138-
it("shows a skeleton while settings are loading", () => {
139-
mocks.invoke.mockImplementation((command: string) => {
140-
if (command === "get_settings") {
141-
return new Promise(() => {});
142-
}
141+
afterEach(() => {
142+
vi.restoreAllMocks();
143+
});
143144

144-
return defaultInvoke(command);
145-
});
145+
it("shows a skeleton while settings are loading", () => {
146+
mocks.getAppUpdateChannel.mockReturnValue(new Promise(() => {}));
146147

147148
render(<SettingsWindow/>);
148149

@@ -178,9 +179,11 @@ describe("SettingsWindow", () => {
178179
});
179180

180181
it("shows an error when settings fail to load", async () => {
182+
const loadError = new Error("config unavailable");
183+
const consoleError = vi.spyOn(console, "error").mockImplementation(() => {});
181184
mocks.invoke.mockImplementation((command: string) => {
182185
if (command === "get_settings") {
183-
return Promise.reject(new Error("config unavailable"));
186+
return Promise.reject(loadError);
184187
}
185188

186189
return defaultInvoke(command);
@@ -191,15 +194,18 @@ describe("SettingsWindow", () => {
191194
expect(await screen.findByRole("alert")).toHaveTextContent("Settings could not be loaded");
192195
expect(screen.getByRole("button", {name: "Retry"})).toBeInTheDocument();
193196
expect(screen.queryByTestId("settings-skeleton")).not.toBeInTheDocument();
197+
expect(consoleError).toHaveBeenCalledWith("Failed to load settings", loadError);
194198
});
195199

196200
it("retries loading settings when retry is clicked", async () => {
201+
const loadError = new Error("config unavailable");
202+
const consoleError = vi.spyOn(console, "error").mockImplementation(() => {});
197203
let getSettingsCalls = 0;
198204
mocks.invoke.mockImplementation((command: string) => {
199205
if (command === "get_settings") {
200206
getSettingsCalls += 1;
201207
if (getSettingsCalls === 1) {
202-
return Promise.reject(new Error("config unavailable"));
208+
return Promise.reject(loadError);
203209
}
204210
}
205211

@@ -213,6 +219,7 @@ describe("SettingsWindow", () => {
213219
expect(await screen.findByLabelText("Terminal")).toBeInTheDocument();
214220
expect(screen.queryByRole("alert")).not.toBeInTheDocument();
215221
expect(getSettingsCalls).toBe(2);
222+
expect(consoleError).toHaveBeenCalledWith("Failed to load settings", loadError);
216223
});
217224

218225
it("shows the Linux custom terminal command only for Custom", async () => {

0 commit comments

Comments
 (0)