Skip to content

Commit 7333e37

Browse files
committed
Refactor TagField from class to functional component
1 parent dd140a7 commit 7333e37

1 file changed

Lines changed: 223 additions & 7 deletions

File tree

client/src/components/tests/TagField-test.js

Lines changed: 223 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,58 @@
11
/* eslint-disable import/no-extraneous-dependencies */
22
/* global jest, test, describe, beforeEach, it, expect, setTimeout, document */
33

4-
import React from 'react';
4+
import React, { forwardRef, useImperativeHandle } from 'react';
55
import { render } from '@testing-library/react';
66
import { Component as TagField } from '../TagField';
77

8+
const MockSelect = forwardRef(({ className, ...props }, ref) => {
9+
useImperativeHandle(ref, () => ({
10+
inputRef: document.createElement('input'),
11+
}));
12+
return (
13+
<div
14+
className={`test-dynamic test-select ${className || ''}`}
15+
data-testid="select-component"
16+
/>
17+
);
18+
});
19+
20+
const MockCreatableSelect = forwardRef(({ className, ...props }, ref) => {
21+
useImperativeHandle(ref, () => ({
22+
inputRef: document.createElement('input'),
23+
}));
24+
return (
25+
<div
26+
className={`test-dynamic test-creatable-select ${className || ''}`}
27+
data-testid="creatable-component"
28+
/>
29+
);
30+
});
31+
32+
const MockAsyncSelect = forwardRef(({ className, ...props }, ref) => {
33+
useImperativeHandle(ref, () => ({
34+
inputRef: document.createElement('input'),
35+
}));
36+
return (
37+
<div
38+
className={`test-dynamic test-async-select ${className || ''}`}
39+
data-testid="async-component"
40+
/>
41+
);
42+
});
43+
44+
const MockAsyncCreatableSelect = forwardRef(({ className, ...props }, ref) => {
45+
useImperativeHandle(ref, () => ({
46+
inputRef: document.createElement('input'),
47+
}));
48+
return (
49+
<div
50+
className={`test-dynamic test-async-creatable-select ${className || ''}`}
51+
data-testid="async-creatable-component"
52+
/>
53+
);
54+
});
55+
856
function makeProps(obj = {}) {
957
return {
1058
name: 'Test',
@@ -13,10 +61,10 @@ function makeProps(obj = {}) {
1361
lazyLoad: false,
1462
creatable: false,
1563
multi: true,
16-
SelectComponent: () => <div className="test-dynamic test-select" />,
17-
CreatableSelectComponent: () => <div className="test-dynamic test-creatable-select" />,
18-
AsyncSelectComponent: () => <div className="test-dynamic test-async-select" />,
19-
AsyncCreatableSelectComponent: () => <div className="test-dynamic test-async-creatable-select" />,
64+
SelectComponent: MockSelect,
65+
CreatableSelectComponent: MockCreatableSelect,
66+
AsyncSelectComponent: MockAsyncSelect,
67+
AsyncCreatableSelectComponent: MockAsyncCreatableSelect,
2068
...obj,
2169
};
2270
}
@@ -40,7 +88,7 @@ test('TagField should render a CreatableSelect with creatable option', () => {
4088
expect(container.querySelector('.test-creatable-select')).not.toBeNull();
4189
});
4290

43-
test('Tagfiled should render an AsyncSelect with lazy load option', () => {
91+
test('Tagfield should render an AsyncSelect with lazy load option', () => {
4492
const { container } = render(
4593
<TagField {...makeProps({
4694
lazyLoad: true
@@ -51,7 +99,7 @@ test('Tagfiled should render an AsyncSelect with lazy load option', () => {
5199
expect(container.querySelector('.test-async-select')).not.toBeNull();
52100
});
53101

54-
test('Tagfiled should render a AsyncCreatableSelect with lazy load and creatable options', () => {
102+
test('Tagfield should render a AsyncCreatableSelect with lazy load and creatable options', () => {
55103
const { container } = render(
56104
<TagField {...makeProps({
57105
lazyLoad: true,
@@ -62,3 +110,171 @@ test('Tagfiled should render a AsyncCreatableSelect with lazy load and creatable
62110
expect(container.querySelectorAll('.test-dynamic')).toHaveLength(1);
63111
expect(container.querySelector('.test-async-creatable-select')).not.toBeNull();
64112
});
113+
114+
test('TagField should support isMulti prop for multi-select functionality', () => {
115+
const { container } = render(
116+
<TagField {...makeProps({
117+
multi: true
118+
})}
119+
/>
120+
);
121+
expect(container.querySelectorAll('.test-dynamic')).toHaveLength(1);
122+
});
123+
124+
test('TagField should support single select mode with isMulti false', () => {
125+
const { container } = render(
126+
<TagField {...makeProps({
127+
multi: false
128+
})}
129+
/>
130+
);
131+
expect(container.querySelectorAll('.test-dynamic')).toHaveLength(1);
132+
});
133+
134+
test('TagField should pass disabled prop to select component', () => {
135+
const { container } = render(
136+
<TagField {...makeProps({
137+
disabled: true
138+
})}
139+
/>
140+
);
141+
const selectComponent = container.querySelector('.test-dynamic');
142+
expect(selectComponent).not.toBeNull();
143+
});
144+
145+
test('TagField should handle value prop and pass it to select component', () => {
146+
const testValue = [{ value: 'test1', label: 'Test 1' }];
147+
const { container } = render(
148+
<TagField {...makeProps({
149+
value: testValue
150+
})}
151+
/>
152+
);
153+
expect(container.querySelectorAll('.test-dynamic')).toHaveLength(1);
154+
});
155+
156+
test('TagField should pass custom labelKey and valueKey to select component', () => {
157+
const { container } = render(
158+
<TagField {...makeProps({
159+
labelKey: 'customLabel',
160+
valueKey: 'customValue'
161+
})}
162+
/>
163+
);
164+
expect(container.querySelectorAll('.test-dynamic')).toHaveLength(1);
165+
});
166+
167+
test('TagField should apply no-change-track class when hasChanges is false', () => {
168+
const { container } = render(
169+
<TagField {...makeProps()}
170+
/>
171+
);
172+
const selectComponent = container.querySelector('.test-dynamic');
173+
expect(selectComponent.className).toContain('no-change-track');
174+
});
175+
176+
test('TagField should handle options prop for static select', () => {
177+
const options = [
178+
{ label: 'Option 1', value: 'opt1' },
179+
{ label: 'Option 2', value: 'opt2' }
180+
];
181+
const { container } = render(
182+
<TagField {...makeProps({
183+
options,
184+
lazyLoad: false
185+
})}
186+
/>
187+
);
188+
expect(container.querySelectorAll('.test-dynamic')).toHaveLength(1);
189+
});
190+
191+
test('TagField should handle empty initial state', () => {
192+
const { container } = render(
193+
<TagField {...makeProps({
194+
value: []
195+
})}
196+
/>
197+
);
198+
expect(container.querySelectorAll('.test-dynamic')).toHaveLength(1);
199+
});
200+
201+
test('TagField should handle undefined value', () => {
202+
const { container } = render(
203+
<TagField {...makeProps({
204+
value: undefined
205+
})}
206+
/>
207+
);
208+
expect(container.querySelectorAll('.test-dynamic')).toHaveLength(1);
209+
});
210+
211+
test('TagField should handle null value', () => {
212+
const { container } = render(
213+
<TagField {...makeProps({
214+
value: null
215+
})}
216+
/>
217+
);
218+
expect(container.querySelectorAll('.test-dynamic')).toHaveLength(1);
219+
});
220+
221+
test('TagField should render with custom passThroughAttributes', () => {
222+
const { container } = render(
223+
<TagField {...makeProps({
224+
className: 'custom-class',
225+
id: 'custom-id'
226+
})}
227+
/>
228+
);
229+
expect(container.querySelectorAll('.test-dynamic')).toHaveLength(1);
230+
});
231+
232+
test('TagField should support controlled component with onChange callback', () => {
233+
const onChange = jest.fn();
234+
const { container } = render(
235+
<TagField {...makeProps({
236+
onChange
237+
})}
238+
/>
239+
);
240+
expect(container.querySelectorAll('.test-dynamic')).toHaveLength(1);
241+
});
242+
243+
test('TagField should support uncontrolled component without onChange callback', () => {
244+
const { container } = render(
245+
<TagField {...makeProps({
246+
onChange: undefined
247+
})}
248+
/>
249+
);
250+
expect(container.querySelectorAll('.test-dynamic')).toHaveLength(1);
251+
});
252+
253+
test('TagField should handle single value object for non-multi select', () => {
254+
const { container } = render(
255+
<TagField {...makeProps({
256+
multi: false,
257+
value: { value: 'single', label: 'Single Value' }
258+
})}
259+
/>
260+
);
261+
expect(container.querySelectorAll('.test-dynamic')).toHaveLength(1);
262+
});
263+
264+
test('TagField should pass onBlur handler to select component', () => {
265+
const { container } = render(
266+
<TagField {...makeProps()}
267+
/>
268+
);
269+
expect(container.querySelectorAll('.test-dynamic')).toHaveLength(1);
270+
});
271+
272+
test('TagField should respect required name prop', () => {
273+
const { container } = render(
274+
<TagField {...makeProps({
275+
name: 'MyTagField'
276+
})}
277+
/>
278+
);
279+
expect(container.querySelectorAll('.test-dynamic')).toHaveLength(1);
280+
});

0 commit comments

Comments
 (0)