diff --git a/tests/end-to-end/.gitignore b/tests/end-to-end/.gitignore index 80243bff8..3e2083ed9 100644 --- a/tests/end-to-end/.gitignore +++ b/tests/end-to-end/.gitignore @@ -17,6 +17,7 @@ notes out/ !**/src/main/**/out/ !**/src/test/**/out/ +.run ### Eclipse ### .apt_generated @@ -41,4 +42,4 @@ bin/ .vscode/ ### Mac OS ### -.DS_Store \ No newline at end of file +.DS_Store diff --git a/tests/end-to-end/build.gradle.kts b/tests/end-to-end/build.gradle.kts index e346689e9..804c54740 100644 --- a/tests/end-to-end/build.gradle.kts +++ b/tests/end-to-end/build.gradle.kts @@ -1,7 +1,6 @@ plugins { kotlin("jvm") version "1.9.21" idea - java id("com.github.ben-manes.versions") version "0.47.0" id("net.serenity-bdd.serenity-gradle-plugin") version "4.0.1" } @@ -30,7 +29,7 @@ repositories { dependencies { testImplementation("io.iohk.atala.prism.walletsdk:atala-prism-sdk:3.0.0") - testImplementation("io.iohk.atala.prism:prism-kotlin-client:1.28.0") + testImplementation("io.iohk.atala.prism:prism-kotlin-client:1.31.0") testImplementation("io.iohk.atala:atala-automation:0.3.2") } @@ -45,5 +44,5 @@ tasks.test { } kotlin { - jvmToolchain(11) + jvmToolchain(17) } diff --git a/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/TestSuite.kt b/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/TestSuite.kt index 3d6f84a74..ec4af8011 100644 --- a/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/TestSuite.kt +++ b/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/TestSuite.kt @@ -7,6 +7,7 @@ import org.junit.runner.RunWith @RunWith(CucumberWithSerenity::class) @CucumberOptions( features = ["src/test/resources/features"], - plugin = ["pretty"] + plugin = ["pretty"], + tags = "not (@proof and @anoncred)" ) class TestSuite diff --git a/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/configuration/Environment.kt b/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/configuration/Environment.kt index 816ad1875..c068405a4 100644 --- a/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/configuration/Environment.kt +++ b/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/configuration/Environment.kt @@ -82,7 +82,7 @@ object Environment { private fun preparePublishedDid(publishedDid: String?) { try { assertThat(publishedDid).isNotEmpty() - val response = RestAssured + RestAssured .given().get("did-registrar/dids/$publishedDid") .then().assertThat().statusCode(200) this.publishedDid = publishedDid!! @@ -190,7 +190,7 @@ object Environment { anoncredSchema.name = "Automation Anoncred" anoncredSchema.version = "1.0" anoncredSchema.issuerId = this.publishedDid - anoncredSchema.attrNames = mutableListOf("name", "age") + anoncredSchema.attrNames = mutableListOf("name", "age", "gender") val credentialSchemaInput = CredentialSchemaInput( author = this.publishedDid, @@ -219,7 +219,7 @@ object Environment { author = publishedDid, schemaId = "${agentUrl}/schema-registry/schemas/${newSchemaGuid}/schema", signatureType = "CL", - supportRevocation = true, + supportRevocation = false, description = "Test Automation Auto-Generated" ) diff --git a/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/steps/CloudAgentSteps.kt b/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/steps/CloudAgentSteps.kt index b5778a30d..db706587a 100644 --- a/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/steps/CloudAgentSteps.kt +++ b/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/steps/CloudAgentSteps.kt @@ -58,6 +58,11 @@ class CloudAgentSteps { cloudAgentWorkflow.askForPresentProof(cloudAgent) } + @When("{actor} asks for present-proof for anoncred") + fun `Cloud Agent asks for present-proof for anoncred`(cloudAgent: Actor) { + cloudAgentWorkflow.askForPresentProofForAnoncred(cloudAgent) + } + @Then("{actor} should have the connection status updated to '{}'") fun `Cloud Agent should have the connection status updated`(cloudAgent: Actor, expectedState: String) { cloudAgentWorkflow.waitForConnectionState(cloudAgent, expectedState) diff --git a/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/steps/EdgeAgentSteps.kt b/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/steps/EdgeAgentSteps.kt index 733465683..790197c1d 100644 --- a/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/steps/EdgeAgentSteps.kt +++ b/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/steps/EdgeAgentSteps.kt @@ -23,7 +23,7 @@ class EdgeAgentSteps { edgeAgentWorkflow.connect(edgeAgent) } - @When("{actor} has {} credentials issued by {actor}") + @When("{actor} has '{}' credentials issued by {actor}") fun `Edge Agent has {} issued credential`(edgeAgent: Actor, numberOfCredentialsIssued: Int, cloudAgent: Actor) { repeat(numberOfCredentialsIssued) { cloudAgentWorkflow.offerCredential(cloudAgent) @@ -35,6 +35,18 @@ class EdgeAgentSteps { } } + @When("{actor} has '{}' anonymous credentials issued by {actor}") + fun `Edge Agent has {} anonymous issued credential`(edgeAgent: Actor, numberOfCredentialsIssued: Int, cloudAgent: Actor) { + repeat(numberOfCredentialsIssued) { + cloudAgentWorkflow.offerAnonymousCredential(cloudAgent) + edgeAgentWorkflow.waitForCredentialOffer(edgeAgent, 1) + edgeAgentWorkflow.acceptCredential(edgeAgent) + cloudAgentWorkflow.verifyCredentialState(cloudAgent, cloudAgent.recall("recordId"), "CredentialSent") + edgeAgentWorkflow.waitToReceiveCredentialIssuance(edgeAgent, 1) + edgeAgentWorkflow.processIssuedCredential(edgeAgent, 1) + } + } + @When("{actor} accepts {} credential offer sequentially from {actor}") fun `Edge Agent accepts multiple credentials offer sequentially from Cloud Agent`( edgeAgent: Actor, diff --git a/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/utils/Keys.kt b/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/utils/Keys.kt deleted file mode 100644 index b654ba5cd..000000000 --- a/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/utils/Keys.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.iohk.atala.prism.utils - -object Keys { - val CONNECTION_ID = "connectionId" - -} diff --git a/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/utils/Utils.kt b/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/utils/Utils.kt new file mode 100644 index 000000000..92a89f426 --- /dev/null +++ b/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/utils/Utils.kt @@ -0,0 +1,21 @@ +package io.iohk.atala.prism.utils + +import java.security.SecureRandom + +object Utils { + fun generateNonce(length: Int): String { + var result = "" + val secureRandom = SecureRandom() + while (result.length < length) { + val byte = ByteArray(1) + secureRandom.nextBytes(byte) + val int = byte[0].toInt() and 0xFF + if (int > 250) { + continue + } + val digit = int % 10 + result += digit + } + return result + } +} diff --git a/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/workflow/CloudAgentWorkflow.kt b/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/workflow/CloudAgentWorkflow.kt index 71a2ddae3..25aaa188a 100644 --- a/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/workflow/CloudAgentWorkflow.kt +++ b/tests/end-to-end/src/test/kotlin/io/iohk/atala/prism/workflow/CloudAgentWorkflow.kt @@ -7,7 +7,15 @@ import io.iohk.atala.automation.serenity.ensure.Ensure import io.iohk.atala.automation.serenity.interactions.PollingWait import io.iohk.atala.automation.serenity.questions.HttpRequest import io.iohk.atala.prism.configuration.Environment -import io.iohk.atala.prism.models.* +import io.iohk.atala.prism.models.AnoncredPresentationRequestV1 +import io.iohk.atala.prism.models.AnoncredRequestedAttributeV1 +import io.iohk.atala.prism.models.AnoncredRequestedPredicateV1 +import io.iohk.atala.prism.models.CreateConnectionRequest +import io.iohk.atala.prism.models.CreateIssueCredentialRecordRequest +import io.iohk.atala.prism.models.Options +import io.iohk.atala.prism.models.ProofRequestAux +import io.iohk.atala.prism.models.RequestPresentationInput +import io.iohk.atala.prism.utils.Utils import net.serenitybdd.rest.SerenityRest.lastResponse import net.serenitybdd.screenplay.Actor import net.serenitybdd.screenplay.rest.interactions.Post @@ -64,13 +72,18 @@ class CloudAgentWorkflow { fun offerAnonymousCredential(cloudAgent: Actor) { val connectionId = cloudAgent.recall("connectionId") val credential = CreateIssueCredentialRecordRequest( - claims = mapOf(Pair("name", "automation"), Pair("age", "99")), + claims = mapOf( + "name" to "automation", + "age" to "99", + "gender" to "M" + ), automaticIssuance = true, issuingDID = Environment.publishedDid, connectionId = UUID.fromString(connectionId), credentialFormat = "AnonCreds", credentialDefinitionId = UUID.fromString(Environment.anoncredDefinitionId) ) + cloudAgent.attemptsTo( Post.to("/issue-credentials/credential-offers").body(credential), Ensure.thatTheLastResponse().statusCode().isEqualTo(HttpStatus.SC_CREATED) @@ -103,6 +116,50 @@ class CloudAgentWorkflow { cloudAgent.remember("presentationId", lastResponse().get("presentationId")) } + fun askForPresentProofForAnoncred(cloudAgent: Actor) { + val credentialDefinitionId = Environment.agentUrl + + "/credential-definition-registry/definitions/" + + Environment.anoncredDefinitionId + + "/definition" + val anoncredsPresentationRequestV1 = AnoncredPresentationRequestV1( + requestedAttributes = mapOf( + "gender" to AnoncredRequestedAttributeV1( + name = "gender", + restrictions = listOf( + mapOf( + "attr::gender::value" to "M", + "cred_def_id" to credentialDefinitionId + ) + ) + ) + ), + requestedPredicates = mapOf( + "age" to AnoncredRequestedPredicateV1( + name = "age", + pType = ">", + pValue = 18, + restrictions = emptyList() + ) + ), + name = "proof_req_1", + nonce = Utils.generateNonce(25), + version = "0.1" + ) + + val presentProofRequest = RequestPresentationInput( + connectionId = UUID.fromString(cloudAgent.recall("connectionId")), + credentialFormat = "AnonCreds", + anoncredPresentationRequest = anoncredsPresentationRequestV1, + proofs = emptyList() + ) + + cloudAgent.attemptsTo( + Post.to("/present-proof/presentations").body(presentProofRequest), + Ensure.thatTheLastResponse().statusCode().isEqualTo(HttpStatus.SC_CREATED) + ) + cloudAgent.remember("presentationId", lastResponse().get("presentationId")) + } + fun verifyCredentialState(cloudAgent: Actor, recordId: String, state: String) { cloudAgent.attemptsTo( PollingWait.until( diff --git a/tests/end-to-end/src/test/resources/features/connection/CreateConnection.feature b/tests/end-to-end/src/test/resources/features/connection/CreateConnection.feature index de4382125..26993017e 100644 --- a/tests/end-to-end/src/test/resources/features/connection/CreateConnection.feature +++ b/tests/end-to-end/src/test/resources/features/connection/CreateConnection.feature @@ -1,3 +1,4 @@ +@connection Feature: Create connection The Edge Agent should be able to create a connection to prism-agent diff --git a/tests/end-to-end/src/test/resources/features/credential/Anoncred.feature b/tests/end-to-end/src/test/resources/features/credential/Anoncred.feature index 7b9b9f035..39d881056 100644 --- a/tests/end-to-end/src/test/resources/features/credential/Anoncred.feature +++ b/tests/end-to-end/src/test/resources/features/credential/Anoncred.feature @@ -1,3 +1,4 @@ +@credential @anoncred Feature: Receive anonymous credential The Edge Agent should be able to receive an anonymous credential from Cloud Agent diff --git a/tests/end-to-end/src/test/resources/features/credential/Credential.feature b/tests/end-to-end/src/test/resources/features/credential/Credential.feature index f2cd02159..38b5caf34 100644 --- a/tests/end-to-end/src/test/resources/features/credential/Credential.feature +++ b/tests/end-to-end/src/test/resources/features/credential/Credential.feature @@ -1,3 +1,4 @@ +@credential @jwt Feature: Receive verifiable credential The Edge Agent should be able to receive a verifiable credential from Cloud Agent diff --git a/tests/end-to-end/src/test/resources/features/present-proof/AnoncredPresentProof.feature b/tests/end-to-end/src/test/resources/features/present-proof/AnoncredPresentProof.feature new file mode 100644 index 000000000..abd1149f6 --- /dev/null +++ b/tests/end-to-end/src/test/resources/features/present-proof/AnoncredPresentProof.feature @@ -0,0 +1,10 @@ +@proof @anoncred +Feature: Respond to anoncred request proof + The Edge Agent should be able to respond to an anoncred proof-of-request + + Scenario: Respond to anoncred request proof + Given Cloud Agent is connected to Edge Agent + And Edge Agent has '1' anonymous credentials issued by Cloud Agent + When Cloud Agent asks for present-proof for anoncred + And Edge Agent sends the present-proof + Then Cloud Agent should see the present-proof is verified diff --git a/tests/end-to-end/src/test/resources/features/present-proof/PresentProof.feature b/tests/end-to-end/src/test/resources/features/present-proof/PresentProof.feature index 28bceda04..d26165c8c 100644 --- a/tests/end-to-end/src/test/resources/features/present-proof/PresentProof.feature +++ b/tests/end-to-end/src/test/resources/features/present-proof/PresentProof.feature @@ -1,9 +1,10 @@ +@proof @jwt Feature: Respond to request proof The Edge Agent should be able to respond to a proof-of-request Scenario: Respond to request proof Given Cloud Agent is connected to Edge Agent - And Edge Agent has 1 credentials issued by Cloud Agent + And Edge Agent has '1' credentials issued by Cloud Agent When Cloud Agent asks for present-proof And Edge Agent sends the present-proof Then Cloud Agent should see the present-proof is verified