Projet

Général

Profil

0001-toulouse_maelis-parsifal-add-referentials-webservice.patch

Nicolas Roche, 13 juillet 2022 00:05

Télécharger (27,2 ko)

Voir les différences:

Subject: [PATCH 1/2] toulouse_maelis: parsifal: add referentials webservices
 (#67325)

 passerelle/contrib/toulouse_maelis/models.py  | 115 +++++++++++
 .../toulouse_maelis/R_read_category_list.xml  |  19 ++
 .../toulouse_maelis/R_read_civility_list.xml  |  15 ++
 .../data/toulouse_maelis/R_read_csp_list.xml  | 179 +++++++++++++++++
 .../toulouse_maelis/R_read_quality_list.xml   |  75 +++++++
 .../toulouse_maelis/R_read_situation_list.xml |  43 ++++
 tests/test_toulouse_maelis.py                 | 185 +++++++++++++++++-
 7 files changed, 630 insertions(+), 1 deletion(-)
 create mode 100644 tests/data/toulouse_maelis/R_read_category_list.xml
 create mode 100644 tests/data/toulouse_maelis/R_read_civility_list.xml
 create mode 100644 tests/data/toulouse_maelis/R_read_csp_list.xml
 create mode 100644 tests/data/toulouse_maelis/R_read_quality_list.xml
 create mode 100644 tests/data/toulouse_maelis/R_read_situation_list.xml
passerelle/contrib/toulouse_maelis/models.py
12 12
# GNU Affero General Public License for more details.
13 13
#
14 14
# You should have received a copy of the GNU Affero General Public License
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16

  
17 17
from urllib.parse import urljoin
18 18

  
19 19
import zeep
20
from django.core.cache import cache
20 21
from django.db import models
21 22
from django.utils.translation import ugettext_lazy as _
22 23
from zeep.helpers import serialize_object
23 24
from zeep.wsse.username import UsernameToken
24 25

  
25 26
from passerelle.base.models import BaseResource, HTTPResource
26 27
from passerelle.utils.api import endpoint
27 28
from passerelle.utils.jsonresponse import APIError
......
63 64
            return method(**kwargs)
64 65
        except zeep.exceptions.Fault as e:
65 66
            raise APIError(e.message, err_code='%s-%s-%s' % (wsdl_short_name, service, e.code))
66 67

  
67 68
    def check_status(self):
68 69
        assert self.call('Family', 'isWSRunning')
69 70
        assert self.call('Activity', 'isWSRunning')
70 71

  
72
    def get_referential(self, referential_name):
73

  
74
        # local referentials
75
        if referential_name == 'Complement':
76
            response = [
77
                {'id': 'B', 'text': 'bis'},
78
                {'id': 'T', 'text': 'ter'},
79
                {'id': 'Q', 'text': 'quater'},
80
            ]
81
            return {'list': response, 'dict': {x['id']: x['text'] for x in response}}
82

  
83
        # remote referentials
84
        cache_key = 'maelis-%s-%s' % (self.pk, referential_name)
85
        data = cache.get(cache_key)
86
        if data is None:
87
            response = self.call('Family', 'read' + referential_name + 'List')
88
            data = {
89
                'list': [{'id': x.code, 'text': x.libelle} for x in response],
90
                'dict': {x.code: x.libelle for x in response},
91
            }
92
            # put in cache for two hours
93
            cache.set(cache_key, data, 3600 * 2)
94
        return data
95

  
96
    def get_referential_value(self, referential_name, key):
97
        try:
98
            return self.get_referential(referential_name)['dict'][key]
99
        except KeyError:
100
            # Maelis DB not properly configurated
101
            self.logger.warning("No '%s' key into Maelis '%s' referential", key, referential_name)
102
            return key
103

  
71 104
    def get_link(self, NameID):
72 105
        try:
73 106
            return self.link_set.get(name_id=NameID)
74 107
        except Link.DoesNotExist:
75 108
            raise APIError('User not linked to family', err_code='not-linked')
76 109

  
77 110
    def get_family(self, family_id):
78 111
        response = self.call('Family', 'readFamily', dossierNumber=family_id)
79 112
        data = serialize_object(response)
113

  
114
        def add_text_value(referential_name, data, keys):
115
            last_key = keys.pop()
116
            for key in keys:
117
                if not isinstance(data, dict) or not key in data:
118
                    return
119
                data = data[key]
120
            if isinstance(data, dict) and last_key in data and data[last_key] is not None:
121
                data[last_key + '_text'] = self.get_referential_value(referential_name, data[last_key])
122

  
123
        # add text from referentials
124
        add_text_value('Category', data, ['category'])
125
        add_text_value('Situation', data, ['situation'])
126
        for rlg in 'RL1', 'RL2':
127
            add_text_value('Civility', data, [rlg, 'civility'])
128
            add_text_value('Quality', data, [rlg, 'quality'])
129
            add_text_value('Complement', data, [rlg, 'adresse', 'numComp'])
130
            add_text_value('CSP', data, [rlg, 'profession', 'codeCSP'])
80 131
        return data
81 132

  
133
    @endpoint(
134
        display_category=_('Family'),
135
        description='Liste des catégories',
136
        name='read-category-list',
137
        perm='can_access',
138
    )
139
    def read_category_list(self, request):
140
        return {'data': self.get_referential('Category')['list']}
141

  
142
    @endpoint(
143
        display_category=_('Family'),
144
        description='Liste des civilités',
145
        name='read-civility-list',
146
        perm='can_access',
147
    )
148
    def read_civility_list(self, request):
149
        return {'data': self.get_referential('Civility')['list']}
150

  
151
    @endpoint(
152
        display_category=_('Family'),
153
        description='Liste des compléments du numéro de voie',
154
        name='read-complement-list',
155
        perm='can_access',
156
    )
157
    def read_complement_list(self, request):
158
        return {'data': self.get_referential('Complement')['list']}
159

  
160
    @endpoint(
161
        display_category=_('Family'),
162
        description='liste des catégories socio-professionnelles',
163
        name='read-csp-list',
164
        perm='can_access',
165
    )
166
    def read_csp_list(self, request):
167
        data = self.get_referential('CSP')['list']
168

  
169
        # remove redundant codes
170
        uniq_text = set()
171
        uniq_data = []
172
        for item in data:
173
            item['text'] = item['text'].strip()
174
            if item['text'] not in uniq_text:
175
                uniq_data.append(item)
176
                uniq_text.add(item['text'])
177
        return {'data': uniq_data}
178

  
179
    @endpoint(
180
        display_category=_('Family'),
181
        description='liste des qualités du référenciel',
182
        name='read-quality-list',
183
        perm='can_access',
184
    )
185
    def read_quality_list(self, request):
186
        return {'data': self.get_referential('Quality')['list']}
187

  
188
    @endpoint(
189
        display_category=_('Family'),
190
        description='liste des situations',
191
        name='read-situation-list',
192
        perm='can_access',
193
    )
194
    def read_situation_list(self, request):
195
        return {'data': self.get_referential('Situation')['list']}
196

  
82 197
    @endpoint(
83 198
        display_category=_('Family'),
84 199
        description=_('Create link between user and family'),
85 200
        perm='can_access',
86 201
        parameters={'NameID': {'description': _('Publik ID')}},
87 202
        post={'request_body': {'schema': {'application/json': schemas.LINK_SCHEMA}}},
88 203
    )
89 204
    def link(self, request, NameID, post_data):
tests/data/toulouse_maelis/R_read_category_list.xml
1
<?xml version="1.0"?>
2
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
3
  <soap:Body>
4
    <ns2:readCategoryListResponse xmlns:ns2="family.ws.maelis.sigec.com">
5
      <itemList>
6
        <code>BI</code>
7
        <libelle>BIPARENTALE</libelle>
8
      </itemList>
9
      <itemList>
10
        <code>ACCEUI</code>
11
        <libelle>FAMILLE D'ACCUEIL</libelle>
12
      </itemList>
13
      <itemList>
14
        <code>MONO</code>
15
        <libelle>MONOPARENTALE</libelle>
16
      </itemList>
17
    </ns2:readCategoryListResponse>
18
  </soap:Body>
19
</soap:Envelope>
tests/data/toulouse_maelis/R_read_civility_list.xml
1
<?xml version="1.0" encoding="utf-8"?>
2
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
3
  <soap:Body>
4
    <ns2:readCivilityListResponse xmlns:ns2="family.ws.maelis.sigec.com">
5
      <itemList>
6
        <code>MME</code>
7
        <libelle>Madame</libelle>
8
      </itemList>
9
      <itemList>
10
        <code>M.</code>
11
        <libelle>Monsieur</libelle>
12
      </itemList>
13
    </ns2:readCivilityListResponse>
14
  </soap:Body>
15
</soap:Envelope>
tests/data/toulouse_maelis/R_read_csp_list.xml
1
<?xml version="1.0" encoding="utf-8"?>
2
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
3
  <soap:Body>
4
    <ns2:readCSPListResponse xmlns:ns2="family.ws.maelis.sigec.com">
5
      <itemList>
6
        <code>14</code>
7
        <libelle>AGENT DE MAITRISE</libelle>
8
      </itemList>
9
      <itemList>
10
        <code>1</code>
11
        <libelle>AGRICULTEUR</libelle>
12
      </itemList>
13
      <itemList>
14
        <code>AGR</code>
15
        <libelle>AGRICULTEUR</libelle>
16
      </itemList>
17
      <itemList>
18
        <code>ARTI</code>
19
        <libelle>ARTISAN</libelle>
20
      </itemList>
21
      <itemList>
22
        <code>ART</code>
23
        <libelle>ARTISAN</libelle>
24
      </itemList>
25
      <itemList>
26
        <code>2</code>
27
        <libelle>ARTISAN-COMMERCANT</libelle>
28
      </itemList>
29
      <itemList>
30
        <code>15</code>
31
        <libelle>AUTRES</libelle>
32
      </itemList>
33
      <itemList>
34
        <code>CADR</code>
35
        <libelle>CADRE</libelle>
36
      </itemList>
37
      <itemList>
38
        <code>4</code>
39
        <libelle>CADRE</libelle>
40
      </itemList>
41
      <itemList>
42
        <code>13</code>
43
        <libelle>CADRE SUPERIEUR</libelle>
44
      </itemList>
45
      <itemList>
46
        <code>3</code>
47
        <libelle>CHEF D'ENTREPRISE</libelle>
48
      </itemList>
49
      <itemList>
50
        <code>CHOM</code>
51
        <libelle>CHOMEUR</libelle>
52
      </itemList>
53
      <itemList>
54
        <code>COM</code>
55
        <libelle>COMMERCANT</libelle>
56
      </itemList>
57
      <itemList>
58
        <code>COMM</code>
59
        <libelle>COMMERCANT</libelle>
60
      </itemList>
61
      <itemList>
62
        <code>7</code>
63
        <libelle>COMMERCANT</libelle>
64
      </itemList>
65
      <itemList>
66
        <code>10</code>
67
        <libelle>DEMANDEUR D'EMPLOI</libelle>
68
      </itemList>
69
      <itemList>
70
        <code>DIV</code>
71
        <libelle>DIVERS</libelle>
72
      </itemList>
73
      <itemList>
74
        <code>EMP</code>
75
        <libelle>EMPLOYE</libelle>
76
      </itemList>
77
      <itemList>
78
        <code>5</code>
79
        <libelle>EMPLOYE</libelle>
80
      </itemList>
81
      <itemList>
82
        <code>ENS</code>
83
        <libelle>ENSEIGNANT</libelle>
84
      </itemList>
85
      <itemList>
86
        <code>EN</code>
87
        <libelle>ENSEIGNANT</libelle>
88
      </itemList>
89
      <itemList>
90
        <code>17</code>
91
        <libelle>ENSEIGNANT</libelle>
92
      </itemList>
93
      <itemList>
94
        <code>ETU</code>
95
        <libelle>ETUDIANT</libelle>
96
      </itemList>
97
      <itemList>
98
        <code>8</code>
99
        <libelle>ETUDIANT</libelle>
100
      </itemList>
101
      <itemList>
102
        <code>11</code>
103
        <libelle>FONCTIONNAIRE</libelle>
104
      </itemList>
105
      <itemList>
106
        <code>FONC</code>
107
        <libelle>FONCTIONNAIRE</libelle>
108
      </itemList>
109
      <itemList>
110
        <code>FONCT</code>
111
        <libelle>FONCTIONNAIRE </libelle>
112
      </itemList>
113
      <itemList>
114
        <code>MAIR</code>
115
        <libelle>MAIRIE DE NICE</libelle>
116
      </itemList>
117
      <itemList>
118
        <code>OUV</code>
119
        <libelle>OUVRIER</libelle>
120
      </itemList>
121
      <itemList>
122
        <code>6</code>
123
        <libelle>OUVRIER</libelle>
124
      </itemList>
125
      <itemList>
126
        <code>PERENS</code>
127
        <libelle>PERISCO ENSEIGNANT</libelle>
128
      </itemList>
129
      <itemList>
130
        <code>PEREXT</code>
131
        <libelle>PERISCO EXTERNE</libelle>
132
      </itemList>
133
      <itemList>
134
        <code>PERMAI</code>
135
        <libelle>PERISCO MAIRIE DE NICE</libelle>
136
      </itemList>
137
      <itemList>
138
        <code>PERANI</code>
139
        <libelle>PERISCO S.ANIMATION</libelle>
140
      </itemList>
141
      <itemList>
142
        <code>9</code>
143
        <libelle>PROFESSION LIBERALE</libelle>
144
      </itemList>
145
      <itemList>
146
        <code>LIB</code>
147
        <libelle>PROFESSION LIBERALE</libelle>
148
      </itemList>
149
      <itemList>
150
        <code>12</code>
151
        <libelle>RETRAITE</libelle>
152
      </itemList>
153
      <itemList>
154
        <code>RET</code>
155
        <libelle>RETRAITE</libelle>
156
      </itemList>
157
      <itemList>
158
        <code>RMI</code>
159
        <libelle>REVENU MINIMUM D'INSERTION</libelle>
160
      </itemList>
161
      <itemList>
162
        <code>16</code>
163
        <libelle>SANS PROFESSION</libelle>
164
      </itemList>
165
      <itemList>
166
        <code>SANPRO</code>
167
        <libelle>SANS PROFESSION</libelle>
168
      </itemList>
169
      <itemList>
170
        <code>SANS</code>
171
        <libelle>SANS PROFESSION</libelle>
172
      </itemList>
173
      <itemList>
174
        <code>SEC</code>
175
        <libelle>SECRETAIRE</libelle>
176
      </itemList>
177
    </ns2:readCSPListResponse>
178
  </soap:Body>
179
</soap:Envelope>
tests/data/toulouse_maelis/R_read_quality_list.xml
1
<?xml version="1.0" encoding="utf-8"?>
2
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
3
  <soap:Body>
4
    <ns2:readQualityListResponse xmlns:ns2="family.ws.maelis.sigec.com">
5
      <itemList>
6
        <code>AU</code>
7
        <libelle>AUTRE</libelle>
8
      </itemList>
9
      <itemList>
10
        <code>BP</code>
11
        <libelle>BEAU PERE</libelle>
12
      </itemList>
13
      <itemList>
14
        <code>BM</code>
15
        <libelle>BELLE MERE</libelle>
16
      </itemList>
17
      <itemList>
18
        <code>CONSO</code>
19
        <libelle>CONSOMMATEUR</libelle>
20
      </itemList>
21
      <itemList>
22
        <code>EN</code>
23
        <libelle>ENFANT</libelle>
24
      </itemList>
25
      <itemList>
26
        <code>FS</code>
27
        <libelle>FRERES ET SOEURS</libelle>
28
      </itemList>
29
      <itemList>
30
        <code>GM</code>
31
        <libelle>GRAND MERE MATERNELLE</libelle>
32
      </itemList>
33
      <itemList>
34
        <code>GP</code>
35
        <libelle>GRAND PERE MATERNEL</libelle>
36
      </itemList>
37
      <itemList>
38
        <code>GMP</code>
39
        <libelle>GRAND-MERE PATERNELLE</libelle>
40
      </itemList>
41
      <itemList>
42
        <code>GPP</code>
43
        <libelle>GRAND-PERE PATERNEL</libelle>
44
      </itemList>
45
      <itemList>
46
        <code>MAIRIE</code>
47
        <libelle>MAIRIE</libelle>
48
      </itemList>
49
      <itemList>
50
        <code>MERE</code>
51
        <libelle>MERE</libelle>
52
      </itemList>
53
      <itemList>
54
        <code>O</code>
55
        <libelle>ONCLE</libelle>
56
      </itemList>
57
      <itemList>
58
        <code>OS</code>
59
        <libelle>ORGANISME SOCIAL</libelle>
60
      </itemList>
61
      <itemList>
62
        <code>PERE</code>
63
        <libelle>PERE</libelle>
64
      </itemList>
65
      <itemList>
66
        <code>T</code>
67
        <libelle>TANTE</libelle>
68
      </itemList>
69
      <itemList>
70
        <code>TUTEUR</code>
71
        <libelle>TUTEUR</libelle>
72
      </itemList>
73
    </ns2:readQualityListResponse>
74
  </soap:Body>
75
</soap:Envelope>
tests/data/toulouse_maelis/R_read_situation_list.xml
1
<?xml version="1.0" encoding="utf-8"?>
2
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
3
  <soap:Body>
4
    <ns2:readSituationListResponse xmlns:ns2="family.ws.maelis.sigec.com">
5
      <itemList>
6
        <code>C</code>
7
        <libelle>Célibataire</libelle>
8
      </itemList>
9
      <itemList>
10
        <code>D</code>
11
        <libelle>Divorcé (e)</libelle>
12
      </itemList>
13
      <itemList>
14
        <code>CS</code>
15
        <libelle>EN COURS DE SEPARATION</libelle>
16
      </itemList>
17
      <itemList>
18
        <code>M</code>
19
        <libelle>Marié (e)</libelle>
20
      </itemList>
21
      <itemList>
22
        <code>P</code>
23
        <libelle>Pacsé (e)</libelle>
24
      </itemList>
25
      <itemList>
26
        <code>S</code>
27
        <libelle>Séparé (e)</libelle>
28
      </itemList>
29
      <itemList>
30
        <code>UL</code>
31
        <libelle>UNION LIBRE</libelle>
32
      </itemList>
33
      <itemList>
34
        <code>V</code>
35
        <libelle>Veuf (ve)</libelle>
36
      </itemList>
37
      <itemList>
38
        <code>VM</code>
39
        <libelle>Vivant maritalement</libelle>
40
      </itemList>
41
    </ns2:readSituationListResponse>
42
  </soap:Body>
43
</soap:Envelope>
tests/test_toulouse_maelis.py
9 9
# This program is distributed in the hope that it will be useful,
10 10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 12
# GNU Affero General Public License for more details.
13 13
#
14 14
# You should have received a copy of the GNU Affero General Public License
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16

  
17
import logging
17 18
import os
18 19

  
19 20
import mock
20 21
import pytest
21 22
from requests.exceptions import ConnectionError
22 23

  
23 24
from passerelle.contrib.toulouse_maelis.models import Link, ToulouseMaelis
24 25
from passerelle.utils.jsonresponse import APIError
......
35 36

  
36 37
CONNECTION_ERROR = ConnectionError('No address associated with hostname')
37 38
FAMILY_SERVICE_WSDL = FakedResponse(content=get_xml_file('FamilyService.wsdl'), status_code=200)
38 39
ACTIVITY_SERVICE_WSDL = FakedResponse(content=get_xml_file('ActivityService.wsdl'), status_code=200)
39 40
FAILED_AUTH = FakedResponse(content=get_xml_file('R_failed_authentication.xml'), status_code=500)
40 41
ISWSRUNNING_TRUE = FakedResponse(content=get_xml_file('R_is_ws_running.xml') % b'true', status_code=200)
41 42
ISWSRUNNING_FALSE = FakedResponse(content=get_xml_file('R_is_ws_running.xml') % b'false', status_code=200)
42 43
READ_FAMILY = FakedResponse(content=get_xml_file('R_read_family.xml'), status_code=200)
44
READ_CATEGORIES = FakedResponse(content=get_xml_file('R_read_category_list.xml'), status_code=200)
45
READ_CIVILITIES = FakedResponse(content=get_xml_file('R_read_civility_list.xml'), status_code=200)
46
READ_CSP = FakedResponse(content=get_xml_file('R_read_csp_list.xml'), status_code=200)
47
READ_QUALITIES = FakedResponse(content=get_xml_file('R_read_quality_list.xml'), status_code=200)
48
READ_SITUATIONS = FakedResponse(content=get_xml_file('R_read_situation_list.xml'), status_code=200)
43 49

  
44 50

  
45 51
def get_endpoint(name):
46 52
    url = generic_endpoint_url('toulouse-maelis', name)
47 53
    assert url == '/toulouse-maelis/test/%s' % name
48 54
    return url
49 55

  
50 56

  
......
155 161
    assert resp.json['err'] == 0
156 162
    assert resp.json['data'] == 'ok'
157 163

  
158 164
    resp = app.post_json(url + '?NameID=local')
159 165
    assert resp.json['err'] == 'not-linked'
160 166
    assert resp.json['err_desc'] == 'User not linked to family'
161 167

  
162 168

  
169
@mock.patch('passerelle.utils.Request.get')
170
@mock.patch('passerelle.utils.Request.post')
171
def test_get_referential_using_cache(mocked_post, mocked_get, con, freezer):
172
    mocked_get.return_value = FAMILY_SERVICE_WSDL
173
    mocked_post.return_value = READ_CATEGORIES
174

  
175
    freezer.move_to('2021-11-10 00:00')
176
    con.get_referential('Category')
177
    assert mocked_post.call_count == 1
178

  
179
    con.get_referential('Category')
180
    assert mocked_post.call_count == 1
181

  
182
    freezer.move_to('2021-11-10 02:00')
183
    con.get_referential('Category')
184
    assert mocked_post.call_count == 2
185

  
186

  
187
@mock.patch('passerelle.utils.Request.get')
188
@mock.patch('passerelle.utils.Request.post')
189
def test_get_referential_value(mocked_post, mocked_get, con):
190
    mocked_get.return_value = FAMILY_SERVICE_WSDL
191
    mocked_post.return_value = READ_CSP
192

  
193
    assert con.get_referential_value('CSP', '1') == 'AGRICULTEUR'
194
    assert con.get_referential_value('CSP', 'AGR') == 'AGRICULTEUR'
195

  
196

  
197
@mock.patch('passerelle.utils.Request.get')
198
@mock.patch('passerelle.utils.Request.post')
199
def test_get_referential_value_not_found(mocked_post, mocked_get, con, caplog):
200
    mocked_get.return_value = FAMILY_SERVICE_WSDL
201
    mocked_post.return_value = READ_CIVILITIES
202

  
203
    assert con.get_referential_value('Civility', 'MR') == 'MR'
204
    assert len(caplog.records) == 1
205
    assert caplog.records[0].levelno == logging.WARNING
206
    assert caplog.records[0].message == "No 'MR' key into Maelis 'Civility' referential"
207

  
208

  
209
@mock.patch('passerelle.utils.Request.get')
210
@mock.patch('passerelle.utils.Request.post')
211
def test_read_category_list(mocked_post, mocked_get, con, app):
212
    mocked_get.return_value = FAMILY_SERVICE_WSDL
213
    mocked_post.return_value = READ_CATEGORIES
214
    url = get_endpoint('read-category-list')
215

  
216
    resp = app.get(url)
217
    assert resp.json['err'] == 0
218
    assert resp.json['data'] == [
219
        {'id': 'BI', 'text': 'BIPARENTALE'},
220
        {'id': 'ACCEUI', 'text': "FAMILLE D'ACCUEIL"},
221
        {'id': 'MONO', 'text': 'MONOPARENTALE'},
222
    ]
223

  
224

  
225
@mock.patch('passerelle.utils.Request.get')
226
@mock.patch('passerelle.utils.Request.post')
227
def test_read_civility_list(mocked_post, mocked_get, con, app):
228
    mocked_get.return_value = FAMILY_SERVICE_WSDL
229
    mocked_post.return_value = READ_CIVILITIES
230
    url = get_endpoint('read-civility-list')
231

  
232
    resp = app.get(url)
233
    assert resp.json['err'] == 0
234
    assert resp.json['data'] == [
235
        {"id": "MME", "text": "Madame"},
236
        {"id": "M.", "text": "Monsieur"},
237
    ]
238

  
239

  
240
def test_read_complement_list(con, app):
241
    url = get_endpoint('read-complement-list')
242

  
243
    resp = app.get(url)
244
    assert resp.json['err'] == 0
245
    assert resp.json['data'] == [
246
        {'id': 'B', 'text': 'bis'},
247
        {'id': 'T', 'text': 'ter'},
248
        {'id': 'Q', 'text': 'quater'},
249
    ]
250

  
251

  
252
@mock.patch('passerelle.utils.Request.get')
253
@mock.patch('passerelle.utils.Request.post')
254
def test_read_csp_list(mocked_post, mocked_get, con, app):
255
    mocked_get.return_value = FAMILY_SERVICE_WSDL
256
    mocked_post.return_value = READ_CSP
257
    url = get_endpoint('read-csp-list')
258

  
259
    resp = app.get(url)
260
    assert resp.json['err'] == 0
261
    assert resp.json['data'] == [
262
        {'id': '14', 'text': 'AGENT DE MAITRISE'},
263
        {'id': '1', 'text': 'AGRICULTEUR'},
264
        {'id': 'ARTI', 'text': 'ARTISAN'},
265
        {'id': '2', 'text': 'ARTISAN-COMMERCANT'},
266
        {'id': '15', 'text': 'AUTRES'},
267
        {'id': 'CADR', 'text': 'CADRE'},
268
        {'id': '13', 'text': 'CADRE SUPERIEUR'},
269
        {'id': '3', 'text': "CHEF D'ENTREPRISE"},
270
        {'id': 'CHOM', 'text': 'CHOMEUR'},
271
        {'id': 'COM', 'text': 'COMMERCANT'},
272
        {'id': '10', 'text': "DEMANDEUR D'EMPLOI"},
273
        {'id': 'DIV', 'text': 'DIVERS'},
274
        {'id': 'EMP', 'text': 'EMPLOYE'},
275
        {'id': 'ENS', 'text': 'ENSEIGNANT'},
276
        {'id': 'ETU', 'text': 'ETUDIANT'},
277
        {'id': '11', 'text': 'FONCTIONNAIRE'},
278
        {'id': 'MAIR', 'text': 'MAIRIE DE NICE'},
279
        {'id': 'OUV', 'text': 'OUVRIER'},
280
        {'id': 'PERENS', 'text': 'PERISCO ENSEIGNANT'},
281
        {'id': 'PEREXT', 'text': 'PERISCO EXTERNE'},
282
        {'id': 'PERMAI', 'text': 'PERISCO MAIRIE DE NICE'},
283
        {'id': 'PERANI', 'text': 'PERISCO S.ANIMATION'},
284
        {'id': '9', 'text': 'PROFESSION LIBERALE'},
285
        {'id': '12', 'text': 'RETRAITE'},
286
        {'id': 'RMI', 'text': "REVENU MINIMUM D'INSERTION"},
287
        {'id': '16', 'text': 'SANS PROFESSION'},
288
        {'id': 'SEC', 'text': 'SECRETAIRE'},
289
    ]
290

  
291

  
292
@mock.patch('passerelle.utils.Request.get')
293
@mock.patch('passerelle.utils.Request.post')
294
def test_read_quality_list(mocked_post, mocked_get, con, app):
295
    mocked_get.return_value = FAMILY_SERVICE_WSDL
296
    mocked_post.return_value = READ_QUALITIES
297
    url = get_endpoint('read-quality-list')
298

  
299
    resp = app.get(url)
300
    assert resp.json['err'] == 0
301
    assert resp.json['data'] == [
302
        {'id': 'AU', 'text': 'AUTRE'},
303
        {'id': 'BP', 'text': 'BEAU PERE'},
304
        {'id': 'BM', 'text': 'BELLE MERE'},
305
        {'id': 'CONSO', 'text': 'CONSOMMATEUR'},
306
        {'id': 'EN', 'text': 'ENFANT'},
307
        {'id': 'FS', 'text': 'FRERES ET SOEURS'},
308
        {'id': 'GM', 'text': 'GRAND MERE MATERNELLE'},
309
        {'id': 'GP', 'text': 'GRAND PERE MATERNEL'},
310
        {'id': 'GMP', 'text': 'GRAND-MERE PATERNELLE'},
311
        {'id': 'GPP', 'text': 'GRAND-PERE PATERNEL'},
312
        {'id': 'MAIRIE', 'text': 'MAIRIE'},
313
        {'id': 'MERE', 'text': 'MERE'},
314
        {'id': 'O', 'text': 'ONCLE'},
315
        {'id': 'OS', 'text': 'ORGANISME SOCIAL'},
316
        {'id': 'PERE', 'text': 'PERE'},
317
        {'id': 'T', 'text': 'TANTE'},
318
        {'id': 'TUTEUR', 'text': 'TUTEUR'},
319
    ]
320

  
321

  
322
@mock.patch('passerelle.utils.Request.get')
323
@mock.patch('passerelle.utils.Request.post')
324
def test_read_situation_list(mocked_post, mocked_get, con, app):
325
    mocked_get.return_value = FAMILY_SERVICE_WSDL
326
    mocked_post.return_value = READ_SITUATIONS
327
    url = get_endpoint('read-situation-list')
328

  
329
    resp = app.get(url)
330
    assert resp.json['err'] == 0
331
    assert resp.json['data'] == [
332
        {'id': 'C', 'text': 'Célibataire'},
333
        {'id': 'D', 'text': 'Divorcé (e)'},
334
        {'id': 'CS', 'text': 'EN COURS DE SEPARATION'},
335
        {'id': 'M', 'text': 'Marié (e)'},
336
        {'id': 'P', 'text': 'Pacsé (e)'},
337
        {'id': 'S', 'text': 'Séparé (e)'},
338
        {'id': 'UL', 'text': 'UNION LIBRE'},
339
        {'id': 'V', 'text': 'Veuf (ve)'},
340
        {'id': 'VM', 'text': 'Vivant maritalement'},
341
    ]
342

  
343

  
163 344
@mock.patch('passerelle.utils.Request.get')
164 345
@mock.patch('passerelle.utils.Request.post')
165 346
def test_read_family(mocked_post, mocked_get, con, app):
166 347
    mocked_get.return_value = FAMILY_SERVICE_WSDL
167
    mocked_post.side_effect = [READ_FAMILY]
348
    mocked_post.side_effect = [READ_FAMILY, READ_CATEGORIES, READ_SITUATIONS, READ_CIVILITIES, READ_QUALITIES]
168 349
    url = get_endpoint('read-family')
169 350
    Link.objects.create(resource=con, family_id='1312', name_id='local')
170 351

  
171 352
    resp = app.get(url + '?NameID=local')
172 353
    assert resp.json['err'] == 0
173 354
    assert resp.json['data']['RL1'] == {
174 355
        'num': '613878',
175 356
        'lastname': 'COSTANZE',
176 357
        'firstname': 'DAMIEN',
177 358
        'quality': 'PERE',
359
        'quality_text': 'PERE',
178 360
        'civility': 'M.',
361
        'civility_text': 'Monsieur',
179 362
        'dateBirth': '1980-10-07T00:00:00+01:00',
180 363
        'adresse': {
181 364
            'idStreet': 'AV0044',
182 365
            'num': 9,
183 366
            'numComp': None,
184 367
            'street1': 'AVENUE VALDILETTA',
185 368
            'street2': 'LES MANDARINIERS',
186 369
            'town': 'NICE',
187
-