use serde_derive::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct RequestMobileFriendlyTest {
pub url: String,
#[serde(rename = "requestScreenshot")]
pub request_screenshot: bool,
}
impl RequestMobileFriendlyTest {
pub fn new(url: &str) -> Self {
Self {
url: url.to_string(),
request_screenshot: false,
}
}
pub fn with_screenshot(mut self) -> Self {
self.request_screenshot = true;
self
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ResponseMobileFriendlyTest {
#[serde(rename = "testStatus")]
pub test_status: TestStatus,
#[serde(rename = "mobileFriendliness")]
pub mobile_friendliness: MobileFriendlyTestResult,
#[serde(rename = "mobileFriendlyIssues")]
pub mobile_friendly_issues: Option<Vec<MobileFriendlyIssue>>,
#[serde(rename = "resourceIssues")]
pub resource_issues: Option<Vec<ResourceIssue>>,
pub screenshot: Option<Image>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct TestStatus {
pub status: TestStatusEnum,
pub details: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum TestStatusEnum {
#[serde(rename = "TEST_STATUS_UNSPECIFIED")]
TestStatusUnspecified,
#[serde(rename = "COMPLETE")]
COMPLETE,
#[serde(rename = "INTERNAL_ERROR")]
InternalError,
#[serde(rename = "PAGE_UNREACHABLE")]
PageUnreachable,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum MobileFriendlyTestResult {
#[serde(rename = "MOBILE_FRIENDLY_TEST_RESULT_UNSPECIFIED")]
MobileFriendlyTestResultUnspecified,
#[serde(rename = "MOBILE_FRIENDLY")]
MobileFriendly,
#[serde(rename = "NOT_MOBILE_FRIENDLY")]
NotMobileFriendly,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct MobileFriendlyIssue {
pub rule: MobileFriendlyRule,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum MobileFriendlyRule {
#[serde(rename = "MOBILE_FRIENDLY_RULE_UNSPECIFIED")]
MobileFriendlyRuleUnspecified,
#[serde(rename = "USES_INCOMPATIBLE_PLUGINS")]
UsesIncompatiblePlugins,
#[serde(rename = "ConfigureViewport")]
ConfigureViewport,
#[serde(rename = "FIXED_WIDTH_VIEWPORT")]
FixedWidthViewport,
#[serde(rename = "SIZE_CONTENT_TO_VIEWPORT")]
SizeContentToViewport,
#[serde(rename = "USE_LEGIBLE_FONT_SIZES")]
UseLegibleFontSizes,
#[serde(rename = "TAP_TARGETS_TOO_CLOSE")]
TapTargetsTooClose,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ResourceIssue {
#[serde(rename = "blockedResource")]
pub blocked_resource: BlockedResource,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct BlockedResource {
pub url: String,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Image {
pub data: String,
#[serde(rename = "mimeType")]
pub mime_type: String,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_request_new() {
let request = RequestMobileFriendlyTest::new("https://example.com/");
assert_eq!(request.url, "https://example.com/");
assert!(!request.request_screenshot);
}
#[test]
fn test_request_with_screenshot() {
let request = RequestMobileFriendlyTest::new("https://example.com/").with_screenshot();
assert_eq!(request.url, "https://example.com/");
assert!(request.request_screenshot);
}
#[test]
fn test_request_default() {
let request = RequestMobileFriendlyTest::default();
assert_eq!(request.url, "");
assert!(!request.request_screenshot);
}
#[test]
fn test_request_serialize() {
let request = RequestMobileFriendlyTest::new("https://example.com/").with_screenshot();
let json = serde_json::to_string(&request).unwrap();
assert!(json.contains("\"url\":\"https://example.com/\""));
assert!(json.contains("\"requestScreenshot\":true"));
}
#[test]
fn test_response_deserialize() {
let json = r#"{
"testStatus": {
"status": "COMPLETE"
},
"mobileFriendliness": "MOBILE_FRIENDLY"
}"#;
let response: ResponseMobileFriendlyTest = serde_json::from_str(json).unwrap();
assert!(matches!(response.test_status.status, TestStatusEnum::COMPLETE));
assert!(matches!(
response.mobile_friendliness,
MobileFriendlyTestResult::MobileFriendly
));
}
#[test]
fn test_response_with_issues() {
let json = r#"{
"testStatus": {
"status": "COMPLETE"
},
"mobileFriendliness": "NOT_MOBILE_FRIENDLY",
"mobileFriendlyIssues": [
{"rule": "TAP_TARGETS_TOO_CLOSE"}
]
}"#;
let response: ResponseMobileFriendlyTest = serde_json::from_str(json).unwrap();
assert!(matches!(
response.mobile_friendliness,
MobileFriendlyTestResult::NotMobileFriendly
));
let issues = response.mobile_friendly_issues.unwrap();
assert_eq!(issues.len(), 1);
assert!(matches!(
issues[0].rule,
MobileFriendlyRule::TapTargetsTooClose
));
}
#[test]
fn test_test_status_enum_deserialize() {
assert!(matches!(
serde_json::from_str::<TestStatusEnum>("\"COMPLETE\"").unwrap(),
TestStatusEnum::COMPLETE
));
assert!(matches!(
serde_json::from_str::<TestStatusEnum>("\"INTERNAL_ERROR\"").unwrap(),
TestStatusEnum::InternalError
));
assert!(matches!(
serde_json::from_str::<TestStatusEnum>("\"PAGE_UNREACHABLE\"").unwrap(),
TestStatusEnum::PageUnreachable
));
}
}