From 5582e236234e4674c1184994a219a62df0820b76 Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Tue, 4 Apr 2023 13:16:56 +0100 Subject: [PATCH 01/32] Incremented version to 0.03-SNAPSHOT --- README.md | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index be60c6c..737537f 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ The Fusion SDK is published to Maven Central and can be retrieved from there usi io.github.jpmorganchase.fusion fusion-sdk - 0.0.2 + 0.0.3 ``` diff --git a/pom.xml b/pom.xml index 9d1c84c..161fbb3 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.jpmorganchase.fusion fusion-sdk jar - 0.0.2 + 0.0.3-SNAPSHOT fusion-sdk A Java SDK for the Fusion platform API From 2f944fe3ccf1f146fa04cdcfd3214eb33635b25c Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Thu, 6 Apr 2023 10:30:03 +0100 Subject: [PATCH 02/32] feature/update usage examples (#30) * Added sdk usage examples * Additional examples and interface verifications fixes #19 --- README.md | 48 +++++-- .../FusionInstanceCreationExamples.java | 43 ------ .../FusionReadMeExampleVerification.java | 135 ++++++++++++++++++ 3 files changed, 175 insertions(+), 51 deletions(-) delete mode 100644 src/test/java/io/github/jpmorganchase/fusion/example/FusionInstanceCreationExamples.java create mode 100644 src/test/java/io/github/jpmorganchase/fusion/example/FusionReadMeExampleVerification.java diff --git a/README.md b/README.md index 737537f..37db6b0 100644 --- a/README.md +++ b/README.md @@ -38,8 +38,11 @@ Once you have the dependency added to your project and imports configured, you w ##### With an OAUth client ID and secret - -https://github.com/jpmorganchase/fusion-java-sdk/blob/3300f986bb55bf70ed0e36953c9834b8caa9960d/src/test/java/io/github/jpmorganchase/fusion/example/FusionInstanceCreationExamples.java#L35-L37 +```java +Fusion fusion = Fusion.builder() + .secretBasedCredentials(CLIENT_ID, CLIENT_SECRET, RESOURCE, AUTH_SERVER_URL) + .build(); +``` This will configure the SDK to retrieve a bearer token from an OAuth server using the supplied parameters: @@ -52,7 +55,9 @@ When configured in this way, the SDK will retrieve the token from the OAuth serv ##### Loading the OAuth configuration from a file -https://github.com/jpmorganchase/fusion-java-sdk/blob/3300f986bb55bf70ed0e36953c9834b8caa9960d/src/test/java/io/github/jpmorganchase/fusion/example/FusionInstanceCreationExamples.java#L43-L45 +```java +Fusion fusion = Fusion.builder().credentialFile(CREDENTIAL_FILE_PATH).build(); +``` This will configure the SDK to retrieve a bearer token from an OAuth server using configuration details stored in a file at the supplied path _CREDENTIAL_FILE_PATH_ @@ -79,7 +84,9 @@ Similar to the above option, this will configure the SDK to manage the tokens on ##### With a pre-existing bearer token -https://github.com/jpmorganchase/fusion-java-sdk/blob/3300f986bb55bf70ed0e36953c9834b8caa9960d/src/test/java/io/github/jpmorganchase/fusion/example/FusionInstanceCreationExamples.java#L28-L30 +```java +Fusion fusion = Fusion.builder().bearerToken(BEARER_TOKEN).build(); +``` Here _BEARER_TOKEN_ is the String value of a bearer token you have retrieved which provides access to the Fusion API. You can use this mechanism in cases where you already have a means to retrieve the token and would prefer to manage that within your application than having the SDK manage that on your behalf. @@ -89,11 +96,36 @@ Note than when your token has expired, you will need to pass a new token to the Once you have initialised the Fusion object, you can interact with it to retrieve metadata or download distribution files for any datasets that you need. -Examples (to follow): +##### Examples: -1. Download some metadata -2. Download as a file -3. Download as a stream +1. List catalogs +```java +Map catalogs = fusion.listCatalogs(); +``` +2. List datasets +```java +Map datasets = fusion.listDatasets("my-catalog"); +``` +3. Download some dataset metadata +```java +Map attributes = fusion.listAttributes("my-catalog", "my-dataset"); +``` +4. List the series members available in the dataset +```java +Map members = fusion.listDatasetMembers("my-catalog", "my-dataset"); +``` +5. List the distributions available in the dataset member +```java +Map distributions = fusion.listDistributions("my-catalog", "my-dataset", "my-series-member"); +``` +6. Download as a file +```java +fusion.download("my-catalog", "my-dataset", "my-series-member", "csv", "/downloads/distributions"); +``` +7. Download as a stream +```java +InputStream is = fusion.downloadStream("my-catalog", "my-dataset", "my-series-member", "csv"); +``` #### Logging diff --git a/src/test/java/io/github/jpmorganchase/fusion/example/FusionInstanceCreationExamples.java b/src/test/java/io/github/jpmorganchase/fusion/example/FusionInstanceCreationExamples.java deleted file mode 100644 index cd51de9..0000000 --- a/src/test/java/io/github/jpmorganchase/fusion/example/FusionInstanceCreationExamples.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.github.jpmorganchase.fusion.example; - -import io.github.jpmorganchase.fusion.Fusion; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -/** - * This class exists to allow us to have working code examples we can link to from documentation - * e.g. in the README.md for the repo. Having these as tests ensures they will not go out of date - * as the code changes. If you make changes to this class, please check the documentation still - * looks correct - * - * If there's a better way to do this we should discuss. This is a bit clunky - */ -public class FusionInstanceCreationExamples { - - private static final String BEARER_TOKEN = "bearer-token-value"; - - private static final String CLIENT_ID = "id"; - private static final String CLIENT_SECRET = "secret"; - private static final String RESOURCE = "resource"; - private static final String AUTH_SERVER_URL = "https://auth-server.domain.com/adfs/oauth2/token"; - - private static final String CREDENTIAL_FILE_PATH = ""; - - @Test - void createWithBearerToken() { - Fusion fusion = Fusion.builder().bearerToken(BEARER_TOKEN).build(); - } - - @Test - void createFromSecretBasedCredentials() { - Fusion fusion = Fusion.builder() - .secretBasedCredentials(CLIENT_ID, CLIENT_SECRET, RESOURCE, AUTH_SERVER_URL) - .build(); - } - - @Test - @Disabled("Disabling temporarily") - void loadCredentialsFromFile() { - Fusion fusion = Fusion.builder().credentialFile(CREDENTIAL_FILE_PATH).build(); - } -} diff --git a/src/test/java/io/github/jpmorganchase/fusion/example/FusionReadMeExampleVerification.java b/src/test/java/io/github/jpmorganchase/fusion/example/FusionReadMeExampleVerification.java new file mode 100644 index 0000000..f995928 --- /dev/null +++ b/src/test/java/io/github/jpmorganchase/fusion/example/FusionReadMeExampleVerification.java @@ -0,0 +1,135 @@ +package io.github.jpmorganchase.fusion.example; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.*; + +import io.github.jpmorganchase.fusion.Fusion; +import io.github.jpmorganchase.fusion.model.*; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +/** + * + * THIS IS NOT A TEST - it is purely to verify the contract that we have published on the README.md has not changed. + * If any of these tests break, please ensure you update the corresponding example in the README.md. + * + * If there's a better way to do this we should discuss. This is a bit clunky + * + */ +@ExtendWith(MockitoExtension.class) +public class FusionReadMeExampleVerification { + + private static final String BEARER_TOKEN = "bearer-token-value"; + private static final String CLIENT_ID = "id"; + private static final String CLIENT_SECRET = "secret"; + private static final String RESOURCE = "resource"; + private static final String AUTH_SERVER_URL = "https://auth-server.domain.com/adfs/oauth2/token"; + private static final String CREDENTIAL_FILE_PATH = ""; + + @Mock + private Fusion fusion; + + @Test + void createWithBearerToken() { + Fusion.builder().bearerToken(BEARER_TOKEN).build(); + } + + @Test + void createFromSecretBasedCredentials() { + Fusion.builder() + .secretBasedCredentials(CLIENT_ID, CLIENT_SECRET, RESOURCE, AUTH_SERVER_URL) + .build(); + } + + @Test + @Disabled("Disabling temporarily") + void loadCredentialsFromFile() { + Fusion.builder().credentialFile(CREDENTIAL_FILE_PATH).build(); + } + + @Test + void listCatalogs() { + Map catalogs = new HashMap<>(); + catalogs.put("my-catalog", Catalog.builder().build()); + + given(fusion.listCatalogs()).willReturn(catalogs); + assertThat( + "Fusion interface has changed, please correct README.md examples", + fusion.listCatalogs(), + is(notNullValue())); + } + + @Test + void listDatasets() { + Map datasets = new HashMap<>(); + datasets.put("my-dataset", Dataset.builder().build()); + + given(fusion.listDatasets("my-catalog")).willReturn(datasets); + assertThat( + "Fusion interface has changed, please correct README.md examples", + fusion.listDatasets("my-catalog"), + is(notNullValue())); + } + + @Test + void listAttributes() { + Map attributes = new HashMap<>(); + attributes.put("my-attributes", Attribute.builder().build()); + + given(fusion.listAttributes("my-catalog", "my-dataset")).willReturn(attributes); + assertThat( + "Fusion interface has changed, please correct README.md examples", + fusion.listAttributes("my-catalog", "my-dataset"), + is(notNullValue())); + } + + @Test + void listDatasetMembers() { + Map series = new HashMap<>(); + series.put("my-dataset-series", DatasetSeries.builder().build()); + + given(fusion.listDatasetMembers("my-catalog", "my-dataset")).willReturn(series); + assertThat( + "Fusion interface has changed, please correct README.md examples", + fusion.listDatasetMembers("my-catalog", "my-dataset"), + is(notNullValue())); + } + + @Test + void listDistributions() { + Map series = new HashMap<>(); + series.put("distributions", Distribution.builder().build()); + + given(fusion.listDistributions("my-catalog", "my-dataset", "my-series-member")) + .willReturn(series); + assertThat( + "Fusion interface has changed, please correct README.md examples", + fusion.listDistributions("my-catalog", "my-dataset", "my-series-member"), + is(notNullValue())); + } + + @Test + void downloadAsFile() { + fusion.download("my-catalog", "my-dataset", "my-series-member", "csv", "/downloads/distributions"); + verify(fusion, times(1)) + .download("my-catalog", "my-dataset", "my-series-member", "csv", "/downloads/distributions"); + } + + @Test + void downloadAsStream() { + given(fusion.downloadStream("my-catalog", "my-dataset", "my-series-member", "csv")) + .willReturn(mock(InputStream.class)); + assertThat( + "Fusion interface has changed, please correct README.md examples", + fusion.downloadStream("my-catalog", "my-dataset", "my-series-member", "csv"), + is(notNullValue())); + } +} From 205848b6bccb98608ca2e4d902b58c259e09011b Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Thu, 6 Apr 2023 17:23:08 +0100 Subject: [PATCH 03/32] Initial play with pact for contract testing --- pom.xml | 7 + .../pact/FusionApiConsumerPactTest.java | 88 +++++++++ src/it/resources/logback-test.xml | 21 +++ .../fusion_sdk_consumer-FusionProvider.json | 174 ++++++++++++++++++ src/test/resources/logback-test.xml | 2 +- 5 files changed, 291 insertions(+), 1 deletion(-) create mode 100644 src/it/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java create mode 100644 src/it/resources/logback-test.xml create mode 100644 src/it/resources/pact-examples/fusion_sdk_consumer-FusionProvider.json diff --git a/pom.xml b/pom.xml index 161fbb3..cfb3b9e 100644 --- a/pom.xml +++ b/pom.xml @@ -121,6 +121,13 @@ test + + au.com.dius.pact.consumer + junit5 + 4.1.41 + test + + diff --git a/src/it/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java b/src/it/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java new file mode 100644 index 0000000..802b586 --- /dev/null +++ b/src/it/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java @@ -0,0 +1,88 @@ +package io.github.jpmorganchase.fusion.pact; + + +import au.com.dius.pact.consumer.MockServer; +import au.com.dius.pact.consumer.dsl.PactDslJsonBody; +import au.com.dius.pact.consumer.dsl.PactDslWithProvider; +import au.com.dius.pact.consumer.junit5.PactConsumerTestExt; +import au.com.dius.pact.consumer.junit5.PactTestFor; +import au.com.dius.pact.core.model.RequestResponsePact; +import au.com.dius.pact.core.model.annotations.Pact; +import io.github.jpmorganchase.fusion.Fusion; +import io.github.jpmorganchase.fusion.model.Catalog; +import org.hamcrest.core.Is; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.util.Map; + +import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.MatcherAssert.assertThat; + +@Tag("integration") +@ExtendWith(PactConsumerTestExt.class) +public class FusionApiConsumerPactTest { + + private static final String FUSION_API_VERSION = "/v1/"; + private static final String USER_AGENT_VAL = "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60"; + private static final String BEARER_TOKEN = "my-bearer-token"; + private static final String AUTH_VAL = "Bearer " + BEARER_TOKEN; + + @Pact(provider = "FusionProvider", consumer = "fusion_sdk_consumer") + public RequestResponsePact catalogs(PactDslWithProvider builder) { + + PactDslJsonBody b = new PactDslJsonBody(); + + b.object("@context") + .stringType("@vocab", "https://www.w3.org/ns/dcat3.jsondld") + .stringType("@base", "https://fusion-api.test.aws.jpmchase.net/v1") + .closeObject() + .asBody() + .stringType("@id", "catalogs/") + .stringType("description", "A list of available catalogs") + .stringType("identifier", "catalogs") + .eachLike("resources") + .stringType("@id", "common") + .stringType("description", "A catalog of common data") + .stringType("identifier", "common") + .stringType("title", "Common data catalog") + .closeArray(); + + return builder + .given("a list of catalogs") + .uponReceiving("a request for available catalogs") + .path("/v1/catalogs") + .matchHeader("Authorization", AUTH_VAL) + .matchHeader("User-Agent", USER_AGENT_VAL) + .method("GET") + .willRespondWith() + .status(200) + .body(b) + .toPact(); + } + + @Test + @PactTestFor(pactMethod = "catalogs") + void testListCatalogs(MockServer mockServer) { + + Fusion fusion = Fusion.builder().rootURL(mockServer.getUrl() + FUSION_API_VERSION).bearerToken("my-bearer-token").build(); + + Map catalogs = fusion.listCatalogs(); + assertThat("Catalogs must not be empty", catalogs, Is.is(notNullValue())); + + assertThat("Expected catalog is missing", catalogs.containsKey("common"), is(true)); + + Catalog catalog = catalogs.get("common"); + assertThat("Expected catalog is null", catalog, is(notNullValue())); + assertThat("Expected catalog identifier to match", catalog.getIdentifier(), is(equalTo("common"))); + assertThat("Expected catalog title to match", catalog.getTitle(), is(equalTo("Common data catalog"))); + assertThat("Expected catalog description to match", catalog.getDescription(), is(equalTo("A catalog of common data"))); + assertThat("Expected catalog LinkedEntity to match", catalog.getLinkedEntity(), is(equalTo("common"))); + + } + + + + +} diff --git a/src/it/resources/logback-test.xml b/src/it/resources/logback-test.xml new file mode 100644 index 0000000..809380a --- /dev/null +++ b/src/it/resources/logback-test.xml @@ -0,0 +1,21 @@ + + + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%kvp- %msg%n + + + + + + + + + + + + \ No newline at end of file diff --git a/src/it/resources/pact-examples/fusion_sdk_consumer-FusionProvider.json b/src/it/resources/pact-examples/fusion_sdk_consumer-FusionProvider.json new file mode 100644 index 0000000..da9f89b --- /dev/null +++ b/src/it/resources/pact-examples/fusion_sdk_consumer-FusionProvider.json @@ -0,0 +1,174 @@ +{ + "provider": { + "name": "FusionProvider" + }, + "consumer": { + "name": "fusion_sdk_consumer" + }, + "interactions": [ + { + "description": "a request for available catalogs", + "request": { + "method": "GET", + "path": "/v1/catalogs", + "headers": { + "Authorization": "Bearer my-bearer-token", + "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + }, + "User-Agent": { + "matchers": [ + { + "match": "regex", + "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json; charset=UTF-8" + }, + "body": { + "identifier": "catalogs", + "description": "A list of available catalogs", + "resources": [ + { + "identifier": "common", + "description": "A catalog of common data", + "@id": "common", + "title": "Common data catalog" + } + ], + "@id": "catalogs/", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + } + }, + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json(;\\s?charset=[\\w\\-]+)?" + } + ], + "combine": "AND" + } + } + } + }, + "providerStates": [ + { + "name": "a list of catalogs" + } + ] + } + ], + "metadata": { + "pactSpecification": { + "version": "3.0.0" + }, + "pact-jvm": { + "version": "4.1.41" + } + } +} diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index d2ac40a..23e68cc 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -11,7 +11,7 @@ - + From e46eef3c694d4c2132adb43abf64fc7ecf5d2fb6 Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Thu, 20 Apr 2023 16:10:30 +0100 Subject: [PATCH 04/32] Added PACT consumer tests --- .gitignore | 1 + pom.xml | 15 + .../pact/FusionApiConsumerPactTest.java | 329 ++- .../pact/FusionUploadConsumerPactTest.java | 146 ++ .../fusion/pact/util/BodyBuilders.java | 197 ++ .../fusion/pact/util/FileHelper.java | 26 + .../pact/util/RequestResponseHelper.java | 63 + .../pact-examples/FusionSdk-FusionApi.json | 2327 +++++++++++++++++ .../pact-examples/FusionSdk-FusionUpload.json | 85 + .../fusion_sdk_consumer-FusionProvider.json | 174 -- .../github/jpmorganchase/fusion/Fusion.java | 12 +- 11 files changed, 3159 insertions(+), 216 deletions(-) create mode 100644 src/it/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java create mode 100644 src/it/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java create mode 100644 src/it/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java create mode 100644 src/it/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java create mode 100644 src/it/resources/pact-examples/FusionSdk-FusionApi.json create mode 100644 src/it/resources/pact-examples/FusionSdk-FusionUpload.json delete mode 100644 src/it/resources/pact-examples/fusion_sdk_consumer-FusionProvider.json diff --git a/.gitignore b/.gitignore index 901e6d8..8df7f8e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ **/localAuthCredential.json **/client_credentials.json .vscode +.DS_Store diff --git a/pom.xml b/pom.xml index cfb3b9e..739a835 100644 --- a/pom.xml +++ b/pom.xml @@ -296,6 +296,21 @@ + + + package + + jar + + + pact + ${project.build.directory}/pacts + + **/* + + + + org.apache.maven.plugins diff --git a/src/it/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java b/src/it/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java index 802b586..5977b14 100644 --- a/src/it/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java +++ b/src/it/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java @@ -2,71 +2,101 @@ import au.com.dius.pact.consumer.MockServer; -import au.com.dius.pact.consumer.dsl.PactDslJsonBody; import au.com.dius.pact.consumer.dsl.PactDslWithProvider; import au.com.dius.pact.consumer.junit5.PactConsumerTestExt; import au.com.dius.pact.consumer.junit5.PactTestFor; import au.com.dius.pact.core.model.RequestResponsePact; import au.com.dius.pact.core.model.annotations.Pact; import io.github.jpmorganchase.fusion.Fusion; -import io.github.jpmorganchase.fusion.model.Catalog; +import io.github.jpmorganchase.fusion.model.*; +import io.github.jpmorganchase.fusion.pact.util.FileHelper; +import lombok.SneakyThrows; import org.hamcrest.core.Is; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.LocalDate; import java.util.Map; +import static io.github.jpmorganchase.fusion.pact.util.BodyBuilders.*; +import static io.github.jpmorganchase.fusion.pact.util.RequestResponseHelper.downloadExpectation; +import static io.github.jpmorganchase.fusion.pact.util.RequestResponseHelper.getExpectation; import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; -@Tag("integration") @ExtendWith(PactConsumerTestExt.class) public class FusionApiConsumerPactTest { private static final String FUSION_API_VERSION = "/v1/"; - private static final String USER_AGENT_VAL = "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60"; - private static final String BEARER_TOKEN = "my-bearer-token"; - private static final String AUTH_VAL = "Bearer " + BEARER_TOKEN; - - @Pact(provider = "FusionProvider", consumer = "fusion_sdk_consumer") - public RequestResponsePact catalogs(PactDslWithProvider builder) { - - PactDslJsonBody b = new PactDslJsonBody(); - - b.object("@context") - .stringType("@vocab", "https://www.w3.org/ns/dcat3.jsondld") - .stringType("@base", "https://fusion-api.test.aws.jpmchase.net/v1") - .closeObject() - .asBody() - .stringType("@id", "catalogs/") - .stringType("description", "A list of available catalogs") - .stringType("identifier", "catalogs") - .eachLike("resources") - .stringType("@id", "common") - .stringType("description", "A catalog of common data") - .stringType("identifier", "common") - .stringType("title", "Common data catalog") - .closeArray(); - - return builder - .given("a list of catalogs") - .uponReceiving("a request for available catalogs") - .path("/v1/catalogs") - .matchHeader("Authorization", AUTH_VAL) - .matchHeader("User-Agent", USER_AGENT_VAL) - .method("GET") - .willRespondWith() - .status(200) - .body(b) - .toPact(); + + Fusion fusion; + InputStream downloadedFileInputStream; + + @Pact(provider = "FusionApi", consumer = "FusionSdk") + public RequestResponsePact listCatalogs(PactDslWithProvider builder) { + return getExpectation(builder, "a list of catalogs", "a request for available catalogs", "/v1/catalogs", catalogs()); + } + + @Pact(provider = "FusionApi", consumer = "FusionSdk") + public RequestResponsePact getCatalogResources(PactDslWithProvider builder) { + return getExpectation(builder, "a list of catalogs resources", "a request for catalogs resources", "/v1/catalogs/common", catalogResources()); + } + + @Pact(provider = "FusionApi", consumer = "FusionSdk") + public RequestResponsePact listProducts(PactDslWithProvider builder) { + return getExpectation(builder, "a list of data products", "a request for a list of data products", "/v1/catalogs/common/products", products()); + } + + @Pact(provider = "FusionApi", consumer = "FusionSdk") + public RequestResponsePact listDatasets(PactDslWithProvider builder) { + return getExpectation(builder, "a list of datasets", "a request for a list of datasets", "/v1/catalogs/common/datasets", datasets()); + } + + @Pact(provider = "FusionApi", consumer = "FusionSdk") + public RequestResponsePact getDatasetResources(PactDslWithProvider builder) { + return getExpectation(builder, "a dataset resource", "a request for a dataset resource", "/v1/catalogs/common/datasets/GFI_OP_CF", datasetResource()); + } + + @Pact(provider = "FusionApi", consumer = "FusionSdk") + public RequestResponsePact listDatasetMembers(PactDslWithProvider builder) { + return getExpectation(builder, "a list of series members for a dataset", "a request for a list of series members of a dataset", "/v1/catalogs/common/datasets/API_TEST/datasetseries", datasetMembers()); + } + @Pact(provider = "FusionApi", consumer = "FusionSdk") + public RequestResponsePact getDatasetMemberResources(PactDslWithProvider builder) { + return getExpectation(builder, "metadata for a dataset series member", "a request dataset series member metadata", "/v1/catalogs/common/datasets/API_TEST/datasetseries/20230319", datasetMemberResources()); + } + @Pact(provider = "FusionApi", consumer = "FusionSdk") + public RequestResponsePact listAttributes(PactDslWithProvider builder) { + return getExpectation(builder, "a list of attributes for a dataset in a catalog", "a request for a list of attributes from a dataset", "/v1/catalogs/common/datasets/API_TEST/attributes", attributes()); + } + + @Pact(provider = "FusionApi", consumer = "FusionSdk") + public RequestResponsePact listDistributions(PactDslWithProvider builder) { + return getExpectation(builder, "a list of distributions available for a series member", "a request for distributions available for a series member", "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220116/distributions", distributions()); + } + + @Pact(provider = "FusionApi", consumer = "FusionSdk") + public RequestResponsePact download(PactDslWithProvider builder) { + return downloadExpectation(builder, "a distribution that is available for download", "a request is made to download the distribution", "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220116/distributions/csv", "A,B,C"); + } + + @AfterEach + @SneakyThrows + public void cleanupDirectory(){ + Files.deleteIfExists(Paths.get("downloads/common_API_TEST_20220116.csv")); } @Test - @PactTestFor(pactMethod = "catalogs") + @PactTestFor(pactMethod = "listCatalogs") void testListCatalogs(MockServer mockServer) { - Fusion fusion = Fusion.builder().rootURL(mockServer.getUrl() + FUSION_API_VERSION).bearerToken("my-bearer-token").build(); + givenInstanceOfFusionSdk(mockServer); Map catalogs = fusion.listCatalogs(); assertThat("Catalogs must not be empty", catalogs, Is.is(notNullValue())); @@ -82,7 +112,226 @@ void testListCatalogs(MockServer mockServer) { } + @Test + @PactTestFor(pactMethod = "getCatalogResources") + void testCatalogResources(MockServer mockServer) { + + givenInstanceOfFusionSdk(mockServer); + + Map> resources = fusion.catalogResources("common"); + assertThat("Catalog resources must not be empty", resources, Is.is(notNullValue())); + + assertThat("Catalog resource missing resources", resources.size(), greaterThanOrEqualTo(1)); + + resources.keySet().forEach(key -> { + assertThat("Catalog resource missing resource", resources.containsKey(key), is(true)); + + Map dataset = resources.get(key); + assertThat("resource @id is missing from resource", dataset.containsKey("@id"), is(true)); + assertThat("resource description is missing from resource", dataset.containsKey("description"), is(true)); + assertThat("resource identifier is missing from resource", dataset.containsKey("identifier"), is(true)); + assertThat("resource title is missing from resource", dataset.containsKey("title"), is(true)); + }); + + } + + @Test + @PactTestFor(pactMethod = "listProducts") + void testListProducts(MockServer mockServer) { + + givenInstanceOfFusionSdk(mockServer); + + Map products = fusion.listProducts("common"); + assertThat("Products must not be empty", products, Is.is(notNullValue())); + assertThat("Data Products Missing", products.get("ESG00008"), is(notNullValue())); + + DataProduct dataProduct = products.get("ESG00008"); + assertThat("data product description incorrect", dataProduct.getDescription(), is(equalTo("MSCI ESG Description"))); + assertThat("data product linkedEntity is incorrect", dataProduct.getLinkedEntity(), is(equalTo("ESG00008/"))); + assertThat("data product title is incorrect", dataProduct.getTitle(), is(equalTo("MSCI ESG Ratings"))); + assertThat("data product status is incorrect", dataProduct.getStatus(), is(equalTo("Available"))); + assertThat("data product identifier is incorrect", dataProduct.getIdentifier(), is(equalTo("ESG00008"))); + + } + + @Test + @PactTestFor(pactMethod = "listDatasets") + void testListDatasets(MockServer mockServer) { + + givenInstanceOfFusionSdk(mockServer); + + Map datasets = fusion.listDatasets("common"); + assertThat("Datasets must not be empty", datasets, Is.is(notNullValue())); + assertThat("Dataset Missing", datasets.get("GFI_OP_CF"), is(notNullValue())); + + Dataset dataset = datasets.get("GFI_OP_CF"); + assertThat("dataset description incorrect", dataset.getDescription(), is(equalTo("Premium, volatility, and greeks for EUR"))); + assertThat("dataset linkedEntity is incorrect", dataset.getLinkedEntity(), is(equalTo("GFI_OP_CF/"))); + assertThat("dataset title is incorrect", dataset.getTitle(), is(equalTo("Swaptions Caps & Floors"))); + assertThat("dataset identifier is incorrect", dataset.getIdentifier(), is(equalTo("GFI_OP_CF"))); + assertThat("dataset frequency is incorrect", dataset.getFrequency(), is(equalTo("Daily"))); + + } + + @Test + @PactTestFor(pactMethod = "getDatasetResources") + void testDatasetResources(MockServer mockServer) { + + givenInstanceOfFusionSdk(mockServer); + + Map> datasetResources = fusion.datasetResources("common", "GFI_OP_CF"); + + assertThat("dataset resources must not be empty", datasetResources, Is.is(notNullValue())); + assertThat("dataset resources expected to contain key", datasetResources.containsKey("datasetseries"), is(true)); + + Map resource = datasetResources.get("datasetseries"); + assertThat("dataset resource @id is incorrect", resource.get("@id"), is(equalTo("datasetseries/"))); + assertThat("dataset resource description is incorrect", resource.get("description"), is(equalTo("A list of available datasetseries of a dataset"))); + assertThat("dataset resource identifier is incorrect", resource.get("identifier"), is(equalTo("datasetseries"))); + assertThat("dataset resource title is incorrect", resource.get("title"), is(equalTo("Datasetseries"))); + + } + @Test + @PactTestFor(pactMethod = "listDatasetMembers") + void testListDatasetMembers(MockServer mockServer) { + + givenInstanceOfFusionSdk(mockServer); + + Map datasetMembers = fusion.listDatasetMembers("common", "API_TEST"); + assertThat("list of dataset members should not be null", datasetMembers, Is.is(notNullValue())); + + DatasetSeries series = datasetMembers.get("20230319"); + assertThat("dataset series @id is incorrect", series.getIdentifier(), is(equalTo("20230319"))); + assertThat("dataset series linked entity is incorrect", series.getLinkedEntity(), is(equalTo("20230319/"))); + assertThat("dataset series createdDate is incorrect", series.getCreatedDate(), is(equalTo(LocalDate.of(2023, 3, 19)))); + assertThat("dataset series fromDate is incorrect", series.getFromDate(), is(equalTo(LocalDate.of(2023, 3, 18)))); + assertThat("dataset series toDate is incorrect", series.getToDate(), is(equalTo(LocalDate.of(2023, 3, 17)))); + + } + + @Test + @PactTestFor(pactMethod = "getDatasetMemberResources") + void testDatasetMemberResources(MockServer mockServer) { + + givenInstanceOfFusionSdk(mockServer); + + Map> datasetMemberResources = fusion.datasetMemberResources("common", "API_TEST", "20230319"); + + assertThat("dataset member resources must not be empty", datasetMemberResources, Is.is(notNullValue())); + assertThat("dataset resources expected to contain key", datasetMemberResources.containsKey("distributions"), is(true)); + + Map resource = datasetMemberResources.get("distributions"); + assertThat("dataset resource @id is incorrect", resource.get("@id"), is(equalTo("distributions/"))); + assertThat("dataset resource description is incorrect", resource.get("description"), is(equalTo("A list of available distributions"))); + assertThat("dataset resource identifier is incorrect", resource.get("identifier"), is(equalTo("distributions"))); + assertThat("dataset resource title is incorrect", resource.get("title"), is(equalTo("Distributions"))); + + } + @Test + @PactTestFor(pactMethod = "listAttributes") + void testListAttributes(MockServer mockServer) { + + givenInstanceOfFusionSdk(mockServer); + + Map attributes = fusion.listAttributes("common", "API_TEST"); + + assertThat("attributes must not be empty", attributes, Is.is(notNullValue())); + assertThat("attributes expected to contain key", attributes.containsKey("A"), is(true)); + + Attribute attribute = attributes.get("A"); + assertThat("attribute identifier is incorrect", attribute.getIdentifier(), is(equalTo("A"))); + assertThat("attribute description is incorrect", attribute.getDescription(), is(equalTo("Description for attribute A"))); + assertThat("attribute title is incorrect", attribute.getTitle(), is(equalTo("A"))); + assertThat("attribute index is incorrect", attribute.getIndex(), is(equalTo(1L))); + assertThat("attribute dataType is incorrect", attribute.getDataType(), is(equalTo("String"))); + } + + @Test + @PactTestFor(pactMethod = "listAttributes") + void testListAttributeResources(MockServer mockServer) { + + givenInstanceOfFusionSdk(mockServer); + + Map> resources = fusion.attributeResources("common", "API_TEST"); + + assertThat("attribute resources must not be empty", resources, Is.is(notNullValue())); + assertThat("attribute resources expected to contain key", resources.containsKey("A"), is(true)); + + Map resource = resources.get("A"); + assertThat("attribute resource id is incorrect", resource.get("id"), is(equalTo("4000003"))); + assertThat("attribute resource identifier is incorrect", resource.get("identifier"), is(equalTo("A"))); + assertThat("attribute resource source is incorrect", resource.get("source"), is(equalTo("Data Query"))); + assertThat("attribute resource dataType is incorrect", resource.get("dataType"), is(equalTo("String"))); + assertThat("attribute resource description is incorrect", resource.get("description"), is(equalTo("Description for attribute A"))); + //TODO : Query - gson seems to translate our index integer as a double + assertThat("attribute resource index is incorrect", resource.get("index"), is(equalTo(1.0))); + assertThat("attribute resource isDatasetKey is incorrect", resource.get("isDatasetKey"), is(false)); + assertThat("attribute resource sourceFieldId is incorrect", resource.get("sourceFieldId"), is(equalTo("a_source_field"))); + assertThat("attribute resource title is incorrect", resource.get("title"), is(equalTo("A"))); + + } + + @Test + @PactTestFor(pactMethod = "listDistributions") + void testListDistributions(MockServer mockServer) { + + givenInstanceOfFusionSdk(mockServer); + + Map distributions = fusion.listDistributions("common", "API_TEST", "20220116"); + + assertThat("distributions must not be empty", distributions, Is.is(notNullValue())); + assertThat("distributions expected to contain key", distributions.containsKey("csv"), is(true)); + + Distribution distribution = distributions.get("csv"); + assertThat("distribution identifier is incorrect", distribution.getIdentifier(), is(equalTo("csv"))); + assertThat("distribution description is incorrect", distribution.getDescription(), is(equalTo("Snapshot data, in tabular, csv format"))); + assertThat("distribution @id is incorrect", distribution.getLinkedEntity(), is(equalTo("csv/"))); + assertThat("distribution title is incorrect", distribution.getTitle(), is(equalTo("CSV"))); + assertThat("distribution fileExtension is incorrect", distribution.getFileExtension(), is(equalTo(".csv"))); + assertThat("distribution mediaType is incorrect", distribution.getMediaType(), is(equalTo("text/csv; header=present; charset=utf-8"))); + } + + @Test + @SneakyThrows + @PactTestFor(pactMethod = "download") + void testDownload(MockServer mockServer) { + + givenInstanceOfFusionSdk(mockServer); + + fusion.download("common", "API_TEST", "20220116", "csv"); + + thenTheFileShouldBeDownloaded("downloads/common_API_TEST_20220116.csv"); + thenTheFileContentsShouldBeEqualTo("A,B,C"); + } + + @Test + @PactTestFor(pactMethod = "download") + void testDownloadStream(MockServer mockServer) { + + givenInstanceOfFusionSdk(mockServer); + + + downloadedFileInputStream = fusion.downloadStream("common", "API_TEST", "20220116", "csv"); + + thenTheFileContentsShouldBeEqualTo("A,B,C"); + } + @SneakyThrows + private void thenTheFileContentsShouldBeEqualTo(String expected) { + String actual = FileHelper.readContentsFromStream(downloadedFileInputStream); + assertThat("download file does not match expected", actual, is(equalTo(expected))); + } + + @SneakyThrows + private void thenTheFileShouldBeDownloaded(String path){ + downloadedFileInputStream = Files.newInputStream(Paths.get(path)); + assertThat("downloaded file is unavailable", downloadedFileInputStream.available(), is(greaterThanOrEqualTo(1))); + } + + private void givenInstanceOfFusionSdk(MockServer mockServer) { + fusion = Fusion.builder().rootURL(mockServer.getUrl() + FUSION_API_VERSION).bearerToken("my-bearer-token").build(); + } + } diff --git a/src/it/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java b/src/it/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java new file mode 100644 index 0000000..0cf59f6 --- /dev/null +++ b/src/it/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java @@ -0,0 +1,146 @@ +package io.github.jpmorganchase.fusion.pact; + + +import au.com.dius.pact.consumer.MockServer; +import au.com.dius.pact.consumer.dsl.PactDslWithProvider; +import au.com.dius.pact.consumer.junit5.PactConsumerTestExt; +import au.com.dius.pact.consumer.junit5.PactTestFor; +import au.com.dius.pact.core.model.RequestResponsePact; +import au.com.dius.pact.core.model.annotations.Pact; +import io.github.jpmorganchase.fusion.Fusion; +import io.github.jpmorganchase.fusion.model.*; +import io.github.jpmorganchase.fusion.oauth.provider.DatasetTokenProvider; +import io.github.jpmorganchase.fusion.pact.util.FileHelper; +import lombok.SneakyThrows; +import org.hamcrest.core.Is; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.io.ByteArrayInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDate; +import java.util.HashMap; +import java.util.Map; + +import static io.github.jpmorganchase.fusion.pact.util.BodyBuilders.*; +import static io.github.jpmorganchase.fusion.pact.util.RequestResponseHelper.*; +import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; + +@ExtendWith(PactConsumerTestExt.class) +public class FusionUploadConsumerPactTest { + + private static final String FUSION_API_VERSION = "/v1/"; + + Fusion fusion; + + @Pact(provider = "FusionUpload", consumer = "FusionSdk") + public RequestResponsePact uploadFile(PactDslWithProvider builder) { + + Map uploadHeaders = givenUploadHeaders("2022-01-15", "2022-01-16", "2022-01-17", "5", "KPD9WTOuUoQrDwpugLaHblJS+OdUnXaML3YWXla28Rg="); + return uploadExpectation( + builder, + "a distribution that is available for download", + "a request is made to download the distribution", + "/v1/catalogs/common/datasets/API_TEST/authorize/token", + "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220117/distributions/csv", + uploadHeaders, "A,B,C"); + } + + @Pact(provider = "FusionUpload", consumer = "FusionSdk") + public RequestResponsePact uploadStream(PactDslWithProvider builder) { + + Map uploadHeaders = givenUploadHeaders("2022-01-16", "2022-01-16", "2022-01-17", "5", "KPD9WTOuUoQrDwpugLaHblJS+OdUnXaML3YWXla28Rg="); + return uploadExpectation( + builder, + "a distribution that is available for download", + "a request is made to download the distribution", + "/v1/catalogs/common/datasets/API_TEST/authorize/token", + "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220117/distributions/csv", + uploadHeaders, "A,B,C"); + } + + @AfterEach + @SneakyThrows + public void cleanupDirectory(){ + Files.deleteIfExists(Paths.get("downloads/common_API_TEST_20220117.csv")); + } + + @Test + @SneakyThrows + @PactTestFor(pactMethod = "uploadFile") + void testUploadFile(MockServer mockServer){ + + givenInstanceOfFusionSdk(mockServer); + givenFileReadForUpload("/common_API_TEST_20220117.csv", "A,B,C"); + + + Assertions.assertDoesNotThrow( + () -> fusion.upload( + "common", + "API_TEST", + "20220117", + "csv", + "downloads/common_API_TEST_20220117.csv", + LocalDate.of(2022, 1, 15), + LocalDate.of(2022, 1, 16), + LocalDate.of(2022, 1, 17)) + ); + } + + @Test + @PactTestFor(pactMethod = "uploadStream") + void testUploadStream(MockServer mockServer){ + givenInstanceOfFusionSdk(mockServer); + + Assertions.assertDoesNotThrow(() -> fusion.upload( + "common", + "API_TEST", + "20220117", + "csv", + new ByteArrayInputStream("A,B,C".getBytes()), + LocalDate.of(2022, 1, 16), + LocalDate.of(2022, 1, 16), + LocalDate.of(2022, 1, 17) + )); + + } + + private static void givenFileReadForUpload(String fileName, String body) throws IOException { + Path downloadsPath = Files.createDirectories(Paths.get("downloads")); + FileOutputStream fos = new FileOutputStream(downloadsPath.toString() + "/" + fileName); + fos.write(body.getBytes()); + fos.close(); + } + + private void givenInstanceOfFusionSdk(MockServer mockServer) { + fusion = Fusion.builder() + .rootURL(mockServer.getUrl() + FUSION_API_VERSION) + .bearerToken("my-bearer-token") + .datasetTokenProvider((catalog, dataset) -> "my-fusion-bearer") + .build(); + } + + private static Map givenUploadHeaders(String fromDate, String toDate, String cDate, String length, String digest) { + Map uploadHeaders = new HashMap<>(); + uploadHeaders.put("x-jpmc-distribution-from-date", fromDate); + uploadHeaders.put("x-jpmc-distribution-to-date", toDate); + uploadHeaders.put("x-jpmc-distribution-created-date", cDate); + uploadHeaders.put("Content-Length", length); + uploadHeaders.put("Digest", "SHA-256=" + digest); + return uploadHeaders; + } + + +} diff --git a/src/it/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java b/src/it/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java new file mode 100644 index 0000000..c059742 --- /dev/null +++ b/src/it/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java @@ -0,0 +1,197 @@ +package io.github.jpmorganchase.fusion.pact.util; + +import au.com.dius.pact.consumer.dsl.DslPart; +import au.com.dius.pact.consumer.dsl.PactDslJsonBody; +import lombok.SneakyThrows; + +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.util.Date; + +import static au.com.dius.pact.consumer.dsl.PactDslJsonRootValue.stringType; + +/** + * These bodies exist to support the tests contained in {@link io.github.jpmorganchase.fusion.pact.FusionApiConsumerPactTest}. + * It should be noted that any change to the bodies defined could have an adverse effect on the corresponding tests. + */ +public class BodyBuilders { + + private BodyBuilders() {} + + public static DslPart catalogs(){ + return header("catalogs/", "A list of available catalogs, catalogs", "catalogs", "Catalogs") + .eachLike("resources") + .stringType("@id", "common") + .stringType("description", "A catalog of common data") + .stringType("identifier", "common") + .stringType("title", "Common data catalog") + .closeArray(); + } + + public static DslPart catalogResources() { + return header("common", "A catalog of common data", "common", "Common data catalog") + .minArrayLike("resources", 1) + .stringType("@id", "datasets/") + .stringType("description", "A list of available datasets (for access or download in one or more formats)") + .stringType("identifier", "datasets") + .stringType("title", "Datasets") + .closeArray(); + } + + public static DslPart products() { + return header("products/", "A list of available products", "products", "Products") + .minArrayLike("resources", 1) + .minArrayLike("category", 0, stringType()) + .integerType("datasetCount", 18) + .minArrayLike("deliveryChannel", 0, stringType()) + .stringType("description", "MSCI ESG Description") + .stringType("identifier", "ESG00008") + .booleanType("isActive", true) + .minArrayLike("maintainer", 0, stringType()) + .stringType("publisher", "J.P. Morgan") + .minArrayLike("region", 0, stringType()) + .date("releaseDate", "yyyy-MM-dd", Date.from(Instant.now())) + .stringType("shortAbstract", "A robust ESG integration tool") + .stringType("status", "Available") + .minArrayLike("subCategory", 0, stringType()) + .minArrayLike("tag", 0, stringType()) + .stringType("theme", "ESG") + .stringType("title", "MSCI ESG Ratings") + .booleanType("isRestricted", true) + .stringType("@id", "ESG00008/") + .closeArray(); + } + + public static DslPart datasets() { + return header("datasets/", "A list of available datasets", "datasets", "Datasets") + .minArrayLike("resources", 1) + .minArrayLike("category", 0, stringType()) + .date("createdDate", "yyyy-MM-dd", Date.from(Instant.now())) + .stringType("description", "Premium, volatility, and greeks for EUR") + .stringType("frequency", "Daily") + .stringType("identifier", "GFI_OP_CF") + .booleanType("isThirdPartyData", false) + .booleanType("isInternalOnlyDataset", false) + .stringType("language", "English") + .stringType("maintainer", "J.P. Morgan DM Rates Research") + .date("modifiedDate", "yyyy-MM-dd", Date.from(Instant.now())) + .stringType("publisher", "J.P. Morgan") + .minArrayLike("region", 0, stringType()) + .minArrayLike("source", 0, stringType()) + .minArrayLike("subCategory", 0, stringType()) + .stringType("title", "Swaptions Caps & Floors") + .minArrayLike("tag", 0, stringType()) + .booleanType("isRestricted", false) + .booleanType("isRawData", false) + .booleanType("hasSample", false) + .stringType("@id", "GFI_OP_CF/") + .closeArray(); + } + + public static DslPart datasetResource() { + return header("GFI_OP_CF/", "Premium, volatility, and greeks for EUR", "GFI_OP_CF", "Swaptions Caps & Floors") + .minArrayLike("resources", 1) + .stringType("@id", "datasetseries/") + .stringType("description", "A list of available datasetseries of a dataset") + .stringType("identifier", "datasetseries") + .stringType("title", "Datasetseries") + .closeArray() + .asBody() + .minArrayLike("category", 0, stringType()) + .date("createdDate", "yyyy-MM-dd", Date.from(Instant.now())) + .stringType("frequency", "Daily") + .booleanType("isThirdPartyData", false) + .booleanType("isInternalOnlyDataset", false) + .stringType("language", "English") + .stringType("maintainer", "J.P. Morgan DM Rates Research") + .date("modifiedDate", "yyyy-MM-dd", Date.from(Instant.now())) + .stringType("publisher", "J.P. Morgan") + .minArrayLike("region", 0, stringType()) + .minArrayLike("source", 0, stringType()) + .minArrayLike("subCategory", 0, stringType()) + .minArrayLike("tag", 0, stringType()) + .booleanType("isRestricted", false) + .booleanType("isRawData", false) + .booleanType("hasSample", false); + } + + public static DslPart datasetMembers() { + + return header("datasetseries/", "A list of available datasetseries of a dataset", "datasetseries", "DatasetSeries") + .minArrayLike("resources", 1) + .date("createdDate", "yyyy-MM-dd", asDate("2023-03-19")) + .date("fromDate", "yyyy-MM-dd", asDate("2023-03-18")) + .date("toDate", "yyyy-MM-dd", asDate("2023-03-17")) + .stringType("identifier", "20230319") + .stringType("@id", "20230319/") + .closeArray(); + } + + public static DslPart datasetMemberResources() { + + PactDslJsonBody b = new PactDslJsonBody(); + return b.object("@context") + .stringType("@vocab", "https://www.w3.org/ns/dcat3.jsondld") + .stringType("@base", "https://fusion-api.test.aws.jpmchase.net/v1") + .closeObject().asBody() + .stringType("@id", "20230319/") + .stringType("identifier", "20230319") + .minArrayLike("resources", 1) + .stringType("@id", "distributions/") + .stringType("description", "A list of available distributions") + .stringType("identifier", "distributions") + .stringType("title", "Distributions") + .closeArray() + .asBody() + .date("createdDate", "yyyy-MM-dd", asDate("2023-03-19")) + .date("fromDate", "yyyy-MM-dd", asDate("2023-03-18")) + .date("toDate", "yyyy-MM-dd", asDate("2023-03-17")); + + } + + public static DslPart attributes() { + return header("attributes/", "A list of available attributes", "attributes", "Attributes") + .minArrayLike("resources", 1) + .stringType("identifier", "A") + .stringType("id", "4000003") + .stringType("source", "Data Query") + .stringType("dataType", "String") + .stringType("description", "Description for attribute A") + .integerType("index", 1) + .booleanType("isDatasetKey", false) + .stringType("sourceFieldId", "a_source_field") + .stringType("title", "A") + .closeArray(); + } + + public static DslPart distributions() { + return header("distributions/", "A list of available distributions", "distributions", "Distributions") + .minArrayLike("resources", 1) + .stringType("description", "Snapshot data, in tabular, csv format") + .stringType("identifier", "csv") + .stringType("@id", "csv/") + .stringType("title", "CSV") + .stringType("fileExtension", ".csv") + .stringType("mediaType", "text/csv; header=present; charset=utf-8") + .closeArray(); + } + + @SneakyThrows + private static Date asDate(String example) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + return sdf.parse(example); + } + + private static PactDslJsonBody header(String id, String desc, String identifier, String title) { + PactDslJsonBody b = new PactDslJsonBody(); + return b.object("@context") + .stringType("@vocab", "https://www.w3.org/ns/dcat3.jsondld") + .stringType("@base", "https://fusion-api.test.aws.jpmchase.net/v1") + .closeObject().asBody() + .stringType("@id", id) + .stringType("description", desc) + .stringType("identifier", identifier) + .stringType("Title", title); + } + +} diff --git a/src/it/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java b/src/it/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java new file mode 100644 index 0000000..9971bbf --- /dev/null +++ b/src/it/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java @@ -0,0 +1,26 @@ +package io.github.jpmorganchase.fusion.pact.util; + +import lombok.SneakyThrows; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; + +public class FileHelper { + + private FileHelper(){} + + @SneakyThrows + public static String readContentsFromStream(InputStream is){ + byte[] bytes = new byte[1024]; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int read = is.read(bytes); + while(read!=-1){ + baos.write(bytes, 0, read); + read = is.read(bytes); + } + baos.close(); + return baos.toString(); + } + + +} diff --git a/src/it/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java b/src/it/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java new file mode 100644 index 0000000..f3ac5fb --- /dev/null +++ b/src/it/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java @@ -0,0 +1,63 @@ +package io.github.jpmorganchase.fusion.pact.util; + +import au.com.dius.pact.consumer.dsl.DslPart; +import au.com.dius.pact.consumer.dsl.PactDslWithProvider; +import au.com.dius.pact.core.model.RequestResponsePact; + +import java.util.Map; + +public class RequestResponseHelper { + + private static final String USER_AGENT_VAL = "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60"; + private static final String BEARER_TOKEN = "my-bearer-token"; + private static final String AUTH_VAL = "Bearer " + BEARER_TOKEN; + + private RequestResponseHelper(){}; + + public static RequestResponsePact getExpectation(PactDslWithProvider builder, String given, String upon, String path, DslPart body) { + return builder + .given(given) + .uponReceiving(upon) + .path(path) + .matchHeader("Authorization", AUTH_VAL) + .matchHeader("User-Agent", USER_AGENT_VAL) + .method("GET") + .willRespondWith() + .status(200) + .body(body) + .toPact(); + } + + public static RequestResponsePact downloadExpectation(PactDslWithProvider builder, String given, String upon, String path, String body){ + return builder + .given(given) + .uponReceiving(upon) + .path(path) + .matchHeader("Authorization", AUTH_VAL) + .matchHeader("User-Agent", USER_AGENT_VAL) + .method("GET") + .willRespondWith() + .status(200) + .body(body) + .toPact(); + } + + public static RequestResponsePact uploadExpectation(PactDslWithProvider builder, String given, String upon, String authPath, String path, Map headers, String body){ + + return builder + .given(given) + .uponReceiving(upon) + .path(path) + .matchHeader("accept", "\\*\\/\\*") + .matchHeader("Authorization", AUTH_VAL) + .matchHeader("Fusion-Authorization", "Bearer my-fusion-bearer") + .matchHeader("Content-Type", "application/octet-stream") + .headers(headers) + .method("PUT") + .body(body) + .willRespondWith() + .status(200) + .toPact(); + } + +} diff --git a/src/it/resources/pact-examples/FusionSdk-FusionApi.json b/src/it/resources/pact-examples/FusionSdk-FusionApi.json new file mode 100644 index 0000000..197469a --- /dev/null +++ b/src/it/resources/pact-examples/FusionSdk-FusionApi.json @@ -0,0 +1,2327 @@ +{ + "provider": { + "name": "FusionApi" + }, + "consumer": { + "name": "FusionSdk" + }, + "interactions": [ + { + "description": "a request for a dataset resource", + "request": { + "method": "GET", + "path": "/v1/catalogs/common/datasets/GFI_OP_CF", + "headers": { + "Authorization": "Bearer my-bearer-token", + "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + }, + "User-Agent": { + "matchers": [ + { + "match": "regex", + "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json; charset=UTF-8" + }, + "body": { + "identifier": "GFI_OP_CF", + "subCategory": [ + "string", + "string" + ], + "isRawData": false, + "isInternalOnlyDataset": false, + "description": "Premium, volatility, and greeks for EUR", + "Title": "Swaptions Caps & Floors", + "resources": [ + { + "identifier": "datasetseries", + "description": "A list of available datasetseries of a dataset", + "@id": "datasetseries/", + "title": "Datasetseries" + } + ], + "language": "English", + "source": [ + "string", + "string" + ], + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + }, + "maintainer": "J.P. Morgan DM Rates Research", + "frequency": "Daily", + "createdDate": "2023-04-20", + "isThirdPartyData": false, + "modifiedDate": "2023-04-20", + "publisher": "J.P. Morgan", + "@id": "GFI_OP_CF/", + "tag": [ + "string", + "string" + ], + "category": [ + "string", + "string" + ], + "region": [ + "string", + "string" + ], + "hasSample": false, + "isRestricted": false + }, + "matchingRules": { + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.Title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 1 + } + ], + "combine": "AND" + }, + "$.resources[*].@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.category": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.category[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.createdDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.frequency": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.isThirdPartyData": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.isInternalOnlyDataset": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.language": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.maintainer": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.modifiedDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.publisher": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.region": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.region[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.source": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.source[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.subCategory": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.subCategory[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.tag": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.tag[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.isRestricted": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.isRawData": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.hasSample": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + } + }, + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json(;\\s?charset=[\\w\\-]+)?" + } + ], + "combine": "AND" + } + } + }, + "generators": { + "body": { + "$.category[*]": { + "type": "RandomString", + "size": 20 + }, + "$.region[*]": { + "type": "RandomString", + "size": 20 + }, + "$.source[*]": { + "type": "RandomString", + "size": 20 + }, + "$.subCategory[*]": { + "type": "RandomString", + "size": 20 + }, + "$.tag[*]": { + "type": "RandomString", + "size": 20 + } + } + } + }, + "providerStates": [ + { + "name": "a dataset resource" + } + ] + }, + { + "description": "a request is made to download the distribution", + "request": { + "method": "GET", + "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220116/distributions/csv", + "headers": { + "Authorization": "Bearer my-bearer-token", + "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + }, + "User-Agent": { + "matchers": [ + { + "match": "regex", + "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "body": "A,B,C" + }, + "providerStates": [ + { + "name": "a distribution that is available for download" + } + ] + }, + { + "description": "a request for a list of attributes from a dataset", + "request": { + "method": "GET", + "path": "/v1/catalogs/common/datasets/API_TEST/attributes", + "headers": { + "Authorization": "Bearer my-bearer-token", + "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + }, + "User-Agent": { + "matchers": [ + { + "match": "regex", + "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json; charset=UTF-8" + }, + "body": { + "identifier": "attributes", + "description": "A list of available attributes", + "Title": "Attributes", + "resources": [ + { + "identifier": "A", + "isDatasetKey": false, + "dataType": "String", + "sourceFieldId": "a_source_field", + "description": "Description for attribute A", + "index": 1, + "id": "4000003", + "source": "Data Query", + "title": "A" + } + ], + "@id": "attributes/", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.Title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 1 + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].source": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].dataType": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].index": { + "matchers": [ + { + "match": "integer" + } + ], + "combine": "AND" + }, + "$.resources[*].isDatasetKey": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].sourceFieldId": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + } + }, + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json(;\\s?charset=[\\w\\-]+)?" + } + ], + "combine": "AND" + } + } + } + }, + "providerStates": [ + { + "name": "a list of attributes for a dataset in a catalog" + } + ] + }, + { + "description": "a request for catalogs resources", + "request": { + "method": "GET", + "path": "/v1/catalogs/common", + "headers": { + "Authorization": "Bearer my-bearer-token", + "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + }, + "User-Agent": { + "matchers": [ + { + "match": "regex", + "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json; charset=UTF-8" + }, + "body": { + "identifier": "common", + "description": "A catalog of common data", + "Title": "Common data catalog", + "resources": [ + { + "identifier": "datasets", + "description": "A list of available datasets (for access or download in one or more formats)", + "@id": "datasets/", + "title": "Datasets" + } + ], + "@id": "common", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.Title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 1 + } + ], + "combine": "AND" + }, + "$.resources[*].@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + } + }, + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json(;\\s?charset=[\\w\\-]+)?" + } + ], + "combine": "AND" + } + } + } + }, + "providerStates": [ + { + "name": "a list of catalogs resources" + } + ] + }, + { + "description": "a request for available catalogs", + "request": { + "method": "GET", + "path": "/v1/catalogs", + "headers": { + "Authorization": "Bearer my-bearer-token", + "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + }, + "User-Agent": { + "matchers": [ + { + "match": "regex", + "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json; charset=UTF-8" + }, + "body": { + "identifier": "catalogs", + "description": "A list of available catalogs, catalogs", + "Title": "Catalogs", + "resources": [ + { + "identifier": "common", + "description": "A catalog of common data", + "@id": "common", + "title": "Common data catalog" + } + ], + "@id": "catalogs/", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.Title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + } + }, + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json(;\\s?charset=[\\w\\-]+)?" + } + ], + "combine": "AND" + } + } + } + }, + "providerStates": [ + { + "name": "a list of catalogs" + } + ] + }, + { + "description": "a request for a list of data products", + "request": { + "method": "GET", + "path": "/v1/catalogs/common/products", + "headers": { + "Authorization": "Bearer my-bearer-token", + "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + }, + "User-Agent": { + "matchers": [ + { + "match": "regex", + "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json; charset=UTF-8" + }, + "body": { + "identifier": "products", + "description": "A list of available products", + "Title": "Products", + "resources": [ + { + "identifier": "ESG00008", + "subCategory": [ + "string", + "string" + ], + "datasetCount": 18, + "releaseDate": "2023-04-20", + "deliveryChannel": [ + "string", + "string" + ], + "description": "MSCI ESG Description", + "isActive": true, + "title": "MSCI ESG Ratings", + "maintainer": [ + "string", + "string" + ], + "shortAbstract": "A robust ESG integration tool", + "publisher": "J.P. Morgan", + "theme": "ESG", + "tag": [ + "string", + "string" + ], + "@id": "ESG00008/", + "category": [ + "string", + "string" + ], + "region": [ + "string", + "string" + ], + "isRestricted": true, + "status": "Available" + } + ], + "@id": "products/", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.Title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 1 + } + ], + "combine": "AND" + }, + "$.resources[*].category": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].category[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].datasetCount": { + "matchers": [ + { + "match": "integer" + } + ], + "combine": "AND" + }, + "$.resources[*].deliveryChannel": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].deliveryChannel[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].isActive": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].maintainer": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].maintainer[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].publisher": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].region": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].region[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].releaseDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.resources[*].shortAbstract": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].status": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].subCategory": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].subCategory[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].tag": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].tag[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].theme": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].isRestricted": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + } + }, + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json(;\\s?charset=[\\w\\-]+)?" + } + ], + "combine": "AND" + } + } + }, + "generators": { + "body": { + "$.resources[*].category[*]": { + "type": "RandomString", + "size": 20 + }, + "$.resources[*].deliveryChannel[*]": { + "type": "RandomString", + "size": 20 + }, + "$.resources[*].maintainer[*]": { + "type": "RandomString", + "size": 20 + }, + "$.resources[*].region[*]": { + "type": "RandomString", + "size": 20 + }, + "$.resources[*].subCategory[*]": { + "type": "RandomString", + "size": 20 + }, + "$.resources[*].tag[*]": { + "type": "RandomString", + "size": 20 + } + } + } + }, + "providerStates": [ + { + "name": "a list of data products" + } + ] + }, + { + "description": "a request for a list of datasets", + "request": { + "method": "GET", + "path": "/v1/catalogs/common/datasets", + "headers": { + "Authorization": "Bearer my-bearer-token", + "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + }, + "User-Agent": { + "matchers": [ + { + "match": "regex", + "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json; charset=UTF-8" + }, + "body": { + "identifier": "datasets", + "description": "A list of available datasets", + "Title": "Datasets", + "resources": [ + { + "identifier": "GFI_OP_CF", + "subCategory": [ + "string", + "string" + ], + "isRawData": false, + "isInternalOnlyDataset": false, + "description": "Premium, volatility, and greeks for EUR", + "language": "English", + "source": [ + "string", + "string" + ], + "title": "Swaptions Caps & Floors", + "maintainer": "J.P. Morgan DM Rates Research", + "frequency": "Daily", + "createdDate": "2023-04-20", + "isThirdPartyData": false, + "modifiedDate": "2023-04-20", + "publisher": "J.P. Morgan", + "tag": [ + "string", + "string" + ], + "@id": "GFI_OP_CF/", + "category": [ + "string", + "string" + ], + "region": [ + "string", + "string" + ], + "hasSample": false, + "isRestricted": false + } + ], + "@id": "datasets/", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.Title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 1 + } + ], + "combine": "AND" + }, + "$.resources[*].category": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].category[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].createdDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.resources[*].description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].frequency": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].isThirdPartyData": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].isInternalOnlyDataset": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].language": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].maintainer": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].modifiedDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.resources[*].publisher": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].region": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].region[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].source": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].source[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].subCategory": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].subCategory[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].tag": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].tag[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].isRestricted": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].isRawData": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].hasSample": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + } + }, + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json(;\\s?charset=[\\w\\-]+)?" + } + ], + "combine": "AND" + } + } + }, + "generators": { + "body": { + "$.resources[*].category[*]": { + "type": "RandomString", + "size": 20 + }, + "$.resources[*].region[*]": { + "type": "RandomString", + "size": 20 + }, + "$.resources[*].source[*]": { + "type": "RandomString", + "size": 20 + }, + "$.resources[*].subCategory[*]": { + "type": "RandomString", + "size": 20 + }, + "$.resources[*].tag[*]": { + "type": "RandomString", + "size": 20 + } + } + } + }, + "providerStates": [ + { + "name": "a list of datasets" + } + ] + }, + { + "description": "a request for distributions available for a series member", + "request": { + "method": "GET", + "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220116/distributions", + "headers": { + "Authorization": "Bearer my-bearer-token", + "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + }, + "User-Agent": { + "matchers": [ + { + "match": "regex", + "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json; charset=UTF-8" + }, + "body": { + "identifier": "distributions", + "description": "A list of available distributions", + "Title": "Distributions", + "resources": [ + { + "identifier": "csv", + "fileExtension": ".csv", + "description": "Snapshot data, in tabular, csv format", + "mediaType": "text/csv; header=present; charset=utf-8", + "@id": "csv/", + "title": "CSV" + } + ], + "@id": "distributions/", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.Title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 1 + } + ], + "combine": "AND" + }, + "$.resources[*].description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].fileExtension": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].mediaType": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + } + }, + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json(;\\s?charset=[\\w\\-]+)?" + } + ], + "combine": "AND" + } + } + } + }, + "providerStates": [ + { + "name": "a list of distributions available for a series member" + } + ] + }, + { + "description": "a request for a list of series members of a dataset", + "request": { + "method": "GET", + "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries", + "headers": { + "Authorization": "Bearer my-bearer-token", + "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + }, + "User-Agent": { + "matchers": [ + { + "match": "regex", + "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json; charset=UTF-8" + }, + "body": { + "identifier": "datasetseries", + "description": "A list of available datasetseries of a dataset", + "Title": "DatasetSeries", + "resources": [ + { + "fromDate": "2023-03-18", + "identifier": "20230319", + "createdDate": "2023-03-19", + "toDate": "2023-03-17", + "@id": "20230319/" + } + ], + "@id": "datasetseries/", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.Title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 1 + } + ], + "combine": "AND" + }, + "$.resources[*].createdDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.resources[*].fromDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.resources[*].toDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + } + }, + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json(;\\s?charset=[\\w\\-]+)?" + } + ], + "combine": "AND" + } + } + } + }, + "providerStates": [ + { + "name": "a list of series members for a dataset" + } + ] + }, + { + "description": "a request dataset series member metadata", + "request": { + "method": "GET", + "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/20230319", + "headers": { + "Authorization": "Bearer my-bearer-token", + "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + }, + "User-Agent": { + "matchers": [ + { + "match": "regex", + "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json; charset=UTF-8" + }, + "body": { + "fromDate": "2023-03-18", + "identifier": "20230319", + "createdDate": "2023-03-19", + "toDate": "2023-03-17", + "resources": [ + { + "identifier": "distributions", + "description": "A list of available distributions", + "@id": "distributions/", + "title": "Distributions" + } + ], + "@id": "20230319/", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 1 + } + ], + "combine": "AND" + }, + "$.resources[*].@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.createdDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.fromDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.toDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + } + }, + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json(;\\s?charset=[\\w\\-]+)?" + } + ], + "combine": "AND" + } + } + } + }, + "providerStates": [ + { + "name": "metadata for a dataset series member" + } + ] + } + ], + "metadata": { + "pactSpecification": { + "version": "3.0.0" + }, + "pact-jvm": { + "version": "4.1.41" + } + } +} diff --git a/src/it/resources/pact-examples/FusionSdk-FusionUpload.json b/src/it/resources/pact-examples/FusionSdk-FusionUpload.json new file mode 100644 index 0000000..b25f921 --- /dev/null +++ b/src/it/resources/pact-examples/FusionSdk-FusionUpload.json @@ -0,0 +1,85 @@ +{ + "provider": { + "name": "FusionUpload" + }, + "consumer": { + "name": "FusionSdk" + }, + "interactions": [ + { + "description": "a request is made to download the distribution", + "request": { + "method": "PUT", + "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220117/distributions/csv", + "headers": { + "Authorization": "Bearer my-bearer-token", + "Fusion-Authorization": "Bearer my-fusion-bearer", + "x-jpmc-distribution-from-date": "2022-01-15", + "x-jpmc-distribution-created-date": "2022-01-17", + "Digest": "SHA-256=KPD9WTOuUoQrDwpugLaHblJS+OdUnXaML3YWXla28Rg=", + "x-jpmc-distribution-to-date": "2022-01-16", + "Content-Length": "5", + "accept": "*/*", + "Content-Type": "application/octet-stream" + }, + "body": "QSxCLEM=", + "matchingRules": { + "header": { + "accept": { + "matchers": [ + { + "match": "regex", + "regex": "\\*\\/\\*" + } + ], + "combine": "AND" + }, + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + }, + "Fusion-Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-fusion-bearer" + } + ], + "combine": "AND" + }, + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/octet-stream" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200 + }, + "providerStates": [ + { + "name": "a distribution that is available for download" + } + ] + } + ], + "metadata": { + "pactSpecification": { + "version": "3.0.0" + }, + "pact-jvm": { + "version": "4.1.41" + } + } +} diff --git a/src/it/resources/pact-examples/fusion_sdk_consumer-FusionProvider.json b/src/it/resources/pact-examples/fusion_sdk_consumer-FusionProvider.json deleted file mode 100644 index da9f89b..0000000 --- a/src/it/resources/pact-examples/fusion_sdk_consumer-FusionProvider.json +++ /dev/null @@ -1,174 +0,0 @@ -{ - "provider": { - "name": "FusionProvider" - }, - "consumer": { - "name": "fusion_sdk_consumer" - }, - "interactions": [ - { - "description": "a request for available catalogs", - "request": { - "method": "GET", - "path": "/v1/catalogs", - "headers": { - "Authorization": "Bearer my-bearer-token", - "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" - }, - "matchingRules": { - "header": { - "Authorization": { - "matchers": [ - { - "match": "regex", - "regex": "Bearer my-bearer-token" - } - ], - "combine": "AND" - }, - "User-Agent": { - "matchers": [ - { - "match": "regex", - "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" - } - ], - "combine": "AND" - } - } - } - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/json; charset=UTF-8" - }, - "body": { - "identifier": "catalogs", - "description": "A list of available catalogs", - "resources": [ - { - "identifier": "common", - "description": "A catalog of common data", - "@id": "common", - "title": "Common data catalog" - } - ], - "@id": "catalogs/", - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - } - }, - "matchingRules": { - "body": { - "$.@context.@vocab": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@context.@base": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.description": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].description": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].title": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - } - }, - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json(;\\s?charset=[\\w\\-]+)?" - } - ], - "combine": "AND" - } - } - } - }, - "providerStates": [ - { - "name": "a list of catalogs" - } - ] - } - ], - "metadata": { - "pactSpecification": { - "version": "3.0.0" - }, - "pact-jvm": { - "version": "4.1.41" - } - } -} diff --git a/src/main/java/io/github/jpmorganchase/fusion/Fusion.java b/src/main/java/io/github/jpmorganchase/fusion/Fusion.java index 76a46d5..cca2b8b 100644 --- a/src/main/java/io/github/jpmorganchase/fusion/Fusion.java +++ b/src/main/java/io/github/jpmorganchase/fusion/Fusion.java @@ -13,6 +13,7 @@ import io.github.jpmorganchase.fusion.model.*; import io.github.jpmorganchase.fusion.oauth.credential.*; import io.github.jpmorganchase.fusion.oauth.exception.OAuthException; +import io.github.jpmorganchase.fusion.oauth.provider.DatasetTokenProvider; import io.github.jpmorganchase.fusion.oauth.provider.OAuthDatasetTokenProvider; import io.github.jpmorganchase.fusion.oauth.provider.OAuthSessionTokenProvider; import io.github.jpmorganchase.fusion.parsing.APIResponseParser; @@ -566,6 +567,7 @@ public static class FusionBuilder { protected String credentialFile; protected String rootURL; protected APIManager api; + protected DatasetTokenProvider datasetTokenProvider; public FusionBuilder bearerToken(String token) { this.credentials = new BearerTokenCredentials(token); @@ -603,6 +605,11 @@ public FusionBuilder rootURL(String rootURL) { this.rootURL = rootURL; return this; } + + public FusionBuilder datasetTokenProvider(DatasetTokenProvider datasetTokenProvider) { + this.datasetTokenProvider = datasetTokenProvider; + return this; + } } private static class CustomFusionBuilder extends FusionBuilder { @@ -646,8 +653,9 @@ public Fusion build() { // TODO : Make this part of the builder journey OAuthSessionTokenProvider sessionTokenProvider = new OAuthSessionTokenProvider(credentials, client); - OAuthDatasetTokenProvider datasetTokenProvider = - new OAuthDatasetTokenProvider(rootURL, sessionTokenProvider, client); + if (datasetTokenProvider == null) { + datasetTokenProvider = new OAuthDatasetTokenProvider(rootURL, sessionTokenProvider, client); + } DigestProducer digestProducer = AlgoSpecificDigestProducer.builder().sha256().build(); From c95755d4f555ca2bdd6e196de675717b5e5238cd Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Thu, 20 Apr 2023 16:26:44 +0100 Subject: [PATCH 05/32] Update build-on-push.yml --- .github/workflows/build-on-push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-on-push.yml b/.github/workflows/build-on-push.yml index dbdbe4c..bdbd23c 100644 --- a/.github/workflows/build-on-push.yml +++ b/.github/workflows/build-on-push.yml @@ -17,4 +17,4 @@ jobs: architecture: x64 cache: maven - name: Build with Maven - run: mvn --batch-mode --update-snapshots package \ No newline at end of file + run: mvn -e --batch-mode --update-snapshots package From c43fffa5c90d1e09eee8210b6fec567ae8546ca9 Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Thu, 20 Apr 2023 16:35:01 +0100 Subject: [PATCH 06/32] Update build-on-push.yml --- .github/workflows/build-on-push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-on-push.yml b/.github/workflows/build-on-push.yml index bdbd23c..645a62b 100644 --- a/.github/workflows/build-on-push.yml +++ b/.github/workflows/build-on-push.yml @@ -17,4 +17,4 @@ jobs: architecture: x64 cache: maven - name: Build with Maven - run: mvn -e --batch-mode --update-snapshots package + run: mvn --batch-mode --update-snapshots package From 24037b1b8c78ba0e504d5110b0d24711c52e970f Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Thu, 20 Apr 2023 16:35:28 +0100 Subject: [PATCH 07/32] Changed home of PACT tests --- .../pact/util/RequestResponseHelper.java | 63 ------ .../pact/FusionApiConsumerPactTest.java | 196 ++++++++++++------ .../pact/FusionUploadConsumerPactTest.java | 74 +++---- .../fusion/pact/util/BodyBuilders.java | 162 ++++++++------- .../fusion/pact/util/FileHelper.java | 11 +- .../pact/util/RequestResponseHelper.java | 68 ++++++ .../pact-samples}/FusionSdk-FusionApi.json | 0 .../pact-samples}/FusionSdk-FusionUpload.json | 0 8 files changed, 322 insertions(+), 252 deletions(-) delete mode 100644 src/it/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java rename src/{it => test}/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java (68%) rename src/{it => test}/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java (69%) rename src/{it => test}/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java (52%) rename src/{it => test}/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java (79%) create mode 100644 src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java rename src/{it/resources/pact-examples => test/resources/io/github/jpmorganchase/fusion/pact-samples}/FusionSdk-FusionApi.json (100%) rename src/{it/resources/pact-examples => test/resources/io/github/jpmorganchase/fusion/pact-samples}/FusionSdk-FusionUpload.json (100%) diff --git a/src/it/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java b/src/it/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java deleted file mode 100644 index f3ac5fb..0000000 --- a/src/it/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java +++ /dev/null @@ -1,63 +0,0 @@ -package io.github.jpmorganchase.fusion.pact.util; - -import au.com.dius.pact.consumer.dsl.DslPart; -import au.com.dius.pact.consumer.dsl.PactDslWithProvider; -import au.com.dius.pact.core.model.RequestResponsePact; - -import java.util.Map; - -public class RequestResponseHelper { - - private static final String USER_AGENT_VAL = "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60"; - private static final String BEARER_TOKEN = "my-bearer-token"; - private static final String AUTH_VAL = "Bearer " + BEARER_TOKEN; - - private RequestResponseHelper(){}; - - public static RequestResponsePact getExpectation(PactDslWithProvider builder, String given, String upon, String path, DslPart body) { - return builder - .given(given) - .uponReceiving(upon) - .path(path) - .matchHeader("Authorization", AUTH_VAL) - .matchHeader("User-Agent", USER_AGENT_VAL) - .method("GET") - .willRespondWith() - .status(200) - .body(body) - .toPact(); - } - - public static RequestResponsePact downloadExpectation(PactDslWithProvider builder, String given, String upon, String path, String body){ - return builder - .given(given) - .uponReceiving(upon) - .path(path) - .matchHeader("Authorization", AUTH_VAL) - .matchHeader("User-Agent", USER_AGENT_VAL) - .method("GET") - .willRespondWith() - .status(200) - .body(body) - .toPact(); - } - - public static RequestResponsePact uploadExpectation(PactDslWithProvider builder, String given, String upon, String authPath, String path, Map headers, String body){ - - return builder - .given(given) - .uponReceiving(upon) - .path(path) - .matchHeader("accept", "\\*\\/\\*") - .matchHeader("Authorization", AUTH_VAL) - .matchHeader("Fusion-Authorization", "Bearer my-fusion-bearer") - .matchHeader("Content-Type", "application/octet-stream") - .headers(headers) - .method("PUT") - .body(body) - .willRespondWith() - .status(200) - .toPact(); - } - -} diff --git a/src/it/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java similarity index 68% rename from src/it/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java rename to src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java index 5977b14..ef731e7 100644 --- a/src/it/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java @@ -1,5 +1,11 @@ package io.github.jpmorganchase.fusion.pact; +import static io.github.jpmorganchase.fusion.pact.util.BodyBuilders.*; +import static io.github.jpmorganchase.fusion.pact.util.RequestResponseHelper.downloadExpectation; +import static io.github.jpmorganchase.fusion.pact.util.RequestResponseHelper.getExpectation; +import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; import au.com.dius.pact.consumer.MockServer; import au.com.dius.pact.consumer.dsl.PactDslWithProvider; @@ -10,25 +16,16 @@ import io.github.jpmorganchase.fusion.Fusion; import io.github.jpmorganchase.fusion.model.*; import io.github.jpmorganchase.fusion.pact.util.FileHelper; -import lombok.SneakyThrows; -import org.hamcrest.core.Is; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Paths; import java.time.LocalDate; import java.util.Map; - -import static io.github.jpmorganchase.fusion.pact.util.BodyBuilders.*; -import static io.github.jpmorganchase.fusion.pact.util.RequestResponseHelper.downloadExpectation; -import static io.github.jpmorganchase.fusion.pact.util.RequestResponseHelper.getExpectation; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import lombok.SneakyThrows; +import org.hamcrest.core.Is; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; @ExtendWith(PactConsumerTestExt.class) public class FusionApiConsumerPactTest { @@ -40,55 +37,103 @@ public class FusionApiConsumerPactTest { @Pact(provider = "FusionApi", consumer = "FusionSdk") public RequestResponsePact listCatalogs(PactDslWithProvider builder) { - return getExpectation(builder, "a list of catalogs", "a request for available catalogs", "/v1/catalogs", catalogs()); + return getExpectation( + builder, "a list of catalogs", "a request for available catalogs", "/v1/catalogs", catalogs()); } @Pact(provider = "FusionApi", consumer = "FusionSdk") public RequestResponsePact getCatalogResources(PactDslWithProvider builder) { - return getExpectation(builder, "a list of catalogs resources", "a request for catalogs resources", "/v1/catalogs/common", catalogResources()); + return getExpectation( + builder, + "a list of catalogs resources", + "a request for catalogs resources", + "/v1/catalogs/common", + catalogResources()); } @Pact(provider = "FusionApi", consumer = "FusionSdk") public RequestResponsePact listProducts(PactDslWithProvider builder) { - return getExpectation(builder, "a list of data products", "a request for a list of data products", "/v1/catalogs/common/products", products()); + return getExpectation( + builder, + "a list of data products", + "a request for a list of data products", + "/v1/catalogs/common/products", + products()); } @Pact(provider = "FusionApi", consumer = "FusionSdk") public RequestResponsePact listDatasets(PactDslWithProvider builder) { - return getExpectation(builder, "a list of datasets", "a request for a list of datasets", "/v1/catalogs/common/datasets", datasets()); + return getExpectation( + builder, + "a list of datasets", + "a request for a list of datasets", + "/v1/catalogs/common/datasets", + datasets()); } @Pact(provider = "FusionApi", consumer = "FusionSdk") public RequestResponsePact getDatasetResources(PactDslWithProvider builder) { - return getExpectation(builder, "a dataset resource", "a request for a dataset resource", "/v1/catalogs/common/datasets/GFI_OP_CF", datasetResource()); + return getExpectation( + builder, + "a dataset resource", + "a request for a dataset resource", + "/v1/catalogs/common/datasets/GFI_OP_CF", + datasetResource()); } @Pact(provider = "FusionApi", consumer = "FusionSdk") public RequestResponsePact listDatasetMembers(PactDslWithProvider builder) { - return getExpectation(builder, "a list of series members for a dataset", "a request for a list of series members of a dataset", "/v1/catalogs/common/datasets/API_TEST/datasetseries", datasetMembers()); + return getExpectation( + builder, + "a list of series members for a dataset", + "a request for a list of series members of a dataset", + "/v1/catalogs/common/datasets/API_TEST/datasetseries", + datasetMembers()); } + @Pact(provider = "FusionApi", consumer = "FusionSdk") public RequestResponsePact getDatasetMemberResources(PactDslWithProvider builder) { - return getExpectation(builder, "metadata for a dataset series member", "a request dataset series member metadata", "/v1/catalogs/common/datasets/API_TEST/datasetseries/20230319", datasetMemberResources()); + return getExpectation( + builder, + "metadata for a dataset series member", + "a request dataset series member metadata", + "/v1/catalogs/common/datasets/API_TEST/datasetseries/20230319", + datasetMemberResources()); } + @Pact(provider = "FusionApi", consumer = "FusionSdk") public RequestResponsePact listAttributes(PactDslWithProvider builder) { - return getExpectation(builder, "a list of attributes for a dataset in a catalog", "a request for a list of attributes from a dataset", "/v1/catalogs/common/datasets/API_TEST/attributes", attributes()); + return getExpectation( + builder, + "a list of attributes for a dataset in a catalog", + "a request for a list of attributes from a dataset", + "/v1/catalogs/common/datasets/API_TEST/attributes", + attributes()); } @Pact(provider = "FusionApi", consumer = "FusionSdk") public RequestResponsePact listDistributions(PactDslWithProvider builder) { - return getExpectation(builder, "a list of distributions available for a series member", "a request for distributions available for a series member", "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220116/distributions", distributions()); + return getExpectation( + builder, + "a list of distributions available for a series member", + "a request for distributions available for a series member", + "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220116/distributions", + distributions()); } @Pact(provider = "FusionApi", consumer = "FusionSdk") public RequestResponsePact download(PactDslWithProvider builder) { - return downloadExpectation(builder, "a distribution that is available for download", "a request is made to download the distribution", "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220116/distributions/csv", "A,B,C"); + return downloadExpectation( + builder, + "a distribution that is available for download", + "a request is made to download the distribution", + "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220116/distributions/csv", + "A,B,C"); } @AfterEach @SneakyThrows - public void cleanupDirectory(){ + public void cleanupDirectory() { Files.deleteIfExists(Paths.get("downloads/common_API_TEST_20220116.csv")); } @@ -107,9 +152,11 @@ void testListCatalogs(MockServer mockServer) { assertThat("Expected catalog is null", catalog, is(notNullValue())); assertThat("Expected catalog identifier to match", catalog.getIdentifier(), is(equalTo("common"))); assertThat("Expected catalog title to match", catalog.getTitle(), is(equalTo("Common data catalog"))); - assertThat("Expected catalog description to match", catalog.getDescription(), is(equalTo("A catalog of common data"))); + assertThat( + "Expected catalog description to match", + catalog.getDescription(), + is(equalTo("A catalog of common data"))); assertThat("Expected catalog LinkedEntity to match", catalog.getLinkedEntity(), is(equalTo("common"))); - } @Test @@ -132,7 +179,6 @@ void testCatalogResources(MockServer mockServer) { assertThat("resource identifier is missing from resource", dataset.containsKey("identifier"), is(true)); assertThat("resource title is missing from resource", dataset.containsKey("title"), is(true)); }); - } @Test @@ -146,12 +192,14 @@ void testListProducts(MockServer mockServer) { assertThat("Data Products Missing", products.get("ESG00008"), is(notNullValue())); DataProduct dataProduct = products.get("ESG00008"); - assertThat("data product description incorrect", dataProduct.getDescription(), is(equalTo("MSCI ESG Description"))); + assertThat( + "data product description incorrect", + dataProduct.getDescription(), + is(equalTo("MSCI ESG Description"))); assertThat("data product linkedEntity is incorrect", dataProduct.getLinkedEntity(), is(equalTo("ESG00008/"))); assertThat("data product title is incorrect", dataProduct.getTitle(), is(equalTo("MSCI ESG Ratings"))); assertThat("data product status is incorrect", dataProduct.getStatus(), is(equalTo("Available"))); assertThat("data product identifier is incorrect", dataProduct.getIdentifier(), is(equalTo("ESG00008"))); - } @Test @@ -165,12 +213,14 @@ void testListDatasets(MockServer mockServer) { assertThat("Dataset Missing", datasets.get("GFI_OP_CF"), is(notNullValue())); Dataset dataset = datasets.get("GFI_OP_CF"); - assertThat("dataset description incorrect", dataset.getDescription(), is(equalTo("Premium, volatility, and greeks for EUR"))); + assertThat( + "dataset description incorrect", + dataset.getDescription(), + is(equalTo("Premium, volatility, and greeks for EUR"))); assertThat("dataset linkedEntity is incorrect", dataset.getLinkedEntity(), is(equalTo("GFI_OP_CF/"))); assertThat("dataset title is incorrect", dataset.getTitle(), is(equalTo("Swaptions Caps & Floors"))); assertThat("dataset identifier is incorrect", dataset.getIdentifier(), is(equalTo("GFI_OP_CF"))); assertThat("dataset frequency is incorrect", dataset.getFrequency(), is(equalTo("Daily"))); - } @Test @@ -182,15 +232,20 @@ void testDatasetResources(MockServer mockServer) { Map> datasetResources = fusion.datasetResources("common", "GFI_OP_CF"); assertThat("dataset resources must not be empty", datasetResources, Is.is(notNullValue())); - assertThat("dataset resources expected to contain key", datasetResources.containsKey("datasetseries"), is(true)); + assertThat( + "dataset resources expected to contain key", datasetResources.containsKey("datasetseries"), is(true)); Map resource = datasetResources.get("datasetseries"); assertThat("dataset resource @id is incorrect", resource.get("@id"), is(equalTo("datasetseries/"))); - assertThat("dataset resource description is incorrect", resource.get("description"), is(equalTo("A list of available datasetseries of a dataset"))); - assertThat("dataset resource identifier is incorrect", resource.get("identifier"), is(equalTo("datasetseries"))); + assertThat( + "dataset resource description is incorrect", + resource.get("description"), + is(equalTo("A list of available datasetseries of a dataset"))); + assertThat( + "dataset resource identifier is incorrect", resource.get("identifier"), is(equalTo("datasetseries"))); assertThat("dataset resource title is incorrect", resource.get("title"), is(equalTo("Datasetseries"))); - } + @Test @PactTestFor(pactMethod = "listDatasetMembers") void testListDatasetMembers(MockServer mockServer) { @@ -203,10 +258,13 @@ void testListDatasetMembers(MockServer mockServer) { DatasetSeries series = datasetMembers.get("20230319"); assertThat("dataset series @id is incorrect", series.getIdentifier(), is(equalTo("20230319"))); assertThat("dataset series linked entity is incorrect", series.getLinkedEntity(), is(equalTo("20230319/"))); - assertThat("dataset series createdDate is incorrect", series.getCreatedDate(), is(equalTo(LocalDate.of(2023, 3, 19)))); - assertThat("dataset series fromDate is incorrect", series.getFromDate(), is(equalTo(LocalDate.of(2023, 3, 18)))); + assertThat( + "dataset series createdDate is incorrect", + series.getCreatedDate(), + is(equalTo(LocalDate.of(2023, 3, 19)))); + assertThat( + "dataset series fromDate is incorrect", series.getFromDate(), is(equalTo(LocalDate.of(2023, 3, 18)))); assertThat("dataset series toDate is incorrect", series.getToDate(), is(equalTo(LocalDate.of(2023, 3, 17)))); - } @Test @@ -215,18 +273,26 @@ void testDatasetMemberResources(MockServer mockServer) { givenInstanceOfFusionSdk(mockServer); - Map> datasetMemberResources = fusion.datasetMemberResources("common", "API_TEST", "20230319"); + Map> datasetMemberResources = + fusion.datasetMemberResources("common", "API_TEST", "20230319"); assertThat("dataset member resources must not be empty", datasetMemberResources, Is.is(notNullValue())); - assertThat("dataset resources expected to contain key", datasetMemberResources.containsKey("distributions"), is(true)); + assertThat( + "dataset resources expected to contain key", + datasetMemberResources.containsKey("distributions"), + is(true)); Map resource = datasetMemberResources.get("distributions"); assertThat("dataset resource @id is incorrect", resource.get("@id"), is(equalTo("distributions/"))); - assertThat("dataset resource description is incorrect", resource.get("description"), is(equalTo("A list of available distributions"))); - assertThat("dataset resource identifier is incorrect", resource.get("identifier"), is(equalTo("distributions"))); + assertThat( + "dataset resource description is incorrect", + resource.get("description"), + is(equalTo("A list of available distributions"))); + assertThat( + "dataset resource identifier is incorrect", resource.get("identifier"), is(equalTo("distributions"))); assertThat("dataset resource title is incorrect", resource.get("title"), is(equalTo("Distributions"))); - } + @Test @PactTestFor(pactMethod = "listAttributes") void testListAttributes(MockServer mockServer) { @@ -240,7 +306,10 @@ void testListAttributes(MockServer mockServer) { Attribute attribute = attributes.get("A"); assertThat("attribute identifier is incorrect", attribute.getIdentifier(), is(equalTo("A"))); - assertThat("attribute description is incorrect", attribute.getDescription(), is(equalTo("Description for attribute A"))); + assertThat( + "attribute description is incorrect", + attribute.getDescription(), + is(equalTo("Description for attribute A"))); assertThat("attribute title is incorrect", attribute.getTitle(), is(equalTo("A"))); assertThat("attribute index is incorrect", attribute.getIndex(), is(equalTo(1L))); assertThat("attribute dataType is incorrect", attribute.getDataType(), is(equalTo("String"))); @@ -262,13 +331,18 @@ void testListAttributeResources(MockServer mockServer) { assertThat("attribute resource identifier is incorrect", resource.get("identifier"), is(equalTo("A"))); assertThat("attribute resource source is incorrect", resource.get("source"), is(equalTo("Data Query"))); assertThat("attribute resource dataType is incorrect", resource.get("dataType"), is(equalTo("String"))); - assertThat("attribute resource description is incorrect", resource.get("description"), is(equalTo("Description for attribute A"))); - //TODO : Query - gson seems to translate our index integer as a double + assertThat( + "attribute resource description is incorrect", + resource.get("description"), + is(equalTo("Description for attribute A"))); + // TODO : Query - gson seems to translate our index integer as a double assertThat("attribute resource index is incorrect", resource.get("index"), is(equalTo(1.0))); assertThat("attribute resource isDatasetKey is incorrect", resource.get("isDatasetKey"), is(false)); - assertThat("attribute resource sourceFieldId is incorrect", resource.get("sourceFieldId"), is(equalTo("a_source_field"))); + assertThat( + "attribute resource sourceFieldId is incorrect", + resource.get("sourceFieldId"), + is(equalTo("a_source_field"))); assertThat("attribute resource title is incorrect", resource.get("title"), is(equalTo("A"))); - } @Test @@ -284,11 +358,17 @@ void testListDistributions(MockServer mockServer) { Distribution distribution = distributions.get("csv"); assertThat("distribution identifier is incorrect", distribution.getIdentifier(), is(equalTo("csv"))); - assertThat("distribution description is incorrect", distribution.getDescription(), is(equalTo("Snapshot data, in tabular, csv format"))); + assertThat( + "distribution description is incorrect", + distribution.getDescription(), + is(equalTo("Snapshot data, in tabular, csv format"))); assertThat("distribution @id is incorrect", distribution.getLinkedEntity(), is(equalTo("csv/"))); assertThat("distribution title is incorrect", distribution.getTitle(), is(equalTo("CSV"))); assertThat("distribution fileExtension is incorrect", distribution.getFileExtension(), is(equalTo(".csv"))); - assertThat("distribution mediaType is incorrect", distribution.getMediaType(), is(equalTo("text/csv; header=present; charset=utf-8"))); + assertThat( + "distribution mediaType is incorrect", + distribution.getMediaType(), + is(equalTo("text/csv; header=present; charset=utf-8"))); } @Test @@ -310,13 +390,11 @@ void testDownloadStream(MockServer mockServer) { givenInstanceOfFusionSdk(mockServer); - downloadedFileInputStream = fusion.downloadStream("common", "API_TEST", "20220116", "csv"); thenTheFileContentsShouldBeEqualTo("A,B,C"); } - @SneakyThrows private void thenTheFileContentsShouldBeEqualTo(String expected) { String actual = FileHelper.readContentsFromStream(downloadedFileInputStream); @@ -324,14 +402,16 @@ private void thenTheFileContentsShouldBeEqualTo(String expected) { } @SneakyThrows - private void thenTheFileShouldBeDownloaded(String path){ + private void thenTheFileShouldBeDownloaded(String path) { downloadedFileInputStream = Files.newInputStream(Paths.get(path)); - assertThat("downloaded file is unavailable", downloadedFileInputStream.available(), is(greaterThanOrEqualTo(1))); + assertThat( + "downloaded file is unavailable", downloadedFileInputStream.available(), is(greaterThanOrEqualTo(1))); } private void givenInstanceOfFusionSdk(MockServer mockServer) { - fusion = Fusion.builder().rootURL(mockServer.getUrl() + FUSION_API_VERSION).bearerToken("my-bearer-token").build(); + fusion = Fusion.builder() + .rootURL(mockServer.getUrl() + FUSION_API_VERSION) + .bearerToken("my-bearer-token") + .build(); } - - } diff --git a/src/it/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java similarity index 69% rename from src/it/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java rename to src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java index 0cf59f6..2ea0d9d 100644 --- a/src/it/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java @@ -1,5 +1,6 @@ package io.github.jpmorganchase.fusion.pact; +import static io.github.jpmorganchase.fusion.pact.util.RequestResponseHelper.*; import au.com.dius.pact.consumer.MockServer; import au.com.dius.pact.consumer.dsl.PactDslWithProvider; @@ -8,35 +9,20 @@ import au.com.dius.pact.core.model.RequestResponsePact; import au.com.dius.pact.core.model.annotations.Pact; import io.github.jpmorganchase.fusion.Fusion; -import io.github.jpmorganchase.fusion.model.*; -import io.github.jpmorganchase.fusion.oauth.provider.DatasetTokenProvider; -import io.github.jpmorganchase.fusion.pact.util.FileHelper; -import lombok.SneakyThrows; -import org.hamcrest.core.Is; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - import java.io.ByteArrayInputStream; import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; -import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.time.LocalDate; import java.util.HashMap; import java.util.Map; - -import static io.github.jpmorganchase.fusion.pact.util.BodyBuilders.*; -import static io.github.jpmorganchase.fusion.pact.util.RequestResponseHelper.*; -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import lombok.SneakyThrows; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; @ExtendWith(PactConsumerTestExt.class) public class FusionUploadConsumerPactTest { @@ -48,60 +34,61 @@ public class FusionUploadConsumerPactTest { @Pact(provider = "FusionUpload", consumer = "FusionSdk") public RequestResponsePact uploadFile(PactDslWithProvider builder) { - Map uploadHeaders = givenUploadHeaders("2022-01-15", "2022-01-16", "2022-01-17", "5", "KPD9WTOuUoQrDwpugLaHblJS+OdUnXaML3YWXla28Rg="); + Map uploadHeaders = givenUploadHeaders( + "2022-01-15", "2022-01-16", "2022-01-17", "5", "KPD9WTOuUoQrDwpugLaHblJS+OdUnXaML3YWXla28Rg="); return uploadExpectation( builder, "a distribution that is available for download", "a request is made to download the distribution", "/v1/catalogs/common/datasets/API_TEST/authorize/token", "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220117/distributions/csv", - uploadHeaders, "A,B,C"); + uploadHeaders, + "A,B,C"); } @Pact(provider = "FusionUpload", consumer = "FusionSdk") public RequestResponsePact uploadStream(PactDslWithProvider builder) { - Map uploadHeaders = givenUploadHeaders("2022-01-16", "2022-01-16", "2022-01-17", "5", "KPD9WTOuUoQrDwpugLaHblJS+OdUnXaML3YWXla28Rg="); + Map uploadHeaders = givenUploadHeaders( + "2022-01-16", "2022-01-16", "2022-01-17", "5", "KPD9WTOuUoQrDwpugLaHblJS+OdUnXaML3YWXla28Rg="); return uploadExpectation( builder, "a distribution that is available for download", "a request is made to download the distribution", "/v1/catalogs/common/datasets/API_TEST/authorize/token", "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220117/distributions/csv", - uploadHeaders, "A,B,C"); + uploadHeaders, + "A,B,C"); } @AfterEach @SneakyThrows - public void cleanupDirectory(){ + public void cleanupDirectory() { Files.deleteIfExists(Paths.get("downloads/common_API_TEST_20220117.csv")); } @Test @SneakyThrows @PactTestFor(pactMethod = "uploadFile") - void testUploadFile(MockServer mockServer){ + void testUploadFile(MockServer mockServer) { givenInstanceOfFusionSdk(mockServer); givenFileReadForUpload("/common_API_TEST_20220117.csv", "A,B,C"); - - Assertions.assertDoesNotThrow( - () -> fusion.upload( - "common", - "API_TEST", - "20220117", - "csv", - "downloads/common_API_TEST_20220117.csv", - LocalDate.of(2022, 1, 15), - LocalDate.of(2022, 1, 16), - LocalDate.of(2022, 1, 17)) - ); + Assertions.assertDoesNotThrow(() -> fusion.upload( + "common", + "API_TEST", + "20220117", + "csv", + "downloads/common_API_TEST_20220117.csv", + LocalDate.of(2022, 1, 15), + LocalDate.of(2022, 1, 16), + LocalDate.of(2022, 1, 17))); } @Test @PactTestFor(pactMethod = "uploadStream") - void testUploadStream(MockServer mockServer){ + void testUploadStream(MockServer mockServer) { givenInstanceOfFusionSdk(mockServer); Assertions.assertDoesNotThrow(() -> fusion.upload( @@ -112,9 +99,7 @@ void testUploadStream(MockServer mockServer){ new ByteArrayInputStream("A,B,C".getBytes()), LocalDate.of(2022, 1, 16), LocalDate.of(2022, 1, 16), - LocalDate.of(2022, 1, 17) - )); - + LocalDate.of(2022, 1, 17))); } private static void givenFileReadForUpload(String fileName, String body) throws IOException { @@ -132,7 +117,8 @@ private void givenInstanceOfFusionSdk(MockServer mockServer) { .build(); } - private static Map givenUploadHeaders(String fromDate, String toDate, String cDate, String length, String digest) { + private static Map givenUploadHeaders( + String fromDate, String toDate, String cDate, String length, String digest) { Map uploadHeaders = new HashMap<>(); uploadHeaders.put("x-jpmc-distribution-from-date", fromDate); uploadHeaders.put("x-jpmc-distribution-to-date", toDate); @@ -141,6 +127,4 @@ private static Map givenUploadHeaders(String fromDate, String to uploadHeaders.put("Digest", "SHA-256=" + digest); return uploadHeaders; } - - } diff --git a/src/it/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java similarity index 52% rename from src/it/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java rename to src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java index c059742..dc133d6 100644 --- a/src/it/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java @@ -1,14 +1,13 @@ package io.github.jpmorganchase.fusion.pact.util; +import static au.com.dius.pact.consumer.dsl.PactDslJsonRootValue.stringType; + import au.com.dius.pact.consumer.dsl.DslPart; import au.com.dius.pact.consumer.dsl.PactDslJsonBody; -import lombok.SneakyThrows; - import java.text.SimpleDateFormat; import java.time.Instant; import java.util.Date; - -import static au.com.dius.pact.consumer.dsl.PactDslJsonRootValue.stringType; +import lombok.SneakyThrows; /** * These bodies exist to support the tests contained in {@link io.github.jpmorganchase.fusion.pact.FusionApiConsumerPactTest}. @@ -18,7 +17,7 @@ public class BodyBuilders { private BodyBuilders() {} - public static DslPart catalogs(){ + public static DslPart catalogs() { return header("catalogs/", "A list of available catalogs, catalogs", "catalogs", "Catalogs") .eachLike("resources") .stringType("@id", "common") @@ -31,70 +30,71 @@ public static DslPart catalogs(){ public static DslPart catalogResources() { return header("common", "A catalog of common data", "common", "Common data catalog") .minArrayLike("resources", 1) - .stringType("@id", "datasets/") - .stringType("description", "A list of available datasets (for access or download in one or more formats)") - .stringType("identifier", "datasets") - .stringType("title", "Datasets") + .stringType("@id", "datasets/") + .stringType( + "description", "A list of available datasets (for access or download in one or more formats)") + .stringType("identifier", "datasets") + .stringType("title", "Datasets") .closeArray(); } public static DslPart products() { return header("products/", "A list of available products", "products", "Products") - .minArrayLike("resources", 1) - .minArrayLike("category", 0, stringType()) - .integerType("datasetCount", 18) - .minArrayLike("deliveryChannel", 0, stringType()) - .stringType("description", "MSCI ESG Description") - .stringType("identifier", "ESG00008") - .booleanType("isActive", true) - .minArrayLike("maintainer", 0, stringType()) - .stringType("publisher", "J.P. Morgan") - .minArrayLike("region", 0, stringType()) - .date("releaseDate", "yyyy-MM-dd", Date.from(Instant.now())) - .stringType("shortAbstract", "A robust ESG integration tool") - .stringType("status", "Available") - .minArrayLike("subCategory", 0, stringType()) - .minArrayLike("tag", 0, stringType()) - .stringType("theme", "ESG") - .stringType("title", "MSCI ESG Ratings") - .booleanType("isRestricted", true) - .stringType("@id", "ESG00008/") + .minArrayLike("resources", 1) + .minArrayLike("category", 0, stringType()) + .integerType("datasetCount", 18) + .minArrayLike("deliveryChannel", 0, stringType()) + .stringType("description", "MSCI ESG Description") + .stringType("identifier", "ESG00008") + .booleanType("isActive", true) + .minArrayLike("maintainer", 0, stringType()) + .stringType("publisher", "J.P. Morgan") + .minArrayLike("region", 0, stringType()) + .date("releaseDate", "yyyy-MM-dd", Date.from(Instant.now())) + .stringType("shortAbstract", "A robust ESG integration tool") + .stringType("status", "Available") + .minArrayLike("subCategory", 0, stringType()) + .minArrayLike("tag", 0, stringType()) + .stringType("theme", "ESG") + .stringType("title", "MSCI ESG Ratings") + .booleanType("isRestricted", true) + .stringType("@id", "ESG00008/") .closeArray(); } public static DslPart datasets() { return header("datasets/", "A list of available datasets", "datasets", "Datasets") - .minArrayLike("resources", 1) - .minArrayLike("category", 0, stringType()) - .date("createdDate", "yyyy-MM-dd", Date.from(Instant.now())) - .stringType("description", "Premium, volatility, and greeks for EUR") - .stringType("frequency", "Daily") - .stringType("identifier", "GFI_OP_CF") - .booleanType("isThirdPartyData", false) - .booleanType("isInternalOnlyDataset", false) - .stringType("language", "English") - .stringType("maintainer", "J.P. Morgan DM Rates Research") - .date("modifiedDate", "yyyy-MM-dd", Date.from(Instant.now())) - .stringType("publisher", "J.P. Morgan") - .minArrayLike("region", 0, stringType()) - .minArrayLike("source", 0, stringType()) - .minArrayLike("subCategory", 0, stringType()) - .stringType("title", "Swaptions Caps & Floors") - .minArrayLike("tag", 0, stringType()) - .booleanType("isRestricted", false) - .booleanType("isRawData", false) - .booleanType("hasSample", false) - .stringType("@id", "GFI_OP_CF/") + .minArrayLike("resources", 1) + .minArrayLike("category", 0, stringType()) + .date("createdDate", "yyyy-MM-dd", Date.from(Instant.now())) + .stringType("description", "Premium, volatility, and greeks for EUR") + .stringType("frequency", "Daily") + .stringType("identifier", "GFI_OP_CF") + .booleanType("isThirdPartyData", false) + .booleanType("isInternalOnlyDataset", false) + .stringType("language", "English") + .stringType("maintainer", "J.P. Morgan DM Rates Research") + .date("modifiedDate", "yyyy-MM-dd", Date.from(Instant.now())) + .stringType("publisher", "J.P. Morgan") + .minArrayLike("region", 0, stringType()) + .minArrayLike("source", 0, stringType()) + .minArrayLike("subCategory", 0, stringType()) + .stringType("title", "Swaptions Caps & Floors") + .minArrayLike("tag", 0, stringType()) + .booleanType("isRestricted", false) + .booleanType("isRawData", false) + .booleanType("hasSample", false) + .stringType("@id", "GFI_OP_CF/") .closeArray(); } public static DslPart datasetResource() { return header("GFI_OP_CF/", "Premium, volatility, and greeks for EUR", "GFI_OP_CF", "Swaptions Caps & Floors") .minArrayLike("resources", 1) - .stringType("@id", "datasetseries/") - .stringType("description", "A list of available datasetseries of a dataset") - .stringType("identifier", "datasetseries") - .stringType("title", "Datasetseries") + .stringType("@id", "datasetseries/") + .stringType("description", "A list of available datasetseries of a dataset") + .stringType("identifier", "datasetseries") + .stringType("title", "Datasetseries") .closeArray() .asBody() .minArrayLike("category", 0, stringType()) @@ -117,7 +117,11 @@ public static DslPart datasetResource() { public static DslPart datasetMembers() { - return header("datasetseries/", "A list of available datasetseries of a dataset", "datasetseries", "DatasetSeries") + return header( + "datasetseries/", + "A list of available datasetseries of a dataset", + "datasetseries", + "DatasetSeries") .minArrayLike("resources", 1) .date("createdDate", "yyyy-MM-dd", asDate("2023-03-19")) .date("fromDate", "yyyy-MM-dd", asDate("2023-03-18")) @@ -131,48 +135,48 @@ public static DslPart datasetMemberResources() { PactDslJsonBody b = new PactDslJsonBody(); return b.object("@context") - .stringType("@vocab", "https://www.w3.org/ns/dcat3.jsondld") - .stringType("@base", "https://fusion-api.test.aws.jpmchase.net/v1") - .closeObject().asBody() + .stringType("@vocab", "https://www.w3.org/ns/dcat3.jsondld") + .stringType("@base", "https://fusion-api.test.aws.jpmchase.net/v1") + .closeObject() + .asBody() .stringType("@id", "20230319/") .stringType("identifier", "20230319") .minArrayLike("resources", 1) - .stringType("@id", "distributions/") - .stringType("description", "A list of available distributions") - .stringType("identifier", "distributions") - .stringType("title", "Distributions") + .stringType("@id", "distributions/") + .stringType("description", "A list of available distributions") + .stringType("identifier", "distributions") + .stringType("title", "Distributions") .closeArray() .asBody() .date("createdDate", "yyyy-MM-dd", asDate("2023-03-19")) .date("fromDate", "yyyy-MM-dd", asDate("2023-03-18")) .date("toDate", "yyyy-MM-dd", asDate("2023-03-17")); - } public static DslPart attributes() { return header("attributes/", "A list of available attributes", "attributes", "Attributes") .minArrayLike("resources", 1) - .stringType("identifier", "A") - .stringType("id", "4000003") - .stringType("source", "Data Query") - .stringType("dataType", "String") - .stringType("description", "Description for attribute A") - .integerType("index", 1) - .booleanType("isDatasetKey", false) - .stringType("sourceFieldId", "a_source_field") - .stringType("title", "A") + .stringType("identifier", "A") + .stringType("id", "4000003") + .stringType("source", "Data Query") + .stringType("dataType", "String") + .stringType("description", "Description for attribute A") + .integerType("index", 1) + .booleanType("isDatasetKey", false) + .stringType("sourceFieldId", "a_source_field") + .stringType("title", "A") .closeArray(); } public static DslPart distributions() { return header("distributions/", "A list of available distributions", "distributions", "Distributions") .minArrayLike("resources", 1) - .stringType("description", "Snapshot data, in tabular, csv format") - .stringType("identifier", "csv") - .stringType("@id", "csv/") - .stringType("title", "CSV") - .stringType("fileExtension", ".csv") - .stringType("mediaType", "text/csv; header=present; charset=utf-8") + .stringType("description", "Snapshot data, in tabular, csv format") + .stringType("identifier", "csv") + .stringType("@id", "csv/") + .stringType("title", "CSV") + .stringType("fileExtension", ".csv") + .stringType("mediaType", "text/csv; header=present; charset=utf-8") .closeArray(); } @@ -187,11 +191,11 @@ private static PactDslJsonBody header(String id, String desc, String identifier, return b.object("@context") .stringType("@vocab", "https://www.w3.org/ns/dcat3.jsondld") .stringType("@base", "https://fusion-api.test.aws.jpmchase.net/v1") - .closeObject().asBody() + .closeObject() + .asBody() .stringType("@id", id) .stringType("description", desc) .stringType("identifier", identifier) .stringType("Title", title); } - } diff --git a/src/it/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java similarity index 79% rename from src/it/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java rename to src/test/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java index 9971bbf..6887efd 100644 --- a/src/it/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java @@ -1,26 +1,23 @@ package io.github.jpmorganchase.fusion.pact.util; -import lombok.SneakyThrows; - import java.io.ByteArrayOutputStream; import java.io.InputStream; +import lombok.SneakyThrows; public class FileHelper { - private FileHelper(){} + private FileHelper() {} @SneakyThrows - public static String readContentsFromStream(InputStream is){ + public static String readContentsFromStream(InputStream is) { byte[] bytes = new byte[1024]; ByteArrayOutputStream baos = new ByteArrayOutputStream(); int read = is.read(bytes); - while(read!=-1){ + while (read != -1) { baos.write(bytes, 0, read); read = is.read(bytes); } baos.close(); return baos.toString(); } - - } diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java new file mode 100644 index 0000000..d5d438d --- /dev/null +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java @@ -0,0 +1,68 @@ +package io.github.jpmorganchase.fusion.pact.util; + +import au.com.dius.pact.consumer.dsl.DslPart; +import au.com.dius.pact.consumer.dsl.PactDslWithProvider; +import au.com.dius.pact.core.model.RequestResponsePact; +import java.util.Map; + +public class RequestResponseHelper { + + private static final String USER_AGENT_VAL = "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60"; + private static final String BEARER_TOKEN = "my-bearer-token"; + private static final String AUTH_VAL = "Bearer " + BEARER_TOKEN; + + private RequestResponseHelper() {} + ; + + public static RequestResponsePact getExpectation( + PactDslWithProvider builder, String given, String upon, String path, DslPart body) { + return builder.given(given) + .uponReceiving(upon) + .path(path) + .matchHeader("Authorization", AUTH_VAL) + .matchHeader("User-Agent", USER_AGENT_VAL) + .method("GET") + .willRespondWith() + .status(200) + .body(body) + .toPact(); + } + + public static RequestResponsePact downloadExpectation( + PactDslWithProvider builder, String given, String upon, String path, String body) { + return builder.given(given) + .uponReceiving(upon) + .path(path) + .matchHeader("Authorization", AUTH_VAL) + .matchHeader("User-Agent", USER_AGENT_VAL) + .method("GET") + .willRespondWith() + .status(200) + .body(body) + .toPact(); + } + + public static RequestResponsePact uploadExpectation( + PactDslWithProvider builder, + String given, + String upon, + String authPath, + String path, + Map headers, + String body) { + + return builder.given(given) + .uponReceiving(upon) + .path(path) + .matchHeader("accept", "\\*\\/\\*") + .matchHeader("Authorization", AUTH_VAL) + .matchHeader("Fusion-Authorization", "Bearer my-fusion-bearer") + .matchHeader("Content-Type", "application/octet-stream") + .headers(headers) + .method("PUT") + .body(body) + .willRespondWith() + .status(200) + .toPact(); + } +} diff --git a/src/it/resources/pact-examples/FusionSdk-FusionApi.json b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/FusionSdk-FusionApi.json similarity index 100% rename from src/it/resources/pact-examples/FusionSdk-FusionApi.json rename to src/test/resources/io/github/jpmorganchase/fusion/pact-samples/FusionSdk-FusionApi.json diff --git a/src/it/resources/pact-examples/FusionSdk-FusionUpload.json b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/FusionSdk-FusionUpload.json similarity index 100% rename from src/it/resources/pact-examples/FusionSdk-FusionUpload.json rename to src/test/resources/io/github/jpmorganchase/fusion/pact-samples/FusionSdk-FusionUpload.json From 5c067d837e23ca1f14438ac1afe7931a52319418 Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Thu, 20 Apr 2023 16:50:00 +0100 Subject: [PATCH 08/32] Additional Logging --- .../fusion/pact/FusionUploadConsumerPactTest.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java index 2ea0d9d..e665770 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java @@ -19,12 +19,14 @@ import java.util.HashMap; import java.util.Map; import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @ExtendWith(PactConsumerTestExt.class) +@Slf4j public class FusionUploadConsumerPactTest { private static final String FUSION_API_VERSION = "/v1/"; @@ -110,6 +112,10 @@ private static void givenFileReadForUpload(String fileName, String body) throws } private void givenInstanceOfFusionSdk(MockServer mockServer) { + + log.atInfo().log("Mock Server is {}", mockServer); + log.atInfo().log("Mock Server url {}", mockServer.getUrl()); + fusion = Fusion.builder() .rootURL(mockServer.getUrl() + FUSION_API_VERSION) .bearerToken("my-bearer-token") From 65b2cb2ed4e45922704ccff3f01d8292ceb245b6 Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Thu, 20 Apr 2023 16:59:09 +0100 Subject: [PATCH 09/32] Updated logging --- src/test/resources/logback-test.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index 23e68cc..a686e7c 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -14,7 +14,7 @@ - + From 9d3d27c3d3af4ba8525ac209819b4a4c1294fbad Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Thu, 20 Apr 2023 17:04:19 +0100 Subject: [PATCH 10/32] Updated Logging --- .../fusion/pact/FusionUploadConsumerPactTest.java | 9 +++++---- .../fusion/pact/util/RequestResponseHelper.java | 4 ++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java index e665770..4cff01d 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java @@ -74,6 +74,8 @@ public void cleanupDirectory() { @PactTestFor(pactMethod = "uploadFile") void testUploadFile(MockServer mockServer) { + log.atInfo().log("Executing upload file test"); + givenInstanceOfFusionSdk(mockServer); givenFileReadForUpload("/common_API_TEST_20220117.csv", "A,B,C"); @@ -91,6 +93,9 @@ void testUploadFile(MockServer mockServer) { @Test @PactTestFor(pactMethod = "uploadStream") void testUploadStream(MockServer mockServer) { + + log.atInfo().log("Executing upload stream test"); + givenInstanceOfFusionSdk(mockServer); Assertions.assertDoesNotThrow(() -> fusion.upload( @@ -112,10 +117,6 @@ private static void givenFileReadForUpload(String fileName, String body) throws } private void givenInstanceOfFusionSdk(MockServer mockServer) { - - log.atInfo().log("Mock Server is {}", mockServer); - log.atInfo().log("Mock Server url {}", mockServer.getUrl()); - fusion = Fusion.builder() .rootURL(mockServer.getUrl() + FUSION_API_VERSION) .bearerToken("my-bearer-token") diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java index d5d438d..0bef301 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java @@ -3,8 +3,11 @@ import au.com.dius.pact.consumer.dsl.DslPart; import au.com.dius.pact.consumer.dsl.PactDslWithProvider; import au.com.dius.pact.core.model.RequestResponsePact; +import lombok.extern.slf4j.Slf4j; + import java.util.Map; +@Slf4j public class RequestResponseHelper { private static final String USER_AGENT_VAL = "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60"; @@ -51,6 +54,7 @@ public static RequestResponsePact uploadExpectation( Map headers, String body) { + log.atInfo().log("Initialising Expectation for upload"); return builder.given(given) .uponReceiving(upon) .path(path) From 3755079781f13886b04be99a4da05213f902fbc5 Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Thu, 20 Apr 2023 17:05:36 +0100 Subject: [PATCH 11/32] spotless --- .../jpmorganchase/fusion/pact/util/RequestResponseHelper.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java index 0bef301..f91d673 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java @@ -3,9 +3,8 @@ import au.com.dius.pact.consumer.dsl.DslPart; import au.com.dius.pact.consumer.dsl.PactDslWithProvider; import au.com.dius.pact.core.model.RequestResponsePact; -import lombok.extern.slf4j.Slf4j; - import java.util.Map; +import lombok.extern.slf4j.Slf4j; @Slf4j public class RequestResponseHelper { From 549f652b48a22e1b791e8212257d0fbd4c010cbc Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Thu, 20 Apr 2023 17:09:29 +0100 Subject: [PATCH 12/32] Log level to DEBUG --- src/test/resources/logback-test.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index a686e7c..584544b 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -14,7 +14,7 @@ - + From cf3de6ecc8630f125e14b4106062afb5d1a5fe68 Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Thu, 20 Apr 2023 17:17:18 +0100 Subject: [PATCH 13/32] Remove verification of User-Agent header in PACT --- .../fusion/pact/util/RequestResponseHelper.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java index f91d673..33c757c 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java @@ -8,8 +8,7 @@ @Slf4j public class RequestResponseHelper { - - private static final String USER_AGENT_VAL = "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60"; + private static final String BEARER_TOKEN = "my-bearer-token"; private static final String AUTH_VAL = "Bearer " + BEARER_TOKEN; @@ -22,7 +21,6 @@ public static RequestResponsePact getExpectation( .uponReceiving(upon) .path(path) .matchHeader("Authorization", AUTH_VAL) - .matchHeader("User-Agent", USER_AGENT_VAL) .method("GET") .willRespondWith() .status(200) @@ -36,7 +34,6 @@ public static RequestResponsePact downloadExpectation( .uponReceiving(upon) .path(path) .matchHeader("Authorization", AUTH_VAL) - .matchHeader("User-Agent", USER_AGENT_VAL) .method("GET") .willRespondWith() .status(200) From bee3e1c9042c16a1f807ac8a84930fd121385351 Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Thu, 20 Apr 2023 17:18:42 +0100 Subject: [PATCH 14/32] spotless --- .../jpmorganchase/fusion/pact/util/RequestResponseHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java index 33c757c..1ebaed7 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java @@ -8,7 +8,7 @@ @Slf4j public class RequestResponseHelper { - + private static final String BEARER_TOKEN = "my-bearer-token"; private static final String AUTH_VAL = "Bearer " + BEARER_TOKEN; From f1224b36db78ebd4b85cdc8c501324cfbb7f55fc Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Mon, 24 Apr 2023 13:02:09 +0100 Subject: [PATCH 15/32] Tidy up following github failing build --- .../fusion/pact/FusionUploadConsumerPactTest.java | 10 ---------- .../fusion/pact/util/RequestResponseHelper.java | 4 ---- src/test/resources/logback-test.xml | 2 +- 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java index 4cff01d..73afd7e 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java @@ -19,14 +19,12 @@ import java.util.HashMap; import java.util.Map; import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @ExtendWith(PactConsumerTestExt.class) -@Slf4j public class FusionUploadConsumerPactTest { private static final String FUSION_API_VERSION = "/v1/"; @@ -42,7 +40,6 @@ public RequestResponsePact uploadFile(PactDslWithProvider builder) { builder, "a distribution that is available for download", "a request is made to download the distribution", - "/v1/catalogs/common/datasets/API_TEST/authorize/token", "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220117/distributions/csv", uploadHeaders, "A,B,C"); @@ -57,7 +54,6 @@ public RequestResponsePact uploadStream(PactDslWithProvider builder) { builder, "a distribution that is available for download", "a request is made to download the distribution", - "/v1/catalogs/common/datasets/API_TEST/authorize/token", "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220117/distributions/csv", uploadHeaders, "A,B,C"); @@ -73,9 +69,6 @@ public void cleanupDirectory() { @SneakyThrows @PactTestFor(pactMethod = "uploadFile") void testUploadFile(MockServer mockServer) { - - log.atInfo().log("Executing upload file test"); - givenInstanceOfFusionSdk(mockServer); givenFileReadForUpload("/common_API_TEST_20220117.csv", "A,B,C"); @@ -93,9 +86,6 @@ void testUploadFile(MockServer mockServer) { @Test @PactTestFor(pactMethod = "uploadStream") void testUploadStream(MockServer mockServer) { - - log.atInfo().log("Executing upload stream test"); - givenInstanceOfFusionSdk(mockServer); Assertions.assertDoesNotThrow(() -> fusion.upload( diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java index 1ebaed7..e824dc8 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java @@ -4,9 +4,7 @@ import au.com.dius.pact.consumer.dsl.PactDslWithProvider; import au.com.dius.pact.core.model.RequestResponsePact; import java.util.Map; -import lombok.extern.slf4j.Slf4j; -@Slf4j public class RequestResponseHelper { private static final String BEARER_TOKEN = "my-bearer-token"; @@ -45,12 +43,10 @@ public static RequestResponsePact uploadExpectation( PactDslWithProvider builder, String given, String upon, - String authPath, String path, Map headers, String body) { - log.atInfo().log("Initialising Expectation for upload"); return builder.given(given) .uponReceiving(upon) .path(path) diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index 584544b..a686e7c 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -14,7 +14,7 @@ - + From 9213ffc42caac5539a2cd22ea8f3521b074b5761 Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Mon, 24 Apr 2023 16:17:18 +0100 Subject: [PATCH 16/32] Update Consumer Tests for FusionApi --- .../fusion/pact/util/BodyBuilders.java | 2 +- .../pact-samples/FusionSdk-FusionApi.json | 162 ++++-------------- 2 files changed, 32 insertions(+), 132 deletions(-) diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java index dc133d6..312c7f4 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java @@ -196,6 +196,6 @@ private static PactDslJsonBody header(String id, String desc, String identifier, .stringType("@id", id) .stringType("description", desc) .stringType("identifier", identifier) - .stringType("Title", title); + .stringType("title", title); } } diff --git a/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/FusionSdk-FusionApi.json b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/FusionSdk-FusionApi.json index 197469a..bbb7047 100644 --- a/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/FusionSdk-FusionApi.json +++ b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/FusionSdk-FusionApi.json @@ -12,8 +12,7 @@ "method": "GET", "path": "/v1/catalogs/common/datasets/GFI_OP_CF", "headers": { - "Authorization": "Bearer my-bearer-token", - "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + "Authorization": "Bearer my-bearer-token" }, "matchingRules": { "header": { @@ -25,15 +24,6 @@ } ], "combine": "AND" - }, - "User-Agent": { - "matchers": [ - { - "match": "regex", - "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" - } - ], - "combine": "AND" } } } @@ -52,7 +42,6 @@ "isRawData": false, "isInternalOnlyDataset": false, "description": "Premium, volatility, and greeks for EUR", - "Title": "Swaptions Caps & Floors", "resources": [ { "identifier": "datasetseries", @@ -66,15 +55,16 @@ "string", "string" ], + "title": "Swaptions Caps & Floors", "@context": { "@base": "https://fusion-api.test.aws.jpmchase.net/v1", "@vocab": "https://www.w3.org/ns/dcat3.jsondld" }, "maintainer": "J.P. Morgan DM Rates Research", "frequency": "Daily", - "createdDate": "2023-04-20", + "createdDate": "2023-04-24", "isThirdPartyData": false, - "modifiedDate": "2023-04-20", + "modifiedDate": "2023-04-24", "publisher": "J.P. Morgan", "@id": "GFI_OP_CF/", "tag": [ @@ -134,7 +124,7 @@ ], "combine": "AND" }, - "$.Title": { + "$.title": { "matchers": [ { "match": "type" @@ -408,8 +398,7 @@ "method": "GET", "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220116/distributions/csv", "headers": { - "Authorization": "Bearer my-bearer-token", - "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + "Authorization": "Bearer my-bearer-token" }, "matchingRules": { "header": { @@ -421,15 +410,6 @@ } ], "combine": "AND" - }, - "User-Agent": { - "matchers": [ - { - "match": "regex", - "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" - } - ], - "combine": "AND" } } } @@ -450,8 +430,7 @@ "method": "GET", "path": "/v1/catalogs/common/datasets/API_TEST/attributes", "headers": { - "Authorization": "Bearer my-bearer-token", - "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + "Authorization": "Bearer my-bearer-token" }, "matchingRules": { "header": { @@ -463,15 +442,6 @@ } ], "combine": "AND" - }, - "User-Agent": { - "matchers": [ - { - "match": "regex", - "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" - } - ], - "combine": "AND" } } } @@ -484,7 +454,6 @@ "body": { "identifier": "attributes", "description": "A list of available attributes", - "Title": "Attributes", "resources": [ { "identifier": "A", @@ -499,6 +468,7 @@ } ], "@id": "attributes/", + "title": "Attributes", "@context": { "@base": "https://fusion-api.test.aws.jpmchase.net/v1", "@vocab": "https://www.w3.org/ns/dcat3.jsondld" @@ -546,7 +516,7 @@ ], "combine": "AND" }, - "$.Title": { + "$.title": { "matchers": [ { "match": "type" @@ -661,8 +631,7 @@ "method": "GET", "path": "/v1/catalogs/common", "headers": { - "Authorization": "Bearer my-bearer-token", - "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + "Authorization": "Bearer my-bearer-token" }, "matchingRules": { "header": { @@ -674,15 +643,6 @@ } ], "combine": "AND" - }, - "User-Agent": { - "matchers": [ - { - "match": "regex", - "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" - } - ], - "combine": "AND" } } } @@ -695,7 +655,6 @@ "body": { "identifier": "common", "description": "A catalog of common data", - "Title": "Common data catalog", "resources": [ { "identifier": "datasets", @@ -705,6 +664,7 @@ } ], "@id": "common", + "title": "Common data catalog", "@context": { "@base": "https://fusion-api.test.aws.jpmchase.net/v1", "@vocab": "https://www.w3.org/ns/dcat3.jsondld" @@ -752,7 +712,7 @@ ], "combine": "AND" }, - "$.Title": { + "$.title": { "matchers": [ { "match": "type" @@ -827,8 +787,7 @@ "method": "GET", "path": "/v1/catalogs", "headers": { - "Authorization": "Bearer my-bearer-token", - "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + "Authorization": "Bearer my-bearer-token" }, "matchingRules": { "header": { @@ -840,15 +799,6 @@ } ], "combine": "AND" - }, - "User-Agent": { - "matchers": [ - { - "match": "regex", - "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" - } - ], - "combine": "AND" } } } @@ -861,7 +811,6 @@ "body": { "identifier": "catalogs", "description": "A list of available catalogs, catalogs", - "Title": "Catalogs", "resources": [ { "identifier": "common", @@ -871,6 +820,7 @@ } ], "@id": "catalogs/", + "title": "Catalogs", "@context": { "@base": "https://fusion-api.test.aws.jpmchase.net/v1", "@vocab": "https://www.w3.org/ns/dcat3.jsondld" @@ -918,7 +868,7 @@ ], "combine": "AND" }, - "$.Title": { + "$.title": { "matchers": [ { "match": "type" @@ -992,8 +942,7 @@ "method": "GET", "path": "/v1/catalogs/common/products", "headers": { - "Authorization": "Bearer my-bearer-token", - "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + "Authorization": "Bearer my-bearer-token" }, "matchingRules": { "header": { @@ -1005,15 +954,6 @@ } ], "combine": "AND" - }, - "User-Agent": { - "matchers": [ - { - "match": "regex", - "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" - } - ], - "combine": "AND" } } } @@ -1026,7 +966,6 @@ "body": { "identifier": "products", "description": "A list of available products", - "Title": "Products", "resources": [ { "identifier": "ESG00008", @@ -1035,7 +974,7 @@ "string" ], "datasetCount": 18, - "releaseDate": "2023-04-20", + "releaseDate": "2023-04-24", "deliveryChannel": [ "string", "string" @@ -1068,6 +1007,7 @@ } ], "@id": "products/", + "title": "Products", "@context": { "@base": "https://fusion-api.test.aws.jpmchase.net/v1", "@vocab": "https://www.w3.org/ns/dcat3.jsondld" @@ -1115,7 +1055,7 @@ ], "combine": "AND" }, - "$.Title": { + "$.title": { "matchers": [ { "match": "type" @@ -1385,8 +1325,7 @@ "method": "GET", "path": "/v1/catalogs/common/datasets", "headers": { - "Authorization": "Bearer my-bearer-token", - "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + "Authorization": "Bearer my-bearer-token" }, "matchingRules": { "header": { @@ -1398,15 +1337,6 @@ } ], "combine": "AND" - }, - "User-Agent": { - "matchers": [ - { - "match": "regex", - "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" - } - ], - "combine": "AND" } } } @@ -1419,7 +1349,6 @@ "body": { "identifier": "datasets", "description": "A list of available datasets", - "Title": "Datasets", "resources": [ { "identifier": "GFI_OP_CF", @@ -1438,9 +1367,9 @@ "title": "Swaptions Caps & Floors", "maintainer": "J.P. Morgan DM Rates Research", "frequency": "Daily", - "createdDate": "2023-04-20", + "createdDate": "2023-04-24", "isThirdPartyData": false, - "modifiedDate": "2023-04-20", + "modifiedDate": "2023-04-24", "publisher": "J.P. Morgan", "tag": [ "string", @@ -1460,6 +1389,7 @@ } ], "@id": "datasets/", + "title": "Datasets", "@context": { "@base": "https://fusion-api.test.aws.jpmchase.net/v1", "@vocab": "https://www.w3.org/ns/dcat3.jsondld" @@ -1507,7 +1437,7 @@ ], "combine": "AND" }, - "$.Title": { + "$.title": { "matchers": [ { "match": "type" @@ -1781,8 +1711,7 @@ "method": "GET", "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220116/distributions", "headers": { - "Authorization": "Bearer my-bearer-token", - "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + "Authorization": "Bearer my-bearer-token" }, "matchingRules": { "header": { @@ -1794,15 +1723,6 @@ } ], "combine": "AND" - }, - "User-Agent": { - "matchers": [ - { - "match": "regex", - "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" - } - ], - "combine": "AND" } } } @@ -1815,7 +1735,6 @@ "body": { "identifier": "distributions", "description": "A list of available distributions", - "Title": "Distributions", "resources": [ { "identifier": "csv", @@ -1827,6 +1746,7 @@ } ], "@id": "distributions/", + "title": "Distributions", "@context": { "@base": "https://fusion-api.test.aws.jpmchase.net/v1", "@vocab": "https://www.w3.org/ns/dcat3.jsondld" @@ -1874,7 +1794,7 @@ ], "combine": "AND" }, - "$.Title": { + "$.title": { "matchers": [ { "match": "type" @@ -1965,8 +1885,7 @@ "method": "GET", "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries", "headers": { - "Authorization": "Bearer my-bearer-token", - "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + "Authorization": "Bearer my-bearer-token" }, "matchingRules": { "header": { @@ -1978,15 +1897,6 @@ } ], "combine": "AND" - }, - "User-Agent": { - "matchers": [ - { - "match": "regex", - "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" - } - ], - "combine": "AND" } } } @@ -1999,7 +1909,6 @@ "body": { "identifier": "datasetseries", "description": "A list of available datasetseries of a dataset", - "Title": "DatasetSeries", "resources": [ { "fromDate": "2023-03-18", @@ -2010,6 +1919,7 @@ } ], "@id": "datasetseries/", + "title": "DatasetSeries", "@context": { "@base": "https://fusion-api.test.aws.jpmchase.net/v1", "@vocab": "https://www.w3.org/ns/dcat3.jsondld" @@ -2057,7 +1967,7 @@ ], "combine": "AND" }, - "$.Title": { + "$.title": { "matchers": [ { "match": "type" @@ -2143,8 +2053,7 @@ "method": "GET", "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/20230319", "headers": { - "Authorization": "Bearer my-bearer-token", - "User-Agent": "fusion-java-sdk/UNPACKAGED (JdkClient) Java/1.8.0_60" + "Authorization": "Bearer my-bearer-token" }, "matchingRules": { "header": { @@ -2156,15 +2065,6 @@ } ], "combine": "AND" - }, - "User-Agent": { - "matchers": [ - { - "match": "regex", - "regex": "fusion-java-sdk/UNPACKAGED \\(JdkClient\\) Java/1\\.8\\.0_60" - } - ], - "combine": "AND" } } } From a50fe6324246b5e3d9289e67c7d6d6c1eaa3576b Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Mon, 1 May 2023 10:46:36 +0100 Subject: [PATCH 17/32] Updating PACT tests to align to provider --- .../pact/FusionApiConsumerPactTest.java | 24 +++++++++---------- .../fusion/pact/util/BodyBuilders.java | 3 +-- .../pact/util/RequestResponseHelper.java | 12 ++++++++-- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java index ef731e7..f6c4ca4 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java @@ -96,8 +96,8 @@ public RequestResponsePact getDatasetMemberResources(PactDslWithProvider builder return getExpectation( builder, "metadata for a dataset series member", - "a request dataset series member metadata", - "/v1/catalogs/common/datasets/API_TEST/datasetseries/20230319", + "a request for dataset series member metadata", + "/v1/catalogs/common/datasets/API_TEST/datasetseries/2022-01-16", datasetMemberResources()); } @@ -108,7 +108,7 @@ public RequestResponsePact listAttributes(PactDslWithProvider builder) { "a list of attributes for a dataset in a catalog", "a request for a list of attributes from a dataset", "/v1/catalogs/common/datasets/API_TEST/attributes", - attributes()); + attributes(), "application/ld\\+json"); } @Pact(provider = "FusionApi", consumer = "FusionSdk") @@ -117,7 +117,7 @@ public RequestResponsePact listDistributions(PactDslWithProvider builder) { builder, "a list of distributions available for a series member", "a request for distributions available for a series member", - "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220116/distributions", + "/v1/catalogs/common/datasets/API_TEST/datasetseries/2022-01-16/distributions", distributions()); } @@ -127,14 +127,14 @@ public RequestResponsePact download(PactDslWithProvider builder) { builder, "a distribution that is available for download", "a request is made to download the distribution", - "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220116/distributions/csv", + "/v1/catalogs/common/datasets/API_TEST/datasetseries/2022-01-16/distributions/csv", "A,B,C"); } @AfterEach @SneakyThrows public void cleanupDirectory() { - Files.deleteIfExists(Paths.get("downloads/common_API_TEST_20220116.csv")); + Files.deleteIfExists(Paths.get("downloads/common_API_TEST_2022-01-16.csv")); } @Test @@ -274,7 +274,7 @@ void testDatasetMemberResources(MockServer mockServer) { givenInstanceOfFusionSdk(mockServer); Map> datasetMemberResources = - fusion.datasetMemberResources("common", "API_TEST", "20230319"); + fusion.datasetMemberResources("common", "API_TEST", "2022-01-16"); assertThat("dataset member resources must not be empty", datasetMemberResources, Is.is(notNullValue())); assertThat( @@ -327,7 +327,7 @@ void testListAttributeResources(MockServer mockServer) { assertThat("attribute resources expected to contain key", resources.containsKey("A"), is(true)); Map resource = resources.get("A"); - assertThat("attribute resource id is incorrect", resource.get("id"), is(equalTo("4000003"))); + assertThat("attribute resource id is incorrect", String.valueOf(resource.get("id")), is(equalTo("4000003.0"))); assertThat("attribute resource identifier is incorrect", resource.get("identifier"), is(equalTo("A"))); assertThat("attribute resource source is incorrect", resource.get("source"), is(equalTo("Data Query"))); assertThat("attribute resource dataType is incorrect", resource.get("dataType"), is(equalTo("String"))); @@ -351,7 +351,7 @@ void testListDistributions(MockServer mockServer) { givenInstanceOfFusionSdk(mockServer); - Map distributions = fusion.listDistributions("common", "API_TEST", "20220116"); + Map distributions = fusion.listDistributions("common", "API_TEST", "2022-01-16"); assertThat("distributions must not be empty", distributions, Is.is(notNullValue())); assertThat("distributions expected to contain key", distributions.containsKey("csv"), is(true)); @@ -378,9 +378,9 @@ void testDownload(MockServer mockServer) { givenInstanceOfFusionSdk(mockServer); - fusion.download("common", "API_TEST", "20220116", "csv"); + fusion.download("common", "API_TEST", "2022-01-16", "csv"); - thenTheFileShouldBeDownloaded("downloads/common_API_TEST_20220116.csv"); + thenTheFileShouldBeDownloaded("downloads/common_API_TEST_2022-01-16.csv"); thenTheFileContentsShouldBeEqualTo("A,B,C"); } @@ -390,7 +390,7 @@ void testDownloadStream(MockServer mockServer) { givenInstanceOfFusionSdk(mockServer); - downloadedFileInputStream = fusion.downloadStream("common", "API_TEST", "20220116", "csv"); + downloadedFileInputStream = fusion.downloadStream("common", "API_TEST", "2022-01-16", "csv"); thenTheFileContentsShouldBeEqualTo("A,B,C"); } diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java index 312c7f4..eeaba11 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java @@ -73,7 +73,6 @@ public static DslPart datasets() { .booleanType("isThirdPartyData", false) .booleanType("isInternalOnlyDataset", false) .stringType("language", "English") - .stringType("maintainer", "J.P. Morgan DM Rates Research") .date("modifiedDate", "yyyy-MM-dd", Date.from(Instant.now())) .stringType("publisher", "J.P. Morgan") .minArrayLike("region", 0, stringType()) @@ -157,7 +156,7 @@ public static DslPart attributes() { return header("attributes/", "A list of available attributes", "attributes", "Attributes") .minArrayLike("resources", 1) .stringType("identifier", "A") - .stringType("id", "4000003") + .integerType("id", 4000003) .stringType("source", "Data Query") .stringType("dataType", "String") .stringType("description", "Description for attribute A") diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java index e824dc8..253d5d7 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java @@ -3,6 +3,8 @@ import au.com.dius.pact.consumer.dsl.DslPart; import au.com.dius.pact.consumer.dsl.PactDslWithProvider; import au.com.dius.pact.core.model.RequestResponsePact; + +import java.util.HashMap; import java.util.Map; public class RequestResponseHelper { @@ -14,7 +16,7 @@ private RequestResponseHelper() {} ; public static RequestResponsePact getExpectation( - PactDslWithProvider builder, String given, String upon, String path, DslPart body) { + PactDslWithProvider builder, String given, String upon, String path, DslPart body, String contentType) { return builder.given(given) .uponReceiving(upon) .path(path) @@ -22,10 +24,16 @@ public static RequestResponsePact getExpectation( .method("GET") .willRespondWith() .status(200) + .matchHeader("Content-Type", contentType) .body(body) .toPact(); } + public static RequestResponsePact getExpectation( + PactDslWithProvider builder, String given, String upon, String path, DslPart body) { + return getExpectation(builder, given, upon, path, body, "application/json"); + } + public static RequestResponsePact downloadExpectation( PactDslWithProvider builder, String given, String upon, String path, String body) { return builder.given(given) @@ -35,7 +43,7 @@ public static RequestResponsePact downloadExpectation( .method("GET") .willRespondWith() .status(200) - .body(body) + .body(body, "text/csv") .toPact(); } From 3d1e11c886a94c62b17597154ab41a029d4a0308 Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Mon, 1 May 2023 10:50:54 +0100 Subject: [PATCH 18/32] Updating PACT tests to align to provider --- .../pact-samples/FusionSdk-FusionApi.json | 400 ++++++++++++------ 1 file changed, 281 insertions(+), 119 deletions(-) diff --git a/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/FusionSdk-FusionApi.json b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/FusionSdk-FusionApi.json index bbb7047..f30f837 100644 --- a/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/FusionSdk-FusionApi.json +++ b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/FusionSdk-FusionApi.json @@ -31,7 +31,7 @@ "response": { "status": 200, "headers": { - "Content-Type": "application/json; charset=UTF-8" + "Content-Type": "application/json" }, "body": { "identifier": "GFI_OP_CF", @@ -62,9 +62,9 @@ }, "maintainer": "J.P. Morgan DM Rates Research", "frequency": "Daily", - "createdDate": "2023-04-24", + "createdDate": "2023-05-01", "isThirdPartyData": false, - "modifiedDate": "2023-04-24", + "modifiedDate": "2023-05-01", "publisher": "J.P. Morgan", "@id": "GFI_OP_CF/", "tag": [ @@ -83,6 +83,17 @@ "isRestricted": false }, "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, "body": { "$.@context.@vocab": { "matchers": [ @@ -348,17 +359,6 @@ ], "combine": "AND" } - }, - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json(;\\s?charset=[\\w\\-]+)?" - } - ], - "combine": "AND" - } } }, "generators": { @@ -396,7 +396,7 @@ "description": "a request is made to download the distribution", "request": { "method": "GET", - "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220116/distributions/csv", + "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/2022-01-16/distributions/csv", "headers": { "Authorization": "Bearer my-bearer-token" }, @@ -416,6 +416,9 @@ }, "response": { "status": 200, + "headers": { + "Content-Type": "text/csv" + }, "body": "A,B,C" }, "providerStates": [ @@ -449,7 +452,7 @@ "response": { "status": 200, "headers": { - "Content-Type": "application/json; charset=UTF-8" + "Content-Type": "application/ld+json" }, "body": { "identifier": "attributes", @@ -462,7 +465,7 @@ "sourceFieldId": "a_source_field", "description": "Description for attribute A", "index": 1, - "id": "4000003", + "id": 4000003, "source": "Data Query", "title": "A" } @@ -475,6 +478,17 @@ } }, "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/ld\\+json" + } + ], + "combine": "AND" + } + }, "body": { "$.@context.@vocab": { "matchers": [ @@ -544,7 +558,7 @@ "$.resources[*].id": { "matchers": [ { - "match": "type" + "match": "integer" } ], "combine": "AND" @@ -605,17 +619,6 @@ ], "combine": "AND" } - }, - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json(;\\s?charset=[\\w\\-]+)?" - } - ], - "combine": "AND" - } } } }, @@ -650,7 +653,7 @@ "response": { "status": 200, "headers": { - "Content-Type": "application/json; charset=UTF-8" + "Content-Type": "application/json" }, "body": { "identifier": "common", @@ -671,6 +674,17 @@ } }, "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, "body": { "$.@context.@vocab": { "matchers": [ @@ -761,17 +775,6 @@ ], "combine": "AND" } - }, - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json(;\\s?charset=[\\w\\-]+)?" - } - ], - "combine": "AND" - } } } }, @@ -806,7 +809,7 @@ "response": { "status": 200, "headers": { - "Content-Type": "application/json; charset=UTF-8" + "Content-Type": "application/json" }, "body": { "identifier": "catalogs", @@ -827,6 +830,17 @@ } }, "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, "body": { "$.@context.@vocab": { "matchers": [ @@ -916,17 +930,6 @@ ], "combine": "AND" } - }, - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json(;\\s?charset=[\\w\\-]+)?" - } - ], - "combine": "AND" - } } } }, @@ -961,7 +964,7 @@ "response": { "status": 200, "headers": { - "Content-Type": "application/json; charset=UTF-8" + "Content-Type": "application/json" }, "body": { "identifier": "products", @@ -974,7 +977,7 @@ "string" ], "datasetCount": 18, - "releaseDate": "2023-04-24", + "releaseDate": "2023-05-01", "deliveryChannel": [ "string", "string" @@ -1014,6 +1017,17 @@ } }, "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, "body": { "$.@context.@vocab": { "matchers": [ @@ -1271,17 +1285,6 @@ ], "combine": "AND" } - }, - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json(;\\s?charset=[\\w\\-]+)?" - } - ], - "combine": "AND" - } } }, "generators": { @@ -1344,7 +1347,7 @@ "response": { "status": 200, "headers": { - "Content-Type": "application/json; charset=UTF-8" + "Content-Type": "application/json" }, "body": { "identifier": "datasets", @@ -1365,11 +1368,10 @@ "string" ], "title": "Swaptions Caps & Floors", - "maintainer": "J.P. Morgan DM Rates Research", "frequency": "Daily", - "createdDate": "2023-04-24", + "createdDate": "2023-05-01", "isThirdPartyData": false, - "modifiedDate": "2023-04-24", + "modifiedDate": "2023-05-01", "publisher": "J.P. Morgan", "tag": [ "string", @@ -1396,6 +1398,17 @@ } }, "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, "body": { "$.@context.@vocab": { "matchers": [ @@ -1528,14 +1541,6 @@ ], "combine": "AND" }, - "$.resources[*].maintainer": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, "$.resources[*].modifiedDate": { "matchers": [ { @@ -1661,17 +1666,6 @@ ], "combine": "AND" } - }, - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json(;\\s?charset=[\\w\\-]+)?" - } - ], - "combine": "AND" - } } }, "generators": { @@ -1709,7 +1703,7 @@ "description": "a request for distributions available for a series member", "request": { "method": "GET", - "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/20220116/distributions", + "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/2022-01-16/distributions", "headers": { "Authorization": "Bearer my-bearer-token" }, @@ -1730,7 +1724,7 @@ "response": { "status": 200, "headers": { - "Content-Type": "application/json; charset=UTF-8" + "Content-Type": "application/json" }, "body": { "identifier": "distributions", @@ -1753,6 +1747,17 @@ } }, "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, "body": { "$.@context.@vocab": { "matchers": [ @@ -1859,17 +1864,6 @@ ], "combine": "AND" } - }, - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json(;\\s?charset=[\\w\\-]+)?" - } - ], - "combine": "AND" - } } } }, @@ -1904,7 +1898,7 @@ "response": { "status": 200, "headers": { - "Content-Type": "application/json; charset=UTF-8" + "Content-Type": "application/json" }, "body": { "identifier": "datasetseries", @@ -1926,6 +1920,17 @@ } }, "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, "body": { "$.@context.@vocab": { "matchers": [ @@ -2027,13 +2032,170 @@ ], "combine": "AND" } + } + } + }, + "providerStates": [ + { + "name": "a list of series members for a dataset" + } + ] + }, + { + "description": "a request dataset series member metadata", + "request": { + "method": "GET", + "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/20230319", + "headers": { + "Authorization": "Bearer my-bearer-token" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" }, + "@id": "20230319/", + "createdDate": "2023-03-19", + "fromDate": "2023-03-18", + "identifier": "20230319", + "resources": [ + { + "@id": "distributions/", + "description": "A list of available distributions", + "identifier": "distributions", + "title": "Distributions" + } + ], + "toDate": "2023-03-17" + }, + "matchingRules": { "header": { "Content-Type": { "matchers": [ { "match": "regex", - "regex": "application/json(;\\s?charset=[\\w\\-]+)?" + "regex": "application/json" + } + ], + "combine": "AND" + } + }, + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 1 + } + ], + "combine": "AND" + }, + "$.resources[*].@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.createdDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.fromDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.toDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" } ], "combine": "AND" @@ -2043,15 +2205,15 @@ }, "providerStates": [ { - "name": "a list of series members for a dataset" + "name": "metadata for a dataset series member" } ] }, { - "description": "a request dataset series member metadata", + "description": "a request for dataset series member metadata", "request": { "method": "GET", - "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/20230319", + "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/2022-01-16", "headers": { "Authorization": "Bearer my-bearer-token" }, @@ -2072,7 +2234,7 @@ "response": { "status": 200, "headers": { - "Content-Type": "application/json; charset=UTF-8" + "Content-Type": "application/json" }, "body": { "fromDate": "2023-03-18", @@ -2094,6 +2256,17 @@ } }, "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, "body": { "$.@context.@vocab": { "matchers": [ @@ -2195,17 +2368,6 @@ ], "combine": "AND" } - }, - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json(;\\s?charset=[\\w\\-]+)?" - } - ], - "combine": "AND" - } } } }, From 8f55772180e8b26544d445c3f574f345ecd522a2 Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Mon, 1 May 2023 11:09:27 +0100 Subject: [PATCH 19/32] spotless corrections --- .../jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java | 3 ++- .../jpmorganchase/fusion/pact/util/RequestResponseHelper.java | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java index f6c4ca4..85350c4 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java @@ -108,7 +108,8 @@ public RequestResponsePact listAttributes(PactDslWithProvider builder) { "a list of attributes for a dataset in a catalog", "a request for a list of attributes from a dataset", "/v1/catalogs/common/datasets/API_TEST/attributes", - attributes(), "application/ld\\+json"); + attributes(), + "application/ld\\+json"); } @Pact(provider = "FusionApi", consumer = "FusionSdk") diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java index 253d5d7..1614d4a 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java @@ -3,8 +3,6 @@ import au.com.dius.pact.consumer.dsl.DslPart; import au.com.dius.pact.consumer.dsl.PactDslWithProvider; import au.com.dius.pact.core.model.RequestResponsePact; - -import java.util.HashMap; import java.util.Map; public class RequestResponseHelper { From e43543d4c3e1c663aa91261c1f493805dc760160 Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Mon, 1 May 2023 12:11:57 +0100 Subject: [PATCH 20/32] Updated provider and consumer ids --- .../pact/FusionApiConsumerPactTest.java | 20 +++++++++---------- .../pact/FusionUploadConsumerPactTest.java | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java index 85350c4..e4fa561 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java @@ -35,13 +35,13 @@ public class FusionApiConsumerPactTest { Fusion fusion; InputStream downloadedFileInputStream; - @Pact(provider = "FusionApi", consumer = "FusionSdk") + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact listCatalogs(PactDslWithProvider builder) { return getExpectation( builder, "a list of catalogs", "a request for available catalogs", "/v1/catalogs", catalogs()); } - @Pact(provider = "FusionApi", consumer = "FusionSdk") + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact getCatalogResources(PactDslWithProvider builder) { return getExpectation( builder, @@ -51,7 +51,7 @@ public RequestResponsePact getCatalogResources(PactDslWithProvider builder) { catalogResources()); } - @Pact(provider = "FusionApi", consumer = "FusionSdk") + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact listProducts(PactDslWithProvider builder) { return getExpectation( builder, @@ -61,7 +61,7 @@ public RequestResponsePact listProducts(PactDslWithProvider builder) { products()); } - @Pact(provider = "FusionApi", consumer = "FusionSdk") + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact listDatasets(PactDslWithProvider builder) { return getExpectation( builder, @@ -71,7 +71,7 @@ public RequestResponsePact listDatasets(PactDslWithProvider builder) { datasets()); } - @Pact(provider = "FusionApi", consumer = "FusionSdk") + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact getDatasetResources(PactDslWithProvider builder) { return getExpectation( builder, @@ -81,7 +81,7 @@ public RequestResponsePact getDatasetResources(PactDslWithProvider builder) { datasetResource()); } - @Pact(provider = "FusionApi", consumer = "FusionSdk") + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact listDatasetMembers(PactDslWithProvider builder) { return getExpectation( builder, @@ -91,7 +91,7 @@ public RequestResponsePact listDatasetMembers(PactDslWithProvider builder) { datasetMembers()); } - @Pact(provider = "FusionApi", consumer = "FusionSdk") + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact getDatasetMemberResources(PactDslWithProvider builder) { return getExpectation( builder, @@ -101,7 +101,7 @@ public RequestResponsePact getDatasetMemberResources(PactDslWithProvider builder datasetMemberResources()); } - @Pact(provider = "FusionApi", consumer = "FusionSdk") + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact listAttributes(PactDslWithProvider builder) { return getExpectation( builder, @@ -112,7 +112,7 @@ public RequestResponsePact listAttributes(PactDslWithProvider builder) { "application/ld\\+json"); } - @Pact(provider = "FusionApi", consumer = "FusionSdk") + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact listDistributions(PactDslWithProvider builder) { return getExpectation( builder, @@ -122,7 +122,7 @@ public RequestResponsePact listDistributions(PactDslWithProvider builder) { distributions()); } - @Pact(provider = "FusionApi", consumer = "FusionSdk") + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact download(PactDslWithProvider builder) { return downloadExpectation( builder, diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java index 73afd7e..c192bf6 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java @@ -31,7 +31,7 @@ public class FusionUploadConsumerPactTest { Fusion fusion; - @Pact(provider = "FusionUpload", consumer = "FusionSdk") + @Pact(provider = "10274-fusionupload-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact uploadFile(PactDslWithProvider builder) { Map uploadHeaders = givenUploadHeaders( @@ -45,7 +45,7 @@ public RequestResponsePact uploadFile(PactDslWithProvider builder) { "A,B,C"); } - @Pact(provider = "FusionUpload", consumer = "FusionSdk") + @Pact(provider = "10274-fusionupload-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact uploadStream(PactDslWithProvider builder) { Map uploadHeaders = givenUploadHeaders( From 2e6f00f41180e9a48e4d7ec1bdc4880dc97bf56a Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Mon, 1 May 2023 12:16:50 +0100 Subject: [PATCH 21/32] Updated PACT Samples --- ...consumer-10274-fusionupload-provider.json} | 4 +- ...k-consumer-110274-fusionapi-provider.json} | 172 +----------------- 2 files changed, 4 insertions(+), 172 deletions(-) rename src/test/resources/io/github/jpmorganchase/fusion/pact-samples/{FusionSdk-FusionUpload.json => 110274-fusionsdk-consumer-10274-fusionupload-provider.json} (96%) rename src/test/resources/io/github/jpmorganchase/fusion/pact-samples/{FusionSdk-FusionApi.json => 110274-fusionsdk-consumer-110274-fusionapi-provider.json} (92%) diff --git a/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/FusionSdk-FusionUpload.json b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-10274-fusionupload-provider.json similarity index 96% rename from src/test/resources/io/github/jpmorganchase/fusion/pact-samples/FusionSdk-FusionUpload.json rename to src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-10274-fusionupload-provider.json index b25f921..66282e4 100644 --- a/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/FusionSdk-FusionUpload.json +++ b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-10274-fusionupload-provider.json @@ -1,9 +1,9 @@ { "provider": { - "name": "FusionUpload" + "name": "10274-fusionupload-provider" }, "consumer": { - "name": "FusionSdk" + "name": "110274-fusionsdk-consumer" }, "interactions": [ { diff --git a/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/FusionSdk-FusionApi.json b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json similarity index 92% rename from src/test/resources/io/github/jpmorganchase/fusion/pact-samples/FusionSdk-FusionApi.json rename to src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json index f30f837..113f4c4 100644 --- a/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/FusionSdk-FusionApi.json +++ b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json @@ -1,9 +1,9 @@ { "provider": { - "name": "FusionApi" + "name": "110274-fusionapi-provider" }, "consumer": { - "name": "FusionSdk" + "name": "110274-fusionsdk-consumer" }, "interactions": [ { @@ -2041,174 +2041,6 @@ } ] }, - { - "description": "a request dataset series member metadata", - "request": { - "method": "GET", - "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/20230319", - "headers": { - "Authorization": "Bearer my-bearer-token" - }, - "matchingRules": { - "header": { - "Authorization": { - "matchers": [ - { - "match": "regex", - "regex": "Bearer my-bearer-token" - } - ], - "combine": "AND" - } - } - } - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/json" - }, - "body": { - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - }, - "@id": "20230319/", - "createdDate": "2023-03-19", - "fromDate": "2023-03-18", - "identifier": "20230319", - "resources": [ - { - "@id": "distributions/", - "description": "A list of available distributions", - "identifier": "distributions", - "title": "Distributions" - } - ], - "toDate": "2023-03-17" - }, - "matchingRules": { - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json" - } - ], - "combine": "AND" - } - }, - "body": { - "$.@context.@vocab": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@context.@base": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources": { - "matchers": [ - { - "match": "type", - "min": 1 - } - ], - "combine": "AND" - }, - "$.resources[*].@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].description": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].title": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.createdDate": { - "matchers": [ - { - "match": "date", - "format": "yyyy-MM-dd" - } - ], - "combine": "AND" - }, - "$.fromDate": { - "matchers": [ - { - "match": "date", - "format": "yyyy-MM-dd" - } - ], - "combine": "AND" - }, - "$.toDate": { - "matchers": [ - { - "match": "date", - "format": "yyyy-MM-dd" - } - ], - "combine": "AND" - } - } - } - }, - "providerStates": [ - { - "name": "metadata for a dataset series member" - } - ] - }, { "description": "a request for dataset series member metadata", "request": { From ee3e2f62d2e7454da48bda9261938ffd124f7842 Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Mon, 1 May 2023 17:03:47 +0100 Subject: [PATCH 22/32] Added some negative test cases for PACT --- .../pact/FusionApiConsumerPactTest.java | 164 ++++++++++++++++-- .../pact/FusionUploadConsumerPactTest.java | 2 +- .../fusion/pact/util/BodyBuilders.java | 38 ++++ .../pact/util/RequestResponseHelper.java | 32 ++++ ...onsumer-110274-fusionupload-provider.json} | 2 +- 5 files changed, 221 insertions(+), 17 deletions(-) rename src/test/resources/io/github/jpmorganchase/fusion/pact-samples/{110274-fusionsdk-consumer-10274-fusionupload-provider.json => 110274-fusionsdk-consumer-110274-fusionupload-provider.json} (98%) diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java index e4fa561..1e89b3e 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java @@ -1,8 +1,7 @@ package io.github.jpmorganchase.fusion.pact; import static io.github.jpmorganchase.fusion.pact.util.BodyBuilders.*; -import static io.github.jpmorganchase.fusion.pact.util.RequestResponseHelper.downloadExpectation; -import static io.github.jpmorganchase.fusion.pact.util.RequestResponseHelper.getExpectation; +import static io.github.jpmorganchase.fusion.pact.util.RequestResponseHelper.*; import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.greaterThanOrEqualTo; @@ -14,6 +13,7 @@ import au.com.dius.pact.core.model.RequestResponsePact; import au.com.dius.pact.core.model.annotations.Pact; import io.github.jpmorganchase.fusion.Fusion; +import io.github.jpmorganchase.fusion.api.APICallException; import io.github.jpmorganchase.fusion.model.*; import io.github.jpmorganchase.fusion.pact.util.FileHelper; import java.io.InputStream; @@ -21,9 +21,12 @@ import java.nio.file.Paths; import java.time.LocalDate; import java.util.Map; + +import io.github.jpmorganchase.fusion.parsing.ParsingException; import lombok.SneakyThrows; import org.hamcrest.core.Is; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -38,29 +41,75 @@ public class FusionApiConsumerPactTest { @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact listCatalogs(PactDslWithProvider builder) { return getExpectation( - builder, "a list of catalogs", "a request for available catalogs", "/v1/catalogs", catalogs()); + builder, + "catalogs are available", + "a request for catalogs", + "/v1/catalogs", + catalogs()); + } + + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") + public RequestResponsePact listCatalogsWhenNoneAreAvailable(PactDslWithProvider builder) { + return getExpectation( + builder, + "no catalogs are available", + "a request for catalogs", + "/v1/catalogs", + noCatalogs()); + } + + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") + public RequestResponsePact listCatalogsWhenNotAuthorized(PactDslWithProvider builder) { + return failedGetExpectation( + builder, + "not authorized to list catalogs", + "a request for catalogs", + "/v1/catalogs", + 401); } @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact getCatalogResources(PactDslWithProvider builder) { return getExpectation( builder, - "a list of catalogs resources", - "a request for catalogs resources", + "catalog resources exist", + "a request for catalog resources", "/v1/catalogs/common", catalogResources()); } + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") + public RequestResponsePact getCatalogResourcesWhenCatalogNotFound(PactDslWithProvider builder) { + return failedGetExpectation( + builder, + "a catalog that does not exist", + "a request for that catalogs resources", + "/v1/catalogs/alternate", + "Not Found", + 404 + ); + } + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact listProducts(PactDslWithProvider builder) { return getExpectation( builder, - "a list of data products", + "data products exist", "a request for a list of data products", "/v1/catalogs/common/products", products()); } + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") + public RequestResponsePact listProductsWhenNoneExist(PactDslWithProvider builder) { + return getExpectation( + builder, + "no data products exist", + "a request for a list of data products", + "/v1/catalogs/common/products", + noProducts()); + } + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact listDatasets(PactDslWithProvider builder) { return getExpectation( @@ -71,12 +120,22 @@ public RequestResponsePact listDatasets(PactDslWithProvider builder) { datasets()); } + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") + public RequestResponsePact listDatasetsWhenNoneExist(PactDslWithProvider builder) { + return getExpectation( + builder, + "no datasets exist", + "a request for a list of datasets", + "/v1/catalogs/common/datasets", + noDatasets()); + } + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact getDatasetResources(PactDslWithProvider builder) { return getExpectation( builder, - "a dataset resource", - "a request for a dataset resource", + "dataset resources are available", + "a request for a dataset resources", "/v1/catalogs/common/datasets/GFI_OP_CF", datasetResource()); } @@ -85,18 +144,28 @@ public RequestResponsePact getDatasetResources(PactDslWithProvider builder) { public RequestResponsePact listDatasetMembers(PactDslWithProvider builder) { return getExpectation( builder, - "a list of series members for a dataset", - "a request for a list of series members of a dataset", + "dataset members are available", + "a request for a list of dataset members", "/v1/catalogs/common/datasets/API_TEST/datasetseries", datasetMembers()); } + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") + public RequestResponsePact listDatasetMembersWhenNoneExist(PactDslWithProvider builder) { + return getExpectation( + builder, + "no dataset members exist", + "a request for a list of dataset members", + "/v1/catalogs/common/datasets/API_TEST/datasetseries", + noDatasetMembers()); + } + @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact getDatasetMemberResources(PactDslWithProvider builder) { return getExpectation( builder, - "metadata for a dataset series member", - "a request for dataset series member metadata", + "metadata belonging to a dataset series member", + "a request for a dataset members metadata", "/v1/catalogs/common/datasets/API_TEST/datasetseries/2022-01-16", datasetMemberResources()); } @@ -105,7 +174,7 @@ public RequestResponsePact getDatasetMemberResources(PactDslWithProvider builder public RequestResponsePact listAttributes(PactDslWithProvider builder) { return getExpectation( builder, - "a list of attributes for a dataset in a catalog", + "attributes belonging to a dataset", "a request for a list of attributes from a dataset", "/v1/catalogs/common/datasets/API_TEST/attributes", attributes(), @@ -116,8 +185,8 @@ public RequestResponsePact listAttributes(PactDslWithProvider builder) { public RequestResponsePact listDistributions(PactDslWithProvider builder) { return getExpectation( builder, - "a list of distributions available for a series member", - "a request for distributions available for a series member", + "distributions available for a dataset member", + "a request to list available distributions belonging to a dataset member", "/v1/catalogs/common/datasets/API_TEST/datasetseries/2022-01-16/distributions", distributions()); } @@ -160,6 +229,29 @@ void testListCatalogs(MockServer mockServer) { assertThat("Expected catalog LinkedEntity to match", catalog.getLinkedEntity(), is(equalTo("common"))); } + @Test + @PactTestFor(pactMethod = "listCatalogsWhenNoneAreAvailable") + void testListCatalogsWhenNoneAreAvailable(MockServer mockServer) { + + givenInstanceOfFusionSdk(mockServer); + + ParsingException ex = Assertions.assertThrows(ParsingException.class, () -> fusion.listCatalogs()); + assertThat("Exception message is incorrect", ex.getMessage(), is(equalTo("Failed to parse resources from JSON, none found"))); + + } + + @Test + @PactTestFor(pactMethod = "listCatalogsWhenNotAuthorized") + void testListCatalogsWhenNotAuthorized(MockServer mockServer) { + + givenInstanceOfFusionSdk(mockServer); + + APICallException ex = Assertions.assertThrows(APICallException.class, () -> fusion.listCatalogs()); + assertThat("Exception message is incorrect", ex.getMessage(), is(equalTo("The bearer token is missing or an invalid bearer token was provided"))); + assertThat("Exception message is incorrect", ex.getResponseCode(), is(equalTo(401))); + + } + @Test @PactTestFor(pactMethod = "getCatalogResources") void testCatalogResources(MockServer mockServer) { @@ -182,6 +274,18 @@ void testCatalogResources(MockServer mockServer) { }); } + @Test + @PactTestFor(pactMethod = "getCatalogResourcesWhenCatalogNotFound") + void testCatalogResourcesNotFound(MockServer mockServer) { + + givenInstanceOfFusionSdk(mockServer); + + APICallException ex = Assertions.assertThrows(APICallException.class, () -> fusion.catalogResources("alternate")); + + assertThat("Exception message is incorrect", ex.getMessage(), is(equalTo("The requested resource does not exist."))); + assertThat("Exception response code is incorrect", ex.getResponseCode(), is(equalTo(404))); + } + @Test @PactTestFor(pactMethod = "listProducts") void testListProducts(MockServer mockServer) { @@ -203,6 +307,16 @@ void testListProducts(MockServer mockServer) { assertThat("data product identifier is incorrect", dataProduct.getIdentifier(), is(equalTo("ESG00008"))); } + @Test + @PactTestFor(pactMethod = "listProductsWhenNoneExist") + void testListProductsWhenNoneExist(MockServer mockServer) { + + givenInstanceOfFusionSdk(mockServer); + + ParsingException ex = Assertions.assertThrows(ParsingException.class, () -> fusion.listProducts("common")); + assertThat("Exception message is incorrect", ex.getMessage(), is(equalTo("Failed to parse resources from JSON, none found"))); + } + @Test @PactTestFor(pactMethod = "listDatasets") void testListDatasets(MockServer mockServer) { @@ -224,6 +338,16 @@ void testListDatasets(MockServer mockServer) { assertThat("dataset frequency is incorrect", dataset.getFrequency(), is(equalTo("Daily"))); } + @Test + @PactTestFor(pactMethod = "listDatasetsWhenNoneExist") + void testListDatasetsWhenNoneExist(MockServer mockServer) { + + givenInstanceOfFusionSdk(mockServer); + + ParsingException ex = Assertions.assertThrows(ParsingException.class, () -> fusion.listDatasets("common")); + assertThat("Exception message is incorrect", ex.getMessage(), is(equalTo("Failed to parse resources from JSON, none found"))); + } + @Test @PactTestFor(pactMethod = "getDatasetResources") void testDatasetResources(MockServer mockServer) { @@ -268,6 +392,16 @@ void testListDatasetMembers(MockServer mockServer) { assertThat("dataset series toDate is incorrect", series.getToDate(), is(equalTo(LocalDate.of(2023, 3, 17)))); } + @Test + @PactTestFor(pactMethod = "listDatasetMembersWhenNoneExist") + void testListDatasetMembersWhenNoneExist(MockServer mockServer) { + + givenInstanceOfFusionSdk(mockServer); + + ParsingException ex = Assertions.assertThrows(ParsingException.class, () -> fusion.listDatasetMembers("common", "API_TEST")); + assertThat("Exception message is incorrect", ex.getMessage(), is(equalTo("Failed to parse resources from JSON, none found"))); + } + @Test @PactTestFor(pactMethod = "getDatasetMemberResources") void testDatasetMemberResources(MockServer mockServer) { diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java index c192bf6..b893ad2 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java @@ -31,7 +31,7 @@ public class FusionUploadConsumerPactTest { Fusion fusion; - @Pact(provider = "10274-fusionupload-provider", consumer = "110274-fusionsdk-consumer") + @Pact(provider = "110274-fusionupload-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact uploadFile(PactDslWithProvider builder) { Map uploadHeaders = givenUploadHeaders( diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java index eeaba11..f24e060 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java @@ -27,6 +27,21 @@ public static DslPart catalogs() { .closeArray(); } + public static DslPart noCatalogs() { + return header("catalogs/", "A list of available catalogs, catalogs", "catalogs", "Catalogs") + .minArrayLike("resources", 0); + } + + public static DslPart error(String path, int status, String error) { + PactDslJsonBody b = new PactDslJsonBody(); + return b.stringType("timestamp", "2023-05-01") + .stringType("path", path) + .integerType("status", status) + .stringType("error", error) + .stringType("requestId"); + + } + public static DslPart catalogResources() { return header("common", "A catalog of common data", "common", "Common data catalog") .minArrayLike("resources", 1) @@ -62,6 +77,12 @@ public static DslPart products() { .closeArray(); } + public static DslPart noProducts() { + return header("products/", "A list of available products", "products", "Products") + .minArrayLike("resources", 0) + .closeArray(); + } + public static DslPart datasets() { return header("datasets/", "A list of available datasets", "datasets", "Datasets") .minArrayLike("resources", 1) @@ -87,6 +108,12 @@ public static DslPart datasets() { .closeArray(); } + public static DslPart noDatasets() { + return header("datasets/", "A list of available datasets", "datasets", "Datasets") + .minArrayLike("resources", 0) + .closeArray(); + } + public static DslPart datasetResource() { return header("GFI_OP_CF/", "Premium, volatility, and greeks for EUR", "GFI_OP_CF", "Swaptions Caps & Floors") .minArrayLike("resources", 1) @@ -130,6 +157,17 @@ public static DslPart datasetMembers() { .closeArray(); } + public static DslPart noDatasetMembers() { + + return header( + "datasetseries/", + "A list of available datasetseries of a dataset", + "datasetseries", + "DatasetSeries") + .minArrayLike("resources", 0) + .closeArray(); + } + public static DslPart datasetMemberResources() { PactDslJsonBody b = new PactDslJsonBody(); diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java index 1614d4a..1a9502b 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java @@ -1,10 +1,14 @@ package io.github.jpmorganchase.fusion.pact.util; +import au.com.dius.pact.consumer.dsl.Dsl; import au.com.dius.pact.consumer.dsl.DslPart; +import au.com.dius.pact.consumer.dsl.PactDslResponse; import au.com.dius.pact.consumer.dsl.PactDslWithProvider; import au.com.dius.pact.core.model.RequestResponsePact; import java.util.Map; +import static io.github.jpmorganchase.fusion.pact.util.BodyBuilders.error; + public class RequestResponseHelper { private static final String BEARER_TOKEN = "my-bearer-token"; @@ -32,6 +36,34 @@ public static RequestResponsePact getExpectation( return getExpectation(builder, given, upon, path, body, "application/json"); } + public static RequestResponsePact failedGetExpectation( + PactDslWithProvider builder, String given, String upon, String path, String error, int status) { + return failedGetExpectation(builder, given, upon, path, status, error(path, status, error)); + } + + public static RequestResponsePact failedGetExpectation( + PactDslWithProvider builder, String given, String upon, String path, int status) { + return failedGetExpectation(builder, given, upon, path, null, status); + } + + public static RequestResponsePact failedGetExpectation( + PactDslWithProvider builder, String given, String upon, String path, int status, DslPart body) { + + PactDslResponse response = builder.given(given) + .uponReceiving(upon) + .path(path) + .matchHeader("Authorization", AUTH_VAL) + .method("GET") + .willRespondWith() + .status(status); + + if (null!=body){ + response.body(body); + } + + return response.toPact(); + } + public static RequestResponsePact downloadExpectation( PactDslWithProvider builder, String given, String upon, String path, String body) { return builder.given(given) diff --git a/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-10274-fusionupload-provider.json b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionupload-provider.json similarity index 98% rename from src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-10274-fusionupload-provider.json rename to src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionupload-provider.json index 66282e4..1507fd3 100644 --- a/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-10274-fusionupload-provider.json +++ b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionupload-provider.json @@ -1,6 +1,6 @@ { "provider": { - "name": "10274-fusionupload-provider" + "name": "110274-fusionupload-provider" }, "consumer": { "name": "110274-fusionsdk-consumer" From 61d0d83b0f05afbe1fc53c66afffa6af322ec8df Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Mon, 1 May 2023 17:06:56 +0100 Subject: [PATCH 23/32] spotless adjustments --- .../pact/FusionApiConsumerPactTest.java | 63 ++++++++++--------- .../fusion/pact/util/BodyBuilders.java | 9 ++- .../pact/util/RequestResponseHelper.java | 9 ++- 3 files changed, 41 insertions(+), 40 deletions(-) diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java index 1e89b3e..a9dd83d 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java @@ -16,13 +16,12 @@ import io.github.jpmorganchase.fusion.api.APICallException; import io.github.jpmorganchase.fusion.model.*; import io.github.jpmorganchase.fusion.pact.util.FileHelper; +import io.github.jpmorganchase.fusion.parsing.ParsingException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Paths; import java.time.LocalDate; import java.util.Map; - -import io.github.jpmorganchase.fusion.parsing.ParsingException; import lombok.SneakyThrows; import org.hamcrest.core.Is; import org.junit.jupiter.api.AfterEach; @@ -40,32 +39,19 @@ public class FusionApiConsumerPactTest { @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact listCatalogs(PactDslWithProvider builder) { - return getExpectation( - builder, - "catalogs are available", - "a request for catalogs", - "/v1/catalogs", - catalogs()); + return getExpectation(builder, "catalogs are available", "a request for catalogs", "/v1/catalogs", catalogs()); } @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact listCatalogsWhenNoneAreAvailable(PactDslWithProvider builder) { return getExpectation( - builder, - "no catalogs are available", - "a request for catalogs", - "/v1/catalogs", - noCatalogs()); + builder, "no catalogs are available", "a request for catalogs", "/v1/catalogs", noCatalogs()); } @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact listCatalogsWhenNotAuthorized(PactDslWithProvider builder) { return failedGetExpectation( - builder, - "not authorized to list catalogs", - "a request for catalogs", - "/v1/catalogs", - 401); + builder, "not authorized to list catalogs", "a request for catalogs", "/v1/catalogs", 401); } @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") @@ -86,8 +72,7 @@ public RequestResponsePact getCatalogResourcesWhenCatalogNotFound(PactDslWithPro "a request for that catalogs resources", "/v1/catalogs/alternate", "Not Found", - 404 - ); + 404); } @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") @@ -236,8 +221,10 @@ void testListCatalogsWhenNoneAreAvailable(MockServer mockServer) { givenInstanceOfFusionSdk(mockServer); ParsingException ex = Assertions.assertThrows(ParsingException.class, () -> fusion.listCatalogs()); - assertThat("Exception message is incorrect", ex.getMessage(), is(equalTo("Failed to parse resources from JSON, none found"))); - + assertThat( + "Exception message is incorrect", + ex.getMessage(), + is(equalTo("Failed to parse resources from JSON, none found"))); } @Test @@ -247,9 +234,11 @@ void testListCatalogsWhenNotAuthorized(MockServer mockServer) { givenInstanceOfFusionSdk(mockServer); APICallException ex = Assertions.assertThrows(APICallException.class, () -> fusion.listCatalogs()); - assertThat("Exception message is incorrect", ex.getMessage(), is(equalTo("The bearer token is missing or an invalid bearer token was provided"))); + assertThat( + "Exception message is incorrect", + ex.getMessage(), + is(equalTo("The bearer token is missing or an invalid bearer token was provided"))); assertThat("Exception message is incorrect", ex.getResponseCode(), is(equalTo(401))); - } @Test @@ -280,9 +269,13 @@ void testCatalogResourcesNotFound(MockServer mockServer) { givenInstanceOfFusionSdk(mockServer); - APICallException ex = Assertions.assertThrows(APICallException.class, () -> fusion.catalogResources("alternate")); + APICallException ex = + Assertions.assertThrows(APICallException.class, () -> fusion.catalogResources("alternate")); - assertThat("Exception message is incorrect", ex.getMessage(), is(equalTo("The requested resource does not exist."))); + assertThat( + "Exception message is incorrect", + ex.getMessage(), + is(equalTo("The requested resource does not exist."))); assertThat("Exception response code is incorrect", ex.getResponseCode(), is(equalTo(404))); } @@ -314,7 +307,10 @@ void testListProductsWhenNoneExist(MockServer mockServer) { givenInstanceOfFusionSdk(mockServer); ParsingException ex = Assertions.assertThrows(ParsingException.class, () -> fusion.listProducts("common")); - assertThat("Exception message is incorrect", ex.getMessage(), is(equalTo("Failed to parse resources from JSON, none found"))); + assertThat( + "Exception message is incorrect", + ex.getMessage(), + is(equalTo("Failed to parse resources from JSON, none found"))); } @Test @@ -345,7 +341,10 @@ void testListDatasetsWhenNoneExist(MockServer mockServer) { givenInstanceOfFusionSdk(mockServer); ParsingException ex = Assertions.assertThrows(ParsingException.class, () -> fusion.listDatasets("common")); - assertThat("Exception message is incorrect", ex.getMessage(), is(equalTo("Failed to parse resources from JSON, none found"))); + assertThat( + "Exception message is incorrect", + ex.getMessage(), + is(equalTo("Failed to parse resources from JSON, none found"))); } @Test @@ -398,8 +397,12 @@ void testListDatasetMembersWhenNoneExist(MockServer mockServer) { givenInstanceOfFusionSdk(mockServer); - ParsingException ex = Assertions.assertThrows(ParsingException.class, () -> fusion.listDatasetMembers("common", "API_TEST")); - assertThat("Exception message is incorrect", ex.getMessage(), is(equalTo("Failed to parse resources from JSON, none found"))); + ParsingException ex = + Assertions.assertThrows(ParsingException.class, () -> fusion.listDatasetMembers("common", "API_TEST")); + assertThat( + "Exception message is incorrect", + ex.getMessage(), + is(equalTo("Failed to parse resources from JSON, none found"))); } @Test diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java index f24e060..9779478 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/BodyBuilders.java @@ -39,7 +39,6 @@ public static DslPart error(String path, int status, String error) { .integerType("status", status) .stringType("error", error) .stringType("requestId"); - } public static DslPart catalogResources() { @@ -160,10 +159,10 @@ public static DslPart datasetMembers() { public static DslPart noDatasetMembers() { return header( - "datasetseries/", - "A list of available datasetseries of a dataset", - "datasetseries", - "DatasetSeries") + "datasetseries/", + "A list of available datasetseries of a dataset", + "datasetseries", + "DatasetSeries") .minArrayLike("resources", 0) .closeArray(); } diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java index 1a9502b..6ba805e 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java @@ -1,14 +1,13 @@ package io.github.jpmorganchase.fusion.pact.util; -import au.com.dius.pact.consumer.dsl.Dsl; +import static io.github.jpmorganchase.fusion.pact.util.BodyBuilders.error; + import au.com.dius.pact.consumer.dsl.DslPart; import au.com.dius.pact.consumer.dsl.PactDslResponse; import au.com.dius.pact.consumer.dsl.PactDslWithProvider; import au.com.dius.pact.core.model.RequestResponsePact; import java.util.Map; -import static io.github.jpmorganchase.fusion.pact.util.BodyBuilders.error; - public class RequestResponseHelper { private static final String BEARER_TOKEN = "my-bearer-token"; @@ -43,7 +42,7 @@ public static RequestResponsePact failedGetExpectation( public static RequestResponsePact failedGetExpectation( PactDslWithProvider builder, String given, String upon, String path, int status) { - return failedGetExpectation(builder, given, upon, path, null, status); + return failedGetExpectation(builder, given, upon, path, null, status); } public static RequestResponsePact failedGetExpectation( @@ -57,7 +56,7 @@ public static RequestResponsePact failedGetExpectation( .willRespondWith() .status(status); - if (null!=body){ + if (null != body) { response.body(body); } From 0f0a0f5b17280f06033c75bf86ad09083e42205e Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Mon, 1 May 2023 17:20:21 +0100 Subject: [PATCH 24/32] Update 110274-fusionsdk-consumer-110274-fusionapi-provider.json --- ...dk-consumer-110274-fusionapi-provider.json | 2839 ++++++++++++++++- 1 file changed, 2716 insertions(+), 123 deletions(-) diff --git a/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json index 113f4c4..a229489 100644 --- a/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json +++ b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json @@ -6,6 +6,229 @@ "name": "110274-fusionsdk-consumer" }, "interactions": [ + { + "description": "a request for that catalogs resources", + "request": { + "method": "GET", + "path": "/v1/catalogs/alternate", + "headers": { + "Authorization": "Bearer my-bearer-token" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 404, + "headers": { + "Content-Type": "application/json; charset=UTF-8" + }, + "body": { + "path": "/v1/catalogs/alternate", + "requestId": "string", + "error": "Not Found", + "timestamp": "2023-05-01", + "status": 404 + }, + "matchingRules": { + "body": { + "$.timestamp": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.path": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.status": { + "matchers": [ + { + "match": "integer" + } + ], + "combine": "AND" + }, + "$.error": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.requestId": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + } + }, + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json(;\\s?charset=[\\w\\-]+)?" + } + ], + "combine": "AND" + } + } + }, + "generators": { + "body": { + "$.requestId": { + "type": "RandomString", + "size": 20 + } + } + } + }, + "providerStates": [ + { + "name": "a catalog that does not exist" + } + ] + }, + { + "description": "a request for catalog resources", + "request": { + "method": "GET", + "path": "/v1/catalogs/common", + "headers": { + "Authorization": "Bearer my-bearer-token" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + }, + "@id": "common", + "description": "A catalog of common data", + "identifier": "common", + "resources": [ + + ], + "title": "Common data catalog" + }, + "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + } + } + } + }, + "providerStates": [ + { + "name": "a catalog with zero resources" + } + ] + }, { "description": "a request for a dataset resource", "request": { @@ -34,53 +257,53 @@ "Content-Type": "application/json" }, "body": { - "identifier": "GFI_OP_CF", - "subCategory": [ + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + }, + "@id": "GFI_OP_CF/", + "category": [ "string", "string" ], - "isRawData": false, - "isInternalOnlyDataset": false, + "createdDate": "2023-05-01", "description": "Premium, volatility, and greeks for EUR", + "frequency": "Daily", + "hasSample": false, + "identifier": "GFI_OP_CF", + "isInternalOnlyDataset": false, + "isRawData": false, + "isRestricted": false, + "isThirdPartyData": false, + "language": "English", + "maintainer": "J.P. Morgan DM Rates Research", + "modifiedDate": "2023-05-01", + "publisher": "J.P. Morgan", + "region": [ + "string", + "string" + ], "resources": [ { - "identifier": "datasetseries", - "description": "A list of available datasetseries of a dataset", "@id": "datasetseries/", + "description": "A list of available datasetseries of a dataset", + "identifier": "datasetseries", "title": "Datasetseries" } ], - "language": "English", "source": [ "string", "string" ], - "title": "Swaptions Caps & Floors", - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - }, - "maintainer": "J.P. Morgan DM Rates Research", - "frequency": "Daily", - "createdDate": "2023-05-01", - "isThirdPartyData": false, - "modifiedDate": "2023-05-01", - "publisher": "J.P. Morgan", - "@id": "GFI_OP_CF/", - "tag": [ - "string", - "string" - ], - "category": [ + "subCategory": [ "string", "string" ], - "region": [ + "tag": [ "string", "string" ], - "hasSample": false, - "isRestricted": false + "title": "Swaptions Caps & Floors" }, "matchingRules": { "header": { @@ -455,27 +678,27 @@ "Content-Type": "application/ld+json" }, "body": { - "identifier": "attributes", - "description": "A list of available attributes", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + }, + "@id": "attributes/", + "description": "A list of available attributes", + "identifier": "attributes", "resources": [ { - "identifier": "A", - "isDatasetKey": false, "dataType": "String", - "sourceFieldId": "a_source_field", "description": "Description for attribute A", - "index": 1, "id": 4000003, + "identifier": "A", + "index": 1, + "isDatasetKey": false, "source": "Data Query", + "sourceFieldId": "a_source_field", "title": "A" } ], - "@id": "attributes/", - "title": "Attributes", - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - } + "title": "Attributes" }, "matchingRules": { "header": { @@ -656,22 +879,22 @@ "Content-Type": "application/json" }, "body": { - "identifier": "common", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + }, + "@id": "common", "description": "A catalog of common data", + "identifier": "common", "resources": [ { - "identifier": "datasets", - "description": "A list of available datasets (for access or download in one or more formats)", "@id": "datasets/", + "description": "A list of available datasets (for access or download in one or more formats)", + "identifier": "datasets", "title": "Datasets" } ], - "@id": "common", - "title": "Common data catalog", - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - } + "title": "Common data catalog" }, "matchingRules": { "header": { @@ -812,22 +1035,22 @@ "Content-Type": "application/json" }, "body": { - "identifier": "catalogs", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + }, + "@id": "catalogs/", "description": "A list of available catalogs, catalogs", + "identifier": "catalogs", "resources": [ { - "identifier": "common", - "description": "A catalog of common data", "@id": "common", + "description": "A catalog of common data", + "identifier": "common", "title": "Common data catalog" } ], - "@id": "catalogs/", - "title": "Catalogs", - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - } + "title": "Catalogs" }, "matchingRules": { "header": { @@ -967,54 +1190,54 @@ "Content-Type": "application/json" }, "body": { - "identifier": "products", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + }, + "@id": "products/", "description": "A list of available products", + "identifier": "products", "resources": [ { - "identifier": "ESG00008", - "subCategory": [ + "@id": "ESG00008/", + "category": [ "string", "string" ], "datasetCount": 18, - "releaseDate": "2023-05-01", "deliveryChannel": [ "string", "string" ], "description": "MSCI ESG Description", + "identifier": "ESG00008", "isActive": true, - "title": "MSCI ESG Ratings", + "isRestricted": true, "maintainer": [ "string", "string" ], - "shortAbstract": "A robust ESG integration tool", "publisher": "J.P. Morgan", - "theme": "ESG", - "tag": [ + "region": [ "string", "string" ], - "@id": "ESG00008/", - "category": [ + "releaseDate": "2023-05-01", + "shortAbstract": "A robust ESG integration tool", + "status": "Available", + "subCategory": [ "string", "string" ], - "region": [ + "tag": [ "string", "string" ], - "isRestricted": true, - "status": "Available" + "theme": "ESG", + "title": "MSCI ESG Ratings" } ], - "@id": "products/", - "title": "Products", - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - } + "title": "Products" }, "matchingRules": { "header": { @@ -1727,24 +1950,24 @@ "Content-Type": "application/json" }, "body": { - "identifier": "distributions", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + }, + "@id": "distributions/", "description": "A list of available distributions", + "identifier": "distributions", "resources": [ { - "identifier": "csv", - "fileExtension": ".csv", + "@id": "csv/", "description": "Snapshot data, in tabular, csv format", + "fileExtension": ".csv", + "identifier": "csv", "mediaType": "text/csv; header=present; charset=utf-8", - "@id": "csv/", "title": "CSV" } ], - "@id": "distributions/", - "title": "Distributions", - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - } + "title": "Distributions" }, "matchingRules": { "header": { @@ -1901,23 +2124,23 @@ "Content-Type": "application/json" }, "body": { - "identifier": "datasetseries", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + }, + "@id": "datasetseries/", "description": "A list of available datasetseries of a dataset", + "identifier": "datasetseries", "resources": [ { + "@id": "20230319/", + "createdDate": "2023-03-19", "fromDate": "2023-03-18", "identifier": "20230319", - "createdDate": "2023-03-19", - "toDate": "2023-03-17", - "@id": "20230319/" + "toDate": "2023-03-17" } ], - "@id": "datasetseries/", - "title": "DatasetSeries", - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - } + "title": "DatasetSeries" }, "matchingRules": { "header": { @@ -2042,10 +2265,10 @@ ] }, { - "description": "a request for dataset series member metadata", + "description": "a request for a list of attributes from a dataset", "request": { "method": "GET", - "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/2022-01-16", + "path": "/v1/catalogs/common/datasets/API_TEST/attributes", "headers": { "Authorization": "Bearer my-bearer-token" }, @@ -2066,22 +2289,26 @@ "response": { "status": 200, "headers": { - "Content-Type": "application/json" + "Content-Type": "application/ld+json" }, "body": { - "fromDate": "2023-03-18", - "identifier": "20230319", - "createdDate": "2023-03-19", - "toDate": "2023-03-17", + "identifier": "attributes", + "description": "A list of available attributes", "resources": [ { - "identifier": "distributions", - "description": "A list of available distributions", - "@id": "distributions/", - "title": "Distributions" + "identifier": "A", + "isDatasetKey": false, + "dataType": "String", + "sourceFieldId": "a_source_field", + "description": "Description for attribute A", + "index": 1, + "id": 4000003, + "source": "Data Query", + "title": "A" } ], - "@id": "20230319/", + "@id": "attributes/", + "title": "Attributes", "@context": { "@base": "https://fusion-api.test.aws.jpmchase.net/v1", "@vocab": "https://www.w3.org/ns/dcat3.jsondld" @@ -2093,7 +2320,7 @@ "matchers": [ { "match": "regex", - "regex": "application/json" + "regex": "application/ld\\+json" } ], "combine": "AND" @@ -2124,6 +2351,14 @@ ], "combine": "AND" }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, "$.identifier": { "matchers": [ { @@ -2132,6 +2367,14 @@ ], "combine": "AND" }, + "$.title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, "$.resources": { "matchers": [ { @@ -2141,7 +2384,7 @@ ], "combine": "AND" }, - "$.resources[*].@id": { + "$.resources[*].identifier": { "matchers": [ { "match": "type" @@ -2149,7 +2392,15 @@ ], "combine": "AND" }, - "$.resources[*].description": { + "$.resources[*].id": { + "matchers": [ + { + "match": "integer" + } + ], + "combine": "AND" + }, + "$.resources[*].source": { "matchers": [ { "match": "type" @@ -2157,7 +2408,7 @@ ], "combine": "AND" }, - "$.resources[*].identifier": { + "$.resources[*].dataType": { "matchers": [ { "match": "type" @@ -2165,7 +2416,7 @@ ], "combine": "AND" }, - "$.resources[*].title": { + "$.resources[*].description": { "matchers": [ { "match": "type" @@ -2173,29 +2424,34 @@ ], "combine": "AND" }, - "$.createdDate": { + "$.resources[*].index": { "matchers": [ { - "match": "date", - "format": "yyyy-MM-dd" + "match": "integer" } ], "combine": "AND" }, - "$.fromDate": { + "$.resources[*].isDatasetKey": { "matchers": [ { - "match": "date", - "format": "yyyy-MM-dd" + "match": "type" } ], "combine": "AND" }, - "$.toDate": { + "$.resources[*].sourceFieldId": { "matchers": [ { - "match": "date", - "format": "yyyy-MM-dd" + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].title": { + "matchers": [ + { + "match": "type" } ], "combine": "AND" @@ -2205,7 +2461,2344 @@ }, "providerStates": [ { - "name": "metadata for a dataset series member" + "name": "attributes belonging to a dataset" + } + ] + }, + { + "description": "a request for catalog resources", + "request": { + "method": "GET", + "path": "/v1/catalogs/common", + "headers": { + "Authorization": "Bearer my-bearer-token" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "identifier": "common", + "description": "A catalog of common data", + "resources": [ + { + "identifier": "datasets", + "description": "A list of available datasets (for access or download in one or more formats)", + "@id": "datasets/", + "title": "Datasets" + } + ], + "@id": "common", + "title": "Common data catalog", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 1 + } + ], + "combine": "AND" + }, + "$.resources[*].@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + } + } + } + }, + "providerStates": [ + { + "name": "catalog resources exist" + } + ] + }, + { + "description": "a request for catalogs", + "request": { + "method": "GET", + "path": "/v1/catalogs", + "headers": { + "Authorization": "Bearer my-bearer-token" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "identifier": "catalogs", + "description": "A list of available catalogs, catalogs", + "resources": [ + { + "identifier": "common", + "description": "A catalog of common data", + "@id": "common", + "title": "Common data catalog" + } + ], + "@id": "catalogs/", + "title": "Catalogs", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + } + } + } + }, + "providerStates": [ + { + "name": "catalogs are available" + } + ] + }, + { + "description": "a request for a list of data products", + "request": { + "method": "GET", + "path": "/v1/catalogs/common/products", + "headers": { + "Authorization": "Bearer my-bearer-token" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "identifier": "products", + "description": "A list of available products", + "resources": [ + { + "identifier": "ESG00008", + "subCategory": [ + "string", + "string" + ], + "datasetCount": 18, + "releaseDate": "2023-05-01", + "deliveryChannel": [ + "string", + "string" + ], + "description": "MSCI ESG Description", + "isActive": true, + "title": "MSCI ESG Ratings", + "maintainer": [ + "string", + "string" + ], + "shortAbstract": "A robust ESG integration tool", + "publisher": "J.P. Morgan", + "theme": "ESG", + "tag": [ + "string", + "string" + ], + "@id": "ESG00008/", + "category": [ + "string", + "string" + ], + "region": [ + "string", + "string" + ], + "isRestricted": true, + "status": "Available" + } + ], + "@id": "products/", + "title": "Products", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 1 + } + ], + "combine": "AND" + }, + "$.resources[*].category": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].category[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].datasetCount": { + "matchers": [ + { + "match": "integer" + } + ], + "combine": "AND" + }, + "$.resources[*].deliveryChannel": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].deliveryChannel[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].isActive": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].maintainer": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].maintainer[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].publisher": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].region": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].region[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].releaseDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.resources[*].shortAbstract": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].status": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].subCategory": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].subCategory[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].tag": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].tag[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].theme": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].isRestricted": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + } + } + }, + "generators": { + "body": { + "$.resources[*].category[*]": { + "type": "RandomString", + "size": 20 + }, + "$.resources[*].deliveryChannel[*]": { + "type": "RandomString", + "size": 20 + }, + "$.resources[*].maintainer[*]": { + "type": "RandomString", + "size": 20 + }, + "$.resources[*].region[*]": { + "type": "RandomString", + "size": 20 + }, + "$.resources[*].subCategory[*]": { + "type": "RandomString", + "size": 20 + }, + "$.resources[*].tag[*]": { + "type": "RandomString", + "size": 20 + } + } + } + }, + "providerStates": [ + { + "name": "data products exist" + } + ] + }, + { + "description": "a request for a list of dataset members", + "request": { + "method": "GET", + "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries", + "headers": { + "Authorization": "Bearer my-bearer-token" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "identifier": "datasetseries", + "description": "A list of available datasetseries of a dataset", + "resources": [ + { + "fromDate": "2023-03-18", + "identifier": "20230319", + "createdDate": "2023-03-19", + "toDate": "2023-03-17", + "@id": "20230319/" + } + ], + "@id": "datasetseries/", + "title": "DatasetSeries", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 1 + } + ], + "combine": "AND" + }, + "$.resources[*].createdDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.resources[*].fromDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.resources[*].toDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + } + } + } + }, + "providerStates": [ + { + "name": "dataset members are available" + } + ] + }, + { + "description": "a request for a dataset resources", + "request": { + "method": "GET", + "path": "/v1/catalogs/common/datasets/GFI_OP_CF", + "headers": { + "Authorization": "Bearer my-bearer-token" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "identifier": "GFI_OP_CF", + "subCategory": [ + "string", + "string" + ], + "isRawData": false, + "isInternalOnlyDataset": false, + "description": "Premium, volatility, and greeks for EUR", + "resources": [ + { + "identifier": "datasetseries", + "description": "A list of available datasetseries of a dataset", + "@id": "datasetseries/", + "title": "Datasetseries" + } + ], + "language": "English", + "source": [ + "string", + "string" + ], + "title": "Swaptions Caps & Floors", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + }, + "maintainer": "J.P. Morgan DM Rates Research", + "frequency": "Daily", + "createdDate": "2023-05-01", + "isThirdPartyData": false, + "modifiedDate": "2023-05-01", + "publisher": "J.P. Morgan", + "@id": "GFI_OP_CF/", + "tag": [ + "string", + "string" + ], + "category": [ + "string", + "string" + ], + "region": [ + "string", + "string" + ], + "hasSample": false, + "isRestricted": false + }, + "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 1 + } + ], + "combine": "AND" + }, + "$.resources[*].@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.category": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.category[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.createdDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.frequency": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.isThirdPartyData": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.isInternalOnlyDataset": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.language": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.maintainer": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.modifiedDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.publisher": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.region": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.region[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.source": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.source[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.subCategory": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.subCategory[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.tag": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.tag[*]": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.isRestricted": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.isRawData": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.hasSample": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + } + } + }, + "generators": { + "body": { + "$.category[*]": { + "type": "RandomString", + "size": 20 + }, + "$.region[*]": { + "type": "RandomString", + "size": 20 + }, + "$.source[*]": { + "type": "RandomString", + "size": 20 + }, + "$.subCategory[*]": { + "type": "RandomString", + "size": 20 + }, + "$.tag[*]": { + "type": "RandomString", + "size": 20 + } + } + } + }, + "providerStates": [ + { + "name": "dataset resources are available" + } + ] + }, + { + "description": "a request to list available distributions belonging to a dataset member", + "request": { + "method": "GET", + "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/2022-01-16/distributions", + "headers": { + "Authorization": "Bearer my-bearer-token" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "identifier": "distributions", + "description": "A list of available distributions", + "resources": [ + { + "identifier": "csv", + "fileExtension": ".csv", + "description": "Snapshot data, in tabular, csv format", + "mediaType": "text/csv; header=present; charset=utf-8", + "@id": "csv/", + "title": "CSV" + } + ], + "@id": "distributions/", + "title": "Distributions", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 1 + } + ], + "combine": "AND" + }, + "$.resources[*].description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].fileExtension": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].mediaType": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + } + } + } + }, + "providerStates": [ + { + "name": "distributions available for a dataset member" + } + ] + }, + { + "description": "a request for a dataset members metadata", + "request": { + "method": "GET", + "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/2022-01-16", + "headers": { + "Authorization": "Bearer my-bearer-token" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "fromDate": "2023-03-18", + "identifier": "20230319", + "createdDate": "2023-03-19", + "toDate": "2023-03-17", + "resources": [ + { + "identifier": "distributions", + "description": "A list of available distributions", + "@id": "distributions/", + "title": "Distributions" + } + ], + "@id": "20230319/", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 1 + } + ], + "combine": "AND" + }, + "$.resources[*].@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.createdDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.fromDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.toDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + } + } + } + }, + "providerStates": [ + { + "name": "metadata belonging to a dataset series member" + } + ] + }, + { + "description": "a request for dataset series member metadata", + "request": { + "method": "GET", + "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/2022-01-16", + "headers": { + "Authorization": "Bearer my-bearer-token" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + }, + "@id": "20230319/", + "createdDate": "2023-03-19", + "fromDate": "2023-03-18", + "identifier": "20230319", + "resources": [ + { + "@id": "distributions/", + "description": "A list of available distributions", + "identifier": "distributions", + "title": "Distributions" + } + ], + "toDate": "2023-03-17" + }, + "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 1 + } + ], + "combine": "AND" + }, + "$.resources[*].@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources[*].title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.createdDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.fromDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + }, + "$.toDate": { + "matchers": [ + { + "match": "date", + "format": "yyyy-MM-dd" + } + ], + "combine": "AND" + } + } + } + }, + "providerStates": [ + { + "name": "metadata for a dataset series member" + } + ] + }, + { + "description": "a request for catalogs", + "request": { + "method": "GET", + "path": "/v1/catalogs", + "headers": { + "Authorization": "Bearer my-bearer-token" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "identifier": "catalogs", + "description": "A list of available catalogs, catalogs", + "resources": [ + + ], + "@id": "catalogs/", + "title": "Catalogs", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + } + } + } + }, + "providerStates": [ + { + "name": "no catalogs are available" + } + ] + }, + { + "description": "a request for a list of data products", + "request": { + "method": "GET", + "path": "/v1/catalogs/common/products", + "headers": { + "Authorization": "Bearer my-bearer-token" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "identifier": "products", + "description": "A list of available products", + "resources": [ + + ], + "@id": "products/", + "title": "Products", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + } + } + } + }, + "providerStates": [ + { + "name": "no data products exist" + } + ] + }, + { + "description": "a request for a list of dataset members", + "request": { + "method": "GET", + "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries", + "headers": { + "Authorization": "Bearer my-bearer-token" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "identifier": "datasetseries", + "description": "A list of available datasetseries of a dataset", + "resources": [ + + ], + "@id": "datasetseries/", + "title": "DatasetSeries", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + } + } + } + }, + "providerStates": [ + { + "name": "no dataset members exist" + } + ] + }, + { + "description": "a request for a list of datasets", + "request": { + "method": "GET", + "path": "/v1/catalogs/common/datasets", + "headers": { + "Authorization": "Bearer my-bearer-token" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "body": { + "identifier": "datasets", + "description": "A list of available datasets", + "resources": [ + + ], + "@id": "datasets/", + "title": "Datasets", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } + }, + "matchingRules": { + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json" + } + ], + "combine": "AND" + } + }, + "body": { + "$.@context.@vocab": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@context.@base": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.@id": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.description": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.identifier": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.title": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.resources": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + } + } + } + }, + "providerStates": [ + { + "name": "no datasets exist" + } + ] + }, + { + "description": "a request for catalogs", + "request": { + "method": "GET", + "path": "/v1/catalogs", + "headers": { + "Authorization": "Bearer my-bearer-token" + }, + "matchingRules": { + "header": { + "Authorization": { + "matchers": [ + { + "match": "regex", + "regex": "Bearer my-bearer-token" + } + ], + "combine": "AND" + } + } + } + }, + "response": { + "status": 401, + "headers": { + "Content-Type": "application/json; charset=UTF-8" + }, + "body": { + "path": "/v1/catalogs", + "requestId": "string", + "timestamp": "2023-05-01", + "status": 401 + }, + "matchingRules": { + "body": { + "$.timestamp": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.path": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.status": { + "matchers": [ + { + "match": "integer" + } + ], + "combine": "AND" + }, + "$.error": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + }, + "$.requestId": { + "matchers": [ + { + "match": "type" + } + ], + "combine": "AND" + } + }, + "header": { + "Content-Type": { + "matchers": [ + { + "match": "regex", + "regex": "application/json(;\\s?charset=[\\w\\-]+)?" + } + ], + "combine": "AND" + } + } + }, + "generators": { + "body": { + "$.requestId": { + "type": "RandomString", + "size": 20 + } + } + } + }, + "providerStates": [ + { + "name": "not authorized to list catalogs" } ] } From 41739231b88f5450cbc76ed470a5c8ff6ff975ef Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Mon, 1 May 2023 17:46:43 +0100 Subject: [PATCH 25/32] Further PACT tweaks --- .../pact/FusionUploadConsumerPactTest.java | 2 +- ...dk-consumer-110274-fusionapi-provider.json | 2160 +---------------- 2 files changed, 126 insertions(+), 2036 deletions(-) diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java index b893ad2..afde2cd 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java @@ -45,7 +45,7 @@ public RequestResponsePact uploadFile(PactDslWithProvider builder) { "A,B,C"); } - @Pact(provider = "10274-fusionupload-provider", consumer = "110274-fusionsdk-consumer") + @Pact(provider = "110274-fusionupload-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact uploadStream(PactDslWithProvider builder) { Map uploadHeaders = givenUploadHeaders( diff --git a/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json index a229489..5ccd118 100644 --- a/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json +++ b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json @@ -111,10 +111,10 @@ ] }, { - "description": "a request for catalog resources", + "description": "a request is made to download the distribution", "request": { "method": "GET", - "path": "/v1/catalogs/common", + "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/2022-01-16/distributions/csv", "headers": { "Authorization": "Bearer my-bearer-token" }, @@ -135,105 +135,21 @@ "response": { "status": 200, "headers": { - "Content-Type": "application/json" - }, - "body": { - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - }, - "@id": "common", - "description": "A catalog of common data", - "identifier": "common", - "resources": [ - - ], - "title": "Common data catalog" + "Content-Type": "text/csv" }, - "matchingRules": { - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json" - } - ], - "combine": "AND" - } - }, - "body": { - "$.@context.@vocab": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@context.@base": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.description": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.title": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources": { - "matchers": [ - { - "match": "type", - "min": 0 - } - ], - "combine": "AND" - } - } - } + "body": "A,B,C" }, "providerStates": [ { - "name": "a catalog with zero resources" + "name": "a distribution that is available for download" } ] }, { - "description": "a request for a dataset resource", + "description": "a request for a list of datasets", "request": { "method": "GET", - "path": "/v1/catalogs/common/datasets/GFI_OP_CF", + "path": "/v1/catalogs/common/datasets", "headers": { "Authorization": "Bearer my-bearer-token" }, @@ -257,53 +173,52 @@ "Content-Type": "application/json" }, "body": { - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - }, - "@id": "GFI_OP_CF/", - "category": [ - "string", - "string" - ], - "createdDate": "2023-05-01", - "description": "Premium, volatility, and greeks for EUR", - "frequency": "Daily", - "hasSample": false, - "identifier": "GFI_OP_CF", - "isInternalOnlyDataset": false, - "isRawData": false, - "isRestricted": false, - "isThirdPartyData": false, - "language": "English", - "maintainer": "J.P. Morgan DM Rates Research", - "modifiedDate": "2023-05-01", - "publisher": "J.P. Morgan", - "region": [ - "string", - "string" - ], + "identifier": "datasets", + "description": "A list of available datasets", "resources": [ { - "@id": "datasetseries/", - "description": "A list of available datasetseries of a dataset", - "identifier": "datasetseries", - "title": "Datasetseries" + "identifier": "GFI_OP_CF", + "subCategory": [ + "string", + "string" + ], + "isRawData": false, + "isInternalOnlyDataset": false, + "description": "Premium, volatility, and greeks for EUR", + "language": "English", + "source": [ + "string", + "string" + ], + "title": "Swaptions Caps & Floors", + "frequency": "Daily", + "createdDate": "2023-05-01", + "isThirdPartyData": false, + "modifiedDate": "2023-05-01", + "publisher": "J.P. Morgan", + "tag": [ + "string", + "string" + ], + "@id": "GFI_OP_CF/", + "category": [ + "string", + "string" + ], + "region": [ + "string", + "string" + ], + "hasSample": false, + "isRestricted": false } ], - "source": [ - "string", - "string" - ], - "subCategory": [ - "string", - "string" - ], - "tag": [ - "string", - "string" - ], - "title": "Swaptions Caps & Floors" + "@id": "datasets/", + "title": "Datasets", + "@context": { + "@base": "https://fusion-api.test.aws.jpmchase.net/v1", + "@vocab": "https://www.w3.org/ns/dcat3.jsondld" + } }, "matchingRules": { "header": { @@ -375,39 +290,7 @@ ], "combine": "AND" }, - "$.resources[*].@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].description": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].title": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.category": { + "$.resources[*].category": { "matchers": [ { "match": "type", @@ -416,7 +299,7 @@ ], "combine": "AND" }, - "$.category[*]": { + "$.resources[*].category[*]": { "matchers": [ { "match": "type" @@ -424,7 +307,7 @@ ], "combine": "AND" }, - "$.createdDate": { + "$.resources[*].createdDate": { "matchers": [ { "match": "date", @@ -433,15 +316,7 @@ ], "combine": "AND" }, - "$.frequency": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.isThirdPartyData": { + "$.resources[*].description": { "matchers": [ { "match": "type" @@ -449,7 +324,7 @@ ], "combine": "AND" }, - "$.isInternalOnlyDataset": { + "$.resources[*].frequency": { "matchers": [ { "match": "type" @@ -457,7 +332,7 @@ ], "combine": "AND" }, - "$.language": { + "$.resources[*].identifier": { "matchers": [ { "match": "type" @@ -465,7 +340,7 @@ ], "combine": "AND" }, - "$.maintainer": { + "$.resources[*].isThirdPartyData": { "matchers": [ { "match": "type" @@ -473,16 +348,7 @@ ], "combine": "AND" }, - "$.modifiedDate": { - "matchers": [ - { - "match": "date", - "format": "yyyy-MM-dd" - } - ], - "combine": "AND" - }, - "$.publisher": { + "$.resources[*].isInternalOnlyDataset": { "matchers": [ { "match": "type" @@ -490,1672 +356,24 @@ ], "combine": "AND" }, - "$.region": { - "matchers": [ - { - "match": "type", - "min": 0 - } - ], - "combine": "AND" - }, - "$.region[*]": { + "$.resources[*].language": { "matchers": [ { "match": "type" } - ], - "combine": "AND" - }, - "$.source": { - "matchers": [ - { - "match": "type", - "min": 0 - } - ], - "combine": "AND" - }, - "$.source[*]": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.subCategory": { - "matchers": [ - { - "match": "type", - "min": 0 - } - ], - "combine": "AND" - }, - "$.subCategory[*]": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.tag": { - "matchers": [ - { - "match": "type", - "min": 0 - } - ], - "combine": "AND" - }, - "$.tag[*]": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.isRestricted": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.isRawData": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.hasSample": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - } - } - }, - "generators": { - "body": { - "$.category[*]": { - "type": "RandomString", - "size": 20 - }, - "$.region[*]": { - "type": "RandomString", - "size": 20 - }, - "$.source[*]": { - "type": "RandomString", - "size": 20 - }, - "$.subCategory[*]": { - "type": "RandomString", - "size": 20 - }, - "$.tag[*]": { - "type": "RandomString", - "size": 20 - } - } - } - }, - "providerStates": [ - { - "name": "a dataset resource" - } - ] - }, - { - "description": "a request is made to download the distribution", - "request": { - "method": "GET", - "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/2022-01-16/distributions/csv", - "headers": { - "Authorization": "Bearer my-bearer-token" - }, - "matchingRules": { - "header": { - "Authorization": { - "matchers": [ - { - "match": "regex", - "regex": "Bearer my-bearer-token" - } - ], - "combine": "AND" - } - } - } - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "text/csv" - }, - "body": "A,B,C" - }, - "providerStates": [ - { - "name": "a distribution that is available for download" - } - ] - }, - { - "description": "a request for a list of attributes from a dataset", - "request": { - "method": "GET", - "path": "/v1/catalogs/common/datasets/API_TEST/attributes", - "headers": { - "Authorization": "Bearer my-bearer-token" - }, - "matchingRules": { - "header": { - "Authorization": { - "matchers": [ - { - "match": "regex", - "regex": "Bearer my-bearer-token" - } - ], - "combine": "AND" - } - } - } - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/ld+json" - }, - "body": { - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - }, - "@id": "attributes/", - "description": "A list of available attributes", - "identifier": "attributes", - "resources": [ - { - "dataType": "String", - "description": "Description for attribute A", - "id": 4000003, - "identifier": "A", - "index": 1, - "isDatasetKey": false, - "source": "Data Query", - "sourceFieldId": "a_source_field", - "title": "A" - } - ], - "title": "Attributes" - }, - "matchingRules": { - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/ld\\+json" - } - ], - "combine": "AND" - } - }, - "body": { - "$.@context.@vocab": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@context.@base": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.description": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.title": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources": { - "matchers": [ - { - "match": "type", - "min": 1 - } - ], - "combine": "AND" - }, - "$.resources[*].identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].id": { - "matchers": [ - { - "match": "integer" - } - ], - "combine": "AND" - }, - "$.resources[*].source": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].dataType": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].description": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].index": { - "matchers": [ - { - "match": "integer" - } - ], - "combine": "AND" - }, - "$.resources[*].isDatasetKey": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].sourceFieldId": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].title": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - } - } - } - }, - "providerStates": [ - { - "name": "a list of attributes for a dataset in a catalog" - } - ] - }, - { - "description": "a request for catalogs resources", - "request": { - "method": "GET", - "path": "/v1/catalogs/common", - "headers": { - "Authorization": "Bearer my-bearer-token" - }, - "matchingRules": { - "header": { - "Authorization": { - "matchers": [ - { - "match": "regex", - "regex": "Bearer my-bearer-token" - } - ], - "combine": "AND" - } - } - } - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/json" - }, - "body": { - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - }, - "@id": "common", - "description": "A catalog of common data", - "identifier": "common", - "resources": [ - { - "@id": "datasets/", - "description": "A list of available datasets (for access or download in one or more formats)", - "identifier": "datasets", - "title": "Datasets" - } - ], - "title": "Common data catalog" - }, - "matchingRules": { - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json" - } - ], - "combine": "AND" - } - }, - "body": { - "$.@context.@vocab": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@context.@base": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.description": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.title": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources": { - "matchers": [ - { - "match": "type", - "min": 1 - } - ], - "combine": "AND" - }, - "$.resources[*].@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].description": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].title": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - } - } - } - }, - "providerStates": [ - { - "name": "a list of catalogs resources" - } - ] - }, - { - "description": "a request for available catalogs", - "request": { - "method": "GET", - "path": "/v1/catalogs", - "headers": { - "Authorization": "Bearer my-bearer-token" - }, - "matchingRules": { - "header": { - "Authorization": { - "matchers": [ - { - "match": "regex", - "regex": "Bearer my-bearer-token" - } - ], - "combine": "AND" - } - } - } - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/json" - }, - "body": { - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - }, - "@id": "catalogs/", - "description": "A list of available catalogs, catalogs", - "identifier": "catalogs", - "resources": [ - { - "@id": "common", - "description": "A catalog of common data", - "identifier": "common", - "title": "Common data catalog" - } - ], - "title": "Catalogs" - }, - "matchingRules": { - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json" - } - ], - "combine": "AND" - } - }, - "body": { - "$.@context.@vocab": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@context.@base": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.description": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.title": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].description": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].title": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - } - } - } - }, - "providerStates": [ - { - "name": "a list of catalogs" - } - ] - }, - { - "description": "a request for a list of data products", - "request": { - "method": "GET", - "path": "/v1/catalogs/common/products", - "headers": { - "Authorization": "Bearer my-bearer-token" - }, - "matchingRules": { - "header": { - "Authorization": { - "matchers": [ - { - "match": "regex", - "regex": "Bearer my-bearer-token" - } - ], - "combine": "AND" - } - } - } - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/json" - }, - "body": { - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - }, - "@id": "products/", - "description": "A list of available products", - "identifier": "products", - "resources": [ - { - "@id": "ESG00008/", - "category": [ - "string", - "string" - ], - "datasetCount": 18, - "deliveryChannel": [ - "string", - "string" - ], - "description": "MSCI ESG Description", - "identifier": "ESG00008", - "isActive": true, - "isRestricted": true, - "maintainer": [ - "string", - "string" - ], - "publisher": "J.P. Morgan", - "region": [ - "string", - "string" - ], - "releaseDate": "2023-05-01", - "shortAbstract": "A robust ESG integration tool", - "status": "Available", - "subCategory": [ - "string", - "string" - ], - "tag": [ - "string", - "string" - ], - "theme": "ESG", - "title": "MSCI ESG Ratings" - } - ], - "title": "Products" - }, - "matchingRules": { - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json" - } - ], - "combine": "AND" - } - }, - "body": { - "$.@context.@vocab": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@context.@base": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.description": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.title": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources": { - "matchers": [ - { - "match": "type", - "min": 1 - } - ], - "combine": "AND" - }, - "$.resources[*].category": { - "matchers": [ - { - "match": "type", - "min": 0 - } - ], - "combine": "AND" - }, - "$.resources[*].category[*]": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].datasetCount": { - "matchers": [ - { - "match": "integer" - } - ], - "combine": "AND" - }, - "$.resources[*].deliveryChannel": { - "matchers": [ - { - "match": "type", - "min": 0 - } - ], - "combine": "AND" - }, - "$.resources[*].deliveryChannel[*]": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].description": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].isActive": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].maintainer": { - "matchers": [ - { - "match": "type", - "min": 0 - } - ], - "combine": "AND" - }, - "$.resources[*].maintainer[*]": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].publisher": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].region": { - "matchers": [ - { - "match": "type", - "min": 0 - } - ], - "combine": "AND" - }, - "$.resources[*].region[*]": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].releaseDate": { - "matchers": [ - { - "match": "date", - "format": "yyyy-MM-dd" - } - ], - "combine": "AND" - }, - "$.resources[*].shortAbstract": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].status": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].subCategory": { - "matchers": [ - { - "match": "type", - "min": 0 - } - ], - "combine": "AND" - }, - "$.resources[*].subCategory[*]": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].tag": { - "matchers": [ - { - "match": "type", - "min": 0 - } - ], - "combine": "AND" - }, - "$.resources[*].tag[*]": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].theme": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].title": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].isRestricted": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - } - } - }, - "generators": { - "body": { - "$.resources[*].category[*]": { - "type": "RandomString", - "size": 20 - }, - "$.resources[*].deliveryChannel[*]": { - "type": "RandomString", - "size": 20 - }, - "$.resources[*].maintainer[*]": { - "type": "RandomString", - "size": 20 - }, - "$.resources[*].region[*]": { - "type": "RandomString", - "size": 20 - }, - "$.resources[*].subCategory[*]": { - "type": "RandomString", - "size": 20 - }, - "$.resources[*].tag[*]": { - "type": "RandomString", - "size": 20 - } - } - } - }, - "providerStates": [ - { - "name": "a list of data products" - } - ] - }, - { - "description": "a request for a list of datasets", - "request": { - "method": "GET", - "path": "/v1/catalogs/common/datasets", - "headers": { - "Authorization": "Bearer my-bearer-token" - }, - "matchingRules": { - "header": { - "Authorization": { - "matchers": [ - { - "match": "regex", - "regex": "Bearer my-bearer-token" - } - ], - "combine": "AND" - } - } - } - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/json" - }, - "body": { - "identifier": "datasets", - "description": "A list of available datasets", - "resources": [ - { - "identifier": "GFI_OP_CF", - "subCategory": [ - "string", - "string" - ], - "isRawData": false, - "isInternalOnlyDataset": false, - "description": "Premium, volatility, and greeks for EUR", - "language": "English", - "source": [ - "string", - "string" - ], - "title": "Swaptions Caps & Floors", - "frequency": "Daily", - "createdDate": "2023-05-01", - "isThirdPartyData": false, - "modifiedDate": "2023-05-01", - "publisher": "J.P. Morgan", - "tag": [ - "string", - "string" - ], - "@id": "GFI_OP_CF/", - "category": [ - "string", - "string" - ], - "region": [ - "string", - "string" - ], - "hasSample": false, - "isRestricted": false - } - ], - "@id": "datasets/", - "title": "Datasets", - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - } - }, - "matchingRules": { - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json" - } - ], - "combine": "AND" - } - }, - "body": { - "$.@context.@vocab": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@context.@base": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.description": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.title": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources": { - "matchers": [ - { - "match": "type", - "min": 1 - } - ], - "combine": "AND" - }, - "$.resources[*].category": { - "matchers": [ - { - "match": "type", - "min": 0 - } - ], - "combine": "AND" - }, - "$.resources[*].category[*]": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].createdDate": { - "matchers": [ - { - "match": "date", - "format": "yyyy-MM-dd" - } - ], - "combine": "AND" - }, - "$.resources[*].description": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].frequency": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].isThirdPartyData": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].isInternalOnlyDataset": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].language": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].modifiedDate": { - "matchers": [ - { - "match": "date", - "format": "yyyy-MM-dd" - } - ], - "combine": "AND" - }, - "$.resources[*].publisher": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].region": { - "matchers": [ - { - "match": "type", - "min": 0 - } - ], - "combine": "AND" - }, - "$.resources[*].region[*]": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].source": { - "matchers": [ - { - "match": "type", - "min": 0 - } - ], - "combine": "AND" - }, - "$.resources[*].source[*]": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].subCategory": { - "matchers": [ - { - "match": "type", - "min": 0 - } - ], - "combine": "AND" - }, - "$.resources[*].subCategory[*]": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].title": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].tag": { - "matchers": [ - { - "match": "type", - "min": 0 - } - ], - "combine": "AND" - }, - "$.resources[*].tag[*]": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].isRestricted": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].isRawData": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].hasSample": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - } - } - }, - "generators": { - "body": { - "$.resources[*].category[*]": { - "type": "RandomString", - "size": 20 - }, - "$.resources[*].region[*]": { - "type": "RandomString", - "size": 20 - }, - "$.resources[*].source[*]": { - "type": "RandomString", - "size": 20 - }, - "$.resources[*].subCategory[*]": { - "type": "RandomString", - "size": 20 - }, - "$.resources[*].tag[*]": { - "type": "RandomString", - "size": 20 - } - } - } - }, - "providerStates": [ - { - "name": "a list of datasets" - } - ] - }, - { - "description": "a request for distributions available for a series member", - "request": { - "method": "GET", - "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/2022-01-16/distributions", - "headers": { - "Authorization": "Bearer my-bearer-token" - }, - "matchingRules": { - "header": { - "Authorization": { - "matchers": [ - { - "match": "regex", - "regex": "Bearer my-bearer-token" - } - ], - "combine": "AND" - } - } - } - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/json" - }, - "body": { - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - }, - "@id": "distributions/", - "description": "A list of available distributions", - "identifier": "distributions", - "resources": [ - { - "@id": "csv/", - "description": "Snapshot data, in tabular, csv format", - "fileExtension": ".csv", - "identifier": "csv", - "mediaType": "text/csv; header=present; charset=utf-8", - "title": "CSV" - } - ], - "title": "Distributions" - }, - "matchingRules": { - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json" - } - ], - "combine": "AND" - } - }, - "body": { - "$.@context.@vocab": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@context.@base": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.description": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.title": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources": { - "matchers": [ - { - "match": "type", - "min": 1 - } - ], - "combine": "AND" - }, - "$.resources[*].description": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].title": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].fileExtension": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].mediaType": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - } - } - } - }, - "providerStates": [ - { - "name": "a list of distributions available for a series member" - } - ] - }, - { - "description": "a request for a list of series members of a dataset", - "request": { - "method": "GET", - "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries", - "headers": { - "Authorization": "Bearer my-bearer-token" - }, - "matchingRules": { - "header": { - "Authorization": { - "matchers": [ - { - "match": "regex", - "regex": "Bearer my-bearer-token" - } - ], - "combine": "AND" - } - } - } - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/json" - }, - "body": { - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - }, - "@id": "datasetseries/", - "description": "A list of available datasetseries of a dataset", - "identifier": "datasetseries", - "resources": [ - { - "@id": "20230319/", - "createdDate": "2023-03-19", - "fromDate": "2023-03-18", - "identifier": "20230319", - "toDate": "2023-03-17" - } - ], - "title": "DatasetSeries" - }, - "matchingRules": { - "header": { - "Content-Type": { + ], + "combine": "AND" + }, + "$.resources[*].modifiedDate": { "matchers": [ { - "match": "regex", - "regex": "application/json" + "match": "date", + "format": "yyyy-MM-dd" } ], "combine": "AND" - } - }, - "body": { - "$.@context.@vocab": { + }, + "$.resources[*].publisher": { "matchers": [ { "match": "type" @@ -2163,15 +381,16 @@ ], "combine": "AND" }, - "$.@context.@base": { + "$.resources[*].region": { "matchers": [ { - "match": "type" + "match": "type", + "min": 0 } ], "combine": "AND" }, - "$.@id": { + "$.resources[*].region[*]": { "matchers": [ { "match": "type" @@ -2179,7 +398,16 @@ ], "combine": "AND" }, - "$.description": { + "$.resources[*].source": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].source[*]": { "matchers": [ { "match": "type" @@ -2187,7 +415,16 @@ ], "combine": "AND" }, - "$.identifier": { + "$.resources[*].subCategory": { + "matchers": [ + { + "match": "type", + "min": 0 + } + ], + "combine": "AND" + }, + "$.resources[*].subCategory[*]": { "matchers": [ { "match": "type" @@ -2195,7 +432,7 @@ ], "combine": "AND" }, - "$.title": { + "$.resources[*].title": { "matchers": [ { "match": "type" @@ -2203,43 +440,40 @@ ], "combine": "AND" }, - "$.resources": { + "$.resources[*].tag": { "matchers": [ { "match": "type", - "min": 1 + "min": 0 } ], "combine": "AND" }, - "$.resources[*].createdDate": { + "$.resources[*].tag[*]": { "matchers": [ { - "match": "date", - "format": "yyyy-MM-dd" + "match": "type" } ], "combine": "AND" }, - "$.resources[*].fromDate": { + "$.resources[*].isRestricted": { "matchers": [ { - "match": "date", - "format": "yyyy-MM-dd" + "match": "type" } ], "combine": "AND" }, - "$.resources[*].toDate": { + "$.resources[*].isRawData": { "matchers": [ { - "match": "date", - "format": "yyyy-MM-dd" + "match": "type" } ], "combine": "AND" }, - "$.resources[*].identifier": { + "$.resources[*].hasSample": { "matchers": [ { "match": "type" @@ -2256,11 +490,35 @@ "combine": "AND" } } + }, + "generators": { + "body": { + "$.resources[*].category[*]": { + "type": "RandomString", + "size": 20 + }, + "$.resources[*].region[*]": { + "type": "RandomString", + "size": 20 + }, + "$.resources[*].source[*]": { + "type": "RandomString", + "size": 20 + }, + "$.resources[*].subCategory[*]": { + "type": "RandomString", + "size": 20 + }, + "$.resources[*].tag[*]": { + "type": "RandomString", + "size": 20 + } + } } }, "providerStates": [ { - "name": "a list of series members for a dataset" + "name": "a list of datasets" } ] }, @@ -4055,174 +2313,6 @@ } ] }, - { - "description": "a request for dataset series member metadata", - "request": { - "method": "GET", - "path": "/v1/catalogs/common/datasets/API_TEST/datasetseries/2022-01-16", - "headers": { - "Authorization": "Bearer my-bearer-token" - }, - "matchingRules": { - "header": { - "Authorization": { - "matchers": [ - { - "match": "regex", - "regex": "Bearer my-bearer-token" - } - ], - "combine": "AND" - } - } - } - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/json" - }, - "body": { - "@context": { - "@base": "https://fusion-api.test.aws.jpmchase.net/v1", - "@vocab": "https://www.w3.org/ns/dcat3.jsondld" - }, - "@id": "20230319/", - "createdDate": "2023-03-19", - "fromDate": "2023-03-18", - "identifier": "20230319", - "resources": [ - { - "@id": "distributions/", - "description": "A list of available distributions", - "identifier": "distributions", - "title": "Distributions" - } - ], - "toDate": "2023-03-17" - }, - "matchingRules": { - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json" - } - ], - "combine": "AND" - } - }, - "body": { - "$.@context.@vocab": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@context.@base": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources": { - "matchers": [ - { - "match": "type", - "min": 1 - } - ], - "combine": "AND" - }, - "$.resources[*].@id": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].description": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].identifier": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.resources[*].title": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.createdDate": { - "matchers": [ - { - "match": "date", - "format": "yyyy-MM-dd" - } - ], - "combine": "AND" - }, - "$.fromDate": { - "matchers": [ - { - "match": "date", - "format": "yyyy-MM-dd" - } - ], - "combine": "AND" - }, - "$.toDate": { - "matchers": [ - { - "match": "date", - "format": "yyyy-MM-dd" - } - ], - "combine": "AND" - } - } - } - }, - "providerStates": [ - { - "name": "metadata for a dataset series member" - } - ] - }, { "description": "a request for catalogs", "request": { From b79ea5be0b1874bdb5f4ebc20c463d9bf79ed322 Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Tue, 2 May 2023 12:23:56 +0100 Subject: [PATCH 26/32] Tweaks as per provider integration of PACT --- .../pact/FusionApiConsumerPactTest.java | 11 +- .../pact/util/RequestResponseHelper.java | 9 +- ...dk-consumer-110274-fusionapi-provider.json | 161 +----------------- 3 files changed, 16 insertions(+), 165 deletions(-) diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java index a9dd83d..a743064 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java @@ -69,9 +69,8 @@ public RequestResponsePact getCatalogResourcesWhenCatalogNotFound(PactDslWithPro return failedGetExpectation( builder, "a catalog that does not exist", - "a request for that catalogs resources", + "a request for catalogs resources", "/v1/catalogs/alternate", - "Not Found", 404); } @@ -231,7 +230,7 @@ void testListCatalogsWhenNoneAreAvailable(MockServer mockServer) { @PactTestFor(pactMethod = "listCatalogsWhenNotAuthorized") void testListCatalogsWhenNotAuthorized(MockServer mockServer) { - givenInstanceOfFusionSdk(mockServer); + givenInstanceOfFusionSdk(mockServer, "invalid-bearer-token"); APICallException ex = Assertions.assertThrows(APICallException.class, () -> fusion.listCatalogs()); assertThat( @@ -547,9 +546,13 @@ private void thenTheFileShouldBeDownloaded(String path) { } private void givenInstanceOfFusionSdk(MockServer mockServer) { + givenInstanceOfFusionSdk(mockServer, "my-bearer-token"); + } + + private void givenInstanceOfFusionSdk(MockServer mockServer, String bearerToken) { fusion = Fusion.builder() .rootURL(mockServer.getUrl() + FUSION_API_VERSION) - .bearerToken("my-bearer-token") + .bearerToken(bearerToken) .build(); } } diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java index 6ba805e..d9e171d 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java @@ -1,7 +1,5 @@ package io.github.jpmorganchase.fusion.pact.util; -import static io.github.jpmorganchase.fusion.pact.util.BodyBuilders.error; - import au.com.dius.pact.consumer.dsl.DslPart; import au.com.dius.pact.consumer.dsl.PactDslResponse; import au.com.dius.pact.consumer.dsl.PactDslWithProvider; @@ -35,14 +33,9 @@ public static RequestResponsePact getExpectation( return getExpectation(builder, given, upon, path, body, "application/json"); } - public static RequestResponsePact failedGetExpectation( - PactDslWithProvider builder, String given, String upon, String path, String error, int status) { - return failedGetExpectation(builder, given, upon, path, status, error(path, status, error)); - } - public static RequestResponsePact failedGetExpectation( PactDslWithProvider builder, String given, String upon, String path, int status) { - return failedGetExpectation(builder, given, upon, path, null, status); + return failedGetExpectation(builder, given, upon, path, status, null); } public static RequestResponsePact failedGetExpectation( diff --git a/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json index 5ccd118..654c179 100644 --- a/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json +++ b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json @@ -7,7 +7,7 @@ }, "interactions": [ { - "description": "a request for that catalogs resources", + "description": "a request for catalogs resources", "request": { "method": "GET", "path": "/v1/catalogs/alternate", @@ -29,80 +29,7 @@ } }, "response": { - "status": 404, - "headers": { - "Content-Type": "application/json; charset=UTF-8" - }, - "body": { - "path": "/v1/catalogs/alternate", - "requestId": "string", - "error": "Not Found", - "timestamp": "2023-05-01", - "status": 404 - }, - "matchingRules": { - "body": { - "$.timestamp": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.path": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.status": { - "matchers": [ - { - "match": "integer" - } - ], - "combine": "AND" - }, - "$.error": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.requestId": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - } - }, - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json(;\\s?charset=[\\w\\-]+)?" - } - ], - "combine": "AND" - } - } - }, - "generators": { - "body": { - "$.requestId": { - "type": "RandomString", - "size": 20 - } - } - } + "status": 404 }, "providerStates": [ { @@ -192,9 +119,9 @@ ], "title": "Swaptions Caps & Floors", "frequency": "Daily", - "createdDate": "2023-05-01", + "createdDate": "2023-05-02", "isThirdPartyData": false, - "modifiedDate": "2023-05-01", + "modifiedDate": "2023-05-02", "publisher": "J.P. Morgan", "tag": [ "string", @@ -1072,7 +999,7 @@ "string" ], "datasetCount": 18, - "releaseDate": "2023-05-01", + "releaseDate": "2023-05-02", "deliveryChannel": [ "string", "string" @@ -1641,9 +1568,9 @@ }, "maintainer": "J.P. Morgan DM Rates Research", "frequency": "Daily", - "createdDate": "2023-05-01", + "createdDate": "2023-05-02", "isThirdPartyData": false, - "modifiedDate": "2023-05-01", + "modifiedDate": "2023-05-02", "publisher": "J.P. Morgan", "@id": "GFI_OP_CF/", "tag": [ @@ -2812,79 +2739,7 @@ } }, "response": { - "status": 401, - "headers": { - "Content-Type": "application/json; charset=UTF-8" - }, - "body": { - "path": "/v1/catalogs", - "requestId": "string", - "timestamp": "2023-05-01", - "status": 401 - }, - "matchingRules": { - "body": { - "$.timestamp": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.path": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.status": { - "matchers": [ - { - "match": "integer" - } - ], - "combine": "AND" - }, - "$.error": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - }, - "$.requestId": { - "matchers": [ - { - "match": "type" - } - ], - "combine": "AND" - } - }, - "header": { - "Content-Type": { - "matchers": [ - { - "match": "regex", - "regex": "application/json(;\\s?charset=[\\w\\-]+)?" - } - ], - "combine": "AND" - } - } - }, - "generators": { - "body": { - "$.requestId": { - "type": "RandomString", - "size": 20 - } - } - } + "status": 401 }, "providerStates": [ { From f67e36e32a942cc4d51880af8465b57beaf438f2 Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Tue, 2 May 2023 12:30:55 +0100 Subject: [PATCH 27/32] Corrected failing test --- .../pact/FusionApiConsumerPactTest.java | 7 ++++++- .../pact/util/RequestResponseHelper.java | 19 ++++++------------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java index a743064..c960989 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionApiConsumerPactTest.java @@ -51,7 +51,12 @@ public RequestResponsePact listCatalogsWhenNoneAreAvailable(PactDslWithProvider @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") public RequestResponsePact listCatalogsWhenNotAuthorized(PactDslWithProvider builder) { return failedGetExpectation( - builder, "not authorized to list catalogs", "a request for catalogs", "/v1/catalogs", 401); + builder, + "not authorized to list catalogs", + "a request for catalogs", + "/v1/catalogs", + 401, + "Bearer invalid-bearer-token"); } @Pact(provider = "110274-fusionapi-provider", consumer = "110274-fusionsdk-consumer") diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java index d9e171d..f6ebbc2 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/RequestResponseHelper.java @@ -1,7 +1,6 @@ package io.github.jpmorganchase.fusion.pact.util; import au.com.dius.pact.consumer.dsl.DslPart; -import au.com.dius.pact.consumer.dsl.PactDslResponse; import au.com.dius.pact.consumer.dsl.PactDslWithProvider; import au.com.dius.pact.core.model.RequestResponsePact; import java.util.Map; @@ -35,25 +34,19 @@ public static RequestResponsePact getExpectation( public static RequestResponsePact failedGetExpectation( PactDslWithProvider builder, String given, String upon, String path, int status) { - return failedGetExpectation(builder, given, upon, path, status, null); + return failedGetExpectation(builder, given, upon, path, status, AUTH_VAL); } public static RequestResponsePact failedGetExpectation( - PactDslWithProvider builder, String given, String upon, String path, int status, DslPart body) { - - PactDslResponse response = builder.given(given) + PactDslWithProvider builder, String given, String upon, String path, int status, String authValue) { + return builder.given(given) .uponReceiving(upon) .path(path) - .matchHeader("Authorization", AUTH_VAL) + .matchHeader("Authorization", authValue) .method("GET") .willRespondWith() - .status(status); - - if (null != body) { - response.body(body); - } - - return response.toPact(); + .status(status) + .toPact(); } public static RequestResponsePact downloadExpectation( From 27f7c566659c4698c78d83784b5ef5229f0d5b67 Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Tue, 2 May 2023 12:41:54 +0100 Subject: [PATCH 28/32] Update 110274-fusionsdk-consumer-110274-fusionapi-provider.json --- .../110274-fusionsdk-consumer-110274-fusionapi-provider.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json index 654c179..a23df3e 100644 --- a/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json +++ b/src/test/resources/io/github/jpmorganchase/fusion/pact-samples/110274-fusionsdk-consumer-110274-fusionapi-provider.json @@ -2722,7 +2722,7 @@ "method": "GET", "path": "/v1/catalogs", "headers": { - "Authorization": "Bearer my-bearer-token" + "Authorization": "Bearer invalid-bearer-token" }, "matchingRules": { "header": { @@ -2730,7 +2730,7 @@ "matchers": [ { "match": "regex", - "regex": "Bearer my-bearer-token" + "regex": "Bearer invalid-bearer-token" } ], "combine": "AND" From 028e099d32be99790190861ec3d559602dc4b258 Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Tue, 2 May 2023 14:56:12 +0100 Subject: [PATCH 29/32] Removing redundant e2e tests --- .../fusion/e2e/MetadataRetrievalTest.java | 62 ------------------- .../catalog-success-response.json | 30 --------- src/it/resources/logback-test.xml | 21 ------- 3 files changed, 113 deletions(-) delete mode 100644 src/it/java/io/github/jpmorganchase/fusion/e2e/MetadataRetrievalTest.java delete mode 100644 src/it/resources/e2e-responses/catalog-success-response.json delete mode 100644 src/it/resources/logback-test.xml diff --git a/src/it/java/io/github/jpmorganchase/fusion/e2e/MetadataRetrievalTest.java b/src/it/java/io/github/jpmorganchase/fusion/e2e/MetadataRetrievalTest.java deleted file mode 100644 index 03af1ff..0000000 --- a/src/it/java/io/github/jpmorganchase/fusion/e2e/MetadataRetrievalTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package io.github.jpmorganchase.fusion.e2e; - -import com.github.tomakehurst.wiremock.common.Slf4jNotifier; -import com.github.tomakehurst.wiremock.junit5.WireMockExtension; -import io.github.jpmorganchase.fusion.Fusion; -import io.github.jpmorganchase.fusion.model.Catalog; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Map; - -import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; -import static com.github.tomakehurst.wiremock.client.WireMock.*; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.MatcherAssert.*; - -/* - Very early Beginnings of end-to-end testing. We need to consider how we want to spin up the stub for Fusion. - Doing it programatically in Wiremock feels like it's going to be difficult to maintain - Look at the work on Pact and decide if that's a good fit here? - */ -@Tag("integration") -public class MetadataRetrievalTest { - - @RegisterExtension - static WireMockExtension wiremock = WireMockExtension.newInstance() - .options(wireMockConfig().dynamicPort().notifier(new Slf4jNotifier(true))) - .configureStaticDsl(true) - .build(); - - @Test - void retrieveListOfCatalogsUsingBearerToken() { - stubFor(get("/catalogs").willReturn(aResponse().withBody(loadTestResource("/e2e-responses/catalog-success-response.json")))); - - Fusion fusion = Fusion.builder() - .rootURL(wiremock.getRuntimeInfo().getHttpBaseUrl()+"/") - .bearerToken("my-token") - .build(); - - - Map catalogMap = fusion.listCatalogs(); - assertThat(catalogMap.size(), is(3)); - assertThat(catalogMap.get("test").getTitle(), is(equalTo("Test data catalog"))); - } - - private static String loadTestResource(String resourceName) { - URL url = MetadataRetrievalTest.class.getResource(resourceName); - try { - Path path = Paths.get(url.toURI()); - return new String(Files.readAllBytes(path), StandardCharsets.UTF_8); - } catch (Exception e) { - throw new RuntimeException("Failed to load test data", e); - } - } -} diff --git a/src/it/resources/e2e-responses/catalog-success-response.json b/src/it/resources/e2e-responses/catalog-success-response.json deleted file mode 100644 index 6a44a86..0000000 --- a/src/it/resources/e2e-responses/catalog-success-response.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "@context": { - "@vocab": "https://www.w3.org/ns/dcat3.jsonld", - "@base": "https://fusion-api.jpmorgan.com/fusion/v1/catalogs/" - }, - "@id": "catalogs/", - "description": "A list of available catalogs", - "identifier": "catalogs", - "resources": [ - { - "@id": "test/", - "description": "A catalog used for test cases", - "identifier": "test", - "title": "Test data catalog" - }, - { - "@id": "test2/", - "description": "A second catalog used for test cases", - "identifier": "test2", - "title": "Test data catalog 2" - }, - { - "@id": "test3/", - "description": "A third catalog used for test cases", - "identifier": "test3", - "title": "Test data catalog 3" - } - ], - "title": "Catalogs" -} \ No newline at end of file diff --git a/src/it/resources/logback-test.xml b/src/it/resources/logback-test.xml deleted file mode 100644 index 809380a..0000000 --- a/src/it/resources/logback-test.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%kvp- %msg%n - - - - - - - - - - - - \ No newline at end of file From 2b62dad5a1bbbbc14985e8f2eeae1b64066421e5 Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Thu, 4 May 2023 11:11:39 +0100 Subject: [PATCH 30/32] simplified the provision of dataset tokens at construction --- .../github/jpmorganchase/fusion/Fusion.java | 14 +++- .../oauth/exception/OAuthException.java | 5 ++ .../provider/SimpleDatasetTokenProvider.java | 27 +++++++ .../SimpleDatasetTokenProviderTest.java | 72 +++++++++++++++++++ .../pact/FusionUploadConsumerPactTest.java | 2 +- 5 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 src/main/java/io/github/jpmorganchase/fusion/oauth/provider/SimpleDatasetTokenProvider.java create mode 100644 src/test/java/io/github/jpmorganchase/fusion/oauth/provider/SimpleDatasetTokenProviderTest.java diff --git a/src/main/java/io/github/jpmorganchase/fusion/Fusion.java b/src/main/java/io/github/jpmorganchase/fusion/Fusion.java index cca2b8b..3be3a2e 100644 --- a/src/main/java/io/github/jpmorganchase/fusion/Fusion.java +++ b/src/main/java/io/github/jpmorganchase/fusion/Fusion.java @@ -13,9 +13,11 @@ import io.github.jpmorganchase.fusion.model.*; import io.github.jpmorganchase.fusion.oauth.credential.*; import io.github.jpmorganchase.fusion.oauth.exception.OAuthException; +import io.github.jpmorganchase.fusion.oauth.model.BearerToken; import io.github.jpmorganchase.fusion.oauth.provider.DatasetTokenProvider; import io.github.jpmorganchase.fusion.oauth.provider.OAuthDatasetTokenProvider; import io.github.jpmorganchase.fusion.oauth.provider.OAuthSessionTokenProvider; +import io.github.jpmorganchase.fusion.oauth.provider.SimpleDatasetTokenProvider; import io.github.jpmorganchase.fusion.parsing.APIResponseParser; import io.github.jpmorganchase.fusion.parsing.GsonAPIResponseParser; import io.github.jpmorganchase.fusion.parsing.ParsingException; @@ -30,6 +32,7 @@ import java.nio.file.Paths; import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.util.HashMap; import java.util.List; import java.util.Map; import lombok.AccessLevel; @@ -567,6 +570,8 @@ public static class FusionBuilder { protected String credentialFile; protected String rootURL; protected APIManager api; + protected Map datasetBearerTokens = new HashMap<>(); + protected DatasetTokenProvider datasetTokenProvider; public FusionBuilder bearerToken(String token) { @@ -606,8 +611,8 @@ public FusionBuilder rootURL(String rootURL) { return this; } - public FusionBuilder datasetTokenProvider(DatasetTokenProvider datasetTokenProvider) { - this.datasetTokenProvider = datasetTokenProvider; + public FusionBuilder datasetBearerToken(String catalog, String dataset, String token) { + datasetBearerTokens.put(String.format("%s_%s", catalog, dataset), BearerToken.of(token)); return this; } } @@ -653,9 +658,12 @@ public Fusion build() { // TODO : Make this part of the builder journey OAuthSessionTokenProvider sessionTokenProvider = new OAuthSessionTokenProvider(credentials, client); - if (datasetTokenProvider == null) { + if (datasetBearerTokens.isEmpty()) { datasetTokenProvider = new OAuthDatasetTokenProvider(rootURL, sessionTokenProvider, client); + } else { + datasetTokenProvider = new SimpleDatasetTokenProvider(datasetBearerTokens); } + DigestProducer digestProducer = AlgoSpecificDigestProducer.builder().sha256().build(); diff --git a/src/main/java/io/github/jpmorganchase/fusion/oauth/exception/OAuthException.java b/src/main/java/io/github/jpmorganchase/fusion/oauth/exception/OAuthException.java index 68e269c..6c16b5b 100644 --- a/src/main/java/io/github/jpmorganchase/fusion/oauth/exception/OAuthException.java +++ b/src/main/java/io/github/jpmorganchase/fusion/oauth/exception/OAuthException.java @@ -4,6 +4,11 @@ public class OAuthException extends RuntimeException { private final String response; + public OAuthException(String message) { + super(message); + this.response = message; + } + public OAuthException(String message, String response) { super(message); this.response = response; diff --git a/src/main/java/io/github/jpmorganchase/fusion/oauth/provider/SimpleDatasetTokenProvider.java b/src/main/java/io/github/jpmorganchase/fusion/oauth/provider/SimpleDatasetTokenProvider.java new file mode 100644 index 0000000..d84a32a --- /dev/null +++ b/src/main/java/io/github/jpmorganchase/fusion/oauth/provider/SimpleDatasetTokenProvider.java @@ -0,0 +1,27 @@ +package io.github.jpmorganchase.fusion.oauth.provider; + +import io.github.jpmorganchase.fusion.oauth.exception.OAuthException; +import io.github.jpmorganchase.fusion.oauth.model.BearerToken; +import java.util.Map; + +public class SimpleDatasetTokenProvider implements DatasetTokenProvider { + + private static final String BEARER_TOKEN_NOT_FOUND_ERROR = "Bearer token not found for catalog %s and dataset %s"; + + private final Map datasetTokens; + + public SimpleDatasetTokenProvider(Map datasetTokens) { + this.datasetTokens = datasetTokens; + } + + @Override + public String getDatasetBearerToken(String catalog, String dataset) { + + String tokenKey = String.format("%s_%s", catalog, dataset); + if (datasetTokens.containsKey(tokenKey)) { + return datasetTokens.get(tokenKey).getToken(); + } + + throw new OAuthException(String.format(BEARER_TOKEN_NOT_FOUND_ERROR, catalog, dataset)); + } +} diff --git a/src/test/java/io/github/jpmorganchase/fusion/oauth/provider/SimpleDatasetTokenProviderTest.java b/src/test/java/io/github/jpmorganchase/fusion/oauth/provider/SimpleDatasetTokenProviderTest.java new file mode 100644 index 0000000..4895076 --- /dev/null +++ b/src/test/java/io/github/jpmorganchase/fusion/oauth/provider/SimpleDatasetTokenProviderTest.java @@ -0,0 +1,72 @@ +package io.github.jpmorganchase.fusion.oauth.provider; + +import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import io.github.jpmorganchase.fusion.oauth.exception.OAuthException; +import io.github.jpmorganchase.fusion.oauth.model.BearerToken; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; + +@SuppressWarnings("SameParameterValue") +public class SimpleDatasetTokenProviderTest { + + private SimpleDatasetTokenProvider tokenProvider; + + private Map datasetTokens = new HashMap<>(); + + private String actualToken; + + private OAuthException oAuthException; + + @Test + public void testGetDatasetBearerToken_whenValidTokenExists_thenReturnToken() { + givenDatasetTokens("catalog1_dataset1", "token1"); + givenTokenProvider(); + + whenGetDatasetBearerTokenIsCalled("catalog1", "dataset1"); + + thenTokenShouldMatch("token1"); + } + + @Test + public void testGetDatasetBearerToken_whenInvalidTokenExists_thenThrowOAuthException() { + givenTokenProvider(); + whenGetDatasetBearerTokenIsCalledExceptionIsExpected("catalog3", "dataset1"); + thenExceptionMessageShouldMatch("Bearer token not found for catalog catalog3 and dataset dataset1"); + } + + @Test + public void testGetDatasetBearerToken_whenTokenDoesNotExist_thenThrowOAuthException() { + givenTokenProvider(); + whenGetDatasetBearerTokenIsCalledExceptionIsExpected("catalog1", "dataset3"); + thenExceptionMessageShouldMatch("Bearer token not found for catalog catalog1 and dataset dataset3"); + } + + private void thenExceptionMessageShouldMatch(String expected) { + assertThat("Exception Message does not match", oAuthException.getMessage(), is(equalTo(expected))); + } + + private void whenGetDatasetBearerTokenIsCalledExceptionIsExpected(String catalog, String dataset) { + oAuthException = + assertThrows(OAuthException.class, () -> tokenProvider.getDatasetBearerToken(catalog, dataset)); + } + + private void thenTokenShouldMatch(String expected) { + assertThat("Token does not match", actualToken, is(equalTo(expected))); + } + + private void whenGetDatasetBearerTokenIsCalled(String catalog, String dataset) { + actualToken = tokenProvider.getDatasetBearerToken(catalog, dataset); + } + + private void givenDatasetTokens(String tokenKey, String token) { + datasetTokens.put(tokenKey, BearerToken.of(token)); + } + + private void givenTokenProvider() { + tokenProvider = new SimpleDatasetTokenProvider(datasetTokens); + } +} diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java index afde2cd..2549ee3 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/FusionUploadConsumerPactTest.java @@ -110,7 +110,7 @@ private void givenInstanceOfFusionSdk(MockServer mockServer) { fusion = Fusion.builder() .rootURL(mockServer.getUrl() + FUSION_API_VERSION) .bearerToken("my-bearer-token") - .datasetTokenProvider((catalog, dataset) -> "my-fusion-bearer") + .datasetBearerToken("common", "API_TEST", "my-fusion-bearer") .build(); } From 2e32d12e212e26065070874060873abeb1ae6bfe Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Thu, 4 May 2023 15:03:21 +0100 Subject: [PATCH 31/32] changes as per pr review --- .../fusion/pact/util/FileHelper.java | 29 +++++++++++-------- src/test/resources/logback-test.xml | 4 +-- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java index 6887efd..a25f489 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java @@ -1,23 +1,28 @@ package io.github.jpmorganchase.fusion.pact.util; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; +import java.io.*; +import java.nio.charset.StandardCharsets; + import lombok.SneakyThrows; public class FileHelper { private FileHelper() {} - @SneakyThrows - public static String readContentsFromStream(InputStream is) { - byte[] bytes = new byte[1024]; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - int read = is.read(bytes); - while (read != -1) { - baos.write(bytes, 0, read); - read = is.read(bytes); + /** + This is a test method to read contents from an input stream and return them as a string. + + @param is The input stream to read from. + @return The contents of the input stream as a string. + */ + public static String readContentsFromStream(InputStream is) throws IOException { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) { + StringBuilder sb = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + sb.append(line); + } + return sb.toString(); } - baos.close(); - return baos.toString(); } } diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index a686e7c..d2ac40a 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -11,10 +11,10 @@ - + - + From 4fb2319b0de9bf035340507e359e0e1948ef83cf Mon Sep 17 00:00:00 2001 From: Ian Knight <128476114+knighto82@users.noreply.github.com> Date: Thu, 4 May 2023 15:05:19 +0100 Subject: [PATCH 32/32] spotless .... --- .../jpmorganchase/fusion/pact/util/FileHelper.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/test/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java b/src/test/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java index a25f489..8efba2b 100644 --- a/src/test/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java +++ b/src/test/java/io/github/jpmorganchase/fusion/pact/util/FileHelper.java @@ -3,17 +3,15 @@ import java.io.*; import java.nio.charset.StandardCharsets; -import lombok.SneakyThrows; - public class FileHelper { private FileHelper() {} /** - This is a test method to read contents from an input stream and return them as a string. - - @param is The input stream to read from. - @return The contents of the input stream as a string. + * This is a test method to read contents from an input stream and return them as a string. + * + * @param is The input stream to read from. + * @return The contents of the input stream as a string. */ public static String readContentsFromStream(InputStream is) throws IOException { try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {