Shadow task fixes, asset link ids, backup verdict
This commit is contained in:
@@ -9,7 +9,8 @@ purchasing decision.
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
from plugins.printers.services.supply_history import (
|
||||
analyse, burn_rate, current_run, find_replacements, normalise, soonest,
|
||||
analyse, band, burn_rate, current_run, find_replacements, normalise,
|
||||
orderlist, soonest,
|
||||
)
|
||||
|
||||
START = datetime(2026, 6, 1, tzinfo=timezone.utc)
|
||||
@@ -170,6 +171,91 @@ def test_burn_rate_needs_elapsed_time():
|
||||
assert burn_rate(points) is None
|
||||
|
||||
|
||||
def cartridge(daysleft, partnumber='CF258X', color='black', printername='PRN',
|
||||
model='HP 428', printerid=1):
|
||||
parts = [{'partnumber': partnumber, 'marketingname': None,
|
||||
'capacitytier': 'standard'}] if partnumber else []
|
||||
return {'daysleft': daysleft, 'partnumbers': parts, 'color': color,
|
||||
'supplytype': 'toner', 'model': model, 'printerid': printerid,
|
||||
'printername': printername}
|
||||
|
||||
|
||||
def test_bands_split_at_two_weeks_and_a_month():
|
||||
assert band(0) == 'empty'
|
||||
assert band(1) == 'soon'
|
||||
assert band(14) == 'soon'
|
||||
assert band(15) == 'month'
|
||||
assert band(30) == 'month'
|
||||
assert band(31) == 'later'
|
||||
|
||||
|
||||
def test_no_estimate_belongs_to_no_band():
|
||||
assert band(None) is None
|
||||
|
||||
|
||||
def test_the_same_part_in_two_printers_is_a_quantity_of_two():
|
||||
"""The number purchasing needs, and the one a per-printer table makes you
|
||||
count by hand."""
|
||||
result = orderlist([cartridge(0, printername='A', printerid=1),
|
||||
cartridge(3, printername='B', printerid=2)])
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0]['quantity'] == 2
|
||||
assert [p['printername'] for p in result[0]['printers']] == ['A', 'B']
|
||||
|
||||
|
||||
def test_the_order_list_stops_at_the_horizon():
|
||||
"""Ordering only what is already empty means running empty; ordering three
|
||||
months out is a stock cupboard."""
|
||||
result = orderlist([cartridge(0), cartridge(90, partnumber='W2021A')])
|
||||
|
||||
assert [item['partnumber'] for item in result] == ['CF258X']
|
||||
|
||||
|
||||
def test_a_cartridge_with_no_part_mapped_is_still_on_the_list():
|
||||
"""Dropping it would quietly shorten the order."""
|
||||
result = orderlist([cartridge(2, partnumber=None)])
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0]['partnumber'] is None
|
||||
assert result[0]['quantity'] == 1
|
||||
|
||||
|
||||
def test_unmapped_parts_sort_last():
|
||||
"""They need a decision before anything can be ordered, so they do not sit
|
||||
at the top of a list meant to be read straight down."""
|
||||
result = orderlist([cartridge(1, partnumber=None), cartridge(1)])
|
||||
|
||||
assert result[0]['partnumber'] == 'CF258X'
|
||||
assert result[-1]['partnumber'] is None
|
||||
|
||||
|
||||
def test_alternate_capacity_tiers_are_offered_not_counted_separately():
|
||||
item = {**cartridge(1), 'partnumbers': [
|
||||
{'partnumber': 'CF258A', 'marketingname': None, 'capacitytier': 'standard'},
|
||||
{'partnumber': 'CF258X', 'marketingname': None, 'capacitytier': 'high'},
|
||||
]}
|
||||
|
||||
result = orderlist([item])
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0]['partnumber'] == 'CF258A'
|
||||
assert result[0]['alternates'] == ['CF258X']
|
||||
|
||||
|
||||
def test_the_same_part_for_a_different_model_is_ordered_separately():
|
||||
"""Two models sharing a part number is a mapping error worth seeing, not a
|
||||
quantity to merge."""
|
||||
result = orderlist([cartridge(1, model='HP 428'),
|
||||
cartridge(1, model='HP M454')])
|
||||
|
||||
assert len(result) == 2
|
||||
|
||||
|
||||
def test_no_estimate_never_reaches_the_order_list():
|
||||
assert orderlist([cartridge(None)]) == []
|
||||
|
||||
|
||||
def test_forecast_endpoint_says_so_when_zabbix_is_absent(client, db):
|
||||
"""A dashboard must be told the data is missing, not shown an empty list
|
||||
that reads as 'nothing runs out soon'."""
|
||||
@@ -179,4 +265,5 @@ def test_forecast_endpoint_says_so_when_zabbix_is_absent(client, db):
|
||||
body = response.get_json()['data']
|
||||
assert body['available'] is False
|
||||
assert 'not configured' in body['reason']
|
||||
assert body['printers'] == []
|
||||
assert body['cartridges'] == []
|
||||
assert body['orderlist'] == []
|
||||
|
||||
Reference in New Issue
Block a user