Aller au contenu principal
Version: 1.0.0

Tester un handler de compensation

Ce test vérifie le contrat entre le SDK et un adaptateur métier de libération de réservation : identifiant, reçu original, clé d'idempotence et résultat. L'adaptateur local conserve une réservation réelle en mémoire pour le test. La création d'une compensation gouvernée par le runtime est décrite dans le guide des compensations.

Installer le SDK​

Terminal
touba sdk install javascript

Définir le handler​

release.mjs
import {createToolHandler, createToolResult} from '@touba/sdk';

export function releaseHandler(releaseReservation) {
return createToolHandler({
toolRef:'tool:reservations/ReleaseReservation',
inputSignature:[{name:'reservation_id',type_ref:'builtin:Text'}],
outputType:'builtin:Text',
run:async ({request:reservation_id, context}) => {
const response = await releaseReservation({
reservationId:reservation_id,
originalReceipt:context.compensation.original_effect_receipt,
idempotencyKey:context.effect.effect_id,
});
return createToolResult(response.message, {
effectReceipt:context.createEffectReceipt({outcome:'applied',receipt_ref:response.receiptRef}),
compensationReceipt:context.createCompensationReceipt({result:'completed'}),
});
},
});
}

Vérifier les données et l'idempotence métier​

Les métadonnées ci-dessous sont des fixtures de test. En exécution, le runtime établit le contexte et vérifie les reçus, l'autorité et les budgets.

exercise.mjs
import assert from 'node:assert/strict';
import {releaseHandler} from './release.mjs';

const reservations = new Set(['RES-42']);
const completed = new Map();
const original = {outcome:'applied', receipt_ref:'reservation:RES-42'};
let writes = 0;
const handler = releaseHandler(async ({reservationId, originalReceipt, idempotencyKey}) => {
assert.equal(reservationId,'RES-42');
assert.deepEqual(originalReceipt,original);
assert.equal(idempotencyKey,'effect:release-42');
if (!completed.has(idempotencyKey)) {
assert.equal(reservations.delete(reservationId),true); writes++;
completed.set(idempotencyKey,{message:'Released',receiptRef:'release:RES-42'});
}
return completed.get(idempotencyKey);
});
const request = {arguments:{reservation_id:'RES-42'},env:{},
compensation:{original_effect_receipt:original}, effect:{effect_id:'effect:release-42'},
createEffectReceipt:value=>value, createCompensationReceipt:value=>value};
await handler(request);
await handler(request);
assert.equal(writes,1); assert.equal(reservations.size,0);
await assert.rejects(handler({...request,arguments:{reservation_id:42}}));
assert.equal(writes,1);
console.log('COMPENSATION_HANDLER_CONTRACT_OK');
Terminal
node exercise.mjs

Résultat : COMPENSATION_HANDLER_CONTRACT_OK. Dans votre application, remplacez l'adaptateur par celui du fournisseur et persistez ses clés d'idempotence. Ce test de callback complète les tests de compensation runtime.