mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
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:
@@ -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([])
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user