Projet

Général

Profil

0003-plone_restapi-add-endpoint-to-get-content-type-57904.patch

Nicolas Roche, 16 octobre 2021 22:45

Télécharger (23,9 ko)

Voir les différences:

Subject: [PATCH 3/5] plone_restapi: add endpoint to get content type (#57904)

 passerelle/apps/plone_restapi/models.py       |  12 +
 .../data/plone_restapi/get_content_type.json  | 692 ++++++++++++++++++
 tests/test_plone_restapi.py                   |  17 +
 3 files changed, 721 insertions(+)
 create mode 100644 tests/data/plone_restapi/get_content_type.json
passerelle/apps/plone_restapi/models.py
208 208
    )
209 209
    def get_content_types(self, request):
210 210
        response = self.request(uri='@types', method='GET')
211 211
        for record in response or []:
212 212
            self.adapt_record(record, '{{ title }}', id_key='PLONE_id')
213 213
            record['id'] = record['id'].split('/')[-1]
214 214
        return {'data': response or []}
215 215

  
216
    @endpoint(
217
        perm='can_access',
218
        description=_('Get content type'),
219
        parameters={
220
            'id': {'description': _('Content type identifier'), 'example_value': 'imio.directory.Contact'}
221
        },
222
        display_order=2,
223
    )
224
    def get_content_type(self, request, id):
225
        response = self.request(uri='@types', uid=id, method='GET')
226
        return {'data': response}
227

  
216 228
    @endpoint(
217 229
        perm='can_access',
218 230
        description=_('Fetch'),
219 231
        parameters={
220 232
            'uri': {'description': _('Uri')},
221 233
            'uid': {'description': _('Uid')},
222 234
            'text_template': {'description': _('Text template')},
223 235
        },
tests/data/plone_restapi/get_content_type.json
1
{
2
  "fieldsets": [
3
    {
4
      "behavior": "plone",
5
      "fields": [
6
        "title",
7
        "description",
8
        "type",
9
        "subtitle",
10
        "logo",
11
        "image",
12
        "image_caption",
13
        "geolocation"
14
      ],
15
      "id": "default",
16
      "title": "G\u00e9n\u00e9ral"
17
    },
18
    {
19
      "behavior": "plone",
20
      "fields": [
21
        "street",
22
        "number",
23
        "complement",
24
        "zipcode",
25
        "city",
26
        "country"
27
      ],
28
      "id": "address",
29
      "title": "Adresse"
30
    },
31
    {
32
      "behavior": "plone",
33
      "fields": [
34
        "vat_number",
35
        "phones",
36
        "mails",
37
        "urls"
38
      ],
39
      "id": "contact_informations",
40
      "title": "Coordonn\u00e9es"
41
    },
42
    {
43
      "behavior": "plone.dexterity.schema.generated",
44
      "fields": [
45
        "selected_entities",
46
        "facilities",
47
        "taxonomy_contact_category",
48
        "topics",
49
        "iam",
50
        "subjects",
51
        "language"
52
      ],
53
      "id": "categorization",
54
      "title": "Cat\u00e9gorisation"
55
    },
56
    {
57
      "behavior": "plone",
58
      "fields": [
59
        "schedule",
60
        "multi_schedule"
61
      ],
62
      "id": "multischedule",
63
      "title": "Horaire multiple"
64
    },
65
    {
66
      "behavior": "plone",
67
      "fields": [
68
        "exceptional_closure"
69
      ],
70
      "id": "exceptionalclosure",
71
      "title": "Fermeture exceptionnelle"
72
    }
73
  ],
74
  "layouts": [
75
    "view"
76
  ],
77
  "properties": {
78
    "city": {
79
      "behavior": "imio.directory.core.contents.contact.content.IContact",
80
      "description": "",
81
      "factory": "Text line (String)",
82
      "title": "Commune",
83
      "type": "string"
84
    },
85
    "complement": {
86
      "behavior": "imio.directory.core.contents.contact.content.IContact",
87
      "description": "",
88
      "factory": "Text line (String)",
89
      "title": "Compl\u00e9ment",
90
      "type": "string"
91
    },
92
    "country": {
93
      "behavior": "imio.directory.core.contents.contact.content.IContact",
94
      "description": "",
95
      "factory": "Choice",
96
      "title": "Pays",
97
      "type": "string",
98
      "vocabulary": {
99
        "@id": "https://annuaire.preprod.imio.be/@vocabularies/imio.smartweb.vocabulary.Countries"
100
      }
101
    },
102
    "description": {
103
      "behavior": "plone.basic",
104
      "description": "Utilis\u00e9 dans les pages listant des \u00e9l\u00e9ments et les pages de r\u00e9sultats de recherche.",
105
      "factory": "Text",
106
      "maxLength": 700,
107
      "title": "Description",
108
      "type": "string",
109
      "widget": "textarea"
110
    },
111
    "exceptional_closure": {
112
      "additionalItems": true,
113
      "behavior": "collective.schedulefield.behavior.IExceptionalClosureContent",
114
      "description": "",
115
      "factory": "Collection",
116
      "items": {
117
        "description": "",
118
        "factory": "File",
119
        "properties": {
120
          "ExceptionalClosure.date": {
121
            "description": "",
122
            "factory": "Date",
123
            "title": "Date",
124
            "type": "string",
125
            "widget": "date"
126
          },
127
          "ExceptionalClosure.title": {
128
            "description": "",
129
            "factory": "Text",
130
            "title": "Titre",
131
            "type": "string",
132
            "widget": "textarea"
133
          }
134
        },
135
        "title": "",
136
        "type": "object"
137
      },
138
      "title": "Dates",
139
      "type": "array",
140
      "uniqueItems": false
141
    },
142
    "facilities": {
143
      "additionalItems": true,
144
      "behavior": "imio.directory.core.contents.contact.content.IContact",
145
      "description": "Important! Ces cat\u00e9gories permettent de mettre en avant et de g\u00e9olocaliser certains services de base",
146
      "factory": "List",
147
      "items": {
148
        "description": "",
149
        "factory": "Choice",
150
        "title": "",
151
        "type": "string",
152
        "vocabulary": {
153
          "@id": "https://annuaire.preprod.imio.be/@vocabularies/imio.directory.vocabulary.Facilities"
154
        }
155
      },
156
      "title": "Facilit\u00e9s",
157
      "type": "array",
158
      "uniqueItems": true
159
    },
160
    "geolocation": {
161
      "behavior": "geolocatable",
162
      "description": "Cliquez sur la carte pour s\u00e9lectionner une localisation, ou utilisez le champ texte pour rechercher par adresse.",
163
      "factory": "File",
164
      "properties": {
165
        "geolocation.latitude": {
166
          "description": "",
167
          "factory": "Floating-point number",
168
          "title": "Latitude",
169
          "type": "number"
170
        },
171
        "geolocation.longitude": {
172
          "description": "",
173
          "factory": "Floating-point number",
174
          "title": "Longitude",
175
          "type": "number"
176
        }
177
      },
178
      "title": "G\u00e9olocalisation",
179
      "type": "object"
180
    },
181
    "iam": {
182
      "additionalItems": true,
183
      "behavior": "imio.smartweb.iam",
184
      "description": "Important! Ces cat\u00e9gories sont utilis\u00e9es pour cr\u00e9er des listes accessibles via le menu navigation",
185
      "factory": "List",
186
      "items": {
187
        "description": "",
188
        "factory": "Choice",
189
        "title": "",
190
        "type": "string",
191
        "vocabulary": {
192
          "@id": "https://annuaire.preprod.imio.be/@vocabularies/imio.smartweb.vocabulary.IAm"
193
        }
194
      },
195
      "title": "Je suis",
196
      "type": "array",
197
      "uniqueItems": true
198
    },
199
    "image": {
200
      "behavior": "plone.leadimage",
201
      "description": "",
202
      "factory": "Image",
203
      "properties": {
204
        "image.contentType": {
205
          "default": "",
206
          "description": "The content type identifies the type of data.",
207
          "factory": "Text line (String)",
208
          "title": "Content Type",
209
          "type": "string"
210
        },
211
        "image.data": {
212
          "default": "",
213
          "description": "The actual content of the object.",
214
          "factory": "Text line (String)",
215
          "title": "Data",
216
          "type": "string"
217
        },
218
        "image.filename": {
219
          "description": "",
220
          "factory": "Text line (String)",
221
          "title": "Filename",
222
          "type": "string"
223
        }
224
      },
225
      "title": "Image principale",
226
      "type": "object"
227
    },
228
    "image_caption": {
229
      "behavior": "plone.leadimage",
230
      "description": "",
231
      "factory": "Text line (String)",
232
      "title": "L\u00e9gende de l'image principale",
233
      "type": "string"
234
    },
235
    "language": {
236
      "behavior": "plone.categorization",
237
      "default": "fr",
238
      "description": "",
239
      "factory": "Choice",
240
      "title": "Langue",
241
      "type": "string",
242
      "vocabulary": {
243
        "@id": "https://annuaire.preprod.imio.be/@vocabularies/plone.app.vocabularies.SupportedContentLanguages"
244
      }
245
    },
246
    "logo": {
247
      "behavior": "imio.directory.core.contents.contact.content.IContact",
248
      "description": "",
249
      "factory": "Image",
250
      "properties": {
251
        "logo.contentType": {
252
          "default": "",
253
          "description": "The content type identifies the type of data.",
254
          "factory": "Text line (String)",
255
          "title": "Content Type",
256
          "type": "string"
257
        },
258
        "logo.data": {
259
          "default": "",
260
          "description": "The actual content of the object.",
261
          "factory": "Text line (String)",
262
          "title": "Data",
263
          "type": "string"
264
        },
265
        "logo.filename": {
266
          "description": "",
267
          "factory": "Text line (String)",
268
          "title": "Filename",
269
          "type": "string"
270
        }
271
      },
272
      "title": "Logo",
273
      "type": "object"
274
    },
275
    "mails": {
276
      "additionalItems": true,
277
      "behavior": "imio.directory.core.contents.contact.content.IContact",
278
      "description": "",
279
      "factory": "List",
280
      "items": {
281
        "description": "",
282
        "factory": "File",
283
        "properties": {
284
          "label": {
285
            "description": "",
286
            "factory": "Text line (String)",
287
            "title": "Intitul\u00e9 (Secr\u00e9tariat, Bureau de la direction, Ventes, ...)",
288
            "type": "string"
289
          },
290
          "mail_address": {
291
            "description": "",
292
            "factory": "Email",
293
            "title": "Adresse e-mail",
294
            "type": "string",
295
            "widget": "email"
296
          },
297
          "type": {
298
            "description": "",
299
            "factory": "Choice",
300
            "title": "Type",
301
            "type": "string",
302
            "vocabulary": {
303
              "@id": "https://annuaire.preprod.imio.be/@vocabularies/imio.directory.vocabulary.MailTypes"
304
            }
305
          }
306
        },
307
        "title": "Value",
308
        "type": "object"
309
      },
310
      "title": "E-mails",
311
      "type": "array",
312
      "uniqueItems": false
313
    },
314
    "multi_schedule": {
315
      "additionalItems": true,
316
      "behavior": "collective.schedulefield.behavior.IMultiScheduledContent",
317
      "description": "",
318
      "factory": "Collection",
319
      "items": {
320
        "description": "",
321
        "factory": "File",
322
        "properties": {
323
          "MultiSchedule.dates": {
324
            "additionalItems": true,
325
            "description": "",
326
            "factory": "List",
327
            "items": {
328
              "description": "",
329
              "factory": "File",
330
              "properties": {
331
                "DateRange.end_date": {
332
                  "description": "",
333
                  "factory": "Date",
334
                  "title": "Date de fin",
335
                  "type": "string",
336
                  "widget": "date"
337
                },
338
                "DateRange.start_date": {
339
                  "description": "",
340
                  "factory": "Date",
341
                  "title": "Date de d\u00e9but",
342
                  "type": "string",
343
                  "widget": "date"
344
                }
345
              },
346
              "title": "",
347
              "type": "object"
348
            },
349
            "title": "Dates",
350
            "type": "array",
351
            "uniqueItems": false
352
          },
353
          "MultiSchedule.schedule": {
354
            "description": "",
355
            "key_type": {
356
              "additional": {},
357
              "schema": {
358
                "description": "",
359
                "factory": "Text line (String)",
360
                "title": "",
361
                "type": "string"
362
              }
363
            },
364
            "title": "Horaire",
365
            "type": "dict",
366
            "value_type": {
367
              "additional": {
368
                "key_type": {
369
                  "additional": {},
370
                  "schema": {
371
                    "description": "",
372
                    "factory": "Text line (String)",
373
                    "title": "",
374
                    "type": "string"
375
                  }
376
                },
377
                "value_type": {
378
                  "additional": {},
379
                  "schema": {
380
                    "description": "",
381
                    "factory": "Text line (String)",
382
                    "title": "",
383
                    "type": "string"
384
                  }
385
                }
386
              },
387
              "schema": {
388
                "description": "",
389
                "key_type": {
390
                  "additional": {},
391
                  "schema": {
392
                    "description": "",
393
                    "factory": "Text line (String)",
394
                    "title": "",
395
                    "type": "string"
396
                  }
397
                },
398
                "title": "",
399
                "type": "dict",
400
                "value_type": {
401
                  "additional": {},
402
                  "schema": {
403
                    "description": "",
404
                    "factory": "Text line (String)",
405
                    "title": "",
406
                    "type": "string"
407
                  }
408
                }
409
              }
410
            }
411
          },
412
          "MultiSchedule.title": {
413
            "description": "",
414
            "factory": "Text",
415
            "title": "Titre",
416
            "type": "string",
417
            "widget": "textarea"
418
          }
419
        },
420
        "title": "",
421
        "type": "object"
422
      },
423
      "title": "Horaire multiple",
424
      "type": "array",
425
      "uniqueItems": false
426
    },
427
    "number": {
428
      "behavior": "imio.directory.core.contents.contact.content.IContact",
429
      "description": "",
430
      "factory": "Text line (String)",
431
      "title": "Num\u00e9ro",
432
      "type": "string"
433
    },
434
    "phones": {
435
      "additionalItems": true,
436
      "behavior": "imio.directory.core.contents.contact.content.IContact",
437
      "description": "",
438
      "factory": "List",
439
      "items": {
440
        "description": "",
441
        "factory": "File",
442
        "properties": {
443
          "label": {
444
            "description": "",
445
            "factory": "Text line (String)",
446
            "title": "Intitul\u00e9 (direction, num\u00e9ro principal, ...)",
447
            "type": "string"
448
          },
449
          "number": {
450
            "description": "",
451
            "factory": "Text line (String)",
452
            "title": "Num\u00e9ro (format: +32475010203)",
453
            "type": "string"
454
          },
455
          "type": {
456
            "description": "",
457
            "factory": "Choice",
458
            "title": "Type",
459
            "type": "string",
460
            "vocabulary": {
461
              "@id": "https://annuaire.preprod.imio.be/@vocabularies/imio.directory.vocabulary.PhoneTypes"
462
            }
463
          }
464
        },
465
        "title": "Value",
466
        "type": "object"
467
      },
468
      "title": "T\u00e9l\u00e9phones",
469
      "type": "array",
470
      "uniqueItems": false
471
    },
472
    "schedule": {
473
      "behavior": "collective.schedulefield.behavior.IMultiScheduledContent",
474
      "description": "",
475
      "key_type": {
476
        "additional": {},
477
        "schema": {
478
          "description": "",
479
          "factory": "Text line (String)",
480
          "title": "",
481
          "type": "string"
482
        }
483
      },
484
      "title": "Horaire",
485
      "type": "dict",
486
      "value_type": {
487
        "additional": {
488
          "key_type": {
489
            "additional": {},
490
            "schema": {
491
              "description": "",
492
              "factory": "Text line (String)",
493
              "title": "",
494
              "type": "string"
495
            }
496
          },
497
          "value_type": {
498
            "additional": {},
499
            "schema": {
500
              "description": "",
501
              "factory": "Text line (String)",
502
              "title": "",
503
              "type": "string"
504
            }
505
          }
506
        },
507
        "schema": {
508
          "description": "",
509
          "key_type": {
510
            "additional": {},
511
            "schema": {
512
              "description": "",
513
              "factory": "Text line (String)",
514
              "title": "",
515
              "type": "string"
516
            }
517
          },
518
          "title": "",
519
          "type": "dict",
520
          "value_type": {
521
            "additional": {},
522
            "schema": {
523
              "description": "",
524
              "factory": "Text line (String)",
525
              "title": "",
526
              "type": "string"
527
            }
528
          }
529
        }
530
      }
531
    },
532
    "selected_entities": {
533
      "additionalItems": true,
534
      "behavior": "imio.directory.core.contents.contact.content.IContact",
535
      "default": [],
536
      "description": "S\u00e9lectionnez les entit\u00e9s dans lesquelles ce contact sera affich\u00e9. L'entit\u00e9 courante sera toujours s\u00e9lectionn\u00e9e.",
537
      "factory": "List",
538
      "items": {
539
        "description": "",
540
        "factory": "Choice",
541
        "title": "",
542
        "type": "string",
543
        "vocabulary": {
544
          "@id": "https://annuaire.preprod.imio.be/@vocabularies/imio.directory.vocabulary.EntitiesUIDs"
545
        }
546
      },
547
      "title": "Entit\u00e9s concern\u00e9es",
548
      "type": "array",
549
      "uniqueItems": true
550
    },
551
    "street": {
552
      "behavior": "imio.directory.core.contents.contact.content.IContact",
553
      "description": "",
554
      "factory": "Text line (String)",
555
      "title": "Rue",
556
      "type": "string"
557
    },
558
    "subjects": {
559
      "additionalItems": true,
560
      "behavior": "plone.categorization",
561
      "description": "Les mots cl\u00e9s sont utilis\u00e9s couramment pour organiser le contenu de fa\u00e7on ad hoc.",
562
      "factory": "Tuple",
563
      "items": {
564
        "description": "",
565
        "factory": "Text line (String)",
566
        "title": "",
567
        "type": "string"
568
      },
569
      "title": "Mots cl\u00e9s",
570
      "type": "array",
571
      "uniqueItems": true,
572
      "widgetOptions": {
573
        "vocabulary": {
574
          "@id": "https://annuaire.preprod.imio.be/@vocabularies/plone.app.vocabularies.Keywords"
575
        }
576
      }
577
    },
578
    "subtitle": {
579
      "behavior": "imio.directory.core.contents.contact.content.IContact",
580
      "description": "",
581
      "factory": "Text line (String)",
582
      "title": "Sous-titre",
583
      "type": "string"
584
    },
585
    "taxonomy_contact_category": {
586
      "additionalItems": true,
587
      "behavior": "collective.taxonomy.generated.contact_category",
588
      "description": "Important! Ces cat\u00e9gories sont utilis\u00e9es pour am\u00e9liorer la recherche et filtrer les fiches dans l'annuaire",
589
      "factory": "List",
590
      "items": {
591
        "description": "",
592
        "factory": "Choice",
593
        "title": "",
594
        "type": "string",
595
        "vocabulary": {
596
          "@id": "https://annuaire.preprod.imio.be/@vocabularies/collective.taxonomy.contact_category"
597
        }
598
      },
599
      "title": "Cat\u00e9gorie",
600
      "type": "array",
601
      "uniqueItems": true
602
    },
603
    "title": {
604
      "behavior": "plone.basic",
605
      "description": "",
606
      "factory": "Text line (String)",
607
      "title": "Titre",
608
      "type": "string"
609
    },
610
    "topics": {
611
      "additionalItems": true,
612
      "behavior": "imio.smartweb.topics",
613
      "description": "Important! Les th\u00e9matiques sont utilis\u00e9es pour filtrer les r\u00e9sultats de la recherche et cr\u00e9er des listes",
614
      "factory": "List",
615
      "items": {
616
        "description": "",
617
        "factory": "Choice",
618
        "title": "",
619
        "type": "string",
620
        "vocabulary": {
621
          "@id": "https://annuaire.preprod.imio.be/@vocabularies/imio.smartweb.vocabulary.Topics"
622
        }
623
      },
624
      "title": "Th\u00e9matiques",
625
      "type": "array",
626
      "uniqueItems": true
627
    },
628
    "type": {
629
      "behavior": "imio.directory.core.contents.contact.content.IContact",
630
      "description": "",
631
      "factory": "Choice",
632
      "title": "Type",
633
      "type": "string",
634
      "vocabulary": {
635
        "@id": "https://annuaire.preprod.imio.be/@vocabularies/imio.directory.vocabulary.ContactTypes"
636
      }
637
    },
638
    "urls": {
639
      "additionalItems": true,
640
      "behavior": "imio.directory.core.contents.contact.content.IContact",
641
      "description": "",
642
      "factory": "List",
643
      "items": {
644
        "description": "",
645
        "factory": "File",
646
        "properties": {
647
          "type": {
648
            "description": "",
649
            "factory": "Choice",
650
            "title": "Type",
651
            "type": "string",
652
            "vocabulary": {
653
              "@id": "https://annuaire.preprod.imio.be/@vocabularies/imio.directory.vocabulary.SiteTypes"
654
            }
655
          },
656
          "url": {
657
            "description": "",
658
            "factory": "URL",
659
            "title": "URL",
660
            "type": "string",
661
            "widget": "url"
662
          }
663
        },
664
        "title": "Value",
665
        "type": "object"
666
      },
667
      "title": "URLs",
668
      "type": "array",
669
      "uniqueItems": false
670
    },
671
    "vat_number": {
672
      "behavior": "imio.directory.core.contents.contact.content.IContact",
673
      "description": "",
674
      "factory": "Text line (String)",
675
      "title": "Num\u00e9ro d'entreprise / TVA",
676
      "type": "string"
677
    },
678
    "zipcode": {
679
      "behavior": "imio.directory.core.contents.contact.content.IContact",
680
      "description": "",
681
      "factory": "Integer",
682
      "title": "Code postal",
683
      "type": "integer"
684
    }
685
  },
686
  "required": [
687
    "title",
688
    "type"
689
  ],
690
  "title": "Contact",
691
  "type": "object"
692
}
tests/test_plone_restapi.py
291 291
    with utils.mock_url(url=url, response=json_get_data('get_content_types')):
292 292
        resp = app.get(endpoint)
293 293
    assert not resp.json['err']
294 294
    assert len(resp.json['data']) == 10
295 295
    assert resp.json['data'][2]['id'] == 'imio.directory.Contact'
296 296
    assert resp.json['data'][2]['text'] == 'Contact'
297 297

  
298 298

  
299
def test_get_content_type(app, connector, token):
300
    endpoint = utils.generic_endpoint_url('plone-restapi', 'get_content_type', slug=connector.slug)
301
    assert endpoint == '/plone-restapi/my_connector/get_content_type'
302
    url = connector.service_url + '/@types/imio.directory.Contact'
303
    params = {'id': 'imio.directory.Contact'}
304
    with utils.mock_url(url=url, response=json_get_data('get_content_type')):
305
        resp = app.get(endpoint, params=params)
306
    assert not resp.json['err']
307
    assert resp.json['data']['title'] == 'Contact'
308
    assert resp.json['data']['required'] == ['title', 'type']
309
    assert len(resp.json['data']['properties']) == 28
310
    assert (
311
        resp.json['data']['properties']['topics']['items']['vocabulary']['@id']
312
        == 'https://annuaire.preprod.imio.be/@vocabularies/imio.smartweb.vocabulary.Topics'
313
    )
314

  
315

  
299 316
def test_create(app, connector, token):
300 317
    endpoint = utils.generic_endpoint_url('plone-restapi', 'create', slug=connector.slug)
301 318
    assert endpoint == '/plone-restapi/my_connector/create'
302 319
    url = connector.service_url + '/braine-l-alleud'
303 320
    payload = {
304 321
        '@type': 'imio.directory.Contact',
305 322
        'title': "Test Entr'ouvert",
306 323
        'type': 'organization',
307
-