misc: retrieve check types from lingo (#66015)

This commit is contained in:
Lauréline Guérin 2022-06-07 15:20:20 +02:00
parent dece1657f7
commit 244dd89cf9
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
3 changed files with 155 additions and 0 deletions

77
chrono/utils/lingo.py Normal file
View File

@ -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

View File

@ -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'}

View File

@ -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'),
]