- Add migration 0014 to drop the notes column from cafes table - Remove notes from domain structs, repository, view model, CLI, routes - Remove notes textarea/column from web templates - Update bootstrap script and all test files
354 lines
9.6 KiB
Rust
354 lines
9.6 KiB
Rust
use crate::helpers::{create_default_cafe, spawn_app_with_auth};
|
|
use brewlog::domain::cafes::{Cafe, NewCafe, UpdateCafe};
|
|
|
|
#[tokio::test]
|
|
async fn creating_a_cafe_returns_a_201_for_valid_data() {
|
|
let app = spawn_app_with_auth().await;
|
|
let client = reqwest::Client::new();
|
|
|
|
let new_cafe = NewCafe {
|
|
name: "Blue Bottle".to_string(),
|
|
city: "San Francisco".to_string(),
|
|
country: "United States".to_string(),
|
|
latitude: 37.7749,
|
|
longitude: -122.4194,
|
|
website: Some("https://bluebottlecoffee.com".to_string()),
|
|
};
|
|
|
|
let response = client
|
|
.post(app.api_url("/cafes"))
|
|
.bearer_auth(app.auth_token.as_ref().unwrap())
|
|
.json(&new_cafe)
|
|
.send()
|
|
.await
|
|
.expect("Failed to execute request");
|
|
|
|
assert_eq!(response.status(), 201);
|
|
|
|
let cafe: Cafe = response.json().await.expect("Failed to parse response");
|
|
assert_eq!(cafe.name, "Blue Bottle");
|
|
assert_eq!(cafe.city, "San Francisco");
|
|
assert_eq!(cafe.country, "United States");
|
|
assert_eq!(cafe.latitude, 37.7749);
|
|
assert_eq!(cafe.longitude, -122.4194);
|
|
assert_eq!(
|
|
cafe.website,
|
|
Some("https://bluebottlecoffee.com".to_string())
|
|
);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn creating_a_cafe_persists_the_data() {
|
|
let app = spawn_app_with_auth().await;
|
|
let client = reqwest::Client::new();
|
|
|
|
let new_cafe = NewCafe {
|
|
name: "Persistent Cafe".to_string(),
|
|
city: "Paris".to_string(),
|
|
country: "France".to_string(),
|
|
latitude: 48.8566,
|
|
longitude: 2.3522,
|
|
website: None,
|
|
};
|
|
|
|
let response = client
|
|
.post(app.api_url("/cafes"))
|
|
.bearer_auth(app.auth_token.as_ref().unwrap())
|
|
.json(&new_cafe)
|
|
.send()
|
|
.await
|
|
.expect("Failed to execute request");
|
|
|
|
let cafe: Cafe = response.json().await.expect("Failed to parse response");
|
|
|
|
let fetched_cafe = app
|
|
.cafe_repo
|
|
.get(cafe.id)
|
|
.await
|
|
.expect("Failed to fetch cafe");
|
|
|
|
assert_eq!(fetched_cafe.name, "Persistent Cafe");
|
|
assert_eq!(fetched_cafe.city, "Paris");
|
|
assert_eq!(fetched_cafe.country, "France");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn creating_a_cafe_requires_authentication() {
|
|
let app = spawn_app_with_auth().await;
|
|
let client = reqwest::Client::new();
|
|
|
|
let new_cafe = NewCafe {
|
|
name: "Auth Test Cafe".to_string(),
|
|
city: "London".to_string(),
|
|
country: "UK".to_string(),
|
|
latitude: 51.5074,
|
|
longitude: -0.1278,
|
|
website: None,
|
|
};
|
|
|
|
let response = client
|
|
.post(app.api_url("/cafes"))
|
|
.json(&new_cafe)
|
|
.send()
|
|
.await
|
|
.expect("Failed to execute request");
|
|
|
|
assert_eq!(response.status(), 401);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn creating_a_cafe_with_missing_required_fields_returns_a_400() {
|
|
let app = spawn_app_with_auth().await;
|
|
let client = reqwest::Client::new();
|
|
|
|
let response = client
|
|
.post(app.api_url("/cafes"))
|
|
.bearer_auth(app.auth_token.as_ref().unwrap())
|
|
.header("content-type", "application/json")
|
|
.body(r#"{"name": "Test Cafe"}"#)
|
|
.send()
|
|
.await
|
|
.expect("Failed to execute request");
|
|
|
|
assert_eq!(response.status(), 400);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn creating_a_cafe_with_malformed_json_returns_a_400() {
|
|
let app = spawn_app_with_auth().await;
|
|
let client = reqwest::Client::new();
|
|
|
|
let response = client
|
|
.post(app.api_url("/cafes"))
|
|
.bearer_auth(app.auth_token.as_ref().unwrap())
|
|
.header("content-type", "application/json")
|
|
.body(r#"{"name": "Test", "city": }"#)
|
|
.send()
|
|
.await
|
|
.expect("Failed to execute request");
|
|
|
|
assert_eq!(response.status(), 400);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn listing_cafes_returns_a_200_with_empty_list() {
|
|
let app = spawn_app_with_auth().await;
|
|
let client = reqwest::Client::new();
|
|
|
|
let response = client
|
|
.get(app.api_url("/cafes"))
|
|
.send()
|
|
.await
|
|
.expect("Failed to execute request");
|
|
|
|
assert_eq!(response.status(), 200);
|
|
|
|
let cafes: Vec<Cafe> = response.json().await.expect("Failed to parse response");
|
|
assert_eq!(cafes.len(), 0);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn listing_cafes_returns_a_200_with_multiple_cafes() {
|
|
let app = spawn_app_with_auth().await;
|
|
let client = reqwest::Client::new();
|
|
|
|
let cafe1 = NewCafe {
|
|
name: "First Cafe".to_string(),
|
|
city: "London".to_string(),
|
|
country: "UK".to_string(),
|
|
latitude: 51.5074,
|
|
longitude: -0.1278,
|
|
website: None,
|
|
};
|
|
|
|
let cafe2 = NewCafe {
|
|
name: "Second Cafe".to_string(),
|
|
city: "Berlin".to_string(),
|
|
country: "Germany".to_string(),
|
|
latitude: 52.52,
|
|
longitude: 13.405,
|
|
website: None,
|
|
};
|
|
|
|
client
|
|
.post(app.api_url("/cafes"))
|
|
.bearer_auth(app.auth_token.as_ref().unwrap())
|
|
.json(&cafe1)
|
|
.send()
|
|
.await
|
|
.expect("Failed to create first cafe");
|
|
|
|
client
|
|
.post(app.api_url("/cafes"))
|
|
.bearer_auth(app.auth_token.as_ref().unwrap())
|
|
.json(&cafe2)
|
|
.send()
|
|
.await
|
|
.expect("Failed to create second cafe");
|
|
|
|
let response = client
|
|
.get(app.api_url("/cafes"))
|
|
.send()
|
|
.await
|
|
.expect("Failed to execute request");
|
|
|
|
assert_eq!(response.status(), 200);
|
|
|
|
let cafes: Vec<Cafe> = response.json().await.expect("Failed to parse response");
|
|
assert_eq!(cafes.len(), 2);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn getting_a_cafe_returns_a_200_for_valid_id() {
|
|
let app = spawn_app_with_auth().await;
|
|
let client = reqwest::Client::new();
|
|
let cafe = create_default_cafe(&app).await;
|
|
|
|
let response = client
|
|
.get(app.api_url(&format!("/cafes/{}", cafe.id)))
|
|
.send()
|
|
.await
|
|
.expect("Failed to execute request");
|
|
|
|
assert_eq!(response.status(), 200);
|
|
|
|
let fetched: Cafe = response.json().await.expect("Failed to parse response");
|
|
assert_eq!(fetched.id, cafe.id);
|
|
assert_eq!(fetched.name, "Blue Bottle");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn getting_a_nonexistent_cafe_returns_a_404() {
|
|
let app = spawn_app_with_auth().await;
|
|
let client = reqwest::Client::new();
|
|
|
|
let response = client
|
|
.get(app.api_url("/cafes/999999"))
|
|
.send()
|
|
.await
|
|
.expect("Failed to execute request");
|
|
|
|
assert_eq!(response.status(), 404);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn updating_a_cafe_returns_a_200_for_valid_data() {
|
|
let app = spawn_app_with_auth().await;
|
|
let client = reqwest::Client::new();
|
|
let cafe = create_default_cafe(&app).await;
|
|
|
|
let update = UpdateCafe {
|
|
name: Some("Updated Cafe".to_string()),
|
|
city: None,
|
|
country: None,
|
|
latitude: None,
|
|
longitude: None,
|
|
website: Some("https://updated.com".to_string()),
|
|
};
|
|
|
|
let response = client
|
|
.put(app.api_url(&format!("/cafes/{}", cafe.id)))
|
|
.bearer_auth(app.auth_token.as_ref().unwrap())
|
|
.json(&update)
|
|
.send()
|
|
.await
|
|
.expect("Failed to execute request");
|
|
|
|
assert_eq!(response.status(), 200);
|
|
|
|
let updated: Cafe = response.json().await.expect("Failed to parse response");
|
|
assert_eq!(updated.name, "Updated Cafe");
|
|
assert_eq!(updated.city, "San Francisco"); // unchanged
|
|
assert_eq!(updated.website, Some("https://updated.com".to_string()));
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn updating_a_cafe_with_no_changes_returns_a_400() {
|
|
let app = spawn_app_with_auth().await;
|
|
let client = reqwest::Client::new();
|
|
let cafe = create_default_cafe(&app).await;
|
|
|
|
let update = UpdateCafe {
|
|
name: None,
|
|
city: None,
|
|
country: None,
|
|
latitude: None,
|
|
longitude: None,
|
|
website: None,
|
|
};
|
|
|
|
let response = client
|
|
.put(app.api_url(&format!("/cafes/{}", cafe.id)))
|
|
.bearer_auth(app.auth_token.as_ref().unwrap())
|
|
.json(&update)
|
|
.send()
|
|
.await
|
|
.expect("Failed to execute request");
|
|
|
|
assert_eq!(response.status(), 400);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn updating_a_nonexistent_cafe_returns_a_404() {
|
|
let app = spawn_app_with_auth().await;
|
|
let client = reqwest::Client::new();
|
|
|
|
let update = UpdateCafe {
|
|
name: Some("New Name".to_string()),
|
|
city: None,
|
|
country: None,
|
|
latitude: None,
|
|
longitude: None,
|
|
website: None,
|
|
};
|
|
|
|
let response = client
|
|
.put(app.api_url("/cafes/999999"))
|
|
.bearer_auth(app.auth_token.as_ref().unwrap())
|
|
.json(&update)
|
|
.send()
|
|
.await
|
|
.expect("Failed to execute request");
|
|
|
|
assert_eq!(response.status(), 404);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn deleting_a_cafe_returns_a_204_for_valid_id() {
|
|
let app = spawn_app_with_auth().await;
|
|
let client = reqwest::Client::new();
|
|
let cafe = create_default_cafe(&app).await;
|
|
|
|
let response = client
|
|
.delete(app.api_url(&format!("/cafes/{}", cafe.id)))
|
|
.bearer_auth(app.auth_token.as_ref().unwrap())
|
|
.send()
|
|
.await
|
|
.expect("Failed to execute request");
|
|
|
|
assert_eq!(response.status(), 204);
|
|
|
|
// Verify cafe was deleted
|
|
let get_response = client
|
|
.get(app.api_url(&format!("/cafes/{}", cafe.id)))
|
|
.send()
|
|
.await
|
|
.expect("Failed to execute request");
|
|
|
|
assert_eq!(get_response.status(), 404);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn deleting_a_nonexistent_cafe_returns_a_404() {
|
|
let app = spawn_app_with_auth().await;
|
|
let client = reqwest::Client::new();
|
|
|
|
let response = client
|
|
.delete(app.api_url("/cafes/999999"))
|
|
.bearer_auth(app.auth_token.as_ref().unwrap())
|
|
.send()
|
|
.await
|
|
.expect("Failed to execute request");
|
|
|
|
assert_eq!(response.status(), 404);
|
|
}
|