Skip to content

Commit 3dcf363

Browse files
Fix serde round-trip for ProviderSummary and add metadata extraction test
Address PR #347 review comments: - Add #[serde(default)] to ProviderSummary.metadata and OrchestratorExt.provider_details for backward-compatible deserialization - Add regression test for responsetimemillis and errors metadata extraction from Prebid Server response ext
1 parent 1c8d068 commit 3dcf363

2 files changed

Lines changed: 60 additions & 1 deletion

File tree

crates/common/src/auction/types.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ pub struct ProviderSummary {
160160
/// Response time in milliseconds.
161161
pub time_ms: u64,
162162
/// Provider-specific metadata (from [`AuctionResponse::metadata`]).
163-
#[serde(skip_serializing_if = "HashMap::is_empty")]
163+
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
164164
pub metadata: HashMap<String, serde_json::Value>,
165165
}
166166

@@ -189,6 +189,7 @@ pub struct OrchestratorExt {
189189
pub total_bids: usize,
190190
pub time_ms: u64,
191191
/// Per-provider breakdown of the auction.
192+
#[serde(default)]
192193
pub provider_details: Vec<ProviderSummary>,
193194
}
194195

crates/common/src/integrations/prebid.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1700,4 +1700,62 @@ fixed_bottom = {placementId = "_s2sBottom"}
17001700
"should parse fixed_bottom zone"
17011701
);
17021702
}
1703+
1704+
#[test]
1705+
fn parse_response_preserves_responsetimemillis_and_errors_metadata() {
1706+
let provider = PrebidAuctionProvider::new(base_config());
1707+
1708+
// Minimal valid OpenRTB response with ext containing diagnostics.
1709+
let response_json = json!({
1710+
"seatbid": [{
1711+
"seat": "kargo",
1712+
"bid": [{
1713+
"impid": "slot-1",
1714+
"price": 2.50,
1715+
"adm": "<div>ad</div>"
1716+
}]
1717+
}],
1718+
"ext": {
1719+
"responsetimemillis": {
1720+
"kargo": 98,
1721+
"appnexus": 0,
1722+
"ix": 120
1723+
},
1724+
"errors": {
1725+
"openx": [{"code": 1, "message": "timeout"}]
1726+
}
1727+
}
1728+
});
1729+
1730+
// Replicate the metadata extraction logic from `run_auction`.
1731+
let mut auction_response = provider.parse_openrtb_response(&response_json, 150);
1732+
1733+
let ext = response_json.get("ext");
1734+
if let Some(rtm) = ext.and_then(|e| e.get("responsetimemillis")) {
1735+
auction_response = auction_response.with_metadata("responsetimemillis", rtm.clone());
1736+
}
1737+
if let Some(errors) = ext.and_then(|e| e.get("errors")) {
1738+
auction_response = auction_response.with_metadata("errors", errors.clone());
1739+
}
1740+
1741+
// Verify bids were parsed.
1742+
assert_eq!(auction_response.bids.len(), 1, "should parse one bid");
1743+
1744+
// Verify responsetimemillis is preserved.
1745+
let rtm = auction_response
1746+
.metadata
1747+
.get("responsetimemillis")
1748+
.expect("should have responsetimemillis in metadata");
1749+
assert_eq!(rtm["kargo"], 98);
1750+
assert_eq!(rtm["appnexus"], 0);
1751+
assert_eq!(rtm["ix"], 120);
1752+
1753+
// Verify errors are preserved.
1754+
let errors = auction_response
1755+
.metadata
1756+
.get("errors")
1757+
.expect("should have errors in metadata");
1758+
assert_eq!(errors["openx"][0]["code"], 1);
1759+
assert_eq!(errors["openx"][0]["message"], "timeout");
1760+
}
17031761
}

0 commit comments

Comments
 (0)