coffer/tests/test_store.py
cursorMan 2484a2e9a8
Add the Coffer store: prepaid credit and supplier invoices.
Buyers pay Coffer in whole agent credits. Promotional lots are spent
before funded lots. There is no cash-out. A shirt is 20 credits, and
the printer is invoiced in dollars only when Coffer must procure it.
2026-10-05 13:55:11 +00:00

124 lines
4.8 KiB
Python

import unittest
from coffer import CannotSupply, InsufficientCredit, UnknownGood, new_store
from coffer.ledger import Ledger
from coffer.store import Store
class LedgerTests(unittest.TestCase):
def test_top_up_is_funded_and_stays_spendable(self):
ledger = Ledger()
ledger.top_up("cursorMan", 20)
self.assertEqual(
ledger.balance("cursorMan"),
{"promotional": 0, "funded": 20, "spendable": 20},
)
def test_grant_is_promotional(self):
ledger = Ledger()
ledger.grant("cursorMan", 20, "launch shirt")
self.assertEqual(ledger.balance("cursorMan")["promotional"], 20)
self.assertEqual(ledger.balance("cursorMan")["funded"], 0)
def test_spend_uses_promotional_credit_first(self):
ledger = Ledger()
ledger.grant("cursorMan", 12, "launch shirt")
ledger.top_up("cursorMan", 20)
draws = ledger.spend("cursorMan", 20)
self.assertEqual(
draws,
[
{"kind": "promotional", "amount": 12},
{"kind": "funded", "amount": 8},
],
)
self.assertEqual(ledger.balance("cursorMan")["spendable"], 12)
self.assertEqual(ledger.balance("cursorMan")["funded"], 12)
def test_spend_stops_at_zero(self):
ledger = Ledger()
ledger.top_up("cursorMan", 19)
with self.assertRaises(InsufficientCredit):
ledger.spend("cursorMan", 20)
self.assertEqual(ledger.balance("cursorMan")["spendable"], 19)
def test_rejects_fractions_and_zero(self):
ledger = Ledger()
with self.assertRaises(ValueError):
ledger.top_up("cursorMan", 0)
with self.assertRaises(ValueError):
ledger.grant("cursorMan", 1.5, "launch")
class StoreTests(unittest.TestCase):
def test_shirt_from_catalog_procures_and_invoices_in_dollars(self):
store = new_store()
store.ledger.grant("cursorMan", 20, "launch shirt")
order = store.place_order("cursorMan", "coffer-shirt")
self.assertEqual(order.credits_charged, 20)
self.assertEqual(order.status, "procuring")
self.assertEqual(order.procured, 1)
invoice = store.invoices[order.invoice_id]
self.assertEqual(invoice.supplier_id, "printer")
self.assertEqual(invoice.dollars, 8)
self.assertEqual(invoice.status, "payable")
self.assertEqual(store.ledger.balance("cursorMan")["spendable"], 0)
self.assertNotIn("printer", store.ledger.accounts)
def test_stock_fulfills_without_an_invoice(self):
store = new_store()
store.receive_stock("coffer-shirt", 2)
self.assertEqual(len(store.invoices), 1)
store.ledger.top_up("buyer", 40)
order = store.place_order("buyer", "coffer-shirt", 2)
self.assertEqual(order.status, "fulfilled")
self.assertEqual(order.from_stock, 2)
self.assertIsNone(order.invoice_id)
self.assertEqual(store.goods["coffer-shirt"].stock, 0)
def test_mixed_stock_and_procurement(self):
store = new_store()
store.goods["coffer-shirt"].stock = 1
store.ledger.top_up("buyer", 60)
order = store.place_order("buyer", "coffer-shirt", 3)
self.assertEqual(order.from_stock, 1)
self.assertEqual(order.procured, 2)
self.assertEqual(store.invoices[order.invoice_id].dollars, 16)
self.assertEqual(order.status, "procuring")
def test_failed_spend_does_not_take_stock(self):
store = new_store()
store.goods["coffer-shirt"].stock = 1
with self.assertRaises(InsufficientCredit):
store.place_order("buyer", "coffer-shirt")
self.assertEqual(store.goods["coffer-shirt"].stock, 1)
self.assertEqual(store.orders, {})
def test_unknown_good_and_no_supplier(self):
store = Store()
store.add_good("own-note", "Note", 5)
store.ledger.top_up("buyer", 5)
with self.assertRaises(UnknownGood):
store.place_order("buyer", "missing")
with self.assertRaises(CannotSupply):
store.place_order("buyer", "own-note", 1)
self.assertEqual(store.ledger.balance("buyer")["spendable"], 5)
def test_idempotency_key_returns_the_same_order(self):
store = new_store()
store.ledger.top_up("buyer", 40)
first = store.place_order("buyer", "coffer-shirt", idempotency_key="k1")
second = store.place_order("buyer", "coffer-shirt", idempotency_key="k1")
self.assertEqual(first.order_id, second.order_id)
self.assertEqual(store.ledger.balance("buyer")["spendable"], 20)
def test_coffer_price_is_not_the_supplier_cost(self):
store = new_store()
good = store.goods["coffer-shirt"]
self.assertEqual(good.credit_price, 20)
self.assertEqual(good.supplier_unit_cost, 8)
if __name__ == "__main__":
unittest.main()