add tests for crew station size updates
This commit is contained in:
@@ -31,12 +31,12 @@ impl Route {
|
|||||||
.ok()
|
.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create(db: &SqlitePool, name: &str) -> Result<(), String> {
|
pub(crate) async fn create(db: &SqlitePool, name: &str) -> Result<Self, String> {
|
||||||
sqlx::query!("INSERT INTO route(name) VALUES (?)", name)
|
let route = sqlx::query!("INSERT INTO route(name) VALUES (?) RETURNING id", name)
|
||||||
.execute(db)
|
.fetch_one(db)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
Ok(())
|
Ok(Self::find_by_id(db, route.id).await.expect("just created"))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn update_name(&self, db: &SqlitePool, name: &str) {
|
async fn update_name(&self, db: &SqlitePool, name: &str) {
|
||||||
|
@@ -72,7 +72,7 @@ async fn create(
|
|||||||
Form(form): Form<CreateForm>,
|
Form(form): Form<CreateForm>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
match Route::create(&db, &form.name).await {
|
match Route::create(&db, &form.name).await {
|
||||||
Ok(()) => suc!(session, t!("route_create_succ", name = form.name)),
|
Ok(_) => suc!(session, t!("route_create_succ", name = form.name)),
|
||||||
Err(e) => er!(
|
Err(e) => er!(
|
||||||
session,
|
session,
|
||||||
t!("route_create_err_duplicate_name", name = form.name, err = e)
|
t!("route_create_err_duplicate_name", name = form.name, err = e)
|
||||||
|
@@ -12,6 +12,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
|
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
|
||||||
use std::ops::DerefMut;
|
use std::ops::DerefMut;
|
||||||
|
|
||||||
|
pub(crate) mod model;
|
||||||
pub(crate) mod print;
|
pub(crate) mod print;
|
||||||
mod typst;
|
mod typst;
|
||||||
mod web;
|
mod web;
|
||||||
@@ -122,7 +123,7 @@ impl Station {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn create(db: &SqlitePool, name: &str) -> Result<(), String> {
|
pub(crate) async fn create(db: &SqlitePool, name: &str) -> Result<Self, String> {
|
||||||
let code = generate_random_alphanumeric(8);
|
let code = generate_random_alphanumeric(8);
|
||||||
let station_id = sqlx::query!(
|
let station_id = sqlx::query!(
|
||||||
"INSERT INTO station(name, pw) VALUES (?, ?) RETURNING id",
|
"INSERT INTO station(name, pw) VALUES (?, ?) RETURNING id",
|
||||||
@@ -133,18 +134,18 @@ impl Station {
|
|||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
let station = Station::find_by_id(db, station_id.id)
|
||||||
|
.await
|
||||||
|
.expect("just created");
|
||||||
|
|
||||||
let mut routes = Route::all(db).await.into_iter();
|
let mut routes = Route::all(db).await.into_iter();
|
||||||
if let Some(route) = routes.next() {
|
if let Some(route) = routes.next() {
|
||||||
if routes.next().is_none() {
|
if routes.next().is_none() {
|
||||||
// Just one route exists -> use it for new station
|
// Just one route exists -> use it for new station
|
||||||
let station = Station::find_by_id(db, station_id.id)
|
|
||||||
.await
|
|
||||||
.expect("just created");
|
|
||||||
|
|
||||||
route.add_station(db, &station).await?;
|
route.add_station(db, &station).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(station)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn new_team_waiting(
|
pub(crate) async fn new_team_waiting(
|
||||||
@@ -324,84 +325,6 @@ impl Station {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn update_name(&self, db: &SqlitePool, name: &str) {
|
|
||||||
sqlx::query!("UPDATE station SET name = ? WHERE id = ?", name, self.id)
|
|
||||||
.execute(db)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn update_notes(&self, db: &SqlitePool, notes: &str) {
|
|
||||||
sqlx::query!("UPDATE station SET notes = ? WHERE id = ?", notes, self.id)
|
|
||||||
.execute(db)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn update_amount_people(
|
|
||||||
&self,
|
|
||||||
db: &SqlitePool,
|
|
||||||
amount_people: i64,
|
|
||||||
) -> Result<(), String> {
|
|
||||||
let mut transaction = db.begin().await.unwrap();
|
|
||||||
|
|
||||||
sqlx::query!(
|
|
||||||
"UPDATE station SET amount_people = ? WHERE id = ?",
|
|
||||||
amount_people,
|
|
||||||
self.id
|
|
||||||
)
|
|
||||||
.execute(transaction.deref_mut())
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
if amount_people == 0 {
|
|
||||||
let teams = self.teams(db).await;
|
|
||||||
for team in teams {
|
|
||||||
let route = team.route(db).await;
|
|
||||||
let Some(station) = route.get_next_first_station_tx(&mut transaction).await else {
|
|
||||||
return Err(t!("last_station_has_to_be_crewful").into());
|
|
||||||
};
|
|
||||||
team.update_first_station_tx(&mut transaction, &station)
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transaction.commit().await.unwrap();
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn update_amount_people_reset(&self, db: &SqlitePool) {
|
|
||||||
sqlx::query!(
|
|
||||||
"UPDATE station SET amount_people = NULL WHERE id = ?",
|
|
||||||
self.id
|
|
||||||
)
|
|
||||||
.execute(db)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn update_location(&self, db: &SqlitePool, lat: f64, lng: f64) {
|
|
||||||
sqlx::query!(
|
|
||||||
"UPDATE station SET lat = ?, lng = ? WHERE id = ?",
|
|
||||||
lat,
|
|
||||||
lng,
|
|
||||||
self.id
|
|
||||||
)
|
|
||||||
.execute(db)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
async fn update_location_clear(&self, db: &SqlitePool) {
|
|
||||||
sqlx::query!(
|
|
||||||
"UPDATE station SET lat = NULL, lng=NULL WHERE id = ?",
|
|
||||||
self.id
|
|
||||||
)
|
|
||||||
.execute(db)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn delete(&self, db: &SqlitePool) -> Result<(), String> {
|
async fn delete(&self, db: &SqlitePool) -> Result<(), String> {
|
||||||
sqlx::query!("DELETE FROM station WHERE id = ?", self.id)
|
sqlx::query!("DELETE FROM station WHERE id = ?", self.id)
|
||||||
.execute(db)
|
.execute(db)
|
||||||
|
1
src/admin/station/model/mod.rs
Normal file
1
src/admin/station/model/mod.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pub(crate) mod update;
|
125
src/admin/station/model/update.rs
Normal file
125
src/admin/station/model/update.rs
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
use crate::Station;
|
||||||
|
use sqlx::SqlitePool;
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
|
||||||
|
impl Station {
|
||||||
|
pub(crate) async fn update_name(&self, db: &SqlitePool, name: &str) {
|
||||||
|
sqlx::query!("UPDATE station SET name = ? WHERE id = ?", name, self.id)
|
||||||
|
.execute(db)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn update_notes(&self, db: &SqlitePool, notes: &str) {
|
||||||
|
sqlx::query!("UPDATE station SET notes = ? WHERE id = ?", notes, self.id)
|
||||||
|
.execute(db)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn update_amount_people(
|
||||||
|
&self,
|
||||||
|
db: &SqlitePool,
|
||||||
|
amount_people: i64,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
let mut transaction = db.begin().await.unwrap();
|
||||||
|
|
||||||
|
sqlx::query!(
|
||||||
|
"UPDATE station SET amount_people = ? WHERE id = ?",
|
||||||
|
amount_people,
|
||||||
|
self.id
|
||||||
|
)
|
||||||
|
.execute(transaction.deref_mut())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if amount_people == 0 {
|
||||||
|
let teams = self.teams(db).await;
|
||||||
|
for team in teams {
|
||||||
|
let route = team.route(db).await;
|
||||||
|
let Some(station) = route.get_next_first_station_tx(&mut transaction).await else {
|
||||||
|
return Err(t!("last_station_has_to_be_crewful").into());
|
||||||
|
};
|
||||||
|
team.update_first_station_tx(&mut transaction, &station)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.commit().await.unwrap();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn update_amount_people_reset(&self, db: &SqlitePool) {
|
||||||
|
sqlx::query!(
|
||||||
|
"UPDATE station SET amount_people = NULL WHERE id = ?",
|
||||||
|
self.id
|
||||||
|
)
|
||||||
|
.execute(db)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn update_location(&self, db: &SqlitePool, lat: f64, lng: f64) {
|
||||||
|
sqlx::query!(
|
||||||
|
"UPDATE station SET lat = ?, lng = ? WHERE id = ?",
|
||||||
|
lat,
|
||||||
|
lng,
|
||||||
|
self.id
|
||||||
|
)
|
||||||
|
.execute(db)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn update_location_clear(&self, db: &SqlitePool) {
|
||||||
|
sqlx::query!(
|
||||||
|
"UPDATE station SET lat = NULL, lng=NULL WHERE id = ?",
|
||||||
|
self.id
|
||||||
|
)
|
||||||
|
.execute(db)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use crate::{
|
||||||
|
admin::{route::Route, team::Team},
|
||||||
|
testdb, Station,
|
||||||
|
};
|
||||||
|
|
||||||
|
use sqlx::SqlitePool;
|
||||||
|
|
||||||
|
#[sqlx::test]
|
||||||
|
async fn succ_update_not_last_crewful_station() {
|
||||||
|
let pool = testdb!();
|
||||||
|
|
||||||
|
let station = Station::create(&pool, "Teststation").await.unwrap();
|
||||||
|
let crew_station = Station::create(&pool, "Bemannte Teststation")
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let route = Route::create(&pool, "Testroute").await.unwrap();
|
||||||
|
route.add_station(&pool, &station).await.unwrap();
|
||||||
|
route.add_station(&pool, &crew_station).await.unwrap();
|
||||||
|
let _ = Team::create(&pool, "Testteam", &route).await.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(station.update_amount_people(&pool, 0).await, Ok(()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[sqlx::test]
|
||||||
|
async fn fail_update_last_crewful_station() {
|
||||||
|
let pool = testdb!();
|
||||||
|
|
||||||
|
let station = Station::create(&pool, "Teststation").await.unwrap();
|
||||||
|
let route = Route::create(&pool, "Testroute").await.unwrap();
|
||||||
|
route.add_station(&pool, &station).await.unwrap();
|
||||||
|
let _ = Team::create(&pool, "Testteam", &route).await.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
station.update_amount_people(&pool, 0).await,
|
||||||
|
Err(t!("last_station_has_to_be_crewful").into())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@@ -28,7 +28,7 @@ async fn create(
|
|||||||
Form(form): Form<CreateForm>,
|
Form(form): Form<CreateForm>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
match Station::create(&db, &form.name).await {
|
match Station::create(&db, &form.name).await {
|
||||||
Ok(()) => suc!(session, t!("station_create_succ", name = form.name)),
|
Ok(_) => suc!(session, t!("station_create_succ", name = form.name)),
|
||||||
Err(e) => er!(
|
Err(e) => er!(
|
||||||
session,
|
session,
|
||||||
t!(
|
t!(
|
||||||
|
@@ -88,7 +88,8 @@ ORDER BY
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CreateError {
|
#[derive(Debug)]
|
||||||
|
pub(crate) enum CreateError {
|
||||||
NoStationForRoute,
|
NoStationForRoute,
|
||||||
DuplicateName(String),
|
DuplicateName(String),
|
||||||
}
|
}
|
||||||
@@ -147,7 +148,11 @@ impl Team {
|
|||||||
.ok()
|
.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create(db: &SqlitePool, name: &str, route: &Route) -> Result<i64, CreateError> {
|
pub(crate) async fn create(
|
||||||
|
db: &SqlitePool,
|
||||||
|
name: &str,
|
||||||
|
route: &Route,
|
||||||
|
) -> Result<i64, CreateError> {
|
||||||
// get next station id which has the lowest amount of teams to have in the first place
|
// get next station id which has the lowest amount of teams to have in the first place
|
||||||
// assigned
|
// assigned
|
||||||
let Some(station) = route.get_next_first_station(db).await else {
|
let Some(station) = route.get_next_first_station(db).await else {
|
||||||
|
Reference in New Issue
Block a user