Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds the get contents operation #80

Merged
merged 1 commit into from
Apr 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,22 @@

package github4s.integration

import cats.data.NonEmptyList
import github4s.Github._
import github4s.GithubResponses._
import github4s.Github
import github4s.utils.TestUtils
import org.scalatest.{AsyncFlatSpec, FlatSpec, Matchers}
import fr.hmil.roshttp.response.SimpleHttpResponse
import github4s.free.domain.{Commit, Repository, User}
import org.scalatest.{AsyncFlatSpec, Matchers}
import github4s.free.domain.{Commit, Content, Repository, User}
import github4s.js.Implicits._
import scala.concurrent.Future

import scala.concurrent.ExecutionContext

class GHReposSpec extends AsyncFlatSpec with Matchers with TestUtils {

override implicit val executionContext =
override implicit val executionContext: ExecutionContext =
scala.concurrent.ExecutionContext.Implicits.global

"Repos >> Get" should "return the expected name when valid repo is provided" in {
"Repos >> Get" should "return the expected name when a valid repo is provided" in {

val response =
Github(accessToken).repos
Expand All @@ -53,6 +53,28 @@ class GHReposSpec extends AsyncFlatSpec with Matchers with TestUtils {
testFutureIsLeft(response)
}

"Repos >> GetContents" should "return the expected contents when valid path is provided" in {

val response =
Github(accessToken).repos
.getContents(validRepoOwner, validRepoName, validFilePath)
.execFuture(headerUserAgent)

testFutureIsRight[NonEmptyList[Content]](response, { r =>
r.result.head.path shouldBe validFilePath
r.statusCode shouldBe okStatusCode
})
}

it should "return error when an invalid path is passed" in {
val response =
Github(accessToken).repos
.getContents(validRepoOwner, validRepoName, validFilePath)
.execFuture(headerUserAgent)

testFutureIsLeft(response)
}

"Repos >> ListCommits" should "return the expected list of commits for valid data" in {
val response =
Github(accessToken).repos
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ trait TestUtils extends Matchers {

val validRepoOwner = "47deg"
val validRepoName = "github4s"
val validFilePath = "README.md"
val invalidFilePath = "NON_EXISTENT_FILE_IN_REPOSITORY"
val invalidRepoName = "GHInvalidRepoName"
val validRedirectUri = "http://localhost:9000/_oauth-callback"
val validPage = 1
Expand Down
24 changes: 22 additions & 2 deletions github4s/jvm/src/test/scala/github4s/integration/GHReposSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package github4s.integration
import cats.Id
import cats.implicits._
import github4s.Github._
import github4s.GithubResponses._
import github4s.Github
import github4s.jvm.Implicits._
import github4s.utils.TestUtils
Expand All @@ -29,7 +28,7 @@ import scalaj.http.HttpResponse

class GHReposSpec extends FlatSpec with Matchers with TestUtils {

"Repos >> Get" should "return the expected name when valid repo is provided" in {
"Repos >> Get" should "return the expected name when a valid repo is provided" in {

val response =
Github(accessToken).repos
Expand All @@ -50,6 +49,27 @@ class GHReposSpec extends FlatSpec with Matchers with TestUtils {
response should be('left)
}

"Repos >> GetContents" should "return the expected contents when valid path is provided" in {

val response =
Github(accessToken).repos
.getContents(validRepoOwner, validRepoName, validFilePath)
.exec[Id, HttpResponse[String]](headerUserAgent)
response should be('right)
response.toOption map { r ⇒
r.result.head.path shouldBe validFilePath
r.statusCode shouldBe okStatusCode
}
}

it should "return error when an invalid path is passed" in {
val response =
Github(accessToken).repos
.getContents(validRepoOwner, validRepoName, invalidFilePath)
.exec[Id, HttpResponse[String]](headerUserAgent)
response should be('left)
}

"Repos >> ListCommits" should "return the expected list of commits for valid data" in {
val response = Github(accessToken).repos
.listCommits(validRepoOwner, validRepoName)
Expand Down
72 changes: 72 additions & 0 deletions github4s/jvm/src/test/scala/github4s/unit/ApiSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,78 @@ class ApiSpec
response should be('left)
}

"Repos >> GetContents" should "return the expected contents when valid repo and a valid file path is provided" in {

val response =
repos.getContents(accessToken, headerUserAgent, validRepoOwner, validRepoName, validFilePath)
response should be('right)

response.toOption map { r ⇒
r.result.head.path shouldBe validFilePath
r.result.tail.isEmpty shouldBe true
r.statusCode shouldBe okStatusCode
}

}

it should "return the expected contents when valid repo and a valid dir path is provided" in {

val response =
repos.getContents(accessToken, headerUserAgent, validRepoOwner, validRepoName, validDirPath)
response should be('right)

response.toOption map { r ⇒
r.result.head.path.startsWith(validDirPath) shouldBe true
r.result.tail.nonEmpty shouldBe true
r.statusCode shouldBe okStatusCode
}

}

it should "return the expected contents when valid repo and a valid symlink path is provided" in {

val response =
repos.getContents(
accessToken,
headerUserAgent,
validRepoOwner,
validRepoName,
validSymlinkPath)
response should be('right)

response.toOption map { r ⇒
r.result.head.path shouldBe validSymlinkPath
r.result.tail.isEmpty shouldBe true
r.statusCode shouldBe okStatusCode
}

}

it should "return the expected contents when valid repo and a valid submodule path is provided" in {

val response =
repos.getContents(
accessToken,
headerUserAgent,
validRepoOwner,
validRepoName,
validSubmodulePath)
response should be('right)

response.toOption map { r ⇒
r.result.head.path shouldBe validSubmodulePath
r.result.tail.isEmpty shouldBe true
r.statusCode shouldBe okStatusCode
}

}

it should "return error when an invalid repo name is passed" in {
val response =
repos.get(accessToken, headerUserAgent, validRepoOwner, invalidRepoName)
response should be('left)
}

"Repos >> ListCommits" should "return the expected list of commits for valid data" in {
val response = repos.listCommits(
accessToken = accessToken,
Expand Down
28 changes: 28 additions & 0 deletions github4s/jvm/src/test/scala/github4s/unit/GHReposSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package github4s.unit

import cats.data.NonEmptyList
import cats.free.Free
import github4s.GHRepos
import github4s.GithubResponses.{GHResponse, GHResult}
Expand All @@ -30,6 +31,33 @@ import org.scalatest.{FlatSpec, Matchers}

class GHReposSpec extends FlatSpec with Matchers with TestUtils {

"GHRepos.contents" should "call to RepositoryOps with the right parameters" in {

val response: Free[GitHub4s, GHResponse[NonEmptyList[Content]]] =
Free.pure(Right(GHResult(NonEmptyList(content, Nil), okStatusCode, Map.empty)))

val repoOps = mock[RepositoryOps[GitHub4s]]
when(
repoOps.getContents(
any[String],
any[String],
any[String],
any[Option[String]],
any[Option[String]]))
.thenReturn(response)

val token = Some("token")
val ghReposData = new GHRepos(token)(repoOps)
ghReposData.getContents(validRepoOwner, validRepoName, validFilePath, Some("master"))

verify(repoOps).getContents(
validRepoOwner,
validRepoName,
validFilePath,
Some("master"),
token)
}

"GHRepos.createRelease" should "call to RepositoryOps with the right parameters" in {

val response: Free[GitHub4s, GHResponse[Release]] =
Expand Down
39 changes: 39 additions & 0 deletions github4s/jvm/src/test/scala/github4s/unit/ReposSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package github4s.unit

import cats.Id
import cats.data.NonEmptyList
import github4s.GithubResponses.{GHResponse, GHResult}
import github4s.api.Repos
import github4s.free.domain._
Expand All @@ -38,6 +39,44 @@ class ReposSpec
with IdInstances
with HttpRequestBuilderExtensionJVM {

"Repos.getContents" should "call to httpClient.get with the right parameters" in {

val response: GHResponse[NonEmptyList[Content]] =
Right(GHResult(NonEmptyList(content, Nil), okStatusCode, Map.empty))

val httpClientMock = mock[HttpClient[HttpResponse[String], Id]]
when(
httpClientMock
.get[NonEmptyList[Content]](
any[Option[String]],
any[String],
any[Map[String, String]],
any[Map[String, String]],
any[Option[Pagination]])(any[Decoder[NonEmptyList[Content]]]))
.thenReturn(response)

val token = Some("token")
val repos = new Repos[HttpResponse[String], Id] {
override val httpClient: HttpClient[HttpResponse[String], Id] = httpClientMock
}
repos.getContents(
accessToken = token,
headers = headerUserAgent,
owner = validRepoOwner,
repo = validRepoName,
path = validFilePath,
ref = Some("master")
)

verify(httpClientMock).get[NonEmptyList[Content]](
argEq(token),
argEq(s"repos/$validRepoOwner/$validRepoName/contents/$validFilePath"),
argEq(headerUserAgent),
argEq(Map("ref" -> "master")),
any[Option[Pagination]]
)(any[Decoder[NonEmptyList[Content]]])
}

"Repos.createRelease" should "call to httpClient.post with the right parameters" in {

val response: GHResponse[Release] = Right(GHResult(release, okStatusCode, Map.empty))
Expand Down
102 changes: 102 additions & 0 deletions github4s/jvm/src/test/scala/github4s/utils/FakeResponses.scala
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,108 @@ trait FakeResponses {
|}
""".stripMargin

val validRepoFileContents =
"""
|{
| "type": "file",
| "encoding": "base64",
| "size": 5362,
| "name": "README.md",
| "path": "README.md",
| "content": "encoded content ...",
| "sha": "3d21ec53a331a6f037a91c368710b99387d012c1",
| "url": "https://api.github.com/repos/octokit/octokit.rb/contents/README.md",
| "git_url": "https://api.github.com/repos/octokit/octokit.rb/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1",
| "html_url": "https://github.com/octokit/octokit.rb/blob/master/README.md",
| "download_url": "https://raw.githubusercontent.com/octokit/octokit.rb/master/README.md",
| "_links": {
| "git": "https://api.github.com/repos/octokit/octokit.rb/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1",
| "self": "https://api.github.com/repos/octokit/octokit.rb/contents/README.md",
| "html": "https://github.com/octokit/octokit.rb/blob/master/README.md"
| }
|}
""".stripMargin

val validRepoDirContents =
"""
|[
| {
| "type": "file",
| "size": 625,
| "name": "octokit.rb",
| "path": "lib/octokit.rb",
| "sha": "fff6fe3a23bf1c8ea0692b4a883af99bee26fd3b",
| "url": "https://api.github.com/repos/octokit/octokit.rb/contents/lib/octokit.rb",
| "git_url": "https://api.github.com/repos/octokit/octokit.rb/git/blobs/fff6fe3a23bf1c8ea0692b4a883af99bee26fd3b",
| "html_url": "https://github.com/octokit/octokit.rb/blob/master/lib/octokit.rb",
| "download_url": "https://raw.githubusercontent.com/octokit/octokit.rb/master/lib/octokit.rb",
| "_links": {
| "self": "https://api.github.com/repos/octokit/octokit.rb/contents/lib/octokit.rb",
| "git": "https://api.github.com/repos/octokit/octokit.rb/git/blobs/fff6fe3a23bf1c8ea0692b4a883af99bee26fd3b",
| "html": "https://github.com/octokit/octokit.rb/blob/master/lib/octokit.rb"
| }
| },
| {
| "type": "dir",
| "size": 0,
| "name": "octokit",
| "path": "lib/octokit",
| "sha": "a84d88e7554fc1fa21bcbc4efae3c782a70d2b9d",
| "url": "https://api.github.com/repos/octokit/octokit.rb/contents/lib/octokit",
| "git_url": "https://api.github.com/repos/octokit/octokit.rb/git/trees/a84d88e7554fc1fa21bcbc4efae3c782a70d2b9d",
| "html_url": "https://github.com/octokit/octokit.rb/tree/master/lib/octokit",
| "download_url": null,
| "_links": {
| "self": "https://api.github.com/repos/octokit/octokit.rb/contents/lib/octokit",
| "git": "https://api.github.com/repos/octokit/octokit.rb/git/trees/a84d88e7554fc1fa21bcbc4efae3c782a70d2b9d",
| "html": "https://github.com/octokit/octokit.rb/tree/master/lib/octokit"
| }
| }
|]
""".stripMargin

val validRepoSymlinkContents =
"""
|{
| "type": "symlink",
| "target": "/path/to/symlink/target",
| "size": 23,
| "name": "some-symlink",
| "path": "bin/some-symlink",
| "sha": "452a98979c88e093d682cab404a3ec82babebb48",
| "url": "https://api.github.com/repos/octokit/octokit.rb/contents/bin/some-symlink",
| "git_url": "https://api.github.com/repos/octokit/octokit.rb/git/blobs/452a98979c88e093d682cab404a3ec82babebb48",
| "html_url": "https://github.com/octokit/octokit.rb/blob/master/bin/some-symlink",
| "download_url": "https://raw.githubusercontent.com/octokit/octokit.rb/master/bin/some-symlink",
| "_links": {
| "git": "https://api.github.com/repos/octokit/octokit.rb/git/blobs/452a98979c88e093d682cab404a3ec82babebb48",
| "self": "https://api.github.com/repos/octokit/octokit.rb/contents/bin/some-symlink",
| "html": "https://github.com/octokit/octokit.rb/blob/master/bin/some-symlink"
| }
|}
""".stripMargin

val validRepoSubmoduleContents =
"""
|{
| "type": "submodule",
| "submodule_git_url": "git://github.com/jquery/qunit.git",
| "size": 0,
| "name": "qunit",
| "path": "test/qunit",
| "sha": "6ca3721222109997540bd6d9ccd396902e0ad2f9",
| "url": "https://api.github.com/repos/jquery/jquery/contents/test/qunit?ref=master",
| "git_url": "https://api.github.com/repos/jquery/qunit/git/trees/6ca3721222109997540bd6d9ccd396902e0ad2f9",
| "html_url": "https://github.com/jquery/qunit/tree/6ca3721222109997540bd6d9ccd396902e0ad2f9",
| "download_url": null,
| "_links": {
| "git": "https://api.github.com/repos/jquery/qunit/git/trees/6ca3721222109997540bd6d9ccd396902e0ad2f9",
| "self": "https://api.github.com/repos/jquery/jquery/contents/test/qunit?ref=master",
| "html": "https://github.com/jquery/qunit/tree/6ca3721222109997540bd6d9ccd396902e0ad2f9"
| }
|}
""".stripMargin

val listCommitsValidResponse =
"""
|[
Expand Down
Loading