This commit is contained in:
parent
33c68c2f44
commit
749f525f83
44 changed files with 5380 additions and 3532 deletions
82
tests/ShouldParseMolliePayments/main.cpp
Normal file
82
tests/ShouldParseMolliePayments/main.cpp
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
catcrafts.net
|
||||
Copyright (C) 2026 Catcrafts
|
||||
|
||||
The source code of this website is made available for viewing purposes only.
|
||||
No permission is granted to copy, modify, distribute, or create derivative works.
|
||||
*/
|
||||
|
||||
// The wire-amount parser (Mollie quotes amounts as strings) and the Mollie
|
||||
// payment parser — the line between "the buyer paid" and "the provider said
|
||||
// something we did not understand". Both refuse rather than guess.
|
||||
|
||||
import std;
|
||||
import Catcrafts.Shared;
|
||||
import Catcrafts.Server;
|
||||
|
||||
using namespace Catcrafts;
|
||||
|
||||
namespace {
|
||||
|
||||
int failures = 0;
|
||||
|
||||
void Check(bool ok, std::string_view what, std::string_view got = {}) {
|
||||
if (ok) return;
|
||||
++failures;
|
||||
std::println(std::cerr, "FAIL: {}{}{}", what,
|
||||
got.empty() ? "" : " got: ", got);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main() {
|
||||
// ── the wire-amount parser ────────────────────────────────────────
|
||||
using Server::ParseAmountToMinor;
|
||||
Check(ParseAmountToMinor("614.00") == 61400, "amount: normal");
|
||||
Check(ParseAmountToMinor("614") == 61400, "amount: no fraction");
|
||||
Check(ParseAmountToMinor("614.5") == 61450, "amount: one fraction digit");
|
||||
Check(ParseAmountToMinor("0.01") == 1, "amount: one cent");
|
||||
Check(!ParseAmountToMinor("614.005").has_value(), "amount: three decimals rejected");
|
||||
Check(!ParseAmountToMinor("-1.00").has_value(), "amount: negative rejected");
|
||||
Check(!ParseAmountToMinor("+1.00").has_value(), "amount: sign rejected");
|
||||
Check(!ParseAmountToMinor("1e3").has_value(), "amount: exponent rejected");
|
||||
Check(!ParseAmountToMinor("1.").has_value(), "amount: trailing dot rejected");
|
||||
Check(!ParseAmountToMinor(".5").has_value(), "amount: bare fraction rejected");
|
||||
Check(!ParseAmountToMinor("").has_value(), "amount: empty rejected");
|
||||
Check(!ParseAmountToMinor("1 000.00").has_value(), "amount: separator rejected");
|
||||
|
||||
// ── the Mollie payment parser ─────────────────────────────────────
|
||||
{
|
||||
const auto p1 = Server::ParseMolliePayment(R"({
|
||||
"resource":"payment","id":"tr_7UhSN1zuXS","status":"open","method":null,
|
||||
"amount":{"value":"578.30","currency":"EUR"},
|
||||
"_links":{"checkout":{"href":"https://www.mollie.com/checkout/select-method/7UhSN1zuXS","type":"text/html"}}})");
|
||||
Check(p1.has_value(), "mollie: open payment parses");
|
||||
if (p1) {
|
||||
Check(p1->id == "tr_7UhSN1zuXS", "mollie: id");
|
||||
Check(p1->status == "open", "mollie: status");
|
||||
Check(p1->amountMinor == 57830, "mollie: amount to cents");
|
||||
Check(p1->checkoutUrl == "https://www.mollie.com/checkout/select-method/7UhSN1zuXS",
|
||||
"mollie: checkout link");
|
||||
Check(p1->method.empty(), "mollie: null method is empty");
|
||||
}
|
||||
const auto p2 = Server::ParseMolliePayment(R"({
|
||||
"id":"tr_x","status":"paid","method":"ideal",
|
||||
"amount":{"value":"578.30","currency":"EUR"},"_links":{}})");
|
||||
Check(p2 && p2->status == "paid" && p2->method == "ideal",
|
||||
"mollie: paid payment carries the method");
|
||||
const auto p3 = Server::ParseMolliePayment(R"({
|
||||
"id":"tr_y","status":"paid","amount":{"value":"578.30","currency":"USD"}})");
|
||||
Check(p3 && p3->amountMinor == 0, "mollie: non-EUR amount refuses to count");
|
||||
Check(!Server::ParseMolliePayment("garbage").has_value(),
|
||||
"mollie: malformed payload rejected");
|
||||
Check(!Server::ParseMolliePayment(R"({"status":"open"})").has_value(),
|
||||
"mollie: missing id rejected");
|
||||
}
|
||||
|
||||
if (failures != 0) {
|
||||
std::println(std::cerr, "{} check(s) failed", failures);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in a new issue