Add test for DefaultBugReporter
This commit is contained in:
@@ -23,6 +23,12 @@ plugins {
|
||||
|
||||
android {
|
||||
namespace = "io.element.android.features.rageshake.impl"
|
||||
|
||||
testOptions {
|
||||
unitTests {
|
||||
isIncludeAndroidResources = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
anvil {
|
||||
@@ -57,6 +63,9 @@ dependencies {
|
||||
testImplementation(libs.test.turbine)
|
||||
testImplementation(libs.test.mockk)
|
||||
testImplementation(projects.libraries.matrix.test)
|
||||
testImplementation(projects.libraries.sessionStorage.implMemory)
|
||||
testImplementation(projects.features.rageshake.test)
|
||||
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 sessionStore: SessionStore,
|
||||
private val buildMeta: BuildMeta,
|
||||
private val bugReporterUrlProvider: BugReporterUrlProvider,
|
||||
) : BugReporter {
|
||||
companion object {
|
||||
// filenames
|
||||
@@ -223,7 +224,7 @@ class DefaultBugReporter @Inject constructor(
|
||||
|
||||
// build the request
|
||||
val request = Request.Builder()
|
||||
.url(context.getString(R.string.bug_report_url))
|
||||
.url(bugReporterUrlProvider.provide())
|
||||
.post(requestBody)
|
||||
.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_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_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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user