Projet

Général

Profil

0001-cityweb-add-city-web-data-source-endpoints-15883.patch

Josué Kouka, 31 mai 2017 13:53

Télécharger (12,5 ko)

Voir les différences:

Subject: [PATCH 1/6] cityweb: add city web data source endpoints (#15883)

 passerelle/contrib/cityweb/__init__.py |   0
 passerelle/contrib/cityweb/models.py   | 124 ++++++++++++++++++++++++
 passerelle/contrib/cityweb/utils.py    |  42 +++++++++
 tests/settings.py                      |   2 +
 tests/test_cityweb.py                  | 168 +++++++++++++++++++++++++++++++++
 5 files changed, 336 insertions(+)
 create mode 100644 passerelle/contrib/cityweb/__init__.py
 create mode 100644 passerelle/contrib/cityweb/models.py
 create mode 100644 passerelle/contrib/cityweb/utils.py
 create mode 100644 tests/test_cityweb.py
passerelle/contrib/cityweb/models.py
1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2017  Entr'ouvert
3
#
4
# This program is free software: you can redistribute it and/or modify it
5
# under the terms of the GNU Affero General Public License as published
6
# by the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU Affero General Public License for more details.
13
#
14
# You should have received a copy of the GNU Affero General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

  
17
import json
18

  
19
from django.db import models
20
from django.utils.translation import ugettext_lazy as _
21

  
22
from passerelle.base.models import BaseResource
23
from passerelle.utils.api import endpoint
24

  
25

  
26
EVENTS_KIND = [
27
    {"id": "NAI", "text": "Naissance"},
28
    {"id": "MAR", "text": "Mariage"},
29
    {"id": "REC", "text": "Reconnaissance"},
30
    {"id": "DEC", "text": "Décès"}
31
]
32

  
33
GENDERS = [
34
    {"id": "M", "text": "Homme"},
35
    {"id": "F", "text": "Femme"},
36
    {"id": "NA", "text": "Autre"}
37
]
38

  
39
TITLES = [
40
    {"id": "M", "text": "Monsieur"},
41
    {"id": "Mme", "text": "Madame"},
42
    {"id": "Mlle", "text": "Mademoiselle"}
43
]
44

  
45
DOCUMENTS_KIND = [
46
    {"id": "CPI", "text": "Copie intégrale"},
47
    {"id": "EXTAF", "text": "Extrait avec filiation"},
48
    {"id": "EXTSF", "text": "Extrait sans filiation"},
49
    {"id": "EXTPL", "text": "Extrait plurilingue"}
50
]
51

  
52
CONCERNED = [
53
    {"id": "reconnu", "text": "Reconnu"},
54
    {"id": "auteur", "text": "Auteur"}
55
]
56

  
57
CANALS = [
58
    {"id": "internet", "text": "Internet"},
59
    {"id": "guichet", "text": "Guichet"},
60
    {"id": "courrier", "text": "Courrier"}
61
]
62

  
63

  
64
class CityWeb(BaseResource):
65
    category = _('Business Process Connectors')
66

  
67
    class Meta:
68
        verbose_name = "CityWeb - Demande d'acte d'etat civil"
69

  
70
    @classmethod
71
    def get_verbose_name(cls):
72
        return cls._meta.verbose_name
73

  
74
    @endpoint(serializer_type='json-api', perm='can_access', methods=['post'])
75
    def create(self, request, *args, **kwargs):
76
        formdata = json.loads(request.body)
77
        demand, created = Demand.objects.get_or_create(resource=self, demand_id='demand_id',
78
                                                       kind='kind')
79
        result = demand.create(formdata)
80
        return {'demand_id': result}
81

  
82
    @endpoint(serializer_type='json-api', perm='can_access')
83
    def titles(self, request, without=''):
84
        return TITLES
85

  
86
    @endpoint(serializer_type='json-api', perm='can_access')
87
    def genders(self, request, without=''):
88
        return GENDERS
89

  
90
    @endpoint(serializer_type='json-api', perm='can_access')
91
    def concerned(self, request, without=''):
92
        return CONCERNED
93

  
94
    @endpoint(serializer_type='json-api', perm='can_access')
95
    def canals(self, request, without=''):
96
        return CANALS
97

  
98
    @endpoint(name='events-kind', serializer_type='json-api', perm='can_access')
99
    def events_kind(self, request, without=''):
100
        return [item for item in EVENTS_KIND
101
                if item.get('id') not in without.split(',')]
102

  
103
    @endpoint(name='documents-kind', serializer_type='json-api', perm='can_access')
104
    def documents_kind(self, request, without=''):
105
        return [item for item in DOCUMENTS_KIND
106
                if item.get('id') not in without.split(',')]
107

  
108

  
109
class Demand(models.Model):
110
    created_at = models.DateTimeField(auto_now_add=True)
111
    updated_at = models.DateTimeField(auto_now=True)
112
    resource = models.ForeignKey(CityWeb)
113
    name = models.CharField(max_length=32)
114
    kind = models.CharField(max_length=32)
115

  
116
    def __unicode__(self):
117
        return '%s - %s - %s' % (self.resource.slug, self.name, self.kind)
118

  
119
    @property
120
    def filename(self):
121
        pass
122

  
123
    def create(self, data):
124
        pass
passerelle/contrib/cityweb/utils.py
1
# Copyright (C) 2017  Entr'ouvert
2
#
3
# This program is free software: you can redistribute it and/or modify it
4
# under the terms of the GNU Affero General Public License as published
5
# by the Free Software Foundation, either version 3 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU Affero General Public License for more details.
12
#
13
# You should have received a copy of the GNU Affero General Public License
14
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
15

  
16
import os
17
import zipfile
18

  
19
from django.core.files.storage import default_storage
20

  
21

  
22
def flatten_payload(*subs):
23
    result = {}
24
    for sub in subs:
25
        result.update(sub)  # priority on last sub dict
26
    return result
27

  
28

  
29
def get_resource_base_dir():
30
    return default_storage.path('cityweb')
31

  
32

  
33
def zipdir(path):
34
    """Zip directory
35
    """
36
    archname = path + '.zip'
37
    with zipfile.ZipFile(archname, 'w', zipfile.ZIP_DEFLATED) as zipf:
38
        for root, dirs, files in os.walk(path):
39
            for f in files:
40
                fpath = os.path.join(root, f)
41
                zipf.write(fpath, os.path.basename(fpath))
42
    return archname
tests/settings.py
28 28
        'passerelle.contrib.stub_invoices',
29 29
        'passerelle.contrib.teamnet_axel',
30 30
        'passerelle.contrib.tlmcom',
31
        'passerelle.contrib.cityweb',
31 32
        )
32 33

  
33 34
PASSERELLE_APP_FAKE_FAMILY_ENABLED = True
......
39 40
PASSERELLE_APP_SOLIS_APA_ENABLED = True
40 41
PASSERELLE_APP_MDEL_ENABLED = True
41 42
PASSERELLE_APP_GRANDLYON_STREETSECTIONS_ENABLED = True
43
PASSERELLE_APP_CITYWEB_ENABLED = True
tests/test_cityweb.py
1
# -*- coding: utf-8 -*-
2
# Passerelle - uniform access to data and services
3
# Copyright (C) 2017  Entr'ouvert
4
#
5
# This program is free software: you can redistribute it and/or modify it
6
# under the terms of the GNU Affero General Public License as published
7
# by the Free Software Foundation, either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU Affero General Public License for more details.
14
#
15
# You should have received a.deepcopy of the GNU Affero General Public License
16
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
from __future__ import unicode_literals
18

  
19
import os
20
import json
21
import shutil
22

  
23
import pytest
24
import mock
25

  
26
import utils
27

  
28
from passerelle.contrib.cityweb.models import CityWeb
29

  
30

  
31
CITYWEB_TEST_BASE_DIR = os.path.join(os.path.dirname(__file__), 'data', 'cityweb')
32

  
33

  
34
def get_file_from_test_base_dir(filename):
35
    path = os.path.join(CITYWEB_TEST_BASE_DIR, filename)
36
    with open(path, 'rb') as fd:
37
        return fd.read()
38

  
39

  
40
@pytest.fixture
41
def setup(db):
42
    return utils.setup_access_rights(CityWeb.objects.create(slug='test'))
43

  
44

  
45
PAYLOAD = [
46
    {
47
        'naissance': json.loads(get_file_from_test_base_dir('formdata_nais.json'))
48
    },
49
    {
50
        'mariage': json.loads(get_file_from_test_base_dir('formdata_mar.json'))
51
    },
52
    {
53
        'deces': json.loads(get_file_from_test_base_dir('formdata_dec.json'))
54
    }
55
]
56

  
57

  
58
@pytest.fixture(params=PAYLOAD)
59
def payload(request):
60
    return request.param
61

  
62

  
63
@mock.patch('passerelle.contrib.cityweb.utils.get_resource_base_dir', CITYWEB_TEST_BASE_DIR)
64
def test_demand_creation(app, setup, payload):
65
    if 'naissance' in payload:
66
        pass
67
    elif 'mariage' in payload:
68
        pass
69
    else:
70
        pass
71

  
72

  
73
def test_datasource_titles(app, setup):
74
    response = app.get('/cityweb/test/titles/')
75
    data = response.json['data']
76
    assert len(data) == 3
77
    for datum in data:
78
        if datum['id'] == 'M':
79
            assert datum['text'] == 'Monsieur'
80
        elif datum['id'] == 'Mme':
81
            assert datum['text'] == 'Madame'
82
        else:
83
            assert datum['id'] == 'Mlle'
84
            assert datum['text'] == 'Mademoiselle'
85

  
86

  
87
def test_datasource_genders(app, setup):
88
    response = app.get('/cityweb/test/genders/')
89
    data = response.json['data']
90
    assert len(data) == 3
91
    for datum in data:
92
        if datum['id'] == 'M':
93
            assert datum['text']
94
        elif datum['id'] == 'F':
95
            assert datum['text'] == 'Femme'
96
        else:
97
            assert datum['id'] == 'NA'
98
            assert datum['text'] == 'Autre'
99

  
100

  
101
def test_datasource_concerned(app, setup):
102
    response = app.get('/cityweb/test/concerned/')
103
    data = response.json['data']
104
    assert len(data) == 2
105
    for datum in data:
106
        if datum['id'] == 'reconnu':
107
            assert datum['text'] == 'Reconnu'
108
        else:
109
            assert datum['id'] == 'auteur'
110
            assert datum['text'] == 'Auteur'
111

  
112

  
113
def test_datasource_canals(app, setup):
114
    response = app.get('/cityweb/test/canals/')
115
    data = response.json['data']
116
    assert len(data) == 3
117
    for datum in data:
118
        if datum['id'] == 'internet':
119
            assert datum['text'] == 'Internet'
120
        elif datum['id'] == 'guichet':
121
            assert datum['text'] == 'Guichet'
122
        else:
123
            assert datum['id'] == 'courrier'
124
            assert datum['text'] == 'Courrier'
125

  
126

  
127
def test_datasource_documents_kind(app, setup):
128
    response = app.get('/cityweb/test/documents-kind/')
129
    data = response.json['data']
130
    assert len(data) == 4
131
    for datum in data:
132
        if datum['id'] == 'CPI':
133
            assert datum['text'] == 'Copie intégrale'
134
        elif datum['id'] == 'EXTAF':
135
            assert datum['text'] == 'Extrait avec filiation'
136
        elif datum['id'] == 'EXTSF':
137
            assert datum['text'] == 'Extrait sans filiation'
138
        else:
139
            datum['id'] == 'EXTPL'
140
            datum['text'] == 'Extrait plurilingue'
141

  
142
    params = {'without': 'EXTAF,EXTSF,EXTPL'}
143
    response = app.get('/cityweb/test/documents-kind/', params=params)
144
    data = response.json['data']
145
    assert len(data) == 1
146
    assert data[0]['id'] == 'CPI'
147
    assert data[0]['text'] == 'Copie intégrale'
148

  
149

  
150
def test_datasource_events_kind(app, setup):
151
    response = app.get('/cityweb/test/events-kind/')
152
    data = response.json['data']
153
    assert len(data) == 4
154
    for datum in data:
155
        if datum['id'] == 'NAI':
156
            assert datum['text'] == 'Naissance'
157
        elif datum['id'] == 'MAR':
158
            assert datum['text'] == 'Mariage'
159
        elif datum['id'] == 'REC':
160
            assert datum['text'] == 'Reconnaissance'
161
        else:
162
            assert datum['id'] == 'DEC'
163
            assert datum['text'] == 'Décès'
164

  
165

  
166
def teardown_module(module):
167
    # remove test/inputs from fs
168
    shutil.rmtree(os.path.join(CITYWEB_TEST_BASE_DIR, 'test', 'inputs'), ignore_errors=True)
0
-