use crate::iq::spec::IqSpec;
use crate::request::InfoQuery;
use crate::types::spam_report::{SpamReportRequest, SpamReportResult, build_spam_list_node};
use wacore_binary::{Jid, Server};
use wacore_binary::{NodeContent, NodeContentRef, NodeRef};
pub use crate::types::spam_report::{
SpamFlow, SpamReportRequest as Request, SpamReportResult as Response,
};
#[derive(Debug, Clone)]
pub struct SpamReportSpec {
pub request: SpamReportRequest,
}
impl SpamReportSpec {
pub fn new(request: SpamReportRequest) -> Self {
Self { request }
}
}
impl IqSpec for SpamReportSpec {
type Response = SpamReportResult;
fn build_iq(&self) -> InfoQuery<'static> {
let spam_list_node = build_spam_list_node(&self.request);
InfoQuery::set(
"spam",
Jid::new("", Server::Pn),
Some(NodeContent::Nodes(vec![spam_list_node])),
)
}
fn parse_response(&self, response: &NodeRef<'_>) -> Result<Self::Response, anyhow::Error> {
let report_id = response
.get_optional_child_by_tag(&["report_id"])
.and_then(|n| match n.content.as_deref() {
Some(NodeContentRef::String(s)) => Some(s.to_string()),
_ => None,
});
Ok(SpamReportResult { report_id })
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::types::spam_report::SpamFlow;
use wacore_binary::builder::NodeBuilder;
#[test]
fn test_spam_report_spec_build_iq() {
let request = SpamReportRequest {
message_id: "TEST123".to_string(),
message_timestamp: 1234567890,
spam_flow: SpamFlow::MessageMenu,
..Default::default()
};
let spec = SpamReportSpec::new(request);
let iq = spec.build_iq();
assert_eq!(iq.namespace, "spam");
assert_eq!(iq.query_type, crate::request::InfoQueryType::Set);
if let Some(NodeContent::Nodes(nodes)) = &iq.content {
assert_eq!(nodes.len(), 1);
assert_eq!(nodes[0].tag, "spam_list");
assert!(
nodes[0]
.attrs
.get("spam_flow")
.is_some_and(|s| s == "MessageMenu")
);
} else {
panic!("Expected NodeContent::Nodes");
}
}
#[test]
fn test_spam_report_spec_parse_response_with_report_id() {
let request = SpamReportRequest {
message_id: "TEST123".to_string(),
message_timestamp: 1234567890,
spam_flow: SpamFlow::MessageMenu,
..Default::default()
};
let spec = SpamReportSpec::new(request);
let response = NodeBuilder::new("iq")
.attr("type", "result")
.children([NodeBuilder::new("report_id")
.string_content("REPORT_ABC123")
.build()])
.build();
let result = spec.parse_response(&response.as_node_ref()).unwrap();
assert_eq!(result.report_id, Some("REPORT_ABC123".to_string()));
}
#[test]
fn test_spam_report_spec_parse_response_without_report_id() {
let request = SpamReportRequest {
message_id: "TEST123".to_string(),
message_timestamp: 1234567890,
spam_flow: SpamFlow::MessageMenu,
..Default::default()
};
let spec = SpamReportSpec::new(request);
let response = NodeBuilder::new("iq").attr("type", "result").build();
let result = spec.parse_response(&response.as_node_ref()).unwrap();
assert_eq!(result.report_id, None);
}
}