Skip to content

Commit

Permalink
Fix identify and view function to send events even if user_id or view…
Browse files Browse the repository at this point in the history
…_name is not present in argument. (#183)
  • Loading branch information
tikidunpon authored Apr 5, 2022
1 parent 6882d2f commit 25d9f68
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 15 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
** 🎉 FEATURE**
- KARTE SDKでURLを開くためのAPIを追加しました。このAPIはSDK内部での利用を想定しており、通常のSDK利用で使用することはありません。

** 🔨 CHANGED**
- identifyイベントのuser_idとviewイベントのview_nameに空文字が指定された場合でも警告の出力のみでイベントが送信されるよう挙動を変更しました。
- 尚、user_id無しで送信されたidentifyのフィールドがKARTE上で永続化されるかどうかは[ユーザーデータ管理](https://support.karte.io/post/6Uu930PTyQBc6SVAOEOTYp)プラグインの利用状況に依存します。
- user_id無しでユーザーに紐づく個人情報以外のフィールドをイベントに付与したい場合は[attribute関数](https://plaidev.github.io/karte-sdk-docs/android/core/latest/core/io.karte.android.tracking/-tracker/index.html#%5Bio.karte.android.tracking%2FTracker%2Fattribute%2F%23java.util.Map%3Cjava.lang.String%2C%3F%3E%2FPointingToDeclaration%2F%2C+io.karte.android.tracking%2FTracker%2Fattribute%2F%23org.json.JSONObject%2FPointingToDeclaration%2F%2C+io.karte.android.tracking%2FTracker%2Fattribute%2F%23java.util.Map%3Cjava.lang.String%2C%3F%3E%23io.karte.android.tracking.TrackCompletion%2FPointingToDeclaration%2F%2C+io.karte.android.tracking%2FTracker%2Fattribute%2F%23org.json.JSONObject%23io.karte.android.tracking.TrackCompletion%2FPointingToDeclaration%2F%5D%2FFunctions%2F96193845)を使用してください。

### InAppMessaging 2.12.0
** 🔨 CHANGED**
- Core 2.17.0で追加されたAPIを利用するように内部処理を修正しました。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ internal object EventValidator {
val messages = mutableListOf<String>()
if (validateEventFieldValue(event.eventName.value, event.values))
messages.add(
"Failed to push Event to queue because view_name or user_id is empty:" +
"view_name or user_id is empty:" +
" EventName=${event.eventName.value},FieldName=${event.values}"
)
return messages
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,6 @@ internal class Dispatcher {
val eventInvalidMessages = EventValidator.getInvalidMessages(record.event)
if (eventInvalidMessages.isNotEmpty()) {
eventInvalidMessages.forEach { Logger.w(LOG_TAG, it) }
completion?.onComplete(false)
return
}

val id = DataStore.put(record)
Expand Down
153 changes: 146 additions & 7 deletions core/src/test/java/io/karte/android/integration/TrackerTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import com.google.common.truth.Truth.assertWithMessage
import io.karte.android.BuildConfig
import io.karte.android.KarteApp
import io.karte.android.TrackerTestCase
import io.karte.android.assertThatNoEventOccured
import io.karte.android.eventNameTransform
import io.karte.android.parseBody
import io.karte.android.proceedBufferedCall
Expand All @@ -40,6 +39,7 @@ import org.robolectric.ParameterizedRobolectricTestRunner
import org.robolectric.Robolectric
import org.robolectric.android.controller.ActivityController
import java.util.Date
import java.util.concurrent.TimeUnit
import kotlin.math.min

private fun createJsonValues(): JSONObject {
Expand Down Expand Up @@ -134,16 +134,146 @@ class TrackerIntegrationTest {

class user_idに空文字を設定した場合 : TrackerTestCase() {
@Test
fun identifyイベントがサーバに送信されないこと() {
fun identifyイベントがサーバに送信されること() {
val jsonValues = createJsonValues()
server.enqueue(
MockResponse().setBody(body.toString()).addHeader(
"Content-Type",
"text/html; charset=utf-8"
)
)
Tracker.identify("", jsonValues.toValues())
proceedBufferedCall()

val request = server.takeRequest()
val event = JSONObject(request.parseBody()).getJSONArray("events").getJSONObject(0)
val eventValues = event.getJSONObject("values")
assertWithMessage("event_nameがtrackサーバに送信されること").that(event.getString("event_name"))
.isEqualTo("identify")
assertWithMessage("数値がtrackサーバに送信されること").that(eventValues.getInt("num"))
.isEqualTo(10)
assertWithMessage("文字列がtrackサーバに送信されること").that(eventValues.getString("str"))
.isEqualTo("hoge")
assertWithMessage("user_idが空のままtrackサーバに送信されること").that(eventValues.getString("user_id"))
.isEqualTo("")
assertWithMessage("日付がtrackサーバに送信されること").that(eventValues.getInt("date"))
.isEqualTo((jsonValues.get("date") as Date).time / 1000)
assertWithMessage("JSONがtrackサーバに送信されること")
.that(eventValues.getJSONObject("json").toString())
.isEqualTo(jsonValues.getJSONObject("json").toString())
assertWithMessage("JSONArrayがtrackサーバに送信されること")
.that(eventValues.getJSONArray("arr").toString())
.isEqualTo(jsonValues.getJSONArray("arr").toString())
}
}
}

@RunWith(Enclosed::class)
@Suppress("DEPRECATION")
class deprecatedなidentifyイベント {
class user_idを設定した場合 : TrackerTestCase() {
@Test
fun identifyイベントがサーバに送信されること() {
val jsonValues = createJsonValues().put("user_id", "test_user")
server.enqueue(
MockResponse().setBody(body.toString()).addHeader(
"Content-Type",
"text/html; charset=utf-8"
)
)
Tracker.identify(jsonValues.toValues())
proceedBufferedCall()

val request = server.takeRequest()
val event = JSONObject(request.parseBody()).getJSONArray("events").getJSONObject(0)
val eventValues = event.getJSONObject("values")
assertWithMessage("event_nameがtrackサーバに送信されること").that(event.getString("event_name"))
.isEqualTo("identify")
assertWithMessage("数値がtrackサーバに送信されること").that(eventValues.getInt("num"))
.isEqualTo(10)
assertWithMessage("文字列がtrackサーバに送信されること").that(eventValues.getString("str"))
.isEqualTo("hoge")
assertWithMessage("user_idがtrackサーバに送信されること").that(eventValues.getString("user_id"))
.isEqualTo("test_user")
assertWithMessage("日付がtrackサーバに送信されること").that(eventValues.getInt("date"))
.isEqualTo((jsonValues.get("date") as Date).time / 1000)
assertWithMessage("JSONがtrackサーバに送信されること")
.that(eventValues.getJSONObject("json").toString())
.isEqualTo(jsonValues.getJSONObject("json").toString())
assertWithMessage("JSONArrayがtrackサーバに送信されること")
.that(eventValues.getJSONArray("arr").toString())
.isEqualTo(jsonValues.getJSONArray("arr").toString())
}
}

class user_idに空文字を設定した場合 : TrackerTestCase() {
@Test
fun identifyイベントがサーバに送信されること() {
val jsonValues = createJsonValues().put("user_id", "")
server.enqueue(
MockResponse().setBody(body.toString()).addHeader(
"Content-Type",
"text/html; charset=utf-8"
)
)
Tracker.identify("", JSONObject())
Tracker.identify(jsonValues.toValues())
proceedBufferedCall()
server.assertThatNoEventOccured()

val request = server.takeRequest(3, TimeUnit.SECONDS)
assertThat(request).isNotNull()
val event = JSONObject(request!!.parseBody()).getJSONArray("events").getJSONObject(0)
val eventValues = event.getJSONObject("values")
assertWithMessage("event_nameがtrackサーバに送信されること").that(event.getString("event_name"))
.isEqualTo("identify")
assertWithMessage("数値がtrackサーバに送信されること").that(eventValues.getInt("num"))
.isEqualTo(10)
assertWithMessage("文字列がtrackサーバに送信されること").that(eventValues.getString("str"))
.isEqualTo("hoge")
assertWithMessage("user_idが空のままtrackサーバに送信されること").that(eventValues.getString("user_id"))
.isEqualTo("")
assertWithMessage("日付がtrackサーバに送信されること").that(eventValues.getInt("date"))
.isEqualTo((jsonValues.get("date") as Date).time / 1000)
assertWithMessage("JSONがtrackサーバに送信されること")
.that(eventValues.getJSONObject("json").toString())
.isEqualTo(jsonValues.getJSONObject("json").toString())
assertWithMessage("JSONArrayがtrackサーバに送信されること")
.that(eventValues.getJSONArray("arr").toString())
.isEqualTo(jsonValues.getJSONArray("arr").toString())
}
}

class user_id未設定な場合 : TrackerTestCase() {
@Test
fun identifyイベントがサーバに送信されること() {
val jsonValues = createJsonValues()
server.enqueue(
MockResponse().setBody(body.toString()).addHeader(
"Content-Type",
"text/html; charset=utf-8"
)
)
Tracker.identify(jsonValues.toValues())
proceedBufferedCall()

val request = server.takeRequest(3, TimeUnit.SECONDS)
assertThat(request).isNotNull()
val event = JSONObject(request!!.parseBody()).getJSONArray("events").getJSONObject(0)
val eventValues = event.getJSONObject("values")
assertWithMessage("event_nameがtrackサーバに送信されること").that(event.getString("event_name"))
.isEqualTo("identify")
assertWithMessage("数値がtrackサーバに送信されること").that(eventValues.getInt("num"))
.isEqualTo(10)
assertWithMessage("文字列がtrackサーバに送信されること").that(eventValues.getString("str"))
.isEqualTo("hoge")
assertWithMessage("user_idがkey自体存在しないこと").that(eventValues.has("user_id")).isFalse()
assertWithMessage("日付がtrackサーバに送信されること").that(eventValues.getInt("date"))
.isEqualTo((jsonValues.get("date") as Date).time / 1000)
assertWithMessage("JSONがtrackサーバに送信されること")
.that(eventValues.getJSONObject("json").toString())
.isEqualTo(jsonValues.getJSONObject("json").toString())
assertWithMessage("JSONArrayがtrackサーバに送信されること")
.that(eventValues.getJSONArray("arr").toString())
.isEqualTo(jsonValues.getJSONArray("arr").toString())
}
}
}
Expand Down Expand Up @@ -182,9 +312,9 @@ class TrackerIntegrationTest {

@RunWith(Enclosed::class)
class viewイベント {
class view_namに空文字を設定した場合 : TrackerTestCase() {
class view_nameに空文字を設定した場合 : TrackerTestCase() {
@Test
fun viewイベントがサーバに送信されないこと() {
fun viewイベントがサーバに送信されること() {
server.enqueue(
MockResponse().setBody(body.toString()).addHeader(
"Content-Type",
Expand All @@ -193,7 +323,16 @@ class TrackerIntegrationTest {
)
Tracker.view("", JSONObject())
proceedBufferedCall()
server.assertThatNoEventOccured()

val request = server.takeRequest()
val event =
JSONObject(request.parseBody()).getJSONArray("events").getJSONObject(0)
val eventValues = event.getJSONObject("values")
assertWithMessage("event_nameがviewとしてtrackサーバに送信されること")
.that(event.getString("event_name"))
.isEqualTo("view")
assertWithMessage("view名が空のままtrackサーバに送信されること").that(eventValues.getString("view_name"))
.isEqualTo("")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,15 @@ class EventValidatorTest {
val messages = EventValidator.getInvalidMessages(this)
assertThat(messages).isNotEmpty()
assertThat(messages.size).isEqualTo(1)
assertThat(messages[0]).startsWith("Failed to push Event")
assertThat(messages[0]).startsWith("view_name or user_id is empty")
}
with(Event(CustomEventName("view"), mapOf("viewName" to ""))) {
assertThat(EventValidator.getDeprecatedMessages(this)).isEmpty()

val messages = EventValidator.getInvalidMessages(this)
assertThat(messages).isNotEmpty()
assertThat(messages.size).isEqualTo(1)
assertThat(messages[0]).startsWith("Failed to push Event")
assertThat(messages[0]).startsWith("view_name or user_id is empty")
}
with(Event(CustomEventName("view"), values = null)) {
assertThat(EventValidator.getDeprecatedMessages(this)).isEmpty()
Expand All @@ -129,15 +129,15 @@ class EventValidatorTest {
val messages = EventValidator.getInvalidMessages(this)
assertThat(messages).isNotEmpty()
assertThat(messages.size).isEqualTo(1)
assertThat(messages[0]).startsWith("Failed to push Event")
assertThat(messages[0]).startsWith("view_name or user_id is empty")
}
with(Event(CustomEventName("identify"), mapOf("user_id" to ""))) {
assertThat(EventValidator.getDeprecatedMessages(this)).isEmpty()

val messages = EventValidator.getInvalidMessages(this)
assertThat(messages).isNotEmpty()
assertThat(messages.size).isEqualTo(1)
assertThat(messages[0]).startsWith("Failed to push Event")
assertThat(messages[0]).startsWith("view_name or user_id is empty")
}
with(Event(CustomEventName("identify"), values = null)) {
assertThat(EventValidator.getDeprecatedMessages(this)).isEmpty()
Expand Down
2 changes: 1 addition & 1 deletion core/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.17.0
2.17.0

0 comments on commit 25d9f68

Please sign in to comment.