mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-06 22:21:29 +02:00
Three independent root causes behind the divergences the reporter flagged after the archived-spool fix shipped — fixed together. (1) Filament Used vs Total Consumed. _compute_run_filament_grams returned the slicer estimate for completed prints even when inventory had measured the actual AMS weight delta. That made Stats and Inventory two different sources of truth: Stats showed slicer-estimate grams, Inventory showed AMS-tracked grams, and the two never agreed. Reordered the helper so the tracked spool delta (same source that drives weight_used behind Total Consumed) takes priority for every status. Slicer estimate stays as the fallback when no inventory was tracked; partial-progress scale stays as the fallback for failed/cancelled with no tracker. The _run_cost block right next to it was already tracker-first; only filament_used_grams was inconsistent. (2) Printer Stats By Time vs Quick Stats Print Time. /archives/slim only set actual_time_seconds when status == "completed". For failed/cancelled rows the frontend fell back to print_time_seconds (the slicer's full-print estimate — wrong number for a print that failed at 15%). Quick Stats already summed elapsed duration across all statuses, so the two halves of the page disagreed by the (estimate - actual-elapsed) gap on every non-completed event. Dropped the completed-only gate; failed/cancelled now report measured elapsed. (3) Success Rate %. Was successful / (successful + failed), excluding cancelled / stopped from the denominator. With "Total Prints: N" displayed right above the gauge that produced confusing numbers — 4 successful, 0 failed, 48 cancelled showed 100% out of an apparent 52 prints. Switched to successful / total_prints — matches the count the user reads from the widget header.
72 lines
3.7 KiB
Python
72 lines
3.7 KiB
Python
"""Unit tests for the per-run filament helper (#1378, #1390).
|
||
|
||
The helper computes what value to write into PrintLogEntry.filament_used_grams
|
||
for a given print event — partial-aware so failed / cancelled / stopped prints
|
||
don't inflate stats with the full slicer estimate, and tracker-aware so
|
||
completed prints agree with the per-spool counter on the Inventory page.
|
||
"""
|
||
|
||
from backend.app.main import _compute_run_filament_grams
|
||
|
||
|
||
class TestComputeRunFilamentGrams:
|
||
def test_completed_no_tracker_returns_archive_estimate(self):
|
||
# Completed print without inventory tracking: the slicer estimate is
|
||
# the canonical "this print used X" value.
|
||
assert _compute_run_filament_grams("completed", 100.0, 100, []) == 100.0
|
||
|
||
def test_completed_prefers_tracked_over_estimate(self):
|
||
# #1390: when inventory tracked the AMS weight delta, Stats should
|
||
# reflect that — same source that drives "Total Consumed" on the
|
||
# Inventory page. Two halves of the app must show the same number.
|
||
assert _compute_run_filament_grams("completed", 100.0, 100, [{"weight_used": 96.5}]) == 96.5
|
||
|
||
def test_failed_uses_tracked_spool_delta(self):
|
||
# Failed reprint at 10g actual: inventory tracked the spool delta.
|
||
# The estimate was 100g; we want 10g recorded for stats.
|
||
assert _compute_run_filament_grams("failed", 100.0, 10, [{"weight_used": 10.0}]) == 10.0
|
||
|
||
def test_cancelled_uses_tracked_spool_delta(self):
|
||
# Same logic for cancelled.
|
||
assert _compute_run_filament_grams("cancelled", 100.0, 12, [{"weight_used": 8.5}]) == 8.5
|
||
|
||
def test_stopped_uses_tracked_spool_delta(self):
|
||
assert _compute_run_filament_grams("stopped", 100.0, 15, [{"weight_used": 12.0}]) == 12.0
|
||
|
||
def test_failed_with_no_tracked_falls_back_to_progress_scale(self):
|
||
# No inventory tracking: scale estimate by progress% (10% of 100g = 10g).
|
||
assert _compute_run_filament_grams("failed", 100.0, 10, []) == 10.0
|
||
|
||
def test_failed_with_no_tracked_and_no_progress_returns_none(self):
|
||
# Nothing to infer from — return None rather than guess the estimate.
|
||
assert _compute_run_filament_grams("failed", 100.0, 0, []) is None
|
||
|
||
def test_failed_with_partial_progress_rounds_correctly(self):
|
||
# 100g × 33% = 33.0g (rounded to 1 decimal)
|
||
assert _compute_run_filament_grams("failed", 100.0, 33, []) == 33.0
|
||
|
||
def test_failed_with_no_estimate_returns_none(self):
|
||
# No estimate, no tracked usage → can't compute anything.
|
||
assert _compute_run_filament_grams("failed", None, 50, []) is None
|
||
|
||
def test_failed_with_no_estimate_but_tracked_uses_tracked(self):
|
||
# Tracked spool delta is authoritative even without an estimate.
|
||
assert _compute_run_filament_grams("failed", None, 50, [{"weight_used": 5.0}]) == 5.0
|
||
|
||
def test_tracked_overrides_progress_scale_when_both_available(self):
|
||
# If inventory says 8g but progress says 15g, trust inventory (it's measured).
|
||
assert _compute_run_filament_grams("failed", 100.0, 15, [{"weight_used": 8.0}]) == 8.0
|
||
|
||
def test_progress_above_100_clamps_to_full_estimate(self):
|
||
# Defensive: progress overshoot doesn't multiply past the estimate.
|
||
assert _compute_run_filament_grams("failed", 100.0, 150, []) == 100.0
|
||
|
||
def test_multiple_tracked_slots_summed(self):
|
||
# Multi-filament print, two slots tracked.
|
||
usage = [{"weight_used": 5.0}, {"weight_used": 3.5}, {"weight_used": 1.0}]
|
||
assert _compute_run_filament_grams("failed", 100.0, 20, usage) == 9.5
|
||
|
||
def test_completed_with_none_estimate_returns_none(self):
|
||
# Archive somehow has no estimate (rare; archive_print parsed nothing).
|
||
assert _compute_run_filament_grams("completed", None, 100, []) is None
|