Skip to content

Commit

Permalink
feature: added network info implementation in core/platform with test…
Browse files Browse the repository at this point in the history
… driven development
  • Loading branch information
BasakK6 committed Sep 26, 2023
1 parent 198c8d0 commit 5d80ce5
Show file tree
Hide file tree
Showing 14 changed files with 340 additions and 0 deletions.
1 change: 1 addition & 0 deletions ios/Flutter/Debug.xcconfig
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
1 change: 1 addition & 0 deletions ios/Flutter/Release.xcconfig
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
44 changes: 44 additions & 0 deletions ios/Podfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '11.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}

def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end

File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

flutter_ios_podfile_setup

target 'Runner' do
use_frameworks!
use_modular_headers!

flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end

post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end
24 changes: 24 additions & 0 deletions lib/core/platform/network_info.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:news_app/core/error/exceptions.dart';

abstract class NetworkInfo {
Future<bool> checkConnection();
}

class NetworkInfoImplementation extends NetworkInfo {
final Connectivity connectivity;

NetworkInfoImplementation(this.connectivity);

@override
Future<bool> checkConnection() async {
final ConnectivityResult result = await connectivity.checkConnectivity();
switch (result) {
case ConnectivityResult.wifi:
case ConnectivityResult.ethernet:
case ConnectivityResult.mobile:
return true;
case ConnectivityResult.bluetooth:
case ConnectivityResult.none:
default:
throw ConnectivityException();
}
}
}
1 change: 1 addition & 0 deletions macos/Flutter/Flutter-Debug.xcconfig
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig"
1 change: 1 addition & 0 deletions macos/Flutter/Flutter-Release.xcconfig
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig"
2 changes: 2 additions & 0 deletions macos/Flutter/GeneratedPluginRegistrant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import FlutterMacOS
import Foundation

import connectivity_plus

func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
}
43 changes: 43 additions & 0 deletions macos/Podfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
platform :osx, '10.14'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}

def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
end

File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

flutter_macos_podfile_setup

target 'Runner' do
use_frameworks!
use_modular_headers!

flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end

post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_macos_build_settings(target)
end
end
70 changes: 70 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.17.2"
connectivity_plus:
dependency: "direct main"
description:
name: connectivity_plus
sha256: "77a180d6938f78ca7d2382d2240eb626c0f6a735d0bfdce227d8ffb80f95c48b"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
connectivity_plus_platform_interface:
dependency: transitive
description:
name: connectivity_plus_platform_interface
sha256: cf1d1c28f4416f8c654d7dc3cd638ec586076255d407cef3ddbdaf178272a71a
url: "https://pub.dev"
source: hosted
version: "1.2.4"
convert:
dependency: transitive
description:
Expand Down Expand Up @@ -185,6 +201,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.10.1"
dbus:
dependency: transitive
description:
name: dbus
sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263"
url: "https://pub.dev"
source: hosted
version: "0.7.8"
equatable:
dependency: "direct main"
description:
Expand All @@ -201,6 +225,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.1"
ffi:
dependency: transitive
description:
name: ffi
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
file:
dependency: transitive
description:
Expand Down Expand Up @@ -235,6 +267,11 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
frontend_server_client:
dependency: transitive
description:
Expand Down Expand Up @@ -355,6 +392,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.4.2"
nm:
dependency: transitive
description:
name: nm
sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254"
url: "https://pub.dev"
source: hosted
version: "0.5.0"
package_config:
dependency: transitive
description:
Expand All @@ -371,6 +416,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.8.3"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750
url: "https://pub.dev"
source: hosted
version: "5.4.0"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d
url: "https://pub.dev"
source: hosted
version: "2.1.6"
pool:
dependency: transitive
description:
Expand Down Expand Up @@ -528,6 +589,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.4.0"
xml:
dependency: transitive
description:
name: xml
sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84"
url: "https://pub.dev"
source: hosted
version: "6.3.0"
yaml:
dependency: transitive
description:
Expand All @@ -538,3 +607,4 @@ packages:
version: "3.1.2"
sdks:
dart: ">=3.1.1 <4.0.0"
flutter: ">=3.3.0"
2 changes: 2 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ dependencies:
dartz: ^0.10.1
# value equality instead of reference equality
equatable: ^2.0.5
# internet connection check
connectivity_plus: ^4.0.2

dev_dependencies:
flutter_test:
Expand Down
100 changes: 100 additions & 0 deletions test/core/platform/network_info_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:news_app/core/error/exceptions.dart';
import 'package:news_app/core/platform/network_info.dart';

import 'network_info_test.mocks.dart';

@GenerateNiceMocks([MockSpec<Connectivity>()])
void main() {
late NetworkInfoImplementation networkInfoImplementation;
late MockConnectivity mockConnectivity;

setUp(() {
mockConnectivity = MockConnectivity();
networkInfoImplementation = NetworkInfoImplementation(mockConnectivity);
});

group("checkConnection() tests", () {
test("should forward the call to Connectivity().checkConnectivity()",
() async {
//arrange
when(mockConnectivity.checkConnectivity())
.thenAnswer((realInvocation) async => ConnectivityResult.wifi);
//act
await networkInfoImplementation.checkConnection();
//assert
verify(mockConnectivity.checkConnectivity());
});

group("there is a connection", () {
test("should return true when there is a internet connection (wifi)",
() async {
//arrange
when(mockConnectivity.checkConnectivity())
.thenAnswer((realInvocation) async => ConnectivityResult.wifi);
//act
final result = await networkInfoImplementation.checkConnection();
//assert
expect(result, true);
verify(mockConnectivity.checkConnectivity());
});

test("should return true when there is a internet connection (ethernet)",
() async {
//arrange
when(mockConnectivity.checkConnectivity())
.thenAnswer((realInvocation) async => ConnectivityResult.ethernet);
//act
final result = await networkInfoImplementation.checkConnection();
//assert
expect(result, true);
verify(mockConnectivity.checkConnectivity());
});

test("should return true when there is a internet connection (mobile)",
() async {
//arrange
when(mockConnectivity.checkConnectivity())
.thenAnswer((realInvocation) async => ConnectivityResult.mobile);
//act
final result = await networkInfoImplementation.checkConnection();
//assert
expect(result, true);
verify(mockConnectivity.checkConnectivity());
});
});

group("there is no connection", () {
test(
"should throw a ConnectivityException when there is no internet connection (bluetooth)",
() async {
//arrange
when(mockConnectivity.checkConnectivity())
.thenAnswer((realInvocation) async => ConnectivityResult.bluetooth);
//act
final calledMethod = networkInfoImplementation.checkConnection;
//assert
expect(
calledMethod, throwsA(const TypeMatcher<ConnectivityException>()));
verify(mockConnectivity.checkConnectivity());
});

test(
"should throw a ConnectivityException when there is no internet connection (none)",
() async {
//arrange
when(mockConnectivity.checkConnectivity())
.thenAnswer((realInvocation) async => ConnectivityResult.none);
//act
final calledMethod = networkInfoImplementation.checkConnection;
//assert
expect(
calledMethod, throwsA(const TypeMatcher<ConnectivityException>()));
verify(mockConnectivity.checkConnectivity());
});
});
});
}
Loading

0 comments on commit 5d80ce5

Please sign in to comment.