Skip to content

Commit

Permalink
Arf 105 create pull request api (#109)
Browse files Browse the repository at this point in the history
* Support the Create Pull Request API

* Create jvm test

* Create js jvm and unit test

* Delete test

* Create unit test

* Create unit test util

* Create unit test util

* Doc update

* ScalaDoc update

* Doc update

* Doc update

* Doc update

* Update pull_request.md

* Doc update

* Fixes a field name in `CreatePullRequest` and increases test coverage

* Update pull_request.md

* Update DecodersSpec.scala

* Update ApiSpec.scala

* delete validPRRepoName
  • Loading branch information
AdrianRaFo authored and juanpedromoreno committed May 3, 2017
1 parent 46f6098 commit 9ee5cc3
Show file tree
Hide file tree
Showing 18 changed files with 1,349 additions and 32 deletions.
41 changes: 38 additions & 3 deletions docs/src/main/tut/pull_request.md
Expand Up @@ -8,8 +8,9 @@ title: Pull Request API
Github4s supports the [Pull Request API](https://developer.github.com/v3/pulls/). As a result,
with github4s, you can:

- [list pull requests](#list-pull-requests)
- [list the files in a pull request](#list-the-files-in-a-pull-request)
- [List pull requests](#list-pull-requests)
- [List the files in a pull request](#list-the-files-in-a-pull-request)
- [Create a pull request](#create-a-pull-request)

The following examples assume the following imports and token:

Expand Down Expand Up @@ -83,4 +84,38 @@ As you can see, a few features of the pull request endpoint (such as the ability
request) are missing. As a result, if you'd like to see a feature supported, feel free to
create a pull request (not through Github4s though).

[pr-scala]: https://github.com/47deg/github4s/blob/master/github4s/shared/src/main/scala/github4s/free/domain/PullRequest.scala
[pr-scala]: https://github.com/47deg/github4s/blob/master/github4s/shared/src/main/scala/github4s/free/domain/PullRequest.scala

## Create a pull request
If you want to create a pull request, we have two ways to create a pull request.

On the one hand, we pass as parameters to create a new pull request:

- the repository coordinates (owner and name of the repository)
- `title` (as part of the `NewPullRequestData` object): Title for the pull request
- `body` (as part of the `NewPullRequestData` object): Description for the pull request
- `head`: The name of the branch where your changes are implemented
- `base`: The name of the branch you want the changes pulled into
- `maintainerCanModify`: Optional. Indicates whether maintainers can modify the pull request. `true` by default

```scala
val createPullRequestData = Github(accessToken).pullRequests.create("47deg", "github4s", NewPullRequestData("title","body"),"my-branch","base-branch",Some(true))
createPullRequestData.exec[cats.Id, HttpResponse[String]]() match {
case Left(e) => println("Something went wrong: s{e.getMessage}")
case Right(r) => println(r.result)
}
```

On the other hand, we can pass a `issue` id (through `NewPullRequestIssue` object) instead of the title and the body to get this parameter of the issue

**NOTE**: This option deletes the issue

```scala
val createPullRequestIssue = Github(accessToken).pullRequests.create("47deg", "github4s", NewPullRequestIssue("105"),"my-branch","base-branch",Some(true))
createPullRequestIssue.exec[cats.Id, HttpResponse[String]]() match {
case Left(e) => println("Something went wrong: s{e.getMessage}")
case Right(r) => println(r.result)
}
```

See [the API doc](https://developer.github.com/v3/pulls/#create-a-pull-request) for full reference.
67 changes: 67 additions & 0 deletions github4s/js/src/test/scala/github4s/unit/DecodersSpec.scala
@@ -0,0 +1,67 @@
/*
* Copyright 2016-2017 47 Degrees, LLC. <http://www.47deg.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package github4s.unit

import cats.data.NonEmptyList
import cats.syntax.either._
import github4s.Decoders._
import github4s.free.domain.{CombinedStatus, Commit, Repository}
import github4s.utils.FakeResponses
import io.circe.generic.auto._
import io.circe.parser._
import org.scalatest._

class DecodersSpec extends FlatSpec with Matchers with FakeResponses {

"Commit decoder" should "return a list of commits when the JSON is valid" in {
decode[List[Commit]](listCommitsValidResponse).isRight shouldBe true
}

it should "return an empty list for an empty JSON" in {
decode[List[Commit]](emptyListResponse).toOption map (_.isEmpty shouldBe true)
}

"Repository decoder" should "return a valid repo for a valid JSON" in {
decode[Repository](getRepoResponse).isRight shouldBe true
}

it should "return an error for an empty JSON" in {
decode[Repository](emptyListResponse).isLeft shouldBe true
}

"CombinedStatus decoder" should "return a valid repo for a valid JSON" in {
decode[CombinedStatus](getCombinedStatusValidResponse).isRight shouldBe true
}

it should "return an error for an empty JSON" in {
decode[CombinedStatus](emptyListResponse).isLeft shouldBe true
}

"NonEmptyList Decoder" should "return a valid NonEmptyList for a valid JSON list" in {
decode[NonEmptyList[Int]]("[1,2,3]") shouldBe Right(NonEmptyList.of(1, 2, 3))
}

case class Foo(a: Int)
it should "return a valid NonEmtpyList for a valid JSON" in {
decode[NonEmptyList[Foo]]("""{"a": 1}""") shouldBe Right(NonEmptyList(Foo(1), Nil))
}

it should "return an error for an empty list" in {
decode[NonEmptyList[Int]](emptyListResponse).isLeft shouldBe true
}

}
107 changes: 107 additions & 0 deletions github4s/js/src/test/scala/github4s/unit/EncodersSpec.scala
@@ -0,0 +1,107 @@
/*
* Copyright 2016-2017 47 Degrees, LLC. <http://www.47deg.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package github4s.unit

import github4s.Encoders._
import github4s.free.domain._
import github4s.utils.TestUtils
import io.circe.parser._
import io.circe.syntax._
import org.scalatest._

class EncodersSpec extends FlatSpec with Matchers with TestUtils {

"TreeData encoder" should "encode the TreeDataSha" in {
val treeData: TreeData = TreeDataSha(validFilePath, validMode, validBlobType, validCommitSha)

val expectedJsonString =
s"""
| {
| "path": "$validFilePath",
| "mode": "$validMode",
| "type": "$validBlobType",
| "sha": "$validCommitSha"
| }
""".stripMargin

val expectedJson = parse(expectedJsonString).right.get
val actualJson = treeData.asJson

actualJson shouldBe expectedJson
}

it should "encode the TreeDataBlob" in {
val treeData: TreeData = TreeDataBlob(validFilePath, validMode, validBlobType, validCommitMsg)

val expectedJsonString =
s"""
| {
| "path": "$validFilePath",
| "mode": "$validMode",
| "type": "$validBlobType",
| "content": "$validCommitMsg"
| }
""".stripMargin

val expectedJson = parse(expectedJsonString).right.get
val actualJson = treeData.asJson

actualJson shouldBe expectedJson
}

"CreatePullRequest encoder" should "encode the CreatePullRequestData" in {
val createPullRequest: CreatePullRequest =
CreatePullRequestData(validIssueTitle, validHead, validBase, validCommitMsg, Some(false))

val expectedJsonString =
s"""
| {
| "title": "$validIssueTitle",
| "head": "$validHead",
| "base": "$validBase",
| "body": "$validCommitMsg",
| "maintainer_can_modify": false
| }
""".stripMargin

val expectedJson = parse(expectedJsonString).right.get
val actualJson = createPullRequest.asJson

actualJson shouldBe expectedJson
}

it should "encode the CreatePullRequestIssue" in {
val createPullRequest: CreatePullRequest =
CreatePullRequestIssue(validIssue, validHead, validBase, Some(false))

val expectedJsonString =
s"""
| {
| "issue": $validIssue,
| "head": "$validHead",
| "base": "$validBase",
| "maintainer_can_modify": false
| }
""".stripMargin

val expectedJson = parse(expectedJsonString).right.get
val actualJson = createPullRequest.asJson

actualJson shouldBe expectedJson
}

}

0 comments on commit 9ee5cc3

Please sign in to comment.