From 4e368bdfcec3ed854460dfe0f301d5ce0a712558 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 19 Sep 2024 12:31:59 +0000 Subject: [PATCH 1/3] build: zio dependency updates (#1356) Signed-off-by: Hyperledger Bot Co-authored-by: Hyperledger Bot --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 9694cf0e98..3e408118d7 100644 --- a/build.sbt +++ b/build.sbt @@ -49,7 +49,7 @@ lazy val V = new { val zioConfig = "4.0.2" val zioLogging = "2.3.1" val zioJson = "0.7.3" - val zioHttp = "3.0.0-RC10" + val zioHttp = "3.0.0" val zioCatsInterop = "3.3.0" // TODO "23.1.0.2" // https://mvnrepository.com/artifact/dev.zio/zio-interop-cats val zioMetricsConnector = "2.3.1" val zioMock = "1.0.0-RC12" From 03ce63af2dacbeb664802036592915040eabb33d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 19 Sep 2024 13:02:35 +0000 Subject: [PATCH 2/3] build: sbt and plugins dependency update (#1357) Signed-off-by: Hyperledger Bot Co-authored-by: Hyperledger Bot Co-authored-by: Fabio Pinheiro --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 3e408118d7..b8129ca75c 100644 --- a/build.sbt +++ b/build.sbt @@ -41,7 +41,7 @@ inThisBuild( ) lazy val V = new { - val munit = "1.0.1" // "0.7.29" + val munit = "1.0.2" // "0.7.29" val munitZio = "0.2.0" // https://mvnrepository.com/artifact/dev.zio/zio From 803be115486ba95545413eb2da35addf9aadaaf7 Mon Sep 17 00:00:00 2001 From: patlo-iog Date: Thu, 19 Sep 2024 22:38:09 +0700 Subject: [PATCH 3/3] test: add presentation-definition crud test (#1367) Signed-off-by: Pat Losoponkul --- build.sbt | 2 +- ...sentationExchangeRepositorySpecSuite.scala | 146 ++++++++++++++++++ ...bcPresentationExchangeRepositorySpec.scala | 36 +++++ 3 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationExchangeRepositorySpecSuite.scala create mode 100644 pollux/sql-doobie/src/test/scala/org/hyperledger/identus/pollux/sql/repository/JdbcPresentationExchangeRepositorySpec.scala diff --git a/build.sbt b/build.sbt index b8129ca75c..e96b09c440 100644 --- a/build.sbt +++ b/build.sbt @@ -792,7 +792,7 @@ lazy val polluxCore = project polluxAnoncreds, polluxVcJWT, polluxSDJWT, - polluxPreX + polluxPreX % "compile->compile;test->test", // Test is for example resources ) lazy val polluxDoobie = project diff --git a/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationExchangeRepositorySpecSuite.scala b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationExchangeRepositorySpecSuite.scala new file mode 100644 index 0000000000..4af60c579b --- /dev/null +++ b/pollux/core/src/test/scala/org/hyperledger/identus/pollux/core/repository/PresentationExchangeRepositorySpecSuite.scala @@ -0,0 +1,146 @@ +package org.hyperledger.identus.pollux.core.repository + +import io.circe.* +import io.circe.generic.auto.* +import io.circe.parser.* +import org.hyperledger.identus.pollux.prex.PresentationDefinition +import org.hyperledger.identus.shared.models.{WalletAccessContext, WalletId} +import zio.{durationInt, ZIO, ZLayer} +import zio.test.* +import zio.test.Assertion.* + +import java.util.UUID +import scala.io.Source +import scala.util.Using + +object PresentationExchangeRepositorySpecSuite { + final case class ExampleTransportEnvelope(presentation_definition: PresentationDefinition) + + private val loadPd = + ZIO + .fromTry(Using(Source.fromResource("pd/minimal_example.json"))(_.mkString)) + .flatMap(json => ZIO.fromEither(decode[ExampleTransportEnvelope](json))) + .map(_.presentation_definition) + + val testSuite = suite("CRUD operations")( + test("createPresentationDefinition creates a new record in DB") { + for { + repo <- ZIO.service[PresentationExchangeRepository] + pd <- loadPd + _ <- repo.createPresentationDefinition(pd) + maybePd <- repo.findPresentationDefinition(UUID.fromString(pd.id)) + } yield assert(maybePd)(isSome(equalTo(pd))) + }, + test("createPresentationDefinition prevents creation of 2 record with the same id") { + for { + repo <- ZIO.service[PresentationExchangeRepository] + pd <- loadPd + _ <- repo.createPresentationDefinition(pd) + exit <- repo.createPresentationDefinition(pd).exit + } yield assert(exit)(dies(anything)) + }, + test("createPresentationDefinition create a record with non-null optional fields") { + for { + repo <- ZIO.service[PresentationExchangeRepository] + pd <- loadPd.map( + _.copy( + name = Some("name"), + purpose = Some("purpose") + ) + ) + _ <- repo.createPresentationDefinition(pd) + maybePd <- repo.findPresentationDefinition(UUID.fromString(pd.id)) + } yield assert(maybePd)(isSome(equalTo(pd))) + }, + test("findPresentationDefinition returns None for non-existing record") { + for { + repo <- ZIO.service[PresentationExchangeRepository] + maybePd <- repo.findPresentationDefinition(UUID.randomUUID()) + _ <- repo.listPresentationDefinition() + } yield assert(maybePd)(isNone) + }, + test("listPresentationDefinition returns empty list when no records exist") { + for { + repo <- ZIO.service[PresentationExchangeRepository] + result <- repo.listPresentationDefinition() + (pdsList, count) = result + } yield assert(pdsList)(isEmpty) && assert(count)(isZero) + }, + test("listPresentationDefinition returns all records") { + for { + repo <- ZIO.service[PresentationExchangeRepository] + pd <- loadPd + pds = (1 to 5).map(_ => pd.copy(id = UUID.randomUUID().toString())) + _ <- ZIO.foreach(pds)(repo.createPresentationDefinition) + result <- repo.listPresentationDefinition() + (pdsList, count) = result + } yield assert(pdsList)(equalTo(pds)) && assert(count)(equalTo(5)) + }, + test("listPresentationDefinition return records respecting limit and offset") { + for { + repo <- ZIO.service[PresentationExchangeRepository] + pd <- loadPd + pds = (1 to 10).map(_ => pd.copy(id = UUID.randomUUID().toString())) + _ <- ZIO.foreach(pds)(pd => TestClock.adjust(1.second) *> repo.createPresentationDefinition(pd)) + result1 <- repo.listPresentationDefinition(offset = Some(0), limit = Some(2)) + (pdsList1, count1) = result1 + result2 <- repo.listPresentationDefinition(offset = Some(2), limit = Some(3)) + (pdsList2, count2) = result2 + } yield assert(pdsList1)(equalTo(pds.drop(0).take(2))) && + assert(count1)(equalTo(10)) && + assert(pdsList2)(equalTo(pds.drop(2).take(3))) && + assert(count2)(equalTo(10)) + } + ).provideSomeLayer(ZLayer.succeed(WalletAccessContext(WalletId.random))) + + val multitenantTestSuite = suite("multi-tenant CRUD operations")( + test("do not see PresentationDefinition outside of the wallet when listing") { + val walletId1 = WalletId.random + val walletId2 = WalletId.random + val wallet1 = ZLayer.succeed(WalletAccessContext(walletId1)) + val wallet2 = ZLayer.succeed(WalletAccessContext(walletId2)) + for { + repo <- ZIO.service[PresentationExchangeRepository] + pd <- loadPd + pds1 = (1 to 3).map(_ => pd.copy(id = UUID.randomUUID().toString())) + pds2 = (1 to 4).map(_ => pd.copy(id = UUID.randomUUID().toString())) + _ <- ZIO.foreach(pds1)(pd => + TestClock.adjust(1.second) *> + repo + .createPresentationDefinition(pd) + .provide(wallet1) + ) + _ <- ZIO.foreach(pds2)(pd => + TestClock.adjust(1.second) *> + repo + .createPresentationDefinition(pd) + .provide(wallet2) + ) + pdsList1 <- repo + .listPresentationDefinition(offset = Some(0), limit = Some(100)) + .provide(wallet1) + pdsList2 <- repo + .listPresentationDefinition(offset = Some(0), limit = Some(100)) + .provide(wallet2) + } yield assert(pdsList1._1)(equalTo(pds1)) && + assert(pdsList2._1)(equalTo(pds2)) + }, + test("can read any presentation-definition by id from any wallet") { + val walletId1 = WalletId.random + val walletId2 = WalletId.random + val wallet1 = ZLayer.succeed(WalletAccessContext(walletId1)) + val wallet2 = ZLayer.succeed(WalletAccessContext(walletId2)) + for { + repo <- ZIO.service[PresentationExchangeRepository] + pd <- loadPd + pd1 = pd.copy(id = UUID.randomUUID().toString()) + pd2 = pd.copy(id = UUID.randomUUID().toString()) + _ <- repo.createPresentationDefinition(pd1).provide(wallet1) + _ <- repo.createPresentationDefinition(pd2).provide(wallet2) + maybePd1 <- repo.findPresentationDefinition(UUID.fromString(pd1.id)) + maybePd2 <- repo.findPresentationDefinition(UUID.fromString(pd2.id)) + } yield assert(maybePd1)(isSome(equalTo(pd1))) && + assert(maybePd2)(isSome(equalTo(pd2))) + } + ) +} diff --git a/pollux/sql-doobie/src/test/scala/org/hyperledger/identus/pollux/sql/repository/JdbcPresentationExchangeRepositorySpec.scala b/pollux/sql-doobie/src/test/scala/org/hyperledger/identus/pollux/sql/repository/JdbcPresentationExchangeRepositorySpec.scala new file mode 100644 index 0000000000..dd0c819dcd --- /dev/null +++ b/pollux/sql-doobie/src/test/scala/org/hyperledger/identus/pollux/sql/repository/JdbcPresentationExchangeRepositorySpec.scala @@ -0,0 +1,36 @@ +package org.hyperledger.identus.pollux.sql.repository + +import com.dimafeng.testcontainers.PostgreSQLContainer +import org.hyperledger.identus.pollux.core.repository.* +import org.hyperledger.identus.shared.db.DbConfig +import org.hyperledger.identus.sharedtest.containers.PostgresTestContainerSupport +import zio.* +import zio.test.* + +object JdbcPresentationExchangeRepositorySpec extends ZIOSpecDefault, PostgresTestContainerSupport { + + private val dbConfig = ZLayer.fromZIO( + for { + postgres <- ZIO.service[PostgreSQLContainer] + } yield DbConfig(postgres.username, postgres.password, postgres.jdbcUrl) + ) + + private val testEnvironmentLayer = ZLayer.make[PresentationExchangeRepository & Migrations]( + JdbcPresentationExchangeRepository.layer, + Migrations.layer, + dbConfig, + pgContainerLayer, + contextAwareTransactorLayer, + systemTransactorLayer + ) + + override def spec = + (suite("JDBC PresentationExchange Repository test suite")( + PresentationExchangeRepositorySpecSuite.testSuite, + PresentationExchangeRepositorySpecSuite.multitenantTestSuite + ) @@ TestAspect.before( + ZIO.serviceWithZIO[Migrations](_.migrate) + )).provide(testEnvironmentLayer) + .provide(Runtime.removeDefaultLoggers) + +}