Projet

Général

Profil

0001-opendatasoft-manage-sort-parameter-54442.patch

Nicolas Roche, 19 juillet 2021 15:03

Télécharger (6,51 ko)

Voir les différences:

Subject: [PATCH] opendatasoft: manage sort parameter (#54442)

 passerelle/apps/opendatasoft/models.py | 21 ++++++++++++++++++---
 tests/test_opendatasoft.py             | 16 +++++++++++++---
 2 files changed, 31 insertions(+), 6 deletions(-)
passerelle/apps/opendatasoft/models.py
59 59
            Query.objects.filter(resource=instance).delete()
60 60
        for data_query in data_queries:
61 61
            query = Query.import_json(data_query)
62 62
            query.resource = instance
63 63
            queries.append(query)
64 64
        Query.objects.bulk_create(queries)
65 65
        return instance
66 66

  
67
    def call_search(self, dataset=None, text_template='', filter_expression='', id=None, q=None, limit=None):
67
    def call_search(
68
        self,
69
        dataset=None,
70
        text_template='',
71
        filter_expression='',
72
        id=None,
73
        q=None,
74
        limit=None,
75
        sort=None,
76
    ):
68 77
        scheme, netloc, path, params, query, fragment = urlparse.urlparse(self.service_url)
69 78
        path = urlparse.urljoin(path, 'api/records/1.0/search/')
70 79
        url = urlparse.urlunparse((scheme, netloc, path, params, query, fragment))
71 80

  
72 81
        if id is not None:
73 82
            query = 'recordid:%s' % id
74 83
        else:
75 84
            query = q
76 85
        params = {
77 86
            'dataset': dataset,
78 87
            'q': query,
79 88
        }
80 89
        if self.api_key:
81 90
            params.update({'apikey': self.api_key})
82 91
        if limit:
83 92
            params.update({'rows': limit})
93
        if sort:
94
            params.update({'sort': sort})
84 95
        params.update(urlparse.parse_qs(filter_expression))
85 96

  
86 97
        result_response = self.requests.get(url, params=params)
87 98
        err_desc = result_response.json().get('error')
88 99
        if err_desc:
89 100
            raise APIError(err_desc, http_status=200)
90 101

  
91 102
        result = []
......
105 116
        perm='can_access',
106 117
        description=_('Search'),
107 118
        parameters={
108 119
            'dataset': {'description': _('Dataset')},
109 120
            'text_template': {'description': _('Text template')},
110 121
            'id': {'description': _('Record identifier')},
111 122
            'q': {'description': _('Full text query')},
112 123
            'limit': {'description': _('Maximum items')},
124
            'sort': {'description': _('Sort field')},
113 125
        },
114 126
    )
115
    def search(self, request, dataset=None, text_template='', id=None, q=None, limit=None, **kwargs):
116
        result = self.call_search(dataset, text_template, '', id, q, limit)
127
    def search(
128
        self, request, dataset=None, text_template='', id=None, q=None, limit=None, sort=None, **kwargs
129
    ):
130
        result = self.call_search(dataset, text_template, '', id, q, limit, sort)
117 131
        return {'data': result}
118 132

  
119 133
    @endpoint(
120 134
        name='q',
121 135
        description=_('Query'),
122 136
        pattern=r'^(?P<query_slug>[\w:_-]+)/$',
123 137
        perm='can_access',
124 138
        show=False,
......
162 176
            dataset=self.dataset,
163 177
            text_template=self.text_template,
164 178
            filter_expression='&'.join(
165 179
                [x.strip() for x in str(self.filter_expression).splitlines() if x.strip()]
166 180
            ),
167 181
            id=kwargs.get('id'),
168 182
            q=kwargs.get('q'),
169 183
            limit=kwargs.get('limit'),
184
            sort=kwargs.get('sort'),
170 185
        )
171 186

  
172 187
    def as_endpoint(self):
173 188
        endpoint = super(Query, self).as_endpoint(path=self.resource.q.endpoint_info.name)
174 189

  
175 190
        search_endpoint = self.resource.search.endpoint_info
176 191
        endpoint.func = search_endpoint.func
177 192
        endpoint.show_undocumented_params = False
tests/test_opendatasoft.py
192 192
def test_search_using_q(mocked_get, app, connector):
193 193
    endpoint = utils.generic_endpoint_url('opendatasoft', 'search', slug=connector.slug)
194 194
    assert endpoint == '/opendatasoft/my_connector/search'
195 195
    params = {
196 196
        'dataset': 'referentiel-adresse-test',
197 197
        'text_template': '{{numero}} {{nom_rue}} {{nom_commun}}',
198 198
        'q': "rue de l'aubepine",
199 199
        'limit': 3,
200
        'sort': '-nom_rue',
200 201
    }
201 202
    mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT_Q_SEARCH, status_code=200)
202 203
    resp = app.get(endpoint, params=params, status=200)
204
    assert mocked_get.call_args[1]['params'] == {
205
        'apikey': 'my_secret',
206
        'dataset': 'referentiel-adresse-test',
207
        'q': "rue de l'aubepine",
208
        'rows': '3',
209
        'sort': '-nom_rue',
210
    }
203 211
    assert not resp.json['err']
204 212
    assert len(resp.json['data']) == 3
205 213
    # check order is kept
206 214
    assert [x['id'] for x in resp.json['data']] == [
207 215
        'e00cf6161e52a4c8fe510b2b74d4952036cb3473',
208 216
        '7cafcd5c692773e8b863587b2d38d6be82e023d8',
209 217
        '0984a5e1745701f71c91af73ce764e1f7132e0ff',
210 218
    ]
......
234 242

  
235 243

  
236 244
@mock.patch('passerelle.utils.Request.get')
237 245
def test_query_q_using_q(mocked_get, app, query):
238 246
    endpoint = '/opendatasoft/my_connector/q/my_query/'
239 247
    params = {
240 248
        'q': "rue de l'aubepine",
241 249
        'limit': 3,
250
        'sort': '-nom_rue',
242 251
    }
243 252
    mocked_get.return_value = utils.FakedResponse(content=FAKED_CONTENT_Q_SEARCH, status_code=200)
244 253
    resp = app.get(endpoint, params=params, status=200)
245 254
    assert mocked_get.call_args[1]['params'] == {
246
        'dataset': 'referentiel-adresse-test',
247
        'q': "rue de l'aubepine",
248 255
        'apikey': 'my_secret',
249
        'rows': '3',
256
        'dataset': 'referentiel-adresse-test',
250 257
        'refine.source': ['Ville et Eurométropole de Strasbourg'],
251 258
        'exclude.numero': ['42', '43'],
259
        'q': "rue de l'aubepine",
260
        'rows': '3',
261
        'sort': '-nom_rue',
252 262
    }
253 263
    assert not resp.json['err']
254 264
    assert len(resp.json['data']) == 3
255 265
    # check order is kept
256 266
    assert [x['id'] for x in resp.json['data']] == [
257 267
        'e00cf6161e52a4c8fe510b2b74d4952036cb3473',
258 268
        '7cafcd5c692773e8b863587b2d38d6be82e023d8',
259 269
        '0984a5e1745701f71c91af73ce764e1f7132e0ff',
260
-