99 lines
4.5 KiB
Python
99 lines
4.5 KiB
Python
|
|
"""Non-regression tests for the P1 issues found during the UI audit.
|
||
|
|
|
||
|
|
The audit VM is not available in this environment; these tests exercise the
|
||
|
|
same routes against the local Flask test database.
|
||
|
|
"""
|
||
|
|
|
||
|
|
from app_new.extensions import db
|
||
|
|
from app_new.core.models.college import Building, Zone, Room
|
||
|
|
from app_new.core.models.maintenance import Intervention
|
||
|
|
from app_new.core.models.cleaning import ProductGeneric
|
||
|
|
|
||
|
|
|
||
|
|
def test_room_form_lists_buildings_and_rejects_cross_building_zone(authenticated_client, app):
|
||
|
|
authenticated_client.post('/equipments/buildings/new', data={'name': 'UI test bâtiment A'})
|
||
|
|
authenticated_client.post('/equipments/buildings/new', data={'name': 'UI test bâtiment B'})
|
||
|
|
with app.app_context():
|
||
|
|
building_a = Building.query.filter_by(name="UI test bâtiment A").one()
|
||
|
|
building_b = Building.query.filter_by(name="UI test bâtiment B").one()
|
||
|
|
zone_b = Zone(name="UI test zone B", building_id=building_b.id)
|
||
|
|
db.session.add(zone_b)
|
||
|
|
db.session.commit()
|
||
|
|
a_id, b_id, zone_id = building_a.id, building_b.id, zone_b.id
|
||
|
|
|
||
|
|
response = authenticated_client.get("/equipments/rooms/new")
|
||
|
|
assert response.status_code == 200
|
||
|
|
body = response.get_data(as_text=True)
|
||
|
|
assert "UI test bâtiment A" in body
|
||
|
|
assert "UI test bâtiment B" in body
|
||
|
|
|
||
|
|
response = authenticated_client.post("/equipments/rooms/new", data={
|
||
|
|
"name": "Salle incohérente",
|
||
|
|
"building_id": str(a_id),
|
||
|
|
"zone_id": str(zone_id),
|
||
|
|
})
|
||
|
|
assert response.status_code == 400
|
||
|
|
with app.app_context():
|
||
|
|
assert Room.query.filter_by(name="Salle incohérente").first() is None
|
||
|
|
|
||
|
|
|
||
|
|
def test_optional_location_is_safe_in_interventions(authenticated_client, app):
|
||
|
|
with app.app_context():
|
||
|
|
intervention = Intervention(title="UI intervention sans localisation")
|
||
|
|
db.session.add(intervention)
|
||
|
|
db.session.commit()
|
||
|
|
assert authenticated_client.get("/interventions/").status_code == 200
|
||
|
|
|
||
|
|
|
||
|
|
def test_optional_equipment_is_safe_on_dashboard(authenticated_client, app):
|
||
|
|
with app.app_context():
|
||
|
|
db.session.add(Intervention(title="UI dashboard sans équipement"))
|
||
|
|
db.session.commit()
|
||
|
|
assert authenticated_client.get("/").status_code == 200
|
||
|
|
|
||
|
|
|
||
|
|
def test_intervention_detail_template_exposes_document_actions():
|
||
|
|
template = open('app_new/interventions/templates/detail.html', encoding='utf-8').read()
|
||
|
|
assert 'documents.download_intervention_document' in template
|
||
|
|
assert 'documents.delete_intervention_document' in template
|
||
|
|
assert 'documents.upload_intervention' in template
|
||
|
|
|
||
|
|
|
||
|
|
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("/companies/new", data={}).status_code == 400
|
||
|
|
|
||
|
|
|
||
|
|
def test_invalid_product_quantity_is_validation_error(authenticated_client, app):
|
||
|
|
authenticated_client.post('/cleaning/products/new', data={
|
||
|
|
'name': 'UI produit quantité invalide',
|
||
|
|
'reference_unit': 'unité',
|
||
|
|
'stock_minimum': '0', 'stock_security': '0', 'forecast_daily_quantity': '0',
|
||
|
|
})
|
||
|
|
with app.app_context():
|
||
|
|
product = ProductGeneric.query.filter_by(name="UI produit quantité invalide").one()
|
||
|
|
product_id = product.id
|
||
|
|
response = authenticated_client.post(f"/cleaning/products/{product_id}/edit", data={
|
||
|
|
"name": "UI produit quantité invalide",
|
||
|
|
"stock_minimum": "pas-un-nombre",
|
||
|
|
"stock_security": "0",
|
||
|
|
"forecast_daily_quantity": "0",
|
||
|
|
})
|
||
|
|
assert response.status_code == 400
|
||
|
|
assert "numériques" in response.get_data(as_text=True)
|
||
|
|
|
||
|
|
|
||
|
|
def test_cleaning_pages_load_without_reference_data(authenticated_client, app):
|
||
|
|
# Some legacy RBAC tests intentionally alter the admin role. Restore only
|
||
|
|
# the permission required by this independent route smoke test.
|
||
|
|
with app.app_context():
|
||
|
|
from app_new.core.models.rbac import Role, Permission, RolePermission
|
||
|
|
role = Role.query.filter_by(slug='admin').first()
|
||
|
|
permission = Permission.query.filter_by(code='stock.view').first()
|
||
|
|
if role and permission and not RolePermission.query.filter_by(role_id=role.id, permission_id=permission.id).first():
|
||
|
|
db.session.add(RolePermission(role_id=role.id, permission_id=permission.id, effect='allow'))
|
||
|
|
db.session.commit()
|
||
|
|
assert authenticated_client.get("/cleaning/transvasement").status_code == 200
|
||
|
|
assert authenticated_client.get("/cleaning/forecast-config").status_code == 200
|
||
|
|
assert authenticated_client.get("/cleaning/stock").status_code == 200
|