feat: make server owner of tabs
This commit is contained in:
+34
-68
@@ -249,27 +249,24 @@ void main() {
|
||||
final tabId = tabIds[random.nextInt(tabIds.length)];
|
||||
final product = random.nextBool() ? _beer : _wine;
|
||||
|
||||
try {
|
||||
switch (random.nextInt(10)) {
|
||||
case < 6:
|
||||
await tabs.addProductToTab(tabId: tabId, product: product);
|
||||
case < 8:
|
||||
final tab = (await tabs.getTabById(tabId))!;
|
||||
if (tab.items.isEmpty) continue;
|
||||
final item = tab.items[random.nextInt(tab.items.length)];
|
||||
await tabs.adjustTabItemQuantity(
|
||||
tabItemId: item.id,
|
||||
delta: random.nextInt(5) - 2,
|
||||
);
|
||||
case 8:
|
||||
await tabs.closeTab(tabId);
|
||||
default:
|
||||
await tabs.deleteTab(tabId);
|
||||
tabIds.remove(tabId);
|
||||
tabIds.add((await tabs.createTab(customerName: 'New')).id);
|
||||
}
|
||||
} on InsufficientStockException {
|
||||
// Running out is part of the scenario.
|
||||
// Running out is part of the scenario: the stock goes negative
|
||||
switch (random.nextInt(10)) {
|
||||
case < 6:
|
||||
await tabs.addProductToTab(tabId: tabId, product: product);
|
||||
case < 8:
|
||||
final tab = (await tabs.getTabById(tabId))!;
|
||||
if (tab.items.isEmpty) continue;
|
||||
final item = tab.items[random.nextInt(tab.items.length)];
|
||||
await tabs.adjustTabItemQuantity(
|
||||
tabItemId: item.id,
|
||||
delta: random.nextInt(5) - 2,
|
||||
);
|
||||
case 8:
|
||||
await tabs.closeTab(tabId);
|
||||
default:
|
||||
await tabs.deleteTab(tabId);
|
||||
tabIds.remove(tabId);
|
||||
tabIds.add((await tabs.createTab(customerName: 'New')).id);
|
||||
}
|
||||
|
||||
for (final product in [_beer, _wine]) {
|
||||
@@ -278,65 +275,48 @@ void main() {
|
||||
await quantityOnOpenTabs(product.id) +
|
||||
await soldInHistory(product.id);
|
||||
expect(accounted, product.stockQuantity, reason: 'step $step');
|
||||
expect(await stockOf(product.id), greaterThanOrEqualTo(0));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('can never sell more than is in stock', () async {
|
||||
test('keeps selling when the stock runs out', () async {
|
||||
final tab = await tabs.createTab(customerName: 'John');
|
||||
var sold = 0;
|
||||
|
||||
for (var i = 0; i < _wine.stockQuantity + 5; i++) {
|
||||
try {
|
||||
await tabs.addProductToTab(tabId: tab.id, product: _wine);
|
||||
sold++;
|
||||
} on InsufficientStockException {
|
||||
// Expected once the wine runs out.
|
||||
}
|
||||
await tabs.addProductToTab(tabId: tab.id, product: _wine);
|
||||
}
|
||||
|
||||
expect(sold, _wine.stockQuantity);
|
||||
expect(await stockOf('wine'), 0);
|
||||
expect((await tabs.getTabById(tab.id))!.totalInCents, 20 * 450);
|
||||
expect(await stockOf('wine'), -5);
|
||||
expect((await tabs.getTabById(tab.id))!.totalInCents, 25 * 450);
|
||||
});
|
||||
|
||||
test('simultaneous orders for the last bottle sell it once', () async {
|
||||
test('simultaneous orders for the last bottle both go through', () async {
|
||||
await products.updateProduct(_wine.copyWith(stockQuantity: 1));
|
||||
final first = await tabs.createTab(customerName: 'A');
|
||||
final second = await tabs.createTab(customerName: 'B');
|
||||
|
||||
final results = await Future.wait([
|
||||
await Future.wait([
|
||||
for (final tab in [first, second])
|
||||
tabs
|
||||
.addProductToTab(tabId: tab.id, product: _wine)
|
||||
.then((_) => true)
|
||||
.catchError(
|
||||
(_) => false,
|
||||
test: (e) => e is InsufficientStockException,
|
||||
),
|
||||
tabs.addProductToTab(tabId: tab.id, product: _wine),
|
||||
]);
|
||||
|
||||
expect(results.where((ok) => ok), hasLength(1));
|
||||
expect(await stockOf('wine'), 0);
|
||||
expect(await quantityOnOpenTabs('wine'), 1);
|
||||
expect(await stockOf('wine'), -1);
|
||||
expect(await quantityOnOpenTabs('wine'), 2);
|
||||
});
|
||||
|
||||
test('raising a quantity past the stock adds nothing', () async {
|
||||
test('raising a quantity past the stock goes below zero', () async {
|
||||
await products.updateProduct(_wine.copyWith(stockQuantity: 2));
|
||||
final tab = await tabs.createTab(customerName: 'John');
|
||||
await tabs.addProductToTab(tabId: tab.id, product: _wine);
|
||||
|
||||
await expectLater(
|
||||
tabs.adjustTabItemQuantity(
|
||||
tabItemId: await itemId(tab.id, 'wine'),
|
||||
delta: 5,
|
||||
),
|
||||
throwsA(isA<InsufficientStockException>()),
|
||||
final applied = await tabs.adjustTabItemQuantity(
|
||||
tabItemId: await itemId(tab.id, 'wine'),
|
||||
delta: 5,
|
||||
);
|
||||
|
||||
expect(await stockOf('wine'), 1);
|
||||
expect((await tabs.getTabById(tab.id))!.items.single.quantity, 1);
|
||||
expect(applied, 5);
|
||||
expect(await stockOf('wine'), -4);
|
||||
expect((await tabs.getTabById(tab.id))!.items.single.quantity, 6);
|
||||
});
|
||||
|
||||
test('lowering past zero only returns what was on the tab', () async {
|
||||
@@ -372,19 +352,5 @@ void main() {
|
||||
|
||||
expect(await stockOf('water'), 0);
|
||||
});
|
||||
|
||||
test('a failed add leaves no item behind', () async {
|
||||
await products.updateProduct(_wine.copyWith(stockQuantity: 0));
|
||||
final tab = await tabs.createTab(customerName: 'John');
|
||||
|
||||
await expectLater(
|
||||
tabs.addProductToTab(tabId: tab.id, product: _wine),
|
||||
throwsA(isA<InsufficientStockException>()),
|
||||
);
|
||||
|
||||
final open = (await tabs.getTabById(tab.id))!;
|
||||
expect(open.items, isEmpty);
|
||||
expect(open.totalInCents, 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user