use crate::common::actions::when;
use crate::common::assertions::{assert_msg_type, then};
use crate::common::cleanup::finally;
use crate::common::setup::{
LOGON_TIMEOUT, given_a_connected_session, given_a_connected_session_with_store,
};
use crate::common::test_messages::TestMessage;
use hotfix::session::Status;
use hotfix::store::MessageStore;
use hotfix::store::in_memory::InMemoryMessageStore;
use hotfix_message::fix44::MsgType;
use std::time::Duration;
#[tokio::test]
async fn test_happy_logon() {
let (mut session, mut mock_counterparty) = given_a_connected_session().await;
then(&mut mock_counterparty)
.receives(|msg| assert_msg_type(msg, MsgType::Logon))
.await;
then(&mut session)
.status_changes_to(Status::AwaitingLogon)
.await;
when(&mut mock_counterparty).sends_logon().await;
then(&mut session).status_changes_to(Status::Active).await;
finally(&session, &mut mock_counterparty).disconnect().await;
}
#[tokio::test]
async fn test_non_logon_response_to_logon() {
let (mut session, mut mock_counterparty) = given_a_connected_session().await;
then(&mut mock_counterparty)
.receives(|msg| assert_msg_type(msg, MsgType::Logon))
.await;
then(&mut session)
.status_changes_to(Status::AwaitingLogon)
.await;
let dummy_report = TestMessage::dummy_execution_report();
when(&mut mock_counterparty)
.sends_message(dummy_report)
.await;
then(&mut mock_counterparty).gets_disconnected().await;
}
#[tokio::test]
async fn test_logon_response_with_sequence_number_too_low() {
let mut message_store = InMemoryMessageStore::default();
message_store.set_target_seq_number(5).await.unwrap();
let (mut session, mut counterparty) = given_a_connected_session_with_store(message_store).await;
then(&mut counterparty)
.receives(|msg| assert_msg_type(msg, MsgType::Logon))
.await;
then(&mut session)
.status_changes_to(Status::AwaitingLogon)
.await;
when(&mut counterparty).sends_logon().await;
then(&mut counterparty)
.receives(|msg| assert_msg_type(msg, MsgType::Logout))
.await;
then(&mut counterparty).gets_disconnected().await;
}
#[tokio::test]
async fn test_logon_response_with_sequence_number_too_high() {
let (mut session, mut counterparty) = given_a_connected_session().await;
let dummy_report = TestMessage::dummy_execution_report();
when(&mut counterparty)
.has_previously_sent(dummy_report)
.await;
then(&mut counterparty)
.receives(|msg| assert_msg_type(msg, MsgType::Logon))
.await;
then(&mut session)
.status_changes_to(Status::AwaitingLogon)
.await;
when(&mut counterparty).sends_logon().await;
then(&mut session)
.status_changes_to(Status::AwaitingResend {
begin: 1,
end: 2,
attempts: 1,
})
.await;
then(&mut counterparty)
.receives(|msg| assert_msg_type(msg, MsgType::ResendRequest))
.await;
when(&mut counterparty).resends_message(1).await; when(&mut counterparty).sends_gap_fill(2, 3).await; then(&mut session).status_changes_to(Status::Active).await;
finally(&session, &mut counterparty).disconnect().await;
}
#[tokio::test(start_paused = true)]
async fn test_logon_timeout() {
let (mut session, mut counterparty) = given_a_connected_session().await;
then(&mut counterparty)
.receives(|msg| assert_msg_type(msg, MsgType::Logon))
.await;
then(&mut session)
.status_changes_to(Status::AwaitingLogon)
.await;
when(Duration::from_secs(LOGON_TIMEOUT)).elapses().await;
then(&mut counterparty).gets_disconnected().await;
}