Assert length on search tests, fixes bug in SQS around on empty return none.

This commit is contained in:
Sam Rose 2024-04-11 09:53:54 +01:00
parent e6c3fd2951
commit 229bbc0d10
No known key found for this signature in database
2 changed files with 56 additions and 29 deletions

View File

@ -6,6 +6,7 @@ import {
Datasource,
EmptyFilterOption,
FieldType,
Row,
SearchFilters,
Table,
} from "@budibase/types"
@ -47,7 +48,7 @@ describe.each([
})
describe("strings", () => {
beforeEach(async () => {
beforeAll(async () => {
table = await config.api.table.save(
tableForDatasource(datasource, {
schema: {
@ -61,6 +62,13 @@ describe.each([
})
const rows = [{ name: "foo" }, { name: "bar" }]
let savedRows: Row[]
beforeAll(async () => {
savedRows = await Promise.all(
rows.map(r => config.api.row.save(table._id!, r))
)
})
interface StringSearchTest {
query: SearchFilters
@ -68,6 +76,8 @@ describe.each([
}
const stringSearchTests: StringSearchTest[] = [
// These three test cases are generic and don't really need
// to be repeated for all data types, so we just do them here.
{ query: {}, expected: rows },
{
query: { onEmptyFilter: EmptyFilterOption.RETURN_ALL },
@ -77,6 +87,7 @@ describe.each([
query: { onEmptyFilter: EmptyFilterOption.RETURN_NONE },
expected: [],
},
// The rest of these tests are specific to strings.
{ query: { string: { name: "foo" } }, expected: [rows[0]] },
{ query: { string: { name: "none" } }, expected: [] },
{ query: { fuzzy: { name: "oo" } }, expected: [rows[0]] },
@ -88,13 +99,11 @@ describe.each([
it.each(stringSearchTests)(
`should be able to run query: $query`,
async ({ query, expected }) => {
const savedRows = await Promise.all(
rows.map(r => config.api.row.save(table._id!, r))
)
const { rows: foundRows } = await config.api.row.search(table._id!, {
tableId: table._id!,
query,
})
expect(foundRows).toHaveLength(expected.length)
expect(foundRows).toEqual(
expect.arrayContaining(
expected.map(r =>
@ -107,7 +116,7 @@ describe.each([
})
describe("number", () => {
beforeEach(async () => {
beforeAll(async () => {
table = await config.api.table.save(
tableForDatasource(datasource, {
schema: {
@ -121,6 +130,13 @@ describe.each([
})
const rows = [{ age: 1 }, { age: 10 }]
let savedRows: Row[]
beforeAll(async () => {
savedRows = await Promise.all(
rows.map(r => config.api.row.save(table._id!, r))
)
})
interface NumberSearchTest {
query: SearchFilters
@ -128,15 +144,6 @@ describe.each([
}
const numberSearchTests: NumberSearchTest[] = [
{ query: {}, expected: rows },
{
query: { onEmptyFilter: EmptyFilterOption.RETURN_ALL },
expected: rows,
},
{
query: { onEmptyFilter: EmptyFilterOption.RETURN_NONE },
expected: [],
},
{ query: { equal: { age: 1 } }, expected: [rows[0]] },
{ query: { equal: { age: 2 } }, expected: [] },
{ query: { notEqual: { age: 1 } }, expected: [rows[1]] },
@ -150,13 +157,11 @@ describe.each([
it.each(numberSearchTests)(
`should be able to run query: $query`,
async ({ query, expected }) => {
const savedRows = await Promise.all(
rows.map(r => config.api.row.save(table._id!, r))
)
const { rows: foundRows } = await config.api.row.search(table._id!, {
tableId: table._id!,
query,
})
expect(foundRows).toHaveLength(expected.length)
expect(foundRows).toEqual(
expect.arrayContaining(
expected.map(r =>
@ -186,6 +191,13 @@ describe.each([
{ dob: new Date("2020-01-01").toISOString() },
{ dob: new Date("2020-01-10").toISOString() },
]
let savedRows: Row[]
beforeEach(async () => {
savedRows = await Promise.all(
rows.map(r => config.api.row.save(table._id!, r))
)
})
interface DateSearchTest {
query: SearchFilters
@ -193,15 +205,6 @@ describe.each([
}
const dateSearchTests: DateSearchTest[] = [
{ query: {}, expected: rows },
{
query: { onEmptyFilter: EmptyFilterOption.RETURN_ALL },
expected: rows,
},
{
query: { onEmptyFilter: EmptyFilterOption.RETURN_NONE },
expected: [],
},
{
query: { equal: { dob: new Date("2020-01-01").toISOString() } },
expected: [rows[0]],
@ -256,13 +259,11 @@ describe.each([
it.each(dateSearchTests)(
`should be able to run query: $query`,
async ({ query, expected }) => {
const savedRows = await Promise.all(
rows.map(r => config.api.row.save(table._id!, r))
)
const { rows: foundRows } = await config.api.row.search(table._id!, {
tableId: table._id!,
query,
})
expect(foundRows).toHaveLength(expected.length)
expect(foundRows).toEqual(
expect.arrayContaining(
expected.map(r =>

View File

@ -22,6 +22,7 @@ import {
SortDirection,
SqlQueryBinding,
Table,
EmptyFilterOption,
} from "@budibase/types"
import environment from "../../environment"
@ -243,6 +244,7 @@ class InternalBuilder {
return query
}
filters = parseFilters(filters)
let noFilters = true
// if all or specified in filters, then everything is an or
const allOr = filters.allOr
if (filters.oneOf) {
@ -250,6 +252,7 @@ class InternalBuilder {
const fnc = allOr ? "orWhereIn" : "whereIn"
query = query[fnc](key, Array.isArray(array) ? array : [array])
})
noFilters = false
}
if (filters.string) {
iterate(filters.string, (key, value) => {
@ -265,9 +268,11 @@ class InternalBuilder {
])
}
})
noFilters = false
}
if (filters.fuzzy) {
iterate(filters.fuzzy, like)
noFilters = false
}
if (filters.range) {
iterate(filters.range, (key, value) => {
@ -300,40 +305,61 @@ class InternalBuilder {
query = query[fnc](key, "<", value.high)
}
})
noFilters = false
}
if (filters.equal) {
iterate(filters.equal, (key, value) => {
const fnc = allOr ? "orWhere" : "where"
query = query[fnc]({ [key]: value })
})
// Somewhere above us in the stack adds `{ type: "row" }` to the `equal`
// key before we get here, so we need to still consider it empty when
// that's the case.
const equalEmpty =
Object.keys(filters.equal).length === 1 && filters.equal.type === "row"
if (!equalEmpty) {
noFilters = false
}
}
if (filters.notEqual) {
iterate(filters.notEqual, (key, value) => {
const fnc = allOr ? "orWhereNot" : "whereNot"
query = query[fnc]({ [key]: value })
})
noFilters = false
}
if (filters.empty) {
iterate(filters.empty, key => {
const fnc = allOr ? "orWhereNull" : "whereNull"
query = query[fnc](key)
})
noFilters = false
}
if (filters.notEmpty) {
iterate(filters.notEmpty, key => {
const fnc = allOr ? "orWhereNotNull" : "whereNotNull"
query = query[fnc](key)
})
noFilters = false
}
if (filters.contains) {
contains(filters.contains)
noFilters = false
}
if (filters.notContains) {
contains(filters.notContains)
noFilters = false
}
if (filters.containsAny) {
contains(filters.containsAny, true)
noFilters = false
}
if (noFilters && filters.onEmptyFilter === EmptyFilterOption.RETURN_NONE) {
query = query.whereRaw("1=0")
}
return query
}