misc: retrieve check types from lingo (#66015)
This commit is contained in:
parent
dece1657f7
commit
244dd89cf9
|
@ -0,0 +1,77 @@
|
|||
# chrono - agendas 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/>.
|
||||
|
||||
import dataclasses
|
||||
import json
|
||||
|
||||
from django.conf import settings
|
||||
from requests.exceptions import RequestException
|
||||
|
||||
from chrono.utils.requests_wrapper import requests
|
||||
|
||||
|
||||
def is_lingo_enabled():
|
||||
return hasattr(settings, 'KNOWN_SERVICES') and settings.KNOWN_SERVICES.get('lingo')
|
||||
|
||||
|
||||
def get_lingo_service():
|
||||
if not is_lingo_enabled():
|
||||
return {}
|
||||
return list(settings.KNOWN_SERVICES.get('lingo').values())[0]
|
||||
|
||||
|
||||
def get_lingo_json(path, log_errors=True):
|
||||
lingo_site = get_lingo_service()
|
||||
if lingo_site is None:
|
||||
return
|
||||
try:
|
||||
response = requests.get(
|
||||
path,
|
||||
remote_service=lingo_site,
|
||||
without_user=True,
|
||||
headers={'accept': 'application/json'},
|
||||
log_errors=log_errors,
|
||||
)
|
||||
response.raise_for_status()
|
||||
except RequestException as e:
|
||||
if e.response is not None:
|
||||
try:
|
||||
# return json if available (on 404 responses by example)
|
||||
return e.response.json()
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
return
|
||||
return response.json()
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class CheckType:
|
||||
slug: str
|
||||
label: str
|
||||
kind: str
|
||||
|
||||
|
||||
def get_agenda_check_types(agenda):
|
||||
result = get_lingo_json('api/agenda/%s/check-types/' % agenda.slug)
|
||||
if result is None:
|
||||
return []
|
||||
if result.get('data') is None:
|
||||
return []
|
||||
|
||||
check_types = []
|
||||
for ct in result['data']:
|
||||
check_types.append(CheckType(slug=ct['id'], label=ct['text'], kind=ct['kind']))
|
||||
return check_types
|
|
@ -27,6 +27,15 @@ KNOWN_SERVICES = {
|
|||
'backoffice-menu-url': 'http://example.org/manage/',
|
||||
}
|
||||
},
|
||||
'lingo': {
|
||||
'default': {
|
||||
'title': 'test',
|
||||
'url': 'http://lingo.example.org',
|
||||
'secret': 'chrono',
|
||||
'orig': 'chrono',
|
||||
'backoffice-menu-url': 'http://example.org/manage/',
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
LEGACY_URLS_MAPPING = {'old.org': 'new.org'}
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
import datetime
|
||||
import json
|
||||
from unittest import mock
|
||||
|
||||
from requests.exceptions import ConnectionError
|
||||
from requests.models import Response
|
||||
|
||||
from chrono.agendas.models import Agenda
|
||||
from chrono.utils.date import get_weekday_index
|
||||
from chrono.utils.lingo import CheckType, get_agenda_check_types
|
||||
|
||||
|
||||
def test_get_weekday_index():
|
||||
|
@ -21,3 +28,65 @@ def test_get_weekday_index():
|
|||
assert get_weekday_index(date.replace(day=28)) == 4
|
||||
assert get_weekday_index(date.replace(day=29)) == 5
|
||||
assert get_weekday_index(date.replace(day=30)) == 5
|
||||
|
||||
|
||||
CHECK_TYPES_DATA = [
|
||||
{'id': 'bar-reason', 'kind': 'presence', 'text': 'Bar reason'},
|
||||
{'id': 'foo-reason', 'kind': 'absence', 'text': 'Foo reason'},
|
||||
]
|
||||
|
||||
|
||||
class MockedRequestResponse(mock.Mock):
|
||||
status_code = 200
|
||||
|
||||
def json(self):
|
||||
return json.loads(self.content)
|
||||
|
||||
|
||||
def test_get_agenda_check_types_no_service(settings):
|
||||
agenda = Agenda(slug='foo')
|
||||
|
||||
settings.KNOWN_SERVICES = {}
|
||||
assert get_agenda_check_types(agenda) == []
|
||||
|
||||
settings.KNOWN_SERVICES = {'other': []}
|
||||
assert get_agenda_check_types(agenda) == []
|
||||
|
||||
|
||||
def test_get_agenda_check_types():
|
||||
agenda = Agenda(slug='foo')
|
||||
|
||||
with mock.patch('requests.Session.get') as requests_get:
|
||||
requests_get.side_effect = ConnectionError()
|
||||
assert get_agenda_check_types(agenda) == []
|
||||
|
||||
with mock.patch('requests.Session.get') as requests_get:
|
||||
mock_resp = Response()
|
||||
mock_resp.status_code = 500
|
||||
requests_get.return_value = mock_resp
|
||||
assert get_agenda_check_types(agenda) == []
|
||||
|
||||
with mock.patch('requests.Session.get') as requests_get:
|
||||
mock_resp = Response()
|
||||
mock_resp.status_code = 404
|
||||
requests_get.return_value = mock_resp
|
||||
assert get_agenda_check_types(agenda) == []
|
||||
|
||||
with mock.patch('requests.Session.get') as requests_get:
|
||||
requests_get.return_value = MockedRequestResponse(content=json.dumps({'foo': 'bar'}))
|
||||
assert get_agenda_check_types(agenda) == []
|
||||
|
||||
data = {'data': []}
|
||||
with mock.patch('requests.Session.get') as requests_get:
|
||||
requests_get.return_value = MockedRequestResponse(content=json.dumps(data))
|
||||
assert get_agenda_check_types(agenda) == []
|
||||
assert requests_get.call_args_list[0][0] == ('api/agenda/foo/check-types/',)
|
||||
assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://lingo.example.org'
|
||||
|
||||
data = {'data': CHECK_TYPES_DATA}
|
||||
with mock.patch('requests.Session.get') as requests_get:
|
||||
requests_get.return_value = MockedRequestResponse(content=json.dumps(data))
|
||||
assert get_agenda_check_types(agenda) == [
|
||||
CheckType(slug='bar-reason', label='Bar reason', kind='presence'),
|
||||
CheckType(slug='foo-reason', label='Foo reason', kind='absence'),
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue