This commit is contained in:
parent
7098ac75cb
commit
df91762271
29 changed files with 3079 additions and 838 deletions
61
project.cpp
61
project.cpp
|
|
@ -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));
|
||||
|
|
|
|||
Loading…
Reference in a new issue