Skip to content

Commit 72d8974

Browse files
committed
Merge remote-tracking branch 'base/main'
2 parents bb0abd1 + b0fcac4 commit 72d8974

File tree

168 files changed

+8838
-1035
lines changed

Some content is hidden

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

168 files changed

+8838
-1035
lines changed
Binary file not shown.
88.8 KB
Binary file not shown.

apps/arkmarket/package.json

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111
"lint": "eslint",
1212
"start": "pnpm with-env next start",
1313
"typecheck": "tsc --noEmit",
14-
"with-env": "dotenv -e ../../.env --"
14+
"with-env": "dotenv -e ../../.env --",
15+
"test": "vitest",
16+
"test:watch": "vitest --watch",
17+
"test:coverage": "vitest run --coverage"
1518
},
1619
"dependencies": {
1720
"@ark-market/ui": "workspace:*",
@@ -58,15 +61,21 @@
5861
"@ark-market/tailwind-config": "workspace:*",
5962
"@ark-market/tsconfig": "workspace:*",
6063
"@tailwindcss/typography": "^0.5.15",
64+
"@testing-library/dom": "^10.4.0",
65+
"@testing-library/jest-dom": "^6.5.0",
66+
"@testing-library/react": "^16.0.1",
6167
"@types/node": "^20.16.4",
62-
"@types/react": "catalog:react18",
6368
"@types/react-dom": "catalog:react18",
69+
"@vitejs/plugin-react": "^4.3.2",
70+
"@vitest/coverage-v8": "2.1.2",
6471
"dotenv-cli": "^7.4.2",
6572
"eslint": "catalog:",
6673
"jiti": "^1.21.6",
74+
"jsdom": "^25.0.1",
6775
"prettier": "catalog:",
6876
"tailwindcss": "catalog:",
69-
"typescript": "catalog:"
77+
"typescript": "catalog:",
78+
"vitest": "^2.1.2"
7079
},
7180
"prettier": "@ark-market/prettier-config"
7281
}
1.36 KB
Binary file not shown.
8.77 KB
Binary file not shown.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
/* eslint-disable @typescript-eslint/no-unsafe-call */
3+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
4+
import React from 'react';
5+
import { render, screen } from '@testing-library/react';
6+
import { vi, describe, it, expect, beforeEach } from "vitest";
7+
import AuthSwitcher from "../components/auth-switcher";
8+
9+
vi.mock("@starknet-react/core", () => ({
10+
useAccount: vi.fn(),
11+
useConnect: vi.fn(() => ({
12+
connect: vi.fn(),
13+
connectors: [],
14+
})),
15+
}));
16+
17+
vi.mock("../components/authentication", () => ({
18+
default: () => (
19+
<div data-testid="authentication-component">Authentication Component</div>
20+
),
21+
}));
22+
23+
24+
import { useAccount, useConnect } from "@starknet-react/core";
25+
26+
describe("AuthSwitcher", () => {
27+
beforeEach(() => {
28+
vi.clearAllMocks();
29+
(useConnect as any).mockReturnValue({
30+
connect: vi.fn(),
31+
connectors: [],
32+
});
33+
});
34+
35+
it('renders Authentication component when account is undefined', () => {
36+
(useAccount as any).mockReturnValue({ account: undefined });
37+
38+
render(<AuthSwitcher>
39+
<div>Child Component</div>
40+
</AuthSwitcher>);
41+
42+
expect(screen.getByTestId('authentication-component')).toBeInTheDocument();
43+
expect(screen.queryByText('Child Component')).not.toBeInTheDocument();
44+
});
45+
46+
it('renders children when account is defined', () => {
47+
(useAccount as any).mockReturnValue({ account: { address: '0x123' } });
48+
49+
render(<AuthSwitcher>
50+
<div>Child Component</div>
51+
</AuthSwitcher>);
52+
53+
expect(screen.queryByTestId('authentication-component')).not.toBeInTheDocument();
54+
expect(screen.getByText('Child Component')).toBeInTheDocument();
55+
});
56+
57+
it('renders children when account is null', () => {
58+
(useAccount as any).mockReturnValue({ account: null });
59+
60+
render(<AuthSwitcher>
61+
<div>Child Component</div>
62+
</AuthSwitcher>);
63+
64+
expect(screen.queryByTestId('authentication-component')).not.toBeInTheDocument();
65+
expect(screen.getByText('Child Component')).toBeInTheDocument();
66+
});
67+
});
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
3+
/* eslint-disable @typescript-eslint/no-unsafe-call */
4+
import React from 'react';
5+
import { render, screen, fireEvent } from '@testing-library/react';
6+
import { vi, describe, it, expect, beforeEach } from 'vitest';
7+
import Authentication from '../components/authentication';
8+
9+
vi.mock('next/image', () => ({
10+
default: (props: any) => <img {...props} />,
11+
}));
12+
13+
vi.mock('@starknet-react/core', () => ({
14+
useConnect: vi.fn(),
15+
}));
16+
17+
import { useConnect } from "@starknet-react/core";
18+
19+
describe("Authentication", () => {
20+
beforeEach(() => {
21+
vi.clearAllMocks();
22+
(useConnect as any).mockReturnValue({
23+
connectors: [
24+
{ id: 'connector1', name: 'Connector 1' },
25+
{ id: 'connector2', name: 'Connector 2' },
26+
],
27+
connect: vi.fn(),
28+
});
29+
});
30+
31+
it('renders the component correctly', () => {
32+
render(<Authentication />);
33+
34+
expect(screen.getByText('Connect your wallet')).toBeInTheDocument();
35+
expect(screen.getByText('Choose a starknet wallet to start with')).toBeInTheDocument();
36+
expect(screen.getByText('Connector 1')).toBeInTheDocument();
37+
expect(screen.getByText('Connector 2')).toBeInTheDocument();
38+
});
39+
40+
it('calls connect function when a connector button is clicked', () => {
41+
const connectMock = vi.fn();
42+
(useConnect as any).mockReturnValue({
43+
connectors: [{ id: 'connector1', name: 'Connector 1' }],
44+
connect: connectMock,
45+
});
46+
47+
render(<Authentication />);
48+
49+
const connectButton = screen.getByText('Connector 1');
50+
fireEvent.click(connectButton);
51+
52+
expect(connectMock).toHaveBeenCalledWith({ connector: { id: 'connector1', name: 'Connector 1' } });
53+
});
54+
55+
it('renders the correct image for mobile view', () => {
56+
render(<Authentication />);
57+
58+
const mobileImage = screen.getByAltText('Authentication');
59+
expect(mobileImage).toHaveAttribute('src', '/authentication-dark.png');
60+
});
61+
62+
it('renders the ArkMarket logo and name', () => {
63+
render(<Authentication />);
64+
65+
expect(screen.getByText('ArkMarket')).toBeInTheDocument();
66+
expect(document.querySelector('svg')).toBeInTheDocument();
67+
});
68+
69+
it('renders the quote correctly', () => {
70+
render(<Authentication />);
71+
72+
const quote = screen.getByText(/This SDK integrates the Ark Project core library/);
73+
expect(quote).toBeInTheDocument();
74+
expect(screen.getByText('Ark Project')).toBeInTheDocument();
75+
});
76+
});
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
2+
/* eslint-disable @typescript-eslint/no-explicit-any */
3+
import React from 'react';
4+
import { render, screen, fireEvent } from '@testing-library/react';
5+
import { vi, describe, it, expect } from "vitest";
6+
import BuyNowDialog from "../components/buy-now-dialog";
7+
import type { Token, CollectionToken } from "~/types";
8+
9+
vi.mock('@ark-market/ui/button', () => ({
10+
Button: ({ children, onClick }: any) => <button onClick={onClick}>{children}</button>,
11+
}));
12+
13+
vi.mock('@ark-market/ui/dialog', () => ({
14+
Dialog: ({ children, open }: any) => open ? <div>{children}</div> : null,
15+
DialogContent: ({ children }: any) => <div>{children}</div>,
16+
DialogTitle: ({ children }: any) => <h2>{children}</h2>,
17+
}));
18+
19+
vi.mock('@ark-market/ui/icons', () => ({
20+
LoaderCircle: () => <div>LoaderCircle</div>,
21+
NoListing: () => <div>NoListing</div>,
22+
Success: () => <div>Success</div>,
23+
}));
24+
25+
vi.mock('~/app/token/[contractAddress]/[tokenId]/components/token-actions-token-overview', () => ({
26+
default: () => <div>TokenActionsTokenOverview</div>,
27+
}));
28+
29+
30+
describe("BuyNowDialog", () => {
31+
const mockToken: Token = {
32+
collection_image: "https://example.com/image.jpg",
33+
collection_name: "Test Collection",
34+
collection_address: '0x1234567890123456789012345678901234567890',
35+
owner: '0x0987654321098765432109876543210987654321',
36+
token_id: '1',
37+
last_price: '1000000000000000000',
38+
price: "1500000000000000000",
39+
metadata: {
40+
name: "Test Token",
41+
image: "https://example.com/token-image.jpg",
42+
animation_key: "",
43+
animation_url: "",
44+
image_key: "",
45+
attributes: [],
46+
},
47+
};
48+
49+
const mockCollectionToken: CollectionToken = {
50+
buy_in_progress: false,
51+
collection_address: '0x1234567890123456789012345678901234567890',
52+
collection_name: 'Test Collection',
53+
floor_difference: 10,
54+
is_listed: true,
55+
listed_at: Date.now(),
56+
listing: {
57+
is_auction: false,
58+
},
59+
owner: '0x0987654321098765432109876543210987654321',
60+
token_id: '2',
61+
last_price: '1000000000000000000',
62+
price: '1500000000000000000',
63+
metadata: {
64+
name: "Test Collection Token",
65+
image: "https://example.com/collection-token-image.jpg",
66+
animation_key: "",
67+
animation_url: "",
68+
image_key: "",
69+
attributes: [],
70+
},
71+
};
72+
73+
const mockSetIsOpen = vi.fn();
74+
75+
it('renders the dialog for Token when open', () => {
76+
render(
77+
<BuyNowDialog
78+
isOpen={true}
79+
setIsOpen={mockSetIsOpen}
80+
isSuccess={false}
81+
token={mockToken}
82+
price="1500000000000000000"
83+
/>
84+
);
85+
86+
expect(screen.getByText('Confirm your purchase')).toBeInTheDocument();
87+
expect(screen.getByText('NoListing')).toBeInTheDocument();
88+
expect(screen.getByText('TokenActionsTokenOverview')).toBeInTheDocument();
89+
expect(screen.getByText('Checking your payment')).toBeInTheDocument();
90+
});
91+
92+
it('renders the dialog for CollectionToken when open', () => {
93+
render(
94+
<BuyNowDialog
95+
isOpen={true}
96+
setIsOpen={mockSetIsOpen}
97+
isSuccess={false}
98+
token={mockCollectionToken}
99+
price="1500000000000000000"
100+
/>
101+
);
102+
103+
expect(screen.getByText('Confirm your purchase')).toBeInTheDocument();
104+
expect(screen.getByText('NoListing')).toBeInTheDocument();
105+
expect(screen.getByText('TokenActionsTokenOverview')).toBeInTheDocument();
106+
expect(screen.getByText('Checking your payment')).toBeInTheDocument();
107+
});
108+
109+
it('renders success state correctly', () => {
110+
render(
111+
<BuyNowDialog
112+
isOpen={true}
113+
setIsOpen={mockSetIsOpen}
114+
isSuccess={true}
115+
token={mockToken}
116+
price="1500000000000000000"
117+
/>
118+
);
119+
120+
expect(screen.getByText('Congratulations for your purchase')).toBeInTheDocument();
121+
expect(screen.getByText('Success')).toBeInTheDocument();
122+
expect(screen.getByText('Nice purchase, this NFT is now in your wallet ;)')).toBeInTheDocument();
123+
expect(screen.getByText('Continue to explore NFTs')).toBeInTheDocument();
124+
});
125+
126+
it('calls setIsOpen when "Continue to explore NFTs" button is clicked', () => {
127+
render(
128+
<BuyNowDialog
129+
isOpen={true}
130+
setIsOpen={mockSetIsOpen}
131+
isSuccess={true}
132+
token={mockToken}
133+
price="1500000000000000000"
134+
/>
135+
);
136+
137+
fireEvent.click(screen.getByText('Continue to explore NFTs'));
138+
expect(mockSetIsOpen).toHaveBeenCalledWith(false);
139+
});
140+
});
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/* eslint-disable @typescript-eslint/unbound-method */
2+
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
3+
import CopyButton from '../components/copy-button';
4+
import { describe, expect, it, beforeEach, vi } from 'vitest';
5+
6+
describe('CopyButton', () => {
7+
beforeEach(() => {
8+
Object.assign(navigator, {
9+
clipboard: {
10+
writeText: vi.fn().mockResolvedValue(undefined),
11+
},
12+
});
13+
});
14+
15+
it('renders the copy button', () => {
16+
render(<CopyButton textToCopy="Hello, World!" className="" />);
17+
expect(screen.getByRole('button')).toBeInTheDocument();
18+
});
19+
20+
it('copies the text when clicked', async () => {
21+
render(<CopyButton textToCopy="Hello, World!" className="" />);
22+
23+
const button = screen.getByRole('button');
24+
fireEvent.click(button);
25+
26+
await waitFor(() => {
27+
const tooltip = screen.getByRole('tooltip', { name: /copied/i });
28+
expect(tooltip).toBeInTheDocument();
29+
});
30+
31+
expect(navigator.clipboard.writeText).toHaveBeenCalledWith('Hello, World!');
32+
});
33+
});

0 commit comments

Comments
 (0)