Skip to content

Commit ec2fb7d

Browse files
committed
refactor to reflect feedback
issue spring-projects#3501
1 parent 157d9b9 commit ec2fb7d

File tree

3 files changed

+179
-493
lines changed

3 files changed

+179
-493
lines changed
Lines changed: 179 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@
3434
import org.springframework.graphql.RequestInput;
3535
import org.springframework.graphql.data.method.annotation.Argument;
3636
import org.springframework.graphql.data.method.annotation.MutationMapping;
37+
import org.springframework.graphql.data.method.annotation.QueryMapping;
38+
import org.springframework.graphql.data.method.annotation.SubscriptionMapping;
3739
import org.springframework.graphql.data.method.annotation.support.AnnotatedControllerConfigurer;
38-
import org.springframework.graphql.execution.BatchLoaderRegistry;
39-
import org.springframework.graphql.execution.DefaultBatchLoaderRegistry;
4040
import org.springframework.graphql.execution.ExecutionGraphQlService;
4141
import org.springframework.graphql.execution.GraphQlSource;
4242
import org.springframework.integration.channel.FluxMessageChannel;
@@ -57,6 +57,7 @@
5757

5858
import graphql.ExecutionResult;
5959
import graphql.ExecutionResultImpl;
60+
import graphql.execution.reactive.SubscriptionPublisher;
6061
import reactor.core.publisher.Flux;
6162
import reactor.core.publisher.Mono;
6263
import reactor.test.StepVerifier;
@@ -66,9 +67,9 @@
6667
* @author Daniel Frey
6768
*
6869
*/
69-
@SpringJUnitConfig(GraphQlMutationMessageHandlerTests.TestConfig.class)
70+
@SpringJUnitConfig(GraphQlMessageHandlerTests.TestConfig.class)
7071
@DirtiesContext
71-
public class GraphQlMutationMessageHandlerTests {
72+
public class GraphQlMessageHandlerTests {
7273

7374
@Autowired
7475
private FluxMessageChannel inputChannel;
@@ -80,14 +81,11 @@ public class GraphQlMutationMessageHandlerTests {
8081
private PollableChannel errorChannel;
8182

8283
@Autowired
83-
UpdateRepository updateRepository;
84+
private UpdateRepository updateRepository;
8485

8586
@Test
8687
@SuppressWarnings("unchecked")
87-
void testHandleMessageForMutation() {
88-
89-
String fakeId = UUID.randomUUID().toString();
90-
Update expected = new Update(fakeId);
88+
void testHandleMessageForQuery() {
9189

9290
StepVerifier verifier = StepVerifier.create(
9391
Flux.from(this.resultChannel)
@@ -97,15 +95,46 @@ void testHandleMessageForMutation() {
9795
.consumeNextWith(result -> {
9896
assertThat(result).isInstanceOf(ExecutionResultImpl.class);
9997
Map<String, Object> data = result.getData();
100-
Map<String, Object> update = (Map<String, Object>) data.get("update");
101-
assertThat(update.get("id")).isEqualTo(fakeId);
102-
103-
assertThat(this.updateRepository.current().block()).isEqualTo(expected);
98+
Map<String, Object> testQuery = (Map<String, Object>) data.get("testQuery");
99+
assertThat(testQuery.get("id")).isEqualTo("test-data");
104100
}
105101
)
106102
.thenCancel()
107103
.verifyLater();
108104

105+
this.inputChannel.send(
106+
MessageBuilder
107+
.withPayload(new RequestInput("{ testQuery { id } }", null, Collections.emptyMap()))
108+
.build()
109+
);
110+
111+
verifier.verify(Duration.ofSeconds(10));
112+
}
113+
114+
@Test
115+
@SuppressWarnings("unchecked")
116+
void testHandleMessageForMutation() {
117+
118+
String fakeId = UUID.randomUUID().toString();
119+
Update expected = new Update(fakeId);
120+
121+
StepVerifier verifier = StepVerifier.create(
122+
Flux.from(this.resultChannel)
123+
.map(Message::getPayload)
124+
.cast(ExecutionResult.class)
125+
)
126+
.consumeNextWith(result -> {
127+
assertThat(result).isInstanceOf(ExecutionResultImpl.class);
128+
Map<String, Object> data = result.getData();
129+
Map<String, Object> update = (Map<String, Object>) data.get("update");
130+
assertThat(update.get("id")).isEqualTo(fakeId);
131+
132+
assertThat(this.updateRepository.current().block()).isEqualTo(expected);
133+
}
134+
)
135+
.thenCancel()
136+
.verifyLater();
137+
109138
this.inputChannel.send(
110139
MessageBuilder
111140
.withPayload(new RequestInput("mutation { update(id: \"" + fakeId + "\") { id } }", null, Collections.emptyMap()))
@@ -121,9 +150,65 @@ void testHandleMessageForMutation() {
121150

122151
}
123152

153+
@Test
154+
@SuppressWarnings("unchecked")
155+
void testHandleMessageForSubscription() {
156+
157+
StepVerifier verifier = StepVerifier.create(
158+
Flux.from(this.resultChannel)
159+
.map(Message::getPayload)
160+
.cast(ExecutionResult.class)
161+
.map(ExecutionResult::getData)
162+
.cast(SubscriptionPublisher.class)
163+
.map(Flux::from)
164+
.flatMap(data -> data)
165+
)
166+
.consumeNextWith(executionResult -> {
167+
Map<String, Object> results = (Map<String, Object>) executionResult.getData();
168+
assertThat(results).containsKey("results");
169+
170+
Map<String, Object> queryResult = (Map<String, Object>) results.get("results");
171+
assertThat(queryResult)
172+
.containsKey("id")
173+
.containsValue("test-data-01");
174+
175+
})
176+
.expectNextCount(9)
177+
.thenCancel()
178+
.verifyLater();
179+
180+
this.inputChannel.send(
181+
MessageBuilder
182+
.withPayload(new RequestInput("subscription { results { id } }", null, Collections.emptyMap()))
183+
.build()
184+
);
185+
186+
verifier.verify(Duration.ofSeconds(10));
187+
}
188+
124189
@Test
125190
void testHandleMessageForQueryWithInvalidPayload() {
126191

192+
this.inputChannel.send(
193+
MessageBuilder
194+
.withPayload("{ testQuery { id } }")
195+
.build()
196+
);
197+
198+
Message<?> errorMessage = errorChannel.receive(10_000);
199+
assertThat(errorMessage).isNotNull()
200+
.isInstanceOf(ErrorMessage.class)
201+
.extracting(Message::getPayload)
202+
.isInstanceOf(MessageHandlingException.class)
203+
.satisfies((ex) -> assertThat((Exception) ex)
204+
.hasMessageContaining(
205+
"Message payload needs to be 'org.springframework.graphql.RequestInput'"));
206+
207+
}
208+
209+
@Test
210+
void testHandleMessageForMutationWithInvalidPayload() {
211+
127212
String fakeId = UUID.randomUUID().toString();
128213

129214
this.inputChannel.send(
@@ -143,20 +228,61 @@ void testHandleMessageForQueryWithInvalidPayload() {
143228

144229
}
145230

231+
@Test
232+
void testHandleMessageForSubscriptionWithInvalidPayload() {
233+
234+
this.inputChannel.send(
235+
MessageBuilder
236+
.withPayload("subscription { results { id } }")
237+
.build()
238+
);
239+
240+
Message<?> errorMessage = errorChannel.receive(10_000);
241+
assertThat(errorMessage).isNotNull()
242+
.isInstanceOf(ErrorMessage.class)
243+
.extracting(Message::getPayload)
244+
.isInstanceOf(MessageHandlingException.class)
245+
.satisfies((ex) -> assertThat((Exception) ex)
246+
.hasMessageContaining(
247+
"Message payload needs to be 'org.springframework.graphql.RequestInput'"));
248+
249+
}
250+
146251
@Controller
147-
static class GraphqlMutationController {
252+
static class GraphQlController {
148253

149254
final UpdateRepository updateRepository;
150255

151-
GraphqlMutationController(UpdateRepository updateRepository) {
256+
GraphQlController(UpdateRepository updateRepository) {
152257
this.updateRepository = updateRepository;
153258
}
154259

260+
@QueryMapping
261+
public Mono<QueryResult> testQuery() {
262+
return Mono.just(new QueryResult("test-data"));
263+
}
264+
155265
@MutationMapping
156266
public Mono<Update> update(@Argument String id) {
157267
return this.updateRepository.save(new Update(id));
158268
}
159269

270+
@SubscriptionMapping
271+
public Flux<QueryResult> results() {
272+
return Flux.just(
273+
new QueryResult("test-data-01"),
274+
new QueryResult("test-data-02"),
275+
new QueryResult("test-data-03"),
276+
new QueryResult("test-data-04"),
277+
new QueryResult("test-data-05"),
278+
new QueryResult("test-data-06"),
279+
new QueryResult("test-data-07"),
280+
new QueryResult("test-data-08"),
281+
new QueryResult("test-data-09"),
282+
new QueryResult("test-data-10")
283+
);
284+
}
285+
160286
}
161287

162288
@Repository
@@ -206,18 +332,15 @@ UpdateRepository updateRepository() {
206332
}
207333

208334
@Bean
209-
GraphqlMutationController graphqlMutationController(final UpdateRepository updateRepository) {
335+
GraphQlController graphqlQueryController(final UpdateRepository updateRepository) {
210336

211-
return new GraphqlMutationController(updateRepository);
337+
return new GraphQlController(updateRepository);
212338
}
213339

214340
@Bean
215-
GraphQlService graphQlService(GraphQlSource graphQlSource, BatchLoaderRegistry batchLoaderRegistry) {
216-
217-
ExecutionGraphQlService service = new ExecutionGraphQlService(graphQlSource);
218-
service.addDataLoaderRegistrar(batchLoaderRegistry);
341+
GraphQlService graphQlService(GraphQlSource graphQlSource) {
219342

220-
return service;
343+
return new ExecutionGraphQlService(graphQlSource);
221344
}
222345

223346
@Bean
@@ -235,12 +358,43 @@ AnnotatedControllerConfigurer annotatedDataFetcherConfigurer() {
235358
return new AnnotatedControllerConfigurer();
236359
}
237360

238-
@Bean
239-
BatchLoaderRegistry batchLoaderRegistry() {
361+
}
362+
363+
static class QueryResult {
364+
365+
private final String id;
366+
367+
QueryResult(final String id) {
368+
this.id = id;
369+
}
370+
371+
String getId() {
372+
return this.id;
373+
}
240374

241-
return new DefaultBatchLoaderRegistry();
375+
@Override
376+
public boolean equals(Object o) {
377+
if (this == o) {
378+
return true;
379+
}
380+
if (!(o instanceof QueryResult)) {
381+
return false;
382+
}
383+
QueryResult that = (QueryResult) o;
384+
return getId().equals(that.getId());
242385
}
243386

387+
@Override
388+
public int hashCode() {
389+
return Objects.hash(getId());
390+
}
391+
392+
@Override
393+
public String toString() {
394+
return "QueryResult{" +
395+
"id='" + id + '\'' +
396+
'}';
397+
}
244398
}
245399

246400
static class Update {

0 commit comments

Comments
 (0)