Projet

Général

Profil

0001-misc-retrieve-check-types-from-lingo-66015.patch

Lauréline Guérin, 10 juin 2022 10:20

Télécharger (6,49 ko)

Voir les différences:

Subject: [PATCH 1/5] misc: retrieve check types from lingo (#66015)

 chrono/utils/lingo.py | 76 +++++++++++++++++++++++++++++++++++++++++++
 tests/settings.py     |  9 +++++
 tests/test_utils.py   | 69 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 154 insertions(+)
 create mode 100644 chrono/utils/lingo.py
chrono/utils/lingo.py
1
# chrono - agendas system
2
# Copyright (C) 2022  Entr'ouvert
3
#
4
# This program is free software: you can redistribute it and/or modify it
5
# under the terms of the GNU Affero General Public License as published
6
# by the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU Affero General Public License for more details.
13
#
14
# You should have received a copy of the GNU Affero General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

  
17
import dataclasses
18
import json
19

  
20
from django.conf import settings
21
from lingo.utils import requests
22
from requests.exceptions import RequestException
23

  
24

  
25
def is_lingo_enabled():
26
    return hasattr(settings, 'KNOWN_SERVICES') and settings.KNOWN_SERVICES.get('lingo')
27

  
28

  
29
def get_lingo_service():
30
    if not is_lingo_enabled():
31
        return {}
32
    return list(settings.KNOWN_SERVICES.get('lingo').values())[0]
33

  
34

  
35
def get_lingo_json(path, log_errors=True):
36
    lingo_site = get_lingo_service()
37
    if lingo_site is None:
38
        return
39
    try:
40
        response = requests.get(
41
            path,
42
            remote_service=lingo_site,
43
            without_user=True,
44
            headers={'accept': 'application/json'},
45
            log_errors=log_errors,
46
        )
47
        response.raise_for_status()
48
    except RequestException as e:
49
        if e.response is not None:
50
            try:
51
                # return json if available (on 404 responses by example)
52
                return e.response.json()
53
            except json.JSONDecodeError:
54
                pass
55
        return
56
    return response.json()
57

  
58

  
59
@dataclasses.dataclass
60
class CheckType:
61
    slug: str
62
    label: str
63
    kind: str
64

  
65

  
66
def get_agenda_check_types(agenda):
67
    result = get_lingo_json('api/agenda/%s/check-types/' % agenda.slug)
68
    if result is None:
69
        return []
70
    if result.get('data') is None:
71
        return []
72

  
73
    check_types = []
74
    for ct in result['data']:
75
        check_types.append(CheckType(slug=ct['id'], label=ct['text'], kind=ct['kind']))
76
    return check_types
tests/settings.py
27 27
            'backoffice-menu-url': 'http://example.org/manage/',
28 28
        }
29 29
    },
30
    'lingo': {
31
        'default': {
32
            'title': 'test',
33
            'url': 'http://lingo.example.org',
34
            'secret': 'chrono',
35
            'orig': 'chrono',
36
            'backoffice-menu-url': 'http://example.org/manage/',
37
        }
38
    },
30 39
}
31 40

  
32 41
LEGACY_URLS_MAPPING = {'old.org': 'new.org'}
tests/test_utils.py
1 1
import datetime
2
import json
3
from unittest import mock
2 4

  
5
from requests.exceptions import ConnectionError
6
from requests.models import Response
7

  
8
from chrono.agendas.models import Agenda
3 9
from chrono.utils.date import get_weekday_index
10
from chrono.utils.lingo import CheckType, get_agenda_check_types
4 11

  
5 12

  
6 13
def test_get_weekday_index():
......
21 28
        assert get_weekday_index(date.replace(day=28)) == 4
22 29
        assert get_weekday_index(date.replace(day=29)) == 5
23 30
        assert get_weekday_index(date.replace(day=30)) == 5
31

  
32

  
33
CHECK_TYPES_DATA = [
34
    {'id': 'bar-reason', 'kind': 'presence', 'text': 'Bar reason'},
35
    {'id': 'foo-reason', 'kind': 'absence', 'text': 'Foo reason'},
36
]
37

  
38

  
39
class MockedRequestResponse(mock.Mock):
40
    status_code = 200
41

  
42
    def json(self):
43
        return json.loads(self.content)
44

  
45

  
46
def test_get_agenda_check_types_no_service(settings):
47
    agenda = Agenda(slug='foo')
48

  
49
    settings.KNOWN_SERVICES = {}
50
    assert get_agenda_check_types(agenda) == []
51

  
52
    settings.KNOWN_SERVICES = {'other': []}
53
    assert get_agenda_check_types(agenda) == []
54

  
55

  
56
def test_get_agenda_check_types():
57
    agenda = Agenda(slug='foo')
58

  
59
    with mock.patch('requests.Session.get') as requests_get:
60
        requests_get.side_effect = ConnectionError()
61
        assert get_agenda_check_types(agenda) == []
62

  
63
    with mock.patch('requests.Session.get') as requests_get:
64
        mock_resp = Response()
65
        mock_resp.status_code = 500
66
        requests_get.return_value = mock_resp
67
        assert get_agenda_check_types(agenda) == []
68

  
69
    with mock.patch('requests.Session.get') as requests_get:
70
        mock_resp = Response()
71
        mock_resp.status_code = 404
72
        requests_get.return_value = mock_resp
73
        assert get_agenda_check_types(agenda) == []
74

  
75
    with mock.patch('requests.Session.get') as requests_get:
76
        requests_get.return_value = MockedRequestResponse(content=json.dumps({'foo': 'bar'}))
77
        assert get_agenda_check_types(agenda) == []
78

  
79
    data = {'data': []}
80
    with mock.patch('requests.Session.get') as requests_get:
81
        requests_get.return_value = MockedRequestResponse(content=json.dumps(data))
82
        assert get_agenda_check_types(agenda) == []
83
        assert requests_get.call_args_list[0][0] == ('api/agenda/foo/check-types/',)
84
        assert requests_get.call_args_list[0][1]['remote_service']['url'] == 'http://lingo.example.org'
85

  
86
    data = {'data': CHECK_TYPES_DATA}
87
    with mock.patch('requests.Session.get') as requests_get:
88
        requests_get.return_value = MockedRequestResponse(content=json.dumps(data))
89
        assert get_agenda_check_types(agenda) == [
90
            CheckType(slug='bar-reason', label='Bar reason', kind='presence'),
91
            CheckType(slug='foo-reason', label='Foo reason', kind='absence'),
92
        ]
24
-