@akinon/ai-modal-table 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/dist/cjs/__tests__/index.test.d.ts +2 -0
  2. package/dist/cjs/__tests__/index.test.d.ts.map +1 -0
  3. package/dist/cjs/__tests__/index.test.js +82 -0
  4. package/dist/cjs/__tests__/index.test.tsx +94 -0
  5. package/dist/cjs/ai-modal-table/__tests__/index.test.d.ts +2 -0
  6. package/dist/cjs/ai-modal-table/__tests__/index.test.d.ts.map +1 -0
  7. package/dist/cjs/ai-modal-table/__tests__/index.test.js +59 -0
  8. package/dist/cjs/ai-modal-table/__tests__/index.test.tsx +98 -0
  9. package/dist/cjs/ai-modal-table/index.d.ts +4 -0
  10. package/dist/cjs/ai-modal-table/index.d.ts.map +1 -0
  11. package/dist/cjs/ai-modal-table/index.js +54 -0
  12. package/dist/cjs/ai-table/__tests__/index.test.d.ts +2 -0
  13. package/dist/cjs/ai-table/__tests__/index.test.d.ts.map +1 -0
  14. package/dist/cjs/ai-table/__tests__/index.test.js +348 -0
  15. package/dist/cjs/ai-table/__tests__/index.test.tsx +572 -0
  16. package/dist/cjs/ai-table/components/__tests__/content.test.d.ts +2 -0
  17. package/dist/cjs/ai-table/components/__tests__/content.test.d.ts.map +1 -0
  18. package/dist/cjs/ai-table/components/__tests__/content.test.js +1349 -0
  19. package/dist/cjs/ai-table/components/__tests__/content.test.tsx +1637 -0
  20. package/dist/cjs/ai-table/components/__tests__/filters.test.d.ts +2 -0
  21. package/dist/cjs/ai-table/components/__tests__/filters.test.d.ts.map +1 -0
  22. package/dist/cjs/ai-table/components/__tests__/filters.test.js +400 -0
  23. package/dist/cjs/ai-table/components/__tests__/filters.test.tsx +534 -0
  24. package/dist/cjs/ai-table/components/__tests__/footer.test.d.ts +2 -0
  25. package/dist/cjs/ai-table/components/__tests__/footer.test.d.ts.map +1 -0
  26. package/dist/cjs/ai-table/components/__tests__/footer.test.js +465 -0
  27. package/dist/cjs/ai-table/components/__tests__/footer.test.tsx +597 -0
  28. package/dist/cjs/ai-table/components/__tests__/mapper.test.d.ts +2 -0
  29. package/dist/cjs/ai-table/components/__tests__/mapper.test.d.ts.map +1 -0
  30. package/dist/cjs/ai-table/components/__tests__/mapper.test.js +453 -0
  31. package/dist/cjs/ai-table/components/__tests__/mapper.test.tsx +601 -0
  32. package/dist/cjs/ai-table/components/__tests__/pagination.test.d.ts +2 -0
  33. package/dist/cjs/ai-table/components/__tests__/pagination.test.d.ts.map +1 -0
  34. package/dist/cjs/ai-table/components/__tests__/pagination.test.js +430 -0
  35. package/dist/cjs/ai-table/components/__tests__/pagination.test.tsx +629 -0
  36. package/dist/cjs/ai-table/components/__tests__/row-actions.test.d.ts +2 -0
  37. package/dist/cjs/ai-table/components/__tests__/row-actions.test.d.ts.map +1 -0
  38. package/dist/cjs/ai-table/components/__tests__/row-actions.test.js +382 -0
  39. package/dist/cjs/ai-table/components/__tests__/row-actions.test.tsx +507 -0
  40. package/dist/cjs/ai-table/components/content.d.ts +11 -0
  41. package/dist/cjs/ai-table/components/content.d.ts.map +1 -0
  42. package/dist/cjs/ai-table/components/content.js +309 -0
  43. package/dist/cjs/ai-table/components/filters.d.ts +10 -0
  44. package/dist/cjs/ai-table/components/filters.d.ts.map +1 -0
  45. package/dist/cjs/ai-table/components/filters.js +55 -0
  46. package/dist/cjs/ai-table/components/footer.d.ts +12 -0
  47. package/dist/cjs/ai-table/components/footer.d.ts.map +1 -0
  48. package/dist/cjs/ai-table/components/footer.js +24 -0
  49. package/dist/cjs/ai-table/components/mapper.d.ts +11 -0
  50. package/dist/cjs/ai-table/components/mapper.d.ts.map +1 -0
  51. package/dist/cjs/ai-table/components/mapper.js +21 -0
  52. package/dist/cjs/ai-table/components/pagination.d.ts +11 -0
  53. package/dist/cjs/ai-table/components/pagination.d.ts.map +1 -0
  54. package/dist/cjs/ai-table/components/pagination.js +106 -0
  55. package/dist/cjs/ai-table/components/row-actions.d.ts +14 -0
  56. package/dist/cjs/ai-table/components/row-actions.d.ts.map +1 -0
  57. package/dist/cjs/ai-table/components/row-actions.js +52 -0
  58. package/dist/cjs/ai-table/constants/index.d.ts +17 -0
  59. package/dist/cjs/ai-table/constants/index.d.ts.map +1 -0
  60. package/dist/cjs/ai-table/constants/index.js +19 -0
  61. package/dist/cjs/ai-table/i18n/index.d.ts +3 -0
  62. package/dist/cjs/ai-table/i18n/index.d.ts.map +1 -0
  63. package/dist/cjs/ai-table/i18n/index.js +14 -0
  64. package/dist/cjs/ai-table/i18n/translations/en.d.ts +8 -0
  65. package/dist/cjs/ai-table/i18n/translations/en.d.ts.map +1 -0
  66. package/dist/cjs/ai-table/i18n/translations/en.js +9 -0
  67. package/dist/cjs/ai-table/i18n/translations/tr.d.ts +8 -0
  68. package/dist/cjs/ai-table/i18n/translations/tr.d.ts.map +1 -0
  69. package/dist/cjs/ai-table/i18n/translations/tr.js +9 -0
  70. package/dist/cjs/ai-table/index.d.ts +4 -0
  71. package/dist/cjs/ai-table/index.d.ts.map +1 -0
  72. package/dist/cjs/ai-table/index.js +71 -0
  73. package/dist/cjs/ai-table/utils/data-format/__tests__/index.test.d.ts +2 -0
  74. package/dist/cjs/ai-table/utils/data-format/__tests__/index.test.d.ts.map +1 -0
  75. package/dist/cjs/ai-table/utils/data-format/__tests__/index.test.js +146 -0
  76. package/dist/cjs/ai-table/utils/data-format/__tests__/index.test.ts +184 -0
  77. package/dist/cjs/ai-table/utils/data-format/index.d.ts +7 -0
  78. package/dist/cjs/ai-table/utils/data-format/index.d.ts.map +1 -0
  79. package/dist/cjs/ai-table/utils/data-format/index.js +43 -0
  80. package/dist/cjs/ai-table/utils/render-mapper-fields/__tests__/index.test.d.ts +2 -0
  81. package/dist/cjs/ai-table/utils/render-mapper-fields/__tests__/index.test.d.ts.map +1 -0
  82. package/dist/cjs/ai-table/utils/render-mapper-fields/__tests__/index.test.js +291 -0
  83. package/dist/cjs/ai-table/utils/render-mapper-fields/__tests__/index.test.tsx +399 -0
  84. package/dist/cjs/ai-table/utils/render-mapper-fields/index.d.ts +10 -0
  85. package/dist/cjs/ai-table/utils/render-mapper-fields/index.d.ts.map +1 -0
  86. package/dist/cjs/ai-table/utils/render-mapper-fields/index.js +48 -0
  87. package/dist/cjs/index.d.ts +4 -0
  88. package/dist/cjs/index.d.ts.map +1 -0
  89. package/dist/cjs/index.js +7 -0
  90. package/dist/cjs/types/index.d.ts +134 -0
  91. package/dist/cjs/types/index.d.ts.map +1 -0
  92. package/dist/cjs/types/index.js +2 -0
  93. package/dist/esm/__tests__/index.test.d.ts +2 -0
  94. package/dist/esm/__tests__/index.test.d.ts.map +1 -0
  95. package/dist/esm/__tests__/index.test.js +80 -0
  96. package/dist/esm/__tests__/index.test.tsx +94 -0
  97. package/dist/esm/ai-modal-table/__tests__/index.test.d.ts +2 -0
  98. package/dist/esm/ai-modal-table/__tests__/index.test.d.ts.map +1 -0
  99. package/dist/esm/ai-modal-table/__tests__/index.test.js +57 -0
  100. package/dist/esm/ai-modal-table/__tests__/index.test.tsx +98 -0
  101. package/dist/esm/ai-modal-table/index.d.ts +4 -0
  102. package/dist/esm/ai-modal-table/index.d.ts.map +1 -0
  103. package/dist/esm/ai-modal-table/index.js +50 -0
  104. package/dist/esm/ai-table/__tests__/index.test.d.ts +2 -0
  105. package/dist/esm/ai-table/__tests__/index.test.d.ts.map +1 -0
  106. package/dist/esm/ai-table/__tests__/index.test.js +346 -0
  107. package/dist/esm/ai-table/__tests__/index.test.tsx +572 -0
  108. package/dist/esm/ai-table/components/__tests__/content.test.d.ts +2 -0
  109. package/dist/esm/ai-table/components/__tests__/content.test.d.ts.map +1 -0
  110. package/dist/esm/ai-table/components/__tests__/content.test.js +1347 -0
  111. package/dist/esm/ai-table/components/__tests__/content.test.tsx +1637 -0
  112. package/dist/esm/ai-table/components/__tests__/filters.test.d.ts +2 -0
  113. package/dist/esm/ai-table/components/__tests__/filters.test.d.ts.map +1 -0
  114. package/dist/esm/ai-table/components/__tests__/filters.test.js +398 -0
  115. package/dist/esm/ai-table/components/__tests__/filters.test.tsx +534 -0
  116. package/dist/esm/ai-table/components/__tests__/footer.test.d.ts +2 -0
  117. package/dist/esm/ai-table/components/__tests__/footer.test.d.ts.map +1 -0
  118. package/dist/esm/ai-table/components/__tests__/footer.test.js +463 -0
  119. package/dist/esm/ai-table/components/__tests__/footer.test.tsx +597 -0
  120. package/dist/esm/ai-table/components/__tests__/mapper.test.d.ts +2 -0
  121. package/dist/esm/ai-table/components/__tests__/mapper.test.d.ts.map +1 -0
  122. package/dist/esm/ai-table/components/__tests__/mapper.test.js +451 -0
  123. package/dist/esm/ai-table/components/__tests__/mapper.test.tsx +601 -0
  124. package/dist/esm/ai-table/components/__tests__/pagination.test.d.ts +2 -0
  125. package/dist/esm/ai-table/components/__tests__/pagination.test.d.ts.map +1 -0
  126. package/dist/esm/ai-table/components/__tests__/pagination.test.js +428 -0
  127. package/dist/esm/ai-table/components/__tests__/pagination.test.tsx +629 -0
  128. package/dist/esm/ai-table/components/__tests__/row-actions.test.d.ts +2 -0
  129. package/dist/esm/ai-table/components/__tests__/row-actions.test.d.ts.map +1 -0
  130. package/dist/esm/ai-table/components/__tests__/row-actions.test.js +380 -0
  131. package/dist/esm/ai-table/components/__tests__/row-actions.test.tsx +507 -0
  132. package/dist/esm/ai-table/components/content.d.ts +11 -0
  133. package/dist/esm/ai-table/components/content.d.ts.map +1 -0
  134. package/dist/esm/ai-table/components/content.js +305 -0
  135. package/dist/esm/ai-table/components/filters.d.ts +10 -0
  136. package/dist/esm/ai-table/components/filters.d.ts.map +1 -0
  137. package/dist/esm/ai-table/components/filters.js +51 -0
  138. package/dist/esm/ai-table/components/footer.d.ts +12 -0
  139. package/dist/esm/ai-table/components/footer.d.ts.map +1 -0
  140. package/dist/esm/ai-table/components/footer.js +20 -0
  141. package/dist/esm/ai-table/components/mapper.d.ts +11 -0
  142. package/dist/esm/ai-table/components/mapper.d.ts.map +1 -0
  143. package/dist/esm/ai-table/components/mapper.js +17 -0
  144. package/dist/esm/ai-table/components/pagination.d.ts +11 -0
  145. package/dist/esm/ai-table/components/pagination.d.ts.map +1 -0
  146. package/dist/esm/ai-table/components/pagination.js +102 -0
  147. package/dist/esm/ai-table/components/row-actions.d.ts +14 -0
  148. package/dist/esm/ai-table/components/row-actions.d.ts.map +1 -0
  149. package/dist/esm/ai-table/components/row-actions.js +48 -0
  150. package/dist/esm/ai-table/constants/index.d.ts +17 -0
  151. package/dist/esm/ai-table/constants/index.d.ts.map +1 -0
  152. package/dist/esm/ai-table/constants/index.js +16 -0
  153. package/dist/esm/ai-table/i18n/index.d.ts +3 -0
  154. package/dist/esm/ai-table/i18n/index.d.ts.map +1 -0
  155. package/dist/esm/ai-table/i18n/index.js +11 -0
  156. package/dist/esm/ai-table/i18n/translations/en.d.ts +8 -0
  157. package/dist/esm/ai-table/i18n/translations/en.d.ts.map +1 -0
  158. package/dist/esm/ai-table/i18n/translations/en.js +7 -0
  159. package/dist/esm/ai-table/i18n/translations/tr.d.ts +8 -0
  160. package/dist/esm/ai-table/i18n/translations/tr.d.ts.map +1 -0
  161. package/dist/esm/ai-table/i18n/translations/tr.js +7 -0
  162. package/dist/esm/ai-table/index.d.ts +4 -0
  163. package/dist/esm/ai-table/index.d.ts.map +1 -0
  164. package/dist/esm/ai-table/index.js +67 -0
  165. package/dist/esm/ai-table/utils/data-format/__tests__/index.test.d.ts +2 -0
  166. package/dist/esm/ai-table/utils/data-format/__tests__/index.test.d.ts.map +1 -0
  167. package/dist/esm/ai-table/utils/data-format/__tests__/index.test.js +144 -0
  168. package/dist/esm/ai-table/utils/data-format/__tests__/index.test.ts +184 -0
  169. package/dist/esm/ai-table/utils/data-format/index.d.ts +7 -0
  170. package/dist/esm/ai-table/utils/data-format/index.d.ts.map +1 -0
  171. package/dist/esm/ai-table/utils/data-format/index.js +38 -0
  172. package/dist/esm/ai-table/utils/render-mapper-fields/__tests__/index.test.d.ts +2 -0
  173. package/dist/esm/ai-table/utils/render-mapper-fields/__tests__/index.test.d.ts.map +1 -0
  174. package/dist/esm/ai-table/utils/render-mapper-fields/__tests__/index.test.js +289 -0
  175. package/dist/esm/ai-table/utils/render-mapper-fields/__tests__/index.test.tsx +399 -0
  176. package/dist/esm/ai-table/utils/render-mapper-fields/index.d.ts +10 -0
  177. package/dist/esm/ai-table/utils/render-mapper-fields/index.d.ts.map +1 -0
  178. package/dist/esm/ai-table/utils/render-mapper-fields/index.js +44 -0
  179. package/dist/esm/index.d.ts +4 -0
  180. package/dist/esm/index.d.ts.map +1 -0
  181. package/dist/esm/index.js +2 -0
  182. package/dist/esm/types/index.d.ts +134 -0
  183. package/dist/esm/types/index.d.ts.map +1 -0
  184. package/dist/esm/types/index.js +1 -0
  185. package/package.json +60 -0
@@ -0,0 +1,572 @@
1
+ import { render, screen, within } from '@testing-library/react';
2
+ import userEvent from '@testing-library/user-event';
3
+ import type { ReactNode } from 'react';
4
+ import * as React from 'react';
5
+ import { describe, expect, it, vi } from 'vitest';
6
+
7
+ import type { AiTableProps } from '../../types';
8
+ import { AiTable } from '../index';
9
+
10
+ // Mock sub-components
11
+ vi.mock('../components/content', () => ({
12
+ TableContent: ({
13
+ data,
14
+ selectedRows,
15
+ onToggleSelection,
16
+ rowKey
17
+ }: {
18
+ data: Record<string, unknown>[];
19
+ selectedRows: (number | string)[];
20
+ onToggleSelection: (id: number | string) => void;
21
+ rowKey?: string;
22
+ }) => (
23
+ <div data-testid="table-content">
24
+ {data.map((row: Record<string, unknown>) => {
25
+ const customId = rowKey
26
+ ? (row[rowKey] as number | string)
27
+ : (row.id as number | string);
28
+ return (
29
+ <div
30
+ key={customId}
31
+ data-testid={`row-${customId}`}
32
+ onClick={() => onToggleSelection(customId)}
33
+ >
34
+ {JSON.stringify(row)}
35
+ </div>
36
+ );
37
+ })}
38
+ <div data-testid="selected-count">{selectedRows.length}</div>
39
+ </div>
40
+ )
41
+ }));
42
+
43
+ vi.mock('../components/filters', () => ({
44
+ TableFilters: ({
45
+ filters,
46
+ onFilterChange
47
+ }: {
48
+ filters: Array<{ key: string }>;
49
+ onFilterChange: (key: string, value: string) => void;
50
+ }) => (
51
+ <div data-testid="table-filters">
52
+ {filters.map(filter => (
53
+ <input
54
+ key={filter.key}
55
+ data-testid={`filter-${filter.key}`}
56
+ onChange={e => onFilterChange(filter.key, e.target.value)}
57
+ placeholder={filter.key}
58
+ />
59
+ ))}
60
+ </div>
61
+ )
62
+ }));
63
+
64
+ vi.mock('../components/footer', () => ({
65
+ TableFooter: ({
66
+ selectedCount,
67
+ isSubmitting,
68
+ onSubmitAll,
69
+ onSubmitSelected
70
+ }: {
71
+ selectedCount: number;
72
+ isSubmitting: boolean;
73
+ onSubmitAll: () => void;
74
+ onSubmitSelected: () => void;
75
+ }) => (
76
+ <div data-testid="table-footer">
77
+ <div data-testid="selected-count">{selectedCount}</div>
78
+ <button
79
+ data-testid="submit-all"
80
+ onClick={onSubmitAll}
81
+ disabled={isSubmitting}
82
+ >
83
+ Submit All
84
+ </button>
85
+ <button
86
+ data-testid="submit-selected"
87
+ onClick={onSubmitSelected}
88
+ disabled={isSubmitting || selectedCount === 0}
89
+ >
90
+ Submit Selected
91
+ </button>
92
+ </div>
93
+ )
94
+ }));
95
+
96
+ vi.mock('../components/pagination', () => ({
97
+ TablePagination: ({
98
+ currentPage,
99
+ pageSize,
100
+ total,
101
+ onPageChange,
102
+ onPageSizeChange
103
+ }: {
104
+ currentPage: number;
105
+ pageSize: number;
106
+ total: number;
107
+ onPageChange: (page: number) => void;
108
+ onPageSizeChange: (size: number) => void;
109
+ }) => (
110
+ <div data-testid="table-pagination">
111
+ <div data-testid="current-page">{currentPage}</div>
112
+ <div data-testid="page-size">{pageSize}</div>
113
+ <div data-testid="total">{total}</div>
114
+ <button
115
+ data-testid="prev-page"
116
+ onClick={() => onPageChange(currentPage - 1)}
117
+ >
118
+ Prev
119
+ </button>
120
+ <button
121
+ data-testid="next-page"
122
+ onClick={() => onPageChange(currentPage + 1)}
123
+ >
124
+ Next
125
+ </button>
126
+ <select
127
+ data-testid="page-size-select"
128
+ onChange={e => onPageSizeChange(Number(e.target.value))}
129
+ value={pageSize}
130
+ >
131
+ <option value="10">10</option>
132
+ <option value="20">20</option>
133
+ </select>
134
+ </div>
135
+ )
136
+ }));
137
+
138
+ vi.mock('@akinon/ui-ai-spinner', () => ({
139
+ AiSpinner: () => <div data-testid="ai-spinner">Loading...</div>
140
+ }));
141
+
142
+ vi.mock('@akinon/ui-button', () => ({
143
+ Button: ({
144
+ children,
145
+ onClick,
146
+ ...props
147
+ }: {
148
+ children: ReactNode;
149
+ onClick?: () => void;
150
+ }) => (
151
+ <button onClick={onClick} {...props}>
152
+ {children}
153
+ </button>
154
+ )
155
+ }));
156
+
157
+ vi.mock('@akinon/ui-layout', () => ({
158
+ Flex: ({ children, ...props }: { children: ReactNode }) => (
159
+ <div {...props}>{children}</div>
160
+ )
161
+ }));
162
+
163
+ describe('AiTable', () => {
164
+ const mockData = [
165
+ { pk: 1, id: 1, name: 'Ali', category: 'Electronics' },
166
+ { pk: 2, id: 2, name: 'Ayşe', category: 'Clothing' },
167
+ { pk: 3, id: 3, name: 'Mehmet', category: 'Electronics' }
168
+ ];
169
+
170
+ const mockColumns = [
171
+ { title: 'ID', dataIndex: 'id' },
172
+ { title: 'Name', dataIndex: 'name' },
173
+ { title: 'Category', dataIndex: 'category' }
174
+ ];
175
+
176
+ const defaultProps: AiTableProps = {
177
+ data: mockData,
178
+ columns: mockColumns,
179
+ selectedRows: [],
180
+ onChangeSelectedRows: vi.fn(),
181
+ onEdit: vi.fn(),
182
+ onSubmitAllData: vi.fn(),
183
+ onSubmitSelectedData: vi.fn(),
184
+ isLoading: false,
185
+ isSubmitting: false,
186
+ submitAllLabel: 'Submit All',
187
+ submitSelectedLabel: 'Submit Selected',
188
+ filters: []
189
+ };
190
+
191
+ describe('Rendering', () => {
192
+ it('should render loading spinner when isLoading is true', () => {
193
+ render(<AiTable {...defaultProps} isLoading={true} />);
194
+
195
+ expect(screen.getByTestId('ai-spinner')).toBeInTheDocument();
196
+ });
197
+
198
+ it('should render all components when data is loaded', () => {
199
+ render(<AiTable {...defaultProps} />);
200
+
201
+ expect(screen.getByTestId('table-filters')).toBeInTheDocument();
202
+ expect(screen.getByTestId('table-content')).toBeInTheDocument();
203
+ expect(screen.getByTestId('table-footer')).toBeInTheDocument();
204
+ expect(screen.getByTestId('table-pagination')).toBeInTheDocument();
205
+ });
206
+
207
+ it('should render custom class name when provided', () => {
208
+ const { container } = render(
209
+ <AiTable {...defaultProps} tableClassName="custom-class" />
210
+ );
211
+
212
+ expect(container.querySelector('.custom-class')).toBeInTheDocument();
213
+ });
214
+
215
+ it('should render expand/collapse buttons when mapperConfig is provided', () => {
216
+ const mapperConfig = {
217
+ dataIndex: 'attributes',
218
+ onAddItem: vi.fn(),
219
+ onRemoveItem: vi.fn(),
220
+ onItemChange: vi.fn()
221
+ };
222
+
223
+ render(<AiTable {...defaultProps} mapperConfig={mapperConfig} />);
224
+
225
+ expect(screen.getByText('Expand All')).toBeInTheDocument();
226
+ expect(screen.getByText('Collapse All')).toBeInTheDocument();
227
+ });
228
+
229
+ it('should not render expand/collapse buttons when mapperConfig is not provided', () => {
230
+ render(<AiTable {...defaultProps} mapperConfig={undefined} />);
231
+
232
+ expect(screen.queryByText('Expand All')).not.toBeInTheDocument();
233
+ expect(screen.queryByText('Collapse All')).not.toBeInTheDocument();
234
+ });
235
+ });
236
+
237
+ describe('Data Display', () => {
238
+ it('should display all data on initial render', () => {
239
+ render(<AiTable {...defaultProps} />);
240
+
241
+ expect(screen.getByTestId('row-1')).toBeInTheDocument();
242
+ expect(screen.getByTestId('row-2')).toBeInTheDocument();
243
+ expect(screen.getByTestId('row-3')).toBeInTheDocument();
244
+ });
245
+
246
+ it('should display empty table when data is empty', () => {
247
+ render(<AiTable {...defaultProps} data={[]} />);
248
+
249
+ expect(screen.getByTestId('table-content')).toBeInTheDocument();
250
+ expect(screen.queryByTestId('row-1')).not.toBeInTheDocument();
251
+ });
252
+
253
+ it('should use custom rowKey when provided', () => {
254
+ const customKeyData: Record<string, unknown>[] = [
255
+ { userId: 'user-1', name: 'Ali' },
256
+ { userId: 'user-2', name: 'Ayşe' }
257
+ ];
258
+
259
+ render(
260
+ <AiTable {...defaultProps} data={customKeyData} rowKey="userId" />
261
+ );
262
+
263
+ expect(screen.getByTestId('row-user-1')).toBeInTheDocument();
264
+ expect(screen.getByTestId('row-user-2')).toBeInTheDocument();
265
+ });
266
+ });
267
+
268
+ describe('Filtering', () => {
269
+ it('should call onFilterChange when filter input changes', async () => {
270
+ const user = userEvent.setup();
271
+ const mockFilters = [{ key: 'name', type: 'text' }];
272
+
273
+ render(<AiTable {...defaultProps} filters={mockFilters} />);
274
+
275
+ const filterInput = screen.getByTestId('filter-name');
276
+ await user.type(filterInput, 'Ali');
277
+
278
+ expect(screen.getByTestId('row-1')).toBeInTheDocument();
279
+ });
280
+
281
+ it('should reset to first page when filter changes', async () => {
282
+ const user = userEvent.setup();
283
+ const mockFilters = [{ key: 'category', type: 'text' }];
284
+
285
+ render(<AiTable {...defaultProps} filters={mockFilters} />);
286
+
287
+ // First change page
288
+ const nextPageBtn = screen.getByTestId('next-page');
289
+ await user.click(nextPageBtn);
290
+ let currentPage = screen.getAllByTestId('current-page')[0];
291
+ expect(currentPage).toHaveTextContent('2');
292
+
293
+ // Then apply filter
294
+ const filterInput = screen.getByTestId('filter-category');
295
+ await user.type(filterInput, 'Electronics');
296
+
297
+ // Should reset to page 1
298
+ currentPage = screen.getAllByTestId('current-page')[0];
299
+ expect(currentPage).toHaveTextContent('1');
300
+ });
301
+
302
+ it('should handle multiple filters simultaneously', async () => {
303
+ const user = userEvent.setup();
304
+ const mockFilters = [
305
+ { key: 'name', type: 'text' },
306
+ { key: 'category', type: 'text' }
307
+ ];
308
+
309
+ render(<AiTable {...defaultProps} filters={mockFilters} />);
310
+
311
+ const nameFilter = screen.getByTestId('filter-name');
312
+ const categoryFilter = screen.getByTestId('filter-category');
313
+
314
+ await user.type(nameFilter, 'Ali');
315
+ await user.type(categoryFilter, 'Electronics');
316
+
317
+ expect(screen.getByTestId('row-1')).toBeInTheDocument();
318
+ });
319
+ });
320
+
321
+ describe('Pagination', () => {
322
+ const largeData = Array.from({ length: 25 }, (_, i) => ({
323
+ id: i + 1,
324
+ name: `Item ${i + 1}`,
325
+ category: 'Test'
326
+ }));
327
+
328
+ it('should display total count correctly', () => {
329
+ render(<AiTable {...defaultProps} data={largeData} />);
330
+
331
+ expect(screen.getByTestId('total')).toHaveTextContent('25');
332
+ });
333
+
334
+ it('should change page when next page button is clicked', async () => {
335
+ const user = userEvent.setup();
336
+
337
+ render(<AiTable {...defaultProps} data={largeData} />);
338
+
339
+ const nextPageBtn = screen.getByTestId('next-page');
340
+ await user.click(nextPageBtn);
341
+
342
+ expect(screen.getAllByTestId('current-page')[0]).toHaveTextContent('2');
343
+ });
344
+
345
+ it('should change page size when page size select changes', async () => {
346
+ const user = userEvent.setup();
347
+
348
+ render(<AiTable {...defaultProps} data={largeData} />);
349
+
350
+ const pageSizeSelect = screen.getByTestId('page-size-select');
351
+ await user.selectOptions(pageSizeSelect, '20');
352
+
353
+ expect(screen.getByTestId('page-size')).toHaveTextContent('20');
354
+ });
355
+
356
+ it('should handle edge case when on last page', () => {
357
+ render(<AiTable {...defaultProps} data={largeData} />);
358
+
359
+ expect(screen.getByTestId('total')).toHaveTextContent('25');
360
+ expect(screen.getByTestId('current-page')).toHaveTextContent('1');
361
+ });
362
+ });
363
+
364
+ describe('Row Selection', () => {
365
+ it('should call onChangeSelectedRows when row selection changes', async () => {
366
+ const user = userEvent.setup();
367
+ const onChangeSelectedRows = vi.fn();
368
+
369
+ render(
370
+ <AiTable
371
+ {...defaultProps}
372
+ onChangeSelectedRows={onChangeSelectedRows}
373
+ />
374
+ );
375
+
376
+ const row1 = screen.getByTestId('row-1');
377
+ await user.click(row1);
378
+
379
+ expect(onChangeSelectedRows).toHaveBeenCalled();
380
+ });
381
+
382
+ it('should maintain selected rows state', () => {
383
+ const selectedRows = [1];
384
+
385
+ render(<AiTable {...defaultProps} selectedRows={selectedRows} />);
386
+
387
+ const footerElement = screen.getByTestId('table-footer');
388
+ const selectedCountElement =
389
+ within(footerElement).getByTestId('selected-count');
390
+ expect(selectedCountElement).toHaveTextContent('1');
391
+ });
392
+
393
+ it('should display correct selected count in footer', () => {
394
+ const selectedRows = [1, 2];
395
+
396
+ render(<AiTable {...defaultProps} selectedRows={selectedRows} />);
397
+
398
+ const footerSelectedCount = screen
399
+ .getAllByTestId('selected-count')
400
+ .find(
401
+ el => el.parentElement?.getAttribute('data-testid') === 'table-footer'
402
+ );
403
+
404
+ expect(footerSelectedCount).toHaveTextContent('2');
405
+ });
406
+
407
+ it('should disable submit selected button when no rows are selected', () => {
408
+ render(<AiTable {...defaultProps} selectedRows={[]} />);
409
+
410
+ const submitSelectedBtn = screen.getByTestId('submit-selected');
411
+ expect(submitSelectedBtn).toBeDisabled();
412
+ });
413
+
414
+ it('should enable submit selected button when rows are selected', () => {
415
+ render(<AiTable {...defaultProps} selectedRows={[1, 2]} />);
416
+
417
+ const submitSelectedBtn = screen.getByTestId('submit-selected');
418
+ expect(submitSelectedBtn).toBeEnabled();
419
+ });
420
+ });
421
+
422
+ describe('Form Submission', () => {
423
+ it('should call onSubmitAllData when submit all is clicked', async () => {
424
+ const user = userEvent.setup();
425
+ const onSubmitAllData = vi.fn();
426
+
427
+ render(<AiTable {...defaultProps} onSubmitAllData={onSubmitAllData} />);
428
+
429
+ const submitAllBtn = screen.getByTestId('submit-all');
430
+ await user.click(submitAllBtn);
431
+
432
+ expect(onSubmitAllData).toHaveBeenCalled();
433
+ });
434
+
435
+ it('should call onSubmitSelectedData when submit selected is clicked', async () => {
436
+ const user = userEvent.setup();
437
+ const onSubmitSelectedData = vi.fn();
438
+
439
+ render(
440
+ <AiTable
441
+ {...defaultProps}
442
+ selectedRows={[1, 2]}
443
+ onSubmitSelectedData={onSubmitSelectedData}
444
+ />
445
+ );
446
+
447
+ const submitSelectedBtn = screen.getByTestId('submit-selected');
448
+ await user.click(submitSelectedBtn);
449
+
450
+ expect(onSubmitSelectedData).toHaveBeenCalled();
451
+ });
452
+
453
+ it('should disable submit buttons when isSubmitting is true', () => {
454
+ render(<AiTable {...defaultProps} isSubmitting={true} />);
455
+
456
+ expect(screen.getByTestId('submit-all')).toBeDisabled();
457
+ expect(screen.getByTestId('submit-selected')).toBeDisabled();
458
+ });
459
+
460
+ it('should display custom submit labels when provided', () => {
461
+ render(
462
+ <AiTable
463
+ {...defaultProps}
464
+ submitAllLabel="Save All"
465
+ submitSelectedLabel="Save Selected"
466
+ />
467
+ );
468
+
469
+ expect(screen.getByText('Submit All')).toBeInTheDocument();
470
+ expect(screen.getByText('Submit Selected')).toBeInTheDocument();
471
+ });
472
+ });
473
+
474
+ describe('Custom Action Buttons', () => {
475
+ it('should render custom action buttons when provided', () => {
476
+ const customActionButtons = (rowId: number | string) => (
477
+ <button key="edit" onClick={vi.fn()}>
478
+ Edit {rowId}
479
+ </button>
480
+ );
481
+
482
+ render(
483
+ <AiTable {...defaultProps} customActionButtons={customActionButtons} />
484
+ );
485
+
486
+ // Note: Since TableContent is mocked, we're verifying the prop is passed
487
+ const tableContent = screen.getByTestId('table-content');
488
+ expect(tableContent).toBeInTheDocument();
489
+ });
490
+ });
491
+
492
+ describe('Mapper Configuration', () => {
493
+ it('should pass mapper configuration to table content', () => {
494
+ const mapperConfig = {
495
+ dataIndex: 'attributes',
496
+ onAddItem: vi.fn(),
497
+ onRemoveItem: vi.fn(),
498
+ onItemChange: vi.fn()
499
+ };
500
+
501
+ render(<AiTable {...defaultProps} mapperConfig={mapperConfig} />);
502
+
503
+ expect(screen.getByTestId('table-content')).toBeInTheDocument();
504
+ });
505
+
506
+ it('should handle expand all button click', async () => {
507
+ const user = userEvent.setup();
508
+ const mapperConfig = {
509
+ dataIndex: 'attributes',
510
+ onAddItem: vi.fn(),
511
+ onRemoveItem: vi.fn(),
512
+ onItemChange: vi.fn()
513
+ };
514
+
515
+ render(<AiTable {...defaultProps} mapperConfig={mapperConfig} />);
516
+
517
+ const expandAllBtn = screen.getByText('Expand All');
518
+ await user.click(expandAllBtn);
519
+
520
+ expect(expandAllBtn).toBeInTheDocument();
521
+ });
522
+
523
+ it('should handle collapse all button click', async () => {
524
+ const user = userEvent.setup();
525
+ const mapperConfig = {
526
+ dataIndex: 'attributes',
527
+ onAddItem: vi.fn(),
528
+ onRemoveItem: vi.fn(),
529
+ onItemChange: vi.fn()
530
+ };
531
+
532
+ render(<AiTable {...defaultProps} mapperConfig={mapperConfig} />);
533
+
534
+ const collapseAllBtn = screen.getByText('Collapse All');
535
+ await user.click(collapseAllBtn);
536
+
537
+ expect(collapseAllBtn).toBeInTheDocument();
538
+ });
539
+ });
540
+
541
+ describe('Edit Functionality', () => {
542
+ it('should pass onEdit callback to table content', () => {
543
+ const onEdit = vi.fn();
544
+
545
+ render(<AiTable {...defaultProps} onEdit={onEdit} />);
546
+
547
+ expect(screen.getByTestId('table-content')).toBeInTheDocument();
548
+ });
549
+
550
+ it('should pass editDataIndexes to table content', () => {
551
+ const editDataIndexes = ['0', '2'];
552
+
553
+ render(<AiTable {...defaultProps} editDataIndexes={editDataIndexes} />);
554
+
555
+ expect(screen.getByTestId('table-content')).toBeInTheDocument();
556
+ });
557
+ });
558
+
559
+ describe('Edge Cases', () => {
560
+ it('should handle empty columns array', () => {
561
+ render(<AiTable {...defaultProps} columns={[]} />);
562
+
563
+ expect(screen.getByTestId('table-content')).toBeInTheDocument();
564
+ });
565
+
566
+ it('should handle zero columns', () => {
567
+ render(<AiTable {...defaultProps} columns={[]} data={[{ id: 1 }]} />);
568
+
569
+ expect(screen.getByTestId('table-content')).toBeInTheDocument();
570
+ });
571
+ });
572
+ });
@@ -0,0 +1,2 @@
1
+ import '@testing-library/jest-dom/vitest';
2
+ //# sourceMappingURL=content.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.test.d.ts","sourceRoot":"","sources":["../../../../../src/ai-table/components/__tests__/content.test.tsx"],"names":[],"mappings":"AACA,OAAO,kCAAkC,CAAC"}