Skip to content

Commit

Permalink
add KarteApp.onNewIntent (#152)
Browse files Browse the repository at this point in the history
* add KarteApp.onNewIntent
* add test
* vup and update CHANGELOG
  • Loading branch information
wasnot authored Mar 11, 2022
1 parent 5c0339a commit 5b0120b
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 29 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@

| モジュール/プラグイン名 | Description | 最新のバージョン |
| :-- | :-- | :-- |
| core | イベントトラッキング機能を提供します。 | 2.15.0 |
| core | イベントトラッキング機能を提供します。 | 2.16.0 |
| inappmessaging | アプリ内メッセージ機能を提供します。 | 2.11.0 |
| notifications | プッシュ通知の受信および効果測定機能を提供します。 | 2.8.0 |
| variables | 設定値配信機能を提供します。 | 2.2.0 |
| visualtracking | ビジュアルトラッキング機能を提供します。| 2.6.0 |
| Karte Gradle Plugin | ビジュアルトラッキング機能に必要なプラグインです。| 2.4.0 |

# Releases - xxxx.xx.xx

### Core 2.16.0
** 🎉 FEATURE**
- launchModeがsingleTopなど、再開時にintentが更新されないActivityでもKARTE SDKのDeeplink処理を行うためのAPIを追加しました。
- 詳細は[こちら](https://developers.karte.io/docs/appendix-relaunch-activity-android-sdk-v2)を確認してください。

# Releases - 2022.02.21

### Core 2.15.0
Expand Down
24 changes: 20 additions & 4 deletions core/src/main/java/io/karte/android/KarteApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package io.karte.android
import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
Expand Down Expand Up @@ -175,6 +176,11 @@ class KarteApp private constructor() : ActivityLifecycleCallback() {
return CommandExecutor.execute(uri)
}

private fun handleDeeplink(intent: Intent) {
self.modules.filterIsInstance<DeepLinkModule>()
.forEach { it.handle(intent) }
}

//region ActivityLifecycleCallback
private var firstActivityCreated = false
private var activityCount = 0
Expand All @@ -187,17 +193,15 @@ class KarteApp private constructor() : ActivityLifecycleCallback() {
self.tracker?.track(Event(AutoEventName.NativeAppOpen, values = null))
firstActivityCreated = true
}
self.modules.filterIsInstance<DeepLinkModule>()
.forEach { it.handle(activity.intent) }
handleDeeplink(activity.intent)
}

override fun onActivityStarted(activity: Activity) {
Logger.v(LOG_TAG, "onActivityStarted $activity")
if (++activityCount == 1) {
self.tracker?.track(Event(AutoEventName.NativeAppForeground, values = null))
}
self.modules.filterIsInstance<DeepLinkModule>()
.forEach { it.handle(activity.intent) }
handleDeeplink(activity.intent)
}

override fun onActivityResumed(activity: Activity) {
Expand Down Expand Up @@ -413,5 +417,17 @@ class KarteApp private constructor() : ActivityLifecycleCallback() {
fun renewVisitorId() {
self.visitorId?.renew()
}

/**
* 渡されたintentを使用してKARTEのDeeplink処理を行います。
*
* launchModeにsingleTopなどを利用していて、[Activity.onNewIntent]にて渡される新しいintentで、KARTEのdeeplink処理を行いたい場合に呼び出してください。
*
* @param[intent] [Activity.onNewIntent]等で新しく渡された[Intent]
*/
@JvmStatic
fun onNewIntent(intent: Intent?) {
intent?.let { self.handleDeeplink(it) }
}
}
}
177 changes: 154 additions & 23 deletions core/src/test/java/io/karte/android/integration/DeepLinkTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,62 @@ import android.app.Activity
import android.content.Intent
import android.net.Uri
import com.google.common.truth.Truth.assertThat
import io.karte.android.KarteApp
import io.karte.android.TrackerRequestDispatcher
import io.karte.android.TrackerTestCase
import io.karte.android.parseBody
import io.karte.android.proceedBufferedCall
import io.karte.android.utilities.map
import org.json.JSONObject
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.robolectric.Robolectric
import org.robolectric.android.controller.ActivityController

class NewIntentActivity : Activity() {
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
KarteApp.onNewIntent(intent)
}
}

abstract class DeepLinkTestCase : TrackerTestCase() {
private lateinit var dispatcher: TrackerRequestDispatcher
var activityController: ActivityController<*>? = null

@Before
fun setup() {
dispatcher = TrackerRequestDispatcher()
server.dispatcher = dispatcher
}

fun launchByDeepLink(uriString: String) {
Robolectric.buildActivity(
Activity::class.java,
@After
fun teardown() {
activityController?.destroy()
activityController = null
}

fun launchByDeepLink(uriString: String?) {
launchByDeepLink(uriString, Activity::class.java)
}

fun <T : Activity> launchByDeepLink(uriString: String?, activityClass: Class<T>) {
val intent = if (uriString == null) {
Intent(Intent.ACTION_VIEW)
} else {
Intent(Intent.ACTION_VIEW, Uri.parse(uriString))
).create().start().resume()
}
activityController = Robolectric.buildActivity(activityClass, intent)
.create().start().resume()
}

fun relaunchWithNewIntent(uriString: String) {
activityController?.newIntent(Intent(Intent.ACTION_VIEW, Uri.parse(uriString)))
?.start()?.resume()
}

fun getEvents(eventNameFilter: String? = null): List<JSONObject> {
private fun getEvents(eventNameFilter: String? = null): List<JSONObject> {
var events = JSONObject(server.takeRequest().parseBody())
.getJSONArray("events")
.map { it }
Expand All @@ -55,72 +84,174 @@ abstract class DeepLinkTestCase : TrackerTestCase() {
}
return events
}

abstract val eventName: String

fun assertEventOccurred(key: String, value: String) {
val events = getEvents(eventName)
assertThat(events).hasSize(1)

val event = events[0]
assertThat(event.getString("event_name")).isEqualTo(eventName)
assertThat(event.getJSONObject("values").getString(key)).isEqualTo(value)
}

fun assertNoEvent() {
assertThat(getEvents(eventName)).isEmpty()
}
}

class FindMySelf : DeepLinkTestCase() {
private val EVENT_NAME = "native_find_myself"
override val eventName = "native_find_myself"

@Test
fun FindMySelf1回のみ発生() {
launchByDeepLink("test://karte.io/find_myself?src=qr")
proceedBufferedCall()

val events = getEvents(EVENT_NAME)
assertThat(events).hasSize(1)
assertEventOccurred("src", "qr")
}

val event = events[0]
assertThat(event.getString("event_name")).isEqualTo(EVENT_NAME)
assertThat(event.getJSONObject("values").getString("src")).isEqualTo("qr")
@Test
fun 再起動すればFindMySelfが繰り返し発生() {
launchByDeepLink("test://karte.io/find_myself?src=qr")
proceedBufferedCall()

assertEventOccurred("src", "qr")

activityController?.pause()?.stop()?.destroy()
launchByDeepLink("test://karte.io/find_myself?src=qr2")
proceedBufferedCall()

assertEventOccurred("src", "qr2")
}

@Test
fun 実装済みならonNewIntentでも発生() {
launchByDeepLink("test://karte.io/find_myself?src=qr", NewIntentActivity::class.java)
proceedBufferedCall()

assertEventOccurred("src", "qr")

activityController?.pause()?.stop()
relaunchWithNewIntent("test://karte.io/find_myself?src=qr2")
proceedBufferedCall()

assertEventOccurred("src", "qr2")
}

@Test
fun 未実装ならonNewIntentでは発生しない() {
launchByDeepLink("test://karte.io/find_myself?src=qr")
proceedBufferedCall()

assertEventOccurred("src", "qr")

activityController?.pause()?.stop()
relaunchWithNewIntent("test://karte.io/find_myself?src=qr2")
proceedBufferedCall()

assertNoEvent()
}

@Test
fun queryがなければ発生しない() {
launchByDeepLink("test://karte.io/find_myself")
proceedBufferedCall()

assertThat(getEvents(EVENT_NAME)).isEmpty()
assertNoEvent()
}

@Test
fun hostが違えば発生しない() {
launchByDeepLink("test://plaid.co.jp/find_myself?src=qr")
proceedBufferedCall()

assertThat(getEvents(EVENT_NAME)).isEmpty()
assertNoEvent()
}

@Test
fun パスが違えば発生しない() {
launchByDeepLink("test://karte.io/preview?src=qr")
proceedBufferedCall()

assertThat(getEvents(EVENT_NAME)).isEmpty()
assertNoEvent()
}
}

class DeepLinkEventTest : DeepLinkTestCase() {
private val EVENT_NAME = "deep_link_app_open"
override val eventName = "deep_link_app_open"

@Test
fun DeepLinkAppOpen1回のみ発生() {
val url = "test://anyrequest?test=true"
launchByDeepLink(url)
proceedBufferedCall()

val events = getEvents(EVENT_NAME)
assertThat(events).hasSize(1)
assertEventOccurred("url", url)
}

val event = events[0]
assertThat(event.getString("event_name")).isEqualTo(EVENT_NAME)
assertThat(event.getJSONObject("values").getString("url")).isEqualTo(url)
@Test
fun 再起動すればFindMySelfが繰り返し発生() {
val url = "test://anyrequest?test=true"
launchByDeepLink(url)
proceedBufferedCall()

assertEventOccurred("url", url)

activityController?.pause()?.stop()?.destroy()
val url2 = "test://anotherrequest?test=true"
launchByDeepLink(url2)
proceedBufferedCall()

assertEventOccurred("url", url2)
}

@Test
fun 実装済みならonNewIntentでも発生() {
val url = "test://anyrequest?test=true"
launchByDeepLink(url, NewIntentActivity::class.java)
proceedBufferedCall()

assertEventOccurred("url", url)

activityController?.pause()?.stop()
val url2 = "test://anotherrequest?test=true"
relaunchWithNewIntent(url2)
proceedBufferedCall()

assertEventOccurred("url", url2)
}

@Test
fun 未実装ならonNewIntentでは発生しない() {
val url = "test://anyrequest?test=true"
launchByDeepLink(url)
proceedBufferedCall()

assertEventOccurred("url", url)

activityController?.pause()?.stop()
val url2 = "test://anotherrequest?test=true"
relaunchWithNewIntent(url2)
proceedBufferedCall()

assertNoEvent()
}

@Test
fun URIが空文字なら発生する() {
launchByDeepLink("")
proceedBufferedCall()

assertEventOccurred("url", "")
}

@Test
fun URIがなければ発生しない() {
Robolectric.buildActivity(Activity::class.java, Intent(Intent.ACTION_VIEW)).create().start()
.resume()
launchByDeepLink(null)
proceedBufferedCall()

assertThat(getEvents(EVENT_NAME)).isEmpty()
assertNoEvent()
}
}
2 changes: 1 addition & 1 deletion core/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.15.0
2.16.0

0 comments on commit 5b0120b

Please sign in to comment.