PluginProbe
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO / 1.4.19
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO v1.4.19
1.4.19 1.4.18 1.4.17 1.4.16 1.4.15 1.4.14 1.4.13 1.4.12 1.4.11 1.4.10 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.54 1.3.53 1.3.52 1.3.51 1.3.50 All 182 releases
disco / backend / views / components / Analytics / __tests__ / pages / Dashboard.test.jsx

Dashboard.test.jsx in Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO 1.4.19, at backend/views/components/Analytics/__tests__/pages/Dashboard.test.jsx

360 lines 8.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import '@testing-library/jest-dom';
2 import { screen } from '@testing-library/react';
3 import Dashboard from '../../pages/Dashboard';
4 import { renderWithProviders } from '../setup/helpers';
5
6 // Mock Recharts — it requires a real DOM measurement layer
7 jest.mock('recharts', () => {
8 const OriginalModule = jest.requireActual('recharts');
9 return {
10 ...OriginalModule,
11 ResponsiveContainer: ({ children }) => (
12 <div data-testid="responsive-container">{children}</div>
13 ),
14 LineChart: ({ children }) => (
15 <div data-testid="line-chart">{children}</div>
16 ),
17 PieChart: ({ children }) => (
18 <div data-testid="pie-chart">{children}</div>
19 ),
20 Line: () => null,
21 Pie: ({ children }) => <div>{children}</div>,
22 Cell: () => null,
23 CartesianGrid: () => null,
24 XAxis: () => null,
25 YAxis: () => null,
26 Tooltip: () => null,
27 Legend: () => null,
28 };
29 });
30
31 // Mock RTK Query hooks to control data states
32 jest.mock('../../features/summary/summaryApi', () => ({
33 useGetSummaryQuery: jest.fn(),
34 useGetRevenueChartQuery: jest.fn(),
35 useGetIntentsPerformanceQuery: jest.fn(),
36 }));
37
38 jest.mock('../../features/campaigns/campaignsApi', () => ({
39 useGetCampaignsQuery: jest.fn(),
40 }));
41
42 jest.mock('../../features/products/productsApi', () => ({
43 useGetProductsQuery: jest.fn(),
44 }));
45
46 const {
47 useGetSummaryQuery,
48 useGetRevenueChartQuery,
49 useGetIntentsPerformanceQuery,
50 } = require('../../features/summary/summaryApi');
51
52 const {
53 useGetCampaignsQuery,
54 } = require('../../features/campaigns/campaignsApi');
55 const { useGetProductsQuery } = require('../../features/products/productsApi');
56
57 // Helper to set all hooks to a specific state
58 function setHooksState(state) {
59 const hookReturn = {
60 data: undefined,
61 isLoading: false,
62 isFetching: false,
63 ...state,
64 };
65 useGetSummaryQuery.mockReturnValue(hookReturn);
66 useGetRevenueChartQuery.mockReturnValue(hookReturn);
67 useGetIntentsPerformanceQuery.mockReturnValue(hookReturn);
68 useGetCampaignsQuery.mockReturnValue(hookReturn);
69 useGetProductsQuery.mockReturnValue(hookReturn);
70 }
71
72 describe('Dashboard', () => {
73 afterEach(() => {
74 jest.clearAllMocks();
75 });
76
77 describe('Rendering', () => {
78 it('renders the dashboard heading', () => {
79 setHooksState({ isLoading: true });
80 renderWithProviders(<Dashboard />);
81
82 expect(screen.getByText('Analytics Dashboard')).toBeInTheDocument();
83 });
84
85 it('renders all summary card titles', () => {
86 useGetSummaryQuery.mockReturnValue({
87 data: {
88 data: {
89 active_campaigns: {
90 current: 12,
91 trend: 'up',
92 change_percent: 10,
93 },
94 net_sales: {
95 current: 45000,
96 trend: 'up',
97 change_percent: 18.6,
98 },
99 discount_sales: {
100 current: 12000,
101 trend: 'up',
102 change_percent: 22,
103 },
104 total_orders: {
105 current: 342,
106 trend: 'up',
107 change_percent: 17.9,
108 },
109 disco_orders: {
110 current: 156,
111 trend: 'down',
112 change_percent: -13,
113 },
114 customers: {
115 current: 98,
116 trend: 'up',
117 change_percent: 15,
118 },
119 },
120 },
121 isLoading: false,
122 isFetching: false,
123 });
124 useGetRevenueChartQuery.mockReturnValue({
125 data: { data: [], interval: 'day' },
126 isLoading: false,
127 });
128 useGetIntentsPerformanceQuery.mockReturnValue({
129 data: {
130 data: [
131 {
132 intent: 'Product',
133 revenue: 1000,
134 orders: 10,
135 percentage: 100,
136 },
137 ],
138 total_revenue: 1000,
139 },
140 isLoading: false,
141 });
142 useGetCampaignsQuery.mockReturnValue({
143 data: {
144 data: [
145 {
146 campaign_id: 1,
147 campaign_name: 'Sale',
148 revenue: 5000,
149 },
150 ],
151 },
152 isLoading: false,
153 isFetching: false,
154 });
155 useGetProductsQuery.mockReturnValue({
156 data: {
157 data: [
158 { id: 1, name: 'Prod', image: '', total_revenue: 3000 },
159 ],
160 },
161 isLoading: false,
162 isFetching: false,
163 });
164
165 renderWithProviders(<Dashboard />);
166
167 expect(screen.getByText('Active Campaigns')).toBeInTheDocument();
168 expect(screen.getByText('Net Sale')).toBeInTheDocument();
169 expect(screen.getByText('Discount Sale')).toBeInTheDocument();
170 expect(screen.getByText('Total Orders')).toBeInTheDocument();
171 expect(
172 screen.getByText('Orders with Discount')
173 ).toBeInTheDocument();
174 expect(screen.getByText('Customers')).toBeInTheDocument();
175 });
176
177 it('renders chart sections', () => {
178 useGetSummaryQuery.mockReturnValue({
179 data: { data: {} },
180 isLoading: false,
181 isFetching: false,
182 });
183 useGetRevenueChartQuery.mockReturnValue({
184 data: {
185 data: [
186 {
187 date: '2025-05-01',
188 net_sales: 1000,
189 discount_sales: 300,
190 },
191 ],
192 interval: 'day',
193 },
194 isLoading: false,
195 });
196 useGetIntentsPerformanceQuery.mockReturnValue({
197 data: {
198 data: [
199 {
200 intent: 'Product',
201 revenue: 5000,
202 orders: 50,
203 percentage: 100,
204 },
205 ],
206 total_revenue: 5000,
207 },
208 isLoading: false,
209 });
210 useGetCampaignsQuery.mockReturnValue({
211 data: {
212 data: [
213 {
214 campaign_id: 1,
215 campaign_name: 'Sale A',
216 revenue: 5000,
217 },
218 ],
219 },
220 isLoading: false,
221 isFetching: false,
222 });
223 useGetProductsQuery.mockReturnValue({
224 data: {
225 data: [
226 {
227 id: 1,
228 name: 'Prod A',
229 image: '',
230 total_revenue: 3000,
231 },
232 ],
233 },
234 isLoading: false,
235 isFetching: false,
236 });
237
238 renderWithProviders(<Dashboard />);
239
240 expect(screen.getByText('Revenue over time')).toBeInTheDocument();
241 expect(screen.getByText('Revenue by intent')).toBeInTheDocument();
242 });
243
244 it('renders top campaigns and top products sections', () => {
245 useGetSummaryQuery.mockReturnValue({
246 data: { data: {} },
247 isLoading: false,
248 isFetching: false,
249 });
250 useGetRevenueChartQuery.mockReturnValue({
251 data: { data: [], interval: 'day' },
252 isLoading: false,
253 });
254 useGetIntentsPerformanceQuery.mockReturnValue({
255 data: {
256 data: [
257 {
258 intent: 'Product',
259 revenue: 1000,
260 orders: 10,
261 percentage: 100,
262 },
263 ],
264 total_revenue: 1000,
265 },
266 isLoading: false,
267 });
268 useGetCampaignsQuery.mockReturnValue({
269 data: {
270 data: [
271 {
272 campaign_id: 1,
273 campaign_name: 'Sale A',
274 revenue: 5000,
275 },
276 ],
277 },
278 isLoading: false,
279 isFetching: false,
280 });
281 useGetProductsQuery.mockReturnValue({
282 data: {
283 data: [
284 {
285 id: 1,
286 name: 'Prod A',
287 image: '',
288 total_revenue: 3000,
289 },
290 ],
291 },
292 isLoading: false,
293 isFetching: false,
294 });
295
296 renderWithProviders(<Dashboard />);
297
298 expect(screen.getByText('Top campaigns')).toBeInTheDocument();
299 expect(
300 screen.getByText('Top products by revenue')
301 ).toBeInTheDocument();
302 });
303 });
304
305 describe('Loading states', () => {
306 it('shows loading skeletons for all sections', () => {
307 setHooksState({ isLoading: true });
308 const { container } = renderWithProviders(<Dashboard />);
309
310 const pulseElements = container.querySelectorAll(
311 '.disco\\:animate-pulse'
312 );
313 expect(pulseElements.length).toBeGreaterThan(0);
314 });
315 });
316
317 describe('Empty states', () => {
318 it('shows empty state when campaigns data is empty', () => {
319 useGetSummaryQuery.mockReturnValue({
320 data: { data: {} },
321 isLoading: false,
322 isFetching: false,
323 });
324 useGetRevenueChartQuery.mockReturnValue({
325 data: { data: [], interval: 'day' },
326 isLoading: false,
327 });
328 useGetIntentsPerformanceQuery.mockReturnValue({
329 data: {
330 data: [
331 {
332 intent: 'Product',
333 revenue: 0,
334 orders: 0,
335 percentage: 0,
336 },
337 ],
338 total_revenue: 0,
339 },
340 isLoading: false,
341 });
342 useGetCampaignsQuery.mockReturnValue({
343 data: { data: [] },
344 isLoading: false,
345 isFetching: false,
346 });
347 useGetProductsQuery.mockReturnValue({
348 data: { data: [] },
349 isLoading: false,
350 isFetching: false,
351 });
352
353 renderWithProviders(<Dashboard />);
354
355 // Empty state for campaigns/products
356 expect(screen.getAllByText(/Not Found!/i).length).toBeGreaterThan(0);
357 });
358 });
359 });
360