Add tests for response processing

This commit is contained in:
Maybe Waffle 2023-02-06 12:17:55 +04:00
parent 2221116d9c
commit 74e32a725d
2 changed files with 121 additions and 0 deletions

View file

@ -17,6 +17,7 @@ pub enum RequestError {
/// The group has been migrated to a supergroup with the specified
/// identifier.
#[error("The group has been migrated to a supergroup with ID #{0}")]
// FIXME: change to `ChatId` :|
MigrateToChatId(i64),
/// In case of exceeding flood control, the number of seconds left to wait

View file

@ -99,6 +99,13 @@ where
let text = response.text().await?;
deserialize_response(text)
}
fn deserialize_response<T>(text: String) -> Result<T, RequestError>
where
T: DeserializeOwned + 'static,
{
serde_json::from_str::<TelegramResponse<T>>(&text)
.map(|mut response| {
use crate::types::{Update, UpdateKind};
@ -152,3 +159,116 @@ where
.map_err(|source| RequestError::InvalidJson { source, raw: text.into() })?
.into()
}
#[cfg(test)]
mod tests {
use std::time::Duration;
use cool_asserts::assert_matches;
use crate::{
net::request::deserialize_response,
types::{True, Update, UpdateKind},
ApiError, RequestError,
};
#[test]
fn smoke_ok() {
let json = r#"{"ok":true,"result":true}"#.to_owned();
let res = deserialize_response::<True>(json);
assert_matches!(res, Ok(True));
}
#[test]
fn smoke_err() {
let json =
r#"{"ok":false,"description":"Forbidden: bot was blocked by the user"}"#.to_owned();
let res = deserialize_response::<True>(json);
assert_matches!(res, Err(RequestError::Api(ApiError::BotBlocked)));
}
#[test]
fn migrate() {
let json = r#"{"ok":false,"description":"this string is ignored","parameters":{"migrate_to_chat_id":123456}}"#.to_owned();
let res = deserialize_response::<True>(json);
assert_matches!(res, Err(RequestError::MigrateToChatId(123456)));
}
#[test]
fn retry_after() {
let json = r#"{"ok":false,"description":"this string is ignored","parameters":{"retry_after":123456}}"#.to_owned();
let res = deserialize_response::<True>(json);
assert_matches!(res, Err(RequestError::RetryAfter(duration)) if duration == Duration::from_secs(123456));
}
#[test]
fn update_ok() {
let json = r#"{
"ok":true,
"result":[
{
"update_id":0,
"poll_answer":{
"poll_id":"POLL_ID",
"user": {"id":42,"is_bot":false,"first_name":"blah"},
"option_ids": []
}
}
]
}"#
.to_owned();
let res = deserialize_response::<Vec<Update>>(json).unwrap();
assert_matches!(res, [Update { id: 0, kind: UpdateKind::PollAnswer(_) }]);
}
/// Check that `get_updates` can work with malformed updates.
#[test]
fn update_err() {
let json = r#"{
"ok":true,
"result":[
{
"update_id":0,
"poll_answer":{
"poll_id":"POLL_ID",
"user": {"id":42,"is_bot":false,"first_name":"blah"},
"option_ids": []
}
},
{
"update_id":1,
"something unknown to us":17
},
{
"update_id":2,
"poll_answer":{
"poll_id":"POLL_ID",
"user": {"id":42,"is_bot":false,"first_name":"blah"},
"option_ids": [3, 4, 8]
}
},
{
"update_id":3,
"message":{"some fields are missing":true}
}
]
}"#
.to_owned();
let res = deserialize_response::<Vec<Update>>(json).unwrap();
assert_matches!(
res,
[
Update { id: 0, kind: UpdateKind::PollAnswer(_) },
Update { id: 1, kind: UpdateKind::Error(v) } if v.is_object(),
Update { id: 2, kind: UpdateKind::PollAnswer(_) },
Update { id: 3, kind: UpdateKind::Error(v) } if v.is_object(),
]
);
}
}