@@ -432,6 +432,36 @@ mod tests {
432432 Some ( ExpectedResponse { status: "400" , schema: ExpectedSchema { schema_type: SchemaType :: String , nullable: false , items_schema_type: None } } ) ,
433433 None
434434 ) ]
435+ // Non-Result: StatusCode alone → no content (covers line 155)
436+ #[ case( "-> StatusCode" , None , None , None ) ]
437+ // Non-Result: Json<T> wrapper → unwraps to T
438+ #[ case(
439+ "-> Json<String>" ,
440+ Some ( ExpectedSchema { schema_type: SchemaType :: String , nullable: false , items_schema_type: None } ) ,
441+ None ,
442+ None
443+ ) ]
444+ // Non-Result: Json<i32> wrapper → unwraps to integer
445+ #[ case(
446+ "-> Json<i32>" ,
447+ Some ( ExpectedSchema { schema_type: SchemaType :: Integer , nullable: false , items_schema_type: None } ) ,
448+ None ,
449+ None
450+ ) ]
451+ // Non-Result: f64 → number type
452+ #[ case(
453+ "-> f64" ,
454+ Some ( ExpectedSchema { schema_type: SchemaType :: Number , nullable: false , items_schema_type: None } ) ,
455+ None ,
456+ None
457+ ) ]
458+ // Non-Result: qualified axum::Json<String> → unwraps to String
459+ #[ case(
460+ "-> axum::Json<String>" ,
461+ Some ( ExpectedSchema { schema_type: SchemaType :: String , nullable: false , items_schema_type: None } ) ,
462+ None ,
463+ None
464+ ) ]
435465 fn test_parse_return_type (
436466 #[ case] return_type_str : & str ,
437467 #[ case] ok_expectation : Option < ExpectedSchema > ,
@@ -698,6 +728,64 @@ mod tests {
698728 assert ! ( headers. is_none( ) ) ;
699729 }
700730
731+ #[ test]
732+ fn test_extract_ok_payload_and_headers_all_non_body_types ( ) {
733+ // (StatusCode, CookieJar) → no body element found, returns original tuple
734+ let ty: syn:: Type = syn:: parse_str ( "(StatusCode, CookieJar)" ) . unwrap ( ) ;
735+ let ( payload, headers) = extract_ok_payload_and_headers ( & ty) ;
736+ // No body element found → falls through to return original type
737+ assert ! ( matches!( payload, syn:: Type :: Tuple ( _) ) ) ;
738+ assert ! ( headers. is_none( ) ) ;
739+ }
740+
741+ #[ test]
742+ fn test_unwrap_json_qualified_path ( ) {
743+ // vespera::axum::Json<String> → should unwrap to String via last-segment matching
744+ let ty: syn:: Type = syn:: parse_str ( "vespera::axum::Json<String>" ) . unwrap ( ) ;
745+ let unwrapped = unwrap_json ( & ty) ;
746+ if let syn:: Type :: Path ( type_path) = unwrapped {
747+ assert_eq ! (
748+ type_path. path. segments. last( ) . unwrap( ) . ident. to_string( ) ,
749+ "String"
750+ ) ;
751+ } else {
752+ panic ! ( "Expected Path type" ) ;
753+ }
754+ }
755+
756+ #[ test]
757+ fn test_unwrap_json_non_generic_path ( ) {
758+ // Type with segments but no angle brackets → returns original
759+ let ty: syn:: Type = syn:: parse_str ( "std::string::String" ) . unwrap ( ) ;
760+ let unwrapped = unwrap_json ( & ty) ;
761+ if let syn:: Type :: Path ( type_path) = unwrapped {
762+ assert_eq ! (
763+ type_path. path. segments. last( ) . unwrap( ) . ident. to_string( ) ,
764+ "String"
765+ ) ;
766+ } else {
767+ panic ! ( "Expected Path type" ) ;
768+ }
769+ }
770+
771+ #[ test]
772+ fn test_parse_return_type_non_result_status_code ( ) {
773+ // Direct StatusCode return (not in Result) → 200 with no content
774+ let known_schemas = HashSet :: new ( ) ;
775+ let struct_definitions = HashMap :: new ( ) ;
776+ let return_type = parse_return_type_str ( "-> StatusCode" ) ;
777+
778+ let responses = parse_return_type ( & return_type, & known_schemas, & struct_definitions) ;
779+
780+ assert_eq ! ( responses. len( ) , 1 ) ;
781+ let ok_response = responses. get ( "200" ) . unwrap ( ) ;
782+ assert ! (
783+ ok_response. content. is_none( ) ,
784+ "StatusCode return should have no content"
785+ ) ;
786+ assert ! ( ok_response. headers. is_none( ) ) ;
787+ }
788+
701789 #[ test]
702790 fn test_is_non_body_type ( ) {
703791 let status: syn:: Type = syn:: parse_str ( "StatusCode" ) . unwrap ( ) ;
0 commit comments