129 lines
3.8 KiB
Dart
129 lines
3.8 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:drift/native.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:http/testing.dart';
|
|
import 'package:kooltap/database/app_database.dart';
|
|
import 'package:kooltap/models/payment_method.dart';
|
|
import 'package:kooltap/models/product.dart';
|
|
import 'package:kooltap/services/bar_tab_service.dart';
|
|
import 'package:kooltap/services/export_service.dart';
|
|
import 'package:package_info_plus/package_info_plus.dart';
|
|
|
|
const _beer = Product(
|
|
id: 'beer',
|
|
name: 'Beer',
|
|
category: 'Drinks',
|
|
stockQuantity: 10,
|
|
lowStockThreshold: 2,
|
|
priceInCents: 250,
|
|
);
|
|
|
|
void main() {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
|
|
late AppDatabase database;
|
|
late DriftBarTabService tabs;
|
|
late List<http.Request> requests;
|
|
late http.Response Function() respond;
|
|
|
|
DefaultExportService exportService({String? token}) {
|
|
return DefaultExportService(
|
|
barTabService: tabs,
|
|
authToken: () async => token,
|
|
client: MockClient((request) async {
|
|
requests.add(request);
|
|
return respond();
|
|
}),
|
|
);
|
|
}
|
|
|
|
setUp(() async {
|
|
PackageInfo.setMockInitialValues(
|
|
appName: 'KoolTap',
|
|
packageName: 'com.kooltap',
|
|
version: '1.2.12',
|
|
buildNumber: '1',
|
|
buildSignature: '',
|
|
);
|
|
|
|
database = AppDatabase(NativeDatabase.memory());
|
|
tabs = DriftBarTabService(database: database);
|
|
requests = [];
|
|
respond = () => http.Response('', 201);
|
|
|
|
await database
|
|
.into(database.products)
|
|
.insert(
|
|
ProductsCompanion.insert(
|
|
id: _beer.id,
|
|
name: _beer.name,
|
|
category: _beer.category,
|
|
stockQuantity: _beer.stockQuantity,
|
|
lowStockThreshold: _beer.lowStockThreshold,
|
|
priceInCents: _beer.priceInCents,
|
|
),
|
|
);
|
|
});
|
|
|
|
tearDown(() async {
|
|
await database.close();
|
|
});
|
|
|
|
test('backs up the totals that were charged', () async {
|
|
final tab = await tabs.createTab(customerName: 'John');
|
|
for (var i = 0; i < 3; i++) {
|
|
await tabs.addProductToTab(tabId: tab.id, product: _beer);
|
|
}
|
|
final item = (await tabs.getTabById(tab.id))!.items.single;
|
|
await tabs.adjustTabItemQuantity(tabItemId: item.id, delta: -1);
|
|
await tabs.closeTab(tab.id, paymentMethod: PaymentMethod.payconiq);
|
|
|
|
await exportService().uploadToServer();
|
|
|
|
final body = jsonDecode(requests.single.body) as Map<String, dynamic>;
|
|
final closed = (body['closedTabs'] as List).single as Map<String, dynamic>;
|
|
final items = closed['items'] as List;
|
|
|
|
expect(body['appVersion'], '1.2.12');
|
|
expect(closed['customerName'], 'John');
|
|
expect(closed['paymentMethod'], 'payconiq');
|
|
expect(closed['totalInCents'], 500);
|
|
expect(closed['itemCount'], 2);
|
|
expect(items, hasLength(3));
|
|
expect(items.where((item) => item['isRemoved'] == true), hasLength(1));
|
|
expect(
|
|
items.fold<int>(
|
|
0,
|
|
(sum, item) => sum + (item['lineTotalInCents'] as int),
|
|
),
|
|
closed['totalInCents'],
|
|
);
|
|
});
|
|
|
|
test('sends the device token when linked', () async {
|
|
await exportService(token: 'secret').uploadToServer();
|
|
|
|
expect(requests.single.headers['Authorization'], 'Bearer secret');
|
|
});
|
|
|
|
test('sends no token when not linked', () async {
|
|
await exportService().uploadToServer();
|
|
|
|
expect(requests.single.headers.containsKey('Authorization'), false);
|
|
});
|
|
|
|
test('never throws when the server is unreachable', () async {
|
|
respond = () => throw http.ClientException('offline');
|
|
|
|
await expectLater(exportService().uploadToServer(), completes);
|
|
});
|
|
|
|
test('never throws when the server errors', () async {
|
|
respond = () => http.Response('oops', 500);
|
|
|
|
await expectLater(exportService().uploadToServer(), completes);
|
|
});
|
|
}
|