fxa_client/internal/commands/
close_tabs.rs
1use crate::internal::telemetry;
6use serde_derive::*;
7
8pub const COMMAND_NAME: &str = "https://identity.mozilla.com/cmd/close-uri/v1";
9pub const COMMAND_TTL: u64 = 2 * 24 * 3600;
11
12#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
13pub struct CloseTabsPayload {
14 pub urls: Vec<String>,
15 #[serde(rename = "flowID", default)]
16 pub flow_id: String,
17 #[serde(rename = "streamID", default)]
18 pub stream_id: String,
19}
20
21impl From<CloseTabsPayload> for crate::CloseTabsPayload {
22 fn from(payload: CloseTabsPayload) -> Self {
23 crate::CloseTabsPayload { urls: payload.urls }
24 }
25}
26
27impl CloseTabsPayload {
28 pub fn with_urls(urls: Vec<String>) -> (Self, telemetry::SentCommand) {
29 let sent_telemetry: telemetry::SentCommand = telemetry::SentCommand::for_close_tabs();
30 (Self::with_telemetry(&sent_telemetry, urls), sent_telemetry)
31 }
32
33 pub fn with_telemetry(sent_telemetry: &telemetry::SentCommand, urls: Vec<String>) -> Self {
34 CloseTabsPayload {
35 urls,
36 flow_id: sent_telemetry.flow_id.clone(),
37 stream_id: sent_telemetry.stream_id.clone(),
38 }
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45
46 use crate::Result;
47
48 #[test]
49 fn test_empty_payload() -> Result<()> {
50 let empty = r#"{ "urls": []}"#;
51 let payload: CloseTabsPayload = serde_json::from_str(empty)?;
52 assert!(payload.urls.is_empty());
53
54 Ok(())
55 }
56
57 #[test]
58 fn test_payload() -> Result<()> {
59 let (payload, telem) = CloseTabsPayload::with_urls(vec!["https://www.mozilla.org".into()]);
60 let json = serde_json::to_string(&payload)?;
61 assert!(!json.is_empty());
62 assert_eq!(telem.flow_id.len(), 12);
63 assert_eq!(telem.stream_id.len(), 12);
64 assert_ne!(telem.flow_id, telem.stream_id);
65
66 let deserialized: CloseTabsPayload = serde_json::from_str(&json)?;
67 assert_eq!(deserialized, payload);
68
69 Ok(())
70 }
71}