Skip to content

Commit

Permalink
Merge branch 'main' into coroutines
Browse files Browse the repository at this point in the history
  • Loading branch information
wzieba committed Nov 8, 2023
2 parents 80454a8 + 1e6e189 commit 5e590c2
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 81 deletions.
5 changes: 5 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
github_checks:
annotations: false

coverage:
status:
project: off
patch: off
1 change: 1 addition & 0 deletions parsely/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ dependencies {
androidTestImplementation "org.assertj:assertj-core:$assertJVersion"
androidTestImplementation "com.squareup.okhttp3:mockwebserver:$mockWebServerVersion"
androidTestImplementation 'androidx.test:runner:1.5.2'
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
androidTestUtil 'androidx.test:orchestrator:1.4.2'
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package com.parsely.parselyandroid
import android.app.Activity
import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.UiSelector
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.core.type.TypeReference
Expand All @@ -14,6 +17,8 @@ import java.lang.reflect.Field
import java.nio.file.Path
import java.util.concurrent.TimeUnit
import kotlin.io.path.Path
import kotlin.time.Duration
import kotlin.time.Duration.Companion.hours
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.runBlocking
Expand Down Expand Up @@ -90,13 +95,13 @@ class FunctionalTests {
parselyTracker.trackPageview("url", null, null, null)
}

Thread.sleep((flushInterval / 2).inWholeMilliseconds)
Thread.sleep((defaultFlushInterval / 2).inWholeMilliseconds)

scenario.onActivity {
parselyTracker.trackPageview("url", null, null, null)
}

Thread.sleep((flushInterval / 2).inWholeMilliseconds)
Thread.sleep((defaultFlushInterval / 2).inWholeMilliseconds)

val firstRequestPayload = server.takeRequest(2000, TimeUnit.MILLISECONDS)?.toMap()
assertThat(firstRequestPayload!!["events"]).hasSize(2)
Expand All @@ -105,13 +110,50 @@ class FunctionalTests {
parselyTracker.trackPageview("url", null, null, null)
}

Thread.sleep(flushInterval.inWholeMilliseconds)
Thread.sleep(defaultFlushInterval.inWholeMilliseconds)

val secondRequestPayload = server.takeRequest(2000, TimeUnit.MILLISECONDS)?.toMap()
assertThat(secondRequestPayload!!["events"]).hasSize(1)
}
}

/**
* In this scenario, the consumer application:
* 1. Goes to the background
* 2. Is re-launched
* This pattern occurs twice, which allows us to confirm the following assertions:
* 1. The event request is triggered when the consumer application is moved to the background
* 2. If the consumer application is sent to the background again within a short interval,
* the request is not duplicated.
*/
@Test
fun appSendsEventsWhenMovedToBackgroundAndDoesntSendDuplicatedRequestWhenItsMovedToBackgroundAgainQuickly() {
val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
ActivityScenario.launch(SampleActivity::class.java).use { scenario ->
scenario.onActivity { activity: Activity ->
beforeEach(activity)
server.enqueue(MockResponse().setResponseCode(200))
server.enqueue(MockResponse().setResponseCode(200))
parselyTracker = initializeTracker(activity, flushInterval = 1.hours)

repeat(20) {
parselyTracker.trackPageview("url", null, null, null)
}
}

device.pressHome()
device.pressRecentApps()
device.findObject(UiSelector().descriptionContains("com.parsely")).click()
device.pressHome()

val firstRequest = server.takeRequest(10000, TimeUnit.MILLISECONDS)?.toMap()
val secondRequest = server.takeRequest(10000, TimeUnit.MILLISECONDS)?.toMap()

assertThat(firstRequest!!["events"]).hasSize(20)
assertThat(secondRequest).isNull()
}
}

private fun RecordedRequest.toMap(): Map<String, List<Event>> {
val listType: TypeReference<Map<String, List<Event>>> =
object : TypeReference<Map<String, List<Event>>>() {}
Expand All @@ -132,7 +174,10 @@ class FunctionalTests {
}
}

private fun initializeTracker(activity: Activity): ParselyTracker {
private fun initializeTracker(
activity: Activity,
flushInterval: Duration = defaultFlushInterval
): ParselyTracker {
return ParselyTracker.sharedInstance(
siteId, flushInterval.inWholeSeconds.toInt(), activity.application
).apply {
Expand All @@ -145,7 +190,7 @@ class FunctionalTests {
private companion object {
const val siteId = "123"
const val localStorageFileName = "parsely-events.ser"
val flushInterval = 5.seconds
val defaultFlushInterval = 5.seconds
}

class SampleActivity : Activity()
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
Copyright 2016 Parse.ly, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
@file:Suppress("DEPRECATION")
package com.parsely.parselyandroid

import android.os.AsyncTask
import java.net.HttpURLConnection
import java.net.URL

internal class ParselyAPIConnection(private val tracker: ParselyTracker) : AsyncTask<String?, Exception?, Void?>() {
private var exception: Exception? = null

@Deprecated("Deprecated in Java")
override fun doInBackground(vararg data: String?): Void? {
var connection: HttpURLConnection? = null
try {
if (data.size == 1) { // non-batched (since no post data is included)
connection = URL(data[0]).openConnection() as HttpURLConnection
connection.inputStream
} else if (data.size == 2) { // batched (post data included)
connection = URL(data[0]).openConnection() as HttpURLConnection
connection.doOutput = true // Triggers POST (aka silliest interface ever)
connection.setRequestProperty("Content-Type", "application/json")
val output = connection.outputStream
output.write(data[1]?.toByteArray())
output.close()
connection.inputStream
}
} catch (ex: Exception) {
exception = ex
}
return null
}

@Deprecated("Deprecated in Java")
override fun onPostExecute(result: Void?) {
if (exception != null) {
ParselyTracker.PLog("Pixel request exception")
ParselyTracker.PLog(exception.toString())
} else {
ParselyTracker.PLog("Pixel request success")

// only purge the queue if the request was successful
tracker.purgeEventsQueue()
ParselyTracker.PLog("Event queue empty, flush timer cleared.")
tracker.stopFlushTimer()
}
}
}

0 comments on commit 5e590c2

Please sign in to comment.