"""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" 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