adds basic resolve_claims + test
This commit is contained in:
@@ -42,7 +42,7 @@ pub type ActionResult<R> = Result<R, diesel::result::Error>;
|
||||
/// x .sell_loot([players], [excluded_item_ids]) -> Success status (bool, player_share)
|
||||
/// // Claims should be resolved after a certain delay
|
||||
/// x .set_claims_timeout()
|
||||
/// x .resolve_claims()
|
||||
/// v .resolve_claims()
|
||||
/// v .add_player(player_data)
|
||||
/// ```
|
||||
///
|
||||
@@ -126,7 +126,7 @@ impl<'q> AsPlayer<'q> {
|
||||
/// # Panics
|
||||
///
|
||||
/// This currently panics if player wealth fails to be updated, as this is
|
||||
/// a serious error. TODO: handle deletion of bought item in case of wealth update failure.
|
||||
/// a serious error.
|
||||
pub fn buy<'a>(self, name: &'a str, price: i32) -> ActionResult<(i32, i32, i32, i32)> {
|
||||
self.conn.transaction(|| {
|
||||
let new_item = models::item::NewLoot::to_player(self.id, (name, price));
|
||||
@@ -146,31 +146,25 @@ impl<'q> AsPlayer<'q> {
|
||||
/// # Panics
|
||||
///
|
||||
/// This currently panics if player wealth fails to be updated, as this is
|
||||
/// a serious error. TODO: handle restoring of sold item in case of wealth update failure.
|
||||
/// a serious error.
|
||||
pub fn sell(
|
||||
self,
|
||||
loot_id: i32,
|
||||
_price_mod: Option<f32>,
|
||||
) -> ActionResult<(i32, i32, i32, i32)> {
|
||||
// Check that the item belongs to player
|
||||
let exists_and_owned: bool =
|
||||
diesel::select(models::Loot::owns(self.id, loot_id)).get_result(self.conn)?;
|
||||
if !exists_and_owned {
|
||||
return Err(diesel::result::Error::NotFound);
|
||||
}
|
||||
self.conn.transaction(|| {
|
||||
use schema::looted::dsl::*;
|
||||
let loot_value = looted
|
||||
let loot = looted
|
||||
.find(loot_id)
|
||||
.select(base_price)
|
||||
.first::<i32>(self.conn)?;
|
||||
let sell_value = (loot_value / 2) as f32;
|
||||
.first::<models::Loot>(self.conn)?;
|
||||
if loot.owner != self.id {
|
||||
// If the item does not belong to player,
|
||||
// it can't be what we're looking for
|
||||
return Err(diesel::result::Error::NotFound);
|
||||
}
|
||||
let sell_value = (loot.base_price / 2) as f32;
|
||||
let _deleted = diesel::delete(looted.find(loot_id))
|
||||
.execute(self.conn)
|
||||
.map(|rows_updated| match rows_updated {
|
||||
1 => (),
|
||||
_ => panic!("RuntimeError: Sell did not update DB as expected"),
|
||||
})?;
|
||||
.execute(self.conn)?;
|
||||
self.update_wealth(sell_value)
|
||||
})
|
||||
|
||||
@@ -271,10 +265,32 @@ impl<'q> AsAdmin<'q> {
|
||||
.grouped_by(&loot);
|
||||
// For each claimed item
|
||||
let data = loot.into_iter().zip(claims).collect::<Vec<_>>();
|
||||
dbg!(data);
|
||||
// If mutiples claims -> find highest resolve, give to this player
|
||||
// If only one claim -> give to claiming
|
||||
Err(diesel::result::Error::NotFound)
|
||||
dbg!(&data);
|
||||
|
||||
for (loot, claims) in data {
|
||||
match claims.len() {
|
||||
1 => {
|
||||
let claim = claims.get(0).unwrap();
|
||||
let player_id = claim.player_id;
|
||||
self.0.transaction(|| {
|
||||
use schema::looted::dsl::*;
|
||||
diesel::update(looted.find(claim.loot_id))
|
||||
.set(owner_id.eq(player_id))
|
||||
.execute(self.0)?;
|
||||
diesel::delete(schema::claims::table.find(claim.id))
|
||||
.execute(self.0)?;
|
||||
{
|
||||
use schema::players::dsl::*;
|
||||
diesel::update(players.find(player_id))
|
||||
.set(debt.eq(debt + (loot.base_price / 2)))
|
||||
.execute(self.0)
|
||||
}
|
||||
})?;
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,7 +320,7 @@ mod tests {
|
||||
/// When migrations are run, a special player with id 0 and name "Groupe"
|
||||
/// must be created.
|
||||
#[test]
|
||||
fn test_group_is_autocreated() {
|
||||
fn global_group_is_autocreated() {
|
||||
let conn = test_connection();
|
||||
let players = DbApi::with_conn(&conn).fetch_players().unwrap();
|
||||
assert_eq!(players.len(), 1);
|
||||
@@ -316,7 +332,7 @@ mod tests {
|
||||
/// When a player updates wealth, a difference is returned by API.
|
||||
/// Added to the previous amount of coins, it should equal the updated weath.
|
||||
#[test]
|
||||
fn test_player_updates_wealth() {
|
||||
fn as_player_updates_wealth() {
|
||||
let conn = test_connection();
|
||||
DbApi::with_conn(&conn)
|
||||
.as_admin()
|
||||
@@ -339,7 +355,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_admin_add_player() {
|
||||
fn as_admin_add_player() {
|
||||
let conn = test_connection();
|
||||
let result = DbApi::with_conn(&conn)
|
||||
.as_admin()
|
||||
@@ -356,15 +372,35 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_admin_resolve_claims() {
|
||||
fn as_admin_resolve_claims() {
|
||||
let conn = test_connection();
|
||||
let claims = DbApi::with_conn(&conn).fetch_claims().unwrap();
|
||||
assert_eq!(claims.len(), 0);
|
||||
assert_eq!(true, false); // Failing as test is not complete
|
||||
|
||||
// Add items
|
||||
assert_eq!(DbApi::with_conn(&conn).as_admin().add_loot(vec![
|
||||
("Épée", 40),
|
||||
("Arc", 40),
|
||||
]).is_ok(), true);
|
||||
// Add players
|
||||
DbApi::with_conn(&conn).as_admin().add_player("Player1".to_string(), 0.0).unwrap();
|
||||
DbApi::with_conn(&conn).as_admin().add_player("Player2".to_string(), 0.0).unwrap();
|
||||
// Put claims on one different item each
|
||||
DbApi::with_conn(&conn).as_player(1).claim(1).unwrap();
|
||||
DbApi::with_conn(&conn).as_player(2).claim(2).unwrap();
|
||||
let result = DbApi::with_conn(&conn).as_admin().resolve_claims();
|
||||
assert_eq!(result.is_ok(), true);
|
||||
// Check that both players received an item
|
||||
let players = DbApi::with_conn(&conn).fetch_players().unwrap();
|
||||
for &i in [1, 2].into_iter() {
|
||||
assert_eq!(DbApi::with_conn(&conn).as_player(i).loot().unwrap().len(), 1);
|
||||
let player = players.get(i as usize).unwrap();
|
||||
assert_eq!(player.debt, 20);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_player_claim_item() {
|
||||
fn as_player_claim_item() {
|
||||
let conn = test_connection();
|
||||
DbApi::with_conn(&conn)
|
||||
.as_admin()
|
||||
@@ -388,7 +424,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_player_unclaim_item() {
|
||||
fn as_player_unclaim_item() {
|
||||
let conn = test_connection();
|
||||
DbApi::with_conn(&conn)
|
||||
.as_admin()
|
||||
@@ -418,8 +454,9 @@ mod tests {
|
||||
///
|
||||
/// Checks that player's chest and wealth are updated.
|
||||
/// Checks that items are sold at half their value.
|
||||
/// Checks that a player cannot sell item he does not own.
|
||||
#[test]
|
||||
fn test_buy_sell_simple() {
|
||||
fn as_player_simple_buy_sell() {
|
||||
let conn = test_connection();
|
||||
DbApi::with_conn(&conn)
|
||||
.as_admin()
|
||||
@@ -438,10 +475,11 @@ mod tests {
|
||||
let players = DbApi::with_conn(&conn).fetch_players().unwrap();
|
||||
let player = players.get(1).unwrap();
|
||||
assert_eq!(player.pp, 2);
|
||||
// A player cannot sell loot from an other's chest
|
||||
let result = DbApi::with_conn(&conn).as_player(0).sell(loot.id, None);
|
||||
assert_eq!(result.is_ok(), false);
|
||||
// Sell back
|
||||
let sold = DbApi::with_conn(&conn)
|
||||
.as_player(1)
|
||||
.sell(loot.id, None);
|
||||
let sold = DbApi::with_conn(&conn).as_player(1).sell(loot.id, None);
|
||||
assert_eq!(sold.ok(), Some((0, 0, 0, 4)));
|
||||
let chest = DbApi::with_conn(&conn).as_player(1).loot().unwrap();
|
||||
assert_eq!(chest.len(), 0);
|
||||
@@ -451,7 +489,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_admin_add_loot() {
|
||||
fn as_admin_add_loot() {
|
||||
let conn = test_connection();
|
||||
assert_eq!(
|
||||
0,
|
||||
|
||||
@@ -35,8 +35,8 @@ type OwnedLoot = Filter<looted::table, WithOwner>;
|
||||
pub(crate) struct Loot {
|
||||
id: i32,
|
||||
name: String,
|
||||
base_price: i32,
|
||||
owner: i32,
|
||||
pub(crate) base_price: i32,
|
||||
pub(crate) owner: i32,
|
||||
}
|
||||
|
||||
impl Loot {
|
||||
|
||||
Reference in New Issue
Block a user