Skip to content

Commit

Permalink
Load polling station and election data from the database
Browse files Browse the repository at this point in the history
  • Loading branch information
rnijveld committed Jul 17, 2024
1 parent e3d3554 commit c28ed7e
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 26 deletions.
6 changes: 6 additions & 0 deletions backend/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,7 @@
"description": "Polling station of a certain [Election]",
"required": [
"id",
"election_id",
"name",
"number",
"polling_station_type",
Expand All @@ -625,6 +626,11 @@
"locality"
],
"properties": {
"election_id": {
"type": "integer",
"format": "int32",
"minimum": 0
},
"house_number": {
"type": "string"
},
Expand Down
6 changes: 5 additions & 1 deletion backend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,11 @@ impl From<serde_json::Error> for APIError {

impl From<sqlx::Error> for APIError {
fn from(err: sqlx::Error) -> Self {
APIError::SqlxError(err)
if matches!(err, RowNotFound) {
APIError::NotFound("Resource not found".to_string())
} else {
APIError::SqlxError(err)
}
}
}

Expand Down
18 changes: 9 additions & 9 deletions backend/src/polling_station/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ impl IntoResponse for DataEntryResponse {
)]
pub async fn polling_station_data_entry(
State(polling_station_data_entries): State<PollingStationDataEntries>,
State(polling_stations_repo): State<PollingStations>,
State(elections): State<Elections>,
Path((id, entry_number)): Path<(u32, u8)>,
data_entry_request: DataEntryRequest,
Expand All @@ -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
Expand Down Expand Up @@ -104,13 +103,12 @@ pub async fn polling_station_data_entry(
pub async fn polling_station_data_entry_finalise(
State(pool): State<SqlitePool>,
State(polling_station_data_entries): State<PollingStationDataEntries>,
State(polling_stations_repo): State<PollingStations>,
State(elections): State<Elections>,
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?;

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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(),
Expand All @@ -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)),
)
Expand Down
59 changes: 45 additions & 14 deletions backend/src/polling_station/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Vec<PollingStation>, 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<PollingStation, sqlx::Error> {
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);
Expand Down
1 change: 1 addition & 0 deletions backend/src/polling_station/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<i64>,
Expand Down
4 changes: 2 additions & 2 deletions backend/tests/polling_station_integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down

0 comments on commit c28ed7e

Please sign in to comment.