improvement(tests): db-mock migration tranche 1 — knowledge, billing/org, workflows/background (#5861)

* improvement(tests): migrate knowledge, billing/org, and workflows/background suites off private @sim/db factories

* improvement(tests): db-mock migration tranche 1 — knowledge, billing/org, workflows/background

- migrate 19 suites off private vi.mock('@sim/db') factories onto the shared
  dbChainMock + queueTableRows API (net ~-1,260 lines of bespoke chain
  plumbing); resolves the known shared-worker rival pairs (knowledge
  processing-queue vs api utils; billing polluters; persistence/utils vs
  schedules/deploy)
- add .for() to the mock's limit builder (drizzle .limit(1).for('update'))
  with a contract test
- document the join-table queue fallback footgun on queueTableRows
This commit is contained in:
Waleed
2026-07-22 14:53:17 -07:00
committed by GitHub
parent c083be9def
commit 62a8ce4953
21 changed files with 710 additions and 1957 deletions
@@ -97,6 +97,14 @@ describe('database mock', () => {
).resolves.toEqual([{ id: 'from-row' }])
})
it('supports the .limit(n).for(mode) row-lock chain', async () => {
queueTableRows(workflowTable, [{ id: 'locked' }])
await expect(db.select().from(workflowTable).where({}).limit(1).for('update')).resolves.toEqual(
[{ id: 'locked' }]
)
expect(dbChainMockFns.for).toHaveBeenCalledWith('update')
})
it('never lets mutation chains consume select queues', async () => {
queueTableRows(workflowTable, [{ id: 'kept' }])
await expect(db.update(workflowTable).set({}).where({})).resolves.toEqual([])
+9 -1
View File
@@ -73,6 +73,12 @@ export function createMockSqlOperators() {
*
* The queue is keyed by table object identity, so pass the same schema-mock
* table object the code under test passes to `.from()` / the join.
*
* Footgun: because a chain falls back to its JOIN tables when the `.from()`
* table has nothing queued, a `from(A).innerJoin(B)` chain you expect to
* resolve empty will consume a set queued for a LATER select on `B`. When a
* suite queues `B` for a subsequent query, queue an explicit empty set on `A`
* first (`queueTableRows(A, [])`) so the joined chain consumes that instead.
*/
const tableRowQueues = new Map<unknown, unknown[][]>()
@@ -221,10 +227,12 @@ const lazyRowsThenable = (getRows: RowsSupplier): any => ({
})
// `.limit()` returns a builder that is awaitable and also exposes `.offset()`
// for keyset/OFFSET paging (`.limit(n).offset(m)`).
// for keyset/OFFSET paging (`.limit(n).offset(m)`) and `.for()` for drizzle's
// `.limit(1).for('update')` row-lock form.
const limitBuilder = (getRows: RowsSupplier) => {
const thenable = lazyRowsThenable(getRows)
thenable.offset = spyOrDefault(offset, () => lazyRowsThenable(getRows))
thenable.for = spyOrDefault(forClause, () => limitBuilder(getRows))
return thenable
}