Skip to content

Commit c573ad2

Browse files
Copilothotlong
andcommitted
test: add DashboardRenderer widget data extraction tests
Tests cover chart data from options.data.items, backward compat from widget.data.items, table data, donut chart, and empty data fallback. Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent 073b390 commit c573ad2

1 file changed

Lines changed: 187 additions & 0 deletions

File tree

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
/**
2+
* ObjectUI
3+
* Copyright (c) 2024-present ObjectStack Inc.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
import { describe, it, expect } from 'vitest';
10+
import { render } from '@testing-library/react';
11+
import { DashboardRenderer } from '../DashboardRenderer';
12+
13+
/**
14+
* Extract component schemas rendered by SchemaRenderer from the DOM.
15+
* When a component type is not registered, SchemaRenderer renders
16+
* an error block containing a JSON <pre> element with the schema.
17+
* We parse those to verify the schema shape produced by DashboardRenderer.
18+
*/
19+
function getRenderedSchemas(container: HTMLElement): any[] {
20+
const pres = container.querySelectorAll('pre');
21+
return Array.from(pres).map(el => JSON.parse(el.textContent!));
22+
}
23+
24+
describe('DashboardRenderer widget data extraction', () => {
25+
it('should extract chart data from options.data.items', () => {
26+
const schema = {
27+
type: 'dashboard' as const,
28+
name: 'test',
29+
title: 'Test',
30+
widgets: [
31+
{
32+
type: 'bar',
33+
title: 'Test Bar',
34+
layout: { x: 0, y: 0, w: 2, h: 2 },
35+
options: {
36+
xField: 'name',
37+
yField: 'value',
38+
data: {
39+
provider: 'value',
40+
items: [
41+
{ name: 'A', value: 100 },
42+
{ name: 'B', value: 200 },
43+
],
44+
},
45+
},
46+
},
47+
],
48+
} as any;
49+
50+
const { container } = render(<DashboardRenderer schema={schema} />);
51+
const schemas = getRenderedSchemas(container);
52+
const chartSchema = schemas.find(s => s.type === 'chart');
53+
54+
expect(chartSchema).toBeDefined();
55+
expect(chartSchema.chartType).toBe('bar');
56+
expect(chartSchema.data).toHaveLength(2);
57+
expect(chartSchema.data[0]).toEqual({ name: 'A', value: 100 });
58+
expect(chartSchema.xAxisKey).toBe('name');
59+
expect(chartSchema.series).toEqual([{ dataKey: 'value' }]);
60+
});
61+
62+
it('should extract chart data from widget.data.items (backward compat)', () => {
63+
const schema = {
64+
type: 'dashboard' as const,
65+
name: 'test',
66+
title: 'Test',
67+
widgets: [
68+
{
69+
type: 'area',
70+
title: 'Test Area',
71+
layout: { x: 0, y: 0, w: 3, h: 2 },
72+
options: { xField: 'month', yField: 'revenue' },
73+
data: {
74+
provider: 'value',
75+
items: [
76+
{ month: 'Jan', revenue: 155000 },
77+
{ month: 'Feb', revenue: 87000 },
78+
],
79+
},
80+
},
81+
],
82+
} as any;
83+
84+
const { container } = render(<DashboardRenderer schema={schema} />);
85+
const schemas = getRenderedSchemas(container);
86+
const chartSchema = schemas.find(s => s.type === 'chart');
87+
88+
expect(chartSchema).toBeDefined();
89+
expect(chartSchema.chartType).toBe('area');
90+
expect(chartSchema.data).toHaveLength(2);
91+
expect(chartSchema.data[0].month).toBe('Jan');
92+
});
93+
94+
it('should extract table data from options.data.items', () => {
95+
const schema = {
96+
type: 'dashboard' as const,
97+
name: 'test',
98+
title: 'Test',
99+
widgets: [
100+
{
101+
type: 'table',
102+
title: 'Test Table',
103+
layout: { x: 0, y: 0, w: 4, h: 2 },
104+
options: {
105+
columns: [
106+
{ header: 'Name', accessorKey: 'name' },
107+
{ header: 'Amount', accessorKey: 'amount' },
108+
],
109+
data: {
110+
provider: 'value',
111+
items: [
112+
{ name: 'Item A', amount: '$100' },
113+
{ name: 'Item B', amount: '$200' },
114+
{ name: 'Item C', amount: '$300' },
115+
],
116+
},
117+
},
118+
},
119+
],
120+
} as any;
121+
122+
const { container } = render(<DashboardRenderer schema={schema} />);
123+
// data-table is a registered component that renders a real table,
124+
// so we verify the data reaches it by checking for rendered cell content
125+
expect(container.textContent).toContain('Item A');
126+
expect(container.textContent).toContain('$200');
127+
expect(container.textContent).toContain('Item C');
128+
});
129+
130+
it('should handle donut chart data from options', () => {
131+
const schema = {
132+
type: 'dashboard' as const,
133+
name: 'test',
134+
title: 'Test',
135+
widgets: [
136+
{
137+
type: 'donut',
138+
title: 'Test Donut',
139+
layout: { x: 0, y: 0, w: 1, h: 2 },
140+
options: {
141+
xField: 'source',
142+
yField: 'value',
143+
data: {
144+
provider: 'value',
145+
items: [
146+
{ source: 'Web', value: 2 },
147+
{ source: 'Referral', value: 1 },
148+
],
149+
},
150+
},
151+
},
152+
],
153+
} as any;
154+
155+
const { container } = render(<DashboardRenderer schema={schema} />);
156+
const schemas = getRenderedSchemas(container);
157+
const chartSchema = schemas.find(s => s.type === 'chart');
158+
159+
expect(chartSchema).toBeDefined();
160+
expect(chartSchema.chartType).toBe('donut');
161+
expect(chartSchema.data).toHaveLength(2);
162+
expect(chartSchema.xAxisKey).toBe('source');
163+
});
164+
165+
it('should default to empty array when no data is provided', () => {
166+
const schema = {
167+
type: 'dashboard' as const,
168+
name: 'test',
169+
title: 'Test',
170+
widgets: [
171+
{
172+
type: 'bar',
173+
title: 'No Data Bar',
174+
layout: { x: 0, y: 0, w: 2, h: 2 },
175+
options: { xField: 'x', yField: 'y' },
176+
},
177+
],
178+
} as any;
179+
180+
const { container } = render(<DashboardRenderer schema={schema} />);
181+
const schemas = getRenderedSchemas(container);
182+
const chartSchema = schemas.find(s => s.type === 'chart');
183+
184+
expect(chartSchema).toBeDefined();
185+
expect(chartSchema.data).toEqual([]);
186+
});
187+
});

0 commit comments

Comments
 (0)