@@ -47,6 +47,7 @@ impl<A: AdResponseValue> AdResponse<A> {
4747 let hash_str = request_hash. to_string ( ) ;
4848 for ( placement_id, ads) in self . data . iter_mut ( ) {
4949 for ( position, ad) in ads. iter_mut ( ) . enumerate ( ) {
50+ let impression_enriching_params = ad. impression_enriching_params ( ) ;
5051 let callbacks = ad. callbacks_mut ( ) ;
5152 callbacks
5253 . click
@@ -55,7 +56,8 @@ impl<A: AdResponseValue> AdResponse<A> {
5556 callbacks
5657 . impression
5758 . query_pairs_mut ( )
58- . append_pair ( "request_hash" , & hash_str) ;
59+ . append_pair ( "request_hash" , & hash_str)
60+ . extend_pairs ( impression_enriching_params) ;
5961 if let Some ( report_url) = callbacks. report . as_mut ( ) {
6062 report_url
6163 . query_pairs_mut ( )
@@ -161,6 +163,9 @@ pub struct AdCallbacks {
161163
162164pub trait AdResponseValue : DeserializeOwned {
163165 fn callbacks_mut ( & mut self ) -> & mut AdCallbacks ;
166+ fn impression_enriching_params ( & self ) -> Vec < ( String , String ) > {
167+ vec ! [ ]
168+ }
164169}
165170
166171impl AdResponseValue for AdImage {
@@ -173,6 +178,10 @@ impl AdResponseValue for AdSpoc {
173178 fn callbacks_mut ( & mut self ) -> & mut AdCallbacks {
174179 & mut self . callbacks
175180 }
181+
182+ fn impression_enriching_params ( & self ) -> Vec < ( String , String ) > {
183+ vec ! [ ( "cap_key" . to_owned( ) , self . caps. cap_key. clone( ) ) ]
184+ }
176185}
177186
178187impl AdResponseValue for AdTile {
@@ -514,6 +523,86 @@ mod tests {
514523 assert ! ( report_1. contains( "position=1" ) ) ;
515524 }
516525
526+ #[ test]
527+ fn test_enrich_callbacks_spoc_impressions_have_cap_key ( ) {
528+ let mut response = AdResponse {
529+ data : HashMap :: from ( [ (
530+ "tile1" . into ( ) ,
531+ vec ! [
532+ AdSpoc {
533+ block_key: "block_key1" . into( ) ,
534+ callbacks: AdCallbacks {
535+ click: Url :: parse( "https://example.com/click1" ) . unwrap( ) ,
536+ impression: Url :: parse( "https://example.com/impression1" ) . unwrap( ) ,
537+ report: Some ( Url :: parse( "https://example.com/report1" ) . unwrap( ) ) ,
538+ } ,
539+ caps: SpocFrequencyCaps {
540+ cap_key: "cap_key1" . into( ) ,
541+ day: 100 ,
542+ } ,
543+ domain: "1.example.com" . into( ) ,
544+ excerpt: "excerpt1" . into( ) ,
545+ format: "format1" . into( ) ,
546+ image_url: "https://example.com/image1.png" . into( ) ,
547+ url: "https://example.com/ad1" . into( ) ,
548+ ranking: SpocRanking {
549+ priority: 1 ,
550+ personalization_models: None ,
551+ item_score: 1.0 ,
552+ } ,
553+ sponsor: "sponsor1" . into( ) ,
554+ sponsored_by_override: None ,
555+ title: "title1" . into( ) ,
556+ } ,
557+ AdSpoc {
558+ block_key: "block_key2" . into( ) ,
559+ callbacks: AdCallbacks {
560+ click: Url :: parse( "https://example.com/click2" ) . unwrap( ) ,
561+ impression: Url :: parse( "https://example.com/impression2" ) . unwrap( ) ,
562+ report: Some ( Url :: parse( "https://example.com/report2" ) . unwrap( ) ) ,
563+ } ,
564+ caps: SpocFrequencyCaps {
565+ cap_key: "cap_key2" . into( ) ,
566+ day: 200 ,
567+ } ,
568+ domain: "2.example.com" . into( ) ,
569+ excerpt: "excerpt2" . into( ) ,
570+ format: "format2" . into( ) ,
571+ image_url: "https://example.com/image2.png" . into( ) ,
572+ url: "https://example.com/ad2" . into( ) ,
573+ ranking: SpocRanking {
574+ priority: 2 ,
575+ personalization_models: None ,
576+ item_score: 2.0 ,
577+ } ,
578+ sponsor: "sponsor2" . into( ) ,
579+ sponsored_by_override: None ,
580+ title: "title2" . into( ) ,
581+ } ,
582+ ] ,
583+ ) ] ) ,
584+ } ;
585+
586+ let request_hash = RequestHash :: from ( "abc123def456" ) ;
587+ response. enrich_callbacks ( & request_hash) ;
588+
589+ let ads = & response. data [ "tile1" ] ;
590+
591+ assert ! ( ads[ 0 ]
592+ . callbacks
593+ . impression
594+ . query( )
595+ . unwrap_or( "" )
596+ . contains( "cap_key=cap_key1" ) ) ;
597+
598+ assert ! ( ads[ 1 ]
599+ . callbacks
600+ . impression
601+ . query( )
602+ . unwrap_or( "" )
603+ . contains( "cap_key=cap_key2" ) ) ;
604+ }
605+
517606 #[ test]
518607 fn test_enrich_callbacks_skips_ads_without_report_url ( ) {
519608 let mut response = AdResponse {
0 commit comments