@@ -203,7 +203,9 @@ use axum::extract::Json;
203
203
use axum:: extract:: Query ;
204
204
use axum:: extract:: State ;
205
205
use axum:: Extension ;
206
+ use chrono:: DateTime ;
206
207
use chrono:: NaiveDateTime ;
208
+ use chrono:: Utc ;
207
209
use diesel:: pg:: Pg ;
208
210
use diesel:: sql_query;
209
211
use diesel:: sql_types:: Jsonb ;
@@ -215,6 +217,11 @@ use editoast_common::geometry::GeoJsonPoint;
215
217
use editoast_derive:: EditoastError ;
216
218
use editoast_derive:: Search ;
217
219
use editoast_derive:: SearchConfigStore ;
220
+ use editoast_schemas:: train_schedule:: Margins ;
221
+ use editoast_schemas:: train_schedule:: PathItem ;
222
+ use editoast_schemas:: train_schedule:: PowerRestrictionItem ;
223
+ use editoast_schemas:: train_schedule:: ScheduleItem ;
224
+ use editoast_schemas:: train_schedule:: TrainScheduleOptions ;
218
225
use editoast_search:: query_into_sql;
219
226
use editoast_search:: SearchConfigStore as _;
220
227
use editoast_search:: SearchError ;
@@ -344,9 +351,8 @@ async fn search(
344
351
Json ( SearchPayload { object, query, dry } ) : Json < SearchPayload > ,
345
352
) -> Result < Json < serde_json:: Value > > {
346
353
let roles: HashSet < BuiltinRole > = match object. as_str ( ) {
347
- "track" | "operationalpoint" | "signal" | "trainschedule" => {
348
- HashSet :: from ( [ BuiltinRole :: InfraRead ] )
349
- }
354
+ "track" | "operationalpoint" | "signal" => HashSet :: from ( [ BuiltinRole :: InfraRead ] ) ,
355
+ "trainschedule" => HashSet :: from ( [ BuiltinRole :: TimetableRead ] ) ,
350
356
"project" | "study" | "scenario" => HashSet :: from ( [ BuiltinRole :: OpsRead ] ) ,
351
357
_ => {
352
358
return Err ( SearchApiError :: ObjectType {
@@ -659,6 +665,7 @@ pub(super) struct SearchResultItemStudy {
659
665
) ]
660
666
#[ allow( unused) ]
661
667
/// A search result item for a query with `object = "scenario"`
668
+ #[ derive( serde:: Deserialize ) ]
662
669
pub ( super ) struct SearchResultItemScenario {
663
670
#[ search( sql = "scenario.id" ) ]
664
671
id : u64 ,
@@ -693,37 +700,38 @@ pub(super) struct SearchResultItemScenario {
693
700
) ]
694
701
#[ allow( unused) ]
695
702
/// A search result item for a query with `object = "trainschedule"`
703
+ #[ derive( serde:: Deserialize ) ]
696
704
pub ( super ) struct SearchResultItemTrainSchedule {
697
705
#[ search( sql = "train_schedule.id" ) ]
698
706
id : u64 ,
699
707
#[ search( sql = "train_schedule.train_name" ) ]
700
- train_name : String , // useless puisqu'on en a besoin pour la request?
708
+ train_name : String ,
701
709
#[ search( sql = "train_schedule.labels" ) ]
702
- labels : Vec < String > ,
710
+ labels : Vec < Option < String > > ,
703
711
#[ search( sql = "train_schedule.rolling_stock_name" ) ]
704
712
rolling_stock_name : String ,
705
713
#[ search( sql = "train_schedule.timetable_id" ) ]
706
- timetable_id : u64 , // useless puisqu'on en a besoin pour la request?
714
+ timetable_id : i64 ,
707
715
#[ search( sql = "train_schedule.start_time" ) ]
708
- start_time : String ,
716
+ start_time : DateTime < Utc > ,
709
717
#[ search( sql = "train_schedule.schedule" ) ]
710
- schedule : Vec < String > ,
718
+ schedule : Vec < ScheduleItem > ,
711
719
#[ search( sql = "train_schedule.margins" ) ]
712
- margins : Vec < String > ,
720
+ margins : Margins ,
713
721
#[ search( sql = "train_schedule.initial_speed" ) ]
714
722
initial_speed : f64 ,
715
723
#[ search( sql = "train_schedule.comfort" ) ]
716
- comfort : i16 ,
724
+ comfort : i64 ,
717
725
#[ search( sql = "train_schedule.path" ) ]
718
- path : Vec < String > ,
726
+ path : Vec < PathItem > ,
719
727
#[ search( sql = "train_schedule.constraint_distribution" ) ]
720
- constraint_distribution : i16 ,
728
+ constraint_distribution : i64 ,
721
729
#[ search( sql = "train_schedule.speed_limit_tag" ) ]
722
- speed_limit_tag : Vec < String > ,
730
+ speed_limit_tag : Option < String > ,
723
731
#[ search( sql = "train_schedule.power_restrictions" ) ]
724
- power_restrictions : Vec < String > ,
732
+ power_restrictions : Vec < PowerRestrictionItem > ,
725
733
#[ search( sql = "train_schedule.options" ) ]
726
- options : Vec < String > ,
734
+ options : TrainScheduleOptions ,
727
735
}
728
736
729
737
/// See [editoast_search::SearchConfigStore::find]
@@ -738,3 +746,70 @@ pub(super) struct SearchResultItemTrainSchedule {
738
746
object( name = "trainschedule" , config = SearchResultItemTrainSchedule ) ,
739
747
) ]
740
748
pub struct SearchConfigFinder ;
749
+
750
+ #[ cfg( test) ]
751
+ pub mod test {
752
+
753
+ use axum:: http:: StatusCode ;
754
+ use pretty_assertions:: assert_eq;
755
+ use rstest:: rstest;
756
+ use serde_json:: json;
757
+
758
+ use super :: * ;
759
+ use crate :: models:: fixtures:: { create_simple_train_schedule, create_timetable} ;
760
+ use crate :: models:: train_schedule:: TrainSchedule ;
761
+ use crate :: views:: test_app:: TestAppBuilder ;
762
+
763
+ #[ rstest]
764
+ async fn search_trainschedule_post ( ) {
765
+ let app = TestAppBuilder :: default_app ( ) ;
766
+ let pool = app. db_pool ( ) ;
767
+
768
+ // Create the timetable in the database
769
+ let timetable = create_timetable ( & mut pool. get_ok ( ) ) . await ;
770
+ let timetable_id = timetable. id ;
771
+
772
+ // Load data of the json file
773
+ #[ derive( serde:: Deserialize ) ]
774
+ struct TrainScheduleInfo {
775
+ pub train_name : String ,
776
+ }
777
+ let train_schedule_info: TrainScheduleInfo =
778
+ serde_json:: from_str ( include_str ! ( "../tests/train_schedules/simple.json" ) )
779
+ . expect ( "Unable to parse" ) ;
780
+ let train_name = train_schedule_info. train_name ;
781
+
782
+ // Add a train_schedule in the database
783
+ let train_schedule: TrainSchedule =
784
+ create_simple_train_schedule ( & mut pool. get_ok ( ) , timetable_id) . await ;
785
+ assert_eq ! ( train_schedule. train_name, train_name) ;
786
+
787
+ // The body
788
+ let request = app. post ( "/search" ) . json ( & json ! ( {
789
+ "object" : "trainschedule" ,
790
+ "query" : [
791
+ "and" ,
792
+ [
793
+ "search" ,
794
+ [
795
+ "train_name"
796
+ ] ,
797
+ train_name
798
+ ] ,
799
+ [
800
+ "=" ,
801
+ [
802
+
803
+ "timetable_id"
804
+ ] ,
805
+ timetable_id
806
+ ]
807
+ ] ,
808
+ } ) ) ;
809
+
810
+ let response: Vec < SearchResultItemTrainSchedule > =
811
+ app. fetch ( request) . assert_status ( StatusCode :: OK ) . json_into ( ) ;
812
+
813
+ assert_eq ! ( response[ 0 ] . train_name, train_name) ;
814
+ }
815
+ }
0 commit comments