diff --git a/lib/api_form.dart b/lib/api_form.dart index 07221a1e..588658bc 100644 --- a/lib/api_form.dart +++ b/lib/api_form.dart @@ -335,7 +335,7 @@ class APIFormField { controller.text = hash; data["value"] = hash; - successTone(); + barcodeSuccessTone(); showSnackIcon( L10().barcodeAssigned, diff --git a/lib/barcode.dart b/lib/barcode.dart index 8781f2d1..85702e0e 100644 --- a/lib/barcode.dart +++ b/lib/barcode.dart @@ -11,15 +11,38 @@ import "package:qr_code_scanner/qr_code_scanner.dart"; import "package:inventree/inventree/stock.dart"; import "package:inventree/inventree/part.dart"; -import "package:inventree/l10.dart"; -import "package:inventree/helpers.dart"; import "package:inventree/api.dart"; +import "package:inventree/helpers.dart"; +import "package:inventree/l10.dart"; +import "package:inventree/preferences.dart"; import "package:inventree/widget/location_display.dart"; import "package:inventree/widget/part_detail.dart"; import "package:inventree/widget/stock_detail.dart"; +/* + * Play an audible 'success' alert to the user. + */ +Future barcodeSuccessTone() async { + + final bool en = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool; + + if (en) { + playAudioFile("sounds/barcode_scan.mp3"); + } +} + +Future barcodeFailureTone() async { + + final bool en = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool; + + if (en) { + playAudioFile("sounds/barcode_error.mp3"); + } +} + + class BarcodeHandler { /* * Class which "handles" a barcode, by communicating with the InvenTree server, @@ -44,7 +67,7 @@ class BarcodeHandler { // Called when the server does not know about a barcode // Override this function - failureTone(); + barcodeFailureTone(); showSnackIcon( L10().barcodeNoMatch, @@ -55,7 +78,7 @@ class BarcodeHandler { Future onBarcodeUnhandled(BuildContext context, Map data) async { - failureTone(); + barcodeFailureTone(); // Called when the server returns an unhandled response showServerError(L10().responseUnknown, data.toString()); @@ -125,7 +148,7 @@ class BarcodeScanHandler extends BarcodeHandler { @override Future onBarcodeUnknown(BuildContext context, Map data) async { - failureTone(); + barcodeFailureTone(); showSnackIcon( L10().barcodeNoMatch, @@ -146,7 +169,7 @@ class BarcodeScanHandler extends BarcodeHandler { if (pk > 0) { - successTone(); + barcodeSuccessTone(); InvenTreeStockLocation().get(pk).then((var loc) { if (loc is InvenTreeStockLocation) { @@ -156,7 +179,7 @@ class BarcodeScanHandler extends BarcodeHandler { }); } else { - failureTone(); + barcodeFailureTone(); showSnackIcon( L10().invalidStockLocation, @@ -170,7 +193,7 @@ class BarcodeScanHandler extends BarcodeHandler { if (pk > 0) { - successTone(); + barcodeSuccessTone(); InvenTreeStockItem().get(pk).then((var item) { @@ -183,7 +206,7 @@ class BarcodeScanHandler extends BarcodeHandler { }); } else { - failureTone(); + barcodeFailureTone(); showSnackIcon( L10().invalidStockItem, @@ -196,7 +219,7 @@ class BarcodeScanHandler extends BarcodeHandler { if (pk > 0) { - successTone(); + barcodeSuccessTone(); InvenTreePart().get(pk).then((var part) { @@ -209,7 +232,7 @@ class BarcodeScanHandler extends BarcodeHandler { }); } else { - failureTone(); + barcodeFailureTone(); showSnackIcon( L10().invalidPart, @@ -218,7 +241,7 @@ class BarcodeScanHandler extends BarcodeHandler { } } else { - failureTone(); + barcodeFailureTone(); showSnackIcon( L10().barcodeUnknown, @@ -275,7 +298,7 @@ class StockItemScanIntoLocationHandler extends BarcodeHandler { if (result) { - successTone(); + barcodeSuccessTone(); Navigator.of(context).pop(); @@ -285,7 +308,7 @@ class StockItemScanIntoLocationHandler extends BarcodeHandler { ); } else { - failureTone(); + barcodeFailureTone(); showSnackIcon( L10().barcodeScanIntoLocationFailure, @@ -294,7 +317,7 @@ class StockItemScanIntoLocationHandler extends BarcodeHandler { } } else { - failureTone(); + barcodeFailureTone(); showSnackIcon( L10().invalidStockLocation, @@ -329,14 +352,14 @@ class StockLocationScanInItemsHandler extends BarcodeHandler { if (item == null) { - failureTone(); + barcodeFailureTone(); showSnackIcon( L10().invalidStockItem, success: false, ); } else if (item.locationId == location.pk) { - failureTone(); + barcodeFailureTone(); showSnackIcon( L10().itemInLocation, @@ -347,7 +370,7 @@ class StockLocationScanInItemsHandler extends BarcodeHandler { if (result) { - successTone(); + barcodeSuccessTone(); showSnackIcon( L10().barcodeScanIntoLocationSuccess, @@ -355,7 +378,7 @@ class StockLocationScanInItemsHandler extends BarcodeHandler { ); } else { - failureTone(); + barcodeFailureTone(); showSnackIcon( L10().barcodeScanIntoLocationFailure, @@ -365,7 +388,7 @@ class StockLocationScanInItemsHandler extends BarcodeHandler { } } else { - failureTone(); + barcodeFailureTone(); // Does not match a valid stock item! showSnackIcon( @@ -401,7 +424,7 @@ class UniqueBarcodeHandler extends BarcodeHandler { @override Future onBarcodeMatched(BuildContext context, Map data) async { - failureTone(); + barcodeFailureTone(); // If the barcode is known, we can"t assign it to the stock item! showSnackIcon( @@ -424,7 +447,7 @@ class UniqueBarcodeHandler extends BarcodeHandler { String hash = (data["hash"] ?? "") as String; if (hash.isEmpty) { - failureTone(); + barcodeFailureTone(); showSnackIcon( L10().barcodeError, @@ -432,7 +455,7 @@ class UniqueBarcodeHandler extends BarcodeHandler { ); } else { - successTone(); + barcodeSuccessTone(); // Close the barcode scanner Navigator.of(context).pop(); diff --git a/lib/helpers.dart b/lib/helpers.dart index 85d550ae..2bdbed53 100644 --- a/lib/helpers.dart +++ b/lib/helpers.dart @@ -8,8 +8,7 @@ */ import "package:audioplayers/audioplayers.dart"; - -import "package:inventree/preferences.dart"; +import "package:one_context/one_context.dart"; String simpleNumberString(double number) { // Ref: https://stackoverflow.com/questions/55152175/how-to-remove-trailing-zeros-using-dart @@ -17,22 +16,19 @@ String simpleNumberString(double number) { return number.toStringAsFixed(number.truncateToDouble() == number ? 0 : 1); } -Future successTone() async { +/* + * Play an audio file from the requested path. + * + * Note: If OneContext module fails the 'hasConext' check, + * we will not attempt to play the sound + */ +Future playAudioFile(String path) async { - final bool en = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool; - - if (en) { - final player = AudioCache(); - player.play("sounds/barcode_scan.mp3"); + if (!OneContext.hasContext) { + return; } + + final player = AudioCache(); + player.play(path); + } - -Future failureTone() async { - - final bool en = await InvenTreeSettingsManager().getValue(INV_SOUNDS_BARCODE, true) as bool; - - if (en) { - final player = AudioCache(); - player.play("sounds/barcode_error.mp3"); - } -} \ No newline at end of file diff --git a/lib/widget/dialogs.dart b/lib/widget/dialogs.dart index e6b3bfb7..5fbe20b1 100644 --- a/lib/widget/dialogs.dart +++ b/lib/widget/dialogs.dart @@ -1,6 +1,6 @@ -import "package:audioplayers/audioplayers.dart"; import "package:flutter/material.dart"; import "package:font_awesome_flutter/font_awesome_flutter.dart"; +import "package:inventree/helpers.dart"; import "package:one_context/one_context.dart"; import "package:inventree/l10.dart"; @@ -108,8 +108,7 @@ Future showServerError(String title, String description) async { final bool tones = await InvenTreeSettingsManager().getValue(INV_SOUNDS_SERVER, true) as bool; if (tones) { - final player = AudioCache(); - player.play("sounds/server_error.mp3"); + playAudioFile("sounds/server_error.mp3"); } showSnackIcon( diff --git a/lib/widget/stock_detail.dart b/lib/widget/stock_detail.dart index b742cfb2..50107797 100644 --- a/lib/widget/stock_detail.dart +++ b/lib/widget/stock_detail.dart @@ -19,7 +19,6 @@ import "package:inventree/widget/stock_item_history.dart"; import "package:inventree/widget/stock_item_test_results.dart"; import "package:inventree/widget/stock_notes.dart"; import "package:inventree/l10.dart"; -import "package:inventree/helpers.dart"; import "package:inventree/api.dart"; import "package:inventree/api_form.dart"; import "package:inventree/preferences.dart"; @@ -1008,7 +1007,7 @@ class _StockItemDisplayState extends RefreshableState { } ).then((result) { if (result) { - successTone(); + barcodeSuccessTone(); showSnackIcon( L10().barcodeAssigned, diff --git a/pubspec.yaml b/pubspec.yaml index 59c3e664..33932d52 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -39,10 +39,10 @@ dependencies: dev_dependencies: flutter_launcher_icons: ^0.9.0 - lint: ^1.8.0 - test: ^1.19.0 flutter_test: sdk: flutter + lint: ^1.8.0 + test: ^1.19.0 flutter_icons: android: true diff --git a/test/api_test.dart b/test/api_test.dart index 0841e7e5..4631c5ca 100644 --- a/test/api_test.dart +++ b/test/api_test.dart @@ -39,6 +39,30 @@ void main() { }); + test("Login Failure", () async { + // Tests for various types of login failures + var api = InvenTreeAPI(); + + // Incorrect server address + var profile = await UserProfileDBManager().getSelectedProfile(); + + assert(profile != null); + + if (profile != null) { + profile.server = "http://localhost:5555"; + await UserProfileDBManager().updateProfile(profile); + } + + bool result = await api.connectToServer(); + + assert(!result); + + // TODO: Test the the right 'error message' is returned + + // TODO: Test incorrect login details + + }); + test("Login Success", () async { // Test that we can login to the server successfully var api = InvenTreeAPI(); @@ -46,10 +70,13 @@ void main() { // Attempt to connect final bool result = await api.connectToServer(); + // Check expected values expect(result, equals(true)); expect(api.hasToken, equals(true)); - expect(api.baseUrl, equals("http://localhost:12345/")); + + expect(api.isConnected(), equals(true)); + expect(api.isConnecting(), equals(false)); }); }); } \ No newline at end of file