def test_errors_for_invalid_sku(self): bus = bootstrap_test_app() bus.handle(commands.CreateBatch("b1", "AREALSKU", 100, None)) with pytest.raises(handlers.InvalidSku, match="Invalid sku NONEXISTENTSKU"): bus.handle(commands.Allocate("o1", "NONEXISTENTSKU", 10))
def test_allocates(self): bus = bootstrap_test_app() bus.handle( commands.CreateBatch("batch1", "COMPLICATED-LAMP", 100, None)) bus.handle(commands.Allocate("o1", "COMPLICATED-LAMP", 10)) [batch] = bus.uow.products.get("COMPLICATED-LAMP").batches assert batch.available_quantity == 90
def test_out_of_stock_email(bus): sku = random_sku() bus.handle(commands.CreateBatch('batch1', sku, 9, None)) bus.handle(commands.Allocate('order1', sku, 10)) email = get_email_from_mailhog(sku) assert email['Raw']['From'] == '*****@*****.**' assert email['Raw']['To'] == ['*****@*****.**'] assert f'Out of stock for {sku}' in email['Raw']['Data']
def allocate_endpoint(): try: cmd = commands.Allocate( request.json['orderid'], request.json['sku'], request.json['qty'], ) bus.handle(cmd) except InvalidSku as e: return jsonify({'message': str(e)}), 400 return 'OK', 202
def test_deallocation(sqlite_bus): sqlite_bus.handle(commands.CreateBatch('b1', 'sku1', 50, None)) sqlite_bus.handle(commands.CreateBatch('b2', 'sku1', 50, today)) sqlite_bus.handle(commands.Allocate('o1', 'sku1', 40)) sqlite_bus.handle(commands.ChangeBatchQuantity('b1', 10)) assert views.allocations('o1', sqlite_bus.uow) == [ { 'sku': 'sku1', 'batchref': 'b2' }, ]
def test_allocations_view(sqlite_bus): sqlite_bus.handle(commands.CreateBatch('sku1batch', 'sku1', 50, None)) sqlite_bus.handle(commands.CreateBatch('sku2batch', 'sku2', 50, today)) sqlite_bus.handle(commands.Allocate('order1', 'sku1', 20)) sqlite_bus.handle(commands.Allocate('order1', 'sku2', 20)) # add a spurious batch and order to make sure we're getting the right ones sqlite_bus.handle( commands.CreateBatch('sku1batch-later', 'sku1', 50, today)) sqlite_bus.handle(commands.Allocate('otherorder', 'sku1', 30)) sqlite_bus.handle(commands.Allocate('otherorder', 'sku2', 10)) assert views.allocations('order1', sqlite_bus.uow) == [ { 'sku': 'sku1', 'batchref': 'sku1batch' }, { 'sku': 'sku2', 'batchref': 'sku2batch' }, ]
def test_sends_email_on_out_of_stock_error(self): fake_notifs = FakeNotifications() bus = bootstrap.bootstrap( start_orm=False, uow=FakeUnitOfWork(), notifications=fake_notifs, publish=lambda *args: None, ) bus.handle(commands.CreateBatch("b1", "POPULAR-CURTAINS", 9, None)) bus.handle(commands.Allocate("o1", "POPULAR-CURTAINS", 10)) assert fake_notifs.sent['*****@*****.**'] == [ f"Out of stock for POPULAR-CURTAINS", ]
def test_reallocates_if_necessary(self): bus = bootstrap_test_app() 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: bus.handle(msg) [batch1, batch2] = bus.uow.products.get(sku="INDIFFERENT-TABLE").batches assert batch1.available_quantity == 10 assert batch2.available_quantity == 50 bus.handle(commands.ChangeBatchQuantity("batch1", 25)) # 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 reallocate( event: events.Deallocated, uow: unit_of_work.AbstractUnitOfWork ): allocate(commands.Allocate(**asdict(event)), uow=uow)
def test_commits(self): bus = bootstrap_test_app() bus.handle(commands.CreateBatch("b1", "OMINOUS-MIRROR", 100, None)) bus.handle(commands.Allocate("o1", "OMINOUS-MIRROR", 10)) assert bus.uow.committed