Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite26ba1a

Browse files
feat(site): do not show popover on update deadline (#11921)
1 parentdcab6fa commite26ba1a

File tree

3 files changed

+243
-247
lines changed

3 files changed

+243
-247
lines changed

‎site/src/api/queries/workspaces.ts‎

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import*asAPIfrom"api/api";
2-
import{QueryClient,typeQueryOptions}from"react-query";
2+
import{
3+
QueryClient,
4+
UseMutationOptions,
5+
typeQueryOptions,
6+
}from"react-query";
37
import{putWorkspaceExtension}from"api/api";
4-
importdayjsfrom"dayjs";
5-
import{getDeadline,getMaxDeadline,getMinDeadline}from"utils/schedule";
8+
import{Dayjs}from"dayjs";
69
import{
710
typeWorkspaceBuildParameter,
811
typeWorkspace,
@@ -103,25 +106,12 @@ export function workspaces(config: WorkspacesRequest = {}) {
103106
}asconstsatisfiesQueryOptions<WorkspacesResponse>;
104107
}
105108

106-
exportconstdecreaseDeadline=(workspace:Workspace)=>{
107-
return{
108-
mutationFn:(hours:number)=>{
109-
constproposedDeadline=getDeadline(workspace).subtract(hours,"hours");
110-
constnewDeadline=dayjs.max(proposedDeadline,getMinDeadline());
111-
returnputWorkspaceExtension(workspace.id,newDeadline);
112-
},
113-
};
114-
};
115-
116-
exportconstincreaseDeadline=(workspace:Workspace)=>{
109+
exportconstupdateDeadline=(
110+
workspace:Workspace,
111+
):UseMutationOptions<void,unknown,Dayjs>=>{
117112
return{
118-
mutationFn:(hours:number)=>{
119-
constproposedDeadline=getDeadline(workspace).add(hours,"hours");
120-
constnewDeadline=dayjs.min(
121-
proposedDeadline,
122-
getMaxDeadline(workspace),
123-
);
124-
returnputWorkspaceExtension(workspace.id,newDeadline);
113+
mutationFn:(deadline:Dayjs)=>{
114+
returnputWorkspaceExtension(workspace.id,deadline);
125115
},
126116
};
127117
};
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import{render,screen}from"@testing-library/react";
2+
import{ThemeProvider}from"contexts/ThemeProvider";
3+
import{QueryClient,QueryClientProvider,useQuery}from"react-query";
4+
import{MockWorkspace}from"testHelpers/entities";
5+
import{WorkspaceScheduleControls}from"./WorkspaceScheduleControls";
6+
import{workspaceByOwnerAndName}from"api/queries/workspaces";
7+
import{RouterProvider,createMemoryRouter}from"react-router-dom";
8+
importuserEventfrom"@testing-library/user-event";
9+
import{server}from"testHelpers/server";
10+
import{rest}from"msw";
11+
importdayjsfrom"dayjs";
12+
import*asAPIfrom"api/api";
13+
import{GlobalSnackbar}from"components/GlobalSnackbar/GlobalSnackbar";
14+
15+
constWrapper=()=>{
16+
const{data:workspace}=useQuery(
17+
workspaceByOwnerAndName(MockWorkspace.owner_name,MockWorkspace.name),
18+
);
19+
20+
if(!workspace){
21+
returnnull;
22+
}
23+
24+
return<WorkspaceScheduleControlsworkspace={workspace}canUpdateSchedule/>;
25+
};
26+
27+
constBASE_DEADLINE=dayjs().add(3,"hour");
28+
29+
constrenderScheduleControls=async()=>{
30+
server.use(
31+
rest.get(
32+
"/api/v2/users/:username/workspace/:workspaceName",
33+
(req,res,ctx)=>{
34+
returnres(
35+
ctx.status(200),
36+
ctx.json({
37+
...MockWorkspace,
38+
latest_build:{
39+
...MockWorkspace.latest_build,
40+
deadline:BASE_DEADLINE.toISOString(),
41+
},
42+
}),
43+
);
44+
},
45+
),
46+
);
47+
render(
48+
<ThemeProvider>
49+
<QueryClientProviderclient={newQueryClient()}>
50+
<RouterProvider
51+
router={createMemoryRouter([{path:"/",element:<Wrapper/>}])}
52+
/>
53+
</QueryClientProvider>
54+
<GlobalSnackbar/>
55+
</ThemeProvider>,
56+
);
57+
awaitscreen.findByTestId("schedule-controls");
58+
expect(screen.getByText("Stop in 3 hours")).toBeInTheDocument();
59+
};
60+
61+
test("add 3 hours to deadline",async()=>{
62+
constuser=userEvent.setup();
63+
constupdateDeadlineSpy=jest
64+
.spyOn(API,"putWorkspaceExtension")
65+
.mockResolvedValue();
66+
67+
awaitrenderScheduleControls();
68+
69+
constaddButton=screen.getByRole("button",{
70+
name:/add1hourtodeadline/i,
71+
});
72+
awaituser.click(addButton);
73+
awaituser.click(addButton);
74+
awaituser.click(addButton);
75+
awaitscreen.findByText(
76+
"Workspace shutdown time has been successfully updated.",
77+
);
78+
expect(screen.getByText("Stop in 6 hours")).toBeInTheDocument();
79+
80+
// Mocks are used here because the 'usedDeadline' is a dayjs object, which
81+
// can't be directly compared.
82+
constusedWorkspaceId=updateDeadlineSpy.mock.calls[0][0];
83+
constusedDeadline=updateDeadlineSpy.mock.calls[0][1];
84+
expect(usedWorkspaceId).toEqual(MockWorkspace.id);
85+
expect(usedDeadline.toISOString()).toEqual(
86+
BASE_DEADLINE.add(3,"hour").toISOString(),
87+
);
88+
});
89+
90+
test("remove 3 hours to deadline",async()=>{
91+
constuser=userEvent.setup();
92+
constupdateDeadlineSpy=jest
93+
.spyOn(API,"putWorkspaceExtension")
94+
.mockResolvedValue();
95+
96+
awaitrenderScheduleControls();
97+
98+
constsubButton=screen.getByRole("button",{
99+
name:/subtract1hourfromdeadline/i,
100+
});
101+
awaituser.click(subButton);
102+
awaituser.click(subButton);
103+
awaitscreen.findByText(
104+
"Workspace shutdown time has been successfully updated.",
105+
);
106+
expect(screen.getByText("Stop in an hour")).toBeInTheDocument();
107+
108+
// Mocks are used here because the 'usedDeadline' is a dayjs object, which
109+
// can't be directly compared.
110+
constusedWorkspaceId=updateDeadlineSpy.mock.calls[0][0];
111+
constusedDeadline=updateDeadlineSpy.mock.calls[0][1];
112+
expect(usedWorkspaceId).toEqual(MockWorkspace.id);
113+
expect(usedDeadline.toISOString()).toEqual(
114+
BASE_DEADLINE.subtract(2,"hour").toISOString(),
115+
);
116+
});
117+
118+
test("rollback to previous deadline on error",async()=>{
119+
constuser=userEvent.setup();
120+
constinitialScheduleMessage="Stop in 3 hours";
121+
jest.spyOn(API,"putWorkspaceExtension").mockRejectedValue({});
122+
123+
awaitrenderScheduleControls();
124+
125+
constaddButton=screen.getByRole("button",{
126+
name:/add1hourtodeadline/i,
127+
});
128+
awaituser.click(addButton);
129+
awaituser.click(addButton);
130+
awaituser.click(addButton);
131+
awaitscreen.findByText(
132+
"We couldn't update your workspace shutdown time. Please try again.",
133+
);
134+
// In case of an error, the schedule message should remain unchanged
135+
expect(screen.getByText(initialScheduleMessage)).toBeInTheDocument();
136+
});
137+
138+
test("request is only sent once when clicking multiple times",async()=>{
139+
constuser=userEvent.setup();
140+
constupdateDeadlineSpy=jest
141+
.spyOn(API,"putWorkspaceExtension")
142+
.mockResolvedValue();
143+
144+
awaitrenderScheduleControls();
145+
146+
constaddButton=screen.getByRole("button",{
147+
name:/add1hourtodeadline/i,
148+
});
149+
awaituser.click(addButton);
150+
awaituser.click(addButton);
151+
awaituser.click(addButton);
152+
awaitscreen.findByText(
153+
"Workspace shutdown time has been successfully updated.",
154+
);
155+
expect(updateDeadlineSpy).toHaveBeenCalledTimes(1);
156+
});

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp