以下保留檔案原文,沒有改寫資料或結果。可使用「複製原始內容」取得完整檔案。
"""Business assertions defined from the frozen contract, not response snapshots."""
from concurrent.futures import ThreadPoolExecutor
from threading import Barrier
import unittest
from .fixture import PaymentEnvironment
CASE_IDS = {
"reject_paid_order": "BE-PAID-REJECT",
"pay_pending_order": "BE-PENDING-PAY",
"concurrent_payment_once": "BE-CONCURRENT",
"reject_invalid_request": "BE-INVALID-REQUEST",
"reject_missing_order": "BE-MISSING-ORDER",
}
class PaymentContract(unittest.TestCase):
implementation = None
fault = "none"
def setUp(self):
self.environment = PaymentEnvironment(self.implementation, self.fault)
self.addCleanup(self.environment.close)
self.api = self.environment.adapter
def test_reject_paid_order(self):
before = self.api.observe("paid-order")
status, body = self.api.pay({"order_id": "paid-order"})
self.assertEqual(status, 409, "Paid order must return HTTP 409")
self.assertEqual(body.get("error"), "ORDER_ALREADY_PAID", "Paid rejection must explain its cause")
self.assertEqual(self.api.observe("paid-order"), before, "Rejected payment must not change DB state")
def test_pay_pending_order(self):
status, body = self.api.pay({"order_id": "pending-order"})
self.assertEqual(status, 200)
self.assertEqual(body, {"order_id": "pending-order", "status": "PAID"})
self.assertEqual(self.api.observe("pending-order"), {"status": "PAID", "payments": 1})
def test_concurrent_payment_once(self):
barrier = Barrier(2)
def pay_together():
barrier.wait(timeout=5)
return self.api.pay({"order_id": "pending-order"})
with ThreadPoolExecutor(max_workers=2) as executor:
results = list(executor.map(lambda _: pay_together(), range(2)))
self.assertEqual(sorted(status for status, _ in results), [200, 409])
self.assertEqual(self.api.observe("pending-order"), {"status": "PAID", "payments": 1},
"Concurrent requests must create exactly one payment")
def test_reject_invalid_request(self):
before = self.api.observe("pending-order")
status, body = self.api.pay({"order_id": ""})
self.assertEqual((status, body), (400, {"error": "INVALID_REQUEST"}))
self.assertEqual(self.api.observe("pending-order"), before)
def test_reject_missing_order(self):
status, body = self.api.pay({"order_id": "unknown-order"})
self.assertEqual((status, body), (404, {"error": "ORDER_NOT_FOUND"}))
self.assertEqual(self.api.observe("unknown-order"), {"status": None, "payments": 0})