Skip to content
This repository was archived by the owner on Apr 24, 2024. It is now read-only.

Commit 886a9c4

Browse files
committed
Return 409 conflict when POST /maps with taken name. close #758
1 parent 41a5b15 commit 886a9c4

4 files changed

Lines changed: 68 additions & 4 deletions

File tree

backend/src/model/entity/map_impl.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
//! Contains the implementation of [`Map`].
22
3-
use diesel::dsl::sql;
3+
use diesel::dsl::{exists, sql};
44
use diesel::pg::Pg;
55
use diesel::sql_types::Float;
66
use diesel::{
7-
debug_query, BoolExpressionMethods, ExpressionMethods, PgTextExpressionMethods, QueryDsl,
8-
QueryResult,
7+
debug_query, select, BoolExpressionMethods, ExpressionMethods, PgTextExpressionMethods,
8+
QueryDsl, QueryResult,
99
};
1010
use diesel_async::{AsyncPgConnection, RunQueryDsl};
1111
use log::debug;
@@ -87,6 +87,16 @@ impl Map {
8787
query.first::<Self>(conn).await.map(Into::into)
8888
}
8989

90+
/// Checks if a map with this name already exists in the database.
91+
///
92+
/// # Errors
93+
/// * Unknown, diesel doesn't say why it might error.
94+
pub async fn is_name_taken(map_name: &str, conn: &mut AsyncPgConnection) -> QueryResult<bool> {
95+
let query = select(exists(maps::table.filter(name.eq(map_name))));
96+
debug!("{}", debug_query::<Pg, _>(&query));
97+
query.get_result(conn).await
98+
}
99+
90100
/// Create a new map in the database.
91101
///
92102
/// # Errors

backend/src/service/map.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ pub async fn create(
5858
) -> Result<MapDto, ServiceError> {
5959
let mut conn = app_data.pool.get().await?;
6060

61+
if Map::is_name_taken(&new_map.name, &mut conn).await? {
62+
return Err(ServiceError::new(
63+
StatusCode::CONFLICT,
64+
"Map name already taken".to_owned(),
65+
));
66+
}
67+
6168
let geometry_validation_result = is_valid_map_geometry(&new_map.geometry);
6269
if let Some(error) = geometry_validation_result {
6370
return Err(error);

backend/src/test/map.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Tests for [`crate::controller::map`].
22
33
use crate::model::dto::UpdateMapGeometryDto;
4+
use crate::test::util::data;
45
use crate::test::util::dummy_map_polygons::small_rectangle;
56
use crate::{
67
model::{
@@ -165,6 +166,52 @@ async fn test_can_create_map() {
165166
assert_eq!(resp.status(), StatusCode::OK);
166167
}
167168

169+
#[actix_rt::test]
170+
async fn test_conflict_on_create_map_with_taken_name() {
171+
let taken_name = "taken name";
172+
let pool = init_test_database(|conn| {
173+
async {
174+
diesel::insert_into(crate::schema::maps::table)
175+
.values(data::TestInsertableMap {
176+
name: taken_name.to_owned(),
177+
..Default::default()
178+
})
179+
.execute(conn)
180+
.await?;
181+
Ok(())
182+
}
183+
.scope_boxed()
184+
})
185+
.await;
186+
let (token, app) = init_test_app(pool.clone()).await;
187+
188+
let map_update = NewMapDto {
189+
name: taken_name.to_owned(),
190+
creation_date: NaiveDate::from_ymd_opt(2023, 5, 8).expect("Could not parse date!"),
191+
deletion_date: None,
192+
last_visit: None,
193+
is_inactive: false,
194+
zoom_factor: 100,
195+
honors: 0,
196+
visits: 0,
197+
harvested: 0,
198+
privacy: PrivacyOption::Public,
199+
description: None,
200+
location: None,
201+
geometry: tall_rectangle(),
202+
};
203+
204+
let resp = test::TestRequest::post()
205+
.uri("/api/maps")
206+
.insert_header((header::AUTHORIZATION, token))
207+
.set_json(map_update)
208+
.send_request(&app)
209+
.await;
210+
211+
// Expect conflict since the map name is already present in the database
212+
assert_eq!(resp.status(), StatusCode::CONFLICT);
213+
}
214+
168215
#[actix_rt::test]
169216
async fn test_update_fails_for_not_owner() {
170217
let pool = init_test_database(|conn| {

doc/changelog.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Syntax: `- short text describing the change _(Your Name)_`
2323
- _()_
2424
- Add points in middle of bezier polygon _(Daniel Steinkogler)_
2525
- _()_
26-
- _()_
26+
- Return 409 Conflict when creating a map with taken name _(Jannis Adamek)_
2727
- _()_
2828
- _()_
2929
- _()_

0 commit comments

Comments
 (0)