refactor(tests): add CLI test macros and deduplicate helpers
- Add `define_cli_auth_test!` macro for authentication-required tests - Add `define_cli_list_test!` macro for unauthenticated list tests - Replace 18 auth tests and 5 list tests with macro invocations - Add `create_entity_cli()` generic, convert per-entity helpers to thin wrappers - Move `create_bag` and `create_gear` from brews_cli.rs to helpers.rs
This commit is contained in:
parent
dcdeaee7ca
commit
1257630019
11 changed files with 250 additions and 463 deletions
|
|
@ -1,4 +1,7 @@
|
||||||
use super::helpers::{create_token, run_brewlog};
|
use super::helpers::{create_token, run_brewlog};
|
||||||
|
use crate::test_macros::define_cli_auth_test;
|
||||||
|
|
||||||
|
define_cli_auth_test!(backup_requires_auth, &["backup"]);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn backup_produces_valid_json() {
|
fn backup_produces_valid_json() {
|
||||||
|
|
@ -25,13 +28,3 @@ fn backup_produces_valid_json() {
|
||||||
assert!(data["cafes"].is_array());
|
assert!(data["cafes"].is_array());
|
||||||
assert!(data["timeline_events"].is_array());
|
assert!(data["timeline_events"].is_array());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn backup_requires_auth() {
|
|
||||||
let output = run_brewlog(&["backup"], &[]);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
!output.status.success(),
|
|
||||||
"backup command should fail without auth"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,23 @@
|
||||||
use crate::helpers::{create_roast, create_roaster, create_token, run_brewlog, server_info};
|
use crate::helpers::{create_roast, create_roaster, create_token, run_brewlog};
|
||||||
|
use crate::test_macros::{define_cli_auth_test, define_cli_list_test};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
#[test]
|
define_cli_auth_test!(
|
||||||
fn test_add_bag_requires_authentication() {
|
test_add_bag_requires_authentication,
|
||||||
let _ = server_info();
|
&["bag", "add", "--roast-id", "123", "--amount", "250.0"]
|
||||||
|
);
|
||||||
let output = run_brewlog(
|
define_cli_auth_test!(
|
||||||
&["bag", "add", "--roast-id", "123", "--amount", "250.0"],
|
test_update_bag_requires_authentication,
|
||||||
&[],
|
&["bag", "update", "--id", "123", "--remaining", "100.0"]
|
||||||
);
|
);
|
||||||
|
define_cli_auth_test!(
|
||||||
assert!(!output.status.success(), "bag add without auth should fail");
|
test_delete_bag_requires_authentication,
|
||||||
}
|
&["bag", "delete", "--id", "123"]
|
||||||
|
);
|
||||||
|
define_cli_list_test!(
|
||||||
|
test_list_bags_works_without_authentication,
|
||||||
|
&["bag", "list"]
|
||||||
|
);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_add_bag_with_authentication() {
|
fn test_add_bag_with_authentication() {
|
||||||
|
|
@ -44,21 +50,6 @@ fn test_add_bag_with_authentication() {
|
||||||
assert!(bag["id"].is_i64());
|
assert!(bag["id"].is_i64());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_update_bag_requires_authentication() {
|
|
||||||
let _ = server_info();
|
|
||||||
|
|
||||||
let output = run_brewlog(
|
|
||||||
&["bag", "update", "--id", "123", "--remaining", "100.0"],
|
|
||||||
&[],
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
!output.status.success(),
|
|
||||||
"bag update without auth should fail"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_update_bag_with_authentication() {
|
fn test_update_bag_with_authentication() {
|
||||||
let token = create_token("test-update-bag");
|
let token = create_token("test-update-bag");
|
||||||
|
|
@ -96,14 +87,6 @@ fn test_update_bag_with_authentication() {
|
||||||
assert_eq!(updated_bag["closed"].as_bool(), Some(true));
|
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(&["bag", "list"], &[]);
|
|
||||||
assert!(output.status.success());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_list_bags_shows_added_bag() {
|
fn test_list_bags_shows_added_bag() {
|
||||||
let token = create_token("test-list-bags");
|
let token = create_token("test-list-bags");
|
||||||
|
|
@ -216,13 +199,6 @@ fn test_list_bags_shows_open_and_closed_bags() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_delete_bag_requires_authentication() {
|
|
||||||
let _ = server_info();
|
|
||||||
let output = run_brewlog(&["bag", "delete", "--id", "123"], &[]);
|
|
||||||
assert!(!output.status.success());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_delete_bag_with_authentication() {
|
fn test_delete_bag_with_authentication() {
|
||||||
let token = create_token("test-delete-bag");
|
let token = create_token("test-delete-bag");
|
||||||
|
|
|
||||||
|
|
@ -1,55 +1,6 @@
|
||||||
use crate::helpers::{create_roast, create_roaster, create_token, run_brewlog};
|
use crate::helpers::{
|
||||||
|
create_bag, create_gear, create_roast, create_roaster, create_token, run_brewlog,
|
||||||
fn create_bag(roast_id: &str, token: &str) -> String {
|
};
|
||||||
let output = run_brewlog(
|
|
||||||
&["bag", "add", "--roast-id", roast_id, "--amount", "250"],
|
|
||||||
&[("BREWLOG_TOKEN", token)],
|
|
||||||
);
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
panic!(
|
|
||||||
"Failed to create bag: {}",
|
|
||||||
String::from_utf8_lossy(&output.stderr)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
||||||
let bag: serde_json::Value = serde_json::from_str(&stdout).expect("Should output valid JSON");
|
|
||||||
bag["id"]
|
|
||||||
.as_i64()
|
|
||||||
.expect("bag id should be numeric")
|
|
||||||
.to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_gear(category: &str, make: &str, model: &str, token: &str) -> String {
|
|
||||||
let output = run_brewlog(
|
|
||||||
&[
|
|
||||||
"gear",
|
|
||||||
"add",
|
|
||||||
"--category",
|
|
||||||
category,
|
|
||||||
"--make",
|
|
||||||
make,
|
|
||||||
"--model",
|
|
||||||
model,
|
|
||||||
],
|
|
||||||
&[("BREWLOG_TOKEN", token)],
|
|
||||||
);
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
panic!(
|
|
||||||
"Failed to create gear: {}",
|
|
||||||
String::from_utf8_lossy(&output.stderr)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
||||||
let gear: serde_json::Value = serde_json::from_str(&stdout).expect("Should output valid JSON");
|
|
||||||
gear["id"]
|
|
||||||
.as_i64()
|
|
||||||
.expect("gear id should be numeric")
|
|
||||||
.to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn brew_add_creates_brew_via_api() {
|
fn brew_add_creates_brew_via_api() {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
use crate::helpers::{create_cafe, create_token, run_brewlog, server_info};
|
use crate::helpers::{create_cafe, create_token, run_brewlog};
|
||||||
|
use crate::test_macros::{define_cli_auth_test, define_cli_list_test};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
#[test]
|
define_cli_auth_test!(
|
||||||
fn test_add_cafe_requires_authentication() {
|
test_add_cafe_requires_authentication,
|
||||||
let _ = server_info();
|
|
||||||
|
|
||||||
let output = run_brewlog(
|
|
||||||
&[
|
&[
|
||||||
"cafe",
|
"cafe",
|
||||||
"add",
|
"add",
|
||||||
|
|
@ -18,16 +16,28 @@ fn test_add_cafe_requires_authentication() {
|
||||||
"--latitude",
|
"--latitude",
|
||||||
"51.5074",
|
"51.5074",
|
||||||
"--longitude",
|
"--longitude",
|
||||||
"-0.1278",
|
"-0.1278"
|
||||||
],
|
]
|
||||||
&[],
|
);
|
||||||
);
|
define_cli_auth_test!(
|
||||||
|
test_delete_cafe_requires_authentication,
|
||||||
assert!(
|
&["cafe", "delete", "--id", "some-id"]
|
||||||
!output.status.success(),
|
);
|
||||||
"cafe add without auth should fail"
|
define_cli_auth_test!(
|
||||||
);
|
test_update_cafe_requires_authentication,
|
||||||
}
|
&[
|
||||||
|
"cafe",
|
||||||
|
"update",
|
||||||
|
"--id",
|
||||||
|
"some-id",
|
||||||
|
"--name",
|
||||||
|
"Updated Name"
|
||||||
|
]
|
||||||
|
);
|
||||||
|
define_cli_list_test!(
|
||||||
|
test_list_cafes_works_without_authentication,
|
||||||
|
&["cafe", "list"]
|
||||||
|
);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_add_cafe_with_authentication() {
|
fn test_add_cafe_with_authentication() {
|
||||||
|
|
@ -67,23 +77,6 @@ fn test_add_cafe_with_authentication() {
|
||||||
assert!(cafe["id"].is_i64(), "Should have an ID");
|
assert!(cafe["id"].is_i64(), "Should have an ID");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_list_cafes_works_without_authentication() {
|
|
||||||
let _ = server_info();
|
|
||||||
|
|
||||||
let output = run_brewlog(&["cafe", "list"], &[]);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
output.status.success(),
|
|
||||||
"cafe list should work without auth"
|
|
||||||
);
|
|
||||||
|
|
||||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
||||||
let cafes: Value = serde_json::from_str(&stdout).expect("Should output valid JSON array");
|
|
||||||
|
|
||||||
assert!(cafes.is_array(), "Should return an array");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_list_cafes_shows_added_cafe() {
|
fn test_list_cafes_shows_added_cafe() {
|
||||||
let token = create_token("test-list-cafes");
|
let token = create_token("test-list-cafes");
|
||||||
|
|
@ -112,37 +105,3 @@ fn test_list_cafes_shows_added_cafe() {
|
||||||
.any(|c| c["id"].as_i64().unwrap().to_string() == cafe_id);
|
.any(|c| c["id"].as_i64().unwrap().to_string() == cafe_id);
|
||||||
assert!(found, "Should find the added cafe in the list");
|
assert!(found, "Should find the added cafe in the list");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_delete_cafe_requires_authentication() {
|
|
||||||
let _ = server_info();
|
|
||||||
|
|
||||||
let output = run_brewlog(&["cafe", "delete", "--id", "some-id"], &[]);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
!output.status.success(),
|
|
||||||
"cafe delete without auth should fail"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_update_cafe_requires_authentication() {
|
|
||||||
let _ = server_info();
|
|
||||||
|
|
||||||
let output = run_brewlog(
|
|
||||||
&[
|
|
||||||
"cafe",
|
|
||||||
"update",
|
|
||||||
"--id",
|
|
||||||
"some-id",
|
|
||||||
"--name",
|
|
||||||
"Updated Name",
|
|
||||||
],
|
|
||||||
&[],
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
!output.status.success(),
|
|
||||||
"cafe update without auth should fail"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
use crate::helpers::{create_token, run_brewlog, server_info};
|
use crate::helpers::{create_token, run_brewlog};
|
||||||
|
use crate::test_macros::{define_cli_auth_test, define_cli_list_test};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
#[test]
|
define_cli_auth_test!(
|
||||||
fn test_add_gear_requires_authentication() {
|
test_add_gear_requires_authentication,
|
||||||
let _ = server_info();
|
|
||||||
|
|
||||||
let output = run_brewlog(
|
|
||||||
&[
|
&[
|
||||||
"gear",
|
"gear",
|
||||||
"add",
|
"add",
|
||||||
|
|
@ -14,16 +12,21 @@ fn test_add_gear_requires_authentication() {
|
||||||
"--make",
|
"--make",
|
||||||
"Baratza",
|
"Baratza",
|
||||||
"--model",
|
"--model",
|
||||||
"Encore",
|
"Encore"
|
||||||
],
|
]
|
||||||
&[],
|
);
|
||||||
);
|
define_cli_auth_test!(
|
||||||
|
test_update_gear_requires_authentication,
|
||||||
assert!(
|
&["gear", "update", "--id", "123", "--make", "Updated"]
|
||||||
!output.status.success(),
|
);
|
||||||
"gear add without auth should fail"
|
define_cli_auth_test!(
|
||||||
);
|
test_delete_gear_requires_authentication,
|
||||||
}
|
&["gear", "delete", "--id", "123"]
|
||||||
|
);
|
||||||
|
define_cli_list_test!(
|
||||||
|
test_list_gear_works_without_authentication,
|
||||||
|
&["gear", "list"]
|
||||||
|
);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_add_gear_with_authentication() {
|
fn test_add_gear_with_authentication() {
|
||||||
|
|
@ -52,18 +55,6 @@ fn test_add_gear_with_authentication() {
|
||||||
assert!(gear["id"].is_i64());
|
assert!(gear["id"].is_i64());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_list_gear_works_without_authentication() {
|
|
||||||
let _ = server_info();
|
|
||||||
|
|
||||||
let output = run_brewlog(&["gear", "list"], &[]);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
output.status.success(),
|
|
||||||
"gear list should work without auth"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_list_gear_shows_added_gear() {
|
fn test_list_gear_shows_added_gear() {
|
||||||
let token = create_token("test-list-gear");
|
let token = create_token("test-list-gear");
|
||||||
|
|
@ -179,18 +170,6 @@ fn test_get_gear_by_id() {
|
||||||
assert_eq!(retrieved_gear["model"], "EG-1");
|
assert_eq!(retrieved_gear["model"], "EG-1");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_update_gear_requires_authentication() {
|
|
||||||
let _ = server_info();
|
|
||||||
|
|
||||||
let output = run_brewlog(&["gear", "update", "--id", "123", "--make", "Updated"], &[]);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
!output.status.success(),
|
|
||||||
"gear update without auth should fail"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_update_gear_with_authentication() {
|
fn test_update_gear_with_authentication() {
|
||||||
let token = create_token("test-update-gear");
|
let token = create_token("test-update-gear");
|
||||||
|
|
@ -224,18 +203,6 @@ fn test_update_gear_with_authentication() {
|
||||||
assert_eq!(updated_gear["model"], "Mini II");
|
assert_eq!(updated_gear["model"], "Mini II");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_delete_gear_requires_authentication() {
|
|
||||||
let _ = server_info();
|
|
||||||
|
|
||||||
let output = run_brewlog(&["gear", "delete", "--id", "123"], &[]);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
!output.status.success(),
|
|
||||||
"gear delete without auth should fail"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_delete_gear_with_authentication() {
|
fn test_delete_gear_with_authentication() {
|
||||||
let token = create_token("test-delete-gear");
|
let token = create_token("test-delete-gear");
|
||||||
|
|
|
||||||
|
|
@ -209,32 +209,33 @@ pub fn run_brewlog(args: &[&str], env: &[(&str, &str)]) -> std::process::Output
|
||||||
cmd.output().expect("Failed to run brewlog command")
|
cmd.output().expect("Failed to run brewlog command")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper to create a roaster and return its ID
|
/// Generic helper: run a CLI command with auth, assert success, parse JSON, extract ID.
|
||||||
pub fn create_roaster(name: &str, token: &str) -> String {
|
fn create_entity_cli(args: &[&str], token: &str, label: &str) -> String {
|
||||||
let output = run_brewlog(
|
let output = run_brewlog(args, &[("BREWLOG_TOKEN", token)]);
|
||||||
&["roaster", "add", "--name", name, "--country", "UK"],
|
|
||||||
&[("BREWLOG_TOKEN", token)],
|
|
||||||
);
|
|
||||||
|
|
||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
panic!(
|
panic!(
|
||||||
"Failed to create roaster: {}",
|
"Failed to create {label}: {}",
|
||||||
String::from_utf8_lossy(&output.stderr)
|
String::from_utf8_lossy(&output.stderr)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||||
let roaster: serde_json::Value =
|
let value: serde_json::Value = serde_json::from_str(&stdout).expect("Should output valid JSON");
|
||||||
serde_json::from_str(&stdout).expect("Should output valid JSON");
|
value["id"]
|
||||||
roaster["id"]
|
|
||||||
.as_i64()
|
.as_i64()
|
||||||
.expect("roaster id should be numeric")
|
.unwrap_or_else(|| panic!("{label} id should be numeric"))
|
||||||
.to_string()
|
.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper to create a roast and return its ID
|
pub fn create_roaster(name: &str, token: &str) -> String {
|
||||||
|
create_entity_cli(
|
||||||
|
&["roaster", "add", "--name", name, "--country", "UK"],
|
||||||
|
token,
|
||||||
|
"roaster",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_roast(roaster_id: &str, name: &str, token: &str) -> String {
|
pub fn create_roast(roaster_id: &str, name: &str, token: &str) -> String {
|
||||||
let output = run_brewlog(
|
create_entity_cli(
|
||||||
&[
|
&[
|
||||||
"roast",
|
"roast",
|
||||||
"add",
|
"add",
|
||||||
|
|
@ -253,25 +254,11 @@ pub fn create_roast(roaster_id: &str, name: &str, token: &str) -> String {
|
||||||
"--tasting-notes",
|
"--tasting-notes",
|
||||||
"Blackcurrant",
|
"Blackcurrant",
|
||||||
],
|
],
|
||||||
&[("BREWLOG_TOKEN", token)],
|
token,
|
||||||
);
|
"roast",
|
||||||
|
)
|
||||||
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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper to create a cafe and return its ID
|
|
||||||
pub fn create_cafe(
|
pub fn create_cafe(
|
||||||
name: &str,
|
name: &str,
|
||||||
city: &str,
|
city: &str,
|
||||||
|
|
@ -280,7 +267,7 @@ pub fn create_cafe(
|
||||||
longitude: &str,
|
longitude: &str,
|
||||||
token: &str,
|
token: &str,
|
||||||
) -> String {
|
) -> String {
|
||||||
let output = run_brewlog(
|
create_entity_cli(
|
||||||
&[
|
&[
|
||||||
"cafe",
|
"cafe",
|
||||||
"add",
|
"add",
|
||||||
|
|
@ -295,20 +282,32 @@ pub fn create_cafe(
|
||||||
"--longitude",
|
"--longitude",
|
||||||
longitude,
|
longitude,
|
||||||
],
|
],
|
||||||
&[("BREWLOG_TOKEN", token)],
|
token,
|
||||||
);
|
"cafe",
|
||||||
|
)
|
||||||
if !output.status.success() {
|
}
|
||||||
panic!(
|
|
||||||
"Failed to create cafe: {}",
|
pub fn create_bag(roast_id: &str, token: &str) -> String {
|
||||||
String::from_utf8_lossy(&output.stderr)
|
create_entity_cli(
|
||||||
);
|
&["bag", "add", "--roast-id", roast_id, "--amount", "250"],
|
||||||
}
|
token,
|
||||||
|
"bag",
|
||||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
)
|
||||||
let cafe: serde_json::Value = serde_json::from_str(&stdout).expect("Should output valid JSON");
|
}
|
||||||
cafe["id"]
|
|
||||||
.as_i64()
|
pub fn create_gear(category: &str, make: &str, model: &str, token: &str) -> String {
|
||||||
.expect("cafe id should be numeric")
|
create_entity_cli(
|
||||||
.to_string()
|
&[
|
||||||
|
"gear",
|
||||||
|
"add",
|
||||||
|
"--category",
|
||||||
|
category,
|
||||||
|
"--make",
|
||||||
|
make,
|
||||||
|
"--model",
|
||||||
|
model,
|
||||||
|
],
|
||||||
|
token,
|
||||||
|
"gear",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,5 @@ pub mod gear_cli;
|
||||||
pub mod helpers;
|
pub mod helpers;
|
||||||
pub mod roasters_cli;
|
pub mod roasters_cli;
|
||||||
pub mod roasts_cli;
|
pub mod roasts_cli;
|
||||||
|
pub mod test_macros;
|
||||||
pub mod tokens_cli;
|
pub mod tokens_cli;
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,37 @@
|
||||||
use crate::helpers::{create_roaster, create_token, run_brewlog, server_info};
|
use crate::helpers::{create_roaster, create_token, run_brewlog};
|
||||||
|
use crate::test_macros::{define_cli_auth_test, define_cli_list_test};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
#[test]
|
define_cli_auth_test!(
|
||||||
fn test_add_roaster_requires_authentication() {
|
test_add_roaster_requires_authentication,
|
||||||
let _ = server_info(); // Ensure server is started
|
|
||||||
|
|
||||||
let output = run_brewlog(
|
|
||||||
&[
|
&[
|
||||||
"roaster",
|
"roaster",
|
||||||
"add",
|
"add",
|
||||||
"--name",
|
"--name",
|
||||||
"Test Roasters",
|
"Test Roasters",
|
||||||
"--country",
|
"--country",
|
||||||
"UK",
|
"UK"
|
||||||
],
|
]
|
||||||
&[],
|
);
|
||||||
);
|
define_cli_auth_test!(
|
||||||
|
test_delete_roaster_requires_authentication,
|
||||||
assert!(
|
&["roaster", "delete", "--id", "some-id"]
|
||||||
!output.status.success(),
|
);
|
||||||
"roaster add without auth should fail"
|
define_cli_auth_test!(
|
||||||
);
|
test_update_roaster_requires_authentication,
|
||||||
}
|
&[
|
||||||
|
"roaster",
|
||||||
|
"update",
|
||||||
|
"--id",
|
||||||
|
"some-id",
|
||||||
|
"--name",
|
||||||
|
"Updated Name"
|
||||||
|
]
|
||||||
|
);
|
||||||
|
define_cli_list_test!(
|
||||||
|
test_list_roasters_works_without_authentication,
|
||||||
|
&["roaster", "list"]
|
||||||
|
);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_add_roaster_with_authentication() {
|
fn test_add_roaster_with_authentication() {
|
||||||
|
|
@ -54,23 +64,6 @@ fn test_add_roaster_with_authentication() {
|
||||||
assert!(roaster["id"].is_i64(), "Should have an ID");
|
assert!(roaster["id"].is_i64(), "Should have an ID");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_list_roasters_works_without_authentication() {
|
|
||||||
let _ = server_info();
|
|
||||||
|
|
||||||
let output = run_brewlog(&["roaster", "list"], &[]);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
output.status.success(),
|
|
||||||
"roaster list should work without auth"
|
|
||||||
);
|
|
||||||
|
|
||||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
||||||
let roasters: Value = serde_json::from_str(&stdout).expect("Should output valid JSON array");
|
|
||||||
|
|
||||||
assert!(roasters.is_array(), "Should return an array");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_list_roasters_shows_added_roaster() {
|
fn test_list_roasters_shows_added_roaster() {
|
||||||
let token = create_token("test-list-roasters");
|
let token = create_token("test-list-roasters");
|
||||||
|
|
@ -96,37 +89,3 @@ fn test_list_roasters_shows_added_roaster() {
|
||||||
.any(|r| r["id"].as_i64().unwrap().to_string() == roaster_id);
|
.any(|r| r["id"].as_i64().unwrap().to_string() == roaster_id);
|
||||||
assert!(found, "Should find the added roaster in the list");
|
assert!(found, "Should find the added roaster in the list");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_delete_roaster_requires_authentication() {
|
|
||||||
let _ = server_info();
|
|
||||||
|
|
||||||
let output = run_brewlog(&["roaster", "delete", "--id", "some-id"], &[]);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
!output.status.success(),
|
|
||||||
"roaster delete without auth should fail"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_update_roaster_requires_authentication() {
|
|
||||||
let _ = server_info();
|
|
||||||
|
|
||||||
let output = run_brewlog(
|
|
||||||
&[
|
|
||||||
"roaster",
|
|
||||||
"update",
|
|
||||||
"--id",
|
|
||||||
"some-id",
|
|
||||||
"--name",
|
|
||||||
"Updated Name",
|
|
||||||
],
|
|
||||||
&[],
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
!output.status.success(),
|
|
||||||
"roaster update without auth should fail"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
use crate::helpers::{create_roast, create_roaster, create_token, run_brewlog, server_info};
|
use crate::helpers::{create_roast, create_roaster, create_token, run_brewlog};
|
||||||
|
use crate::test_macros::{define_cli_auth_test, define_cli_list_test};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
#[test]
|
define_cli_auth_test!(
|
||||||
fn test_add_roast_requires_authentication() {
|
test_add_roast_requires_authentication,
|
||||||
let _ = server_info();
|
|
||||||
|
|
||||||
let output = run_brewlog(
|
|
||||||
&[
|
&[
|
||||||
"roast",
|
"roast",
|
||||||
"add",
|
"add",
|
||||||
|
|
@ -20,16 +18,21 @@ fn test_add_roast_requires_authentication() {
|
||||||
"--producer",
|
"--producer",
|
||||||
"Local Coop",
|
"Local Coop",
|
||||||
"--process",
|
"--process",
|
||||||
"Washed",
|
"Washed"
|
||||||
],
|
]
|
||||||
&[],
|
);
|
||||||
);
|
define_cli_auth_test!(
|
||||||
|
test_update_roast_requires_authentication,
|
||||||
assert!(
|
&["roast", "update", "--id", "123", "--name", "Updated"]
|
||||||
!output.status.success(),
|
);
|
||||||
"roast add without auth should fail"
|
define_cli_auth_test!(
|
||||||
);
|
test_delete_roast_requires_authentication,
|
||||||
}
|
&["roast", "delete", "--id", "some-id"]
|
||||||
|
);
|
||||||
|
define_cli_list_test!(
|
||||||
|
test_list_roasts_works_without_authentication,
|
||||||
|
&["roast", "list"]
|
||||||
|
);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_add_roast_with_authentication() {
|
fn test_add_roast_with_authentication() {
|
||||||
|
|
@ -78,23 +81,6 @@ fn test_add_roast_with_authentication() {
|
||||||
assert!(roast["id"].is_i64(), "Should have an ID");
|
assert!(roast["id"].is_i64(), "Should have an ID");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_list_roasts_works_without_authentication() {
|
|
||||||
let _ = server_info();
|
|
||||||
|
|
||||||
let output = run_brewlog(&["roast", "list"], &[]);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
output.status.success(),
|
|
||||||
"roast list should work without auth"
|
|
||||||
);
|
|
||||||
|
|
||||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
||||||
let roasts: Value = serde_json::from_str(&stdout).expect("Should output valid JSON array");
|
|
||||||
|
|
||||||
assert!(roasts.is_array(), "Should return an array");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_list_roasts_shows_added_roast() {
|
fn test_list_roasts_shows_added_roast() {
|
||||||
let token = create_token("test-list-roasts");
|
let token = create_token("test-list-roasts");
|
||||||
|
|
@ -156,21 +142,6 @@ fn test_list_roasts_shows_added_roast() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_update_roast_requires_authentication() {
|
|
||||||
let _ = server_info();
|
|
||||||
|
|
||||||
let output = run_brewlog(
|
|
||||||
&["roast", "update", "--id", "123", "--name", "Updated"],
|
|
||||||
&[],
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
!output.status.success(),
|
|
||||||
"roast update without auth should fail"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_update_roast_with_authentication() {
|
fn test_update_roast_with_authentication() {
|
||||||
let token = create_token("test-update-roast");
|
let token = create_token("test-update-roast");
|
||||||
|
|
@ -196,15 +167,3 @@ fn test_update_roast_with_authentication() {
|
||||||
let updated_roast: Value = serde_json::from_slice(&output.stdout).unwrap();
|
let updated_roast: Value = serde_json::from_slice(&output.stdout).unwrap();
|
||||||
assert_eq!(updated_roast["name"], "Updated Name");
|
assert_eq!(updated_roast["name"], "Updated Name");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_delete_roast_requires_authentication() {
|
|
||||||
let _ = server_info();
|
|
||||||
|
|
||||||
let output = run_brewlog(&["roast", "delete", "--id", "some-id"], &[]);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
!output.status.success(),
|
|
||||||
"roast delete without auth should fail"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
40
tests/cli/test_macros.rs
Normal file
40
tests/cli/test_macros.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
/// Generates a test that asserts a CLI command fails without authentication.
|
||||||
|
macro_rules! define_cli_auth_test {
|
||||||
|
($name:ident, $args:expr) => {
|
||||||
|
#[test]
|
||||||
|
fn $name() {
|
||||||
|
let _ = crate::helpers::server_info();
|
||||||
|
let output = crate::helpers::run_brewlog($args, &[]);
|
||||||
|
assert!(
|
||||||
|
!output.status.success(),
|
||||||
|
"{} should require authentication",
|
||||||
|
stringify!($name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generates a test that asserts a CLI list command succeeds without
|
||||||
|
/// authentication and returns a valid JSON array.
|
||||||
|
macro_rules! define_cli_list_test {
|
||||||
|
($name:ident, $args:expr) => {
|
||||||
|
#[test]
|
||||||
|
fn $name() {
|
||||||
|
let _ = crate::helpers::server_info();
|
||||||
|
let output = crate::helpers::run_brewlog($args, &[]);
|
||||||
|
assert!(
|
||||||
|
output.status.success(),
|
||||||
|
"{} should succeed: {}",
|
||||||
|
stringify!($name),
|
||||||
|
String::from_utf8_lossy(&output.stderr)
|
||||||
|
);
|
||||||
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||||
|
let items: serde_json::Value =
|
||||||
|
serde_json::from_str(&stdout).expect("Should output valid JSON");
|
||||||
|
assert!(items.is_array(), "Should return a JSON array");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) use define_cli_auth_test;
|
||||||
|
pub(crate) use define_cli_list_test;
|
||||||
|
|
@ -1,16 +1,11 @@
|
||||||
use crate::helpers::{create_token, run_brewlog, server_info};
|
use crate::helpers::{create_token, run_brewlog};
|
||||||
|
use crate::test_macros::define_cli_auth_test;
|
||||||
|
|
||||||
#[test]
|
define_cli_auth_test!(test_list_tokens_requires_authentication, &["token", "list"]);
|
||||||
fn test_list_tokens_requires_authentication() {
|
define_cli_auth_test!(
|
||||||
let _ = server_info();
|
test_revoke_token_requires_authentication,
|
||||||
|
&["token", "revoke", "--id", "1"]
|
||||||
let output = run_brewlog(&["token", "list"], &[]);
|
);
|
||||||
|
|
||||||
assert!(
|
|
||||||
!output.status.success(),
|
|
||||||
"token list without auth should fail"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_list_tokens_with_authentication() {
|
fn test_list_tokens_with_authentication() {
|
||||||
|
|
@ -30,18 +25,6 @@ fn test_list_tokens_with_authentication() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_revoke_token_requires_authentication() {
|
|
||||||
let _ = server_info();
|
|
||||||
|
|
||||||
let output = run_brewlog(&["token", "revoke", "--id", "1"], &[]);
|
|
||||||
|
|
||||||
assert!(
|
|
||||||
!output.status.success(),
|
|
||||||
"token revoke without auth should fail"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_revoke_token_with_authentication() {
|
fn test_revoke_token_with_authentication() {
|
||||||
let token = create_token("test-revoke-token");
|
let token = create_token("test-revoke-token");
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue