sanctions block list
All checks were successful
Deploy / build-deploy (push) Successful in 2m18s

This commit is contained in:
Jorijn van der Graaf 2026-08-15 03:22:25 +02:00
commit b0666841f6
7 changed files with 139 additions and 31 deletions

View file

@ -480,6 +480,15 @@ void AlwaysOnValidation(TestServer& srv) {
"email=ca%40example.org&name=Terry&street=1%20Bloor%20St&postal=M4W&city=Toronto&country=CA");
srv.CheckStatus("/shop/fp6-pmos", "422", "POST",
"email=us%40example.org&name=Pat&street=1%20Main%20St&postal=43004&city=Columbus&country=us");
// Sanctioned destinations (Money::SanctionedCountries) refuse through the
// same always-on gate — this refusal is the law, so of all the checks in
// this file it is the one that must survive every refactor.
srv.CheckStatus("/shop/fp6-pmos", "422", "POST",
"email=ru%40example.org&name=Sasha&street=1%20Tverskaya&postal=125009&city=Moscow&country=RU");
srv.CheckStatus("/shop/fp6-pmos", "422", "POST",
"email=by%40example.org&name=Vanya&street=1%20Kastrychnitskaya&postal=220030&city=Minsk&country=BY");
srv.CheckStatus("/shop/fp6-pmos", "422", "POST",
"email=ru%40example.org&name=Sasha&street=1%20Tverskaya&postal=125009&city=Moscow&country=ru");
// Refused in validation means nothing reached the ledger and no payment
// link was ever created.
Check(LedgerLines(srv).size() == before, "a refused destination creates no order record");
@ -514,13 +523,28 @@ void RejectedFormEcho(TestServer& srv) {
Check(refused.body.find("value=\"Pat\"") != std::string::npos,
"a refused submission keeps what was typed");
}
// A sanctioned destination gets the sanctions sentence, not the policy
// one — the buyer should learn the law forbids the sale, not wonder what
// insurance has to do with Moscow.
{
const auto refused = srv.Post("/shop/fp6-pmos",
"email=ru%40example.org&name=Sasha&street=1%20Tverskaya&postal=125009&city=Moscow&country=RU");
Check(refused.body.find("EU sanctions prohibit") != std::string::npos,
"sanctions refusal explains itself on the form");
Check(refused.body.find("field__error\">Catcrafts does not sell") == std::string::npos,
"sanctions refusal is not worded as the policy one");
}
// The buy panel warns before anyone fills it in, and the preview script
// carries the same list so it cannot quote a total the server would
// carries the same lists so it cannot quote a total the server would
// refuse.
srv.BodyHas("/shop/fp6-pmos", "does not sell or ship to the United States or Canada",
"buy panel states where the shop does not sell");
srv.BodyHas("/shop/fp6-pmos", "cannot sell or ship to Russia, Belarus or North Korea",
"buy panel states where the law forbids selling");
srv.BodyHas("/shop/fp6-pmos", ""x":["US","CA"]",
"total preview knows the refused destinations");
srv.BodyHas("/shop/fp6-pmos", ""s":["RU","BY","KP"]",
"total preview knows the sanctioned destinations");
// The honeypot message must not name the trap, or it teaches the next
// bot. Only the ERROR NOTICE is inspected: the re-rendered form
// legitimately contains the name="website" field itself — that IS the