Skip to content

Commit 4c7b480

Browse files
committed
Added tests for file input handlers.
1 parent f19938e commit 4c7b480

File tree

5 files changed

+41
-10
lines changed

5 files changed

+41
-10
lines changed

packages/react-form-renderer/src/files/use-field-api.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,6 @@ const useFieldApi = ({ name, initializeOnMount, component, render, validate, ...
7676
};
7777

7878
const fieldProps = useField(name, enhancedProps);
79-
if (fieldProps.input.type === 'file' && typeof fieldProps.input.value === 'object') {
80-
fieldProps.input = { ...fieldProps.input, value: fieldProps.input.value.inputValue };
81-
}
8279

8380
/** Reinitilize type */
8481
useEffect(() => {
@@ -180,6 +177,8 @@ const useFieldApi = ({ name, initializeOnMount, component, render, validate, ...
180177
...(arrayValidator ? { arrayValidator } : {}),
181178
input: {
182179
...fieldProps.input,
180+
value:
181+
fieldProps.input.type === 'file' && typeof fieldProps.input.value === 'object' ? fieldProps.input.value.inputValue : fieldProps.input.value,
183182
onChange: (...args) => {
184183
enhancedOnChange(
185184
{

packages/react-form-renderer/src/tests/form-renderer/enhanced-on-change.test.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,15 @@ describe('#enhancedOnChange', () => {
9090
expect(enhancedOnChange({ onChange: (value) => value, initial, clearedValue }, value)).toEqual(value);
9191
});
9292
});
93+
94+
describe('#input type file', () => {
95+
it('should return an object with inputValue and inputFiles keys', () => {
96+
const value = { target: { value: 'fakepath/file.foo', files: [], type: 'file' } };
97+
const expectedValue = {
98+
inputValue: 'fakepath/file.foo',
99+
inputFiles: []
100+
};
101+
expect(enhancedOnChange({ onChange: (value) => value }, value)).toEqual(expectedValue);
102+
});
103+
});
93104
});

packages/react-form-renderer/src/tests/form-renderer/use-field-api.test.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import RendererContext from '../../files/renderer-context';
99

1010
describe('useFieldApi', () => {
1111
const Catcher = ({ children }) => children;
12+
const registerInputFileSpy = jest.fn();
1213

1314
const TestField = (props) => {
1415
const rest = useFieldApi(props);
@@ -29,7 +30,9 @@ describe('useFieldApi', () => {
2930
<form onSubmit={handleSubmit}>
3031
<RendererContext.Provider
3132
value={{
32-
formOptions: {},
33+
formOptions: {
34+
registerInputFile: registerInputFileSpy
35+
},
3336
validatorMapper: { required: () => (value) => (!value ? 'required' : undefined) }
3437
}}
3538
>
@@ -52,6 +55,7 @@ describe('useFieldApi', () => {
5255
component: 'text-field',
5356
onSubmit: (values) => onSubmit(values)
5457
};
58+
registerInputFileSpy.mockClear();
5559
});
5660

5761
it('reloads type when component changes', () => {
@@ -158,4 +162,21 @@ describe('useFieldApi', () => {
158162

159163
expect(wrapper.find(Catcher).props().meta.initial).toEqual('pepa');
160164
});
165+
166+
it('should assing correct value to type file input', () => {
167+
const wrapper = mount(
168+
<WrapperComponent
169+
{...initialProps}
170+
name="file-input"
171+
type="file"
172+
initialValue={{
173+
inputValue: '',
174+
inputFiles: []
175+
}}
176+
/>
177+
);
178+
179+
expect(wrapper.find('input').prop('value')).toEqual('');
180+
expect(registerInputFileSpy).toHaveBeenCalledWith('file-input');
181+
});
161182
});

packages/react-renderer-demo/src/app/examples/components/file-upload/upload-handler.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ const toBase64 = (file) =>
1111

1212
const submitFunction = async (values, formApi) => {
1313
const myFile = get(values, formApi.fileInputs[0]); // there can be multiple inputs of this type
14-
const fileFakePath = myFile.inputValue; // the fake path shown as the input value
1514
const fileList = myFile.inputFiles; // list of file renferences that should be uploaded to somewhere
1615
const base64Encoded = await toBase64(fileList[0]); // files list is always an array
1716
const formData = new FormData();

packages/react-renderer-demo/src/app/pages/renderer/file-input.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,26 @@ import CodeExample from '../../src/components/code-example';
99

1010
# File input
1111

12-
Files cannot be easilly uploaded in JSON payload. In order to upload files usigng the input type *file* you can follow these steps.
12+
Files cannot be easily uploaded in JSON payload. In order to upload files using the input type *file* you can follow these steps.
1313

1414
## File onChange payload
1515

16-
In order to successfully store the file reference, you have either use an input of type file or use an object with the following shape in your on change function ([visit MDN docs for more info on file upload](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file)).
16+
In order to successfully store the file reference, you have either use an input of "file" type or use an object with the following shape in your on change function ([visit MDN docs for more info on file upload](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file)).
1717
```jsx
1818
{
1919
target: {
2020
value: string, // usually it is the path to the file
21-
files: FileList // an array of file references
21+
files: FileList // an array of file references,
22+
type: 'file' // type which allows the renderer to distinguish file payload
2223
}
2324
}
2425
```
2526

2627
## Getting file from state.
2728

28-
When submitting, you will have to construct the binary via FormData or encode the file to Base64, depending on your use case. Be aware that FormData cannot be sent in the JSON payload. Binaries are destroyed when serializing JSON. There will be a list of field names with the type file avaiable in the submit function arguments.
29+
When submitting, you will have to construct the binary via FormData or encode the file to Base64, depending on your use case. Be aware that FormData cannot be sent in the JSON payload. Binaries are destroyed when serializing JSON. There will be a list of field names with the type file available in the submit function arguments.
2930

30-
The `formApi.fileInputs` is an array of field names with `type: file`. Be aware that if your filed name is in nested, you have to use the lodash like method of getting the value from state.
31+
The `formApi.fileInputs` is an array of field names with `type: file`. Be aware that if your field name is in nested, you have to use the lodash like method of getting the value from state.
3132

3233
<CodeExample source="components/file-upload/upload-handler" />
3334

0 commit comments

Comments
 (0)