@@ -21,7 +21,8 @@ pub use web_proof_circuits_witness_generator::json::JsonKey;
2121
2222use crate :: {
2323 errors:: ManifestError ,
24- parser:: { DataFormat , ExtractionValues , ExtractorConfig } ,
24+ manifest:: ManifestValidationResult ,
25+ parser:: { DataFormat , ExtractionResult , ExtractorConfig } ,
2526 template,
2627 template:: TemplateVar ,
2728} ;
@@ -154,27 +155,29 @@ impl NotaryResponse {
154155 pub fn match_and_extract (
155156 & self ,
156157 other : & ManifestResponse ,
157- ) -> Result < Option < ExtractionValues > , ManifestError > {
158+ ) -> Result < ExtractionResult , ManifestError > {
159+ let mut result = ExtractionResult :: default ( ) ;
160+
158161 // Check basic response properties
159- if self . response . status != other. status
160- || self . response . version != other. version
161- || self . response . message != other. message
162- {
163- debug ! ( "Exact matches for status, version, or message do not match" ) ;
164- return Ok ( None ) ;
162+ if self . response . status != other. status {
163+ result. report_error ( & format ! (
164+ "Status mismatch: expected={}, actual={}" ,
165+ other. status, self . response. status
166+ ) ) ;
165167 }
166-
167- // Check headers
168- if !self . headers_match ( other) {
169- return Ok ( None ) ;
168+ if self . response . version != other. version {
169+ result. report_error ( & format ! (
170+ "Version mismatch: expected={}, actual={}" ,
171+ other. version, self . response. version
172+ ) ) ;
173+ }
174+ if self . response . message != other. message {
175+ result. report_error ( & format ! (
176+ "Message mismatch: expected={}, actual={}" ,
177+ other. version, self . response. version
178+ ) ) ;
170179 }
171180
172- // Check body
173- self . body_matches ( other)
174- }
175-
176- /// Helper method to check if headers match
177- fn headers_match ( & self , other : & ManifestResponse ) -> bool {
178181 for ( key, other_value) in & other. headers {
179182 match self
180183 . response
@@ -184,51 +187,58 @@ impl NotaryResponse {
184187 {
185188 Some ( actual_value) if actual_value. to_lowercase ( ) == other_value. to_lowercase ( ) => continue ,
186189 Some ( actual_value) => {
187- debug ! (
188- "Header mismatch for key: {}: expected={}, actual={}" ,
189- key, other_value, actual_value
190- ) ;
191- return false ;
190+ result. report_error ( & format ! (
191+ "Header mismatch: expected={}, actual={}" ,
192+ other_value, actual_value
193+ ) ) ;
192194 } ,
193195 None => {
194- debug ! ( "Header key not present in self: {}" , key) ;
195- return false ;
196+ result. report_error ( & format ! ( "Header missing: {}" , key) ) ;
196197 } ,
197198 }
198199 }
199- true
200+
201+ // Check body
202+ let body_result = self . body_matches ( other) ?;
203+ result. merge ( body_result) ;
204+
205+ // Return combined result
206+ Ok ( result)
200207 }
201208
202209 /// Helper method to check if body matches and extract values
203- fn body_matches (
204- & self ,
205- other : & ManifestResponse ,
206- ) -> Result < Option < ExtractionValues > , ManifestError > {
210+ fn body_matches ( & self , other : & ManifestResponse ) -> Result < ExtractionResult , ManifestError > {
207211 match & self . notary_response_body . body {
208212 Some ( body) => {
209- let result = other. body . 0 . extract_and_validate ( body) ?;
213+ let mut body_result = other. body . 0 . extract_and_validate ( body) ?;
210214
211- if !result. errors . is_empty ( ) {
212- debug ! ( "Response body does not match: {:?}" , result. errors) ;
213- return Ok ( None ) ;
215+ if !body_result. errors . is_empty ( ) {
216+ debug ! ( "Response body does not match: {:?}" , body_result. errors) ;
217+ body_result. report_error ( "Response body does not match" ) ;
218+ return Ok ( body_result) ;
214219 }
215220
216- if result . values . len ( ) != other. body . 0 . extractors . len ( ) {
221+ if body_result . values . len ( ) != other. body . 0 . extractors . len ( ) {
217222 debug ! ( "Not all extractors were matched" ) ;
218- return Ok ( None ) ;
223+ body_result. report_error ( "Not all extractors were matched" ) ;
224+ return Ok ( body_result) ;
219225 }
220226
221227 debug ! ( "Client response matches" ) ;
222- Ok ( Some ( result . values ) )
228+ Ok ( body_result )
223229 } ,
224230 None if other. body . 0 . extractors . is_empty ( ) => {
225231 // If we get here, there was a match but no data
226232 debug ! ( "Client response matches (no data in response body)" ) ;
227- Ok ( Some ( HashMap :: new ( ) ) )
233+ let mut result = ExtractionResult :: default ( ) ;
234+ result. report_error ( "No data in response body" ) ;
235+ Ok ( result)
228236 } ,
229237 None => {
230238 debug ! ( "No data to match against" ) ;
231- Ok ( None )
239+ let mut result = ExtractionResult :: default ( ) ;
240+ result. report_error ( "No data to match against" ) ;
241+ Ok ( result)
232242 } ,
233243 }
234244 }
@@ -502,34 +512,60 @@ impl ManifestRequest {
502512 /// - All headers in `self` must exist in `other` with matching values.
503513 /// - All vars in `self` must exist in `other` with matching constraints.
504514 /// - All remaining fields like `method`, `url`, and `body` must also match.
505- pub fn is_subset_of ( & self , other : & ManifestRequest ) -> bool {
515+ pub fn is_subset_of (
516+ & self ,
517+ other : & ManifestRequest ,
518+ ) -> Result < ManifestValidationResult , ManifestError > {
519+ let mut result = ManifestValidationResult :: default ( ) ;
520+
506521 // Check if all headers in `self` exist in `other` with the same value
507522 for ( key, value) in & self . headers {
508523 let expected_header =
509524 other. headers . get ( key) . or_else ( || other. headers . get ( & key. to_lowercase ( ) ) ) ;
510525 if expected_header != Some ( value) {
511- return false ;
526+ result . report_error ( & format ! ( "Header mismatch: expected={}, actual={}" , value , key ) ) ;
512527 }
513528 }
514529
515- // TODO: Not sure how to handle `vars` now, so disabling this
516- // Check if all vars in `self` exist in `other` with the same or compatible constraints
517- // for (key, var) in &self.vars {
518- // match other.vars.get(key) {
519- // Some(other_var) =>
520- // if var != other_var {
521- // return false;
522- // },
523- // None => {
524- // return false;
525- // },
526- // }
527- // }
528-
529- // TODO: Notice that we match body exactly below
530- // TODO: What to do with the body? Ominous
531- // self.method == other.method && self.url == other.url && self.body == other.body
532- self . method == other. method && self . url == other. url
530+ for ( key, var) in & self . vars {
531+ match other. vars . get ( key) {
532+ Some ( other_var) =>
533+ if var != other_var {
534+ result. report_error ( & format ! ( "Var mismatch: expected={}, actual={}" , var, key) ) ;
535+ } ,
536+ None => {
537+ result. report_error ( & format ! ( "Var missing: {}" , key) ) ;
538+ } ,
539+ }
540+ }
541+
542+ if self . method != other. method {
543+ result. report_error ( & format ! (
544+ "Method mismatch: expected={}, actual={}" ,
545+ other. method, self . method
546+ ) ) ;
547+ }
548+
549+ if self . url != other. url {
550+ result. report_error ( & format ! ( "URL mismatch: expected={}, actual={}" , other. url, self . url) ) ;
551+ }
552+
553+ if self . version != other. version {
554+ result. report_error ( & format ! (
555+ "Version mismatch: expected={}, actual={}" ,
556+ other. version, self . version
557+ ) ) ;
558+ }
559+
560+ if self . body != other. body {
561+ result. report_error ( & format ! (
562+ "Body mismatch: expected={:?}, actual={:?}" ,
563+ other. body. clone( ) ,
564+ self . body. clone( )
565+ ) ) ;
566+ }
567+
568+ Ok ( result)
533569 }
534570}
535571
@@ -553,7 +589,7 @@ pub mod tests {
553589 url: "https://example.com" . to_string( ) ,
554590 version: "HTTP/1.1" . to_string( ) ,
555591 headers: std:: collections:: HashMap :: from( [
556- ( "Authorization" . to_string( ) , "Bearer <TOKEN>" . to_string( ) ) ,
592+ ( "Authorization" . to_string( ) , "Bearer <% TOKEN% >" . to_string( ) ) ,
557593 ( "User-Agent" . to_string( ) , "test-agent" . to_string( ) ) ,
558594 ] ) ,
559595 body: None ,
@@ -590,7 +626,20 @@ pub mod tests {
590626 headers: std:: collections:: HashMap :: from( [
591627 ( "Content-Type" . to_string( ) , "application/json" . to_string( ) )
592628 ] ) ,
593- body: ManifestResponseBody :: default ( ) ,
629+ body: ManifestResponseBody {
630+ 0 : ExtractorConfig {
631+ format: DataFormat :: Json ,
632+ extractors: vec![ crate :: parser:: Extractor {
633+ id: "dummy" . to_string( ) ,
634+ description: "Dummy extractor" . to_string( ) ,
635+ selector: vec![ ] ,
636+ extractor_type: crate :: parser:: ExtractorType :: String ,
637+ required: true ,
638+ predicates: vec![ ] ,
639+ attribute: None ,
640+ } ] ,
641+ } ,
642+ } ,
594643 } ;
595644
596645 // Override default fields with provided arguments
@@ -664,12 +713,12 @@ pub mod tests {
664713
665714 // Is a perfect match with itself
666715 let matching_result = notary_response. match_and_extract ( & response) . unwrap ( ) ;
667- assert ! ( matching_result. is_some ( ) ) ;
668- assert_eq ! ( matching_result. unwrap ( ) . get( "testKey" ) . unwrap( ) , & json!( 3 ) ) ;
716+ assert ! ( matching_result. is_success ( ) ) ;
717+ assert_eq ! ( matching_result. values . get( "testKey" ) . unwrap( ) , & json!( 3 ) ) ;
669718
670719 // Fails if it doesn't match directly
671720 let non_matching_response = response ! ( status: "201" . to_string( ) ) ;
672- assert ! ( notary_response. match_and_extract( & non_matching_response) . unwrap( ) . is_none ( ) ) ;
721+ assert ! ( ! notary_response. match_and_extract( & non_matching_response) . unwrap( ) . is_success ( ) ) ;
673722
674723 // Superset case
675724 let response_superset = {
@@ -683,7 +732,7 @@ pub mod tests {
683732 ) ) ;
684733 res
685734 } ;
686- assert ! ( response_superset. match_and_extract( & response) . unwrap( ) . is_some ( ) ) ;
735+ assert ! ( response_superset. match_and_extract( & response) . unwrap( ) . is_success ( ) ) ;
687736 }
688737
689738 #[ test]
@@ -786,7 +835,7 @@ pub mod tests {
786835 ) ] ,
787836 } )
788837 ) ;
789- assert ! ( !base_response. match_and_extract( & other_response) . unwrap( ) . is_some ( ) ) ;
838+ assert ! ( !base_response. match_and_extract( & other_response) . unwrap( ) . is_success ( ) ) ;
790839 }
791840
792841 #[ test]
0 commit comments