tests for bidding when auction is expired
This commit is contained in:
@@ -6,6 +6,7 @@ use crate::{
|
|||||||
App, BotError, BotResult, RootDialogue,
|
App, BotError, BotResult, RootDialogue,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
|
use chrono::Utc;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use teloxide::types::*;
|
use teloxide::types::*;
|
||||||
@@ -84,9 +85,14 @@ pub async fn handle_awaiting_confirm_bid_amount_callback(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if listing.base.ends_at < Utc::now() {
|
||||||
|
return app
|
||||||
|
.send_message(MessageType::BidInvalidListingExpired { listing, buyer })
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
let bid = NewBid::new_basic(listing.persisted.id, buyer.persisted.id, bid_amount);
|
let bid = NewBid::new_basic(listing.persisted.id, buyer.persisted.id, bid_amount);
|
||||||
let bid = app.daos.bid.insert_bid(&bid).await?;
|
let bid = app.daos.bid.insert_bid(&bid).await?;
|
||||||
|
|
||||||
dialogue.exit().await.context("failed to exit dialogue")?;
|
dialogue.exit().await.context("failed to exit dialogue")?;
|
||||||
|
|
||||||
app.send_message(MessageType::BidHasBeenConfirmedForBuyer {
|
app.send_message(MessageType::BidHasBeenConfirmedForBuyer {
|
||||||
@@ -132,12 +138,22 @@ pub async fn handle_awaiting_confirm_bid_amount_callback(
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{db::DAOs, message_sender::MockMessageSender, test_utils::*};
|
use crate::{db::DAOs, message_sender::MockMessageSender, test_utils::*};
|
||||||
use dptree::{deps, di::Injectable};
|
use chrono::{Duration, Utc};
|
||||||
|
use dptree::{
|
||||||
|
deps,
|
||||||
|
di::{DependencyMap, Injectable},
|
||||||
|
};
|
||||||
use mockall::predicate::function;
|
use mockall::predicate::function;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[tokio::test]
|
struct Fixtures {
|
||||||
async fn test_confirm_bid_amount() {
|
deps: DependencyMap,
|
||||||
|
seller: PersistedUser,
|
||||||
|
buyer: PersistedUser,
|
||||||
|
prev_buyer: PersistedUser,
|
||||||
|
listing: PersistedListing,
|
||||||
|
}
|
||||||
|
async fn set_up_fixtures() -> Fixtures {
|
||||||
let deps = create_deps().await;
|
let deps = create_deps().await;
|
||||||
let seller = with_test_user(&deps, |seller| {
|
let seller = with_test_user(&deps, |seller| {
|
||||||
seller.username = Some("seller".to_string());
|
seller.username = Some("seller".to_string());
|
||||||
@@ -155,6 +171,77 @@ mod tests {
|
|||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
let listing = with_test_listing(&deps, &seller, |_| {}).await;
|
let listing = with_test_listing(&deps, &seller, |_| {}).await;
|
||||||
|
Fixtures {
|
||||||
|
deps,
|
||||||
|
seller,
|
||||||
|
buyer,
|
||||||
|
prev_buyer,
|
||||||
|
listing,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_confirm_bid_with_expired_listing() {
|
||||||
|
let Fixtures {
|
||||||
|
deps,
|
||||||
|
buyer,
|
||||||
|
mut listing,
|
||||||
|
..
|
||||||
|
} = set_up_fixtures().await;
|
||||||
|
|
||||||
|
// listing has already expired
|
||||||
|
listing.base.ends_at = Utc::now() - Duration::days(1);
|
||||||
|
let listing = deps
|
||||||
|
.get::<DAOs>()
|
||||||
|
.listing
|
||||||
|
.update_listing(&listing)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let cb_query = create_tele_callback_query(
|
||||||
|
"confirm_bid",
|
||||||
|
create_tele_user(|user| user.id = buyer.telegram_id.into()),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut message_sender = MockMessageSender::new();
|
||||||
|
{
|
||||||
|
let l = listing.clone();
|
||||||
|
let b = buyer.clone();
|
||||||
|
message_sender
|
||||||
|
.expect_send_message()
|
||||||
|
.once()
|
||||||
|
.with(function(move |m| match m {
|
||||||
|
MessageType::BidInvalidListingExpired { listing, buyer } => {
|
||||||
|
assert_eq!(listing, &l);
|
||||||
|
assert_eq!(buyer, &b);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}))
|
||||||
|
.returning(|_| Ok(()));
|
||||||
|
}
|
||||||
|
let deps = with_message_sender(deps, message_sender).await;
|
||||||
|
|
||||||
|
let mut deps = with_dialogue(deps, &buyer).await;
|
||||||
|
deps.insert_container(deps![
|
||||||
|
listing,
|
||||||
|
cb_query,
|
||||||
|
buyer,
|
||||||
|
MoneyAmount::from_str("100.00").unwrap()
|
||||||
|
]);
|
||||||
|
let ret = handle_awaiting_confirm_bid_amount_callback.inject(&deps)().await;
|
||||||
|
assert!(ret.is_ok(), "{ret:?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_confirm_bid_amount() {
|
||||||
|
let Fixtures {
|
||||||
|
deps,
|
||||||
|
seller,
|
||||||
|
buyer,
|
||||||
|
prev_buyer,
|
||||||
|
listing,
|
||||||
|
} = set_up_fixtures().await;
|
||||||
|
|
||||||
deps.get::<DAOs>()
|
deps.get::<DAOs>()
|
||||||
.bid
|
.bid
|
||||||
|
|||||||
@@ -103,6 +103,10 @@ impl MessageSender for BotMessageSender {
|
|||||||
MessageType::BidHasBeenConfirmedForBuyer { listing, bid } => {
|
MessageType::BidHasBeenConfirmedForBuyer { listing, bid } => {
|
||||||
self.send_bid_has_been_confirmed(listing, bid).await?;
|
self.send_bid_has_been_confirmed(listing, bid).await?;
|
||||||
}
|
}
|
||||||
|
MessageType::BidInvalidListingExpired { listing, buyer } => {
|
||||||
|
self.send_bid_invalid_listing_expired(listing, buyer)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -165,4 +169,20 @@ impl BotMessageSender {
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn send_bid_invalid_listing_expired(
|
||||||
|
&self,
|
||||||
|
listing: PersistedListing,
|
||||||
|
buyer: PersistedUser,
|
||||||
|
) -> BotResult {
|
||||||
|
self.with_target(buyer.into())
|
||||||
|
.send_html_message(
|
||||||
|
format!(
|
||||||
|
"Auction <b>{title}</b> has already ended",
|
||||||
|
title = listing.base.title
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ pub async fn enter_edit_listing_draft(
|
|||||||
async fn save_listing(listing_dao: &ListingDAO, draft: ListingDraft) -> BotResult<String> {
|
async fn save_listing(listing_dao: &ListingDAO, draft: ListingDraft) -> BotResult<String> {
|
||||||
let (listing, success_message) = if let Some(fields) = draft.persisted {
|
let (listing, success_message) = if let Some(fields) = draft.persisted {
|
||||||
let listing = listing_dao
|
let listing = listing_dao
|
||||||
.update_listing(PersistedListing {
|
.update_listing(&PersistedListing {
|
||||||
persisted: fields,
|
persisted: fields,
|
||||||
base: draft.base,
|
base: draft.base,
|
||||||
fields: draft.fields,
|
fields: draft.fields,
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ impl ListingDAO {
|
|||||||
Ok(FromRow::from_row(&row)?)
|
Ok(FromRow::from_row(&row)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_listing(&self, listing: PersistedListing) -> Result<PersistedListing> {
|
pub async fn update_listing(&self, listing: &PersistedListing) -> Result<PersistedListing> {
|
||||||
let now = Utc::now();
|
let now = Utc::now();
|
||||||
let binds = binds_for_listing(&listing).push("updated_at", &now);
|
let binds = binds_for_listing(&listing).push("updated_at", &now);
|
||||||
|
|
||||||
@@ -123,6 +123,8 @@ fn binds_for_base(base: &ListingBase) -> BindFields {
|
|||||||
.push("title", &base.title)
|
.push("title", &base.title)
|
||||||
.push("description", &base.description)
|
.push("description", &base.description)
|
||||||
.push("currency_type", &base.currency_type)
|
.push("currency_type", &base.currency_type)
|
||||||
|
.push("starts_at", &base.starts_at)
|
||||||
|
.push("ends_at", &base.ends_at)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn binds_for_fields(fields: &ListingFields) -> BindFields {
|
fn binds_for_fields(fields: &ListingFields) -> BindFields {
|
||||||
|
|||||||
@@ -16,4 +16,8 @@ pub enum MessageType {
|
|||||||
listing: PersistedListing,
|
listing: PersistedListing,
|
||||||
bid: PersistedBid,
|
bid: PersistedBid,
|
||||||
},
|
},
|
||||||
|
BidInvalidListingExpired {
|
||||||
|
listing: PersistedListing,
|
||||||
|
buyer: PersistedUser,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user