mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
FE-1856: fix shared api report filters (#38775)
* fix filters * handle numbers
This commit is contained in:
1 parent
11b6f77db4
commit
08960d0f48
2 files changed
+122
-8
No files matched your search
@@ -0,0 +1,105 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { generateRegexpWhere } from './Reports.constants'
|
||||
import type { ReportFilterItem } from './Reports.types'
|
||||
|
||||
describe('generateRegexpWhere', () => {
|
||||
it('should return empty string when no filters provided', () => {
|
||||
const result = generateRegexpWhere([])
|
||||
expect(result).toBe('')
|
||||
})
|
||||
|
||||
it('should generate WHERE clause for single filter', () => {
|
||||
const filters: ReportFilterItem[] = [
|
||||
{
|
||||
key: 'request.path',
|
||||
value: '/api/users',
|
||||
compare: 'is',
|
||||
},
|
||||
]
|
||||
const result = generateRegexpWhere(filters, true)
|
||||
expect(result).toBe("WHERE request.path = '/api/users'")
|
||||
})
|
||||
|
||||
it('should generate AND clause for single filter with prepend=false', () => {
|
||||
const filters: ReportFilterItem[] = [
|
||||
{
|
||||
key: 'request.path',
|
||||
value: '/api/users',
|
||||
compare: 'is',
|
||||
},
|
||||
]
|
||||
const result = generateRegexpWhere(filters, false)
|
||||
expect(result).toBe("AND request.path = '/api/users'")
|
||||
})
|
||||
|
||||
it('should handle different comparison operators', () => {
|
||||
const filters: ReportFilterItem[] = [
|
||||
{
|
||||
key: 'request.path',
|
||||
value: '/api/*',
|
||||
compare: 'matches',
|
||||
},
|
||||
{
|
||||
key: 'response.status_code',
|
||||
value: 404,
|
||||
compare: 'is',
|
||||
},
|
||||
]
|
||||
const result = generateRegexpWhere(filters, true)
|
||||
expect(result).toBe(
|
||||
"WHERE REGEXP_CONTAINS(request.path, '/api/*') AND response.status_code = 404"
|
||||
)
|
||||
})
|
||||
|
||||
it('should handle values with quotes', () => {
|
||||
const filters: ReportFilterItem[] = [
|
||||
{
|
||||
key: 'request.path',
|
||||
value: '"/api/users"',
|
||||
compare: 'is',
|
||||
},
|
||||
]
|
||||
|
||||
const result = generateRegexpWhere(filters, true)
|
||||
expect(result).toBe(`WHERE request.path = "/api/users"`)
|
||||
})
|
||||
|
||||
it('should handle values without quotes', () => {
|
||||
const filters: ReportFilterItem[] = [
|
||||
{
|
||||
key: 'request.path',
|
||||
value: '/api/users',
|
||||
compare: 'is',
|
||||
},
|
||||
]
|
||||
|
||||
const result = generateRegexpWhere(filters, true)
|
||||
expect(result).toBe("WHERE request.path = '/api/users'")
|
||||
})
|
||||
|
||||
it('should handle values with quotes and lowercase', () => {
|
||||
const filters: ReportFilterItem[] = [
|
||||
{
|
||||
key: 'request.path',
|
||||
value: '"/Api/Users"',
|
||||
compare: 'is',
|
||||
},
|
||||
]
|
||||
|
||||
const result = generateRegexpWhere(filters, true)
|
||||
expect(result).toBe(`WHERE request.path = "/api/users"`)
|
||||
})
|
||||
|
||||
it('should handle numbers', () => {
|
||||
const filters: ReportFilterItem[] = [
|
||||
{
|
||||
key: 'request.status_code',
|
||||
value: 200,
|
||||
compare: 'is',
|
||||
},
|
||||
]
|
||||
|
||||
const result = generateRegexpWhere(filters, true)
|
||||
expect(result).toBe(`WHERE request.status_code = 200`)
|
||||
})
|
||||
})
|
||||
@@ -86,25 +86,34 @@ export const generateRegexpWhere = (filters: ReportFilterItem[], prepend = true)
|
||||
const normalizedKey = [splitKey[splitKey.length - 2], splitKey[splitKey.length - 1]].join('.')
|
||||
const filterKey = filter.key.includes('.') ? normalizedKey : filter.key
|
||||
|
||||
const hasQuotes =
|
||||
filter.value.toString().includes('"') || filter.value.toString().includes("'")
|
||||
|
||||
const valueIsNumber = !isNaN(Number(filter.value))
|
||||
const valueWithQuotes = !valueIsNumber && hasQuotes ? filter.value : `'${filter.value}'`
|
||||
const lowercaseValue = !valueIsNumber && String(valueWithQuotes).toLowerCase()
|
||||
|
||||
const finalValue = valueIsNumber ? filter.value : lowercaseValue
|
||||
|
||||
// Handle different comparison operators
|
||||
switch (filter.compare) {
|
||||
case 'matches':
|
||||
return `REGEXP_CONTAINS(${filterKey}, '${filter.value}')`
|
||||
return `REGEXP_CONTAINS(${filterKey}, ${finalValue})`
|
||||
case 'is':
|
||||
return `${filterKey} = ${filter.value}`
|
||||
return `${filterKey} = ${finalValue}`
|
||||
case '!=':
|
||||
return `${filterKey} != ${filter.value}`
|
||||
return `${filterKey} != ${finalValue}`
|
||||
case '>=':
|
||||
return `${filterKey} >= ${filter.value}`
|
||||
return `${filterKey} >= ${finalValue}`
|
||||
case '<=':
|
||||
return `${filterKey} <= ${filter.value}`
|
||||
return `${filterKey} <= ${finalValue}`
|
||||
case '>':
|
||||
return `${filterKey} > ${filter.value}`
|
||||
return `${filterKey} > ${finalValue}`
|
||||
case '<':
|
||||
return `${filterKey} < ${filter.value}`
|
||||
return `${filterKey} < ${finalValue}`
|
||||
default:
|
||||
// Fallback to exact match for unknown operators
|
||||
return `${filterKey} = ${filter.value}`
|
||||
return `${filterKey} = ${finalValue}`
|
||||
}
|
||||
})
|
||||
.filter(Boolean) // Remove any null/undefined conditions
|
||||
|
||||
Reference in new issue
Block a user