Files
cantarire-etichetare/tests/test_fields.py
T
ske087 bff6d70b17 Initial commit: aplicatie de cantarire si etichetare
Aplicatie Flask + SQLite pentru productie alimentara: cantarirea
componentelor unui produs finit si tiparirea etichetei prin QZ Tray.

- produse finite (retete) formate din componente cantarite
- designer vizual de etichete (mm/px, zona sigura, campuri variabile,
  cod QR cu continut din mai multe bucati)
- legare produs finit -> sablon de eticheta
- navigare pe doua taburi: Cantarire / Setari
- administrare: componente, produse finite, sabloane, campuri, istoric
- backup, resetare baza de date, checklist de pregatire, /healthz
- CLI de administrare si serviciu systemd pentru productie
- vendor/syncpulse-scale-bridge (GPL-3.0-or-later) pentru citirea cantarului
2026-10-18 23:38:45 +03:00

191 lines
7.7 KiB
Python

"""Campuri variabile proprii (custom.*): CRUD, validare si randare pe eticheta."""
from __future__ import annotations
import json
import pytest
from cantarire import designer
def _create_field(client, label="Contact firmă", template="Tel. {{company.phone}}",
active="on"):
return client.post("/campuri/nou", data={
"label": label, "template": template, "active": active,
}, follow_redirects=True)
def test_fields_page_and_nav(client):
page = client.get("/campuri")
assert page.status_code == 200
html = page.get_data(as_text=True)
assert "Câmpuri variabile" in html
assert 'href="/campuri/nou"' in html
# link in subnavigatia din Setari, nu in bara principala
flat = " ".join(html.split())
assert 'href="/campuri"' in flat
assert ">Câmpuri</a>" in flat
def test_create_field_generates_key_and_shows_preview(client):
_create_field(client)
html = client.get("/campuri").get_data(as_text=True)
assert "Contact firmă" in html
assert "custom.contact_firma" in html
assert "Tel. 0700 000 000" in html # rezultatul demo
with client.application.app_context():
from cantarire.repositories import get_label_field_by_key
row = get_label_field_by_key("custom.contact_firma")
assert row is not None and row["active"] == 1
def test_duplicate_labels_get_unique_keys(client):
_create_field(client, label="Alergeni", template="Poate conține gluten")
_create_field(client, label="Alergeni", template="Poate conține lactoză")
with client.application.app_context():
from cantarire.repositories import list_label_fields
keys = [row["key"] for row in list_label_fields()]
assert keys == ["custom.alergeni", "custom.alergeni_2"]
def test_unknown_placeholder_is_rejected(client):
response = _create_field(client, label="Greșit", template="X {{does.not.exist}}")
html = response.get_data(as_text=True)
assert "Campuri necunoscute" in html
with client.application.app_context():
from cantarire.repositories import list_label_fields
assert list_label_fields() == []
def test_empty_template_is_rejected(client):
response = _create_field(client, label="Gol", template=" ")
assert "Textul campului este obligatoriu." in response.get_data(as_text=True)
def test_update_keeps_key_and_can_deactivate(client):
_create_field(client)
with client.application.app_context():
from cantarire.repositories import get_label_field_by_key
field_id = get_label_field_by_key("custom.contact_firma")["id"]
client.post(f"/campuri/{field_id}/editare", data={
"label": "Contact (nou)", "template": "{{company.phone}}",
}, follow_redirects=True)
with client.application.app_context():
from cantarire.repositories import get_label_field, list_label_fields
row = get_label_field(field_id)
assert row["label"] == "Contact (nou)"
assert row["key"] == "custom.contact_firma" # cheia ramane stabila
assert row["active"] == 0 # fara bifa = inactiv
assert [f["key"] for f in list_label_fields()] == [] # ascuns din designer
def test_delete_field(client):
_create_field(client, label="Șters", template="text")
with client.application.app_context():
from cantarire.repositories import get_label_field_by_key
field_id = get_label_field_by_key("custom.sters")["id"]
response = client.post(f"/campuri/{field_id}/stergere", follow_redirects=True)
assert "a fost sters" in response.get_data(as_text=True)
with client.application.app_context():
from cantarire.repositories import get_label_field_by_key
assert get_label_field_by_key("custom.sters") is None
def test_preview_endpoint(client):
ok = client.get("/campuri/previzualizare",
query_string={"template": "{{recipe.name}} · {{package.lot}}"})
assert ok.get_json() == {"ok": True, "value": "Fasole cu carne · LOT-2610-A"}
bad = client.get("/campuri/previzualizare", query_string={"template": "{{nope.x}}"})
data = bad.get_json()
assert data["ok"] is False and "Campuri necunoscute" in data["error"]
def test_custom_field_is_offered_in_designer_picker(client):
_create_field(client, label="Contact firmă", template="Tel. {{company.phone}}")
response = client.post("/sabloane/designer/nou", data={"name": "Cu camp propriu"},
follow_redirects=True)
assert response.status_code == 200
html = response.get_data(as_text=True)
assert "custom.contact_firma" in html
assert "Tel. 0700 000 000" in html # sample pentru previzualizare
# denumirea trece prin tojson, deci diacriticele sunt escapate
assert "Contact firm\\u0103" in html
def test_custom_field_renders_on_label(client):
_create_field(client, label="Contact", template="Tel. {{company.phone}}")
design = designer.validate_design({
"width_mm": 100, "height_mm": 60,
"blocks": [
{"type": "field", "x": 3, "y": 3, "w": 70, "h": 6, "field": "custom.contact"},
],
}, 100, 60)
assert design["blocks"][0]["field"] == "custom.contact"
with client.application.app_context():
from cantarire.repositories import list_label_fields
fields = designer.apply_custom_fields(designer.demo_fields(), list_label_fields())
html = designer.render_design(design, fields, [])
assert "Tel. 0700 000 000" in html
def test_deleted_custom_field_renders_empty_not_wrong(client):
"""Un design care refera un camp sters nu trebuie sa cada sau sa afiseze altceva."""
design = designer.validate_design({
"width_mm": 100, "height_mm": 60,
"blocks": [{"type": "field", "x": 3, "y": 3, "w": 70, "h": 6, "field": "custom.sters"}],
}, 100, 60)
assert design["blocks"][0]["field"] == "custom.sters"
html = designer.render_design(design, designer.demo_fields(), [])
assert "Fasole cu carne" not in html # nu cade pe alt camp
assert "> <" in html or html.count("d-field") == 1
def test_custom_field_template_rejects_custom_reference():
"""Campurile proprii se pot referi doar la campuri fixe (fara bucle)."""
errors = designer.custom_template_errors("X {{custom.altceva}}")
assert errors and "Campuri necunoscute" in errors[0]
assert designer.custom_template_errors("{{company.phone}}") == []
@pytest.mark.parametrize("text,expected", [
("", ""),
("text simplu", "text simplu"),
("{{company.name}}", "Moto Adv SRL"),
("{{ package.lot }}/{{package.operator}}", "LOT-2610-A/Maria"),
])
def test_expand_custom(text, expected):
assert designer.expand_custom(text, designer.demo_fields()) == expected
def test_usage_counter_reports_templates(client):
_create_field(client, label="Folosit", template="X")
client.post("/sabloane/designer/nou", data={"name": "Cu folosit"})
with client.application.app_context():
from cantarire.repositories import (count_label_field_usage, get_default_template,
get_label_field_by_key, list_templates,
save_template_design)
field = get_label_field_by_key("custom.folosit")
target = [t for t in list_templates() if t["name"] == "Cu folosit"][0]
payload = {"version": 1, "width_mm": 100, "height_mm": 60, "blocks": [
{"id": "b1", "type": "field", "x": 1, "y": 1, "w": 50, "h": 6,
"field": "custom.folosit"},
]}
save_template_design(target["id"], json.dumps(payload))
assert count_label_field_usage(field["key"]) == 1
assert count_label_field_usage("custom.inexistent") == 0
assert get_default_template() is not None