Skip to content

Commit

Permalink
fix(forms): add sessionStorageId support to Field.Upload with empty…
Browse files Browse the repository at this point in the history
… file list rendering (#4339)

When using `sessionStorageId` on `Form.Handler` alongside `Field.Upload`
with a specified path, file data is stored. However, during
serialization, Blob information is not preserved in session storage. As
a result, reading this data causes `Field.Upload` to throw an exception.

This PR ensures invalid files are not rendered, preventing such errors.

In the future, we could explore storing Blobs in IndexedDB, but that
would require a more extensive effort.
  • Loading branch information
tujoworker authored Nov 26, 2024
1 parent a5623f5 commit d02a0af
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,11 @@ function UploadComponent(props: Props) {
const { files: fileContext, setFiles } = useUpload(id)

useEffect(() => {
setFiles(value)
// Files stored in session storage will not have a property (due to serialization).
const hasInvalidFiles = value?.some(({ file }) => !file?.name)
if (!hasInvalidFiles) {
setFiles(value)
}
}, [setFiles, value])

const handleChangeAsync = useCallback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1253,4 +1253,57 @@ describe('Field.Upload', () => {
)
})
})

it('should not set files from session storage if they are invalid', async () => {
const file = createMockFile('fileName.png', 100, 'image/png')

const { unmount } = render(
<Form.Handler sessionStorageId="session-storage-id">
<Field.Upload path="/myFiles" />
</Form.Handler>
)

const element = getRootElement()

await waitFor(() =>
fireEvent.drop(element, {
dataTransfer: {
files: [file],
},
})
)

expect(
document.querySelectorAll('.dnb-upload__file-cell').length
).toBe(1)

let dataContext = null

// Don't rerender, but render again to make sure the files are not set
unmount()
render(
<Form.Handler sessionStorageId="session-storage-id">
<Field.Upload path="/myFiles" />
<DataContext.Consumer>
{(context) => {
dataContext = context
return null
}}
</DataContext.Consumer>
</Form.Handler>
)

expect(dataContext.internalDataRef.current.myFiles).toEqual([
{
exists: false,
file: {},
id: expect.any(String),
},
])
const [title] = Array.from(document.querySelectorAll('p'))
expect(title).toHaveTextContent(nbShared.Upload.title)
expect(
document.querySelectorAll('.dnb-upload__file-cell').length
).toBe(0)
})
})

0 comments on commit d02a0af

Please sign in to comment.