Skip to content

Commit 0f342ed

Browse files
test(site): move users page test to storybook (#14579)
By using [Storybook interaction tests](https://storybook.js.org/tutorials/ui-testing-handbook/react/en/interaction-testing/), we improve the developer experience, as we can see what is happening in the browser, use browser tools to debug, and snapshot the component after interactions, making our tests more reliable and easier to maintain. Fixes #14535
1 parent 208a5be commit 0f342ed

File tree

15 files changed

+2061
-393
lines changed

15 files changed

+2061
-393
lines changed

site/src/api/api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1282,7 +1282,7 @@ class ApiMethods {
12821282
updateUserPassword = async (
12831283
userId: TypesGen.User["id"],
12841284
updatePassword: TypesGen.UpdateUserPasswordRequest,
1285-
): Promise<undefined> => {
1285+
): Promise<void> => {
12861286
await this.axios.put(`/api/v2/users/${userId}/password`, updatePassword);
12871287
};
12881288

site/src/api/queries/deployment.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { API } from "api/api";
22

3+
export const deploymentConfigQueryKey = ["deployment", "config"];
4+
35
export const deploymentConfig = () => {
46
return {
5-
queryKey: ["deployment", "config"],
7+
queryKey: deploymentConfigQueryKey,
68
queryFn: API.getDeploymentConfig,
79
};
810
};

site/src/api/queries/groups.ts

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import type { QueryClient, UseQueryOptions } from "react-query";
88

99
type GroupSortOrder = "asc" | "desc";
1010

11-
const groupsQueryKey = ["groups"];
11+
export const groupsQueryKey = ["groups"];
1212

1313
export const groups = () => {
1414
return {
@@ -49,27 +49,29 @@ export type GroupsByUserId = Readonly<Map<string, readonly Group[]>>;
4949
export function groupsByUserId() {
5050
return {
5151
...groups(),
52-
select: (allGroups) => {
53-
// Sorting here means that nothing has to be sorted for the individual
54-
// user arrays later
55-
const sorted = sortGroupsByName(allGroups, "asc");
56-
const userIdMapper = new Map<string, Group[]>();
57-
58-
for (const group of sorted) {
59-
for (const user of group.members) {
60-
let groupsForUser = userIdMapper.get(user.id);
61-
if (groupsForUser === undefined) {
62-
groupsForUser = [];
63-
userIdMapper.set(user.id, groupsForUser);
64-
}
65-
66-
groupsForUser.push(group);
67-
}
52+
select: selectGroupsByUserId,
53+
} satisfies UseQueryOptions<Group[], unknown, GroupsByUserId>;
54+
}
55+
56+
export function selectGroupsByUserId(groups: Group[]): GroupsByUserId {
57+
// Sorting here means that nothing has to be sorted for the individual
58+
// user arrays later
59+
const sorted = sortGroupsByName(groups, "asc");
60+
const userIdMapper = new Map<string, Group[]>();
61+
62+
for (const group of sorted) {
63+
for (const user of group.members) {
64+
let groupsForUser = userIdMapper.get(user.id);
65+
if (groupsForUser === undefined) {
66+
groupsForUser = [];
67+
userIdMapper.set(user.id, groupsForUser);
6868
}
6969

70-
return userIdMapper as GroupsByUserId;
71-
},
72-
} satisfies UseQueryOptions<Group[], unknown, GroupsByUserId>;
70+
groupsForUser.push(group);
71+
}
72+
}
73+
74+
return userIdMapper as GroupsByUserId;
7375
}
7476

7577
export function groupsForUser(userId: string) {

site/src/api/queries/roles.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ const getRoleQueryKey = (organizationId: string, roleName: string) => [
99
roleName,
1010
];
1111

12+
export const rolesQueryKey = ["roles"];
13+
1214
export const roles = () => {
1315
return {
14-
queryKey: ["roles"],
16+
queryKey: rolesQueryKey,
1517
queryFn: API.getRoles,
1618
};
1719
};

site/src/api/queries/users.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,13 @@ export const updateRoles = (queryClient: QueryClient) => {
115115
};
116116
};
117117

118+
export const authMethodsQueryKey = ["authMethods"];
119+
118120
export const authMethods = () => {
119121
return {
120122
// Even the endpoint being /users/authmethods we don't want to revalidate it
121123
// when users change so its better add a unique query key
122-
queryKey: ["authMethods"],
124+
queryKey: authMethodsQueryKey,
123125
queryFn: API.getAuthMethods,
124126
};
125127
};

site/src/components/Filter/filter.tsx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -294,21 +294,21 @@ const PresetMenu: FC<PresetMenuProps> = ({
294294
</MenuItem>
295295
))}
296296
{learnMoreLink && (
297-
<>
298-
<Divider css={{ borderColor: theme.palette.divider }} />
299-
<MenuItem
300-
component="a"
301-
href={learnMoreLink}
302-
target="_blank"
303-
css={{ fontSize: 13, fontWeight: 500 }}
304-
onClick={() => {
305-
setIsOpen(false);
306-
}}
307-
>
308-
<OpenInNewOutlined css={{ fontSize: "14px !important" }} />
309-
View advanced filtering
310-
</MenuItem>
311-
</>
297+
<Divider css={{ borderColor: theme.palette.divider }} />
298+
)}
299+
{learnMoreLink && (
300+
<MenuItem
301+
component="a"
302+
href={learnMoreLink}
303+
target="_blank"
304+
css={{ fontSize: 13, fontWeight: 500 }}
305+
onClick={() => {
306+
setIsOpen(false);
307+
}}
308+
>
309+
<OpenInNewOutlined css={{ fontSize: "14px !important" }} />
310+
View advanced filtering
311+
</MenuItem>
312312
)}
313313
{learnMoreLink2 && learnMoreLabel2 && (
314314
<MenuItem

site/src/pages/ManagementSettingsPage/OrganizationMembersPage.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ const updateUserRole = async (role: SlimRole) => {
6464
}
6565

6666
// Click on the "edit icon" to display the role options
67-
const editButton = within(userRow).getByTitle("Edit user roles");
67+
const editButton = within(userRow).getByLabelText("Edit user roles");
6868
fireEvent.click(editButton);
6969

7070
// Click on the role option

site/src/pages/ManagementSettingsPage/UserTable/EditRolesButton.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { Interpolation, Theme } from "@emotion/react";
22
import UserIcon from "@mui/icons-material/PersonOutline";
33
import Checkbox from "@mui/material/Checkbox";
44
import IconButton from "@mui/material/IconButton";
5+
import Tooltip from "@mui/material/Tooltip";
56
import type { SlimRole } from "api/typesGenerated";
67
import {
78
HelpTooltip,
@@ -116,13 +117,15 @@ export const EditRolesButton: FC<EditRolesButtonProps> = ({
116117
return (
117118
<Popover>
118119
<PopoverTrigger>
119-
<IconButton
120-
size="small"
121-
css={styles.editButton}
122-
title="Edit user roles"
123-
>
124-
<EditSquare />
125-
</IconButton>
120+
<Tooltip title="Edit user roles">
121+
<IconButton
122+
aria-label="Edit user roles"
123+
size="small"
124+
css={styles.editButton}
125+
>
126+
<EditSquare />
127+
</IconButton>
128+
</Tooltip>
126129
</PopoverTrigger>
127130

128131
<PopoverContent classes={{ paper }}>

0 commit comments

Comments
 (0)