diff --git a/build.sbt b/build.sbt index 4003a48..ff2085c 100644 --- a/build.sbt +++ b/build.sbt @@ -70,7 +70,8 @@ "org.testcontainers" % "postgresql" % "1.14.3" % "test", "net.i2p.crypto" % "eddsa" % "0.3.0", "is.tagomor.woothee" % "woothee-java" % "1.11.0", - "org.ec4j.core" % "ec4j-core" % "0.0.3" + "org.ec4j.core" % "ec4j-core" % "0.0.3", + "org.kohsuke" % "github-api" % "1.116" % "test" ) // Compiler settings @@ -120,6 +121,12 @@ "org.eclipse.jetty" % "jetty-util" % JettyVersion % "executable" ) +// Run package task before test to generate target/webapp for integration test +test in Test := { + _root_.sbt.Keys.`package`.value + (test in Test).value +} + val executableKey = TaskKey[File]("executable") executableKey := { import java.util.jar.Attributes.{Name => AttrName} diff --git a/src/main/scala/gitbucket/core/api/ApiRepository.scala b/src/main/scala/gitbucket/core/api/ApiRepository.scala index 0f4ff77..410e63d 100644 --- a/src/main/scala/gitbucket/core/api/ApiRepository.scala +++ b/src/main/scala/gitbucket/core/api/ApiRepository.scala @@ -19,7 +19,6 @@ val forks_count = forks val watchers_count = watchers val url = ApiPath(s"/api/v3/repos/${full_name}") - val http_url = ApiPath(s"/git/${full_name}.git") val clone_url = ApiPath(s"/git/${full_name}.git") val html_url = ApiPath(s"/${full_name}") val ssh_url = Some(SshPath(s":${full_name}.git")) diff --git a/src/test/scala/gitbucket/core/TestingGitBucketServer.scala b/src/test/scala/gitbucket/core/TestingGitBucketServer.scala new file mode 100644 index 0000000..6f6db5b --- /dev/null +++ b/src/test/scala/gitbucket/core/TestingGitBucketServer.scala @@ -0,0 +1,66 @@ +package gitbucket.core + +import java.net.InetSocketAddress +import java.nio.file.Files +import java.io.File + +import gitbucket.core.util.{FileUtil, HttpClientUtil} +import org.apache.http.client.methods.HttpGet +import org.eclipse.jetty.server.handler.StatisticsHandler +import org.eclipse.jetty.server.{Handler, Server} +import org.eclipse.jetty.webapp.WebAppContext +import org.kohsuke.github.GitHub + +class TestingGitBucketServer(val port: Int = 19999) extends AutoCloseable { + private var server: Server = null + private var dir: File = null + + start() + + private def start(): Unit = { + System.setProperty("java.awt.headless", "true") + + dir = Files.createTempDirectory("gitbucket-test-").toFile + System.setProperty("gitbucket.home", dir.getAbsolutePath) + + val address = new InetSocketAddress(port) + server = new Server(address) + + val context = new WebAppContext + context.setResourceBase("./target/webapp") + context.setContextPath("") + context.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false") + context.setServer(server) + + val handler = addStatisticsHandler(context) + server.setHandler(handler) + + server.start() + + HttpClientUtil.withHttpClient(None) { httpClient => + var launched = false + var count = 0 + while (!launched && count < 10) { + Thread.sleep(500) + val res = httpClient.execute(new HttpGet(s"http://localhost:${port}/")) + launched = res.getStatusLine.getStatusCode == 200 + count += 1 + } + } + } + + def client(login: String, password: String): GitHub = + GitHub.connectToEnterprise(s"http://localhost:${port}/api/v3", login, password) + + private def addStatisticsHandler(handler: Handler) = { // The graceful shutdown is implemented via the statistics handler. + // See the following: https://bugs.eclipse.org/bugs/show_bug.cgi?id=420142 + val statisticsHandler = new StatisticsHandler + statisticsHandler.setHandler(handler) + statisticsHandler + } + + def close(): Unit = { + server.stop() + FileUtil.deleteIfExists(dir) + } +} diff --git a/src/test/scala/gitbucket/core/api/ApiIntegrationTest.scala b/src/test/scala/gitbucket/core/api/ApiIntegrationTest.scala new file mode 100644 index 0000000..fae81c3 --- /dev/null +++ b/src/test/scala/gitbucket/core/api/ApiIntegrationTest.scala @@ -0,0 +1,136 @@ +package gitbucket.core.api + +import gitbucket.core.TestingGitBucketServer +import org.scalatest.funsuite.AnyFunSuite + +import scala.util.Using +import org.kohsuke.github.{GHCommitState, GitHub} + +class ApiIntegrationTest extends AnyFunSuite { + + test("create repository") { + Using.resource(new TestingGitBucketServer(19999)) { server => + val github = server.client("root", "root") + + { + val repository = github + .createRepository("test") + .description("test repository") + .private_(false) + .autoInit(true) + .create() + + assert(repository.getName == "test") + assert(repository.getDescription == "test repository") + assert(repository.getDefaultBranch == "master") + assert(repository.getWatchers == 0) + assert(repository.getWatchersCount == 0) + assert(repository.getForks == 0) + assert(repository.getForksCount == 0) + assert(repository.isPrivate == false) + assert(repository.getOwner.getLogin == "root") + assert(repository.hasIssues == true) + assert(repository.getUrl.toString == s"http://localhost:${server.port}/api/v3/repos/root/test") + assert(repository.getHttpTransportUrl == s"http://localhost:${server.port}/git/root/test.git") + assert(repository.getHtmlUrl.toString == s"http://localhost:${server.port}/root/test") + } + { + val repositories = github.getUser("root").listRepositories().toList + assert(repositories.size() == 1) + + val repository = repositories.get(0) + assert(repository.getName == "test") + assert(repository.getDescription == "test repository") + assert(repository.getDefaultBranch == "master") + assert(repository.getWatchers == 0) + assert(repository.getWatchersCount == 0) + assert(repository.getForks == 0) + assert(repository.getForksCount == 0) + assert(repository.isPrivate == false) + assert(repository.getOwner.getLogin == "root") + assert(repository.hasIssues == true) + assert(repository.getUrl.toString == s"http://localhost:${server.port}/api/v3/repos/root/test") + assert(repository.getHttpTransportUrl == s"http://localhost:${server.port}/git/root/test.git") + assert(repository.getHtmlUrl.toString == s"http://localhost:${server.port}/root/test") + } + } + } + + test("commit status") { + Using.resource(new TestingGitBucketServer(19999)) { server => + val github = server.client("root", "root") + + val repo = github.createRepository("create_status_test").autoInit(true).create() + val sha1 = repo.getBranch("master").getSHA1 + + { + val status = repo.getLastCommitStatus(sha1) + assert(status == null) + } + { + val statusList = repo.listCommitStatuses(sha1).toList + assert(statusList.size() == 0) + } + { + val status = + repo.createCommitStatus(sha1, GHCommitState.SUCCESS, "http://localhost/target", "description", "context") + assert(status.getState == GHCommitState.SUCCESS) + assert(status.getTargetUrl == "http://localhost/target") + assert(status.getDescription == "description") + assert(status.getContext == "context") + assert( + status.getUrl.toString == s"http://localhost:19999/api/v3/repos/root/create_status_test/commits/${sha1}/statuses" + ) + } + { + val status = repo.getLastCommitStatus(sha1) + assert(status.getState == GHCommitState.SUCCESS) + assert(status.getTargetUrl == "http://localhost/target") + assert(status.getDescription == "description") + assert(status.getContext == "context") + assert( + status.getUrl.toString == s"http://localhost:19999/api/v3/repos/root/create_status_test/commits/${sha1}/statuses" + ) + } + { + val statusList = repo.listCommitStatuses(sha1).toList + assert(statusList.size() == 1) + + val status = repo.getLastCommitStatus(sha1) + assert(status.getState == GHCommitState.SUCCESS) + assert(status.getTargetUrl == "http://localhost/target") + assert(status.getDescription == "description") + assert(status.getContext == "context") + assert( + status.getUrl.toString == s"http://localhost:19999/api/v3/repos/root/create_status_test/commits/${sha1}/statuses" + ) + } + { + // Update the status + repo.createCommitStatus(sha1, GHCommitState.FAILURE, "http://localhost/target", "description", "context") + + val status = repo.getLastCommitStatus(sha1) + assert(status.getState == GHCommitState.FAILURE) + + val statusList = repo.listCommitStatuses(sha1).toList + assert(statusList.size() == 1) + assert(statusList.get(0).getState == GHCommitState.FAILURE) + } + { + // Add status in a different context + repo.createCommitStatus(sha1, GHCommitState.ERROR, "http://localhost/target", "description", "context2") + + val status = repo.getLastCommitStatus(sha1) + assert(status.getState == GHCommitState.ERROR) + + val statusList = repo.listCommitStatuses(sha1).toList + assert(statusList.size() == 2) + assert(statusList.get(0).getState == GHCommitState.ERROR) + assert(statusList.get(0).getContext == "context2") + assert(statusList.get(1).getState == GHCommitState.FAILURE) + assert(statusList.get(1).getContext == "context") + } + } + } + +} diff --git a/src/test/scala/gitbucket/core/api/ApiSpecModels.scala b/src/test/scala/gitbucket/core/api/ApiSpecModels.scala index 36c8811..237d8d0 100644 --- a/src/test/scala/gitbucket/core/api/ApiSpecModels.scala +++ b/src/test/scala/gitbucket/core/api/ApiSpecModels.scala @@ -464,7 +464,6 @@ |"forks_count":1, |"watchers_count":0, |"url":"http://gitbucket.exmple.com/api/v3/repos/octocat/Hello-World", - |"http_url":"http://gitbucket.exmple.com/git/octocat/Hello-World.git", |"clone_url":"http://gitbucket.exmple.com/git/octocat/Hello-World.git", |"html_url":"http://gitbucket.exmple.com/octocat/Hello-World" |}""".stripMargin