@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.
- package/dist/cjs/__tests__/index.test.d.ts +2 -0
- package/dist/cjs/__tests__/index.test.d.ts.map +1 -0
- package/dist/cjs/__tests__/index.test.js +82 -0
- package/dist/cjs/__tests__/index.test.tsx +94 -0
- package/dist/cjs/ai-modal-table/__tests__/index.test.d.ts +2 -0
- package/dist/cjs/ai-modal-table/__tests__/index.test.d.ts.map +1 -0
- package/dist/cjs/ai-modal-table/__tests__/index.test.js +59 -0
- package/dist/cjs/ai-modal-table/__tests__/index.test.tsx +98 -0
- package/dist/cjs/ai-modal-table/index.d.ts +4 -0
- package/dist/cjs/ai-modal-table/index.d.ts.map +1 -0
- package/dist/cjs/ai-modal-table/index.js +54 -0
- package/dist/cjs/ai-table/__tests__/index.test.d.ts +2 -0
- package/dist/cjs/ai-table/__tests__/index.test.d.ts.map +1 -0
- package/dist/cjs/ai-table/__tests__/index.test.js +348 -0
- package/dist/cjs/ai-table/__tests__/index.test.tsx +572 -0
- package/dist/cjs/ai-table/components/__tests__/content.test.d.ts +2 -0
- package/dist/cjs/ai-table/components/__tests__/content.test.d.ts.map +1 -0
- package/dist/cjs/ai-table/components/__tests__/content.test.js +1349 -0
- package/dist/cjs/ai-table/components/__tests__/content.test.tsx +1637 -0
- package/dist/cjs/ai-table/components/__tests__/filters.test.d.ts +2 -0
- package/dist/cjs/ai-table/components/__tests__/filters.test.d.ts.map +1 -0
- package/dist/cjs/ai-table/components/__tests__/filters.test.js +400 -0
- package/dist/cjs/ai-table/components/__tests__/filters.test.tsx +534 -0
- package/dist/cjs/ai-table/components/__tests__/footer.test.d.ts +2 -0
- package/dist/cjs/ai-table/components/__tests__/footer.test.d.ts.map +1 -0
- package/dist/cjs/ai-table/components/__tests__/footer.test.js +465 -0
- package/dist/cjs/ai-table/components/__tests__/footer.test.tsx +597 -0
- package/dist/cjs/ai-table/components/__tests__/mapper.test.d.ts +2 -0
- package/dist/cjs/ai-table/components/__tests__/mapper.test.d.ts.map +1 -0
- package/dist/cjs/ai-table/components/__tests__/mapper.test.js +453 -0
- package/dist/cjs/ai-table/components/__tests__/mapper.test.tsx +601 -0
- package/dist/cjs/ai-table/components/__tests__/pagination.test.d.ts +2 -0
- package/dist/cjs/ai-table/components/__tests__/pagination.test.d.ts.map +1 -0
- package/dist/cjs/ai-table/components/__tests__/pagination.test.js +430 -0
- package/dist/cjs/ai-table/components/__tests__/pagination.test.tsx +629 -0
- package/dist/cjs/ai-table/components/__tests__/row-actions.test.d.ts +2 -0
- package/dist/cjs/ai-table/components/__tests__/row-actions.test.d.ts.map +1 -0
- package/dist/cjs/ai-table/components/__tests__/row-actions.test.js +382 -0
- package/dist/cjs/ai-table/components/__tests__/row-actions.test.tsx +507 -0
- package/dist/cjs/ai-table/components/content.d.ts +11 -0
- package/dist/cjs/ai-table/components/content.d.ts.map +1 -0
- package/dist/cjs/ai-table/components/content.js +309 -0
- package/dist/cjs/ai-table/components/filters.d.ts +10 -0
- package/dist/cjs/ai-table/components/filters.d.ts.map +1 -0
- package/dist/cjs/ai-table/components/filters.js +55 -0
- package/dist/cjs/ai-table/components/footer.d.ts +12 -0
- package/dist/cjs/ai-table/components/footer.d.ts.map +1 -0
- package/dist/cjs/ai-table/components/footer.js +24 -0
- package/dist/cjs/ai-table/components/mapper.d.ts +11 -0
- package/dist/cjs/ai-table/components/mapper.d.ts.map +1 -0
- package/dist/cjs/ai-table/components/mapper.js +21 -0
- package/dist/cjs/ai-table/components/pagination.d.ts +11 -0
- package/dist/cjs/ai-table/components/pagination.d.ts.map +1 -0
- package/dist/cjs/ai-table/components/pagination.js +106 -0
- package/dist/cjs/ai-table/components/row-actions.d.ts +14 -0
- package/dist/cjs/ai-table/components/row-actions.d.ts.map +1 -0
- package/dist/cjs/ai-table/components/row-actions.js +52 -0
- package/dist/cjs/ai-table/constants/index.d.ts +17 -0
- package/dist/cjs/ai-table/constants/index.d.ts.map +1 -0
- package/dist/cjs/ai-table/constants/index.js +19 -0
- package/dist/cjs/ai-table/i18n/index.d.ts +3 -0
- package/dist/cjs/ai-table/i18n/index.d.ts.map +1 -0
- package/dist/cjs/ai-table/i18n/index.js +14 -0
- package/dist/cjs/ai-table/i18n/translations/en.d.ts +8 -0
- package/dist/cjs/ai-table/i18n/translations/en.d.ts.map +1 -0
- package/dist/cjs/ai-table/i18n/translations/en.js +9 -0
- package/dist/cjs/ai-table/i18n/translations/tr.d.ts +8 -0
- package/dist/cjs/ai-table/i18n/translations/tr.d.ts.map +1 -0
- package/dist/cjs/ai-table/i18n/translations/tr.js +9 -0
- package/dist/cjs/ai-table/index.d.ts +4 -0
- package/dist/cjs/ai-table/index.d.ts.map +1 -0
- package/dist/cjs/ai-table/index.js +71 -0
- package/dist/cjs/ai-table/utils/data-format/__tests__/index.test.d.ts +2 -0
- package/dist/cjs/ai-table/utils/data-format/__tests__/index.test.d.ts.map +1 -0
- package/dist/cjs/ai-table/utils/data-format/__tests__/index.test.js +146 -0
- package/dist/cjs/ai-table/utils/data-format/__tests__/index.test.ts +184 -0
- package/dist/cjs/ai-table/utils/data-format/index.d.ts +7 -0
- package/dist/cjs/ai-table/utils/data-format/index.d.ts.map +1 -0
- package/dist/cjs/ai-table/utils/data-format/index.js +43 -0
- package/dist/cjs/ai-table/utils/render-mapper-fields/__tests__/index.test.d.ts +2 -0
- package/dist/cjs/ai-table/utils/render-mapper-fields/__tests__/index.test.d.ts.map +1 -0
- package/dist/cjs/ai-table/utils/render-mapper-fields/__tests__/index.test.js +291 -0
- package/dist/cjs/ai-table/utils/render-mapper-fields/__tests__/index.test.tsx +399 -0
- package/dist/cjs/ai-table/utils/render-mapper-fields/index.d.ts +10 -0
- package/dist/cjs/ai-table/utils/render-mapper-fields/index.d.ts.map +1 -0
- package/dist/cjs/ai-table/utils/render-mapper-fields/index.js +48 -0
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +7 -0
- package/dist/cjs/types/index.d.ts +134 -0
- package/dist/cjs/types/index.d.ts.map +1 -0
- package/dist/cjs/types/index.js +2 -0
- package/dist/esm/__tests__/index.test.d.ts +2 -0
- package/dist/esm/__tests__/index.test.d.ts.map +1 -0
- package/dist/esm/__tests__/index.test.js +80 -0
- package/dist/esm/__tests__/index.test.tsx +94 -0
- package/dist/esm/ai-modal-table/__tests__/index.test.d.ts +2 -0
- package/dist/esm/ai-modal-table/__tests__/index.test.d.ts.map +1 -0
- package/dist/esm/ai-modal-table/__tests__/index.test.js +57 -0
- package/dist/esm/ai-modal-table/__tests__/index.test.tsx +98 -0
- package/dist/esm/ai-modal-table/index.d.ts +4 -0
- package/dist/esm/ai-modal-table/index.d.ts.map +1 -0
- package/dist/esm/ai-modal-table/index.js +50 -0
- package/dist/esm/ai-table/__tests__/index.test.d.ts +2 -0
- package/dist/esm/ai-table/__tests__/index.test.d.ts.map +1 -0
- package/dist/esm/ai-table/__tests__/index.test.js +346 -0
- package/dist/esm/ai-table/__tests__/index.test.tsx +572 -0
- package/dist/esm/ai-table/components/__tests__/content.test.d.ts +2 -0
- package/dist/esm/ai-table/components/__tests__/content.test.d.ts.map +1 -0
- package/dist/esm/ai-table/components/__tests__/content.test.js +1347 -0
- package/dist/esm/ai-table/components/__tests__/content.test.tsx +1637 -0
- package/dist/esm/ai-table/components/__tests__/filters.test.d.ts +2 -0
- package/dist/esm/ai-table/components/__tests__/filters.test.d.ts.map +1 -0
- package/dist/esm/ai-table/components/__tests__/filters.test.js +398 -0
- package/dist/esm/ai-table/components/__tests__/filters.test.tsx +534 -0
- package/dist/esm/ai-table/components/__tests__/footer.test.d.ts +2 -0
- package/dist/esm/ai-table/components/__tests__/footer.test.d.ts.map +1 -0
- package/dist/esm/ai-table/components/__tests__/footer.test.js +463 -0
- package/dist/esm/ai-table/components/__tests__/footer.test.tsx +597 -0
- package/dist/esm/ai-table/components/__tests__/mapper.test.d.ts +2 -0
- package/dist/esm/ai-table/components/__tests__/mapper.test.d.ts.map +1 -0
- package/dist/esm/ai-table/components/__tests__/mapper.test.js +451 -0
- package/dist/esm/ai-table/components/__tests__/mapper.test.tsx +601 -0
- package/dist/esm/ai-table/components/__tests__/pagination.test.d.ts +2 -0
- package/dist/esm/ai-table/components/__tests__/pagination.test.d.ts.map +1 -0
- package/dist/esm/ai-table/components/__tests__/pagination.test.js +428 -0
- package/dist/esm/ai-table/components/__tests__/pagination.test.tsx +629 -0
- package/dist/esm/ai-table/components/__tests__/row-actions.test.d.ts +2 -0
- package/dist/esm/ai-table/components/__tests__/row-actions.test.d.ts.map +1 -0
- package/dist/esm/ai-table/components/__tests__/row-actions.test.js +380 -0
- package/dist/esm/ai-table/components/__tests__/row-actions.test.tsx +507 -0
- package/dist/esm/ai-table/components/content.d.ts +11 -0
- package/dist/esm/ai-table/components/content.d.ts.map +1 -0
- package/dist/esm/ai-table/components/content.js +305 -0
- package/dist/esm/ai-table/components/filters.d.ts +10 -0
- package/dist/esm/ai-table/components/filters.d.ts.map +1 -0
- package/dist/esm/ai-table/components/filters.js +51 -0
- package/dist/esm/ai-table/components/footer.d.ts +12 -0
- package/dist/esm/ai-table/components/footer.d.ts.map +1 -0
- package/dist/esm/ai-table/components/footer.js +20 -0
- package/dist/esm/ai-table/components/mapper.d.ts +11 -0
- package/dist/esm/ai-table/components/mapper.d.ts.map +1 -0
- package/dist/esm/ai-table/components/mapper.js +17 -0
- package/dist/esm/ai-table/components/pagination.d.ts +11 -0
- package/dist/esm/ai-table/components/pagination.d.ts.map +1 -0
- package/dist/esm/ai-table/components/pagination.js +102 -0
- package/dist/esm/ai-table/components/row-actions.d.ts +14 -0
- package/dist/esm/ai-table/components/row-actions.d.ts.map +1 -0
- package/dist/esm/ai-table/components/row-actions.js +48 -0
- package/dist/esm/ai-table/constants/index.d.ts +17 -0
- package/dist/esm/ai-table/constants/index.d.ts.map +1 -0
- package/dist/esm/ai-table/constants/index.js +16 -0
- package/dist/esm/ai-table/i18n/index.d.ts +3 -0
- package/dist/esm/ai-table/i18n/index.d.ts.map +1 -0
- package/dist/esm/ai-table/i18n/index.js +11 -0
- package/dist/esm/ai-table/i18n/translations/en.d.ts +8 -0
- package/dist/esm/ai-table/i18n/translations/en.d.ts.map +1 -0
- package/dist/esm/ai-table/i18n/translations/en.js +7 -0
- package/dist/esm/ai-table/i18n/translations/tr.d.ts +8 -0
- package/dist/esm/ai-table/i18n/translations/tr.d.ts.map +1 -0
- package/dist/esm/ai-table/i18n/translations/tr.js +7 -0
- package/dist/esm/ai-table/index.d.ts +4 -0
- package/dist/esm/ai-table/index.d.ts.map +1 -0
- package/dist/esm/ai-table/index.js +67 -0
- package/dist/esm/ai-table/utils/data-format/__tests__/index.test.d.ts +2 -0
- package/dist/esm/ai-table/utils/data-format/__tests__/index.test.d.ts.map +1 -0
- package/dist/esm/ai-table/utils/data-format/__tests__/index.test.js +144 -0
- package/dist/esm/ai-table/utils/data-format/__tests__/index.test.ts +184 -0
- package/dist/esm/ai-table/utils/data-format/index.d.ts +7 -0
- package/dist/esm/ai-table/utils/data-format/index.d.ts.map +1 -0
- package/dist/esm/ai-table/utils/data-format/index.js +38 -0
- package/dist/esm/ai-table/utils/render-mapper-fields/__tests__/index.test.d.ts +2 -0
- package/dist/esm/ai-table/utils/render-mapper-fields/__tests__/index.test.d.ts.map +1 -0
- package/dist/esm/ai-table/utils/render-mapper-fields/__tests__/index.test.js +289 -0
- package/dist/esm/ai-table/utils/render-mapper-fields/__tests__/index.test.tsx +399 -0
- package/dist/esm/ai-table/utils/render-mapper-fields/index.d.ts +10 -0
- package/dist/esm/ai-table/utils/render-mapper-fields/index.d.ts.map +1 -0
- package/dist/esm/ai-table/utils/render-mapper-fields/index.js +44 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/types/index.d.ts +134 -0
- package/dist/esm/types/index.d.ts.map +1 -0
- package/dist/esm/types/index.js +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
13
|
+
import { fireEvent, render, screen } from '@testing-library/react';
|
|
14
|
+
import * as React from 'react';
|
|
15
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
16
|
+
import { TableFooter } from '../footer';
|
|
17
|
+
vi.mock('@akinon/ui-button', () => ({
|
|
18
|
+
Button: (_a) => {
|
|
19
|
+
var { onClick, disabled, loading, type, className, children } = _a, props = __rest(_a, ["onClick", "disabled", "loading", "type", "className", "children"]);
|
|
20
|
+
return (React.createElement("button", Object.assign({ onClick: onClick, disabled: disabled, "data-loading": loading, "data-type": type, className: className }, props), children));
|
|
21
|
+
}
|
|
22
|
+
}));
|
|
23
|
+
vi.mock('@akinon/ui-layout', () => ({
|
|
24
|
+
Flex: (_a) => {
|
|
25
|
+
var { children, justify, gap } = _a, props = __rest(_a, ["children", "justify", "gap"]);
|
|
26
|
+
return (React.createElement("div", Object.assign({ "data-testid": "flex-footer", "data-justify": justify, "data-gap": gap }, props), children));
|
|
27
|
+
}
|
|
28
|
+
}));
|
|
29
|
+
describe('TableFooter', () => {
|
|
30
|
+
const mockOnSubmitAll = vi.fn();
|
|
31
|
+
const mockOnSubmitSelected = vi.fn();
|
|
32
|
+
const defaultProps = {
|
|
33
|
+
isSubmitting: false,
|
|
34
|
+
selectedCount: 0,
|
|
35
|
+
submitAllLabel: 'Submit All',
|
|
36
|
+
submitSelectedLabel: 'Submit Selected',
|
|
37
|
+
onSubmitAll: mockOnSubmitAll,
|
|
38
|
+
onSubmitSelected: mockOnSubmitSelected
|
|
39
|
+
};
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
vi.clearAllMocks();
|
|
42
|
+
});
|
|
43
|
+
const renderComponent = (props = {}) => {
|
|
44
|
+
return render(React.createElement(TableFooter, Object.assign({}, defaultProps, props)));
|
|
45
|
+
};
|
|
46
|
+
describe('Rendering', () => {
|
|
47
|
+
it('should render Flex container', () => {
|
|
48
|
+
renderComponent();
|
|
49
|
+
expect(screen.getByTestId('flex-footer')).toBeInTheDocument();
|
|
50
|
+
});
|
|
51
|
+
it('should render two buttons', () => {
|
|
52
|
+
renderComponent();
|
|
53
|
+
const buttons = screen.getAllByRole('button');
|
|
54
|
+
expect(buttons).toHaveLength(2);
|
|
55
|
+
});
|
|
56
|
+
it('should have correct Flex props', () => {
|
|
57
|
+
renderComponent();
|
|
58
|
+
const flexContainer = screen.getByTestId('flex-footer');
|
|
59
|
+
expect(flexContainer).toHaveAttribute('data-justify', 'end');
|
|
60
|
+
expect(flexContainer).toHaveAttribute('data-gap', '10');
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
describe('Button Labels', () => {
|
|
64
|
+
it('should render submitAllLabel on first button', () => {
|
|
65
|
+
renderComponent();
|
|
66
|
+
const buttons = screen.getAllByRole('button');
|
|
67
|
+
expect(buttons[0]).toHaveTextContent('Submit All');
|
|
68
|
+
});
|
|
69
|
+
it('should render submitSelectedLabel on second button', () => {
|
|
70
|
+
renderComponent();
|
|
71
|
+
const buttons = screen.getAllByRole('button');
|
|
72
|
+
expect(buttons[1]).toHaveTextContent('Submit Selected');
|
|
73
|
+
});
|
|
74
|
+
it('should display custom submitAllLabel', () => {
|
|
75
|
+
renderComponent({ submitAllLabel: 'Custom All' });
|
|
76
|
+
expect(screen.getByText('Custom All')).toBeInTheDocument();
|
|
77
|
+
});
|
|
78
|
+
it('should display custom submitSelectedLabel', () => {
|
|
79
|
+
renderComponent({ submitSelectedLabel: 'Custom Selected' });
|
|
80
|
+
expect(screen.getByText('Custom Selected')).toBeInTheDocument();
|
|
81
|
+
});
|
|
82
|
+
it('should display selected count when selectedCount > 0', () => {
|
|
83
|
+
renderComponent({ selectedCount: 5 });
|
|
84
|
+
const buttons = screen.getAllByRole('button');
|
|
85
|
+
expect(buttons[1]).toHaveTextContent('Submit Selected (5)');
|
|
86
|
+
});
|
|
87
|
+
it('should not display count when selectedCount is 0', () => {
|
|
88
|
+
renderComponent({ selectedCount: 0 });
|
|
89
|
+
const buttons = screen.getAllByRole('button');
|
|
90
|
+
expect(buttons[1]).toHaveTextContent('Submit Selected');
|
|
91
|
+
expect(buttons[1]).not.toHaveTextContent('(0)');
|
|
92
|
+
});
|
|
93
|
+
it('should update count when selectedCount changes', () => {
|
|
94
|
+
const { rerender } = renderComponent({ selectedCount: 3 });
|
|
95
|
+
let buttons = screen.getAllByRole('button');
|
|
96
|
+
expect(buttons[1]).toHaveTextContent('Submit Selected (3)');
|
|
97
|
+
rerender(React.createElement(TableFooter, Object.assign({}, defaultProps, { selectedCount: 10 })));
|
|
98
|
+
buttons = screen.getAllByRole('button');
|
|
99
|
+
expect(buttons[1]).toHaveTextContent('Submit Selected (10)');
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
describe('Button Styling', () => {
|
|
103
|
+
it('should have uppercase and semibold classes on both buttons', () => {
|
|
104
|
+
renderComponent();
|
|
105
|
+
const buttons = screen.getAllByRole('button');
|
|
106
|
+
expect(buttons[0]).toHaveClass('uppercase', 'font-semibold');
|
|
107
|
+
expect(buttons[1]).toHaveClass('uppercase', 'font-semibold');
|
|
108
|
+
});
|
|
109
|
+
it('should have primary type on second button', () => {
|
|
110
|
+
renderComponent();
|
|
111
|
+
const buttons = screen.getAllByRole('button');
|
|
112
|
+
expect(buttons[0]).not.toHaveAttribute('data-type', 'primary');
|
|
113
|
+
expect(buttons[1]).toHaveAttribute('data-type', 'primary');
|
|
114
|
+
});
|
|
115
|
+
it('should not have type on first button', () => {
|
|
116
|
+
renderComponent();
|
|
117
|
+
const buttons = screen.getAllByRole('button');
|
|
118
|
+
expect(buttons[0]).not.toHaveAttribute('data-type');
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
describe('Submit All Button', () => {
|
|
122
|
+
it('should not be disabled when isSubmitting is false', () => {
|
|
123
|
+
renderComponent({ isSubmitting: false });
|
|
124
|
+
const buttons = screen.getAllByRole('button');
|
|
125
|
+
expect(buttons[0]).not.toBeDisabled();
|
|
126
|
+
});
|
|
127
|
+
it('should be disabled when isSubmitting is true', () => {
|
|
128
|
+
renderComponent({ isSubmitting: true });
|
|
129
|
+
const buttons = screen.getAllByRole('button');
|
|
130
|
+
expect(buttons[0]).toBeDisabled();
|
|
131
|
+
});
|
|
132
|
+
it('should have loading state when isSubmitting is true', () => {
|
|
133
|
+
renderComponent({ isSubmitting: true });
|
|
134
|
+
const buttons = screen.getAllByRole('button');
|
|
135
|
+
expect(buttons[0]).toHaveAttribute('data-loading', 'true');
|
|
136
|
+
});
|
|
137
|
+
it('should not have loading state when isSubmitting is false', () => {
|
|
138
|
+
renderComponent({ isSubmitting: false });
|
|
139
|
+
const buttons = screen.getAllByRole('button');
|
|
140
|
+
expect(buttons[0]).toHaveAttribute('data-loading', 'false');
|
|
141
|
+
});
|
|
142
|
+
it('should call onSubmitAll when clicked', () => {
|
|
143
|
+
renderComponent();
|
|
144
|
+
const buttons = screen.getAllByRole('button');
|
|
145
|
+
fireEvent.click(buttons[0]);
|
|
146
|
+
expect(mockOnSubmitAll).toHaveBeenCalledOnce();
|
|
147
|
+
});
|
|
148
|
+
it('should not call onSubmitAll when disabled', () => {
|
|
149
|
+
renderComponent({ isSubmitting: true });
|
|
150
|
+
const buttons = screen.getAllByRole('button');
|
|
151
|
+
fireEvent.click(buttons[0]);
|
|
152
|
+
expect(mockOnSubmitAll).not.toHaveBeenCalled();
|
|
153
|
+
});
|
|
154
|
+
it('should handle missing onSubmitAll callback', () => {
|
|
155
|
+
renderComponent({ onSubmitAll: undefined });
|
|
156
|
+
const buttons = screen.getAllByRole('button');
|
|
157
|
+
expect(() => {
|
|
158
|
+
fireEvent.click(buttons[0]);
|
|
159
|
+
}).not.toThrow();
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
describe('Submit Selected Button', () => {
|
|
163
|
+
it('should not be disabled when selectedCount > 0 and not submitting', () => {
|
|
164
|
+
renderComponent({ selectedCount: 5, isSubmitting: false });
|
|
165
|
+
const buttons = screen.getAllByRole('button');
|
|
166
|
+
expect(buttons[1]).not.toBeDisabled();
|
|
167
|
+
});
|
|
168
|
+
it('should be disabled when selectedCount is 0', () => {
|
|
169
|
+
renderComponent({ selectedCount: 0, isSubmitting: false });
|
|
170
|
+
const buttons = screen.getAllByRole('button');
|
|
171
|
+
expect(buttons[1]).toBeDisabled();
|
|
172
|
+
});
|
|
173
|
+
it('should be disabled when isSubmitting is true', () => {
|
|
174
|
+
renderComponent({ selectedCount: 5, isSubmitting: true });
|
|
175
|
+
const buttons = screen.getAllByRole('button');
|
|
176
|
+
expect(buttons[1]).toBeDisabled();
|
|
177
|
+
});
|
|
178
|
+
it('should be disabled when both selectedCount is 0 and isSubmitting is true', () => {
|
|
179
|
+
renderComponent({ selectedCount: 0, isSubmitting: true });
|
|
180
|
+
const buttons = screen.getAllByRole('button');
|
|
181
|
+
expect(buttons[1]).toBeDisabled();
|
|
182
|
+
});
|
|
183
|
+
it('should have loading state when isSubmitting is true', () => {
|
|
184
|
+
renderComponent({ isSubmitting: true, selectedCount: 5 });
|
|
185
|
+
const buttons = screen.getAllByRole('button');
|
|
186
|
+
expect(buttons[1]).toHaveAttribute('data-loading', 'true');
|
|
187
|
+
});
|
|
188
|
+
it('should not have loading state when isSubmitting is false', () => {
|
|
189
|
+
renderComponent({ isSubmitting: false });
|
|
190
|
+
const buttons = screen.getAllByRole('button');
|
|
191
|
+
expect(buttons[1]).toHaveAttribute('data-loading', 'false');
|
|
192
|
+
});
|
|
193
|
+
it('should call onSubmitSelected when clicked with selection', () => {
|
|
194
|
+
renderComponent({ selectedCount: 5 });
|
|
195
|
+
const buttons = screen.getAllByRole('button');
|
|
196
|
+
fireEvent.click(buttons[1]);
|
|
197
|
+
expect(mockOnSubmitSelected).toHaveBeenCalledOnce();
|
|
198
|
+
});
|
|
199
|
+
it('should not call onSubmitSelected when no selection', () => {
|
|
200
|
+
renderComponent({ selectedCount: 0 });
|
|
201
|
+
const buttons = screen.getAllByRole('button');
|
|
202
|
+
fireEvent.click(buttons[1]);
|
|
203
|
+
expect(mockOnSubmitSelected).not.toHaveBeenCalled();
|
|
204
|
+
});
|
|
205
|
+
it('should handle missing onSubmitSelected callback', () => {
|
|
206
|
+
renderComponent({ onSubmitSelected: undefined, selectedCount: 5 });
|
|
207
|
+
const buttons = screen.getAllByRole('button');
|
|
208
|
+
expect(() => {
|
|
209
|
+
fireEvent.click(buttons[1]);
|
|
210
|
+
}).not.toThrow();
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
describe('Selected Count', () => {
|
|
214
|
+
it('should display 1 when selectedCount is 1', () => {
|
|
215
|
+
renderComponent({ selectedCount: 1 });
|
|
216
|
+
const buttons = screen.getAllByRole('button');
|
|
217
|
+
expect(buttons[1]).toHaveTextContent('Submit Selected (1)');
|
|
218
|
+
});
|
|
219
|
+
it('should display 10 when selectedCount is 10', () => {
|
|
220
|
+
renderComponent({ selectedCount: 10 });
|
|
221
|
+
const buttons = screen.getAllByRole('button');
|
|
222
|
+
expect(buttons[1]).toHaveTextContent('Submit Selected (10)');
|
|
223
|
+
});
|
|
224
|
+
it('should display 100 when selectedCount is 100', () => {
|
|
225
|
+
renderComponent({ selectedCount: 100 });
|
|
226
|
+
const buttons = screen.getAllByRole('button');
|
|
227
|
+
expect(buttons[1]).toHaveTextContent('Submit Selected (100)');
|
|
228
|
+
});
|
|
229
|
+
it('should display large number correctly', () => {
|
|
230
|
+
renderComponent({ selectedCount: 9999 });
|
|
231
|
+
const buttons = screen.getAllByRole('button');
|
|
232
|
+
expect(buttons[1]).toHaveTextContent('Submit Selected (9999)');
|
|
233
|
+
});
|
|
234
|
+
it('should enable button when selectedCount changes from 0 to 1', () => {
|
|
235
|
+
const { rerender } = renderComponent({ selectedCount: 0 });
|
|
236
|
+
let buttons = screen.getAllByRole('button');
|
|
237
|
+
expect(buttons[1]).toBeDisabled();
|
|
238
|
+
rerender(React.createElement(TableFooter, Object.assign({}, defaultProps, { selectedCount: 1 })));
|
|
239
|
+
buttons = screen.getAllByRole('button');
|
|
240
|
+
expect(buttons[1]).not.toBeDisabled();
|
|
241
|
+
});
|
|
242
|
+
it('should disable button when selectedCount changes from 1 to 0', () => {
|
|
243
|
+
const { rerender } = renderComponent({ selectedCount: 1 });
|
|
244
|
+
let buttons = screen.getAllByRole('button');
|
|
245
|
+
expect(buttons[1]).not.toBeDisabled();
|
|
246
|
+
rerender(React.createElement(TableFooter, Object.assign({}, defaultProps, { selectedCount: 0 })));
|
|
247
|
+
buttons = screen.getAllByRole('button');
|
|
248
|
+
expect(buttons[1]).toBeDisabled();
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
describe('Submitting State', () => {
|
|
252
|
+
it('should have both buttons with loading state when submitting', () => {
|
|
253
|
+
renderComponent({ isSubmitting: true, selectedCount: 5 });
|
|
254
|
+
const buttons = screen.getAllByRole('button');
|
|
255
|
+
expect(buttons[0]).toHaveAttribute('data-loading', 'true');
|
|
256
|
+
expect(buttons[1]).toHaveAttribute('data-loading', 'true');
|
|
257
|
+
});
|
|
258
|
+
it('should have both buttons disabled when submitting', () => {
|
|
259
|
+
renderComponent({ isSubmitting: true, selectedCount: 5 });
|
|
260
|
+
const buttons = screen.getAllByRole('button');
|
|
261
|
+
expect(buttons[0]).toBeDisabled();
|
|
262
|
+
expect(buttons[1]).toBeDisabled();
|
|
263
|
+
});
|
|
264
|
+
it('should toggle submitting state', () => {
|
|
265
|
+
const { rerender } = renderComponent({
|
|
266
|
+
isSubmitting: false,
|
|
267
|
+
selectedCount: 5
|
|
268
|
+
});
|
|
269
|
+
let buttons = screen.getAllByRole('button');
|
|
270
|
+
expect(buttons[0]).not.toBeDisabled();
|
|
271
|
+
expect(buttons[1]).not.toBeDisabled();
|
|
272
|
+
rerender(React.createElement(TableFooter, Object.assign({}, defaultProps, { isSubmitting: true, selectedCount: 5 })));
|
|
273
|
+
buttons = screen.getAllByRole('button');
|
|
274
|
+
expect(buttons[0]).toBeDisabled();
|
|
275
|
+
expect(buttons[1]).toBeDisabled();
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
describe('Callbacks', () => {
|
|
279
|
+
it('should call onSubmitAll only once per click', () => {
|
|
280
|
+
renderComponent();
|
|
281
|
+
const buttons = screen.getAllByRole('button');
|
|
282
|
+
fireEvent.click(buttons[0]);
|
|
283
|
+
fireEvent.click(buttons[0]);
|
|
284
|
+
fireEvent.click(buttons[0]);
|
|
285
|
+
expect(mockOnSubmitAll).toHaveBeenCalledTimes(3);
|
|
286
|
+
});
|
|
287
|
+
it('should call onSubmitSelected only once per click', () => {
|
|
288
|
+
renderComponent({ selectedCount: 5 });
|
|
289
|
+
const buttons = screen.getAllByRole('button');
|
|
290
|
+
fireEvent.click(buttons[1]);
|
|
291
|
+
fireEvent.click(buttons[1]);
|
|
292
|
+
expect(mockOnSubmitSelected).toHaveBeenCalledTimes(2);
|
|
293
|
+
});
|
|
294
|
+
it('should call correct callback for each button', () => {
|
|
295
|
+
renderComponent({ selectedCount: 5 });
|
|
296
|
+
const buttons = screen.getAllByRole('button');
|
|
297
|
+
fireEvent.click(buttons[0]);
|
|
298
|
+
expect(mockOnSubmitAll).toHaveBeenCalledOnce();
|
|
299
|
+
expect(mockOnSubmitSelected).not.toHaveBeenCalled();
|
|
300
|
+
fireEvent.click(buttons[1]);
|
|
301
|
+
expect(mockOnSubmitAll).toHaveBeenCalledOnce();
|
|
302
|
+
expect(mockOnSubmitSelected).toHaveBeenCalledOnce();
|
|
303
|
+
});
|
|
304
|
+
it('should not throw when callbacks are undefined', () => {
|
|
305
|
+
renderComponent({
|
|
306
|
+
selectedCount: 5,
|
|
307
|
+
onSubmitAll: undefined,
|
|
308
|
+
onSubmitSelected: undefined
|
|
309
|
+
});
|
|
310
|
+
const buttons = screen.getAllByRole('button');
|
|
311
|
+
expect(() => {
|
|
312
|
+
fireEvent.click(buttons[0]);
|
|
313
|
+
fireEvent.click(buttons[1]);
|
|
314
|
+
}).not.toThrow();
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
describe('Edge Cases', () => {
|
|
318
|
+
it('should handle empty labels', () => {
|
|
319
|
+
renderComponent({
|
|
320
|
+
submitAllLabel: '',
|
|
321
|
+
submitSelectedLabel: ''
|
|
322
|
+
});
|
|
323
|
+
const buttons = screen.getAllByRole('button');
|
|
324
|
+
expect(buttons[0].textContent).toBe('');
|
|
325
|
+
expect(buttons[1].textContent).toBe('');
|
|
326
|
+
});
|
|
327
|
+
it('should handle very long labels', () => {
|
|
328
|
+
const longLabel = 'a'.repeat(100);
|
|
329
|
+
renderComponent({
|
|
330
|
+
submitAllLabel: longLabel,
|
|
331
|
+
submitSelectedLabel: longLabel
|
|
332
|
+
});
|
|
333
|
+
const buttons = screen.getAllByRole('button');
|
|
334
|
+
expect(buttons[0]).toHaveTextContent(longLabel);
|
|
335
|
+
expect(buttons[1]).toHaveTextContent(longLabel);
|
|
336
|
+
});
|
|
337
|
+
it('should handle negative selectedCount gracefully', () => {
|
|
338
|
+
renderComponent({ selectedCount: -1 });
|
|
339
|
+
const buttons = screen.getAllByRole('button');
|
|
340
|
+
// Component only shows count when > 0, so negative counts are not shown
|
|
341
|
+
expect(buttons[1]).toHaveTextContent('Submit Selected');
|
|
342
|
+
expect(buttons[1]).not.toHaveTextContent('(-1)');
|
|
343
|
+
});
|
|
344
|
+
it('should handle special characters in labels', () => {
|
|
345
|
+
const specialLabel = '&<>"\'';
|
|
346
|
+
renderComponent({
|
|
347
|
+
submitAllLabel: specialLabel,
|
|
348
|
+
submitSelectedLabel: specialLabel
|
|
349
|
+
});
|
|
350
|
+
const buttons = screen.getAllByRole('button');
|
|
351
|
+
expect(buttons[0]).toHaveTextContent(specialLabel);
|
|
352
|
+
expect(buttons[1]).toHaveTextContent(specialLabel);
|
|
353
|
+
});
|
|
354
|
+
it('should handle unicode characters in labels', () => {
|
|
355
|
+
const unicodeLabel = '你好 🚀 مرحبا';
|
|
356
|
+
renderComponent({
|
|
357
|
+
submitAllLabel: unicodeLabel,
|
|
358
|
+
submitSelectedLabel: unicodeLabel
|
|
359
|
+
});
|
|
360
|
+
const buttons = screen.getAllByRole('button');
|
|
361
|
+
expect(buttons[0]).toHaveTextContent(unicodeLabel);
|
|
362
|
+
expect(buttons[1]).toHaveTextContent(unicodeLabel);
|
|
363
|
+
});
|
|
364
|
+
it('should handle rapid prop changes', () => {
|
|
365
|
+
const { rerender } = renderComponent({
|
|
366
|
+
selectedCount: 0,
|
|
367
|
+
isSubmitting: false
|
|
368
|
+
});
|
|
369
|
+
for (let i = 1; i <= 5; i++) {
|
|
370
|
+
rerender(React.createElement(TableFooter, Object.assign({}, defaultProps, { selectedCount: i, isSubmitting: i % 2 === 0 })));
|
|
371
|
+
const buttons = screen.getAllByRole('button');
|
|
372
|
+
const submitSelectedBtn = buttons[1];
|
|
373
|
+
if (i % 2 === 0) {
|
|
374
|
+
expect(submitSelectedBtn).toBeDisabled();
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
expect(submitSelectedBtn).not.toBeDisabled();
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
describe('Integration Tests', () => {
|
|
383
|
+
it('should handle complete workflow with no selection', () => {
|
|
384
|
+
renderComponent({ selectedCount: 0, isSubmitting: false });
|
|
385
|
+
const buttons = screen.getAllByRole('button');
|
|
386
|
+
// Submit all should be clickable
|
|
387
|
+
expect(buttons[0]).not.toBeDisabled();
|
|
388
|
+
fireEvent.click(buttons[0]);
|
|
389
|
+
expect(mockOnSubmitAll).toHaveBeenCalledOnce();
|
|
390
|
+
// Submit selected should be disabled
|
|
391
|
+
expect(buttons[1]).toBeDisabled();
|
|
392
|
+
});
|
|
393
|
+
it('should handle complete workflow with selection', () => {
|
|
394
|
+
renderComponent({ selectedCount: 3, isSubmitting: false });
|
|
395
|
+
const buttons = screen.getAllByRole('button');
|
|
396
|
+
// Both buttons should be clickable
|
|
397
|
+
expect(buttons[0]).not.toBeDisabled();
|
|
398
|
+
expect(buttons[1]).not.toBeDisabled();
|
|
399
|
+
// Selected count should show
|
|
400
|
+
expect(buttons[1]).toHaveTextContent('Submit Selected (3)');
|
|
401
|
+
// Click both
|
|
402
|
+
fireEvent.click(buttons[0]);
|
|
403
|
+
fireEvent.click(buttons[1]);
|
|
404
|
+
expect(mockOnSubmitAll).toHaveBeenCalledOnce();
|
|
405
|
+
expect(mockOnSubmitSelected).toHaveBeenCalledOnce();
|
|
406
|
+
});
|
|
407
|
+
it('should handle workflow with selection then submission', () => {
|
|
408
|
+
const { rerender } = renderComponent({
|
|
409
|
+
selectedCount: 5,
|
|
410
|
+
isSubmitting: false
|
|
411
|
+
});
|
|
412
|
+
const buttons = screen.getAllByRole('button');
|
|
413
|
+
expect(buttons[1]).not.toHaveAttribute('data-loading', 'true');
|
|
414
|
+
// User clicks submit
|
|
415
|
+
fireEvent.click(buttons[0]);
|
|
416
|
+
expect(mockOnSubmitAll).toHaveBeenCalledOnce();
|
|
417
|
+
// State changes to submitting
|
|
418
|
+
rerender(React.createElement(TableFooter, Object.assign({}, defaultProps, { selectedCount: 5, isSubmitting: true })));
|
|
419
|
+
const updatedButtons = screen.getAllByRole('button');
|
|
420
|
+
expect(updatedButtons[0]).toBeDisabled();
|
|
421
|
+
expect(updatedButtons[1]).toBeDisabled();
|
|
422
|
+
expect(updatedButtons[0]).toHaveAttribute('data-loading', 'true');
|
|
423
|
+
expect(updatedButtons[1]).toHaveAttribute('data-loading', 'true');
|
|
424
|
+
});
|
|
425
|
+
it('should handle selection changes during submission', () => {
|
|
426
|
+
const { rerender } = renderComponent({
|
|
427
|
+
selectedCount: 10,
|
|
428
|
+
isSubmitting: true
|
|
429
|
+
});
|
|
430
|
+
let buttons = screen.getAllByRole('button');
|
|
431
|
+
expect(buttons[1]).toHaveTextContent('Submit Selected (10)');
|
|
432
|
+
expect(buttons[1]).toBeDisabled();
|
|
433
|
+
// Selection changes (though unlikely during submission)
|
|
434
|
+
rerender(React.createElement(TableFooter, Object.assign({}, defaultProps, { selectedCount: 20, isSubmitting: true })));
|
|
435
|
+
buttons = screen.getAllByRole('button');
|
|
436
|
+
expect(buttons[1]).toHaveTextContent('Submit Selected (20)');
|
|
437
|
+
expect(buttons[1]).toBeDisabled();
|
|
438
|
+
});
|
|
439
|
+
it('should handle all possible disabled state combinations', () => {
|
|
440
|
+
const combinations = [
|
|
441
|
+
{ selectedCount: 0, isSubmitting: false, expectedDisabled: true }, // no selection
|
|
442
|
+
{ selectedCount: 0, isSubmitting: true, expectedDisabled: true }, // no selection, submitting
|
|
443
|
+
{ selectedCount: 5, isSubmitting: false, expectedDisabled: false }, // has selection
|
|
444
|
+
{ selectedCount: 5, isSubmitting: true, expectedDisabled: true } // has selection, submitting
|
|
445
|
+
];
|
|
446
|
+
combinations.forEach(({ selectedCount, isSubmitting, expectedDisabled }, index) => {
|
|
447
|
+
const { unmount } = renderComponent({ selectedCount, isSubmitting });
|
|
448
|
+
const buttons = screen.getAllByRole('button');
|
|
449
|
+
const submitSelectedBtn = buttons[1];
|
|
450
|
+
if (expectedDisabled) {
|
|
451
|
+
expect(submitSelectedBtn).toBeDisabled();
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
expect(submitSelectedBtn).not.toBeDisabled();
|
|
455
|
+
}
|
|
456
|
+
// Cleanup between iterations
|
|
457
|
+
if (index < combinations.length - 1) {
|
|
458
|
+
unmount();
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
});
|
|
462
|
+
});
|
|
463
|
+
});
|