diff --git a/AUTHORS.md b/AUTHORS.md index e119d46a..24bcd109 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -8,68 +8,9 @@ The maintainers of the project are: -- [![bond15](https://avatars.githubusercontent.com/u/9124653?v=4&s=20) **bond15**](https://github.com/bond15) -- [![47erbot](https://avatars.githubusercontent.com/u/24799081?v=4&s=20) **47erbot**](https://github.com/47erbot) -- [![AdrianRaFo](https://avatars.githubusercontent.com/u/15971742?v=4&s=20) **Adrian Ramirez Fornell (AdrianRaFo)**](https://github.com/AdrianRaFo) -- [![alejandrohdezma](https://avatars.githubusercontent.com/u/9027541?v=4&s=20) **Alejandro Hernández (alejandrohdezma)**](https://github.com/alejandrohdezma) -- [![anamariamv](https://avatars.githubusercontent.com/u/2183589?v=4&s=20) **Ana Mª Marquez (anamariamv)**](https://github.com/anamariamv) -- [![AntonioMateoGomez](https://avatars.githubusercontent.com/u/25897490?v=4&s=20) **Antonio Mateo (AntonioMateoGomez)**](https://github.com/AntonioMateoGomez) -- [![BenFradet](https://avatars.githubusercontent.com/u/1737211?v=4&s=20) **Ben Fradet (BenFradet)**](https://github.com/BenFradet) -- [![fedefernandez](https://avatars.githubusercontent.com/u/720923?v=4&s=20) **Fede Fernández (fedefernandez)**](https://github.com/fedefernandez) -- [![jdesiloniz](https://avatars.githubusercontent.com/u/2835739?v=4&s=20) **Javier de Silóniz Sandino (jdesiloniz)**](https://github.com/jdesiloniz) -- [![JesusMtnez](https://avatars.githubusercontent.com/u/8639179?v=4&s=20) **Jesús Martínez (JesusMtnez)**](https://github.com/JesusMtnez) -- [![juanpedromoreno](https://avatars.githubusercontent.com/u/4879373?v=4&s=20) **Juan Pedro Moreno (juanpedromoreno)**](https://github.com/juanpedromoreno) -- [![calvellido](https://avatars.githubusercontent.com/u/7753447?v=4&s=20) **Juan Valencia (calvellido)**](https://github.com/calvellido) -- [![MaureenElsberry](https://avatars.githubusercontent.com/u/17556002?v=4&s=20) **Maureen Elsberry (MaureenElsberry)**](https://github.com/MaureenElsberry) -- [![pepegar](https://avatars.githubusercontent.com/u/694179?v=4&s=20) **Pepe García (pepegar)**](https://github.com/pepegar) -- [![peterneyens](https://avatars.githubusercontent.com/u/6407606?v=4&s=20) **Peter Neyens (peterneyens)**](https://github.com/peterneyens) -- [![rafaparadela](https://avatars.githubusercontent.com/u/315070?v=4&s=20) **Rafa Paradela (rafaparadela)**](https://github.com/rafaparadela) -- [![sloshy](https://avatars.githubusercontent.com/u/427237?v=4&s=20) **Ryan Peters (sloshy)**](https://github.com/sloshy) + ## Contributors These are the people that have contributed to the _github4s_ project: -- [![BenFradet](https://avatars.githubusercontent.com/u/1737211?v=4&s=20) **BenFradet**](https://github.com/BenFradet) -- [![juanpedromoreno](https://avatars.githubusercontent.com/u/4879373?v=4&s=20) **juanpedromoreno**](https://github.com/juanpedromoreno) -- [![47erbot](https://avatars.githubusercontent.com/u/24799081?v=4&s=20) **47erbot**](https://github.com/47erbot) -- [![rafaparadela](https://avatars.githubusercontent.com/u/315070?v=4&s=20) **rafaparadela**](https://github.com/rafaparadela) -- [![47degdev](https://avatars.githubusercontent.com/u/5580770?v=4&s=20) **47degdev**](https://github.com/47degdev) -- [![fedefernandez](https://avatars.githubusercontent.com/u/720923?v=4&s=20) **fedefernandez**](https://github.com/fedefernandez) -- [![jdesiloniz](https://avatars.githubusercontent.com/u/2835739?v=4&s=20) **jdesiloniz**](https://github.com/jdesiloniz) -- [![anamariamv](https://avatars.githubusercontent.com/u/2183589?v=4&s=20) **anamariamv**](https://github.com/anamariamv) -- [![sloshy](https://avatars.githubusercontent.com/u/427237?v=4&s=20) **sloshy**](https://github.com/sloshy) -- [![calvellido](https://avatars.githubusercontent.com/u/7753447?v=4&s=20) **calvellido**](https://github.com/calvellido) -- [![AdrianRaFo](https://avatars.githubusercontent.com/u/15971742?v=4&s=20) **AdrianRaFo**](https://github.com/AdrianRaFo) -- [![alejandrohdezma](https://avatars.githubusercontent.com/u/9027541?v=4&s=20) **alejandrohdezma**](https://github.com/alejandrohdezma) -- [![georgeorfanidi](https://avatars.githubusercontent.com/u/24582954?v=4&s=20) **georgeorfanidi**](https://github.com/georgeorfanidi) -- [![mfirry](https://avatars.githubusercontent.com/u/1107071?v=4&s=20) **mfirry**](https://github.com/mfirry) -- [![mkobzik](https://avatars.githubusercontent.com/u/18078706?v=4&s=20) **mkobzik**](https://github.com/mkobzik) -- [![AntonioMateoGomez](https://avatars.githubusercontent.com/u/25897490?v=4&s=20) **AntonioMateoGomez**](https://github.com/AntonioMateoGomez) -- [![duanebester](https://avatars.githubusercontent.com/u/2539656?v=4&s=20) **duanebester**](https://github.com/duanebester) -- [![lloydmeta](https://avatars.githubusercontent.com/u/914805?v=4&s=20) **lloydmeta**](https://github.com/lloydmeta) -- [![aleksandr-vin](https://avatars.githubusercontent.com/u/223293?v=4&s=20) **aleksandr-vin**](https://github.com/aleksandr-vin) -- [![loonydev](https://avatars.githubusercontent.com/u/7644109?v=4&s=20) **loonydev**](https://github.com/loonydev) -- [![GRBurst](https://avatars.githubusercontent.com/u/4647221?v=4&s=20) **GRBurst**](https://github.com/GRBurst) -- [![JesusMtnez](https://avatars.githubusercontent.com/u/8639179?v=4&s=20) **JesusMtnez**](https://github.com/JesusMtnez) -- [![YarekTyshchenko](https://avatars.githubusercontent.com/u/185304?v=4&s=20) **YarekTyshchenko**](https://github.com/YarekTyshchenko) -- [![bond15](https://avatars.githubusercontent.com/u/9124653?v=4&s=20) **bond15**](https://github.com/bond15) -- [![zachkirlew](https://avatars.githubusercontent.com/u/15320944?v=4&s=20) **zachkirlew**](https://github.com/zachkirlew) -- [![kusaeva](https://avatars.githubusercontent.com/u/5486933?v=4&s=20) **kusaeva**](https://github.com/kusaeva) -- [![pepegar](https://avatars.githubusercontent.com/u/694179?v=4&s=20) **pepegar**](https://github.com/pepegar) -- [![reimai](https://avatars.githubusercontent.com/u/1123908?v=4&s=20) **reimai**](https://github.com/reimai) -- [![nihirash](https://avatars.githubusercontent.com/u/5459892?v=4&s=20) **nihirash**](https://github.com/nihirash) -- [![asoltysik](https://avatars.githubusercontent.com/u/17353292?v=4&s=20) **asoltysik**](https://github.com/asoltysik) -- [![chalenge](https://avatars.githubusercontent.com/u/5385518?v=4&s=20) **chalenge**](https://github.com/chalenge) -- [![dcsobral](https://avatars.githubusercontent.com/u/141079?v=4&s=20) **dcsobral**](https://github.com/dcsobral) -- [![drwlrsn](https://avatars.githubusercontent.com/u/981387?v=4&s=20) **drwlrsn**](https://github.com/drwlrsn) -- [![guersam](https://avatars.githubusercontent.com/u/969120?v=4&s=20) **guersam**](https://github.com/guersam) -- [![kalexmills](https://avatars.githubusercontent.com/u/22620342?v=4&s=20) **kalexmills**](https://github.com/kalexmills) -- [![mscharley](https://avatars.githubusercontent.com/u/336509?v=4&s=20) **mscharley**](https://github.com/mscharley) -- [![MaureenElsberry](https://avatars.githubusercontent.com/u/17556002?v=4&s=20) **MaureenElsberry**](https://github.com/MaureenElsberry) -- [![mikegirkin](https://avatars.githubusercontent.com/u/4907402?v=4&s=20) **mikegirkin**](https://github.com/mikegirkin) -- [![peterneyens](https://avatars.githubusercontent.com/u/6407606?v=4&s=20) **peterneyens**](https://github.com/peterneyens) -- [![raulraja](https://avatars.githubusercontent.com/u/456796?v=4&s=20) **raulraja**](https://github.com/raulraja) -- [![satorg](https://avatars.githubusercontent.com/u/3954178?v=4&s=20) **satorg**](https://github.com/satorg) -- [![suhasgaddam](https://avatars.githubusercontent.com/u/7282584?v=4&s=20) **suhasgaddam**](https://github.com/suhasgaddam) -- [![oybek](https://avatars.githubusercontent.com/u/2409985?v=4&s=20) **oybek**](https://github.com/oybek) \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aead5213..04018dce 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,14 +4,14 @@ # Contributing -Discussion around _github4s_ happens in the [GitHub issues](https://github.com/47degrees/github4s/issues) and [pull requests](https://github.com/47degrees/github4s/pulls). +Discussion around _github4s_ happens in the [GitHub issues](https://github.com//issues) and [pull requests](https://github.com//pulls). Feel free to open an issue if you notice a bug, have an idea for a feature, or have a question about the code. Pull requests are also welcome. People are expected to follow the [Code of Conduct](CODE_OF_CONDUCT.md) when discussing _github4s_ on the Github page or other venues. -If you are being harassed, please contact one of [us](AUTHORS.md#maintainers) immediately so that we can support you. In case you cannot get in touch with us please write an email to [47 Degrees Open Source](mailto:hello@47deg.com). +If you are being harassed, please contact one of [us](AUTHORS.md#maintainers) immediately so that we can support you. In case you cannot get in touch with us please write an email to [com.47deg](mailto:). ## How can I help? diff --git a/LICENSE.md b/LICENSE.md index 61f6eedd..3811c9ed 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright (C) 2016-2021 47 Degrees Open Source + Copyright (C) com.47deg Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/NOTICE.md b/NOTICE.md index 54bb181e..c0328fa1 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -4,6 +4,6 @@ github4s -Copyright (c) 2016-2021 47 Degrees Open Source. All rights reserved. +Copyright (c) com.47deg. All rights reserved. -Licensed under Apache-2.0. See [LICENSE](LICENSE.md) for terms. \ No newline at end of file +Licensed under . See [LICENSE](LICENSE.md) for terms. \ No newline at end of file diff --git a/README.md b/README.md index 84c2dadb..e02c78ef 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -[![Join the chat at https://gitter.im/47degrees/github4s](https://badges.gitter.im/47degrees/github4s.svg)](https://gitter.im/47degrees/github4s?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![codecov.io](http://codecov.io/gh/47degrees/github4s/branch/master/graph/badge.svg)](http://codecov.io/gh/47degrees/github4s) [![Maven Central](https://img.shields.io/badge/maven%20central-0.28.1-green.svg)](https://oss.sonatype.org/#nexus-search;gav~com.47deg~github4s*) [![License](https://img.shields.io/badge/license-Apache%202-blue.svg)](https://raw.githubusercontent.com/47degrees/github4s/master/LICENSE) [![Latest version](https://img.shields.io/badge/github4s-0.28.1-green.svg)](https://index.scala-lang.org/47degrees/github4s) [![GitHub Issues](https://img.shields.io/github/issues/47degrees/github4s.svg)](https://github.com/47degrees/github4s/issues) +[![Join the chat at https://gitter.im/47degrees/github4s](https://badges.gitter.im/47degrees/github4s.svg)](https://gitter.im/47degrees/github4s?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![codecov.io](http://codecov.io/gh/47degrees/github4s/branch/master/graph/badge.svg)](http://codecov.io/gh/47degrees/github4s) [![Maven Central](https://img.shields.io/badge/maven%20central-0.28.5-green.svg)](https://oss.sonatype.org/#nexus-search;gav~com.47deg~github4s*) [![License](https://img.shields.io/badge/license-Apache%202-blue.svg)](https://raw.githubusercontent.com/47degrees/github4s/master/LICENSE) [![Latest version](https://img.shields.io/badge/github4s-0.28.5-green.svg)](https://index.scala-lang.org/47degrees/github4s) [![GitHub Issues](https://img.shields.io/github/issues/47degrees/github4s.svg)](https://github.com/47degrees/github4s/issues) Github4s ============= @@ -11,7 +11,7 @@ Github4s To get started with SBT, simply add the following to your build.sbt file. ```scala -libraryDependencies += "com.47deg" %% "github4s" % "0.28.1" +libraryDependencies += "com.47deg" %% "github4s" % "0.28.5" ``` ## Github4s in the wild diff --git a/github4s/src/main/scala/github4s/Decoders.scala b/github4s/src/main/scala/github4s/Decoders.scala index ccfa5c50..f348f960 100644 --- a/github4s/src/main/scala/github4s/Decoders.scala +++ b/github4s/src/main/scala/github4s/Decoders.scala @@ -242,6 +242,17 @@ object Decoders { ) ) + implicit val decodeWatchedRepository: Decoder[WatchedRepository] = + Decoder[Repository] + .map(WatchedRepository(_)) + .or( + Decoder.instance(c => + for { + repo <- c.downField("repo").as[Repository] + } yield WatchedRepository(repo) + ) + ) + implicit def decodeNonEmptyList[T](implicit D: Decoder[T]): Decoder[NonEmptyList[T]] = { def decodeCursors(cursors: List[HCursor]): Result[NonEmptyList[T]] = diff --git a/github4s/src/main/scala/github4s/algebras/Activities.scala b/github4s/src/main/scala/github4s/algebras/Activities.scala index b9cd3c60..bcb20575 100644 --- a/github4s/src/main/scala/github4s/algebras/Activities.scala +++ b/github4s/src/main/scala/github4s/algebras/Activities.scala @@ -76,4 +76,18 @@ trait Activities[F[_]] { headers: Map[String, String] = Map() ): F[GHResponse[List[StarredRepository]]] + /** + * List the respositories watched by a particular user + * + * @param username User for which we want to retrieve the starred repositories + * @param pagination Limit and Offset for pagination + * @param headers Optional user headers to include in the request + * @return GHResponse with the list of starred repositories for this user + */ + def listWatchedRespositories( + username: String, + pagination: Option[Pagination] = None, + headers: Map[String, String] = Map() + ): F[GHResponse[List[WatchedRepository]]] + } diff --git a/github4s/src/main/scala/github4s/domain/Activity.scala b/github4s/src/main/scala/github4s/domain/Activity.scala index 51023c40..9bda86eb 100644 --- a/github4s/src/main/scala/github4s/domain/Activity.scala +++ b/github4s/src/main/scala/github4s/domain/Activity.scala @@ -39,3 +39,7 @@ final case class StarredRepository( repo: Repository, starred_at: Option[String] = None ) + +final case class WatchedRepository( + repo: Repository +) diff --git a/github4s/src/main/scala/github4s/interpreters/ActivitiesInterpreter.scala b/github4s/src/main/scala/github4s/interpreters/ActivitiesInterpreter.scala index f8a2dbc3..7a14ee5b 100644 --- a/github4s/src/main/scala/github4s/interpreters/ActivitiesInterpreter.scala +++ b/github4s/src/main/scala/github4s/interpreters/ActivitiesInterpreter.scala @@ -69,4 +69,15 @@ class ActivitiesInterpreter[F[_]](implicit client: HttpClient[F]) extends Activi ).collect { case (key, Some(value)) => key -> value }, pagination = pagination ) + + override def listWatchedRespositories( + username: String, + pagination: Option[Pagination], + headers: Map[String, String] + ): F[GHResponse[List[WatchedRepository]]] = + client.get[List[WatchedRepository]]( + s"users/$username/subscriptions", + headers = headers, + pagination = pagination + ) } diff --git a/github4s/src/test/scala/github4s/integration/ActivitiesSpec.scala b/github4s/src/test/scala/github4s/integration/ActivitiesSpec.scala index 33c8e1bb..4d896760 100644 --- a/github4s/src/test/scala/github4s/integration/ActivitiesSpec.scala +++ b/github4s/src/test/scala/github4s/integration/ActivitiesSpec.scala @@ -125,6 +125,8 @@ trait ActivitiesSpec extends BaseIntegrationSpec { testIsRight[List[StarredRepository]]( response, { r => + println("Here is response") + println(r) r.nonEmpty shouldBe true forAll(r)(s => s.starred_at shouldBe defined) } @@ -143,4 +145,36 @@ trait ActivitiesSpec extends BaseIntegrationSpec { testIsLeft[NotFoundError, List[StarredRepository]](response) response.statusCode shouldBe notFoundStatusCode } + + "Activity >> ListWatchedRepositories" should "return empty list if user has no watched repos" taggedAs Integration in { + val response = clientResource + .use { client => + Github[IO](client, accessToken).activities + .listWatchedRespositories(validUsername, headers = headerUserAgent) + } + .unsafeRunSync() + + testIsRight[List[WatchedRepository]]( + response, + r => r.isEmpty shouldBe true + ) + response.statusCode shouldBe okStatusCode + } + + it should "return expected list of watched repos" taggedAs Integration in { + + val response = clientResource + .use { client => + Github[IO](client, accessToken).activities + .listWatchedRespositories(validUsername, headers = headerUserAgent) + } + .unsafeRunSync() + + testIsRight[List[WatchedRepository]]( + response, + r => r.nonEmpty shouldBe true + ) + response.statusCode shouldBe okStatusCode + } + } diff --git a/github4s/src/test/scala/github4s/unit/ActivitiesSpec.scala b/github4s/src/test/scala/github4s/unit/ActivitiesSpec.scala index 0eb30d71..0e768e03 100644 --- a/github4s/src/test/scala/github4s/unit/ActivitiesSpec.scala +++ b/github4s/src/test/scala/github4s/unit/ActivitiesSpec.scala @@ -73,4 +73,19 @@ class ActivitiesSpec extends BaseSpec { activities.listStarredRepositories(validUsername, false, None, None, None, headerUserAgent) } + "Activity.listWatchedRespositories" should "call httpClient.get with the right parameters" in { + + val response: IO[GHResponse[List[WatchedRepository]]] = + IO(GHResponse(List(watchedRepository).asRight, okStatusCode, Map.empty)) + + implicit val httpClientMock = httpClientMockGet[List[WatchedRepository]]( + url = s"users/$validUsername/subscriptions", + response = response + ) + + val activities = new ActivitiesInterpreter[IO] + + activities.listWatchedRespositories(validUsername, None, headerUserAgent) + } + } diff --git a/github4s/src/test/scala/github4s/unit/DecodersSpec.scala b/github4s/src/test/scala/github4s/unit/DecodersSpec.scala index 1af003ea..38d3a99b 100644 --- a/github4s/src/test/scala/github4s/unit/DecodersSpec.scala +++ b/github4s/src/test/scala/github4s/unit/DecodersSpec.scala @@ -67,6 +67,14 @@ class DecodersSpec extends AnyFlatSpec with Matchers with FakeResponses { decode[StarredRepository](getStarredRepoValidResponse).isRight shouldBe true } + "WatchedRepository decoder" should "return a watched repository if given a repo" in { + decode[WatchedRepository](getRepoResponse).isRight shouldBe true + } + + it should "return a watched repository if given a watched repository" in { + decode[WatchedRepository](getStarredRepoValidResponse).isRight 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)) } diff --git a/github4s/src/test/scala/github4s/utils/FakeResponses.scala b/github4s/src/test/scala/github4s/utils/FakeResponses.scala index 2de071b7..6f245695 100644 --- a/github4s/src/test/scala/github4s/utils/FakeResponses.scala +++ b/github4s/src/test/scala/github4s/utils/FakeResponses.scala @@ -515,6 +515,13 @@ trait FakeResponses { |} """.stripMargin + val getWatchedRepoValidResponse = + s""" + |{ + | "repo": $getRepoResponse + |} + """.stripMargin + val getUserRepoPermissionResponse = s""" |{ diff --git a/github4s/src/test/scala/github4s/utils/TestData.scala b/github4s/src/test/scala/github4s/utils/TestData.scala index d26ac84b..f27cb14e 100644 --- a/github4s/src/test/scala/github4s/utils/TestData.scala +++ b/github4s/src/test/scala/github4s/utils/TestData.scala @@ -19,7 +19,7 @@ package github4s.utils import java.util.UUID import com.github.marklister.base64.Base64._ -import github4s.domain.{Stargazer, StarredRepository, Subscription, _} +import github4s.domain.{Stargazer, StarredRepository, Subscription, WatchedRepository, _} trait TestData { @@ -434,6 +434,7 @@ trait TestData { val stargazer = Stargazer(user) val starredRepository = StarredRepository(repo) + val watchedRepository = WatchedRepository(repo) val pullRequestReview = PullRequestReview( id = validPullRequestReviewNumber,