@@ -269,6 +269,9 @@ impl HttpPart for HttpRequest {
269269 }
270270}
271271
272+ /// Attributes a V4 body fragment may hold alongside its content.
273+ const BODY_ATTRIBUTES : [ & str ; 4 ] = [ "content" , "contentType" , "contentTypeHint" , "encoded" ] ;
274+
272275/// Set up an OptionalBody from a JSON fragment. The contents for the body will be looked up from
273276/// the attribute given by `attr_name`. The headers will be used to work out the content type,
274277/// if required.
@@ -361,8 +364,16 @@ pub fn body_from_json(json: &Value, attr_name: &str, headers: &Option<HashMap<St
361364 }
362365 } ,
363366
364- // No content attribute, assume a missing body
365- None => OptionalBody :: Missing
367+ None => if body_attrs. keys ( ) . all ( |k| BODY_ATTRIBUTES . contains ( & k. as_str ( ) ) ) {
368+ // Only body attributes, so the body really is missing
369+ OptionalBody :: Missing
370+ } else {
371+ // The payload has been set where the body attributes belong. Treat it the same as a
372+ // body that is not a JSON object, rather than silently dropping it.
373+ warn ! ( "Body in attribute '{}' from JSON file has no 'content' attribute, will load the \
374+ whole value as the body", attr_name) ;
375+ OptionalBody :: Present ( body. to_string ( ) . into ( ) , None , None )
376+ }
366377 }
367378 } ,
368379
@@ -993,6 +1004,35 @@ mod tests {
9931004 expect ! ( body) . to ( be_equal_to ( OptionalBody :: Null ) ) ;
9941005 }
9951006
1007+ #[ test]
1008+ fn body_from_json_returns_missing_if_the_body_only_has_body_attributes ( ) {
1009+ let json = json ! ( {
1010+ "body" : {
1011+ "contentType" : "application/json" ,
1012+ "encoded" : false
1013+ }
1014+ } ) ;
1015+ expect ! ( body_from_json( & json, "body" , & None ) ) . to ( be_equal_to ( OptionalBody :: Missing ) ) ;
1016+
1017+ let json = json ! ( {
1018+ "body" : { }
1019+ } ) ;
1020+ expect ! ( body_from_json( & json, "body" , & None ) ) . to ( be_equal_to ( OptionalBody :: Missing ) ) ;
1021+ }
1022+
1023+ #[ test]
1024+ fn body_from_json_loads_the_whole_value_if_the_body_has_no_content_attribute ( ) {
1025+ // The payload has been set where the body attributes belong. Previously this was read as a
1026+ // missing body, so an interaction with a mismatched payload verified successfully.
1027+ let json = json ! ( {
1028+ "body" : {
1029+ "Payload" : "exists"
1030+ }
1031+ } ) ;
1032+ expect ! ( body_from_json( & json, "body" , & None ) ) . to ( be_equal_to (
1033+ OptionalBody :: Present ( "{\" Payload\" :\" exists\" }" . into ( ) , None , None ) ) ) ;
1034+ }
1035+
9961036 #[ test]
9971037 fn body_from_json_returns_json_string_if_the_body_is_json_but_not_a_string ( ) {
9981038 let json = json ! ( {
0 commit comments