adds basic resolve_claims + test

This commit is contained in:
2019-07-24 15:55:08 +02:00
parent 89172177eb
commit 7350d5222c
2 changed files with 74 additions and 36 deletions

View File

@@ -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,

View File

@@ -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 {