Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 175 additions & 3 deletions stationapi/src/use_case/interactor/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,10 +404,38 @@ where
.filter(|s| matches_transport_filter(s.transport_type, transport_type))
.collect();

let stations = self
// lines, companies, station_numbers等を付与(train_typeはNoneで空になる)
let mut stations = self
.update_station_vec_with_attributes(stations, None, transport_type)
.await?;

// 複数line_group_idの列車種別を一括取得してセット
let train_types = self
.train_type_repository
.get_by_line_group_id_vec(line_group_ids)
.await?;
let train_type_map: std::collections::HashMap<i32, &TrainType> = train_types
.iter()
.filter_map(|tt| tt.station_cd.map(|cd| (cd, tt)))
.collect();

for station in stations.iter_mut() {
station.train_type = train_type_map
.get(&station.station_cd)
.cloned()
.cloned()
.map(Box::new);
for line in station.lines.iter_mut() {
if let Some(ref mut nested_station) = line.station {
nested_station.train_type = train_type_map
.get(&nested_station.station_cd)
.cloned()
.cloned()
.map(Box::new);
}
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Ok(stations)
}
fn get_station_numbers(&self, station: &Station) -> Vec<StationNumber> {
Expand Down Expand Up @@ -1724,15 +1752,22 @@ mod tests {
struct ConfigurableMockStationRepository {
stations_by_group: Vec<Station>,
bus_stops: Vec<Station>,
stations_by_line_group: Vec<Station>,
}

impl ConfigurableMockStationRepository {
fn new(stations_by_group: Vec<Station>, bus_stops: Vec<Station>) -> Self {
Self {
stations_by_group,
bus_stops,
stations_by_line_group: vec![],
}
}

fn with_line_group_stations(mut self, stations: Vec<Station>) -> Self {
self.stations_by_line_group = stations;
self
}
}

#[async_trait::async_trait]
Expand Down Expand Up @@ -1793,7 +1828,7 @@ mod tests {
&self,
_: &[u32],
) -> Result<Vec<Station>, DomainError> {
Ok(vec![])
Ok(self.stations_by_line_group.clone())
}
async fn get_route_stops(
&self,
Expand Down Expand Up @@ -1903,7 +1938,7 @@ mod tests {
&self,
_: &[u32],
) -> Result<Vec<TrainType>, DomainError> {
Ok(vec![])
Ok(self.train_types.clone())
}
}

Expand Down Expand Up @@ -2451,6 +2486,143 @@ mod tests {
assert!(!line.line_symbols.is_empty());
}
}

#[tokio::test]
async fn test_get_stations_by_line_group_id_vec_populates_train_type() {
let company = create_test_company(1, "JR東日本");

let mut station1 = create_test_station(101, 1001, 100, Some(1000));
station1.company_cd = Some(1);

let mut station2 = create_test_station(201, 2001, 200, Some(2000));
station2.company_cd = Some(1);

let train_type1 = create_test_train_type_for_station(101, "快速");
let mut train_type2 = create_test_train_type_for_station(201, "特急");
train_type2.line_group_cd = Some(2000);

let line1 = create_test_line_for_station_group(100, 1001);
let line2 = create_test_line_for_station_group(200, 2001);

let station_repo = ConfigurableMockStationRepository::new(
vec![station1.clone(), station2.clone()],
vec![],
)
.with_line_group_stations(vec![station1.clone(), station2.clone()]);

let interactor = QueryInteractor {
station_repository: station_repo,
line_repository: ConfigurableMockLineRepository::new(vec![line1, line2]),
train_type_repository: ConfigurableMockTrainTypeRepository::new(vec![
train_type1.clone(),
train_type2.clone(),
]),
company_repository: ConfigurableMockCompanyRepository::new(vec![company]),
};

let result = interactor
.get_stations_by_line_group_id_vec(&[1000, 2000], TransportTypeFilter::Rail)
.await
.expect("Should succeed");

assert_eq!(result.len(), 2);

// top-level train_type が設定されていること
let s1 = result.iter().find(|s| s.station_cd == 101).unwrap();
assert!(
s1.train_type.is_some(),
"station 101 should have train_type"
);
assert_eq!(s1.train_type.as_ref().unwrap().type_name, "快速");
assert_eq!(s1.train_type.as_ref().unwrap().station_cd, Some(101));

let s2 = result.iter().find(|s| s.station_cd == 201).unwrap();
assert!(
s2.train_type.is_some(),
"station 201 should have train_type"
);
assert_eq!(s2.train_type.as_ref().unwrap().type_name, "特急");
assert_eq!(s2.train_type.as_ref().unwrap().station_cd, Some(201));
}

#[tokio::test]
async fn test_get_stations_by_line_group_id_vec_populates_nested_train_type() {
let company = create_test_company(1, "JR東日本");

let mut station = create_test_station(101, 1001, 100, Some(1000));
station.company_cd = Some(1);

// 同じstation_g_cdで別路線のstation(lines配列内のネスト先になる)
let mut station_other_line = create_test_station(102, 1001, 200, Some(1000));
station_other_line.company_cd = Some(1);

let train_type1 = create_test_train_type_for_station(101, "快速");
let train_type2 = create_test_train_type_for_station(102, "快速");

let line1 = create_test_line_for_station_group(100, 1001);
let line2 = create_test_line_for_station_group(200, 1001);

let station_repo = ConfigurableMockStationRepository::new(
vec![station.clone(), station_other_line.clone()],
vec![],
)
.with_line_group_stations(vec![station.clone()]);

let interactor = QueryInteractor {
station_repository: station_repo,
line_repository: ConfigurableMockLineRepository::new(vec![line1, line2]),
train_type_repository: ConfigurableMockTrainTypeRepository::new(vec![
train_type1.clone(),
train_type2.clone(),
]),
company_repository: ConfigurableMockCompanyRepository::new(vec![company]),
};

let result = interactor
.get_stations_by_line_group_id_vec(&[1000], TransportTypeFilter::Rail)
.await
.expect("Should succeed");

assert_eq!(result.len(), 1);

let station_result = &result[0];
// top-level train_type
assert!(
station_result.train_type.is_some(),
"top-level station should have train_type"
);
assert_eq!(
station_result.train_type.as_ref().unwrap().type_name,
"快速"
);

// nested stations in lines[] should also have train_type
for line in &station_result.lines {
if let Some(ref nested_station) = line.station {
assert!(
nested_station.train_type.is_some(),
"nested station (station_cd={}) should have train_type",
nested_station.station_cd
);
assert_eq!(
nested_station.train_type.as_ref().unwrap().type_name,
"快速"
);
}
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

#[tokio::test]
async fn test_get_stations_by_line_group_id_vec_empty_input() {
let interactor = create_configurable_interactor(vec![], vec![], vec![], vec![], vec![]);

let result = interactor
.get_stations_by_line_group_id_vec(&[], TransportTypeFilter::Rail)
.await
.expect("Should succeed");

assert!(result.is_empty());
}
}

// ========================================
Expand Down