Первые тесты

This commit is contained in:
2026-05-19 00:48:07 +03:00
parent fd6f2e5879
commit eecaf44b72
58 changed files with 1634 additions and 501 deletions

View File

@@ -21,6 +21,8 @@ dependencies {
implementation(libs.kotlinx.coroutines.core)
testImplementation(libs.junit)
testImplementation(libs.kotlinx.coroutines.test)
testImplementation(libs.mockwebserver)
implementation(project(":domain"))
implementation(project(":vault-contracts"))

View File

@@ -1,24 +0,0 @@
package com.github.nullptroma.wallenc.domain.vault
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.github.nullptroma.wallenc.domain.vault.test", appContext.packageName)
}
}

View File

@@ -1,6 +1,7 @@
package com.github.nullptroma.wallenc.domain.vault.network.yandexdisk
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.github.nullptroma.wallenc.domain.vault.network.yandexdisk.repository.YandexDiskRepository
import com.github.nullptroma.wallenc.domain.vault.ports.YandexAccountStore
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.runBlocking
@@ -72,7 +73,30 @@ class YandexDiskApiFactory(
}
companion object {
private const val BASE_URL = "https://cloud-api.yandex.net/"
const val BASE_URL = "https://cloud-api.yandex.net/"
private const val OAUTH_TOKEN_CACHE_TTL_MS = 120_000L
fun createRepositoryWithToken(
oauthToken: String,
ioDispatcher: CoroutineDispatcher,
): YandexDiskRepository {
val client = OkHttpClient.Builder()
.addInterceptor { chain ->
chain.proceed(
chain.request().newBuilder()
.header("Authorization", "OAuth $oauthToken")
.header("Accept", "application/json")
.build(),
)
}
.build()
val api = Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(JacksonConverterFactory.create(jacksonObjectMapper().findAndRegisterModules()))
.build()
.create(YandexDiskApi::class.java)
return YandexDiskRepository(api, OkHttpClient(), ioDispatcher)
}
}
}

View File

@@ -0,0 +1,47 @@
package com.github.nullptroma.wallenc.domain.vault.errors
import com.github.nullptroma.wallenc.domain.errors.WallencException
import com.github.nullptroma.wallenc.domain.vault.network.yandexdisk.YandexDiskAuthException
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import okhttp3.ResponseBody.Companion.toResponseBody
import retrofit2.HttpException
import retrofit2.Response
import java.io.FileNotFoundException
import java.io.IOException
class VaultThrowableMappingTest {
@Test
fun mapsYandexDiskAuthToAuthFailed() {
val mapped = YandexDiskAuthException("unauthorized").toVaultWallencException()
assertEquals(WallencException.Auth.Failed, mapped)
}
@Test
fun mapsHttpExceptionToNetworkHttpFailed() {
val response = Response.error<String>(401, "".toResponseBody(null))
val mapped = HttpException(response).toVaultWallencException()
assertTrue(mapped is WallencException.Network.HttpFailed)
assertEquals(401, (mapped as WallencException.Network.HttpFailed).statusCode)
}
@Test
fun mapsMissingOAuthTokenIoToTokenMissing() {
val mapped = IOException("Yandex OAuth token is missing").toVaultWallencException()
assertEquals(WallencException.Auth.TokenMissing, mapped)
}
@Test
fun mapsFileNotFoundToStorageFileNotFound() {
val mapped = FileNotFoundException("x").toVaultWallencException()
assertEquals(WallencException.Storage.FileNotFound, mapped)
}
@Test
fun mapsIllegalStateNotAFile() {
val mapped = IllegalStateException("Not a file").toVaultWallencException()
assertEquals(WallencException.Storage.NotAFile, mapped)
}
}

View File

@@ -0,0 +1,48 @@
package com.github.nullptroma.wallenc.domain.vault.network.yandexdisk
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.github.nullptroma.wallenc.domain.vault.network.yandexdisk.repository.YandexDiskRepository
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.jackson.JacksonConverterFactory
import java.io.IOException
object YandexDiskRepositoryTestFactory {
private val jackson = jacksonObjectMapper().findAndRegisterModules()
fun create(
baseUrl: String,
oauthToken: String,
ioDispatcher: CoroutineDispatcher = Dispatchers.IO,
rawHttp: OkHttpClient = OkHttpClient(),
): YandexDiskRepository {
val api = createApi(baseUrl) { oauthToken }
return YandexDiskRepository(api, rawHttp, ioDispatcher)
}
fun createApi(
baseUrl: String,
tokenProvider: () -> String?,
): YandexDiskApi {
val client = OkHttpClient.Builder()
.addInterceptor { chain ->
val token = tokenProvider()
?: throw IOException("Yandex OAuth token is missing")
chain.proceed(
chain.request().newBuilder()
.header("Authorization", "OAuth $token")
.build(),
)
}
.build()
return Retrofit.Builder()
.baseUrl(baseUrl)
.client(client)
.addConverterFactory(JacksonConverterFactory.create(jackson))
.build()
.create(YandexDiskApi::class.java)
}
}

View File

@@ -0,0 +1,66 @@
package com.github.nullptroma.wallenc.domain.vault.network.yandexdisk.repository
import com.github.nullptroma.wallenc.domain.vault.network.yandexdisk.YandexDiskAuthException
import com.github.nullptroma.wallenc.domain.vault.network.yandexdisk.YandexDiskRepositoryTestFactory
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import okhttp3.OkHttpClient
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
class YandexDiskRepositoryTest {
private lateinit var server: MockWebServer
private lateinit var repository: YandexDiskRepository
@Before
fun setUp() {
server = MockWebServer()
server.start()
val api = YandexDiskRepositoryTestFactory.createApi(server.url("/").toString()) { "test-token" }
repository = YandexDiskRepository(api, OkHttpClient(), Dispatchers.IO)
}
@After
fun tearDown() {
server.shutdown()
}
@Test
fun diskInfoParsesResponse() = runBlocking {
server.enqueue(
MockResponse()
.setResponseCode(200)
.setBody("""{"total_space":1000,"used_space":200,"trash_size":0}""")
.addHeader("Content-Type", "application/json"),
)
val info = repository.diskInfo()
assertEquals(1000L, info.totalSpace)
assertEquals(200L, info.usedSpace)
}
@Test
fun listReturnsEmptyEmbeddedOn404() = runBlocking {
repeat(2) {
server.enqueue(MockResponse().setResponseCode(404))
}
val result = repository.list("disk:/missing", limit = 10, offset = 0)
assertTrue(result.embedded?.items?.isEmpty() == true)
}
@Test
fun diskInfoThrowsAuthExceptionOn401() = runBlocking {
server.enqueue(MockResponse().setResponseCode(401))
try {
repository.diskInfo()
error("Expected YandexDiskAuthException")
} catch (_: YandexDiskAuthException) {
// expected
}
}
}

View File

@@ -1,17 +0,0 @@
package com.github.nullptroma.wallenc.domain.vault
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}