Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade connectivity_plus from v5.0.2 to v6.0.5 with updated implementations and tests #2671

Merged
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
17 changes: 9 additions & 8 deletions lib/services/third_party_service/connectivity_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
/// * Checking if the device has any type of network connection - [hasConnection]
class ConnectivityService {
/// Stream controller for network status changes.
late StreamController<ConnectivityResult> connectionStatusController;
late StreamController<List<ConnectivityResult>> connectionStatusController;

/// Getter for the stream of connection status changes.
Stream<ConnectivityResult> get connectionStream =>
Stream<List<ConnectivityResult>> get connectionStream =>
connectionStatusController.stream;

/// Checks the current internet connectivity status of the device.
Expand All @@ -27,8 +27,8 @@
/// None
///
/// **returns**:
/// * `Future<ConnectivityResult>`: indicates if the url is reachable.
Future<ConnectivityResult> getConnectionType() async {
/// * `Future<List<ConnectivityResult>>`: indicates if the url is reachable.
Future<List<ConnectivityResult>> getConnectionType() async {
final result = await connectivity.checkConnectivity();
return result;
}
Expand All @@ -45,7 +45,7 @@
/// None
Future<void> initConnectivity({required http.Client client}) async {
_client = client;
connectionStatusController = StreamController<ConnectivityResult>();
connectionStatusController = StreamController<List<ConnectivityResult>>();

/// Listen for future changes in connectivity
enableSubscription();
Expand All @@ -60,7 +60,7 @@
/// None
Future<void> enableSubscription() async {
connectivity.onConnectivityChanged.listen(
(ConnectivityResult result) {
(List<ConnectivityResult> result) {

Check warning on line 63 in lib/services/third_party_service/connectivity_service.dart

View check run for this annotation

Codecov / codecov/patch

lib/services/third_party_service/connectivity_service.dart#L63

Added line #L63 was not covered by tests
print(result);
connectionStatusController.add(result);
},
Expand Down Expand Up @@ -107,8 +107,9 @@
/// * `Future<bool>`: indicating whether the device has a network connection.
Future<bool> hasConnection() async {
try {
final result = await getConnectionType();
return result != ConnectivityResult.none;
final results = await getConnectionType();
return results.isNotEmpty &&
results.any((result) => result != ConnectivityResult.none);

Check warning on line 112 in lib/services/third_party_service/connectivity_service.dart

View check run for this annotation

Codecov / codecov/patch

lib/services/third_party_service/connectivity_service.dart#L110-L112

Added lines #L110 - L112 were not covered by tests
} catch (e) {
return false;
}
Expand Down
17 changes: 10 additions & 7 deletions lib/view_model/connectivity_view_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import 'package:talawa/view_model/base_view_model.dart';
/// * Triggers the snackbar UI to show online status.: [showSnackbar]
class AppConnectivity extends BaseModel {
/// Stream from [ConnectivityService].
late final Stream<ConnectivityResult> connectivityStream;
late final Stream<List<ConnectivityResult>> connectivityStream;

/// Subscription of the [connectivityStream]
StreamSubscription? _subscription;
Expand Down Expand Up @@ -51,24 +51,27 @@ class AppConnectivity extends BaseModel {
/// None
void enableSubscription() {
try {
_subscription = connectivityStream.listen((ConnectivityResult result) {
_subscription =
connectivityStream.listen((List<ConnectivityResult> result) {
handleConnection(result);
});
} catch (e) {
print("Error subscribing to connectivity stream: $e");
}
}

/// This function handles the device's connectivity status based on the provided [ConnectivityResult].
/// This function handles the device's connectivity status based on the provided [List<ConnectivityResult>].
///
/// **params**:
/// * `result`: A [ConnectivityResult] indicating the current connectivity status.
/// * `result`: A [List<ConnectivityResult>] indicating the current connectivity status.
///
/// **returns**:
/// None
Future<void> handleConnection(ConnectivityResult result) async {
if (![ConnectivityResult.none, ConnectivityResult.bluetooth]
.contains(result)) {
Future<void> handleConnection(List<ConnectivityResult> result) async {
if (result.any(
(r) =>
![ConnectivityResult.none, ConnectivityResult.bluetooth].contains(r),
)) {
handleOnline();
} else {
handleOffline();
Expand Down
8 changes: 4 additions & 4 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -205,18 +205,18 @@ packages:
dependency: "direct main"
description:
name: connectivity_plus
sha256: "224a77051d52a11fbad53dd57827594d3bd24f945af28bd70bab376d68d437f0"
sha256: e0817759ec6d2d8e57eb234e6e57d2173931367a865850c7acea40d4b4f9c27d
url: "https://pub.dev"
source: hosted
version: "5.0.2"
version: "6.0.5"
connectivity_plus_platform_interface:
dependency: transitive
description:
name: connectivity_plus_platform_interface
sha256: cf1d1c28f4416f8c654d7dc3cd638ec586076255d407cef3ddbdaf178272a71a
sha256: "42657c1715d48b167930d5f34d00222ac100475f73d10162ddf43e714932f204"
url: "https://pub.dev"
source: hosted
version: "1.2.4"
version: "2.0.1"
contained_tab_bar_view:
dependency: "direct main"
description:
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ dependencies:
auto_size_text: ^3.0.0
cached_network_image: ^3.4.1
clock: ^1.1.1
connectivity_plus: ^5.0.2
connectivity_plus: ^6.0.5
contained_tab_bar_view: ^0.8.0

crypto: ^3.0.5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ import 'package:talawa/services/third_party_service/connectivity_service.dart';
import '../../helpers/test_helpers.dart';
import '../../helpers/test_locator.dart' as testgetit;

ConnectivityResult? connectivityStatus = ConnectivityResult.mobile;
List<ConnectivityResult>? connectivityStatus = [ConnectivityResult.mobile];
bool internetAccessible = true;

class MockConnectivityService extends Mock
with MockPlatformInterfaceMixin
implements ConnectivityService {
final controller = StreamController<ConnectivityResult>();
final controller = StreamController<List<ConnectivityResult>>();

@override
// TODO: implement connectionStatusController
StreamController<ConnectivityResult> get connectionStatusController =>
StreamController<List<ConnectivityResult>> get connectionStatusController =>
controller;

@override
Expand All @@ -32,29 +32,53 @@ class MockConnectivityService extends Mock
}

@override
Stream<ConnectivityResult> get connectionStream => controller.stream;
Stream<List<ConnectivityResult>> get connectionStream => controller.stream;

@override
Future<ConnectivityResult> getConnectionType() {
return Future.value(connectivityStatus);
Future<List<ConnectivityResult>> getConnectionType() {
return Future.value(connectivityStatus!);
}

@override
Future<bool> isReachable({http.Client? client, String? uriString}) {
return Future.value(internetAccessible);
Future<bool> hasConnection() async {
try {
final results = await getConnectionType();
return results.isNotEmpty &&
results.any((result) => result != ConnectivityResult.none);
} catch (e) {
return false;
}
}

@override
Future<bool> isReachable({
http.Client? client,
String? uriString,
}) async {
try {
await client!
.get(Uri.parse(uriString ?? graphqlConfig.httpLink.uri.toString()))
.timeout(const Duration(seconds: 30));
return true;
} catch (e) {
print('Timeout while checking reachability: $e');
return false;
}
}
}

class MockConnectivity extends Mock implements Connectivity {
final controller = StreamController<ConnectivityResult>();
final controller = StreamController<List<ConnectivityResult>>();

StreamController<ConnectivityResult> get connectivityController => controller;
StreamController<List<ConnectivityResult>> get connectivityController =>
controller;

@override
Stream<ConnectivityResult> get onConnectivityChanged => controller.stream;
Stream<List<ConnectivityResult>> get onConnectivityChanged =>
controller.stream;

@override
Future<ConnectivityResult> checkConnectivity() async {
Future<List<ConnectivityResult>> checkConnectivity() async {
// TODO: implement checkConnectivity
if (connectivityStatus == null) {
throw const SocketException('socket exception');
Expand All @@ -75,13 +99,13 @@ class MockClient extends Mock implements http.Client {

void main() {
late MockClient mockClient;
late ConnectivityService service;
late MockConnectivityService service;
setUpAll(() {
TestWidgetsFlutterBinding.ensureInitialized();
mockClient = MockClient();
getAndRegisterConnectivity();
connectivityStatus = ConnectivityResult.mobile;
service = ConnectivityService();
connectivityStatus = [ConnectivityResult.mobile];
service = MockConnectivityService();
locator.registerSingleton<ConnectivityService>(service);
connectivityService.initConnectivity(client: http.Client());
});
Expand All @@ -90,33 +114,89 @@ void main() {
test(
'connectionStream getter',
() async {
expect(connectivityService, isA<ConnectivityService>());
expect(service, isA<ConnectivityService>());
expect(
connectivityService.connectionStream,
isA<Stream<ConnectivityResult>>(),
service.connectionStream,
isA<Stream<List<ConnectivityResult>>>(),
);
},
);

test('listener', () async {
final mockConnectivity = testgetit.connectivity as MockConnectivity;
mockConnectivity.connectivityController.add(ConnectivityResult.mobile);
mockConnectivity.connectivityController.add([ConnectivityResult.mobile]);

mockConnectivity.connectivityController
.addError(Exception("Something went wrong!"));
});

test('check has connection', () async {
connectivityStatus = ConnectivityResult.none;
test('successfully listens to connectivity changes', () async {
final expectedResults = [
ConnectivityResult.mobile,
ConnectivityResult.wifi,
];
final MockConnectivity mockConnectivity = MockConnectivity();
mockConnectivity.onConnectivityChanged.listen(
(List<ConnectivityResult> results) {
expect(results, equals(expectedResults));
},
);

// Trigger the event
mockConnectivity.connectivityController.add(expectedResults);
});

test('enableSubscription handles errors gracefully', () async {
final mockConnectivity = MockConnectivity();
mockConnectivity.connectivityController.addError(Exception("Error!"));

expect(
mockConnectivity.onConnectivityChanged,
emitsError(isA<Exception>()),
);
});

test('Returns true if there is a valid connectivity result', () async {
final mockConnectivityService = MockConnectivityService();
connectivityStatus = [ConnectivityResult.mobile, ConnectivityResult.wifi];
final result = await mockConnectivityService.getConnectionType();
final hasConnection = result.isNotEmpty &&
result.any((result) => result != ConnectivityResult.none);

// Verify the conditions
expect(hasConnection, true);
});

test('check has connection - no connection', () async {
connectivityStatus = [ConnectivityResult.none];
expect(await service.hasConnection(), false);
});

test('check has connection - with connection', () async {
connectivityStatus = [ConnectivityResult.mobile];
expect(await service.hasConnection(), true);
});

test('check has connection - empty list', () async {
connectivityStatus = [];
expect(await service.hasConnection(), false);
});

connectivityStatus = ConnectivityResult.mobile;
test('check has connection - mixed results', () async {
connectivityStatus = [ConnectivityResult.none, ConnectivityResult.wifi];
expect(await service.hasConnection(), true);
});

test('check has connection - all none', () async {
connectivityStatus = [ConnectivityResult.none, ConnectivityResult.none];
expect(await service.hasConnection(), false);
});

test('isReachable', () async {
final reached =
await service.isReachable(uriString: 'https://google.com');
final reached = await service.isReachable(
client: mockClient,
uriString: 'https://google.com',
);
expect(reached, true);
});
may-tas marked this conversation as resolved.
Show resolved Hide resolved

Expand Down
8 changes: 4 additions & 4 deletions test/view_model_tests/connectivity_view_model_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@ void main() {
group('test connectivity view model', () {
test('handleConnection when demoMode', () {
MainScreenViewModel.demoMode = true;
model.handleConnection(ConnectivityResult.mobile);
model.handleConnection([ConnectivityResult.mobile]);
});

test('handleConnection when offline', () {
internetAccessible = false;
model.handleConnection(ConnectivityResult.none);
model.handleConnection([ConnectivityResult.none]);
});
test('handleConnection when online', () async {
MainScreenViewModel.demoMode = false;
Expand All @@ -95,7 +95,7 @@ void main() {
);

print(cacheService.offlineActionQueue.getActions());
model.handleConnection(ConnectivityResult.mobile);
model.handleConnection([ConnectivityResult.mobile]);
});

testWidgets('showSnackbar when online', (tester) async {
Expand All @@ -114,7 +114,7 @@ void main() {

test('check enableSubscription body', () {
connectivityService.connectionStatusController
.add(ConnectivityResult.none);
.add([ConnectivityResult.none]);
});

test('enableSubscirption exception', () async {
Expand Down
Loading