chrono/tests/api/test_subscription.py

1120 lines
41 KiB
Python

import datetime
import pytest
from django.utils.timezone import make_aware, now
from chrono.agendas.models import Agenda, Booking, Event, Subscription
pytestmark = pytest.mark.django_db
def test_api_list_subscription(app, user):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
subscription = Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
user_first_name='Foo',
user_last_name='BAR',
user_email='foo@bar.com',
user_phone_number='06',
extra_data={'foo': 'bar'},
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
resp = app.get('/api/agenda/%s/subscription/' % agenda.slug, status=401)
app.authorization = ('Basic', ('john.doe', 'password'))
resp = app.get('/api/agenda/%s/subscription/' % agenda.slug)
assert len(resp.json['data']) == 1
assert resp.json['data'][0] == {
'id': subscription.pk,
'user_external_id': 'xxx',
'user_first_name': 'Foo',
'user_last_name': 'BAR',
'user_email': 'foo@bar.com',
'user_phone_number': '06',
'date_start': '2021-09-01',
'date_end': '2021-10-01',
'extra_data': {
'foo': 'bar',
},
}
def test_api_list_subscription_filter_user_external_id(app, user):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
subscription1 = Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
subscription2 = Subscription.objects.create(
agenda=agenda,
user_external_id='yyy',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
other_agenda = Agenda.objects.create(label='Foo bar 2', kind='events')
Subscription.objects.create(
agenda=other_agenda,
user_external_id='xxx',
date_start=datetime.date(year=2000, month=1, day=1),
date_end=datetime.date(year=2099, month=12, day=31),
)
app.authorization = ('Basic', ('john.doe', 'password'))
resp = app.get('/api/agenda/%s/subscription/' % agenda.slug, params={'user_external_id': 'xxx'})
assert [d['id'] for d in resp.json['data']] == [subscription1.pk]
resp = app.get('/api/agenda/%s/subscription/' % agenda.slug, params={'user_external_id': 'yyy'})
assert [d['id'] for d in resp.json['data']] == [subscription2.pk]
resp = app.get('/api/agenda/%s/subscription/' % agenda.slug, params={'user_external_id': 'zzz'})
assert [d['id'] for d in resp.json['data']] == []
def test_api_list_subscription_filter_date_overlaps(app, user):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
subscription1 = Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
subscription2 = Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
date_start=datetime.date(year=2022, month=9, day=1),
date_end=datetime.date(year=2022, month=10, day=1),
)
app.authorization = ('Basic', ('john.doe', 'password'))
resp = app.get(
'/api/agenda/%s/subscription/' % agenda.slug,
params={'date_start': '2021-08-31', 'date_end': '2021-09-01'},
)
assert [d['id'] for d in resp.json['data']] == []
resp = app.get(
'/api/agenda/%s/subscription/' % agenda.slug,
params={'date_start': '2021-08-31', 'date_end': '2021-09-02'},
)
assert [d['id'] for d in resp.json['data']] == [subscription1.pk]
resp = app.get(
'/api/agenda/%s/subscription/' % agenda.slug,
params={'date_start': '2021-09-02', 'date_end': '2021-09-30'},
)
assert [d['id'] for d in resp.json['data']] == [subscription1.pk]
resp = app.get(
'/api/agenda/%s/subscription/' % agenda.slug,
params={'date_start': '2021-09-30', 'date_end': '2021-10-01'},
)
assert [d['id'] for d in resp.json['data']] == [subscription1.pk]
resp = app.get(
'/api/agenda/%s/subscription/' % agenda.slug,
params={'date_start': '2021-10-01', 'date_end': '2021-10-02'},
)
assert [d['id'] for d in resp.json['data']] == []
resp = app.get(
'/api/agenda/%s/subscription/' % agenda.slug,
params={'date_start': '2021-09-15', 'date_end': '2022-09-15'},
)
assert [d['id'] for d in resp.json['data']] == [subscription1.pk, subscription2.pk]
resp = app.get(
'/api/agenda/%s/subscription/' % agenda.slug,
params={'date_start': 'wrong-format', 'date_end': '2021-09-01'},
status=400,
)
assert resp.json['err_class'] == 'invalid filters'
resp = app.get(
'/api/agenda/%s/subscription/' % agenda.slug,
params={'date_start': '2021-08-31', 'date_end': 'wrong-format'},
status=400,
)
assert resp.json['err_class'] == 'invalid filters'
resp = app.get(
'/api/agenda/%s/subscription/' % agenda.slug, params={'date_start': '2021-08-31'}, status=400
)
assert resp.json['err_class'] == 'invalid filters'
assert resp.json['errors']['date_end'] == 'This filter is required when using "date_start" filter.'
resp = app.get(
'/api/agenda/%s/subscription/' % agenda.slug, params={'date_end': '2021-09-01'}, status=400
)
assert resp.json['err_class'] == 'invalid filters'
assert resp.json['errors']['date_start'] == 'This filter is required when using "date_end" filter.'
def test_api_create_subscription(app, user):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
resp = app.post('/api/agenda/%s/subscription/' % agenda.slug, status=401)
app.authorization = ('Basic', ('john.doe', 'password'))
params = {
'user_external_id': 'xxx',
'user_first_name': 'Foo',
'user_last_name': 'BAR',
'user_email': 'foo@bar.com',
'user_phone_number': '06',
'date_start': '2021-09-01',
'date_end': '2021-10-01',
'foo': 'bar',
}
resp = app.post('/api/agenda/%s/subscription/' % agenda.slug, params=params)
subscription = Subscription.objects.get(pk=resp.json['id'])
assert subscription.agenda == agenda
assert subscription.user_external_id == 'xxx'
assert subscription.user_first_name == 'Foo'
assert subscription.user_last_name == 'BAR'
assert subscription.user_email == 'foo@bar.com'
assert subscription.user_phone_number == '06'
assert subscription.extra_data == {'foo': 'bar'}
assert subscription.date_start == datetime.date(year=2021, month=9, day=1)
assert subscription.date_end == datetime.date(year=2021, month=10, day=1)
subscription.delete()
params = {
'user_external_id': 'xxx',
'user_first_name': 'Foo',
'user_last_name': 'BAR',
'date_start': '2021-09-01',
'date_end': '2021-10-01',
}
resp = app.post('/api/agenda/%s/subscription/' % agenda.slug, params=params)
subscription = Subscription.objects.get(pk=resp.json['id'])
assert subscription.agenda == agenda
assert subscription.user_external_id == 'xxx'
assert subscription.user_first_name == 'Foo'
assert subscription.user_last_name == 'BAR'
assert subscription.user_email == ''
assert subscription.user_phone_number == ''
assert subscription.extra_data == {}
assert subscription.date_start == datetime.date(year=2021, month=9, day=1)
assert subscription.date_end == datetime.date(year=2021, month=10, day=1)
# check errors
resp = app.post('/api/agenda/%s/subscription/' % agenda.slug, params={}, status=400)
assert resp.json['err_class'] == 'invalid payload'
for field in ('user_external_id', 'user_first_name', 'user_last_name', 'date_start', 'date_end'):
assert 'required' in resp.json['errors'][field][0]
params = {
'user_external_id': 'xxx',
'user_first_name': 'Foo',
'user_last_name': 'BAR',
'date_start': 'wrong-format',
'date_end': 'wrong-format',
}
resp = app.post('/api/agenda/%s/subscription/' % agenda.slug, params=params, status=400)
assert resp.json['err_class'] == 'invalid payload'
assert 'wrong format' in resp.json['errors']['date_start'][0]
assert 'wrong format' in resp.json['errors']['date_end'][0]
params = {
'user_external_id': 'xxx',
'user_first_name': 'Foo',
'user_last_name': 'BAR',
'date_start': '2021-10-01',
'date_end': '2021-09-01',
}
resp = app.post('/api/agenda/%s/subscription/' % agenda.slug, params=params, status=400)
assert resp.json['errors']['non_field_errors'][0] == 'start_datetime must be before end_datetime'
def test_api_create_subscription_check_dates(app, user):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
Subscription.objects.create(
agenda=agenda,
user_external_id='yyy', # another user
date_start=datetime.date(year=2021, month=8, day=1),
date_end=datetime.date(year=2021, month=9, day=1),
)
other_agenda = Agenda.objects.create(label='Foo bar', kind='events')
Subscription.objects.create(
agenda=other_agenda, # another agenda
user_external_id='xxx',
date_start=datetime.date(year=2021, month=8, day=1),
date_end=datetime.date(year=2021, month=9, day=1),
)
app.authorization = ('Basic', ('john.doe', 'password'))
params = {
'user_external_id': 'xxx',
'user_first_name': 'Foo',
'user_last_name': 'BAR',
'date_start': '2021-09-10',
'date_end': '2021-09-20',
}
resp = app.post('/api/agenda/%s/subscription/' % agenda.slug, params=params, status=400)
assert resp.json['err_desc'] == 'another subscription overlapping this period already exists'
params.update(
{
'date_start': '2021-09-01',
'date_end': '2021-10-01',
}
)
resp = app.post('/api/agenda/%s/subscription/' % agenda.slug, params=params, status=400)
assert resp.json['err_desc'] == 'another subscription overlapping this period already exists'
params.update(
{
'date_start': '2021-08-01',
'date_end': '2021-09-02',
}
)
resp = app.post('/api/agenda/%s/subscription/' % agenda.slug, params=params, status=400)
assert resp.json['err_desc'] == 'another subscription overlapping this period already exists'
params.update(
{
'date_start': '2021-09-30',
'date_end': '2021-11-01',
}
)
resp = app.post('/api/agenda/%s/subscription/' % agenda.slug, params=params, status=400)
assert resp.json['err_desc'] == 'another subscription overlapping this period already exists'
params.update(
{
'date_start': '2021-08-01',
'date_end': '2021-09-01',
}
)
resp = app.post('/api/agenda/%s/subscription/' % agenda.slug, params=params)
assert resp.json['err'] == 0
params.update(
{
'date_start': '2021-10-01',
'date_end': '2021-11-01',
}
)
resp = app.post('/api/agenda/%s/subscription/' % agenda.slug, params=params)
assert resp.json['err'] == 0
def test_api_get_subscription(app, user):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
subscription = Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
user_first_name='Foo',
user_last_name='BAR',
user_email='foo@bar.com',
user_phone_number='06',
extra_data={'foo': 'bar'},
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
other_agenda = Agenda.objects.create(label='Foo bar', kind='events')
other_subscription = Subscription.objects.create(
agenda=other_agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
resp = app.get('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), status=401)
app.authorization = ('Basic', ('john.doe', 'password'))
resp = app.get('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk))
assert resp.json == {
'id': subscription.pk,
'user_external_id': 'xxx',
'user_first_name': 'Foo',
'user_last_name': 'BAR',
'user_email': 'foo@bar.com',
'user_phone_number': '06',
'date_start': '2021-09-01',
'date_end': '2021-10-01',
'extra_data': {
'foo': 'bar',
},
'err': 0,
}
resp = app.get('/api/agenda/%s/subscription/%s/' % (other_agenda.slug, other_subscription.pk))
assert resp.json == {
'id': other_subscription.pk,
'user_external_id': 'xxx',
'user_first_name': '',
'user_last_name': '',
'user_email': '',
'user_phone_number': '',
'date_start': '2021-09-01',
'date_end': '2021-10-01',
'extra_data': None,
'err': 0,
}
app.get('/api/agenda/%s/subscription/%s/' % (agenda.slug, other_subscription.pk), status=404)
app.get('/api/agenda/%s/subscription/%s/' % (agenda.slug, 0), status=404)
app.get('/api/agenda/%s/subscription/%s/' % ('unknown', subscription.pk), status=404)
for kind in ['meetings', 'virtual']:
agenda.kind = kind
agenda.save()
app.get('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), status=404)
def test_api_delete_subscription(app, user):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
subscription = Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
user_first_name='Foo',
user_last_name='BAR',
user_email='foo@bar.com',
user_phone_number='06',
extra_data={'foo': 'bar'},
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
other_agenda = Agenda.objects.create(label='Foo bar', kind='events')
other_subscription = Subscription.objects.create(
agenda=other_agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
resp = app.delete('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), status=401)
app.authorization = ('Basic', ('john.doe', 'password'))
app.delete('/api/agenda/%s/subscription/%s/' % (agenda.slug, other_subscription.pk), status=404)
app.delete('/api/agenda/%s/subscription/%s/' % (agenda.slug, 0), status=404)
app.delete('/api/agenda/%s/subscription/%s/' % ('unknown', subscription.pk), status=404)
for kind in ['meetings', 'virtual']:
agenda.kind = kind
agenda.save()
app.delete('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), status=404)
agenda.kind = 'events'
agenda.save()
resp = app.delete('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk))
assert resp.json['err'] == 0
assert Subscription.objects.filter(pk=subscription.pk).exists() is False
@pytest.mark.parametrize(
'date_now, event_date, user_id, in_waiting_list, cancelled, deleted',
[
# event in the future, but no booking for the user
('2021-09-09 09:59', (2021, 9, 10, 12, 0), 'yyy', False, False, False),
# event in the future
('2021-09-09 09:59', (2021, 9, 10, 12, 0), 'xxx', False, False, True),
('2021-09-09 09:59', (2021, 9, 10, 12, 0), 'xxx', True, False, True),
('2021-09-09 09:59', (2021, 9, 10, 12, 0), 'xxx', False, True, True),
# event in the past
('2021-09-10 10:00', (2021, 9, 10, 12, 0), 'xxx', False, False, False),
# event in the future, before the period
('2021-08-01 10:00', (2021, 8, 14, 12, 0), 'xxx', False, False, False),
('2021-08-01 10:00', (2021, 8, 31, 12, 0), 'xxx', False, False, False),
# event in the future, after the period
('2021-08-01 10:00', (2021, 10, 1, 12, 0), 'xxx', False, False, False),
('2021-08-01 10:00', (2021, 10, 16, 12, 0), 'xxx', False, False, False),
],
)
def test_api_delete_subscription_and_bookings(
app, user, freezer, date_now, event_date, user_id, in_waiting_list, cancelled, deleted
):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
subscription = Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
Subscription.objects.create(
agenda=agenda,
user_external_id='zzz', # another user
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
other_agenda = Agenda.objects.create(label='Foo bar', kind='events')
Subscription.objects.create(
agenda=other_agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
app.authorization = ('Basic', ('john.doe', 'password'))
freezer.move_to(date_now)
event = Event.objects.create(
agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
)
booking = Booking.objects.create(
event=event,
user_external_id=user_id,
in_waiting_list=in_waiting_list,
cancellation_datetime=(now() if cancelled else None),
)
resp = app.delete('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk))
assert resp.json['err'] == 0
assert Subscription.objects.filter(pk=subscription.pk).exists() is False
assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
@pytest.mark.parametrize(
'event_date, deleted',
[
# just before first day
((2021, 8, 31, 12, 00), False),
# first day
((2021, 9, 1, 12, 00), True),
# last day
((2021, 9, 30, 12, 00), True),
# just after last day
((2021, 10, 1, 12, 00), False),
],
)
def test_api_delete_subscription_and_bookings_on_limit(app, user, freezer, event_date, deleted):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
subscription = Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
app.authorization = ('Basic', ('john.doe', 'password'))
freezer.move_to('2021-08-01 10:00')
event = Event.objects.create(
agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
)
booking = Booking.objects.create(
event=event,
user_external_id='xxx',
)
resp = app.delete('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk))
assert resp.json['err'] == 0
assert Subscription.objects.filter(pk=subscription.pk).exists() is False
assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
def test_api_patch_subscription(app, user):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
subscription = Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
user_first_name='Foo',
user_last_name='BAR',
user_email='foo@bar.com',
user_phone_number='06',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
other_agenda = Agenda.objects.create(label='Foo bar', kind='events')
other_subscription = Subscription.objects.create(
agenda=other_agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), status=401)
app.authorization = ('Basic', ('john.doe', 'password'))
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk))
assert resp.json == {
'id': subscription.pk,
'user_external_id': 'xxx',
'user_first_name': 'Foo',
'user_last_name': 'BAR',
'user_email': 'foo@bar.com',
'user_phone_number': '06',
'date_start': '2021-09-01',
'date_end': '2021-10-01',
'extra_data': None,
'err': 0,
}
# user_external_id is not updatable
params = {
'user_external_id': 'xxx',
}
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
assert resp.json['user_external_id'] == 'xxx'
subscription.refresh_from_db()
assert subscription.user_external_id == 'xxx'
params = {
'user_external_id': 'foobar',
}
resp = app.patch(
'/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params, status=400
)
assert resp.json['err_class'] == 'it is not possible to change user_external_id value'
to_test = [
('user_first_name', 'fooo', 'fooo'),
('user_last_name', 'baaaar', 'baaaar'),
('user_email', '', ''),
('user_email', 'fooo@baaaar.com', 'fooo@baaaar.com'),
('user_phone_number', '', ''),
('user_phone_number', '0606', '0606'),
('date_start', '2021-08-31', datetime.date(2021, 8, 31)),
('date_end', '2022-07-31', datetime.date(2022, 7, 31)),
]
for key, value, db_value in to_test:
params = {
key: value,
}
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
assert resp.json[key] == value
subscription.refresh_from_db()
assert getattr(subscription, key) == db_value
params = {
'foo': 'bar',
}
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
assert resp.json['extra_data'] == {'foo': 'bar'}
subscription.refresh_from_db()
assert subscription.extra_data == {'foo': 'bar'}
params = {
'foo': 'bar2',
}
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
assert resp.json['extra_data'] == {'foo': 'bar2'}
subscription.refresh_from_db()
assert subscription.extra_data == {'foo': 'bar2'}
params = {
'user_phone_number': '060606', # mix normal attribute and extra_data
'bar': 'baz',
}
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
assert resp.json['user_phone_number'] == '060606'
assert resp.json['extra_data'] == {'foo': 'bar2', 'bar': 'baz'}
subscription.refresh_from_db()
assert subscription.user_phone_number == '060606'
assert subscription.extra_data == {'foo': 'bar2', 'bar': 'baz'}
params = {
'date_start': 'foobar',
'date_end': 'foobar',
}
resp = app.patch(
'/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params, status=400
)
assert resp.json['err_class'] == 'invalid payload'
assert 'wrong format' in resp.json['errors']['date_start'][0]
assert 'wrong format' in resp.json['errors']['date_end'][0]
params = {
'date_start': '2021-10-01',
'date_end': '2021-09-01',
}
resp = app.patch(
'/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params, status=400
)
assert resp.json['errors']['non_field_errors'][0] == 'start_datetime must be before end_datetime'
app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, other_subscription.pk), status=404)
app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, 0), status=404)
app.patch('/api/agenda/%s/subscription/%s/' % ('unknown', subscription.pk), status=404)
for kind in ['meetings', 'virtual']:
agenda.kind = kind
agenda.save()
app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), status=404)
def test_api_patch_subscription_check_dates(app, user):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
Subscription.objects.create(
agenda=agenda,
user_external_id='yyy', # another user
date_start=datetime.date(year=2021, month=8, day=1),
date_end=datetime.date(year=2021, month=9, day=1),
)
other_agenda = Agenda.objects.create(label='Foo bar', kind='events')
Subscription.objects.create(
agenda=other_agenda, # another agenda
user_external_id='xxx',
date_start=datetime.date(year=2021, month=8, day=1),
date_end=datetime.date(year=2021, month=9, day=1),
)
# subscription to update
subscription = Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=8, day=1),
date_end=datetime.date(year=2021, month=9, day=1),
)
app.authorization = ('Basic', ('john.doe', 'password'))
params = {
'date_end': '2021-09-02',
}
resp = app.patch(
'/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params, status=400
)
assert resp.json['err_desc'] == 'another subscription overlapping this period already exists'
params = {
'date_start': '2021-09-10',
'date_end': '2021-09-20',
}
resp = app.patch(
'/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params, status=400
)
assert resp.json['err_desc'] == 'another subscription overlapping this period already exists'
params = {
'date_start': '2021-09-01',
'date_end': '2021-10-01',
}
resp = app.patch(
'/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params, status=400
)
assert resp.json['err_desc'] == 'another subscription overlapping this period already exists'
params = {
'date_start': '2021-08-01',
'date_end': '2021-09-02',
}
resp = app.patch(
'/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params, status=400
)
assert resp.json['err_desc'] == 'another subscription overlapping this period already exists'
params = {
'date_start': '2021-09-30',
'date_end': '2021-11-01',
}
resp = app.patch(
'/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params, status=400
)
assert resp.json['err_desc'] == 'another subscription overlapping this period already exists'
params = {
'date_start': '2021-08-01',
'date_end': '2021-09-01',
}
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
assert resp.json['err'] == 0
params = {
'date_start': '2021-10-01',
'date_end': '2021-11-01',
}
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
assert resp.json['err'] == 0
params = {
'date_start': '2021-09-30',
}
resp = app.patch(
'/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params, status=400
)
assert resp.json['err_desc'] == 'another subscription overlapping this period already exists'
@pytest.mark.parametrize(
'date_now, event_date, user_id, in_waiting_list, cancelled, deleted',
[
# event in the future, but no booking for the user
('2021-09-04 09:59', (2021, 9, 4, 12, 0), 'yyy', False, False, False),
# event in the future
('2021-09-04 09:59', (2021, 9, 4, 12, 0), 'xxx', False, False, True),
('2021-09-04 09:59', (2021, 9, 4, 12, 0), 'xxx', True, False, True),
('2021-09-04 09:59', (2021, 9, 4, 12, 0), 'xxx', False, True, True),
# event in the past
('2021-09-04 10:00', (2021, 9, 4, 12, 0), 'xxx', False, False, False),
# event in the future, before the period
('2021-08-01 10:00', (2021, 8, 14, 12, 0), 'xxx', False, False, False),
('2021-08-01 10:00', (2021, 8, 31, 12, 0), 'xxx', False, False, False),
# event in the future, after the period
('2021-08-01 10:00', (2021, 10, 1, 12, 0), 'xxx', False, False, False),
('2021-08-01 10:00', (2021, 10, 16, 12, 0), 'xxx', False, False, False),
],
)
def test_api_patch_subscription_date_changes_delete_bookings(
app, user, freezer, date_now, event_date, user_id, in_waiting_list, cancelled, deleted
):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
subscription = Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
Subscription.objects.create(
agenda=agenda,
user_external_id='zzz', # another user
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
other_agenda = Agenda.objects.create(label='Foo bar', kind='events')
Subscription.objects.create(
agenda=other_agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
app.authorization = ('Basic', ('john.doe', 'password'))
freezer.move_to(date_now)
event = Event.objects.create(
agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
)
booking = Booking.objects.create(
event=event,
user_external_id=user_id,
in_waiting_list=in_waiting_list,
cancellation_datetime=(now() if cancelled else None),
)
# date_start is postponed, date_end is brought forward
params = {
'date_start': '2021-09-05',
'date_end': '2021-09-25',
}
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
assert resp.json['err'] == 0
assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
@pytest.mark.parametrize(
'event_date, deleted',
[
# just before old first day
((2021, 8, 31, 12, 00), False),
# old first day
((2021, 9, 1, 12, 00), True),
# old last day
((2021, 9, 30, 12, 00), True),
# just after old last day
((2021, 10, 1, 12, 00), False),
],
)
def test_api_patch_subscription_date_changes_delete_bookings_forwards_no_overlaps(
app, user, freezer, event_date, deleted
):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
subscription = Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
app.authorization = ('Basic', ('john.doe', 'password'))
freezer.move_to('2021-08-01 10:00')
event = Event.objects.create(
agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
)
booking = Booking.objects.create(
event=event,
user_external_id='xxx',
)
# subscription moved forwards, no overlaps
params = {
'date_start': '2021-11-01',
'date_end': '2021-12-01',
}
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
assert resp.json['err'] == 0
assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
@pytest.mark.parametrize(
'event_date, deleted',
[
# just before old first day
((2021, 8, 31, 12, 00), False),
# old first day
((2021, 9, 1, 12, 00), True),
# old last day
((2021, 9, 30, 12, 00), True),
# just after old last day
((2021, 10, 1, 12, 00), False),
],
)
def test_api_patch_subscription_date_changes_delete_bookings_backwards_no_overlaps(
app, user, freezer, event_date, deleted
):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
subscription = Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
app.authorization = ('Basic', ('john.doe', 'password'))
freezer.move_to('2021-06-01 10:00')
event = Event.objects.create(
agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
)
booking = Booking.objects.create(
event=event,
user_external_id='xxx',
)
# subscription moved backwards, no overlaps
params = {
'date_start': '2021-07-01',
'date_end': '2021-08-01',
}
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
assert resp.json['err'] == 0
assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
@pytest.mark.parametrize(
'event_date, deleted',
[
# just before old first day
((2021, 8, 31, 12, 00), False),
# old first day
((2021, 9, 1, 12, 00), True),
# just before new first day
((2021, 9, 4, 12, 00), True),
# new first day
((2021, 9, 5, 12, 00), False),
# new last day
((2021, 9, 25, 12, 00), False),
# just after new last day
((2021, 9, 26, 12, 00), True),
# old last day
((2021, 9, 30, 12, 00), True),
# just after old last day
((2021, 10, 1, 12, 00), False),
],
)
def test_api_patch_subscription_date_changes_delete_bookings_shorter_period(
app, user, freezer, event_date, deleted
):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
subscription = Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
app.authorization = ('Basic', ('john.doe', 'password'))
freezer.move_to('2021-08-01 10:00')
event = Event.objects.create(
agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
)
booking = Booking.objects.create(
event=event,
user_external_id='xxx',
)
# date_start is postponed, date_end is brought forward
params = {
'date_start': '2021-09-05',
'date_end': '2021-09-26',
}
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
assert resp.json['err'] == 0
assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
@pytest.mark.parametrize(
'event_date, deleted',
[
# just before old first day
((2021, 8, 31, 12, 00), False),
# old first day
((2021, 9, 1, 12, 00), True),
# just before new first day
((2021, 9, 14, 12, 00), True),
# new first day
((2021, 9, 15, 12, 00), False),
# old last day
((2021, 9, 30, 12, 00), False),
# just before old last day
((2021, 10, 1, 12, 00), False),
],
)
def test_api_patch_subscription_date_changes_delete_bookings_forwards_with_overlaps(
app, user, freezer, event_date, deleted
):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
subscription = Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
app.authorization = ('Basic', ('john.doe', 'password'))
freezer.move_to('2021-08-01 10:00')
event = Event.objects.create(
agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
)
booking = Booking.objects.create(
event=event,
user_external_id='xxx',
)
# subscription moved forwards, with overlaps
params = {
'date_start': '2021-09-15',
'date_end': '2021-10-15',
}
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
assert resp.json['err'] == 0
assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
@pytest.mark.parametrize(
'event_date, deleted',
[
# just before old first day
((2021, 8, 31, 12, 00), False),
# old first day
((2021, 9, 1, 12, 00), False),
# new last day
((2021, 9, 15, 12, 00), False),
# just after new last day
((2021, 9, 16, 12, 00), True),
# old last day
((2021, 9, 30, 12, 00), True),
# just after old last day
((2021, 10, 1, 12, 00), False),
],
)
def test_api_patch_subscription_date_changes_delete_bookings_backwards_with_overlaps(
app, user, freezer, event_date, deleted
):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
subscription = Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
app.authorization = ('Basic', ('john.doe', 'password'))
freezer.move_to('2021-08-01 10:00')
event = Event.objects.create(
agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
)
booking = Booking.objects.create(
event=event,
user_external_id='xxx',
)
# subscription moved backwards, with overlaps
params = {
'date_start': '2021-08-15',
'date_end': '2021-09-16',
}
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
assert resp.json['err'] == 0
assert Booking.objects.filter(pk=booking.pk).exists() is not deleted
@pytest.mark.parametrize(
'date_now, event_date, user_id, in_waiting_list, cancelled, updated',
[
# event in the future, but no booking for the user
('2021-09-01 09:59', (2021, 9, 1, 12, 0), 'yyy', False, False, False),
# event in the future
('2021-09-01 09:59', (2021, 9, 1, 12, 0), 'xxx', False, False, True),
('2021-09-01 09:59', (2021, 9, 1, 12, 0), 'xxx', True, False, True),
('2021-09-01 09:59', (2021, 9, 1, 12, 0), 'xxx', False, True, True),
# event in the past
('2021-09-01 10:00', (2021, 9, 1, 12, 0), 'xxx', False, False, False),
# event in the future
('2021-08-01 10:00', (2021, 9, 1, 12, 0), 'xxx', False, False, True),
('2021-08-01 10:00', (2021, 9, 30, 12, 0), 'xxx', False, False, True),
# event in the future, before the period
('2021-08-01 10:00', (2021, 8, 31, 12, 0), 'xxx', False, False, False),
# event in the future, after the period
('2021-08-01 10:00', (2021, 10, 1, 12, 0), 'xxx', False, False, False),
],
)
def test_api_patch_subscription_update_bookings_extra_data(
app, user, freezer, date_now, event_date, user_id, in_waiting_list, cancelled, updated
):
agenda = Agenda.objects.create(label='Foo bar', kind='events')
subscription = Subscription.objects.create(
agenda=agenda,
user_external_id='xxx',
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
app.authorization = ('Basic', ('john.doe', 'password'))
freezer.move_to(date_now)
event = Event.objects.create(
agenda=agenda, start_datetime=make_aware(datetime.datetime(*event_date)), places=10
)
booking = Booking.objects.create(
event=event,
user_external_id=user_id,
in_waiting_list=in_waiting_list,
cancellation_datetime=(now() if cancelled else None),
)
# extra_data is None
params = {
'foo': 'bar',
}
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
assert resp.json['err'] == 0
booking.refresh_from_db()
if updated:
assert booking.extra_data == {'foo': 'bar'}
else:
assert booking.extra_data is None
booking.extra_data = {'some': 'thing'}
booking.save()
# extra_data is not None, update
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
assert resp.json['err'] == 0
booking.refresh_from_db()
if updated:
assert booking.extra_data == {'foo': 'bar', 'some': 'thing'}
else:
assert booking.extra_data == {'some': 'thing'}
# extra_data is not None, merge
params = {
'foo': 'bar2',
}
resp = app.patch('/api/agenda/%s/subscription/%s/' % (agenda.slug, subscription.pk), params=params)
assert resp.json['err'] == 0
booking.refresh_from_db()
if updated:
assert booking.extra_data == {'foo': 'bar2', 'some': 'thing'}
else:
assert booking.extra_data == {'some': 'thing'}