Skip to content
This repository was archived by the owner on Dec 19, 2023. It is now read-only.

Commit a340f8f

Browse files
committed
feat: clean up and add more test for individual case with custom path
1 parent 8d946fb commit a340f8f

File tree

5 files changed

+82
-11
lines changed

5 files changed

+82
-11
lines changed

graphql-spring-boot-test/src/main/java/com/graphql/spring/boot/test/GraphQLTestTemplate.java

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.util.Arrays;
1313
import java.util.Collections;
1414
import java.util.List;
15+
import java.util.function.IntFunction;
1516
import lombok.Getter;
1617
import lombok.NonNull;
1718
import org.springframework.beans.factory.annotation.Value;
@@ -313,24 +314,36 @@ public GraphQLResponse postMultipart(String query, String variables) {
313314
* will be a part of multipart request. GraphQL Servlet will use <i>map</i> part to walk through
314315
* variables.files and validate the request in combination with other binary file parts
315316
*
316-
* <p>-------------- request beginning ---------------
317+
* <p>----------------------------dummyid
317318
*
318-
* <p>operations: { "query": "mutation($files:[Upload]!) {uploadFiles(files:$files)}",
319-
* "operationName": "uploadFiles", "variables": { "files": [null, null] } }
319+
* <p>Content-Disposition: form-data; name="operations"
320320
*
321-
* <p>-----------------------------------------------
321+
* <p>{ "query": "mutation($files:[Upload]!) {uploadFiles(files:$files)}", "operationName":
322+
* "uploadFiles", "variables": { "files": [null, null] } }
323+
*
324+
* <p>----------------------------dummyid
325+
*
326+
* <p>Content-Disposition: form-data; name="map"
322327
*
323328
* <p>map: { "1":["variables.files.0"], "2":["variables.files.1"] }
324329
*
325-
* <p>-----------------------------------------------
330+
* <p>----------------------------dummyid
331+
*
332+
* <p>Content-Disposition: form-data; name="1"; filename="file1.pdf"
333+
*
334+
* <p>Content-Type: application/octet-stream
335+
*
336+
* <p>--file 1 binary code--
337+
*
338+
* <p>----------------------------dummyid
326339
*
327-
* <p>1: --file 1 binary code--
340+
* <p>Content-Disposition: form-data; name="2"; filename="file2.pdf"
328341
*
329-
* <p>-----------------------------------------------
342+
* <p>Content-Type: application/octet-stream
330343
*
331344
* <p>2: --file 2 binary code--
332345
*
333-
* <p>-------------- request end ---------------------
346+
* <p>
334347
*
335348
* @param graphqlResource path to the classpath resource containing the GraphQL query
336349
* @param variables the input variables for the GraphQL query
@@ -344,12 +357,39 @@ public GraphQLResponse postFiles(
344357
String graphqlResource, ObjectNode variables, List<ClassPathResource> files)
345358
throws IOException {
346359

360+
return postFiles(
361+
graphqlResource, variables, files, index -> String.format("variables.files.%d", index));
362+
}
363+
364+
/**
365+
* Handle the multipart files upload request to GraphQL servlet
366+
*
367+
* @param graphqlResource path to the classpath resource containing the GraphQL query
368+
* @param variables the input variables for the GraphQL query
369+
* @param files ClassPathResource instance for each file that will be uploaded to GraphQL server.
370+
* When Spring RestTemplate processes the request, it will automatically produce a valid part
371+
* representing given file inside multipart request (including size, submittedFileName, etc.)
372+
* @param pathFunc function to generate the path to file inside variables. For example:
373+
* <ul>
374+
* <li>index -> String.format("variables.files.%d", index) for multiple files
375+
* <li>index -> "variables.file" for single file
376+
* </ul>
377+
*
378+
* @return {@link GraphQLResponse} containing the result of query execution
379+
* @throws IOException if the resource cannot be loaded from the classpath
380+
*/
381+
public GraphQLResponse postFiles(
382+
String graphqlResource,
383+
ObjectNode variables,
384+
List<ClassPathResource> files,
385+
IntFunction<String> pathFunc)
386+
throws IOException {
347387
MultiValueMap<String, Object> values = new LinkedMultiValueMap<>();
348388
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
349389

350390
for (int i = 0; i < files.size(); i++) {
351391
String valueKey = String.valueOf(i + 1); // map value and part index starts at 1
352-
map.add(valueKey, String.format("variables.files.%d", i));
392+
map.add(valueKey, pathFunc.apply(i));
353393

354394
values.add(valueKey, files.get(i));
355395
}

graphql-spring-boot-test/src/test/java/com/graphql/spring/boot/test/GraphQLTestTemplateIntegrationTest.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@ class GraphQLTestTemplateIntegrationTest {
3131
private static final String QUERY_WITH_VARIABLES = "query-with-variables.graphql";
3232
private static final String COMPLEX_TEST_QUERY = "complex-query.graphql";
3333
private static final String MULTIPLE_QUERIES = "multiple-queries.graphql";
34-
private static final String UPLOAD_MUTATION = "upload-files.graphql";
34+
private static final String UPLOAD_FILES_MUTATION = "upload-files.graphql";
35+
private static final String UPLOAD_FILE_MUTATION = "upload-file.graphql";
3536
private static final String INPUT_STRING_VALUE = "input-value";
3637
private static final String INPUT_STRING_NAME = "input";
3738
private static final String INPUT_HEADER_NAME = "headerName";
3839
private static final String FILES_STRING_NAME = "files";
40+
private static final String UPLOADING_FILE_STRING_NAME = "uploadingFile";
3941
private static final String TEST_HEADER_NAME = "x-test";
4042
private static final String TEST_HEADER_VALUE = String.valueOf(UUID.randomUUID());
4143
private static final String FOO = "FOO";
@@ -47,6 +49,7 @@ class GraphQLTestTemplateIntegrationTest {
4749
private static final String DATA_FIELD_QUERY_WITH_HEADER = "$.data.queryWithHeader";
4850
private static final String DATA_FIELD_DUMMY = "$.data.dummy";
4951
private static final String DATA_FILE_UPLOAD_FILES = "$.data.uploadFiles";
52+
private static final String DATA_FILE_UPLOAD_FILE = "$.data.uploadFile";
5053
private static final String OPERATION_NAME_WITH_VARIABLES = "withVariable";
5154
private static final String OPERATION_NAME_TEST_QUERY_1 = "testQuery1";
5255
private static final String OPERATION_NAME_TEST_QUERY_2 = "testQuery2";
@@ -246,10 +249,29 @@ void testPerformWithFileUploads() throws IOException {
246249
fileNames.stream().map(ClassPathResource::new).collect(Collectors.toList());
247250
// WHEN - THEN
248251
graphQLTestTemplate
249-
.postFiles(UPLOAD_MUTATION, variables, testUploadFiles)
252+
.postFiles(UPLOAD_FILES_MUTATION, variables, testUploadFiles)
250253
.assertThatNoErrorsArePresent()
251254
.assertThatField(DATA_FILE_UPLOAD_FILES)
252255
.asListOf(String.class)
253256
.isEqualTo(fileNames);
254257
}
258+
259+
@Test
260+
@DisplayName("Test perform with individual file upload and custom path.")
261+
void testPerformWithIndividualFileUpload() throws IOException {
262+
// GIVEN
263+
final ObjectNode variables = objectMapper.createObjectNode();
264+
variables.put(UPLOADING_FILE_STRING_NAME, objectMapper.valueToTree(null));
265+
266+
List<String> fileNames = List.of("multiple-queries.graphql");
267+
List<ClassPathResource> testUploadFiles =
268+
fileNames.stream().map(ClassPathResource::new).collect(Collectors.toList());
269+
// WHEN - THEN
270+
graphQLTestTemplate
271+
.postFiles(UPLOAD_FILE_MUTATION, variables, testUploadFiles, index -> "variables.file")
272+
.assertThatNoErrorsArePresent()
273+
.assertThatField(DATA_FILE_UPLOAD_FILE)
274+
.asString()
275+
.isEqualTo(fileNames.get(0));
276+
}
255277
}

graphql-spring-boot-test/src/test/java/com/graphql/spring/boot/test/beans/DummyMutation.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,9 @@ public List<String> uploadFiles(List<Part> files, DataFetchingEnvironment env) {
2424
List<Part> actualFiles = env.getArgument("files");
2525
return actualFiles.stream().map(Part::getSubmittedFileName).collect(Collectors.toList());
2626
}
27+
28+
public String uploadFile(Part file, DataFetchingEnvironment env) {
29+
Part actualFile = env.getArgument("file");
30+
return actualFile.getSubmittedFileName();
31+
}
2732
}

graphql-spring-boot-test/src/test/resources/test-schema.graphqls

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ type Query {
2323

2424
type Mutation {
2525
uploadFiles(files: [Upload]!): [String!]
26+
uploadFile(file: Upload): String!
2627
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
mutation($file: Upload) {
2+
uploadFile(file: $file)
3+
}

0 commit comments

Comments
 (0)