From fce83c8a3a0804f1edc22687ac52b5373311babe Mon Sep 17 00:00:00 2001 From: Emmanuel Cazenave Date: Mon, 10 Dec 2018 19:05:07 +0100 Subject: [PATCH] create 'getfreegaps' enpoint fot availibilty queries (#28827) It has the same capabilities than 'getdays' by using display=date and 'getplaces' by using display=place. Search intervals can be specificed with days delta from now. display=full will return a data easy to use in a template to display global availability. The place referential gain adresses. --- passerelle/contrib/planitech/models.py | 192 +++++++------ tests/test_planitech.py | 377 +++++++++++++------------ 2 files changed, 301 insertions(+), 268 deletions(-) diff --git a/passerelle/contrib/planitech/models.py b/passerelle/contrib/planitech/models.py index c9a4baa..7d755a9 100644 --- a/passerelle/contrib/planitech/models.py +++ b/passerelle/contrib/planitech/models.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from datetime import datetime, time, timedelta +from datetime import date, datetime, time, timedelta import hashlib import json import re @@ -136,10 +136,11 @@ def get_salt(salt): return re.match(r'<(.*?)>', salt).groups()[0] -def get_utc_datetime(date_str, time_str): - date_obj = parse_date(date_str) +def get_utc_datetime(date_p, time_str): + if not isinstance(date_p, date): + date_p = parse_date(date_p) time_obj = parse_time(time_str) - datetime_obj = datetime.combine(date_obj, time_obj) + datetime_obj = datetime.combine(date_p, time_obj) return TZ.localize(datetime_obj).astimezone(utc) @@ -217,6 +218,11 @@ class PlanitechConnector(BaseResource): ) for place in data['requestedPlaces']: ref[place['identifier']]['capacity'] = place.get('capacity') + ref[place['identifier']]['street_number'] = place.get('streetNumber') + ref[place['identifier']]['address'] = place.get('address1') + ref[place['identifier']]['city'] = place.get('city') + ref[place['identifier']]['zipcode'] = place.get('zipCode') + cache.set(cache_key, ref) return ref @@ -288,6 +294,59 @@ class PlanitechConnector(BaseResource): def hourly(self): self._get_places_referential(refresh_cache=True) + def _date_display(self, raw_data): + available_dates = set() + for place in raw_data.get('availablePlaces', []): + for freegap in place.get('freeGaps', []): + available_dates.add(freegap[0].date()) + res = [] + available_dates = list(available_dates) + available_dates.sort() + for date_obj in available_dates: + date_text = dateformat.format(date_obj, 'l d F Y') + short_text = dateformat.format(date_obj, 'd/m/Y') + res.append({ + "id": date_obj.isoformat(), "text": date_text, + "short_text": short_text}) + return res + + def _place_display(self, raw_data): + available_places = [] + for place in raw_data.get('availablePlaces', []): + available_places.append(place['placeIdentifier']) + places_ref = self._get_places_referential() + res = [] + for place in available_places: + res.append({"id": place, "text": places_ref[place]['label']}) + return res + + def _full_display(self, raw_data): + places_ref = self._get_places_referential() + res = { + 'date': self._date_display(raw_data), + 'place': self._place_display(raw_data) + } + all_dates = [d['id'] for d in res['date']] + full = [] + for place in raw_data.get('availablePlaces', []): + place_id = place['placeIdentifier'] + place_data = { + 'id': int(place_id), + 'text': places_ref[place_id]['label'], + 'dates': [] + } + place_dates = [] + for freegap in place.get('freeGaps', []): + place_dates.append(freegap[0].date().isoformat()) + for d in all_dates: + available = d in place_dates + place_data['dates'].append({'id': d, 'available': available}) + assert len(place_data['dates']) == len(all_dates) + full.append(place_data) + + res['full'] = full + return res + @endpoint( description_get=_('Get days available for reservation'), methods=['get'], perm='can_access', @@ -304,6 +363,10 @@ class PlanitechConnector(BaseResource): 'description': _('Start date'), 'example_value': '2018-10-10', }, + 'start_days': { + 'description': _('Start days'), + 'example_value': '2', + }, 'end_date': { 'description': _('End date'), 'example_value': '2018-12-10', @@ -316,6 +379,10 @@ class PlanitechConnector(BaseResource): 'description': _('End time'), 'example_value': '18:00', }, + 'end_days': { + 'description': _('End days'), + 'example_value': '10', + }, 'weekdays': { 'description': _('Week days'), 'example_value': 'true', @@ -325,24 +392,48 @@ class PlanitechConnector(BaseResource): 'description': _('Place identifier'), 'example_value': '2', 'type': 'int', - } + }, + 'display': { + 'description': _('Display'), + 'example_value': 'date', + }, }) - def getdays( - self, request, start_date, start_time, end_time, min_capacity=0, - end_date=None, max_capacity=100000, weekdays=False, place_id=None): - if place_id is not None: - places_id = [float(place_id)] + def getfreegaps( + self, request, display, start_time, end_time, min_capacity=0, start_date=None, + start_days=None, end_date=None, end_days=None, max_capacity=100000, weekdays=False, + place_id=None): + + # Additional parameters check + valid_displays = ['date', 'place', 'full'] + if display not in valid_displays: + raise APIError("Valid display are: %s" % ", ".join(valid_displays)) + if start_date is None and start_days is None: + raise APIError("start_date or start_days is required") + + # Starting date computation + if start_date is not None: + utc_start_datetime = get_utc_datetime(start_date, start_time) else: - places_id = self._get_places_by_capacity(int(min_capacity), int(max_capacity)) + date_obj = (datetime.now() + timedelta(int(start_days))).date() + utc_start_datetime = get_utc_datetime(date_obj, start_time) - utc_start_datetime = get_utc_datetime(start_date, start_time) - if end_date is None: - utc_end_datetime = utc_start_datetime + timedelta(days=365) - else: + # Ending date computation + if end_date is None and end_days is None: + utc_end_datetime = (utc_start_datetime + timedelta(days=1)).replace(hour=0, minute=0) + elif end_date is not None: utc_end_datetime = get_utc_datetime(end_date, '00:00') + elif end_days is not None: + date_obj = (datetime.now() + timedelta(int(end_days))).date() + utc_end_datetime = get_utc_datetime(date_obj, '00:00') duration = get_duration(start_time, end_time) + # Places restriction + if place_id is not None: + places_id = [float(place_id)] + else: + places_id = self._get_places_by_capacity(int(min_capacity), int(max_capacity)) + params = { "placeIdentifiers": places_id, "startingDate": utc_start_datetime, @@ -354,74 +445,15 @@ class PlanitechConnector(BaseResource): params['reservationDays'] = [mste.Uint32(0), mste.Uint32(6)] raw_data = self._call_planitech(self.requests.post, 'getFreeGaps', params) - available_dates = set() - for place in raw_data.get('availablePlaces', []): - for freegap in place.get('freeGaps', []): - available_dates.add(freegap[0].date()) - res = [] - available_dates = list(available_dates) - available_dates.sort() - for date_obj in available_dates: - date_text = dateformat.format(date_obj, 'l d F Y') - res.append({"id": date_obj.isoformat(), "text": date_text}) + if display == 'date': + return {'data': self._date_display(raw_data)} - return {'data': res} - - @endpoint( - description_get=_('Get places available for reservation'), - methods=['get'], perm='can_access', - parameters={ - 'min_capacity': { - 'description': _('Minimum capacity'), - 'example_value': '1', - }, - 'max_capacity': { - 'description': _('Maximum capacity'), - 'example_value': '10', - }, - 'start_date': { - 'description': _('Start date'), - 'example_value': '2018-10-10', - }, - 'start_time': { - 'description': _('Start time'), - 'example_value': '10:00', - }, - 'end_time': { - 'description': _('End time'), - 'example_value': '18:00', - }, - }) - def getplaces( - self, request, start_date, start_time, end_time, min_capacity=0, max_capacity=100000): - - places_id = self._get_places_by_capacity(min_capacity, max_capacity) - - utc_start_datetime = get_utc_datetime(start_date, start_time) - utc_end_datetime = utc_start_datetime + timedelta(days=1) - duration = get_duration(start_time, end_time) - - params = { - "placeIdentifiers": places_id, - "startingDate": utc_start_datetime, - "endingDate": utc_end_datetime, - "requestedStartingTime": float(0), - "requestedEndingTime": duration - } - - raw_data = self._call_planitech(self.requests.post, 'getFreeGaps', params) - available_places = [] - for place in raw_data.get('availablePlaces', []): - available_places.append(place['placeIdentifier']) - - places_ref = self._get_places_referential() - - res = [] - for place in available_places: - res.append({"id": place, "text": places_ref[place]['label']}) + if display == 'place': + return {'data': self._place_display(raw_data)} - return {'data': res} + if display == 'full': + return {'data': self._full_display(raw_data)} @endpoint(description_get=_('Get places referential'), methods=['get'], perm='can_access') def getplacesreferential(self, request): diff --git a/tests/test_planitech.py b/tests/test_planitech.py index bc0711a..3eebe2d 100644 --- a/tests/test_planitech.py +++ b/tests/test_planitech.py @@ -215,7 +215,11 @@ def test_getplaces_referential(app, connector, monkeypatch): }, { 'requestedPlaces': [ - {'identifier': 1.0, 'capacity': 10.0}, + { + 'identifier': 1.0, 'capacity': 10.0, + 'streetNumber': 1, 'address1': 'rue planitech', + 'city': 'thecity', 'zipCode': '00000' + }, {'identifier': 2.0, 'capacity': 20.0} ] } @@ -224,10 +228,14 @@ def test_getplaces_referential(app, connector, monkeypatch): response = app.get('/planitech/slug-planitech/getplacesreferential') expected_res = { u'2.0': { - u'capacity': 20.0, u'label': u'salle 2', u'identifier': 2.0 + u'capacity': 20.0, u'label': u'salle 2', u'identifier': 2.0, + 'street_number': None, 'address': None, + 'city': None, 'zipcode': None }, u'1.0': { - u'capacity': 10.0, u'label': u'salle 1', u'identifier': 1.0 + u'capacity': 10.0, u'label': u'salle 1', u'identifier': 1.0, + 'street_number': 1, 'address': 'rue planitech', + 'city': 'thecity', 'zipcode': '00000' } } assert response.json['data'] == expected_res @@ -241,8 +249,54 @@ def test_getplaces_referential_use_cache(app, connector): cache.delete(cache_key) -def test_get_days(app, connector, monkeypatch, settings): - settings.LANGUAGE_CODE = 'fr-fr' +def test_login(connector): + + @urlmatch(netloc=r'(.*\.)?planitech\.com$') + def planitech_mock(url, request): + raise requests.exceptions.RequestException("Bad news") + + with HTTMock(planitech_mock): + with pytest.raises(APIError) as excinfo: + connector._login() + assert str(excinfo.value) == 'Authentication to Planitech failed: Bad news' + + +def test_update_reservation(app, connector, monkeypatch): + mock_call_planitech = mock_planitech( + monkeypatch, return_value={'modificationStatus': 'OK'} + ) + response = app.post_json( + '/planitech/slug-planitech/updatereservation', + params={'status': 'confirmed', 'reservation_id': 1} + ) + json_resp = response.json + assert json_resp['err'] == 0 + assert json_resp['data']['raw_data'] == {'modificationStatus': 'OK'} + call_params = mock_call_planitech.call_args[0][2] + assert call_params['reservationIdentifier'] == 1 + assert call_params['situation'] == 3 + + # Update failed + mock_planitech( + monkeypatch, return_value={'modificationStatus': 'NOTOK'} + ) + response = app.post_json( + '/planitech/slug-planitech/updatereservation', + params={'status': 'confirmed', 'reservation_id': 1} + ) + json_resp = response.json + assert json_resp['err'] == 1 + assert json_resp['err_desc'] == 'Update reservation failed: NOTOK' + + # Connector bad param + response = app.post_json( + '/planitech/slug-planitech/updatereservation', params={'status': 'confirmed'}, status=400) + json_resp = response.json + assert json_resp['err'] == 1 + assert json_resp['err_desc'] == "'reservation_id' is a required property" + + +def freegaps_data(): referential = { 2.0: { u'capacity': 20.0, u'label': u'salle 2', u'identifier': 2.0 @@ -251,255 +305,202 @@ def test_get_days(app, connector, monkeypatch, settings): u'capacity': 10.0, u'label': u'salle 1', u'identifier': 1.0 } } - - def get_free_gaps(): - return [ - [datetime(year=2018, month=11, day=11, hour=10, minute=0), - datetime(year=2018, month=11, day=11, hour=11, minute=0)], - [datetime(year=2018, month=11, day=12, hour=10, minute=0), - datetime(year=2018, month=11, day=12, hour=11, minute=0)] - ] - - getfreegaps = { + place1_gaps = [ + [datetime(year=2018, month=11, day=11, hour=10, minute=0), + datetime(year=2018, month=11, day=11, hour=11, minute=0)], + [datetime(year=2018, month=11, day=12, hour=10, minute=0), + datetime(year=2018, month=11, day=12, hour=11, minute=0)] + ] + place2_gaps = [ + [datetime(year=2018, month=11, day=11, hour=10, minute=0), + datetime(year=2018, month=11, day=11, hour=11, minute=0)], + [datetime(year=2018, month=11, day=12, hour=10, minute=0), + datetime(year=2018, month=11, day=12, hour=11, minute=0)], + [datetime(year=2018, month=11, day=13, hour=10, minute=0), + datetime(year=2018, month=11, day=13, hour=11, minute=0)] + ] + planitech_r = { 'availablePlaces': [ { - 'freeGaps': get_free_gaps() + 'placeIdentifier': 1.0, + 'freeGaps': place1_gaps }, { - 'freeGaps': get_free_gaps() + 'placeIdentifier': 2.0, + 'freeGaps': place2_gaps } ] } + return referential, planitech_r + + +def test_get_freegaps(app, connector, monkeypatch, settings): + settings.LANGUAGE_CODE = 'fr-fr' + referential, planitech_r = freegaps_data() mock_call_planitech = mock_planitech( - monkeypatch, return_value=getfreegaps, referential=referential) + monkeypatch, return_value=planitech_r, referential=referential) + + # date display response = app.get( - '/planitech/slug-planitech/getdays?start_time=10:00&&end_time=11:00' - '&start_date=2018-11-11' + '/planitech/slug-planitech/getfreegaps?start_time=10:00&&end_time=11:00' + '&start_date=2018-11-11&display=date' ) assert response.json['data'] == [ - {u'id': u'2018-11-11', u'text': u'dimanche 11 novembre 2018'}, - {u'id': u'2018-11-12', u'text': u'lundi 12 novembre 2018'} + { + u'id': u'2018-11-11', u'text': u'dimanche 11 novembre 2018', + u'short_text': '11/11/2018' + }, + { + u'id': u'2018-11-12', u'text': u'lundi 12 novembre 2018', + u'short_text': '12/11/2018' + }, + { + u'id': u'2018-11-13', u'text': u'mardi 13 novembre 2018', + u'short_text': '13/11/2018' + } ] - call_params = mock_call_planitech.call_args[0][2] - assert call_params['startingDate'] == datetime(2018, 11, 11, 10, 0, tzinfo=utc) - assert call_params['endingDate'] == datetime(2019, 11, 11, 10, 0, tzinfo=utc) - assert call_params['placeIdentifiers'] == [1.0, 2.0] - assert call_params['requestedStartingTime'] == 0.0 - assert call_params['requestedEndingTime'] == 60.0 - assert call_params['reservationDays'] == [0, 6] - # capcacity - mock_call_planitech.reset_mock() - app.get( - '/planitech/slug-planitech/getdays?start_time=10:00&&end_time=11:00' - '&start_date=2018-11-11&min_capacity=15' - ) - call_params = mock_call_planitech.call_args[0][2] - assert call_params['placeIdentifiers'] == [2.0] - - freegaps = get_free_gaps()[:1] - getfreegaps = { - 'availablePlaces': [ - { - 'freeGaps': freegaps - }, - { - 'freeGaps': freegaps - } - ] - } - mock_call_planitech = mock_planitech( - monkeypatch, return_value=getfreegaps, referential=referential) + # place display response = app.get( - '/planitech/slug-planitech/getdays?max_capacity=3&start_time=10:00&&end_time=11:00' - '&start_date=2018-11-11' + '/planitech/slug-planitech/getfreegaps?start_time=10:00&&end_time=11:00' + '&start_date=2018-11-11&display=place' ) assert response.json['data'] == [ - {u'id': u'2018-11-11', u'text': u'dimanche 11 novembre 2018'}, + {u'id': 1.0, u'text': u'salle 1'}, + {u'id': 2.0, u'text': u'salle 2'} ] - getfreegaps = { - 'availablePlaces': [ - { - 'freeGaps': [] - }, - { - 'freeGaps': [] - } - ] - } - mock_call_planitech = mock_planitech( - monkeypatch, return_value=getfreegaps, referential=referential) + # full display response = app.get( - '/planitech/slug-planitech/getdays?max_capacity=3&start_time=10:00&&end_time=11:00' - '&start_date=2018-11-11' + '/planitech/slug-planitech/getfreegaps?start_time=10:00&&end_time=11:00' + '&start_date=2018-11-11&display=full' ) - assert response.json['data'] == [] + res = response.json['data'] + assert 'place' in res + assert 'date' in res + full = res['full'] + place_1 = full[0] + assert place_1['id'] == 1.0 + assert place_1['text'] == u'salle 1' + assert place_1['dates'] == [ + {u'available': True, u'id': u'2018-11-11'}, + {u'available': True, u'id': u'2018-11-12'}, + {u'available': False, u'id': u'2018-11-13'} + ] + + place_2 = full[1] + assert place_2['id'] == 2.0 + assert place_2['text'] == u'salle 2' + assert place_2['dates'] == [ + {u'available': True, u'id': u'2018-11-11'}, + {u'available': True, u'id': u'2018-11-12'}, + {u'available': True, u'id': u'2018-11-13'} + ] - # end date + # general params interpretation mock_call_planitech.reset_mock() response = app.get( - '/planitech/slug-planitech/getdays?start_time=10:00&&end_time=11:00' - '&start_date=2018-11-11&end_date=2018-11-12' + '/planitech/slug-planitech/getfreegaps?start_time=10:00&&end_time=11:00' + '&start_date=2018-11-11&end_date=2018-11-12&display=date' ) call_params = mock_call_planitech.call_args[0][2] assert call_params['startingDate'] == datetime(2018, 11, 11, 10, 0, tzinfo=utc) assert call_params['endingDate'] == datetime(2018, 11, 12, 00, 0, tzinfo=utc) + assert call_params['placeIdentifiers'] == [1.0, 2.0] + assert call_params['requestedStartingTime'] == 0.0 # means startingDate + assert call_params['requestedEndingTime'] == 60.0 # means startingDate + 60 minutes + assert call_params['reservationDays'] == [0, 6] # means every day of the week - # start time + # no end date means only the starting date is interesting + # so ending date is the day after at midnight + # which gives only results for starting date mock_call_planitech.reset_mock() response = app.get( - '/planitech/slug-planitech/getdays?start_time=11:00&&end_time=12:00' - '&start_date=2018-11-11' + '/planitech/slug-planitech/getfreegaps?start_time=10:00&&end_time=11:00' + '&start_date=2018-11-11&display=place' ) call_params = mock_call_planitech.call_args[0][2] - assert call_params['startingDate'] == datetime(2018, 11, 11, 11, 0, tzinfo=utc) + assert call_params['startingDate'] == datetime(2018, 11, 11, 10, 0, tzinfo=utc) + assert call_params['endingDate'] == datetime(2018, 11, 12, 0, 0, tzinfo=utc) - # duration + # capacity used against referential to restrict placeIdentifiers mock_call_planitech.reset_mock() - response = app.get( - '/planitech/slug-planitech/getdays?start_time=11:00&&end_time=14:00' - '&start_date=2018-11-11' + app.get( + '/planitech/slug-planitech/getfreegaps?start_time=10:00&&end_time=11:00' + '&start_date=2018-11-11&max_capacity=15&display=place' ) call_params = mock_call_planitech.call_args[0][2] - assert call_params['requestedEndingTime'] == 180.0 + assert call_params['placeIdentifiers'] == [1.0] - # place_id filter + # place_id parameter override capacity mock_call_planitech.reset_mock() response = app.get( - '/planitech/slug-planitech/getdays?start_time=11:00&&end_time=14:00' - '&start_date=2018-11-11&place_id=2' + '/planitech/slug-planitech/getfreegaps?start_time=11:00&&end_time=14:00' + '&start_date=2018-11-11&max_capacity=15&place_id=2&display=place' ) call_params = mock_call_planitech.call_args[0][2] assert call_params['placeIdentifiers'] == [2.0] - # date bad format + # weekdays means no week days exclusion + mock_call_planitech.reset_mock() + response = app.get( + '/planitech/slug-planitech/getfreegaps?start_time=11:00&&end_time=14:00' + '&start_date=2018-11-11&max_capacity=15&place_id=2&display=place' + '&weekdays=true' + ) + call_params = mock_call_planitech.call_args[0][2] + assert 'reservationDays' not in call_params + + # BAD REQUEST + # bad date format response = app.get( - '/planitech/slug-planitech/getdays?start_time=11:00&&end_time=14:00' - '&start_date=notadate' + '/planitech/slug-planitech/getfreegaps?start_time=11:00&&end_time=14:00' + '&start_date=notadate&display=place' ) json_resp = response.json assert json_resp['err'] == 1 assert json_resp['err_desc'] == "Invalid date format: notadate" - # date time format + # bad time format response = app.get( - '/planitech/slug-planitech/getdays?start_time=notatime&&end_time=14:00' - '&start_date=2018-11-11' + '/planitech/slug-planitech/getfreegaps?start_time=notatime&&end_time=14:00' + '&start_date=2018-11-11&display=place' ) json_resp = response.json assert json_resp['err'] == 1 assert json_resp['err_desc'] == "Invalid time format: notatime" - -def test_get_places(app, connector, monkeypatch, settings): - referential = { - 2.0: { - u'capacity': 20.0, u'label': u'salle 2', u'identifier': 2.0 - }, - 1.0: { - u'capacity': 10.0, u'label': u'salle 1', u'identifier': 1.0 - } - } - - def get_free_gaps(): - return [ - [datetime(year=2018, month=11, day=11, hour=10, minute=0), - datetime(year=2018, month=11, day=11, hour=11, minute=0)], - [datetime(year=2018, month=11, day=12, hour=10, minute=0), - datetime(year=2018, month=11, day=12, hour=11, minute=0)] - ] - - getfreegaps = { - 'availablePlaces': [ - { - 'placeIdentifier': 1.0, - 'freeGaps': get_free_gaps() - }, - { - 'placeIdentifier': 2.0, - 'freeGaps': get_free_gaps() - } - ] - } - mock_call_planitech = mock_planitech( - monkeypatch, return_value=getfreegaps, referential=referential) + # start_date or start_days required response = app.get( - '/planitech/slug-planitech/getplaces?start_time=10:00&&end_time=11:00' - '&start_date=2018-11-11' - ) - assert response.json['data'] == [ - {u'id': 1.0, u'text': u'salle 1'}, - {u'id': 2.0, u'text': u'salle 2'} - ] - call_params = mock_call_planitech.call_args[0][2] - assert call_params['startingDate'] == datetime(2018, 11, 11, 10, 0, tzinfo=utc) - assert call_params['endingDate'] == datetime(2018, 11, 12, 10, 0, tzinfo=utc) - assert call_params['placeIdentifiers'] == [1.0, 2.0] - assert call_params['requestedStartingTime'] == 0.0 - assert call_params['requestedEndingTime'] == 60.0 - - # date bad format - response = app.get( - '/planitech/slug-planitech/getplaces?start_time=10:00&&end_time=11:00' - '&start_date=notadate' + '/planitech/slug-planitech/getfreegaps?start_time=notatime&&end_time=14:00' + '&display=place' ) json_resp = response.json assert json_resp['err'] == 1 - assert json_resp['err_desc'] == "Invalid date format: notadate" + assert json_resp['err_desc'] == "start_date or start_days is required" - # date time format + # invalid display param response = app.get( - '/planitech/slug-planitech/getplaces?start_time=notatime&&end_time=11:00' - '&start_date=2018-11-11' + '/planitech/slug-planitech/getfreegaps?start_time=notatime&&end_time=14:00' + '&start_date=2018-11-11&display=unkown' ) json_resp = response.json assert json_resp['err'] == 1 - assert json_resp['err_desc'] == "Invalid time format: notatime" + assert json_resp['err_desc'] == "Valid display are: date, place, full" -def test_login(connector): - - @urlmatch(netloc=r'(.*\.)?planitech\.com$') - def planitech_mock(url, request): - raise requests.exceptions.RequestException("Bad news") - - with HTTMock(planitech_mock): - with pytest.raises(APIError) as excinfo: - connector._login() - assert str(excinfo.value) == 'Authentication to Planitech failed: Bad news' - - -def test_update_reservation(app, connector, monkeypatch): +def test_get_freegaps_start_days(app, connector, monkeypatch, settings, freezer): + freezer.move_to('2018-11-09 23:50:00') + settings.LANGUAGE_CODE = 'fr-fr' + referential, planitech_r = freegaps_data() mock_call_planitech = mock_planitech( - monkeypatch, return_value={'modificationStatus': 'OK'} - ) - response = app.post_json( - '/planitech/slug-planitech/updatereservation', - params={'status': 'confirmed', 'reservation_id': 1} - ) - json_resp = response.json - assert json_resp['err'] == 0 - assert json_resp['data']['raw_data'] == {'modificationStatus': 'OK'} - call_params = mock_call_planitech.call_args[0][2] - assert call_params['reservationIdentifier'] == 1 - assert call_params['situation'] == 3 + monkeypatch, return_value=planitech_r, referential=referential) - # Update failed - mock_planitech( - monkeypatch, return_value={'modificationStatus': 'NOTOK'} - ) - response = app.post_json( - '/planitech/slug-planitech/updatereservation', - params={'status': 'confirmed', 'reservation_id': 1} + # starting_date and ending_date can be specified as days delta from now + app.get( + '/planitech/slug-planitech/getfreegaps?start_time=10:00&&end_time=11:00' + '&start_days=2&end_days=4&display=place' ) - json_resp = response.json - assert json_resp['err'] == 1 - assert json_resp['err_desc'] == 'Update reservation failed: NOTOK' - - # Connector bad param - response = app.post_json( - '/planitech/slug-planitech/updatereservation', params={'status': 'confirmed'}, status=400) - json_resp = response.json - assert json_resp['err'] == 1 - assert json_resp['err_desc'] == "'reservation_id' is a required property" + call_params = mock_call_planitech.call_args[0][2] + assert call_params['startingDate'] == datetime(2018, 11, 11, 10, 0, tzinfo=utc) + assert call_params['endingDate'] == datetime(2018, 11, 13, 0, 0, tzinfo=utc) -- 2.19.2