Skip to content

Commit fc805c2

Browse files
authored
List repository projects (#365)
* add GET list project in a repository * updated doc * added test * Update docs/docs/project.md
1 parent 3a1e46f commit fc805c2

5 files changed

Lines changed: 130 additions & 0 deletions

File tree

docs/docs/project.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Github4s supports the [Project API](https://developer.github.com/v3/projects/).
1515
with Github4s, you can interact with:
1616

1717
- [Project](#project)
18+
- [List repository projects](#list-repository-projects)
1819
- [List projects](#list-projects)
1920
- [Columns](#columns)
2021
- [List project columns](#list-project-columns)
@@ -37,6 +38,36 @@ LiftIO syntax for `cats.Id` and `Future` are provided in `GithubIOSyntax`.
3738

3839
## Project
3940

41+
### List repository projects
42+
43+
You can list the projects for a particular repository with `listProjectsRepository`; it takes as arguments:
44+
45+
- `owner`: name of the owner for which we want to retrieve the projects.
46+
- `repo`: name of the repository for which we want to retrieve the projects.
47+
- `state`: filter projects returned by their state. Can be either `open`, `closed`, `all`. Default: `open`, optional
48+
- `pagination`: Limit and Offset for pagination, optional.
49+
- `header`: headers to include in the request, optional.
50+
51+
To list the projects for owner `47deg` and repository `github4s`:
52+
53+
```scala mdoc:compile-only
54+
val listProjectsRepository = Github[IO](accessToken).projects.listProjectsRepository(
55+
owner = "47deg",
56+
repo = "github4s",
57+
headers = Map("Accept" -> "application/vnd.github.inertia-preview+json"))
58+
listProjectsRepository.unsafeRunSync() match {
59+
case Left(e) => println(s"Something went wrong: ${e.getMessage}")
60+
case Right(r) => println(r.result)
61+
}
62+
```
63+
64+
The `result` on the right is the corresponding [List[Project]][project-scala].
65+
66+
See [the API doc](https://developer.github.com/v3/projects/#list-repository-projects) for full reference.
67+
68+
[project-scala]: https://github.com/47deg/github4s/blob/master/github4s/src/main/scala/github4s/domain/Project.scala
69+
70+
4071
### List projects
4172

4273
You can list the project for a particular organization with `listProjects`; it takes as arguments:

github4s/src/main/scala/github4s/algebras/Projects.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,25 @@ trait Projects[F[_]] {
3838
headers: Map[String, String] = Map()
3939
): F[GHResponse[List[Project]]]
4040

41+
/**
42+
* List the projects belonging to a specific repository
43+
*
44+
* @param owner of the repo
45+
* @param repo name of the repo
46+
* @param state Filter projects returned by their state. Can be either `open`, `closed`, `all`.
47+
* Default: `open`
48+
* @param pagination Limit and Offset for pagination
49+
* @param headers Optional user headers to include in the request
50+
* @return GHResponse with lists the projects in a repository.
51+
*/
52+
def listProjectsRepository(
53+
owner: String,
54+
repo: String,
55+
state: Option[String] = None,
56+
pagination: Option[Pagination] = None,
57+
headers: Map[String, String] = Map()
58+
): F[GHResponse[List[Project]]]
59+
4160
/**
4261
* List the columns belonging to a specific project id
4362
*

github4s/src/main/scala/github4s/interpreters/ProjectsInterpreter.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,21 @@ class ProjectsInterpreter[F[_]](
4242
pagination
4343
)
4444

45+
override def listProjectsRepository(
46+
owner: String,
47+
repo: String,
48+
state: Option[String],
49+
pagination: Option[Pagination],
50+
headers: Map[String, String]
51+
): F[GHResponse[List[Project]]] =
52+
client.get[List[Project]](
53+
accessToken,
54+
s"repos/$owner/$repo/projects",
55+
headers,
56+
state.fold(Map.empty[String, String])(s => Map("state" -> s)),
57+
pagination
58+
)
59+
4560
override def listColumns(
4661
project_id: Int,
4762
pagination: Option[Pagination],

github4s/src/test/scala/github4s/integration/GHProjectsSpec.scala

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,48 @@ trait GHProjectsSpec extends BaseIntegrationSpec {
4444
testIsLeft(response)
4545
}
4646

47+
"Project >> ListProjectsRepository" should "return the expected projects when a valid owner and repo are provided" taggedAs Integration in {
48+
val response =
49+
Github[IO](accessToken).projects
50+
.listProjectsRepository(
51+
validRepoOwner,
52+
validRepoName,
53+
headers = headerUserAgent ++ headerAccept
54+
)
55+
.unsafeRunSync()
56+
57+
testIsRight[List[Project]](response, { r =>
58+
r.result.nonEmpty shouldBe true
59+
r.statusCode shouldBe okStatusCode
60+
})
61+
}
62+
63+
it should "return error when an invalid repo is passed" taggedAs Integration in {
64+
val response =
65+
Github[IO](accessToken).projects
66+
.listProjectsRepository(
67+
validRepoOwner,
68+
invalidRepoName,
69+
headers = headerUserAgent ++ headerAccept
70+
)
71+
.unsafeRunSync()
72+
73+
testIsLeft(response)
74+
}
75+
76+
it should "return error when an invalid owner is passed" taggedAs Integration in {
77+
val response =
78+
Github[IO](accessToken).projects
79+
.listProjectsRepository(
80+
invalidRepoOwner,
81+
validRepoName,
82+
headers = headerUserAgent ++ headerAccept
83+
)
84+
.unsafeRunSync()
85+
86+
testIsLeft(response)
87+
}
88+
4789
"Project >> ListColumns" should "return the expected column when a valid project id is provided" taggedAs Integration in {
4890
val response =
4991
Github[IO](accessToken).projects

github4s/src/test/scala/github4s/unit/ProjectSpec.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,29 @@ class ProjectSpec extends BaseSpec {
4343

4444
}
4545

46+
"Project.listProjectsRepository" should "call to httpClient.get with the right parameters" in {
47+
48+
val response: IO[GHResponse[List[Project]]] =
49+
IO(Right(GHResult(List(project), okStatusCode, Map.empty)))
50+
51+
implicit val httpClientMock = httpClientMockGet[List[Project]](
52+
url = s"repos/$validRepoOwner/$validRepoName/projects",
53+
headers = headerAccept,
54+
response = response
55+
)
56+
57+
val projects = new ProjectsInterpreter[IO]
58+
59+
projects.listProjectsRepository(
60+
validRepoOwner,
61+
validRepoName,
62+
None,
63+
None,
64+
headers = headerUserAgent ++ headerAccept
65+
)
66+
67+
}
68+
4669
"Project.listColumns" should "call to httpClient.get with the right parameters" in {
4770

4871
val response: IO[GHResponse[List[Column]]] =

0 commit comments

Comments
 (0)