Rewrite the printer Zabbix integration (Bearer auth, host-by-IP, tag-based supply lookup, ping) and replace the hardcoded toner table with a modelsupplies table + CRUD + seed. Add mock Zabbix server, live test harness, and the Playwright screenshot tooling. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
122 lines
4.3 KiB
Python
122 lines
4.3 KiB
Python
"""Tests for the model-supplies (toner part-number) management API."""
|
|
|
|
import pytest
|
|
|
|
|
|
@pytest.fixture
|
|
def model(db):
|
|
"""A vendor + printer model to attach supplies to."""
|
|
from shopdb.core.models import Vendor, Model
|
|
|
|
vendor = Vendor(vendor='TestVendor')
|
|
db.session.add(vendor)
|
|
db.session.flush()
|
|
|
|
model = Model(modelnumber='TestModel C999', vendorid=vendor.vendorid)
|
|
db.session.add(model)
|
|
db.session.commit()
|
|
return model
|
|
|
|
|
|
def test_supplies_meta_lists_allowed_values(client, db):
|
|
response = client.get('/api/printers/supplies/meta')
|
|
assert response.status_code == 200
|
|
data = response.get_json()['data']
|
|
assert 'toner' in data['supplytypes']
|
|
assert 'black' in data['colors']
|
|
assert 'metered' in data['capacitytiers']
|
|
|
|
|
|
def test_create_and_list_model_supply(client, model, auth_headers):
|
|
create = client.post(
|
|
f'/api/printers/models/{model.modelnumberid}/supplies',
|
|
json={
|
|
'supplytype': 'toner', 'color': 'black', 'capacitytier': 'standard',
|
|
'partnumber': 'W2020A', 'marketingname': '414A Black', 'pageyield': 2400,
|
|
},
|
|
headers=auth_headers,
|
|
)
|
|
assert create.status_code == 201
|
|
|
|
listing = client.get(f'/api/printers/models/{model.modelnumberid}/supplies')
|
|
assert listing.status_code == 200
|
|
supplies = listing.get_json()['data']['supplies']
|
|
assert len(supplies) == 1
|
|
assert supplies[0]['partnumber'] == 'W2020A'
|
|
|
|
|
|
def test_duplicate_partnumber_rejected(client, model, auth_headers):
|
|
payload = {'partnumber': 'W2020A', 'color': 'black'}
|
|
client.post(f'/api/printers/models/{model.modelnumberid}/supplies',
|
|
json=payload, headers=auth_headers)
|
|
second = client.post(f'/api/printers/models/{model.modelnumberid}/supplies',
|
|
json=payload, headers=auth_headers)
|
|
assert second.status_code == 409
|
|
|
|
|
|
def test_invalid_enum_rejected(client, model, auth_headers):
|
|
response = client.post(
|
|
f'/api/printers/models/{model.modelnumberid}/supplies',
|
|
json={'partnumber': 'X1', 'color': 'purple'},
|
|
headers=auth_headers,
|
|
)
|
|
assert response.status_code == 400
|
|
|
|
|
|
def test_create_requires_auth(client, model):
|
|
response = client.post(
|
|
f'/api/printers/models/{model.modelnumberid}/supplies',
|
|
json={'partnumber': 'X1'},
|
|
)
|
|
assert response.status_code == 401
|
|
|
|
|
|
def test_update_and_delete_supply(client, model, auth_headers):
|
|
created = client.post(
|
|
f'/api/printers/models/{model.modelnumberid}/supplies',
|
|
json={'partnumber': 'W2020A', 'color': 'black', 'capacitytier': 'standard'},
|
|
headers=auth_headers,
|
|
).get_json()['data']
|
|
supplyid = created['modelsupplyid']
|
|
|
|
updated = client.put(
|
|
f'/api/printers/supplies/{supplyid}',
|
|
json={'capacitytier': 'high', 'marketingname': '414X Black'},
|
|
headers=auth_headers,
|
|
)
|
|
assert updated.status_code == 200
|
|
assert updated.get_json()['data']['capacitytier'] == 'high'
|
|
|
|
deleted = client.delete(f'/api/printers/supplies/{supplyid}', headers=auth_headers)
|
|
assert deleted.status_code == 200
|
|
|
|
listing = client.get(f'/api/printers/models/{model.modelnumberid}/supplies')
|
|
assert listing.get_json()['data']['supplies'] == []
|
|
|
|
|
|
def test_listmodels_reports_supplycount(client, model, auth_headers):
|
|
client.post(f'/api/printers/models/{model.modelnumberid}/supplies',
|
|
json={'partnumber': 'W2020A', 'color': 'black'}, headers=auth_headers)
|
|
|
|
response = client.get('/api/printers/models', query_string={'search': 'C999'})
|
|
assert response.status_code == 200
|
|
rows = response.get_json()['data']
|
|
match = next(r for r in rows if r['modelnumberid'] == model.modelnumberid)
|
|
assert match['supplycount'] == 1
|
|
|
|
|
|
def test_seed_supplies_corrected_data(app, db):
|
|
"""The seed loads corrected part numbers (C405 colors, no B405 waste)."""
|
|
with app.app_context():
|
|
from plugins.printers.services import seedsupplies, lookupsupplies
|
|
from shopdb.core.models import Model
|
|
|
|
seedsupplies()
|
|
|
|
c405 = Model.query.filter(Model.modelnumber.ilike('%C405%')).first()
|
|
yellow = lookupsupplies(c405.modelnumberid, 'yellow', 'toner')
|
|
assert any(s['partnumber'] == '106R03501' for s in yellow)
|
|
|
|
b405 = Model.query.filter(Model.modelnumber.ilike('%B405%')).first()
|
|
assert lookupsupplies(b405.modelnumberid, 'none', 'waste') == []
|