Make the connector more generic; Fixed urls and some pylint issues

Features
    * Added 'get_courrier_type' endpoint that return a 'courrier type' for a given type_dossier
    * Added url parameter 'type_dossier_detaille' to 'create_dossier' to post it in the request body
    * Replaced the way 'type fichier' is defined: now looks into 'XXX_type_raw' for file 'XXX'

Fixes
    * Url components are now encoded
    * Pylint warnings
    * Loging do not raise an error when 'files' var is empty in 'create_dossier'

Tests
    * Added 2 new errors tests to 'test_create_dossier'
    * Added 'test_get_courrier_type' to test endpoint 'get_courrier_type'
    * Fixed pylint warnings
This commit is contained in:
Michael Bideau 2019-10-24 17:24:55 +02:00
parent 6197d8ae62
commit 6809c75d33
3 changed files with 247 additions and 44 deletions

View File

@ -144,7 +144,7 @@ JSON_SCHEMA_CREATE_DOSSIER_IN = {
"terrain_code_postal", "terrain_code_postal",
"terrain_localite", "terrain_localite",
"reference_cadastrale", "reference_cadastrale",
"proprietaire", #"proprietaire",
"qualite", "qualite",
"nom", "nom",
"prenom", "prenom",

View File

@ -24,11 +24,12 @@ import base64
import datetime import datetime
import json import json
import os import os
import re
import urlparse import urlparse
import magic import magic
from urllib import quote
from django.db import models from django.db import models
from django.http import Http404 from django.http import Http404
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -162,6 +163,8 @@ class ForwardFile(models.Model, BaseModel): # pylint: disable=too-many-instance
# @see: https://docs.djangoproject.com/en/2.2/topics/db/models/ # @see: https://docs.djangoproject.com/en/2.2/topics/db/models/
# The note entitled "Overridden model methods are not called on bulk operations" # The note entitled "Overridden model methods are not called on bulk operations"
def save(self, *args, **kwargs): # pylint: disable=arguments-differ def save(self, *args, **kwargs): # pylint: disable=arguments-differ
"""Save the entity, overwritten to preprocessing data and validate model."""
# delete file content (on success) # delete file content (on success)
if self.upload_status == 'success': if self.upload_status == 'success':
# pylint: disable=no-member # pylint: disable=no-member
@ -181,6 +184,8 @@ class ForwardFile(models.Model, BaseModel): # pylint: disable=too-many-instance
# 'file_hash', 'orig_filename', 'upload_file' # 'file_hash', 'orig_filename', 'upload_file'
# because if they are all empty we dont have any usefull information about the upload # because if they are all empty we dont have any usefull information about the upload
def clean(self, *args, **kwargs): # pylint: disable=arguments-differ def clean(self, *args, **kwargs): # pylint: disable=arguments-differ
"""Check all the fields, overwritten to check grouped blank/null fields."""
ret = super(ForwardFile, self).clean(*args, **kwargs) ret = super(ForwardFile, self).clean(*args, **kwargs)
if (not self.file_hash if (not self.file_hash
and not self.orig_filename and not self.orig_filename
@ -226,7 +231,7 @@ class Collectivite(models.Model, BaseModel):
if fields: if fields:
rels = [] rels = []
for rel_name in ['forward_file', 'guichet']: for rel_name in ['forward_file', 'guichet']:
if (fields[0] and hasattr(fields[0], 'name') and fields[0].name == rel_name): if fields[0] and hasattr(fields[0], 'name') and fields[0].name == rel_name:
rels.append(fields.pop(0)) rels.append(fields.pop(0))
for rel in reversed(rels): for rel in reversed(rels):
fields.append(rel) fields.append(rel)
@ -510,7 +515,7 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
# } # }
# } # }
) )
# pylint: disable=unused-argument,arguments-differ,keyword-arg-before-vararg # pylint: disable=unused-argument,arguments-differ
def check_status(self, request=None, *args, **kwargs): def check_status(self, request=None, *args, **kwargs):
"""Check avaibility of the openADS.API service.""" """Check avaibility of the openADS.API service."""
url = urlparse.urljoin(self.openADS_API_url, '__api__') url = urlparse.urljoin(self.openADS_API_url, '__api__')
@ -525,6 +530,8 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
example_pattern='{type_dossier}/', example_pattern='{type_dossier}/',
parameters={ parameters={
'type_dossier': {'description': _("Type of 'dossier'"), 'example_value': 'DIA'}, 'type_dossier': {'description': _("Type of 'dossier'"), 'example_value': 'DIA'},
'type_dossier_detaille': {'description': _("Detailled type of 'dossier'"),
'example_value': 'CUb'},
'collectivite': { 'collectivite': {
'description': _("Use this collectivite (instead of the default one)"), 'description': _("Use this collectivite (instead of the default one)"),
'example_value': '3' 'example_value': '3'
@ -537,7 +544,7 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
'request_body': { 'request_body': {
'schema': { 'schema': {
'application/json': JSON_SCHEMA_CREATE_DOSSIER_IN 'application/json': JSON_SCHEMA_CREATE_DOSSIER_IN
} # pylint: disable=too-many-statements,too-many-branches,too-many-locals } # pylint: disable=too-many-statements,too-many-branches,too-many-locals,too-many-arguments
} }
# 'response_body': { # 'response_body': {
# 'schema': { # 'schema': {
@ -546,8 +553,9 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
# } # }
} }
) )
# pylint: disable=unused-argument,keyword-arg-before-vararg # pylint: disable=unused-argument
def create_dossier(self, request, type_dossier, collectivite=None, now=None, *args, **kwargs): def create_dossier(self, request, type_dossier, type_dossier_detaille=None, collectivite=None,
now=None, *args, **kwargs):
"""Create an openADS 'dossier'.""" """Create an openADS 'dossier'."""
# loads the request body as JSON content # loads the request body as JSON content
@ -571,7 +579,7 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
else: else:
# the collectivite has a guichet # the collectivite has a guichet
if (hasattr(collectivite, 'guichet') and collectivite.guichet): if hasattr(collectivite, 'guichet') and collectivite.guichet:
# get the datetime against which the 'guichet' is checked for opening # get the datetime against which the 'guichet' is checked for opening
now_fmt = '%Y-%m-%d %H:%M:%S' now_fmt = '%Y-%m-%d %H:%M:%S'
@ -592,7 +600,13 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
return {'message': _(u"Guichet closed for collectivite '%s'" % collectivite)} return {'message': _(u"Guichet closed for collectivite '%s'" % collectivite)}
# build the payload # build the payload
payload = {"collectivite": int(collectivite_id)} payload = {
"collectivite": int(collectivite_id),
#"type_detaille": type_dossier
}
if type_dossier_detaille:
payload["type_detaille"] = type_dossier_detaille
payload["terrain"] = { payload["terrain"] = {
"numero_voie": normalize(json_data['fields']['terrain_numero_voie']), "numero_voie": normalize(json_data['fields']['terrain_numero_voie']),
@ -620,7 +634,8 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
# setup demandeur variable prefix # setup demandeur variable prefix
prefixes = {"demandeurs": ''} prefixes = {"demandeurs": ''}
if normalize(json_data['fields']['proprietaire']) != 'Oui': if ('proprietaire' in json_data['fields'] and
normalize(json_data['fields']['proprietaire']) != 'Oui'):
prefixes["mandataires"] = 'mandataire_' prefixes["mandataires"] = 'mandataire_'
# for each type of demandeur with associated prefix # for each type of demandeur with associated prefix
@ -679,7 +694,7 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
self.log_json_payload(payload) self.log_json_payload(payload)
# every field key that might contain a file content # every field key that might contain a file content
file_keys = ['cerfa'] + ['plan_cadastral_%s' % i for i in range(1, 5)] + ['pouvoir_mandat'] file_keys = ['cerfa'] + ['annexe_%s' % i for i in range(1, 5)]
# prepare files that will be forwarded # prepare files that will be forwarded
files = [] files = []
@ -688,6 +703,7 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
and json_data['fields'][k] and json_data['fields'][k]
and isinstance(json_data['fields'][k], dict) and isinstance(json_data['fields'][k], dict)
and 'content' in json_data['fields'][k]): and 'content' in json_data['fields'][k]):
# get the content decoded from base 64 # get the content decoded from base 64
content = base64.b64decode(json_data['fields'][k]['content']) content = base64.b64decode(json_data['fields'][k]['content'])
@ -728,8 +744,18 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
elif '.' not in filename: elif '.' not in filename:
filename += file_extension filename += file_extension
# set the type fichier based on the key (less than 10 chars) # get the type fichier (less than 10 chars)
type_fichier = re.sub(r'_.*$', '', k)[:10] type_fichier = None
if k + '_type_raw' in json_data['fields']:
type_fichier = json_data['fields'][k + '_type_raw']
if len(type_fichier) > 10:
raise APIError(u"Type '%s' for file '%s' is too long "
"(%d chars, but max is %d)" % (
type_fichier, k, len(type_fichier), 10))
elif k.lower() == 'cerfa':
type_fichier = 'CERFA'
else:
raise APIError(u"No type field/value for file '%s'" % k)
# append the file to the list # append the file to the list
files.append({ files.append({
@ -742,11 +768,11 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
# log files to be forwarded # log files to be forwarded
self.logger.debug("----- files (begining) -----") self.logger.debug("----- files (begining) -----")
self.logger.debug("%r", files) self.logger.debug('%s', files) if files else self.logger.debug("(no files)") # pylint: disable=expression-not-assigned
self.logger.debug("----- files (end) -----") self.logger.debug("----- files (end) -----")
# make a request to openADS.API (with the payload) # make a request to openADS.API (with the payload)
url = urlparse.urljoin(self.openADS_API_url, '/dossiers/%s' % type_dossier) url = urlparse.urljoin(self.openADS_API_url, '/dossiers/%s' % quote(type_dossier))
response = self.requests.post( response = self.requests.post(
url, url,
json=payload, json=payload,
@ -863,13 +889,13 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
# } # }
# } # }
) )
# pylint: disable=unused-argument,keyword-arg-before-vararg # pylint: disable=unused-argument
def get_dossier(self, request, type_dossier, numero_dossier, *args, **kwargs): def get_dossier(self, request, type_dossier, numero_dossier, *args, **kwargs):
"""Get informations about an openADS 'dossier'.""" """Get informations about an openADS 'dossier'."""
# make a request to openADS.API # make a request to openADS.API
url = urlparse.urljoin(self.openADS_API_url, url = urlparse.urljoin(self.openADS_API_url, '/dossier/%s/%s' % (
'/dossier/%s/%s' % (type_dossier, numero_dossier)) quote(type_dossier), quote(numero_dossier)))
response = self.requests.get(url) response = self.requests.get(url)
# response is an error # response is an error
@ -910,7 +936,7 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
# } # }
# } # }
) )
# pylint: disable=unused-argument,keyword-arg-before-vararg,no-self-use # pylint: disable=unused-argument,no-self-use
def get_fwd_files(self, request, numero_dossier, fichier_id=None, *args, **kwargs): def get_fwd_files(self, request, numero_dossier, fichier_id=None, *args, **kwargs):
"""Get informations about the forwarding of user files to openADS.""" """Get informations about the forwarding of user files to openADS."""
payload = [] payload = []
@ -973,7 +999,7 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
# } # }
# } # }
) )
# pylint: disable=unused-argument,keyword-arg-before-vararg # pylint: disable=unused-argument
def get_fwd_files_status(self, request, numero_dossier, fichier_id=None, *args, **kwargs): def get_fwd_files_status(self, request, numero_dossier, fichier_id=None, *args, **kwargs):
"""Get informations about the forwarding of a user file to openADS.""" """Get informations about the forwarding of a user file to openADS."""
@ -1006,7 +1032,7 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
@endpoint( @endpoint(
perm='can_access', perm='can_access',
description=_("Get a 'courrier' from an openADS 'dossier'"), description=_("Get a 'courrier' from an openADS 'dossier'"),
pattern='^(?P<type_dossier>\w+)/(?P<numero_dossier>\w+)/(?P<lettre_type>\w+)/?$', # noqa: W605,E501, pylint: disable=anomalous-backslash-in-string pattern='^(?P<type_dossier>\w+)/(?P<numero_dossier>\w+)/(?P<lettre_type>[\w.,_ -]+)/?$', # noqa: W605,E501, pylint: disable=anomalous-backslash-in-string
example_pattern='{type_dossier}/{numero_dossier}/{lettre_type}', example_pattern='{type_dossier}/{numero_dossier}/{lettre_type}',
parameters={ parameters={
'type_dossier': {'description': _("Type of 'dossier'"), 'example_value': 'DIA'}, 'type_dossier': {'description': _("Type of 'dossier'"), 'example_value': 'DIA'},
@ -1024,14 +1050,13 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
# } # }
# } # }
) )
# pylint: disable=unused-argument,keyword-arg-before-vararg # pylint: disable=unused-argument
def get_courrier(self, request, type_dossier, numero_dossier, lettre_type, *args, **kwargs): def get_courrier(self, request, type_dossier, numero_dossier, lettre_type, *args, **kwargs):
"""Get a 'courrier' from an openADS 'dossier'.""" """Get a 'courrier' from an openADS 'dossier'."""
# make a request to openADS.API # make a request to openADS.API
url = urlparse.urljoin( url = urlparse.urljoin(self.openADS_API_url, '/dossier/%s/%s/courrier/%s' % (
self.openADS_API_url, quote(type_dossier), quote(numero_dossier), quote(lettre_type)))
'/dossier/%s/%s/courrier/%s' % (type_dossier, numero_dossier, lettre_type))
response = self.requests.get(url) response = self.requests.get(url)
# response is an error # response is an error
@ -1115,7 +1140,7 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
# } # }
) )
# @raise ForwareFile.DoesNotExist if not found # @raise ForwareFile.DoesNotExist if not found
# pylint: disable=unused-argument,keyword-arg-before-vararg # pylint: disable=unused-argument
def upload_user_files(self, request, type_dossier, numero_dossier, file_ids=None, def upload_user_files(self, request, type_dossier, numero_dossier, file_ids=None,
*args, **kwargs): *args, **kwargs):
"""A Job to forward user uploaded files to openADS.""" """A Job to forward user uploaded files to openADS."""
@ -1198,8 +1223,8 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
self.log_json_payload(payload, 'payload') self.log_json_payload(payload, 'payload')
# make the request to openADS.API (with a specific timeout) # make the request to openADS.API (with a specific timeout)
url = urlparse.urljoin(self.openADS_API_url, url = urlparse.urljoin(self.openADS_API_url, '/dossier/%s/%s/files' % (
'/dossier/%s/%s/files' % (type_dossier, numero_dossier)) quote(type_dossier), quote(numero_dossier)))
response = self.requests.post( response = self.requests.post(
url, url,
json=payload, json=payload,
@ -1294,3 +1319,67 @@ class AtrealOpenads(BaseResource, HTTPResource, BaseModel):
# return something to please pylint # return something to please pylint
return True return True
@endpoint(
perm='can_access',
description=_("Get the type of 'courrier' of an openADS 'dossier'"),
pattern='^(?P<type_dossier>\w+)/?$', # noqa: W605,E501, pylint: disable=anomalous-backslash-in-string
example_pattern='{type_dossier}/',
parameters={
'type_dossier': {'description': _("Type of 'dossier'"), 'example_value': 'DIA'},
'type_dossier_detaille': {'description': _("Detailled type of 'dossier'"),
'example_value': 'CUb'},
'specific': {'description': _("Get a specific version of the 'courrier type'"),
'example_value': 'refus'},
} # pylint: disable=too-many-branches
) # pylint: disable=no-self-use
# pylint: disable=unused-argument
def get_courrier_type(self, request, type_dossier, type_dossier_detaille=None, specific=None,
*args, **kwargs):
"""Get the type of 'courrier' for an openADS 'dossier'."""
courrier_type = None
if type_dossier == 'DIA':
courrier_type = 'dia_renonciation_preempter'
if specific == 'delegation':
courrier_type = 'dia_delegation'
elif specific == 'irrecevabilite':
courrier_type = 'dia_irrecevabilite'
elif specific == 'preemption':
courrier_type = 'dia_souhait_preempter'
elif type_dossier == 'CU':
courrier_type = 'CUa'
if type_dossier_detaille == 'CUb':
courrier_type = 'CUb - ACCORD'
if specific == 'refus':
courrier_type = 'CUb - REFUS'
elif type_dossier == 'DP':
courrier_type = 'decision_non_opposition_DP'
if specific == 'annulation':
courrier_type = 'arrete_annulation_DP'
elif specific == 'prolongation':
courrier_type = 'arrete_prorogation_DP'
elif specific == 'prolongation_refus':
courrier_type = 'arrete_refus_prorogation_DP'
elif specific == 'transfert_refus':
courrier_type = 'arrete_refus_transfert_DP'
elif specific == 'transfert':
courrier_type = 'arrete_transfert_DP'
elif specific == 'attestation_tacite':
courrier_type = 'attestation_non opposition_tacite_DP'
elif specific == 'opposition':
courrier_type = 'decision_opposition_DP'
elif specific == 'certificat_tacite':
courrier_type = 'certificat_opposition_tacite_DP'
elif type_dossier == 'PC' or type_dossier == 'PI':
courrier_type = 'arrete_ss_reserves'
if specific == 'refus':
courrier_type = 'arrete_refus'
# TODO add others type and specifics variants
return {'courrier_type': courrier_type}

View File

@ -432,21 +432,24 @@ def test_create_dossier(fake_conf, atreal_openads, collectivite_1, collectivite_
"field_id": "50", "field_id": "50",
"filename": os.path.basename(fake_conf['TEST_FILE_CERFA_DIA']) "filename": os.path.basename(fake_conf['TEST_FILE_CERFA_DIA'])
}, },
"plan_cadastral_1": { "annexe_1_type_raw": "plan",
"annexe_1": {
"content": get_file_data(fake_conf['TEST_FILE_PLAN_CADASTRAL']), "content": get_file_data(fake_conf['TEST_FILE_PLAN_CADASTRAL']),
"content_type": "application/pdf", "content_type": "application/pdf",
"filename": os.path.basename(fake_conf['TEST_FILE_PLAN_CADASTRAL']) "filename": os.path.basename(fake_conf['TEST_FILE_PLAN_CADASTRAL'])
}, },
"plan_cadastral_2": { "annexe_2_type_raw": "plan",
"annexe_2": {
"content": get_file_data(fake_conf['TEST_FILE_PLAN_CADASTRAL']), "content": get_file_data(fake_conf['TEST_FILE_PLAN_CADASTRAL']),
"content_type": "application/pdf", "content_type": "application/pdf",
# "filename": 'plan_cad' # "filename": 'plan_cad'
}, },
"pouvoir_mandat": { "annexe_3_type_raw": "pouvoir",
"annexe_3": {
"content": get_file_data(fake_conf['TEST_FILE_CERFA_DIA']), "content": get_file_data(fake_conf['TEST_FILE_CERFA_DIA']),
"content_type": "application/pdf", "content_type": "application/pdf",
"filename": 'mandat' "filename": 'mandat'
} },
} }
} }
request_1.method = 'POST' request_1.method = 'POST'
@ -469,7 +472,8 @@ def test_create_dossier(fake_conf, atreal_openads, collectivite_1, collectivite_
with pytest.raises(APIError) as exception: with pytest.raises(APIError) as exception:
with mock.patch('passerelle.utils.Request.post') as requests_post: with mock.patch('passerelle.utils.Request.post') as requests_post:
requests_post.return_value = fake_resp_bad requests_post.return_value = fake_resp_bad
atreal_openads.create_dossier(request_1, 'DIA', collectivite_1.openADS_id, now=now_open) atreal_openads.create_dossier(request_1, 'DIA', collectivite=collectivite_1.openADS_id,
now=now_open)
assert unicode(exception.value) == "HTTP error: 502" assert unicode(exception.value) == "HTTP error: 502"
# TODO update the code and return message when it will be # TODO update the code and return message when it will be
@ -484,7 +488,8 @@ def test_create_dossier(fake_conf, atreal_openads, collectivite_1, collectivite_
atreal_openads.create_dossier(request_1, 'DIA', collectivite=999) atreal_openads.create_dossier(request_1, 'DIA', collectivite=999)
assert unicode(exception.value) == "HTTP error: 404" assert unicode(exception.value) == "HTTP error: 404"
jresp = atreal_openads.create_dossier(request_1, 'DIA', collectivite_1.openADS_id, now_closed) jresp = atreal_openads.create_dossier(request_1, 'DIA', collectivite=collectivite_1.openADS_id,
now=now_closed)
assert jresp is not None assert jresp is not None
assert len(jresp) == 1 assert len(jresp) == 1
assert 'message' in jresp assert 'message' in jresp
@ -492,8 +497,8 @@ def test_create_dossier(fake_conf, atreal_openads, collectivite_1, collectivite_
now_str_fmt = '%Y-%m-%d %H:%M:%S' now_str_fmt = '%Y-%m-%d %H:%M:%S'
now_closed_str = now_closed.strftime(now_str_fmt) now_closed_str = now_closed.strftime(now_str_fmt)
jresp = atreal_openads.create_dossier(request_1, 'DIA', collectivite_1.openADS_id, jresp = atreal_openads.create_dossier(request_1, 'DIA', collectivite=collectivite_1.openADS_id,
now_closed_str) now=now_closed_str)
assert jresp is not None assert jresp is not None
assert len(jresp) == 1 assert len(jresp) == 1
assert 'message' in jresp assert 'message' in jresp
@ -501,14 +506,42 @@ def test_create_dossier(fake_conf, atreal_openads, collectivite_1, collectivite_
now_invalid = {'invalid': 'type'} now_invalid = {'invalid': 'type'}
with pytest.raises(APIError) as exception: with pytest.raises(APIError) as exception:
jresp = atreal_openads.create_dossier(request_1, 'DIA', collectivite_1.openADS_id, jresp = atreal_openads.create_dossier(request_1, 'DIA',
now_invalid) collectivite=collectivite_1.openADS_id,
now=now_invalid)
assert unicode(exception.value) == ( assert unicode(exception.value) == (
u"Invalid value of type '%s' for now argument of endpoint '%s' (must be: %s)" % ( u"Invalid value of type '%s' for now argument of endpoint '%s' (must be: %s)" % (
type(now_invalid), type(now_invalid),
'create_dossier', 'create_dossier',
"datetime or string formatted to '%s'" % now_str_fmt)) "datetime or string formatted to '%s'" % now_str_fmt))
annexe_3_type_bak = fake_req_json['fields']['annexe_3_type_raw']
fake_req_json['fields']['annexe_3_type_raw'] = 'toooooooooooo_looonnnngggggg'
request_1._body = json.dumps(fake_req_json) # pylint: disable=protected-access
with pytest.raises(APIError) as exception:
with mock.patch('passerelle.utils.Request.post') as requests_post:
requests_post.return_value = fake_resp_bad
atreal_openads.create_dossier(request_1, 'DIA', collectivite=collectivite_1.openADS_id,
now=now_open)
assert unicode(exception.value) == (
u"Type '%s' for file '%s' is too long (%d chars, but max is %d)" % (
fake_req_json['fields']['annexe_3_type_raw'],
'annexe_3',
len(fake_req_json['fields']['annexe_3_type_raw']),
10))
del fake_req_json['fields']['annexe_3_type_raw']
request_1._body = json.dumps(fake_req_json) # pylint: disable=protected-access
with pytest.raises(APIError) as exception:
with mock.patch('passerelle.utils.Request.post') as requests_post:
requests_post.return_value = fake_resp_bad
atreal_openads.create_dossier(request_1, 'DIA', collectivite=collectivite_1.openADS_id,
now=now_open)
assert unicode(exception.value) == u"No type field/value for file '%s'" % 'annexe_3'
fake_req_json['fields']['annexe_3_type_raw'] = annexe_3_type_bak
request_1._body = json.dumps(fake_req_json) # pylint: disable=protected-access
fake_resp_json = { fake_resp_json = {
'numero_dossier': fake_conf['FAKE_NUMERO_DOSSIER'], 'numero_dossier': fake_conf['FAKE_NUMERO_DOSSIER'],
'files': [{ 'files': [{
@ -526,8 +559,9 @@ def test_create_dossier(fake_conf, atreal_openads, collectivite_1, collectivite_
with mock.patch('passerelle.utils.Request.post') as requests_post: with mock.patch('passerelle.utils.Request.post') as requests_post:
requests_post.return_value = fake_resp requests_post.return_value = fake_resp
jresp = atreal_openads.create_dossier(request_1, 'DIA', collectivite_1.openADS_id, jresp = atreal_openads.create_dossier(request_1, 'DIA',
now=now_open) collectivite=collectivite_1.openADS_id,
now=now_open, type_dossier_detaille='DIA')
assert jresp['numero_dossier'] == fake_resp_json['numero_dossier'] assert jresp['numero_dossier'] == fake_resp_json['numero_dossier']
assert jresp['recepisse']['b64_content'] == fake_resp_json['files'][0]['b64_content'] assert jresp['recepisse']['b64_content'] == fake_resp_json['files'][0]['b64_content']
assert jresp['recepisse']['content_type'] == 'application/pdf' assert jresp['recepisse']['content_type'] == 'application/pdf'
@ -538,7 +572,8 @@ def test_create_dossier(fake_conf, atreal_openads, collectivite_1, collectivite_
with pytest.raises(APIError) as exception: with pytest.raises(APIError) as exception:
with mock.patch('passerelle.utils.Request.post') as requests_post: with mock.patch('passerelle.utils.Request.post') as requests_post:
requests_post.return_value = fake_resp requests_post.return_value = fake_resp
atreal_openads.create_dossier(request_1, 'DIA', collectivite_1.openADS_id, now=now_open) atreal_openads.create_dossier(request_1, 'DIA', collectivite=collectivite_1.openADS_id,
now=now_open)
assert unicode(exception.value) == ( assert unicode(exception.value) == (
u"Expecting '%s' value in JSON response to be a %s (not a %s)" % ( u"Expecting '%s' value in JSON response to be a %s (not a %s)" % (
'numero_dossier', 'string', type({}))) 'numero_dossier', 'string', type({})))
@ -548,7 +583,8 @@ def test_create_dossier(fake_conf, atreal_openads, collectivite_1, collectivite_
with pytest.raises(APIError) as exception: with pytest.raises(APIError) as exception:
with mock.patch('passerelle.utils.Request.post') as requests_post: with mock.patch('passerelle.utils.Request.post') as requests_post:
requests_post.return_value = fake_resp requests_post.return_value = fake_resp
atreal_openads.create_dossier(request_1, 'DIA', collectivite_1.openADS_id, now=now_open) atreal_openads.create_dossier(request_1, 'DIA', collectivite=collectivite_1.openADS_id,
now=now_open)
assert unicode(exception.value) == u"Expecting 'numero_dossier' key in JSON response" assert unicode(exception.value) == u"Expecting 'numero_dossier' key in JSON response"
fake_resp_json['files'][0]['b64_content'] = 'invalid_;{[content}' fake_resp_json['files'][0]['b64_content'] = 'invalid_;{[content}'
@ -556,14 +592,16 @@ def test_create_dossier(fake_conf, atreal_openads, collectivite_1, collectivite_
with pytest.raises(APIError) as exception: with pytest.raises(APIError) as exception:
with mock.patch('passerelle.utils.Request.post') as requests_post: with mock.patch('passerelle.utils.Request.post') as requests_post:
requests_post.return_value = fake_resp requests_post.return_value = fake_resp
atreal_openads.create_dossier(request_1, 'DIA', collectivite_1.openADS_id, now=now_open) atreal_openads.create_dossier(request_1, 'DIA', collectivite=collectivite_1.openADS_id,
now=now_open)
assert unicode(exception.value) == u'Failed to decode recepisse content from base 64' assert unicode(exception.value) == u'Failed to decode recepisse content from base 64'
fake_resp._content = 'df[{gfd;g#vfd' # pylint: disable=protected-access fake_resp._content = 'df[{gfd;g#vfd' # pylint: disable=protected-access
with pytest.raises(APIError) as exception: with pytest.raises(APIError) as exception:
with mock.patch('passerelle.utils.Request.post') as requests_post: with mock.patch('passerelle.utils.Request.post') as requests_post:
requests_post.return_value = fake_resp requests_post.return_value = fake_resp
atreal_openads.create_dossier(request_1, 'DIA', collectivite_1.openADS_id, now=now_open) atreal_openads.create_dossier(request_1, 'DIA', collectivite=collectivite_1.openADS_id,
now=now_open)
# pylint: disable=protected-access # pylint: disable=protected-access
assert unicode(exception.value) == u'No JSON content returned: %r' % fake_resp._content assert unicode(exception.value) == u'No JSON content returned: %r' % fake_resp._content
@ -955,3 +993,79 @@ def test_upload_user_files(fake_conf, atreal_openads, request_1):
assert ffup.upload_attempt == 3 assert ffup.upload_attempt == 3
assert ffup.upload_status == 'success' assert ffup.upload_status == 'success'
assert ffup.upload_msg == 'uploaded successfuly' assert ffup.upload_msg == 'uploaded successfuly'
# pylint: disable=unused-argument,redefined-outer-name
# pylint: disable=too-many-statements
def test_get_courrier_type(fake_conf, atreal_openads):
"""Test the method AtrealOpenads.get_courrier_type()."""
type_mapping = {
'DIA': {
'default': 'dia_renonciation_preempter',
'detailled': [],
'specifics': [
('delegation', 'dia_delegation'),
('irrecevabilite', 'dia_irrecevabilite'),
('preemption', 'dia_souhait_preempter')]},
'CU': {
'default': 'CUa',
'detailled': ['CUa', 'CUb'],
'CUb': {
'default': 'CUb - ACCORD',
'specifics': [
('refus', 'CUb - REFUS')]}},
'DP': {
'default': 'decision_non_opposition_DP',
'detailled': [],
'specifics': [
('annulation', 'arrete_annulation_DP'),
('prolongation', 'arrete_prorogation_DP'),
('prolongation_refus', 'arrete_refus_prorogation_DP'),
('transfert_refus', 'arrete_refus_transfert_DP'),
('transfert', 'arrete_transfert_DP'),
('attestation_tacite', 'attestation_non opposition_tacite_DP'),
('opposition', 'decision_opposition_DP'),
('certificat_tacite', 'certificat_opposition_tacite_DP')]},
'PC': {
'default': 'arrete_ss_reserves',
'detailled': [],
'specifics': [
('refus', 'arrete_refus')]},
'PI': {
'default': 'arrete_ss_reserves',
'detailled': [],
'specifics': [
('refus', 'arrete_refus')]}
}
# pylint: disable=too-many-nested-blocks
for type_dossier, infos in type_mapping.items():
courrier_type = infos['default']
types_detailles = infos['detailled'] if infos['detailled'] else [None]
for type_detaille in types_detailles:
if type_detaille:
if type_detaille in infos:
if 'default' in infos[type_detaille]:
courrier_type = infos[type_detaille]['default']
res = atreal_openads.get_courrier_type(None, type_dossier,
type_dossier_detaille=type_detaille)
assert res == {'courrier_type': courrier_type}
if 'specifics' in infos[type_detaille]:
for specific_t in infos[type_detaille]['specifics']:
res = atreal_openads.get_courrier_type(
None, type_dossier, type_dossier_detaille=type_detaille,
specific=specific_t[0])
assert res == {'courrier_type': specific_t[1]}
elif 'specifics' in infos:
for specific_t in infos['specifics']:
res = atreal_openads.get_courrier_type(None, type_dossier,
type_dossier_detaille=type_detaille,
specific=specific_t[0])
assert res == {'courrier_type': specific_t[1]}
else:
res = atreal_openads.get_courrier_type(None, type_dossier)
assert res == {'courrier_type': courrier_type}