Skip to content

Commit 6066a7e

Browse files
Use {argName} for validating deep link arguments
While in many cases query parameters are in the form of myarg={myarg}, this should never be a hard requirement. Instead, only the value within braces (what is actually used as the argument name) should be used when validating that all required arguments are present in the NavDeepLink. Relnote: "Fixed a regression introduced in [Navigation `2.4.0-alpha09`](#2.4.0-alpha09) when using deep links with query parameters where Navigation would incorrectly validate argument names using the query parameter name (i.e., the `id` of `?id={userId}`) rather than using the actual argument names present in the value (the `userId` in the example above)." Test: new NavDestinationAndroidTest tests pass BUG: 200845660 Change-Id: Id2f399a5e19e593f34e02fc811f1cc28ec0689b8
1 parent ddc7cd2 commit 6066a7e

2 files changed

Lines changed: 40 additions & 2 deletions

File tree

navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDestinationAndroidTest.kt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,44 @@ class NavDestinationAndroidTest {
111111
.isEqualTo(43)
112112
}
113113

114+
@Test
115+
fun matchDeepLinkWithQueryParams() {
116+
val destination = NoOpNavigator().createDestination()
117+
destination.addArgument("id", intArgument())
118+
destination.addDeepLink("www.example.com/users?id={id}")
119+
120+
val match = destination.matchDeepLink(
121+
Uri.parse("https://www.example.com/users?id=43")
122+
)
123+
124+
assertWithMessage("Deep link should match")
125+
.that(match)
126+
.isNotNull()
127+
128+
assertWithMessage("Deep link should extract id argument correctly")
129+
.that(match?.matchingArgs?.getInt("id"))
130+
.isEqualTo(43)
131+
}
132+
133+
@Test
134+
fun matchDeepLinkWithNonMatchingQueryParams() {
135+
val destination = NoOpNavigator().createDestination()
136+
destination.addArgument("id", intArgument())
137+
destination.addDeepLink("www.example.com/users?userId={id}")
138+
139+
val match = destination.matchDeepLink(
140+
Uri.parse("https://www.example.com/users?userId=43")
141+
)
142+
143+
assertWithMessage("Deep link should match")
144+
.that(match)
145+
.isNotNull()
146+
147+
assertWithMessage("Deep link should extract id argument correctly")
148+
.that(match?.matchingArgs?.getInt("id"))
149+
.isEqualTo(43)
150+
}
151+
114152
@Test
115153
fun matchDeepLinkBestMatchExact() {
116154
val destination = NoOpNavigator().createDestination()

navigation/navigation-common/src/main/java/androidx/navigation/NavDeepLink.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public class NavDeepLink internal constructor(
5656

5757
/** Arguments present in the deep link, including both path and query arguments. */
5858
internal val argumentsNames: List<String>
59-
get() = arguments + paramArgMap.keys
59+
get() = arguments + paramArgMap.values.flatMap { it.arguments }
6060

6161
public var isExactDeepLink: Boolean = false
6262
/** @suppress */
@@ -234,7 +234,7 @@ public class NavDeepLink internal constructor(
234234
*/
235235
private class ParamQuery {
236236
var paramRegex: String? = null
237-
private val arguments = mutableListOf<String>()
237+
val arguments = mutableListOf<String>()
238238

239239
fun addArgumentName(name: String) {
240240
arguments.add(name)

0 commit comments

Comments
 (0)