Skip to content

Commit

Permalink
add new endpoint - list repository events (#811)
Browse files Browse the repository at this point in the history
  • Loading branch information
josevi96 authored Aug 11, 2022
1 parent 1bd762f commit e7c0793
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 13 deletions.
4 changes: 2 additions & 2 deletions github4s/shared/src/main/scala/github4s/Decoders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ object Decoders {
)
)

implicit val decodePublicOrganizationEvent: Decoder[PublicOrganizationEvent] =
implicit val decodePublicGitHubEvent: Decoder[PublicGitHubEvent] =
Decoder.instance(c =>
for {
id <- c.downField("id").as[Long]
Expand All @@ -255,7 +255,7 @@ object Decoders {
repo_full_name <- c.downField("repo").downField("full_name").as[String]
public <- c.downField("public").as[Boolean]
created_at <- c.downField("created_at").as[String]
} yield PublicOrganizationEvent(
} yield PublicGitHubEvent(
id,
event_type,
actor_login,
Expand Down
2 changes: 1 addition & 1 deletion github4s/shared/src/main/scala/github4s/Encoders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ object Encoders {
}
}

implicit val encoderPublicOrganizationEvents: Encoder[PublicOrganizationEvent] =
implicit val encoderPublicGitHubEvents: Encoder[PublicGitHubEvent] =
Encoder.instance { e =>
Json.obj(
"id" -> e.id.asJson,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,22 @@ trait Activities[F[_]] {
org: String,
pagination: Option[Pagination] = None,
headers: Map[String, String] = Map()
): F[GHResponse[List[PublicOrganizationEvent]]]
): F[GHResponse[List[PublicGitHubEvent]]]

/**
* List the events of a particular repository
*
* @param owner The account owner of the repository. The name is not case sensitive.
* @param repo The name of the repository. The name is not case sensitive.
* @param pagination Limit and Offset for pagination
* @param headers Optional user headers to include in the request
* @return GHResponse with the list of events for this public repository
*/
def listPublicRepositoryEvents(
owner: String,
repo: String,
pagination: Option[Pagination] = None,
headers: Map[String, String] = Map()
): F[GHResponse[List[PublicGitHubEvent]]]

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ final case class StarredRepository(
starred_at: Option[String] = None
)

final case class PublicOrganizationEvent(
final case class PublicGitHubEvent(
id: Long,
`type`: String,
actor_login: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,24 @@ class ActivitiesInterpreter[F[_]](implicit client: HttpClient[F]) extends Activi
org: String,
pagination: Option[Pagination],
headers: Map[String, String]
): F[GHResponse[List[PublicOrganizationEvent]]] =
client.get[List[PublicOrganizationEvent]](
): F[GHResponse[List[PublicGitHubEvent]]] =
client.get[List[PublicGitHubEvent]](
method = s"orgs/$org/events",
headers + eventsRecommendedHeader,
Map.empty,
pagination = pagination
)

override def listPublicRepositoryEvents(
owner: String,
repo: String,
pagination: Option[Pagination],
headers: Map[String, String]
): F[GHResponse[List[PublicGitHubEvent]]] =
client.get[List[PublicGitHubEvent]](
method = s"repos/$owner/$repo/events",
headers + eventsRecommendedHeader,
Map.empty,
pagination = pagination
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ trait ActivitiesSpec extends BaseIntegrationSpec {
}
.unsafeRunSync()

testIsRight[List[PublicOrganizationEvent]](
testIsRight[List[PublicGitHubEvent]](
response,
{ r =>
r.nonEmpty shouldBe true
Expand All @@ -172,7 +172,51 @@ trait ActivitiesSpec extends BaseIntegrationSpec {
}
.unsafeRunSync()

testIsLeft[NotFoundError, List[PublicOrganizationEvent]](response)
testIsLeft[NotFoundError, List[PublicGitHubEvent]](response)
response.statusCode shouldBe notFoundStatusCode
}

"Activity >> PublicRepositoryEvents" should "return the expected list of events" taggedAs Integration in {
val response = clientResource
.use { client =>
Github[IO](client, accessToken).activities
.listPublicRepositoryEvents(validRepoOwner, validRepoName, headers = headerUserAgent)
}
.unsafeRunSync()

testIsRight[List[PublicGitHubEvent]](
response,
{ r =>
r.nonEmpty shouldBe true
forAll(r)(s => s.public shouldBe true)
forAll(r)(s => s.actor_login.nonEmpty shouldBe true)
forAll(r)(s => s.repo_full_name.nonEmpty shouldBe true)
}
)
response.statusCode shouldBe okStatusCode
}

it should "return error for invalid repository owner" taggedAs Integration in {
val response = clientResource
.use { client =>
Github[IO](client, accessToken).activities
.listPublicRepositoryEvents(invalidRepoOwner, validRepoName, headers = headerUserAgent)
}
.unsafeRunSync()

testIsLeft[NotFoundError, List[PublicGitHubEvent]](response)
response.statusCode shouldBe notFoundStatusCode
}

it should "return error for invalid repository name" taggedAs Integration in {
val response = clientResource
.use { client =>
Github[IO](client, accessToken).activities
.listPublicRepositoryEvents(validRepoOwner, invalidRepoName, headers = headerUserAgent)
}
.unsafeRunSync()

testIsLeft[NotFoundError, List[PublicGitHubEvent]](response)
response.statusCode shouldBe notFoundStatusCode
}

Expand Down
18 changes: 16 additions & 2 deletions github4s/shared/src/test/scala/github4s/unit/ActivitiesSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ class ActivitiesSpec extends BaseSpec {

"Activity.listPublicOrganizationEvents" should "call to httpClient.get with the right parameters" in {

implicit val httpClientMock: HttpClient[IO] = httpClientMockGet[List[PublicOrganizationEvent]](
implicit val httpClientMock: HttpClient[IO] = httpClientMockGet[List[PublicGitHubEvent]](
url = s"orgs/$validOrganizationName/events",
response = IO.pure(List(publicOrganizationEvent))
response = IO.pure(List(publicGitHubEvent))
)

val activities = new ActivitiesInterpreter[IO]
Expand All @@ -84,4 +84,18 @@ class ActivitiesSpec extends BaseSpec {
.shouldNotFail
}

"Activity.listPublicRepositoryEvents" should "call to httpClient.get with the right parameters" in {

implicit val httpClientMock: HttpClient[IO] = httpClientMockGet[List[PublicGitHubEvent]](
url = s"orgs/$validRepoOwner/$validRepoName/events",
response = IO.pure(List(publicGitHubEvent))
)

val activities = new ActivitiesInterpreter[IO]

activities
.listPublicRepositoryEvents(validRepoOwner, validRepoName, None, headerUserAgent)
.shouldNotFail
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ trait TestData {
val stargazer = Stargazer(user)
val starredRepository = StarredRepository(repo)

val publicOrganizationEvent = PublicOrganizationEvent(
val publicGitHubEvent = PublicGitHubEvent(
id = 21492285567L,
`type` = "PushEvent",
actor_login = "47erbot",
Expand Down
27 changes: 26 additions & 1 deletion microsite/docs/activity.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ with Github4s, you can interact with:
- [List stargazers](#list-stargazers)
- [List starred repositories](#list-starred-repositories)
- [List public organization events](#list-public-organization-events)
- [List public repository events](#list-public-repository-events)

The following examples assume the following code:

Expand Down Expand Up @@ -125,11 +126,35 @@ listPublicOrganizationEvents.flatMap(_.result match {
})
```

The `result` on the right is the corresponding [List[PublicOrganizationEvent]][activity-scala].
The `result` on the right is the corresponding [List[PublicGitHubEvent]][activity-scala].

See [the API doc](https://docs.github.com/en/rest/activity/events#list-public-organization-events)
for full reference.

### List public repository events

You can list the events of a particular repository with `listPublicRepositoryEvents`; it takes
as arguments:

- `owner`: The account owner of the repository. The name is not case sensitive.
- `repo`: The name of the repository. The name is not case sensitive.
- `pagination`: Limit and Offset for pagination, optional.

To list the events from the `github4s` repository owned by `47degrees`:

```scala mdoc:compile-only
val listPublicRepositoryEvents = gh.activities.listPublicRepositoryEvents("47degrees", "github4s")
listPublicRepositoryEvents.flatMap(_.result match {
case Left(e) => IO.println(s"Something went wrong: ${e.getMessage}")
case Right(r) => IO.println(r)
})
```

The `result` on the right is the corresponding [List[PublicGitHubEvent]][activity-scala].

See [the API doc](https://docs.github.com/en/rest/activity/events#list-repository-events)
for full reference.

As you can see, a few features of the activity endpoint are missing.

As a result, if you'd like to see a feature supported, feel free to create an issue and/or a pull request!
Expand Down

0 comments on commit e7c0793

Please sign in to comment.