Skip to content

Commit

Permalink
- Expand PathQueryCondition to enable matching requests on multiple…
Browse files Browse the repository at this point in the history
… query parameters (per issue [#16](#16))

- Compatibility is maintained with previous versions
  • Loading branch information
abcarrell authored and koral-- committed Aug 2, 2023
1 parent 3748ca3 commit c577672
Show file tree
Hide file tree
Showing 6 changed files with 268 additions and 31 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
### 1.1.7 - 01.08.2023

- Expand `PathQueryCondition` to enable matching requests on multiple query parameters (per issue [#16](https://github.com/DroidsOnRoids/mockwebserver-path-dispatcher/issues/16))
- Compatibility is maintained with previous versions

### 1.1.6 - 09.01.2023

- Add option to mock timeout failure

### 1.1.5 - 01.12.2022

- Make FixtureDispatcher thread-safe
Expand Down
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ fun factory() {
dispatcher.putResponse(factory.withPathSuffixAndQueryParameter("suffix", "param"), "response_with_query_parameter")
// match all URLs with path ending with "suffix" and have "param" with "value" as query parameter e.g. http://example.test/prefix/user/suffix?param=value
dispatcher.putResponse(factory.withPathSuffixAndQueryParameter("suffix", "param", "value"), "response_with_query_parameter_and_value")
// match all URLs with path ending with "suffix" and have multiple parameter name/value pairs e.g.http://example.test/prefix/user/suffix?param=value&param2=value2
dispatcher.putResponse(
factory.withPathSuffixAndQueryParameters("suffix", mapOf("param" to "value", "param2" to "value2")),
"response_with_multiple_query_parameters"
)
mockWebServer.setDispatcher(dispatcher)
}
```
Expand All @@ -140,6 +145,15 @@ fun pathQueryCondition() {
}
```
Also supports a map of multiple query parameters:

```kotlin
fun pathQueryConditions() {
val dispatcher = FixtureDispatcher()
dispatcher.putResponse(PathQueryCondition("/prefix/suffix", mapOf("param" to "value", "param2" to "value2")), "response_with_query_parameters_and_values")
mockWebServer.setDispatcher(dispatcher)
}
```

`HttpUrlCondition` - when you want to match by some part of URL other than path or single query
parameter:
Expand Down Expand Up @@ -175,15 +189,15 @@ fun condition() {
For unit tests:

```gradle
testImplementation 'pl.droidsonroids.testing:mockwebserver-path-dispatcher:1.1.1'
testImplementation 'pl.droidsonroids.testing:mockwebserver-path-dispatcher:1.1.7'
```

or for Android instrumentation tests:

```gradle
androidTestImplementation 'pl.droidsonroids.testing:mockwebserver-path-dispatcher:1.1.1'
androidTestImplementation 'pl.droidsonroids.testing:mockwebserver-path-dispatcher:1.1.7'
```

### License

Library uses the MIT License. See [LICENSE](LICENSE) file.
Library uses the MIT License. See [LICENSE](LICENSE) file.
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,36 @@ package pl.droidsonroids.testing.mockwebserver.condition
import okhttp3.HttpUrl

/**
* A [Condition] matching by URL path, optional query parameter name and optional query parameter value for that name.
* Instances are sorted from least to most general e.g. one containing query parameter name comes before
* another containing path only.
* A [Condition] matching by URL path and a [Map] of query parameter name/value pairs.
* Instances are sorted from least to most general, based on the number of specified query parameter names and
* the corresponding non-null values.
* @property path URL path, required
* @property queryParameterName query parameter name, optional
* @property queryParameterName query parameter value for given name, optional
* @property httpMethod [HTTPMethod] to map to for the given condition, optional
* @property queryParameters [Map] query parameter name/value pairs, optional, defaulting to an empty map
*/
data class PathQueryCondition(
internal val path: String,
override val httpMethod: HTTPMethod,
internal val queryParameterName: String? = null,
internal val queryParameterValue: String? = null
internal val queryParameters: Map<String, String?> = emptyMap()
) : HttpUrlCondition() {
constructor(path: String, queryParameters: Map<String, String?>) :
this(path, HTTPMethod.ANY, queryParameters)

/**
*
* A [Condition] matching by URL path, optional query parameter name and optional query parameter value for that name.
* Instances are sorted from least to most general e.g. one containing query parameter name comes before
* another containing path only.
* @property path URL path, required
* @property httpMethod [HTTPMethod] to map to for the given condition, optional
* @property queryParameterName query parameter name, optional
* @property queryParameterName query parameter value for given name, optional
*/
constructor(path: String, httpMethod: HTTPMethod, queryParameterName: String, queryParameterValue: String? = null) :
this(path, httpMethod, mapOf(queryParameterName to queryParameterValue))

constructor(path: String, queryParameterName: String, queryParameterValue: String? = null) :
this(path, HTTPMethod.ANY, mapOf(queryParameterName to queryParameterValue))

override fun compareTo(other: Condition) = when {
other == this -> 0
Expand All @@ -26,14 +43,12 @@ data class PathQueryCondition(
}

override fun isUrlMatching(url: HttpUrl): Boolean {
val requestQueryParameterNames = url.queryParameterNames
if (url.encodedPath == path) {
when {
queryParameterName == null -> return true
requestQueryParameterNames.contains(queryParameterName) -> {
val requestQueryParameterValue = url.queryParameter(queryParameterName)
if (queryParameterValue == null || queryParameterValue == requestQueryParameterValue) {
return true
queryParameters.isEmpty() -> return true
queryParameters.keys.all { it in url.queryParameterNames } -> {
return queryParameters.all {
it.value == null || it.value == url.queryParameter(it.key)
}
}
}
Expand All @@ -42,13 +57,6 @@ data class PathQueryCondition(
}

private val score: Int
get() {
if (queryParameterName == null) {
return 0
} else if (queryParameterValue == null) {
return 1
}
return 2
}

get() = queryParameters.keys.count() +
queryParameters.values.count { !it.isNullOrEmpty() }
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,33 @@ package pl.droidsonroids.testing.mockwebserver.condition
* @constructor creates new factory with given prefix
*/
class PathQueryConditionFactory constructor(private val pathPrefix: String = "") {
/**
* Creates condition with <code>path</code> and a <code>Map</code> of one or more query parameter name/value pairs.
* @param pathSuffix path suffix, may be empty
* @param queryParameters <code>Map</code> of query parameter name/value pairs
* @param httpMethod optional HTTPMethod for matching, defaults to HTTPMethod.ANY
* @return a PathQueryCondition
* @since 1.1.7
*/
@JvmOverloads
fun withPathSuffixAndQueryParameters(
pathSuffix: String,
queryParameters: Map<String, String?>,
httpMethod: HTTPMethod = HTTPMethod.ANY
) =
PathQueryCondition(
pathPrefix + pathSuffix,
httpMethod,
queryParameters
)

/**
* Creates condition with both <code>path</code>, <code>queryParameterName</code>
* and <code>queryParameterValue</code>.
* @param pathSuffix path suffix, may be empty
* @param queryParameterName query parameter name <code>queryParameterName</code>
* @param queryParameterValue query parameter value for given
* @param httpMethod optional HTTPMethod for matching, defaults to HTTPMethod.ANY
* @return a PathQueryCondition
* @since 1.1.0
*/
Expand All @@ -33,6 +54,7 @@ class PathQueryConditionFactory constructor(private val pathPrefix: String = "")
/**
* Creates condition with <code>path</code> only.
* @param pathSuffix path suffix, may be empty
* @param httpMethod optional HTTPMethod for matching, defaults to HTTPMethod.ANY
* @return a PathQueryCondition
* @since 1.1.0
*/
Expand All @@ -48,6 +70,7 @@ class PathQueryConditionFactory constructor(private val pathPrefix: String = "")
/**
* Creates condition with <code>path</code> only.
* @param path the path
* @param httpMethod optional HTTPMethod for matching, defaults to HTTPMethod.ANY
* @return a PathQueryCondition
*/
fun withPath(
Expand Down Expand Up @@ -108,4 +131,4 @@ class PathQueryConditionFactory constructor(private val pathPrefix: String = "")
@Deprecated("Infix renamed to suffix", replaceWith = ReplaceWith("withPathSuffix"))
fun withPathInfix(pathInfix: String) =
withPathSuffix(pathInfix)
}
}
Loading

0 comments on commit c577672

Please sign in to comment.