Skip to content

Commit 15fcbdd

Browse files
authored
test(objectql): pin the two vacuous-filter carve-outs nothing held (#4121, #4181) (#4231)
`?filter=` with an empty value must mean "no filter", not "an invalid one". Four shapes express that; only `{}` and `''` were pinned. `[]` (which #4121 exempts explicitly) and `' '` (which #4181 blanks via .trim(), never exercised — only `''` was tested) were decisions stated in a comment and held by nothing, each one line from a rejection: #4121's array branch guards on `length > 0`, #4181's blank guard calls `.trim()`. This family has moved from tolerate to reject five times, so the next tightening would silently turn "I sent no filter" into a 400. Mutation-checked: dropping `length > 0` fails 1 case, replacing `.trim() === ''` with `=== ''` fails 2. This branch originally carried a full query-expression conformance suite; #4240 landed the sort/select/expand half independently under the same filename while it waited, which both conflicted and made its KNOWN GAP pins assert behavior that no longer exists. Only the part #4240 does not cover is kept.
1 parent 23fc3e2 commit 15fcbdd

2 files changed

Lines changed: 32 additions & 0 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
---
3+
4+
test(objectql): pin the two vacuous-filter carve-outs (#4121, #4181)
5+
6+
Test-only; no package behavior changes, so this changeset releases nothing.

packages/objectql/src/protocol-data.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,32 @@ describe('ObjectStackProtocolImplementation - Data Operations', () => {
832832
expect(engine.find.mock.calls[1][1].where).toEqual({ owner_id: 'usr_1' });
833833
});
834834

835+
it('every OTHER vacuous filter shape means "absent" too — the two deliberate carve-outs nothing pinned', async () => {
836+
// Both of these are decisions the code states in a comment and no
837+
// test held. They sit one line away from a rejection, so a future
838+
// tightening of the surrounding guard would silently turn "no
839+
// filter" into a 400 for callers who send an empty one:
840+
//
841+
// [] — #4121 rejects an array `isFilterAST` refuses, but
842+
// deliberately exempts the EMPTY array ("it means no
843+
// filter, and every path already treats it that way").
844+
// ' ' — #4181 rejects an unparseable filter STRING via
845+
// JSON.parse, but blanks it first with `.trim()`, so a
846+
// whitespace-only filter is absent rather than invalid.
847+
// Only `''` was covered; `' '` never exercised trim().
848+
const { protocol, engine } = makeProtocol();
849+
for (const filter of [[], ' ']) {
850+
await protocol.findData({
851+
object: 'showcase_task',
852+
query: { filter, owner_id: 'usr_1' },
853+
});
854+
}
855+
for (const call of engine.find.mock.calls) {
856+
expect(call[1].where).toEqual({ owner_id: 'usr_1' });
857+
}
858+
expect(engine.find).toHaveBeenCalledTimes(2);
859+
});
860+
835861
it('count() sees the merged where — pagination totals cannot disagree with records (#4164)', async () => {
836862
const { protocol, engine } = makeProtocol();
837863
await protocol.findData({

0 commit comments

Comments
 (0)