async def test(): # start with two batches and an order allocated to one of them orderid, sku = random_orderid(), random_sku() earlier_batch, later_batch = random_batchref(1), random_batchref(2) await api_client.post_to_add_batch(earlier_batch, sku, qty=10, eta=datetime(2021, 4, 26).isoformat()) await api_client.post_to_add_batch(later_batch, sku, qty=10, eta=datetime(2021, 4, 27).isoformat()) response = await api_client.post_to_allocate(orderid, sku, 10) assert response.json()["batchref"] == earlier_batch await redis_client.publish_message(commands.ChangeBatchQuantity, { "batchref": earlier_batch, "qty": 5 }) await redis_client.subscribe_to(events.Allocated) channel = redis_client.channels[-1] async for msg in channel.iter(encoding="utf8"): data = json.loads(msg) assert data["orderid"] == orderid assert data["batchref"] == later_batch break
def test_rolls_back_uncommitted_work_by_default(get_session, cleanup_uow): ref, sku = random_batchref(), random_sku() uow = cleanup_uow(sku, ref) with uow: insert_product(uow.session, sku) insert_batch(uow.session, ref, sku, 100, None) # Commit 을 안한 경우 실제 DB에 데이터가 반영되지 않습니다. new_session = get_session() rows = list(new_session.execute("SELECT * FROM batch WHERE sku=:sku", {"sku": sku})) assert [] == rows, f"{rows}"
def test_rolls_back_committed(get_session, cleanup_uow): ref, sku = random_batchref(), random_sku() uow = cleanup_uow(sku, ref) with uow: insert_product(uow.session, sku) insert_batch(uow.session, ref, sku, 100, None) uow.session.commit() # commit 을 하면 DB 상태가 변경되어야 합니다. new_session = get_session() [ref_got] = next( new_session.execute("SELECT reference FROM batch WHERE sku=:sku", {"sku": sku}) ) assert ref == ref_got, f"{ref} != {ref_got}"
def test_rolls_back_on_error(get_session, cleanup_uow): class MyException(Exception): pass ref, sku = random_batchref(), random_sku() uow = cleanup_uow(sku, ref) with pytest.raises(MyException): with uow: insert_product(uow.session, sku) insert_batch(uow.session, ref, sku, 100, None) raise MyException() uow.commit() new_session = get_session() rows = list(new_session.execute("SELECT * FROM batch WHERE sku=:sku", {"sku": sku})) assert rows == []
def test_uow_can_retrieve_a_batch_and_allocate_to_it( get_session: SessionMaker, session_with_product: Any, ): ref, sku = random_batchref(), random_sku() session = session_with_product(ref, sku, 100, None) uow = SqlAlchemyUnitOfWork([Product], get_session) with uow: product = uow[Product].get(sku) if product: line = OrderLine("o1", sku, 10) product.allocate(line) uow.commit() ref_got = get_allocated_batch_ref(session, "o1", sku) assert ref == ref_got
def insert_batch(session: Session, ref: str = "", sku: str = "") -> int: if not ref: ref = random_batchref() if not sku: sku = random_sku() session.execute( "INSERT INTO batch (reference, sku, _purchased_quantity, eta)" " VALUES (:ref, :sku, 100, null)", dict(ref=ref, sku=sku), ) [[batch_id]] = session.execute( "SELECT id FROM batch WHERE reference=:ref AND sku=:sku", dict(ref=ref, sku=sku)) return cast(int, batch_id)
def setup_batches(cnt_batches): return [random_batchref(i) for i in range(cnt_batches)]