add planned mod
This commit is contained in:
76
src/model/planned/trip/create.rs
Normal file
76
src/model/planned/trip/create.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
use super::Trip;
|
||||
use crate::model::{
|
||||
notification::Notification,
|
||||
planned::{tripdetails::TripDetails, triptype::TripType},
|
||||
user::{ErgoUser, SteeringUser, User},
|
||||
};
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
impl Trip {
|
||||
/// Cox decides to create own trip.
|
||||
pub async fn new_own(db: &SqlitePool, cox: &SteeringUser, trip_details: TripDetails) {
|
||||
Self::perform_new(db, &cox.user, trip_details).await
|
||||
}
|
||||
|
||||
/// ErgoUser decides to create ergo 'trip'. Returns false, if trip is not a ergo-session (and
|
||||
/// thus User is not allowed to create such a trip)
|
||||
pub async fn new_own_ergo(db: &SqlitePool, ergo: &ErgoUser, trip_details: TripDetails) -> bool {
|
||||
if let Some(typ) = trip_details.triptype(db).await {
|
||||
let allowed_type = TripType::find_by_id(db, 4).await.unwrap();
|
||||
if typ == allowed_type {
|
||||
Self::perform_new(db, &ergo.user, trip_details).await;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
async fn perform_new(db: &SqlitePool, user: &User, trip_details: TripDetails) {
|
||||
let _ = sqlx::query!(
|
||||
"INSERT INTO trip (cox_id, trip_details_id) VALUES(?, ?)",
|
||||
user.id,
|
||||
trip_details.id
|
||||
)
|
||||
.execute(db)
|
||||
.await;
|
||||
|
||||
Self::notify_trips_same_datetime(db, trip_details, user).await;
|
||||
}
|
||||
|
||||
async fn notify_trips_same_datetime(db: &SqlitePool, trip_details: TripDetails, user: &User) {
|
||||
let same_starting_datetime = TripDetails::find_by_startingdatetime(
|
||||
db,
|
||||
trip_details.day,
|
||||
trip_details.planned_starting_time,
|
||||
)
|
||||
.await;
|
||||
|
||||
for notify in same_starting_datetime {
|
||||
// don't notify oneself
|
||||
if notify.id == trip_details.id {
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't notify people who have cancelled their trip
|
||||
if notify.cancelled() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(trip) = Trip::find_by_trip_details(db, notify.id).await {
|
||||
let user_earlier_trip = User::find_by_id(db, trip.cox_id as i32).await.unwrap();
|
||||
Notification::create(
|
||||
db,
|
||||
&user_earlier_trip,
|
||||
&format!(
|
||||
"{user} hat eine Ausfahrt zur selben Zeit ({} um {}) wie du erstellt",
|
||||
trip.day, trip.planned_starting_time
|
||||
),
|
||||
"Neue Ausfahrt zur selben Zeit",
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
697
src/model/planned/trip/mod.rs
Normal file
697
src/model/planned/trip/mod.rs
Normal file
@@ -0,0 +1,697 @@
|
||||
use chrono::{Local, NaiveDate};
|
||||
use serde::Serialize;
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
mod create;
|
||||
|
||||
use super::{
|
||||
event::{Event, Registration},
|
||||
tripdetails::TripDetails,
|
||||
triptype::TripType,
|
||||
usertrip::UserTrip,
|
||||
};
|
||||
use crate::model::{
|
||||
log::Log,
|
||||
notification::Notification,
|
||||
user::{SteeringUser, User},
|
||||
};
|
||||
|
||||
#[derive(Serialize, Clone, Debug)]
|
||||
pub struct Trip {
|
||||
pub id: i64,
|
||||
pub cox_id: i64,
|
||||
pub cox_name: String,
|
||||
trip_details_id: Option<i64>,
|
||||
pub planned_starting_time: String,
|
||||
pub max_people: i64,
|
||||
pub day: String,
|
||||
pub notes: Option<String>,
|
||||
pub allow_guests: bool,
|
||||
trip_type_id: Option<i64>,
|
||||
always_show: bool,
|
||||
is_locked: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
pub struct TripWithDetails {
|
||||
#[serde(flatten)]
|
||||
pub trip: Trip,
|
||||
pub rower: Vec<Registration>,
|
||||
trip_type: Option<TripType>,
|
||||
cancelled: bool,
|
||||
}
|
||||
|
||||
pub struct TripUpdate<'a> {
|
||||
pub cox: &'a User,
|
||||
pub trip: &'a Trip,
|
||||
pub max_people: i32,
|
||||
pub notes: Option<&'a str>,
|
||||
pub trip_type: Option<i64>, //TODO: Move to `TripType`
|
||||
pub is_locked: bool,
|
||||
}
|
||||
|
||||
impl TripUpdate<'_> {
|
||||
fn cancelled(&self) -> bool {
|
||||
self.max_people == -1
|
||||
}
|
||||
}
|
||||
|
||||
impl TripWithDetails {
|
||||
pub async fn from(db: &SqlitePool, trip: Trip) -> Self {
|
||||
let mut trip_type = None;
|
||||
if let Some(trip_type_id) = trip.trip_type_id {
|
||||
trip_type = TripType::find_by_id(db, trip_type_id).await;
|
||||
}
|
||||
Self {
|
||||
rower: Registration::all_rower(db, trip.trip_details_id.unwrap()).await,
|
||||
trip_type,
|
||||
cancelled: trip.is_cancelled(),
|
||||
trip,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Trip {
|
||||
pub async fn find_by_trip_details(db: &SqlitePool, tripdetails_id: i64) -> Option<Self> {
|
||||
sqlx::query_as!(
|
||||
Self,
|
||||
"
|
||||
SELECT trip.id, cox_id, user.name as cox_name, trip_details_id, planned_starting_time, max_people, day, trip_details.notes, allow_guests, trip_type_id, always_show, is_locked
|
||||
FROM trip
|
||||
INNER JOIN trip_details ON trip.trip_details_id = trip_details.id
|
||||
INNER JOIN user ON trip.cox_id = user.id
|
||||
WHERE trip_details.id=?
|
||||
",
|
||||
tripdetails_id
|
||||
)
|
||||
.fetch_one(db)
|
||||
.await
|
||||
.ok()
|
||||
}
|
||||
|
||||
pub(crate) async fn trip_type(&self, db: &SqlitePool) -> Option<TripType> {
|
||||
if let Some(trip_type_id) = self.trip_type_id {
|
||||
TripType::find_by_id(db, trip_type_id).await
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn all(db: &SqlitePool) -> Vec<Self> {
|
||||
sqlx::query_as!(
|
||||
Self,
|
||||
"
|
||||
SELECT trip.id, cox_id, user.name as cox_name, trip_details_id, planned_starting_time, max_people, day, trip_details.notes, allow_guests, trip_type_id, always_show, is_locked
|
||||
FROM trip
|
||||
INNER JOIN trip_details ON trip.trip_details_id = trip_details.id
|
||||
INNER JOIN user ON trip.cox_id = user.id
|
||||
",
|
||||
)
|
||||
.fetch_all(db)
|
||||
.await
|
||||
.unwrap() //TODO: fixme
|
||||
}
|
||||
|
||||
pub async fn all_with_user(db: &SqlitePool, user: &User) -> Vec<Self> {
|
||||
let mut ret = Vec::new();
|
||||
let trips = Self::all(db).await;
|
||||
for trip in trips {
|
||||
if user.id == trip.cox_id {
|
||||
ret.push(trip.clone());
|
||||
}
|
||||
if let Some(trip_details_id) = trip.trip_details_id {
|
||||
if UserTrip::find_by_userid_and_trip_detail_id(db, user.id, trip_details_id)
|
||||
.await
|
||||
.is_some()
|
||||
{
|
||||
ret.push(trip);
|
||||
}
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
pub async fn find_by_id(db: &SqlitePool, id: i64) -> Option<Self> {
|
||||
sqlx::query_as!(
|
||||
Self,
|
||||
"
|
||||
SELECT trip.id, cox_id, user.name as cox_name, trip_details_id, planned_starting_time, max_people, day, trip_details.notes, allow_guests, trip_type_id, always_show, is_locked
|
||||
FROM trip
|
||||
INNER JOIN trip_details ON trip.trip_details_id = trip_details.id
|
||||
INNER JOIN user ON trip.cox_id = user.id
|
||||
WHERE trip.id=?
|
||||
",
|
||||
id
|
||||
)
|
||||
.fetch_one(db)
|
||||
.await
|
||||
.ok()
|
||||
}
|
||||
|
||||
/// Cox decides to help in a event.
|
||||
pub async fn new_join(
|
||||
db: &SqlitePool,
|
||||
cox: &SteeringUser,
|
||||
event: &Event,
|
||||
) -> Result<(), CoxHelpError> {
|
||||
if event.is_rower_registered(db, cox).await {
|
||||
return Err(CoxHelpError::AlreadyRegisteredAsRower);
|
||||
}
|
||||
|
||||
if event.trip_details(db).await.is_locked {
|
||||
return Err(CoxHelpError::DetailsLocked);
|
||||
}
|
||||
|
||||
if event.is_cancelled() {
|
||||
return Err(CoxHelpError::CanceledEvent);
|
||||
}
|
||||
|
||||
match sqlx::query!(
|
||||
"INSERT INTO trip (cox_id, planned_event_id) VALUES(?, ?)",
|
||||
cox.id,
|
||||
event.id
|
||||
)
|
||||
.execute(db)
|
||||
.await
|
||||
{
|
||||
Ok(_) => Ok(()),
|
||||
Err(_) => Err(CoxHelpError::AlreadyRegisteredAsCox),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_for_today(db: &SqlitePool) -> Vec<TripWithDetails> {
|
||||
let today = Local::now().date_naive();
|
||||
Self::get_for_day(db, today).await
|
||||
}
|
||||
|
||||
pub async fn get_for_day(db: &SqlitePool, day: NaiveDate) -> Vec<TripWithDetails> {
|
||||
let day = format!("{day}");
|
||||
let trips = sqlx::query_as!(
|
||||
Trip,
|
||||
"
|
||||
SELECT trip.id, cox_id, user.name as cox_name, trip_details_id, planned_starting_time, max_people, day, trip_details.notes, allow_guests, trip_type_id, always_show, is_locked
|
||||
FROM trip
|
||||
INNER JOIN trip_details ON trip.trip_details_id = trip_details.id
|
||||
INNER JOIN user ON trip.cox_id = user.id
|
||||
WHERE day=?
|
||||
",
|
||||
day
|
||||
)
|
||||
.fetch_all(db)
|
||||
.await
|
||||
.unwrap(); //Okay, as Trip can only be created with proper DB backing
|
||||
|
||||
let mut ret = Vec::new();
|
||||
for trip in trips {
|
||||
ret.push(TripWithDetails::from(db, trip).await);
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
/// Cox decides to update own trip.
|
||||
pub async fn update_own(
|
||||
db: &SqlitePool,
|
||||
update: &TripUpdate<'_>,
|
||||
) -> Result<(), TripUpdateError> {
|
||||
if !update.trip.is_trip_from_user(update.cox.id) {
|
||||
return Err(TripUpdateError::NotYourTrip);
|
||||
}
|
||||
|
||||
if update.trip_type != Some(4) && !update.cox.allowed_to_steer(db).await {
|
||||
return Err(TripUpdateError::TripTypeNotAllowed);
|
||||
}
|
||||
|
||||
let Some(trip_details_id) = update.trip.trip_details_id else {
|
||||
return Err(TripUpdateError::TripDetailsDoesNotExist); //TODO: Remove?
|
||||
};
|
||||
|
||||
let tripdetails = TripDetails::find_by_id(db, trip_details_id).await.unwrap();
|
||||
let was_already_cancelled = tripdetails.cancelled();
|
||||
|
||||
let is_locked = if update.cancelled() {
|
||||
false
|
||||
} else {
|
||||
update.is_locked
|
||||
};
|
||||
|
||||
sqlx::query!(
|
||||
"UPDATE trip_details SET max_people = ?, notes = ?, trip_type_id = ?, is_locked = ? WHERE id = ?",
|
||||
update.max_people,
|
||||
update.notes,
|
||||
update.trip_type,
|
||||
is_locked,
|
||||
trip_details_id
|
||||
)
|
||||
.execute(db)
|
||||
.await
|
||||
.unwrap(); //Okay, as trip_details can only be created with proper DB backing
|
||||
|
||||
if update.cancelled() && !was_already_cancelled {
|
||||
let rowers = TripWithDetails::from(db, update.trip.clone()).await.rower;
|
||||
for user in rowers {
|
||||
if let Some(user) = User::find_by_name(db, &user.name).await {
|
||||
let notes = match update.notes {
|
||||
Some(n) if !n.is_empty() => format!("Grund der Absage: {n}"),
|
||||
_ => String::from(""),
|
||||
};
|
||||
|
||||
Notification::create(
|
||||
db,
|
||||
&user,
|
||||
&format!(
|
||||
"Die Ausfahrt von {} am {} um {} wurde abgesagt. {} Bitte gib Bescheid, dass du die Info erhalten hast indem du auf ✓ klickst.",
|
||||
update.cox.name,
|
||||
update.trip.day,
|
||||
update.trip.planned_starting_time,
|
||||
notes
|
||||
),
|
||||
"Absage Ausfahrt",
|
||||
None,
|
||||
Some(&format!(
|
||||
"remove_user_trip_with_trip_details_id:{}",
|
||||
trip_details_id
|
||||
)),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Notification::delete_by_action(
|
||||
db,
|
||||
&format!("remove_user_trip_with_trip_details_id:{}", trip_details_id),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
if !update.cancelled() && was_already_cancelled {
|
||||
Notification::delete_by_action(
|
||||
db,
|
||||
&format!("remove_user_trip_with_trip_details_id:{}", trip_details_id),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
let trip_details = TripDetails::find_by_id(db, trip_details_id).await.unwrap();
|
||||
trip_details.check_free_spaces(db).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn trip_details(&self, db: &SqlitePool) -> Option<TripDetails> {
|
||||
if let Some(trip_details_id) = self.trip_type_id {
|
||||
return TripDetails::find_by_id(db, trip_details_id).await;
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub async fn delete_by_planned_event(
|
||||
db: &SqlitePool,
|
||||
cox: &SteeringUser,
|
||||
event: &Event,
|
||||
) -> Result<(), TripHelpDeleteError> {
|
||||
if event.trip_details(db).await.is_locked {
|
||||
return Err(TripHelpDeleteError::DetailsLocked);
|
||||
}
|
||||
|
||||
let affected_rows = sqlx::query!(
|
||||
"DELETE FROM trip WHERE cox_id = ? AND planned_event_id = ?",
|
||||
cox.id,
|
||||
event.id
|
||||
)
|
||||
.execute(db)
|
||||
.await
|
||||
.unwrap()
|
||||
.rows_affected();
|
||||
|
||||
if affected_rows == 0 {
|
||||
return Err(TripHelpDeleteError::CoxNotHelping);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn delete(&self, db: &SqlitePool, user: &User) -> Result<(), TripDeleteError> {
|
||||
let registered_rower = Registration::all_rower(db, self.trip_details_id.unwrap()).await;
|
||||
if !registered_rower.is_empty() {
|
||||
return Err(TripDeleteError::SomebodyAlreadyRegistered);
|
||||
}
|
||||
|
||||
if !self.is_trip_from_user(user.id) && !user.has_role(db, "admin").await {
|
||||
return Err(TripDeleteError::NotYourTrip);
|
||||
}
|
||||
|
||||
Log::create(db, format!("{} deleted trip: {:#?}", user.name, self)).await;
|
||||
|
||||
sqlx::query!("DELETE FROM trip WHERE id = ?", self.id)
|
||||
.execute(db)
|
||||
.await
|
||||
.unwrap(); //TODO: fixme
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_trip_from_user(&self, user_id: i64) -> bool {
|
||||
self.cox_id == user_id
|
||||
}
|
||||
|
||||
pub(crate) async fn toggle_always_show(&self, db: &SqlitePool) {
|
||||
if let Some(trip_details) = self.trip_details_id {
|
||||
let new_state = !self.always_show;
|
||||
sqlx::query!(
|
||||
"UPDATE trip_details SET always_show = ? WHERE id = ?",
|
||||
new_state,
|
||||
trip_details
|
||||
)
|
||||
.execute(db)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn get_pinned_for_day(
|
||||
db: &sqlx::Pool<sqlx::Sqlite>,
|
||||
day: NaiveDate,
|
||||
) -> Vec<TripWithDetails> {
|
||||
let mut trips = Self::get_for_day(db, day).await;
|
||||
trips.retain(|e| e.trip.always_show);
|
||||
trips
|
||||
}
|
||||
|
||||
pub(crate) fn is_cancelled(&self) -> bool {
|
||||
self.max_people == -1
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CoxHelpError {
|
||||
AlreadyRegisteredAsRower,
|
||||
AlreadyRegisteredAsCox,
|
||||
DetailsLocked,
|
||||
CanceledEvent,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum TripHelpDeleteError {
|
||||
DetailsLocked,
|
||||
CoxNotHelping,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum TripDeleteError {
|
||||
SomebodyAlreadyRegistered,
|
||||
NotYourTrip,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TripUpdateError {
|
||||
NotYourTrip,
|
||||
TripDetailsDoesNotExist,
|
||||
TripTypeNotAllowed,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::{
|
||||
model::{
|
||||
notification::Notification,
|
||||
planned::{
|
||||
event::Event,
|
||||
trip::{self, TripDeleteError},
|
||||
tripdetails::TripDetails,
|
||||
usertrip::UserTrip,
|
||||
},
|
||||
user::{SteeringUser, User},
|
||||
},
|
||||
testdb,
|
||||
};
|
||||
|
||||
use chrono::Local;
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
use super::Trip;
|
||||
|
||||
#[sqlx::test]
|
||||
fn test_new_own() {
|
||||
let pool = testdb!();
|
||||
|
||||
let cox = SteeringUser::new(
|
||||
&pool,
|
||||
&User::find_by_name(&pool, "cox".into()).await.unwrap(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let trip_details = TripDetails::find_by_id(&pool, 1).await.unwrap();
|
||||
|
||||
Trip::new_own(&pool, &cox, trip_details).await;
|
||||
|
||||
assert!(Trip::find_by_id(&pool, 1).await.is_some());
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
fn test_notification_cox_if_same_datetime() {
|
||||
let pool = testdb!();
|
||||
let cox = SteeringUser::new(
|
||||
&pool,
|
||||
&User::find_by_name(&pool, "cox".into()).await.unwrap(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let trip_details = TripDetails::find_by_id(&pool, 1).await.unwrap();
|
||||
Trip::new_own(&pool, &cox, trip_details).await;
|
||||
|
||||
let cox2 = SteeringUser::new(
|
||||
&pool,
|
||||
&User::find_by_name(&pool, "cox2".into()).await.unwrap(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let trip_details = TripDetails::find_by_id(&pool, 3).await.unwrap();
|
||||
Trip::new_own(&pool, &cox2, trip_details).await;
|
||||
|
||||
let last_notification = &Notification::for_user(&pool, &cox).await[0];
|
||||
|
||||
assert!(
|
||||
last_notification
|
||||
.message
|
||||
.starts_with("cox2 hat eine Ausfahrt zur selben Zeit")
|
||||
);
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
fn test_get_day_cox_trip() {
|
||||
let pool = testdb!();
|
||||
|
||||
let tomorrow = Local::now().date_naive() + chrono::Duration::days(1);
|
||||
let res = Trip::get_for_day(&pool, tomorrow).await;
|
||||
assert_eq!(res.len(), 1);
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
fn test_new_succ_join() {
|
||||
let pool = testdb!();
|
||||
|
||||
let cox = SteeringUser::new(
|
||||
&pool,
|
||||
&User::find_by_name(&pool, "cox2".into()).await.unwrap(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let planned_event = Event::find_by_id(&pool, 1).await.unwrap();
|
||||
|
||||
assert!(Trip::new_join(&pool, &cox, &planned_event).await.is_ok());
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
fn test_new_failed_join_already_cox() {
|
||||
let pool = testdb!();
|
||||
|
||||
let cox = SteeringUser::new(
|
||||
&pool,
|
||||
&User::find_by_name(&pool, "cox2".into()).await.unwrap(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let planned_event = Event::find_by_id(&pool, 1).await.unwrap();
|
||||
|
||||
Trip::new_join(&pool, &cox, &planned_event).await.unwrap();
|
||||
assert!(Trip::new_join(&pool, &cox, &planned_event).await.is_err());
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
fn test_succ_update_own() {
|
||||
let pool = testdb!();
|
||||
|
||||
let cox = SteeringUser::new(
|
||||
&pool,
|
||||
&User::find_by_name(&pool, "cox".into()).await.unwrap(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let trip = Trip::find_by_id(&pool, 1).await.unwrap();
|
||||
|
||||
let update = trip::TripUpdate {
|
||||
cox: &cox,
|
||||
trip: &trip,
|
||||
max_people: 10,
|
||||
notes: None,
|
||||
trip_type: None,
|
||||
is_locked: false,
|
||||
};
|
||||
|
||||
assert!(Trip::update_own(&pool, &update).await.is_ok());
|
||||
|
||||
let trip = Trip::find_by_id(&pool, 1).await.unwrap();
|
||||
assert_eq!(trip.max_people, 10);
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
fn test_succ_update_own_with_triptype() {
|
||||
let pool = testdb!();
|
||||
|
||||
let cox = SteeringUser::new(
|
||||
&pool,
|
||||
&User::find_by_name(&pool, "cox".into()).await.unwrap(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let trip = Trip::find_by_id(&pool, 1).await.unwrap();
|
||||
|
||||
let update = trip::TripUpdate {
|
||||
cox: &cox,
|
||||
trip: &trip,
|
||||
max_people: 10,
|
||||
notes: None,
|
||||
trip_type: Some(1),
|
||||
is_locked: false,
|
||||
};
|
||||
assert!(Trip::update_own(&pool, &update).await.is_ok());
|
||||
|
||||
let trip = Trip::find_by_id(&pool, 1).await.unwrap();
|
||||
assert_eq!(trip.max_people, 10);
|
||||
assert_eq!(trip.trip_type_id, Some(1));
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
fn test_fail_update_own_not_your_trip() {
|
||||
let pool = testdb!();
|
||||
|
||||
let cox = SteeringUser::new(
|
||||
&pool,
|
||||
&User::find_by_name(&pool, "cox2".into()).await.unwrap(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let trip = Trip::find_by_id(&pool, 1).await.unwrap();
|
||||
|
||||
let update = trip::TripUpdate {
|
||||
cox: &cox,
|
||||
trip: &trip,
|
||||
max_people: 10,
|
||||
notes: None,
|
||||
trip_type: None,
|
||||
is_locked: false,
|
||||
};
|
||||
assert!(Trip::update_own(&pool, &update).await.is_err());
|
||||
assert_eq!(trip.max_people, 1);
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
fn test_succ_delete_by_planned_event() {
|
||||
let pool = testdb!();
|
||||
|
||||
let cox = SteeringUser::new(
|
||||
&pool,
|
||||
&User::find_by_name(&pool, "cox".into()).await.unwrap(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let planned_event = Event::find_by_id(&pool, 1).await.unwrap();
|
||||
|
||||
Trip::new_join(&pool, &cox, &planned_event).await.unwrap();
|
||||
|
||||
//TODO: check why following assert fails
|
||||
//assert!(Trip::find_by_id(&pool, 2).await.is_some());
|
||||
Trip::delete_by_planned_event(&pool, &cox, &planned_event)
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(Trip::find_by_id(&pool, 2).await.is_none());
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
fn test_succ_delete() {
|
||||
let pool = testdb!();
|
||||
|
||||
let cox = SteeringUser::new(
|
||||
&pool,
|
||||
&User::find_by_name(&pool, "cox".into()).await.unwrap(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let trip = Trip::find_by_id(&pool, 1).await.unwrap();
|
||||
|
||||
trip.delete(&pool, &cox).await.unwrap();
|
||||
|
||||
assert!(Trip::find_by_id(&pool, 1).await.is_none());
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
fn test_fail_delete_diff_cox() {
|
||||
let pool = testdb!();
|
||||
|
||||
let cox = SteeringUser::new(
|
||||
&pool,
|
||||
&User::find_by_name(&pool, "cox2".into()).await.unwrap(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let trip = Trip::find_by_id(&pool, 1).await.unwrap();
|
||||
|
||||
let result = trip
|
||||
.delete(&pool, &cox)
|
||||
.await
|
||||
.expect_err("It should not be possible to delete trips from others");
|
||||
let expected = TripDeleteError::NotYourTrip;
|
||||
|
||||
assert_eq!(result, expected);
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
fn test_fail_delete_someone_registered() {
|
||||
let pool = testdb!();
|
||||
|
||||
let cox = SteeringUser::new(
|
||||
&pool,
|
||||
&User::find_by_name(&pool, "cox".into()).await.unwrap(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let trip = Trip::find_by_id(&pool, 1).await.unwrap();
|
||||
|
||||
let trip_details = TripDetails::find_by_id(&pool, trip.trip_details_id.unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
let user = User::find_by_name(&pool, "rower".into()).await.unwrap();
|
||||
|
||||
UserTrip::create(&pool, &user, &trip_details, None)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let result = trip
|
||||
.delete(&pool, &cox)
|
||||
.await
|
||||
.expect_err("It should not be possible to delete trips if somebody already registered");
|
||||
let expected = TripDeleteError::SomebodyAlreadyRegistered;
|
||||
|
||||
assert_eq!(result, expected);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user