Add test for DefaultBugReporter
This commit is contained in:
parent
124e708160
commit
b5b14d38a0
8 changed files with 285 additions and 1 deletions
|
|
@ -23,6 +23,12 @@ plugins {
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "io.element.android.features.rageshake.impl"
|
namespace = "io.element.android.features.rageshake.impl"
|
||||||
|
|
||||||
|
testOptions {
|
||||||
|
unitTests {
|
||||||
|
isIncludeAndroidResources = true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
anvil {
|
anvil {
|
||||||
|
|
@ -57,6 +63,9 @@ dependencies {
|
||||||
testImplementation(libs.test.turbine)
|
testImplementation(libs.test.turbine)
|
||||||
testImplementation(libs.test.mockk)
|
testImplementation(libs.test.mockk)
|
||||||
testImplementation(projects.libraries.matrix.test)
|
testImplementation(projects.libraries.matrix.test)
|
||||||
|
testImplementation(projects.libraries.sessionStorage.implMemory)
|
||||||
testImplementation(projects.features.rageshake.test)
|
testImplementation(projects.features.rageshake.test)
|
||||||
testImplementation(projects.tests.testutils)
|
testImplementation(projects.tests.testutils)
|
||||||
|
testImplementation(projects.services.toolbox.test)
|
||||||
|
testImplementation(libs.network.mockwebserver)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.features.rageshake.impl.reporter
|
||||||
|
|
||||||
|
import okhttp3.HttpUrl
|
||||||
|
|
||||||
|
fun interface BugReporterUrlProvider {
|
||||||
|
fun provide(): HttpUrl
|
||||||
|
}
|
||||||
|
|
@ -75,6 +75,7 @@ class DefaultBugReporter @Inject constructor(
|
||||||
private val userAgentProvider: UserAgentProvider,
|
private val userAgentProvider: UserAgentProvider,
|
||||||
private val sessionStore: SessionStore,
|
private val sessionStore: SessionStore,
|
||||||
private val buildMeta: BuildMeta,
|
private val buildMeta: BuildMeta,
|
||||||
|
private val bugReporterUrlProvider: BugReporterUrlProvider,
|
||||||
) : BugReporter {
|
) : BugReporter {
|
||||||
companion object {
|
companion object {
|
||||||
// filenames
|
// filenames
|
||||||
|
|
@ -223,7 +224,7 @@ class DefaultBugReporter @Inject constructor(
|
||||||
|
|
||||||
// build the request
|
// build the request
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url(context.getString(R.string.bug_report_url))
|
.url(bugReporterUrlProvider.provide())
|
||||||
.post(requestBody)
|
.post(requestBody)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.features.rageshake.impl.reporter
|
||||||
|
|
||||||
|
import com.squareup.anvil.annotations.ContributesBinding
|
||||||
|
import io.element.android.features.rageshake.impl.R
|
||||||
|
import io.element.android.libraries.di.AppScope
|
||||||
|
import io.element.android.services.toolbox.api.strings.StringProvider
|
||||||
|
import okhttp3.HttpUrl
|
||||||
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ContributesBinding(AppScope::class)
|
||||||
|
class DefaultBugReporterUrlProvider @Inject constructor(
|
||||||
|
private val stringProvider: StringProvider
|
||||||
|
) : BugReporterUrlProvider {
|
||||||
|
override fun provide(): HttpUrl {
|
||||||
|
return stringProvider.getString(R.string.bug_report_url).toHttpUrl()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,150 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.features.rageshake.impl.reporter
|
||||||
|
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.features.rageshake.api.reporter.BugReporterListener
|
||||||
|
import io.element.android.features.rageshake.test.crash.FakeCrashDataStore
|
||||||
|
import io.element.android.features.rageshake.test.screenshot.FakeScreenshotHolder
|
||||||
|
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
||||||
|
import io.element.android.libraries.network.useragent.DefaultUserAgentProvider
|
||||||
|
import io.element.android.libraries.sessionstorage.impl.memory.InMemorySessionStore
|
||||||
|
import io.element.android.services.toolbox.test.systemclock.FakeSystemClock
|
||||||
|
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||||
|
import kotlinx.coroutines.test.TestScope
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.mockwebserver.MockResponse
|
||||||
|
import okhttp3.mockwebserver.MockWebServer
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.robolectric.RobolectricTestRunner
|
||||||
|
import org.robolectric.RuntimeEnvironment
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner::class)
|
||||||
|
class DefaultBugReporterTest {
|
||||||
|
@Test
|
||||||
|
fun `test sendBugReport success`() = runTest {
|
||||||
|
val server = MockWebServer()
|
||||||
|
server.enqueue(
|
||||||
|
MockResponse()
|
||||||
|
.setResponseCode(200)
|
||||||
|
)
|
||||||
|
server.start()
|
||||||
|
val sut = createDefaultBugReporter(server)
|
||||||
|
var onUploadCancelledCalled = false
|
||||||
|
var onUploadFailedCalled = false
|
||||||
|
var progressValues = mutableListOf<Int>()
|
||||||
|
var onUploadSucceedCalled = false
|
||||||
|
sut.sendBugReport(
|
||||||
|
withDevicesLogs = true,
|
||||||
|
withCrashLogs = true,
|
||||||
|
withScreenshot = true,
|
||||||
|
theBugDescription = "a bug occurred",
|
||||||
|
canContact = true,
|
||||||
|
listener = object : BugReporterListener {
|
||||||
|
override fun onUploadCancelled() {
|
||||||
|
onUploadCancelledCalled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onUploadFailed(reason: String?) {
|
||||||
|
onUploadFailedCalled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onProgress(progress: Int) {
|
||||||
|
progressValues.add(progress)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onUploadSucceed() {
|
||||||
|
onUploadSucceedCalled = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
server.shutdown()
|
||||||
|
assertThat(onUploadCancelledCalled).isFalse()
|
||||||
|
assertThat(onUploadFailedCalled).isFalse()
|
||||||
|
assertThat(progressValues.size).isEqualTo(10)
|
||||||
|
assertThat(onUploadSucceedCalled).isTrue()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test sendBugReport error`() = runTest {
|
||||||
|
val server = MockWebServer()
|
||||||
|
server.enqueue(
|
||||||
|
MockResponse()
|
||||||
|
.setResponseCode(400)
|
||||||
|
.setBody("""{"error": "An error body"}""")
|
||||||
|
)
|
||||||
|
server.start()
|
||||||
|
val sut = createDefaultBugReporter(server)
|
||||||
|
var onUploadCancelledCalled = false
|
||||||
|
var onUploadFailedCalled = false
|
||||||
|
var onUploadFailedReason: String? = null
|
||||||
|
var progressValues = mutableListOf<Int>()
|
||||||
|
var onUploadSucceedCalled = false
|
||||||
|
sut.sendBugReport(
|
||||||
|
withDevicesLogs = true,
|
||||||
|
withCrashLogs = true,
|
||||||
|
withScreenshot = true,
|
||||||
|
theBugDescription = "a bug occurred",
|
||||||
|
canContact = true,
|
||||||
|
listener = object : BugReporterListener {
|
||||||
|
override fun onUploadCancelled() {
|
||||||
|
onUploadCancelledCalled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onUploadFailed(reason: String?) {
|
||||||
|
onUploadFailedCalled = true
|
||||||
|
onUploadFailedReason = reason
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onProgress(progress: Int) {
|
||||||
|
progressValues.add(progress)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onUploadSucceed() {
|
||||||
|
onUploadSucceedCalled = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
server.shutdown()
|
||||||
|
assertThat(onUploadCancelledCalled).isFalse()
|
||||||
|
assertThat(onUploadFailedCalled).isTrue()
|
||||||
|
assertThat(onUploadFailedReason).isEqualTo("An error body")
|
||||||
|
assertThat(progressValues.size).isEqualTo(10)
|
||||||
|
assertThat(onUploadSucceedCalled).isFalse()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun TestScope.createDefaultBugReporter(
|
||||||
|
server: MockWebServer
|
||||||
|
): DefaultBugReporter {
|
||||||
|
val buildMeta = aBuildMeta()
|
||||||
|
return DefaultBugReporter(
|
||||||
|
context = RuntimeEnvironment.getApplication(),
|
||||||
|
screenshotHolder = FakeScreenshotHolder(),
|
||||||
|
crashDataStore = FakeCrashDataStore(),
|
||||||
|
coroutineScope = this,
|
||||||
|
systemClock = FakeSystemClock(),
|
||||||
|
coroutineDispatchers = testCoroutineDispatchers(),
|
||||||
|
okHttpClient = { OkHttpClient.Builder().build() },
|
||||||
|
userAgentProvider = DefaultUserAgentProvider(buildMeta),
|
||||||
|
sessionStore = InMemorySessionStore(),
|
||||||
|
buildMeta = buildMeta,
|
||||||
|
bugReporterUrlProvider = { server.url("/") }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.features.rageshake.impl.reporter
|
||||||
|
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.services.toolbox.test.strings.FakeStringProvider
|
||||||
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class DefaultBugReporterUrlProviderTest {
|
||||||
|
@Test
|
||||||
|
fun `test DefaultBugReporterUrlProvider`() {
|
||||||
|
val sut = DefaultBugReporterUrlProvider(FakeStringProvider("https://example.org"))
|
||||||
|
val result = sut.provide()
|
||||||
|
assertThat(result).isEqualTo("https://example.org".toHttpUrl())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -113,6 +113,7 @@ network_okhttp_bom = "com.squareup.okhttp3:okhttp-bom:4.12.0"
|
||||||
network_okhttp_logging = { module = "com.squareup.okhttp3:logging-interceptor" }
|
network_okhttp_logging = { module = "com.squareup.okhttp3:logging-interceptor" }
|
||||||
network_okhttp_okhttp = { module = "com.squareup.okhttp3:okhttp" }
|
network_okhttp_okhttp = { module = "com.squareup.okhttp3:okhttp" }
|
||||||
network_okhttp = { module = "com.squareup.okhttp3:okhttp" }
|
network_okhttp = { module = "com.squareup.okhttp3:okhttp" }
|
||||||
|
network_mockwebserver = { module = "com.squareup.okhttp3:mockwebserver" }
|
||||||
network_retrofit = "com.squareup.retrofit2:retrofit:2.9.0"
|
network_retrofit = "com.squareup.retrofit2:retrofit:2.9.0"
|
||||||
network_retrofit_converter_serialization = "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0"
|
network_retrofit_converter_serialization = "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 New Vector Ltd
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.services.toolbox.test.strings
|
||||||
|
|
||||||
|
import io.element.android.services.toolbox.api.strings.StringProvider
|
||||||
|
|
||||||
|
class FakeStringProvider(
|
||||||
|
private val defaultResult: String = "A string"
|
||||||
|
) : StringProvider {
|
||||||
|
override fun getString(resId: Int): String {
|
||||||
|
return defaultResult
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getString(resId: Int, vararg formatArgs: Any?): String {
|
||||||
|
return defaultResult
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getQuantityString(resId: Int, quantity: Int, vararg formatArgs: Any?): String {
|
||||||
|
return defaultResult
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue