Merge pull request #1121 from nowcommunity/fix/occurrence-country-continent-filter

Fix continent search in /occurrence country filter
This commit is contained in:
Kari Lintulaakso
2026-04-17 11:57:35 +03:00
committed by GitHub
3 changed files with 46 additions and 2 deletions
@@ -1,4 +1,5 @@
import type { CrossSearch } from '../../../../frontend/src/shared/types'
import { matchesCountryOrContinent } from '../../../../frontend/src/shared/validators/countryContinents'
import { beforeAll, afterAll, describe, it, expect } from '@jest/globals'
import { resetDatabase, send, resetDatabaseTimeout, login, logout } from '../utils'
import { pool } from '../../utils/db'
@@ -91,6 +92,14 @@ describe('Getting cross-search data', () => {
'Spain',
])
const { body: responseBodyEurope, status: responseStatusEurope } = await send<CrossSearch[]>(
`crosssearch/all/200/0/[{"id": "country", "value": "Europe"}]/[]`,
'GET'
)
expect(responseStatusEurope).toEqual(200)
expect(responseBodyEurope.length).toBeGreaterThan(0)
expect(responseBodyEurope.every(row => matchesCountryOrContinent(row.country, 'Europe'))).toBe(true)
const { body: responseBody3, status: responseStatus3 } = await send<CrossSearch[]>(
`crosssearch/all/20/0/[{"id": "lid_now_loc", "value": "invalid"}]/[]`,
'GET'
@@ -1,5 +1,6 @@
import { Prisma } from '../../../prisma/generated/now_test_client'
import { ColumnFilter } from '../../../../frontend/src/shared/types'
import { getCountriesForContinentFilter } from '../../../../frontend/src/shared/validators/countryContinents'
const generateWhereClause = (showAll: boolean, allowedLocalities: Array<number>, columnFilters: ColumnFilter[]) => {
let userCheck: Prisma.Sql
@@ -15,6 +16,17 @@ const generateWhereClause = (showAll: boolean, allowedLocalities: Array<number>,
else {
const conditions: Prisma.Sql[] = []
for (const filter of columnFilters) {
if (filter.id === 'now_loc.country') {
const continentCountries = getCountriesForContinentFilter(filter.value)
if (continentCountries.length > 0) {
const newQuery = Prisma.sql`(${Prisma.raw(filter.id)} LIKE ${'%' + filter.value + '%'} OR ${Prisma.raw(
filter.id
)} IN (${Prisma.join(continentCountries)}))`
conditions.push(newQuery)
continue
}
}
const newQuery = Prisma.sql`${Prisma.raw(filter.id)} LIKE ${'%' + filter.value + '%'}`
conditions.push(newQuery)
}
@@ -284,9 +284,9 @@ const continentAliases: Record<Continent, string[]> = {
Antarctica: ['antarctica'],
Asia: ['asia'],
Europe: ['europe'],
'North America': ['north america', 'northern america', 'central america', 'caribbean'],
'North America': ['north america', 'northern america', 'central america', 'caribbean', 'americas'],
Oceania: ['oceania', 'australia', 'australasia', 'pacific'],
'South America': ['south america', 'southern america', 'latin america'],
'South America': ['south america', 'southern america', 'latin america', 'americas'],
}
const normalize = (value: string | null | undefined) => value?.trim().toLowerCase() ?? ''
@@ -325,3 +325,26 @@ export const matchesCountryOrContinent = (
return continentAliases[continent].some(alias => alias.includes(normalizedFilter))
}
export const getContinentsMatchingFilter = (filterValue: string | null | undefined): Continent[] => {
const normalizedFilter = normalize(filterValue)
if (!normalizedFilter) return []
const continents = Object.keys(continentAliases) as Continent[]
return continents.filter(continent => {
const normalizedContinent = continent.toLowerCase()
if (normalizedContinent.includes(normalizedFilter)) return true
return continentAliases[continent].some(alias => alias.includes(normalizedFilter))
})
}
export const getCountriesForContinentFilter = (filterValue: string | null | undefined): string[] => {
const matchingContinents = new Set(getContinentsMatchingFilter(filterValue))
if (matchingContinents.size === 0) return []
return Object.keys(countryToContinentMap).filter(country => {
const continent = countryToContinentMap[country as keyof typeof countryToContinentMap]
return matchingContinents.has(continent)
})
}