Skip to content

Commit fb71deb

Browse files
committed
editoast: adapt simulation endpoint
1 parent ca988aa commit fb71deb

File tree

1 file changed

+75
-49
lines changed

1 file changed

+75
-49
lines changed

editoast/src/views/timetable/paced_train.rs

Lines changed: 75 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use core_client::signal_projection::SignalUpdate;
1515
use core_client::simulation::PhysicsConsist;
1616
use database::DbConnectionPoolV2;
1717
use editoast_derive::EditoastError;
18+
use editoast_models::TrainScheduleException;
1819
use editoast_models::prelude::*;
1920
use editoast_models::round_trips::TrainScheduleRoundTrips;
2021
use itertools::Itertools;
@@ -401,6 +402,12 @@ pub(in crate::views) struct ExceptionQueryParam {
401402
exception_key: Option<String>,
402403
}
403404

405+
#[derive(Debug, Default, Clone, Serialize, Deserialize, IntoParams, ToSchema)]
406+
#[into_params(parameter_in = Query)]
407+
pub(in crate::views) struct TrainScheduleExceptionQueryParam {
408+
exception_id: Option<i64>,
409+
}
410+
404411
/// Get a path from a paced train given an infrastructure id and a paced train id
405412
#[editoast_derive::route]
406413
#[utoipa::path(
@@ -516,7 +523,9 @@ pub(in crate::views) async fn simulation(
516523
Query(ElectricalProfileSetIdQueryParam {
517524
electrical_profile_set_id,
518525
}): Query<ElectricalProfileSetIdQueryParam>,
519-
Query(ExceptionQueryParam { exception_key }): Query<ExceptionQueryParam>,
526+
Query(TrainScheduleExceptionQueryParam { exception_id }): Query<
527+
TrainScheduleExceptionQueryParam,
528+
>,
520529
) -> Result<Json<simulation::Response>> {
521530
let authorized = auth
522531
.check_roles([authz::Role::OperationalStudies].into())
@@ -547,17 +556,20 @@ pub(in crate::views) async fn simulation(
547556
})
548557
.await?;
549558

550-
let train_schedule = match exception_key {
551-
Some(exception_key) => {
552-
let exception = train_schedule
553-
.exceptions
554-
.iter()
555-
.find(|e| e.key == exception_key)
556-
.ok_or_else(|| TrainScheduleError::ExceptionNotFound {
557-
exception_key: exception_key.clone(),
558-
})?;
559-
560-
train_schedule.apply_exception(exception)
559+
let train_schedule = match exception_id {
560+
Some(exception_id) => {
561+
let exception = TrainScheduleException::retrieve_or_fail(
562+
db_pool.get().await?,
563+
exception_id,
564+
|| {
565+
TrainScheduleError::ExceptionNotFound {
566+
// TODO rename to exception_id
567+
exception_key: exception_id.to_string(),
568+
}
569+
},
570+
)
571+
.await?;
572+
train_schedule.apply_train_schedule_exception(&exception.into())
561573
}
562574
None => train_schedule.into_train_occurrence(),
563575
};
@@ -1548,6 +1560,7 @@ mod tests {
15481560
use core_client::simulation::ReportTrain;
15491561
use core_client::simulation::SpeedLimitProperties;
15501562
use database::DbConnectionPoolV2;
1563+
use editoast_models::TrainScheduleException;
15511564
use editoast_models::prelude::*;
15521565
use editoast_models::rolling_stock::TrainMainCategory;
15531566
use pretty_assertions::assert_eq;
@@ -1579,6 +1592,8 @@ mod tests {
15791592
use crate::models::fixtures::create_paced_train_with_exceptions;
15801593
use crate::models::fixtures::create_simple_paced_train;
15811594
use crate::models::fixtures::create_small_infra;
1595+
use crate::models::fixtures::create_timetable_with_train_schedule_set;
1596+
use crate::models::fixtures::create_train_schedule_exception;
15821597
use crate::models::fixtures::create_train_schedule_set;
15831598
use crate::models::fixtures::simple_paced_train_base;
15841599
use crate::models::fixtures::simple_paced_train_changeset;
@@ -1884,12 +1899,16 @@ mod tests {
18841899
assert_eq!(response.train_schedule, paced_train.into());
18851900
}
18861901

1887-
async fn app_infra_id_paced_train_id_for_simulation_tests() -> (TestApp, i64, i64) {
1902+
async fn app_infra_id_paced_train_id_for_simulation_tests()
1903+
-> (TestApp, i64, i64, TrainScheduleException) {
18881904
let db_pool = DbConnectionPoolV2::for_tests();
18891905
let small_infra = create_small_infra(&mut db_pool.get_ok()).await;
1890-
let train_schedule_set = create_train_schedule_set(&mut db_pool.get_ok()).await;
18911906
let rolling_stock =
18921907
create_fast_rolling_stock(&mut db_pool.get_ok(), "simulation_rolling_stock").await;
1908+
let (timetable, train_schedule_set) =
1909+
create_timetable_with_train_schedule_set(&mut db_pool.get_ok()).await;
1910+
let exception = create_created_exception_with_change_groups("created_exception_key");
1911+
18931912
let paced_train_base = TrainSchedule {
18941913
train_occurrence: TrainOccurrence {
18951914
rolling_stock_name: rolling_stock.name.clone(),
@@ -1898,9 +1917,7 @@ mod tests {
18981917
paced: Some(Paced {
18991918
time_window: Duration::hours(1).try_into().unwrap(),
19001919
interval: Duration::minutes(15).try_into().unwrap(),
1901-
exceptions: vec![create_created_exception_with_change_groups(
1902-
"created_exception_key",
1903-
)],
1920+
exceptions: vec![],
19041921
}),
19051922
};
19061923
let paced_train: TrainScheduleChangeset = paced_train_base.into();
@@ -1909,17 +1926,28 @@ mod tests {
19091926
.create(&mut db_pool.get_ok())
19101927
.await
19111928
.expect("Failed to create paced train");
1929+
1930+
let exception = create_train_schedule_exception(
1931+
&mut db_pool.get_ok(),
1932+
timetable.id,
1933+
paced_train.id,
1934+
None,
1935+
Some("created_exception_key".to_string()),
1936+
Some(exception.change_groups),
1937+
)
1938+
.await;
1939+
19121940
let core = mocked_core_pathfinding_sim_and_proj();
19131941
let app = TestAppBuilder::new()
19141942
.db_pool(db_pool)
19151943
.core_client(core.into())
19161944
.build();
1917-
(app, small_infra.id, paced_train.id)
1945+
(app, small_infra.id, paced_train.id, exception)
19181946
}
19191947

19201948
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
19211949
async fn paced_train_simulation() {
1922-
let (app, infra_id, train_schedule_id) =
1950+
let (app, infra_id, train_schedule_id, _exception) =
19231951
app_infra_id_paced_train_id_for_simulation_tests().await;
19241952
let request = app.get(
19251953
format!("/train_schedules/{train_schedule_id}/simulation/?infra_id={infra_id}")
@@ -1936,11 +1964,11 @@ mod tests {
19361964

19371965
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
19381966
async fn paced_train_exception_simulation_with_invalid_exception_key() {
1939-
let (app, infra_id, train_schedule_id) =
1967+
let (app, infra_id, train_schedule_id, _exception) =
19401968
app_infra_id_paced_train_id_for_simulation_tests().await;
19411969
let request = app.get(
19421970
format!(
1943-
"/train_schedules/{train_schedule_id}/simulation/?infra_id={infra_id}&exception_key=toto"
1971+
"/train_schedules/{train_schedule_id}/simulation/?infra_id={infra_id}&exception_id=9999"
19441972
)
19451973
.as_str(),
19461974
);
@@ -1958,10 +1986,14 @@ mod tests {
19581986

19591987
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
19601988
async fn paced_train_exception_simulation() {
1961-
let (app, infra_id, train_schedule_id) =
1989+
let (app, infra_id, train_schedule_id, exception) =
19621990
app_infra_id_paced_train_id_for_simulation_tests().await;
19631991
let request = app.get(
1964-
format!("/train_schedules/{train_schedule_id}/simulation/?infra_id={infra_id}&exception_key=created_exception_key").as_str(),
1992+
format!(
1993+
"/train_schedules/{train_schedule_id}/simulation/?infra_id={infra_id}&exception_id={}",
1994+
exception.id
1995+
)
1996+
.as_str(),
19651997
);
19661998
let response: simulation::Response = app
19671999
.fetch(request)
@@ -2014,34 +2046,28 @@ mod tests {
20142046
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
20152047
async fn paced_train_exception_simulation_with_rolling_stock_not_found() {
20162048
// GIVEN
2017-
let (app, infra_id, train_schedule_id) =
2049+
let (app, infra_id, train_schedule_id, exception) =
20182050
app_infra_id_paced_train_id_for_simulation_tests().await;
2019-
let request = app.get(format!("/train_schedules/{train_schedule_id}").as_str());
2020-
let mut paced_train_response: TrainScheduleResponse = app
2021-
.fetch(request)
2022-
.await
2023-
.assert_status(StatusCode::OK)
2024-
.json_into();
2025-
paced_train_response
2026-
.train_schedule
2027-
.paced
2028-
.as_mut()
2029-
.unwrap()
2030-
.exceptions[0]
2031-
.change_groups
2032-
.rolling_stock = Some(RollingStockChangeGroup {
2051+
2052+
let mut change_groupe = exception.change_groups;
2053+
change_groupe.rolling_stock = Some(RollingStockChangeGroup {
20332054
rolling_stock_name: "R2D2".into(),
20342055
comfort: Comfort::AirConditioning,
20352056
});
2036-
let request = app
2037-
.put(format!("/train_schedules/{train_schedule_id}").as_str())
2038-
.json(&json!(paced_train_response.train_schedule));
2039-
app.fetch(request)
2057+
let exception = editoast_models::TrainScheduleException::changeset()
2058+
.change_groups(change_groupe)
2059+
.update(&mut app.db_pool().get_ok(), train_schedule_id)
20402060
.await
2041-
.assert_status(StatusCode::NO_CONTENT);
2061+
.expect("Fail to update exception")
2062+
.expect("Fail to update exception");
2063+
20422064
// WHEN
20432065
let request = app.get(
2044-
format!("/train_schedules/{train_schedule_id}/simulation/?infra_id={infra_id}&exception_key=created_exception_key").as_str(),
2066+
format!(
2067+
"/train_schedules/{train_schedule_id}/simulation/?infra_id={infra_id}&exception_id={}",
2068+
exception.id
2069+
)
2070+
.as_str(),
20452071
);
20462072
let response: simulation::Response = app
20472073
.fetch(request)
@@ -2064,7 +2090,7 @@ mod tests {
20642090

20652091
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
20662092
async fn paced_train_simulation_not_found() {
2067-
let (app, infra_id, _paced_train_id) =
2093+
let (app, infra_id, _paced_train_id, _exception) =
20682094
app_infra_id_paced_train_id_for_simulation_tests().await;
20692095
let request =
20702096
app.get(format!("/train_schedules/{}/simulation/?infra_id={}", 0, infra_id).as_str());
@@ -2080,7 +2106,7 @@ mod tests {
20802106

20812107
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
20822108
async fn paced_train_simulation_summary() {
2083-
let (app, infra_id, paced_train_id) =
2109+
let (app, infra_id, paced_train_id, _exception) =
20842110
app_infra_id_paced_train_id_for_simulation_tests().await;
20852111
let request = app.get(format!("/train_schedules/{paced_train_id}").as_str());
20862112
let mut paced_train_response: TrainScheduleResponse = app
@@ -2184,7 +2210,7 @@ mod tests {
21842210

21852211
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
21862212
async fn paced_train_simulation_summary_not_found() {
2187-
let (app, infra_id, _paced_train_id) =
2213+
let (app, infra_id, _paced_train_id, _exception) =
21882214
app_infra_id_paced_train_id_for_simulation_tests().await;
21892215
let request = app
21902216
.post("/train_schedules/simulation_summary")
@@ -2478,8 +2504,8 @@ mod tests {
24782504
}
24792505

24802506
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
2481-
async fn train_schedule_occupancy_blocks() {
2482-
let (app, infra_id, paced_train_id) =
2507+
async fn paced_train_occupancy_blocks() {
2508+
let (app, infra_id, paced_train_id, _exception) =
24832509
app_infra_id_paced_train_id_for_simulation_tests().await;
24842510

24852511
let request = app.get(format!("/train_schedules/{paced_train_id}").as_str());

0 commit comments

Comments
 (0)