2026-08-14 23:24:42 +02:00
|
|
|
from uuid import uuid4
|
|
|
|
|
|
|
|
|
|
from app_new.extensions import db
|
2026-08-15 01:12:51 +02:00
|
|
|
from app_new.core.models.college import Building, HousingUnit, HousingOccupancy, Room, Zone
|
2026-08-14 23:24:42 +02:00
|
|
|
from app_new.core.models.equipment import Equipment, EquipmentCategory
|
|
|
|
|
from app_new.core.models.maintenance import Lot
|
|
|
|
|
from app_new.wizard.routes import bulk_create_equipments, equipment_wizard
|
|
|
|
|
from app_new.housing.routes import detail as housing_detail
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _location():
|
|
|
|
|
suffix = uuid4().hex[:8]
|
|
|
|
|
building = Building(name=f"Logements {suffix}")
|
|
|
|
|
db.session.add(building)
|
|
|
|
|
db.session.flush()
|
|
|
|
|
zone = Zone(name="Habitation", building_id=building.id)
|
|
|
|
|
db.session.add(zone)
|
|
|
|
|
db.session.flush()
|
|
|
|
|
rooms = [Room(name=name, building_id=building.id, zone_id=zone.id) for name in ("Séjour", "Cuisine")]
|
|
|
|
|
db.session.add_all(rooms)
|
|
|
|
|
db.session.flush()
|
|
|
|
|
return building, rooms
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_housing_groups_rooms_and_is_available_in_navigation(app):
|
|
|
|
|
with app.app_context():
|
|
|
|
|
building, rooms = _location()
|
|
|
|
|
unit = HousingUnit(name="Logement de fonction", building_id=building.id)
|
|
|
|
|
db.session.add(unit)
|
|
|
|
|
db.session.flush()
|
|
|
|
|
for room in rooms:
|
|
|
|
|
room.housing_unit_id = unit.id
|
|
|
|
|
db.session.commit()
|
|
|
|
|
with app.test_request_context(f"/housing/{unit.id}"):
|
|
|
|
|
response = housing_detail.__wrapped__(unit.id)
|
|
|
|
|
assert "Séjour" in response
|
|
|
|
|
assert "Inventorier" in response
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_bulk_inventory_creates_room_groups_and_individual_units(app):
|
|
|
|
|
with app.app_context():
|
|
|
|
|
_, rooms = _location()
|
|
|
|
|
category = EquipmentCategory(name=f"Luminaire {uuid4().hex[:6]}")
|
|
|
|
|
lot = Lot(name=f"Lot éclairage {uuid4().hex[:6]}", category=category)
|
|
|
|
|
db.session.add_all([category, lot])
|
|
|
|
|
db.session.commit()
|
|
|
|
|
payload = {"room_ids": [r.id for r in rooms], "items": [{
|
|
|
|
|
"name": "Luminaire", "category_id": category.id, "lot_id": lot.id,
|
|
|
|
|
"quantity": 2, "mode": "individuel", "mobility": "fixe",
|
|
|
|
|
}]}
|
|
|
|
|
with app.test_request_context(json=payload):
|
|
|
|
|
response = bulk_create_equipments.__wrapped__()
|
|
|
|
|
assert response.status_code == 200
|
|
|
|
|
root = Equipment.query.filter_by(name="Luminaire", parent_id=None).order_by(Equipment.id.desc()).first()
|
|
|
|
|
assert root.quantity == 4
|
|
|
|
|
assert root.children.count() == 2
|
|
|
|
|
assert all(group.children.count() == 2 for group in root.children)
|
|
|
|
|
assert all(unit.effective_lot_id == lot.id for group in root.children for unit in group.children)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_bulk_inventory_rolls_back_everything_when_one_line_is_invalid(app):
|
|
|
|
|
with app.app_context():
|
|
|
|
|
_, rooms = _location()
|
|
|
|
|
category = EquipmentCategory(name=f"Test {uuid4().hex[:6]}")
|
|
|
|
|
lot = Lot(name=f"Lot test {uuid4().hex[:6]}", category=category)
|
|
|
|
|
db.session.add_all([category, lot])
|
|
|
|
|
db.session.commit()
|
|
|
|
|
before = Equipment.query.count()
|
|
|
|
|
payload = {"room_ids": [rooms[0].id], "items": [
|
|
|
|
|
{"name": "Valide", "category_id": category.id, "lot_id": lot.id, "quantity": 1},
|
|
|
|
|
{"name": "Invalide", "category_id": 0, "lot_id": lot.id, "quantity": 1},
|
|
|
|
|
]}
|
|
|
|
|
with app.test_request_context(json=payload):
|
|
|
|
|
_, status = bulk_create_equipments.__wrapped__()
|
|
|
|
|
assert status == 400
|
|
|
|
|
assert Equipment.query.count() == before
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_guided_inventory_page_renders_with_housing_preselection(app):
|
|
|
|
|
with app.app_context():
|
|
|
|
|
building, rooms = _location()
|
|
|
|
|
unit = HousingUnit(name=f"Logement {uuid4().hex[:6]}", building_id=building.id)
|
|
|
|
|
db.session.add(unit)
|
|
|
|
|
db.session.flush()
|
|
|
|
|
rooms[0].housing_unit_id = unit.id
|
|
|
|
|
db.session.commit()
|
|
|
|
|
with app.test_request_context(f"/wizard/equipments?housing_id={unit.id}"):
|
|
|
|
|
html = equipment_wizard.__wrapped__()
|
|
|
|
|
assert "Inventaire guidé" in html
|
|
|
|
|
assert f"[{rooms[0].id}]" in html
|
2026-08-15 01:12:51 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_housing_keeps_occupancy_history(authenticated_client, app):
|
|
|
|
|
with app.app_context():
|
|
|
|
|
building, _ = _location()
|
|
|
|
|
building_id = building.id
|
|
|
|
|
db.session.commit()
|
|
|
|
|
response = authenticated_client.post('/housing/new', data={
|
|
|
|
|
'name': 'Logement historique', 'code': f'H-{uuid4().hex[:6]}',
|
|
|
|
|
'building_id': building_id, 'occupancy_status': 'occupe',
|
|
|
|
|
'occupant_name': 'Occupant test', 'occupancy_start': '2026-08-01',
|
|
|
|
|
'key_count': '3', 'entry_condition': 'Bon état',
|
|
|
|
|
})
|
|
|
|
|
assert response.status_code == 302
|
|
|
|
|
with app.app_context():
|
|
|
|
|
unit = HousingUnit.query.filter_by(name='Logement historique').one()
|
|
|
|
|
occupancy = HousingOccupancy.query.filter_by(housing_unit_id=unit.id).one()
|
|
|
|
|
assert occupancy.key_count == 3
|
|
|
|
|
assert occupancy.entry_condition == 'Bon état'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_occupied_housing_model_can_be_inserted(app):
|
|
|
|
|
with app.app_context():
|
|
|
|
|
building, _ = _location()
|
|
|
|
|
unit = HousingUnit(name='Insertion occupée', code=f'I-{uuid4().hex[:6]}',
|
|
|
|
|
building_id=building.id, occupancy_status='occupe',
|
|
|
|
|
occupant_name='Test', occupancy_start=None)
|
|
|
|
|
db.session.add(unit)
|
|
|
|
|
db.session.commit()
|
|
|
|
|
assert unit.id
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_inventory_hierarchy_is_loaded_on_demand(authenticated_client, app):
|
|
|
|
|
with app.app_context():
|
|
|
|
|
building, rooms = _location()
|
|
|
|
|
category = EquipmentCategory(name=f"Lazy {uuid4().hex[:6]}")
|
|
|
|
|
lot = Lot(name=f"Lot lazy {uuid4().hex[:6]}", category=category)
|
|
|
|
|
root = Equipment(name=f"Famille lazy {uuid4().hex[:6]}", category=category, lot=lot,
|
|
|
|
|
is_group=True, quantity=40)
|
|
|
|
|
db.session.add_all([category, lot, root]); db.session.flush()
|
|
|
|
|
for index in range(40):
|
|
|
|
|
db.session.add(Equipment(name=f'Unité lazy {index}', parent_id=root.id,
|
|
|
|
|
room_id=rooms[index % 2].id, status='en_service'))
|
|
|
|
|
db.session.commit()
|
|
|
|
|
root_id = root.id
|
|
|
|
|
|
|
|
|
|
page = authenticated_client.get('/equipments/')
|
|
|
|
|
assert page.status_code == 200
|
|
|
|
|
assert b'Unit\xc3\xa9 lazy 39' not in page.data
|
|
|
|
|
# Conserver le même contexte évite que le moteur MariaDB de test ne
|
|
|
|
|
# recycle la connexion entre la création et la requête HTTP.
|
|
|
|
|
with app.app_context():
|
|
|
|
|
hierarchy = authenticated_client.get(f'/equipments/{root_id}/hierarchy')
|
|
|
|
|
assert hierarchy.status_code == 200
|
|
|
|
|
assert sum(zone['count'] for zone in hierarchy.get_json()['zones']) == 40
|