api: list agenda's check types (#66008)

This commit is contained in:
Lauréline Guérin 2022-06-07 10:41:13 +02:00
parent 713216742c
commit ba77a40f73
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
7 changed files with 156 additions and 0 deletions

0
lingo/api/__init__.py Normal file
View File

27
lingo/api/urls.py Normal file
View File

@ -0,0 +1,27 @@
# lingo - payment and billing system
# Copyright (C) 2022 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.conf.urls import url
from . import views
urlpatterns = [
url(
r'^agenda/(?P<agenda_identifier>[\w-]+)/check-types/$',
views.agenda_check_type_list,
name='api-agenda-check-types',
),
]

51
lingo/api/utils.py Normal file
View File

@ -0,0 +1,51 @@
# lingo - payment and billing system
# Copyright (C) 2022 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import gettext_lazy as _
from rest_framework.response import Response
from rest_framework.views import exception_handler as DRF_exception_handler
class APIError(Exception):
http_status = 200
def __init__(self, message, *args, err=1, err_class=None, errors=None):
self.err_desc = _(message) % args
self.err = err
self.err_class = err_class or message % args
self.errors = errors
super().__init__(self.err_desc)
def to_response(self):
data = {
'err': self.err,
'err_class': self.err_class,
'err_desc': self.err_desc,
}
if self.errors:
data['errors'] = self.errors
return Response(data, status=self.http_status)
class APIErrorBadRequest(APIError):
http_status = 400
def exception_handler(exc, context):
if isinstance(exc, APIError):
return exc.to_response()
return DRF_exception_handler(exc, context)

39
lingo/api/views.py Normal file
View File

@ -0,0 +1,39 @@
# lingo - payment and billing system
# Copyright (C) 2022 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.shortcuts import get_object_or_404
from rest_framework.views import APIView
from lingo.agendas.models import Agenda
from lingo.api.utils import Response
class AgendaCheckTypeList(APIView):
permission_classes = ()
def get(self, request, agenda_identifier=None, format=None):
agenda = get_object_or_404(Agenda, slug=agenda_identifier)
check_types = []
if agenda.check_type_group:
check_types = [
{'id': x.slug, 'text': x.label, 'kind': x.kind}
for x in agenda.check_type_group.check_types.filter(disabled=False)
]
return Response({'data': check_types})
agenda_check_type_list = AgendaCheckTypeList.as_view()

View File

@ -55,6 +55,7 @@ INSTALLED_APPS = (
'eopayment',
'gadjo',
'lingo.agendas',
'lingo.api',
'lingo.manager',
'lingo.pricing',
)
@ -194,6 +195,7 @@ def debug_show_toolbar(request):
DEBUG_TOOLBAR_CONFIG = {'SHOW_TOOLBAR_CALLBACK': debug_show_toolbar}
REST_FRAMEWORK = {'EXCEPTION_HANDLER': 'lingo.api.utils.exception_handler'}
local_settings_file = os.environ.get(
'LINGO_SETTINGS_FILE', os.path.join(os.path.dirname(__file__), 'local_settings.py')

View File

@ -19,6 +19,7 @@ from django.conf.urls import include, url
from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from .api.urls import urlpatterns as lingo_api_urls
from .manager.urls import urlpatterns as lingo_manager_urls
from .pricing.urls import urlpatterns as lingo_pricing_urls
from .urls_utils import decorated_includes, manager_required
@ -28,6 +29,7 @@ urlpatterns = [
url(r'^$', homepage, name='homepage'),
url(r'^manage/', decorated_includes(manager_required, include(lingo_manager_urls))),
url(r'^manage/pricing/', decorated_includes(manager_required, include(lingo_pricing_urls))),
url(r'^api/', include(lingo_api_urls)),
url(r'^login/$', login, name='auth_login'),
url(r'^logout/$', logout, name='auth_logout'),
]

35
tests/test_api.py Normal file
View File

@ -0,0 +1,35 @@
import pytest
from lingo.agendas.models import Agenda, CheckType, CheckTypeGroup
pytestmark = pytest.mark.django_db
def test_agendas_check_types_api(app):
agenda = Agenda.objects.create(label='Foo bar')
group = CheckTypeGroup.objects.create(label='Foo bar')
CheckType.objects.create(label='Foo reason', group=group, kind='absence')
CheckType.objects.create(label='Bar reason', group=group, kind='presence')
CheckType.objects.create(label='Baz reason', group=group, kind='presence', disabled=True)
group2 = CheckTypeGroup.objects.create(label='Foo bar 2')
resp = app.get('/api/agenda/%s/check-types/' % agenda.slug)
assert resp.json == {'data': []}
agenda.check_type_group = group2
agenda.save()
resp = app.get('/api/agenda/%s/check-types/' % agenda.slug)
assert resp.json == {'data': []}
agenda.check_type_group = group
agenda.save()
resp = app.get('/api/agenda/%s/check-types/' % agenda.slug)
assert resp.json == {
'data': [
{'id': 'bar-reason', 'kind': 'presence', 'text': 'Bar reason'},
{'id': 'foo-reason', 'kind': 'absence', 'text': 'Foo reason'},
]
}
# unknown
resp = app.get('/api/agenda/xxxx/resources/', status=404)