Add some tests
This commit is contained in:
parent
0b35ae3030
commit
d1b934dea1
7 changed files with 219 additions and 7 deletions
87
.idea/androidTestResultsUserPreferences.xml
Normal file
87
.idea/androidTestResultsUserPreferences.xml
Normal 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>
|
|
@ -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'
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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++
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue