From 146f014eb8db8a7beb4fff462b481785a0d5d9db Mon Sep 17 00:00:00 2001
From: dabund24 <dabund24@gmail.com>
Date: Thu, 9 Jan 2025 00:09:36 +0100
Subject: [PATCH] implement `formatTransfers()`, use it `formatJourneysReq()`
 functions and re-add corresponding unit test

---
 format/transfers.js              | 10 ++++++++++
 lib/default-profile.js           |  2 ++
 p/db/journeys-req.js             |  3 ++-
 p/dbnav/journeys-req.js          |  3 ++-
 test/format/db-journeys-query.js | 19 +++++++++++++++++++
 5 files changed, 35 insertions(+), 2 deletions(-)
 create mode 100644 format/transfers.js

diff --git a/format/transfers.js b/format/transfers.js
new file mode 100644
index 00000000..c374a7dd
--- /dev/null
+++ b/format/transfers.js
@@ -0,0 +1,10 @@
+const formatTransfers = (transfers) => {
+	if (transfers === -1) { // profiles may not accept -1: https://github.com/public-transport/db-vendo-client/issues/5
+		return undefined;
+	}
+	return transfers;
+};
+
+export {
+	formatTransfers,
+};
diff --git a/lib/default-profile.js b/lib/default-profile.js
index 7b7f5a94..42b09bfe 100644
--- a/lib/default-profile.js
+++ b/lib/default-profile.js
@@ -36,6 +36,7 @@ import {formatTime, formatTimeOfDay} from '../format/time.js';
 import {formatLocation} from '../format/location.js';
 import {formatTravellers} from '../format/travellers.js';
 import {formatLoyaltyCard} from '../format/loyalty-cards.js';
+import {formatTransfers} from '../format/transfers.js';
 
 const DEBUG = (/(^|,)hafas-client(,|$)/).test(process.env.DEBUG || '');
 const logRequest = DEBUG
@@ -103,6 +104,7 @@ const defaultProfile = {
 	formatStation,
 	formatTime,
 	formatTimeOfDay,
+	formatTransfers,
 	formatTravellers,
 	formatRectangle: id,
 
diff --git a/p/db/journeys-req.js b/p/db/journeys-req.js
index 9b0fa122..0d0fc399 100644
--- a/p/db/journeys-req.js
+++ b/p/db/journeys-req.js
@@ -4,10 +4,11 @@ const formatJourneysReq = (ctx, from, to, when, outFrwd, journeysRef) => {
 	from = profile.formatLocation(profile, from, 'from');
 	to = profile.formatLocation(profile, to, 'to');
 	const filters = profile.formatProductsFilter({profile}, opt.products || {});
+	const transfers = profile.formatTransfers(opt.transfers);
 	// TODO opt.accessibility
 	// TODO routingMode
 	let query = {
-		maxUmstiege: opt.transfers,
+		maxUmstiege: transfers,
 		minUmstiegszeit: opt.transferTime,
 		deutschlandTicketVorhanden: false,
 		nurDeutschlandTicketVerbindungen: false,
diff --git a/p/dbnav/journeys-req.js b/p/dbnav/journeys-req.js
index 668f7a81..4c07bf1f 100644
--- a/p/dbnav/journeys-req.js
+++ b/p/dbnav/journeys-req.js
@@ -31,6 +31,7 @@ const formatJourneysReq = (ctx, from, to, when, outFrwd, journeysRef) => {
 	from = profile.formatLocation(profile, from, 'from');
 	to = profile.formatLocation(profile, to, 'to');
 	const filters = profile.formatProductsFilter({profile}, opt.products || {}, 'dbnav');
+	const transfers = profile.formatTransfers(opt.transfers) ?? undefined; // `dbnav` does not allow `undefined` here
 	// TODO opt.accessibility
 	// TODO routingMode
 	let query = formatBaseJourneysReq(ctx);
@@ -46,7 +47,7 @@ const formatJourneysReq = (ctx, from, to, when, outFrwd, journeysRef) => {
 				? [{locationId: profile.formatLocation(profile, opt.via, 'opt.via').lid}]
 				: undefined,
 			zielLocationId: to.lid,
-			maxUmstiege: opt.transfers ?? undefined,
+			maxUmstiege: transfers,
 			minUmstiegsdauer: opt.transferTime || undefined,
 			fahrradmitnahme: opt.bike,
 		},
diff --git a/test/format/db-journeys-query.js b/test/format/db-journeys-query.js
index 7ad0367b..ebb6bab6 100644
--- a/test/format/db-journeys-query.js
+++ b/test/format/db-journeys-query.js
@@ -114,3 +114,22 @@ tap.test('formats a journeys() request with BC correctly (DB)', (t) => {
 	});
 	t.end();
 });
+
+tap.test('formats a journeys() request with unlimited transfers (DB)', (t) => {
+	const _opt = {...opt};
+	const ctx = {profile, opt: _opt};
+
+	ctx.opt.transfers = 0; // no transfers
+	const reqZeroTransfers = profile.formatJourneysReq(ctx, '8098160', '8000284', new Date('2024-12-07T23:50:12+01:00'), true, null);
+	t.equal(reqZeroTransfers.body.maxUmstiege, 0);
+
+	ctx.opt.transfers = undefined; // unconstrained transfers implicit
+	const reqUnlimitedTransfersImplicit = profile.formatJourneysReq(ctx, '8098160', '8000284', new Date('2024-12-07T23:50:12+01:00'), true, null);
+	t.equal(reqUnlimitedTransfersImplicit.body.maxUmstiege, undefined);
+
+	ctx.opt.transfers = -1; // unconstrained transfers explicit
+	const reqUnlimitedTransfersExplicit = profile.formatJourneysReq(ctx, '8098160', '8000284', new Date('2024-12-07T23:50:12+01:00'), true, null);
+	t.equal(reqUnlimitedTransfersExplicit.body.maxUmstiege, undefined);
+
+	t.end();
+});