Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Verified Commit eb3d947a authored by Fahim M. Choudhury's avatar Fahim M. Choudhury
Browse files

test: cover pre-enqueue install gating

Pin the new pre-enqueue orchestration logic after the install refactor so short-circuit regressions are caught directly.
parent 36b64557
Loading
Loading
Loading
Loading
+144 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2026 e Foundation
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

package foundation.e.apps.installProcessor

import foundation.e.apps.data.enums.Source
import foundation.e.apps.data.enums.Type
import foundation.e.apps.data.install.AppManagerWrapper
import foundation.e.apps.data.install.models.AppInstall
import foundation.e.apps.data.install.workmanager.AppInstallAgeLimitGate
import foundation.e.apps.data.install.workmanager.AppInstallDevicePreconditions
import foundation.e.apps.data.install.workmanager.AppInstallDownloadUrlRefresher
import foundation.e.apps.data.install.workmanager.AppInstallPreEnqueueChecker
import foundation.e.apps.domain.model.install.Status
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.mockk
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test

@OptIn(ExperimentalCoroutinesApi::class)
class AppInstallPreEnqueueCheckerTest {
    private lateinit var appInstallDownloadUrlRefresher: AppInstallDownloadUrlRefresher
    private lateinit var appManagerWrapper: AppManagerWrapper
    private lateinit var appInstallAgeLimitGate: AppInstallAgeLimitGate
    private lateinit var appInstallDevicePreconditions: AppInstallDevicePreconditions
    private lateinit var checker: AppInstallPreEnqueueChecker

    @Before
    fun setup() {
        appInstallDownloadUrlRefresher = mockk(relaxed = true)
        appManagerWrapper = mockk(relaxed = true)
        appInstallAgeLimitGate = mockk(relaxed = true)
        appInstallDevicePreconditions = mockk(relaxed = true)
        checker = AppInstallPreEnqueueChecker(
            appInstallDownloadUrlRefresher,
            appManagerWrapper,
            appInstallAgeLimitGate,
            appInstallDevicePreconditions
        )
    }

    @Test
    fun canEnqueue_skipsDownloadUrlRefreshForPwaInstalls() = runTest {
        val appInstall = createPwaInstall()
        coEvery { appManagerWrapper.addDownload(appInstall) } returns true
        coEvery { appInstallAgeLimitGate.allow(appInstall) } returns true
        coEvery { appInstallDevicePreconditions.canProceed(appInstall) } returns true

        val result = checker.canEnqueue(appInstall)

        assertTrue(result)
        coVerify(exactly = 0) {
            appInstallDownloadUrlRefresher.updateDownloadUrls(any(), any())
        }
    }

    @Test
    fun canEnqueue_stopsWhenDownloadRefreshFails() = runTest {
        val appInstall = createNativeInstall()
        coEvery { appInstallDownloadUrlRefresher.updateDownloadUrls(appInstall, false) } returns false

        val result = checker.canEnqueue(appInstall)

        assertFalse(result)
        coVerify(exactly = 0) { appManagerWrapper.addDownload(any()) }
        coVerify(exactly = 0) { appInstallAgeLimitGate.allow(any()) }
        coVerify(exactly = 0) { appInstallDevicePreconditions.canProceed(any()) }
    }

    @Test
    fun canEnqueue_stopsWhenAddingDownloadFails() = runTest {
        val appInstall = createNativeInstall()
        coEvery { appInstallDownloadUrlRefresher.updateDownloadUrls(appInstall, false) } returns true
        coEvery { appManagerWrapper.addDownload(appInstall) } returns false

        val result = checker.canEnqueue(appInstall)

        assertFalse(result)
        coVerify(exactly = 0) { appInstallAgeLimitGate.allow(any()) }
        coVerify(exactly = 0) { appInstallDevicePreconditions.canProceed(any()) }
    }

    @Test
    fun canEnqueue_stopsWhenAgeLimitRejectsInstall() = runTest {
        val appInstall = createNativeInstall()
        coEvery { appInstallDownloadUrlRefresher.updateDownloadUrls(appInstall, false) } returns true
        coEvery { appManagerWrapper.addDownload(appInstall) } returns true
        coEvery { appInstallAgeLimitGate.allow(appInstall) } returns false

        val result = checker.canEnqueue(appInstall)

        assertFalse(result)
        coVerify(exactly = 0) { appInstallDevicePreconditions.canProceed(any()) }
    }

    @Test
    fun canEnqueue_returnsTrueWhenAllChecksPass() = runTest {
        val appInstall = createNativeInstall()
        coEvery { appInstallDownloadUrlRefresher.updateDownloadUrls(appInstall, false) } returns true
        coEvery { appManagerWrapper.addDownload(appInstall) } returns true
        coEvery { appInstallAgeLimitGate.allow(appInstall) } returns true
        coEvery { appInstallDevicePreconditions.canProceed(appInstall) } returns true

        val result = checker.canEnqueue(appInstall)

        assertTrue(result)
    }

    private fun createPwaInstall() = AppInstall(
        type = Type.PWA,
        id = "123",
        status = Status.AWAITING,
        downloadURLList = mutableListOf("apk"),
        packageName = "com.example.app"
    )

    private fun createNativeInstall() = AppInstall(
        type = Type.NATIVE,
        source = Source.PLAY_STORE,
        id = "123",
        status = Status.AWAITING,
        packageName = "com.example.app"
    )
}