Skip to content

Commit 1f2037e

Browse files
authored
Merge pull request #349 from aldbr/main_FEAT_link-stories-to-jest-tests
build: link stories to unit test to track changes
2 parents 9d208cd + bfed3b8 commit 1f2037e

57 files changed

Lines changed: 1333 additions & 2082 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/developer/contribute.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,10 @@
2020

2121
- **Testing**:
2222

23-
- **Component Testing**: Write tests for your components to ensure they work as expected. Use [Jest](https://jestjs.io/) for unit testing and snapshot testing of your React components.
23+
- **Component Testing**: Write tests for your stories to ensure they work as expected. Use [Jest](https://jestjs.io/) for unit testing and snapshot testing of your React components.
2424
- **Application Testing**: Use [Cypress](https://www.cypress.io/) for end-to-end testing to simulate real user interactions and ensure your application behaves correctly.
2525
- **Test Coverage**: Maintain good test coverage to ensure that your critical features are well-protected during updates. Tools like Jest provide [coverage reports](https://jestjs.io/docs/code-coverage) that help you identify untested parts of your code.
2626

27-
2827
- **Accessibility**: Make your application accessible to all users. Use semantic HTML, ARIA attributes, and test your application with different screen sizes and assistive technologies.
2928

3029
By following these practices, you'll ensure that your codebase remains robust, secure, and maintainable.

packages/diracx-web-components/.storybook/main.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,13 @@ const config: StorybookConfig = {
3737
config.resolve.alias = {
3838
...config.resolve.alias,
3939
"@axa-fr/react-oidc": require.resolve(
40-
"../stories/mocks/react-oidc.mock.ts",
40+
"../stories/mocks/react-oidc.mock.tsx",
4141
),
42-
"@actual/react-oidc": require.resolve("@axa-fr/react-oidc"),
43-
44-
"@actual/hooks/metadata$": require.resolve("../src/hooks/metadata"),
4542
"../../hooks/metadata": require.resolve(
46-
"../stories/mocks/metadata.mock.ts",
47-
),
48-
49-
"@actual/components/JobMonitor/JobDataService$": require.resolve(
50-
"../src/components/JobMonitor/JobDataService.ts",
43+
"../stories/mocks/metadata.mock.tsx",
5144
),
5245
"./JobDataService": require.resolve(
53-
"../stories/mocks/JobDataService.mock.ts",
46+
"../stories/mocks/JobDataService.mock.tsx",
5447
),
5548
};
5649
return config;

packages/diracx-web-components/jest.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ const config = {
99

1010
// The test environment that will be used for testing
1111
testEnvironment: "jest-environment-jsdom",
12+
13+
moduleNameMapper: {
14+
"^@axa-fr/react-oidc$": "<rootDir>/stories/mocks/react-oidc.mock.tsx",
15+
"^../../hooks/metadata$": "<rootDir>/stories/mocks/metadata.mock.tsx",
16+
"^./JobDataService$": "<rootDir>/stories/mocks/JobDataService.mock.tsx",
17+
},
1218
};
1319

1420
export default config;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
import "@testing-library/jest-dom";
2+
3+
jest.mock("@axa-fr/react-oidc");

packages/diracx-web-components/src/components/BaseApp/BaseApp.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import { useOidcAccessToken } from "@axa-fr/react-oidc/";
3+
import { useOidcAccessToken } from "@axa-fr/react-oidc";
44
import { useOIDCContext } from "../../hooks/oidcConfiguration";
55

66
/**

packages/diracx-web-components/src/components/DashboardLayout/Dashboard.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
import { ProfileButton } from "./ProfileButton";
1616
import { ThemeToggleButton } from "./ThemeToggleButton";
1717
import DashboardDrawer from "./DashboardDrawer";
18-
import { ShareButton } from "./ShareButton";
18+
import { ExportButton } from "./ExportButton";
1919
import { ImportButton } from "./ImportButton";
2020

2121
interface DashboardProps {
@@ -124,7 +124,7 @@ export default function Dashboard({
124124
>
125125
<Stack direction="row" spacing={1} alignItems="center">
126126
<ImportButton />
127-
<ShareButton />
127+
<ExportButton />
128128
<ThemeToggleButton />
129129
<ProfileButton />
130130
</Stack>

packages/diracx-web-components/src/components/DashboardLayout/DashboardDrawer.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,10 @@ export default function DashboardDrawer({
434434
}}
435435
>
436436
<ListItem key={"Add application"}>
437-
<ListItemButton onClick={() => setAppDialogOpen(true)}>
437+
<ListItemButton
438+
onClick={() => setAppDialogOpen(true)}
439+
data-testid="add-application-button"
440+
>
438441
<ListItemIcon>{<Add />}</ListItemIcon>
439442
<ListItemText primary={"Add application"} />
440443
</ListItemButton>

packages/diracx-web-components/src/components/DashboardLayout/DrawerItem.tsx

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
useTheme,
1111
TextField,
1212
} from "@mui/material";
13-
import { DragIndicator } from "@mui/icons-material";
13+
import { DragIndicator, SvgIconComponent } from "@mui/icons-material";
1414
import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
1515
import {
1616
draggable,
@@ -23,14 +23,15 @@ import {
2323
extractClosestEdge,
2424
} from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
2525
import { setCustomNativeDragPreview } from "@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview";
26+
import EggIcon from "@mui/icons-material/Egg";
2627
import { ThemeProvider } from "../../contexts/ThemeProvider";
2728
import { useSearchParamsUtils } from "../../hooks/searchParamsUtils";
2829
import { useApplicationId } from "../../hooks/application";
29-
import { DashboardGroup } from "../../types";
30+
import { DashboardGroup, DashboardItem } from "../../types";
3031

3132
interface DrawerItemProps {
3233
/** The item object containing the title, id, and icon. */
33-
item: { title: string; id: string; icon: React.ComponentType };
34+
item: DashboardItem;
3435
/** The index of the item. */
3536
index: number;
3637
/** The title of the group. */
@@ -53,7 +54,7 @@ interface DrawerItemProps {
5354
* @returns The rendered JSX for the drawer item.
5455
*/
5556
export default function DrawerItem({
56-
item: { title, id, icon },
57+
item,
5758
index,
5859
groupTitle,
5960
renamingItemId,
@@ -100,7 +101,7 @@ export default function DrawerItem({
100101
width: source.element.getBoundingClientRect().width,
101102
}}
102103
>
103-
<ItemPreview title={title} icon={icon} />
104+
<ItemPreview title={item.title} icon={item.icon} />
104105
</div>
105106
</ThemeProvider>,
106107
);
@@ -136,9 +137,9 @@ export default function DrawerItem({
136137
const sourceIndex = source.data.index;
137138
if (typeof sourceIndex === "number") {
138139
const isItemBeforeSource =
139-
index === sourceIndex - 1 && source.data.title === title;
140+
index === sourceIndex - 1 && source.data.title === item.title;
140141
const isItemAfterSource =
141-
index === sourceIndex + 1 && source.data.title === title;
142+
index === sourceIndex + 1 && source.data.title === item.title;
142143

143144
const isDropIndicatorHidden =
144145
(isItemBeforeSource && closestEdge === "bottom") ||
@@ -159,7 +160,7 @@ export default function DrawerItem({
159160
},
160161
}),
161162
);
162-
}, [index, groupTitle, icon, theme, title, id]);
163+
}, [index, groupTitle, item, theme]);
163164

164165
// Handle renaming of the item
165166
const handleItemRename = () => {
@@ -169,8 +170,8 @@ export default function DrawerItem({
169170
if (group.title === groupTitle) {
170171
return {
171172
...group,
172-
items: group.items.map((item) =>
173-
item.id === id ? { ...item, title: renameValue } : item,
173+
items: group.items.map((i) =>
174+
i.id === item.id ? { ...item, title: renameValue } : i,
174175
),
175176
};
176177
}
@@ -185,16 +186,16 @@ export default function DrawerItem({
185186
<>
186187
<ListItemButton
187188
disableGutters
188-
key={title}
189-
onClick={() => setParam("appId", id)}
189+
key={item.title}
190+
onClick={() => setParam("appId", item.id)}
190191
sx={{ pl: 2, borderRadius: 2, pr: 1 }}
191192
ref={dragRef}
192-
selected={appId === id}
193+
selected={appId === item.id}
193194
>
194195
<ListItemIcon>
195-
<Icon component={icon} />
196+
<Icon component={item.icon ?? EggIcon} />
196197
</ListItemIcon>
197-
{renamingItemId === id ? (
198+
{renamingItemId === item.id ? (
198199
<TextField
199200
value={renameValue}
200201
onChange={(e) => setRenameValue(e.target.value)}
@@ -211,7 +212,7 @@ export default function DrawerItem({
211212
/>
212213
) : (
213214
<ListItemText
214-
primary={title}
215+
primary={item.title}
215216
sx={{
216217
whiteSpace: "nowrap",
217218
overflow: "hidden",
@@ -239,15 +240,15 @@ export default function DrawerItem({
239240
*
240241
* @param {Object} props - The component props.
241242
* @param {string} props.title - The title of the item.
242-
* @param {React.ComponentType} props.icon - The icon component for the item.
243+
* @param {SvgIconComponent} props.icon - The icon component for the item.
243244
* @returns {JSX.Element} The rendered item preview.
244245
*/
245246
function ItemPreview({
246247
title,
247248
icon,
248249
}: {
249250
title: string;
250-
icon: React.ComponentType;
251+
icon: SvgIconComponent | null;
251252
}) {
252253
return (
253254
<ListItemButton
@@ -261,7 +262,7 @@ function ItemPreview({
261262
}}
262263
>
263264
<ListItemIcon>
264-
<Icon component={icon} />
265+
<Icon component={icon ?? EggIcon} />
265266
</ListItemIcon>
266267
<ListItemText
267268
primary={title}

packages/diracx-web-components/src/components/DashboardLayout/DrawerItemGroup.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
AccordionSummary,
77
TextField,
88
} from "@mui/material";
9-
import { ExpandMore, Apps } from "@mui/icons-material";
9+
import { ExpandMore } from "@mui/icons-material";
1010
import React, { useEffect, useRef, useState } from "react";
1111
import { dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
1212
import { DashboardGroup } from "../../types/DashboardGroup";
@@ -139,10 +139,10 @@ export default function DrawerItemGroup({
139139
</AccordionSummary>
140140
{/* Accordion details */}
141141
<AccordionDetails>
142-
{items.map(({ title: itemTitle, id, icon }, index) => (
143-
<div onContextMenu={handleContextMenu("item", id)} key={id}>
142+
{items.map((item, index) => (
143+
<div onContextMenu={handleContextMenu("item", item.id)} key={item.id}>
144144
<DrawerItem
145-
item={{ title: itemTitle, id, icon: icon || Apps }}
145+
item={item}
146146
index={index}
147147
groupTitle={title}
148148
renamingItemId={renamingItemId}

packages/diracx-web-components/src/components/DashboardLayout/ShareButton.tsx renamed to packages/diracx-web-components/src/components/DashboardLayout/ExportButton.tsx

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ import { DashboardGroup } from "../../types/DashboardGroup";
2525

2626
import { ApplicationsContext } from "../../contexts";
2727

28-
interface ShareDialogProps {
28+
interface ExportDialogProps {
2929
open: boolean;
3030
onClose: () => void;
3131
state: string;
3232
}
3333

34-
function ShareDialog({ open, onClose, state }: ShareDialogProps) {
34+
function ExportDialog({ open, onClose, state }: ExportDialogProps) {
3535
const theme = useTheme();
3636
const handleCopy = () => {
3737
navigator.clipboard.writeText(state);
@@ -57,11 +57,14 @@ function ShareDialog({ open, onClose, state }: ShareDialogProps) {
5757
</Typography>
5858
</DialogContent>
5959
<DialogActions>
60-
<Button onClick={onClose}>Cancel</Button>
60+
<Button onClick={onClose} data-testid="cancel-export-button">
61+
Cancel
62+
</Button>
6163
<Button
6264
onClick={handleCopy}
6365
startIcon={<ContentCopyIcon />}
6466
variant="contained"
67+
data-testid="validate-export-button"
6568
>
6669
Copy to Clipboard
6770
</Button>
@@ -71,10 +74,10 @@ function ShareDialog({ open, onClose, state }: ShareDialogProps) {
7174
}
7275

7376
/**
74-
* ShareButton component allows users to share the state of selected applications.
77+
* ExportButton component allows users to share the state of selected applications.
7578
* It provides a menu with checkboxes for each application and a dialog to display the state.
7679
*/
77-
export function ShareButton() {
80+
export function ExportButton() {
7881
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
7982
const [dialogOpen, setDialogOpen] = useState(false);
8083
const [selectedApps, setSelectedApps] = useState<string[]>([]);
@@ -103,7 +106,7 @@ export function ShareButton() {
103106

104107
// Function to handle the share action
105108
// It collects the state of selected applications and opens the dialog
106-
const handleShare = () => {
109+
const handleExport = () => {
107110
const states = selectedApps.map((appId) => {
108111
const app = groups.flatMap((g) => g.items).find((a) => a.id === appId);
109112
if (!app) return null;
@@ -123,8 +126,8 @@ export function ShareButton() {
123126

124127
return (
125128
<>
126-
<Tooltip title="Share application state">
127-
<IconButton onClick={handleClick}>
129+
<Tooltip title="Export application state">
130+
<IconButton onClick={handleClick} data-testid="export-button">
128131
<OutputIcon />
129132
</IconButton>
130133
</Tooltip>
@@ -188,16 +191,16 @@ export function ShareButton() {
188191
<Button
189192
fullWidth
190193
variant="contained"
191-
onClick={handleShare}
194+
onClick={handleExport}
192195
startIcon={<OutputIcon />}
193196
>
194-
Share {selectedApps.length} selected
197+
Export {selectedApps.length} selected
195198
</Button>
196199
</Box>
197200
)}
198201
</Menu>
199202

200-
<ShareDialog
203+
<ExportDialog
201204
open={dialogOpen}
202205
onClose={() => setDialogOpen(false)}
203206
state={selectedState}

0 commit comments

Comments
 (0)