diff --git a/src/db/votes.rs b/src/db/votes.rs index cf4eec2..20bc5ea 100644 --- a/src/db/votes.rs +++ b/src/db/votes.rs @@ -80,7 +80,7 @@ mod tests { #[ignore] async fn get_all_by_account_id_ok() -> Result { let manager = Db::open_unittests().await?.votes().await?; - let mut vote = Vote::new(1, TankId(42), Rating::Like); + let mut vote = Vote::new(1, TankId(42), 1, Rating::Like); vote.timestamp = vote.timestamp.duration_round(Duration::seconds(1))?; manager.insert(&vote).await?; @@ -116,7 +116,7 @@ mod tests { #[ignore] async fn delete_vote_ok() -> Result { let manager = Db::open_unittests().await?.votes().await?; - let vote = Vote::new(1, TankId(42), Rating::Like); + let vote = Vote::new(1, TankId(42), 1, Rating::Like); manager.insert(&vote).await?; manager.delete(vote.id.account_id, vote.id.tank_id).await?; assert!( diff --git a/src/models/vote.rs b/src/models/vote.rs index f11ebde..011e3ed 100644 --- a/src/models/vote.rs +++ b/src/models/vote.rs @@ -33,15 +33,24 @@ pub struct Vote { deserialize_with = "Rating::deserialize" )] pub rating: Rating, + + #[serde(rename = "nb")] + pub n_battles: u32, } impl Vote { - pub fn new(account_id: impl Into, tank_id: TankId, rating: Rating) -> Self { + pub fn new( + account_id: impl Into, + tank_id: TankId, + n_battles: u32, + rating: Rating, + ) -> Self { Self { id: VoteId { account_id: account_id.into(), tank_id, }, + n_battles, rating, timestamp: Utc::now(), } diff --git a/src/web/state.rs b/src/web/state.rs index 573ef2b..07fed48 100644 --- a/src/web/state.rs +++ b/src/web/state.rs @@ -80,8 +80,7 @@ impl AppState { .get_vehicles_stats(account_id) .await? .into_iter() - .filter(VehicleStats::is_played) - .filter(|stats| is_known_tank_id(stats.tank_id)) + .filter(|stats| stats.inner.n_battles != 0 && is_known_tank_id(stats.tank_id)) .sorted_unstable_by(|lhs, rhs| rhs.last_battle_time.cmp(&lhs.last_battle_time)) .map(|stats| (stats.tank_id, stats)) .collect(); @@ -93,12 +92,12 @@ impl AppState { } #[instrument(skip_all, fields(account_id = %account_id, tank_id = %tank_id))] - pub async fn owns_vehicle(&self, account_id: AccountId, tank_id: TankId) -> Result { + pub async fn get_battle_count(&self, account_id: AccountId, tank_id: TankId) -> Result { Ok(self .get_vehicles_stats(account_id) .await? .get(&tank_id) - .is_some_and(VehicleStats::is_played)) + .map_or(0, |stats| stats.inner.n_battles)) } #[instrument(skip_all, fields(account_id = %account_id))] diff --git a/src/web/views/profile.rs b/src/web/views/profile.rs index 269d37f..d5c401a 100644 --- a/src/web/views/profile.rs +++ b/src/web/views/profile.rs @@ -127,15 +127,16 @@ async fn rate_vehicle( if params.account_id != user.account_id { return Err(WebError::Forbidden(ForbiddenReason::NonOwner)); } - if !state.owns_vehicle(user.account_id, params.tank_id).await? { + if state.get_battle_count(user.account_id, params.tank_id).await? == 0 { return Err(WebError::ImATeapot); } info!(?rating); if let Some(rating) = rating { + let n_battles = state.get_battle_count(user.account_id, params.tank_id).await?; state .vote_manager - .insert(&Vote::new(user.account_id, params.tank_id, rating)) + .insert(&Vote::new(user.account_id, params.tank_id, n_battles, rating)) .await?; } else { state.vote_manager.delete(user.account_id, params.tank_id).await?; diff --git a/src/wg.rs b/src/wg.rs index 26fddc8..f44f61a 100644 --- a/src/wg.rs +++ b/src/wg.rs @@ -197,10 +197,6 @@ pub struct VehicleStats { } impl VehicleStats { - pub const fn is_played(&self) -> bool { - self.inner.n_battles != 0 - } - /// Deserialize last battle time and take care of missing timestamps in the response. #[inline] fn deserialize_last_battle_time<'de, D: Deserializer<'de>>(