388 lines
12 KiB
Python
388 lines
12 KiB
Python
# -*- coding: utf-8 -*-
|
||
import mock
|
||
import pytest
|
||
import utils
|
||
|
||
from passerelle.apps.vivaticket.models import VivaTicket
|
||
from passerelle.utils.jsonresponse import APIError
|
||
|
||
ERROR_RESPONSE = """{
|
||
"Message": "Une erreur s’est 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 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 = utils.FakedResponse(content=ERROR_RESPONSE, ok=False)
|
||
connector.get_apikey()
|
||
mocked_post.return_value = 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 = utils.FakedResponse(content=EVENTS_RESPONSE, status_code=200)
|
||
mocked_post.return_value = utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
|
||
result = 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 = utils.FakedResponse(content=EVENTS_RESPONSE, status_code=401)
|
||
mocked_post.return_value = utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
|
||
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 = utils.FakedResponse(content=ROOMS_RESPONSE, status_code=200)
|
||
mocked_post.return_value = utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
|
||
result = 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 = 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 = utils.FakedResponse(content=ROOMS_RESPONSE, status_code=200)
|
||
mocked_post.return_value = utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
|
||
result = 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 = 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 = utils.FakedResponse(content=SCHOOL_LEVELS_RESPONSE, status_code=200)
|
||
mocked_post.return_value = utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
|
||
result = 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 = utils.FakedResponse(content='', ok=False)
|
||
mocked_post.side_effect = [
|
||
utils.FakedResponse(content=KEY_RESPONSE, status_code=200),
|
||
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 = utils.FakedResponse(
|
||
content='{"InternalCode": "0000000273", "ReturnCode": 0, "Error": null}', status_code=200
|
||
)
|
||
mocked_get.return_value = utils.FakedResponse(content=CONTACT_RESPONSE, ok=True)
|
||
mocked_put.return_value = 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 = utils.FakedResponse(content=CONTACT_RESPONSE, status_code=200)
|
||
url = 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'] = 1
|
||
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 = [
|
||
utils.FakedResponse(content=KEY_RESPONSE, status_code=200),
|
||
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]['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 = [
|
||
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'
|