Refactoring: fix most of the (many many) 'pylint' complaints

This commit is contained in:
Michael Bideau 2019-08-22 14:44:52 +00:00
parent 2786bc29e7
commit afcca49f53
11 changed files with 1953 additions and 1203 deletions

408
.pylintrc Normal file
View File

@ -0,0 +1,408 @@
[MASTER]
# Specify a configuration file.
#rcfile=
# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
#init-hook=
# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=CVS
# Add files or directories matching the regex patterns to the blacklist. The
# regex matches against base names, not paths.
ignore-patterns=
# Pickle collected data for later comparisons.
persistent=yes
# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=
# Use multiple processes to speed up Pylint.
jobs=1
# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code
extension-pkg-whitelist=
# Allow optimization of some AST trees. This will activate a peephole AST
# optimizer, which will apply various small optimizations. For instance, it can
# be used to obtain the result of joining multiple strings with the addition
# operator. Joining a lot of strings can lead to a maximum recursion error in
# Pylint and this flag can prevent that. It has one side effect, the resulting
# AST will be different than the one from reality. This option is deprecated
# and it will be removed in Pylint 2.0.
optimize-ast=no
[MESSAGES CONTROL]
# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
confidence=
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once). See also the "--disable" option for examples.
#enable=
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once).You can also use "--disable=all" to
# disable everything first and then reenable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
#disable=import-star-module-level,old-octal-literal,oct-method,print-statement,unpacking-in-except,parameter-unpacking,backtick,old-raise-syntax,old-ne-operator,long-suffix,dict-view-method,dict-iter-method,metaclass-assignment,next-method-called,raising-string,indexing-exception,raw_input-builtin,long-builtin,file-builtin,execfile-builtin,coerce-builtin,cmp-builtin,buffer-builtin,basestring-builtin,apply-builtin,filter-builtin-not-iterating,using-cmp-argument,useless-suppression,range-builtin-not-iterating,suppressed-message,no-absolute-import,old-division,cmp-method,reload-builtin,zip-builtin-not-iterating,intern-builtin,unichr-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,input-builtin,round-builtin,hex-method,nonzero-method,map-builtin-not-iterating
disable=import-star-module-level,old-octal-literal,oct-method,print-statement,unpacking-in-except,parameter-unpacking,backtick,old-raise-syntax,old-ne-operator,long-suffix,dict-view-method,dict-iter-method,metaclass-assignment,next-method-called,raising-string,indexing-exception,raw_input-builtin,long-builtin,file-builtin,execfile-builtin,coerce-builtin,cmp-builtin,buffer-builtin,basestring-builtin,apply-builtin,filter-builtin-not-iterating,using-cmp-argument,useless-suppression,range-builtin-not-iterating,suppressed-message,no-absolute-import,old-division,cmp-method,reload-builtin,zip-builtin-not-iterating,intern-builtin,unichr-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,input-builtin,round-builtin,hex-method,nonzero-method,map-builtin-not-iterating
[REPORTS]
# Set the output format. Available formats are text, parseable, colorized, msvs
# (visual studio) and html. You can also give a reporter class, eg
# mypackage.mymodule.MyReporterClass.
output-format=text
# Put messages in a separate file for each module / package specified on the
# command line instead of printing them on stdout. Reports (if any) will be
# written in a file name "pylint_global.[txt|html]". This option is deprecated
# and it will be removed in Pylint 2.0.
files-output=no
# Tells whether to display a full report or only the messages
reports=yes
# Python expression which should return a note less than 10 (10 is the highest
# note). You have access to the variables errors warning, statement which
# respectively contain the number of errors / warnings messages and the total
# number of statements analyzed. This is used by the global evaluation report
# (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details
#msg-template=
[BASIC]
# Good variable names which should always be accepted, separated by a comma
good-names=i,j,k,ex,Run,_
# Bad variable names which should always be refused, separated by a comma
bad-names=foo,bar,baz,toto,tutu,tata
# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=
# Include a hint for the correct naming format with invalid-name
include-naming-hint=no
# List of decorators that produce properties, such as abc.abstractproperty. Add
# to this list to register other decorators that produce valid properties.
property-classes=abc.abstractproperty
# Regular expression matching correct function names
function-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for function names
function-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct variable names
variable-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for variable names
variable-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct constant names
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Naming hint for constant names
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Regular expression matching correct attribute names
attr-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for attribute names
attr-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct argument names
argument-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for argument names
argument-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct class attribute names
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
# Naming hint for class attribute names
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
# Regular expression matching correct inline iteration names
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
# Naming hint for inline iteration names
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
# Regular expression matching correct class names
class-rgx=[A-Z_][a-zA-Z0-9]+$
# Naming hint for class names
class-name-hint=[A-Z_][a-zA-Z0-9]+$
# Regular expression matching correct module names
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Naming hint for module names
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Regular expression matching correct method names
method-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for method names
method-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=^_
# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=-1
[ELIF]
# Maximum number of nested blocks for function / method body
max-nested-blocks=5
[SIMILARITIES]
# Minimum lines number of a similarity.
min-similarity-lines=4
# Ignore comments when computing similarities.
ignore-comments=yes
# Ignore docstrings when computing similarities.
ignore-docstrings=yes
# Ignore imports when computing similarities.
ignore-imports=no
[TYPECHECK]
# Tells whether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes
# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching.
ignored-modules=
# List of class names for which member attributes should not be checked (useful
# for classes with dynamically set attributes). This supports the use of
# qualified names.
ignored-classes=optparse.Values,thread._local,_thread._local
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
generated-members=
# List of decorators that produce context managers, such as
# contextlib.contextmanager. Add to this list to register other decorators that
# produce valid context managers.
contextmanager-decorators=contextlib.contextmanager
[VARIABLES]
# Tells whether we should check for unused import in __init__ files.
init-import=no
# A regular expression matching the name of dummy variables (i.e. expectedly
# not used).
dummy-variables-rgx=(_+[a-zA-Z0-9]*?$)|dummy
# List of additional names supposed to be defined in builtins. Remember that
# you should avoid to define new builtins when possible.
additional-builtins=
# List of strings which can identify a callback function by name. A callback
# name must start or end with one of those strings.
callbacks=cb_,_cb
# List of qualified module names which can have objects that can redefine
# builtins.
redefining-builtins-modules=six.moves,future.builtins
[LOGGING]
# Logging modules to check that the string format arguments are in logging
# function parameter format
logging-modules=logging
[FORMAT]
# Maximum number of characters on a single line.
max-line-length=100
# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=no
# List of optional constructs for which whitespace checking is disabled. `dict-
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
# `empty-line` allows space-only lines.
no-space-check=trailing-comma,dict-separator
# Maximum number of lines in a module
max-module-lines=1000
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
indent-string=' '
# Number of spaces of indent required inside a hanging or continued line.
indent-after-paren=4
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
expected-line-ending-format=
[SPELLING]
# Spelling dictionary name. Available dictionaries: none. To make it working
# install python-enchant package.
spelling-dict=
# List of comma separated words that should not be checked.
spelling-ignore-words=
# A path to a file that contains private dictionary; one word per line.
spelling-private-dict-file=
# Tells whether to store unknown words to indicated private dictionary in
# --spelling-private-dict-file option instead of raising a message.
spelling-store-unknown-words=no
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,XXX,TODO
[CLASSES]
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,__new__,setUp
# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls
# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=mcs
# List of member names, which should be excluded from the protected access
# warning.
exclude-protected=_asdict,_fields,_replace,_source,_make
[DESIGN]
# Maximum number of arguments for function / method
max-args=5
# Argument names that match this expression will be ignored. Default to name
# with leading underscore
ignored-argument-names=_.*
# Maximum number of locals for function / method body
max-locals=15
# Maximum number of return / yield for function / method body
max-returns=6
# Maximum number of branch for function / method body
max-branches=12
# Maximum number of statements in function / method body
max-statements=50
# Maximum number of parents for a class (see R0901).
max-parents=7
# Maximum number of attributes for a class (see R0902).
max-attributes=7
# Minimum number of public methods for a class (see R0903).
min-public-methods=2
# Maximum number of public methods for a class (see R0904).
max-public-methods=20
# Maximum number of boolean expressions in a if statement
max-bool-expr=5
[IMPORTS]
# Deprecated modules which should not be used, separated by a comma
deprecated-modules=regsub,TERMIOS,Bastion,rexec
# Create a graph of every (i.e. internal and external) dependencies in the
# given file (report RP0402 must not be disabled)
import-graph=
# Create a graph of external dependencies in the given file (report RP0402 must
# not be disabled)
ext-import-graph=
# Create a graph of internal dependencies in the given file (report RP0402 must
# not be disabled)
int-import-graph=
# Force import order to recognize a module as part of the standard
# compatibility libraries.
known-standard-library=
# Force import order to recognize a module as part of a third party library.
known-third-party=enchant
# Analyse import fallback blocks. This can be used to support both Python 2 and
# 3 compatible code, which means that the block might have code that exists
# only in one or another interpreter, leading to false positives when analysed.
analyse-fallback-blocks=no
[EXCEPTIONS]
# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=Exception

View File

@ -18,67 +18,70 @@
# You should have received a copy of the GNU Affero General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Forms for each of the Models."""
from django.forms import ModelForm from django.forms import ModelForm
from .models import ForwardFile, Collectivite, Guichet from .models import ForwardFile, Collectivite, Guichet
class ForwardFileForm(ModelForm): class ForwardFileForm(ModelForm):
"""Form for the ForwardFile model."""
class Meta: class Meta:
model = ForwardFile # pylint: disable=too-few-public-methods,no-init,old-style-class,missing-docstring
model = ForwardFile
exclude = ['connecteur', 'size', 'file_hash'] exclude = ['connecteur', 'size', 'file_hash']
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
connecteur = kwargs.pop('connecteur' , None) connecteur = kwargs.pop('connecteur', None)
collectivite = kwargs.pop('collectivite', None) collectivite = kwargs.pop('collectivite', None)
super(ForwardFileForm, self).__init__(*args, **kwargs) super(ForwardFileForm, self).__init__(*args, **kwargs)
if ( if ((not hasattr(self.instance, 'connecteur') or not self.instance.connecteur)
(not hasattr(self.instance, 'connecteur') or not self.instance.connecteur) and connecteur):
and connecteur
):
self.instance.connecteur = connecteur self.instance.connecteur = connecteur
if ( if ((not hasattr(self.instance, 'collectivite') or not self.instance.collectivite)
(not hasattr(self.instance, 'collectivite') or not self.instance.collectivite) and collectivite):
and collectivite
):
self.instance.collectivite = collectivite self.instance.collectivite = collectivite
# only allow to select a 'collectivite' that belongs to the connecteur # only allow to select a 'collectivite' that belongs to the connecteur
if hasattr(self.instance, 'connecteur') and self.instance.connecteur: if hasattr(self.instance, 'connecteur') and self.instance.connecteur:
self.fields['collectivite'].queryset = Collectivite.objects.filter(connecteur=self.instance.connecteur) # pylint: disable=no-member
self.fields['collectivite'].queryset = Collectivite.objects.filter(
connecteur=self.instance.connecteur)
# TODO if the status is 'uploading' make everything read-only # TODO if the status is 'uploading' make everything read-only
class CollectiviteForm(ModelForm): class CollectiviteForm(ModelForm):
"""Form for the Collectivite model."""
class Meta: class Meta:
model = Collectivite # pylint: disable=too-few-public-methods,no-init,old-style-class,missing-docstring
model = Collectivite
exclude = ['connecteur'] exclude = ['connecteur']
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
connecteur = kwargs.pop('connecteur', None) connecteur = kwargs.pop('connecteur', None)
super(CollectiviteForm, self).__init__(*args, **kwargs) super(CollectiviteForm, self).__init__(*args, **kwargs)
if ( if ((not hasattr(self.instance, 'connecteur') or not self.instance.connecteur)
(not hasattr(self.instance, 'connecteur') or not self.instance.connecteur) and connecteur):
and connecteur
):
self.instance.connecteur = connecteur self.instance.connecteur = connecteur
class GuichetForm(ModelForm): class GuichetForm(ModelForm):
"""Form for the Guichet model."""
class Meta: class Meta:
model = Guichet # pylint: disable=too-few-public-methods,no-init,old-style-class,missing-docstring
model = Guichet
exclude = ['collectivite'] exclude = ['collectivite']
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
collectivite = kwargs.pop('collectivite', None) collectivite = kwargs.pop('collectivite', None)
super(GuichetForm, self).__init__(*args, **kwargs) super(GuichetForm, self).__init__(*args, **kwargs)
if ( if ((not hasattr(self.instance, 'collectivite') or not self.instance.collectivite)
(not hasattr(self.instance, 'collectivite') or not self.instance.collectivite) and collectivite):
and collectivite
):
self.instance.collectivite = collectivite self.instance.collectivite = collectivite

View File

@ -18,6 +18,8 @@
# You should have received a copy of the GNU Affero General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""JSON schemas used by endpoints to validate input/ouput."""
# TODO add string limits (maxLength) # TODO add string limits (maxLength)
@ -27,11 +29,11 @@ JSON_SCHEMA_FILE = {
"$id" : "#file", "$id" : "#file",
"type": "object", "type": "object",
"properties": { "properties": {
"content" : { "type": "string" }, "content" : {"type": "string"},
"content_type": { "type": ["string","null"] }, "content_type": {"type": ["string", "null"]},
"filename" : { "type": "string" } "filename" : {"type": "string"}
}, },
"required": ["content","filename"] "required": ["content", "filename"]
} }
JSON_SCHEMA_FILE_B64 = { JSON_SCHEMA_FILE_B64 = {
@ -39,15 +41,16 @@ JSON_SCHEMA_FILE_B64 = {
"$id" : "#file", "$id" : "#file",
"type": "object", "type": "object",
"properties": { "properties": {
"b64_content" : { "type": "string" }, "b64_content" : {"type": "string"},
"content_type": { "type": ["string","null"] }, "content_type": {"type": ["string", "null"]},
"filename" : { "type": "string" } "filename" : {"type": "string"}
}, },
"required": ["b64_content","filename"] "required": ["b64_content", "filename"]
} }
JSON_SCHEMA_DATE_FRENCH = { JSON_SCHEMA_DATE_FRENCH = {
"type": "string", "type": "string",
# pylint: disable=anomalous-backslash-in-string
"pattern": "^(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/\d{4}$" "pattern": "^(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/\d{4}$"
} }
@ -56,7 +59,7 @@ JSON_SCHEMA_CHECK_STATUS_OUT = {
"title" : "Response of an openADS 'connexion' test", "title" : "Response of an openADS 'connexion' test",
"type" : "object", "type" : "object",
"properties": { "properties": {
"response": { "type": "integer" } "response": {"type": "integer"}
}, },
"required": ["response"] "required": ["response"]
} }
@ -78,7 +81,7 @@ JSON_SCHEMA_CREATE_DOSSIER_IN = {
"file": JSON_SCHEMA_FILE, "file": JSON_SCHEMA_FILE,
"file_plan_cadastral": { "file_plan_cadastral": {
"description": "A 'plan cadastral' document file", "description": "A 'plan cadastral' document file",
"anyOf": [{ "$ref": "#/definitions/file" }, { "type": "null" }] "anyOf": [{"$ref": "#/definitions/file"}, {"type": "null"}]
} }
}, },
"type": "object", "type": "object",
@ -89,22 +92,22 @@ JSON_SCHEMA_CREATE_DOSSIER_IN = {
"cerfa": { "cerfa": {
"description": "A 'CERFA' PDF document file", "description": "A 'CERFA' PDF document file",
"type": "object", "type": "object",
"allOf": [{"$ref": "#/definitions/file" }] "allOf": [{"$ref": "#/definitions/file"}]
}, },
"plan_cadastral_1": { "$ref": "#/definitions/file_plan_cadastral" }, "plan_cadastral_1": {"$ref": "#/definitions/file_plan_cadastral"},
"plan_cadastral_2": { "$ref": "#/definitions/file_plan_cadastral" }, "plan_cadastral_2": {"$ref": "#/definitions/file_plan_cadastral"},
"plan_cadastral_3": { "$ref": "#/definitions/file_plan_cadastral" }, "plan_cadastral_3": {"$ref": "#/definitions/file_plan_cadastral"},
"plan_cadastral_4": { "$ref": "#/definitions/file_plan_cadastral" }, "plan_cadastral_4": {"$ref": "#/definitions/file_plan_cadastral"},
"plan_cadastral_5": { "$ref": "#/definitions/file_plan_cadastral" }, "plan_cadastral_5": {"$ref": "#/definitions/file_plan_cadastral"},
"terrain_numero_voie" : { "type": "string" }, "terrain_numero_voie" : {"type": "string"},
"terrain_nom_voie" : { "type": "string" }, "terrain_nom_voie" : {"type": "string"},
"terrain_code_postal" : { "type": "string" }, "terrain_code_postal" : {"type": "string"},
"terrain_localite" : { "type": "string" }, "terrain_localite" : {"type": "string"},
"terrain_lieu_dit" : { "type": ["string","null"] }, "terrain_lieu_dit" : {"type": ["string", "null"]},
"reference_cadastrale": { "reference_cadastrale": {
"description": "A list of 'cadastrales' references", "description": "A list of 'cadastrales' references",
"type": "array", "type": "array",
"items": { "$ref": "#/definitions/refs-cadastrales" } "items": {"$ref": "#/definitions/refs-cadastrales"}
}, },
"autres_parcelles": { "autres_parcelles": {
"type": "boolean" "type": "boolean"
@ -113,24 +116,24 @@ JSON_SCHEMA_CREATE_DOSSIER_IN = {
"description": "A list of 'cadastrales' references", "description": "A list of 'cadastrales' references",
# conditionaly required and typed below # conditionaly required and typed below
}, },
"proprietaire" : { "enum": ["Oui","Non"] }, "proprietaire" : {"enum": ["Oui", "Non"]},
"qualite" : { "type": "string" }, "qualite" : {"type": "string"},
"denomination" : { }, # conditionaly required and typed below "denomination" : {}, # conditionaly required and typed below
"raison_sociale" : { }, # conditionaly required and typed below "raison_sociale" : {}, # conditionaly required and typed below
"nom" : { "type": "string" }, "nom" : {"type": "string"},
"prenom" : { "type": "string" }, "prenom" : {"type": "string"},
"numero_voie" : { "type": "string" }, "numero_voie" : {"type": "string"},
"nom_voie" : { "type": "string" }, "nom_voie" : {"type": "string"},
"code_postal" : { "type": "string" }, "code_postal" : {"type": "string"},
"localite" : { "type": "string" }, "localite" : {"type": "string"},
"lieu_dit" : { "type": ["string","null"] }, "lieu_dit" : {"type": ["string", "null"]},
"mandataire_nom" : { }, # conditionaly required and typed below "mandataire_nom" : {}, # conditionaly required and typed below
"mandataire_prenom" : { }, # conditionaly required and typed below "mandataire_prenom" : {}, # conditionaly required and typed below
"mandataire_numero_voie": { }, # conditionaly required and typed below "mandataire_numero_voie": {}, # conditionaly required and typed below
"mandataire_nom_voie" : { }, # conditionaly required and typed below "mandataire_nom_voie" : {}, # conditionaly required and typed below
"mandataire_code_postal": { }, # conditionaly required and typed below "mandataire_code_postal": {}, # conditionaly required and typed below
"mandataire_localite" : { }, # conditionaly required and typed below "mandataire_localite" : {}, # conditionaly required and typed below
"mandataire_lieu_dit" : { } # conditionaly required and typed below "mandataire_lieu_dit" : {} # conditionaly required and typed below
}, },
# requirements # requirements
@ -162,9 +165,9 @@ JSON_SCHEMA_CREATE_DOSSIER_IN = {
# and must be null # and must be null
{ {
"properties": { "properties": {
"qualite": { "const": "Un particulier" }, "qualite": {"const": "Un particulier"},
"denomination" : { "type": "null" }, "denomination" : {"type": "null"},
"raison_sociale": { "type": "null" } "raison_sociale": {"type": "null"}
} }
}, },
# if qualite == "Une personne morale" # if qualite == "Une personne morale"
@ -172,11 +175,11 @@ JSON_SCHEMA_CREATE_DOSSIER_IN = {
# and must be string # and must be string
{ {
"properties": { "properties": {
"qualite": { "const": "Une personne morale" }, "qualite": {"const": "Une personne morale"},
"denomination" : { "type": "string" }, "denomination" : {"type": "string"},
"raison_sociale": { "type": "string" } "raison_sociale": {"type": "string"}
}, },
"required": ["denomination","raison_sociale"] "required": ["denomination", "raison_sociale"]
} }
] ]
}, },
@ -189,14 +192,14 @@ JSON_SCHEMA_CREATE_DOSSIER_IN = {
# and must be null # and must be null
{ {
"properties": { "properties": {
"proprietaire": { "const": "Oui" }, "proprietaire": {"const": "Oui"},
"mandataire_nom" : { "type": "null" }, "mandataire_nom" : {"type": "null"},
"mandataire_prenom" : { "type": "null" }, "mandataire_prenom" : {"type": "null"},
"mandataire_numero_voie": { "type": "null" }, "mandataire_numero_voie": {"type": "null"},
"mandataire_nom_voie" : { "type": "null" }, "mandataire_nom_voie" : {"type": "null"},
"mandataire_code_postal": { "type": "null" }, "mandataire_code_postal": {"type": "null"},
"mandataire_localite" : { "type": "null" }, "mandataire_localite" : {"type": "null"},
"mandataire_lieu_dit" : { "type": "null" } "mandataire_lieu_dit" : {"type": "null"}
} }
}, },
@ -206,15 +209,15 @@ JSON_SCHEMA_CREATE_DOSSIER_IN = {
# and conditions are checked against mandataire_qualite # and conditions are checked against mandataire_qualite
{ {
"properties": { "properties": {
"proprietaire": { "const": "Non" }, "proprietaire": {"const": "Non"},
"mandataire_nom" : { "type": "string" }, "mandataire_nom" : {"type": "string"},
"mandataire_prenom" : { "type": "string" }, "mandataire_prenom" : {"type": "string"},
"mandataire_numero_voie": { "type": "string" }, "mandataire_numero_voie": {"type": "string"},
"mandataire_nom_voie" : { "type": "string" }, "mandataire_nom_voie" : {"type": "string"},
"mandataire_code_postal": { "type": "string" }, "mandataire_code_postal": {"type": "string"},
"mandataire_localite" : { "type": "string" }, "mandataire_localite" : {"type": "string"},
"mandataire_qualite" : { "type": "string" }, "mandataire_qualite" : {"type": "string"},
"mandataire_lieu_dit" : { "type": ["string","null"] } "mandataire_lieu_dit" : {"type": ["string", "null"]}
}, },
"required": [ "required": [
"mandataire_nom", "mandataire_nom",
@ -230,25 +233,28 @@ JSON_SCHEMA_CREATE_DOSSIER_IN = {
"anyOf": [ "anyOf": [
# if mandataire_qualite == "Un particulier" # if mandataire_qualite == "Un particulier"
# "mandataire_denomination" and "mandataire_raison_sociale" are not required # "mandataire_denomination" and "mandataire_raison_sociale"
# and must be null # are not required and must be null
{ {
"properties": { "properties": {
"mandataire_qualite": { "const": "Un particulier" }, "mandataire_qualite": {"const": "Un particulier"},
"mandataire_denomination" : { "type": "null" }, "mandataire_denomination" : {"type": "null"},
"mandataire_raison_sociale": { "type": "null" } "mandataire_raison_sociale": {"type": "null"}
} }
}, },
# if mandataire_qualite == "Une personne morale" # if mandataire_qualite == "Une personne morale"
# "mandataire_denomination" and "mandataire_raison_sociale" are required # "mandataire_denomination" and "mandataire_raison_sociale"
# and must be string # are required and must be string
{ {
"properties": { "properties": {
"mandataire_qualite": { "const": "Une personne morale" }, "mandataire_qualite": {"const": "Une personne morale"},
"mandataire_denomination" : { "type": "string" }, "mandataire_denomination" : {"type": "string"},
"mandataire_raison_sociale": { "type": "string" } "mandataire_raison_sociale": {"type": "string"}
}, },
"required": ["mandataire_denomination","mandataire_raison_sociale"] "required": [
"mandataire_denomination",
"mandataire_raison_sociale"
]
} }
] ]
} }
@ -263,8 +269,8 @@ JSON_SCHEMA_CREATE_DOSSIER_IN = {
# and must be null # and must be null
{ {
"properties": { "properties": {
"autres_parcelles": { "const": False }, "autres_parcelles": {"const": False},
"references_cadastrales": { "type": "null" } "references_cadastrales": {"type": "null"}
} }
}, },
# if autres_parcelles == True # if autres_parcelles == True
@ -272,10 +278,10 @@ JSON_SCHEMA_CREATE_DOSSIER_IN = {
# and must be of type "array" of "refs-cadastrales" # and must be of type "array" of "refs-cadastrales"
{ {
"properties": { "properties": {
"autres_parcelles": { "const": True }, "autres_parcelles": {"const": True},
"references_cadastrales": { "references_cadastrales": {
"type": "array", "type": "array",
"items": { "$ref": "#/definitions/refs-cadastrales" } "items": {"$ref": "#/definitions/refs-cadastrales"}
} }
}, },
"required": ["autres_parcelles", "references_cadastrales"] "required": ["autres_parcelles", "references_cadastrales"]
@ -293,7 +299,7 @@ JSON_SCHEMA_CREATE_DOSSIER_OUT = {
"title" : "Response of a 'dossier' creation in openADS.API", "title" : "Response of a 'dossier' creation in openADS.API",
"type" : "object", "type" : "object",
"properties": { "properties": {
"numero_dossier": { "type": "string" }, "numero_dossier": {"type": "string"},
"recepisse": JSON_SCHEMA_FILE_B64 "recepisse": JSON_SCHEMA_FILE_B64
}, },
"required": ["numero_dossier", "recepisse"] "required": ["numero_dossier", "recepisse"]
@ -304,11 +310,11 @@ JSON_SCHEMA_GET_DOSSIER_OUT = {
"title" : "Response of a 'dossier' creation in openADS.API", "title" : "Response of a 'dossier' creation in openADS.API",
"type" : "object", "type" : "object",
"properties": { "properties": {
"etat" : { "type": "string" }, "etat" : {"type": "string"},
"date_depot" : JSON_SCHEMA_DATE_FRENCH, "date_depot" : JSON_SCHEMA_DATE_FRENCH,
"date_decision": JSON_SCHEMA_DATE_FRENCH, "date_decision": JSON_SCHEMA_DATE_FRENCH,
"date_limite_instruction": JSON_SCHEMA_DATE_FRENCH, "date_limite_instruction": JSON_SCHEMA_DATE_FRENCH,
"decision" : { "type": "string" } "decision" : {"type": "string"}
}, },
"required": [ "required": [
"etat", "etat",
@ -324,18 +330,18 @@ JSON_SCHEMA_FORWARDFILE = {
"$id" : "#forwardfile", "$id" : "#forwardfile",
"type": "object", "type": "object",
"properties": { "properties": {
"id" : { "type": "integer" }, "id" : {"type": "integer"},
"numero_demande" : { "type": "string" }, "numero_demande" : {"type": "string"},
"numero_dossier" : { "type": "string" }, "numero_dossier" : {"type": "string"},
"type_fichier" : { "type": "string" }, "type_fichier" : {"type": "string"},
"file_hash" : { "type": "string" }, "file_hash" : {"type": "string"},
"orig_filename" : { "type": "string" }, "orig_filename" : {"type": "string"},
"content_type" : { "type": "string" }, "content_type" : {"type": "string"},
"upload_status" : { "type": "string" }, "upload_status" : {"type": "string"},
"upload_attempt" : { "type": "integer" }, "upload_attempt" : {"type": "integer"},
"upload_msg" : { "type": "string" }, "upload_msg" : {"type": "string"},
"content_size" : { "type": "integer" }, "content_size" : {"type": "integer"},
"last_update_datetime": { "type": "string", "format": "date-time" } "last_update_datetime": {"type": "string", "format": "date-time"}
}, },
"required": [ "required": [
"id", "id",
@ -357,7 +363,7 @@ JSON_SCHEMA_GET_FWD_FILES_OUT = {
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "http://json-schema.org/draft-07/schema#",
"title" : "Response of a request about the forwarding (detailled) of user files to openADS", "title" : "Response of a request about the forwarding (detailled) of user files to openADS",
"type" : "array", "type" : "array",
"items": { "$ref": "#/definitions/forwardfile" }, "items": {"$ref": "#/definitions/forwardfile"},
"definitions": { "definitions": {
"forwardfile" : JSON_SCHEMA_FORWARDFILE "forwardfile" : JSON_SCHEMA_FORWARDFILE
} }
@ -367,6 +373,7 @@ JSON_SCHEMA_GET_FWD_FILE_STATUS = {
"description": "The status of a ForwardFile", "description": "The status of a ForwardFile",
"$id" : "#forwardfile-status", "$id" : "#forwardfile-status",
"type": "string", "type": "string",
# pylint: disable=anomalous-backslash-in-string
"pattern": "^\[\w+\] .+ => .+$" "pattern": "^\[\w+\] .+ => .+$"
} }
@ -375,13 +382,13 @@ JSON_SCHEMA_GET_FWD_FILES_STATUS_OUT = {
"title" : "Response of a request about the forwarding (summarized) of user files to openADS", "title" : "Response of a request about the forwarding (summarized) of user files to openADS",
"type" : "object", "type" : "object",
"properties": { "properties": {
"all_forwarded": { "type": "boolean" }, "all_forwarded": {"type": "boolean"},
"pending" : { "type": "array", "items": { "$ref": "#/definitions/forwardfile-status" } }, "pending" : {"type": "array", "items": {"$ref": "#/definitions/forwardfile-status"}},
"uploading": { "type": "array", "items": { "$ref": "#/definitions/forwardfile-status" } }, "uploading": {"type": "array", "items": {"$ref": "#/definitions/forwardfile-status"}},
"success" : { "type": "array", "items": { "$ref": "#/definitions/forwardfile-status" } }, "success" : {"type": "array", "items": {"$ref": "#/definitions/forwardfile-status"}},
"failed" : { "type": "array", "items": { "$ref": "#/definitions/forwardfile-status" } } "failed" : {"type": "array", "items": {"$ref": "#/definitions/forwardfile-status"}}
}, },
"required": ["all_forwarded","pending","uploading","success","failed"], "required": ["all_forwarded", "pending", "uploading", "success", "failed"],
"definitions": { "definitions": {
"forwardfile-status" : JSON_SCHEMA_GET_FWD_FILE_STATUS "forwardfile-status" : JSON_SCHEMA_GET_FWD_FILE_STATUS
} }

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,8 @@
# You should have received a copy of the GNU Affero General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""The urls for this connector module and its entities views."""
import re import re
from django.conf.urls import url from django.conf.urls import url
@ -40,27 +42,28 @@ from .views import (
) )
# pylint: disable=invalid-name
urlpatterns = [ urlpatterns = [
url(r'^(?P<slug>[\w,-]+)/$', AtrealOpenadsView.as_view(), name='view-connector') url(r'^(?P<slug>[\w,-]+)/$', AtrealOpenadsView.as_view(), name='view-connector')
] ]
# pylint: disable=invalid-name
management_urlpatterns = [] management_urlpatterns = []
for view in [ for view in [
ForwardFileView, ForwardFileView,
ForwardFileListView, ForwardFileListView,
ForwardFileUpdateView, ForwardFileUpdateView,
ForwardFileDeleteView, ForwardFileDeleteView,
CollectiviteView, CollectiviteView,
CollectiviteListView, CollectiviteListView,
CollectiviteCreateView, CollectiviteCreateView,
CollectiviteUpdateView, CollectiviteUpdateView,
CollectiviteDeleteView, CollectiviteDeleteView,
GuichetView, GuichetView,
GuichetCreateView, GuichetCreateView,
GuichetUpdateView, GuichetUpdateView,
GuichetDeleteView GuichetDeleteView]:
]:
view_class_name = str(view.__name__) view_class_name = str(view.__name__)
m = re.search(r'^.*(Create|Update|Delete|List)View$', view_class_name) m = re.search(r'^.*(Create|Update|Delete|List)View$', view_class_name)
if m: if m:
@ -69,12 +72,13 @@ for view in [
view_action = 'view' view_action = 'view'
# no prefix for action 'view' # no prefix for action 'view'
url_prefix = view_action.replace('update', 'edit') + '-' url_prefix = view_action.replace('update', 'edit') + '-'
regex_base = r'^(?P<connecteur>[\w,-]+)/' regex_base = r'^(?P<connecteur>[\w,-]+)/'
regex_pkey = '/(?P<pk>[\w,-]+)' # pylint: disable=anomalous-backslash-in-string
regex_pkey = '/(?P<pk>[\w,-]+)'
url_name = url_prefix + view.model.get_class_name_dash_case() url_name = url_prefix + view.model.get_class_name_dash_case()
regex_url = '%s%s' % (url_prefix if view_action != 'view' else '', regex_url = '%s%s' % (url_prefix if view_action != 'view' else '',
view.model.get_class_name_dash_case()) view.model.get_class_name_dash_case())
@ -84,8 +88,8 @@ for view in [
# plural form of the url for action 'list' and no prefix # plural form of the url for action 'list' and no prefix
if view_action == 'list': if view_action == 'list':
url_name = url_prefix + view.model.get_class_name_plural_dash_case() url_name = url_prefix + view.model.get_class_name_plural_dash_case()
regex_url = view.model.get_class_name_plural_dash_case() regex_url = view.model.get_class_name_plural_dash_case()
# for 'guichet' prefix the regex by the collectivite # for 'guichet' prefix the regex by the collectivite
if view.model.get_class_name() == 'Guichet': if view.model.get_class_name() == 'Guichet':
@ -101,7 +105,7 @@ for view in [
ff_list_regex_url = ForwardFileListView.model.get_class_name_plural_dash_case() ff_list_regex_url = ForwardFileListView.model.get_class_name_plural_dash_case()
management_urlpatterns += [ management_urlpatterns += [
url( url(
r'^(?P<connecteur>[\w,-]+)/collectivite/(?P<collectivite>[\w,-]+)/' + ff_list_regex_url + '$', r'^(?P<connecteur>[\w,-]+)/collectivite/(?P<collectivite>[\w,-]+)/%s$' % ff_list_regex_url,
ForwardFileListView.as_view(), ForwardFileListView.as_view(),
name='col-list-' + ff_list_regex_url name='col-list-' + ff_list_regex_url
) )

View File

@ -18,6 +18,8 @@
# You should have received a copy of the GNU Affero General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Utilities functions."""
import json import json
import base64 import base64
import datetime import datetime
@ -33,8 +35,9 @@ from django.urls import reverse_lazy
def to_dash_case(camel_str): def to_dash_case(camel_str):
s1 = re.sub('(.)([A-Z][a-z]+)', r'\1-\2', camel_str) """Convert a string formatted from camel case to dash case (like snake case with dash)."""
return re.sub('([a-z0-9])([A-Z])', r'\1-\2', s1).lower() converted = re.sub('(.)([A-Z][a-z]+)', r'\1-\2', camel_str)
return re.sub('([a-z0-9])([A-Z])', r'\1-\2', converted).lower()
# from: https://stackoverflow.com/a/13848698 # from: https://stackoverflow.com/a/13848698
@ -44,26 +47,27 @@ def force_encoded_string_output(func, default_enc='utf-8'):
def _func(*args, **kwargs): def _func(*args, **kwargs):
return func(*args, **kwargs).encode(sys.stdout.encoding or default_enc) return func(*args, **kwargs).encode(sys.stdout.encoding or default_enc)
return _func return _func
else: return func
return func
class MLStripper(HTMLParser): class MLStripper(HTMLParser):
"""HTML parser that removes html tags.""" """HTML parser that removes html tags."""
# pylint: disable=super-init-not-called
def __init__(self): def __init__(self):
self.reset() self.reset()
self.fed = [] self.fed = []
def handle_data(self, d): def handle_data(self, data):
self.fed.append(d) self.fed.append(data)
def get_data(self): def get_data(self):
"""Get the stripped data as a string."""
return ''.join(self.fed) return ''.join(self.fed)
def strip_tags(html): def strip_tags(html):
"""Remove html tags from a string.""" """Remove html tags from a string."""
s = MLStripper() stripper = MLStripper()
s.feed(html) stripper.feed(html)
return s.get_data() return stripper.get_data()
def clean_spaces(text): def clean_spaces(text):
@ -88,10 +92,10 @@ def normalize(value):
def get_file_data(path, b64=True): def get_file_data(path, b64=True):
"""Return the content of a file as a string, in base64 if specified.""" """Return the content of a file as a string, in base64 if specified."""
with open(path, 'r') as f: with open(path, 'r') as file_pt:
if b64: if b64:
return base64.b64encode(f.read()) return base64.b64encode(file_pt.read())
return f.read() return file_pt.read()
# copy-pasted from 'wcs/qommon/misc.py' # copy-pasted from 'wcs/qommon/misc.py'
@ -100,6 +104,7 @@ def get_file_digest(content, chunk_size=100000):
digest = hashlib.sha256() digest = hashlib.sha256()
content.seek(0) content.seek(0)
def read_chunk(): def read_chunk():
"""Read 'chunk_size' amount of data from the content."""
return content.read(chunk_size) return content.read(chunk_size)
for chunk in iter(read_chunk, ''): for chunk in iter(read_chunk, ''):
digest.update(chunk) digest.update(chunk)
@ -108,7 +113,7 @@ def get_file_digest(content, chunk_size=100000):
def get_upload_path(instance, filename=None): def get_upload_path(instance, filename=None):
"""Return a relative upload path for a file.""" """Return a relative upload path for a file."""
fn_ref = instance.orig_filename if instance.orig_filename else filename fn_ref = instance.orig_filename if instance.orig_filename else filename
# file_hash and content_type attribute are updated on file save() # file_hash and content_type attribute are updated on file save()
# so if the file was not yet saved, it may have those attributes undefined # so if the file was not yet saved, it may have those attributes undefined
# this is why we update them here, if they are empty # this is why we update them here, if they are empty
@ -134,6 +139,7 @@ def get_file_extension(filename, mimetype=None):
return file_extension if file_extension else '' return file_extension if file_extension else ''
# pylint: disable=invalid-encoded-data
def trunc_str_values(value, limit, visited=None, truncate_text=u''): def trunc_str_values(value, limit, visited=None, truncate_text=u''):
"""Truncate a string value (not dict keys) and append a truncate text.""" """Truncate a string value (not dict keys) and append a truncate text."""
@ -142,11 +148,11 @@ def trunc_str_values(value, limit, visited=None, truncate_text=u'…'):
if not value in visited: if not value in visited:
if isinstance(value, basestring) and len(value) > limit: if isinstance(value, basestring) and len(value) > limit:
value = value[:limit] + truncate_text value = value[:limit] + truncate_text
elif isinstance(value, dict) or isinstance(value, list) or isinstance(value, tuple): elif isinstance(value, (dict, list, tuple)):
visited.append(value) visited.append(value)
iterator = value.iteritems() if isinstance(value, dict) else enumerate(value) iterator = value.iteritems() if isinstance(value, dict) else enumerate(value)
for k,v in iterator: for _key, _value in iterator:
value[k] = trunc_str_values(v, limit, visited, truncate_text) value[_key] = trunc_str_values(_value, limit, visited, truncate_text)
return value return value
@ -164,8 +170,8 @@ class DictDumper(object):
- max_str_len integer the maximul length of string values - max_str_len integer the maximul length of string values
- use_json_dumps boolean True to use json.dumps() else it uses unicode() - use_json_dumps boolean True to use json.dumps() else it uses unicode()
""" """
self.dic = dic self.dic = dic
self.max_str_len = max_str_len self.max_str_len = max_str_len
self.use_json_dumps = use_json_dumps self.use_json_dumps = use_json_dumps
@force_encoded_string_output @force_encoded_string_output
@ -179,7 +185,7 @@ class DictDumper(object):
def __unicode__(self): def __unicode__(self):
dict_trunc = trunc_str_values(copy.deepcopy(self.dic), self.max_str_len) dict_trunc = trunc_str_values(copy.deepcopy(self.dic), self.max_str_len)
dict_ref = json.dumps(dict_trunc) if self.use_json_dumps else dict_trunc dict_ref = json.dumps(dict_trunc) if self.use_json_dumps else dict_trunc
return unicode(dict_ref) return unicode(dict_ref)
@ -191,40 +197,53 @@ class BaseModel(object):
@classmethod @classmethod
def get_verbose_name(cls): def get_verbose_name(cls):
"""Return the verbose name of the class (helper for META option).""" """Return the verbose name of the class (helper for META option)."""
# pylint: disable=no-member
return cls._meta.verbose_name return cls._meta.verbose_name
@classmethod @classmethod
def get_verbose_name_plural(cls): def get_verbose_name_plural(cls):
"""Return the plural form of the verbose name of the class (helper for META option).""" """Return the plural form of the verbose name of the class (helper for META option)."""
# pylint: disable=no-member
return cls._meta.verbose_name_plural return cls._meta.verbose_name_plural
@classmethod @classmethod
def get_class_name(cls): def get_class_name(cls):
"""Return the object class name."""
return cls.__name__ return cls.__name__
@classmethod @classmethod
def get_class_name_plural(cls): def get_class_name_plural(cls):
"""Return the plural form of the object class name."""
return cls.get_class_name() + 's' return cls.get_class_name() + 's'
@classmethod @classmethod
def get_class_name_dash_case(cls): def get_class_name_dash_case(cls):
"""Return the object class name formatted to dash case."""
return to_dash_case(cls.get_class_name()) return to_dash_case(cls.get_class_name())
@classmethod @classmethod
def get_class_name_plural_dash_case(cls): def get_class_name_plural_dash_case(cls):
"""Return the plural form of the object class name
formatted to dash case.
"""
return to_dash_case(cls.get_class_name_plural()) return to_dash_case(cls.get_class_name_plural())
@classmethod @classmethod
def get_class_name_title(cls): def get_class_name_title(cls):
"""Return the object class name formatted to 'title' case."""
return cls.get_class_name_dash_case().replace('-', ' ').title() return cls.get_class_name_dash_case().replace('-', ' ').title()
@classmethod @classmethod
def get_class_name_plural_title(cls): def get_class_name_plural_title(cls):
"""Return the plural form of the object class name
formatted to 'title' case.
"""
return cls.get_class_name_plural_dash_case().replace('-', ' ').title() return cls.get_class_name_plural_dash_case().replace('-', ' ').title()
@classmethod @classmethod
def get_fields(cls): def get_fields(cls):
"""Return the fields of the class (helper for META option).""" """Return the fields of the class (helper for META option)."""
# pylint: disable=no-member
return cls._meta.get_fields(include_parents=True, include_hidden=False) return cls._meta.get_fields(include_parents=True, include_hidden=False)
@force_encoded_string_output @force_encoded_string_output
@ -234,26 +253,33 @@ class BaseModel(object):
# mainly for the view # mainly for the view
def get_fields_kv(self): def get_fields_kv(self):
"""Return the model's list of field's key value.""" """Return the model's list of field's key value."""
# pylint: disable=no-member
return [(field, getattr(self, field.name, None)) for field in self._meta.get_fields()] return [(field, getattr(self, field.name, None)) for field in self._meta.get_fields()]
def get_url_name(self, prefix='', plural=False): def get_url_name(self, prefix='', plural=False):
"""Return a base name for url for this object."""
class_name_dash_case = self.__class__.get_class_name_dash_case() class_name_dash_case = self.__class__.get_class_name_dash_case()
if plural: if plural:
class_name_dash_case = self.__class__.get_class_name_plural_dash_case() class_name_dash_case = self.__class__.get_class_name_plural_dash_case()
return '%s%s' % (prefix + '-' if prefix else '', class_name_dash_case) return '%s%s' % (prefix + '-' if prefix else '', class_name_dash_case)
def get_url_params(self, primary_key=True): def get_url_params(self, primary_key=True):
"""Return the parameters for 'reverse()' to build url for this object."""
# pylint: disable=no-member
return {'pk': self.id} if primary_key else {} return {'pk': self.id} if primary_key else {}
def get_absolute_url(self): def get_absolute_url(self):
"""Return the 'absolute' url for this object."""
return reverse_lazy(self.get_url_name('view'), kwargs=self.get_url_params()) return reverse_lazy(self.get_url_name('view'), kwargs=self.get_url_params())
def get_edit_url(self): def get_edit_url(self):
"""Return the 'edit' url for this object."""
return reverse_lazy(self.get_url_name('edit'), kwargs=self.get_url_params()) return reverse_lazy(self.get_url_name('edit'), kwargs=self.get_url_params())
def get_delete_url(self): def get_delete_url(self):
"""Return the 'delete' url for this object."""
return reverse_lazy(self.get_url_name('delete'), kwargs=self.get_url_params()) return reverse_lazy(self.get_url_name('delete'), kwargs=self.get_url_params())
def get_list_url(self): def get_list_url(self):
"""Return the 'list' url for this object."""
return reverse_lazy(self.get_url_name('list', True), kwargs=self.get_url_params(False)) return reverse_lazy(self.get_url_name('list', True), kwargs=self.get_url_params(False))

View File

@ -18,6 +18,8 @@
# You should have received a copy of the GNU Affero General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Views for the models."""
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.views.generic.detail import DetailView from django.views.generic.detail import DetailView
@ -44,21 +46,28 @@ def get_collectivite_from_request(view, key='collectivite'):
if not hasattr(view, 'collectivite') or not view.collectivite and view.request: if not hasattr(view, 'collectivite') or not view.collectivite and view.request:
collectivite_id = view.request.resolver_match.kwargs.get(key, None) collectivite_id = view.request.resolver_match.kwargs.get(key, None)
if collectivite_id: if collectivite_id:
# pylint: disable=no-member
view.collectivite = Collectivite.objects.get(id=collectivite_id) view.collectivite = Collectivite.objects.get(id=collectivite_id)
return view.collectivite if hasattr(view, 'collectivite') else None return view.collectivite if hasattr(view, 'collectivite') else None
# pylint: disable=too-many-ancestors
class ForwardFileView(DetailView): class ForwardFileView(DetailView):
"""View to display a ForwardFile."""
model = ForwardFile model = ForwardFile
template_name = 'atreal_openads/manage/forwardfile_view.html' template_name = 'atreal_openads/manage/forwardfile_view.html'
def get_context_data(self, *args, **kwargs): def get_context_data(self, **kwargs):
context = super(ForwardFileView, self).get_context_data(*args, **kwargs) context = super(ForwardFileView, self).get_context_data(**kwargs)
context['connecteur'] = get_connecteur_from_request(self) context['connecteur'] = get_connecteur_from_request(self)
return context return context
# pylint: disable=too-many-ancestors
class ForwardFileListView(ListView): class ForwardFileListView(ListView):
"""View to display a list of ForwardFiles."""
model = ForwardFile model = ForwardFile
template_name = 'atreal_openads/manage/forwardfile_list.html' template_name = 'atreal_openads/manage/forwardfile_list.html'
paginate_by = 50 paginate_by = 50
@ -86,25 +95,28 @@ class ForwardFileListView(ListView):
return qset.order_by(order_by) if order_by else qset # qset.order_by() return qset.order_by(order_by) if order_by else qset # qset.order_by()
def get_context_data(self, *args, **kwargs): def get_context_data(self, **kwargs):
context = super(ForwardFileListView, self).get_context_data(*args, **kwargs) context = super(ForwardFileListView, self).get_context_data(**kwargs)
context['connecteur'] = get_connecteur_from_request(self)
context['collectivite'] = get_collectivite_from_request(self)
return context
class ForwardFileUpdateView(UpdateView):
model = ForwardFile
form_class = ForwardFileForm
template_name = 'atreal_openads/manage/forwardfile_form.html'
def get_context_data(self, *args, **kwargs):
context = super(ForwardFileUpdateView, self).get_context_data(*args, **kwargs)
context['connecteur'] = get_connecteur_from_request(self) context['connecteur'] = get_connecteur_from_request(self)
context['collectivite'] = get_collectivite_from_request(self) context['collectivite'] = get_collectivite_from_request(self)
return context return context
def get_success_url(self, *args, **kwargs):
# pylint: disable=too-many-ancestors
class ForwardFileUpdateView(UpdateView):
"""View to edit a ForwardFile."""
model = ForwardFile
form_class = ForwardFileForm
template_name = 'atreal_openads/manage/forwardfile_form.html'
def get_context_data(self, **kwargs):
context = super(ForwardFileUpdateView, self).get_context_data(**kwargs)
context['connecteur'] = get_connecteur_from_request(self)
context['collectivite'] = get_collectivite_from_request(self)
return context
def get_success_url(self):
back_to = self.request.GET.get('back-to') back_to = self.request.GET.get('back-to')
if back_to == 'list-forward-files': if back_to == 'list-forward-files':
return reverse_lazy('list-forward-files', kwargs={ return reverse_lazy('list-forward-files', kwargs={
@ -120,18 +132,21 @@ class ForwardFileUpdateView(UpdateView):
return self.get_object().get_absolute_url() return self.get_object().get_absolute_url()
# pylint: disable=too-many-ancestors
class ForwardFileDeleteView(DeleteView): class ForwardFileDeleteView(DeleteView):
"""View to delete a ForwardFile."""
model = ForwardFile model = ForwardFile
form_class = ForwardFileForm form_class = ForwardFileForm
template_name = 'atreal_openads/manage/forwardfile_form.html' template_name = 'atreal_openads/manage/forwardfile_form.html'
def get_context_data(self, *args, **kwargs): def get_context_data(self, **kwargs):
context = super(ForwardFileDeleteView, self).get_context_data(*args, **kwargs) context = super(ForwardFileDeleteView, self).get_context_data(**kwargs)
context['connecteur'] = get_connecteur_from_request(self) context['connecteur'] = get_connecteur_from_request(self)
context['collectivite'] = get_collectivite_from_request(self) context['collectivite'] = get_collectivite_from_request(self)
return context return context
def get_success_url(self, *args, **kwargs): def get_success_url(self):
back_to = self.request.GET.get('back-to') back_to = self.request.GET.get('back-to')
if back_to == 'list-forward-files': if back_to == 'list-forward-files':
return reverse_lazy('list-forward-files', kwargs={ return reverse_lazy('list-forward-files', kwargs={
@ -150,12 +165,15 @@ class ForwardFileDeleteView(DeleteView):
}) })
# pylint: disable=too-many-ancestors
class CollectiviteView(DetailView): class CollectiviteView(DetailView):
"""View to display a Collectivite."""
model = Collectivite model = Collectivite
template_name = 'atreal_openads/manage/collectivite_view.html' template_name = 'atreal_openads/manage/collectivite_view.html'
def get_context_data(self, *args, **kwargs): def get_context_data(self, **kwargs):
context = super(CollectiviteView, self).get_context_data(*args, **kwargs) context = super(CollectiviteView, self).get_context_data(**kwargs)
context['connecteur'] = get_connecteur_from_request(self) context['connecteur'] = get_connecteur_from_request(self)
context['guichet_add_url'] = reverse_lazy('create-guichet', kwargs={ context['guichet_add_url'] = reverse_lazy('create-guichet', kwargs={
'connecteur' : context['connecteur'].slug, 'connecteur' : context['connecteur'].slug,
@ -166,7 +184,10 @@ class CollectiviteView(DetailView):
return context return context
# pylint: disable=too-many-ancestors
class CollectiviteListView(ListView): class CollectiviteListView(ListView):
"""View to display a list of Collectivites."""
model = Collectivite model = Collectivite
template_name = 'atreal_openads/manage/collectivite_list.html' template_name = 'atreal_openads/manage/collectivite_list.html'
paginate_by = 50 paginate_by = 50
@ -186,21 +207,24 @@ class CollectiviteListView(ListView):
return qset.order_by(order_by) if order_by else qset # qset.order_by() return qset.order_by(order_by) if order_by else qset # qset.order_by()
def get_context_data(self, *args, **kwargs): def get_context_data(self, **kwargs):
context = super(CollectiviteListView, self).get_context_data(*args, **kwargs) context = super(CollectiviteListView, self).get_context_data(**kwargs)
context['connecteur'] = get_connecteur_from_request(self) context['connecteur'] = get_connecteur_from_request(self)
context['collectivite_add_url'] = reverse_lazy('create-collectivite', kwargs={ context['collectivite_add_url'] = reverse_lazy('create-collectivite', kwargs={
'connecteur': context['connecteur'].slug}) 'connecteur': context['connecteur'].slug})
return context return context
# pylint: disable=too-many-ancestors
class CollectiviteCreateView(CreateView): class CollectiviteCreateView(CreateView):
"""View to create a Collectivite."""
model = Collectivite model = Collectivite
form_class = CollectiviteForm form_class = CollectiviteForm
template_name = 'atreal_openads/manage/collectivite_form.html' template_name = 'atreal_openads/manage/collectivite_form.html'
def get_context_data(self, *args, **kwargs): def get_context_data(self, **kwargs):
context = super(CollectiviteCreateView, self).get_context_data(*args, **kwargs) context = super(CollectiviteCreateView, self).get_context_data(**kwargs)
context['connecteur'] = get_connecteur_from_request(self) context['connecteur'] = get_connecteur_from_request(self)
return context return context
@ -209,7 +233,7 @@ class CollectiviteCreateView(CreateView):
kwargs['connecteur'] = get_connecteur_from_request(self) kwargs['connecteur'] = get_connecteur_from_request(self)
return kwargs return kwargs
def get_success_url(self, *args, **kwargs): def get_success_url(self):
if self.request.GET.get('back-to') == 'list-collectivites': if self.request.GET.get('back-to') == 'list-collectivites':
return reverse_lazy('list-collectivites', kwargs={ return reverse_lazy('list-collectivites', kwargs={
'connecteur' : get_connecteur_from_request(self).slug 'connecteur' : get_connecteur_from_request(self).slug
@ -220,17 +244,20 @@ class CollectiviteCreateView(CreateView):
}) })
# pylint: disable=too-many-ancestors
class CollectiviteUpdateView(UpdateView): class CollectiviteUpdateView(UpdateView):
"""View to edit a Collectivite."""
model = Collectivite model = Collectivite
form_class = CollectiviteForm form_class = CollectiviteForm
template_name = 'atreal_openads/manage/collectivite_form.html' template_name = 'atreal_openads/manage/collectivite_form.html'
def get_context_data(self, *args, **kwargs): def get_context_data(self, **kwargs):
context = super(CollectiviteUpdateView, self).get_context_data(*args, **kwargs) context = super(CollectiviteUpdateView, self).get_context_data(**kwargs)
context['connecteur'] = get_connecteur_from_request(self) context['connecteur'] = get_connecteur_from_request(self)
return context return context
def get_success_url(self, *args, **kwargs): def get_success_url(self):
if self.request.GET.get('back-to') == 'list-collectivites': if self.request.GET.get('back-to') == 'list-collectivites':
return reverse_lazy('list-collectivites', kwargs={ return reverse_lazy('list-collectivites', kwargs={
'connecteur' : get_connecteur_from_request(self).slug 'connecteur' : get_connecteur_from_request(self).slug
@ -238,17 +265,20 @@ class CollectiviteUpdateView(UpdateView):
return self.get_object().get_absolute_url() return self.get_object().get_absolute_url()
# pylint: disable=too-many-ancestors
class CollectiviteDeleteView(DeleteView): class CollectiviteDeleteView(DeleteView):
"""View to delete a Collectivite."""
model = Collectivite model = Collectivite
form_class = CollectiviteForm form_class = CollectiviteForm
template_name = 'atreal_openads/manage/collectivite_form.html' template_name = 'atreal_openads/manage/collectivite_form.html'
def get_context_data(self, *args, **kwargs): def get_context_data(self, **kwargs):
context = super(CollectiviteDeleteView, self).get_context_data(*args, **kwargs) context = super(CollectiviteDeleteView, self).get_context_data(**kwargs)
context['connecteur'] = get_connecteur_from_request(self) context['connecteur'] = get_connecteur_from_request(self)
return context return context
def get_success_url(self, *args, **kwargs): def get_success_url(self):
if self.request.GET.get('back-to') == 'list-collectivites': if self.request.GET.get('back-to') == 'list-collectivites':
return reverse_lazy('list-collectivites', kwargs={ return reverse_lazy('list-collectivites', kwargs={
'connecteur' : get_connecteur_from_request(self).slug 'connecteur' : get_connecteur_from_request(self).slug
@ -259,18 +289,24 @@ class CollectiviteDeleteView(DeleteView):
}) })
# pylint: disable=too-many-ancestors
class GuichetView(DetailView): class GuichetView(DetailView):
"""View to display a Guichet."""
model = Guichet model = Guichet
template_name = 'atreal_openads/manage/guichet_view.html' template_name = 'atreal_openads/manage/guichet_view.html'
def get_context_data(self, *args, **kwargs): def get_context_data(self, **kwargs):
context = super(GuichetView, self).get_context_data(*args, **kwargs) context = super(GuichetView, self).get_context_data(**kwargs)
context['connecteur'] = get_connecteur_from_request(self) context['connecteur'] = get_connecteur_from_request(self)
context['collectivite'] = get_collectivite_from_request(self) context['collectivite'] = get_collectivite_from_request(self)
return context return context
# pylint: disable=too-many-ancestors
class GuichetCreateView(CreateView): class GuichetCreateView(CreateView):
"""View to create a Guichet."""
model = Guichet model = Guichet
form_class = GuichetForm form_class = GuichetForm
template_name = 'atreal_openads/manage/guichet_form.html' template_name = 'atreal_openads/manage/guichet_form.html'
@ -280,9 +316,9 @@ class GuichetCreateView(CreateView):
kwargs['collectivite'] = get_collectivite_from_request(self) kwargs['collectivite'] = get_collectivite_from_request(self)
return kwargs return kwargs
def get_context_data(self, *args, **kwargs): def get_context_data(self, **kwargs):
context = super(GuichetCreateView, self).get_context_data(*args, **kwargs) context = super(GuichetCreateView, self).get_context_data(**kwargs)
context['connecteur'] = get_connecteur_from_request(self) context['connecteur'] = get_connecteur_from_request(self)
context['collectivite'] = get_collectivite_from_request(self) context['collectivite'] = get_collectivite_from_request(self)
return context return context
@ -293,44 +329,52 @@ class GuichetCreateView(CreateView):
}) })
# pylint: disable=too-many-ancestors
class GuichetUpdateView(UpdateView): class GuichetUpdateView(UpdateView):
"""View to edit a Guichet."""
model = Guichet model = Guichet
form_class = GuichetForm form_class = GuichetForm
template_name = 'atreal_openads/manage/guichet_form.html' template_name = 'atreal_openads/manage/guichet_form.html'
def get_context_data(self, *args, **kwargs): def get_context_data(self, **kwargs):
context = super(GuichetUpdateView, self).get_context_data(*args, **kwargs) context = super(GuichetUpdateView, self).get_context_data(**kwargs)
context['connecteur'] = get_connecteur_from_request(self) context['connecteur'] = get_connecteur_from_request(self)
context['collectivite'] = get_collectivite_from_request(self) context['collectivite'] = get_collectivite_from_request(self)
return context return context
# pylint: disable=too-many-ancestors
class GuichetDeleteView(DeleteView): class GuichetDeleteView(DeleteView):
"""View to delete a Guichet."""
model = Guichet model = Guichet
form_class = GuichetForm form_class = GuichetForm
template_name = 'atreal_openads/manage/guichet_form.html' template_name = 'atreal_openads/manage/guichet_form.html'
def get_context_data(self, *args, **kwargs): def get_context_data(self, **kwargs):
context = super(GuichetDeleteView, self).get_context_data(*args, **kwargs) context = super(GuichetDeleteView, self).get_context_data(**kwargs)
context['connecteur'] = get_connecteur_from_request(self) context['connecteur'] = get_connecteur_from_request(self)
context['collectivite'] = get_collectivite_from_request(self) context['collectivite'] = get_collectivite_from_request(self)
return context return context
def get_success_url(self, *args, **kwargs): def get_success_url(self):
return reverse_lazy('view-collectivite', kwargs={ return reverse_lazy('view-collectivite', kwargs={
'connecteur': get_connecteur_from_request(self).slug, 'connecteur': get_connecteur_from_request(self).slug,
'pk' : get_collectivite_from_request(self).id 'pk' : get_collectivite_from_request(self).id
}) })
# pylint: disable=too-many-ancestors
class AtrealOpenadsView(GenericConnectorView): class AtrealOpenadsView(GenericConnectorView):
"""View to display a connector AtrealOpenads."""
model = AtrealOpenads model = AtrealOpenads
template_name = 'atreal_openads/manage/connector_view.html' template_name = 'atreal_openads/manage/connector_view.html'
def get_context_data(self, *args, **kwargs): def get_context_data(self, slug=None, **kwargs):
context = super(AtrealOpenadsView, self).get_context_data(*args, **kwargs) context = super(AtrealOpenadsView, self).get_context_data(slug=slug, **kwargs)
context['collectivite_fields'] = Collectivite.get_fields() context['collectivite_fields'] = Collectivite.get_fields()
context['collectivite_add_url'] = reverse_lazy('create-collectivite', kwargs={ context['collectivite_add_url'] = reverse_lazy('create-collectivite', kwargs={
'connecteur': self.get_object().slug}) 'connecteur': self.get_object().slug})
return context return context

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,13 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import pytest """Testing forms."""
import os import os
import base64 import base64
import datetime import datetime
import pytest
from django.core.files import File from django.core.files import File
from atreal_openads.forms import ( from atreal_openads.forms import (
@ -21,89 +24,101 @@ from atreal_openads.models import (
) )
CONNECTOR_NAME = 'atreal-openads' CONNECTOR_NAME = 'atreal-openads'
CONNECTOR_SLUG = 'atreal' CONNECTOR_SLUG = 'atreal'
COLLECTIVITE = 79 COLLECTIVITE = 79
OPENADS_API_LOGIN = 'publik-passerelle' OPENADS_API_LOGIN = 'publik-passerelle'
OPENADS_API_PASSWORD = base64.urlsafe_b64encode(os.urandom(20)) OPENADS_API_PASSWORD = base64.urlsafe_b64encode(os.urandom(20))
OPENADS_API_URL = 'http://openads.api/' OPENADS_API_URL = 'http://openads.api/'
FAKE_COOKIE_CRSF = base64.urlsafe_b64encode(os.urandom(20)) FAKE_COOKIE_CRSF = base64.urlsafe_b64encode(os.urandom(20))
FAKE_NUMERO_DOSSIER = base64.urlsafe_b64encode(os.urandom(10)) FAKE_NUMERO_DOSSIER = base64.urlsafe_b64encode(os.urandom(10))
TESTS_DIR = os.path.dirname(__file__) TESTS_DIR = os.path.dirname(__file__)
RESOURCES_DIR = os.path.join(TESTS_DIR, 'resources') RESOURCES_DIR = os.path.join(TESTS_DIR, 'resources')
TEST_FILE_CERFA_DIA = os.path.join(RESOURCES_DIR, 'cerfa_10072-02.pdf') TEST_FILE_CERFA_DIA = os.path.join(RESOURCES_DIR, 'cerfa_10072-02.pdf')
TEST_FILE_PLAN_CADASTRAL = os.path.join(RESOURCES_DIR, 'plancadastral.pdf') TEST_FILE_PLAN_CADASTRAL = os.path.join(RESOURCES_DIR, 'plancadastral.pdf')
@pytest.fixture @pytest.fixture
# pylint: disable=unused-argument,invalid-name
def atreal_openads(db): def atreal_openads(db):
"""Return an instance of a connector AtrealOpenads."""
return AtrealOpenads.objects.create( return AtrealOpenads.objects.create(
slug = CONNECTOR_SLUG, slug=CONNECTOR_SLUG,
default_collectivite_openADS_id = COLLECTIVITE, default_collectivite_openADS_id=COLLECTIVITE,
openADS_API_url = OPENADS_API_URL, openADS_API_url=OPENADS_API_URL,
basic_auth_username = OPENADS_API_LOGIN, basic_auth_username=OPENADS_API_LOGIN,
basic_auth_password = OPENADS_API_PASSWORD basic_auth_password=OPENADS_API_PASSWORD
) )
@pytest.fixture @pytest.fixture
# pylint: disable=unused-argument,redefined-outer-name,invalid-name
def collectivite_1(db, atreal_openads): def collectivite_1(db, atreal_openads):
return Collectivite.objects.create( """Return an instance of a 'Collectivite'."""
name = u'Macollectivité', return Collectivite.objects.create( # pylint: disable=no-member
connecteur = atreal_openads, name=u'Macollectivité',
openADS_id = '3' connecteur=atreal_openads,
openADS_id='3'
) )
@pytest.fixture @pytest.fixture
# pylint: disable=unused-argument,redefined-outer-name,invalid-name
def collectivite_1_guichet(db, atreal_openads, collectivite_1): def collectivite_1_guichet(db, atreal_openads, collectivite_1):
return Guichet.objects.create( """Return an instance of a 'Guichet'."""
collectivite = collectivite_1, return Guichet.objects.create( # pylint: disable=no-member
ouverture_jour_h = datetime.time(9, 0), collectivite=collectivite_1,
fermeture_jour_h = datetime.time(17, 0), ouverture_jour_h=datetime.time(9, 0),
ouverture_sem_d = 1, # Lundi fermeture_jour_h=datetime.time(17, 0),
fermeture_sem_d = 5, # Vendredi ouverture_sem_d=1, # Lundi
ouverture_sem_h = datetime.time(8, 30), fermeture_sem_d=5, # Vendredi
fermeture_sem_h = datetime.time(12, 15) ouverture_sem_h=datetime.time(8, 30),
fermeture_sem_h=datetime.time(12, 15)
) )
# pylint: disable=unused-argument,redefined-outer-name
def test_forwardfile_form(atreal_openads, collectivite_1): def test_forwardfile_form(atreal_openads, collectivite_1):
"""Test for ForwardFileForm."""
form = ForwardFileForm() form = ForwardFileForm()
assert form.instance is not None assert form.instance is not None
ff = ForwardFile( forwardfile = ForwardFile(
connecteur = None, connecteur=None,
collectivite = None, collectivite=None,
numero_demande = '45641531', numero_demande='45641531',
numero_dossier = FAKE_NUMERO_DOSSIER, numero_dossier=FAKE_NUMERO_DOSSIER,
type_fichier = 'CERFA', type_fichier='CERFA',
orig_filename = os.path.basename(TEST_FILE_CERFA_DIA), orig_filename=os.path.basename(TEST_FILE_CERFA_DIA),
content_type = 'application/pdf', content_type='application/pdf',
file_hash = 'ffdf456fdsvgb4bgfb6g4f5b', file_hash='ffdf456fdsvgb4bgfb6g4f5b',
upload_file = File(open(TEST_FILE_CERFA_DIA, 'r')), upload_file=File(open(TEST_FILE_CERFA_DIA, 'r')),
upload_status = 'pending' upload_status='pending'
) )
form_with_instance = ForwardFileForm(instance=ff, collectivite=collectivite_1) form_with_instance = ForwardFileForm(instance=forwardfile, collectivite=collectivite_1)
assert form_with_instance.instance is ff assert form_with_instance.instance is forwardfile
assert form_with_instance.instance.collectivite is collectivite_1 assert form_with_instance.instance.collectivite is collectivite_1
form_with_instance = ForwardFileForm(instance=ff, connecteur=atreal_openads) form_with_instance = ForwardFileForm(instance=forwardfile, connecteur=atreal_openads)
assert form_with_instance.instance is ff assert form_with_instance.instance is forwardfile
assert form_with_instance.instance.connecteur is atreal_openads assert form_with_instance.instance.connecteur is atreal_openads
# TODO check the queryset of the collectivite # TODO check the queryset of the collectivite
# pylint: disable=unused-argument,redefined-outer-name
def test_collectivite_form(atreal_openads): def test_collectivite_form(atreal_openads):
"""Test for CollectiviteForm."""
form = CollectiviteForm() form = CollectiviteForm()
assert form.instance is not None assert form.instance is not None
col = Collectivite( col = Collectivite(
connecteur = None, connecteur=None,
name = u'Ma collectivité', name=u'Ma collectivité',
openADS_id = 3 openADS_id=3
) )
form_with_instance = CollectiviteForm(instance=col, connecteur=atreal_openads) form_with_instance = CollectiviteForm(instance=col, connecteur=atreal_openads)
@ -111,18 +126,21 @@ def test_collectivite_form(atreal_openads):
assert form_with_instance.instance.connecteur is atreal_openads assert form_with_instance.instance.connecteur is atreal_openads
# pylint: disable=unused-argument,redefined-outer-name
def test_guichet_form(atreal_openads, collectivite_1): def test_guichet_form(atreal_openads, collectivite_1):
"""Test for GuichetForm."""
form = GuichetForm() form = GuichetForm()
assert form.instance is not None assert form.instance is not None
gui = Guichet( gui = Guichet(
collectivite = None, collectivite=None,
ouverture_jour_h = datetime.time(9, 0, 0), ouverture_jour_h=datetime.time(9, 0, 0),
fermeture_jour_h = datetime.time(18, 0, 0), fermeture_jour_h=datetime.time(18, 0, 0),
ouverture_sem_d = 1, ouverture_sem_d=1,
fermeture_sem_d = 5, fermeture_sem_d=5,
ouverture_sem_h = datetime.time(10, 30, 0), ouverture_sem_h=datetime.time(10, 30, 0),
fermeture_sem_h = datetime.time(12, 15, 0) fermeture_sem_h=datetime.time(12, 15, 0)
) )
form_with_instance = GuichetForm(instance=gui, collectivite=collectivite_1) form_with_instance = GuichetForm(instance=gui, collectivite=collectivite_1)

View File

@ -1,17 +1,14 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# to run it use the following command in the 'tests' directory: """Testing utilities functions."""
# ~> DJANGO_SETTINGS_MODULE=passerelle.settings pytest -W ignore::django.utils.deprecation.RemovedInDjango20Warning test_atreal_openads.py -vv
#
# and with 'coverage':
# ~> DJANGO_SETTINGS_MODULE=passerelle.settings pytest -W ignore::django.utils.deprecation.RemovedInDjango20Warning test_atreal_openads.py -vv --cov=~/src/passerelle/passerelle/apps/atreal_openads
import pytest
import os import os
import base64 import base64
import re import re
import datetime import datetime
import pytest
from django.core.files import File from django.core.files import File
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
@ -37,62 +34,73 @@ from atreal_openads.models import (
) )
CONNECTOR_NAME = 'atreal-openads' CONNECTOR_NAME = 'atreal-openads'
CONNECTOR_SLUG = 'atreal' CONNECTOR_SLUG = 'atreal'
COLLECTIVITE = 79 COLLECTIVITE = 79
OPENADS_API_LOGIN = 'publik-passerelle' OPENADS_API_LOGIN = 'publik-passerelle'
OPENADS_API_PASSWORD = base64.urlsafe_b64encode(os.urandom(20)) OPENADS_API_PASSWORD = base64.urlsafe_b64encode(os.urandom(20))
OPENADS_API_URL = 'http://openads.api/' OPENADS_API_URL = 'http://openads.api/'
FAKE_COOKIE_CRSF = base64.urlsafe_b64encode(os.urandom(20)) FAKE_COOKIE_CRSF = base64.urlsafe_b64encode(os.urandom(20))
FAKE_NUMERO_DOSSIER = base64.urlsafe_b64encode(os.urandom(10)) FAKE_NUMERO_DOSSIER = base64.urlsafe_b64encode(os.urandom(10))
TESTS_DIR = os.path.dirname(__file__) TESTS_DIR = os.path.dirname(__file__)
RESOURCES_DIR = os.path.join(TESTS_DIR, 'resources') RESOURCES_DIR = os.path.join(TESTS_DIR, 'resources')
TEST_FILE_CERFA_DIA = os.path.join(RESOURCES_DIR, 'cerfa_10072-02.pdf') TEST_FILE_CERFA_DIA = os.path.join(RESOURCES_DIR, 'cerfa_10072-02.pdf')
TEST_FILE_PLAN_CADASTRAL = os.path.join(RESOURCES_DIR, 'plancadastral.pdf') TEST_FILE_PLAN_CADASTRAL = os.path.join(RESOURCES_DIR, 'plancadastral.pdf')
@pytest.fixture @pytest.fixture
# pylint: disable=unused-argument,invalid-name
def atreal_openads(db): def atreal_openads(db):
"""Return an instance of a connector AtrealOpenads."""
return AtrealOpenads.objects.create( return AtrealOpenads.objects.create(
slug = CONNECTOR_SLUG, slug=CONNECTOR_SLUG,
default_collectivite_openADS_id = COLLECTIVITE, default_collectivite_openADS_id=COLLECTIVITE,
openADS_API_url = OPENADS_API_URL, openADS_API_url=OPENADS_API_URL,
basic_auth_username = OPENADS_API_LOGIN, basic_auth_username=OPENADS_API_LOGIN,
basic_auth_password = OPENADS_API_PASSWORD basic_auth_password=OPENADS_API_PASSWORD
) )
@pytest.fixture @pytest.fixture
# pylint: disable=unused-argument,redefined-outer-name,invalid-name
def collectivite_1(db, atreal_openads): def collectivite_1(db, atreal_openads):
return Collectivite.objects.create( """Return an instance of a 'Collectivite'."""
name = u'Macollectivité', return Collectivite.objects.create( # pylint: disable=no-member
connecteur = atreal_openads, name=u'Macollectivité',
openADS_id = '3' connecteur=atreal_openads,
openADS_id='3'
) )
@pytest.fixture @pytest.fixture
# pylint: disable=unused-argument,redefined-outer-name,invalid-name
def collectivite_1_guichet(db, atreal_openads, collectivite_1): def collectivite_1_guichet(db, atreal_openads, collectivite_1):
return Guichet.objects.create( """Return an instance of a 'Guichet'."""
collectivite = collectivite_1, return Guichet.objects.create( # pylint: disable=no-member
ouverture_jour_h = datetime.time(9, 0), collectivite=collectivite_1,
fermeture_jour_h = datetime.time(17, 0), ouverture_jour_h=datetime.time(9, 0),
ouverture_sem_d = 1, # Lundi fermeture_jour_h=datetime.time(17, 0),
fermeture_sem_d = 5, # Vendredi ouverture_sem_d=1, # Lundi
ouverture_sem_h = datetime.time(8, 30), fermeture_sem_d=5, # Vendredi
fermeture_sem_h = datetime.time(12, 15) ouverture_sem_h=datetime.time(8, 30),
fermeture_sem_h=datetime.time(12, 15)
) )
def test_to_dash_case(): def test_to_dash_case():
s = 'ACamelCaseName' """Test for function 'to_dash_case()'."""
assert to_dash_case(s) == 'a-camel-case-name'
astring = 'ACamelCaseName'
assert to_dash_case(astring) == 'a-camel-case-name'
assert to_dash_case('') == '' assert to_dash_case('') == ''
def test_force_encoded_string_output(): def test_force_encoded_string_output(): # pylint: disable=invalid-name
"""Test for function 'force_encoded_string_output()'."""
def a_str_function(): def a_str_function():
"""Return a hardcoded string 'toto'."""
return str('toto') return str('toto')
ret = force_encoded_string_output(a_str_function)() ret = force_encoded_string_output(a_str_function)()
assert isinstance(ret, str) assert isinstance(ret, str)
@ -100,6 +108,7 @@ def test_force_encoded_string_output():
assert isinstance(ret, str) assert isinstance(ret, str)
def an_unicode_function(): def an_unicode_function():
"""Return a hardcoded string 'toto' in unicode."""
return u'toto' return u'toto'
ret = force_encoded_string_output(an_unicode_function)() ret = force_encoded_string_output(an_unicode_function)()
assert isinstance(ret, str) assert isinstance(ret, str)
@ -108,52 +117,65 @@ def test_force_encoded_string_output():
def test_strip_tags(): def test_strip_tags():
s = 'aaa b cc ' """Test for function 'strip_tags()'."""
assert strip_tags(s) == s
ss = s + '<em>dd' base_string = 'aaa b cc '
assert strip_tags(ss) == s + 'dd' assert strip_tags(base_string) == base_string
ss = s + '<em>dd</em>' astring = base_string + '<em>dd'
assert strip_tags(ss) == s + 'dd' assert strip_tags(astring) == base_string + 'dd'
ss = s + '<em>dd</em>' astring = base_string + '<em>dd</em>'
assert strip_tags(ss) == s + 'dd' assert strip_tags(astring) == base_string + 'dd'
ss = s + ' 1 < 3' astring = base_string + '<em>dd</em>'
assert strip_tags(ss) == s + ' 1 < 3' assert strip_tags(astring) == base_string + 'dd'
astring = base_string + ' 1 < 3'
assert strip_tags(astring) == base_string + ' 1 < 3'
def test_clean_spaces(): def test_clean_spaces():
s = 'aaa b cc ' """Test for function 'clean_spaces()'."""
assert clean_spaces(s) == 'aaa b cc'
s = 'a\ta b\nb c\rc d\\n\\r\\td' astring = 'aaa b cc '
assert clean_spaces(s) == 'a a b b c c d d' assert clean_spaces(astring) == 'aaa b cc'
astring = 'a\ta b\nb c\rc d\\n\\r\\td'
assert clean_spaces(astring) == 'a a b b c c d d'
def test_normalize(): def test_normalize():
"""Test for function 'normalize()'."""
assert normalize(None) == '' assert normalize(None) == ''
s = 'aaa b cc ' astring = 'aaa b cc '
assert normalize(s) == 'aaa b cc' assert normalize(astring) == 'aaa b cc'
s = 'a\ta b\nb c\rc d\\n\\r\\td' astring = 'a\ta b\nb c\rc d\\n\\r\\td'
assert normalize(s) == 'a a b b c c d d' assert normalize(astring) == 'a a b b c c d d'
def test_get_file_data(): def test_get_file_data():
"""Test for function 'get_file_data()'."""
assert get_file_data(TEST_FILE_CERFA_DIA) == base64.b64encode(open(TEST_FILE_CERFA_DIA).read()) assert get_file_data(TEST_FILE_CERFA_DIA) == base64.b64encode(open(TEST_FILE_CERFA_DIA).read())
assert get_file_data(TEST_FILE_CERFA_DIA, b64=False) == open(TEST_FILE_CERFA_DIA).read() assert get_file_data(TEST_FILE_CERFA_DIA, b64=False) == open(TEST_FILE_CERFA_DIA).read()
def test_get_file_digest(): def test_get_file_digest():
with open(TEST_FILE_CERFA_DIA) as fd: """Test for function 'get_file_digest()'."""
assert get_file_digest(fd) == 'cc90a620982760fdee16a5b4fe1b5ac3b4fe868fd02d2f70b27f1e46d283ea51'
with open(TEST_FILE_CERFA_DIA) as file_pt:
assert get_file_digest(file_pt) == ('cc90a620982760fdee16a5b4fe1b5ac3'
'b4fe868fd02d2f70b27f1e46d283ea51')
def test_get_upload_path(): def test_get_upload_path():
ff = ForwardFile( """Test for function 'get_upload_path()'."""
forwardfile = ForwardFile(
numero_demande='45641531', numero_demande='45641531',
numero_dossier=FAKE_NUMERO_DOSSIER, numero_dossier=FAKE_NUMERO_DOSSIER,
type_fichier='CERFA', type_fichier='CERFA',
@ -167,10 +189,12 @@ def test_get_upload_path():
) )
regex = r"^to_openADS__%s__%s\.pdf$" % ( regex = r"^to_openADS__%s__%s\.pdf$" % (
'[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}h[0-9]{2}m[0-9]{2}s[0-9]+', 'ffdf') '[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}h[0-9]{2}m[0-9]{2}s[0-9]+', 'ffdf')
assert re.search(regex, get_upload_path(ff)) assert re.search(regex, get_upload_path(forwardfile))
def test_get_file_extension(): def test_get_file_extension():
"""Test for function 'get_file_extension()'."""
assert get_file_extension('afile.pdf') == '.pdf' assert get_file_extension('afile.pdf') == '.pdf'
assert get_file_extension('afile', 'application/pdf') == '.pdf' assert get_file_extension('afile', 'application/pdf') == '.pdf'
assert get_file_extension('') == '' assert get_file_extension('') == ''
@ -178,65 +202,78 @@ def test_get_file_extension():
def test_trunc_str_values(): def test_trunc_str_values():
d = {} """Test for function 'trunc_str_values()'."""
assert trunc_str_values(d, 10) == d
d = {'a': '123456789'}
assert trunc_str_values(d, 0) == {'a': u''}
d = {'a': '123456789'}
assert trunc_str_values(d, 1) == {'a': u'1…'}
d = {'a': '123456789'}
assert trunc_str_values(d, 2) == {'a': u'12…'}
d = {'a': '123456789'}
assert trunc_str_values(d, 5) == {'a': u'12345…'}
d = {'a': '123456789'}
assert trunc_str_values(d, 8) == {'a': u'12345678…'}
d = {'a': '123456789'}
assert trunc_str_values(d, 9) == {'a': u'123456789'}
d = {'a': '123456789'}
assert trunc_str_values(d, 10) == d
d = {'a': '123456789', 'b123456789': '987654321'} dic = {}
assert trunc_str_values(d, 5) == {'a': u'12345…', 'b123456789': u'98765…'} assert trunc_str_values(dic, 10) == dic
dic = {'a': '123456789'}
assert trunc_str_values(dic, 0) == {'a': u''}
dic = {'a': '123456789'}
assert trunc_str_values(dic, 1) == {'a': u'1…'}
dic = {'a': '123456789'}
assert trunc_str_values(dic, 2) == {'a': u'12…'}
dic = {'a': '123456789'}
assert trunc_str_values(dic, 5) == {'a': u'12345…'}
dic = {'a': '123456789'}
assert trunc_str_values(dic, 8) == {'a': u'12345678…'}
dic = {'a': '123456789'}
assert trunc_str_values(dic, 9) == {'a': u'123456789'}
dic = {'a': '123456789'}
assert trunc_str_values(dic, 10) == dic
d = {'a': '123456789', 'b123456789': '987654321', 'c': {'c1':'ABCDEFGHIJK'}} dic = {'a': '123456789', 'b123456789': '987654321'}
assert trunc_str_values(d, 5) == {'a': u'12345…', 'b123456789': u'98765…', 'c': {'c1': u'ABCDE…'}} assert trunc_str_values(dic, 5) == {'a': u'12345…', 'b123456789': u'98765…'}
d = {'a': '123456789', 'b123456789': '987654321', 'c': {'c1':'ABCDEFGHIJK'}, 'd': ['123456789']} dic = {'a': '123456789', 'b123456789': '987654321', 'c': {'c1':'ABCDEFGHIJK'}}
assert trunc_str_values(d, 5) == {'a': u'12345…', 'b123456789': u'98765…', 'c': {'c1': u'ABCDE…'}, 'd': [u'12345…']} assert trunc_str_values(dic, 5) == {'a': u'12345…', 'b123456789': u'98765…',
'c': {'c1': u'ABCDE…'}}
d = {'a': '123456789', 'b123456789': '987654321', 'c': {'c1':'ABCDEFGHIJK'}, 'd': ['123456789', {'eeeeeeeeee':'132456789'}]} dic = {'a': '123456789', 'b123456789': '987654321', 'c': {'c1':'ABCDEFGHIJK'},
assert trunc_str_values(d, 5) == {'a': u'12345…', 'b123456789': u'98765…', 'c': {'c1': u'ABCDE…'}, 'd': [u'12345…', {'eeeeeeeeee': u'13245…'}]} 'd': ['123456789']}
assert trunc_str_values(dic, 5) == {'a': u'12345…', 'b123456789': u'98765…',
'c': {'c1': u'ABCDE…'}, 'd': [u'12345…']}
dic = {'a': '123456789', 'b123456789': '987654321', 'c': {'c1':'ABCDEFGHIJK'},
'd': ['123456789', {'eeeeeeeeee':'132456789'}]}
assert trunc_str_values(dic, 5) == {'a': u'12345…', 'b123456789': u'98765…',
'c': {'c1': u'ABCDE…'},
'd': [u'12345…', {'eeeeeeeeee': u'13245…'}]}
def test_dict_dumper(): def test_dict_dumper():
d = {} """Test for methods of class 'DictDumper'."""
dd = DictDumper(d, use_json_dumps=False) dic = {}
assert repr(dd) == (u'DictDumper(dic=%r,max_str_len=%r,use_json_dumps=%r)' % (
d, dd.max_str_len, dd.use_json_dumps)).encode('utf-8')
assert str(dd) == '{}'
assert unicode(dd) == u'{}'
assert d == dd.dic dumped = DictDumper(dic, use_json_dumps=False)
assert unicode(d) == unicode(dd) assert repr(dumped) == (u'DictDumper(dic=%r,max_str_len=%r,use_json_dumps=%r)' % (
dd = DictDumper(d, 0, use_json_dumps=False) dic, dumped.max_str_len, dumped.use_json_dumps)).encode('utf-8')
assert d == dd.dic assert str(dumped) == '{}'
assert unicode(d) == unicode(dd) assert unicode(dumped) == u'{}'
d = {'a': '123456789'} assert dic == dumped.dic
dd = DictDumper(d, 10, use_json_dumps=False) assert unicode(dic) == unicode(dumped)
assert d == dd.dic dumped = DictDumper(dic, 0, use_json_dumps=False)
assert unicode(d) == unicode(dd) assert dic == dumped.dic
dd = DictDumper(d, 5, use_json_dumps=False) assert unicode(dic) == unicode(dumped)
assert d == dd.dic
assert unicode(dd) == unicode({'a': u'12345…'}) dic = {'a': '123456789'}
dd = DictDumper(d, 5, use_json_dumps=True) dumped = DictDumper(dic, 10, use_json_dumps=False)
assert d == dd.dic assert dic == dumped.dic
assert unicode(dd) == u'{"a": "12345\\u2026"}' assert unicode(dic) == unicode(dumped)
dumped = DictDumper(dic, 5, use_json_dumps=False)
assert dic == dumped.dic
assert unicode(dumped) == unicode({'a': u'12345…'})
dumped = DictDumper(dic, 5, use_json_dumps=True)
assert dic == dumped.dic
assert unicode(dumped) == u'{"a": "12345\\u2026"}'
# pylint: disable=unused-argument,redefined-outer-name
def test_base_model(atreal_openads, collectivite_1, collectivite_1_guichet): def test_base_model(atreal_openads, collectivite_1, collectivite_1_guichet):
ff = ForwardFile( """Test for methods of class 'BaseModel' through instance of a ForwardFile."""
forwardfile = ForwardFile(
numero_demande='45641531', numero_demande='45641531',
numero_dossier=FAKE_NUMERO_DOSSIER, numero_dossier=FAKE_NUMERO_DOSSIER,
type_fichier='CERFA', type_fichier='CERFA',
@ -249,24 +286,24 @@ def test_base_model(atreal_openads, collectivite_1, collectivite_1_guichet):
collectivite=None collectivite=None
) )
assert ff.get_verbose_name() == 'Forward File' assert forwardfile.get_verbose_name() == 'Forward File'
assert ff.get_verbose_name_plural() == 'Forward Files' assert forwardfile.get_verbose_name_plural() == 'Forward Files'
assert ff.get_class_name() == 'ForwardFile' assert forwardfile.get_class_name() == 'ForwardFile'
assert ff.get_class_name_plural() == 'ForwardFiles' assert forwardfile.get_class_name_plural() == 'ForwardFiles'
assert ff.get_class_name_dash_case() == 'forward-file' assert forwardfile.get_class_name_dash_case() == 'forward-file'
assert ff.get_class_name_plural_dash_case() == 'forward-files' assert forwardfile.get_class_name_plural_dash_case() == 'forward-files'
assert ff.get_class_name_title() == 'Forward File' assert forwardfile.get_class_name_title() == 'Forward File'
assert ff.get_class_name_plural_title() == 'Forward Files' assert forwardfile.get_class_name_plural_title() == 'Forward Files'
assert ff.get_url_name('list', plural=True) == 'list-forward-files' assert forwardfile.get_url_name('list', plural=True) == 'list-forward-files'
assert ff.get_absolute_url() == '/manage/atreal-openads/atreal/forward-file/None' assert forwardfile.get_absolute_url() == '/manage/atreal-openads/atreal/forward-file/None'
assert ff.get_edit_url() == '/manage/atreal-openads/atreal/edit-forward-file/None' assert forwardfile.get_edit_url() == '/manage/atreal-openads/atreal/edit-forward-file/None'
assert ff.get_delete_url() == '/manage/atreal-openads/atreal/delete-forward-file/None' assert forwardfile.get_delete_url() == '/manage/atreal-openads/atreal/delete-forward-file/None'
assert ff.get_list_url() == '/manage/atreal-openads/atreal/forward-files' assert forwardfile.get_list_url() == '/manage/atreal-openads/atreal/forward-files'
assert atreal_openads.get_class_name_plural() == 'AtrealOpenads' assert atreal_openads.get_class_name_plural() == 'AtrealOpenads'
@ -276,13 +313,12 @@ def test_base_model(atreal_openads, collectivite_1, collectivite_1_guichet):
assert params['connector'] == 'atreal-openads' assert params['connector'] == 'atreal-openads'
assert params['slug'] == atreal_openads.slug assert params['slug'] == atreal_openads.slug
with pytest.raises(Exception) as e: with pytest.raises(Exception) as exception:
atreal_openads.get_list_url() atreal_openads.get_list_url()
assert unicode(e.value) == u"AtrealOpenads:get_list_url() method should not be called" assert unicode(exception.value) == u"AtrealOpenads:get_list_url() method should not be called"
# TODO add more collectivite test cases # TODO add more collectivite test cases
with pytest.raises(Exception) as e: with pytest.raises(Exception) as exception:
collectivite_1_guichet.get_list_url() collectivite_1_guichet.get_list_url()
assert unicode(e.value) == u"Guichet:get_list_url() method should not be called" assert unicode(exception.value) == u"Guichet:get_list_url() method should not be called"

View File

@ -1,10 +1,13 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import pytest """Testing views."""
import os import os
import base64 import base64
import datetime import datetime
import pytest
from django.http.request import HttpRequest, QueryDict from django.http.request import HttpRequest, QueryDict
from django.urls.base import resolve from django.urls.base import resolve
from django.core.files import File from django.core.files import File
@ -36,80 +39,91 @@ from atreal_openads.models import (
) )
CONNECTOR_NAME = 'atreal-openads' CONNECTOR_NAME = 'atreal-openads'
CONNECTOR_SLUG = 'atreal' CONNECTOR_SLUG = 'atreal'
COLLECTIVITE = 79 COLLECTIVITE = 79
OPENADS_API_LOGIN = 'publik-passerelle' OPENADS_API_LOGIN = 'publik-passerelle'
OPENADS_API_PASSWORD = base64.urlsafe_b64encode(os.urandom(20)) OPENADS_API_PASSWORD = base64.urlsafe_b64encode(os.urandom(20))
OPENADS_API_URL = 'http://openads.api/' OPENADS_API_URL = 'http://openads.api/'
FAKE_COOKIE_CRSF = base64.urlsafe_b64encode(os.urandom(20)) FAKE_COOKIE_CRSF = base64.urlsafe_b64encode(os.urandom(20))
FAKE_NUMERO_DOSSIER = base64.urlsafe_b64encode(os.urandom(10)) FAKE_NUMERO_DOSSIER = base64.urlsafe_b64encode(os.urandom(10))
TESTS_DIR = os.path.dirname(__file__) TESTS_DIR = os.path.dirname(__file__)
RESOURCES_DIR = os.path.join(TESTS_DIR, 'resources') RESOURCES_DIR = os.path.join(TESTS_DIR, 'resources')
TEST_FILE_CERFA_DIA = os.path.join(RESOURCES_DIR, 'cerfa_10072-02.pdf') TEST_FILE_CERFA_DIA = os.path.join(RESOURCES_DIR, 'cerfa_10072-02.pdf')
TEST_FILE_PLAN_CADASTRAL = os.path.join(RESOURCES_DIR, 'plancadastral.pdf') TEST_FILE_PLAN_CADASTRAL = os.path.join(RESOURCES_DIR, 'plancadastral.pdf')
@pytest.fixture @pytest.fixture
# pylint: disable=unused-argument,invalid-name
def atreal_openads(db): def atreal_openads(db):
"""Return an instance of a connector AtrealOpenads."""
return AtrealOpenads.objects.create( return AtrealOpenads.objects.create(
slug = CONNECTOR_SLUG, slug=CONNECTOR_SLUG,
default_collectivite_openADS_id = COLLECTIVITE, default_collectivite_openADS_id=COLLECTIVITE,
openADS_API_url = OPENADS_API_URL, openADS_API_url=OPENADS_API_URL,
basic_auth_username = OPENADS_API_LOGIN, basic_auth_username=OPENADS_API_LOGIN,
basic_auth_password = OPENADS_API_PASSWORD basic_auth_password=OPENADS_API_PASSWORD
) )
@pytest.fixture @pytest.fixture
# pylint: disable=unused-argument,redefined-outer-name,invalid-name
def collectivite_1(db, atreal_openads): def collectivite_1(db, atreal_openads):
return Collectivite.objects.create( """Return an instance of a 'Collectivite'."""
name = u'Macollectivité', return Collectivite.objects.create( # pylint: disable=no-member
connecteur = atreal_openads, name=u'Macollectivité',
openADS_id = '3' connecteur=atreal_openads,
openADS_id='3'
) )
@pytest.fixture @pytest.fixture
# pylint: disable=unused-argument,redefined-outer-name,invalid-name
def collectivite_1_guichet(db, atreal_openads, collectivite_1): def collectivite_1_guichet(db, atreal_openads, collectivite_1):
return Guichet.objects.create( """Return an instance of a 'Guichet'."""
collectivite = collectivite_1, return Guichet.objects.create( # pylint: disable=no-member
ouverture_jour_h = datetime.time(9, 0), collectivite=collectivite_1,
fermeture_jour_h = datetime.time(17, 0), ouverture_jour_h=datetime.time(9, 0),
ouverture_sem_d = 1, # Lundi fermeture_jour_h=datetime.time(17, 0),
fermeture_sem_d = 5, # Vendredi ouverture_sem_d=1, # Lundi
ouverture_sem_h = datetime.time(8, 30), fermeture_sem_d=5, # Vendredi
fermeture_sem_h = datetime.time(12, 15) ouverture_sem_h=datetime.time(8, 30),
fermeture_sem_h=datetime.time(12, 15)
) )
@pytest.fixture @pytest.fixture
# pylint: disable=unused-argument,redefined-outer-name,invalid-name
def forwardfile_1(db, atreal_openads, collectivite_1): def forwardfile_1(db, atreal_openads, collectivite_1):
return ForwardFile.objects.create( """Return an instance of a 'ForwardFile'."""
connecteur = atreal_openads, return ForwardFile.objects.create( # pylint: disable=no-member
collectivite = collectivite_1, connecteur=atreal_openads,
numero_demande = '45641531', collectivite=collectivite_1,
numero_dossier = FAKE_NUMERO_DOSSIER, numero_demande='45641531',
type_fichier = 'CERFA', numero_dossier=FAKE_NUMERO_DOSSIER,
orig_filename = os.path.basename(TEST_FILE_CERFA_DIA), type_fichier='CERFA',
content_type = 'application/pdf', orig_filename=os.path.basename(TEST_FILE_CERFA_DIA),
file_hash = 'ffdf456fdsvgb4bgfb6g4f5b', content_type='application/pdf',
upload_file = File(open(TEST_FILE_CERFA_DIA, 'r')), file_hash='ffdf456fdsvgb4bgfb6g4f5b',
upload_status = 'pending' upload_file=File(open(TEST_FILE_CERFA_DIA, 'r')),
upload_status='pending'
) )
def test_get_connecteur_from_request(atreal_openads, forwardfile_1): # pylint: disable=unused-argument,redefined-outer-name
def test_get_connecteur_from_request(atreal_openads, forwardfile_1): # pylint: disable=invalid-name
"""Test for function 'get_connecteur_from_request()'."""
req = HttpRequest() req = HttpRequest()
req.path = '/manage/atreal-openads/%s/forward-file/%s' % ( req.path = '/manage/atreal-openads/%s/forward-file/%s' % (
atreal_openads.slug, forwardfile_1.id) atreal_openads.slug, forwardfile_1.id)
req.method = 'GET' req.method = 'GET'
req.encoding = 'utf-8' req.encoding = 'utf-8'
req.GET = QueryDict(mutable=True) # required because of encoding setter req.GET = QueryDict(mutable=True) # required because of encoding setter
req.POST = QueryDict(mutable=True) # required because of encoding setter req.POST = QueryDict(mutable=True) # required because of encoding setter
req.content_params = None req.content_params = None
req.COOKIES = {} req.COOKIES = {}
req.META = {} req.META = {}
req._read_started = False req._read_started = False # pylint: disable=protected-access
req.resolver_match = resolve(req.path) req.resolver_match = resolve(req.path)
view = ForwardFileView() view = ForwardFileView()
@ -120,18 +134,21 @@ def test_get_connecteur_from_request(atreal_openads, forwardfile_1):
assert connecteur.slug == atreal_openads.slug assert connecteur.slug == atreal_openads.slug
def test_get_collectivite_from_request(atreal_openads, collectivite_1): # pylint: disable=unused-argument,redefined-outer-name
def test_get_collectivite_from_request(atreal_openads, collectivite_1): # pylint: disable=invalid-name
"""Test for function 'get_collectivite_from_request()'."""
req = HttpRequest() req = HttpRequest()
req.path = '/manage/atreal-openads/%s/collectivite/%s/forward-files' % ( req.path = '/manage/atreal-openads/%s/collectivite/%s/forward-files' % (
atreal_openads.slug, collectivite_1.id) atreal_openads.slug, collectivite_1.id)
req.method = 'GET' req.method = 'GET'
req.encoding = 'utf-8' req.encoding = 'utf-8'
req.GET = QueryDict(mutable=True) # required because of encoding setter req.GET = QueryDict(mutable=True) # required because of encoding setter
req.POST = QueryDict(mutable=True) # required because of encoding setter req.POST = QueryDict(mutable=True) # required because of encoding setter
req.content_params = None req.content_params = None
req.COOKIES = {} req.COOKIES = {}
req.META = {} req.META = {}
req._read_started = False req._read_started = False # pylint: disable=protected-access
req.resolver_match = resolve(req.path) req.resolver_match = resolve(req.path)
view = ForwardFileListView() view = ForwardFileListView()
@ -142,31 +159,34 @@ def test_get_collectivite_from_request(atreal_openads, collectivite_1):
assert collectivite.id == collectivite_1.id assert collectivite.id == collectivite_1.id
# pylint: disable=too-many-statements
def test_forwardfile_view(atreal_openads, collectivite_1, forwardfile_1): def test_forwardfile_view(atreal_openads, collectivite_1, forwardfile_1):
"""Test for views 'ForwardFile*View'."""
req = HttpRequest() req = HttpRequest()
req.path = '/manage/atreal-openads/%s/forward-file/%s' % ( req.path = '/manage/atreal-openads/%s/forward-file/%s' % (
atreal_openads.slug, forwardfile_1.id) atreal_openads.slug, forwardfile_1.id)
req.method = 'GET' req.method = 'GET'
req.encoding = 'utf-8' req.encoding = 'utf-8'
req.GET = QueryDict(mutable=True) # required because of encoding setter req.GET = QueryDict(mutable=True) # required because of encoding setter
req.POST = QueryDict(mutable=True) # required because of encoding setter req.POST = QueryDict(mutable=True) # required because of encoding setter
req.content_params = None req.content_params = None
req.COOKIES = {} req.COOKIES = {}
req.META = {} req.META = {}
req._read_started = False req._read_started = False # pylint: disable=protected-access
req.resolver_match = resolve(req.path) req.resolver_match = resolve(req.path)
view = ForwardFileView() view = ForwardFileView()
view.request = req view.request = req
view.object = None view.object = None
view.kwargs = req.resolver_match.kwargs view.kwargs = req.resolver_match.kwargs
context = view.get_context_data() context = view.get_context_data()
assert context['connecteur'].slug == atreal_openads.slug assert context['connecteur'].slug == atreal_openads.slug
view = ForwardFileUpdateView() view = ForwardFileUpdateView()
view.request = req view.request = req
view.object = None view.object = None
view.kwargs = req.resolver_match.kwargs view.kwargs = req.resolver_match.kwargs
context = view.get_context_data() context = view.get_context_data()
assert context['connecteur'].slug == atreal_openads.slug assert context['connecteur'].slug == atreal_openads.slug
url = view.get_success_url() url = view.get_success_url()
@ -182,11 +202,11 @@ def test_forwardfile_view(atreal_openads, collectivite_1, forwardfile_1):
view = ForwardFileDeleteView() view = ForwardFileDeleteView()
view.request = req view.request = req
view.object = None view.object = None
view.kwargs = req.resolver_match.kwargs view.kwargs = req.resolver_match.kwargs
context = view.get_context_data() context = view.get_context_data()
assert context['connecteur'].slug == atreal_openads.slug assert context['connecteur'].slug == atreal_openads.slug
del(req.GET['back-to']) del req.GET['back-to']
url = view.get_success_url() url = view.get_success_url()
assert url == u'/atreal-openads/%s/' % atreal_openads.slug assert url == u'/atreal-openads/%s/' % atreal_openads.slug
req.GET['back-to'] = 'list-forward-files' req.GET['back-to'] = 'list-forward-files'
@ -203,72 +223,77 @@ def test_forwardfile_view(atreal_openads, collectivite_1, forwardfile_1):
view = ForwardFileListView() view = ForwardFileListView()
view.request = req view.request = req
view.object_list = [] view.object_list = []
view.kwargs = req.resolver_match.kwargs view.kwargs = req.resolver_match.kwargs
context = view.get_context_data() context = view.get_context_data()
assert context['connecteur'].slug == atreal_openads.slug assert context['connecteur'].slug == atreal_openads.slug
assert context['collectivite'].id == collectivite_1.id assert context['collectivite'].id == collectivite_1.id
qs = view.get_queryset() queryset = view.get_queryset()
assert qs.query is not None assert queryset.query is not None
assert qs.query.order_by == ['id'] assert queryset.query.order_by == ['id']
assert qs.query.default_ordering == True assert queryset.query.default_ordering
assert qs.query.get_meta().ordering == ['-last_update_datetime'] assert queryset.query.get_meta().ordering == ['-last_update_datetime']
assert qs.ordered assert queryset.ordered
req.GET['order-by'] = '-id' req.GET['order-by'] = '-id'
qs = view.get_queryset() queryset = view.get_queryset()
assert qs.query is not None assert queryset.query is not None
assert qs.query.order_by == ['-id'] assert queryset.query.order_by == ['-id']
assert qs.query.default_ordering == True assert queryset.query.default_ordering
req.path = '/manage/atreal-openads/%s/forward-files' % atreal_openads.slug req.path = '/manage/atreal-openads/%s/forward-files' % atreal_openads.slug
req.resolver_match = resolve(req.path) req.resolver_match = resolve(req.path)
del(req.GET['back-to']) del req.GET['back-to']
del(req.GET['order-by']) del req.GET['order-by']
view = ForwardFileListView() view = ForwardFileListView()
view.request = req view.request = req
view.object_list = [] view.object_list = []
view.kwargs = req.resolver_match.kwargs view.kwargs = req.resolver_match.kwargs
context = view.get_context_data() context = view.get_context_data()
assert context['connecteur'].slug == atreal_openads.slug assert context['connecteur'].slug == atreal_openads.slug
qs = view.get_queryset() queryset = view.get_queryset()
assert qs.query is not None assert queryset.query is not None
assert qs.query.order_by == ['id'] assert queryset.query.order_by == ['id']
assert qs.query.default_ordering == True assert queryset.query.default_ordering
assert qs.query.get_meta().ordering == ['-last_update_datetime'] assert queryset.query.get_meta().ordering == ['-last_update_datetime']
assert qs.ordered assert queryset.ordered
# pylint: disable=too-many-statements
def test_collectivite_view(atreal_openads, collectivite_1, forwardfile_1): def test_collectivite_view(atreal_openads, collectivite_1, forwardfile_1):
"""Test for views 'Collectivite*View'."""
req = HttpRequest() req = HttpRequest()
req.path = '/manage/atreal-openads/%s/collectivite/%s' % ( req.path = '/manage/atreal-openads/%s/collectivite/%s' % (
atreal_openads.slug, collectivite_1.id) atreal_openads.slug, collectivite_1.id)
req.method = 'GET' req.method = 'GET'
req.encoding = 'utf-8' req.encoding = 'utf-8'
req.GET = QueryDict(mutable=True) # required because of encoding setter req.GET = QueryDict(mutable=True) # required because of encoding setter
req.POST = QueryDict(mutable=True) # required because of encoding setter req.POST = QueryDict(mutable=True) # required because of encoding setter
req.content_params = None req.content_params = None
req.COOKIES = {} req.COOKIES = {}
req.META = {} req.META = {}
req._read_started = False req._read_started = False # pylint: disable=protected-access
req.resolver_match = resolve(req.path) req.resolver_match = resolve(req.path)
view = CollectiviteView() view = CollectiviteView()
view.request = req view.request = req
view.object = None view.object = None
view.kwargs = req.resolver_match.kwargs view.kwargs = req.resolver_match.kwargs
context = view.get_context_data() context = view.get_context_data()
assert context['connecteur'].slug == atreal_openads.slug assert context['connecteur'].slug == atreal_openads.slug
assert context['guichet_add_url'] == u'/manage/atreal-openads/%s/collectivite/%s/create-guichet' % ( assert context['guichet_add_url'] == (
atreal_openads.slug, collectivite_1.id) u'/manage/atreal-openads/%s/collectivite/%s/create-guichet' % (
assert context['forward_files_list_url'] == u'/manage/atreal-openads/%s/collectivite/%s/forward-files' % ( atreal_openads.slug, collectivite_1.id))
atreal_openads.slug, collectivite_1.id) assert context['forward_files_list_url'] == (
u'/manage/atreal-openads/%s/collectivite/%s/forward-files' % (
atreal_openads.slug, collectivite_1.id))
view = CollectiviteUpdateView() view = CollectiviteUpdateView()
view.request = req view.request = req
view.object = None view.object = None
view.kwargs = req.resolver_match.kwargs view.kwargs = req.resolver_match.kwargs
context = view.get_context_data() context = view.get_context_data()
assert context['connecteur'].slug == atreal_openads.slug assert context['connecteur'].slug == atreal_openads.slug
url = view.get_success_url() url = view.get_success_url()
@ -280,11 +305,11 @@ def test_collectivite_view(atreal_openads, collectivite_1, forwardfile_1):
view = CollectiviteDeleteView() view = CollectiviteDeleteView()
view.request = req view.request = req
view.object = None view.object = None
view.kwargs = req.resolver_match.kwargs view.kwargs = req.resolver_match.kwargs
context = view.get_context_data() context = view.get_context_data()
assert context['connecteur'].slug == atreal_openads.slug assert context['connecteur'].slug == atreal_openads.slug
del(req.GET['back-to']) del req.GET['back-to']
url = view.get_success_url() url = view.get_success_url()
assert url == u'/atreal-openads/%s/' % atreal_openads.slug assert url == u'/atreal-openads/%s/' % atreal_openads.slug
req.GET['back-to'] = 'list-collectivites' req.GET['back-to'] = 'list-collectivites'
@ -295,13 +320,13 @@ def test_collectivite_view(atreal_openads, collectivite_1, forwardfile_1):
req.path = '/manage/atreal-openads/%s/create-collectivite' % atreal_openads.slug req.path = '/manage/atreal-openads/%s/create-collectivite' % atreal_openads.slug
req.resolver_match = resolve(req.path) req.resolver_match = resolve(req.path)
view.request = req view.request = req
view.object = None view.object = None
view.kwargs = req.resolver_match.kwargs view.kwargs = req.resolver_match.kwargs
context = view.get_context_data() context = view.get_context_data()
assert context['connecteur'].slug == atreal_openads.slug assert context['connecteur'].slug == atreal_openads.slug
kwargs = view.get_form_kwargs() kwargs = view.get_form_kwargs()
assert kwargs['connecteur'].slug == atreal_openads.slug assert kwargs['connecteur'].slug == atreal_openads.slug
del(req.GET['back-to']) del req.GET['back-to']
url = view.get_success_url() url = view.get_success_url()
assert url == u'/atreal-openads/%s/' % atreal_openads.slug assert url == u'/atreal-openads/%s/' % atreal_openads.slug
req.GET['back-to'] = 'list-collectivites' req.GET['back-to'] = 'list-collectivites'
@ -313,59 +338,62 @@ def test_collectivite_view(atreal_openads, collectivite_1, forwardfile_1):
view = CollectiviteListView() view = CollectiviteListView()
view.request = req view.request = req
view.object_list = [] view.object_list = []
view.kwargs = req.resolver_match.kwargs view.kwargs = req.resolver_match.kwargs
context = view.get_context_data() context = view.get_context_data()
assert context['connecteur'].slug == atreal_openads.slug assert context['connecteur'].slug == atreal_openads.slug
assert context['collectivite_add_url'] == u'/manage/atreal-openads/%s/create-collectivite' % atreal_openads.slug assert context['collectivite_add_url'] == (
u'/manage/atreal-openads/%s/create-collectivite' % atreal_openads.slug)
qs = view.get_queryset() queryset = view.get_queryset()
assert qs.query is not None assert queryset.query is not None
assert qs.query.order_by == ['id'] assert queryset.query.order_by == ['id']
assert qs.query.default_ordering == True assert queryset.query.default_ordering
assert qs.query.get_meta().ordering == ['name'] assert queryset.query.get_meta().ordering == ['name']
assert qs.ordered assert queryset.ordered
req.GET['order-by'] = '-id' req.GET['order-by'] = '-id'
qs = view.get_queryset() queryset = view.get_queryset()
assert qs.query is not None assert queryset.query is not None
assert qs.query.order_by == ['-id'] assert queryset.query.order_by == ['-id']
assert qs.query.default_ordering == True assert queryset.query.default_ordering
def test_guichet_view(atreal_openads, collectivite_1, collectivite_1_guichet): def test_guichet_view(atreal_openads, collectivite_1, collectivite_1_guichet):
"""Test for views 'Guichet*View'."""
req = HttpRequest() req = HttpRequest()
req.path = '/manage/atreal-openads/%s/collectivite/%s/guichet/%s' % ( req.path = '/manage/atreal-openads/%s/collectivite/%s/guichet/%s' % (
atreal_openads.slug, collectivite_1.id, collectivite_1_guichet.id) atreal_openads.slug, collectivite_1.id, collectivite_1_guichet.id)
req.method = 'GET' req.method = 'GET'
req.encoding = 'utf-8' req.encoding = 'utf-8'
req.GET = QueryDict(mutable=True) # required because of encoding setter req.GET = QueryDict(mutable=True) # required because of encoding setter
req.POST = QueryDict(mutable=True) # required because of encoding setter req.POST = QueryDict(mutable=True) # required because of encoding setter
req.content_params = None req.content_params = None
req.COOKIES = {} req.COOKIES = {}
req.META = {} req.META = {}
req._read_started = False req._read_started = False # pylint: disable=protected-access
req.resolver_match = resolve(req.path) req.resolver_match = resolve(req.path)
view = GuichetView() view = GuichetView()
view.request = req view.request = req
view.object = None view.object = None
view.kwargs = req.resolver_match.kwargs view.kwargs = req.resolver_match.kwargs
context = view.get_context_data() context = view.get_context_data()
assert context['connecteur'].slug == atreal_openads.slug assert context['connecteur'].slug == atreal_openads.slug
assert context['collectivite'].id == collectivite_1.id assert context['collectivite'].id == collectivite_1.id
view = GuichetUpdateView() view = GuichetUpdateView()
view.request = req view.request = req
view.object = None view.object = None
view.kwargs = req.resolver_match.kwargs view.kwargs = req.resolver_match.kwargs
context = view.get_context_data() context = view.get_context_data()
assert context['connecteur'].slug == atreal_openads.slug assert context['connecteur'].slug == atreal_openads.slug
assert context['collectivite'].id == collectivite_1.id assert context['collectivite'].id == collectivite_1.id
view = GuichetDeleteView() view = GuichetDeleteView()
view.request = req view.request = req
view.object = None view.object = None
view.kwargs = req.resolver_match.kwargs view.kwargs = req.resolver_match.kwargs
context = view.get_context_data() context = view.get_context_data()
assert context['connecteur'].slug == atreal_openads.slug assert context['connecteur'].slug == atreal_openads.slug
assert context['collectivite'].id == collectivite_1.id assert context['collectivite'].id == collectivite_1.id
@ -378,8 +406,8 @@ def test_guichet_view(atreal_openads, collectivite_1, collectivite_1_guichet):
atreal_openads.slug, collectivite_1.id) atreal_openads.slug, collectivite_1.id)
req.resolver_match = resolve(req.path) req.resolver_match = resolve(req.path)
view.request = req view.request = req
view.object = None view.object = None
view.kwargs = req.resolver_match.kwargs view.kwargs = req.resolver_match.kwargs
context = view.get_context_data() context = view.get_context_data()
assert context['connecteur'].slug == atreal_openads.slug assert context['connecteur'].slug == atreal_openads.slug
assert context['collectivite'].id == collectivite_1.id assert context['collectivite'].id == collectivite_1.id
@ -391,23 +419,25 @@ def test_guichet_view(atreal_openads, collectivite_1, collectivite_1_guichet):
def test_connecteur_view(atreal_openads): def test_connecteur_view(atreal_openads):
"""Test for views 'AtrealOpenadsView'."""
req = HttpRequest() req = HttpRequest()
req.path = '/atreal-openads/%s/' % atreal_openads.slug req.path = '/atreal-openads/%s/' % atreal_openads.slug
req.method = 'GET' req.method = 'GET'
req.encoding = 'utf-8' req.encoding = 'utf-8'
req.GET = QueryDict(mutable=True) # required because of encoding setter req.GET = QueryDict(mutable=True) # required because of encoding setter
req.POST = QueryDict(mutable=True) # required because of encoding setter req.POST = QueryDict(mutable=True) # required because of encoding setter
req.content_params = None req.content_params = None
req.COOKIES = {} req.COOKIES = {}
req.META = {} req.META = {}
req._read_started = False req._read_started = False # pylint: disable=protected-access
req.resolver_match = resolve(req.path) req.resolver_match = resolve(req.path)
view = AtrealOpenadsView() view = AtrealOpenadsView()
view.request = req view.request = req
view.object = atreal_openads view.object = atreal_openads
view.kwargs = req.resolver_match.kwargs view.kwargs = req.resolver_match.kwargs
context = view.get_context_data() context = view.get_context_data()
assert context['collectivite_fields'] == Collectivite.get_fields() assert context['collectivite_fields'] == Collectivite.get_fields()
assert context['collectivite_add_url'] == u'/manage/atreal-openads/%s/create-collectivite' % atreal_openads.slug assert context['collectivite_add_url'] == (
u'/manage/atreal-openads/%s/create-collectivite' % atreal_openads.slug)