""" Smoke coverage for the pages whose queries were rewritten during the database optimization pass: the dashboard, the issues list, and the reports overview. These routes had no request-level tests, so a query rewrite that produced invalid SQL or a broken scope would only have surfaced in production. Each test here drives the real route through the test client for a role that exercises a DIFFERENT branch of the scoping code: admin -- unscoped branch inspector -- InspectorAssignment / get_inspector_scope() branch customer -- CustomerAssignment / get_customer_scope() branch The assertions are deliberately about behaviour that must hold (status code, scope isolation), not about markup. """ from datetime import timedelta import pytest from app import db as _db from app.models.issue import Issue from app.models.project import Project, CustomerAssignment from app.models.inspector_assignment import InspectorAssignment from app.utils.time_utils import now_eastern @pytest.fixture def make_issue(db): def _make(facility=None, area=None, severity='high', status='open', hours_ago=1, **kw): issue = Issue( facility_id=facility.id if facility else None, area_id=area.id if area else None, severity=severity, description=kw.pop('description', 'test issue'), status=status, reported_at=now_eastern() - timedelta(hours=hours_ago), ) for k, v in kw.items(): setattr(issue, k, v) db.session.add(issue) db.session.commit() return issue return _make @pytest.fixture def project(db): proj = Project(name='Contract A', active=True) db.session.add(proj) db.session.commit() return proj @pytest.fixture def other_project(db): proj = Project(name='Contract B', active=True) db.session.add(proj) db.session.commit() return proj # ── Dashboard ──────────────────────────────────────────────────────────────── @pytest.mark.parametrize('role', ['admin', 'director', 'project_manager', 'auditor']) def test_dashboard_renders_for_staff_roles(client, login, make_user, make_facility, make_issue, project, role): """The card queries (severity / handler / SLA splits) build and run.""" facility = make_facility(project=project) make_issue(facility=facility, severity='critical', hours_ago=100) make_issue(facility=facility, severity='low', status='in_progress') make_issue(facility=facility, status='resolved', resolved_at=now_eastern()) login(make_user(role=role)) assert client.get('/').status_code == 200 def test_dashboard_renders_for_scoped_inspector(client, login, make_user, db, make_facility, make_area, make_issue, project): inspector = make_user(role='inspector') db.session.add(InspectorAssignment(user_id=inspector.id, project_id=project.id)) db.session.commit() facility = make_facility(project=project) area = make_area(facility) make_issue(area=area, severity='high', hours_ago=50) # reached via area make_issue(facility=facility, severity='medium') # reached directly login(inspector) assert client.get('/').status_code == 200 def test_dashboard_renders_for_inspector_with_no_assignments(client, login, make_user): """Strict scoping: no assignments must render an empty dashboard, not 500.""" login(make_user(role='inspector')) assert client.get('/').status_code == 200 def test_dashboard_renders_for_customer(client, login, make_user, db, make_facility, make_issue, project): customer = make_user(role='customer') facility = make_facility(project=project) db.session.add(CustomerAssignment(user_id=customer.id, project_id=project.id)) db.session.commit() make_issue(facility=facility) login(customer) assert client.get('/').status_code == 200 # ── Issues list ────────────────────────────────────────────────────────────── def test_issues_list_renders(client, login, make_user, make_facility, make_issue, project): facility = make_facility(project=project) make_issue(facility=facility) login(make_user(role='admin')) assert client.get('/issues/').status_code == 200 @pytest.mark.parametrize('query', [ '?facility_id=abc', # non-numeric -- used to raise ValueError -> 500 '?facility_id=', '?facility_id=999999', # numeric but nonexistent '?contract_id=abc', '?issue_id=abc', '?severity=high&status=open', '?handler_type=vendor', '?unassigned=1', '?sla=breached', '?date_from=notadate&date_to=alsonot', ]) def test_issues_list_survives_malformed_filters(client, login, make_user, make_facility, make_issue, project, query): """A hand-edited or stale query string must never 500 the list.""" facility = make_facility(project=project) make_issue(facility=facility) login(make_user(role='admin')) assert client.get('/issues/' + query).status_code == 200 def test_issues_list_scopes_a_customer_to_their_own_facilities( client, login, make_user, db, make_facility, make_issue, project, other_project): """The scope filter still isolates customers after the query rewrite.""" customer = make_user(role='customer') mine = make_facility(project=project, name='Mine') theirs = make_facility(project=other_project, name='Theirs') db.session.add(CustomerAssignment(user_id=customer.id, project_id=project.id)) db.session.commit() make_issue(facility=mine, description='visible to me') make_issue(facility=theirs, description='other customer only') login(customer) body = client.get('/issues/').get_data(as_text=True) assert 'visible to me' in body assert 'other customer only' not in body # ── Reports overview ───────────────────────────────────────────────────────── def test_reports_overview_renders_for_admin(client, login, make_user, make_facility, make_template, make_inspection, project): admin = make_user(role='admin') inspector = make_user(role='inspector') facility = make_facility(project=project) make_inspection(facility, inspector, make_template()) login(admin) assert client.get('/reports/').status_code == 200 def test_reports_overview_inspector_scope_uses_subquery( client, login, make_user, db, make_facility, make_template, make_inspection, make_issue, project): """_scope_issue() now filters via a subquery instead of an id list.""" inspector = make_user(role='inspector') db.session.add(InspectorAssignment(user_id=inspector.id, project_id=project.id)) db.session.commit() facility = make_facility(project=project) insp = make_inspection(facility, inspector, make_template()) make_issue(facility=facility, inspection_id=insp.id) login(inspector) assert client.get('/reports/').status_code == 200 def test_reports_overview_inspector_with_no_inspections(client, login, make_user): """IN (empty subquery) must match nothing rather than error.""" login(make_user(role='inspector')) assert client.get('/reports/').status_code == 200