Projet

Général

Profil

0001-add-civil-status-common-api-16768.patch

Josué Kouka, 01 août 2017 10:42

Télécharger (6,6 ko)

Voir les différences:

Subject: [PATCH] add civil status common api (#16768)

 passerelle/civilstatus/__init__.py | 65 +++++++++++++++++++++++++++++++++
 passerelle/contrib/mdel/models.py  |  3 +-
 tests/test_civilstatus.py          | 73 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 140 insertions(+), 1 deletion(-)
 create mode 100644 passerelle/civilstatus/__init__.py
 create mode 100644 tests/test_civilstatus.py
passerelle/civilstatus/__init__.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 copy of the GNU Affero General Public License
16
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
import json
18

  
19
from django.utils.translation import ugettext_lazy as _
20

  
21
from passerelle.utils.api import endpoint
22
from passerelle.utils.jsonresponse import APIError
23

  
24

  
25
# Dict of mandatory keys and their expected values
26

  
27
MANDATORY_DATA = {
28
    'application_id': None,
29
    'application_time': None,
30
    'certificate_type': ('birth', 'mariage', 'death', 'other'),
31
    'document_type': ('full', 'multilingual', 'with-filiation', 'without-filiation'),
32
    'applicant_lastname': None,
33
    'applicant_firstnames': None,
34
    'concerned_lastname': None,
35
    'concerned_firstnames': None,
36
}
37

  
38

  
39
class CivilStatusMixin(object):
40

  
41
    category = _('Civil Status')
42

  
43
    def check_keys(self, formdata):
44
        for key in MANDATORY_DATA:
45
            if (key not in formdata):
46
                raise APIError('<%s> is required.' % key)
47
            expected_values = MANDATORY_DATA[key]
48
            if expected_values and formdata[key] not in expected_values:
49
                raise APIError('<%s> value must be one of %s' % (key, expected_values))
50

  
51
    def create_demand(self, formdata, *args, **kwargs):
52
        raise NotImplementedError
53

  
54
    def get_status(self, demand_id, **kwargs):
55
        raise NotImplementedError
56

  
57
    @endpoint(perm='can_access', methods=['post'])
58
    def create(self, request, *args, **kwargs):
59
        formdata = json.loads(request.body)
60
        self.check_keys(formdata)
61
        return self.create_demand(formdata, *args, **kwargs)
62

  
63
    @endpoint(perm='can_access', methods=['get'])
64
    def status(self, request, demand_id, **kwargs):
65
        return self.get_status(demand_id)
passerelle/contrib/mdel/models.py
23 23
from django.db import models
24 24
from django.utils.translation import ugettext_lazy as _
25 25

  
26
from passerelle.civilstatus import CivilStatusMixin
26 27
from passerelle.base.models import BaseResource
27 28
from passerelle.utils.api import endpoint
28 29
from passerelle.utils.jsonresponse import APIError
......
67 68
    {'id': 'EXTRAIT-PLURILINGUE', 'text': 'Extrait plurilingue'}]
68 69

  
69 70

  
70
class MDEL(BaseResource):
71
class MDEL(CivilStatusMixin, BaseResource):
71 72
    """Connector converting Publik's Demand into
72 73
    MDEL (XML based format) Demand.
73 74
    It's able to manage demand such as :
tests/test_civilstatus.py
1
# -*- coding: utf-8 -*-
2
import json
3
import mock
4
import pytest
5

  
6
from passerelle.civilstatus import CivilStatusMixin, MANDATORY_DATA
7
from passerelle.utils.jsonresponse import APIError
8

  
9
from django.test import RequestFactory
10

  
11

  
12
C_DEMAND = {'demand_id': '123-NAIS-0'}
13
S_DEMAND = {'closed': True, 'status': 'rejected'}
14

  
15

  
16
def build_post_request(data):
17
    request = RequestFactory()
18
    return request.post('/', content_type='application/json',
19
                        data=json.dumps(data))
20

  
21

  
22
@pytest.fixture
23
def base_payload():
24
    return {
25
        "application_id": "123",
26
        "application_time": "2017-06-11T10:30:25",
27
        "certificate_type_label": "Acte de Naissance",
28
        "certificate_type": "birth",
29
        "document_type_label": "Copie Intégrale",
30
        "document_type": "full",
31
        "applicant_firstnames": "Johhny Jumper",
32
        "applicant_lastname": "Doe",
33
        "concerned_firstnames": "Johnny Jumper",
34
        "concerned_lastname": "Dalton",
35
        "concerned_birthdate": "1980-07-07",
36
        "concerned_birthcity": "Nantes",
37
        "concerned_birthcountry": "France",
38
    }
39

  
40

  
41
@pytest.fixture(params=MANDATORY_DATA)
42
def case(request, base_payload):
43
    base_payload.pop(request.param)
44
    return request.param, base_payload
45

  
46

  
47
def test_civilstatus_mixin_missing_keys(app, case):
48
    missing_key, payload = case
49
    mixin = CivilStatusMixin()
50
    with pytest.raises(APIError) as exc:
51
        mixin.create(build_post_request(payload))
52

  
53
    assert exc.value.message == '<%s> is required.' % missing_key
54

  
55

  
56
@mock.patch('passerelle.civilstatus.CivilStatusMixin.create_demand',
57
            side_effect=lambda x: C_DEMAND)
58
@mock.patch('passerelle.civilstatus.CivilStatusMixin.get_status',
59
            side_effect=lambda x: S_DEMAND)
60
def test_civilstatus_mixin_expected_keys(mock_cvs_status, mock_cvs_create, app, base_payload):
61
    base_payload['certificate_type'] = 'whatever'
62
    mixin = CivilStatusMixin()
63
    with pytest.raises(APIError) as exc:
64
        mixin.create(build_post_request(base_payload))
65

  
66
    assert exc.value.message == "<certificate_type> value must be one of ('birth', 'mariage', 'death', 'other')"
67
    base_payload['certificate_type'] = 'birth'
68
    request = build_post_request(base_payload)
69
    resp_json = mixin.create(request)
70
    assert resp_json['demand_id'] == '123-NAIS-0'
71
    resp_json = mixin.status(request, '123-NAIS-0')
72
    assert resp_json['status'] == 'rejected'
73
    assert resp_json['closed'] is True
0
-