diff --git a/tests/cli/bags_cli.rs b/tests/cli/bags_cli.rs new file mode 100644 index 0000000..e690c19 --- /dev/null +++ b/tests/cli/bags_cli.rs @@ -0,0 +1,159 @@ +use crate::helpers::{create_roast, create_roaster, create_token, run_brewlog, server_info}; +use serde_json::Value; + +#[test] +fn test_add_bag_requires_authentication() { + let _ = server_info(); + + let output = run_brewlog(&["add-bag", "--roast-id", "123", "--amount", "250.0"], &[]); + + assert!(!output.status.success(), "add-bag without auth should fail"); +} + +#[test] +fn test_add_bag_with_authentication() { + let token = create_token("test-add-bag"); + + // Setup: Create Roaster & Roast + let roaster_id = create_roaster("Bag Add Roaster", &token); + let roast_id = create_roast(&roaster_id, "Bag Add Roast", &token); + + // Test: Add Bag + let output = run_brewlog( + &[ + "add-bag", + "--roast-id", + &roast_id, + "--amount", + "250.0", + "--roast-date", + "2023-01-01", + ], + &[("BREWLOG_TOKEN", &token)], + ); + + assert!(output.status.success()); + let bag: Value = serde_json::from_slice(&output.stdout).unwrap(); + + assert_eq!(bag["amount"].as_f64(), Some(250.0)); + assert_eq!(bag["roast_date"], "2023-01-01"); + assert!(bag["id"].is_i64()); +} + +#[test] +fn test_update_bag_requires_authentication() { + let _ = server_info(); + + let output = run_brewlog(&["update-bag", "--id", "123", "--remaining", "100.0"], &[]); + + assert!( + !output.status.success(), + "update-bag without auth should fail" + ); +} + +#[test] +fn test_update_bag_with_authentication() { + let token = create_token("test-update-bag"); + + // Setup: Create Roaster & Roast & Bag + let roaster_id = create_roaster("Bag Update Roaster", &token); + let roast_id = create_roast(&roaster_id, "Bag Update Roast", &token); + + let bag_output = run_brewlog( + &["add-bag", "--roast-id", &roast_id, "--amount", "250.0"], + &[("BREWLOG_TOKEN", &token)], + ); + let bag: Value = serde_json::from_slice(&bag_output.stdout).unwrap(); + let bag_id = bag["id"].as_i64().unwrap().to_string(); + + // Test: Update Bag + let output = run_brewlog( + &[ + "update-bag", + "--id", + &bag_id, + "--remaining", + "150.0", + "--closed", + "true", + ], + &[("BREWLOG_TOKEN", &token)], + ); + + assert!(output.status.success()); + let updated_bag: Value = serde_json::from_slice(&output.stdout).unwrap(); + + assert_eq!(updated_bag["remaining"].as_f64(), Some(150.0)); + assert_eq!(updated_bag["closed"].as_bool(), Some(true)); +} + +#[test] +fn test_list_bags_works_without_authentication() { + let _ = server_info(); + // Listing without roast_id might return all or empty, but should succeed (200 OK) + let output = run_brewlog(&["list-bags"], &[]); + assert!(output.status.success()); +} + +#[test] +fn test_list_bags_shows_added_bag() { + let token = create_token("test-list-bags"); + + // Setup + let roaster_id = create_roaster("Bag List Roaster", &token); + let roast_id = create_roast(&roaster_id, "Bag List Roast", &token); + + let bag_output = run_brewlog( + &["add-bag", "--roast-id", &roast_id, "--amount", "250.0"], + &[("BREWLOG_TOKEN", &token)], + ); + let bag: Value = serde_json::from_slice(&bag_output.stdout).unwrap(); + let bag_id = bag["id"].as_i64().unwrap(); + + // Test: List Bags (Authenticated) + let output = run_brewlog( + &["list-bags", "--roast-id", &roast_id], + &[("BREWLOG_TOKEN", &token)], + ); + + assert!(output.status.success()); + let bags: Value = serde_json::from_slice(&output.stdout).unwrap(); + assert!(bags.is_array()); + let bags_array = bags.as_array().unwrap(); + assert!(bags_array.iter().any(|b| b["id"].as_i64() == Some(bag_id))); +} + +#[test] +fn test_delete_bag_requires_authentication() { + let _ = server_info(); + let output = run_brewlog(&["delete-bag", "--id", "123"], &[]); + assert!(!output.status.success()); +} + +#[test] +fn test_delete_bag_with_authentication() { + let token = create_token("test-delete-bag"); + + // Setup + let roaster_id = create_roaster("Bag Delete Roaster", &token); + let roast_id = create_roast(&roaster_id, "Bag Delete Roast", &token); + + let bag_output = run_brewlog( + &["add-bag", "--roast-id", &roast_id, "--amount", "250.0"], + &[("BREWLOG_TOKEN", &token)], + ); + let bag: Value = serde_json::from_slice(&bag_output.stdout).unwrap(); + let bag_id = bag["id"].as_i64().unwrap().to_string(); + + // Test: Delete Bag + let output = run_brewlog( + &["delete-bag", "--id", &bag_id], + &[("BREWLOG_TOKEN", &token)], + ); + assert!(output.status.success()); + + // Verify deletion + let get_output = run_brewlog(&["get-bag", "--id", &bag_id], &[]); + assert!(!get_output.status.success()); +} diff --git a/tests/cli/helpers.rs b/tests/cli/helpers.rs index 1415581..8671e90 100644 --- a/tests/cli/helpers.rs +++ b/tests/cli/helpers.rs @@ -161,3 +161,64 @@ pub fn run_brewlog(args: &[&str], env: &[(&str, &str)]) -> std::process::Output cmd.output().expect("Failed to run brewlog command") } + +/// Helper to create a roaster and return its ID +pub fn create_roaster(name: &str, token: &str) -> String { + let output = run_brewlog( + &["add-roaster", "--name", name, "--country", "UK"], + &[("BREWLOG_TOKEN", token)], + ); + + if !output.status.success() { + panic!( + "Failed to create roaster: {}", + String::from_utf8_lossy(&output.stderr) + ); + } + + let stdout = String::from_utf8_lossy(&output.stdout); + let roaster: serde_json::Value = + serde_json::from_str(&stdout).expect("Should output valid JSON"); + roaster["id"] + .as_i64() + .expect("roaster id should be numeric") + .to_string() +} + +/// Helper to create a roast and return its ID +pub fn create_roast(roaster_id: &str, name: &str, token: &str) -> String { + let output = run_brewlog( + &[ + "add-roast", + "--roaster-id", + roaster_id, + "--name", + name, + "--origin", + "Kenya", + "--region", + "Nyeri", + "--producer", + "Coop", + "--process", + "Washed", + "--tasting-notes", + "Blackcurrant", + ], + &[("BREWLOG_TOKEN", token)], + ); + + if !output.status.success() { + panic!( + "Failed to create roast: {}", + String::from_utf8_lossy(&output.stderr) + ); + } + + let stdout = String::from_utf8_lossy(&output.stdout); + let roast: serde_json::Value = serde_json::from_str(&stdout).expect("Should output valid JSON"); + roast["id"] + .as_i64() + .expect("roast id should be numeric") + .to_string() +} diff --git a/tests/cli/main.rs b/tests/cli/main.rs index 70b9274..1a0d87c 100644 --- a/tests/cli/main.rs +++ b/tests/cli/main.rs @@ -1,3 +1,4 @@ +pub mod bags_cli; pub mod helpers; pub mod roasters_cli; pub mod roasts_cli; diff --git a/tests/cli/roasters_cli.rs b/tests/cli/roasters_cli.rs index 0f26871..19ad5ed 100644 --- a/tests/cli/roasters_cli.rs +++ b/tests/cli/roasters_cli.rs @@ -1,4 +1,4 @@ -use crate::helpers::{create_token, run_brewlog, server_info}; +use crate::helpers::{create_roaster, create_token, run_brewlog, server_info}; use serde_json::Value; #[test] @@ -62,28 +62,7 @@ fn test_list_roasters_shows_added_roaster() { let token = create_token("test-list-roasters"); // Add a roaster - let add_output = run_brewlog( - &[ - "add-roaster", - "--name", - "Example Roasters", - "--country", - "USA", - ], - &[("BREWLOG_TOKEN", &token)], - ); - - assert!( - add_output.status.success(), - "Failed to add roaster: {}", - String::from_utf8_lossy(&add_output.stderr) - ); - - let stdout = String::from_utf8_lossy(&add_output.stdout); - let added_roaster: Value = serde_json::from_str(&stdout).expect("Should output valid JSON"); - let roaster_id = added_roaster["id"] - .as_i64() - .expect("roaster id should be numeric"); + let roaster_id = create_roaster("Example Roasters", &token); // List roasters let list_output = run_brewlog(&["list-roasters"], &[]); @@ -100,7 +79,7 @@ fn test_list_roasters_shows_added_roaster() { // Find our roaster in the list let found = roasters_array .iter() - .any(|r| r["id"].as_i64() == Some(roaster_id)); + .any(|r| r["id"].as_i64().unwrap().to_string() == roaster_id); assert!(found, "Should find the added roaster in the list"); } diff --git a/tests/cli/roasts_cli.rs b/tests/cli/roasts_cli.rs index 1faccdf..793d129 100644 --- a/tests/cli/roasts_cli.rs +++ b/tests/cli/roasts_cli.rs @@ -1,4 +1,4 @@ -use crate::helpers::{create_token, run_brewlog, server_info}; +use crate::helpers::{create_roaster, create_token, run_brewlog, server_info}; use serde_json::Value; #[test] @@ -35,32 +35,14 @@ fn test_add_roast_with_authentication() { let token = create_token("test-add-roast"); // First create a roaster - let roaster_output = run_brewlog( - &[ - "add-roaster", - "--name", - "Test Roasters Add", - "--country", - "UK", - ], - &[("BREWLOG_TOKEN", &token)], - ); - - assert!(roaster_output.status.success()); - - let roaster_stdout = String::from_utf8_lossy(&roaster_output.stdout); - let roaster: Value = serde_json::from_str(&roaster_stdout).expect("Should output valid JSON"); - let roaster_id = roaster["id"] - .as_i64() - .expect("roaster id should be numeric"); - let roaster_id_arg = roaster_id.to_string(); + let roaster_id = create_roaster("Test Roasters Add", &token); // Now add a roast let output = run_brewlog( &[ "add-roast", "--roaster-id", - &roaster_id_arg, + &roaster_id, "--name", "Ethiopian Yirgacheffe", "--origin", @@ -87,7 +69,10 @@ fn test_add_roast_with_authentication() { let roast: Value = serde_json::from_str(&stdout).expect("Should output valid JSON"); assert_eq!(roast["name"], "Ethiopian Yirgacheffe"); - assert_eq!(roast["roaster_id"].as_i64(), Some(roaster_id)); + assert_eq!( + roast["roaster_id"].as_i64().unwrap().to_string(), + roaster_id + ); assert!(roast["id"].is_i64(), "Should have an ID"); } @@ -113,30 +98,14 @@ fn test_list_roasts_shows_added_roast() { let token = create_token("test-list-roasts"); // First create a roaster - let roaster_output = run_brewlog( - &[ - "add-roaster", - "--name", - "Test Roasters List", - "--country", - "UK", - ], - &[("BREWLOG_TOKEN", &token)], - ); - - let roaster_stdout = String::from_utf8_lossy(&roaster_output.stdout); - let roaster: Value = serde_json::from_str(&roaster_stdout).unwrap(); - let roaster_id = roaster["id"] - .as_i64() - .expect("roaster id should be numeric"); - let roaster_id_arg = roaster_id.to_string(); + let roaster_id = create_roaster("Test Roasters List", &token); // Add a roast let add_output = run_brewlog( &[ "add-roast", "--roaster-id", - &roaster_id_arg, + &roaster_id, "--name", "Colombian Supremo", "--origin",