476 lines
17 KiB
Python
476 lines
17 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
# 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/>.
|
|
|
|
import pytest
|
|
import mock
|
|
import requests
|
|
|
|
from httmock import urlmatch, HTTMock, response
|
|
|
|
from django.core.urlresolvers import reverse
|
|
from django.utils import timezone
|
|
|
|
from passerelle.apps.api_entreprise.models import APIEntreprise
|
|
|
|
from utils import make_resource, endpoint_get, FakedResponse
|
|
|
|
ETABLISSEMENTS_RESPONSE = {
|
|
"etablissement": {
|
|
"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
|
|
}
|
|
|
|
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",
|
|
"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
|
|
}
|
|
|
|
EXTRAITS_RCS_RESPONSE = {
|
|
"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 = {
|
|
"association" : {
|
|
"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 = {
|
|
"nombre_documents": 2,
|
|
"documents": [
|
|
{
|
|
"type": "Statuts",
|
|
"url": "https://apientreprise.fr/attestations/40ab0b07d434d0417e8997ce7c5afbef/attestation_document_association.pdf",
|
|
"timestamp": "1500660325"
|
|
},
|
|
{
|
|
"type": "Récépissé",
|
|
"url": "https://apientreprise.fr/attestations/40ab0b07d434d0417e8997ce7c5afbef/recepisse_association.pdf",
|
|
"timestamp": "1500667325"
|
|
},
|
|
{
|
|
"timestamp": "1337158058",
|
|
"url": "https://apientreprise.fr/attestations/40ab0b07d434d0417e8997ce7c5afbef/attestation_document_association.pdf",
|
|
"type": "Statuts"
|
|
},
|
|
]
|
|
}
|
|
|
|
DOCUMENT_ASSOCIATION_RESPONSE = "binary content"
|
|
|
|
REQUEST_PARAMS = {'context': 'MSP', 'object': 'demand', 'recipient': 'siret'}
|
|
|
|
@urlmatch(netloc='^entreprise.api.gouv.fr$',
|
|
path='^/v2/etablissements/')
|
|
def api_entreprise_etablissements(url, request):
|
|
return response(200, ETABLISSEMENTS_RESPONSE, request=request)
|
|
|
|
|
|
@urlmatch(netloc='^entreprise.api.gouv.fr$',
|
|
path='^/v2/entreprises/')
|
|
def api_entreprise_entreprises(url, request):
|
|
return response(200, ENTREPRISES_RESPONSE, request=request)
|
|
|
|
|
|
@urlmatch(netloc='^entreprise.api.gouv.fr$',
|
|
path='^/v2/associations/')
|
|
def api_entreprise_associations(url, request):
|
|
return response(200, ASSOCIATIONS_RESPONSE, request=request)
|
|
|
|
|
|
@urlmatch(netloc='^entreprise.api.gouv.fr$',
|
|
path='^/v2/extraits_rcs_infogreffe/')
|
|
def api_entreprise_extraits_rcs(url, request):
|
|
return response(200, EXTRAITS_RCS_RESPONSE, request=request)
|
|
|
|
@urlmatch(netloc='^entreprise.api.gouv.fr$',
|
|
path='^/v2/documents_associations/')
|
|
def api_entreprise_documents_associations(url, request):
|
|
return response(200, DOCUMENTS_ASSOCIATION_RESPONSE, request=request)
|
|
|
|
@urlmatch(netloc='^apientreprise.fr$',
|
|
path='^/attestations/')
|
|
def api_entreprise_document_association(url, request):
|
|
return response(200, DOCUMENT_ASSOCIATION_RESPONSE, request=request)
|
|
|
|
|
|
@urlmatch(netloc='^entreprise.api.gouv.fr$')
|
|
def api_entreprise_error_500(url, request):
|
|
return response(500, 'bad error happened', request=request)
|
|
|
|
@urlmatch(netloc='^entreprise.api.gouv.fr$')
|
|
def api_entreprise_connection_error(url, request):
|
|
raise requests.RequestException('connection timed-out')
|
|
|
|
@urlmatch(netloc='^entreprise.api.gouv.fr$')
|
|
def api_entreprise_error_not_json(url, request):
|
|
return response(200, 'simple text', request=request)
|
|
|
|
|
|
@urlmatch(netloc='^entreprise.api.gouv.fr$')
|
|
def api_entreprise_error_not_found(url, request):
|
|
return response(404, {
|
|
'error': 'not_found',
|
|
'message': u'Page not found'
|
|
}, request=request)
|
|
|
|
|
|
@pytest.yield_fixture
|
|
def mock_api_entreprise():
|
|
with HTTMock(api_entreprise_etablissements, api_entreprise_entreprises, api_entreprise_associations, api_entreprise_extraits_rcs,
|
|
api_entreprise_associations, api_entreprise_documents_associations, api_entreprise_document_association):
|
|
yield None
|
|
|
|
|
|
@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, mock_api_entreprise):
|
|
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_code'] == '5699'
|
|
assert data['entreprise']['siren'] == '418166096'
|
|
assert data['entreprise']['date_creation'] == '1998-03-31'
|
|
assert data['entreprise']['mandataires_sociaux'][0]['date_naissance'] == '1965-01-27'
|
|
|
|
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']['date_mise_a_jour'] == '2015-12-03'
|
|
|
|
|
|
def test_etablissements_endpoint(app, resource, mock_api_entreprise):
|
|
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']['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'
|
|
|
|
|
|
def test_associations_endpoint(app, resource, mock_api_entreprise):
|
|
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, mock_api_entreprise):
|
|
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, mock_api_entreprise):
|
|
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, mock_api_entreprise, freezer):
|
|
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, mock_api_entreprise, freezer):
|
|
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
|
|
resp = app.get(document['url'],
|
|
params={'context': 'MSP', 'object': 'demand', 'recipient': 'siret'},
|
|
status=200)
|
|
# try to get document with wrong signature
|
|
url = document['url']
|
|
wrong_url = document['url'] + "wrong/"
|
|
resp = app.get(wrong_url, status=404)
|
|
|
|
# try expired url
|
|
freezer.move_to(timezone.now() + timezone.timedelta(days=8))
|
|
resp = app.get(document['url'], status=404)
|
|
|
|
|
|
def test_error_500(app, resource, mock_api_entreprise):
|
|
with HTTMock(api_entreprise_error_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, mock_api_entreprise):
|
|
with HTTMock(api_entreprise_error_not_json):
|
|
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, mock_api_entreprise):
|
|
with HTTMock(api_entreprise_error_not_found):
|
|
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, mock_api_entreprise):
|
|
with HTTMock(api_entreprise_connection_error):
|
|
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'] == []
|