1
1
/*
2
- * Copyright 2002-2023 the original author or authors.
2
+ * Copyright 2002-2024 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
30
30
import java .util .function .Consumer ;
31
31
import java .util .function .Function ;
32
32
33
+ import com .jayway .jsonpath .Configuration ;
34
+ import com .jayway .jsonpath .spi .mapper .MappingProvider ;
33
35
import org .hamcrest .Matcher ;
34
36
import org .hamcrest .MatcherAssert ;
35
37
import org .reactivestreams .Publisher ;
57
59
import org .springframework .web .reactive .function .client .ClientRequest ;
58
60
import org .springframework .web .reactive .function .client .ClientResponse ;
59
61
import org .springframework .web .reactive .function .client .ExchangeFunction ;
62
+ import org .springframework .web .reactive .function .client .ExchangeStrategies ;
60
63
import org .springframework .web .util .UriBuilder ;
61
64
import org .springframework .web .util .UriBuilderFactory ;
62
65
@@ -72,6 +75,9 @@ class DefaultWebTestClient implements WebTestClient {
72
75
73
76
private final WiretapConnector wiretapConnector ;
74
77
78
+ @ Nullable
79
+ private final JsonEncoderDecoder jsonEncoderDecoder ;
80
+
75
81
private final ExchangeFunction exchangeFunction ;
76
82
77
83
private final UriBuilderFactory uriBuilderFactory ;
@@ -91,13 +97,15 @@ class DefaultWebTestClient implements WebTestClient {
91
97
private final AtomicLong requestIndex = new AtomicLong ();
92
98
93
99
94
- DefaultWebTestClient (ClientHttpConnector connector ,
100
+ DefaultWebTestClient (ClientHttpConnector connector , ExchangeStrategies exchangeStrategies ,
95
101
Function <ClientHttpConnector , ExchangeFunction > exchangeFactory , UriBuilderFactory uriBuilderFactory ,
96
102
@ Nullable HttpHeaders headers , @ Nullable MultiValueMap <String , String > cookies ,
97
103
Consumer <EntityExchangeResult <?>> entityResultConsumer ,
98
104
@ Nullable Duration responseTimeout , DefaultWebTestClientBuilder clientBuilder ) {
99
105
100
106
this .wiretapConnector = new WiretapConnector (connector );
107
+ this .jsonEncoderDecoder = JsonEncoderDecoder .from (
108
+ exchangeStrategies .messageWriters (), exchangeStrategies .messageReaders ());
101
109
this .exchangeFunction = exchangeFactory .apply (this .wiretapConnector );
102
110
this .uriBuilderFactory = uriBuilderFactory ;
103
111
this .defaultHeaders = headers ;
@@ -362,6 +370,7 @@ public ResponseSpec exchange() {
362
370
this .requestId , this .uriTemplate , getResponseTimeout ());
363
371
364
372
return new DefaultResponseSpec (result , response ,
373
+ DefaultWebTestClient .this .jsonEncoderDecoder ,
365
374
DefaultWebTestClient .this .entityResultConsumer , getResponseTimeout ());
366
375
}
367
376
@@ -399,18 +408,23 @@ private static class DefaultResponseSpec implements ResponseSpec {
399
408
400
409
private final ClientResponse response ;
401
410
411
+ @ Nullable
412
+ private final JsonEncoderDecoder jsonEncoderDecoder ;
413
+
402
414
private final Consumer <EntityExchangeResult <?>> entityResultConsumer ;
403
415
404
416
private final Duration timeout ;
405
417
406
418
407
419
DefaultResponseSpec (
408
420
ExchangeResult exchangeResult , ClientResponse response ,
421
+ @ Nullable JsonEncoderDecoder jsonEncoderDecoder ,
409
422
Consumer <EntityExchangeResult <?>> entityResultConsumer ,
410
423
Duration timeout ) {
411
424
412
425
this .exchangeResult = exchangeResult ;
413
426
this .response = response ;
427
+ this .jsonEncoderDecoder = jsonEncoderDecoder ;
414
428
this .entityResultConsumer = entityResultConsumer ;
415
429
this .timeout = timeout ;
416
430
}
@@ -466,7 +480,7 @@ public BodyContentSpec expectBody() {
466
480
ByteArrayResource resource = this .response .bodyToMono (ByteArrayResource .class ).block (this .timeout );
467
481
byte [] body = (resource != null ? resource .getByteArray () : null );
468
482
EntityExchangeResult <byte []> entityResult = initEntityExchangeResult (body );
469
- return new DefaultBodyContentSpec (entityResult );
483
+ return new DefaultBodyContentSpec (entityResult , this . jsonEncoderDecoder );
470
484
}
471
485
472
486
private <B > EntityExchangeResult <B > initEntityExchangeResult (@ Nullable B body ) {
@@ -625,10 +639,14 @@ private static class DefaultBodyContentSpec implements BodyContentSpec {
625
639
626
640
private final EntityExchangeResult <byte []> result ;
627
641
642
+ @ Nullable
643
+ private final JsonEncoderDecoder jsonEncoderDecoder ;
644
+
628
645
private final boolean isEmpty ;
629
646
630
- DefaultBodyContentSpec (EntityExchangeResult <byte []> result ) {
647
+ DefaultBodyContentSpec (EntityExchangeResult <byte []> result , @ Nullable JsonEncoderDecoder jsonEncoderDecoder ) {
631
648
this .result = result ;
649
+ this .jsonEncoderDecoder = jsonEncoderDecoder ;
632
650
this .isEmpty = (result .getResponseBody () == null || result .getResponseBody ().length == 0 );
633
651
}
634
652
@@ -666,8 +684,16 @@ public BodyContentSpec xml(String expectedXml) {
666
684
}
667
685
668
686
@ Override
687
+ public JsonPathAssertions jsonPath (String expression ) {
688
+ return new JsonPathAssertions (this , getBodyAsString (), expression ,
689
+ JsonPathConfigurationProvider .getConfiguration (this .jsonEncoderDecoder ));
690
+ }
691
+
692
+ @ Override
693
+ @ SuppressWarnings ("removal" )
669
694
public JsonPathAssertions jsonPath (String expression , Object ... args ) {
670
- return new JsonPathAssertions (this , getBodyAsString (), expression , args );
695
+ Assert .hasText (expression , "expression must not be null or empty" );
696
+ return jsonPath (expression .formatted (args ));
671
697
}
672
698
673
699
@ Override
@@ -697,4 +723,18 @@ public EntityExchangeResult<byte[]> returnResult() {
697
723
}
698
724
}
699
725
726
+
727
+ private static class JsonPathConfigurationProvider {
728
+
729
+ static Configuration getConfiguration (@ Nullable JsonEncoderDecoder jsonEncoderDecoder ) {
730
+ Configuration jsonPathConfiguration = Configuration .defaultConfiguration ();
731
+ if (jsonEncoderDecoder != null ) {
732
+ MappingProvider mappingProvider = new EncoderDecoderMappingProvider (
733
+ jsonEncoderDecoder .encoder (), jsonEncoderDecoder .decoder ());
734
+ return jsonPathConfiguration .mappingProvider (mappingProvider );
735
+ }
736
+ return jsonPathConfiguration ;
737
+ }
738
+ }
739
+
700
740
}
0 commit comments