Skip to content

Commit 4db5be6

Browse files
test(desktop): improve market mvvm test coverage with msw
1 parent 8e271ca commit 4db5be6

File tree

7 files changed

+993
-0
lines changed

7 files changed

+993
-0
lines changed

.changeset/wise-rivers-change.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"ledger-live-desktop": minor
3+
---
4+
5+
improve market coverage on mvvm
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
import React from "react";
2+
import { render, screen, fireEvent } from "tests/testSetup";
3+
import { RowItemView } from "../RowItemView";
4+
import { MOCK_MARKET_CURRENCY_DATA } from "@ledgerhq/live-common/market/utils/fixtures";
5+
import { RowItemViewProps } from "../types";
6+
7+
const mockCurrency = MOCK_MARKET_CURRENCY_DATA[0];
8+
9+
function createDefaultProps(overrides: Partial<RowItemViewProps> = {}): RowItemViewProps {
10+
return {
11+
style: {},
12+
currency: mockCurrency,
13+
counterCurrency: "usd",
14+
locale: "en",
15+
isStarred: false,
16+
hasActions: false,
17+
currentPriceChangePercentage: 2.5,
18+
earnStakeLabelCoin: "Earn",
19+
availableOnBuy: false,
20+
availableOnSwap: false,
21+
availableOnStake: false,
22+
buyLabel: "Buy",
23+
swapLabel: "Swap",
24+
onCurrencyClick: jest.fn(),
25+
onStarClick: jest.fn(),
26+
onBuy: jest.fn(),
27+
onSwap: jest.fn(),
28+
onStake: jest.fn(),
29+
...overrides,
30+
};
31+
}
32+
33+
describe("RowItemView", () => {
34+
beforeEach(() => {
35+
jest.clearAllMocks();
36+
});
37+
38+
it("should render currency name and ticker", () => {
39+
render(<RowItemView {...createDefaultProps()} />);
40+
41+
expect(screen.getByText("Bitcoin")).toBeVisible();
42+
expect(screen.getByText("BTC")).toBeVisible();
43+
});
44+
45+
it("should render marketcap rank", () => {
46+
render(<RowItemView {...createDefaultProps()} />);
47+
48+
expect(screen.getByText("1")).toBeVisible();
49+
});
50+
51+
it("should render row when marketcapRank is present", () => {
52+
render(<RowItemView {...createDefaultProps()} />);
53+
54+
const row = screen.getByTestId("market-BTC-row");
55+
expect(row).toBeVisible();
56+
});
57+
58+
it("should render CryptoIcon when ledgerIds has entries", () => {
59+
render(<RowItemView {...createDefaultProps()} />);
60+
61+
expect(screen.queryByAltText("currency logo")).toBeNull();
62+
});
63+
64+
it("should render img fallback when ledgerIds is empty", () => {
65+
const currency = { ...mockCurrency, ledgerIds: [] };
66+
render(<RowItemView {...createDefaultProps({ currency })} />);
67+
68+
expect(screen.getByAltText("currency logo")).toBeVisible();
69+
});
70+
71+
it("should show Buy/Swap/Stake buttons when hasActions and all available", () => {
72+
render(
73+
<RowItemView
74+
{...createDefaultProps({
75+
hasActions: true,
76+
availableOnBuy: true,
77+
availableOnSwap: true,
78+
availableOnStake: true,
79+
})}
80+
/>,
81+
);
82+
83+
expect(screen.getByTestId("market-BTC-buy-button")).toBeVisible();
84+
expect(screen.getByTestId("market-BTC-swap-button")).toBeVisible();
85+
expect(screen.getByTestId("market-BTC-stake-button")).toBeVisible();
86+
});
87+
88+
it("should hide action buttons when hasActions is false", () => {
89+
render(<RowItemView {...createDefaultProps({ hasActions: false })} />);
90+
91+
expect(screen.queryByTestId("market-BTC-buy-button")).toBeNull();
92+
expect(screen.queryByTestId("market-BTC-swap-button")).toBeNull();
93+
expect(screen.queryByTestId("market-BTC-stake-button")).toBeNull();
94+
});
95+
96+
it("should show only Buy button when only availableOnBuy is true", () => {
97+
render(
98+
<RowItemView
99+
{...createDefaultProps({
100+
hasActions: true,
101+
availableOnBuy: true,
102+
availableOnSwap: false,
103+
availableOnStake: false,
104+
})}
105+
/>,
106+
);
107+
108+
expect(screen.getByTestId("market-BTC-buy-button")).toBeVisible();
109+
expect(screen.queryByTestId("market-BTC-swap-button")).toBeNull();
110+
expect(screen.queryByTestId("market-BTC-stake-button")).toBeNull();
111+
});
112+
113+
it("should render '-' when currentPriceChangePercentage is undefined", () => {
114+
render(<RowItemView {...createDefaultProps({ currentPriceChangePercentage: undefined })} />);
115+
116+
const priceChangeCell = screen.getByTestId("market-price-change");
117+
expect(priceChangeCell).toHaveTextContent("-");
118+
});
119+
120+
it("should render FormattedVal when currentPriceChangePercentage is defined", () => {
121+
render(<RowItemView {...createDefaultProps({ currentPriceChangePercentage: 5.5 })} />);
122+
123+
const priceChangeCell = screen.getByTestId("market-price-change");
124+
expect(priceChangeCell).not.toHaveTextContent("-");
125+
});
126+
127+
it("should render star button when isStarred is true", () => {
128+
render(<RowItemView {...createDefaultProps({ isStarred: true })} />);
129+
130+
expect(screen.getByTestId("market-BTC-star-button")).toBeVisible();
131+
});
132+
133+
it("should render star button when isStarred is false", () => {
134+
render(<RowItemView {...createDefaultProps({ isStarred: false })} />);
135+
136+
expect(screen.getByTestId("market-BTC-star-button")).toBeVisible();
137+
});
138+
139+
it("should call onCurrencyClick on row click", () => {
140+
const onCurrencyClick = jest.fn();
141+
render(<RowItemView {...createDefaultProps({ onCurrencyClick })} />);
142+
143+
fireEvent.click(screen.getByTestId("market-BTC-row"));
144+
expect(onCurrencyClick).toHaveBeenCalledTimes(1);
145+
});
146+
147+
it("should call onStarClick on star button click", () => {
148+
const onStarClick = jest.fn();
149+
render(<RowItemView {...createDefaultProps({ onStarClick })} />);
150+
151+
fireEvent.click(screen.getByTestId("market-BTC-star-button"));
152+
expect(onStarClick).toHaveBeenCalledTimes(1);
153+
});
154+
155+
it("should call onBuy when Buy button is clicked", () => {
156+
const onBuy = jest.fn();
157+
render(
158+
<RowItemView
159+
{...createDefaultProps({
160+
hasActions: true,
161+
availableOnBuy: true,
162+
onBuy,
163+
})}
164+
/>,
165+
);
166+
167+
fireEvent.click(screen.getByTestId("market-BTC-buy-button"));
168+
expect(onBuy).toHaveBeenCalledTimes(1);
169+
});
170+
171+
it("should call onSwap when Swap button is clicked", () => {
172+
const onSwap = jest.fn();
173+
render(
174+
<RowItemView
175+
{...createDefaultProps({
176+
hasActions: true,
177+
availableOnSwap: true,
178+
onSwap,
179+
})}
180+
/>,
181+
);
182+
183+
fireEvent.click(screen.getByTestId("market-BTC-swap-button"));
184+
expect(onSwap).toHaveBeenCalledTimes(1);
185+
});
186+
187+
it("should call onStake when Stake button is clicked", () => {
188+
const onStake = jest.fn();
189+
render(
190+
<RowItemView
191+
{...createDefaultProps({
192+
hasActions: true,
193+
availableOnStake: true,
194+
onStake,
195+
})}
196+
/>,
197+
);
198+
199+
fireEvent.click(screen.getByTestId("market-BTC-stake-button"));
200+
expect(onStake).toHaveBeenCalledTimes(1);
201+
});
202+
203+
it("should render sparkline chart when sparklineIn7d exists", () => {
204+
const currency = {
205+
...mockCurrency,
206+
sparklineIn7d: { path: "M0 0L1 1", viewBox: "0 0 100 50", isPositive: true },
207+
};
208+
render(<RowItemView {...createDefaultProps({ currency })} />);
209+
210+
const graphCell = screen.getByTestId("market-small-graph");
211+
expect(graphCell.querySelector("svg")).toBeVisible();
212+
});
213+
214+
it("should not render sparkline chart when sparklineIn7d is undefined", () => {
215+
const currency = { ...mockCurrency, sparklineIn7d: undefined };
216+
render(<RowItemView {...createDefaultProps({ currency })} />);
217+
218+
const graphCell = screen.getByTestId("market-small-graph");
219+
expect(graphCell.querySelector("svg")).toBeNull();
220+
});
221+
});

0 commit comments

Comments
 (0)