Skip to content

Commit

Permalink
feat: Added test for executor and problem reports (#117)
Browse files Browse the repository at this point in the history
* feat: Added test for executor and problem reports
Signed-off-by: Shailesh Patil <shailesh.patil@iohk.io>

* lift the future effec into zio

Signed-off-by: Shailesh Patil <shailesh.patil@iohk.io>

---------

Signed-off-by: Shailesh Patil <shailesh.patil@iohk.io>
  • Loading branch information
mineme0110 committed Apr 30, 2024
1 parent 933b0b3 commit 4b4c444
Show file tree
Hide file tree
Showing 10 changed files with 772 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,22 +94,43 @@ object MediatorCoordinationExecuter
case m: KeylistUpdate =>
for {
_ <- ZIO.logInfo("KeylistUpdate")
didRequestingKeyListUpdate = m.from.asFROMTO
repo <- ZIO.service[UserAccountRepo]
updateResponse <- ZIO.foreach(m.updates) {
case (fromto, KeylistAction.add) =>
repo.addAlias(m.from.toDID, fromto.toDID).map {
case Left(value) => (fromto, KeylistAction.add, KeylistResult.server_error)
case Right(0) => (fromto, KeylistAction.add, KeylistResult.no_change)
case Right(newState) => (fromto, KeylistAction.add, KeylistResult.success)
}
case (fromto, KeylistAction.remove) =>
repo.removeAlias(m.from.toDID, fromto.toDID).map {
case Left(value) => (fromto, KeylistAction.remove, KeylistResult.server_error)
case Right(0) => (fromto, KeylistAction.remove, KeylistResult.no_change)
case Right(newState) => (fromto, KeylistAction.remove, KeylistResult.success)
}
}
} yield SyncReplyOnly(m.makeKeylistResponse(updateResponse).toPlaintextMessage)
mayBeDidAccount <- repo.getDidAccount(didRequestingKeyListUpdate.toDID)
res <-
mayBeDidAccount match
case None =>
ZIO.succeed(
Problems
.notEnroledError(
from = m.to.asFROM,
to = Some(m.from.asTO),
pthid = m.id, // TODO CHECK pthid
piuri = m.piuri,
didNotEnrolled = didRequestingKeyListUpdate.asFROM.toDIDSubject,
)
.toPlaintextMessage
)
case Some(didAccount) =>
for {
updateResponse <- ZIO.foreach(m.updates) {
case (fromto, KeylistAction.add) =>
repo.addAlias(m.from.toDID, fromto.toDID).map {
case Left(value) => (fromto, KeylistAction.add, KeylistResult.server_error)
case Right(0) => (fromto, KeylistAction.add, KeylistResult.no_change)
case Right(newState) => (fromto, KeylistAction.add, KeylistResult.success)
}
case (fromto, KeylistAction.remove) =>
repo.removeAlias(m.from.toDID, fromto.toDID).map {
case Left(value) => (fromto, KeylistAction.remove, KeylistResult.server_error)
case Right(0) => (fromto, KeylistAction.remove, KeylistResult.no_change)
case Right(newState) => (fromto, KeylistAction.remove, KeylistResult.success)
}
}
result <- ZIO.succeed(m.makeKeylistResponse(updateResponse).toPlaintextMessage)
} yield result

} yield SyncReplyOnly(res)
case m: KeylistResponse =>
ZIO.logWarning("KeylistResponse") *> ZIO.succeed(NoReply) *>
ZIO.succeed(
Expand Down
50 changes: 50 additions & 0 deletions mediator/src/test/scala/io/iohk/atala/mediator/db/AgentStub.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.iohk.atala.mediator.db
import fmgp.crypto.{Curve, KTY, OKPPrivateKey}
import fmgp.did.Agent
import fmgp.did.comm.EncryptedMessage
import fmgp.did.method.peer.{DIDPeer2, DIDPeerServiceEncoded}
import io.iohk.atala.mediator.app.{MediatorAgent, MediatorConfig}
import zio.{ULayer, ZLayer}

import java.net.URI

object AgentStub {

def keyAgreement(d: String, x: String): OKPPrivateKey =
OKPPrivateKey(kty = KTY.OKP, crv = Curve.X25519, d = d, x = x, kid = None)

def keyAuthentication(d: String, x: String): OKPPrivateKey =
OKPPrivateKey(kty = KTY.OKP, crv = Curve.Ed25519, d = d, x = x, kid = None)

val endpoint = new URI("http://localhost:8080")
val mediatorConfig = MediatorConfig(
endpoint,
keyAgreement("Z6D8LduZgZ6LnrOHPrMTS6uU2u5Btsrk1SGs4fn8M7c", "Sr4SkIskjN_VdKTn0zkjYbhGTWArdUNE4j_DmUpnQGw"),
keyAuthentication("INXCnxFEl0atLIIQYruHzGd5sUivMRyQOzu87qVerug", "MBjnXZxkMcoQVVL21hahWAw43RuAG-i64ipbeKKqwoA")
)

val endpointBob = "http://localhost:8081"
val bobAgent = DIDPeer2.makeAgent(
Seq(
keyAgreement("H5wHQcecUqobAMT3RiNsAaYaFXIfTLCNhWAYXgTYv7E", "f8ce_zxdhIEy76JE21XpVDviRtR2amXaZ6NjYyIPjg4"),
keyAuthentication("LyMSyr_usdn3pHZc00IbJaS2RcvF4OcJTJIB2Vw6dLQ", "TQdV8Wduyz3OylN3YbyHR0R-aynF3C1tmvHAgl6b34I")
),
Seq(DIDPeerServiceEncoded(endpointBob))
)

val endpointAlice = "http://localhost:8081"
val aliceAgent = DIDPeer2.makeAgent(
Seq(
keyAgreement("Z6D8LduZgZ6LnrOHPrMTS6uU2u5Btsrk1SGs4fn8M7c", "Sr4SkIskjN_VdKTn0zkjYbhGTWArdUNE4j_DmUpnQGw"),
keyAuthentication("INXCnxFEl0atLIIQYruHzGd5sUivMRyQOzu87qVerug", "MBjnXZxkMcoQVVL21hahWAw43RuAG-i64ipbeKKqwoA")
),
Seq(DIDPeerServiceEncoded(endpointAlice))
)

def aliceAgentLayer: ULayer[Agent] = ZLayer.succeed(aliceAgent)

def bobAgentLayer: ULayer[Agent] = ZLayer.succeed(bobAgent)

val agentLayer = mediatorConfig.agentLayer

}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package io.iohk.atala.mediator.db
import fmgp.did.comm.EncryptedMessage
import fmgp.did.comm.{EncryptedMessage, PlaintextMessage}
import fmgp.did.method.peer.{DIDPeer2, DIDPeerServiceEncoded}
//import io.iohk.atala.mediator.db.AgentStub.{keyAgreement, keyAuthentication}
import zio.json.*
trait AccountStubSetup {
trait DidAccountStubSetup {
val alice =
"did:peer:2.Ez6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y.Vz6Mkhh1e5CEYYq6JBUcTZ6Cp2ranCWRrv7Yax3Le4N59R6dd.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9hbGljZS5kaWQuZm1ncC5hcHAvIiwiciI6W10sImEiOlsiZGlkY29tbS92MiJdfQ"
"did:peer:2.Ez6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y.Vz6Mkhh1e5CEYYq6JBUcTZ6Cp2ranCWRrv7Yax3Le4N59R6dd.SeyJ0IjoiZG0iLCJzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwIiwiciI6W10sImEiOlsiZGlkY29tbS92MiJdfQ"
val bob =
"did:peer:2.Ez6LSkGy3e2z54uP4U9HyXJXRpaF2ytsnTuVgh6SNNmCyGZQZ.Vz6Mkjdwvf9hWc6ibZndW9B97si92DSk9hWAhGYBgP9kUFk8Z.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9ib2IuZGlkLmZtZ3AuYXBwLyIsInIiOltdLCJhIjpbImRpZGNvbW0vdjIiXX0"

Expand Down Expand Up @@ -31,4 +33,5 @@ trait AccountStubSetup {
| "tag": "iR0meUd8R3X5dleMywNHq5NaGJ4g0h2tok414SJ7UGI",
| "iv": "T-I0b4fIktFXVhAIFoSmQg"
|}""".stripMargin.fromJson[EncryptedMessage]

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,19 @@ import de.flapdoodle.embed.process.io.ProcessOutput
import de.flapdoodle.reverse.TransitionWalker
import de.flapdoodle.reverse.transitions.Start
import zio.{Task, ZIO, ZLayer}

import reactivemongo.api.indexes.{Index, IndexType}
import reactivemongo.api.bson.BSONDocument
object EmbeddedMongoDBInstance {

val port = 27777
val hostIp = "localhost"
val connectionString = s"mongodb://$hostIp:$port/messages"
val index = Index(
key = Seq("alias" -> IndexType.Ascending),
name = Some("alias_did"),
unique = true,
background = true,
partialFilter = Some(BSONDocument("alias.0" -> BSONDocument("$exists" -> true)))
)
def layer(
port: Int = 27077,
hostIp: String = "localhost"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ import zio.ExecutionStrategy.Sequential
import zio.json.*
import zio.test.*
import zio.test.Assertion.*
import io.iohk.atala.mediator.db.EmbeddedMongoDBInstance.*

object MessageItemRepoSpec extends ZIOSpecDefault with AccountStubSetup {
val port = 27777
val hostIp = "localhost"
val connectionString = s"mongodb://$hostIp:$port/messages"
object MessageItemRepoSpec extends ZIOSpecDefault with DidAccountStubSetup {

override def spec = suite("MessageItemSpec")(
test("insert message") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,9 @@ import zio.ExecutionStrategy.Sequential
import zio.json.*
import zio.test.*
import zio.test.Assertion.*

import io.iohk.atala.mediator.db.EmbeddedMongoDBInstance.*
import scala.concurrent.ExecutionContext.Implicits.global
object UserAccountRepoSpec extends ZIOSpecDefault with AccountStubSetup {
val port = 27778
val hostIp = "localhost"

val connectionString = s"mongodb://$hostIp:$port/messages"
// Define the index
val index = Index(
key = Seq("alias" -> IndexType.Ascending),
name = Some("alias_did"),
unique = true,
background = true
)
object UserAccountRepoSpec extends ZIOSpecDefault with DidAccountStubSetup {

override def spec = suite("UserAccountRepoSpec")(
test("insert new Did Account") {
Expand Down Expand Up @@ -133,7 +122,7 @@ object UserAccountRepoSpec extends ZIOSpecDefault with AccountStubSetup {
}
},
test("addMessage to inbox for given Account") {
val xRequestId = "b373423c-c78f-4cbc-a3fe-89cbc1351835"
val xRequestId = "b373423c-c78f-4cbc-a3fe-89cbc1351835"
ZIO.logAnnotate(XRequestId.value, xRequestId) {
for {
userAccount <- ZIO.service[UserAccountRepo]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package io.iohk.atala.mediator.protocols

import fmgp.did.comm.protocol.reportproblem2.{ProblemCode, ProblemReport}
import fmgp.did.comm.{EncryptedMessage, Operations, PlaintextMessage, SignedMessage, layerDefault}
import fmgp.did.method.peer.DidPeerResolver
import fmgp.util.Base64
import io.iohk.atala.mediator.comm.MessageDispatcherJVM
import io.iohk.atala.mediator.db.*
import io.iohk.atala.mediator.db.MessageItemRepoSpec.encryptedMessageAlice
import io.iohk.atala.mediator.protocols.ForwardMessageExecuter
import zio.*
import zio.ExecutionStrategy.Sequential
import zio.http.Client
import zio.json.*
import zio.test.*
import zio.test.Assertion.*
import fmgp.did.DIDSubject

import scala.concurrent.ExecutionContext.Implicits.global
import io.iohk.atala.mediator.db.EmbeddedMongoDBInstance.*
import io.iohk.atala.mediator.protocols.MediatorCoordinationExecuterSpec.setupAndClean
import reactivemongo.api.bson.BSONDocument
object ForwardMessageExecutorSpec extends ZIOSpecDefault with DidAccountStubSetup with MessageSetup {

override def spec = suite("ForwardMessageExecutorSpec")(
test("Forward message for notEnrolled DID receives problem report ") {
val executer = ForwardMessageExecuter
for {
userAccount <- ZIO.service[UserAccountRepo]
result <- userAccount.createOrFindDidAccount(DIDSubject(alice))
msg <- ZIO.fromEither(plaintextForwardNotEnrolledDidMessage)
result <- executer.execute(msg)
message <- ZIO.fromOption(result)
} yield {
assertTrue(message.isInstanceOf[SignedMessage])
val signedMessage = message.asInstanceOf[SignedMessage]
val jsonString = Base64.fromBase64url(signedMessage.payload.base64url).decodeToString
val problemReport = jsonString.fromJson[PlaintextMessage].flatMap(ProblemReport.fromPlaintextMessage)
assert(problemReport)(
isRight(
hasField("code", (p: ProblemReport) => p.code, equalTo(ProblemCode.ErroFail("req", "not_enroll"))) &&
hasField(
"from",
(p: ProblemReport) => p.from,
equalTo(alice)
)
)
)
}
} @@ TestAspect.before(setupAndClean),
test("Forward message for enrolled DID receives NoReply") {
val executer = ForwardMessageExecuter
for {
userAccount <- ZIO.service[UserAccountRepo]
result <- userAccount.createOrFindDidAccount(DIDSubject(alice))
result <- userAccount.addAlias(owner = DIDSubject(alice), newAlias = DIDSubject(alice))
msg <- ZIO.fromEither(plaintextForwardEnrolledDidMessage)
result <- executer.execute(msg)
} yield assertTrue(result.isEmpty)

} @@ TestAspect.before(setupAndClean)
).provideSomeLayer(DidPeerResolver.layerDidPeerResolver)
.provideSomeLayer(Operations.layerDefault)
.provideSomeLayer(Scope.default >>> Client.default >>> MessageDispatcherJVM.layer)
.provideSomeLayer(DidPeerResolver.layerDidPeerResolver)
.provideSomeLayer(AgentStub.agentLayer)
.provideLayerShared(dataAccessLayer) @@ TestAspect.sequential

def setupAndClean = {
for {
userAccount <- ZIO.service[UserAccountRepo]
col <- userAccount.collection
_ = col.indexesManager.create(index)
_ = col.delete.one(BSONDocument())
} yield {}
}

val dataAccessLayer = EmbeddedMongoDBInstance.layer(port, hostIp)
>>> AsyncDriverResource.layer
>>> ReactiveMongoApi.layer(connectionString)
>>> (UserAccountRepo.layer ++ MessageItemRepo.layer ++ OutboxMessageRepo.layer)

}

0 comments on commit 4b4c444

Please sign in to comment.