Skip filtered lookup for empty occurrence exports

This commit is contained in:
karilint
2026-06-15 15:25:24 +03:00
parent bf464fe579
commit d57a8b3a6b
2 changed files with 25 additions and 0 deletions
@@ -82,6 +82,24 @@ describe('DwC-A occurrence export (admin-only)', () => {
expect(occurrenceCsv).not.toContain('NOW:OCC:24750:') expect(occurrenceCsv).not.toContain('NOW:OCC:24750:')
}) })
it('uses the unfiltered export path for empty POST filters', async () => {
const loginResult = await send<{ token: string }>('user/login', 'POST', { username: 'testSu', password: 'test' })
expect(loginResult.status).toEqual(200)
const result = await request(app)
.post('/occurrence/export/dwc-archive')
.set('authorization', `bearer ${loginResult.body.token}`)
.send({ columnFilters: [], sorting: [] })
.buffer(true)
.parse(parseBinary)
expect(result.status).toEqual(200)
const zip = await JSZip.loadAsync(result.body as unknown as Buffer)
const occurrenceCsv = await zip.file('occurrence.csv')!.async('string')
expect(occurrenceCsv).toContain('NOW:OCC:21050:')
expect(occurrenceCsv).toContain('NOW:OCC:24750:')
})
it('returns an empty filtered DwC-DP ZIP archive for POST requests', async () => { it('returns an empty filtered DwC-DP ZIP archive for POST requests', async () => {
const loginResult = await send<{ token: string }>('user/login', 'POST', { username: 'testSu', password: 'test' }) const loginResult = await send<{ token: string }>('user/login', 'POST', { username: 'testSu', password: 'test' })
expect(loginResult.status).toEqual(200) expect(loginResult.status).toEqual(200)
+7
View File
@@ -32,6 +32,12 @@ const defaultCrossSearchExportFilters = {
sorting: [], sorting: [],
} satisfies CrossSearchRequestParameters } satisfies CrossSearchRequestParameters
const hasEmptyExportFilters = (parameters: Partial<CrossSearchRequestParameters>): boolean => {
const columnFilters = parameters.columnFilters ?? defaultCrossSearchExportFilters.columnFilters
const sorting = parameters.sorting ?? defaultCrossSearchExportFilters.sorting
return Array.isArray(columnFilters) && columnFilters.length === 0 && Array.isArray(sorting) && sorting.length === 0
}
class ExportFilterValidationError extends Error { class ExportFilterValidationError extends Error {
validationErrors: ValidationObject[] validationErrors: ValidationObject[]
@@ -44,6 +50,7 @@ class ExportFilterValidationError extends Error {
const resolveOccurrenceKeysForExport = async (req: Request): Promise<DwcOccurrenceKey[] | undefined> => { const resolveOccurrenceKeysForExport = async (req: Request): Promise<DwcOccurrenceKey[] | undefined> => {
if (req.method === 'GET') return undefined if (req.method === 'GET') return undefined
const body = req.body as Partial<CrossSearchRequestParameters> | undefined const body = req.body as Partial<CrossSearchRequestParameters> | undefined
if (!body || hasEmptyExportFilters(body)) return undefined
const result = await getFilteredCrossSearchOccurrenceKeys(req.user, { const result = await getFilteredCrossSearchOccurrenceKeys(req.user, {
columnFilters: body?.columnFilters ?? defaultCrossSearchExportFilters.columnFilters, columnFilters: body?.columnFilters ?? defaultCrossSearchExportFilters.columnFilters,
sorting: body?.sorting ?? defaultCrossSearchExportFilters.sorting, sorting: body?.sorting ?? defaultCrossSearchExportFilters.sorting,