PluginProbe ʕ •ᴥ•ʔ
Presto Player / 4.3.2
Presto Player v4.3.2
4.3.2 4.3.1 4.3.0 4.2.4 4.2.3 4.2.2 4.2.0 4.2.1 trunk 1.10.0 1.10.1 1.10.2 1.11.0 1.12.0 1.13.0 1.14.0 1.14.1 1.5.10 1.5.11 1.5.12 1.5.13 1.5.14 1.5.15 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.10 1.6.11 1.6.12 1.6.13 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.2.0 2.2.1 2.2.2 2.2.3 2.2.3-beta1 2.3.0 2.3.1 2.3.2 2.3.3 3.0.0 3.0.0-beta1 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.1.0 3.1.1 3.1.2 3.1.3 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4
presto-player / src / admin / dashboard / hooks / test / useCompleteOnboarding.spec.js
presto-player / src / admin / dashboard / hooks / test Last commit date
useCompleteOnboarding.spec.js 1 month ago useDateRangePicker.spec.js 2 months ago useEmail.spec.js 2 months ago useEngagementChartData.spec.js 2 months ago useLicenseSettings.spec.js 2 months ago useLink.spec.js 2 months ago useMediaDetail.spec.js 2 months ago useMediaLibrary.spec.js 2 months ago useMediaList.spec.js 1 month ago usePerformanceSettings.spec.js 2 months ago useRegisterActivePage.spec.js 2 months ago useSettingOption.spec.js 2 months ago useSimpleSettingsPage.spec.js 2 months ago useTopPerforming.spec.js 2 months ago useTopVideosPaginated.spec.js 2 months ago useUpgradeCTA.spec.js 2 months ago useUserDetail.spec.js 2 months ago
useCompleteOnboarding.spec.js
169 lines
1 import { renderHook, act } from "@testing-library/react-hooks";
2 import apiFetch from "@wordpress/api-fetch";
3 import useCompleteOnboarding, {
4 __resetInFlightForTests,
5 } from "../useCompleteOnboarding";
6
7 jest.mock("@wordpress/api-fetch");
8
9 let originalLocation;
10
11 beforeEach(() => {
12 apiFetch.mockReset();
13 __resetInFlightForTests();
14
15 originalLocation = window.location;
16 delete window.location;
17 window.location = { href: "" };
18 });
19
20 afterEach(() => {
21 window.location = originalLocation;
22 delete window.prestoPlayer;
23 });
24
25 describe("useCompleteOnboarding", () => {
26 it("POSTs the completed status and redirects on success", async () => {
27 apiFetch.mockResolvedValueOnce({ ok: true });
28
29 const { result } = renderHook(() => useCompleteOnboarding());
30 await act(async () => {
31 await result.current.completeOnboarding("admin.php?page=done");
32 });
33
34 expect(apiFetch).toHaveBeenCalledWith({
35 path: "/presto-player/v1/onboarding/set-status",
36 method: "POST",
37 data: { status: "completed" },
38 });
39 expect(window.location.href).toBe("admin.php?page=done");
40 });
41
42 it("redirects even when the API call fails (best-effort completion)", async () => {
43 const errorSpy = jest
44 .spyOn(console, "error")
45 .mockImplementation(() => {});
46 apiFetch.mockRejectedValueOnce(new Error("server"));
47
48 const { result } = renderHook(() => useCompleteOnboarding());
49 await act(async () => {
50 await result.current.completeOnboarding("admin.php?page=done");
51 });
52
53 expect(window.location.href).toBe("admin.php?page=done");
54 expect(errorSpy).toHaveBeenCalled();
55 errorSpy.mockRestore();
56 });
57
58 it("ignores re-entrant calls while a submission is in flight", async () => {
59 let resolveFetch;
60 apiFetch.mockReturnValueOnce(
61 new Promise((res) => {
62 resolveFetch = res;
63 })
64 );
65
66 const { result } = renderHook(() => useCompleteOnboarding());
67
68 let firstPending;
69 act(() => {
70 firstPending = result.current.completeOnboarding("first");
71 });
72
73 await act(async () => {
74 // Second call should short-circuit (no second apiFetch).
75 await result.current.completeOnboarding("second");
76 });
77
78 expect(apiFetch).toHaveBeenCalledTimes(1);
79
80 await act(async () => {
81 resolveFetch({ ok: true });
82 await firstPending;
83 });
84
85 expect(window.location.href).toBe("first");
86 });
87
88 it("blocks exit from another hook instance while a completion is in flight", async () => {
89 let resolveFetch;
90 apiFetch.mockReturnValueOnce(
91 new Promise((res) => {
92 resolveFetch = res;
93 })
94 );
95
96 // Two instances, like the premium step's button and the topbar Exit.
97 const first = renderHook(() => useCompleteOnboarding());
98 const second = renderHook(() => useCompleteOnboarding());
99
100 let completePending;
101 act(() => {
102 completePending = first.result.current.completeOnboarding("license-page");
103 });
104
105 await act(async () => {
106 await second.result.current.exitOnboarding("premium_features");
107 });
108
109 expect(apiFetch).toHaveBeenCalledTimes(1);
110
111 await act(async () => {
112 resolveFetch({ ok: true });
113 await completePending;
114 });
115
116 expect(window.location.href).toBe("license-page");
117 });
118
119 describe("exitOnboarding", () => {
120 it("POSTs a skip with the step id and redirects to the dashboard", async () => {
121 window.prestoPlayer = { dashboardUrl: "admin.php?page=presto-dashboard&custom" };
122 apiFetch.mockResolvedValueOnce({ ok: true });
123
124 const { result } = renderHook(() => useCompleteOnboarding());
125 await act(async () => {
126 await result.current.exitOnboarding("premium_features");
127 });
128
129 expect(apiFetch).toHaveBeenCalledWith({
130 path: "/presto-player/v1/onboarding/set-status",
131 method: "POST",
132 data: { status: "skipped", skipped_on_step: "premium_features" },
133 });
134 expect(window.location.href).toBe("admin.php?page=presto-dashboard&custom");
135 });
136
137 it("records a completion when exiting from the done step", async () => {
138 apiFetch.mockResolvedValueOnce({ ok: true });
139
140 const { result } = renderHook(() => useCompleteOnboarding());
141 await act(async () => {
142 await result.current.exitOnboarding(null);
143 });
144
145 expect(apiFetch).toHaveBeenCalledWith({
146 path: "/presto-player/v1/onboarding/set-status",
147 method: "POST",
148 data: { status: "completed" },
149 });
150 expect(window.location.href).toBe("admin.php?page=presto-dashboard");
151 });
152
153 it("redirects even when the API call fails", async () => {
154 const errorSpy = jest
155 .spyOn(console, "error")
156 .mockImplementation(() => {});
157 apiFetch.mockRejectedValueOnce(new Error("server"));
158
159 const { result } = renderHook(() => useCompleteOnboarding());
160 await act(async () => {
161 await result.current.exitOnboarding("welcome");
162 });
163
164 expect(window.location.href).toBe("admin.php?page=presto-dashboard");
165 errorSpy.mockRestore();
166 });
167 });
168 });
169