22 * @vitest -environment node
33 */
44import { hybridAuthMockFns } from '@sim/testing'
5- import { NextRequest } from 'next/server'
5+ import { NextRequest , NextResponse } from 'next/server'
66import { beforeEach , describe , expect , it , vi } from 'vitest'
77import type { TableDefinition } from '@/lib/table'
88
9- const {
10- mockCheckAccess,
11- mockMarkTableJobRunning,
12- mockRunTableDelete,
13- mockBuildFilterClause,
14- TableQueryValidationError,
15- } = vi . hoisted ( ( ) => ( {
16- mockCheckAccess : vi . fn ( ) ,
17- mockMarkTableJobRunning : vi . fn ( ) ,
18- mockRunTableDelete : vi . fn ( ) ,
19- mockBuildFilterClause : vi . fn ( ) ,
20- TableQueryValidationError : class extends Error { } ,
21- } ) )
9+ const { mockCheckAccess, mockMarkTableJobRunning, mockRunTableDelete, mockTableFilterError } =
10+ vi . hoisted ( ( ) => ( {
11+ mockCheckAccess : vi . fn ( ) ,
12+ mockMarkTableJobRunning : vi . fn ( ) ,
13+ mockRunTableDelete : vi . fn ( ) ,
14+ mockTableFilterError : vi . fn ( ) ,
15+ } ) )
2216
2317vi . mock ( '@sim/utils/id' , ( ) => ( {
2418 generateId : vi . fn ( ) . mockReturnValue ( 'job-id-xyz' ) ,
2519 generateShortId : vi . fn ( ) . mockReturnValue ( 'short-id' ) ,
2620} ) )
2721vi . mock ( '@/lib/table/service' , ( ) => ( { markTableJobRunning : mockMarkTableJobRunning } ) )
2822vi . mock ( '@/lib/table/delete-runner' , ( ) => ( { runTableDelete : mockRunTableDelete } ) )
29- vi . mock ( '@/lib/table/sql' , ( ) => ( {
30- buildFilterClause : mockBuildFilterClause ,
31- TableQueryValidationError,
32- } ) )
3323vi . mock ( '@/lib/core/utils/background' , ( ) => ( {
3424 runDetached : ( _label : string , work : ( ) => Promise < unknown > ) => {
3525 void work ( )
@@ -41,6 +31,7 @@ vi.mock('@/app/api/table/utils', async () => {
4131 checkAccess : mockCheckAccess ,
4232 accessError : ( result : { status : number } ) =>
4333 NextResponse . json ( { error : 'denied' } , { status : result . status } ) ,
34+ tableFilterError : mockTableFilterError ,
4435 }
4536} )
4637
@@ -90,7 +81,7 @@ describe('POST /api/table/[tableId]/delete-async', () => {
9081 mockCheckAccess . mockResolvedValue ( { ok : true , table : buildTable ( ) } )
9182 mockMarkTableJobRunning . mockResolvedValue ( true )
9283 mockRunTableDelete . mockResolvedValue ( undefined )
93- mockBuildFilterClause . mockReturnValue ( { } )
84+ mockTableFilterError . mockReturnValue ( null )
9485 } )
9586
9687 it ( 'claims the job slot and kicks off the delete worker with filter + exclusions' , async ( ) => {
@@ -99,7 +90,11 @@ describe('POST /api/table/[tableId]/delete-async', () => {
9990
10091 expect ( response . status ) . toBe ( 200 )
10192 expect ( data . data ) . toEqual ( { tableId : 'tbl_1' , jobId : 'job-id-xyz' } )
102- expect ( mockMarkTableJobRunning ) . toHaveBeenCalledWith ( 'tbl_1' , 'job-id-xyz' , 'delete' )
93+ expect ( mockMarkTableJobRunning ) . toHaveBeenCalledWith ( 'tbl_1' , 'job-id-xyz' , 'delete' , {
94+ filter : { status : 'archived' } ,
95+ excludeRowIds : [ 'row_keep' ] ,
96+ cutoff : expect . any ( String ) ,
97+ } )
10398 expect ( mockRunTableDelete ) . toHaveBeenCalledWith (
10499 expect . objectContaining ( {
105100 jobId : 'job-id-xyz' ,
@@ -128,9 +123,7 @@ describe('POST /api/table/[tableId]/delete-async', () => {
128123 } )
129124
130125 it ( 'returns 400 on an invalid filter without claiming the slot' , async ( ) => {
131- mockBuildFilterClause . mockImplementation ( ( ) => {
132- throw new TableQueryValidationError ( 'bad field' )
133- } )
126+ mockTableFilterError . mockReturnValue ( NextResponse . json ( { error : 'bad field' } , { status : 400 } ) )
134127 const response = await makeRequest ( validBody )
135128 expect ( response . status ) . toBe ( 400 )
136129 expect ( mockMarkTableJobRunning ) . not . toHaveBeenCalled ( )
0 commit comments