use httpmock::prelude::*;
use serde_json::json;
use slack_rs::api::ApiClient;
use slack_rs::commands::thread_get;
#[tokio::test]
async fn test_thread_get_single_page() {
let server = MockServer::start();
let mock = server.mock(|when, then| {
when.method(GET)
.path("/conversations.replies")
.header("Authorization", "Bearer test-token")
.query_param("channel", "C123456")
.query_param("ts", "1234567890.123456")
.query_param("limit", "100");
then.status(200)
.header("content-type", "application/json")
.json_body(json!({
"ok": true,
"messages": [
{
"type": "message",
"user": "U123",
"text": "Parent message",
"ts": "1234567890.123456"
},
{
"type": "message",
"user": "U456",
"text": "Reply 1",
"ts": "1234567891.123456",
"thread_ts": "1234567890.123456"
}
],
"has_more": false,
"response_metadata": {
"next_cursor": ""
}
}));
});
let client = ApiClient::new_with_base_url("test-token".to_string(), server.base_url());
let response = thread_get(
&client,
"C123456".to_string(),
"1234567890.123456".to_string(),
None,
None,
)
.await
.unwrap();
assert!(response.ok);
let messages = response.data.get("messages").unwrap().as_array().unwrap();
assert_eq!(messages.len(), 2);
assert_eq!(messages[0]["text"], "Parent message");
assert_eq!(messages[1]["text"], "Reply 1");
mock.assert();
}
#[tokio::test]
async fn test_thread_get_with_pagination() {
let server = MockServer::start();
let mock_page_1 = server.mock(|when, then| {
when.method(GET)
.path("/conversations.replies")
.query_param("channel", "C123456")
.query_param("ts", "1234567890.123456")
.query_param("limit", "2")
.query_param_missing("cursor");
then.status(200).json_body(json!({
"ok": true,
"messages": [
{"type": "message", "user": "U123", "text": "Message 1", "ts": "1234567890.123456"},
{"type": "message", "user": "U456", "text": "Message 2", "ts": "1234567891.123456"},
],
"has_more": true,
"response_metadata": {"next_cursor": "cursor-1"}
}));
});
let mock_page_2 = server.mock(|when, then| {
when.method(GET)
.path("/conversations.replies")
.query_param("channel", "C123456")
.query_param("ts", "1234567890.123456")
.query_param("limit", "2")
.query_param("cursor", "cursor-1");
then.status(200).json_body(json!({
"ok": true,
"messages": [
{"type": "message", "user": "U789", "text": "Message 3", "ts": "1234567892.123456"}
],
"has_more": false,
"response_metadata": {"next_cursor": ""}
}));
});
let client = ApiClient::new_with_base_url("test-token".to_string(), server.base_url());
let response = thread_get(
&client,
"C123456".to_string(),
"1234567890.123456".to_string(),
Some(2),
None,
)
.await
.unwrap();
assert_eq!(mock_page_1.calls(), 1);
assert_eq!(mock_page_2.calls(), 1);
assert!(response.ok);
let messages = response.data.get("messages").unwrap().as_array().unwrap();
assert_eq!(messages.len(), 3);
assert_eq!(messages[0]["text"], "Message 1");
assert_eq!(messages[1]["text"], "Message 2");
assert_eq!(messages[2]["text"], "Message 3");
let metadata = response.data.get("response_metadata").unwrap();
assert_eq!(metadata["next_cursor"], "");
}
#[tokio::test]
async fn test_thread_get_with_inclusive_param() {
let server = MockServer::start();
let mock = server.mock(|when, then| {
when.method(GET)
.path("/conversations.replies")
.header("Authorization", "Bearer test-token")
.query_param("channel", "C123456")
.query_param("ts", "1234567890.123456")
.query_param("limit", "100")
.query_param("inclusive", "true");
then.status(200)
.header("content-type", "application/json")
.json_body(json!({
"ok": true,
"messages": [
{
"type": "message",
"user": "U123",
"text": "Parent message",
"ts": "1234567890.123456"
}
],
"response_metadata": {
"next_cursor": ""
}
}));
});
let client = ApiClient::new_with_base_url("test-token".to_string(), server.base_url());
let response = thread_get(
&client,
"C123456".to_string(),
"1234567890.123456".to_string(),
None,
Some(true),
)
.await
.unwrap();
assert!(response.ok);
let messages = response.data.get("messages").unwrap().as_array().unwrap();
assert_eq!(messages.len(), 1);
mock.assert();
}