Projet

Général

Profil

0002-api-expose-card-relations-in-schema-58448.patch

Lauréline Guérin, 26 novembre 2021 15:19

Télécharger (11,9 ko)

Voir les différences:

Subject: [PATCH 2/2] api: expose card relations in schema (#58448)

 tests/api/test_carddef.py | 205 ++++++++++++++++++++++++++++++++++++++
 wcs/formdef.py            |  34 +++++++
 2 files changed, 239 insertions(+)
tests/api/test_carddef.py
13 13
from wcs import fields, qommon
14 14
from wcs.api_access import ApiAccess
15 15
from wcs.api_utils import sign_url
16
from wcs.blocks import BlockDef
16 17
from wcs.carddef import CardDef
17 18
from wcs.categories import CardDefCategory
18 19
from wcs.data_sources import NamedDataSource
20
from wcs.formdef import FormDef
19 21
from wcs.qommon.afterjobs import AfterJob
20 22
from wcs.qommon.http_request import HTTPRequest
21 23
from wcs.qommon.upload_storage import PicklableUpload
......
222 224
    resp = get_app(pub).get('/api/cards/test/@schema', status=403)
223 225

  
224 226

  
227
def test_carddef_schema_relations(pub):
228
    FormDef.wipe()
229
    CardDef.wipe()
230
    BlockDef.wipe()
231

  
232
    formdef = FormDef()
233
    formdef.name = 'formdef'
234
    formdef.fields = [
235
        fields.ItemField(
236
            id='0', label='unknown', type='item', varname='unknown', data_source={'type': 'carddef:unknown'}
237
        ),
238
        fields.ItemField(id='1', label='card1', type='item', data_source={'type': 'carddef:carddef-1'}),
239
        fields.ItemField(
240
            id='2', label='card2', type='item', varname='card2', data_source={'type': 'carddef:carddef-2'}
241
        ),
242
        fields.ItemsField(id='3', label='cards1', type='items', data_source={'type': 'carddef:carddef-1'}),
243
        fields.ItemsField(
244
            id='4', label='cards2', type='items', varname='cards2', data_source={'type': 'carddef:carddef-2'}
245
        ),
246
        fields.ComputedField(
247
            id='5',
248
            label='computed card2',
249
            type='computed',
250
            varname='computed_card2',
251
            data_source={'type': 'carddef:carddef-2'},
252
        ),
253
    ]
254
    formdef.store()
255

  
256
    carddef1 = CardDef()
257
    carddef1.name = 'carddef 1'
258
    carddef1.fields = [
259
        fields.ItemField(
260
            id='0', label='unknown', type='item', varname='unknown', data_source={'type': 'carddef:unknown'}
261
        ),
262
        fields.ItemField(
263
            id='1', label='card2', type='item', varname='card2', data_source={'type': 'carddef:carddef-2'}
264
        ),
265
        fields.ItemField(
266
            id='2', label='card3', type='item', data_source={'type': 'carddef:carddef-3'}
267
        ),  # no varname
268
        fields.ItemsField(
269
            id='3', label='cards2', type='items', varname='cards2', data_source={'type': 'carddef:carddef-2'}
270
        ),
271
        fields.ItemsField(
272
            id='4', label='cards3', type='items', data_source={'type': 'carddef:carddef-3'}
273
        ),  # no varname
274
        fields.ComputedField(
275
            id='5',
276
            label='computed card2',
277
            type='computed',
278
            varname='computed_card2',
279
            data_source={'type': 'carddef:carddef-2'},
280
        ),
281
    ]
282
    carddef1.store()
283

  
284
    carddef2 = CardDef()
285
    carddef2.name = 'carddef 2'
286
    carddef2.store()
287

  
288
    carddef3 = CardDef()
289
    carddef3.name = 'carddef 3'
290
    carddef3.fields = [
291
        # no varnames
292
        fields.ItemField(id='1', label='card2', type='item', data_source={'type': 'carddef:carddef-2'}),
293
        fields.ItemsField(id='2', label='cards2', type='items', data_source={'type': 'carddef:carddef-2'}),
294
    ]
295
    carddef3.store()
296

  
297
    resp = get_app(pub).get(sign_uri('/api/cards/carddef-1/@schema'), status=200)
298
    assert resp.json['relations'] == [
299
        {'varname': 'card2', 'type': 'item', 'obj': 'carddef:carddef-2', 'reverse': False},
300
        {'varname': 'cards2', 'type': 'items', 'obj': 'carddef:carddef-2', 'reverse': False},
301
        {'varname': 'computed_card2', 'type': 'computed', 'obj': 'carddef:carddef-2', 'reverse': False},
302
    ]
303
    resp = get_app(pub).get(sign_uri('/api/cards/carddef-2/@schema'), status=200)
304
    assert resp.json['relations'] == [
305
        {'varname': 'card2', 'type': 'item', 'obj': 'carddef:carddef-1', 'reverse': True},
306
        {'varname': 'cards2', 'type': 'items', 'obj': 'carddef:carddef-1', 'reverse': True},
307
        {'varname': 'computed_card2', 'type': 'computed', 'obj': 'carddef:carddef-1', 'reverse': True},
308
    ]
309

  
310
    # custom views ?
311
    carddef1.fields[1] = fields.ItemField(
312
        id='1', label='card2', type='item', varname='card2', data_source={'type': 'carddef:carddef-2:view'}
313
    )
314
    carddef1.store()
315
    resp = get_app(pub).get(sign_uri('/api/cards/carddef-1/@schema'), status=200)
316
    assert resp.json['relations'] == [
317
        {'varname': 'card2', 'type': 'item', 'obj': 'carddef:carddef-2', 'reverse': False},
318
        {'varname': 'cards2', 'type': 'items', 'obj': 'carddef:carddef-2', 'reverse': False},
319
        {'varname': 'computed_card2', 'type': 'computed', 'obj': 'carddef:carddef-2', 'reverse': False},
320
    ]
321
    resp = get_app(pub).get(sign_uri('/api/cards/carddef-2/@schema'), status=200)
322
    assert resp.json['relations'] == [
323
        {'varname': 'card2', 'type': 'item', 'obj': 'carddef:carddef-1', 'reverse': True},
324
        {'varname': 'cards2', 'type': 'items', 'obj': 'carddef:carddef-1', 'reverse': True},
325
        {'varname': 'computed_card2', 'type': 'computed', 'obj': 'carddef:carddef-1', 'reverse': True},
326
    ]
327

  
328
    # circular relation ?
329
    carddef1.fields = [
330
        fields.ItemField(
331
            id='1', label='card1', type='item', varname='card1', data_source={'type': 'carddef:carddef-1'}
332
        ),
333
    ]
334
    carddef1.store()
335
    resp = get_app(pub).get(sign_uri('/api/cards/carddef-1/@schema'), status=200)
336
    assert resp.json['relations'] == [
337
        {'varname': 'card1', 'type': 'item', 'obj': 'carddef:carddef-1', 'reverse': False},
338
        {'varname': 'card1', 'type': 'item', 'obj': 'carddef:carddef-1', 'reverse': True},
339
    ]
340
    resp = get_app(pub).get(sign_uri('/api/cards/carddef-2/@schema'), status=200)
341
    assert resp.json['relations'] == []
342

  
343
    # block field
344
    block1 = BlockDef()
345
    block1.name = 'block 1'
346
    block1.fields = [
347
        fields.ItemField(
348
            id='0', label='unknown', type='item', varname='unknown', data_source={'type': 'carddef:unknown'}
349
        ),
350
        fields.ItemField(
351
            id='1',
352
            label='card1',
353
            type='item',
354
            varname='card1',
355
            data_source={'type': 'carddef:carddef-1'},
356
        ),
357
        fields.ItemField(
358
            id='2',
359
            label='card2',
360
            type='item',
361
            varname='card2',
362
            data_source={'type': 'carddef:carddef-2'},
363
        ),
364
        fields.ItemsField(
365
            id='3', label='cards1', type='items', varname='cards1', data_source={'type': 'carddef:carddef-1'}
366
        ),
367
        fields.ItemsField(
368
            id='4', label='cards2', type='items', varname='cards2', data_source={'type': 'carddef:carddef-2'}
369
        ),
370
        fields.ComputedField(
371
            id='5',
372
            label='computed card1',
373
            type='computed',
374
            varname='computed_card1',
375
            data_source={'type': 'carddef:carddef-1'},
376
        ),
377
        fields.ComputedField(
378
            id='6',
379
            label='computed card2',
380
            type='computed',
381
            varname='computed_card2',
382
            data_source={'type': 'carddef:carddef-2'},
383
        ),
384
    ]
385
    block1.store()
386

  
387
    # no varname on block field
388
    carddef1.fields = [fields.BlockField(id='1', label='block', type='block:%s' % block1.slug)]
389
    carddef1.store()
390
    resp = get_app(pub).get(sign_uri('/api/cards/carddef-1/@schema'), status=200)
391
    assert resp.json['relations'] == []
392
    resp = get_app(pub).get(sign_uri('/api/cards/carddef-2/@schema'), status=200)
393
    assert resp.json['relations'] == []
394

  
395
    # with varname
396
    carddef1.fields = [
397
        fields.BlockField(id='1', label='block', varname='block1', type='block:%s' % block1.slug)
398
    ]
399
    carddef1.store()
400
    resp = get_app(pub).get(sign_uri('/api/cards/carddef-1/@schema'), status=200)
401
    assert resp.json['relations'] == [
402
        {'varname': 'block1_card1', 'type': 'item', 'obj': 'carddef:carddef-1', 'reverse': False},
403
        {'varname': 'block1_card1', 'type': 'item', 'obj': 'carddef:carddef-1', 'reverse': True},
404
        {'varname': 'block1_card2', 'type': 'item', 'obj': 'carddef:carddef-2', 'reverse': False},
405
        {'varname': 'block1_cards1', 'type': 'items', 'obj': 'carddef:carddef-1', 'reverse': False},
406
        {'varname': 'block1_cards1', 'type': 'items', 'obj': 'carddef:carddef-1', 'reverse': True},
407
        {'varname': 'block1_cards2', 'type': 'items', 'obj': 'carddef:carddef-2', 'reverse': False},
408
        {
409
            'varname': 'block1_computed_card1',
410
            'type': 'computed',
411
            'obj': 'carddef:carddef-1',
412
            'reverse': False,
413
        },
414
        {'varname': 'block1_computed_card1', 'type': 'computed', 'obj': 'carddef:carddef-1', 'reverse': True},
415
        {
416
            'varname': 'block1_computed_card2',
417
            'type': 'computed',
418
            'obj': 'carddef:carddef-2',
419
            'reverse': False,
420
        },
421
    ]
422
    resp = get_app(pub).get(sign_uri('/api/cards/carddef-2/@schema'), status=200)
423
    assert resp.json['relations'] == [
424
        {'varname': 'block1_card2', 'type': 'item', 'obj': 'carddef:carddef-1', 'reverse': True},
425
        {'varname': 'block1_cards2', 'type': 'items', 'obj': 'carddef:carddef-1', 'reverse': True},
426
        {'varname': 'block1_computed_card2', 'type': 'computed', 'obj': 'carddef:carddef-1', 'reverse': True},
427
    ]
428

  
429

  
225 430
@pytest.mark.parametrize('auth', ['signature', 'http-basic'])
226 431
def test_cards_import_csv(pub, local_user, auth):
227 432
    pub.role_class.wipe()
wcs/formdef.py
949 949
        return d
950 950

  
951 951
    def export_to_json(self, include_id=False, indent=None):
952
        from wcs.carddef import CardDef
953

  
952 954
        charset = get_publisher().site_charset
953 955
        root = {}
954 956
        root['name'] = force_text(self.name, charset)
......
993 995
        if self.required_authentication_contexts:
994 996
            root['required_authentication_contexts'] = self.required_authentication_contexts[:]
995 997

  
998
        if isinstance(self, CardDef):
999
            card_relations = []
1000
            for objdef, relations in self.build_relations_by_ref().items():
1001
                if not objdef.startswith('carddef:'):
1002
                    continue
1003
                try:
1004
                    CardDef.get_by_urlname(objdef.split(':')[1])
1005
                except KeyError:
1006
                    continue
1007
                for relation in relations:
1008
                    if not relation['varname']:
1009
                        continue
1010
                    card_relations.append(
1011
                        {
1012
                            'varname': relation['varname'],
1013
                            'type': relation['type'],
1014
                            'obj': objdef,
1015
                            'reverse': False,
1016
                        }
1017
                    )
1018

  
1019
            for relation in self.reverse_relations or []:
1020
                if not relation['obj'].startswith('carddef:'):
1021
                    continue
1022
                if not relation['varname']:
1023
                    continue
1024
                rel = relation.copy()
1025
                rel.update({'reverse': True})
1026
                card_relations.append(rel)
1027

  
1028
            root['relations'] = sorted(card_relations, key=itemgetter('varname'))
1029

  
996 1030
        return json.dumps(root, indent=indent, sort_keys=True, cls=JSONEncoder)
997 1031

  
998 1032
    @classmethod
999
-