rowt/src/model/trip.rs

764 lines
22 KiB
Rust
Raw Normal View History

use chrono::{Local, NaiveDate};
2024-09-09 21:51:01 +03:00
use ics::properties::{DtStart, Summary};
2023-04-04 15:16:21 +02:00
use serde::Serialize;
use sqlx::SqlitePool;
2023-04-26 16:54:53 +02:00
use super::{
2024-05-28 09:08:48 +02:00
event::{Event, Registration},
2024-09-03 21:35:43 +03:00
log::Log,
2024-03-20 16:09:55 +01:00
notification::Notification,
2023-04-26 16:54:53 +02:00
tripdetails::TripDetails,
2023-04-28 21:19:51 +02:00
triptype::TripType,
2024-11-25 12:12:36 +01:00
user::{ErgoUser, SteeringUser, User},
2024-09-09 21:51:01 +03:00
usertrip::UserTrip,
2023-04-26 16:54:53 +02:00
};
2023-04-05 17:25:22 +02:00
2023-04-26 16:54:53 +02:00
#[derive(Serialize, Clone, Debug)]
2023-04-04 15:16:21 +02:00
pub struct Trip {
id: i64,
2024-03-20 15:56:34 +01:00
pub cox_id: i64,
2023-04-04 15:16:21 +02:00
cox_name: String,
trip_details_id: Option<i64>,
planned_starting_time: String,
2023-07-23 14:21:27 +02:00
pub max_people: i64,
2024-03-20 15:56:34 +01:00
pub day: String,
2023-07-23 14:21:27 +02:00
pub notes: Option<String>,
pub allow_guests: bool,
2023-04-28 21:19:51 +02:00
trip_type_id: Option<i64>,
2023-07-23 19:45:48 +02:00
always_show: bool,
2023-08-09 11:54:18 +02:00
is_locked: bool,
2023-04-04 15:16:21 +02:00
}
#[derive(Serialize, Debug)]
2023-04-28 21:19:51 +02:00
pub struct TripWithUserAndType {
2023-04-04 15:16:21 +02:00
#[serde(flatten)]
pub trip: Trip,
pub rower: Vec<Registration>,
2023-04-28 21:19:51 +02:00
trip_type: Option<TripType>,
2023-04-04 15:16:21 +02:00
}
2024-05-22 00:13:23 +02:00
pub struct TripUpdate<'a> {
2024-11-25 12:12:36 +01:00
pub cox: &'a User,
2024-05-22 00:13:23 +02:00
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 TripWithUserAndType {
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,
trip_type,
}
}
}
2023-04-04 15:16:21 +02:00
impl Trip {
2023-04-26 16:54:53 +02:00
/// Cox decides to create own trip.
pub async fn new_own(db: &SqlitePool, cox: &SteeringUser, trip_details: TripDetails) {
2024-11-25 12:12:36 +01:00
Self::perform_new(db, &cox.user, trip_details).await
}
pub async fn new_own_ergo(db: &SqlitePool, ergo: &ErgoUser, trip_details: TripDetails) {
let typ = trip_details.triptype(db).await;
if let Some(typ) = typ {
let allowed_type = TripType::find_by_id(db, 4).await.unwrap();
if typ == allowed_type {
Self::perform_new(db, &ergo.user, trip_details).await;
}
}
}
async fn perform_new(db: &SqlitePool, user: &User, trip_details: TripDetails) {
2023-05-24 13:11:47 +02:00
let _ = sqlx::query!(
2023-04-26 16:54:53 +02:00
"INSERT INTO trip (cox_id, trip_details_id) VALUES(?, ?)",
2024-11-25 12:12:36 +01:00
user.id,
2023-04-26 16:54:53 +02:00
trip_details.id
2023-04-04 15:16:21 +02:00
)
2023-04-26 16:54:53 +02:00
.execute(db)
2023-05-24 13:11:47 +02:00
.await;
2024-03-20 16:09:55 +01:00
let same_starting_datetime = TripDetails::find_by_startingdatetime(
db,
trip_details.day,
trip_details.planned_starting_time,
)
.await;
2025-03-09 19:17:34 +01:00
for notify in same_starting_datetime {
// don't notify oneself
if notify.id == trip_details.id {
continue;
}
2024-08-27 09:24:21 +02:00
2025-03-09 19:17:34 +01:00
// don't notify people who have cancelled their trip
if notify.cancelled() {
continue;
}
2024-08-27 09:24:21 +02:00
2025-03-09 19:17:34 +01:00
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!(
"{} hat eine Ausfahrt zur selben Zeit ({} um {}) wie du erstellt",
user.name, trip.day, trip.planned_starting_time
),
"Neue Ausfahrt zur selben Zeit",
None,
None,
)
.await;
2024-03-20 16:09:55 +01:00
}
}
2023-04-04 15:16:21 +02:00
}
2024-03-20 15:56:34 +01:00
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()
}
2024-09-11 11:42:59 +02:00
pub(crate) async fn get_vevent(self, user: &User) -> ics::Event {
2024-09-09 21:51:01 +03:00
let mut vevent = ics::Event::new(format!("{}@rudernlinz.at", self.id), "19900101T180000");
vevent.push(DtStart::new(format!(
"{}T{}00",
self.day.replace('-', ""),
self.planned_starting_time.replace(':', "")
)));
let mut name = String::new();
if self.is_cancelled() {
name.push_str("ABGESAGT");
if let Some(notes) = &self.notes {
if !notes.is_empty() {
name.push_str(&format!(" (Grund: {notes})"))
}
}
name.push_str("! :-( ");
}
2024-09-11 11:42:59 +02:00
if self.cox_id == user.id {
name.push_str("Ruderausfahrt (selber ausgeschrieben)");
} else {
name.push_str(&format!("Ruderausfahrt mit {} ", self.cox_name));
}
2024-09-09 21:51:01 +03:00
vevent.push(Summary::new(name));
vevent
}
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 {
2024-09-11 11:42:59 +02:00
if user.id == trip.cox_id {
ret.push(trip.clone());
}
2024-09-09 21:51:01 +03:00
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
}
2023-04-26 16:54:53 +02:00
pub async fn find_by_id(db: &SqlitePool, id: i64) -> Option<Self> {
2023-04-05 17:25:22 +02:00
sqlx::query_as!(
2023-04-26 16:54:53 +02:00
Self,
2023-04-04 15:16:21 +02:00
"
2023-12-30 21:21:30 +01:00
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
2023-04-26 16:54:53 +02:00
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
2023-04-04 15:16:21 +02:00
)
2023-04-26 16:54:53 +02:00
.fetch_one(db)
2023-04-04 15:16:21 +02:00
.await
2023-04-26 16:54:53 +02:00
.ok()
2023-04-04 15:16:21 +02:00
}
2024-05-28 09:08:48 +02:00
/// Cox decides to help in a event.
pub async fn new_join(
db: &SqlitePool,
cox: &SteeringUser,
2024-05-28 09:08:48 +02:00
event: &Event,
) -> Result<(), CoxHelpError> {
2024-05-28 09:08:48 +02:00
if event.is_rower_registered(db, cox).await {
return Err(CoxHelpError::AlreadyRegisteredAsRower);
}
2024-05-28 09:08:48 +02:00
if event.trip_details(db).await.is_locked {
2023-08-09 11:54:18 +02:00
return Err(CoxHelpError::DetailsLocked);
}
2024-05-28 09:08:48 +02:00
if event.max_people == 0 {
2024-05-21 22:16:42 +02:00
return Err(CoxHelpError::CanceledEvent);
}
match sqlx::query!(
2023-04-04 15:16:21 +02:00
"INSERT INTO trip (cox_id, planned_event_id) VALUES(?, ?)",
2023-04-26 16:54:53 +02:00
cox.id,
2024-05-28 09:08:48 +02:00
event.id
2023-04-04 15:16:21 +02:00
)
.execute(db)
.await
{
Ok(_) => Ok(()),
Err(_) => Err(CoxHelpError::AlreadyRegisteredAsCox),
}
2023-04-04 15:16:21 +02:00
}
pub async fn get_for_today(db: &SqlitePool) -> Vec<TripWithUserAndType> {
let today = Local::now().date_naive();
Self::get_for_day(db, today).await
}
2023-04-28 21:19:51 +02:00
pub async fn get_for_day(db: &SqlitePool, day: NaiveDate) -> Vec<TripWithUserAndType> {
2023-04-26 16:54:53 +02:00
let day = format!("{day}");
let trips = sqlx::query_as!(
Trip,
"
2023-12-30 21:21:30 +01:00
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
2023-04-26 16:54:53 +02:00
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
2023-05-24 13:11:47 +02:00
.unwrap(); //Okay, as Trip can only be created with proper DB backing
2023-05-03 13:32:23 +02:00
2023-04-26 16:54:53 +02:00
let mut ret = Vec::new();
for trip in trips {
ret.push(TripWithUserAndType::from(db, trip).await);
2023-04-26 16:54:53 +02:00
}
ret
}
2023-04-07 11:54:56 +02:00
/// Cox decides to update own trip.
pub async fn update_own(
db: &SqlitePool,
2024-05-22 00:13:23 +02:00
update: &TripUpdate<'_>,
2023-04-07 11:54:56 +02:00
) -> Result<(), TripUpdateError> {
2024-05-22 00:13:23 +02:00
if !update.trip.is_trip_from_user(update.cox.id) {
2023-04-07 11:54:56 +02:00
return Err(TripUpdateError::NotYourTrip);
}
if update.trip_type != Some(4) && !update.cox.allowed_to_steer(db).await {
return Err(TripUpdateError::TripTypeNotAllowed);
2024-11-25 12:12:36 +01:00
}
2024-05-22 00:13:23 +02:00
let Some(trip_details_id) = update.trip.trip_details_id else {
return Err(TripUpdateError::TripDetailsDoesNotExist); //TODO: Remove?
2023-04-07 11:54:56 +02:00
};
2024-05-21 22:16:42 +02:00
let tripdetails = TripDetails::find_by_id(db, trip_details_id).await.unwrap();
let was_already_cancelled = tripdetails.max_people == 0;
let is_locked = if update.max_people == 0 {
false
} else {
update.is_locked
};
2023-04-07 11:54:56 +02:00
sqlx::query!(
"UPDATE trip_details SET max_people = ?, notes = ?, trip_type_id = ?, is_locked = ? WHERE id = ?",
2024-05-22 00:13:23 +02:00
update.max_people,
update.notes,
update.trip_type,
is_locked,
2023-04-07 11:54:56 +02:00
trip_details_id
)
.execute(db)
.await
2023-04-26 16:54:53 +02:00
.unwrap(); //Okay, as trip_details can only be created with proper DB backing
2023-04-07 11:54:56 +02:00
2024-05-22 00:18:17 +02:00
if update.max_people == 0 && !was_already_cancelled {
2024-05-22 00:13:23 +02:00
let rowers = TripWithUserAndType::from(db, update.trip.clone())
.await
.rower;
for user in rowers {
if let Some(user) = User::find_by_name(db, &user.name).await {
2024-05-30 11:57:03 +02:00
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.",
2024-11-25 12:12:36 +01:00
update.cox.name,
2024-05-22 00:13:23 +02:00
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;
}
2024-05-22 00:18:17 +02:00
if update.max_people > 0 && was_already_cancelled {
2024-05-21 22:16:42 +02:00
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;
2023-04-07 11:54:56 +02:00
Ok(())
}
2023-08-09 11:54:18 +02:00
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
}
2023-04-26 16:54:53 +02:00
pub async fn delete_by_planned_event(
db: &SqlitePool,
cox: &SteeringUser,
2024-05-28 09:08:48 +02:00
event: &Event,
2023-08-09 11:54:18 +02:00
) -> Result<(), TripHelpDeleteError> {
2024-05-28 09:08:48 +02:00
if event.trip_details(db).await.is_locked {
2023-08-09 11:54:18 +02:00
return Err(TripHelpDeleteError::DetailsLocked);
}
let affected_rows = sqlx::query!(
2023-04-04 15:16:21 +02:00
"DELETE FROM trip WHERE cox_id = ? AND planned_event_id = ?",
2023-04-26 16:54:53 +02:00
cox.id,
2024-05-28 09:08:48 +02:00
event.id
2023-04-04 15:16:21 +02:00
)
.execute(db)
.await
.unwrap()
2023-08-09 11:54:18 +02:00
.rows_affected();
if affected_rows == 0 {
return Err(TripHelpDeleteError::CoxNotHelping);
}
Ok(())
2023-04-04 15:16:21 +02:00
}
2024-11-25 12:12:36 +01:00
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;
2023-04-28 18:08:01 +02:00
if !registered_rower.is_empty() {
return Err(TripDeleteError::SomebodyAlreadyRegistered);
}
2024-09-03 21:35:43 +03:00
if !self.is_trip_from_user(user.id) && !user.has_role(db, "admin").await {
return Err(TripDeleteError::NotYourTrip);
}
2024-11-25 12:12:36 +01:00
Log::create(db, format!("{} deleted trip: {:#?}", user.name, self)).await;
2024-09-03 21:35:43 +03:00
sqlx::query!("DELETE FROM trip WHERE id = ?", self.id)
.execute(db)
.await
.unwrap(); //TODO: fixme
Ok(())
}
2023-04-07 11:54:56 +02:00
2023-05-30 14:47:44 +02:00
fn is_trip_from_user(&self, user_id: i64) -> bool {
2023-04-26 16:54:53 +02:00
self.cox_id == user_id
2023-04-07 11:54:56 +02:00
}
2023-07-23 19:45:48 +02:00
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();
}
}
2023-07-23 19:45:48 +02:00
pub(crate) async fn get_pinned_for_day(
db: &sqlx::Pool<sqlx::Sqlite>,
day: NaiveDate,
) -> Vec<TripWithUserAndType> {
let mut trips = Self::get_for_day(db, day).await;
trips.retain(|e| e.trip.always_show);
trips
}
2024-09-09 21:51:01 +03:00
fn is_cancelled(&self) -> bool {
self.max_people == 0
}
}
2023-04-04 15:16:21 +02:00
2023-04-26 16:54:53 +02:00
#[derive(Debug)]
pub enum CoxHelpError {
AlreadyRegisteredAsRower,
AlreadyRegisteredAsCox,
2023-08-09 11:54:18 +02:00
DetailsLocked,
2024-05-21 22:16:42 +02:00
CanceledEvent,
2023-08-09 11:54:18 +02:00
}
#[derive(Debug, PartialEq)]
pub enum TripHelpDeleteError {
DetailsLocked,
CoxNotHelping,
2023-04-04 15:16:21 +02:00
}
2023-04-28 18:18:00 +02:00
#[derive(Debug, PartialEq)]
pub enum TripDeleteError {
SomebodyAlreadyRegistered,
NotYourTrip,
}
2023-04-07 11:54:56 +02:00
2023-04-26 16:54:53 +02:00
#[derive(Debug)]
2023-04-07 11:54:56 +02:00
pub enum TripUpdateError {
NotYourTrip,
2023-04-26 16:54:53 +02:00
TripDetailsDoesNotExist,
2024-11-25 12:12:36 +01:00
TripTypeNotAllowed,
2023-04-26 16:54:53 +02:00
}
#[cfg(test)]
mod test {
use crate::{
model::{
2024-05-28 09:08:48 +02:00
event::Event,
2025-03-09 19:17:34 +01:00
notification::Notification,
2024-05-22 00:13:23 +02:00
trip::{self, TripDeleteError},
2023-04-26 16:54:53 +02:00
tripdetails::TripDetails,
user::{SteeringUser, User},
2023-04-28 18:18:00 +02:00
usertrip::UserTrip,
2023-04-26 16:54:53 +02:00
},
testdb,
};
2024-09-02 13:35:12 +03:00
use chrono::Local;
2023-04-26 16:54:53 +02:00
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();
2023-04-26 16:54:53 +02:00
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());
}
2025-03-09 19:17:34 +01:00
#[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"));
}
2023-04-26 16:54:53 +02:00
#[sqlx::test]
fn test_get_day_cox_trip() {
let pool = testdb!();
2024-09-02 13:35:12 +03:00
let tomorrow = Local::now().date_naive() + chrono::Duration::days(1);
let res = Trip::get_for_day(&pool, tomorrow).await;
2023-04-26 16:54:53 +02:00
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();
2023-04-26 16:54:53 +02:00
2024-05-28 09:08:48 +02:00
let planned_event = Event::find_by_id(&pool, 1).await.unwrap();
2023-04-26 16:54:53 +02:00
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();
2023-04-26 16:54:53 +02:00
2024-05-28 09:08:48 +02:00
let planned_event = Event::find_by_id(&pool, 1).await.unwrap();
2023-04-26 16:54:53 +02:00
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();
2023-04-26 16:54:53 +02:00
let trip = Trip::find_by_id(&pool, 1).await.unwrap();
2024-05-22 00:13:23 +02:00
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());
2023-05-03 16:53:36 +02:00
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();
2023-05-03 16:53:36 +02:00
let trip = Trip::find_by_id(&pool, 1).await.unwrap();
2024-05-22 00:13:23 +02:00
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());
2023-04-26 16:54:53 +02:00
let trip = Trip::find_by_id(&pool, 1).await.unwrap();
assert_eq!(trip.max_people, 10);
2023-05-03 16:53:36 +02:00
assert_eq!(trip.trip_type_id, Some(1));
2023-04-26 16:54:53 +02:00
}
#[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();
2023-04-26 16:54:53 +02:00
let trip = Trip::find_by_id(&pool, 1).await.unwrap();
2024-05-22 00:13:23 +02:00
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());
2023-04-26 16:54:53 +02:00
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();
2023-04-26 16:54:53 +02:00
2024-05-28 09:08:48 +02:00
let planned_event = Event::find_by_id(&pool, 1).await.unwrap();
2023-04-26 16:54:53 +02:00
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());
2023-08-09 11:54:18 +02:00
Trip::delete_by_planned_event(&pool, &cox, &planned_event)
.await
.unwrap();
2023-04-26 16:54:53 +02:00
assert!(Trip::find_by_id(&pool, 2).await.is_none());
}
2023-04-28 18:08:01 +02:00
#[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();
2023-04-28 18:08:01 +02:00
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());
}
2023-04-28 18:18:00 +02:00
#[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();
2023-04-28 18:18:00 +02:00
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();
2023-04-28 18:18:00 +02:00
let trip = Trip::find_by_id(&pool, 1).await.unwrap();
2023-04-28 19:08:17 +02:00
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();
2023-08-09 20:30:37 +00:00
UserTrip::create(&pool, &user, &trip_details, None)
.await
.unwrap();
2023-04-28 18:18:00 +02:00
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);
}
2023-04-07 11:54:56 +02:00
}