@@ -280,4 +280,61 @@ describe("Loan Dispute/Appeal Mechanism", () => {
280280 expect ( res . status ) . toBe ( 200 ) ;
281281 expect ( res . body . success ) . toBe ( true ) ;
282282 } ) ;
283+
284+ it ( "should allow admin to resolve dispute via JWT and log audit" , async ( ) => {
285+ const adminToken = jwt . sign (
286+ { publicKey : TEST_PUBLIC_KEY , role : "admin" , scopes : [ ] } ,
287+ process . env . JWT_SECRET ! ,
288+ { algorithm : "HS256" , expiresIn : "1h" } ,
289+ ) ;
290+
291+ mockQuery
292+ . mockResolvedValueOnce ( dbOk ( ) ) // [1] INSERT audit_logs (middleware runs first)
293+ . mockResolvedValueOnce (
294+ dbRows ( [
295+ {
296+ id : disputeId ,
297+ loan_id : LOAN_ID ,
298+ borrower : TEST_PUBLIC_KEY ,
299+ status : "open" ,
300+ } ,
301+ ] ) ,
302+ ) // [2] SELECT dispute
303+ . mockResolvedValueOnce ( dbOk ( "UPDATE" ) ) // [3] UPDATE dispute
304+ . mockResolvedValueOnce ( dbOk ( ) ) ; // [4] INSERT contract_events
305+
306+ const res = await request ( app )
307+ . post ( `/api/admin/disputes/${ disputeId } /resolve` )
308+ . set ( "Authorization" , `Bearer ${ adminToken } ` )
309+ . send ( {
310+ action : "confirm" ,
311+ resolution : "JWT valid default." ,
312+ token : "super_secret_token" ,
313+ } ) ;
314+
315+ expect ( res . status ) . toBe ( 200 ) ;
316+ expect ( res . body . success ) . toBe ( true ) ;
317+
318+ // Wait for the async audit log query to fire
319+ await new Promise ( ( resolve ) => setTimeout ( resolve , 50 ) ) ;
320+
321+ const calls = mockQuery . mock . calls ;
322+ const auditLogCall = calls . find (
323+ ( call : any [ ] ) =>
324+ typeof call [ 0 ] === "string" &&
325+ call [ 0 ] . includes ( "INSERT INTO audit_logs" ) ,
326+ ) ;
327+
328+ expect ( auditLogCall ) . toBeDefined ( ) ;
329+ if ( auditLogCall ) {
330+ expect ( auditLogCall [ 1 ] [ 0 ] ) . toBe ( TEST_PUBLIC_KEY ) ;
331+ expect ( auditLogCall [ 1 ] [ 1 ] ) . toContain ( "POST /disputes" ) ;
332+ expect ( auditLogCall [ 1 ] [ 2 ] ) . toBe ( `DisputeID:${ disputeId } ` ) ;
333+
334+ const payloadString = auditLogCall [ 1 ] [ 3 ] ;
335+ expect ( payloadString ) . toContain ( "JWT valid default." ) ;
336+ expect ( payloadString ) . toContain ( "[REDACTED]" ) ;
337+ expect ( payloadString ) . not . toContain ( "super_secret_token" ) ;
338+ }
339+ } ) ;
283340} ) ;
0 commit comments