diff --git a/lib/api.dart b/lib/api.dart
index 99d005d4..4d42be04 100644
--- a/lib/api.dart
+++ b/lib/api.dart
@@ -201,6 +201,8 @@ class InvenTreeAPI {
   // Authentication token (initially empty, must be requested)
   String _token = "";
 
+  bool get hasToken => _token.isNotEmpty;
+
   /*
    * Check server connection and display messages if not connected.
    * Useful as a precursor check before performing operations.
@@ -278,7 +280,7 @@ class InvenTreeAPI {
   bool _connecting = false;
 
   bool isConnected() {
-    return profile != null && _connected && baseUrl.isNotEmpty && _token.isNotEmpty;
+    return profile != null && _connected && baseUrl.isNotEmpty && hasToken;
   }
 
   bool isConnecting() {
diff --git a/lib/l10.dart b/lib/l10.dart
index ce9f3199..2b44f962 100644
--- a/lib/l10.dart
+++ b/lib/l10.dart
@@ -7,16 +7,18 @@ import "package:flutter/material.dart";
 // Shortcut function to reduce boilerplate!
 I18N L10()
 {
-  BuildContext? _ctx = OneContext().context;
+  if (OneContext.hasContext) {
+    BuildContext? _ctx = OneContext().context;
 
-  if (_ctx != null) {
-    I18N? i18n = I18N.of(_ctx);
+    if (_ctx != null) {
+      I18N? i18n = I18N.of(_ctx);
 
-    if (i18n != null) {
-      return i18n;
+      if (i18n != null) {
+        return i18n;
+      }
     }
   }
 
   // Fallback for "null" context
-   return I18NEn();
+  return I18NEn();
 }
\ No newline at end of file
diff --git a/lib/widget/snacks.dart b/lib/widget/snacks.dart
index e6ee8644..f578debf 100644
--- a/lib/widget/snacks.dart
+++ b/lib/widget/snacks.dart
@@ -1,21 +1,19 @@
-
-/*
- * Display a snackbar with:
- *
- * a) Text on the left
- * b) Icon on the right
- *
- * | Text          <icon> |
- */
-
 import "package:flutter/material.dart";
 import "package:font_awesome_flutter/font_awesome_flutter.dart";
 import "package:one_context/one_context.dart";
 import "package:inventree/l10.dart";
 
 
+/*
+ * Display a configurable 'snackbar' at the bottom of the screen
+ */
 void showSnackIcon(String text, {IconData? icon, Function()? onAction, bool? success, String? actionText}) {
 
+  // Escape quickly if we do not have context
+  if (!OneContext.hasContext) {
+    return;
+  }
+
   BuildContext? context = OneContext().context;
 
   if (context != null) {
diff --git a/pubspec.lock b/pubspec.lock
index a418a5b4..0f7c12f7 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -7,14 +7,14 @@ packages:
       name: _fe_analyzer_shared
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "40.0.0"
+    version: "31.0.0"
   analyzer:
     dependency: transitive
     description:
       name: analyzer
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "4.1.0"
+    version: "2.8.0"
   archive:
     dependency: transitive
     description:
@@ -113,6 +113,13 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "1.3.1"
+  cli_util:
+    dependency: transitive
+    description:
+      name: cli_util
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.3.5"
   clock:
     dependency: transitive
     description:
@@ -140,7 +147,7 @@ packages:
       name: coverage
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.3.2"
+    version: "1.0.3"
   cross_file:
     dependency: transitive
     description:
@@ -218,6 +225,13 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "0.6.3"
+  fake_async:
+    dependency: transitive
+    description:
+      name: fake_async
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.2.0"
   ffi:
     dependency: transitive
     description:
@@ -284,6 +298,11 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "2.0.5"
+  flutter_test:
+    dependency: "direct dev"
+    description: flutter
+    source: sdk
+    version: "0.0.0"
   flutter_web_plugins:
     dependency: transitive
     description: flutter
@@ -839,21 +858,21 @@ packages:
       name: test
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.21.1"
+    version: "1.19.5"
   test_api:
     dependency: transitive
     description:
       name: test_api
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.4.9"
+    version: "0.4.8"
   test_core:
     dependency: transitive
     description:
       name: test_core
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.4.13"
+    version: "0.4.9"
   typed_data:
     dependency: transitive
     description:
@@ -937,7 +956,7 @@ packages:
       name: vm_service
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "8.3.0"
+    version: "7.5.0"
   watcher:
     dependency: transitive
     description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 7489e150..59c3e664 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -40,7 +40,9 @@ dependencies:
 dev_dependencies:
   flutter_launcher_icons: ^0.9.0
   lint: ^1.8.0
-  test: ^1.21.0
+  test: ^1.19.0
+  flutter_test:
+    sdk: flutter
 
 flutter_icons:
   android: true
@@ -63,29 +65,3 @@ flutter:
     - assets/sounds/barcode_scan.mp3
     - assets/sounds/barcode_error.mp3
     - assets/sounds/server_error.mp3
-
-  # An image asset can refer to one or more resolution-specific "variants", see
-  # https://flutter.dev/assets-and-images/#resolution-aware.
-
-  # For details regarding adding assets from package dependencies, see
-  # https://flutter.dev/assets-and-images/#from-packages
-
-  # To add custom fonts to your application, add a fonts section here,
-  # in this "flutter" section. Each entry in this list should have a
-  # "family" key with the font family name, and a "fonts" key with a
-  # list giving the asset and other descriptors for the font. For
-  # example:
-  # fonts:
-  #   - family: Schyler
-  #     fonts:
-  #       - asset: fonts/Schyler-Regular.ttf
-  #       - asset: fonts/Schyler-Italic.ttf
-  #         style: italic
-  #   - family: Trajan Pro
-  #     fonts:
-  #       - asset: fonts/TrajanPro.ttf
-  #       - asset: fonts/TrajanPro_Bold.ttf
-  #         weight: 700
-  #
-  # For details regarding fonts from package dependencies,
-  # see https://flutter.dev/custom-fonts/#from-packages
diff --git a/test/api_test.dart b/test/api_test.dart
new file mode 100644
index 00000000..0841e7e5
--- /dev/null
+++ b/test/api_test.dart
@@ -0,0 +1,55 @@
+/*
+ * Unit tests for the InvenTree API code
+ */
+
+import "package:test/test.dart";
+
+import "package:inventree/api.dart";
+import "package:inventree/user_profile.dart";
+
+
+
+void main() {
+  
+  setUp(() async {
+    
+    // Create and select a profile to user
+    await UserProfileDBManager().addProfile(UserProfile(
+      name: "Test Profile",
+      server: "http://localhost:12345",
+      username: "testuser",
+      password: "testpassword",
+      selected: true,
+    ));
+
+  });
+
+  group("Login Tests:", () {
+
+    test("Disconnected", () async {
+      // Test that calling disconnect() does the right thing
+      var api = InvenTreeAPI();
+
+      api.disconnectFromServer();
+
+      // Check expected values
+      expect(api.isConnected(), equals(false));
+      expect(api.isConnecting(), equals(false));
+      expect(api.hasToken, equals(false));
+
+    });
+
+    test("Login Success", () async {
+      // Test that we can login to the server successfully
+      var api = InvenTreeAPI();
+
+      // Attempt to connect
+      final bool result = await api.connectToServer();
+
+      expect(result, equals(true));
+      expect(api.hasToken, equals(true));
+
+      expect(api.baseUrl, equals("http://localhost:12345/"));
+    });
+  });
+}
\ No newline at end of file