Skip to content

Commit

Permalink
test: add new tests and refactoring (#1442)
Browse files Browse the repository at this point in the history
Signed-off-by: Hyperledger Bot <hyperledger-bot@hyperledger.org>
Signed-off-by: Allain Magyar <allain.magyar@iohk.io>
Co-authored-by: Hyperledger Bot <hyperledger-bot@hyperledger.org>
  • Loading branch information
amagyar-iohk and hyperledger-bot authored Nov 20, 2024
1 parent 7839b95 commit 8781d3d
Show file tree
Hide file tree
Showing 32 changed files with 355 additions and 318 deletions.
83 changes: 40 additions & 43 deletions tests/integration-tests/src/test/kotlin/abilities/ListenToEvents.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,37 @@ package abilities
import com.google.gson.GsonBuilder
import common.TestConstants
import io.iohk.atala.automation.restassured.CustomGsonObjectMapperFactory
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import models.*
import io.ktor.http.HttpStatusCode
import io.ktor.server.application.Application
import io.ktor.server.application.call
import io.ktor.server.engine.ApplicationEngine
import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
import io.ktor.server.request.receiveText
import io.ktor.server.response.respond
import io.ktor.server.routing.get
import io.ktor.server.routing.post
import io.ktor.server.routing.routing
import models.ConnectionEvent
import models.CredentialEvent
import models.DidEvent
import models.Event
import models.PresentationEvent
import models.PresentationStatusAdapter
import net.serenitybdd.screenplay.Ability
import net.serenitybdd.screenplay.Actor
import net.serenitybdd.screenplay.HasTeardown
import net.serenitybdd.screenplay.Question
import org.hyperledger.identus.client.models.*
import org.hyperledger.identus.client.models.Connection
import org.hyperledger.identus.client.models.IssueCredentialRecord
import java.net.URL
import java.time.OffsetDateTime

open class ListenToEvents(
private val url: URL,
webhookPort: Int?,
) : Ability, HasTeardown {
) : Ability,
HasTeardown {

private val server: ApplicationEngine
private val gson = GsonBuilder()
Expand Down Expand Up @@ -88,48 +99,36 @@ open class ListenToEvents(
}

companion object {
fun at(url: URL, webhookPort: Int?): ListenToEvents {
return ListenToEvents(url, webhookPort)
}
fun at(url: URL, webhookPort: Int?): ListenToEvents = ListenToEvents(url, webhookPort)

fun with(actor: Actor): ListenToEvents {
return actor.abilityTo(ListenToEvents::class.java)
}
fun with(actor: Actor): ListenToEvents = actor.abilityTo(ListenToEvents::class.java)

fun presentationProofStatus(actor: Actor): Question<PresentationStatusAdapter.Status?> {
return Question.about("presentation status").answeredBy {
val proofEvent = with(actor).presentationEvents.lastOrNull {
it.data.thid == actor.recall<String>("thid")
}
proofEvent?.data?.status
fun presentationProofStatus(actor: Actor): Question<PresentationStatusAdapter.Status?> = Question.about("presentation status").answeredBy {
val proofEvent = with(actor).presentationEvents.lastOrNull {
it.data.thid == actor.recall<String>("thid")
}
proofEvent?.data?.status
}

fun connectionState(actor: Actor): Question<Connection.State?> {
return Question.about("connection state").answeredBy {
val lastEvent = with(actor).connectionEvents.lastOrNull {
it.data.thid == actor.recall<Connection>("connection").thid
}
lastEvent?.data?.state
fun connectionState(actor: Actor): Question<Connection.State?> = Question.about("connection state").answeredBy {
val lastEvent = with(actor).connectionEvents.lastOrNull {
it.data.thid == actor.recall<Connection>("connection").thid
}
lastEvent?.data?.state
}

fun credentialState(actor: Actor): Question<IssueCredentialRecord.ProtocolState?> {
return Question.about("credential state").answeredBy {
val credentialEvent = ListenToEvents.with(actor).credentialEvents.lastOrNull {
it.data.thid == actor.recall<String>("thid")
}
credentialEvent?.data?.protocolState
fun credentialState(actor: Actor): Question<IssueCredentialRecord.ProtocolState?> = Question.about("credential state").answeredBy {
val credentialEvent = ListenToEvents.with(actor).credentialEvents.lastOrNull {
it.data.thid == actor.recall<String>("thid")
}
credentialEvent?.data?.protocolState
}

fun didStatus(actor: Actor): Question<String> {
return Question.about("did status").answeredBy {
val didEvent = ListenToEvents.with(actor).didEvents.lastOrNull {
it.data.did == actor.recall<String>("shortFormDid")
}
didEvent?.data?.status
fun didStatus(actor: Actor): Question<String> = Question.about("did status").answeredBy {
val didEvent = ListenToEvents.with(actor).didEvents.lastOrNull {
it.data.did == actor.recall<String>("shortFormDid")
}
didEvent?.data?.status
}
}

Expand All @@ -143,9 +142,7 @@ open class ListenToEvents(
.start(wait = false)
}

override fun toString(): String {
return "Listen HTTP port at $url"
}
override fun toString(): String = "Listen HTTP port at $url"

override fun tearDown() {
server.stop()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package common

import org.hyperledger.identus.client.models.ManagedDIDKeyTemplate
import org.hyperledger.identus.client.models.Service

data class DidDocumentTemplate(
val publicKeys: MutableList<ManagedDIDKeyTemplate>,
val services: MutableList<Service>,
)
41 changes: 0 additions & 41 deletions tests/integration-tests/src/test/kotlin/common/DidPurpose.kt

This file was deleted.

50 changes: 50 additions & 0 deletions tests/integration-tests/src/test/kotlin/common/DidType.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package common

import org.hyperledger.identus.client.models.*

enum class DidType {
CUSTOM {
override val documentTemplate get() = DidDocumentTemplate(
publicKeys = mutableListOf(),
services = mutableListOf(),
)
},
SD_JWT {
override val documentTemplate get() = DidDocumentTemplate(
publicKeys = mutableListOf(
ManagedDIDKeyTemplate("auth-1", Purpose.AUTHENTICATION, Curve.ED25519),
ManagedDIDKeyTemplate("assertion-1", Purpose.ASSERTION_METHOD, Curve.ED25519),
),
services = mutableListOf(),
)
},
JWT {
override val documentTemplate get() = DidDocumentTemplate(
publicKeys = mutableListOf(
ManagedDIDKeyTemplate("auth-1", Purpose.AUTHENTICATION, Curve.SECP256K1),
ManagedDIDKeyTemplate("auth-2", Purpose.AUTHENTICATION, Curve.ED25519),
ManagedDIDKeyTemplate("assertion-1", Purpose.ASSERTION_METHOD, Curve.SECP256K1),
ManagedDIDKeyTemplate("assertion-2", Purpose.ASSERTION_METHOD, Curve.ED25519),
),
services = mutableListOf(),
)
},
OIDC_JWT {
override val documentTemplate get() = DidDocumentTemplate(
publicKeys = mutableListOf(
ManagedDIDKeyTemplate("auth-1", Purpose.AUTHENTICATION, Curve.SECP256K1),
ManagedDIDKeyTemplate("auth-2", Purpose.AUTHENTICATION, Curve.ED25519),
ManagedDIDKeyTemplate("assertion-1", Purpose.ASSERTION_METHOD, Curve.SECP256K1),
),
services = mutableListOf(),
)
},
ANONCRED {
override val documentTemplate get() = DidDocumentTemplate(
publicKeys = mutableListOf(),
services = mutableListOf(),
)
}, ;

abstract val documentTemplate: DidDocumentTemplate
}
38 changes: 17 additions & 21 deletions tests/integration-tests/src/test/kotlin/steps/common/CommonSteps.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package steps.common

import common.CredentialSchema
import common.DidPurpose
import common.DidType
import interactions.Get
import io.cucumber.java.en.Given
import io.iohk.atala.automation.extensions.get
Expand All @@ -13,39 +13,39 @@ import org.hyperledger.identus.client.models.Connection
import org.hyperledger.identus.client.models.ConnectionsPage
import steps.connection.ConnectionSteps
import steps.credentials.*
import steps.did.PublishDidSteps
import steps.did.CreateDidSteps
import steps.schemas.CredentialSchemasSteps

class CommonSteps {
@Given("{actor} has a jwt issued credential from {actor}")
fun holderHasIssuedJwtCredentialFromIssuer(holder: Actor, issuer: Actor) {
actorsHaveExistingConnection(issuer, holder)

val publishDidSteps = PublishDidSteps()
publishDidSteps.agentHasAnUnpublishedDID(holder, DidPurpose.JWT)
publishDidSteps.agentHasAPublishedDID(issuer, DidPurpose.JWT)
val createDidSteps = CreateDidSteps()
createDidSteps.agentHasAnUnpublishedDID(holder, DidType.JWT)
createDidSteps.agentHasAPublishedDID(issuer, DidType.JWT)

val jwtCredentialSteps = JwtCredentialSteps()
val credentialSteps = CredentialSteps()

jwtCredentialSteps.issuerOffersAJwtCredential(issuer, holder, "short")
credentialSteps.holderReceivesCredentialOffer(holder)
jwtCredentialSteps.holderAcceptsJwtCredentialOfferForJwt(holder)
jwtCredentialSteps.holderAcceptsJwtCredentialOfferForJwt(holder, "auth-1")
credentialSteps.issuerIssuesTheCredential(issuer)
credentialSteps.holderReceivesTheIssuedCredential(holder)
}

@Given("{actor} has a jwt issued credential with {} schema from {actor}")
@Given("{actor} has a jwt issued credential with '{}' schema from {actor}")
fun holderHasIssuedJwtCredentialFromIssuerWithSchema(
holder: Actor,
schema: CredentialSchema,
issuer: Actor,
) {
actorsHaveExistingConnection(issuer, holder)

val publishDidSteps = PublishDidSteps()
publishDidSteps.agentHasAnUnpublishedDID(holder, DidPurpose.JWT)
publishDidSteps.agentHasAPublishedDID(issuer, DidPurpose.JWT)
val createDidSteps = CreateDidSteps()
createDidSteps.agentHasAnUnpublishedDID(holder, DidType.JWT)
createDidSteps.agentHasAPublishedDID(issuer, DidType.JWT)

val schemaSteps = CredentialSchemasSteps()
schemaSteps.agentHasAPublishedSchema(issuer, schema)
Expand All @@ -54,7 +54,7 @@ class CommonSteps {
val credentialSteps = CredentialSteps()
jwtCredentialSteps.issuerOffersJwtCredentialToHolderUsingSchema(issuer, holder, "short", schema)
credentialSteps.holderReceivesCredentialOffer(holder)
jwtCredentialSteps.holderAcceptsJwtCredentialOfferForJwt(holder)
jwtCredentialSteps.holderAcceptsJwtCredentialOfferForJwt(holder, "auth-1")
credentialSteps.issuerIssuesTheCredential(issuer)
credentialSteps.holderReceivesTheIssuedCredential(holder)
}
Expand All @@ -63,9 +63,9 @@ class CommonSteps {
fun holderHasIssuedSdJwtCredentialFromIssuer(holder: Actor, issuer: Actor) {
actorsHaveExistingConnection(issuer, holder)

val publishDidSteps = PublishDidSteps()
publishDidSteps.agentHasAnUnpublishedDID(holder, DidPurpose.SD_JWT)
publishDidSteps.agentHasAPublishedDID(issuer, DidPurpose.SD_JWT)
val createDidSteps = CreateDidSteps()
createDidSteps.agentHasAnUnpublishedDID(holder, DidType.SD_JWT)
createDidSteps.agentHasAPublishedDID(issuer, DidType.SD_JWT)

val sdJwtCredentialSteps = SdJwtCredentialSteps()
val credentialSteps = CredentialSteps()
Expand All @@ -80,9 +80,9 @@ class CommonSteps {
fun holderHasIssuedSdJwtCredentialFromIssuerWithKeyBind(holder: Actor, issuer: Actor) {
actorsHaveExistingConnection(issuer, holder)

val publishDidSteps = PublishDidSteps()
publishDidSteps.agentHasAnUnpublishedDID(holder, DidPurpose.SD_JWT)
publishDidSteps.agentHasAPublishedDID(issuer, DidPurpose.SD_JWT)
val createDidSteps = CreateDidSteps()
createDidSteps.agentHasAnUnpublishedDID(holder, DidType.SD_JWT)
createDidSteps.agentHasAPublishedDID(issuer, DidType.SD_JWT)

val sdJwtCredentialSteps = SdJwtCredentialSteps()
val credentialSteps = CredentialSteps()
Expand All @@ -97,8 +97,6 @@ class CommonSteps {
fun actorsHaveExistingConnection(inviter: Actor, invitee: Actor) {
inviter.attemptsTo(
Get.resource("/connections"),
)
inviter.attemptsTo(
Ensure.thatTheLastResponse().statusCode().isEqualTo(HttpStatus.SC_OK),
)
val inviterConnection = SerenityRest.lastResponse().get<ConnectionsPage>().contents!!.firstOrNull {
Expand All @@ -109,8 +107,6 @@ class CommonSteps {
if (inviterConnection != null) {
invitee.attemptsTo(
Get.resource("/connections"),
)
invitee.attemptsTo(
Ensure.thatTheLastResponse().statusCode().isEqualTo(HttpStatus.SC_OK),
)
inviteeConnection = SerenityRest.lastResponse().get<ConnectionsPage>().contents!!.firstOrNull {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ import org.apache.http.HttpStatus.SC_CREATED
import org.apache.http.HttpStatus.SC_OK
import org.assertj.core.api.Assertions.assertThat
import org.hamcrest.CoreMatchers
import org.hyperledger.identus.client.models.*
import org.hyperledger.identus.client.models.AcceptConnectionInvitationRequest
import org.hyperledger.identus.client.models.Connection
import org.hyperledger.identus.client.models.Connection.State.CONNECTION_RESPONSE_RECEIVED
import org.hyperledger.identus.client.models.Connection.State.CONNECTION_RESPONSE_SENT
import org.hyperledger.identus.client.models.Connection.State.INVITATION_GENERATED
import org.hyperledger.identus.client.models.CreateConnectionRequest

class ConnectionSteps {

Expand All @@ -29,12 +32,11 @@ class ConnectionSteps {

inviter.attemptsTo(
Post.to("/connections").body(CreateConnectionRequest(label = connectionLabel)),
Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_CREATED),
)

val connection = SerenityRest.lastResponse().get<Connection>()

inviter.attemptsTo(
Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_CREATED),
Ensure.that(connection.label!!).isEqualTo(connectionLabel),
Ensure.that(connection.state).isEqualTo(Connection.State.INVITATION_GENERATED),
Ensure.that(connection.role).isEqualTo(Connection.Role.INVITER),
Expand All @@ -48,20 +50,14 @@ class ConnectionSteps {
fun inviteeSendsAConnectionRequestToInviter(invitee: Actor, inviter: Actor) {
// Bob accepts connection using achieved out-of-band invitation
val inviterConnection = inviter.recall<Connection>("connection")
val body = AcceptConnectionInvitationRequest(inviterConnection.invitation.invitationUrl.split("=")[1])
invitee.attemptsTo(
Post.to("/connection-invitations")
.with {
it.body(
AcceptConnectionInvitationRequest(
inviterConnection.invitation.invitationUrl.split("=")[1],
),
)
},
Post.to("/connection-invitations").body(body),
Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_OK),
)
val inviteeConnection = SerenityRest.lastResponse().get<Connection>()

val inviteeConnection = SerenityRest.lastResponse().get<Connection>()
invitee.attemptsTo(
Ensure.thatTheLastResponse().statusCode().isEqualTo(SC_OK),
Ensure.that(inviteeConnection.invitation.from).isEqualTo(inviterConnection.invitation.from),
Ensure.that(inviteeConnection.invitation.id).isEqualTo(inviterConnection.invitation.id),
Ensure.that(inviteeConnection.invitation.invitationUrl)
Expand Down
Loading

0 comments on commit 8781d3d

Please sign in to comment.