chrome_for_testing/api/
known_good_versions.rs1use crate::api::version::Version;
2use crate::api::{API_BASE_URL, Download};
3use crate::error::Result;
4use serde::Deserialize;
5
6const KNOWN_GOOD_VERSIONS_WITH_DOWNLOADS_JSON_PATH: &str =
30 "/chrome-for-testing/known-good-versions-with-downloads.json";
31
32#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
34pub struct Downloads {
35 pub chrome: Vec<Download>,
37
38 pub chromedriver: Option<Vec<Download>>,
41}
42
43#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
47pub struct VersionWithoutChannel {
48 pub version: Version,
50
51 pub revision: String,
53
54 pub downloads: Downloads,
56}
57
58#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
64pub struct KnownGoodVersions {
65 #[serde(with = "time::serde::rfc3339")]
67 pub timestamp: time::OffsetDateTime,
68
69 pub versions: Vec<VersionWithoutChannel>,
71}
72
73impl KnownGoodVersions {
74 pub async fn fetch(client: reqwest::Client) -> Result<Self> {
84 Self::fetch_with_base_url(client, API_BASE_URL.clone()).await
85 }
86
87 pub async fn fetch_with_base_url(
93 client: reqwest::Client,
94 base_url: reqwest::Url,
95 ) -> Result<Self> {
96 let result = client
97 .get(base_url.join(KNOWN_GOOD_VERSIONS_WITH_DOWNLOADS_JSON_PATH)?)
98 .send()
99 .await?
100 .json::<Self>()
101 .await?;
102 Ok(result)
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109 use crate::api::Download;
110 use crate::api::known_good_versions::KnownGoodVersions;
111 use crate::api::platform::Platform;
112 use crate::api::version::Version;
113 use assertr::prelude::*;
114 use time::macros::datetime;
115 use url::Url;
116
117 #[tokio::test]
118 async fn can_request_from_real_world_endpoint() {
119 let result = KnownGoodVersions::fetch(reqwest::Client::new()).await;
120 assert_that!(result).is_ok();
121 }
122
123 #[tokio::test]
125 async fn can_query_known_good_versions_api_endpoint_and_deserialize_response() {
126 let mut server = mockito::Server::new_async().await;
127
128 let _mock = server
129 .mock("GET", KNOWN_GOOD_VERSIONS_WITH_DOWNLOADS_JSON_PATH)
130 .with_status(200)
131 .with_header("content-type", "application/json")
132 .with_body(include_str!(
133 "./../../test-data/known_good_versions_test_response.json"
134 ))
135 .create();
136
137 let url: Url = server.url().parse().unwrap();
138
139 let data = KnownGoodVersions::fetch_with_base_url(reqwest::Client::new(), url)
140 .await
141 .unwrap();
142
143 assert_that!(data).is_equal_to(KnownGoodVersions {
144 timestamp: datetime!(2025-01-17 10:09:31.689 UTC),
145 versions: vec![
146 VersionWithoutChannel {
147 version: Version { major: 113, minor: 0, patch: 5672, build: 0 },
148 revision: String::from("1121455"),
149 downloads: Downloads {
150 chrome: vec![
151 Download { platform: Platform::Linux64, url: String::from("https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.0/linux64/chrome-linux64.zip") },
152 Download { platform: Platform::MacArm64, url: String::from("https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.0/mac-arm64/chrome-mac-arm64.zip") },
153 Download { platform: Platform::MacX64, url: String::from("https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.0/mac-x64/chrome-mac-x64.zip") },
154 Download { platform: Platform::Win32, url: String::from("https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.0/win32/chrome-win32.zip") },
155 Download { platform: Platform::Win64, url: String::from("https://storage.googleapis.com/chrome-for-testing-public/113.0.5672.0/win64/chrome-win64.zip") },
156 ],
157 chromedriver: None,
158 },
159 },
160 VersionWithoutChannel {
161 version: Version { major: 134, minor: 0, patch: 6962, build: 0 },
162 revision: String::from("1407692"),
163 downloads: Downloads {
164 chrome: vec![
165 Download { platform: Platform::Linux64, url: String::from("https://storage.googleapis.com/chrome-for-testing-public/134.0.6962.0/linux64/chrome-linux64.zip") },
166 Download { platform: Platform::MacArm64, url: String::from("https://storage.googleapis.com/chrome-for-testing-public/134.0.6962.0/mac-arm64/chrome-mac-arm64.zip") },
167 Download { platform: Platform::MacX64, url: String::from("https://storage.googleapis.com/chrome-for-testing-public/134.0.6962.0/mac-x64/chrome-mac-x64.zip") },
168 Download { platform: Platform::Win32, url: String::from("https://storage.googleapis.com/chrome-for-testing-public/134.0.6962.0/win32/chrome-win32.zip") },
169 Download { platform: Platform::Win64, url: String::from("https://storage.googleapis.com/chrome-for-testing-public/134.0.6962.0/win64/chrome-win64.zip") },
170 ],
171 chromedriver: Some(vec![
172 Download { platform: Platform::Linux64, url: String::from("https://storage.googleapis.com/chrome-for-testing-public/134.0.6962.0/linux64/chromedriver-linux64.zip") },
173 Download { platform: Platform::MacArm64, url: String::from("https://storage.googleapis.com/chrome-for-testing-public/134.0.6962.0/mac-arm64/chromedriver-mac-arm64.zip") },
174 Download { platform: Platform::MacX64, url: String::from("https://storage.googleapis.com/chrome-for-testing-public/134.0.6962.0/mac-x64/chromedriver-mac-x64.zip") },
175 Download { platform: Platform::Win32, url: String::from("https://storage.googleapis.com/chrome-for-testing-public/134.0.6962.0/win32/chromedriver-win32.zip") },
176 Download { platform: Platform::Win64, url: String::from("https://storage.googleapis.com/chrome-for-testing-public/134.0.6962.0/win64/chromedriver-win64.zip") },
177 ]),
178 },
179 },
180 ],
181 });
182 }
183}