@@ -246,3 +246,133 @@ impl AuctionResponse {
246246 self
247247 }
248248}
249+
250+ #[ cfg( test) ]
251+ mod tests {
252+ use super :: * ;
253+ use serde_json:: json;
254+
255+ fn make_bid ( bidder : & str ) -> Bid {
256+ Bid {
257+ slot_id : "slot-1" . to_string ( ) ,
258+ price : Some ( 1.0 ) ,
259+ currency : "USD" . to_string ( ) ,
260+ creative : None ,
261+ adomain : None ,
262+ bidder : bidder. to_string ( ) ,
263+ width : 300 ,
264+ height : 250 ,
265+ nurl : None ,
266+ burl : None ,
267+ metadata : HashMap :: new ( ) ,
268+ }
269+ }
270+
271+ #[ test]
272+ fn provider_summary_from_successful_response ( ) {
273+ let response = AuctionResponse :: success (
274+ "prebid" ,
275+ vec ! [ make_bid( "kargo" ) , make_bid( "pubmatic" ) , make_bid( "ix" ) ] ,
276+ 95 ,
277+ ) ;
278+
279+ let summary = ProviderSummary :: from ( & response) ;
280+
281+ assert_eq ! ( summary. name, "prebid" , "should use provider name" ) ;
282+ assert_eq ! ( summary. status, BidStatus :: Success , "should preserve status" ) ;
283+ assert_eq ! ( summary. bid_count, 3 , "should count all bids" ) ;
284+ assert_eq ! (
285+ summary. bidders,
286+ vec![ "ix" , "kargo" , "pubmatic" ] ,
287+ "should list unique bidders sorted"
288+ ) ;
289+ assert_eq ! ( summary. time_ms, 95 , "should preserve response time" ) ;
290+ assert ! ( summary. metadata. is_empty( ) , "should have no metadata" ) ;
291+ }
292+
293+ #[ test]
294+ fn provider_summary_deduplicates_bidder_names ( ) {
295+ let response = AuctionResponse :: success (
296+ "prebid" ,
297+ vec ! [ make_bid( "kargo" ) , make_bid( "kargo" ) , make_bid( "pubmatic" ) ] ,
298+ 50 ,
299+ ) ;
300+
301+ let summary = ProviderSummary :: from ( & response) ;
302+
303+ assert_eq ! (
304+ summary. bid_count, 3 ,
305+ "should count all bids including dupes"
306+ ) ;
307+ assert_eq ! (
308+ summary. bidders,
309+ vec![ "kargo" , "pubmatic" ] ,
310+ "should deduplicate bidder names"
311+ ) ;
312+ }
313+
314+ #[ test]
315+ fn provider_summary_from_no_bid_response ( ) {
316+ let response = AuctionResponse :: no_bid ( "aps" , 110 ) ;
317+
318+ let summary = ProviderSummary :: from ( & response) ;
319+
320+ assert_eq ! ( summary. name, "aps" , "should use provider name" ) ;
321+ assert_eq ! (
322+ summary. status,
323+ BidStatus :: NoBid ,
324+ "should preserve no-bid status"
325+ ) ;
326+ assert_eq ! ( summary. bid_count, 0 , "should have zero bids" ) ;
327+ assert ! ( summary. bidders. is_empty( ) , "should have no bidders" ) ;
328+ }
329+
330+ #[ test]
331+ fn provider_summary_from_error_response ( ) {
332+ let response = AuctionResponse :: error ( "prebid" , 200 ) ;
333+
334+ let summary = ProviderSummary :: from ( & response) ;
335+
336+ assert_eq ! (
337+ summary. status,
338+ BidStatus :: Error ,
339+ "should preserve error status"
340+ ) ;
341+ assert_eq ! ( summary. bid_count, 0 , "should have zero bids" ) ;
342+ assert ! ( summary. bidders. is_empty( ) , "should have no bidders" ) ;
343+ }
344+
345+ #[ test]
346+ fn provider_summary_passes_through_metadata ( ) {
347+ let response = AuctionResponse :: success ( "prebid" , vec ! [ make_bid( "kargo" ) ] , 80 )
348+ . with_metadata ( "responsetimemillis" , json ! ( { "kargo" : 70 , "pubmatic" : 90 } ) )
349+ . with_metadata ( "errors" , json ! ( { "pubmatic" : [ { "code" : 1 } ] } ) ) ;
350+
351+ let summary = ProviderSummary :: from ( & response) ;
352+
353+ assert_eq ! ( summary. metadata. len( ) , 2 , "should forward all metadata" ) ;
354+ assert_eq ! (
355+ summary. metadata[ "responsetimemillis" ] ,
356+ json!( { "kargo" : 70 , "pubmatic" : 90 } ) ,
357+ "should preserve responsetimemillis"
358+ ) ;
359+ assert_eq ! (
360+ summary. metadata[ "errors" ] ,
361+ json!( { "pubmatic" : [ { "code" : 1 } ] } ) ,
362+ "should preserve errors"
363+ ) ;
364+ }
365+
366+ #[ test]
367+ fn provider_summary_skips_metadata_in_serialization_when_empty ( ) {
368+ let response = AuctionResponse :: no_bid ( "aps" , 100 ) ;
369+ let summary = ProviderSummary :: from ( & response) ;
370+
371+ let json = serde_json:: to_value ( & summary) . expect ( "should serialize" ) ;
372+
373+ assert ! (
374+ json. get( "metadata" ) . is_none( ) ,
375+ "should omit metadata field when empty"
376+ ) ;
377+ }
378+ }
0 commit comments