capmonstercloud_client/requests/
recaptcha_v3_enterprise.rs1use serde::Serialize;
2
3use super::recaptcha_v3::check_min_score;
4use super::{require_non_empty, CaptchaRequest};
5use crate::error::Result;
6use crate::timeouts::GetResultTimeouts;
7
8#[derive(Debug, Clone, Serialize)]
10pub struct RecaptchaV3EnterpriseRequest {
11 #[serde(rename = "websiteURL")]
13 pub website_url: String,
14 #[serde(rename = "websiteKey")]
16 pub website_key: String,
17 #[serde(rename = "minScore", skip_serializing_if = "Option::is_none")]
19 pub min_score: Option<f64>,
20 #[serde(rename = "pageAction", skip_serializing_if = "Option::is_none")]
22 pub page_action: Option<String>,
23}
24
25impl RecaptchaV3EnterpriseRequest {
26 pub fn new(website_url: impl Into<String>, website_key: impl Into<String>) -> Self {
27 Self {
28 website_url: website_url.into(),
29 website_key: website_key.into(),
30 min_score: None,
31 page_action: None,
32 }
33 }
34
35 pub fn with_min_score(mut self, value: f64) -> Self {
37 self.min_score = Some(value);
38 self
39 }
40
41 pub fn with_page_action(mut self, value: impl Into<String>) -> Self {
42 self.page_action = Some(value.into());
43 self
44 }
45}
46
47impl CaptchaRequest for RecaptchaV3EnterpriseRequest {
48 const TASK_TYPE: &'static str = "RecaptchaV3EnterpriseTask";
49
50 fn timeouts(&self) -> GetResultTimeouts {
53 GetResultTimeouts::secs(1.0, 10.0, 3.0, 180.0)
54 }
55
56 fn validate(&self) -> Result<()> {
57 require_non_empty("websiteURL", &self.website_url)?;
58 require_non_empty("websiteKey", &self.website_key)?;
59 check_min_score(self.min_score)
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66 use crate::error::Error;
67 use serde_json::json;
68
69 #[test]
70 fn minimal_task() {
71 let task = RecaptchaV3EnterpriseRequest::new("https://example.com", "KEY")
72 .to_task()
73 .unwrap();
74 assert_eq!(
75 task,
76 json!({"type": "RecaptchaV3EnterpriseTask", "websiteURL": "https://example.com", "websiteKey": "KEY"})
77 );
78 }
79
80 #[test]
81 fn full_task() {
82 let task = RecaptchaV3EnterpriseRequest::new("https://example.com", "KEY")
83 .with_min_score(0.9)
84 .with_page_action("login")
85 .to_task()
86 .unwrap();
87 assert_eq!(
88 task,
89 json!({"type": "RecaptchaV3EnterpriseTask", "websiteURL": "https://example.com",
90 "websiteKey": "KEY", "minScore": 0.9, "pageAction": "login"})
91 );
92 }
93
94 #[test]
95 fn min_score_out_of_range() {
96 let err = RecaptchaV3EnterpriseRequest::new("u", "k")
97 .with_min_score(0.95)
98 .to_task()
99 .unwrap_err();
100 assert!(matches!(err, Error::Validation(_)));
101 }
102
103 #[test]
104 fn empty_required_strings_are_rejected() {
105 for (url, key, field) in [
106 ("", "KEY", "websiteURL"),
107 ("https://example.com", "", "websiteKey"),
108 ] {
109 let err = RecaptchaV3EnterpriseRequest::new(url, key)
110 .to_task()
111 .unwrap_err();
112 assert!(matches!(err, crate::error::Error::Validation(ref m) if m.contains(field)));
113 }
114 }
115}