-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathObjectGalleryIntegration.test.tsx
More file actions
156 lines (132 loc) · 5.81 KB
/
ObjectGalleryIntegration.test.tsx
File metadata and controls
156 lines (132 loc) · 5.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, act, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom';
import { ListView, ObjectGallery } from '@object-ui/plugin-list';
import { ComponentRegistry } from '@object-ui/core';
import { SchemaRendererProvider } from '@object-ui/react';
// Mock UI components
vi.mock('@object-ui/components', async (importOriginal) => {
const actual = await importOriginal<any>();
return {
...actual,
cn: (...inputs: any[]) => inputs.filter(Boolean).join(' '),
Button: ({ children, onClick }: any) => <button onClick={onClick}>{children}</button>,
Input: (props: any) => <input {...props} data-testid="mock-input" />,
ToggleGroup: ({ children, value, onValueChange }: any) => <div data-value={value} onChange={onValueChange}>{children}</div>,
ToggleGroupItem: ({ children, value }: any) => <button data-value={value}>{children}</button>,
Tabs: ({ children }: any) => <div>{children}</div>,
TabsList: ({ children }: any) => <div>{children}</div>,
TabsTrigger: ({ children }: any) => <button>{children}</button>,
Empty: ({ children }: any) => <div>{children}</div>,
Popover: ({ children }: any) => <div>{children}</div>,
PopoverTrigger: ({ children }: any) => <div>{children}</div>,
PopoverContent: ({ children }: any) => <div>{children}</div>,
};
});
describe('ObjectGallery & ListView Integration', () => {
beforeEach(() => {
// Register the gallery component so SchemaRenderer can find it
ComponentRegistry.register('object-gallery', ObjectGallery, { namespace: 'plugin-list' });
// Register other views to avoid warnings
ComponentRegistry.register('object-grid', () => <div>Grid</div>);
});
const mockData = [
{ _id: '1', name: 'Product A', category: 'Tech', image: 'http://img/a.jpg' },
{ _id: '2', name: 'Product B', category: 'Home', image: 'http://img/b.jpg' },
];
const mockDataSource = {
find: vi.fn(),
delete: vi.fn()
};
it('should receive data from ListView and render items', async () => {
mockDataSource.find.mockResolvedValue(mockData);
const schema = {
objectName: 'product',
viewType: 'gallery',
options: {
gallery: {
imageField: 'image',
titleField: 'name',
subtitleField: 'category'
}
}
};
await act(async () => {
render(
<SchemaRendererProvider dataSource={mockDataSource}>
<ListView schema={schema as any} dataSource={mockDataSource} />
</SchemaRendererProvider>
);
});
// Wait for data fetch
await waitFor(() => {
expect(mockDataSource.find).toHaveBeenCalledWith('product', expect.objectContaining({
$top: 100
}));
});
// Check if items are rendered
// ObjectGallery uses: <h3 ...>{item[titleField]}</h3>
expect(screen.getByText('Product A')).toBeInTheDocument();
expect(screen.getByText('Product B')).toBeInTheDocument();
});
it('should handle empty data gracefully', async () => {
mockDataSource.find.mockResolvedValue([]);
const schema = {
objectName: 'product',
viewType: 'gallery',
options: { gallery: {} }
};
await act(async () => {
render(
<SchemaRendererProvider dataSource={mockDataSource}>
<ListView schema={schema as any} dataSource={mockDataSource} />
</SchemaRendererProvider>
);
});
expect(screen.getByText('No items found')).toBeInTheDocument();
});
it('should use default configured fields if not specified in schema', async () => {
mockDataSource.find.mockResolvedValue([{ name: 'Mystery Item', image: 'test.jpg' }]);
const schema = {
objectName: 'product',
viewType: 'gallery',
// No options provided, defaults should be imageField='image', titleField='name'
};
await act(async () => {
render(
<SchemaRendererProvider dataSource={mockDataSource}>
<ListView schema={schema as any} dataSource={mockDataSource} />
</SchemaRendererProvider>
);
});
expect(screen.getByText('Mystery Item')).toBeInTheDocument();
// Since we didn't provide imageField in schema, ObjectGallery defaults to 'image'
// The img tag should be present
const img = screen.getByRole('img');
expect(img).toHaveAttribute('src', 'test.jpg');
});
it('should show placeholder if image is missing', async () => {
mockDataSource.find.mockResolvedValue([{ name: 'No Image Item' }]); // Missing 'image' field
const schema = {
objectName: 'product',
viewType: 'gallery',
options: {
gallery: {
imageField: 'photo' // Key that doesn't exist
}
}
};
await act(async () => {
render(
<SchemaRendererProvider dataSource={mockDataSource}>
<ListView schema={schema as any} dataSource={mockDataSource} />
</SchemaRendererProvider>
);
});
expect(screen.getByText('No Image Item')).toBeInTheDocument();
// Should verify fallback rendered.
// Logic: if (item[imageField]) render img else render div with initial
expect(screen.queryByRole('img')).toBeNull();
expect(screen.getByText('N')).toBeInTheDocument(); // Initial of 'No Image Item'
});
});