Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/flutter/lib/parse_server_sdk_flutter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ class Parse extends sdk.Parse

if (list.contains(ConnectivityResult.wifi)) {
return sdk.ParseConnectivityResult.wifi;
} else if (list.contains(ConnectivityResult.ethernet)) {
return sdk.ParseConnectivityResult.ethernet;
} else if (list.contains(ConnectivityResult.mobile)) {
return sdk.ParseConnectivityResult.mobile;
} else {
Expand All @@ -136,6 +138,8 @@ class Parse extends sdk.Parse
) {
if (event.contains(ConnectivityResult.wifi)) {
return sdk.ParseConnectivityResult.wifi;
} else if (event.contains(ConnectivityResult.ethernet)) {
return sdk.ParseConnectivityResult.ethernet;
} else if (event.contains(ConnectivityResult.mobile)) {
return sdk.ParseConnectivityResult.mobile;
} else {
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ dependencies:
flutter:
sdk: flutter

parse_server_sdk: ">=6.4.0 <10.0.0"
parse_server_sdk: ">=9.4.2 <10.0.0"
# Uncomment for local testing
#parse_server_sdk:
# path: ../dart
Expand Down
161 changes: 161 additions & 0 deletions packages/flutter/test/parse_connectivity_mapping_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:parse_server_sdk_flutter/parse_server_sdk_flutter.dart';

void main() {
TestWidgetsFlutterBinding.ensureInitialized();

group('Connectivity mapping logic', () {
test('should map connectivity_plus results to ParseConnectivityResult',
() {
// This test documents the expected mapping behavior
// The actual Parse class implementation follows this mapping:

// Test enum structure
expect(ParseConnectivityResult.values.length, 4);
expect(ParseConnectivityResult.values,
containsAll([
ParseConnectivityResult.wifi,
ParseConnectivityResult.ethernet,
ParseConnectivityResult.mobile,
ParseConnectivityResult.none,
]));
});

test('ParseConnectivityResult should have correct ordering for priority',
() {
// Verify enum ordering (wifi has highest priority in the if-else chain)
expect(ParseConnectivityResult.wifi.index, 0);
expect(ParseConnectivityResult.ethernet.index, 1);
expect(ParseConnectivityResult.mobile.index, 2);
expect(ParseConnectivityResult.none.index, 3);
});

test('should identify online vs offline states correctly', () {
// Online states
expect(ParseConnectivityResult.wifi != ParseConnectivityResult.none,
true);
expect(
ParseConnectivityResult.ethernet != ParseConnectivityResult.none,
true);
expect(ParseConnectivityResult.mobile != ParseConnectivityResult.none,
true);

// Offline state
expect(ParseConnectivityResult.none == ParseConnectivityResult.none,
true);
});

test('mapping logic follows priority: wifi > ethernet > mobile > none',
() {
// This documents the if-else chain priority in checkConnectivity()
// If a list contains wifi, it returns wifi
// Else if it contains ethernet, it returns ethernet
// Else if it contains mobile, it returns mobile
// Else it returns none

// Simulating the mapping logic
ParseConnectivityResult mapResult(List<ConnectivityResult> list) {
if (list.contains(ConnectivityResult.wifi)) {
return ParseConnectivityResult.wifi;
} else if (list.contains(ConnectivityResult.ethernet)) {
return ParseConnectivityResult.ethernet;
} else if (list.contains(ConnectivityResult.mobile)) {
return ParseConnectivityResult.mobile;
} else {
return ParseConnectivityResult.none;
}
}

// Test single connection types
expect(mapResult([ConnectivityResult.wifi]),
ParseConnectivityResult.wifi);
expect(mapResult([ConnectivityResult.ethernet]),
ParseConnectivityResult.ethernet);
expect(mapResult([ConnectivityResult.mobile]),
ParseConnectivityResult.mobile);
expect(mapResult([ConnectivityResult.none]),
ParseConnectivityResult.none);

// Test priority when multiple connections exist
expect(mapResult([ConnectivityResult.wifi, ConnectivityResult.ethernet]),
ParseConnectivityResult.wifi);
expect(mapResult([ConnectivityResult.wifi, ConnectivityResult.mobile]),
ParseConnectivityResult.wifi);
expect(
mapResult([ConnectivityResult.ethernet, ConnectivityResult.mobile]),
ParseConnectivityResult.ethernet);

// Test that ethernet takes priority over mobile (important for issue #1042)
expect(
mapResult([ConnectivityResult.mobile, ConnectivityResult.ethernet]),
ParseConnectivityResult.ethernet);

// Test fallback behavior for unsupported types
expect(mapResult([ConnectivityResult.bluetooth]),
ParseConnectivityResult.none);
expect(mapResult([ConnectivityResult.vpn]), ParseConnectivityResult.none);
expect(
mapResult([ConnectivityResult.other]), ParseConnectivityResult.none);

// Test mixed with unsupported types
expect(
mapResult([ConnectivityResult.ethernet, ConnectivityResult.vpn]),
ParseConnectivityResult.ethernet);
});
Comment on lines 9 to 62
Copy link

@coderabbitai coderabbitai bot Dec 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Find the actual connectivity implementation in the Parse SDK
find . -name "*.dart" -type f | head -20

Repository: parse-community/Parse-SDK-Flutter

Length of output: 210


🏁 Script executed:

# Search for ConnectivityResult usage and actual mapping implementation
rg -n "checkConnectivity|mapResult" --type=dart -B 3 -A 3

Repository: parse-community/Parse-SDK-Flutter

Length of output: 210


🏁 Script executed:

# Look for the actual implementation file being tested
rg -n "ConnectivityResult\.(wifi|ethernet|mobile|none)" --type=dart -B 5 -A 5 | head -100

Repository: parse-community/Parse-SDK-Flutter

Length of output: 210


🏁 Script executed:

# Find the parse_connectivity file structure
fd "parse_connectivity" --type f

Repository: parse-community/Parse-SDK-Flutter

Length of output: 210


🏁 Script executed:

# Check the actual implementation that should be tested
cat -n packages/flutter/lib/src/parse_connectivity.dart 2>/dev/null | head -80

Repository: parse-community/Parse-SDK-Flutter

Length of output: 210


🌐 Web query:

Parse Flutter SDK ConnectivityResult checkConnectivity implementation

💡 Result:

Short summary of how checkConnectivity() / ConnectivityResult works (connectivity_plus):

  • Signature & return: Connectivity().checkConnectivity() is async and returns a List (one or more network interface types currently active). [1][2]

  • What the values mean: ConnectivityResult enumerates interface types (wifi, mobile, ethernet, vpn, bluetooth, none, other). The list can contain multiple entries (e.g., vpn + wifi). Use .contains(...) to check for a particular type. [2]

  • Implementation responsibility: The Dart API calls a platform-specific implementation (ConnectivityPlatform). Each platform plugin (Android/iOS/macos/linux/windows) implements checkConnectivity() to query the OS network APIs and map results to ConnectivityResult values. The platform interface defines the API and throws UnimplementedError if not overridden. [3]

  • Practical notes / caveats:

    • checkConnectivity reports the active network interface(s), not whether remote Internet access is reachable — you should still perform an actual network request (or ping) for “has internet.” [2]
    • Platform/OS differences and bugs exist (e.g., iOS simulator/versions have reported checkConnectivity returning none); platform behavior can change and issues are tracked in the plugin repo. [4]

If you want, I can fetch and paste the exact platform implementation files (Android/iOS/Linux/Windows) and explain line-by-line. Which platform(s) do you want analyzed?


🌐 Web query:

parse-flutter-sdk connectivity mapping ethernet wifi mobile priority

💡 Result:

Short answer: Parse Flutter SDK maps only wifi -> wifi, mobile -> mobile, and everything else -> none — it doesn’t expose ethernet (or other ConnectivityResult values) and thus treats those as none. [1][2]

Sources:

  • Parse Flutter SDK connectivityStream implementation (maps ConnectivityResult.wifi → ParseConnectivityResult.wifi, ConnectivityResult.mobile → ParseConnectivityResult.mobile, default → ParseConnectivityResult.none). [1]
  • connectivity_plus docs / changelog showing ConnectivityResult includes ethernet (and other types) on supported platforms. [2][3]

References:
[1] Parse SDK Flutter — connectivityStream implementation.
[2] connectivity_plus package docs (connectivity types & usage).
[3] connectivity_plus changelog (ethernet support added).


🌐 Web query:

Parse Flutter SDK issue 1042 ethernet connectivity

💡 Result:

Summary: The Parse Flutter SDK’s connectivityStream maps connectivity_plus values but only handles wifi and mobile — any other ConnectivityResult (including ethernet) falls to the default branch and is returned as ParseConnectivityResult.none. That causes devices on Ethernet to appear as “no connectivity” to the Parse SDK. Source code excerpt shows the mapping only for wifi/mobile and default -> none. [1]

Context / evidence:

  • Parse SDK docs (connectivityStream implementation) — maps ConnectivityResult.wifi -> ParseConnectivityResult.wifi, ConnectivityResult.mobile -> ParseConnectivityResult.mobile, all other cases -> ParseConnectivityResult.none. [1]
  • Related upstream bug reports show connectivity_plus returning ConnectivityResult.ethernet on macOS/desktop when both Wi‑Fi and LAN are present (so ethernet is a real value that needs handling). [2]

Impact: Apps using Parse’s connectivityStream will treat ethernet-connected devices as offline (ParseConnectivityResult.none), affecting logic that depends on network state (e.g., LiveQuery reconnect logic, background sync).

Minimal fixes:

  • Short-term: Patch parse_server_sdk_flutter to map ConnectivityResult.ethernet to an appropriate ParseConnectivityResult (e.g., wifi or add a new ethernet enum) in connectivityStream.
  • Alternate: Update consumer code to use connectivity_plus directly (and handle ethernet) rather than relying on Parse’s connectivityStream.

References:

  • Parse SDK connectivityStream implementation. [1]
  • connectivity_plus issue reporting ethernet-only result on desktop. [2]

Test expects ethernet connectivity handling that does not exist in the actual Parse SDK implementation.

The mapResult function tests logic for mapping ConnectivityResult.ethernet to ParseConnectivityResult.ethernet (lines 65, 88), but the current Parse Flutter SDK's connectivityStream only handles wifi and mobile—ethernet and other connectivity types are mapped to ParseConnectivityResult.none. This test will pass while devices on ethernet fail silently in production.

If this test is for issue #1042 (adding ethernet support), it should either:

  • Be marked as a failing test or skipped until ethernet handling is implemented, or
  • Be accompanied by changes to the actual Parse SDK connectivityStream to map ethernet appropriately.

If this test is meant for the current implementation, remove the ethernet-related test cases (lines 75-77, 88-90, 102-104) and the ethernet priority logic from mapResult.

🤖 Prompt for AI Agents
In packages/flutter/test/parse_connectivity_mapping_test.dart around lines 49 to
105, the test asserts handling and priority for ConnectivityResult.ethernet but
the current Parse Flutter SDK maps ethernet to none; update the test to match
the implementation by either (A) removing the ethernet-specific expectations and
the ethernet branch in mapResult (remove tests at lines ~75-77, ~88-90, ~102-104
and the etherenet condition), or (B) mark those ethernet-related test cases as
skipped/expected to fail until ethernet support is implemented, or (C) implement
ethernet mapping in the SDK and then keep the tests—choose one approach and make
the corresponding change so tests reflect the actual supported behavior.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kirkmorrow What would be the response to this review feedback?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!


test('ethernet should be treated as online connection type', () {
// Critical test for issue #1042 fix
// Ethernet must be treated as an online state, not as "none"

final isOnline =
ParseConnectivityResult.ethernet != ParseConnectivityResult.none;
expect(isOnline, true,
reason:
'Ethernet should be treated as online for LiveQuery connectivity');
});

test('all online states should be distinguishable from none', () {
final onlineStates = [
ParseConnectivityResult.wifi,
ParseConnectivityResult.ethernet,
ParseConnectivityResult.mobile,
];

for (final state in onlineStates) {
expect(state != ParseConnectivityResult.none, true,
reason: '$state should be distinguishable from none');
}
});
});

group('ConnectivityResult enum compatibility', () {
test('should handle all connectivity_plus enum values', () {
// Ensure we're aware of all possible values from connectivity_plus
final allConnectivityResults = [
ConnectivityResult.wifi,
ConnectivityResult.ethernet,
ConnectivityResult.mobile,
ConnectivityResult.none,
ConnectivityResult.bluetooth,
ConnectivityResult.vpn,
ConnectivityResult.other,
];

// Verify all values exist (will fail if connectivity_plus adds new values)
expect(allConnectivityResults.length, 7);
});

test('ParseConnectivityResult should support main connection types', () {
// The Parse SDK should support the main internet connection types
final supportedTypes = [
ParseConnectivityResult.wifi,
ParseConnectivityResult.ethernet,
ParseConnectivityResult.mobile,
];

expect(supportedTypes.length, 3,
reason: 'Should support 3 main online connection types');
});
});
}
Loading