taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit 6200fcdd87c1539dea55568bdeb59ab87d57b329
parent 61157df2531fed7db753bbce30e2a5faaef9fb77
Author: Florian Dold <dold@taler.net>
Date:   Tue, 21 Jul 2026 02:18:05 +0200

util: test that the observable HTTP client releases cancellation callbacks

Diffstat:
Apackages/taler-util/src/observability.test.ts | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+), 0 deletions(-)

diff --git a/packages/taler-util/src/observability.test.ts b/packages/taler-util/src/observability.test.ts @@ -0,0 +1,54 @@ +/* + This file is part of GNU Taler + (C) 2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +import { test } from "node:test"; +import assert from "node:assert"; +import { CancellationToken } from "./CancellationToken.js"; +import { HttpRequestLibrary, HttpResponse } from "./http-common.js"; +import { ObservableHttpClientLibrary } from "./observability.js"; + +function stubResponse(url: string): HttpResponse { + return { + requestUrl: url, + requestMethod: "GET", + status: 200, + headers: new Headers(), + json: async () => ({}), + text: async () => "", + bytes: async () => new Uint8Array(), + }; +} + +test("ObservableHttpClientLibrary releases the caller's cancellation callback", async (t) => { + const inner: HttpRequestLibrary = { + fetch: async (url) => stubResponse(url), + }; + const client = new ObservableHttpClientLibrary(inner, { observe: () => {} }); + const source = CancellationToken.create(); + + // The Set of registered callbacks is exposed for leak detection. + const callbacks = (): Set<unknown> => (source.token as any)._callbacks; + + for (let i = 0; i < 50; i++) { + await client.fetch("http://example.com/", { + cancellationToken: source.token, + }); + } + + // A completed request must unregister the callback it added to the caller's + // long-lived token, not leave one behind per request. + assert.strictEqual(callbacks().size, 0); +});