Projet

Général

Profil

0002-toulouse_smart-add-get-intervention-endpoint-55230.patch

Nicolas Roche, 02 août 2021 16:18

Télécharger (7,4 ko)

Voir les différences:

Subject: [PATCH 2/7] toulouse_smart: add get-intervention endpoint (#55230)

 passerelle/contrib/toulouse_smart/models.py   | 29 ++++++++++
 .../data/toulouse_smart/get_intervention.json | 54 +++++++++++++++++++
 tests/test_toulouse_smart.py                  | 43 ++++++++++++++-
 3 files changed, 125 insertions(+), 1 deletion(-)
 create mode 100644 tests/data/toulouse_smart/get_intervention.json
passerelle/contrib/toulouse_smart/models.py
17 17
import datetime
18 18

  
19 19
import lxml.etree as ET
20 20
from django.contrib.postgres.fields import JSONField
21 21
from django.db import models
22 22
from django.utils.text import slugify
23 23
from django.utils.timezone import now
24 24
from django.utils.translation import ugettext_lazy as _
25
from requests import RequestException
25 26

  
26 27
from passerelle.base.models import BaseResource, HTTPResource
27 28
from passerelle.utils import xml
28 29
from passerelle.utils.api import endpoint
30
from passerelle.utils.jsonresponse import APIError
29 31

  
30 32

  
31 33
class ToulouseSmartResource(BaseResource, HTTPResource):
32 34
    category = _('Business Process Connectors')
33 35

  
34 36
    webservice_base_url = models.URLField(_('Webservice Base URL'))
35 37

  
36 38
    log_requests_errors = False
......
102 104
                    {
103 105
                        'id': '',
104 106
                        'text': _('Service is unavailable'),
105 107
                        'disabled': True,
106 108
                    }
107 109
                ]
108 110
            }
109 111

  
112
    def request(self, url, json=None):
113
        headers = {'Accept': 'application/json'}
114
        if json:
115
            headers['Content-Type'] = 'application/json'
116
            response = self.requests.post(url, headers=headers, json=json)
117
        else:
118
            response = self.requests.get(url, headers=headers)
119
        try:
120
            response.raise_for_status()
121
        except RequestException as e:
122
            raise APIError('failed to %s %s: %s' % ('post' if json else 'get', url, e))
123
        return response
124

  
125
    @endpoint(
126
        name='get-intervention',
127
        methods=['get'],
128
        description=_('Retrieve an intervention'),
129
        perm='can_access',
130
        parameters={
131
            'id': {'description': _('Intervention identifier')},
132
        },
133
    )
134
    def get_intervention(self, request, id):
135
        url = self.webservice_base_url + 'v1/intervention/%s' % id
136
        response = self.request(url)
137
        return {'data': response.json()}
138

  
110 139

  
111 140
class Cache(models.Model):
112 141
    resource = models.ForeignKey(
113 142
        verbose_name=_('Resource'),
114 143
        to=ToulouseSmartResource,
115 144
        on_delete=models.CASCADE,
116 145
        related_name='cache_entries',
117 146
    )
tests/data/toulouse_smart/get_intervention.json
1
{
2
  "id": "3f0558bd-7d85-49a8-97e4-d07bc7f8dc9b",
3
  "name": "DI-20210731-0103",
4
  "description": "Justice nul part",
5
  "geom": {
6
    "type": "Point",
7
    "coordinates": [
8
      2.1431744096480547,
9
      48.69856386916798
10
    ],
11
    "crs": "EPSG:3943"
12
  },
13
  "interventionData": {},
14
  "safeguardRequired": false,
15
  "media": null,
16
  "safeguardDone": null,
17
  "interventionCreated": "2021-07-30T22:44:38.748Z",
18
  "interventionDesired": "2021-07-31T00:40:03Z",
19
  "interventionDone": null,
20
  "submitter": {
21
    "id": null,
22
    "lastName": "",
23
    "firstName": "admin",
24
    "mail": "admin@localhost",
25
    "furtherInformation": null,
26
    "phoneNumber": "0699999999",
27
    "address": ""
28
  },
29
  "submitterType": "usager",
30
  "organizations": [
31
    {
32
      "id": "f1378d8a-12bf-4c14-913f-22624b0ecab8",
33
      "name": "Direction des P\u00f4les"
34
    },
35
    {
36
      "id": "8ad4af63-70b5-416f-a75d-c510d83ce1bd",
37
      "name": "Transport Logistique"
38
    }
39
  ],
40
  "domain": null,
41
  "state": {
42
    "id": "e844e67f-5382-4c0f-94d8-56f618263485",
43
    "table": null,
44
    "stateLabel": "Nouveau",
45
    "closes": false
46
  },
47
  "interventionTypeId": "407ef8d6-9b8c-4187-be51-d89f24424768",
48
  "onPrivateLand": false,
49
  "duplicates": null,
50
  "external_number": "36-10",
51
  "external_status": "statut 1",
52
  "cityId": "12345",
53
  "address": "https://wcs.dev.publik.love/backoffice/management/smart/10/"
54
}
tests/test_toulouse_smart.py
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 17
import functools
18 18
import io
19
import os
19 20
import zipfile
20 21

  
21 22
import httmock
22 23
import lxml.etree as ET
23 24
import pytest
24 25
import utils
25 26
from test_manager import login
26 27

  
27 28
from passerelle.contrib.toulouse_smart.models import ToulouseSmartResource
28
from passerelle.utils.xml import to_json
29

  
30
TEST_BASE_DIR = os.path.join(os.path.dirname(__file__), 'data', 'toulouse_smart')
29 31

  
30 32

  
31 33
@pytest.fixture
32 34
def smart(db):
33 35
    return utils.make_resource(
34 36
        ToulouseSmartResource,
35 37
        title='Test',
36 38
        slug='test',
......
67 69
            with httmock.HTTMock(*handlers):
68 70
                return func(*args, **kwargs)
69 71

  
70 72
        return wrapper
71 73

  
72 74
    return decorator
73 75

  
74 76

  
77
def get_json_file(filename):
78
    with open(os.path.join(TEST_BASE_DIR, "%s.json" % filename)) as desc:
79
        return desc.read()
80

  
81

  
75 82
@mock_response(['/v1/type-intervention', b'<List></List>'])
76 83
def test_empty_intervention_types(smart):
77 84
    assert smart.get_intervention_types() == []
78 85

  
79 86

  
80 87
INTERVENTION_TYPES = '''<List>
81 88
   <item>
82 89
       <id>1234</id>
......
192 199
      <validation>
193 200
        <type>digits</type>
194 201
      </validation>
195 202
    </field>
196 203
  </fields>
197 204
</block>
198 205
'''
199 206
            )
207

  
208

  
209
@mock_response(
210
    ['/v1/intervention', get_json_file('get_intervention')],
211
)
212
def test_get_intervention(app, smart):
213
    resp = app.get(URL + 'get-intervention?id=3f0558bd-7d85-49a8-97e4-d07bc7f8dc9b')
214
    assert not resp.json['err']
215
    assert resp.json['data']['id'] == '3f0558bd-7d85-49a8-97e4-d07bc7f8dc9b'
216
    assert resp.json['data']['state'] == {
217
        'id': 'e844e67f-5382-4c0f-94d8-56f618263485',
218
        'table': None,
219
        'stateLabel': 'Nouveau',
220
        'closes': False,
221
    }
222

  
223

  
224
@mock_response(
225
    ['/v1/intervention', None, 500],
226
)
227
def test_get_intervention_error_status(app, smart):
228
    resp = app.get(URL + 'get-intervention?id=3f0558bd-7d85-49a8-97e4-d07bc7f8dc9b')
229
    assert resp.json['err']
230
    assert 'failed to get' in resp.json['err_desc']
231

  
232

  
233
@mock_response(
234
    ['/v1/intervention', None, 404],
235
)
236
def test_get_intervention_wrond_id(app, smart):
237
    resp = app.get(URL + 'get-intervention?id=3f0558bd-7d85-49a8-97e4-d07bc7f8dc9b')
238
    assert resp.json['err']
239
    assert 'failed to get' in resp.json['err_desc']
240
    assert '404' in resp.json['err_desc']
200
-