diff --git a/backend/openapi.json b/backend/openapi.json index 07a0373a3..2dacb13a7 100644 --- a/backend/openapi.json +++ b/backend/openapi.json @@ -616,6 +616,7 @@ "description": "Polling station of a certain [Election]", "required": [ "id", + "election_id", "name", "number", "polling_station_type", @@ -625,6 +626,11 @@ "locality" ], "properties": { + "election_id": { + "type": "integer", + "format": "int32", + "minimum": 0 + }, "house_number": { "type": "string" }, diff --git a/backend/src/polling_station/mod.rs b/backend/src/polling_station/mod.rs index ea203ab65..3ffe4673a 100644 --- a/backend/src/polling_station/mod.rs +++ b/backend/src/polling_station/mod.rs @@ -54,6 +54,7 @@ impl IntoResponse for DataEntryResponse { )] pub async fn polling_station_data_entry( State(polling_station_data_entries): State, + State(polling_stations_repo): State, State(elections): State, Path((id, entry_number)): Path<(u32, u8)>, data_entry_request: DataEntryRequest, @@ -65,10 +66,8 @@ pub async fn polling_station_data_entry( )); } - // future: need to resolve election id from polling station once we have - // polling stations in the database, #106 - let election_id = 1; - let election = elections.get(election_id).await?; + let polling_station = polling_stations_repo.get(id).await?; + let election = elections.get(polling_station.election_id).await?; let mut validation_results = ValidationResults::default(); data_entry_request @@ -104,13 +103,12 @@ pub async fn polling_station_data_entry( pub async fn polling_station_data_entry_finalise( State(pool): State, State(polling_station_data_entries): State, + State(polling_stations_repo): State, State(elections): State, Path((id, entry_number)): Path<(u32, u8)>, ) -> Result<(), APIError> { - // future: need to resolve election id from polling station once we have - // polling stations in the database, #106 - let election_id = 1; - let election = elections.get(election_id).await?; + let polling_station = polling_stations_repo.get(id).await?; + let election = elections.get(polling_station.election_id).await?; let mut tx = pool.begin().await?; @@ -167,7 +165,7 @@ mod tests { use super::*; - #[sqlx::test(fixtures(path = "../../fixtures", scripts("elections")))] + #[sqlx::test(fixtures(path = "../../fixtures", scripts("elections", "polling_stations")))] async fn test_polling_station_data_entry_valid(pool: SqlitePool) { let mut request_body = DataEntryRequest { data: PollingStationResults { @@ -212,6 +210,7 @@ mod tests { async fn save(pool: SqlitePool, request_body: DataEntryRequest) -> Response { polling_station_data_entry( State(PollingStationDataEntries::new(pool.clone())), + State(PollingStations::new(pool.clone())), State(Elections::new(pool.clone())), Path((1, 1)), request_body.clone(), @@ -224,6 +223,7 @@ mod tests { polling_station_data_entry_finalise( State(pool.clone()), State(PollingStationDataEntries::new(pool.clone())), + State(PollingStations::new(pool.clone())), State(Elections::new(pool.clone())), Path((1, 1)), ) diff --git a/backend/src/polling_station/repository.rs b/backend/src/polling_station/repository.rs index 0ef8e2fd9..70e348872 100644 --- a/backend/src/polling_station/repository.rs +++ b/backend/src/polling_station/repository.rs @@ -8,29 +8,60 @@ use super::PollingStation; pub struct PollingStations(SqlitePool); impl PollingStations { + #[cfg(test)] + pub fn new(pool: SqlitePool) -> Self { + Self(pool) + } + pub async fn list(&self, election_id: u32) -> Result, sqlx::Error> { query_as!( PollingStation, r#" -SELECT - id, - name, - number, - number_of_voters, - polling_station_type, - street, - house_number, - house_number_addition, - postal_code, - locality -FROM polling_stations -WHERE election_id = $1; -"#, + SELECT + id AS "id: u32", + election_id AS "election_id: u32", + name, + number, + number_of_voters, + polling_station_type, + street, + house_number, + house_number_addition, + postal_code, + locality + FROM polling_stations + WHERE election_id = $1 + "#, election_id ) .fetch_all(&self.0) .await } + + pub async fn get(&self, id: u32) -> Result { + query_as!( + PollingStation, + r#" + SELECT + id AS "id: u32", + election_id AS "election_id: u32", + name, + number, + number_of_voters, + polling_station_type, + street, + house_number, + house_number_addition, + postal_code, + locality + FROM polling_stations + WHERE id = $1 + "#, + id + ) + .fetch_one(&self.0) + .await + } } pub struct PollingStationDataEntries(SqlitePool); diff --git a/backend/src/polling_station/structs.rs b/backend/src/polling_station/structs.rs index da07951e9..9bd8d4cf2 100644 --- a/backend/src/polling_station/structs.rs +++ b/backend/src/polling_station/structs.rs @@ -20,6 +20,7 @@ pub trait Validate { #[derive(Serialize, Deserialize, ToSchema, Debug, FromRow)] pub struct PollingStation { pub id: i64, + pub election_id: u32, pub name: String, pub number: i64, pub number_of_voters: Option, diff --git a/backend/tests/polling_station_integration_test.rs b/backend/tests/polling_station_integration_test.rs index f3b6400d7..b16d34b17 100644 --- a/backend/tests/polling_station_integration_test.rs +++ b/backend/tests/polling_station_integration_test.rs @@ -34,7 +34,7 @@ async fn test_polling_station_listing_works(pool: SqlitePool) { .any(|ps| ps.name == "Stembureau \"Op Rolletjes\"")); } -#[sqlx::test(fixtures(path = "../fixtures", scripts("elections")))] +#[sqlx::test(fixtures(path = "../fixtures", scripts("elections", "polling_stations")))] async fn test_polling_station_data_entry_valid(pool: SqlitePool) { let addr = serve_api(pool).await; @@ -129,7 +129,7 @@ async fn test_polling_station_data_entry_invalid(pool: SqlitePool) { ); } -#[sqlx::test(fixtures(path = "../fixtures", scripts("elections")))] +#[sqlx::test(fixtures(path = "../fixtures", scripts("elections", "polling_stations")))] async fn test_polling_station_data_entry_validation(pool: SqlitePool) { let addr = serve_api(pool).await;