Skip to content

Commit 3670e40

Browse files
mercury2269gcatanese
authored andcommitted
Fix union types deserialization with transfer webhooks
1 parent 453bb88 commit 3670e40

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

.vscode/settings.json

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
{
2+
}

src/__tests__/transferWebhook.spec.ts

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import BankingWebhookHandler from "../notification/bankingWebhookHandler";
2+
import { EstimationTrackingData } from "../typings/transferWebhooks/estimationTrackingData";
3+
4+
describe("Transfer Webhook Serialization", (): void => {
5+
it("should correctly deserialize union types in transfer webhooks", () => {
6+
// Simplest possible webhook with just the fields we need to test
7+
const webhookData = {
8+
data: {
9+
id: "test-transfer-id",
10+
tracking: {
11+
estimatedArrivalTime: "2025-04-23T22:30:00+02:00",
12+
type: "estimation",
13+
},
14+
},
15+
type: "balancePlatform.transfer.updated",
16+
};
17+
18+
const jsonString = JSON.stringify(webhookData);
19+
const bankingWebhookHandler = new BankingWebhookHandler(jsonString);
20+
const transferNotification =
21+
bankingWebhookHandler.getTransferNotificationRequest();
22+
23+
if (transferNotification.data.tracking?.type === "estimation") {
24+
// Verify that the tracking object is properly deserialized to the correct type
25+
expect(transferNotification.data.tracking).toBeInstanceOf(
26+
EstimationTrackingData
27+
);
28+
29+
// Verify that estimatedArrivalTime is properly converted to a Date object
30+
expect(
31+
transferNotification.data.tracking.estimatedArrivalTime
32+
).toBeInstanceOf(Date);
33+
}
34+
});
35+
});

src/typings/transferWebhooks/models.ts

+19
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,25 @@ export class ObjectSerializer {
259259
return expectedType;
260260
}
261261

262+
// Handle union types
263+
if (expectedType.includes(" | ")) {
264+
const unionTypes = expectedType.split(" | ").map((t) => t.trim());
265+
266+
// For tracking field specifically, use the 'type' field to determine the actual type
267+
if (data && data.type && unionTypes.some((t) => t.includes("TrackingData"))) {
268+
if (data.type === "estimation") return "EstimationTrackingData";
269+
if (data.type === "confirmation") return "ConfirmationTrackingData";
270+
if (data.type === "internalReview") return "InternalReviewTrackingData";
271+
}
272+
273+
// For other union types, return the first non-null type that exists in typeMap
274+
for (const type of unionTypes) {
275+
if (type !== "null" && typeMap[type]) {
276+
return type;
277+
}
278+
}
279+
}
280+
262281
if (!typeMap[expectedType]) {
263282
return expectedType; // w/e we don't know the type
264283
}

0 commit comments

Comments
 (0)