diff --git a/components/merino/src/worldcup/http.rs b/components/merino/src/worldcup/http.rs index 897636c8bd..b16de88b10 100644 --- a/components/merino/src/worldcup/http.rs +++ b/components/merino/src/worldcup/http.rs @@ -14,6 +14,7 @@ pub struct WorldCupQueryParams { pub limit: Option, pub teams: Option, pub accept_language: Option, + pub date: Option, } pub trait HttpClientTrait { @@ -27,7 +28,7 @@ impl HttpClientTrait for HttpClient { } pub fn build_url(endpoint_url: Url, params: &WorldCupQueryParams) -> Url { - if params.limit.is_none() && params.teams.is_none() { + if params.limit.is_none() && params.teams.is_none() && params.date.is_none() { return endpoint_url; } let mut url = endpoint_url; @@ -39,6 +40,9 @@ pub fn build_url(endpoint_url: Url, params: &WorldCupQueryParams) -> Url { if let Some(v) = ¶ms.teams { pairs.append_pair("teams", v); } + if let Some(v) = ¶ms.date { + pairs.append_pair("date", v); + } } url } @@ -112,6 +116,7 @@ mod tests { limit: Some(5), teams: Some("FRA,ENG".to_string()), accept_language: Some("en-GB".to_string()), + date: None, }; let url = build_url(base_url(), &options); assert!(has_param(&url, "limit", "5")); @@ -131,6 +136,7 @@ mod tests { limit: Some(3), teams: Some("FRA".to_string()), accept_language: Some("en-US".to_string()), + date: None, }; let url = build_url(base_url(), &options); assert_eq!( diff --git a/components/merino/src/worldcup/mod.rs b/components/merino/src/worldcup/mod.rs index cc078718ed..9c80ff2c11 100644 --- a/components/merino/src/worldcup/mod.rs +++ b/components/merino/src/worldcup/mod.rs @@ -117,6 +117,7 @@ impl WorldCupClientInner { limit: options.limit, teams, accept_language: options.accept_language, + date: options.date, } } diff --git a/components/merino/src/worldcup/schema.rs b/components/merino/src/worldcup/schema.rs index 1976a9a434..70e32c6149 100644 --- a/components/merino/src/worldcup/schema.rs +++ b/components/merino/src/worldcup/schema.rs @@ -15,4 +15,6 @@ pub struct WorldCupOptions { pub teams: Option>, /// Language for results (e.g. `"en-US"`). (Not supported yet) pub accept_language: Option, + /// ISO 8601 date string to filter matches by date (e.g. `"2026-06-14"`). + pub date: Option, } diff --git a/components/merino/src/worldcup/tests.rs b/components/merino/src/worldcup/tests.rs index e7071d6afe..616e9a9344 100644 --- a/components/merino/src/worldcup/tests.rs +++ b/components/merino/src/worldcup/tests.rs @@ -29,6 +29,7 @@ fn default_options() -> WorldCupOptions { limit: None, teams: None, accept_language: None, + date: None, } } @@ -162,6 +163,7 @@ fn test_accept_language_is_passed_as_header() { limit: None, teams: None, accept_language: Some("en-US".to_string()), + date: None, }, ); let response = result.unwrap().unwrap(); @@ -212,6 +214,7 @@ fn test_matches_endpoint_url_with_limit() { limit: Some(2), teams: None, accept_language: None, + date: None, }, ); let captured = captured_url.lock().unwrap(); @@ -246,3 +249,25 @@ fn test_builder_fails_with_invalid_base_host() { Ok(_) => panic!("Expected error for invalid base_host"), } } + +#[test] +fn test_matches_endpoint_url_with_date() { + let captured_url = std::sync::Arc::new(std::sync::Mutex::new(None::)); + let client_inner = WorldCupClientInner::new_with_client(FakeCapturingClient { + captured_url: captured_url.clone(), + }); + let _ = client_inner.make_request( + base_url().join("matches").unwrap(), + WorldCupOptions { + limit: None, + teams: None, + accept_language: None, + date: Some("2026-06-14".to_string()), + }, + ); + let captured = captured_url.lock().unwrap(); + assert_eq!( + captured.as_ref().unwrap().as_str(), + "https://merino.services.mozilla.com/api/v1/wcs/matches?date=2026-06-14" + ); +} diff --git a/examples/merino-cli/src/main.rs b/examples/merino-cli/src/main.rs index 486788bcc5..1bd22286f7 100644 --- a/examples/merino-cli/src/main.rs +++ b/examples/merino-cli/src/main.rs @@ -99,6 +99,9 @@ enum Commands { /// Language for results (e.g. "en-US") #[arg(long)] accept_language: Option, + /// Date to filter matches by, in `YYYY-MM-DD` format (e.g. "2026-06-14") + #[arg(long)] + date: Option, #[command(subcommand)] endpoint: WorldCupEndpoint, @@ -186,6 +189,7 @@ fn main() -> Result<()> { limit, teams, accept_language, + date, endpoint, } => { let client = WorldCupClient::new(WorldCupConfig { @@ -195,6 +199,7 @@ fn main() -> Result<()> { limit, teams, accept_language, + date, }; let result = match endpoint { WorldCupEndpoint::Teams => client.get_teams(options),