Skip to content

Commit 328e483

Browse files
committed
refactor: clean up heavy test case
1 parent 69af1f6 commit 328e483

File tree

2 files changed

+121
-113
lines changed

2 files changed

+121
-113
lines changed
Lines changed: 22 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,109 +1,22 @@
1-
import $ from "jquery";
2-
import type { ComponentChildren } from "preact";
31
import { render } from "preact";
42
import { act } from "preact/test-utils";
53
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
64

7-
const {
8-
triliumEventHandlers,
9-
latestModalPropsRef,
10-
latestNoteAutocompletePropsRef,
11-
addLinkSpy,
12-
logErrorSpy,
13-
showRecentNotesSpy,
14-
setTextSpy
15-
} = vi.hoisted(() => ({
16-
triliumEventHandlers: new Map<string, (payload: any) => void>(),
17-
latestModalPropsRef: { current: null as any },
18-
latestNoteAutocompletePropsRef: { current: null as any },
19-
addLinkSpy: vi.fn(() => Promise.resolve()),
20-
logErrorSpy: vi.fn(),
21-
showRecentNotesSpy: vi.fn(),
22-
setTextSpy: vi.fn()
23-
}));
24-
25-
vi.mock("../../services/i18n", () => ({
26-
t: (key: string) => key
27-
}));
28-
29-
vi.mock("../../services/tree", () => ({
30-
default: {
31-
getNoteIdFromUrl: (notePath: string) => notePath.split("/").at(-1),
32-
getNoteTitle: vi.fn(async () => "Target note")
33-
}
34-
}));
35-
36-
vi.mock("../../services/ws", () => ({
37-
logError: logErrorSpy
38-
}));
39-
40-
vi.mock("../../services/note_autocomplete", () => ({
41-
__esModule: true,
42-
default: {
43-
showRecentNotes: showRecentNotesSpy,
44-
setText: setTextSpy
45-
}
46-
}));
47-
48-
vi.mock("../react/react_utils", () => ({
49-
refToJQuerySelector: (ref: { current: HTMLInputElement | null }) => ref.current ? $(ref.current) : $()
50-
}));
51-
52-
vi.mock("../react/hooks", () => ({
53-
useTriliumEvent: (name: string, handler: (payload: any) => void) => {
54-
triliumEventHandlers.set(name, handler);
55-
}
56-
}));
57-
58-
vi.mock("../react/Modal", () => ({
59-
default: (props: any) => {
60-
latestModalPropsRef.current = props;
61-
62-
if (!props.show) {
63-
return null;
64-
}
65-
66-
return (
67-
<form onSubmit={(e) => {
68-
e.preventDefault();
69-
props.onSubmit?.();
70-
}}>
71-
{props.children}
72-
{props.footer}
73-
</form>
74-
);
75-
}
76-
}));
77-
78-
vi.mock("../react/FormGroup", () => ({
79-
default: ({ children }: { children: ComponentChildren }) => <div>{children}</div>
80-
}));
81-
82-
vi.mock("../react/Button", () => ({
83-
default: ({ text }: { text: string }) => <button type="submit">{text}</button>
84-
}));
85-
86-
vi.mock("../react/FormRadioGroup", () => ({
87-
default: () => null
88-
}));
89-
90-
vi.mock("../react/NoteAutocomplete", () => ({
91-
default: (props: any) => {
92-
latestNoteAutocompletePropsRef.current = props;
93-
return <input ref={props.inputRef} />;
94-
}
95-
}));
96-
97-
import AddLinkDialog from "./add_link";
5+
import { type AddLinkDialogTestState,createAddLinkDialogTestState, setupAddLinkDialogMocks } from "./add_link.spec_utils";
986

997
describe("AddLinkDialog", () => {
1008
let container: HTMLDivElement;
9+
let AddLinkDialog: (props: object) => JSX.Element;
10+
let state: AddLinkDialogTestState;
10111

102-
beforeEach(() => {
12+
beforeEach(async () => {
13+
vi.resetModules();
14+
state = createAddLinkDialogTestState();
10315
vi.clearAllMocks();
104-
latestModalPropsRef.current = null;
105-
latestNoteAutocompletePropsRef.current = null;
106-
triliumEventHandlers.clear();
16+
setupAddLinkDialogMocks(state);
17+
18+
({ default: AddLinkDialog } = await import("./add_link"));
19+
10720
container = document.createElement("div");
10821
document.body.appendChild(container);
10922
});
@@ -120,41 +33,37 @@ describe("AddLinkDialog", () => {
12033
render(<AddLinkDialog />, container);
12134
});
12235

123-
const showDialog = triliumEventHandlers.get("showAddLinkDialog");
124-
expect(showDialog).toBeTypeOf("function");
36+
const showDialog = state.triliumEventHandlers.get("showAddLinkDialog");
37+
if (!showDialog) {
38+
throw new Error("showAddLinkDialog handler was not registered");
39+
}
12540

12641
await act(async () => {
127-
showDialog?.({
42+
showDialog({
12843
text: "",
12944
hasSelection: false,
130-
addLink: addLinkSpy
45+
addLink: state.addLinkSpy
13146
});
13247
});
13348

134-
const suggestion = {
135-
notePath: "root/target-note",
136-
noteTitle: "Target note"
137-
};
138-
13949
act(() => {
140-
latestNoteAutocompletePropsRef.current.onKeyDownCapture({
50+
state.latestNoteAutocompletePropsRef.current.onKeyDownCapture({
14151
key: "Enter",
14252
ctrlKey: false,
14353
metaKey: false,
14454
shiftKey: false,
14555
altKey: false,
14656
isComposing: false
14757
});
148-
latestNoteAutocompletePropsRef.current.onChange(suggestion);
58+
state.latestNoteAutocompletePropsRef.current.onChange({
59+
notePath: "root/target-note"
60+
});
14961
});
15062

151-
expect(latestModalPropsRef.current.show).toBe(false);
152-
expect(logErrorSpy).not.toHaveBeenCalled();
153-
15463
await act(async () => {
155-
latestModalPropsRef.current.onHidden();
64+
state.latestModalPropsRef.current.onHidden();
15665
});
15766

158-
expect(addLinkSpy).toHaveBeenCalledWith("root/target-note", null);
67+
expect(state.addLinkSpy).toHaveBeenCalledWith("root/target-note", null);
15968
});
16069
});
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import $ from "jquery";
2+
import type { ComponentChildren } from "preact";
3+
import { vi } from "vitest";
4+
5+
export interface AddLinkDialogTestState {
6+
triliumEventHandlers: Map<string, (payload: any) => void>;
7+
latestModalPropsRef: { current: any };
8+
latestNoteAutocompletePropsRef: { current: any };
9+
addLinkSpy: ReturnType<typeof vi.fn>;
10+
logErrorSpy: ReturnType<typeof vi.fn>;
11+
showRecentNotesSpy: ReturnType<typeof vi.fn>;
12+
setTextSpy: ReturnType<typeof vi.fn>;
13+
}
14+
15+
export function createAddLinkDialogTestState(): AddLinkDialogTestState {
16+
return {
17+
triliumEventHandlers: new Map<string, (payload: any) => void>(),
18+
latestModalPropsRef: { current: null as any },
19+
latestNoteAutocompletePropsRef: { current: null as any },
20+
addLinkSpy: vi.fn(() => Promise.resolve()),
21+
logErrorSpy: vi.fn(),
22+
showRecentNotesSpy: vi.fn(),
23+
setTextSpy: vi.fn()
24+
};
25+
}
26+
27+
export function setupAddLinkDialogMocks(state: AddLinkDialogTestState) {
28+
vi.doMock("../../services/i18n", () => ({
29+
t: (key: string) => key
30+
}));
31+
32+
vi.doMock("../../services/tree", () => ({
33+
default: {
34+
getNoteIdFromUrl: (notePath: string) => notePath.split("/").at(-1),
35+
getNoteTitle: vi.fn(async () => "Target note")
36+
}
37+
}));
38+
39+
vi.doMock("../../services/ws", () => ({
40+
logError: state.logErrorSpy
41+
}));
42+
43+
vi.doMock("../../services/note_autocomplete", () => ({
44+
__esModule: true,
45+
default: {
46+
showRecentNotes: state.showRecentNotesSpy,
47+
setText: state.setTextSpy
48+
}
49+
}));
50+
51+
vi.doMock("../react/react_utils", () => ({
52+
refToJQuerySelector: (ref: { current: HTMLInputElement | null }) => ref.current ? $(ref.current) : $()
53+
}));
54+
55+
vi.doMock("../react/hooks", () => ({
56+
useTriliumEvent: (name: string, handler: (payload: any) => void) => {
57+
state.triliumEventHandlers.set(name, handler);
58+
}
59+
}));
60+
61+
vi.doMock("../react/Modal", () => ({
62+
default: (props: any) => {
63+
state.latestModalPropsRef.current = props;
64+
65+
if (!props.show) {
66+
return null;
67+
}
68+
69+
return (
70+
<form onSubmit={(e) => {
71+
e.preventDefault();
72+
props.onSubmit?.();
73+
}}>
74+
{props.children}
75+
{props.footer}
76+
</form>
77+
);
78+
}
79+
}));
80+
81+
vi.doMock("../react/FormGroup", () => ({
82+
default: ({ children }: { children: ComponentChildren }) => <div>{children}</div>
83+
}));
84+
85+
vi.doMock("../react/Button", () => ({
86+
default: ({ text }: { text: string }) => <button type="submit">{text}</button>
87+
}));
88+
89+
vi.doMock("../react/FormRadioGroup", () => ({
90+
default: () => null
91+
}));
92+
93+
vi.doMock("../react/NoteAutocomplete", () => ({
94+
default: (props: any) => {
95+
state.latestNoteAutocompletePropsRef.current = props;
96+
return <input ref={props.inputRef} />;
97+
}
98+
}));
99+
}

0 commit comments

Comments
 (0)