import 'package:drift/native.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:kooltap/database/app_database.dart'; /// The parts of the v12 schema that the v13 migration touches. const _v12Schema = [ 'CREATE TABLE bar_tabs (id TEXT NOT NULL, customer_name TEXT NOT NULL, ' "status TEXT NOT NULL DEFAULT 'open', opened_at INTEGER NOT NULL, " 'closed_at INTEGER NULL, version INTEGER NOT NULL DEFAULT 0, ' 'PRIMARY KEY (id))', 'CREATE TABLE tab_items (id TEXT NOT NULL, tab_id TEXT NOT NULL, ' 'product_id TEXT NOT NULL, product_name TEXT NOT NULL, ' 'quantity INTEGER NOT NULL, unit_price_in_cents INTEGER NOT NULL, ' 'created_at INTEGER NOT NULL, PRIMARY KEY (id))', 'CREATE TABLE tab_item_purchases (id TEXT NOT NULL, ' 'tab_item_id TEXT NOT NULL, purchased_at INTEGER NOT NULL, ' 'removed_at INTEGER NULL, PRIMARY KEY (id))', "INSERT INTO bar_tabs VALUES ('tab-1', 'Alice', 'open', 1700000000, NULL, 4)", "INSERT INTO tab_items VALUES ('item-1', 'tab-1', 'prod-1', 'Beer', 3, 400, " '1700000100)', "INSERT INTO tab_item_purchases VALUES ('p-1', 'item-1', 1700000200, NULL)", "INSERT INTO tab_item_purchases VALUES ('p-2', 'item-1', 1700000300, " '1700000400)', "INSERT INTO tab_item_purchases VALUES ('orphan', 'gone', 1700000500, NULL)", 'PRAGMA user_version = 12', ]; void main() { late AppDatabase database; setUp(() { database = AppDatabase( NativeDatabase.memory( setup: (rawDatabase) { for (final statement in _v12Schema) { rawDatabase.execute(statement); } }, ), ); }); tearDown(() async { await database.close(); }); test('drops the unused status columns and keeps the tab', () async { final tabs = await database.select(database.barTabs).get(); expect(tabs.single.customerName, 'Alice'); expect(tabs.single.version, 4); final columns = await database .customSelect('PRAGMA table_info(bar_tabs)') .map((row) => row.read('name')) .get(); expect(columns, isNot(contains('status'))); expect(columns, isNot(contains('closed_at'))); }); test('backfills missing purchases up to the item quantity', () async { final purchases = await (database.select( database.tabItemPurchases, )..where((row) => row.tabItemId.equals('item-1'))).get(); final active = purchases.where((row) => row.removedAt == null); expect(active, hasLength(3)); expect(purchases.where((row) => row.removedAt != null), hasLength(1)); }); test('deletes purchases whose item no longer exists', () async { final orphan = await (database.select( database.tabItemPurchases, )..where((row) => row.id.equals('orphan'))).getSingleOrNull(); expect(orphan, isNull); }); }