Skip to content

Commit 4251ead

Browse files
Add comprehensive tests for new view components
Co-authored-by: xuyushun441-sys <255036401+xuyushun441-sys@users.noreply.github.com>
1 parent 4ab61a2 commit 4251ead

4 files changed

Lines changed: 706 additions & 0 deletions

File tree

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
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, vi, beforeEach } from 'vitest';
10+
import { render, screen, waitFor } from '@testing-library/react';
11+
import { ObjectCalendar } from '../ObjectCalendar';
12+
import type { ObjectGridSchema, DataSource } from '@object-ui/types';
13+
14+
describe('ObjectCalendar', () => {
15+
let mockDataSource: DataSource;
16+
let mockSchema: ObjectGridSchema;
17+
18+
beforeEach(() => {
19+
// Mock data source
20+
mockDataSource = {
21+
query: vi.fn().mockResolvedValue([
22+
{
23+
_id: '1',
24+
title: 'Meeting 1',
25+
start_date: '2024-01-15T10:00:00Z',
26+
end_date: '2024-01-15T11:00:00Z',
27+
},
28+
{
29+
_id: '2',
30+
title: 'Meeting 2',
31+
start_date: '2024-01-20T14:00:00Z',
32+
end_date: '2024-01-20T15:00:00Z',
33+
},
34+
]),
35+
getObjectSchema: vi.fn().mockResolvedValue({
36+
name: 'events',
37+
label: 'Events',
38+
fields: {
39+
title: { type: 'text', label: 'Title' },
40+
start_date: { type: 'datetime', label: 'Start Date' },
41+
end_date: { type: 'datetime', label: 'End Date' },
42+
},
43+
}),
44+
} as any;
45+
46+
// Mock schema with calendar config
47+
mockSchema = {
48+
type: 'object-grid',
49+
objectName: 'events',
50+
data: {
51+
provider: 'object',
52+
object: 'events',
53+
},
54+
filter: {
55+
calendar: {
56+
startDateField: 'start_date',
57+
endDateField: 'end_date',
58+
titleField: 'title',
59+
},
60+
},
61+
} as any;
62+
});
63+
64+
it('should render loading state initially', () => {
65+
render(<ObjectCalendar schema={mockSchema} dataSource={mockDataSource} />);
66+
expect(screen.getByText(/Loading calendar/i)).toBeInTheDocument();
67+
});
68+
69+
it('should fetch and display calendar data', async () => {
70+
render(<ObjectCalendar schema={mockSchema} dataSource={mockDataSource} />);
71+
72+
await waitFor(() => {
73+
expect(mockDataSource.query).toHaveBeenCalledWith('events', expect.any(Object));
74+
});
75+
76+
await waitFor(() => {
77+
expect(screen.getByText('Meeting 1')).toBeInTheDocument();
78+
expect(screen.getByText('Meeting 2')).toBeInTheDocument();
79+
});
80+
});
81+
82+
it('should render with inline data', async () => {
83+
const schemaWithInlineData = {
84+
...mockSchema,
85+
data: {
86+
provider: 'value',
87+
items: [
88+
{
89+
id: '1',
90+
title: 'Event A',
91+
start_date: '2024-01-15T10:00:00Z',
92+
},
93+
],
94+
},
95+
} as any;
96+
97+
render(<ObjectCalendar schema={schemaWithInlineData} />);
98+
99+
await waitFor(() => {
100+
expect(screen.getByText('Event A')).toBeInTheDocument();
101+
});
102+
});
103+
104+
it('should show error when calendar config is missing', async () => {
105+
const schemaWithoutCalendar = {
106+
...mockSchema,
107+
filter: {},
108+
} as any;
109+
110+
render(<ObjectCalendar schema={schemaWithoutCalendar} dataSource={mockDataSource} />);
111+
112+
await waitFor(() => {
113+
expect(screen.getByText(/Calendar configuration required/i)).toBeInTheDocument();
114+
});
115+
});
116+
117+
it('should display month navigation', async () => {
118+
render(<ObjectCalendar schema={mockSchema} dataSource={mockDataSource} />);
119+
120+
await waitFor(() => {
121+
expect(screen.getByText('Previous')).toBeInTheDocument();
122+
expect(screen.getByText('Today')).toBeInTheDocument();
123+
expect(screen.getByText('Next')).toBeInTheDocument();
124+
});
125+
});
126+
127+
it('should handle event click', async () => {
128+
const onEventClick = vi.fn();
129+
render(
130+
<ObjectCalendar
131+
schema={mockSchema}
132+
dataSource={mockDataSource}
133+
onEventClick={onEventClick}
134+
/>
135+
);
136+
137+
await waitFor(() => {
138+
expect(screen.getByText('Meeting 1')).toBeInTheDocument();
139+
});
140+
141+
const event = screen.getByText('Meeting 1');
142+
event.click();
143+
144+
expect(onEventClick).toHaveBeenCalledWith(
145+
expect.objectContaining({ title: 'Meeting 1' })
146+
);
147+
});
148+
149+
it('should display day names header', async () => {
150+
render(<ObjectCalendar schema={mockSchema} dataSource={mockDataSource} />);
151+
152+
await waitFor(() => {
153+
expect(screen.getByText('Sun')).toBeInTheDocument();
154+
expect(screen.getByText('Mon')).toBeInTheDocument();
155+
expect(screen.getByText('Tue')).toBeInTheDocument();
156+
expect(screen.getByText('Wed')).toBeInTheDocument();
157+
expect(screen.getByText('Thu')).toBeInTheDocument();
158+
expect(screen.getByText('Fri')).toBeInTheDocument();
159+
expect(screen.getByText('Sat')).toBeInTheDocument();
160+
});
161+
});
162+
});
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
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, vi, beforeEach } from 'vitest';
10+
import { render, screen, waitFor } from '@testing-library/react';
11+
import { ObjectGantt } from '../ObjectGantt';
12+
import type { ObjectGridSchema, DataSource } from '@object-ui/types';
13+
14+
describe('ObjectGantt', () => {
15+
let mockDataSource: DataSource;
16+
let mockSchema: ObjectGridSchema;
17+
18+
beforeEach(() => {
19+
// Mock data source
20+
mockDataSource = {
21+
query: vi.fn().mockResolvedValue([
22+
{
23+
_id: '1',
24+
title: 'Task 1',
25+
start_date: '2024-01-01T00:00:00Z',
26+
end_date: '2024-01-15T00:00:00Z',
27+
progress: 50,
28+
},
29+
{
30+
_id: '2',
31+
title: 'Task 2',
32+
start_date: '2024-01-10T00:00:00Z',
33+
end_date: '2024-01-25T00:00:00Z',
34+
progress: 75,
35+
},
36+
]),
37+
getObjectSchema: vi.fn().mockResolvedValue({
38+
name: 'tasks',
39+
label: 'Tasks',
40+
fields: {
41+
title: { type: 'text', label: 'Title' },
42+
start_date: { type: 'date', label: 'Start Date' },
43+
end_date: { type: 'date', label: 'End Date' },
44+
progress: { type: 'number', label: 'Progress' },
45+
},
46+
}),
47+
} as any;
48+
49+
// Mock schema with gantt config
50+
mockSchema = {
51+
type: 'object-grid',
52+
objectName: 'tasks',
53+
data: {
54+
provider: 'object',
55+
object: 'tasks',
56+
},
57+
filter: {
58+
gantt: {
59+
startDateField: 'start_date',
60+
endDateField: 'end_date',
61+
titleField: 'title',
62+
progressField: 'progress',
63+
},
64+
},
65+
} as any;
66+
});
67+
68+
it('should render loading state initially', () => {
69+
render(<ObjectGantt schema={mockSchema} dataSource={mockDataSource} />);
70+
expect(screen.getByText(/Loading Gantt chart/i)).toBeInTheDocument();
71+
});
72+
73+
it('should fetch and display gantt data', async () => {
74+
render(<ObjectGantt schema={mockSchema} dataSource={mockDataSource} />);
75+
76+
await waitFor(() => {
77+
expect(mockDataSource.query).toHaveBeenCalledWith('tasks', expect.any(Object));
78+
});
79+
80+
await waitFor(() => {
81+
expect(screen.getByText('Task 1')).toBeInTheDocument();
82+
expect(screen.getByText('Task 2')).toBeInTheDocument();
83+
});
84+
});
85+
86+
it('should display task progress', async () => {
87+
render(<ObjectGantt schema={mockSchema} dataSource={mockDataSource} />);
88+
89+
await waitFor(() => {
90+
expect(screen.getByText('50%')).toBeInTheDocument();
91+
expect(screen.getByText('75%')).toBeInTheDocument();
92+
});
93+
});
94+
95+
it('should render with inline data', async () => {
96+
const schemaWithInlineData = {
97+
...mockSchema,
98+
data: {
99+
provider: 'value',
100+
items: [
101+
{
102+
id: '1',
103+
title: 'Project A',
104+
start_date: '2024-01-01',
105+
end_date: '2024-01-31',
106+
progress: 30,
107+
},
108+
],
109+
},
110+
} as any;
111+
112+
render(<ObjectGantt schema={schemaWithInlineData} />);
113+
114+
await waitFor(() => {
115+
expect(screen.getByText('Project A')).toBeInTheDocument();
116+
expect(screen.getByText('30%')).toBeInTheDocument();
117+
});
118+
});
119+
120+
it('should show error when gantt config is missing', async () => {
121+
const schemaWithoutGantt = {
122+
...mockSchema,
123+
filter: {},
124+
} as any;
125+
126+
render(<ObjectGantt schema={schemaWithoutGantt} dataSource={mockDataSource} />);
127+
128+
await waitFor(() => {
129+
expect(screen.getByText(/Gantt configuration required/i)).toBeInTheDocument();
130+
});
131+
});
132+
133+
it('should handle task click', async () => {
134+
const onTaskClick = vi.fn();
135+
render(
136+
<ObjectGantt
137+
schema={mockSchema}
138+
dataSource={mockDataSource}
139+
onTaskClick={onTaskClick}
140+
/>
141+
);
142+
143+
await waitFor(() => {
144+
expect(screen.getByText('Task 1')).toBeInTheDocument();
145+
});
146+
147+
// Click on task in the list
148+
const task = screen.getAllByText('Task 1')[0].closest('div');
149+
if (task) {
150+
task.click();
151+
expect(onTaskClick).toHaveBeenCalledWith(
152+
expect.objectContaining({ title: 'Task 1' })
153+
);
154+
}
155+
});
156+
157+
it('should display task list section', async () => {
158+
render(<ObjectGantt schema={mockSchema} dataSource={mockDataSource} />);
159+
160+
await waitFor(() => {
161+
expect(screen.getByText('Tasks')).toBeInTheDocument();
162+
});
163+
});
164+
165+
it('should display date ranges for tasks', async () => {
166+
render(<ObjectGantt schema={mockSchema} dataSource={mockDataSource} />);
167+
168+
await waitFor(() => {
169+
// Should display formatted dates
170+
const dateElements = screen.getAllByText(/-/);
171+
expect(dateElements.length).toBeGreaterThan(0);
172+
});
173+
});
174+
});

0 commit comments

Comments
 (0)