Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,7 @@ class NavDeepLinkTest {
val id = 211
val matchArgs = deepLink.getMatchingArguments(
Uri.parse(deepLinkArgument.replace("{id}", id.toString())),
mapOf(
"id" to intArgument(),
"myarg" to stringArgument()
)
mapOf("id" to intArgument())
)
assertWithMessage("Args should not be null")
.that(matchArgs)
Expand Down Expand Up @@ -332,7 +329,7 @@ class NavDeepLinkTest {

val matchArgs = deepLink.getMatchingArguments(
Uri.parse("$DEEP_LINK_EXACT_HTTPS/users"),
mapOf("myarg" to nullableStringArgument())
mapOf("myarg" to nullableStringArgument(null))
)
assertWithMessage("Args should not be null")
.that(matchArgs)
Expand Down Expand Up @@ -369,7 +366,7 @@ class NavDeepLinkTest {

val matchArgs = deepLink.getMatchingArguments(
Uri.parse(deepLinkArgument),
mapOf("myarg" to nullableStringArgument())
mapOf("myarg" to nullableStringArgument(null))
)
assertWithMessage("Args should not be null")
.that(matchArgs)
Expand Down Expand Up @@ -442,7 +439,7 @@ class NavDeepLinkTest {
Uri.parse("$DEEP_LINK_EXACT_HTTPS/users?id={id}".replace("{id}", id.toString())),
mapOf(
"id" to intArgument(),
"optional" to nullableStringArgument()
"optional" to nullableStringArgument(null)
)
)
assertWithMessage("Args should not be null")
Expand Down Expand Up @@ -536,7 +533,7 @@ class NavDeepLinkTest {

val matchArgs = deepLink.getMatchingArguments(
Uri.parse("$DEEP_LINK_EXACT_HTTPS/users?id={id}&extraParam={extraParam}"),
mapOf("myarg" to nullableStringArgument())
mapOf("myarg" to nullableStringArgument(null))
)
assertWithMessage("Args should not be null")
.that(matchArgs)
Expand Down Expand Up @@ -574,7 +571,7 @@ class NavDeepLinkTest {

val matchArgs = deepLink.getMatchingArguments(
Uri.parse("$DEEP_LINK_EXACT_HTTPS/users"),
mapOf("myarg" to nullableStringArgument())
mapOf("myarg" to nullableStringArgument(null))
)
assertWithMessage("Args should not be null")
.that(matchArgs)
Expand Down Expand Up @@ -627,7 +624,7 @@ class NavDeepLinkTest {

val matchArgs = deepLink.getMatchingArguments(
Uri.parse("$DEEP_LINK_EXACT_HTTPS/users"),
mapOf("myarg" to nullableStringArgument())
mapOf("myarg" to nullableStringArgument(null))
)
assertWithMessage("Args should not be null")
.that(matchArgs)
Expand Down Expand Up @@ -738,8 +735,8 @@ class NavDeepLinkTest {
val matchArgs = deepLink.getMatchingArguments(
Uri.parse("$DEEP_LINK_EXACT_HTTPS/users"),
mapOf(
"first" to nullableStringArgument(),
"last" to nullableStringArgument()
"first" to nullableStringArgument(null),
"last" to nullableStringArgument(null)
)
)
assertWithMessage("Args should not be null")
Expand Down Expand Up @@ -799,7 +796,7 @@ class NavDeepLinkTest {

val matchArgs = deepLink.getMatchingArguments(
Uri.parse("$DEEP_LINK_EXACT_HTTPS/users?productId=wildCardMatch-{myarg}"),
mapOf("myarg" to nullableStringArgument())
mapOf("myarg" to nullableStringArgument(null))
)
assertWithMessage("Args should not be null")
.that(matchArgs)
Expand Down Expand Up @@ -913,7 +910,7 @@ class NavDeepLinkTest {

val matchArgs = deepLink.getMatchingArguments(
Uri.parse("$DEEP_LINK_EXACT_HTTPS/users"),
mapOf("path" to nullableStringArgument())
mapOf("path" to nullableStringArgument(null))
)
assertWithMessage("Args should not be null")
.that(matchArgs)
Expand Down Expand Up @@ -1113,10 +1110,46 @@ class NavDeepLinkTest {
.replace("{param}", param.toString())
val matchArgs = deepLink.getMatchingArguments(
Uri.parse(deepLinkUpper),
mapOf("param" to intArgument())
mapOf("param" to intArgument(0))
)

assertWithMessage("Args should be not be null")
assertWithMessage("Args should not be null")
.that(matchArgs)
.isNotNull()
assertWithMessage("Args bundle should be empty")
.that(matchArgs?.isEmpty)
.isTrue()
}

@Test
fun deepLinkMissingRequiredArgument() {
val deepLinkString = "$DEEP_LINK_EXACT_HTTPS/greeting?title={title}&text={text}"
val deepLink = NavDeepLink(deepLinkString)

val matchArgs = deepLink.getMatchingArguments(
Uri.parse("$DEEP_LINK_EXACT_HTTPS/greeting?title=No%20text"),
mapOf(
"title" to stringArgument(),
"text" to stringArgument()
)
)

assertWithMessage("Args should be null")
.that(matchArgs)
.isNull()
}

@Test
fun deepLinkMissingOptionalArgument() {
val deepLinkString = "$DEEP_LINK_EXACT_HTTPS/greeting?text={text}"
val deepLink = NavDeepLink(deepLinkString)

val matchArgs = deepLink.getMatchingArguments(
Uri.parse("$DEEP_LINK_EXACT_HTTPS/greeting"),
mapOf("text" to stringArgument("Default greeting"))
)

assertWithMessage("Args should not be null")
.that(matchArgs)
.isNotNull()
assertWithMessage("Args bundle should be empty")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import android.os.Bundle
import androidx.core.net.toUri
import androidx.navigation.NavDestination.Companion.createRoute
import androidx.navigation.test.intArgument
import androidx.navigation.test.nullableStringArgument
import androidx.navigation.test.stringArgument
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
Expand Down Expand Up @@ -116,7 +117,7 @@ class NavDestinationAndroidTest {

destination.addDeepLink("www.example.com/users/index.html")

destination.addArgument("name", stringArgument())
destination.addArgument("name", nullableStringArgument(null))
destination.addDeepLink("www.example.com/users/{name}")

val match = destination.matchDeepLink(
Expand All @@ -138,7 +139,7 @@ class NavDestinationAndroidTest {
destination.addArgument("tab", stringArgument())
destination.addDeepLink("www.example.com/users/anonymous?tab={tab}")

destination.addArgument("name", stringArgument())
destination.addArgument("name", nullableStringArgument(null))
destination.addDeepLink("www.example.com/users/{name}?tab={tab}")

val match = destination.matchDeepLink(
Expand Down Expand Up @@ -224,15 +225,15 @@ class NavDestinationAndroidTest {
fun matchDeepLinkBestMimeType() {
val destination = NoOpNavigator().createDestination()

destination.addArgument("deeplink1", stringArgument())
destination.addArgument("deeplink1", nullableStringArgument(null))
destination.addDeepLink(
NavDeepLink(
"www.example.com/users/{deeplink1}",
null, "*/*"
)
)

destination.addArgument("deeplink2", stringArgument())
destination.addArgument("deeplink2", nullableStringArgument(null))
destination.addDeepLink(
NavDeepLink(
"www.example.com/users/{deeplink2}",
Expand Down Expand Up @@ -281,9 +282,8 @@ class NavDestinationAndroidTest {
val destination = NoOpNavigator().createDestination()
destination.addArgument("testString", stringArgument())
destination.addDeepLink("android-app://androidx.navigation.test/{testString}")
val deepLink = Uri.parse("android-app://androidx.navigation.test/test")
destination.addDeepLink(deepLink.toString())

val deepLink = Uri.parse("android-app://androidx.navigation.test/test")
assertWithMessage("Deep link should match")
.that(destination.hasDeepLink(deepLink)).isTrue()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package androidx.navigation

import android.net.Uri
import androidx.navigation.test.nullableStringArgument
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
Expand Down Expand Up @@ -70,11 +71,8 @@ class NavGraphAndroidTest {

graph.addDeepLink("www.example.com/users/index.html")

val idArgument = NavArgument.Builder()
.setType(NavType.StringType)
.build()
graph.addArgument("id", idArgument)
graph.addDeepLink("www.example.com/users/{name}")
graph.addArgument("id", nullableStringArgument(null))
graph.addDeepLink("www.example.com/users/{id}")

val match = graph.matchDeepLink(
Uri.parse("https://www.example.com/users/index.html")
Expand Down Expand Up @@ -155,16 +153,10 @@ class NavGraphAndroidTest {
val graph = navigatorProvider.getNavigator(NavGraphNavigator::class.java)
.createDestination()

val codeArgument = NavArgument.Builder()
.setType(NavType.StringType)
.build()
graph.addArgument("code", codeArgument)
graph.addArgument("code", nullableStringArgument(null))
graph.addDeepLink("www.example.com/users?code={code}")

val idArgument = NavArgument.Builder()
.setType(NavType.StringType)
.build()
graph.addArgument("id", idArgument)
graph.addArgument("id", nullableStringArgument(null))
graph.addDeepLink("www.example.com/users?id={id}")

val match = graph.matchDeepLink(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,11 @@ fun stringArgument(
.setDefaultValue(defaultValue)
.build()

fun nullableStringArgument() = NavArgument.Builder().setType(StringType)
fun nullableStringArgument(
defaultValue: String?
) = NavArgument.Builder().setType(StringType)
.setIsNullable(true)
.setDefaultValue(defaultValue)
.build()
// endregion

Expand All @@ -89,4 +92,4 @@ fun stringArrayArgument(
.setIsNullable(true)
.setDefaultValue(defaultValue)
.build()
// endregion
// endregion
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ public class NavDeepLink internal constructor(

private var mimeTypePattern: Pattern? = null

/** Arguments present in the deep link, including both path and query arguments. */
internal val argumentsNames: List<String>
get() = arguments + paramArgMap.keys

public var isExactDeepLink: Boolean = false
/** @suppress */
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
Expand Down Expand Up @@ -192,6 +196,13 @@ public class NavDeepLink internal constructor(
}
}
}

// Check that all required arguments are present in bundle
for ((argName, argument) in arguments.entries) {
val argumentIsRequired = argument != null && !argument.isDefaultValuePresent
if (argumentIsRequired && !bundle.containsKey(argName)) return null
}

return bundle
}

Expand Down Expand Up @@ -283,7 +294,8 @@ public class NavDeepLink internal constructor(
public class Builder {

/** @suppress */
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) public constructor()
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public constructor()

private var uriPattern: String? = null
private var action: String? = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,14 @@ public open class NavDestination(
* @see NavController.navigate
*/
public fun addDeepLink(navDeepLink: NavDeepLink) {
val missingRequiredArguments = arguments.filterValues { !it.isDefaultValuePresent }
.keys
.filter { it !in navDeepLink.argumentsNames }
require(missingRequiredArguments.isEmpty()) {
"Deep link ${navDeepLink.uriPattern} can't be used to open destination $this.\n" +
"Following required arguments are missing: $missingRequiredArguments"
}

deepLinks.add(navDeepLink)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class NavControllerActivityTest {
navController.setGraph(R.navigation.nav_simple)
navController.handleDeepLink(
Intent().apply {
data = Uri.parse("android-app://androidx.navigation.test/test")
data = Uri.parse("android-app://androidx.navigation.test/test/arg2")
}
)
assertThat(navController.currentDestination?.id)
Expand All @@ -97,7 +97,7 @@ class NavControllerActivityTest {
val activity = activityRule.activity

val intent = Intent().apply {
data = Uri.parse("android-app://androidx.navigation.test/test")
data = Uri.parse("android-app://androidx.navigation.test/test/arg2")
}

activity.intent = intent
Expand Down
Loading