Skip to content

Commit

Permalink
feat:implement tests
Browse files Browse the repository at this point in the history
  • Loading branch information
cunla committed Jan 28, 2024
1 parent e395717 commit aba723a
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 33 deletions.
24 changes: 0 additions & 24 deletions .run/Run Plugin Tests.run.xml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ internal class ProjectRepositories(val toolWindow: ToolWindow) {

class GhActionsToolWindowFactory : ToolWindowFactory, DumbAware {
private lateinit var settingsService: GhActionsSettingsService
private val accountManager = service<GHAccountManager>()
private val projectReposMap = mutableMapOf<Project, ProjectRepositories>()
private val scope = CoroutineScope(SupervisorJob())

Expand All @@ -68,6 +67,7 @@ class GhActionsToolWindowFactory : ToolWindowFactory, DumbAware {
updateRepos(toolWindow, it)
}
}
val accountManager = service<GHAccountManager>()
scope.launch {
accountManager.accountsState.collect {
updateRepos(toolWindow, repositoriesManager.knownRepositories)
Expand Down Expand Up @@ -104,23 +104,23 @@ class GhActionsToolWindowFactory : ToolWindowFactory, DumbAware {
if ((GHAccountsUtil.accounts.isEmpty() && settingsService.state.useGitHubSettings)
|| (!settingsService.state.useGitHubSettings && settingsService.state.apiToken == "")
) {
noGitHubAccountPanel(disposable, projectRepos)
createNoAccountPanel(disposable, projectRepos)
} else if (projectRepos.knownRepositories.isEmpty()) {
noRepositories(disposable, projectRepos)
createNoReposPanel(disposable, projectRepos)
} else {
val countRepos = projectRepos.knownRepositories.count {
settingsService.state.customRepos[it.remote.url]?.included ?: false
}
if (settingsService.state.useCustomRepos && countRepos == 0) {
noActiveRepositories(disposable, projectRepos)
createNoActiveReposPanel(disposable, projectRepos)
} else {
ghAccountAndReposConfigured(disposable, projectRepos)
createRepoWorkflowsPanels(disposable, projectRepos)
}
}
}
}

private fun noActiveRepositories(
private fun createNoActiveReposPanel(
disposable: Disposable,
projectRepositories: ProjectRepositories
) =
Expand Down Expand Up @@ -148,7 +148,7 @@ class GhActionsToolWindowFactory : ToolWindowFactory, DumbAware {
)
}

private fun noGitHubAccountPanel(
private fun createNoAccountPanel(
disposable: Disposable,
projectRepositories: ProjectRepositories
) = with(projectRepositories.toolWindow.contentManager) {
Expand Down Expand Up @@ -182,7 +182,7 @@ class GhActionsToolWindowFactory : ToolWindowFactory, DumbAware {
)
}

private fun noRepositories(
private fun createNoReposPanel(
disposable: Disposable,
projectRepositories: ProjectRepositories
) = with(projectRepositories.toolWindow.contentManager) {
Expand All @@ -203,7 +203,7 @@ class GhActionsToolWindowFactory : ToolWindowFactory, DumbAware {
return accounts.firstOrNull { it.server.equals(repo.repository.serverPath, true) }
}

private fun ghAccountAndReposConfigured(
private fun createRepoWorkflowsPanels(
parentDisposable: Disposable,
projectRepositories: ProjectRepositories
) =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package com.dsoftware.ghmanager

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.toolWindow.ToolWindowHeadlessManagerImpl.MockToolWindow
import com.intellij.util.ThrowableRunnable
import com.intellij.util.concurrency.annotations.RequiresEdt
import kotlinx.coroutines.runBlocking
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.api.data.GithubRepo
import org.jetbrains.plugins.github.api.data.GithubResponsePage
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.GHHostedRepositoriesManager


/**
*
* The base class for JUnit platform tests of the github plugin.<br></br>
* Extend this test to write a test on GitHub which has the following features/limitations:
*
* * This is a "platform test case", which means that IDEA "almost" production platform is set up before the test starts.
* * Project base directory is the root of everything.
*
*
* All tests inherited from this class are required to have a token to access the Github server.
* They are set up in Environment variables: <br></br>
* `idea_test_github_host<br></br>
* idea_test_github_token1<br></br> // token test user
* idea_test_github_token2` // token user with configured test repositories
*
*/
abstract class GitHubActionsManagerBaseTest : BasePlatformTestCase() {
private lateinit var accountManager: GHAccountManager
private lateinit var organisation: String
protected lateinit var repositoriesManager: GHHostedRepositoriesManager
protected lateinit var mainAccount: AccountData

private val mainRepos = mutableSetOf<String>()
protected lateinit var myProject: Project
protected lateinit var factory: GhActionsToolWindowFactory
protected lateinit var toolWindow: ToolWindow
override fun setUp() {
super.setUp()
myProject = project
factory = GhActionsToolWindowFactory()
toolWindow = MockToolWindow(myProject)
val host =
GithubServerPath.from(System.getenv("idea_test_github_host") ?: System.getenv("idea.test.github.host"))
val token1 = System.getenv("idea_test_github_token1") ?: System.getenv("idea.test.github.token1")

assertNotNull(token1)
accountManager = service()
repositoriesManager = project.service()

organisation = System.getenv("idea_test_github_org") ?: System.getenv("idea.test.github.org")
assertNotNull(organisation)
mainAccount = createAccountData(host, token1)
setCurrentAccount(mainAccount)
}

private fun createAccountData(host: GithubServerPath, token: String): AccountData {
val account = GHAccountManager.createAccount("token", host)
runBlocking { accountManager.updateAccount(account, token) }
val executor = service<GithubApiRequestExecutor.Factory>().create(token)
val username = executor.execute(GithubApiRequests.CurrentUser.get(account.server)).login
val repos =
executor.execute<GithubResponsePage<GithubRepo>>(GithubApiRequests.CurrentUser.Repos.get(account.server))
repos.items.forEach { mainRepos.add(it.name) }

return AccountData(token, account, username, executor)
}


protected open fun setCurrentAccount(accountData: AccountData?) {
GHAccountsUtil.setDefaultAccount(myProject, accountData?.account)
}

protected data class AccountData(
val token: String,
val account: GithubAccount,
val username: String,
val executor: GithubApiRequestExecutor
)


@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<String>) {
// 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

internal fun retry(LOG: Logger, exception: Boolean = true, action: () -> Unit) {
for (i in 1..RETRIES) {
try {
LOG.debug("Attempt #$i")
return action()
} catch (e: Throwable) {
if (i == RETRIES) {
if (exception) throw e
else {
LOG.error(e)
return
}
}
Thread.sleep(1000L)
}
}
}
}
}

@RequiresEdt
fun executeSomeCoroutineTasksAndDispatchAllInvocationEvents(project: Project) {
repeat(3) {
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue()
runWithModalProgressBlocking(project, "") {
yield()
}
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue()
}
}
16 changes: 16 additions & 0 deletions src/test/kotlin/com/dsoftware/ghmanager/ToolWindowFactoryTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.dsoftware.ghmanager

import com.intellij.ui.components.JBPanelWithEmptyText
import junit.framework.TestCase


class ToolWindowFactoryTest : GitHubActionsManagerBaseTest() {
fun testNoGitHubAccountPanel() {
factory.init(toolWindow)
executeSomeCoroutineTasksAndDispatchAllInvocationEvents(project)

TestCase.assertEquals(1, toolWindow.contentManager.contentCount)
val panel = toolWindow.contentManager.contents[0].component
TestCase.assertTrue(panel is JBPanelWithEmptyText)
}
}

0 comments on commit aba723a

Please sign in to comment.