254 lines
7.0 KiB
Dart
254 lines
7.0 KiB
Dart
import 'package:drift/drift.dart' hide isNull, isNotNull;
|
|
import 'package:drift/native.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:kooltab2/database/app_database.dart';
|
|
import 'package:kooltab2/models/product.dart';
|
|
import 'package:kooltab2/services/product_service.dart';
|
|
|
|
void main() {
|
|
late AppDatabase database;
|
|
late DriftProductService service;
|
|
|
|
setUp(() {
|
|
database = AppDatabase(NativeDatabase.memory());
|
|
service = DriftProductService(database: database);
|
|
});
|
|
|
|
tearDown(() async {
|
|
await database.close();
|
|
});
|
|
|
|
group('DriftProductService', () {
|
|
group('getProducts', () {
|
|
test('returns empty list when no products', () async {
|
|
final products = await service.getProducts();
|
|
expect(products, isEmpty);
|
|
});
|
|
|
|
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),
|
|
),
|
|
);
|
|
|
|
final products = await service.getProducts();
|
|
|
|
expect(products.length, 1);
|
|
expect(products.first.name, 'Active Product');
|
|
});
|
|
|
|
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,
|
|
),
|
|
);
|
|
|
|
final products = await service.getProducts();
|
|
|
|
expect(products.first.name, 'Apple');
|
|
expect(products.last.name, 'Zebra');
|
|
});
|
|
});
|
|
|
|
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,
|
|
),
|
|
);
|
|
|
|
final product = await service.getProductById('prod-123');
|
|
|
|
expect(product, isNotNull);
|
|
expect(product!.name, 'Test Product');
|
|
});
|
|
|
|
test('returns null when not exists', () async {
|
|
final product = await service.getProductById('nonexistent');
|
|
expect(product, isNull);
|
|
});
|
|
});
|
|
|
|
group('createProduct', () {
|
|
test('creates product successfully', () async {
|
|
await service.createProduct(
|
|
name: 'New Product',
|
|
category: 'Food',
|
|
stockQuantity: 20,
|
|
lowStockThreshold: 5,
|
|
priceInCents: 850,
|
|
imagePath: null,
|
|
);
|
|
|
|
final products = await service.getProducts();
|
|
expect(products.length, 1);
|
|
expect(products.first.name, 'New Product');
|
|
expect(products.first.stockQuantity, 20);
|
|
});
|
|
});
|
|
|
|
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 service.updateProduct(
|
|
const Product(
|
|
id: 'update-test',
|
|
name: 'Updated',
|
|
category: 'Food',
|
|
stockQuantity: 15,
|
|
lowStockThreshold: 3,
|
|
priceInCents: 750,
|
|
active: true,
|
|
),
|
|
);
|
|
|
|
final product = await service.getProductById('update-test');
|
|
expect(product!.name, 'Updated');
|
|
expect(product.stockQuantity, 15);
|
|
expect(product.priceInCents, 750);
|
|
});
|
|
});
|
|
|
|
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 service.deleteProduct('delete-test');
|
|
|
|
final products = await database.select(database.products).get();
|
|
expect(products, isEmpty);
|
|
});
|
|
});
|
|
|
|
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 service.decreaseStock('stock-test', 3);
|
|
|
|
final product = await service.getProductById('stock-test');
|
|
expect(product!.stockQuantity, 7);
|
|
});
|
|
|
|
test('throws when product not found', () async {
|
|
expect(
|
|
() => service.decreaseStock('nonexistent', 1),
|
|
throwsA(isA<Exception>()),
|
|
);
|
|
});
|
|
|
|
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,
|
|
),
|
|
);
|
|
|
|
expect(
|
|
() => service.decreaseStock('low-stock', 5),
|
|
throwsA(isA<InsufficientStockException>()),
|
|
);
|
|
});
|
|
});
|
|
|
|
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 service.increaseStock('increase-test', 5);
|
|
|
|
final product = await service.getProductById('increase-test');
|
|
expect(product!.stockQuantity, 15);
|
|
});
|
|
|
|
test('throws when product not found', () async {
|
|
expect(
|
|
() => service.increaseStock('nonexistent', 1),
|
|
throwsA(isA<Exception>()),
|
|
);
|
|
});
|
|
});
|
|
});
|
|
}
|