diff --git a/src/test/java/eu/enmeshed/ChallengesTest.java b/src/test/java/eu/enmeshed/ChallengesTest.java index 10778ec..94758f7 100644 --- a/src/test/java/eu/enmeshed/ChallengesTest.java +++ b/src/test/java/eu/enmeshed/ChallengesTest.java @@ -31,7 +31,7 @@ public static void setUp() { client1 = ConnectorClient.create(connector1.getConnectionString(), connector1.getApiKey()); client2 = ConnectorClient.create(connector2.getConnectionString(), connector2.getApiKey()); - relationship = TestUtils.establishRelationship(client1, client2); + relationship = TestUtils.Relationships.establishRelationship(client1, client2); } @Test diff --git a/src/test/java/eu/enmeshed/RelationshipTemplateTest.java b/src/test/java/eu/enmeshed/RelationshipTemplateTest.java new file mode 100644 index 0000000..4cb6339 --- /dev/null +++ b/src/test/java/eu/enmeshed/RelationshipTemplateTest.java @@ -0,0 +1,154 @@ +package eu.enmeshed; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import eu.enmeshed.model.relationshipTemplates.ArbitraryRelationshipTemplateContent; +import eu.enmeshed.model.relationshipTemplates.RelationshipTemplate; +import eu.enmeshed.model.relationshipTemplates.RelationshipTemplateContentDerivation; +import eu.enmeshed.requests.relationshipTemplates.CreateOwnRelationshipTemplateRequest; +import eu.enmeshed.requests.relationshipTemplates.GetOwnRelationshipTemplatesQuery; +import eu.enmeshed.requests.relationshipTemplates.GetRelationshipTemplatesQuery; +import eu.enmeshed.utils.ConnectorContainer; +import eu.enmeshed.utils.TestUtils; +import java.time.ZonedDateTime; +import org.hamcrest.CoreMatchers; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +@Testcontainers +public class RelationshipTemplateTest { + + @Container + public static ConnectorContainer connector1 = new ConnectorContainer(); + @Container + public static ConnectorContainer connector2 = new ConnectorContainer(); + + private static ConnectorClient client1; + private static ConnectorClient client2; + + @BeforeAll + public static void setUp() { + client1 = ConnectorClient.create(connector1.getConnectionString(), connector1.getApiKey()); + client2 = ConnectorClient.create(connector2.getConnectionString(), connector2.getApiKey()); + } + + @Test + public void createTemplate() { + + var template = client1.relationshipTemplates.createOwnRelationshipTemplate(getCreateOwnTemplateRequest(1)).getResult(); + + assertThat(template.getId(), CoreMatchers.startsWith("RLT")); + assertThat(template.getCreatedBy(), CoreMatchers.equalTo(client1.account.getIdentityInfo().getResult().getAddress())); + } + + @Test + public void createTemplateWithUndefinedMaxNumberOfAllocations() { + + var template = client1.relationshipTemplates.createOwnRelationshipTemplate(getCreateOwnTemplateRequestWithUndefinedMaxNumberOfAllocations()).getResult(); + + assertThat(template.getId(), CoreMatchers.startsWith("RLT")); + assertThat(template.getMaxNumberOfAllocations(), CoreMatchers.nullValue()); + } + + @Test + public void readTemplateWithUndefinedMaxNumberOfAllocations() { + + var createdTemplate = client1.relationshipTemplates.createOwnRelationshipTemplate(getCreateOwnTemplateRequestWithUndefinedMaxNumberOfAllocations()).getResult(); + var createdTemplateId = createdTemplate.getId(); + + var response = client1.relationshipTemplates.getRelationshipTemplate(createdTemplateId).getResult(); + + assertThat(response.getId(), CoreMatchers.startsWith("RLT")); + assertThat(response.getMaxNumberOfAllocations(), CoreMatchers.nullValue()); + } + + @Test + public void seeIfTemplateExistsInOwnTemplates() { + + var createdTemplate = client1.relationshipTemplates.createOwnRelationshipTemplate(getCreateOwnTemplateRequest(1)).getResult(); + + var ownTemplates = client1.relationshipTemplates.getOwnRelationshipTemplates(GetOwnRelationshipTemplatesQuery.builder().maxNumberOfAllocations(1).build()).getResult(); + var ownTemplateIds = ownTemplates.stream().map(t -> createdTemplate.getId()).toList(); + + assertThat(ownTemplateIds, CoreMatchers.hasItem(createdTemplate.getId())); + } + + @Test + public void seeIfTemplateExistsWhenFetchingWithId() { + + var createdTemplate = client1.relationshipTemplates.createOwnRelationshipTemplate(getCreateOwnTemplateRequest(1)).getResult(); + + var fetchedTemplate = client1.relationshipTemplates.getRelationshipTemplate(createdTemplate.getId()).getResult(); + + assertThat(fetchedTemplate.getId(), CoreMatchers.startsWith("RLT")); + assertThat(fetchedTemplate.getCreatedBy(), CoreMatchers.equalTo(client1.account.getIdentityInfo().getResult().getAddress())); + } + + @Test + public void expectValidationErrorForSendingMaxNumberOfAllocationsIsZero() { + + var exception = assertThrows( + Exception.class, + () -> client1.relationshipTemplates.createOwnRelationshipTemplate(getCreateOwnTemplateRequest(0)).getResult()); + + assertThat(exception.getMessage(), CoreMatchers.equalTo("maxNumberOfAllocations must be >= 1")); + } + + @Test + public void queryTemplates() { + var template1 = client1.relationshipTemplates.createOwnRelationshipTemplate(getCreateOwnTemplateRequest(1)).getResult(); + var template2 = client1.relationshipTemplates.createOwnRelationshipTemplate(getCreateOwnTemplateRequest(1)).getResult(); + var template3 = client1.relationshipTemplates.createOwnRelationshipTemplate(getCreateOwnTemplateRequest(1)).getResult(); + + var templates = client1.relationshipTemplates.getRelationshipTemplates(GetRelationshipTemplatesQuery.builder() + .maxNumberOfAllocations(1) + .isOwn(true) + .build()).getResult(); + + assertThat(templates.stream().map(RelationshipTemplate::getId).toList(), CoreMatchers.hasItems(template1.getId(), template2.getId(), template3.getId())); + } + + @Test + public void queryOwnTemplates() { + var template1 = client1.relationshipTemplates.createOwnRelationshipTemplate(getCreateOwnTemplateRequest(1)).getResult(); + var template2 = client1.relationshipTemplates.createOwnRelationshipTemplate(getCreateOwnTemplateRequest(1)).getResult(); + var template3 = client1.relationshipTemplates.createOwnRelationshipTemplate(getCreateOwnTemplateRequest(1)).getResult(); + + var templates = client1.relationshipTemplates.getOwnRelationshipTemplates(GetOwnRelationshipTemplatesQuery.builder() + .maxNumberOfAllocations(1) + .build()).getResult(); + + assertThat(templates.stream().map(RelationshipTemplate::getId).toList(), CoreMatchers.hasItems(template1.getId(), template2.getId(), template3.getId())); + } + + @Test + public void queryPeerTemplates() { + var templateId1 = TestUtils.RelationshipTemplates.exchangeTemplate(client1, client2).getId(); + var templateId2 = TestUtils.RelationshipTemplates.exchangeTemplate(client1, client2).getId(); + var templateId3 = TestUtils.RelationshipTemplates.exchangeTemplate(client1, client2).getId(); + + var templates = client2.relationshipTemplates.getRelationshipTemplates(GetRelationshipTemplatesQuery.builder() + .maxNumberOfAllocations(1) + .isOwn(false) + .build()).getResult(); + + assertThat(templates.stream().map(RelationshipTemplate::getId).toList(), CoreMatchers.hasItems(templateId1, templateId2, templateId3)); + } + + private CreateOwnRelationshipTemplateRequest getCreateOwnTemplateRequest(int maxNumberOfAllocations) { + return + CreateOwnRelationshipTemplateRequest.builder() + .maxNumberOfAllocations(maxNumberOfAllocations) + .content(ArbitraryRelationshipTemplateContent.builder().value("value").build()) + .expiresAt(ZonedDateTime.now().plusDays(1)).build(); + } + + private CreateOwnRelationshipTemplateRequest getCreateOwnTemplateRequestWithUndefinedMaxNumberOfAllocations() { + return CreateOwnRelationshipTemplateRequest.builder() + .content(ArbitraryRelationshipTemplateContent.builder().value("value").build()) + .expiresAt(ZonedDateTime.now().plusDays(1)).build(); + } +} diff --git a/src/test/java/eu/enmeshed/RelationshipTest.java b/src/test/java/eu/enmeshed/RelationshipTest.java new file mode 100644 index 0000000..f9836e1 --- /dev/null +++ b/src/test/java/eu/enmeshed/RelationshipTest.java @@ -0,0 +1,99 @@ +package eu.enmeshed; + +import static org.hamcrest.MatcherAssert.assertThat; + +import eu.enmeshed.model.relationships.RelationshipAuditLogEntry.Reason; +import eu.enmeshed.model.relationships.RelationshipStatus; +import eu.enmeshed.utils.ConnectorContainer; +import eu.enmeshed.utils.TestUtils; +import org.hamcrest.CoreMatchers; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.testcontainers.junit.jupiter.Testcontainers; + +@Testcontainers +public class RelationshipTest { + + private ConnectorClient client1; + private ConnectorClient client2; + + @BeforeEach + public void setUp() { + // recreate containers before each test case due to relationships created in different tests interfered with each other + ConnectorContainer connector1 = new ConnectorContainer(); + ConnectorContainer connector2 = new ConnectorContainer(); + + connector1.start(); + connector2.start(); + + client1 = ConnectorClient.create(connector1.getConnectionString(), connector1.getApiKey()); + client2 = ConnectorClient.create(connector2.getConnectionString(), connector2.getApiKey()); + } + + @Test + public void shouldCreateRelationship() { + + var relationshipId = TestUtils.Relationships.establishRelationship(client1, client2).getId(); + + expectRelationshipToHaveStatus(client1, relationshipId, RelationshipStatus.ACTIVE); + expectRelationshipToHaveStatus(client2, relationshipId, RelationshipStatus.ACTIVE); + } + + @Test + public void rejectRelationship() { + + var relationshipId = TestUtils.Relationships.rejectRelationship(client1, client2).getId(); + + expectRelationshipToHaveStatus(client1, relationshipId, RelationshipStatus.REJECTED); + expectRelationshipToHaveStatus(client2, relationshipId, RelationshipStatus.REJECTED); + } + + @Test + public void revokeRelationship() { + + var relationshipId = TestUtils.Relationships.revokeRelationship(client1, client2).getId(); + + expectRelationshipToHaveStatus(client1, relationshipId, RelationshipStatus.REVOKED); + expectRelationshipToHaveStatus(client2, relationshipId, RelationshipStatus.REVOKED); + } + + @Test + public void terminateAndReactivateRelationship() { + + var relationshipId = TestUtils.Relationships.establishAndTerminateRelationship(client1, client2).getId(); + + expectRelationshipToHaveStatus(client1, relationshipId, RelationshipStatus.TERMINATED); + expectRelationshipToHaveStatus(client2, relationshipId, RelationshipStatus.TERMINATED); + + TestUtils.Relationships.reactivateRelationship(client1, client2, relationshipId); + expectRelationshipToHaveStatusAndReason(client1, relationshipId, RelationshipStatus.TERMINATED, Reason.REACTIVATION_REQUESTED); + expectRelationshipToHaveStatusAndReason(client2, relationshipId, RelationshipStatus.TERMINATED, Reason.REACTIVATION_REQUESTED); + + TestUtils.Relationships.rejectReactivationOfRelationship(client2, client1, relationshipId); + expectRelationshipToHaveStatusAndReason(client1, relationshipId, RelationshipStatus.TERMINATED, Reason.REJECTION_OF_REACTIVATION); + expectRelationshipToHaveStatusAndReason(client2, relationshipId, RelationshipStatus.TERMINATED, Reason.REJECTION_OF_REACTIVATION); + + TestUtils.Relationships.reactivateRelationship(client1, client2, relationshipId); + TestUtils.Relationships.revokeReactivationOfRelationship(client1, client2, relationshipId); + expectRelationshipToHaveStatusAndReason(client1, relationshipId, RelationshipStatus.TERMINATED, Reason.REVOCATION_OF_REACTIVATION); + expectRelationshipToHaveStatusAndReason(client2, relationshipId, RelationshipStatus.TERMINATED, Reason.REVOCATION_OF_REACTIVATION); + + TestUtils.Relationships.reactivateRelationship(client1, client2, relationshipId); + TestUtils.Relationships.acceptReactivationOfRelationship(client2, client1, relationshipId); + expectRelationshipToHaveStatusAndReason(client1, relationshipId, RelationshipStatus.ACTIVE, Reason.ACCEPTANCE_OF_REACTIVATION); + expectRelationshipToHaveStatusAndReason(client2, relationshipId, RelationshipStatus.ACTIVE, Reason.ACCEPTANCE_OF_REACTIVATION); + } + + private void expectRelationshipToHaveStatus(ConnectorClient client, String relationshipId, RelationshipStatus status) + { + var response = client.relationships.getRelationship(relationshipId).getResult(); + assertThat(response.getStatus(), CoreMatchers.equalTo(status)); + } + + private void expectRelationshipToHaveStatusAndReason(ConnectorClient client, String relationshipId, RelationshipStatus status, Reason reason) + { + var response = client.relationships.getRelationship(relationshipId).getResult(); + assertThat(response.getStatus(), CoreMatchers.equalTo(status)); + assertThat(response.getAuditLog().get(response.getAuditLog().size() - 1).getReason(), CoreMatchers.equalTo(reason)); + } +} diff --git a/src/test/java/eu/enmeshed/utils/TestUtils.java b/src/test/java/eu/enmeshed/utils/TestUtils.java index ef87c2f..1eff16a 100644 --- a/src/test/java/eu/enmeshed/utils/TestUtils.java +++ b/src/test/java/eu/enmeshed/utils/TestUtils.java @@ -8,6 +8,7 @@ import eu.enmeshed.model.relationships.RelationshipStatus; import eu.enmeshed.model.tokens.ConnectorToken; import eu.enmeshed.requests.relationshipTemplates.CreateOwnRelationshipTemplateRequest; +import eu.enmeshed.requests.relationshipTemplates.CreateTokenForOwnRelationshipTemplateRequest; import eu.enmeshed.requests.relationshipTemplates.LoadPeerRelationshipTemplateRequest; import eu.enmeshed.requests.relationships.CreateRelationshipRequest; import eu.enmeshed.requests.tokens.CreateOwnTokenRequest; @@ -17,64 +18,150 @@ public class TestUtils { - public static ConnectorRelationship establishRelationship(ConnectorClient client1, ConnectorClient client2) { - var template = exchangeTemplate(client1, client2); + public static class Relationships { - var creationContent = ArbitraryRelationshipCreationContent.builder().value("value").build(); - var createRelationshipResponse = client2.relationships.createRelationship( - CreateRelationshipRequest.builder().creationContent(creationContent).templateId(template.getId()).build()); + private static ConnectorRelationship createPendingRelationship(ConnectorClient client1, ConnectorClient client2) { - var relationship = syncUntilHasRelationshipInStatus(client1, createRelationshipResponse.getResult().getId(), RelationshipStatus.PENDING); + var template = RelationshipTemplates.exchangeTemplate(client1, client2); - var acceptResponse = client1.relationships.acceptRelationship(relationship.getId()); + var creationContent = ArbitraryRelationshipCreationContent.builder().value("value").build(); + var createRelationshipResponse = client2.relationships.createRelationship( + CreateRelationshipRequest.builder().creationContent(creationContent).templateId(template.getId()).build()); - return syncUntilHasRelationshipInStatus(client2, acceptResponse.getResult().getId(), RelationshipStatus.ACTIVE); - } + return syncUntilHasRelationshipInStatus(client1, createRelationshipResponse.getResult().getId(), RelationshipStatus.PENDING); + } - private static ConnectorRelationship syncUntilHasRelationshipInStatus(ConnectorClient client, String id, RelationshipStatus relationshipStatus) { - for (int i = 0; i < 10; i++) { - client.account.sync(); + public static ConnectorRelationship establishRelationship(ConnectorClient client1, ConnectorClient client2) { - var relationship = getRelationshipSafeById(client, id); - if (relationship == null) { - continue; - } + var relationship = createPendingRelationship(client1, client2); + var acceptResponse = client1.relationships.acceptRelationship(relationship.getId()); + + return syncUntilHasRelationshipInStatus(client2, acceptResponse.getResult().getId(), RelationshipStatus.ACTIVE); + } + + public static ConnectorRelationship rejectRelationship(ConnectorClient client1, ConnectorClient client2) { + + var relationship = Relationships.createPendingRelationship(client1, client2); + var rejectResponse = client1.relationships.rejectRelationship(relationship.getId()); + + return syncUntilHasRelationshipInStatus(client2, rejectResponse.getResult().getId(), RelationshipStatus.REJECTED); + } + + public static ConnectorRelationship revokeRelationship(ConnectorClient client1, ConnectorClient client2) { + + var relationship = Relationships.createPendingRelationship(client1, client2); + var revokeResponse = client2.relationships.revokeRelationship(relationship.getId()); + + return syncUntilHasRelationshipInStatus(client1, revokeResponse.getResult().getId(), RelationshipStatus.REVOKED); + } + + public static ConnectorRelationship establishAndTerminateRelationship(ConnectorClient client1, ConnectorClient client2) { + + var relationship = Relationships.establishRelationship(client1, client2); + client1.relationships.terminateRelationship(relationship.getId()); + + syncUntilHasRelationshipInStatus(client1, relationship.getId(), RelationshipStatus.TERMINATED); + syncUntilHasRelationshipInStatus(client2, relationship.getId(), RelationshipStatus.TERMINATED); + + return relationship; + } + + public static void reactivateRelationship(ConnectorClient client1, ConnectorClient client2, String relationshipId) { + + client1.relationships.requestRelationshipReactivation(relationshipId).getResult(); + + syncUntilHasRelationshipInStatus(client1, relationshipId, RelationshipStatus.TERMINATED); + syncUntilHasRelationshipInStatus(client2, relationshipId, RelationshipStatus.TERMINATED); + } + + public static void rejectReactivationOfRelationship(ConnectorClient rejectingClient, ConnectorClient peerClient, String relationshipId) { + rejectingClient.relationships.rejectRelationshipReactivation(relationshipId).getResult(); - if (relationship.getStatus() == relationshipStatus) { - return relationship; + syncUntilHasRelationshipInStatus(rejectingClient, relationshipId, RelationshipStatus.TERMINATED); + syncUntilHasRelationshipInStatus(peerClient, relationshipId, RelationshipStatus.TERMINATED); + } + + public static void revokeReactivationOfRelationship(ConnectorClient revokingClient, ConnectorClient peerClient, String relationshipId) { + revokingClient.relationships.revokeRelationshipReactivation(relationshipId).getResult(); + + syncUntilHasRelationshipInStatus(revokingClient, relationshipId, RelationshipStatus.TERMINATED); + syncUntilHasRelationshipInStatus(peerClient, relationshipId, RelationshipStatus.TERMINATED); + } + + public static void acceptReactivationOfRelationship(ConnectorClient acceptingClient, ConnectorClient peerClient, String relationshipId) { + acceptingClient.relationships.acceptRelationshipReactivation(relationshipId).getResult(); + + syncUntilHasRelationshipInStatus(acceptingClient, relationshipId, RelationshipStatus.ACTIVE); + syncUntilHasRelationshipInStatus(peerClient, relationshipId, RelationshipStatus.ACTIVE); + } + + private static ConnectorRelationship syncUntilHasRelationshipInStatus(ConnectorClient client, String id, RelationshipStatus relationshipStatus) { + for (int i = 0; i < 10; i++) { + client.account.sync(); + + var relationship = getRelationshipSafeById(client, id); + if (relationship == null) { + continue; + } + + if (relationship.getStatus() == relationshipStatus) { + return relationship; + } + + try { + Thread.sleep(1000 + (i * 200)); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } + throw new RuntimeException("Relationship " + id + " did not reach status " + relationshipStatus); + } + + private static ConnectorRelationship getRelationshipSafeById(ConnectorClient client, String id) { try { - Thread.sleep(1000 + (i * 200)); - } catch (InterruptedException e) { - throw new RuntimeException(e); + return client.relationships.getRelationship(id).getResult(); + } catch (Exception e) { + return null; } } - - throw new RuntimeException("Relationship " + id + " did not reach status " + relationshipStatus); } - private static ConnectorRelationship getRelationshipSafeById(ConnectorClient client, String id) { - try { - return client.relationships.getRelationship(id).getResult(); - } catch (Exception e) { - return null; + public static class RelationshipTemplates { + + public static RelationshipTemplate createTemplate(ConnectorClient client) { + return client.relationshipTemplates.createOwnRelationshipTemplate( + CreateOwnRelationshipTemplateRequest.builder() + .content(ArbitraryRelationshipTemplateContent.builder().value("value").build()) + .maxNumberOfAllocations(1) + .expiresAt(ZonedDateTime.now().plusDays(1)).build()).getResult(); } - } - public static RelationshipTemplate exchangeTemplate(ConnectorClient client1, ConnectorClient client2) { - var template = createTemplate(client1); + private static ConnectorToken createTemplateToken(ConnectorClient client, String templateId) { + return client.relationshipTemplates.createTokenForOwnRelationshipTemplate( + templateId, + CreateTokenForOwnRelationshipTemplateRequest.builder() + .expiresAt(ZonedDateTime.now().plusDays(1)) + .build()) + .getResult(); + } - var response = client2.relationshipTemplates.loadPeerRelationshipTemplate(new LoadPeerRelationshipTemplateRequest(template.getTruncatedReference())); - return response.getResult(); - } + private static void loadPeerRelationshipTemplate(ConnectorClient client, ConnectorToken token) { + client.relationshipTemplates.loadPeerRelationshipTemplate( + LoadPeerRelationshipTemplateRequest.builder() + .reference(token.getTruncatedReference()) + .build()) + .getResult(); + } - public static RelationshipTemplate createTemplate(ConnectorClient client) { - var template = client.relationshipTemplates.createOwnRelationshipTemplate( - CreateOwnRelationshipTemplateRequest.builder().content(ArbitraryRelationshipTemplateContent.builder().value("value").build()).expiresAt(ZonedDateTime.now().plusDays(1)) - .build()); + public static RelationshipTemplate exchangeTemplate(ConnectorClient clientCreator, ConnectorClient clientRecipient) { - return template.getResult(); + var template = createTemplate(clientCreator); + var templateToken = createTemplateToken(clientCreator, template.getId()); + loadPeerRelationshipTemplate(clientRecipient, templateToken); + + return template; + } } public static ConnectorToken exchangeToken(ConnectorClient client1, ConnectorClient client2) {