Refine documentSource locations

Closes gh-338
This commit is contained in:
rstoyanchev
2022-04-01 21:39:21 +01:00
parent 9289f0a1b5
commit 696f2cd02f
11 changed files with 68 additions and 18 deletions

View File

@@ -295,9 +295,11 @@ For example:
The document for a request is a `String` that may be defined in a local variable or
constant, or it may be produced through a code generated request object.
Alternatively, you can also keep documents in files with extensions `.graphql` or `
.gql`, on the classpath or anywhere else, and refer to those by file name. For example,
given:
You can also create document files with extensions `.graphql` or `.gql` under
`"graphql-documents/"` on the classpath and refer to them by file name.
For example, given a file called `projectReleases.graphql` in
`src/main/resources/graphql-documents`, with content:
[source,graphql,indent=0,subs="verbatim,quotes"]
.src/main/resources/graphql/project.graphql
@@ -316,7 +318,7 @@ You can then:
[source,java,indent=0,subs="verbatim,quotes"]
----
Mono<Project> projectMono = graphQlClient.documentName("project") <1>
Mono<Project> projectMono = graphQlClient.documentName("projectReleases") <1>
.variable("slug", "spring-framework") <2>
.retrieve()
.toEntity(Project.class);

View File

@@ -281,8 +281,10 @@ project release versions from the response:
The JsonPath is relative to the "data" section of the response.
You can also create document files with extensions `.graphql` or `.gql` under
`"graphql/"` on the classpath and refer to them by file name. For example, given a file
called `projectReleases.graphql` in `src/main/resources/graphql`, with content:
`"graphql-test/"` on the classpath and refer to them by file name.
For example, given a file called `projectReleases.graphql` in
`src/main/resources/graphql-test`, with content:
[source,graphql,indent=0,subs="verbatim,quotes"]
----

View File

@@ -16,6 +16,7 @@
package org.springframework.graphql.test.tester;
import java.time.Duration;
import java.util.Collections;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -27,6 +28,7 @@ import com.jayway.jsonpath.spi.mapper.MappingProvider;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.core.io.ClassPathResource;
import org.springframework.graphql.GraphQlRequest;
import org.springframework.graphql.GraphQlResponse;
import org.springframework.graphql.ResponseError;
@@ -64,13 +66,24 @@ public abstract class AbstractGraphQlTesterBuilder<B extends AbstractGraphQlTest
@Nullable
private Predicate<ResponseError> errorFilter;
private DocumentSource documentSource = new CachingDocumentSource(new ResourceDocumentSource());
private DocumentSource documentSource;
private Configuration jsonPathConfig = Configuration.builder().build();
private Duration responseTimeout = DEFAULT_RESPONSE_DURATION;
public AbstractGraphQlTesterBuilder() {
this.documentSource = initDocumentSource();
}
private static DocumentSource initDocumentSource() {
return new ResourceDocumentSource(
Collections.singletonList(new ClassPathResource("graphql-test/")),
ResourceDocumentSource.FILE_EXTENSIONS);
}
@Override
public B errorFilter(Predicate<ResponseError> predicate) {
this.errorFilter = (this.errorFilter != null ? errorFilter.and(predicate) : predicate);

View File

@@ -64,8 +64,8 @@ public interface GraphQlTester {
/**
* Variant of {@link #document(String)} that uses the given key to resolve
* the GraphQL document from a file, or in another way with the help of the
* {@link DocumentSource} that the client is configured with.
* the GraphQL document from a file with the help of the configured
* {@link Builder#documentSource(DocumentSource) DocumentSource}.
* @return spec for response assertions
* @throws IllegalArgumentException if the documentName cannot be resolved
* @throws AssertionError if the response status is not 200 (OK)
@@ -108,7 +108,9 @@ public interface GraphQlTester {
/**
* Configure a {@link DocumentSource} for use with
* {@link #documentName(String)} for resolving a document by name.
* <p>By default, {@link ResourceDocumentSource} is used.
* <p>By default, this is set to {@link ResourceDocumentSource} with
* classpath location {@code "graphql-test/"} and
* {@link ResourceDocumentSource#FILE_EXTENSIONS} as extensions.
*/
B documentSource(DocumentSource contentLoader);

View File

@@ -35,6 +35,14 @@ public class GraphQlTesterBuilderTests extends GraphQlTesterTestSupport {
private static final String DOCUMENT = "{ Query }";
@Test
void defaultDocumentSource() {
String document = "{ greeting }";
getGraphQlService().setDataAsJson(document, "{}");
graphQlTester().documentName("greeting").execute();
assertThat(getActualRequestDocument()).isEqualTo(document);
}
@Test
void mutateDocumentSource() {

View File

@@ -0,0 +1 @@
{ greeting }

View File

@@ -18,11 +18,13 @@ package org.springframework.graphql.client;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import org.springframework.core.codec.Decoder;
import org.springframework.core.codec.Encoder;
import org.springframework.core.io.ClassPathResource;
import org.springframework.graphql.client.GraphQlClientInterceptor.Chain;
import org.springframework.graphql.client.GraphQlClientInterceptor.SubscriptionChain;
import org.springframework.graphql.support.CachingDocumentSource;
@@ -56,7 +58,7 @@ public abstract class AbstractGraphQlClientBuilder<B extends AbstractGraphQlClie
private final List<GraphQlClientInterceptor> interceptors = new ArrayList<>();
private DocumentSource documentSource = new CachingDocumentSource(new ResourceDocumentSource());
private DocumentSource documentSource;
@Nullable
private Encoder<?> jsonEncoder;
@@ -71,6 +73,13 @@ public abstract class AbstractGraphQlClientBuilder<B extends AbstractGraphQlClie
* during, by overriding {@link #build()}.
*/
protected AbstractGraphQlClientBuilder() {
this.documentSource = initDocumentSource();
}
private static DocumentSource initDocumentSource() {
return new CachingDocumentSource(new ResourceDocumentSource(
Collections.singletonList(new ClassPathResource("graphql-documents/")),
ResourceDocumentSource.FILE_EXTENSIONS));
}

View File

@@ -59,8 +59,8 @@ public interface GraphQlClient {
/**
* Variant of {@link #document(String)} that uses the given key to resolve
* the GraphQL document from a file, or in another way with the help of the
* {@link DocumentSource} that the client is configured with.
* the GraphQL document from a file with the help of the configured
* {@link Builder#documentSource(DocumentSource) DocumentSource}.
* @throws IllegalArgumentException if the content could not be loaded
*/
RequestSpec documentName(String name);
@@ -109,7 +109,9 @@ public interface GraphQlClient {
/**
* Configure a {@link DocumentSource} for use with
* {@link #documentName(String)} for resolving a document by name.
* <p>By default, {@link ResourceDocumentSource} is used.
* <p>By default, this is set to {@link ResourceDocumentSource} with
* classpath location {@code "graphql-documents/"} and
* {@link ResourceDocumentSource#FILE_EXTENSIONS} as extensions.
*/
B documentSource(DocumentSource contentLoader);

View File

@@ -65,20 +65,22 @@ public class ResourceDocumentSource implements DocumentSource {
* Constructor with given locations and extensions.
*/
public ResourceDocumentSource(List<Resource> locations, List<String> extensions) {
this.locations = new ArrayList<>(locations);
this.extensions = new ArrayList<>(extensions);
this.locations = Collections.unmodifiableList(new ArrayList<>(locations));
this.extensions = Collections.unmodifiableList(new ArrayList<>(extensions));
}
/**
* Return the configured locations where to check for documents.
* Return a read-only list with the configured locations where to check for
* documents.
*/
public List<Resource> getLocations() {
return this.locations;
}
/**
* Return the file extensions to try when checking for documents by name.
* Return a read-only list with the file extensions to try when checking
* for documents by name.
*/
public List<String> getExtensions() {
return this.extensions;

View File

@@ -38,6 +38,14 @@ public class GraphQlClientBuilderTests extends GraphQlClientTestSupport {
private static final String DOCUMENT = "{ Query }";
@Test
void defaultDocumentSource() {
String document = "{ greeting }";
getGraphQlService().setDataAsJson(document, "{}");
graphQlClient().documentName("greeting").execute().block();
assertThat(getGraphQlService().getGraphQlRequest().getDocument()).isEqualTo(document);
}
@Test
void mutateDocumentSource() {

View File

@@ -0,0 +1 @@
{ greeting }