google_search_console_api/mobile_friendly_test/
mod.rs1use serde_derive::{Deserialize, Serialize};
6
7#[derive(Debug, Serialize, Deserialize, Clone, Default)]
18pub struct RequestMobileFriendlyTest {
19 pub url: String,
21 #[serde(rename = "requestScreenshot")]
23 pub request_screenshot: bool,
24}
25
26impl RequestMobileFriendlyTest {
27 pub fn new(url: &str) -> Self {
33 Self {
34 url: url.to_string(),
35 request_screenshot: false,
36 }
37 }
38
39 pub fn with_screenshot(mut self) -> Self {
43 self.request_screenshot = true;
44 self
45 }
46}
47
48#[derive(Debug, Serialize, Deserialize, Clone)]
50pub struct ResponseMobileFriendlyTest {
51 #[serde(rename = "testStatus")]
53 pub test_status: TestStatus,
54 #[serde(rename = "mobileFriendliness")]
56 pub mobile_friendliness: MobileFriendlyTestResult,
57 #[serde(rename = "mobileFriendlyIssues")]
59 pub mobile_friendly_issues: Option<Vec<MobileFriendlyIssue>>,
60 #[serde(rename = "resourceIssues")]
62 pub resource_issues: Option<Vec<ResourceIssue>>,
63 pub screenshot: Option<Image>,
65}
66
67#[derive(Debug, Serialize, Deserialize, Clone)]
69pub struct TestStatus {
70 pub status: TestStatusEnum,
72 pub details: Option<String>,
74}
75
76#[derive(Debug, Serialize, Deserialize, Clone)]
78pub enum TestStatusEnum {
79 #[serde(rename = "TEST_STATUS_UNSPECIFIED")]
81 TestStatusUnspecified,
82 #[serde(rename = "COMPLETE")]
84 COMPLETE,
85 #[serde(rename = "INTERNAL_ERROR")]
87 InternalError,
88 #[serde(rename = "PAGE_UNREACHABLE")]
90 PageUnreachable,
91}
92
93#[derive(Debug, Serialize, Deserialize, Clone)]
95pub enum MobileFriendlyTestResult {
96 #[serde(rename = "MOBILE_FRIENDLY_TEST_RESULT_UNSPECIFIED")]
98 MobileFriendlyTestResultUnspecified,
99 #[serde(rename = "MOBILE_FRIENDLY")]
101 MobileFriendly,
102 #[serde(rename = "NOT_MOBILE_FRIENDLY")]
104 NotMobileFriendly,
105}
106
107#[derive(Debug, Serialize, Deserialize, Clone)]
109pub struct MobileFriendlyIssue {
110 pub rule: MobileFriendlyRule,
112}
113
114#[derive(Debug, Serialize, Deserialize, Clone)]
116pub enum MobileFriendlyRule {
117 #[serde(rename = "MOBILE_FRIENDLY_RULE_UNSPECIFIED")]
119 MobileFriendlyRuleUnspecified,
120 #[serde(rename = "USES_INCOMPATIBLE_PLUGINS")]
122 UsesIncompatiblePlugins,
123 #[serde(rename = "ConfigureViewport")]
125 ConfigureViewport,
126 #[serde(rename = "FIXED_WIDTH_VIEWPORT")]
128 FixedWidthViewport,
129 #[serde(rename = "SIZE_CONTENT_TO_VIEWPORT")]
131 SizeContentToViewport,
132 #[serde(rename = "USE_LEGIBLE_FONT_SIZES")]
134 UseLegibleFontSizes,
135 #[serde(rename = "TAP_TARGETS_TOO_CLOSE")]
137 TapTargetsTooClose,
138}
139
140#[derive(Debug, Serialize, Deserialize, Clone)]
142pub struct ResourceIssue {
143 #[serde(rename = "blockedResource")]
145 pub blocked_resource: BlockedResource,
146}
147
148#[derive(Debug, Serialize, Deserialize, Clone)]
150pub struct BlockedResource {
151 pub url: String,
153}
154
155#[derive(Debug, Serialize, Deserialize, Clone)]
157pub struct Image {
158 pub data: String,
160 #[serde(rename = "mimeType")]
162 pub mime_type: String,
163}
164
165#[cfg(test)]
166mod tests {
167 use super::*;
168
169 #[test]
170 fn test_request_new() {
171 let request = RequestMobileFriendlyTest::new("https://example.com/");
172 assert_eq!(request.url, "https://example.com/");
173 assert!(!request.request_screenshot);
174 }
175
176 #[test]
177 fn test_request_with_screenshot() {
178 let request = RequestMobileFriendlyTest::new("https://example.com/").with_screenshot();
179 assert_eq!(request.url, "https://example.com/");
180 assert!(request.request_screenshot);
181 }
182
183 #[test]
184 fn test_request_default() {
185 let request = RequestMobileFriendlyTest::default();
186 assert_eq!(request.url, "");
187 assert!(!request.request_screenshot);
188 }
189
190 #[test]
191 fn test_request_serialize() {
192 let request = RequestMobileFriendlyTest::new("https://example.com/").with_screenshot();
193
194 let json = serde_json::to_string(&request).unwrap();
195 assert!(json.contains("\"url\":\"https://example.com/\""));
196 assert!(json.contains("\"requestScreenshot\":true"));
197 }
198
199 #[test]
200 fn test_response_deserialize() {
201 let json = r#"{
202 "testStatus": {
203 "status": "COMPLETE"
204 },
205 "mobileFriendliness": "MOBILE_FRIENDLY"
206 }"#;
207
208 let response: ResponseMobileFriendlyTest = serde_json::from_str(json).unwrap();
209 assert!(matches!(response.test_status.status, TestStatusEnum::COMPLETE));
210 assert!(matches!(
211 response.mobile_friendliness,
212 MobileFriendlyTestResult::MobileFriendly
213 ));
214 }
215
216 #[test]
217 fn test_response_with_issues() {
218 let json = r#"{
219 "testStatus": {
220 "status": "COMPLETE"
221 },
222 "mobileFriendliness": "NOT_MOBILE_FRIENDLY",
223 "mobileFriendlyIssues": [
224 {"rule": "TAP_TARGETS_TOO_CLOSE"}
225 ]
226 }"#;
227
228 let response: ResponseMobileFriendlyTest = serde_json::from_str(json).unwrap();
229 assert!(matches!(
230 response.mobile_friendliness,
231 MobileFriendlyTestResult::NotMobileFriendly
232 ));
233
234 let issues = response.mobile_friendly_issues.unwrap();
235 assert_eq!(issues.len(), 1);
236 assert!(matches!(
237 issues[0].rule,
238 MobileFriendlyRule::TapTargetsTooClose
239 ));
240 }
241
242 #[test]
243 fn test_test_status_enum_deserialize() {
244 assert!(matches!(
245 serde_json::from_str::<TestStatusEnum>("\"COMPLETE\"").unwrap(),
246 TestStatusEnum::COMPLETE
247 ));
248 assert!(matches!(
249 serde_json::from_str::<TestStatusEnum>("\"INTERNAL_ERROR\"").unwrap(),
250 TestStatusEnum::InternalError
251 ));
252 assert!(matches!(
253 serde_json::from_str::<TestStatusEnum>("\"PAGE_UNREACHABLE\"").unwrap(),
254 TestStatusEnum::PageUnreachable
255 ));
256 }
257}