def test_for_new_product(self): uow = FakeUnitOfWork() messagebus.handle( commands.CreateBatch("b1", "CRUNCHY-ARMCHAIR", 100, None), uow ) assert uow.products.get("CRUNCHY-ARMCHAIR") is not None assert uow.committed
def test_allocates(self): uow = FakeUnitOfWork() messagebus.handle( commands.CreateBatch("batch1", "COMPLICATED-LAMP", 100, None), uow) messagebus.handle(commands.Allocate("o1", "COMPLICATED-LAMP", 10), uow) [batch] = uow.products.get("COMPLICATED-LAMP").batches assert batch.available_quantity == 90
def test_errors_for_invalid_sku(self): uow = FakeUnitOfWork() messagebus.handle(commands.CreateBatch("b1", "AREALSKU", 100, None), uow) with pytest.raises(handlers.InvalidSku, match="Invalid sku NONEXISTENTSKU"): messagebus.handle( commands.Allocate("o1", "NONEXISTENTSKU", 10), uow )
def test_commits(self): uow = FakeUnitOfWork() messagebus.handle( commands.CreateBatch("b1", "OMINOUS-MIRROR", 100, None), uow ) messagebus.handle( commands.Allocate("o1", "OMINOUS-MIRROR", 10), uow ) assert uow.committed
def test_sends_email_on_out_of_stock_error(self): uow = FakeUnitOfWork() messagebus.handle( commands.CreateBatch("b1", "POPULAR-CURTAINS", 9, None), uow) with mock.patch("allocation.adapters.email.send") as mock_send_mail: messagebus.handle(commands.Allocate("o1", "POPULAR-CURTAINS", 10), uow) assert mock_send_mail.call_args == mock.call( "*****@*****.**", f"Out of stock for POPULAR-CURTAINS")
def test_for_existing_product(self): uow = FakeUnitOfWork() messagebus.handle(commands.CreateBatch("b1", "GARISH-RUG", 100, None), uow) messagebus.handle(commands.CreateBatch("b2", "GARISH-RUG", 99, None), uow) assert "b2" in [ b.reference for b in uow.products.get("GARISH-RUG").batches ]
def test_changes_available_quantity(self): uow = FakeUnitOfWork() messagebus.handle( commands.CreateBatch("batch1", "ADORABLE-SETTEE", 100, None), uow) [batch] = uow.products.get(sku="ADORABLE-SETTEE").batches assert batch.available_quantity == 100 messagebus.handle(commands.ChangeBatchQuantity("batch1", 50), uow) assert batch.available_quantity == 50
def allocate_endpoint(): try: cmd = commands.Allocate( request.json["orderid"], request.json["sku"], request.json["qty"], ) uow = unit_of_work.SqlAlchemyUnitOfWork() messagebus.handle(cmd, uow) except InvalidSku as e: return jsonify({"message": str(e)}), 400 return "OK", 202
def add_batch(): eta = request.json['eta'] if eta is not None: eta = datetime.fromisoformat(eta).date() cmd = commands.CreateBatch( request.json['ref'], request.json['sku'], request.json['qty'], eta, ) uow = unit_of_work.SqlAlchemyUnitOfWork() messagebus.handle(cmd, uow) return 'OK', 201
def add_batch(): eta = request.json["eta"] if eta is not None: eta = datetime.fromisoformat(eta).date() cmd = commands.CreateBatch( request.json["ref"], request.json["sku"], request.json["qty"], eta, ) uow = unit_of_work.SqlAlchemyUnitOfWork() messagebus.handle(cmd, uow) return "OK", 201
def test_deallocation(sqlite_session_factory): uow = unit_of_work.SqlAlchemyUnitOfWork(sqlite_session_factory) messagebus.handle(commands.CreateBatch("b1", "sku1", 50, None), uow) messagebus.handle(commands.CreateBatch("b2", "sku1", 50, today), uow) messagebus.handle(commands.Allocate("o1", "sku1", 40), uow) messagebus.handle(commands.ChangeBatchQuantity("b1", 10), uow) assert views.allocations("o1", uow) == [ {"sku": "sku1", "batchref": "b2"}, ]
def test_reallocates_if_necessary(self): uow = FakeUnitOfWork() history = [ commands.CreateBatch("batch1", "INDIFFERENT-TABLE", 50, None), commands.CreateBatch("batch2", "INDIFFERENT-TABLE", 50, date.today()), commands.Allocate("order1", "INDIFFERENT-TABLE", 20), commands.Allocate("order2", "INDIFFERENT-TABLE", 20), ] for msg in history: messagebus.handle(msg, uow) [batch1, batch2] = uow.products.get(sku="INDIFFERENT-TABLE").batches assert batch1.available_quantity == 10 assert batch2.available_quantity == 50 messagebus.handle(commands.ChangeBatchQuantity("batch1", 25), uow) # order1 or order2 will be deallocated, so we'll have 25 - 20 assert batch1.available_quantity == 5 # and 20 will be reallocated to the next batch assert batch2.available_quantity == 30
def test_deallocation(sqlite_session_factory): uow = unit_of_work.SqlAlchemyUnitOfWork(sqlite_session_factory) messagebus.handle(commands.CreateBatch('b1', 'sku1', 50, None), uow) messagebus.handle(commands.CreateBatch('b2', 'sku1', 50, today), uow) messagebus.handle(commands.Allocate('o1', 'sku1', 40), uow) messagebus.handle(commands.ChangeBatchQuantity('b1', 10), uow) assert views.allocations('o1', uow) == [ { 'sku': 'sku1', 'batchref': 'b2' }, ]
def allocate_endpoint(): try: cmd = commands.Allocate( request.json['orderid'], request.json['sku'], request.json['qty'], ) uow = unit_of_work.SqlAlchemyUnitOfWork() results = messagebus.handle(cmd, uow) batchref = results.pop(0) except InvalidSku as e: return jsonify({'message': str(e)}), 400 return jsonify({'batchref': batchref}), 201
def test_allocations_view(sqlite_session_factory): uow = unit_of_work.SqlAlchemyUnitOfWork(sqlite_session_factory) messagebus.handle(commands.CreateBatch('sku1batch', 'sku1', 50, None), uow) messagebus.handle(commands.CreateBatch('sku2batch', 'sku2', 50, today), uow) messagebus.handle(commands.Allocate('order1', 'sku1', 20), uow) messagebus.handle(commands.Allocate('order1', 'sku2', 20), uow) assert views.allocations('order1', uow) == [ { 'sku': 'sku1', 'batchref': 'sku1batch' }, { 'sku': 'sku2', 'batchref': 'sku2batch' }, ]
def test_allocations_view(sqlite_session_factory): uow = unit_of_work.SqlAlchemyUnitOfWork(sqlite_session_factory) messagebus.handle(commands.CreateBatch('sku1batch', 'sku1', 50, None), uow) messagebus.handle(commands.CreateBatch('sku2batch', 'sku2', 50, today), uow) messagebus.handle(commands.Allocate('order1', 'sku1', 20), uow) messagebus.handle(commands.Allocate('order1', 'sku2', 20), uow) # add a spurious batch and order to make sure we're getting the right ones messagebus.handle( commands.CreateBatch('sku1batch-later', 'sku1', 50, today), uow) messagebus.handle(commands.Allocate('otherorder', 'sku1', 30), uow) messagebus.handle(commands.Allocate('otherorder', 'sku2', 10), uow) assert views.allocations('order1', uow) == [ { 'sku': 'sku1', 'batchref': 'sku1batch' }, { 'sku': 'sku2', 'batchref': 'sku2batch' }, ]
def handle_change_batch_quantity(m): logging.debug("handling %s", m) data = json.loads(m["data"]) cmd = commands.ChangeBatchQuantity(ref=data["batchref"], qty=data["qty"]) messagebus.handle(cmd, uow=unit_of_work.SqlAlchemyUnitOfWork())
def handle_change_batch_quantity(m): logging.debug('handling %s', m) data = json.loads(m['data']) cmd = commands.ChangeBatchQuantity(ref=data['batchref'], qty=data['qty']) messagebus.handle(cmd, uow=unit_of_work.SqlAlchemyUnitOfWork())
def test_allocations_view(sqlite_session_factory): uow = unit_of_work.SqlAlchemyUnitOfWork(sqlite_session_factory) messagebus.handle(commands.CreateBatch("sku1batch", "sku1", 50, None), uow) messagebus.handle(commands.CreateBatch("sku2batch", "sku2", 50, today), uow) messagebus.handle(commands.Allocate("order1", "sku1", 20), uow) messagebus.handle(commands.Allocate("order1", "sku2", 20), uow) # add a spurious batch and order to make sure we're getting the right ones messagebus.handle(commands.CreateBatch("sku1batch-later", "sku1", 50, today), uow) messagebus.handle(commands.Allocate("otherorder", "sku1", 30), uow) messagebus.handle(commands.Allocate("otherorder", "sku2", 10), uow) assert views.allocations("order1", uow) == [ {"sku": "sku1", "batchref": "sku1batch"}, {"sku": "sku2", "batchref": "sku2batch"}, ]