146 lines
4.2 KiB
Rust
146 lines
4.2 KiB
Rust
use crate::helpers::{create_roaster_with_payload, spawn_app};
|
|
use brewlog::domain::roasters::NewRoaster;
|
|
use brewlog::domain::roasts::NewRoast;
|
|
use reqwest::Client;
|
|
use tokio::time::{Duration, sleep};
|
|
|
|
async fn create_roast(app: &crate::helpers::TestApp, roaster_id: &str, name: &str) {
|
|
let client = Client::new();
|
|
let roast = NewRoast {
|
|
roaster_id: roaster_id.to_string(),
|
|
name: name.to_string(),
|
|
origin: "Ethiopia".to_string(),
|
|
region: "Yirgacheffe".to_string(),
|
|
producer: "Chelbesa Cooperative".to_string(),
|
|
tasting_notes: vec!["Blueberry".to_string(), "Jasmine".to_string()],
|
|
process: "Washed".to_string(),
|
|
};
|
|
|
|
let response = client
|
|
.post(app.api_url("/roasts"))
|
|
.json(&roast)
|
|
.send()
|
|
.await
|
|
.expect("failed to create roast");
|
|
|
|
assert_eq!(response.status(), 201);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn timeline_page_returns_a_200_with_empty_state() {
|
|
// Arrange
|
|
let app = spawn_app().await;
|
|
let client = Client::new();
|
|
|
|
// Act
|
|
let response = client
|
|
.get(format!("{}/timeline", app.address))
|
|
.send()
|
|
.await
|
|
.expect("failed to fetch timeline");
|
|
|
|
// Assert
|
|
assert_eq!(response.status(), 200);
|
|
|
|
let body = response.text().await.expect("failed to read response body");
|
|
assert!(
|
|
body.contains("No events yet"),
|
|
"Expected empty timeline state message, got: {body}"
|
|
);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn creating_a_roaster_surfaces_on_the_timeline() {
|
|
// Arrange
|
|
let app = spawn_app().await;
|
|
let client = Client::new();
|
|
|
|
let roaster_name = "Timeline Roasters";
|
|
let roaster = create_roaster_with_payload(
|
|
&app,
|
|
NewRoaster {
|
|
name: roaster_name.to_string(),
|
|
country: "UK".to_string(),
|
|
city: Some("Bristol".to_string()),
|
|
homepage: Some("https://example.com".to_string()),
|
|
notes: None,
|
|
},
|
|
)
|
|
.await;
|
|
let roaster_id = roaster.id.clone();
|
|
|
|
// Give the database a brief moment to commit timestamps
|
|
sleep(Duration::from_millis(10)).await;
|
|
|
|
// Act
|
|
let response = client
|
|
.get(format!("{}/timeline", app.address))
|
|
.send()
|
|
.await
|
|
.expect("failed to fetch timeline");
|
|
|
|
// Assert
|
|
assert_eq!(response.status(), 200);
|
|
|
|
let body = response.text().await.expect("failed to read response body");
|
|
assert!(
|
|
body.contains("Roaster Added"),
|
|
"Expected 'Roaster Added' badge in timeline HTML, got: {body}"
|
|
);
|
|
assert!(
|
|
body.contains(roaster_name),
|
|
"Expected roaster name to appear in timeline HTML, got: {body}"
|
|
);
|
|
assert!(
|
|
body.contains(&format!("/roasters/{}", roaster_id)),
|
|
"Expected roaster detail link in timeline HTML, got: {body}"
|
|
);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn creating_a_roast_surfaces_on_the_timeline() {
|
|
// Arrange
|
|
let app = spawn_app().await;
|
|
let client = Client::new();
|
|
|
|
let roaster_id = create_roaster_with_payload(
|
|
&app,
|
|
NewRoaster {
|
|
name: "Timeline Roast Roasters".to_string(),
|
|
country: "UK".to_string(),
|
|
city: Some("Bristol".to_string()),
|
|
homepage: Some("https://example.com".to_string()),
|
|
notes: None,
|
|
},
|
|
)
|
|
.await
|
|
.id;
|
|
// Ensure the roast event occurs after the roaster event to make ordering deterministic
|
|
sleep(Duration::from_millis(5)).await;
|
|
let roast_name = "Timeline Natural";
|
|
create_roast(&app, &roaster_id, roast_name).await;
|
|
|
|
// Act
|
|
let response = client
|
|
.get(format!("{}/timeline", app.address))
|
|
.send()
|
|
.await
|
|
.expect("failed to fetch timeline");
|
|
|
|
// Assert
|
|
assert_eq!(response.status(), 200);
|
|
|
|
let body = response.text().await.expect("failed to read response body");
|
|
assert!(
|
|
body.contains("Roast Added"),
|
|
"Expected 'Roast Added' badge in timeline HTML, got: {body}"
|
|
);
|
|
assert!(
|
|
body.contains(roast_name),
|
|
"Expected roast name to appear in timeline HTML, got: {body}"
|
|
);
|
|
assert!(
|
|
body.contains("Blueberry"),
|
|
"Expected tasting notes to appear in timeline HTML, got: {body}"
|
|
);
|
|
}
|