Replaced mollie
All checks were successful
Deploy / build-deploy (push) Successful in 3m47s

This commit is contained in:
Jorijn van der Graaf 2026-08-20 20:15:47 +02:00
commit df91762271
29 changed files with 3079 additions and 838 deletions

View file

@ -87,7 +87,7 @@ static Configuration* SharedLibrary(std::span<const std::string_view> args) {
// Catcrafts.ServerCore — every implementation unit of the server except
// main.cpp, as a static library. The split exists for the tests: a test can
// only LINK a library-type dependency (crafter-build exports -L/-l for
// libraries alone), and the Mollie/EURC/Sendcloud parsers and the invoice
// libraries alone), and the bunq/EURC/Sendcloud parsers and the invoice
// builder all live here. The exe is main.cpp plus this library, so the
// split costs nothing at deploy time.
//
@ -108,24 +108,29 @@ static Configuration* ServerCore(std::span<const std::string_view> args, Configu
std::array<fs::path, 1> ifaces = {
"server/interfaces/Catcrafts.Server",
};
std::array<fs::path, 8> impls = {
std::array<fs::path, 10> impls = {
"server/implementations/Catcrafts.Server-Http",
"server/implementations/Catcrafts.Server-Orders",
"server/implementations/Catcrafts.Server-Mollie",
"server/implementations/Catcrafts.Server-Rails",
"server/implementations/Catcrafts.Server-Invoice",
"server/implementations/Catcrafts.Server-Eurc",
"server/implementations/Catcrafts.Server-Transfer",
"server/implementations/Catcrafts.Server-Bunq",
"server/implementations/Catcrafts.Server-Shipping",
"server/implementations/Catcrafts.Server-Mail",
"server/implementations/Catcrafts.Server-Financials",
};
core->GetInterfacesAndImplementations(ifaces, impls);
// Both rails reach their provider over TLS, which is what libssl is for
// here; libcrypto arrives as its dependency. (It was named explicitly
// while the bunq callback verified RSA body signatures through EVP — that
// integration is retired.) On the lib rather than the exe because link
// flags propagate to consumers — the exe and every test get them from here.
// The rails reach the outside world over TLS, which is what libssl is for.
// libcrypto is named EXPLICITLY again because the bunq credit source signs
// every request body with RSA-SHA256 through EVP: relying on it arriving as
// libssl's transitive dependency worked while nothing called EVP directly,
// and would break confusingly the moment a linker ordered them otherwise.
// On the lib rather than the exe because link flags propagate to consumers
// — the exe and every test get them from here.
core->linkFlags.push_back("-lssl");
core->linkFlags.push_back("-lcrypto");
return core.get();
}
@ -223,13 +228,14 @@ extern "C" Configuration CrafterBuildProject(std::span<const std::string_view> a
cfg.AddTest("ShouldParseSendcloudRates").Dependencies({ core, shared });
cfg.AddTest("ShouldMintOrderTokens").Dependencies({ core, shared });
cfg.AddTest("ShouldParseMolliePayments").Dependencies({ core, shared });
cfg.AddTest("ShouldParseEurcChains").Dependencies({ core, shared });
cfg.AddTest("ShouldGuardRequestProvenance").Dependencies({ core, shared });
cfg.AddTest("ShouldBuildInvoices").Dependencies({ core, shared });
cfg.AddTest("ShouldPublishFinancials").Dependencies({ core, shared });
cfg.AddTest("ShouldFoldTheOrderLedger").Dependencies({ core, shared });
cfg.AddTest("ShouldIssueEurcAddresses").Dependencies({ core, shared });
cfg.AddTest("ShouldMatchBankTransfers").Dependencies({ core, shared });
cfg.AddTest("ShouldParseBunqPayments").Dependencies({ core, shared });
// ── black-box suites (the tools/e2e.sh port) ──────────────────
// Each spawns the REAL binary — depending on &cfg is what builds it
@ -268,21 +274,30 @@ extern "C" Configuration CrafterBuildProject(std::span<const std::string_view> a
.Requires("tool:gpg")
.Timeout(std::chrono::seconds(180));
// ── live-provider suites ──────────────────────────────────────
// The two payment rails against their REAL counterparts: Mollie's
// API on a test-mode key, and the EURC rail settling an actual
// on-chain transfer on Base Sepolia. Both are MANDATORY deploy
// gates in CI (the workflow supplies MOLLIE_TEST_API_KEY and
// EURC_E2E_PRIVATE_KEY, and the suites fail there if either is
// missing); locally they skip unless those variables are exported.
// That gate lives in the suites themselves rather than in a
// Requires() — a Requires would skip silently when the credential
// vanished, which is exactly the pass this gate must never give.
// Timeouts cover real network: Mollie is a few round trips; the
// EURC suite waits out block inclusion plus the rail's 30 s poll.
cfg.AddTest("ShouldCreateMollieTestPayments", harness)
// The bank rail's full lifecycle against the REAL transfer rail —
// not a stand-in. It needs no credential and no network, because a
// self-hosted rail has no provider to authenticate to: the rail reads
// its credits from a file, so the suite can play the part of the bank
// by writing one. Every step in between is production code. It waits
// out the reconciler, hence the raised timeout.
cfg.AddTest("ShouldSettleBankTransfers", harness)
.Dependencies({ &cfg, shared, network }).Args({ serverBin })
.Timeout(std::chrono::seconds(120));
.Timeout(std::chrono::seconds(180));
// ── live-provider suite ───────────────────────────────────────
// The EURC rail settling an actual on-chain transfer on a testnet: a
// MANDATORY deploy gate in CI (the workflow supplies
// EURC_E2E_PRIVATE_KEY and the suite FAILS there if it is missing);
// locally it skips unless that variable is exported. The gate lives in
// the suite itself rather than in a Requires() — a Requires would skip
// silently when the credential vanished, which is exactly the pass
// this gate must never give.
//
// It is the only live suite now. There were two, until the hosted bank
// provider closed the account on 2026-08-20; the bank rail that
// replaced it has no counterpart to call, which is why its coverage
// sits above with the ordinary black-box suites instead. The timeout
// waits out block inclusion plus the rail's own poll.
cfg.AddTest("ShouldSettleEurcOnTestnet", harness)
.Dependencies({ &cfg, shared, network }).Args({ serverBin })
.Timeout(std::chrono::seconds(300));