# -*- coding: utf-8 -*-

"""Test permissions

    On a deux utilisateurs dans la base test API: 
     - "test", avec le rôle LecteurAPI qui a la permission ScoView, 
     - et "other", qui n'a aucune permission.


    Lancer :
        pytest tests/api/test_api_permissions.py
"""

import requests

from tests.api.setup_test_api import API_URL, SCODOC_URL, CHECK_CERTIFICATE, api_headers

from app import create_app
from app.scodoc import sco_utils as scu
from config import RunningConfig


def test_permissions(api_headers):
    """
    vérification de la permissions ScoView et du non accès sans role
    de toutes les routes de l'API
    """
    # Ce test va récupérer toutes les routes de l'API
    app = create_app(RunningConfig)
    assert app
    # Les routes de l'API avec GET, excluant les logos pour le moment XXX
    api_rules = [
        r
        for r in app.url_map.iter_rules()
        if str(r).startswith("/ScoDoc/api")
        and "logo" not in str(r)  # ignore logos
        and "absence" not in str(r)  # ignore absences
        and "GET" in r.methods
    ]
    assert len(api_rules) > 0
    all_args = {
        "acronym": "TAPI",
        "code_type": "etudid",
        "code": 1,
        "dept_id": 1,
        "dept_ident": "TAPI",
        "dept": "TAPI",
        "etape_apo": "???",
        "etat": "I",
        "etudid": 1,
        "evaluation_id": 1,
        "formation_id": 1,
        "formsemestre_id": 1,
        "group_id": 1,
        "ine": "INE1",
        "module_id": 1,
        "moduleimpl_id": 1,
        "nip": 1,
        "partition_id": 1,
        "role_name": "Ens",
        "start": "abc",
        "uid": 1,
        "validation_id": 1,
        "version": "long",
        "assiduite_id": 1,
        "justif_id": 1,
        "etudids": "1",
    }
    # Arguments spécifiques pour certaines routes
    # par défaut, on passe tous les arguments de all_args
    endpoint_args = {
        "api.formsemestres_query": {},
    }
    for rule in api_rules:
        args = endpoint_args.get(rule.endpoint, all_args)
        path = rule.build(args)[1]
        if not "GET" in rule.methods:
            # skip all POST routes
            continue

        if any(
            path.startswith(p)
            for p in [
                "/ScoDoc/api/justificatif/1/list",
                "/ScoDoc/api/justificatif/1/justifies",
            ]
        ):
            # On passe la route "api/justificatif/<>/list" car elle nécessite la permission ScoJustifView
            # On passe la route "api/justificatif/<>/justifies" car elle nécessite la permission ScoJustifChange
            continue

        r = requests.get(
            SCODOC_URL + path,
            headers=api_headers,
            verify=CHECK_CERTIFICATE,
            timeout=scu.SCO_TEST_API_TIMEOUT,
        )
        assert r.status_code == 200

    # Même chose sans le jeton:
    for rule in api_rules:
        path = rule.build(args)[1]
        if not "GET" in rule.methods:
            # skip all POST routes
            continue
        r = requests.get(
            SCODOC_URL + path,
            verify=CHECK_CERTIFICATE,
            timeout=scu.SCO_TEST_API_TIMEOUT,
        )
        assert r.status_code == 401

    # Demande un jeton pour "other"
    r = requests.post(
        API_URL + "/tokens", auth=("other", "other"), timeout=scu.SCO_TEST_API_TIMEOUT
    )
    assert r.status_code == 200
    token = r.json()["token"]
    headers = {"Authorization": f"Bearer {token}"}
    # Vérifie que tout est interdit
    for rule in api_rules:
        path = rule.build(args)[1]
        if not "GET" in rule.methods:
            # skip all POST routes
            continue
        r = requests.get(
            SCODOC_URL + path,
            headers=headers,
            verify=CHECK_CERTIFICATE,
            timeout=scu.SCO_TEST_API_TIMEOUT,
        )
        assert r.status_code == 401
