Projet

Général

Profil

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

Lauréline Guérin, 17 juin 2022 23:27

Télécharger (6,5 ko)

Voir les différences:

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

 chrono/utils/lingo.py | 77 +++++++++++++++++++++++++++++++++++++++++++
 tests/settings.py     |  9 +++++
 tests/test_utils.py   | 69 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 155 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 requests.exceptions import RequestException
22

  
23
from chrono.utils.requests_wrapper import requests
24

  
25

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

  
29

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

  
35

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

  
59

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

  
66

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

  
74
    check_types = []
75
    for ct in result['data']:
76
        check_types.append(CheckType(slug=ct['id'], label=ct['text'], kind=ct['kind']))
77
    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
-