Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 3 additions & 0 deletions packages/dart/lib/src/network/parse_connectivity.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ enum ParseConnectivityResult {
/// WiFi: Device connected via Wi-Fi
wifi,

/// Ethernet: Device connected via Ethernet
ethernet,

/// Mobile: Device connected to cellular network
mobile,

Expand Down
144 changes: 144 additions & 0 deletions packages/dart/test/src/network/parse_live_query_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,30 @@ import 'package:test/test.dart';

import '../../test_utils.dart';

/// Mock connectivity provider for testing different connectivity states
class MockConnectivityProvider implements ParseConnectivityProvider {
final StreamController<ParseConnectivityResult> _controller =
StreamController<ParseConnectivityResult>.broadcast();
ParseConnectivityResult _currentState = ParseConnectivityResult.wifi;

@override
Future<ParseConnectivityResult> checkConnectivity() async {
return _currentState;
}

@override
Stream<ParseConnectivityResult> get connectivityStream => _controller.stream;

void setConnectivity(ParseConnectivityResult state) {
_currentState = state;
_controller.add(state);
}

void dispose() {
_controller.close();
}
}

void main() {
setUpAll(() async {
// Create a fake server
Expand Down Expand Up @@ -62,4 +86,124 @@ void main() {
// 10 millisecond hold for stream
await Future.delayed(Duration(milliseconds: 10));
});

group('Connectivity handling', () {
late MockConnectivityProvider mockConnectivity;

// Initialize once with mock provider, then test state changes
setUpAll(() async {
mockConnectivity = MockConnectivityProvider();
// Initialize Parse once with the mock provider
await Parse().initialize(
'appId',
serverUrl,
debug: false,
fileDirectory: 'someDirectory',
appName: 'appName',
appPackageName: 'somePackageName',
appVersion: 'someAppVersion',
connectivityProvider: mockConnectivity,
);
});

tearDownAll(() {
mockConnectivity.dispose();
});

// Test data for parameterized connectivity state tests
final connectivityTestCases = <Map<String, dynamic>>[
{
'state': ParseConnectivityResult.wifi,
'isOnline': true,
'description': 'wifi should be treated as online',
},
{
'state': ParseConnectivityResult.ethernet,
'isOnline': true,
'description': 'ethernet should be treated as online',
},
{
'state': ParseConnectivityResult.mobile,
'isOnline': true,
'description': 'mobile should be treated as online',
},
{
'state': ParseConnectivityResult.none,
'isOnline': false,
'description': 'none should be treated as offline',
},
];

for (final testCase in connectivityTestCases) {
test(testCase['description'], () async {
// arrange
final state = testCase['state'] as ParseConnectivityResult;
final isOnline = testCase['isOnline'] as bool;

// act
mockConnectivity.setConnectivity(state);
final result = await mockConnectivity.checkConnectivity();

// assert - verify the state is correctly identified
expect(result, state);
expect(result != ParseConnectivityResult.none, isOnline);
});
}

test('should emit connectivity state transitions through stream', () async {
// arrange
final emittedStates = <ParseConnectivityResult>[];
final subscription = mockConnectivity.connectivityStream.listen((state) {
emittedStates.add(state);
});

// act - transition through different connectivity states
mockConnectivity.setConnectivity(ParseConnectivityResult.wifi);
await Future.delayed(Duration(milliseconds: 10));
mockConnectivity.setConnectivity(ParseConnectivityResult.ethernet);
await Future.delayed(Duration(milliseconds: 10));
mockConnectivity.setConnectivity(ParseConnectivityResult.mobile);
await Future.delayed(Duration(milliseconds: 10));
mockConnectivity.setConnectivity(ParseConnectivityResult.none);
await Future.delayed(Duration(milliseconds: 10));

// assert - all state changes should be emitted
expect(emittedStates.length, 4);
expect(emittedStates[0], ParseConnectivityResult.wifi);
expect(emittedStates[1], ParseConnectivityResult.ethernet);
expect(emittedStates[2], ParseConnectivityResult.mobile);
expect(emittedStates[3], ParseConnectivityResult.none);

// verify online states (wifi, ethernet, mobile) are not "none"
expect(emittedStates[0], isNot(ParseConnectivityResult.none));
expect(emittedStates[1], isNot(ParseConnectivityResult.none));
expect(emittedStates[2], isNot(ParseConnectivityResult.none));

await subscription.cancel();
});

test('should transition from offline to online correctly', () async {
// arrange
final stateChanges = <ParseConnectivityResult>[];
final subscription = mockConnectivity.connectivityStream.listen((state) {
stateChanges.add(state);
});

// act - start offline, then go online via ethernet
mockConnectivity.setConnectivity(ParseConnectivityResult.none);
await Future.delayed(Duration(milliseconds: 10));
mockConnectivity.setConnectivity(ParseConnectivityResult.ethernet);
await Future.delayed(Duration(milliseconds: 10));

// assert
expect(stateChanges.length, 2);
expect(stateChanges[0], ParseConnectivityResult.none);
expect(stateChanges[1], ParseConnectivityResult.ethernet);
// Verify the transition is from offline to online
expect(stateChanges[0] == ParseConnectivityResult.none, true);
expect(stateChanges[1] != ParseConnectivityResult.none, true);

await subscription.cancel();
});
});
}