fix: Make transactions atomic / AutoLogout
This commit is contained in:
+171
-101
@@ -26,27 +26,31 @@ void main() {
|
||||
});
|
||||
|
||||
test('returns only active products', () async {
|
||||
await database.into(database.products).insert(
|
||||
ProductsCompanion.insert(
|
||||
id: '1',
|
||||
name: 'Active Product',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 10,
|
||||
lowStockThreshold: 2,
|
||||
priceInCents: 500,
|
||||
),
|
||||
);
|
||||
await database.into(database.products).insert(
|
||||
ProductsCompanion.insert(
|
||||
id: '2',
|
||||
name: 'Inactive Product',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 5,
|
||||
lowStockThreshold: 1,
|
||||
priceInCents: 300,
|
||||
active: const Value(false),
|
||||
),
|
||||
);
|
||||
await database
|
||||
.into(database.products)
|
||||
.insert(
|
||||
ProductsCompanion.insert(
|
||||
id: '1',
|
||||
name: 'Active Product',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 10,
|
||||
lowStockThreshold: 2,
|
||||
priceInCents: 500,
|
||||
),
|
||||
);
|
||||
await database
|
||||
.into(database.products)
|
||||
.insert(
|
||||
ProductsCompanion.insert(
|
||||
id: '2',
|
||||
name: 'Inactive Product',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 5,
|
||||
lowStockThreshold: 1,
|
||||
priceInCents: 300,
|
||||
active: const Value(false),
|
||||
),
|
||||
);
|
||||
|
||||
final products = await service.getProducts();
|
||||
|
||||
@@ -55,26 +59,30 @@ void main() {
|
||||
});
|
||||
|
||||
test('returns products sorted by name', () async {
|
||||
await database.into(database.products).insert(
|
||||
ProductsCompanion.insert(
|
||||
id: '1',
|
||||
name: 'Zebra',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 10,
|
||||
lowStockThreshold: 2,
|
||||
priceInCents: 500,
|
||||
),
|
||||
);
|
||||
await database.into(database.products).insert(
|
||||
ProductsCompanion.insert(
|
||||
id: '2',
|
||||
name: 'Apple',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 5,
|
||||
lowStockThreshold: 1,
|
||||
priceInCents: 300,
|
||||
),
|
||||
);
|
||||
await database
|
||||
.into(database.products)
|
||||
.insert(
|
||||
ProductsCompanion.insert(
|
||||
id: '1',
|
||||
name: 'Zebra',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 10,
|
||||
lowStockThreshold: 2,
|
||||
priceInCents: 500,
|
||||
),
|
||||
);
|
||||
await database
|
||||
.into(database.products)
|
||||
.insert(
|
||||
ProductsCompanion.insert(
|
||||
id: '2',
|
||||
name: 'Apple',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 5,
|
||||
lowStockThreshold: 1,
|
||||
priceInCents: 300,
|
||||
),
|
||||
);
|
||||
|
||||
final products = await service.getProducts();
|
||||
|
||||
@@ -85,16 +93,18 @@ void main() {
|
||||
|
||||
group('getProductById', () {
|
||||
test('returns product when exists', () async {
|
||||
await database.into(database.products).insert(
|
||||
ProductsCompanion.insert(
|
||||
id: 'prod-123',
|
||||
name: 'Test Product',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 10,
|
||||
lowStockThreshold: 2,
|
||||
priceInCents: 500,
|
||||
),
|
||||
);
|
||||
await database
|
||||
.into(database.products)
|
||||
.insert(
|
||||
ProductsCompanion.insert(
|
||||
id: 'prod-123',
|
||||
name: 'Test Product',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 10,
|
||||
lowStockThreshold: 2,
|
||||
priceInCents: 500,
|
||||
),
|
||||
);
|
||||
|
||||
final product = await service.getProductById('prod-123');
|
||||
|
||||
@@ -128,16 +138,18 @@ void main() {
|
||||
|
||||
group('updateProduct', () {
|
||||
test('updates product fields', () async {
|
||||
await database.into(database.products).insert(
|
||||
ProductsCompanion.insert(
|
||||
id: 'update-test',
|
||||
name: 'Original',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 10,
|
||||
lowStockThreshold: 2,
|
||||
priceInCents: 500,
|
||||
),
|
||||
);
|
||||
await database
|
||||
.into(database.products)
|
||||
.insert(
|
||||
ProductsCompanion.insert(
|
||||
id: 'update-test',
|
||||
name: 'Original',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 10,
|
||||
lowStockThreshold: 2,
|
||||
priceInCents: 500,
|
||||
),
|
||||
);
|
||||
|
||||
await service.updateProduct(
|
||||
const Product(
|
||||
@@ -160,16 +172,18 @@ void main() {
|
||||
|
||||
group('deleteProduct', () {
|
||||
test('removes product from database', () async {
|
||||
await database.into(database.products).insert(
|
||||
ProductsCompanion.insert(
|
||||
id: 'delete-test',
|
||||
name: 'To Delete',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 10,
|
||||
lowStockThreshold: 2,
|
||||
priceInCents: 500,
|
||||
),
|
||||
);
|
||||
await database
|
||||
.into(database.products)
|
||||
.insert(
|
||||
ProductsCompanion.insert(
|
||||
id: 'delete-test',
|
||||
name: 'To Delete',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 10,
|
||||
lowStockThreshold: 2,
|
||||
priceInCents: 500,
|
||||
),
|
||||
);
|
||||
|
||||
await service.deleteProduct('delete-test');
|
||||
|
||||
@@ -180,16 +194,18 @@ void main() {
|
||||
|
||||
group('decreaseStock', () {
|
||||
test('decreases stock quantity', () async {
|
||||
await database.into(database.products).insert(
|
||||
ProductsCompanion.insert(
|
||||
id: 'stock-test',
|
||||
name: 'Stock Test',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 10,
|
||||
lowStockThreshold: 2,
|
||||
priceInCents: 500,
|
||||
),
|
||||
);
|
||||
await database
|
||||
.into(database.products)
|
||||
.insert(
|
||||
ProductsCompanion.insert(
|
||||
id: 'stock-test',
|
||||
name: 'Stock Test',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 10,
|
||||
lowStockThreshold: 2,
|
||||
priceInCents: 500,
|
||||
),
|
||||
);
|
||||
|
||||
await service.decreaseStock('stock-test', 3);
|
||||
|
||||
@@ -205,16 +221,18 @@ void main() {
|
||||
});
|
||||
|
||||
test('throws when not enough stock', () async {
|
||||
await database.into(database.products).insert(
|
||||
ProductsCompanion.insert(
|
||||
id: 'low-stock',
|
||||
name: 'Low Stock',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 3,
|
||||
lowStockThreshold: 1,
|
||||
priceInCents: 500,
|
||||
),
|
||||
);
|
||||
await database
|
||||
.into(database.products)
|
||||
.insert(
|
||||
ProductsCompanion.insert(
|
||||
id: 'low-stock',
|
||||
name: 'Low Stock',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 3,
|
||||
lowStockThreshold: 1,
|
||||
priceInCents: 500,
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
() => service.decreaseStock('low-stock', 5),
|
||||
@@ -225,16 +243,18 @@ void main() {
|
||||
|
||||
group('increaseStock', () {
|
||||
test('increases stock quantity', () async {
|
||||
await database.into(database.products).insert(
|
||||
ProductsCompanion.insert(
|
||||
id: 'increase-test',
|
||||
name: 'Increase Test',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 10,
|
||||
lowStockThreshold: 2,
|
||||
priceInCents: 500,
|
||||
),
|
||||
);
|
||||
await database
|
||||
.into(database.products)
|
||||
.insert(
|
||||
ProductsCompanion.insert(
|
||||
id: 'increase-test',
|
||||
name: 'Increase Test',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 10,
|
||||
lowStockThreshold: 2,
|
||||
priceInCents: 500,
|
||||
),
|
||||
);
|
||||
|
||||
await service.increaseStock('increase-test', 5);
|
||||
|
||||
@@ -248,6 +268,56 @@ void main() {
|
||||
throwsA(isA<Exception>()),
|
||||
);
|
||||
});
|
||||
|
||||
test('rejects non-positive stock adjustments', () async {
|
||||
await database
|
||||
.into(database.products)
|
||||
.insert(
|
||||
ProductsCompanion.insert(
|
||||
id: 'invalid-adjustment',
|
||||
name: 'Invalid Adjustment',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 10,
|
||||
lowStockThreshold: 2,
|
||||
priceInCents: 500,
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
() => service.decreaseStock('invalid-adjustment', 0),
|
||||
throwsA(isA<ArgumentError>()),
|
||||
);
|
||||
expect(
|
||||
() => service.increaseStock('invalid-adjustment', -1),
|
||||
throwsA(isA<ArgumentError>()),
|
||||
);
|
||||
});
|
||||
|
||||
test('does not allow concurrent decrements below zero', () async {
|
||||
await database
|
||||
.into(database.products)
|
||||
.insert(
|
||||
ProductsCompanion.insert(
|
||||
id: 'concurrent-stock',
|
||||
name: 'Concurrent Stock',
|
||||
category: 'Drinks',
|
||||
stockQuantity: 1,
|
||||
lowStockThreshold: 0,
|
||||
priceInCents: 500,
|
||||
),
|
||||
);
|
||||
|
||||
await expectLater(
|
||||
Future.wait([
|
||||
service.decreaseStock('concurrent-stock', 1),
|
||||
service.decreaseStock('concurrent-stock', 1),
|
||||
]),
|
||||
throwsA(isA<InsufficientStockException>()),
|
||||
);
|
||||
|
||||
final product = await service.getProductById('concurrent-stock');
|
||||
expect(product!.stockQuantity, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user