| 362 | |
| 363 | /** Model a concurrent remover that wins immediately after policy update. */ |
| 364 | const removePolicyAfterUpdate = (db: FumaDb, armed: () => boolean): FumaDb => { |
| 365 | const wrap = (inner: FumaDb): FumaDb => |
| 366 | new Proxy(inner, { |
| 367 | get(target, property) { |
| 368 | if (property === "withContext") { |
| 369 | return (context: unknown) => |
| 370 | wrap((target.withContext as (value: unknown) => FumaDb)(context)); |
| 371 | } |
| 372 | if (property === "transaction") { |
| 373 | return (run: (transactionDb: FumaDb) => Promise<unknown>) => |
| 374 | target.transaction((transactionDb) => run(wrap(transactionDb as FumaDb))); |
| 375 | } |
| 376 | if (property === "updateMany") { |
| 377 | return async (...args: Parameters<FumaDb["updateMany"]>) => { |
| 378 | const [table, input] = args; |
| 379 | const result = await target.updateMany(...args); |
| 380 | if (armed() && table === "tool_policy") { |
| 381 | await target.deleteMany(table, { where: input.where }); |
| 382 | } |
| 383 | return result; |
| 384 | }; |
| 385 | } |
| 386 | return Reflect.get(target, property); |
| 387 | }, |
| 388 | }); |
| 389 | return wrap(db); |
| 390 | }; |
| 391 | |
| 392 | describe("executor.policies", () => { |
| 393 | it.effect("list is empty when no rules exist", () => |