From 9341ca3a5afcfd3aded80d95f449066de6aa9fb2 Mon Sep 17 00:00:00 2001
From: Serghei Mihai <smihai@entrouvert.com>
Date: Mon, 15 Apr 2019 16:13:19 +0200
Subject: [PATCH] cityweb: add option to zip demand files (#32091)

---
 passerelle/apps/cityweb/cityweb.py            |  12 +-
 .../cityweb/migrations/0004_cityweb_do_zip.py |  20 ++
 passerelle/apps/cityweb/models.py             |   4 +-
 tests/test_cityweb.py                         | 181 ++++++++++--------
 4 files changed, 136 insertions(+), 81 deletions(-)
 create mode 100644 passerelle/apps/cityweb/migrations/0004_cityweb_do_zip.py

diff --git a/passerelle/apps/cityweb/cityweb.py b/passerelle/apps/cityweb/cityweb.py
index c58c4269..8f92ae6e 100644
--- a/passerelle/apps/cityweb/cityweb.py
+++ b/passerelle/apps/cityweb/cityweb.py
@@ -374,13 +374,15 @@ class CivilStatusApplication(ComplexType):
             self.origine = Origin(data['application_origin'])
         self.commentaire = data.get('application_comment', '')
 
-    def save(self, path):
+    def save(self, path, do_zip=True):
         basename = os.path.join(path, self.identifiant)
         archname = basename + '.zip'
         filepath = basename + '.xml'
         content = etree.tostring(self.xml, pretty_print=True)
         default_storage.save(filepath, ContentFile(content))
-        with zipfile.ZipFile(archname, 'w', zipfile.ZIP_DEFLATED) as zipf:
-            zipf.write(filepath, os.path.basename(filepath))
-        os.remove(filepath)
-        return archname
+        if do_zip:
+            with zipfile.ZipFile(archname, 'w', zipfile.ZIP_DEFLATED) as zipf:
+                zipf.write(filepath, os.path.basename(filepath))
+                os.remove(filepath)
+            return archname
+        return filepath
diff --git a/passerelle/apps/cityweb/migrations/0004_cityweb_do_zip.py b/passerelle/apps/cityweb/migrations/0004_cityweb_do_zip.py
new file mode 100644
index 00000000..931e4e49
--- /dev/null
+++ b/passerelle/apps/cityweb/migrations/0004_cityweb_do_zip.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-04-15 13:35
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('cityweb', '0003_remove_cityweb_log_level'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='cityweb',
+            name='do_zip',
+            field=models.BooleanField(default=True, verbose_name='Zip generated file'),
+        ),
+    ]
diff --git a/passerelle/apps/cityweb/models.py b/passerelle/apps/cityweb/models.py
index 0474039a..98409daa 100644
--- a/passerelle/apps/cityweb/models.py
+++ b/passerelle/apps/cityweb/models.py
@@ -19,6 +19,7 @@ import json
 
 from django.utils.translation import ugettext_lazy as _
 from django.core.files.storage import default_storage
+from django.db import models
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
@@ -29,6 +30,7 @@ from .cityweb import (CivilStatusApplication, TITLES, SEXES, DOCUMENT_TYPES,
 
 
 class CityWeb(BaseResource):
+    do_zip = models.BooleanField(_('Zip generated file'), default=True)
     category = _('Civil Status Connectors')
 
     class Meta:
@@ -47,7 +49,7 @@ class CityWeb(BaseResource):
                 raise APIError('<%s> is required' % key)
 
         application = CivilStatusApplication(payload)
-        application.save(self.basepath)
+        application.save(self.basepath, do_zip=self.do_zip)
         return {'data': {'demand_id': application.identifiant}}
 
     @property
diff --git a/tests/test_cityweb.py b/tests/test_cityweb.py
index 74a1e082..bd366745 100644
--- a/tests/test_cityweb.py
+++ b/tests/test_cityweb.py
@@ -59,25 +59,93 @@ PAYLOAD = [
     }
 ]
 
+BIRTH_ASSERTIONS = {
+    'identifiant': 'N201610154',
+    'demandeur.qualiteDemandeur': 'concerne',
+    'demandeur.individu.noms.nomDeFamille': 'Whatever',
+    'demandeur.individu.prenoms': 'Kim Chelsea',
+    'demandeur.individu.adresse.ligneAdr1': "37 Rue de l'Aigle Blanc",
+    'demandeur.individu.adresse.codePostal': 54000,
+    'demandeur.individu.adresse.lieu.ville': 'Nancy',
+    'demandeur.individu.adresse.lieu.pays': 'France',
+    'demandeur.individu.adresse.mail': 'chelsea@whatever.com',
+    'natureDocument': 'CPI', 'nbExemplaire': 1,
+    'dateDemande': '2016-10-20T14:41:20Z',
+    'evenement.natureEvenement': 'NAI',
+    'evenement.dateEvenement.dateDebut': '2012-07-14',
+    'evenement.lieuEvenement.ville': 'Nancy',
+    'evenement.interesse.pere.noms.nomDeFamille': 'Smith',
+    'evenement.interesse.pere.prenoms': 'John Oliver',
+    'evenement.interesse.mere.noms.nomDeFamille': 'Smith',
+    'evenement.interesse.mere.prenoms': 'Kim',
+}
+
+MARRIAGE_ASSERTIONS = {
+    'identifiant': 'M201610161',
+    'demandeur.qualiteDemandeur': 'concerne',
+    'demandeur.individu.noms.nomDeFamille': 'Whatever',
+    'demandeur.individu.prenoms': 'Kim Chelsea',
+    'demandeur.individu.adresse.ligneAdr1': "37 Rue de l'Aigle Blanc",
+    'demandeur.individu.adresse.codePostal': 54000,
+    'demandeur.individu.adresse.lieu.ville': 'Nancy',
+    'demandeur.individu.adresse.lieu.pays': 'France',
+    'demandeur.individu.adresse.mail': 'chelsea@whatever.com',
+    'natureDocument': 'CPI', 'nbExemplaire': 1,
+    'dateDemande': '2016-10-20T14:41:20Z',
+    'evenement.natureEvenement': 'MAR',
+    'evenement.dateEvenement.dateDebut': '2012-07-14',
+    'evenement.lieuEvenement.ville': 'Nancy',
+    'evenement.interesse.pere.noms.nomDeFamille': 'Smith',
+    'evenement.interesse.pere.prenoms': 'John Oliver',
+    'evenement.interesse.mere.noms.nomDeFamille': 'Smith',
+    'evenement.interesse.mere.prenoms': 'Kim',
+    'evenement.conjoint.noms.nomDeFamille': 'Contrao',
+    'evenement.conjoint.pere.noms.nomDeFamille': 'Scaramucci',
+    'evenement.conjoint.pere.prenoms': 'Antonio',
+    'evenement.conjoint.mere.noms.nomDeFamille': 'Scaramucci',
+    'evenement.conjoint.mere.prenoms': 'Marguerite',
+}
+
+DEATH_ASSERTIONS = {
+    'identifiant': 'D201610171',
+    'demandeur.qualiteDemandeur': 'concerne',
+    'demandeur.individu.noms.nomDeFamille': 'Whatever',
+    'demandeur.individu.prenoms': 'Kim Chelsea',
+    'demandeur.individu.adresse.ligneAdr1': "37 Rue de l'Aigle Blanc",
+    'demandeur.individu.adresse.codePostal': 54000,
+    'demandeur.individu.adresse.lieu.ville': 'Nancy',
+    'demandeur.individu.adresse.lieu.pays': 'France',
+    'demandeur.individu.adresse.mail': 'chelsea@whatever.com',
+    'natureDocument': 'EXTSF', 'nbExemplaire': 1,
+    'dateDemande': '2016-10-20T14:41:20Z',
+    'evenement.natureEvenement': 'DEC',
+    'evenement.dateEvenement.dateDebut': '2012-07-14',
+    'evenement.lieuEvenement.ville': 'Nancy',
+}
+
 
 @pytest.fixture(params=PAYLOAD)
 def payload(request):
     return request.param
 
 
-def assert_xml_doc(archive, assertions):
+def assert_xml_doc(filename, assertions, zipped=True):
     schema = etree.XMLSchema(
         etree.parse(open(os.path.join(get_test_base_dir('cityweb'), 'cityweb.xsd'))))
-    with zipfile.ZipFile(archive) as zfd:
-        content = zfd.read(zfd.filelist[0].filename)
-        xml_content = etree.fromstring(content)
-        assert len(xml_content.nsmap) == 1
-        assert xml_content.nsmap['xs'] == "http://tempuri.org/XMLSchema.xsd"
-        schema.assertValid(xml_content)
-        root = xobject.fromstring(content)
-        for epath, value in assertions.items():
-            path = xobject.ObjectPath('demandeEtatCivil.%s' % epath)
-            assert path.find(root) == value
+    if zipped:
+        with zipfile.ZipFile(filename) as zfd:
+            content = zfd.read(zfd.filelist[0].filename)
+    else:
+        content = file(filename).read()
+
+    xml_content = etree.fromstring(content)
+    assert len(xml_content.nsmap) == 1
+    assert xml_content.nsmap['xs'] == "http://tempuri.org/XMLSchema.xsd"
+    schema.assertValid(xml_content)
+    root = xobject.fromstring(content)
+    for epath, value in assertions.items():
+        path = xobject.ObjectPath('demandeEtatCivil.%s' % epath)
+        assert path.find(root) == value
 
 
 @mock.patch('passerelle.apps.cityweb.models.default_storage.path', get_test_base_dir)
@@ -87,79 +155,42 @@ def test_demand_creation(app, setup, payload):
         response = app.post_json(url, params=payload['birth'])
         assert response.json['data']['demand_id'] == 'N201610154'
         archive = os.path.join(get_test_base_dir('cityweb'), 'test', 'N201610154.zip')
-        assertions = {
-            'identifiant': 'N201610154',
-            'demandeur.qualiteDemandeur': 'concerne',
-            'demandeur.individu.noms.nomDeFamille': 'Whatever',
-            'demandeur.individu.prenoms': 'Kim Chelsea',
-            'demandeur.individu.adresse.ligneAdr1': "37 Rue de l'Aigle Blanc",
-            'demandeur.individu.adresse.codePostal': 54000,
-            'demandeur.individu.adresse.lieu.ville': 'Nancy',
-            'demandeur.individu.adresse.lieu.pays': 'France',
-            'demandeur.individu.adresse.mail': 'chelsea@whatever.com',
-            'natureDocument': 'CPI', 'nbExemplaire': 1,
-            'dateDemande': '2016-10-20T14:41:20Z',
-            'evenement.natureEvenement': 'NAI',
-            'evenement.dateEvenement.dateDebut': '2012-07-14',
-            'evenement.lieuEvenement.ville': 'Nancy',
-            'evenement.interesse.pere.noms.nomDeFamille': 'Smith',
-            'evenement.interesse.pere.prenoms': 'John Oliver',
-            'evenement.interesse.mere.noms.nomDeFamille': 'Smith',
-            'evenement.interesse.mere.prenoms': 'Kim',
-        }
-        assert_xml_doc(archive, assertions)
+        assert_xml_doc(archive, BIRTH_ASSERTIONS)
 
     elif 'mariage' in payload:
         response = app.post_json(url, params=payload['mariage'])
         assert response.json['data']['demand_id'] == 'M201610161'
         archive = os.path.join(get_test_base_dir('cityweb'), 'test', 'M201610161.zip')
-        assertions = {
-            'identifiant': 'M201610161',
-            'demandeur.qualiteDemandeur': 'concerne',
-            'demandeur.individu.noms.nomDeFamille': 'Whatever',
-            'demandeur.individu.prenoms': 'Kim Chelsea',
-            'demandeur.individu.adresse.ligneAdr1': "37 Rue de l'Aigle Blanc",
-            'demandeur.individu.adresse.codePostal': 54000,
-            'demandeur.individu.adresse.lieu.ville': 'Nancy',
-            'demandeur.individu.adresse.lieu.pays': 'France',
-            'demandeur.individu.adresse.mail': 'chelsea@whatever.com',
-            'natureDocument': 'CPI', 'nbExemplaire': 1,
-            'dateDemande': '2016-10-20T14:41:20Z',
-            'evenement.natureEvenement': 'MAR',
-            'evenement.dateEvenement.dateDebut': '2012-07-14',
-            'evenement.lieuEvenement.ville': 'Nancy',
-            'evenement.interesse.pere.noms.nomDeFamille': 'Smith',
-            'evenement.interesse.pere.prenoms': 'John Oliver',
-            'evenement.interesse.mere.noms.nomDeFamille': 'Smith',
-            'evenement.interesse.mere.prenoms': 'Kim',
-            'evenement.conjoint.noms.nomDeFamille': 'Contrao',
-            'evenement.conjoint.pere.noms.nomDeFamille': 'Scaramucci',
-            'evenement.conjoint.pere.prenoms': 'Antonio',
-            'evenement.conjoint.mere.noms.nomDeFamille': 'Scaramucci',
-            'evenement.conjoint.mere.prenoms': 'Marguerite',
-        }
-        assert_xml_doc(archive, assertions)
+        assert_xml_doc(archive, MARRIAGE_ASSERTIONS)
     else:
         response = app.post_json(url, params=payload['death'])
         assert response.json['data']['demand_id'] == 'D201610171'
         archive = os.path.join(get_test_base_dir('cityweb'), 'test', 'D201610171.zip')
-        assertions = {
-            'identifiant': 'D201610171',
-            'demandeur.qualiteDemandeur': 'concerne',
-            'demandeur.individu.noms.nomDeFamille': 'Whatever',
-            'demandeur.individu.prenoms': 'Kim Chelsea',
-            'demandeur.individu.adresse.ligneAdr1': "37 Rue de l'Aigle Blanc",
-            'demandeur.individu.adresse.codePostal': 54000,
-            'demandeur.individu.adresse.lieu.ville': 'Nancy',
-            'demandeur.individu.adresse.lieu.pays': 'France',
-            'demandeur.individu.adresse.mail': 'chelsea@whatever.com',
-            'natureDocument': 'EXTSF', 'nbExemplaire': 1,
-            'dateDemande': '2016-10-20T14:41:20Z',
-            'evenement.natureEvenement': 'DEC',
-            'evenement.dateEvenement.dateDebut': '2012-07-14',
-            'evenement.lieuEvenement.ville': 'Nancy',
-        }
-        assert_xml_doc(archive, assertions)
+        assert_xml_doc(archive, DEATH_ASSERTIONS)
+
+
+@mock.patch('passerelle.apps.cityweb.models.default_storage.path', get_test_base_dir)
+def test_demand_creation_with_no_zipping(app, setup, payload):
+
+    setup.do_zip = False
+    setup.save()
+
+    url = '/cityweb/test/create/'
+    if 'birth' in payload:
+        response = app.post_json(url, params=payload['birth'])
+        assert response.json['data']['demand_id'] == 'N201610154'
+        filename = os.path.join(get_test_base_dir('cityweb'), 'test', 'N201610154.xml')
+        assert_xml_doc(filename, BIRTH_ASSERTIONS, zipped=False)
+    elif 'mariage' in payload:
+        response = app.post_json(url, params=payload['mariage'])
+        assert response.json['data']['demand_id'] == 'M201610161'
+        filename = os.path.join(get_test_base_dir('cityweb'), 'test', 'M201610161.xml')
+        assert_xml_doc(filename, MARRIAGE_ASSERTIONS, zipped=False)
+    else:
+        response = app.post_json(url, params=payload['death'])
+        assert response.json['data']['demand_id'] == 'D201610171'
+        filename = os.path.join(get_test_base_dir('cityweb'), 'test', 'D201610171.xml')
+        assert_xml_doc(filename, DEATH_ASSERTIONS, zipped=False)
 
 
 def test_date_type_parsing():
-- 
2.20.1

