diff --git a/templates/pages/edit_bag.html b/templates/pages/edit_bag.html
index ddb43e9..d21a39e 100644
--- a/templates/pages/edit_bag.html
+++ b/templates/pages/edit_bag.html
@@ -15,7 +15,7 @@
data-signals:_submit-error="''"
data-signals:_roast-date="'{{ roast_date }}'"
data-signals:_amount="{{ amount }}"
- data-on:submit="$_submitting = true; $_submitError = ''; @put('/api/v1/bags/{{ id }}')"
+ data-on:submit="$_submitting = true; $_submitError = ''; @put('/api/v1/bags/{{ id }}', {contentType: 'form'})"
data-on:datastar-fetch="if (!$_submitting) return;
if (evt.detail.type === 'finished') { $_submitting = false; sessionStorage.setItem('toast', 'Bag updated'); window.location.href = evt.detail.response.headers.get('location') || '/bags/{{ id }}' }
else if (evt.detail.type === 'error') { $_submitting = false; $_submitError = 'Failed to save changes.' }"
diff --git a/templates/pages/edit_brew.html b/templates/pages/edit_brew.html
index 3186979..d2dbed8 100644
--- a/templates/pages/edit_brew.html
+++ b/templates/pages/edit_brew.html
@@ -19,8 +19,13 @@
data-signals:_water-volume="{{ water_volume }}"
data-signals:_water-temp="{{ water_temp }}"
data-signals:_brew-time="{{ brew_time }}"
- data-signals:_quick-notes="'{{ quick_notes }}'"
- data-on:submit="$_submitting = true; $_submitError = ''; @put('/api/v1/brews/{{ id }}')"
+ data-signals:_qn-good="{% if quick_notes.contains("good") %}true{% else %}false{% endif %}"
+ data-signals:_qn-too-fast="{% if quick_notes.contains("too-fast") %}true{% else %}false{% endif %}"
+ data-signals:_qn-too-slow="{% if quick_notes.contains("too-slow") %}true{% else %}false{% endif %}"
+ data-signals:_qn-too-hot="{% if quick_notes.contains("too-hot") %}true{% else %}false{% endif %}"
+ data-signals:_qn-under-extracted="{% if quick_notes.contains("under-extracted") %}true{% else %}false{% endif %}"
+ data-signals:_qn-over-extracted="{% if quick_notes.contains("over-extracted") %}true{% else %}false{% endif %}"
+ data-on:submit="$_submitting = true; $_submitError = ''; @put('/api/v1/brews/{{ id }}', {contentType: 'form'})"
data-on:datastar-fetch="if (!$_submitting) return;
if (evt.detail.type === 'finished') { $_submitting = false; sessionStorage.setItem('toast', 'Brew updated'); window.location.href = evt.detail.response.headers.get('location') || '/brews/{{ id }}' }
else if (evt.detail.type === 'error') { $_submitting = false; $_submitError = 'Failed to save changes.' }"
@@ -301,19 +306,55 @@
Quick Notes
-
+ Good
+
+
+
+
+
+
+
+
{{ img::deferred_upload("edit-brew-image", "Brew Image") }}
diff --git a/templates/pages/edit_cafe.html b/templates/pages/edit_cafe.html
index 6112002..6e43c7a 100644
--- a/templates/pages/edit_cafe.html
+++ b/templates/pages/edit_cafe.html
@@ -20,7 +20,7 @@
data-signals:_latitude="{{ latitude }}"
data-signals:_longitude="{{ longitude }}"
data-signals:_website="'{{ website }}'"
- data-on:submit="$_submitting = true; $_submitError = ''; @put('/api/v1/cafes/{{ id }}')"
+ data-on:submit="$_submitting = true; $_submitError = ''; @put('/api/v1/cafes/{{ id }}', {contentType: 'form'})"
data-on:datastar-fetch="if (!$_submitting) return;
if (evt.detail.type === 'finished') { $_submitting = false; sessionStorage.setItem('toast', 'Cafe updated'); window.location.href = evt.detail.response.headers.get('location') || '/cafes/{{ id }}' }
else if (evt.detail.type === 'error') { $_submitting = false; $_submitError = 'Failed to save changes.' }"
diff --git a/templates/pages/edit_cup.html b/templates/pages/edit_cup.html
index aacf872..e92c829 100644
--- a/templates/pages/edit_cup.html
+++ b/templates/pages/edit_cup.html
@@ -14,7 +14,7 @@
class="flex flex-col gap-4"
data-signals:_submitting="false"
data-signals:_submit-error="''"
- data-on:submit="$_submitting = true; $_submitError = ''; @put('/api/v1/cups/{{ id }}')"
+ data-on:submit="$_submitting = true; $_submitError = ''; @put('/api/v1/cups/{{ id }}', {contentType: 'form'})"
data-on:datastar-fetch="if (!$_submitting) return;
if (evt.detail.type === 'finished') { $_submitting = false; sessionStorage.setItem('toast', 'Cup updated'); window.location.href = evt.detail.response.headers.get('location') || '/cups/{{ id }}' }
else if (evt.detail.type === 'error') { $_submitting = false; $_submitError = 'Failed to save changes.' }"
diff --git a/templates/pages/edit_gear.html b/templates/pages/edit_gear.html
index 2ff71ee..6db4047 100644
--- a/templates/pages/edit_gear.html
+++ b/templates/pages/edit_gear.html
@@ -16,7 +16,7 @@
data-signals:_submit-error="''"
data-signals:_make="'{{ make }}'"
data-signals:_model="'{{ model }}'"
- data-on:submit="$_submitting = true; $_submitError = ''; @put('/api/v1/gear/{{ id }}')"
+ data-on:submit="$_submitting = true; $_submitError = ''; @put('/api/v1/gear/{{ id }}', {contentType: 'form'})"
data-on:datastar-fetch="if (!$_submitting) return;
if (evt.detail.type === 'finished') { $_submitting = false; sessionStorage.setItem('toast', 'Gear updated'); window.location.href = evt.detail.response.headers.get('location') || '/gear/{{ id }}' }
else if (evt.detail.type === 'error') { $_submitting = false; $_submitError = 'Failed to save changes.' }"
diff --git a/templates/pages/edit_roast.html b/templates/pages/edit_roast.html
index 1eabd74..2234f34 100644
--- a/templates/pages/edit_roast.html
+++ b/templates/pages/edit_roast.html
@@ -20,7 +20,7 @@
data-signals:_producer="'{{ producer }}'"
data-signals:_process="'{{ process }}'"
data-signals:_tasting-notes="'{{ tasting_notes }}'"
- data-on:submit="$_submitting = true; $_submitError = ''; @put('/api/v1/roasts/{{ id }}')"
+ data-on:submit="$_submitting = true; $_submitError = ''; @put('/api/v1/roasts/{{ id }}', {contentType: 'form'})"
data-on:datastar-fetch="if (!$_submitting) return;
if (evt.detail.type === 'finished') { $_submitting = false; sessionStorage.setItem('toast', 'Roast updated'); window.location.href = evt.detail.response.headers.get('location') || '/roasts/{{ id }}' }
else if (evt.detail.type === 'error') { $_submitting = false; $_submitError = 'Failed to save changes.' }"
diff --git a/templates/pages/edit_roaster.html b/templates/pages/edit_roaster.html
index a99d7ba..6ca7b3f 100644
--- a/templates/pages/edit_roaster.html
+++ b/templates/pages/edit_roaster.html
@@ -18,7 +18,7 @@
data-signals:_country="'{{ country }}'"
data-signals:_city="'{{ city }}'"
data-signals:_homepage="'{{ homepage }}'"
- data-on:submit="$_submitting = true; $_submitError = ''; @put('/api/v1/roasters/{{ id }}')"
+ data-on:submit="$_submitting = true; $_submitError = ''; @put('/api/v1/roasters/{{ id }}', {contentType: 'form'})"
data-on:datastar-fetch="if (!$_submitting) return;
if (evt.detail.type === 'finished') { $_submitting = false; sessionStorage.setItem('toast', 'Roaster updated'); window.location.href = evt.detail.response.headers.get('location') || '/roasters/{{ id }}' }
else if (evt.detail.type === 'error') { $_submitting = false; $_submitError = 'Failed to save changes.' }"
diff --git a/tests/cli/brews_cli.rs b/tests/cli/brews_cli.rs
index fabb10a..fe66e44 100644
--- a/tests/cli/brews_cli.rs
+++ b/tests/cli/brews_cli.rs
@@ -1,6 +1,7 @@
use crate::helpers::{
- create_bag, create_gear, create_roast, create_roaster, create_token, run_brewlog,
+ create_bag, create_brew, create_gear, create_roast, create_roaster, create_token, run_brewlog,
};
+use crate::test_macros::define_cli_auth_test;
#[test]
fn brew_add_creates_brew_via_api() {
@@ -235,3 +236,45 @@ fn brew_delete_removes_brew() {
"brew get should fail after deletion"
);
}
+
+define_cli_auth_test!(
+ test_update_brew_requires_authentication,
+ &["brew", "update", "--id", "123", "--coffee-weight", "16.0"]
+);
+
+#[test]
+fn test_update_brew_with_authentication() {
+ let token = create_token("test-update-brew");
+ let roaster_id = create_roaster("Update Brew Roaster", &token);
+ let roast_id = create_roast(&roaster_id, "Update Brew Roast", &token);
+ let bag_id = create_bag(&roast_id, &token);
+ let grinder_id = create_gear("grinder", "Weber", "Key", &token);
+ let brewer_id = create_gear("brewer", "Origami", "Air", &token);
+ let brew_id = create_brew(&bag_id, &grinder_id, &brewer_id, &token);
+
+ let output = run_brewlog(
+ &[
+ "brew",
+ "update",
+ "--id",
+ &brew_id,
+ "--coffee-weight",
+ "16.0",
+ "--water-temp",
+ "94.0",
+ ],
+ &[("BREWLOG_TOKEN", &token)],
+ );
+
+ assert!(
+ output.status.success(),
+ "brew update should succeed: {}",
+ String::from_utf8_lossy(&output.stderr)
+ );
+
+ let stdout = String::from_utf8_lossy(&output.stdout);
+ let brew: serde_json::Value = serde_json::from_str(&stdout).expect("Should output valid JSON");
+
+ assert_eq!(brew["coffee_weight"], 16.0);
+ assert_eq!(brew["water_temp"], 94.0);
+}
diff --git a/tests/cli/cups_cli.rs b/tests/cli/cups_cli.rs
new file mode 100644
index 0000000..96af9fb
--- /dev/null
+++ b/tests/cli/cups_cli.rs
@@ -0,0 +1,36 @@
+use crate::helpers::{
+ create_cafe, create_cup, create_roast, create_roaster, create_token, run_brewlog,
+};
+use crate::test_macros::define_cli_auth_test;
+
+define_cli_auth_test!(
+ test_update_cup_requires_authentication,
+ &["cup", "update", "--id", "123", "--roast-id", "1"]
+);
+
+#[test]
+fn test_update_cup_with_authentication() {
+ let token = create_token("test-update-cup");
+ let roaster_id = create_roaster("Update Cup Roaster", &token);
+ let roast_id = create_roast(&roaster_id, "Update Cup Roast", &token);
+ let cafe_id = create_cafe("Update Cup Cafe", "London", "UK", "51.5", "-0.1", &token);
+ let cup_id = create_cup(&roast_id, &cafe_id, &token);
+
+ // Create a second roast to update the cup to
+ let roast_id_2 = create_roast(&roaster_id, "Update Cup Roast 2", &token);
+
+ let output = run_brewlog(
+ &["cup", "update", "--id", &cup_id, "--roast-id", &roast_id_2],
+ &[("BREWLOG_TOKEN", &token)],
+ );
+
+ assert!(
+ output.status.success(),
+ "cup update should succeed: {}",
+ String::from_utf8_lossy(&output.stderr)
+ );
+
+ let stdout = String::from_utf8_lossy(&output.stdout);
+ let cup: serde_json::Value = serde_json::from_str(&stdout).expect("Should output valid JSON");
+ assert!(cup["id"].is_i64(), "cup should have an id");
+}
diff --git a/tests/cli/helpers.rs b/tests/cli/helpers.rs
index 0e935b4..6ebaf2c 100644
--- a/tests/cli/helpers.rs
+++ b/tests/cli/helpers.rs
@@ -316,3 +316,28 @@ pub fn create_gear(category: &str, make: &str, model: &str, token: &str) -> Stri
"gear",
)
}
+
+pub fn create_brew(bag_id: &str, grinder_id: &str, brewer_id: &str, token: &str) -> String {
+ create_entity_cli(
+ &[
+ "brew",
+ "add",
+ "--bag-id",
+ bag_id,
+ "--grinder-id",
+ grinder_id,
+ "--brewer-id",
+ brewer_id,
+ ],
+ token,
+ "brew",
+ )
+}
+
+pub fn create_cup(roast_id: &str, cafe_id: &str, token: &str) -> String {
+ create_entity_cli(
+ &["cup", "add", "--roast-id", roast_id, "--cafe-id", cafe_id],
+ token,
+ "cup",
+ )
+}
diff --git a/tests/cli/main.rs b/tests/cli/main.rs
index 23d2ca6..e19073f 100644
--- a/tests/cli/main.rs
+++ b/tests/cli/main.rs
@@ -2,6 +2,7 @@ pub mod backup_cli;
pub mod bags_cli;
pub mod brews_cli;
pub mod cafes_cli;
+pub mod cups_cli;
pub mod gear_cli;
pub mod helpers;
pub mod roasters_cli;