@conorheffron/ironoc-frontend 9.1.6 → 9.1.7
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/package.json
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
|
3
3
|
import RepoIssues from '../RepoIssues';
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
// Track useMaterialReactTable call opts for assertions (must start with 'mock' for Jest hoisting)
|
|
6
|
+
const mockUseMRTOpts = [];
|
|
5
7
|
|
|
6
8
|
// Mock react-router
|
|
7
9
|
jest.mock('react-router', () => ({
|
|
@@ -27,16 +29,31 @@ jest.mock('react-bootstrap', () => ({
|
|
|
27
29
|
jest.mock('../../AppNavbar', () => () => <div data-testid="navbar">Navbar</div>);
|
|
28
30
|
jest.mock('../../LoadingSpinner', () => () => <div data-testid="spinner">Loading...</div>);
|
|
29
31
|
|
|
30
|
-
// Mock MaterialReactTable and useMaterialReactTable
|
|
32
|
+
// Mock MaterialReactTable and useMaterialReactTable.
|
|
33
|
+
// useMaterialReactTable is a plain function (not jest.fn) so React 19 concurrent mode
|
|
34
|
+
// commits re-renders correctly. Calls are tracked via mockUseMRTOpts for assertions.
|
|
35
|
+
// columnFilters from initialState are applied to table.data so MaterialReactTable
|
|
36
|
+
// only receives the filtered rows, allowing DOM-level assertions on visibility.
|
|
31
37
|
jest.mock('material-react-table', () => ({
|
|
32
38
|
MaterialReactTable: ({ table }) => (
|
|
33
39
|
<div data-testid="mrt-table">
|
|
34
|
-
{table
|
|
40
|
+
{(table?.data ?? []).map((issue, idx) => (
|
|
35
41
|
<div key={idx} data-testid="mrt-row">{issue.title}</div>
|
|
36
42
|
))}
|
|
37
43
|
</div>
|
|
38
44
|
),
|
|
39
|
-
useMaterialReactTable:
|
|
45
|
+
useMaterialReactTable: (opts) => {
|
|
46
|
+
mockUseMRTOpts.push(opts);
|
|
47
|
+
const filters = opts?.initialState?.columnFilters ?? [];
|
|
48
|
+
let data = opts?.data ?? [];
|
|
49
|
+
filters.forEach((filter) => {
|
|
50
|
+
data = data.filter((row) => {
|
|
51
|
+
const val = row[filter.id];
|
|
52
|
+
return Array.isArray(filter.value) ? filter.value.includes(val) : val === filter.value;
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
return { ...opts, data };
|
|
56
|
+
},
|
|
40
57
|
}));
|
|
41
58
|
|
|
42
59
|
// Mock @mui/material theme functions
|
|
@@ -58,6 +75,7 @@ describe('RepoIssues', () => {
|
|
|
58
75
|
const mockIssuesResponse = [];
|
|
59
76
|
|
|
60
77
|
beforeEach(() => {
|
|
78
|
+
mockUseMRTOpts.length = 0;
|
|
61
79
|
jest.clearAllMocks();
|
|
62
80
|
useNavigate.mockReturnValue(mockNavigate);
|
|
63
81
|
global.fetch = jest.fn(() =>
|
|
@@ -98,19 +116,21 @@ describe('RepoIssues', () => {
|
|
|
98
116
|
expect(screen.queryByTestId('spinner')).not.toBeInTheDocument()
|
|
99
117
|
);
|
|
100
118
|
expect(screen.getByTestId('mrt-table')).toBeInTheDocument();
|
|
119
|
+
expect(screen.getByText('Test Issue')).toBeInTheDocument();
|
|
101
120
|
});
|
|
102
121
|
|
|
103
|
-
it('
|
|
122
|
+
it('defaults to open issues while hiding state and description columns', async () => {
|
|
104
123
|
useParams.mockReturnValue({ id: 'user', repo: 'repo' });
|
|
105
124
|
render(<RepoIssues />);
|
|
106
125
|
await waitFor(() =>
|
|
107
126
|
expect(screen.queryByTestId('spinner')).not.toBeInTheDocument()
|
|
108
127
|
);
|
|
109
128
|
|
|
110
|
-
expect(
|
|
129
|
+
expect(mockUseMRTOpts).toContainEqual(
|
|
111
130
|
expect.objectContaining({
|
|
112
131
|
initialState: expect.objectContaining({
|
|
113
132
|
showColumnFilters: true,
|
|
133
|
+
columnFilters: [{ id: 'state', value: ['open'] }],
|
|
114
134
|
columnVisibility: {
|
|
115
135
|
state: false,
|
|
116
136
|
body: false,
|
|
@@ -120,6 +140,24 @@ describe('RepoIssues', () => {
|
|
|
120
140
|
);
|
|
121
141
|
});
|
|
122
142
|
|
|
143
|
+
it('renders open issues and excludes closed issues by default', async () => {
|
|
144
|
+
useParams.mockReturnValue({ id: 'user', repo: 'repo' });
|
|
145
|
+
global.fetch = jest.fn(() =>
|
|
146
|
+
Promise.resolve({
|
|
147
|
+
json: () => Promise.resolve([
|
|
148
|
+
{ number: 1, state: 'open', labels: [], title: 'Open Issue', body: '' },
|
|
149
|
+
{ number: 2, state: 'closed', labels: [], title: 'Closed Issue', body: '' },
|
|
150
|
+
]),
|
|
151
|
+
})
|
|
152
|
+
);
|
|
153
|
+
window.fetch = global.fetch;
|
|
154
|
+
render(<RepoIssues />);
|
|
155
|
+
await waitFor(() =>
|
|
156
|
+
expect(screen.getByText('Open Issue')).toBeInTheDocument()
|
|
157
|
+
);
|
|
158
|
+
expect(screen.queryByText('Closed Issue')).not.toBeInTheDocument();
|
|
159
|
+
});
|
|
160
|
+
|
|
123
161
|
it('navigates on form submit', async () => {
|
|
124
162
|
useParams.mockReturnValue({ id: 'user', repo: 'repo' });
|
|
125
163
|
global.fetch = jest.fn(() => Promise.resolve({ json: () => Promise.resolve([]) }));
|