Projet

Général

Profil

0001-generic-endpoint-define-optional-category-for-displa.patch

Lauréline Guérin, 05 mai 2020 14:38

Télécharger (5,81 ko)

Voir les différences:

Subject: [PATCH 1/2] generic endpoint: define optional category for display
 (#17729)

 passerelle/base/models.py                     |  5 +++-
 .../passerelle/manage/service_view.html       | 16 +++++++-----
 passerelle/utils/api.py                       | 17 +++++++++++--
 tests/test_generic_endpoint.py                | 25 +++++++++++++++++++
 4 files changed, 54 insertions(+), 9 deletions(-)
passerelle/base/models.py
132 132
    # permission descriptions
133 133
    _can_access_description = _('Access is limited to the following API users:')
134 134

  
135
    # category ordering for display
136
    _category_ordering = []
137

  
135 138
    class Meta:
136 139
        abstract = True
137 140

  
......
253 256
                    endpoint_info = copy.copy(method.endpoint_info)
254 257
                    endpoint_info.http_method = http_method
255 258
                    endpoints.append(endpoint_info)
256
        endpoints.sort(key=lambda x: (x.display_order or 99999999, x.name or '', x.pattern or ''))
259
        endpoints.sort(key=lambda x: (x.display_category_order, x.display_category, x.display_order or 99999999, x.name or '', x.pattern or ''))
257 260
        if hasattr(self, 'queries'):
258 261
            self.append_custom_queries(endpoints)
259 262
        return endpoints
passerelle/templates/passerelle/manage/service_view.html
62 62
  <div>
63 63
  {% if object.api_description %}<p>{{object.api_description|safe}}</p>{% endif %}
64 64
  {% block endpoints %}
65
    <ul class="endpoints">
66
    {% for endpoint in object.get_endpoints_infos %}
67
      {% if endpoint.show %}
68
        {% include "passerelle/manage/endpoint.html" with endpoint=endpoint %}
69
      {% endif %}
65
    {% regroup object.get_endpoints_infos by display_category as endpoints_groups %}
66
    {% for endpoints in endpoints_groups %}
67
      {% if endpoints.grouper %}<h4>{{ endpoints.grouper }}</h4>{% elif not forloop.first %}<h4>{% trans "Misc" %}</h4>{% endif %}
68
      <ul class="endpoints">
69
        {% for endpoint in endpoints.list %}
70
          {% if endpoint.show %}
71
            {% include "passerelle/manage/endpoint.html" with endpoint=endpoint %}
72
          {% endif %}
73
        {% endfor %}
74
      </ul>
70 75
    {% endfor %}
71
    </ul>
72 76
  {% endblock %}
73 77
  </div>
74 78
</div>
passerelle/utils/api.py
23 23
from django.utils.safestring import mark_safe
24 24

  
25 25
# make APIError available from this module
26
from .jsonresponse import APIError
26
from .jsonresponse import APIError  # noqa
27 27

  
28 28

  
29 29
class endpoint(object):
......
45 45
                 post=None,
46 46
                 show=True,
47 47
                 show_undocumented_params=True,
48
                 display_order=0):
48
                 display_order=0,
49
                 display_category=''):
49 50
        self.perm = perm
50 51
        self.methods = methods
51 52
        self.serializer_type = serializer_type
......
75 76
        self.show = show
76 77
        self.show_undocumented_params = show_undocumented_params
77 78
        self.display_order = display_order
79
        self.display_category = display_category
78 80

  
79 81
    def __call__(self, func):
80 82
        func.endpoint_info = self
......
83 85
        self.func = func
84 86
        return func
85 87

  
88
    @property
89
    def display_category_order(self):
90
        if not self.display_category:
91
            # no category, put it at the end
92
            return 99999999
93
        # self.object is attached in BaseResource.get_endpoints_infos method
94
        if self.display_category not in self.object._category_ordering:
95
            # category without ordering, put it at the end, just before no category
96
            return 99999998
97
        return self.object._category_ordering.index(self.display_category)
98

  
86 99
    def get_example_params(self):
87 100
        return dict([(x, self.parameters[x]['example_value']) for x in self.parameters or {}
88 101
                     if x in self.parameters and 'example_value' in self.parameters[x]])
tests/test_generic_endpoint.py
752 752
        pass
753 753

  
754 754

  
755
class DummyConnectorWithOrderingAndCategory(DummyConnectorBase):
756
    _category_ordering = ['Foo', 'Bar']
757

  
758
    @endpoint(display_category='Foo')
759
    def a(self, request):
760
        pass
761

  
762
    @endpoint(display_category='Bar', display_order=2)
763
    def b(self, request):
764
        pass
765

  
766
    @endpoint()
767
    def c(self, request):
768
        pass
769

  
770
    @endpoint(display_category='Bar', display_order=1)
771
    def d(self, request):
772
        pass
773

  
774
    @endpoint(display_category='Blah')
775
    def e(self, request):
776
        pass
777

  
778

  
755 779
@pytest.mark.parametrize('connector_class, expected_ordering', [
756 780
    (DummyConnectorWithoutOrdering, ['a', 'b', 'caa', 'cbb']),
757 781
    (DummyConnectorWithOrdering, ['caa', 'cbb', 'a', 'b']),
782
    (DummyConnectorWithOrderingAndCategory, ['a', 'd', 'b', 'e', 'c']),
758 783
])
759 784
def test_generic_up_in_endpoints_ordering(db, app, connector_class, expected_ordering):
760 785
    connector = connector_class()
761
-