# tests/test_api_entreprise.py
# Copyright (C) 2019  Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from unittest import mock

import pytest
import requests
import responses
from django.utils import timezone

from passerelle.apps.api_entreprise.models import APIEntreprise
from tests.utils import FakedResponse, make_resource

ETABLISSEMENTS_RESPONSE = {
    "data": {
        "siege_social": True,
        "siret": "41816609600051",
        "date_mise_a_jour": 1449183600,
        "tranche_effectif_salarie": {
            "de": 200,
            "a": 249,
            "code": "31",
            "date_reference": "2014",
            "intitule": "200 à 249 salariés",
        },
        "date_creation": 1108594800,
        "region_implantation": {"code": "11", "value": "Île-de-France"},
        "adresse": {
            "acheminement_postal": {
                "l1": "OCTO TECHNOLOGY",
                "l2": None,
                "l3": None,
                "l4": "50 AVENUE DES CHAMPS ELYSEES",
                "l5": None,
                "l6": "75008 PARIS",
                "l7": "FRANCE",
            },
            "numero_voie": "50",
            "type_voie": "AV",
            "libelle_voie": "DES CHAMPS ELYSEES",
            "code_postal": "75008",
            "libelle_commune": "PARIS 8",
            "code_commune": "75108",
        },
        "etat_administratif": {"value": "F", "date_fermeture": 1315173600},
        "activite_principale": {
            "code": "62.02A",
            "libelle": "Conseil en systèmes et logiciels informatiques",
        },
    },
    "gateway_error": False,
}

ENTREPRISES_RESPONSE = {
    "entreprise": {
        "siren": "418166096",
        "capital_social": 459356,
        "numero_tva_intracommunautaire": "FR16418166096",
        "forme_juridique": "SA à directoire (s.a.i.)",
        "forme_juridique_code": "5699",
        "nom_commercial": "OCTO-TECHNOLOGY",
        "procedure_collective": False,
        "naf_entreprise": "6202A",
        "libelle_naf_entreprise": "Conseil en systèmes et logiciels informatiques",
        "raison_sociale": "OCTO-TECHNOLOGY",
        "siret_siege_social": "41816609600051",
        "code_effectif_entreprise": "31",
        "date_creation": 891381600,
        "categorie_entreprise": "PME",
        "diffusable_commercialement": True,
        "tranche_effectif_salarie_entreprise": {
            "de": 200,
            "a": 249,
            "code": "31",
            "date_reference": "2014",
            "intitule": "200 à 249 salariés",
        },
        "mandataires_sociaux": [
            {
                "nom": "HISQUIN",
                "prenom": "FRANCOIS",
                "fonction": "PRESIDENT DU DIRECTOIRE",
                "dirigeant": True,
                "date_naissance": "1965-01-27",
                "raison_sociale": "",
                "identifiant": "",
                "type": "PP",
            },
            {
                "nom": "",
                "prenom": "",
                "fonction": "COMMISSAIRE AUX COMPTES SUPPLEANT",
                "dirigeant": True,
                "date_naissance": "",
                "date_naissance_timestamp": 0,
                "raison_sociale": "BCRH & ASSOCIES - SOCIETE A RESPONSABILITE LIMITEE A ASSOCIE UNIQUE",
                "identifiant": "490092574",
                "type": "PM",
            },
        ],
        "etat_administratif": {
            "value": "C",  # A (actif) ou C (cessé)
            "date_cessation": 1315173600,  # null quand actif (A), un timestamp (un entier) quand cessé (C )
        },
    },
    "etablissement_siege": {
        "siege_social": True,
        "siret": "41816609600051",
        "naf": "6202A",
        "libelle_naf": "Conseil en systèmes et logiciels informatiques",
        "date_mise_a_jour": 1449183600,
        "tranche_effectif_salarie_etablissement": {
            "de": 200,
            "a": 249,
            "code": "31",
            "date_reference": "2014",
            "intitule": "200 à 249 salariés",
        },
        "date_creation_etablissement": 1108594800,
        "region_implantation": {"code": "11", "value": "Île-de-France"},
        "commune_implantation": {"code": "75108", "value": "PARIS 8"},
        "adresse": {
            "l1": "OCTO TECHNOLOGY",
            "l4": "50 AVENUE DES CHAMPS ELYSEES",
            "l6": "75008 PARIS",
            "l7": "FRANCE",
            "numero_voie": "50",
            "type_voie": "AV",
            "nom_voie": "DES CHAMPS ELYSEES",
            "code_postal": "75008",
            "localite": "PARIS 8",
            "code_insee_localite": "75108",
        },
        "etat_administratif": {"value": "F", "date_fermeture": 1315173600},
    },
    "gateway_error": False,
}

UNITES_LEGALES_RESPONSE = {
    "data": {
        "siren": "418166096",
        "siret_siege_social": "41816609600051",
        "numero_tva_intracommunautaire": "FR16418166096",
        "forme_juridique": {
            "libelle": "SA à directoire (s.a.i.)",
            "code": "5699",
        },
        "activite_principale": {
            "code": "62.02A",
            "libelle": "Conseil en systèmes et logiciels informatiques",
        },
        "personne_morale_attributs": {
            "raison_sociale": "OCTO-TECHNOLOGY",
        },
        "tranche_effectif_salarie": {
            "de": 200,
            "a": 249,
            "code": "31",
            "date_reference": "2014",
            "intitule": "200 à 249 salariés",
        },
        "date_creation": 891381600,
        "categorie_entreprise": "PME",
        "diffusable_commercialement": True,
    }
}

UNITES_LEGALES_SIEGE_RESPONSE = {
    "data": {
        "siret": "41816609600051",
        "adresse": {
            "numero_voie": "50",
            "type_voie": "AV",
            "libelle_voie": "DES CHAMPS ELYSEES",
            "code_postal": "75008",
            "libelle_commune": "PARIS 8",
            "code_commune": "75108",
            "acheminement_postal": {
                "l1": "OCTO TECHNOLOGY",
                "l4": "50 AVENUE DES CHAMPS ELYSEES",
                "l6": "75008 PARIS",
                "l7": "FRANCE",
            },
        },
    },
    "meta": {
        "date_derniere_mise_a_jour": 1449183600,
    },
}

RCS_UNITES_LEGALES_MANDATAIRES_SOCIAUX_RESPONSE = {
    "data": [
        {
            "nom": "HISQUIN",
            "prenom": "FRANCOIS",
            "fonction": "PRESIDENT DU DIRECTOIRE",
            "dirigeant": True,
            "date_naissance": "1965-01-27",
            "raison_sociale": "",
            "identifiant": "",
            "type": "PP",
        },
        {
            "fonction": "COMMISSAIRE AUX COMPTES SUPPLEANT",
            "dirigeant": True,
            "date_naissance": "",
            "date_naissance_timestamp": 0,
            "raison_sociale": "BCRH & ASSOCIES - SOCIETE A RESPONSABILITE LIMITEE A ASSOCIE UNIQUE",
            "identifiant": "490092574",
            "type": "PM",
        },
    ]
}

EXTRAITS_RCS_RESPONSE = {
    "data": {
        "siren": "418166096",
        "date_immatriculation": "1998-03-27",
        "date_immatriculation_timestamp": 890953200,
        "date_extrait": "21 AVRIL 2017",
        "observations": [
            {
                "date": "2000-02-23",
                "date_timestamp": 951260400,
                "numero": "12197",
                "libelle": " LA SOCIETE NE CONSERVE AUCUNE ACTIVITE A SON ANCIEN SIEGE ",
            }
        ],
    }
}

ASSOCIATIONS_RESPONSE = {
    "data": {
        "rna_id": "W751135389",
        "titre": "ALLIANCE DU COEUR: UNION NATIONALE DES FEDERATIONS ET ASSOCIATIONS DE MALADES CARDIOVASCULAIRES",
        "objet": "information, soutien, solidarité et accompagnement psycho médico social des personnes malades cardiovasculaires et de leurs proches...",
        "siret": "42135938100025",
        "siret_siege_social": "42135938100033",
        "date_creation": "1993-02-11",
        "date_declaration": "2013-06-28",
        "date_publication": "1993-03-03",
        "adresse_siege": {
            "numero_voie": "10",
            "type_voie": "RUE",
            "libelle_voie": "Lebouis",
            "code_insee": "75120",
            "code_postal": ["75014"],
            "commune": "Paris",
        },
        "groupement": "Simple",
        "mise_a_jour": "2013-06-28",
    }
}

DOCUMENTS_ASSOCIATION_RESPONSE = {
    "meta": {"nombre_documents": 2, "nombre_documents_deficients": 0},
    "data": [
        {
            "data": {
                "type": "Statuts",
                "url": "https://apientreprise.fr/attestations/40ab0b07d434d0417e8997ce7c5afbef/attestation_document_association.pdf",
                "timestamp": "1500660325",
            },
        },
        {
            "data": {
                "type": "Récépissé",
                "url": "https://apientreprise.fr/attestations/40ab0b07d434d0417e8997ce7c5afbef/recepisse_association.pdf",
                "timestamp": "1500667325",
            },
        },
        {
            "data": {
                "timestamp": "1337158058",
                "url": "https://apientreprise.fr/attestations/40ab0b07d434d0417e8997ce7c5afbef/attestation_document_association.pdf",
                "type": "Statuts",
            },
        },
    ],
}


EFFECTIFS_ANNUELS_ACOSS_COVID = {"siren": "418166096", "annee": "2019", "effectifs_annuels": 100.5}


ENTREPRISE_EFFECTIFS_MENSUELS_ACOSS_COVID = {
    "siren": "418166096",
    "annee": "2019",
    "mois": "02",
    "effectifs_mensuels": 100.5,
}


ETABLISSEMENT_EFFECTIFS_MENSUELS_ACOSS_COVID = {
    "siret": "41816609600051",
    "annee": "2019",
    "mois": "02",
    "effectifs_mensuels": 100.5,
}


EXERCICES_RESPONSE = {
    "exercices": [
        {
            "ca": "648374448",
            "date_fin_exercice": "2016-12-31T00:00:00+01:00",
            "date_fin_exercice_timestamp": 1483138800,
        },
        {
            "ca": "491463386",
            "date_fin_exercice": "2015-12-31T00:00:00+01:00",
            "date_fin_exercice_timestamp": 1451516400,
        },
        {
            "ca": "473899061",
            "date_fin_exercice": "2014-12-31T00:00:00+01:00",
            "date_fin_exercice_timestamp": 1419980400,
        },
    ]
}


DOCUMENT_ASSOCIATION_RESPONSE = "binary content"

REQUEST_PARAMS = {'context': 'MSP', 'object': 'demand', 'recipient': 'siret'}


@pytest.fixture
def resource(db):
    return make_resource(
        APIEntreprise,
        slug='test',
        title='API Entreprise',
        description='API Entreprise',
        token='83c68bf0b6013c4daf3f8213f7212aa5',
        recipient='recipient',
    )


@mock.patch('passerelle.utils.Request.get')
def test_endpoint_with_no_params(mocked_get, app, resource):
    mocked_get.return_value = FakedResponse(content='{}', status_code=200)
    response = app.get('/api-entreprise/test/documents_associations/443170139/', status=400)
    assert response.json['err_class'] == 'passerelle.views.WrongParameter'
    assert response.json['err_desc'] == "missing parameters: 'context'."
    params = {'context': 'Custom context', 'object': 'Custom object'}
    response = app.get('/api-entreprise/test/documents_associations/443170139/', params=params)
    assert mocked_get.call_args[1]['data']['context'] == 'Custom context'
    assert mocked_get.call_args[1]['data']['object'] == 'Custom object'
    assert mocked_get.call_args[1]['data']['recipient'] == 'recipient'
    params['recipient'] = 'Custom recipient'
    response = app.get('/api-entreprise/test/documents_associations/443170139/', params=params)
    assert mocked_get.call_args[1]['data']['recipient'] == 'Custom recipient'


def test_entreprises_endpoint(app, resource):
    with responses.RequestsMock() as rsps:
        rsps.get(
            'https://entreprise.api.gouv.fr/v3/insee/sirene/unites_legales/diffusibles/443170139',
            json=UNITES_LEGALES_RESPONSE,
        )
        rsps.get(
            'https://entreprise.api.gouv.fr/v3/insee/sirene/unites_legales/diffusibles/443170139/siege_social',
            json=UNITES_LEGALES_SIEGE_RESPONSE,
        )
        rsps.get(
            'https://entreprise.api.gouv.fr/v3/infogreffe/rcs/unites_legales/443170139/mandataires_sociaux',
            json=RCS_UNITES_LEGALES_MANDATAIRES_SOCIAUX_RESPONSE,
        )

        request_params = REQUEST_PARAMS.copy()
        request_params['mandataires'] = True
        response = app.get('/api-entreprise/test/entreprises/443170139/', params=request_params)

    data = response.json['data']
    assert data['entreprise']['categorie_entreprise'] == 'PME'
    assert data['entreprise']['numero_tva_intracommunautaire'] == 'FR16418166096'
    assert data['entreprise']['siret_siege_social'] == '41816609600051'
    assert data['entreprise']['forme_juridique'] == 'SA à directoire (s.a.i.)'
    assert data['entreprise']['forme_juridique_code'] == '5699'
    assert data['entreprise']['siren'] == '418166096'
    assert data['entreprise']['date_creation'] == '1998-03-31'
    assert data['entreprise']['diffusable_commercialement'] is True
    assert data['entreprise']['naf_entreprise'] == '6202A'
    assert data['entreprise']['naf_point_entreprise'] == '62.02A'
    assert data['entreprise']['libelle_naf_entreprise'] == 'Conseil en systèmes et logiciels informatiques'
    assert data['entreprise']['raison_sociale'] == 'OCTO-TECHNOLOGY'
    assert data['entreprise']['tranche_effectif_salarie_entreprise']['intitule'] == '200 à 249 salariés'

    assert 'mandataires_sociaux' in data['entreprise']
    mandataires_sociaux = data['entreprise']['mandataires_sociaux']
    assert mandataires_sociaux[0]['date_naissance'] == '1965-01-27'
    assert mandataires_sociaux[0]['nom'] == 'HISQUIN'
    assert mandataires_sociaux[0]['prenom'] == 'FRANCOIS'
    assert mandataires_sociaux[0]['fonction'] == 'PRESIDENT DU DIRECTOIRE'
    assert mandataires_sociaux[1]['nom'] == ''
    assert mandataires_sociaux[1]['prenom'] == ''
    assert mandataires_sociaux[1]['fonction'] == 'COMMISSAIRE AUX COMPTES SUPPLEANT'

    assert 'etablissement_siege' in data
    assert data['etablissement_siege']['siret'] == '41816609600051'
    assert data['etablissement_siege']['adresse']['numero_voie'] == '50'
    assert data['etablissement_siege']['adresse']['type_voie'] == 'AV'
    assert data['etablissement_siege']['adresse']['nom_voie'] == 'DES CHAMPS ELYSEES'
    assert data['etablissement_siege']['adresse']['code_postal'] == '75008'
    assert data['etablissement_siege']['adresse']['localite'] == 'PARIS 8'
    assert data['etablissement_siege']['adresse']['code_insee_localite'] == '75108'
    assert data['etablissement_siege']['adresse']['l1'] == 'OCTO TECHNOLOGY'
    assert data['etablissement_siege']['adresse']['l4'] == '50 AVENUE DES CHAMPS ELYSEES'
    assert data['etablissement_siege']['adresse']['l6'] == '75008 PARIS'
    assert data['etablissement_siege']['adresse']['l7'] == 'FRANCE'
    assert data['etablissement_siege']['date_mise_a_jour'] == '2015-12-03'


def test_simple_match_mandataire_social(app, resource):
    params = {
        'first_name': 'françois',
        'last_name': 'hIsQuIn',
        'birthdate': '19650127',
        'method': 'simple',
    }
    params.update(REQUEST_PARAMS)

    with responses.RequestsMock() as rsps:
        rsps.get('https://entreprise.api.gouv.fr/v2/entreprises/443170139/', json=ENTREPRISES_RESPONSE)
        url = '/api-entreprise/test/match_mandataire_social/443170139/'
        response = app.get(url, params=params)

        # successful matching
        data = response.json['data']
        assert data['nom'] == 'HISQUIN'
        assert data['prenom'] == 'FRANCOIS'
        assert data['date_naissance'] == '1965-01-27'
        assert data['type'] == 'PP'

        params['method'] = 'unkwown'
        response = app.get(url, params=params)

        # unsupported method
        assert response.json['err']
        assert 'data' not in response.json

        params['method'] = 'simple'
        params.pop('first_name')
        response = app.get(url, params=params, status=400)

        # missing parameter
        assert not response.json['data']
        assert 'missing parameter' in response.json['err_desc']

        params['first_name'] = 'JOHN'
        response = app.get(url, params=params)

        # matching failed
        assert not response.json['err']
        assert not response.json['data']


def test_levenshtein_match_mandataire_social(app, resource):
    params = {
        'first_name': 'françois',
        'last_name': 'hIsQuIn',
        'birthdate': '19650127',
        'method': 'levenshtein',
    }
    params.update(REQUEST_PARAMS)

    with responses.RequestsMock() as rsps:
        rsps.get('https://entreprise.api.gouv.fr/v2/entreprises/443170139/', json=ENTREPRISES_RESPONSE)

        url = '/api-entreprise/test/match_mandataire_social/443170139/'
        response = app.get(url, params=params)

        # successful matching
        data = response.json['data']
        assert data['nom'] == 'HISQUIN'
        assert data['prenom'] == 'FRANCOIS'
        assert data['date_naissance'] == '1965-01-27'
        assert data['type'] == 'PP'

        params['first_name'] = 'JOHN'
        response = app.get(url, params=params)

        # matching failed
        assert not response.json['err']
        assert not response.json['data']

        params['first_name'] = 'francoi'
        params['last_name'] = 'hisquinn'
        response = app.get(url, params=params)

        # successful matching within distance bracket
        data = response.json['data']
        assert data['nom'] == 'HISQUIN'
        assert data['prenom'] == 'FRANCOIS'
        assert data['date_naissance'] == '1965-01-27'
        assert data['type'] == 'PP'


def test_entreprises_endpoint_include_private(app, resource):
    with responses.RequestsMock() as rsps:
        rsps.get(
            'https://entreprise.api.gouv.fr/v3/insee/sirene/unites_legales/443170139',
            json=UNITES_LEGALES_RESPONSE,
        )
        rsps.get(
            'https://entreprise.api.gouv.fr/v3/insee/sirene/unites_legales/443170139/siege_social',
            json=UNITES_LEGALES_SIEGE_RESPONSE,
        )
        request_params = REQUEST_PARAMS.copy()
        request_params['include_private'] = True
        app.get('/api-entreprise/test/entreprises/443170139/', params=request_params)
        # the mocked URLS do not contain 'diffusibles'
        # responses would raise an error if they were not called


def test_entreprises_endpoint_no_mandataires(app, resource):
    with responses.RequestsMock() as rsps:
        rsps.get(
            'https://entreprise.api.gouv.fr/v3/insee/sirene/unites_legales/diffusibles/443170139',
            json=UNITES_LEGALES_RESPONSE,
        )
        rsps.get(
            'https://entreprise.api.gouv.fr/v3/insee/sirene/unites_legales/diffusibles/443170139/siege_social',
            json=UNITES_LEGALES_SIEGE_RESPONSE,
        )
        response = app.get('/api-entreprise/test/entreprises/443170139/', params=REQUEST_PARAMS)
        assert response.json['data']['entreprise']['mandataires_sociaux'] == []


def test_etablissements_endpoint(app, resource):
    with responses.RequestsMock() as rsps:
        rsps.get(
            'https://entreprise.api.gouv.fr/v3/insee/sirene/etablissements/diffusibles/44317013900036',
            json=ETABLISSEMENTS_RESPONSE,
        )
        response = app.get('/api-entreprise/test/etablissements/44317013900036/', params=REQUEST_PARAMS)
    assert 'data' in response.json
    data = response.json['data']

    assert 'etablissement' in data
    assert data['etablissement']['siret'] == '41816609600051'
    assert data['etablissement']['naf'] == '6202A'
    assert data['etablissement']['naf_point'] == '62.02A'
    assert data['etablissement']['date_mise_a_jour'] == '2015-12-03'
    assert data['etablissement']['date_creation_etablissement'] == '2005-02-16'

    assert 'adresse' in data['etablissement']
    assert data['etablissement']['adresse']['code_postal'] == '75008'
    assert data['etablissement']['adresse']['localite'] == 'PARIS 8'
    assert data['etablissement']['adresse']['code_insee_localite'] == '75108'
    assert data['etablissement']['adresse']['nom_voie'] == 'DES CHAMPS ELYSEES'
    assert data['etablissement']['adresse']['libelle_voie'] == 'DES CHAMPS ELYSEES'
    assert data['etablissement']['adresse']['l1'] == 'OCTO TECHNOLOGY'
    assert data['etablissement']['adresse']['l2'] is None
    assert data['etablissement']['adresse']['l3'] is None
    assert data['etablissement']['adresse']['l4'] == '50 AVENUE DES CHAMPS ELYSEES'
    assert data['etablissement']['adresse']['l5'] is None
    assert data['etablissement']['adresse']['l6'] == '75008 PARIS'
    assert data['etablissement']['adresse']['l7'] == 'FRANCE'
    assert data['etablissement']['commune_implantation']['code'] == '75108'
    assert data['etablissement']['commune_implantation']['value'] == 'PARIS 8'
    assert data['etablissement']['tranche_effectif_salarie_etablissement']['de'] == 200
    assert data['etablissement']['tranche_effectif_salarie_etablissement']['a'] == 249
    assert data['etablissement']['tranche_effectif_salarie_etablissement']['code'] == '31'
    assert data['etablissement']['tranche_effectif_salarie_etablissement']['date_reference'] == '2014'
    assert data['etablissement']['tranche_effectif_salarie_etablissement']['intitule'] == '200 à 249 salariés'


def test_associations_endpoint(app, resource):
    with responses.RequestsMock() as rsps:
        rsps.get(
            'https://entreprise.api.gouv.fr/v3/ministere_interieur/rna/associations/443170139',
            json=ASSOCIATIONS_RESPONSE,
        )
        response = app.get('/api-entreprise/test/associations/443170139/', params=REQUEST_PARAMS)
    assert 'data' in response.json
    data = response.json['data']

    assert 'association' in data
    assert data['association']['id'] == 'W751135389'
    assert data['association']['siret'] == '42135938100025'
    assert data['association']['date_creation'] == '1993-02-11'
    assert data['association']['date_declaration'] == '2013-06-28'
    assert data['association']['date_publication'] == '1993-03-03'

    assert 'adresse_siege' in data['association']
    assert data['association']['adresse_siege']['code_postal'] == '75014'
    assert data['association']['adresse_siege']['code_insee'] == '75120'


def test_documents_associations_endpoint(app, resource):
    with responses.RequestsMock() as rsps:
        rsps.get(
            'https://entreprise.api.gouv.fr/v3/ministere_interieur/rna/associations/443170139/documents',
            json=DOCUMENTS_ASSOCIATION_RESPONSE,
        )

        response = app.get('/api-entreprise/test/documents_associations/443170139/', params=REQUEST_PARAMS)
    assert 'data' in response.json
    data = response.json['data']
    assert len(data) == 3
    for document in data:
        assert 'id' in document
        assert 'text' in document
        assert 'url' in document
        assert 'type' in document
        assert 'datetime' in document


def test_associations_last_document_of_type_endpoint(app, resource):
    with responses.RequestsMock() as rsps:
        rsps.get(
            'https://entreprise.api.gouv.fr/v3/ministere_interieur/rna/associations/443170139/documents',
            json=DOCUMENTS_ASSOCIATION_RESPONSE,
        )

        params = REQUEST_PARAMS
        params['document_type'] = 'Statuts'
        response = app.get('/api-entreprise/test/document_association/443170139/get-last/', params=params)
        assert 'data' in response.json
        data = response.json['data']
        assert data['timestamp'] == '1500660325'

        params['document_type'] = 'Liste des dirigeants'
        response = app.get('/api-entreprise/test/document_association/443170139/get-last/', params=params)
        assert not response.json['data']


def test_extraits_rcs(app, resource):
    with responses.RequestsMock() as rsps:
        rsps.get(
            'https://entreprise.api.gouv.fr/v3/infogreffe/rcs/unites_legales/443170139/extrait_kbis',
            json=EXTRAITS_RCS_RESPONSE,
        )
        response = app.get('/api-entreprise/test/extraits_rcs/443170139/', params=REQUEST_PARAMS)
    assert 'data' in response.json
    data = response.json['data']

    assert data['siren'] == '418166096'
    assert data['date_extrait'] == '21 AVRIL 2017'
    assert data['date_immatriculation_timestamp'] == 890953200
    assert data['date_immatriculation'] == '1998-03-27'
    assert data['date_immatriculation_datetime'] == '1998-03-26T23:00:00Z'


def test_document_association(app, resource, freezer):
    with responses.RequestsMock() as rsps:
        rsps.get(
            'https://entreprise.api.gouv.fr/v3/ministere_interieur/rna/associations/443170139/documents',
            json=DOCUMENTS_ASSOCIATION_RESPONSE,
        )

        response = app.get('/api-entreprise/test/documents_associations/443170139/', params=REQUEST_PARAMS)
        assert 'data' in response.json
        data = response.json['data']
        assert len(data) == 3
        document = data[0]
        assert 'url' in document

        rsps.get(
            'https://apientreprise.fr/attestations/40ab0b07d434d0417e8997ce7c5afbef/attestation_document_association.pdf',
            body='binary content',
        )

        app.get(
            document['url'], params={'context': 'MSP', 'object': 'demand', 'recipient': 'siret'}, status=200
        )
        # try to get document with wrong signature
        wrong_url = document['url'] + "wrong/"
        app.get(wrong_url, status=404)

        # try expired url
        freezer.move_to(timezone.now() + timezone.timedelta(days=8))
        app.get(document['url'], status=404)


def test_effectifs_annuels_acoss_covid(app, resource):
    with responses.RequestsMock() as rsps:
        rsps.get(
            'https://entreprise.api.gouv.fr/v2/effectifs_annuels_acoss_covid/418166096/',
            json=EFFECTIFS_ANNUELS_ACOSS_COVID,
        )

        response = app.get(
            '/api-entreprise/test/effectifs_annuels_acoss_covid/418166096/', params=REQUEST_PARAMS
        )
    data = response.json['data']
    assert data['siren'] == '418166096'
    assert data['annee'] == '2019'
    assert data['effectifs_annuels'] == 100.5


def test_entreprise_effectifs_mensuels_acoss_covid(app, resource):
    with responses.RequestsMock() as rsps:
        rsps.get(
            'https://entreprise.api.gouv.fr/v2/effectifs_mensuels_acoss_covid/2019/02/entreprise/418166096/',
            json=ENTREPRISE_EFFECTIFS_MENSUELS_ACOSS_COVID,
        )

        response = app.get(
            '/api-entreprise/test/entreprise_effectifs_mensuels_acoss_covid/2019/02/418166096/',
            params=REQUEST_PARAMS,
        )

    data = response.json['data']
    assert data['siren'] == '418166096'
    assert data['annee'] == '2019'
    assert data['mois'] == '02'
    assert data['effectifs_mensuels'] == 100.5


def test_etablissment_effectifs_mensuels_acoss_covid(app, resource):
    with responses.RequestsMock() as rsps:
        rsps.get(
            'https://entreprise.api.gouv.fr/v2/effectifs_mensuels_acoss_covid/2019/02/etablissement/418166096/',
            json=ETABLISSEMENT_EFFECTIFS_MENSUELS_ACOSS_COVID,
        )

        response = app.get(
            '/api-entreprise/test/etablissement_effectifs_mensuels_acoss_covid/2019/02/418166096/',
            params=REQUEST_PARAMS,
        )
    data = response.json['data']
    assert data['siret'] == '41816609600051'
    assert data['annee'] == '2019'
    assert data['mois'] == '02'
    assert data['effectifs_mensuels'] == 100.5


def test_exercices(app, resource):
    with responses.RequestsMock() as rsps:
        rsps.get('https://entreprise.api.gouv.fr/v2/exercices/418166096/', json=EXERCICES_RESPONSE)
        response = app.get('/api-entreprise/test/exercices/418166096/', params=REQUEST_PARAMS)
    data = response.json['data']
    assert len(data['exercices']) == 3
    exercice = data['exercices'][0]
    assert exercice['ca'] == '648374448'
    assert exercice['date_fin_exercice'] == '2016-12-31T00:00:00+01:00'
    assert exercice['date_fin_exercice_timestamp'] == 1483138800
    assert exercice['date_fin_exercice_datetime'] == '2016-12-30T23:00:00Z'


def test_error_500(app, resource):
    with responses.RequestsMock() as rsps:
        rsps.get(
            'https://entreprise.api.gouv.fr/v3/insee/sirene/unites_legales/diffusibles/443170139',
            body='bad error happened',
            status=500,
        )
        response = app.get('/api-entreprise/test/entreprises/443170139/', params=REQUEST_PARAMS)
        assert response.status_code == 200
        assert response.json['err'] == 1
        assert response.json['data']['status_code'] == 500
        assert 'error happened' in response.json['err_desc']


def test_no_json_error(app, resource):
    with responses.RequestsMock() as rsps:
        rsps.get(
            'https://entreprise.api.gouv.fr/v3/insee/sirene/unites_legales/diffusibles/443170139',
            body='simple text',
        )
        response = app.get('/api-entreprise/test/entreprises/443170139/', params=REQUEST_PARAMS)
        assert response.status_code == 200
        assert response.json['err'] == 1
        assert (
            response.json['err_desc']
            == "API-entreprise returned non-JSON content with status 200: simple text"
        )


def test_error_404(app, resource):
    with responses.RequestsMock() as rsps:
        rsps.get(
            'https://entreprise.api.gouv.fr/v3/insee/sirene/unites_legales/diffusibles/443170139',
            json={'error': 'not_found', 'message': 'Page not found'},
            status=404,
        )
        response = app.get('/api-entreprise/test/entreprises/443170139/', params=REQUEST_PARAMS)
        assert response.status_code == 200
        assert response.json['err'] == 1
        assert response.json['err_desc'] == 'Page not found'


def test_connection_error(app, resource):
    with responses.RequestsMock() as rsps:
        rsps.get(
            'https://entreprise.api.gouv.fr/v3/insee/sirene/unites_legales/diffusibles/443170139',
            body=requests.RequestException('connection timed-out'),
        )
        response = app.get('/api-entreprise/test/entreprises/443170139/', params=REQUEST_PARAMS)
        assert response.status_code == 200
        assert response.json['err'] == 1
        assert response.json['err_desc'] == 'API-entreprise connection error: connection timed-out'
        assert response.json['data'] == []
