fix(rbac): masquer le lien journaux sans permission
This commit is contained in:
parent
864f65d3e0
commit
f2783a05c8
2 changed files with 81 additions and 1 deletions
|
|
@ -129,7 +129,7 @@
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- Notifications système : interprétations et watchdogs -->
|
<!-- Notifications système : interprétations et watchdogs -->
|
||||||
{% if has_permission('audit.view') %}<a href="/logs/" class="btn btn-sm btn-outline-light me-2 position-relative" title="Notifications système et logs watchdogs" aria-label="Notifications système et logs watchdogs">
|
{% if has_permission('watchdog_dnd.view') %}<a href="/logs/" class="btn btn-sm btn-outline-light me-2 position-relative" title="Notifications système et logs watchdogs" aria-label="Notifications système et logs watchdogs">
|
||||||
<i class="bi bi-journal-text"></i>
|
<i class="bi bi-journal-text"></i>
|
||||||
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger" id="notif-count" style="font-size:0.6rem; display:none;">0</span>
|
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger" id="notif-count" style="font-size:0.6rem; display:none;">0</span>
|
||||||
</a>{% endif %}
|
</a>{% endif %}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ from app_new.extensions import db
|
||||||
from app_new.core.models.college import Building, Zone, Room
|
from app_new.core.models.college import Building, Zone, Room
|
||||||
from app_new.core.models.maintenance import Intervention
|
from app_new.core.models.maintenance import Intervention
|
||||||
from app_new.core.models.cleaning import ProductGeneric
|
from app_new.core.models.cleaning import ProductGeneric
|
||||||
|
from app_new.core.models.equipment import Equipment, EquipmentCategory
|
||||||
|
|
||||||
|
|
||||||
def test_room_form_lists_buildings_and_rejects_cross_building_zone(authenticated_client, app):
|
def test_room_form_lists_buildings_and_rejects_cross_building_zone(authenticated_client, app):
|
||||||
|
|
@ -45,6 +46,44 @@ def test_optional_location_is_safe_in_interventions(authenticated_client, app):
|
||||||
assert authenticated_client.get("/interventions/").status_code == 200
|
assert authenticated_client.get("/interventions/").status_code == 200
|
||||||
|
|
||||||
|
|
||||||
|
def test_intervention_list_supports_all_optional_location_combinations(authenticated_client, app):
|
||||||
|
"""Une intervention peut cibler salle, équipement, les deux ou aucun."""
|
||||||
|
with app.app_context():
|
||||||
|
building = Building(name="UI combinations building")
|
||||||
|
db.session.add(building)
|
||||||
|
db.session.flush()
|
||||||
|
room = Room(name="UI combinations room", building_id=building.id)
|
||||||
|
category = EquipmentCategory(name="UI combinations category")
|
||||||
|
db.session.add_all([room, category])
|
||||||
|
db.session.flush()
|
||||||
|
equipment = Equipment(
|
||||||
|
name="UI combinations equipment", room_id=room.id,
|
||||||
|
category_id=category.id, status="en_service",
|
||||||
|
)
|
||||||
|
db.session.add(equipment)
|
||||||
|
db.session.flush()
|
||||||
|
interventions = [
|
||||||
|
Intervention(title="UI both", room_id=room.id, equipment_id=equipment.id),
|
||||||
|
Intervention(title="UI room only", room_id=room.id),
|
||||||
|
Intervention(title="UI equipment only", equipment_id=equipment.id),
|
||||||
|
Intervention(title="UI neither"),
|
||||||
|
]
|
||||||
|
db.session.add_all(interventions)
|
||||||
|
db.session.commit()
|
||||||
|
intervention_ids = [intervention.id for intervention in interventions]
|
||||||
|
|
||||||
|
response = authenticated_client.get("/interventions/")
|
||||||
|
assert response.status_code == 200
|
||||||
|
source = open("app_new/interventions/templates/index.html", encoding="utf-8").read()
|
||||||
|
assert "Localisation non renseignée" in source
|
||||||
|
from app_new.interventions.crud import detail as intervention_detail
|
||||||
|
with app.app_context(), app.test_request_context("/interventions/1"):
|
||||||
|
for intervention_id in intervention_ids:
|
||||||
|
rendered = intervention_detail.__wrapped__(intervention_id)
|
||||||
|
assert "Intervention" in rendered or "Localisation" in rendered
|
||||||
|
assert authenticated_client.get("/").status_code == 200
|
||||||
|
|
||||||
|
|
||||||
def test_optional_equipment_is_safe_on_dashboard(authenticated_client, app):
|
def test_optional_equipment_is_safe_on_dashboard(authenticated_client, app):
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
db.session.add(Intervention(title="UI dashboard sans équipement"))
|
db.session.add(Intervention(title="UI dashboard sans équipement"))
|
||||||
|
|
@ -59,6 +98,47 @@ def test_intervention_detail_template_exposes_document_actions():
|
||||||
assert 'documents.upload_intervention' in template
|
assert 'documents.upload_intervention' in template
|
||||||
|
|
||||||
|
|
||||||
|
def test_logs_navigation_uses_the_permission_required_by_logs_route():
|
||||||
|
from app_new.core.authorization import required_permission
|
||||||
|
|
||||||
|
assert required_permission("logs.index", "GET") == "watchdog_dnd.view"
|
||||||
|
source = open("app_new/templates/base.html", encoding="utf-8").read()
|
||||||
|
assert "has_permission('watchdog_dnd.view')" in source
|
||||||
|
assert "has_permission('audit.view')" not in source[source.find("Notifications système") - 200:source.find("Notifications système") + 200]
|
||||||
|
|
||||||
|
|
||||||
|
def test_grouped_equipment_detail_and_hierarchy(authenticated_client, app):
|
||||||
|
"""Une famille quantitative localisée doit rester consultable."""
|
||||||
|
with app.app_context():
|
||||||
|
building = Building(name="UI equipment detail building")
|
||||||
|
db.session.add(building)
|
||||||
|
db.session.flush()
|
||||||
|
room = Room(name="UI equipment detail room", building_id=building.id)
|
||||||
|
category = EquipmentCategory(name="UI equipment detail category")
|
||||||
|
db.session.add_all([room, category])
|
||||||
|
db.session.flush()
|
||||||
|
equipment = Equipment(
|
||||||
|
name="UI grouped chairs", room_id=room.id, category_id=category.id,
|
||||||
|
status="en_service", is_group=False, quantity=30, mobility="mobile",
|
||||||
|
)
|
||||||
|
db.session.add(equipment)
|
||||||
|
db.session.commit()
|
||||||
|
equipment_id = equipment.id
|
||||||
|
assert db.session.get(Equipment, equipment_id) is not None
|
||||||
|
db.session.remove()
|
||||||
|
|
||||||
|
from app_new.equipments.main import detail as equipment_detail, hierarchy as equipment_hierarchy
|
||||||
|
with app.app_context(), app.test_request_context(f"/equipments/{equipment_id}"):
|
||||||
|
detail_response = equipment_detail.__wrapped__(equipment_id)
|
||||||
|
assert "UI grouped chairs" in detail_response
|
||||||
|
hierarchy_response = equipment_hierarchy.__wrapped__(equipment_id)
|
||||||
|
assert hierarchy_response.status_code == 200
|
||||||
|
payload = hierarchy_response.get_json()
|
||||||
|
assert payload["zones"]
|
||||||
|
assert payload["zones"][0]["rooms"][0]["name"] == "UI equipment detail room"
|
||||||
|
assert payload["zones"][0]["rooms"][0]["items"][0]["quantity"] == 30
|
||||||
|
|
||||||
|
|
||||||
def test_empty_intervention_and_company_are_validation_errors(authenticated_client):
|
def test_empty_intervention_and_company_are_validation_errors(authenticated_client):
|
||||||
assert authenticated_client.post("/interventions/new", data={}).status_code == 400
|
assert authenticated_client.post("/interventions/new", data={}).status_code == 400
|
||||||
assert authenticated_client.post("/companies/new", data={}).status_code == 400
|
assert authenticated_client.post("/companies/new", data={}).status_code == 400
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue