"""Configuration et génération des planches de badges (API).""" import base64 from app.models import Role from tests.factories import dt_at, make_position, make_shift, make_volunteer # PNG 1×1 valide (transparent), le plus petit possible. _PNG = base64.b64decode( "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY" "42YAAAAASUVORK5CYII=" ) def _badges_url(edition): return f"/editions/{edition.id}/badges" def _set_full_name_field(client, edition): return client.put( f"{_badges_url(edition)}/template/fields", json={ "fields": [ { "field_type": "FULL_NAME", "x_mm": 5, "y_mm": 5, "width_mm": 60, "height_mm": 10, "font_size": 12, } ] }, ) def test_template_is_coordinator_only(edition, make_account, as_account): lead = make_account(Role.LEAD, email="lead@e.fr") client = as_account(lead) assert client.get(f"{_badges_url(edition)}/template").status_code == 403 resp = client.put(f"{_badges_url(edition)}/template/fields", json={"fields": []}) assert resp.status_code == 403 def test_template_starts_empty(client, edition): resp = client.get(f"{_badges_url(edition)}/template") assert resp.status_code == 200 body = resp.json() assert body["has_front_image"] is False assert body["has_back_image"] is False assert body["fields"] == [] def test_uploading_front_and_back_images(client, edition): front = client.put( f"{_badges_url(edition)}/template/front-image", files={"file": ("front.png", _PNG, "image/png")}, ) assert front.status_code == 200 assert front.json()["has_front_image"] is True back = client.put( f"{_badges_url(edition)}/template/back-image", files={"file": ("back.png", _PNG, "image/png")}, ) assert back.status_code == 200 assert back.json()["has_back_image"] is True served = client.get(f"{_badges_url(edition)}/template/front-image") assert served.status_code == 200 assert served.headers["content-type"] == "image/png" assert served.content == _PNG def test_uploading_an_unsupported_image_type_is_rejected(client, edition): resp = client.put( f"{_badges_url(edition)}/template/front-image", files={"file": ("front.gif", b"not-a-real-gif", "image/gif")}, ) assert resp.status_code == 422 assert resp.json()["detail"]["code"] == "badge.image_type_not_supported" def test_setting_the_same_field_type_twice_is_rejected(client, edition): resp = client.put( f"{_badges_url(edition)}/template/fields", json={ "fields": [ { "field_type": "FULL_NAME", "x_mm": 0, "y_mm": 0, "width_mm": 10, "height_mm": 10, }, { "field_type": "FULL_NAME", "x_mm": 5, "y_mm": 5, "width_mm": 10, "height_mm": 10, }, ] }, ) assert resp.status_code == 422 assert resp.json()["detail"]["code"] == "badge.duplicate_field_type" def test_generating_without_any_field_configured_is_rejected(client, edition, session): make_volunteer(session, edition, first_name="Alex", last_name="Martin") resp = client.post(f"{_badges_url(edition)}/generate", json={}) assert resp.status_code == 422 assert resp.json()["detail"]["code"] == "badge.no_fields" def test_generating_with_no_matching_volunteers_is_rejected(client, edition, session): _set_full_name_field(client, edition) make_volunteer(session, edition, first_name="Alex", last_name="Martin") resp = client.post( f"{_badges_url(edition)}/generate", json={"volunteer_ids": ["00000000-0000-0000-0000-000000000000"]}, ) assert resp.status_code == 422 assert resp.json()["detail"]["code"] == "badge.no_volunteers" def test_generating_produces_a_pdf(client, edition, session): from app.models import Assignment resp = client.put( f"{_badges_url(edition)}/template/fields", json={ "fields": [ { "field_type": "FULL_NAME", "x_mm": 5, "y_mm": 5, "width_mm": 60, "height_mm": 10, "font_size": 12, }, { "field_type": "POSITIONS", "x_mm": 5, "y_mm": 20, "width_mm": 60, "height_mm": 10, "font_size": 9, }, ] }, ) assert resp.status_code == 200 client.put( f"{_badges_url(edition)}/template/front-image", files={"file": ("front.png", _PNG, "image/png")}, ) client.put( f"{_badges_url(edition)}/template/back-image", files={"file": ("back.png", _PNG, "image/png")}, ) volunteer = make_volunteer(session, edition, first_name="Alex", last_name="Martin") position = make_position(session, edition, name="Bar central") shift = make_shift(session, edition, position, start=dt_at(9, 18), end=dt_at(9, 22)) session.add(Assignment(edition_id=edition.id, volunteer_id=volunteer.id, shift_id=shift.id)) session.commit() resp = client.post( f"{_badges_url(edition)}/generate", json={"volunteer_ids": [str(volunteer.id)]}, ) assert resp.status_code == 200 assert resp.headers["content-type"] == "application/pdf" assert resp.content.startswith(b"%PDF")