diff --git a/build.gradle.kts b/build.gradle.kts index 03cc132f..b5be8d6f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -31,6 +31,7 @@ dependencies { testing { dependencies { implementation(libs.dotenv) + implementation(libs.mockito) } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5faf0a36..d9c0cc69 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,6 +15,7 @@ serialization = "1.6.0" annotations = { group = "org.jetbrains", name = "annotations", version.ref = "annotations" } serialization = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "serialization" } dotenv = { group = "io.github.cdimascio", name = "dotenv-kotlin", version = "6.4.1" } +mockito = { group = "org.mockito.kotlin", name = "mockito-kotlin", version = "5.2.1" } [plugins] changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" } diff --git a/src/main/kotlin/com/dsoftware/ghmanager/data/GhActionsService.kt b/src/main/kotlin/com/dsoftware/ghmanager/data/GhActionsService.kt index 4744348b..1c3def2c 100644 --- a/src/main/kotlin/com/dsoftware/ghmanager/data/GhActionsService.kt +++ b/src/main/kotlin/com/dsoftware/ghmanager/data/GhActionsService.kt @@ -1,29 +1,28 @@ package com.dsoftware.ghmanager.data -import com.dsoftware.ghmanager.ui.settings.GhActionsSettingsService -import com.intellij.collaboration.auth.Account -import com.intellij.openapi.components.Service import com.intellij.openapi.components.service import com.intellij.openapi.project.Project -import git4idea.remote.GitRemoteUrlCoordinates import git4idea.remote.hosting.knownRepositories import kotlinx.coroutines.flow.StateFlow import org.jetbrains.plugins.github.authentication.accounts.GHAccountManager import org.jetbrains.plugins.github.authentication.accounts.GithubAccount import org.jetbrains.plugins.github.util.GHGitRepositoryMapping import org.jetbrains.plugins.github.util.GHHostedRepositoriesManager -import org.jetbrains.plugins.github.util.LazyCancellableBackgroundProcessValue -@Service(Service.Level.PROJECT) -class GhActionsService(project: Project) { +interface GhActionsService { + val knownRepositoriesState: StateFlow> + val knownRepositories: Set + val accountsState: StateFlow> +} - val repositoriesManager = project.service() - val accountManager = service() +open class GhActionsServiceImpl(project: Project) : GhActionsService { + private val repositoriesManager = project.service() + private val accountManager = service() - val knownRepositoriesState: kotlinx.coroutines.flow.StateFlow> + override val knownRepositoriesState: StateFlow> get() = repositoriesManager.knownRepositoriesState - val knownRepositories: Set + override val knownRepositories: Set get() = repositoriesManager.knownRepositories - val accountsState: StateFlow> + override val accountsState: StateFlow> get() = accountManager.accountsState } \ No newline at end of file diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 9b0827cc..356bd64d 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -19,6 +19,9 @@ parentId="tools" instance="com.dsoftware.ghmanager.ui.settings.GhActionsManagerConfigurable" displayName="GitHub Workflows Manager"/> + diff --git a/src/test/kotlin/com/dsoftware/ghmanager/GitHubActionsManagerBaseTest.kt b/src/test/kotlin/com/dsoftware/ghmanager/GitHubActionsManagerBaseTest.kt index d41f1c40..36c55555 100644 --- a/src/test/kotlin/com/dsoftware/ghmanager/GitHubActionsManagerBaseTest.kt +++ b/src/test/kotlin/com/dsoftware/ghmanager/GitHubActionsManagerBaseTest.kt @@ -1,27 +1,27 @@ package com.dsoftware.ghmanager +import com.dsoftware.ghmanager.data.GhActionsService import com.dsoftware.ghmanager.ui.GhActionsToolWindowFactory -import com.intellij.openapi.components.service import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.project.Project import com.intellij.openapi.wm.ToolWindow import com.intellij.platform.ide.progress.runWithModalProgressBlocking import com.intellij.testFramework.PlatformTestUtil -import com.intellij.testFramework.RunAll import com.intellij.testFramework.fixtures.BasePlatformTestCase +import com.intellij.testFramework.registerServiceInstance import com.intellij.toolWindow.ToolWindowHeadlessManagerImpl.MockToolWindow -import com.intellij.util.ThrowableRunnable import com.intellij.util.concurrency.annotations.RequiresEdt import io.github.cdimascio.dotenv.Dotenv import io.github.cdimascio.dotenv.dotenv -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.yield import org.jetbrains.plugins.github.api.GithubApiRequestExecutor -import org.jetbrains.plugins.github.api.GithubApiRequests import org.jetbrains.plugins.github.api.GithubServerPath import org.jetbrains.plugins.github.authentication.GHAccountsUtil import org.jetbrains.plugins.github.authentication.accounts.GHAccountManager import org.jetbrains.plugins.github.authentication.accounts.GithubAccount +import org.jetbrains.plugins.github.util.GHGitRepositoryMapping import org.jetbrains.plugins.github.util.GHHostedRepositoriesManager @@ -42,48 +42,36 @@ import org.jetbrains.plugins.github.util.GHHostedRepositoriesManager * */ abstract class GitHubActionsManagerBaseTest : BasePlatformTestCase() { - protected lateinit var organisation: String - protected lateinit var executor: GithubApiRequestExecutor - protected lateinit var accountManager: GHAccountManager - protected lateinit var repositoriesManager: GHHostedRepositoriesManager - protected lateinit var mainAccount: AccountData + private lateinit var ghRepositoryManager: GHHostedRepositoriesManager protected lateinit var myProject: Project protected lateinit var factory: GhActionsToolWindowFactory protected lateinit var toolWindow: ToolWindow - protected lateinit var host: GithubServerPath + protected val host: GithubServerPath = GithubServerPath.from("github.com") override fun setUp() { super.setUp() Dotenv.configure().load() - val dotenv= dotenv() + val dotenv = dotenv() myProject = project factory = GhActionsToolWindowFactory() toolWindow = MockToolWindow(myProject) - host = GithubServerPath.from(dotenv.get("idea_test_github_host") ?: dotenv.get("idea.test.github.host")) - - val token1 = dotenv.get("idea_test_github_token1") ?: dotenv.get("idea.test.github.token1") - - assertNotNull(token1) - executor = service().create(token1) - accountManager = service() - repositoriesManager = project.service() - - organisation = dotenv.get("idea_test_github_org") ?: dotenv.get("idea.test.github.org") - assertNotNull(organisation) - mainAccount = createAccountData(token1) - setCurrentAccount(mainAccount) } - protected fun createAccountData(token: String): AccountData { - val account = GHAccountManager.createAccount("token", host) - val username = executor.execute(GithubApiRequests.CurrentUser.get(account.server)).login - val repos = executor.execute(GithubApiRequests.CurrentUser.Repos.get(account.server)) - - return AccountData(token, account, username, executor, repos.items.map { it.name }.toSet()) + fun mockGhActionsService(repoUrls: Set, accountNames: Collection) { + val accounts = accountNames.map { GHAccountManager.createAccount(it, host) } + val repos: Set = emptySet() + + project.registerServiceInstance(GhActionsService::class.java, object : GhActionsService { + override val knownRepositoriesState: StateFlow> + get() = MutableStateFlow(repos) + override val knownRepositories: Set + get() = repos + override val accountsState: StateFlow> + get() = MutableStateFlow(accounts) + }) } - protected open fun setCurrentAccount(accountData: AccountData?) { GHAccountsUtil.setDefaultAccount(myProject, accountData?.account) } @@ -97,27 +85,6 @@ abstract class GitHubActionsManagerBaseTest : BasePlatformTestCase() { ) - @Throws(Exception::class) - override fun tearDown() { - RunAll( - ThrowableRunnable { setCurrentAccount(null) }, - ThrowableRunnable { if (::accountManager.isInitialized) runBlocking { accountManager.updateAccounts(emptyMap()) } }, - ThrowableRunnable { super.tearDown() } - ).run() - } - -// -// private fun deleteRepos(account: AccountData, repos: Collection) { -// setCurrentAccount(account) -// for (repo in repos) { -// retry(LOG, true) { -// account.executor.execute(GithubApiRequests.Repos.delete(repo)) -// val info = account.executor.execute(GithubApiRequests.Repos.get(repo)) -// check(info == null) { "Repository still exists" } -// } -// } -// } - companion object { private const val RETRIES = 3 diff --git a/src/test/kotlin/com/dsoftware/ghmanager/ToolWindowFactoryTest.kt b/src/test/kotlin/com/dsoftware/ghmanager/ToolWindowFactoryTest.kt index 9b019cc9..36eb87f2 100644 --- a/src/test/kotlin/com/dsoftware/ghmanager/ToolWindowFactoryTest.kt +++ b/src/test/kotlin/com/dsoftware/ghmanager/ToolWindowFactoryTest.kt @@ -3,11 +3,12 @@ package com.dsoftware.ghmanager import com.intellij.ui.SimpleColoredComponent import com.intellij.ui.components.JBPanelWithEmptyText import junit.framework.TestCase -import kotlinx.coroutines.runBlocking class ToolWindowFactoryTest : GitHubActionsManagerBaseTest() { fun testNoGitHubAccountPanel() { + mockGhActionsService(emptySet(), emptySet()) + factory.init(toolWindow) executeSomeCoroutineTasksAndDispatchAllInvocationEvents(project) @@ -24,7 +25,7 @@ class ToolWindowFactoryTest : GitHubActionsManagerBaseTest() { } fun testGitHubAccountNoReposPanel() { - runBlocking { accountManager.updateAccount(mainAccount.account, mainAccount.token) } + mockGhActionsService(emptySet(), setOf("account1")) factory.init(toolWindow) executeSomeCoroutineTasksAndDispatchAllInvocationEvents(project) @@ -36,16 +37,16 @@ class ToolWindowFactoryTest : GitHubActionsManagerBaseTest() { TestCase.assertEquals("No git repositories in project", panel.emptyText.text) } -// fun testGitHubAccountWithReposPanel() { -// //TODO -// runBlocking { accountManager.updateAccount(mainAccount.account, mainAccount.token) } -// factory.init(toolWindow) -// executeSomeCoroutineTasksAndDispatchAllInvocationEvents(project) -// -// TestCase.assertEquals(1, toolWindow.contentManager.contentCount) -// val component = toolWindow.contentManager.contents[0].component -// TestCase.assertTrue(component is JBPanelWithEmptyText) -// val panel = component as JBPanelWithEmptyText -// TestCase.assertEquals("No git repositories in project", panel.emptyText.text) -// } + fun testGitHubAccountWithReposPanel() { + mockGhActionsService(emptySet(), setOf("account1")) + + factory.init(toolWindow) + executeSomeCoroutineTasksAndDispatchAllInvocationEvents(project) + + TestCase.assertEquals(1, toolWindow.contentManager.contentCount) + val component = toolWindow.contentManager.contents[0].component + TestCase.assertTrue(component is JBPanelWithEmptyText) + val panel = component as JBPanelWithEmptyText + TestCase.assertEquals("No git repositories in project", panel.emptyText.text) + } } \ No newline at end of file