diff --git a/CHANGELOG.md b/CHANGELOG.md
index 786f911..dc6182f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## 0.2.0
+
+* Added: Unit testing for a few of the files.
+* Modified: Android and iOS projects both in the plugin and the example now use Kotlin/Swift.
+* Modified: Android projects both in the plugin and the example now use AndroidX namespaces.
+* Fixed: Last '&' character was not removed from parametized URLs.
+* Fixed: Duplicate GET parameters when using `get`.
+
## 0.1.1
* Fixed: HTTP Methods have misaligned parameters. Now they are called via named parameters to avoid type mismatch exceptions when being used.
diff --git a/README.md b/README.md
index 16de5a5..886eec5 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,7 @@
[](https://pub.dev/packages/http_interceptor)
[](https://github.com/tenhobi/effective_dart)
[](https://opensource.org/licenses/MIT)
+[](https://codecov.io/gh/CodingAleCR/http_interceptor)
[](https://github.com/codingalecr/http_interceptor)
A middleware library that lets you modify requests and responses if desired. Based of on [http_middleware](https://github.com/TEDConsulting/http_middleware)
diff --git a/analysis_options.yml b/analysis_options.yml
index 30dcb3b..c9cf67f 100644
--- a/analysis_options.yml
+++ b/analysis_options.yml
@@ -1 +1 @@
-include: package:effective_dart/analysis_options.1.1.0.yaml
\ No newline at end of file
+include: package:effective_dart/analysis_options.1.2.1.yaml
\ No newline at end of file
diff --git a/android/.gitignore b/android/.gitignore
deleted file mode 100644
index c6cbe56..0000000
--- a/android/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-*.iml
-.gradle
-/local.properties
-/.idea/workspace.xml
-/.idea/libraries
-.DS_Store
-/build
-/captures
diff --git a/android/build.gradle b/android/build.gradle
deleted file mode 100644
index f7e5eca..0000000
--- a/android/build.gradle
+++ /dev/null
@@ -1,44 +0,0 @@
-group 'com.example.http_interceptor'
-version '1.0-SNAPSHOT'
-
-buildscript {
- ext.kotlin_version = '1.2.71'
- repositories {
- google()
- jcenter()
- }
-
- dependencies {
- classpath 'com.android.tools.build:gradle:3.2.1'
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- }
-}
-
-rootProject.allprojects {
- repositories {
- google()
- jcenter()
- }
-}
-
-apply plugin: 'com.android.library'
-apply plugin: 'kotlin-android'
-
-android {
- compileSdkVersion 28
-
- sourceSets {
- main.java.srcDirs += 'src/main/kotlin'
- }
- defaultConfig {
- minSdkVersion 16
- testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
- }
- lintOptions {
- disable 'InvalidPackage'
- }
-}
-
-dependencies {
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
-}
diff --git a/android/gradle.properties b/android/gradle.properties
deleted file mode 100644
index bb04111..0000000
--- a/android/gradle.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-android.enableJetifier=true
-android.useAndroidX=true
-org.gradle.jvmargs=-Xmx1536M
-
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index 019065d..0000000
--- a/android/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
diff --git a/android/settings.gradle b/android/settings.gradle
deleted file mode 100644
index 34edcd5..0000000
--- a/android/settings.gradle
+++ /dev/null
@@ -1 +0,0 @@
-rootProject.name = 'http_interceptor'
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
deleted file mode 100644
index 8b62ad8..0000000
--- a/android/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
diff --git a/android/src/main/kotlin/com/example/http_interceptor/HttpInterceptorPlugin.kt b/android/src/main/kotlin/com/example/http_interceptor/HttpInterceptorPlugin.kt
deleted file mode 100644
index 83429b8..0000000
--- a/android/src/main/kotlin/com/example/http_interceptor/HttpInterceptorPlugin.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.example.http_interceptor
-
-import io.flutter.plugin.common.MethodCall
-import io.flutter.plugin.common.MethodChannel
-import io.flutter.plugin.common.MethodChannel.MethodCallHandler
-import io.flutter.plugin.common.MethodChannel.Result
-import io.flutter.plugin.common.PluginRegistry.Registrar
-
-class HttpInterceptorPlugin: MethodCallHandler {
- companion object {
- @JvmStatic
- fun registerWith(registrar: Registrar) {
- val channel = MethodChannel(registrar.messenger(), "http_interceptor")
- channel.setMethodCallHandler(HttpInterceptorPlugin())
- }
- }
-
- override fun onMethodCall(call: MethodCall, result: Result) {
- if (call.method == "getPlatformVersion") {
- result.success("Android ${android.os.Build.VERSION.RELEASE}")
- } else {
- result.notImplemented()
- }
- }
-}
diff --git a/example/.gitignore b/example/.gitignore
index 95c7e97..ae1f183 100644
--- a/example/.gitignore
+++ b/example/.gitignore
@@ -18,56 +18,20 @@
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
-.vscode/
+#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
+.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
-# Android related
-**/android/**/gradle-wrapper.jar
-**/android/.gradle
-**/android/captures/
-**/android/gradlew
-**/android/gradlew.bat
-**/android/local.properties
-**/android/**/GeneratedPluginRegistrant.java
-
-# iOS/XCode related
-**/ios/**/*.mode1v3
-**/ios/**/*.mode2v3
-**/ios/**/*.moved-aside
-**/ios/**/*.pbxuser
-**/ios/**/*.perspectivev3
-**/ios/**/*sync/
-**/ios/**/.sconsign.dblite
-**/ios/**/.tags*
-**/ios/**/.vagrant/
-**/ios/**/DerivedData/
-**/ios/**/Icon?
-**/ios/**/Pods/
-**/ios/**/.symlinks/
-**/ios/**/profile
-**/ios/**/xcuserdata
-**/ios/.generated/
-**/ios/Flutter/App.framework
-**/ios/Flutter/Flutter.framework
-**/ios/Flutter/Generated.xcconfig
-**/ios/Flutter/app.flx
-**/ios/Flutter/app.zip
-**/ios/Flutter/flutter_assets/
-**/ios/Flutter/flutter_export_environment.sh
-**/ios/ServiceDefinitions.json
-**/ios/Runner/GeneratedPluginRegistrant.*
+# Web related
+lib/generated_plugin_registrant.dart
# Exceptions to above rules.
-!**/ios/**/default.mode1v3
-!**/ios/**/default.mode2v3
-!**/ios/**/default.pbxuser
-!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
diff --git a/example/README.md b/example/README.md
index 1aea750..5f5a94d 100644
--- a/example/README.md
+++ b/example/README.md
@@ -1,5 +1,4 @@
# OpenWeatherApp
-**http_interceptor example**
Demonstrates how to use the http_interceptor plugin.
@@ -8,4 +7,5 @@ Demonstrates how to use the http_interceptor plugin.
This app implements the usage of the http_interceptor plugin. It uses the OpenWeatherAPI and intercepts the requests done to add the App Id Key and the unit system desired for the response. Notice that this example is for **show purposes only, it is not intended as a full testable implementation**.
### Running the example
-In order to run this example locally you will need to replace the API Key in the `credentials.dart`. You can get your own at https://openweathermap.org/
+
+In order to run this example locally you will need to replace the API Key in the `credentials.dart`. You can get your own at
diff --git a/example/android/.gitignore b/example/android/.gitignore
new file mode 100644
index 0000000..bc2100d
--- /dev/null
+++ b/example/android/.gitignore
@@ -0,0 +1,7 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/gradlew.bat
+/local.properties
+GeneratedPluginRegistrant.java
diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle
index 2c76e94..0f6a5e5 100644
--- a/example/android/app/build.gradle
+++ b/example/android/app/build.gradle
@@ -62,6 +62,6 @@ flutter {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation 'junit:junit:4.12'
- androidTestImplementation 'androidx.test.ext:junit:1.1.1'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
+ androidTestImplementation 'androidx.test:runner:1.1.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}
diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml
index 2877140..8bc6007 100644
--- a/example/android/app/src/main/AndroidManifest.xml
+++ b/example/android/app/src/main/AndroidManifest.xml
@@ -1,6 +1,5 @@
-
-
+
+
diff --git a/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt b/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt
index e2c0fd3..1656503 100644
--- a/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt
+++ b/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt
@@ -1,13 +1,12 @@
package com.example.example
-import android.os.Bundle
-
-import io.flutter.app.FlutterActivity
+import androidx.annotation.NonNull;
+import io.flutter.embedding.android.FlutterActivity
+import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- GeneratedPluginRegistrant.registerWith(this)
- }
+ override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
+ GeneratedPluginRegistrant.registerWith(flutterEngine);
+ }
}
diff --git a/example/android/app/src/main/kotlin/com/example/http_interceptor_example/MainActivity.kt b/example/android/app/src/main/kotlin/com/example/http_interceptor_example/MainActivity.kt
deleted file mode 100644
index 11012ad..0000000
--- a/example/android/app/src/main/kotlin/com/example/http_interceptor_example/MainActivity.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.example.http_interceptor_example
-
-import android.os.Bundle
-
-import io.flutter.app.FlutterActivity
-import io.flutter.plugins.GeneratedPluginRegistrant
-
-class MainActivity: FlutterActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- GeneratedPluginRegistrant.registerWith(this)
- }
-}
diff --git a/example/android/build.gradle b/example/android/build.gradle
index b7faad8..3100ad2 100644
--- a/example/android/build.gradle
+++ b/example/android/build.gradle
@@ -1,12 +1,12 @@
buildscript {
- ext.kotlin_version = '1.2.71'
+ ext.kotlin_version = '1.3.50'
repositories {
google()
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.2.1'
+ classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
diff --git a/example/android/gradle.properties b/example/android/gradle.properties
index bb04111..38c8d45 100644
--- a/example/android/gradle.properties
+++ b/example/android/gradle.properties
@@ -1,4 +1,4 @@
-android.enableJetifier=true
-android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536M
-
+android.enableR8=true
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties
index 2819f02..296b146 100644
--- a/example/android/gradle/wrapper/gradle-wrapper.properties
+++ b/example/android/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
diff --git a/example/ios/.gitignore b/example/ios/.gitignore
new file mode 100644
index 0000000..e96ef60
--- /dev/null
+++ b/example/ios/.gitignore
@@ -0,0 +1,32 @@
+*.mode1v3
+*.mode2v3
+*.moved-aside
+*.pbxuser
+*.perspectivev3
+**/*sync/
+.sconsign.dblite
+.tags*
+**/.vagrant/
+**/DerivedData/
+Icon?
+**/Pods/
+**/.symlinks/
+profile
+xcuserdata
+**/.generated/
+Flutter/App.framework
+Flutter/Flutter.framework
+Flutter/Flutter.podspec
+Flutter/Generated.xcconfig
+Flutter/app.flx
+Flutter/app.zip
+Flutter/flutter_assets/
+Flutter/flutter_export_environment.sh
+ServiceDefinitions.json
+Runner/GeneratedPluginRegistrant.*
+
+# Exceptions to above rules.
+!default.mode1v3
+!default.mode2v3
+!default.pbxuser
+!default.perspectivev3
diff --git a/example/ios/Flutter/Debug.xcconfig b/example/ios/Flutter/Debug.xcconfig
index e8efba1..592ceee 100644
--- a/example/ios/Flutter/Debug.xcconfig
+++ b/example/ios/Flutter/Debug.xcconfig
@@ -1,2 +1 @@
-#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
diff --git a/example/ios/Flutter/Release.xcconfig b/example/ios/Flutter/Release.xcconfig
index 399e934..592ceee 100644
--- a/example/ios/Flutter/Release.xcconfig
+++ b/example/ios/Flutter/Release.xcconfig
@@ -1,2 +1 @@
-#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
diff --git a/example/ios/Podfile b/example/ios/Podfile
deleted file mode 100644
index e9286cb..0000000
--- a/example/ios/Podfile
+++ /dev/null
@@ -1,74 +0,0 @@
-# Uncomment this line to define a global platform for your project
-# platform :ios, '9.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 parse_KV_file(file, separator='=')
- file_abs_path = File.expand_path(file)
- if !File.exists? file_abs_path
- return [];
- end
- pods_ary = []
- skip_line_start_symbols = ["#", "/"]
- File.foreach(file_abs_path) { |line|
- next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
- plugin = line.split(pattern=separator)
- if plugin.length == 2
- podname = plugin[0].strip()
- path = plugin[1].strip()
- podpath = File.expand_path("#{path}", file_abs_path)
- pods_ary.push({:name => podname, :path => podpath});
- else
- puts "Invalid plugin specification: #{line}"
- end
- }
- return pods_ary
-end
-
-target 'Runner' do
- use_frameworks!
-
- # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
- # referring to absolute paths on developers' machines.
- system('rm -rf .symlinks')
- system('mkdir -p .symlinks/plugins')
-
- # Flutter Pods
- generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig')
- if generated_xcode_build_settings.empty?
- puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first."
- end
- generated_xcode_build_settings.map { |p|
- if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
- symlink = File.join('.symlinks', 'flutter')
- File.symlink(File.dirname(p[:path]), symlink)
- pod 'Flutter', :path => File.join(symlink, File.basename(p[:path]))
- end
- }
-
- # Plugin Pods
- plugin_pods = parse_KV_file('../.flutter-plugins')
- plugin_pods.map { |p|
- symlink = File.join('.symlinks', 'plugins', p[:name])
- File.symlink(p[:path], symlink)
- pod p[:name], :path => File.join(symlink, 'ios')
- }
-end
-
-# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
-install! 'cocoapods', :disable_input_output_paths => true
-
-post_install do |installer|
- installer.pods_project.targets.each do |target|
- target.build_configurations.each do |config|
- config.build_settings['ENABLE_BITCODE'] = 'NO'
- end
- end
-end
diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj
index 7d30b69..0d45b98 100644
--- a/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/example/ios/Runner.xcodeproj/project.pbxproj
@@ -14,7 +14,6 @@
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
- 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
@@ -153,7 +152,7 @@
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
- LastSwiftMigration = 0910;
+ LastSwiftMigration = 1100;
};
};
};
@@ -182,7 +181,6 @@
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
- 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
@@ -298,6 +296,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
@@ -324,7 +323,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
- SWIFT_VERSION = 4.0;
+ SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
@@ -430,6 +429,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
@@ -458,7 +458,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_VERSION = 4.0;
+ SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
@@ -484,7 +484,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
- SWIFT_VERSION = 4.0;
+ SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
@@ -513,7 +513,6 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
-
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
diff --git a/example/lib/main.dart b/example/lib/main.dart
index 0528620..318094b 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -137,14 +137,15 @@ class WeatherSearch extends SearchDelegate {
return FutureBuilder(
future: repo.fetchCityWeather(city["id"]),
builder: (context, snapshot) {
- if (!snapshot.hasData) {
+ if (snapshot.hasError) {
return Center(
- child: CircularProgressIndicator(),
+ child: Text(snapshot.error),
);
}
- if (snapshot.hasError) {
+
+ if (!snapshot.hasData) {
return Center(
- child: Text(snapshot.error),
+ child: CircularProgressIndicator(),
);
}
final weather = snapshot.data;
@@ -261,7 +262,10 @@ class WeatherRepository {
if (response.statusCode == 200) {
parsedWeather = json.decode(response.body);
} else {
- throw Exception("Error while fetching. \n ${response.body}");
+ return Future.error(
+ "Error while fetching.",
+ StackTrace.fromString("${response.body}"),
+ );
}
} catch (e) {
print(e);
diff --git a/example/pubspec.lock b/example/pubspec.lock
index 71d5064..7eaf55f 100644
--- a/example/pubspec.lock
+++ b/example/pubspec.lock
@@ -1,13 +1,27 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
+ archive:
+ dependency: transitive
+ description:
+ name: archive
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.11"
+ args:
+ dependency: transitive
+ description:
+ name: args
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.5.2"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
- version: "2.3.0"
+ version: "2.4.0"
boolean_selector:
dependency: transitive
description:
@@ -29,6 +43,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.11"
+ convert:
+ dependency: transitive
+ description:
+ name: convert
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.1.1"
+ crypto:
+ dependency: transitive
+ description:
+ name: crypto
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.1.3"
cupertino_icons:
dependency: "direct main"
description:
@@ -67,20 +95,27 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.3"
+ image:
+ dependency: transitive
+ description:
+ name: image
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.1.4"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
- version: "0.12.5"
+ version: "0.12.6"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
- version: "1.1.7"
+ version: "1.1.8"
path:
dependency: transitive
description:
@@ -95,6 +130,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0+1"
+ petitparser:
+ dependency: transitive
+ description:
+ name: petitparser
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.4.0"
quiver:
dependency: transitive
description:
@@ -148,7 +190,7 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
- version: "0.2.5"
+ version: "0.2.11"
typed_data:
dependency: transitive
description:
@@ -163,5 +205,12 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
+ xml:
+ dependency: transitive
+ description:
+ name: xml
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "3.5.0"
sdks:
- dart: ">=2.2.2 <3.0.0"
+ dart: ">=2.4.0 <3.0.0"
diff --git a/example/pubspec.yaml b/example/pubspec.yaml
index 05b761a..e04274b 100644
--- a/example/pubspec.yaml
+++ b/example/pubspec.yaml
@@ -1,5 +1,6 @@
name: http_interceptor_example
description: Demonstrates how to use the http_interceptor plugin.
+version: 0.0.1+1
publish_to: 'none'
environment:
@@ -8,9 +9,6 @@ environment:
dependencies:
flutter:
sdk: flutter
-
- # The following adds the Cupertino Icons font to your application.
- # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
dev_dependencies:
@@ -20,44 +18,5 @@ dev_dependencies:
http_interceptor:
path: ../
-# For information on the generic Dart part of this file, see the
-# following page: https://www.dartlang.org/tools/pub/pubspec
-
-# The following section is specific to Flutter.
flutter:
-
- # The following line ensures that the Material Icons font is
- # included with your application, so that you can use the icons in
- # the material Icons class.
uses-material-design: true
-
- # To add assets to your application, add an assets section, like this:
- # assets:
- # - images/a_dot_burr.jpeg
- # - images/a_dot_ham.jpeg
-
- # An image asset can refer to one or more resolution-specific "variants", see
- # https://flutter.io/assets-and-images/#resolution-aware.
-
- # For details regarding adding assets from package dependencies, see
- # https://flutter.io/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.io/custom-fonts/#from-packages
diff --git a/ios/.gitignore b/ios/.gitignore
deleted file mode 100644
index aa479fd..0000000
--- a/ios/.gitignore
+++ /dev/null
@@ -1,37 +0,0 @@
-.idea/
-.vagrant/
-.sconsign.dblite
-.svn/
-
-.DS_Store
-*.swp
-profile
-
-DerivedData/
-build/
-GeneratedPluginRegistrant.h
-GeneratedPluginRegistrant.m
-
-.generated/
-
-*.pbxuser
-*.mode1v3
-*.mode2v3
-*.perspectivev3
-
-!default.pbxuser
-!default.mode1v3
-!default.mode2v3
-!default.perspectivev3
-
-xcuserdata
-
-*.moved-aside
-
-*.pyc
-*sync/
-Icon?
-.tags*
-
-/Flutter/Generated.xcconfig
-/Flutter/flutter_export_environment.sh
\ No newline at end of file
diff --git a/ios/Assets/.gitkeep b/ios/Assets/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/ios/Classes/HttpInterceptorPlugin.h b/ios/Classes/HttpInterceptorPlugin.h
deleted file mode 100644
index 0f1f54b..0000000
--- a/ios/Classes/HttpInterceptorPlugin.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#import
-
-@interface HttpInterceptorPlugin : NSObject
-@end
diff --git a/ios/Classes/HttpInterceptorPlugin.m b/ios/Classes/HttpInterceptorPlugin.m
deleted file mode 100644
index 2115192..0000000
--- a/ios/Classes/HttpInterceptorPlugin.m
+++ /dev/null
@@ -1,8 +0,0 @@
-#import "HttpInterceptorPlugin.h"
-#import
-
-@implementation HttpInterceptorPlugin
-+ (void)registerWithRegistrar:(NSObject*)registrar {
- [SwiftHttpInterceptorPlugin registerWithRegistrar:registrar];
-}
-@end
diff --git a/ios/Classes/SwiftHttpInterceptorPlugin.swift b/ios/Classes/SwiftHttpInterceptorPlugin.swift
deleted file mode 100644
index 5b0cde1..0000000
--- a/ios/Classes/SwiftHttpInterceptorPlugin.swift
+++ /dev/null
@@ -1,14 +0,0 @@
-import Flutter
-import UIKit
-
-public class SwiftHttpInterceptorPlugin: NSObject, FlutterPlugin {
- public static func register(with registrar: FlutterPluginRegistrar) {
- let channel = FlutterMethodChannel(name: "http_interceptor", binaryMessenger: registrar.messenger())
- let instance = SwiftHttpInterceptorPlugin()
- registrar.addMethodCallDelegate(instance, channel: channel)
- }
-
- public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
- result("iOS " + UIDevice.current.systemVersion)
- }
-}
diff --git a/ios/http_interceptor.podspec b/ios/http_interceptor.podspec
deleted file mode 100644
index e7d8d93..0000000
--- a/ios/http_interceptor.podspec
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
-#
-Pod::Spec.new do |s|
- s.name = 'http_interceptor'
- s.version = '0.0.1'
- s.summary = 'A new flutter plugin project.'
- s.description = <<-DESC
-A new flutter plugin project.
- DESC
- s.homepage = 'http://example.com'
- s.license = { :file => '../LICENSE' }
- s.author = { 'Your Company' => 'email@example.com' }
- s.source = { :path => '.' }
- s.source_files = 'Classes/**/*'
- s.public_header_files = 'Classes/**/*.h'
- s.dependency 'Flutter'
-
- s.ios.deployment_target = '8.0'
-end
-
diff --git a/lib/http_client_with_interceptor.dart b/lib/http_client_with_interceptor.dart
index 541054c..cd9c959 100644
--- a/lib/http_client_with_interceptor.dart
+++ b/lib/http_client_with_interceptor.dart
@@ -6,6 +6,7 @@ import 'package:http/http.dart' as http;
import 'package:http/http.dart';
import 'package:http_interceptor/models/models.dart';
import 'package:http_interceptor/interceptor_contract.dart';
+import 'package:http_interceptor/utils.dart';
import 'http_methods.dart';
@@ -42,11 +43,13 @@ class HttpClientWithInterceptor extends http.BaseClient {
HttpClientWithInterceptor._internal({this.interceptors, this.requestTimeout});
factory HttpClientWithInterceptor.build({
- List interceptors,
+ @required List interceptors,
Duration requestTimeout,
}) {
+ assert(interceptors != null);
+
//Remove any value that is null.
- interceptors?.removeWhere((interceptor) => interceptor == null);
+ interceptors.removeWhere((interceptor) => interceptor == null);
return HttpClientWithInterceptor._internal(
interceptors: interceptors,
requestTimeout: requestTimeout,
@@ -123,25 +126,15 @@ class HttpClientWithInterceptor extends http.BaseClient {
Future _sendUnstreamed({
@required Method method,
- @required String url,
+ @required url,
@required Map headers,
Map params,
dynamic body,
Encoding encoding,
}) async {
- String paramUrl = url;
- if (params != null && params.length > 0) {
- paramUrl += "?";
- params.forEach((key, value) {
- paramUrl += "$key=$value&";
- });
- paramUrl = paramUrl.substring(
- 0, paramUrl.length - 1); // to remove the last '&' character
- }
-
- var requestUrl = Uri.parse(paramUrl);
- var request = new Request(methodToString(method), requestUrl);
+ if (url is String) url = Uri.parse(addParametersToUrl(url, params));
+ Request request = new Request(methodToString(method), url);
if (headers != null) request.headers.addAll(headers);
if (encoding != null) request.encoding = encoding;
if (body != null) {
@@ -156,13 +149,8 @@ class HttpClientWithInterceptor extends http.BaseClient {
}
}
- //Perform request interception
- for (InterceptorContract interceptor in interceptors) {
- RequestData interceptedData = await interceptor.interceptRequest(
- data: RequestData.fromHttpRequest(request),
- );
- request = interceptedData.toHttpRequest();
- }
+ // Intercept request
+ await _interceptRequest(request);
var stream = requestTimeout == null
? await send(request)
@@ -170,12 +158,10 @@ class HttpClientWithInterceptor extends http.BaseClient {
var response = await Response.fromStream(stream);
- var responseData = ResponseData.fromHttpResponse(response);
- for (InterceptorContract interceptor in interceptors) {
- responseData = await interceptor.interceptResponse(data: responseData);
- }
+ // Intercept response
+ response = await _interceptResponse(response);
- return responseData.toHttpResponse();
+ return response;
}
void _checkResponseSuccess(url, Response response) {
@@ -188,6 +174,30 @@ class HttpClientWithInterceptor extends http.BaseClient {
throw new ClientException("$message.", url);
}
+ /// This internal function intercepts the request.
+ Future _interceptRequest(Request request) async {
+ for (InterceptorContract interceptor in interceptors) {
+ RequestData interceptedData = await interceptor.interceptRequest(
+ data: RequestData.fromHttpRequest(request),
+ );
+ request = interceptedData.toHttpRequest();
+ }
+
+ return request;
+ }
+
+ /// This internal function intercepts the response.
+ Future _interceptResponse(Response response) async {
+ for (InterceptorContract interceptor in interceptors) {
+ ResponseData responseData = await interceptor.interceptResponse(
+ data: ResponseData.fromHttpResponse(response),
+ );
+ response = responseData.toHttpResponse();
+ }
+
+ return response;
+ }
+
void close() {
_client.close();
}
diff --git a/lib/http_with_interceptor.dart b/lib/http_with_interceptor.dart
index 15ac2e9..19e9b55 100644
--- a/lib/http_with_interceptor.dart
+++ b/lib/http_with_interceptor.dart
@@ -3,8 +3,7 @@ import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
-import 'package:http_interceptor/http_methods.dart';
-import 'package:http_interceptor/models/models.dart';
+import 'package:http_interceptor/http_interceptor.dart';
import 'package:http_interceptor/interceptor_contract.dart';
///Class to be used by the user as a replacement for 'http' with interceptor supported.
@@ -36,69 +35,48 @@ class HttpWithInterceptor {
});
factory HttpWithInterceptor.build({
- List interceptors,
+ @required List interceptors,
Duration requestTimeout,
}) {
+ assert(interceptors != null);
+
//Remove any value that is null.
interceptors?.removeWhere((interceptor) => interceptor == null);
return new HttpWithInterceptor._internal(
- interceptors: interceptors, requestTimeout: requestTimeout);
+ interceptors: interceptors,
+ requestTimeout: requestTimeout,
+ );
}
Future head(url, {Map headers}) async {
- await _sendInterception(method: Method.HEAD, headers: headers, url: url);
return _withClient((client) => client.head(url, headers: headers));
}
Future get(url,
{Map headers, Map params}) async {
- RequestData data = await _sendInterception(
- method: Method.GET, headers: headers, url: url, params: params);
- return _withClient(
- (client) => client.get(data.requestUrl, headers: data.headers));
+ return _withClient((client) => client.get(url, headers: headers, params: params));
}
Future post(url,
{Map headers, body, Encoding encoding}) async {
- RequestData data = await _sendInterception(
- method: Method.POST,
- headers: headers,
- url: url,
- body: body,
- encoding: encoding);
- return _withClient((client) => client.post(data.url,
- headers: data.headers, body: data.body, encoding: data.encoding));
+ return _withClient((client) =>
+ client.post(url, headers: headers, body: body, encoding: encoding));
}
Future put(url,
{Map headers, body, Encoding encoding}) async {
- RequestData data = await _sendInterception(
- method: Method.PUT,
- headers: headers,
- url: url,
- body: body,
- encoding: encoding);
- return _withClient((client) => client.put(data.url,
- headers: data.headers, body: data.body, encoding: data.encoding));
+ return _withClient((client) =>
+ client.put(url, headers: headers, body: body, encoding: encoding));
}
Future patch(url,
{Map headers, body, Encoding encoding}) async {
- RequestData data = await _sendInterception(
- method: Method.PATCH,
- headers: headers,
- url: url,
- body: body,
- encoding: encoding);
- return _withClient((client) => client.patch(data.url,
- headers: data.headers, body: data.body, encoding: data.encoding));
+ return _withClient((client) =>
+ client.patch(url, headers: headers, body: body, encoding: encoding));
}
Future delete(url, {Map headers}) async {
- RequestData data = await _sendInterception(
- method: Method.DELETE, headers: headers, url: url);
- return _withClient(
- (client) => client.delete(data.url, headers: data.headers));
+ return _withClient((client) => client.delete(url, headers: headers));
}
Future read(url, {Map headers}) {
@@ -108,48 +86,14 @@ class HttpWithInterceptor {
Future readBytes(url, {Map headers}) =>
_withClient((client) => client.readBytes(url, headers: headers));
- Future _sendInterception({
- @required Method method,
- @required String url,
- @required Map headers,
- Map params,
- dynamic body,
- Encoding encoding,
- }) async {
- RequestData data = RequestData(
- method: method,
- encoding: encoding,
- body: body,
- url: url,
- headers: headers ?? {},
- params: params ?? {},
+ Future _withClient(
+ Future fn(HttpClientWithInterceptor client)) async {
+ var client = new HttpClientWithInterceptor.build(
+ interceptors: interceptors,
+ requestTimeout: requestTimeout,
);
-
- //Perform request interception
- for (InterceptorContract interceptor in interceptors) {
- data = await interceptor.interceptRequest(
- data: data,
- );
- }
- return data;
- }
-
- Future _withClient(Future fn(Client client)) async {
- var client = new Client();
try {
- T response = requestTimeout == null
- ? await fn(client)
- : await fn(client).timeout(requestTimeout);
- if (response is Response) {
- var responseData = ResponseData.fromHttpResponse(response);
- for (InterceptorContract interceptor in interceptors) {
- responseData =
- await interceptor.interceptResponse(data: responseData);
- }
-
- return responseData.toHttpResponse() as T;
- }
- return response;
+ return await fn(client);
} finally {
client.close();
}
diff --git a/lib/models/models.dart b/lib/models/models.dart
index 0510593..f03bc76 100644
--- a/lib/models/models.dart
+++ b/lib/models/models.dart
@@ -1,2 +1,2 @@
export 'request_data.dart';
-export 'response_data.dart';
\ No newline at end of file
+export 'response_data.dart';
diff --git a/lib/models/request_data.dart b/lib/models/request_data.dart
index 101aa2f..04de9e2 100644
--- a/lib/models/request_data.dart
+++ b/lib/models/request_data.dart
@@ -1,62 +1,51 @@
import 'dart:convert';
+import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:http_interceptor/http_methods.dart';
+import 'package:http_interceptor/utils.dart';
class RequestData {
Method method;
- String url;
+ String baseUrl;
Map headers;
Map params;
dynamic body;
Encoding encoding;
RequestData({
- this.method,
- this.url,
+ @required this.method,
+ @required this.baseUrl,
this.headers,
this.params,
this.body,
this.encoding,
- });
+ }) : assert(method != null),
+ assert(baseUrl != null);
- String get requestUrl {
- var paramUrl = url;
- if (params != null && params.length > 0) {
- paramUrl += "?";
- params.forEach((key, value) {
- paramUrl += "$key=$value&";
- });
- paramUrl = paramUrl.substring(0, paramUrl.length);
- }
- return paramUrl;
- }
+ String get url => addParametersToUrl(baseUrl, params);
factory RequestData.fromHttpRequest(Request request) {
var params = Map();
request.url.queryParameters.forEach((key, value) {
params[key] = value;
});
+ String baseUrl = request.url.origin + request.url.path;
return RequestData(
method: methodFromString(request.method),
encoding: request.encoding,
body: request.body,
- url: request.url.toString(),
+ baseUrl: baseUrl,
headers: request.headers ?? {},
params: params ?? {},
);
}
Request toHttpRequest() {
- var paramUrl = url;
- if (params != null && params.length > 0) {
- paramUrl += "?";
- params.forEach((key, value) {
- paramUrl += "$key=$value&";
- });
- paramUrl = paramUrl.substring(0, paramUrl.length);
- }
- var request = new Request(methodToString(method), Uri.parse(paramUrl));
+ var reqUrl = Uri.parse(addParametersToUrl(baseUrl, params));
+
+ Request request = new Request(methodToString(method), reqUrl);
+
if (headers != null) request.headers.addAll(headers);
if (encoding != null) request.encoding = encoding;
if (body != null) {
diff --git a/lib/utils.dart b/lib/utils.dart
new file mode 100644
index 0000000..25a3cbf
--- /dev/null
+++ b/lib/utils.dart
@@ -0,0 +1,18 @@
+/// When having an URL as String and no parameters sent then it adds
+/// them to the string.
+String addParametersToUrl(String url, Map parameters) {
+ if (parameters == null) return url;
+
+ String paramUrl = url;
+ if (parameters != null && parameters.length > 0) {
+ if (paramUrl.contains("?"))
+ paramUrl += "&";
+ else
+ paramUrl += "?";
+ parameters.forEach((key, value) {
+ paramUrl += "$key=$value&";
+ });
+ paramUrl = paramUrl.substring(0, paramUrl.length - 1);
+ }
+ return paramUrl;
+}
diff --git a/pubspec.lock b/pubspec.lock
index 5ee37c1..873f69e 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -1,13 +1,27 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
+ archive:
+ dependency: transitive
+ description:
+ name: archive
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.11"
+ args:
+ dependency: transitive
+ description:
+ name: args
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.5.2"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
- version: "2.3.0"
+ version: "2.4.0"
boolean_selector:
dependency: transitive
description:
@@ -29,13 +43,27 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.11"
+ convert:
+ dependency: transitive
+ description:
+ name: convert
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.1.1"
+ crypto:
+ dependency: transitive
+ description:
+ name: crypto
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.1.3"
effective_dart:
dependency: "direct dev"
description:
name: effective_dart
url: "https://pub.dartlang.org"
source: hosted
- version: "1.1.1"
+ version: "1.2.1"
flutter:
dependency: "direct main"
description: flutter
@@ -60,20 +88,27 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.3"
+ image:
+ dependency: transitive
+ description:
+ name: image
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.1.4"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
- version: "0.12.5"
+ version: "0.12.6"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
- version: "1.1.7"
+ version: "1.1.8"
path:
dependency: transitive
description:
@@ -88,6 +123,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0+1"
+ petitparser:
+ dependency: transitive
+ description:
+ name: petitparser
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.4.0"
quiver:
dependency: transitive
description:
@@ -141,7 +183,7 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
- version: "0.2.5"
+ version: "0.2.11"
typed_data:
dependency: transitive
description:
@@ -156,5 +198,12 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
+ xml:
+ dependency: transitive
+ description:
+ name: xml
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "3.5.0"
sdks:
- dart: ">=2.2.2 <3.0.0"
+ dart: ">=2.4.0 <3.0.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index 6033c7d..a539e80 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,7 +1,6 @@
name: http_interceptor
description: A lightweight, simple plugin that allows you to intercept request and response objects and modify them if desired.
version: 0.1.1
-author: Alejandro Ulate (codingalecr)
homepage: https://github.com/CodingAleCR/http_interceptor
environment:
@@ -15,11 +14,7 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
- effective_dart: ^1.1.0
+ effective_dart: ^1.2.1
flutter:
- plugin:
- androidPackage: codingalecr.http_interceptor
- pluginClass: HttpInterceptorPlugin
-
diff --git a/test/http_methods_test.dart b/test/http_methods_test.dart
new file mode 100644
index 0000000..bc0f83e
--- /dev/null
+++ b/test/http_methods_test.dart
@@ -0,0 +1,142 @@
+import 'package:flutter_test/flutter_test.dart';
+import 'package:http_interceptor/http_methods.dart';
+
+main() {
+ group("Can parse from string", () {
+ test("with HEAD method", () {
+ // Arrange
+ Method method;
+ String methodString = "HEAD";
+
+ // Act
+ method = methodFromString(methodString);
+
+ // Assert
+ expect(method, equals(Method.HEAD));
+ });
+ test("with GET method", () {
+ // Arrange
+ Method method;
+ String methodString = "GET";
+
+ // Act
+ method = methodFromString(methodString);
+
+ // Assert
+ expect(method, equals(Method.GET));
+ });
+ test("with POST method", () {
+ // Arrange
+ Method method;
+ String methodString = "POST";
+
+ // Act
+ method = methodFromString(methodString);
+
+ // Assert
+ expect(method, equals(Method.POST));
+ });
+ test("with PUT method", () {
+ // Arrange
+ Method method;
+ String methodString = "PUT";
+
+ // Act
+ method = methodFromString(methodString);
+
+ // Assert
+ expect(method, equals(Method.PUT));
+ });
+ test("with PATCH method", () {
+ // Arrange
+ Method method;
+ String methodString = "PATCH";
+
+ // Act
+ method = methodFromString(methodString);
+
+ // Assert
+ expect(method, equals(Method.PATCH));
+ });
+ test("with DELETE method", () {
+ // Arrange
+ Method method;
+ String methodString = "DELETE";
+
+ // Act
+ method = methodFromString(methodString);
+
+ // Assert
+ expect(method, equals(Method.DELETE));
+ });
+ });
+
+ group("Can parse to string", () {
+ test("to 'HEAD' string." , () {
+ // Arrange
+ String methodString;
+ Method method = Method.HEAD;
+
+ // Act
+ methodString = methodToString(method);
+
+ // Assert
+ expect(methodString, equals("HEAD"));
+ });
+ test("to 'GET' string." , () {
+ // Arrange
+ String methodString;
+ Method method = Method.GET;
+
+ // Act
+ methodString = methodToString(method);
+
+ // Assert
+ expect(methodString, equals("GET"));
+ });
+ test("to 'POST' string." , () {
+ // Arrange
+ String methodString;
+ Method method = Method.POST;
+
+ // Act
+ methodString = methodToString(method);
+
+ // Assert
+ expect(methodString, equals("POST"));
+ });
+ test("to 'PUT' string." , () {
+ // Arrange
+ String methodString;
+ Method method = Method.PUT;
+
+ // Act
+ methodString = methodToString(method);
+
+ // Assert
+ expect(methodString, equals("PUT"));
+ });
+ test("to 'PATCH' string." , () {
+ // Arrange
+ String methodString;
+ Method method = Method.PATCH;
+
+ // Act
+ methodString = methodToString(method);
+
+ // Assert
+ expect(methodString, equals("PATCH"));
+ });
+ test("to 'DELETE' string." , () {
+ // Arrange
+ String methodString;
+ Method method = Method.DELETE;
+
+ // Act
+ methodString = methodToString(method);
+
+ // Assert
+ expect(methodString, equals("DELETE"));
+ });
+ });
+}
diff --git a/test/models/request_data_test.dart b/test/models/request_data_test.dart
new file mode 100644
index 0000000..cf72481
--- /dev/null
+++ b/test/models/request_data_test.dart
@@ -0,0 +1,89 @@
+import 'package:flutter_test/flutter_test.dart';
+import 'package:http/http.dart';
+import 'package:http_interceptor/models/request_data.dart';
+import 'package:http_interceptor/http_methods.dart';
+
+main() {
+ group("Initialization: ", () {
+ test("can be instantiated", () {
+ // Arrange
+ RequestData requestData;
+
+ // Act
+ requestData = RequestData(
+ method: Method.GET, baseUrl: "https://www.google.com/helloworld");
+
+ // Assert
+ expect(requestData, isNotNull);
+ });
+ test("can be instantiated from HTTP GET Request", () {
+ // Arrange
+ Uri url = Uri.parse("https://www.google.com/helloworld");
+
+ Request request = Request("GET", url);
+ RequestData requestData;
+
+ // Act
+ requestData = RequestData.fromHttpRequest(request);
+
+ // Assert
+ expect(requestData, isNotNull);
+ expect(requestData.method, equals(Method.GET));
+ expect(requestData.url, equals("https://www.google.com/helloworld"));
+ });
+ test("can be instantiated from HTTP GET Request with long path", () {
+ // Arrange
+ Uri url = Uri.parse("https://www.google.com/helloworld/foo/bar");
+
+ Request request = Request("GET", url);
+ RequestData requestData;
+
+ // Act
+ requestData = RequestData.fromHttpRequest(request);
+
+ // Assert
+ expect(requestData, isNotNull);
+ expect(requestData.method, equals(Method.GET));
+ expect(requestData.url, equals("https://www.google.com/helloworld/foo/bar"));
+ });
+ test("can be instantiated from HTTP GET Request with parameters", () {
+ // Arrange
+ Uri url = Uri.parse(
+ "https://www.google.com/helloworld?key=123ABC&name=Hugo&type=3");
+
+ Request request = Request("GET", url);
+ RequestData requestData;
+
+ // Act
+ requestData = RequestData.fromHttpRequest(request);
+
+ // Assert
+ expect(requestData, isNotNull);
+ expect(requestData.method, equals(Method.GET));
+ expect(requestData.baseUrl, equals("https://www.google.com/helloworld"));
+ expect(
+ requestData.url,
+ equals(
+ "https://www.google.com/helloworld?key=123ABC&name=Hugo&type=3"));
+ });
+ test("correctly creates the request URL string", () {
+ // Arrange
+ Uri url = Uri.parse(
+ "https://www.google.com/helloworld?key=123ABC&name=Hugo&type=3");
+
+ Request request = Request("GET", url);
+ RequestData requestData;
+
+ // Act
+ requestData = RequestData.fromHttpRequest(request);
+
+ // Assert
+ expect(requestData, isNotNull);
+ expect(requestData.method, equals(Method.GET));
+ expect(
+ requestData.url,
+ equals(
+ "https://www.google.com/helloworld?key=123ABC&name=Hugo&type=3"));
+ });
+ });
+}
diff --git a/test/models/response_data_test.dart b/test/models/response_data_test.dart
new file mode 100644
index 0000000..202b0ed
--- /dev/null
+++ b/test/models/response_data_test.dart
@@ -0,0 +1,17 @@
+import 'package:flutter_test/flutter_test.dart';
+import 'package:http_interceptor/models/response_data.dart';
+
+main() {
+ group("Initialization", () {
+ test("ResponseData can be instantiated", () {
+ // Arrange
+ ResponseData requestData;
+
+ // Act
+ requestData = ResponseData();
+
+ // Assert
+ expect(requestData, isNotNull);
+ });
+ });
+}
diff --git a/test/utils_test.dart b/test/utils_test.dart
new file mode 100644
index 0000000..4d7032c
--- /dev/null
+++ b/test/utils_test.dart
@@ -0,0 +1,33 @@
+import 'package:flutter_test/flutter_test.dart';
+import 'package:http_interceptor/utils.dart';
+
+main() {
+ group("addParametersToUrl", () {
+ test("Adds parameters to a URL string without parameters", () {
+ // Arrange
+ String url = "https://www.google.com/helloworld";
+ Map parameters = {"foo": "bar", "num": "0"};
+
+ // Act
+ String parameterUrl = addParametersToUrl(url, parameters);
+
+ // Assert
+ expect(parameterUrl,
+ equals("https://www.google.com/helloworld?foo=bar&num=0"));
+ });
+ test("Adds parameters to a URL string with parameters", () {
+ // Arrange
+ String url = "https://www.google.com/helloworld?foo=bar&num=0";
+ Map parameters = {"extra": "1", "extra2": "anotherone"};
+
+ // Act
+ String parameterUrl = addParametersToUrl(url, parameters);
+
+ // Assert
+ expect(
+ parameterUrl,
+ equals(
+ "https://www.google.com/helloworld?foo=bar&num=0&extra=1&extra2=anotherone"));
+ });
+ });
+}