passerelle/tests/test_vivaticket.py

393 lines
13 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from unittest import mock
import pytest
import tests.utils
from passerelle.apps.vivaticket.models import VivaTicket
from passerelle.utils.jsonresponse import APIError
ERROR_RESPONSE = """{
"Message": "Une erreur sest produite."
}"""
KEY_RESPONSE = """{
"Key": "86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074",
"ReturnCode": 0,
"Error": null
}"""
EVENTS_RESPONSE = """{
"ListOfSettings": [
{
"Code": "01",
"Label": "Visite Musée"
},
{
"Code": "02",
"Label": "Visite Exposition"
},
{
"Code": "03",
"Label": "Visite Musée + Atelier"
},
{
"Code": "04",
"Label": "Visite Musée + Expo + Atelier"
},
{
"Code": "06",
"Label": "Atelier"
},
{
"Code": "05",
"Label": "Auditorium"
},
{
"Code": "10",
"Label": "Prévente"
}
],
"ReturnCode": 0,
"Error": null
}"""
ROOMS_RESPONSE = """{
"ListOfSettings": [
{
"Code": "001",
"Label": "Collections Permanentes"
},
{
"Code": "002",
"Label": "Exposition"
},
{
"Code": "003",
"Label": "Salle Pédagogique 1"
},
{
"Code": "004",
"Label": "Salle Pédagogique 2"
},
{
"Code": "006",
"Label": "Laboratoire"
},
{
"Code": "005",
"Label": "Auditorium"
}
],
"ReturnCode": 0,
"Error": null
}"""
THEMES_RESPONSE = """{
"ListOfSettings": [
{
"Code": "A0001",
"Label": "Atelier scolaire"
},
{
"Code": "A0002",
"Label": "Atelier Enfant - Individuel"
},,
{
"Code": "C0001",
"Label": "Conférence - Sujet 1"
},
{
"Code": "C0002",
"Label": "Conférence - Sujet 2"
},
{
"Code": "R0001",
"Label": "Petit Déjeuner"
},
{
"Code": "R0002",
"Label": "Déjeuner"
},
{
"Code": "S0001",
"Label": "Spectacle - Titre 1"
},
{
"Code": "S0002",
"Label": "Spectacle - Titre 2"
},
{
"Code": "S0003",
"Label": "Spectacle - Titre 3"
},
{
"Code": "V001",
"Label": "Visite Guidée Musée - Individuel"
},
{
"Code": "V002",
"Label": "Visite Guidée Musée - Groupe"
},
{
"Code": "V003",
"Label": "Visite Guidée Musée - Scolaire"
},
{
"Code": "V004",
"Label": "Visite Libre Musée - Groupe"
},
{
"Code": "V0041",
"Label": "Visite Libre Musée - Scolaire"
},
{
"Code": "V005",
"Label": "Visite Guidée Expo - Individuel"
},
{
"Code": "V006",
"Label": "Visite Guidée Expo - Groupe"
},
{
"Code": "V007",
"Label": "Visite Guidée Expo - Scolaire"
},
{
"Code": "V008",
"Label": "Visite Libre Expo - Groupe"
},
{
"Code": "V009",
"Label": "Visite Libre Expo - Scolaire"
}
],
"ReturnCode": 0,
"Error": null
}"""
CONTACT_RESPONSE = """{
"InternalCode": "0000000273",
"LastName": "Bar",
"FirstName": "Foo",
"SocialReason": null,
"Address1": null,
"Address2": null,
"Address3": null,
"Address4": null,
"ZipCode": null,
"City": null,
"Country": "FR",
"Email": "foo@example.com",
"Phone": null,
"Mobile": null,
"ExternalCode": "foo",
"Civility": null
}"""
BOOKING_RESPONSE = """{
"bookingCode": "II0000013",
"ReturnCode": 0,
"Error": null
}"""
SCHOOL_LEVELS_RESPONSE = """{
"ListOfSettings": [
{
"Code": "00",
"Label": "Maternelle"
},
{
"Code": "01",
"Label": "Cp"
},
{
"Code": "02",
"Label": "Ce1-Ce2"
},
{
"Code": "03",
"Label": "Cm1-Cm2"
}
],
"ReturnCode": 0,
"Error": null
}"""
@pytest.fixture
def connector(db):
return tests.utils.setup_access_rights(
VivaTicket.objects.create(
slug='test', login='foo', password='bar', url='http://example.net/vivaticket'
)
)
@mock.patch('passerelle.utils.Request.post')
def test_get_api_key(mocked_post, app, connector):
with pytest.raises(APIError):
mocked_post.return_value = tests.utils.FakedResponse(content=ERROR_RESPONSE, ok=False)
connector.get_apikey()
mocked_post.return_value = tests.utils.FakedResponse(content=KEY_RESPONSE, ok=True)
connector.get_apikey()
assert mocked_post.call_count == 2
assert 'Connect/PostConnect' in mocked_post.call_args[0][0]
assert mocked_post.call_args[1]['json']['Login'] == 'foo'
assert mocked_post.call_args[1]['json']['Password'] == 'bar'
# make sure the key from cache is used
connector.get_apikey()
assert mocked_post.call_count == 2
connector.get_apikey(True)
assert mocked_post.call_count == 3
@mock.patch('passerelle.utils.Request.post')
@mock.patch('passerelle.utils.Request.get')
def test_get_events(mocked_get, mocked_post, app, connector):
mocked_get.return_value = tests.utils.FakedResponse(content=EVENTS_RESPONSE, status_code=200)
mocked_post.return_value = tests.utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
result = tests.utils.endpoint_get('/vivaticket/test/events', app, connector, 'events')
assert mocked_post.call_count == 1
assert mocked_get.call_args[1]['params']['key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074'
assert 'data' in result.json
for item in result.json['data']:
assert 'id' in item
assert 'text' in item
@mock.patch('passerelle.utils.Request.post')
@mock.patch('passerelle.utils.Request.get')
def test_get_events_with_expired_key(mocked_get, mocked_post, app, connector):
mocked_get.return_value = tests.utils.FakedResponse(content=EVENTS_RESPONSE, status_code=401)
mocked_post.return_value = tests.utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
tests.utils.endpoint_get('/vivaticket/test/events', app, connector, 'events')
assert mocked_post.call_count == 2
@mock.patch('passerelle.utils.Request.post')
@mock.patch('passerelle.utils.Request.get')
def test_get_rooms(mocked_get, mocked_post, app, connector):
mocked_get.return_value = tests.utils.FakedResponse(content=ROOMS_RESPONSE, status_code=200)
mocked_post.return_value = tests.utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
result = tests.utils.endpoint_get('/vivaticket/test/rooms', app, connector, 'rooms')
assert mocked_get.call_args[1]['params']['key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074'
assert 'data' in result.json
for item in result.json['data']:
assert 'id' in item
assert 'text' in item
result = tests.utils.endpoint_get(
'/vivaticket/test/rooms', app, connector, 'rooms', params={'event': '02'}
)
assert mocked_get.call_args[1]['params']['eventCategory'] == '02'
@mock.patch('passerelle.utils.Request.post')
@mock.patch('passerelle.utils.Request.get')
def test_get_themes(mocked_get, mocked_post, app, connector):
mocked_get.return_value = tests.utils.FakedResponse(content=ROOMS_RESPONSE, status_code=200)
mocked_post.return_value = tests.utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
result = tests.utils.endpoint_get('/vivaticket/test/themes', app, connector, 'themes')
assert mocked_get.call_args[1]['params']['key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074'
assert 'data' in result.json
for item in result.json['data']:
assert 'id' in item
assert 'text' in item
result = tests.utils.endpoint_get(
'/vivaticket/test/themes', app, connector, 'themes', params={'room': '001'}
)
assert mocked_get.call_args[1]['params']['room'] == '001'
@mock.patch('passerelle.utils.Request.post')
@mock.patch('passerelle.utils.Request.get')
def test_get_school_levels(mocked_get, mocked_post, app, connector):
mocked_get.return_value = tests.utils.FakedResponse(content=SCHOOL_LEVELS_RESPONSE, status_code=200)
mocked_post.return_value = tests.utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
result = tests.utils.endpoint_get('/vivaticket/test/school-levels', app, connector, 'school-levels')
assert mocked_get.call_args[1]['params']['key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074'
assert 'data' in result.json
for item in result.json['data']:
assert 'id' in item
assert 'text' in item
@mock.patch('passerelle.utils.Request.post')
@mock.patch('passerelle.utils.Request.put')
@mock.patch('passerelle.utils.Request.get')
def test_get_or_create_contact(mocked_get, mocked_put, mocked_post, app, connector):
mocked_get.return_value = tests.utils.FakedResponse(content='', ok=False)
mocked_post.side_effect = [
tests.utils.FakedResponse(content=KEY_RESPONSE, status_code=200),
tests.utils.FakedResponse(
content='{"InternalCode": "0000000273", "ReturnCode": 0, "Error": null}', status_code=200
),
]
assert connector.get_or_create_contact({'email': 'foo@example.com'}) == {'InternalCode': '0000000273'}
assert mocked_get.call_args[1]['params']['externalCode'] == 'b48def645758b95537d4'
assert mocked_get.call_args[1]['params']['email'] == 'foo@example.com'
mocked_put.assert_not_called()
assert mocked_post.call_args[1]['json']['Key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074'
assert mocked_post.call_args[1]['json']['Contact']['Email'] == 'foo@example.com'
assert mocked_post.call_args[1]['json']['Contact']['ExternalCode'] == 'b48def645758b95537d4'
mocked_post.return_value = tests.utils.FakedResponse(
content='{"InternalCode": "0000000273", "ReturnCode": 0, "Error": null}', status_code=200
)
mocked_get.return_value = tests.utils.FakedResponse(content=CONTACT_RESPONSE, ok=True)
mocked_put.return_value = tests.utils.FakedResponse(content='', status_code=204)
connector.get_or_create_contact({'email': 'foo@example.com'})
mocked_put.assert_called()
assert mocked_put.call_args[1]['params']['id'] == '0000000273'
assert mocked_put.call_args[1]['json']['Key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074'
assert mocked_put.call_args[1]['json']['Contact']['Email'] == 'foo@example.com'
@mock.patch('passerelle.utils.Request.post')
@mock.patch('passerelle.utils.Request.put')
@mock.patch('passerelle.utils.Request.get')
def test_book(mocked_get, mocked_put, mocked_post, app, connector):
mocked_get.return_value = tests.utils.FakedResponse(content=CONTACT_RESPONSE, status_code=200)
url = tests.utils.generic_endpoint_url('vivaticket', 'book')
payload = {'id': 'formid', 'email': 'foo@example.com'}
response = app.post_json(url, params=payload, status=400)
payload['start_datetime'] = '2019-01-15'
payload['end_datetime'] = '2019-01-15'
payload['event'] = '01'
payload['theme'] = '001'
payload['room'] = 'v001'
payload['school_level'] = '01'
payload['quantity'] = '01'
payload['booking_comment'] = 'Booking comment'
payload['room_comment'] = 'Room comment'
payload['form_url'] = 'http://mysite.com/form/id/'
response = app.post_json(url, params=payload, status=400)
assert "does not match '^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}$" in response.json['err_desc']
payload['start_datetime'] = '2019-01-15T10:00'
payload['end_datetime'] = '2019-01-15T11:00'
# first return the API key, then the result of the booking creation
mocked_post.side_effect = [
tests.utils.FakedResponse(content=KEY_RESPONSE, status_code=200),
tests.utils.FakedResponse(content=BOOKING_RESPONSE),
Exception(),
]
response = app.post_json(url, params=payload)
assert mocked_post.call_args[1]['json']['Key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074'
assert mocked_post.call_args[1]['json']['Booking']['externalCode'] == 'formid'
assert mocked_post.call_args[1]['json']['Booking']['startDateTime'] == '2019-01-15T10:00'
assert mocked_post.call_args[1]['json']['Booking']['endDateTime'] == '2019-01-15T11:00'
assert mocked_post.call_args[1]['json']['Booking']['comment'] == 'Booking comment'
assert mocked_post.call_args[1]['json']['Booking']['roomList'][0]['comment'] == 'Room comment'
assert mocked_post.call_args[1]['json']['Booking']['roomList'][0]['quantity'] == 1
assert mocked_post.call_args[1]['json']['Booking']['roomList'][0]['schoolLevelCode'] == '01'
assert mocked_post.call_args[1]['json']['Booking']['contact'] == {'InternalCode': '0000000273'}
assert mocked_post.call_args[1]['headers'] == {'X-Vivaticket-Form-URL': 'http://mysite.com/form/id/'}
assert response.json['data']['bookingCode'] == 'II0000013'
# no more need to fake key response because the key is in cache
mocked_post.side_effect = [
tests.utils.FakedResponse(text='This external booking code already exists.', ok=False)
]
response = app.post_json(url, params=payload)
assert response.json['err'] == 1
assert response.json['err_desc'] == 'This external booking code already exists.'
assert response.json['err_class'] == 'passerelle.utils.jsonresponse.APIError'