Skip to content

Commit c1b45d7

Browse files
Merge branch 'deriv-com:main' into yaswanth/FEQ-1858_Implement_circular_progressbar
2 parents 6d05dd4 + eedfbaa commit c1b45d7

File tree

14 files changed

+322
-52
lines changed

14 files changed

+322
-52
lines changed

package-lock.json

+9-18
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
"test": "jest",
3232
"test:report": "jest --collectCoverage"
3333
},
34+
"dependencies": {
35+
"@types/react-modal": "^3.16.3"
36+
},
3437
"devDependencies": {
3538
"@babel/preset-env": "^7.24.3",
3639
"@babel/preset-react": "^7.24.1",
@@ -53,9 +56,8 @@
5356
"@testing-library/user-event": "^14.5.2",
5457
"@types/jest": "^29.5.12",
5558
"@types/node": "^20.11.30",
56-
"@types/react": "^18.2.71",
59+
"@types/react": "^18.2.72",
5760
"@types/react-dom": "^18.2.22",
58-
"@types/react-modal": "^3.16.3",
5961
"@typescript-eslint/eslint-plugin": "^7.4.0",
6062
"@typescript-eslint/parser": "^7.4.0",
6163
"@vitejs/plugin-react": "^4.2.1",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import React from "react";
2+
import { render } from "@testing-library/react";
3+
import { InlineMessage } from "..";
4+
5+
describe("InlineMessage Component", () => {
6+
it("renders children correctly", () => {
7+
const { getByText } = render(<InlineMessage>Test Message</InlineMessage>);
8+
expect(getByText("Test Message")).toBeInTheDocument();
9+
});
10+
11+
it("renders with specified variant", () => {
12+
const { container } = render(
13+
<InlineMessage variant="error">Error Message</InlineMessage>
14+
);
15+
expect(container.firstChild).toHaveClass(
16+
"deriv-inline-message__error--filled"
17+
);
18+
});
19+
20+
it("renders with specified icon", () => {
21+
const { container } = render(
22+
<InlineMessage icon={<span>Icon</span>}>Message with Icon</InlineMessage>
23+
);
24+
expect(container.querySelector(".deriv-inline-message__icon")).toBeInTheDocument();
25+
});
26+
27+
it("renders with specified type", () => {
28+
const { container } = render(
29+
<InlineMessage variant="warning" type="outlined">Outlined Warning Message</InlineMessage>
30+
);
31+
expect(container.firstChild).toHaveClass(
32+
"deriv-inline-message__warning--outlined"
33+
);
34+
});
35+
36+
it("renders with custom class name", () => {
37+
const { container } = render(
38+
<InlineMessage className="custom-class">Custom Message</InlineMessage>
39+
);
40+
expect(container.firstChild).toHaveClass("custom-class");
41+
});
42+
43+
it("should position the icon at the top", () => {
44+
const { container } = render(
45+
<InlineMessage iconPosition="top" variant="info">
46+
Test Message
47+
</InlineMessage>
48+
);
49+
const iconElement = container.querySelector(".deriv-inline-message__icon--top")
50+
expect(iconElement).toBeInTheDocument();
51+
});
52+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import React from "react";
2+
import { render, screen } from "@testing-library/react";
3+
import { PageLayout } from "..";
4+
import * as hooks from "../../../hooks"
5+
6+
// Mocking the useDevice hook
7+
jest.mock("../../../hooks", () => ({
8+
useDevice: jest.fn().mockReturnValue({isMobile:false}),
9+
}));
10+
11+
describe("PageLayout Component", () => {
12+
it("renders children correctly", () => {
13+
render(
14+
<PageLayout>
15+
<div>Content</div>
16+
</PageLayout>
17+
);
18+
const content =screen.getByText("Content")
19+
expect(content).toBeInTheDocument();
20+
});
21+
22+
it("renders sidebar when provided and not on mobile", () => {
23+
const sidebar = <div>Sidebar</div>;
24+
render(<PageLayout sidebar={sidebar} />);
25+
const sidebarContent =screen.getByText("Sidebar")
26+
expect(sidebarContent).toBeInTheDocument();
27+
});
28+
29+
it("does not render sidebar on mobile", () => {
30+
jest.spyOn(hooks,'useDevice').mockImplementation(()=>({isMobile:true, isDesktop:false, isTablet:false}))
31+
const sidebar = <div>Sidebar</div>;
32+
render(<PageLayout sidebar={sidebar} />);
33+
const sidebarContent =screen.queryByText("Sidebar")
34+
expect(sidebarContent).not.toBeInTheDocument()
35+
});
36+
37+
it("does not render sidebar when not provided", () => {
38+
render(<PageLayout />);
39+
const sidebarContent=screen.queryByTestId("sidebar")
40+
expect(sidebarContent).toBeNull();
41+
});
42+
});

src/components/PageLayout/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from "react";
2-
import { useDevice } from "../../hooks/useDevice";
2+
import { useDevice } from "../../hooks";
33
import "./PageLayout.scss";
44

55
type PageLayoutProps = {

src/components/SideNote/SideNote.scss

+7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
color: #333333;
44
padding: 16px 24px;
55
border-radius: 8px;
6+
display: flex;
7+
flex-direction: column;
8+
9+
&__title {
10+
margin-bottom: 8px;
11+
}
612

713
&:hover > &__action {
814
text-decoration: underline;
@@ -14,5 +20,6 @@
1420
align-items: center;
1521
gap: 8px;
1622
cursor: pointer;
23+
margin-top: 16px;
1724
}
1825
}

src/components/SideNote/index.tsx

+5-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type SideNoteProps = Omit<ComponentProps<"div">, "className"> & {
1515
className?: HTMLDivElement["className"];
1616
actionClick?: MouseEventHandler<HTMLButtonElement>;
1717
actionClassName?: HTMLDivElement["className"];
18+
titleClassName?: HTMLDivElement["className"];
1819
actionLabel?: ReactNode;
1920
};
2021

@@ -25,6 +26,7 @@ type SideNoteProps = Omit<ComponentProps<"div">, "className"> & {
2526
* @param {SideNoteProps.className} className - Add an extra className to the container.
2627
* @param {SideNoteProps.actionClick} actionClick - An onclick handler for the action button.
2728
* @param {SideNoteProps.actionClassName} actionClassName - Add an extra className to the action button.
29+
* @param {SideNoteProps.titleClassName} titleClassName - Add an extra className to the title.
2830
* @param {SideNoteProps.actionLabel} actionLabel - Display the label of the action. (default: "Learn more")
2931
* @returns {React.JSX.Element} - Returns the SideNote component.
3032
*/
@@ -35,17 +37,18 @@ export const SideNote = ({
3537
className,
3638
actionClick,
3739
actionClassName,
40+
titleClassName,
3841
actionLabel = "Learn more",
3942
...props
4043
}: PropsWithChildren<SideNoteProps>) => (
4144
<div className={clsx("deriv-side-note", className)} {...props}>
4245
{title && (
43-
<Text data-testid="dt_deriv-side-note-title" size={titleSize} align="left" weight="bold">
46+
<Text data-testid="dt_deriv-side-note-title" className={clsx("deriv-side-note__title", titleClassName)} size={titleSize} align="left" weight="bold">
4447
{title}
4548
</Text>
4649
)}
4750

48-
<div>{children}</div>
51+
{children}
4952

5053
{actionClick && (
5154
<button
+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
2+
import React from "react";
3+
import { render, fireEvent, screen } from "@testing-library/react";
4+
import { Tab, Tabs } from "..";
5+
6+
describe("Tabs Component", () => {
7+
it("renders Tabs component with primary variant by default", () => {
8+
const { container } = render(
9+
<Tabs>
10+
<Tab title="Tab 1">Tab 1 Content</Tab>
11+
<Tab title="Tab 2">Tab 2 Content</Tab>
12+
</Tabs>
13+
);
14+
15+
const tabsComponent = container.querySelector(".derivs-primary-tabs")
16+
const tabTitle = screen.getByText("Tab 1")
17+
const tab1Content = screen.getByText("Tab 1 Content")
18+
expect(tabTitle).toBeInTheDocument();
19+
expect(tabsComponent).toBeInTheDocument();
20+
expect(tab1Content).toBeInTheDocument();
21+
expect(tabsComponent).toHaveClass("derivs-primary-tabs");
22+
});
23+
24+
it("changes active tab when clicked and checks active tab content showing", () => {
25+
render(
26+
<Tabs activeTab="Tab 1">
27+
<Tab title="Tab 1">Tab 1 Content</Tab>
28+
<Tab title="Tab 2">Tab 2 Content</Tab>
29+
</Tabs>
30+
);
31+
const tab1 = screen.getByText("Tab 1 Content")
32+
expect(tab1).toBeInTheDocument();
33+
const tab2 = screen.getByText("Tab 2");
34+
fireEvent.click(tab2);
35+
const activeButton = screen.getAllByRole("button")[1];
36+
const tabContent = screen.getByText("Tab 2 Content")
37+
expect(tabContent).toBeInTheDocument();
38+
expect(activeButton).toHaveClass("derivs-primary-tabs__btn--active");
39+
});
40+
41+
it("should render tabs with correct variant", () => {
42+
const { container } = render(
43+
<Tabs variant="secondary">
44+
<Tab title="Tab 1">Tab 1 Content</Tab>
45+
<Tab title="Tab 2">Tab 2 Content</Tab>
46+
</Tabs>
47+
);
48+
const tabsComponent = container.querySelector(".derivs-secondary-tabs")
49+
expect(tabsComponent).toBeInTheDocument();
50+
});
51+
52+
it("should render tabs with correct title font size", () => {
53+
const { container } = render(
54+
<Tabs TitleFontSize="lg">
55+
<Tab title="Tab 1">Tab 1 Content</Tab>
56+
<Tab title="Tab 2">Tab 2 Content</Tab>
57+
</Tabs>
58+
);
59+
60+
const tabsComponent = container.querySelector(".derivs-primary-tabs")
61+
62+
expect(tabsComponent).toHaveStyle("font-size: lg;");
63+
});
64+
65+
it("should call onChange handler when a tab is clicked", () => {
66+
const mockOnChange = jest.fn();
67+
const { getByText } = render(
68+
<Tabs onChange={mockOnChange}>
69+
<Tab title="Tab 1">Tab 1 Content</Tab>
70+
<Tab title="Tab 2">Tab 2 Content</Tab>
71+
</Tabs>
72+
);
73+
const tabTitle = getByText("Tab 1");
74+
fireEvent.click(tabTitle);
75+
expect(mockOnChange).toHaveBeenCalled();
76+
});
77+
78+
it("applies custom class to wrapper", () => {
79+
const { container } = render(
80+
<Tabs wrapperClassName="custom-wrapper">
81+
<Tab title="Tab 1">Tab 1 Content</Tab>
82+
<Tab title="Tab 2">Tab 2 Content</Tab>
83+
</Tabs>
84+
);
85+
const tabsWrapper = container.querySelector(".custom-wrapper");
86+
expect(tabsWrapper).toBeInTheDocument();
87+
});
88+
});

0 commit comments

Comments
 (0)