Skip to content
Snippets Groups Projects
Commit 829e4847 authored by Torsten Grote's avatar Torsten Grote
Browse files

Merge branch 'fix-official-mirror-added-as-user-mirror' into 'master'

Don't add official mirror as user mirror when adding repo via official mirror

Closes #2981

See merge request fdroid/fdroidclient!1530
parents 7fbcdf74 319ff867
No related branches found
No related tags found
No related merge requests found
......@@ -25,7 +25,7 @@ internal object TestUtils {
fun assertRepoEquals(repoV2: RepoV2, repo: Repository) {
val repoId = repo.repoId
// mirrors
val expectedMirrors = repoV2.mirrors.map { it.toMirror(repoId) }.toSet()
val expectedMirrors = repoV2.mirrors.toMirrors(repoId).toSet()
Assert.assertEquals(expectedMirrors, repo.mirrors.toSet())
// anti-features
val expectedAntiFeatures = repoV2.antiFeatures.toRepoAntiFeatures(repoId).toSet()
......
......@@ -288,6 +288,10 @@ internal fun MirrorV2.toMirror(repoId: Long) = Mirror(
countryCode = countryCode,
)
internal fun List<MirrorV2>.toMirrors(repoId: Long): List<Mirror> {
return this.map { it.toMirror(repoId) }
}
/**
* An attribute belonging to a [Repository].
*/
......
......@@ -7,6 +7,7 @@ import org.fdroid.database.LocalizedIcon
import org.fdroid.database.Repository
import org.fdroid.database.RepositoryPreferences
import org.fdroid.database.toCoreRepository
import org.fdroid.database.toMirrors
import org.fdroid.database.toRepoAntiFeatures
import org.fdroid.database.toRepoCategories
import org.fdroid.database.toRepoReleaseChannel
......@@ -36,7 +37,7 @@ internal open class RepoV2StreamReceiver(
formatVersion = formatVersion,
certificate = certificate
),
mirrors = emptyList(),
mirrors = repo.mirrors.toMirrors(REPO_ID),
antiFeatures = repo.antiFeatures.toRepoAntiFeatures(REPO_ID),
categories = repo.categories.toRepoCategories(REPO_ID),
releaseChannels = repo.releaseChannels.toRepoReleaseChannel(REPO_ID),
......
......@@ -29,6 +29,7 @@ import org.fdroid.database.Repository
import org.fdroid.database.RepositoryDaoInt
import org.fdroid.database.RepositoryPreferences
import org.fdroid.database.toCoreRepository
import org.fdroid.database.toMirrors
import org.fdroid.download.Downloader
import org.fdroid.download.DownloaderFactory
import org.fdroid.download.HttpManager
......@@ -47,6 +48,7 @@ import org.fdroid.repo.AddRepoError.ErrorType.UNKNOWN_SOURCES_DISALLOWED
import org.fdroid.repo.FetchResult.IsNewMirror
import org.fdroid.repo.FetchResult.IsNewRepoAndNewMirror
import org.fdroid.repo.FetchResult.IsNewRepository
import org.fdroid.test.TestDataMidV2
import org.fdroid.test.TestDataMinV2
import org.fdroid.test.TestUtils.decodeHex
import org.fdroid.test.TestUtils.getRandomString
......@@ -178,6 +180,39 @@ internal class RepoAdderTest {
}
}
@Test
fun testAddingMidRepoByOfficialMirror() = runTest {
val url = "https://mid-v1.com/repo" // official mirror
val repoName = TestDataMidV2.repo.name.getBestLocale(localeList)
mockMidRepoDownload(url)
// repo not in DB
every { repoDao.getRepository(any<String>()) } returns null
expectMidRepoPreview(repoName, url, IsNewRepository)
val newRepo: Repository = mockk()
mockNewRepoDbInsertion(repoName, TestDataMidV2.repo.address, newRepo)
repoAdder.addRepoState.test {
val fetching: Fetching = awaitItem() as Fetching // still Fetching from last call
assertIs<IsNewRepository>(fetching.fetchResult)
repoAdder.addFetchedRepository()
assertIs<Adding>(awaitItem()) // now moved to Adding
val addedState = awaitItem()
assertIs<Added>(addedState)
assertEquals(newRepo, addedState.repo)
}
verify(exactly = 0) {
repoDao.updateUserMirrors(42L, listOf(url))
}
}
@Test
fun testAddingUserMirrorForExistingMinRepo() = runTest {
val url = "https://user-mirror-of-min-v1.org/repo"
......@@ -807,6 +842,18 @@ internal class RepoAdderTest {
)
}
private fun mockMidRepoDownload(
// Override the URL to download, e.g., when adding via a user/official mirror
downloadUrl: String = TestDataMidV2.repo.address,
) {
mockRepoDownload(
downloadUrl,
"index-mid-v2.json",
"diff-empty-mid/entry.jar",
"561630a90ec9bcc29bc133cbd14b2d14d94124bb043c8d48effbad9d18d482fb",
)
}
private fun mockRepoDownload(
downloadUrlTrimmed: String,
indexFile: String,
......@@ -882,6 +929,54 @@ internal class RepoAdderTest {
repoName: String?,
url: String,
expectedFetchResult: FetchResult,
) {
expectRepoPreview(
repoName,
url,
expectedFetchResult,
TestDataMinV2.repo,
) { awaitItem ->
val state = awaitItem()
assertIs<Fetching>(state)
assertEquals(TestDataMinV2.packages.size, state.apps.size)
assertEquals(TestDataMinV2.PACKAGE_NAME, state.apps[0].packageName)
assertFalse(state.done)
}
}
private suspend fun expectMidRepoPreview(
repoName: String?,
url: String,
expectedFetchResult: FetchResult,
) {
expectRepoPreview(
repoName,
url,
expectedFetchResult,
TestDataMidV2.repo,
) { awaitItem ->
val state = awaitItem()
assertIs<Fetching>(state)
assertEquals(1, state.apps.size)
assertEquals(TestDataMidV2.PACKAGE_NAME_1, state.apps[0].packageName)
assertFalse(state.done)
// onAppReceived (second app)
val stateNext = awaitItem()
assertIs<Fetching>(stateNext)
assertEquals(TestDataMidV2.packages.size, stateNext.apps.size)
assertEquals(TestDataMidV2.PACKAGE_NAME_1, stateNext.apps[0].packageName)
assertEquals(TestDataMidV2.PACKAGE_NAME_2, stateNext.apps[1].packageName)
assertFalse(stateNext.done)
}
}
private suspend fun expectRepoPreview(
repoName: String?,
url: String,
expectedFetchResult: FetchResult,
expectedRepo: RepoV2,
onAppsReceived: suspend (suspend () -> AddRepoState) -> Unit,
) {
repoAdder.addRepoState.test {
assertIs<None>(awaitItem())
......@@ -904,19 +999,16 @@ internal class RepoAdderTest {
val state2 = awaitItem()
assertIs<Fetching>(state2)
val repo = state2.receivedRepo ?: fail()
assertEquals(TestDataMinV2.repo.address, repo.address)
assertEquals(expectedRepo.address, repo.address)
assertEquals(repoName, repo.getName(localeList))
assertEquals(expectedRepo.mirrors.toMirrors(0L), repo.mirrors)
val result = state2.fetchResult ?: fail()
assertEquals(expectedFetchResult, result)
assertTrue(state2.apps.isEmpty())
assertFalse(state2.done)
// onAppReceived
val state3 = awaitItem()
assertIs<Fetching>(state3)
assertEquals(TestDataMinV2.packages.size, state3.apps.size)
assertEquals(TestDataMinV2.PACKAGE_NAME, state3.apps[0].packageName)
assertFalse(state3.done)
// onAppReceived (state3)
onAppsReceived(::awaitItem)
// final result
val state4 = awaitItem()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment