Add some tests

This commit is contained in:
William Brawner 2022-11-06 21:40:54 -07:00
parent 0b35ae3030
commit d1b934dea1
7 changed files with 219 additions and 7 deletions

View file

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AndroidTestResultsUserPreferences">
<option name="androidTestResultsTableState">
<map>
<entry key="-1598607000">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_3a_API_31_arm64-v8a" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-1495681164">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_3a_API_31_arm64-v8a" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-363639403">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_3a_API_31_arm64-v8a" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-205275315">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_3a_API_31_arm64-v8a" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="173580342">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_3a_API_31_arm64-v8a" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="925139469">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_3a_API_31_arm64-v8a" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
</map>
</option>
</component>
</project>

View file

@ -18,10 +18,13 @@ android {
versionName "0.1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArguments clearPackageData: 'true'
consumerProguardFiles "consumer-rules.pro"
buildConfigField "String", "VERSION", "\"$versionName\""
}
testOptions {
execution 'ANDROIDX_TEST_ORCHESTRATOR'
}
buildTypes {
release {
minifyEnabled false
@ -54,4 +57,8 @@ dependencies {
implementation "com.squareup.okhttp3:okhttp:$okhttp_version"
testImplementation "com.squareup.okhttp3:mockwebserver:$okhttp_version"
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestUtil 'androidx.test:orchestrator:1.4.1'
}

View file

@ -0,0 +1,45 @@
package com.wbrawner.plausible.android
import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import java.io.File
@RunWith(AndroidJUnit4::class)
internal class NetworkFirstPlausibleClientTest {
private lateinit var client: NetworkFirstPlausibleClient
private lateinit var config: PlausibleConfig
private lateinit var eventDir: File
@Before
fun setup() {
eventDir = File.createTempFile("PlausibleTest", "", null)
eventDir.delete()
eventDir.mkdir()
config = ThreadSafePlausibleConfig(eventDir, SCREEN_WIDTH)
TODO("Set up a mock web server and validate the requests received are correct")
}
@Ignore("Not yet implemented")
@Test
fun events_are_sent_to_server() = networkFirstClientTest {
client.event(
domain = "test.example.com",
name = "eventUrl",
url = "referrer",
referrer = "referrer",
screenWidth = SCREEN_WIDTH,
props = mapOf("prop1" to "propVal")
)
}
private fun networkFirstClientTest(test: suspend () -> Unit) = runBlocking {
client = NetworkFirstPlausibleClient(config, coroutineContext)
test()
}
}

View file

@ -0,0 +1,57 @@
package com.wbrawner.plausible.android
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.wbrawner.plausible.android.fake.FakePlausibleClient
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.io.File
internal const val SCREEN_WIDTH = 123
@RunWith(AndroidJUnit4::class)
internal class PlausibleTest {
lateinit var client: FakePlausibleClient
lateinit var config: PlausibleConfig
lateinit var eventDir: File
@Before
fun setup() {
eventDir = File.createTempFile("PlausibleTest", "", null)
eventDir.delete()
eventDir.mkdir()
client = FakePlausibleClient()
config = ThreadSafePlausibleConfig(eventDir, SCREEN_WIDTH)
Plausible.init(client, config)
}
@Test
fun enable_is_sent_to_config() {
assertTrue(config.enable)
Plausible.enable(false)
assertFalse(config.enable)
}
@Test
fun user_agent_is_sent_to_config() {
val oldUserAgent = config.userAgent
Plausible.setUserAgent("test user agent")
assertNotEquals(oldUserAgent, config.userAgent)
assertEquals("test user agent", config.userAgent)
}
@Test
fun events_are_sent_to_client() {
config.domain = "test.example.com"
Plausible.event("eventName", "eventUrl", "referrer", mapOf("prop1" to "propVal"))
assertEquals(1, client.events.size)
val event = client.events.first()
assertEquals("test.example.com", event.domain)
assertEquals("eventName", event.name)
assertEquals("app://localhost/eventUrl", event.url)
assertEquals(123, event.screenWidth)
assertEquals("referrer", event.referrer)
assertEquals("{\"prop1\":\"propVal\"}", event.props)
}
}

View file

@ -0,0 +1,12 @@
package com.wbrawner.plausible.android.fake
import com.wbrawner.plausible.android.Event
import com.wbrawner.plausible.android.PlausibleClient
internal class FakePlausibleClient : PlausibleClient {
val events = mutableListOf<Event>()
override fun event(event: Event) {
events.add(event)
}
}

View file

@ -14,6 +14,7 @@ import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.File
import java.io.IOException
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
@ -79,8 +80,11 @@ internal interface PlausibleClient {
* The primary client for sending events to Plausible. It will attempt to send events immediately,
* caching them to disk to send later upon failure.
*/
internal class NetworkFirstPlausibleClient(private val config: PlausibleConfig) : PlausibleClient {
private val coroutineScope = CoroutineScope(Dispatchers.IO)
internal class NetworkFirstPlausibleClient(
private val config: PlausibleConfig,
coroutineContext: CoroutineContext = Dispatchers.IO
) : PlausibleClient {
private val coroutineScope = CoroutineScope(coroutineContext)
init {
coroutineScope.launch {
@ -125,7 +129,7 @@ internal class NetworkFirstPlausibleClient(private val config: PlausibleConfig)
postEvent(event)
file.delete()
break
} catch(e: IOException) {
} catch (e: IOException) {
retryAttempts++
}
}

View file

@ -69,19 +69,19 @@ open class ThreadSafePlausibleConfig(
override val screenWidth: Int
) : PlausibleConfig {
private val enableRef = AtomicBoolean()
private val enableRef = AtomicBoolean(true)
override var enable: Boolean
get() = enableRef.get()
set(value) = enableRef.set(value)
private val domainRef = AtomicReference<String>()
private val domainRef = AtomicReference("")
override var domain: String
get() = domainRef.get()
set(value) = domainRef.set(value)
private val hostRef = AtomicReference(DEFAULT_PLAUSIBLE_HOST)
override var host: String
get() = hostRef.get()
get() = hostRef.get() ?: ""
set(value) = hostRef.set(value.ifBlank { DEFAULT_PLAUSIBLE_HOST })
private val retryRef = AtomicBoolean(true)