passerelle/tests/test_clicrdv.py

246 lines
9.2 KiB
Python

from unittest import mock
from urllib import parse as urlparse
import pytest
from django.contrib.contenttypes.models import ContentType
from requests.exceptions import HTTPError
from passerelle.apps.clicrdv.models import ClicRdv
from passerelle.base.models import AccessRight, ApiUser
from tests.test_manager import login
@pytest.fixture
def connector(db):
return ClicRdv.objects.create(
slug='test', group_id='5242', apikey='test', username='test', password='test'
)
def test_connector_is_legacy(connector, app, admin_user):
app = login(app)
# check the existing instance is displayed on homepage
resp = app.get('/manage/', status=200)
assert 'Clicrdv Agenda' in resp
# and check it's not available on "add connector" page
resp = resp.click('Add Connector')
assert 'Clicrdv Agenda' not in resp
@mock.patch('passerelle.utils.Request.request')
def test_request_call(mocked_request, app, connector):
mocked_request.json.return_value = 'foo'
connector.request('bar')
assert mocked_request.call_count == 1
req = mocked_request.call_args[0][1]
assert req.startswith('https://sandbox.clicrdv.com/api/v1/groups/5242/bar')
@mock.patch('passerelle.utils.Request.request')
def test_interventionsets(mocked_request, app, connector):
response = mock.Mock()
response.json.return_value = {
'totalRecords': 2,
'records': [
{
'sort': 1,
'publicname': 'Une Demande de Passeport',
'name': 'Demande',
'id': 7032,
'group_id': 5242,
},
{
'sort': 2,
'publicname': 'Un Retrait de Passeport',
'name': 'Retrait',
'id': 7033,
'group_id': 5242,
},
],
}
mocked_request.return_value = response
resp = app.get('/clicrdv/test/interventionsets/')
assert len(resp.json.get('data')) == 2
assert resp.json.get('data')[0]['text'] == 'Une Demande de Passeport'
@mock.patch('passerelle.utils.Request.request')
def test_interventionsets_details(mocked_request, app, connector):
response = mock.Mock()
response.json.return_value = {
'totalRecords': 2,
'records': [
{
'sort': 1,
'publicname': 'pour une personne',
'description': None,
'name': '1 personne',
'interventionset_id': 7032,
'group_id': 5242,
'id': 63258,
'abbr': '1 demande',
},
{
'sort': 2,
'publicname': 'pour deuxs personnes',
'description': None,
'name': '2 personnes',
'interventionset_id': 7032,
'group_id': 5242,
'id': 63259,
'abbr': '2 demandes',
},
],
}
mocked_request.return_value = response
resp = app.get('/clicrdv/test/interventionsets/7032/')
assert len(resp.json.get('data')) == 2
assert resp.json.get('data')[0]['text'] == 'pour une personne'
@mock.patch('passerelle.utils.Request.request')
def test_interventions_get_datetimes(mocked_request, app, connector):
response = mock.Mock()
response.json.return_value = {'availabletimeslots': []}
mocked_request.return_value = response
resp = app.get('/clicrdv/test/interventions/63258/dates/')
assert resp.json.get('data') == []
assert resp.json.get('err') == 0
assert mocked_request.call_count == 1
url = mocked_request.call_args[0][1]
# https://sandbox.clicrdv.com/api/v1/groups/5242/availabletimeslots?
# intervention_ids[]=63258&start=2016-09-21&end=2017-09-22&apikey=test&format=json
scheme, netloc, path, params, query, fragment = urlparse.urlparse(url)
query = urlparse.parse_qs(query, keep_blank_values=True)
assert scheme == 'https'
assert netloc == 'sandbox.clicrdv.com'
assert path == '/api/v1/groups/5242/availabletimeslots'
assert params == ''
assert fragment == ''
assert query['intervention_ids[]'] == ['63258']
assert 'start' in query
assert 'end' in query
assert query['apikey'] == ['test']
assert query['format'] == ['json']
response.json.return_value = {
'availabletimeslots': [{'start': '2016-09-21 12:34:56'}, {'start': '2016-09-22 11:22:33'}]
}
mocked_request.return_value = response
resp = app.get('/clicrdv/test/interventions/63258/dates/').json
assert mocked_request.call_count == 2
assert resp.get('err') == 0
assert len(resp.get('data')) == 2
assert resp['data'][0] == {'id': '2016-09-21', 'text': '21 September 2016'}
assert resp['data'][1] == {'id': '2016-09-22', 'text': '22 September 2016'}
response.json.return_value = {
'availabletimeslots': [{'start': '2016-09-22 11:22:33'}, {'start': '2016-09-21 12:34:56'}]
} # will be sorted
mocked_request.return_value = response
resp = app.get('/clicrdv/test/interventions/63258/datetimes/').json
assert mocked_request.call_count == 3
assert resp.get('err') == 0
assert len(resp.get('data')) == 2
assert resp['data'][0] == {'id': '2016-09-21-12:34:56', 'text': '21 September 2016 12:34'}
assert resp['data'][1] == {'id': '2016-09-22-11:22:33', 'text': '22 September 2016 11:22'}
response.json.return_value = {
'availabletimeslots': [{'start': '2016-09-21 12:34:56'}, {'start': '2016-09-21 11:22:33'}]
} # will be sorted
mocked_request.return_value = response
resp = app.get('/clicrdv/test/interventions/63258/2016-09-21/times').json
assert mocked_request.call_count == 4
url = mocked_request.call_args[0][1]
scheme, netloc, path, params, query, fragment = urlparse.urlparse(url)
query = urlparse.parse_qs(query, keep_blank_values=True)
assert query['start'] == ['2016-09-21 00:00:00']
assert query['end'] == ['2016-09-21 23:59:59']
assert resp.get('err') == 0
assert len(resp.get('data')) == 2
assert resp['data'][0] == {'id': '11:22:33', 'text': '11:22'}
assert resp['data'][1] == {'id': '12:34:56', 'text': '12:34'}
@mock.patch('passerelle.utils.Request.request')
def test_interventions_get_datetimes_error(mocked_request, app, connector):
def raise_for_status():
raise HTTPError('400 Client Error: Bad Request for url: xxx')
response = mock.Mock()
response.json.return_value = [
{'error': 'The intervention_ids parameter contains at least one invalid id'}
]
response.raise_for_status = raise_for_status
mocked_request.return_value = response
resp = app.get('/clicrdv/test/interventions/63258/datetimes/').json
assert len(resp.get('data')) == 0
@mock.patch('passerelle.utils.Request.request')
def test_cancel_appointment(mocked_request, app, connector):
obj_type = ContentType.objects.get_for_model(ClicRdv)
apiuser = ApiUser.objects.create(username='apiuser', keytype='API', key='apiuser')
AccessRight.objects.create(
codename='can_manage_appointment', resource_type=obj_type, resource_pk=connector.pk, apiuser=apiuser
)
resp = app.get('/clicrdv/test/63258/cancel?apikey=apiuser').json
assert mocked_request.call_count == 1
assert resp['data']['success']
@mock.patch('passerelle.utils.Request.request')
def test_failed_cancel_appointment(mocked_request, app, connector):
def raise_for_status():
raise HTTPError('400 Client Error: Bad Request for url: xxx')
response = mock.Mock()
response.json.return_value = [{'msg': 'cancel failed'}]
response.raise_for_status = raise_for_status
mocked_request.return_value = response
obj_type = ContentType.objects.get_for_model(ClicRdv)
apiuser = ApiUser.objects.create(username='apiuser', keytype='API', key='apiuser')
AccessRight.objects.create(
codename='can_manage_appointment', resource_type=obj_type, resource_pk=connector.pk, apiuser=apiuser
)
resp = app.get('/clicrdv/test/63258/cancel?apikey=apiuser').json
assert mocked_request.call_count == 1
assert resp.get('err') == 0
assert resp['data']
assert 'cancel failed' in resp['data']['error']
@mock.patch('passerelle.utils.Request.request')
def test_failed_appointment_creation(mocked_request, app, connector):
def raise_for_status():
raise HTTPError('400 Client Error: Bad Request for url: xxx')
response = mock.Mock()
response.json.return_value = [{'msg': 'creation failed'}]
response.raise_for_status = raise_for_status
mocked_request.return_value = response
obj_type = ContentType.objects.get_for_model(ClicRdv)
apiuser = ApiUser.objects.create(username='apiuser', keytype='API', key='apiuser')
AccessRight.objects.create(
codename='can_manage_appointment', resource_type=obj_type, resource_pk=connector.pk, apiuser=apiuser
)
data = {
'fields': {
'clicrdv_date_raw': '2017-01-01',
'clicrdv_time_raw': '12:00:00',
'clicrdv_fiche_str10': 'Test',
'firstname': 'Foo',
'lastname': 'Bar',
'email': 'foobar@example.com',
}
}
resp = app.post_json('/clicrdv/test/interventions/63258/create?apikey=apiuser', params=data).json
assert resp['data']
assert not resp['data']['success']
assert 'creation failed' in resp['data']['error']