From b86e3760654d6ec94c1bb5617aeec2ce40b537d4 Mon Sep 17 00:00:00 2001 From: Jay Ohms Date: Tue, 27 Feb 2024 16:21:55 -0500 Subject: [PATCH 1/2] Use the WebView's resolved location to determine whether to pass messages to components --- .../kotlin/dev/hotwire/strada/BridgeDelegate.kt | 12 +++++++----- .../dev/hotwire/strada/BridgeDelegateTest.kt | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/strada/src/main/kotlin/dev/hotwire/strada/BridgeDelegate.kt b/strada/src/main/kotlin/dev/hotwire/strada/BridgeDelegate.kt index d25c07e..516f6bf 100644 --- a/strada/src/main/kotlin/dev/hotwire/strada/BridgeDelegate.kt +++ b/strada/src/main/kotlin/dev/hotwire/strada/BridgeDelegate.kt @@ -13,6 +13,8 @@ class BridgeDelegate( internal var bridge: Bridge? = null private var destinationIsActive: Boolean = false private val initializedComponents = hashMapOf>() + private val resolvedLocation: String + get() = bridge?.webView?.url ?: location val activeComponents: List> get() = initializedComponents.map { it.value }.takeIf { destinationIsActive }.orEmpty() @@ -35,7 +37,7 @@ class BridgeDelegate( bridge?.load() } } else { - logWarning("bridgeNotInitializedForWebView", location) + logWarning("bridgeNotInitializedForWebView", resolvedLocation) } } @@ -58,7 +60,7 @@ class BridgeDelegate( } internal fun bridgeDidReceiveMessage(message: Message): Boolean { - return if (destinationIsActive && location == message.metadata?.url) { + return if (destinationIsActive && resolvedLocation == message.metadata?.url) { logEvent("bridgeDidReceiveMessage", message.toString()) getOrCreateComponent(message.component)?.didReceive(message) true @@ -75,7 +77,7 @@ class BridgeDelegate( // Lifecycle events override fun onStart(owner: LifecycleOwner) { - logEvent("bridgeDestinationDidStart", location) + logEvent("bridgeDestinationDidStart", resolvedLocation) destinationIsActive = true activeComponents.forEach { it.didStart() } } @@ -83,12 +85,12 @@ class BridgeDelegate( override fun onStop(owner: LifecycleOwner) { activeComponents.forEach { it.didStop() } destinationIsActive = false - logEvent("bridgeDestinationDidStop", location) + logEvent("bridgeDestinationDidStop", resolvedLocation) } override fun onDestroy(owner: LifecycleOwner) { destinationIsActive = false - logEvent("bridgeDestinationDidDestroy", location) + logEvent("bridgeDestinationDidDestroy", resolvedLocation) } // Retrieve component(s) by type diff --git a/strada/src/test/kotlin/dev/hotwire/strada/BridgeDelegateTest.kt b/strada/src/test/kotlin/dev/hotwire/strada/BridgeDelegateTest.kt index 1ffcd81..7156430 100644 --- a/strada/src/test/kotlin/dev/hotwire/strada/BridgeDelegateTest.kt +++ b/strada/src/test/kotlin/dev/hotwire/strada/BridgeDelegateTest.kt @@ -77,6 +77,23 @@ class BridgeDelegateTest { assertNotNull(delegate.component()) } + @Test + fun bridgeDidReceiveMessageForResolvedLocation() { + whenever(webView.url).thenReturn("https://37signals.com/new_url") + + val message = Message( + id = "1", + component = "one", + event = "connect", + metadata = Metadata("https://37signals.com/new_url"), + jsonData = """{"title":"Page-title","subtitle":"Page-subtitle"}""" + ) + + assertNull(delegate.component()) + assertEquals(true, delegate.bridgeDidReceiveMessage(message)) + assertNotNull(delegate.component()) + } + @Test fun bridgeDidReceiveMessageIgnored() { val message = Message( From 4c13175469f8e98e8b1e048500e8ee65bf434d52 Mon Sep 17 00:00:00 2001 From: Jay Ohms Date: Tue, 27 Feb 2024 16:26:13 -0500 Subject: [PATCH 2/2] Add a test to ensure that a resolved location with a trailing slash passing along the bridge message --- .../dev/hotwire/strada/BridgeDelegateTest.kt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/strada/src/test/kotlin/dev/hotwire/strada/BridgeDelegateTest.kt b/strada/src/test/kotlin/dev/hotwire/strada/BridgeDelegateTest.kt index 7156430..76f9b42 100644 --- a/strada/src/test/kotlin/dev/hotwire/strada/BridgeDelegateTest.kt +++ b/strada/src/test/kotlin/dev/hotwire/strada/BridgeDelegateTest.kt @@ -77,6 +77,23 @@ class BridgeDelegateTest { assertNotNull(delegate.component()) } + @Test + fun bridgeDidReceiveMessageForLocationWithTrailingSlash() { + whenever(webView.url).thenReturn("https://37signals.com/") + + val message = Message( + id = "1", + component = "one", + event = "connect", + metadata = Metadata("https://37signals.com/"), + jsonData = """{"title":"Page-title","subtitle":"Page-subtitle"}""" + ) + + assertNull(delegate.component()) + assertEquals(true, delegate.bridgeDidReceiveMessage(message)) + assertNotNull(delegate.component()) + } + @Test fun bridgeDidReceiveMessageForResolvedLocation() { whenever(webView.url).thenReturn("https://37signals.com/new_url")