lingo/tests/api/test_basket.py

656 lines
27 KiB
Python

import datetime
import decimal
import uuid
import pytest
from lingo.basket.models import Basket, BasketLine, BasketLineItem
from lingo.invoicing.models import DraftInvoice, Regie
pytestmark = pytest.mark.django_db
def test_add_basket(settings, app, user):
app.post('/api/regie/foo/baskets/', status=403)
app.authorization = ('Basic', ('john.doe', 'password'))
resp = app.post('/api/regie/foo/baskets/', status=404)
regie = Regie.objects.create(label='Foo')
resp = app.post('/api/regie/foo/baskets/', status=400)
assert resp.json['err']
assert resp.json['errors'] == {
'payer_nameid': ['This field is required.'],
'payer_external_id': ['This field is required.'],
'payer_first_name': ['This field is required.'],
'payer_last_name': ['This field is required.'],
'payer_address': ['This field is required.'],
}
params = {
'payer_nameid': 'uuid1',
'payer_external_id': 'payer:1',
'payer_first_name': 'First',
'payer_last_name': 'Last',
'payer_address': '41 rue des kangourous\n99999 Kangourou Ville',
}
resp = app.post('/api/regie/foo/baskets/', params=params)
assert Basket.objects.count() == 1
basket = Basket.objects.latest('pk')
assert resp.json == {'err': 0, 'data': {'basket_id': str(basket.uuid)}}
assert basket.regie == regie
assert basket.payer_nameid == 'uuid1'
assert basket.payer_external_id == 'payer:1'
assert basket.payer_first_name == 'First'
assert basket.payer_last_name == 'Last'
assert basket.payer_address == '41 rue des kangourous\n99999 Kangourou Ville'
assert basket.status == 'open'
assert basket.validated_at is None
assert basket.paid_at is None
assert basket.completed_at is None
assert basket.cancelled_at is None
assert basket.expired_at is None
assert basket.created_at is not None
assert basket.expiry_at is not None
assert (basket.expiry_at - basket.created_at) < datetime.timedelta(minutes=60)
assert basket.expiry_at - basket.created_at > datetime.timedelta(minutes=59)
assert DraftInvoice.objects.count() == 1
invoice = DraftInvoice.objects.latest('pk')
assert invoice.label == 'Invoice from %s' % datetime.date.today().strftime('%d/%m/%Y')
assert invoice.total_amount == 0
assert invoice.date_publication == datetime.date.today()
assert invoice.date_payment_deadline == datetime.date.today() + datetime.timedelta(days=1)
assert invoice.date_due == datetime.date.today() + datetime.timedelta(days=1)
assert invoice.date_debit is None
assert invoice.regie == regie
assert invoice.payer_external_id == 'payer:1'
assert invoice.payer_first_name == 'First'
assert invoice.payer_last_name == 'Last'
assert invoice.payer_address == '41 rue des kangourous\n99999 Kangourou Ville'
assert invoice.payer_demat is True
assert invoice.payer_direct_debit is False
assert invoice.pool is None
assert invoice.lines.count() == 0
# basket already open
resp = app.post('/api/regie/foo/baskets/', params=params)
assert resp.json == {'err': 0, 'data': {'basket_id': str(basket.uuid)}}
assert Basket.objects.count() == 1
assert DraftInvoice.objects.count() == 1
# basket to be paid, cannot open another one
basket.status = 'tobepaid'
basket.save()
resp = app.post('/api/regie/foo/baskets/', params=params, status=400)
assert resp.json['err']
assert resp.json['errors'] == {'payer_nameid': ['a basket to finalize already exists']}
# basket completed, cancelled or expired, ok to open another one
for status in ['completed', 'cancelled', 'expired']:
basket.status = status
basket.save()
resp = app.post('/api/regie/foo/baskets/', params=params)
assert resp.json['err'] == 0
assert resp.json['data']['basket_id'] != basket.uuid
Basket.objects.filter(uuid=resp.json['data']['basket_id']).delete()
# basket already open in another regie, cannot open another one
basket.delete()
other_regie = Regie.objects.create(label='Other')
invoice = DraftInvoice.objects.create(
regie=other_regie,
date_publication=datetime.date(2023, 4, 21),
date_payment_deadline=datetime.date(2023, 4, 22),
date_due=datetime.date(2023, 4, 23),
)
basket = Basket.objects.create(regie=other_regie, draft_invoice=invoice, payer_nameid='uuid1')
resp = app.post('/api/regie/foo/baskets/', params=params, status=400)
assert resp.json['err']
assert resp.json['errors'] == {'payer_nameid': ['a basket to finalize already exists']}
basket.status = 'tobepaid'
basket.save()
resp = app.post('/api/regie/foo/baskets/', params=params, status=400)
assert resp.json['err']
assert resp.json['errors'] == {'payer_nameid': ['a basket to finalize already exists']}
settings.BASKET_EXPIRY_DELAY = 30
# basket completed, cancelled or expired in another regie, ok to open another one
for status in ['completed', 'cancelled', 'expired']:
basket.status = status
basket.save()
resp = app.post('/api/regie/foo/baskets/', params=params)
assert resp.json['err'] == 0
assert resp.json['data']['basket_id'] != basket.uuid
new_basket = Basket.objects.latest('pk')
assert new_basket.expiry_at is not None
assert (new_basket.expiry_at - new_basket.created_at) < datetime.timedelta(minutes=30)
assert new_basket.expiry_at - new_basket.created_at > datetime.timedelta(minutes=29)
Basket.objects.filter(uuid=resp.json['data']['basket_id']).delete()
def test_line_available(app, user):
app.get('/api/regie/foo/basket/check/', status=403)
app.authorization = ('Basic', ('john.doe', 'password'))
app.get('/api/regie/bar/basket/check/', status=404)
regie = Regie.objects.create(label='Foo')
resp = app.get('/api/regie/foo/basket/check/', status=400)
assert resp.json['err']
assert resp.json['errors'] == {
'payer_nameid': ['This field is required.'],
'user_external_id': ['This field is required.'],
}
params = {
'payer_nameid': 'uuid1',
'user_external_id': 'user:1',
}
resp = app.get('/api/regie/foo/basket/check/', params=params)
assert resp.json['err'] == 0
# existing basket for other payer_nameid
invoice = DraftInvoice.objects.create(
regie=regie,
date_publication=datetime.date(2023, 4, 21),
date_payment_deadline=datetime.date(2023, 4, 22),
date_due=datetime.date(2023, 4, 23),
)
basket = Basket.objects.create(regie=regie, draft_invoice=invoice, payer_nameid='uuid2')
BasketLine.objects.create(basket=basket, user_external_id='user:1')
resp = app.get('/api/regie/foo/basket/check/', params=params)
assert resp.json['err'] == 0
# existing basket for user, but no line
invoice = DraftInvoice.objects.create(
regie=regie,
date_publication=datetime.date(2023, 4, 21),
date_payment_deadline=datetime.date(2023, 4, 22),
date_due=datetime.date(2023, 4, 23),
)
basket = Basket.objects.create(regie=regie, draft_invoice=invoice, payer_nameid='uuid1')
resp = app.get('/api/regie/foo/basket/check/', params=params)
assert resp.json['err'] == 0
# existing line for another user
BasketLine.objects.create(basket=basket, user_external_id='user:42')
resp = app.get('/api/regie/foo/basket/check/', params=params)
assert resp.json['err'] == 0
# existing line for this user
line = BasketLine.objects.create(basket=basket, user_external_id='user:1')
resp = app.get('/api/regie/foo/basket/check/', params=params, status=400)
assert resp.json['err']
assert resp.json['err_class'] == 'user_existing_line'
assert resp.json['errors'] == {
'user_external_id': ['a line already exists in active basket in this regie for this user_external_id']
}
line.closed = True
line.save()
resp = app.get('/api/regie/foo/basket/check/', params=params, status=400)
assert resp.json['err']
assert resp.json['err_class'] == 'user_existing_line'
assert resp.json['errors'] == {
'user_external_id': ['a line already exists in active basket in this regie for this user_external_id']
}
# check basket status
for status in ['completed', 'cancelled', 'expired']:
basket.status = status
basket.save()
resp = app.get('/api/regie/foo/basket/check/', params=params)
assert resp.json['err'] == 0
for status in ['open', 'tobepaid']:
basket.status = status
basket.save()
resp = app.get('/api/regie/foo/basket/check/', params=params, status=400)
assert resp.json['err']
assert resp.json['err_class'] == 'user_existing_line'
assert resp.json['errors'] == {
'user_external_id': [
'a line already exists in active basket in this regie for this user_external_id'
]
}
# basket already open in another regie
BasketLine.objects.all().delete()
basket.delete()
other_regie = Regie.objects.create(label='Other')
invoice = DraftInvoice.objects.create(
regie=other_regie,
date_publication=datetime.date(2023, 4, 21),
date_payment_deadline=datetime.date(2023, 4, 22),
date_due=datetime.date(2023, 4, 23),
)
basket = Basket.objects.create(regie=other_regie, draft_invoice=invoice, payer_nameid='uuid1')
resp = app.get('/api/regie/foo/basket/check/', params=params, status=400)
assert resp.json['err']
assert resp.json['err_class'] == 'payer_active_basket'
assert resp.json['errors'] == {'payer_nameid': ['a basket to finalize already exists in another regie']}
basket.status = 'tobepaid'
basket.save()
resp = app.get('/api/regie/foo/basket/check/', params=params, status=400)
assert resp.json['err']
assert resp.json['err_class'] == 'payer_active_basket'
assert resp.json['errors'] == {'payer_nameid': ['a basket to finalize already exists in another regie']}
# basket completed, cancelled or expired in another regie, ok to open another one
for status in ['completed', 'cancelled', 'expired']:
basket.status = status
basket.save()
resp = app.get('/api/regie/foo/basket/check/', params=params)
assert resp.json['err'] == 0
def test_add_line(app, user):
app.post('/api/regie/foo/basket/%s/lines/' % uuid.uuid4(), status=403)
app.authorization = ('Basic', ('john.doe', 'password'))
app.post('/api/regie/foo/basket/%s/lines/' % uuid.uuid4(), status=404)
regie = Regie.objects.create(label='Foo')
app.post('/api/regie/foo/basket/%s/lines/' % uuid.uuid4(), status=404)
invoice = DraftInvoice.objects.create(
regie=regie,
date_publication=datetime.date(2023, 4, 21),
date_payment_deadline=datetime.date(2023, 4, 22),
date_due=datetime.date(2023, 4, 23),
)
basket = Basket.objects.create(regie=regie, draft_invoice=invoice)
old_expiry_at = basket.expiry_at
app.post('/api/regie/bar/basket/%s/lines/' % basket.uuid, status=404)
resp = app.post('/api/regie/foo/basket/%s/lines/' % basket.uuid, status=400)
assert resp.json['err']
assert resp.json['errors'] == {
'user_external_id': ['This field is required.'],
'user_first_name': ['This field is required.'],
'user_last_name': ['This field is required.'],
}
params = {
'user_external_id': 'user:1',
'user_first_name': 'First1',
'user_last_name': 'Last1',
'information_message': 'foo baz',
'cancel_information_message': 'foo bar',
'form_url': 'http://form.com',
'validation_callback_url': 'http://validation.com',
'payment_callback_url': 'http://payment.com',
'credit_callback_url': 'http://credit.com',
'cancel_callback_url': 'http://cancel.com',
'expiration_callback_url': 'http://expiration.com',
}
resp = app.post('/api/regie/foo/basket/%s/lines/' % basket.uuid, params=params)
assert BasketLine.objects.count() == 1
line = BasketLine.objects.latest('pk')
assert resp.json == {'err': 0, 'data': {'line_id': str(line.uuid), 'closed': False}}
assert line.basket == basket
assert line.user_external_id == 'user:1'
assert line.user_first_name == 'First1'
assert line.user_last_name == 'Last1'
assert line.information_message == 'foo baz'
assert line.cancel_information_message == 'foo bar'
assert line.group_items is False
assert line.form_url == 'http://form.com'
assert line.validation_callback_url == 'http://validation.com'
assert line.payment_callback_url == 'http://payment.com'
assert line.credit_callback_url == 'http://credit.com'
assert line.cancel_callback_url == 'http://cancel.com'
assert line.expiration_callback_url == 'http://expiration.com'
assert line.closed is False
basket.refresh_from_db()
assert basket.expiry_at == old_expiry_at
assert invoice.lines.count() == 0
# again, aline already exists for this user
resp = app.post('/api/regie/foo/basket/%s/lines/' % basket.uuid, params=params, status=400)
assert resp.json['err']
assert resp.json['errors'] == {
'user_external_id': ['a line is already opened in basket for this user_external_id']
}
# even if line is closed
line.closed = True
line.save()
resp = app.post('/api/regie/foo/basket/%s/lines/' % basket.uuid, params=params, status=400)
assert resp.json['err']
assert resp.json['errors'] == {
'user_external_id': ['a line is already opened in basket for this user_external_id']
}
# ok for another user
params = {
'user_external_id': 'user:2',
'user_first_name': 'First2',
'user_last_name': 'Last2',
'group_items': True,
}
resp = app.post('/api/regie/foo/basket/%s/lines/' % basket.uuid, params=params)
assert BasketLine.objects.count() == 2
line = BasketLine.objects.latest('pk')
assert resp.json == {'err': 0, 'data': {'line_id': str(line.uuid), 'closed': False}}
assert line.basket == basket
assert line.user_external_id == 'user:2'
assert line.user_first_name == 'First2'
assert line.user_last_name == 'Last2'
assert line.information_message == ''
assert line.cancel_information_message == ''
assert line.group_items is True
assert line.form_url == ''
assert line.validation_callback_url == ''
assert line.payment_callback_url == ''
assert line.credit_callback_url == ''
assert line.cancel_callback_url == ''
assert line.expiration_callback_url == ''
assert line.closed is False
# basket wrong status
for status in ['tobepaid', 'completed', 'cancelled', 'expired']:
basket.status = status
basket.save()
app.post('/api/regie/foo/basket/%s/lines/' % basket.uuid, status=404)
def test_add_item(app, user):
app.post('/api/regie/foo/basket/%s/line/%s/items/' % (uuid.uuid4(), uuid.uuid4()), status=403)
app.authorization = ('Basic', ('john.doe', 'password'))
app.post('/api/regie/foo/basket/%s/line/%s/items/' % (uuid.uuid4(), uuid.uuid4()), status=404)
regie = Regie.objects.create(label='Foo')
app.post('/api/regie/foo/basket/%s/line/%s/items/' % (uuid.uuid4(), uuid.uuid4()), status=404)
invoice = DraftInvoice.objects.create(
regie=regie,
date_publication=datetime.date(2023, 4, 21),
date_payment_deadline=datetime.date(2023, 4, 22),
date_due=datetime.date(2023, 4, 23),
)
basket = Basket.objects.create(regie=regie, draft_invoice=invoice)
old_expiry_at = basket.expiry_at
app.post('/api/regie/foo/basket/%s/line/%s/items/' % (basket.uuid, uuid.uuid4()), status=404)
line = BasketLine.objects.create(basket=basket)
app.post('/api/regie/bar/basket/%s/line/%s/items/' % (basket.uuid, line.uuid), status=404)
app.post('/api/regie/foo/basket/%s/line/%s/items/' % (uuid.uuid4(), line.uuid), status=404)
resp = app.post('/api/regie/foo/basket/%s/line/%s/items/' % (basket.uuid, line.uuid), status=400)
assert resp.json['err']
assert resp.json['errors'] == {
'label': ['This field is required.'],
'quantity': ['This field is required.'],
'unit_amount': ['This field is required.'],
}
params = {
'label': 'Repas',
'subject': 'Réservation',
'details': 'Lun 06/11, Mar 07/11',
'quantity': 2,
'unit_amount': 3,
}
resp = app.post('/api/regie/foo/basket/%s/line/%s/items/' % (basket.uuid, line.uuid), params=params)
assert BasketLineItem.objects.count() == 1
item = BasketLineItem.objects.latest('pk')
assert resp.json == {'err': 0, 'data': {'item_id': str(item.uuid)}}
assert item.line == line
assert item.label == 'Repas'
assert item.subject == 'Réservation'
assert item.details == 'Lun 06/11, Mar 07/11'
assert item.quantity == 2
assert item.unit_amount == 3
basket.refresh_from_db()
assert basket.expiry_at == old_expiry_at
assert invoice.lines.count() == 0
# it's ok to add exactly the same item
resp = app.post('/api/regie/foo/basket/%s/line/%s/items/' % (basket.uuid, line.uuid), params=params)
assert BasketLineItem.objects.count() == 2
item = BasketLineItem.objects.latest('pk')
assert resp.json == {'err': 0, 'data': {'item_id': str(item.uuid)}}
assert item.line == line
assert item.label == 'Repas'
assert item.subject == 'Réservation'
assert item.details == 'Lun 06/11, Mar 07/11'
assert item.quantity == 2
assert item.unit_amount == 3
# add a negative item
params = {
'label': 'Repas',
'subject': 'Annulation',
'details': 'Jeu 09/11',
'quantity': -1,
'unit_amount': 3,
}
resp = app.post('/api/regie/foo/basket/%s/line/%s/items/' % (basket.uuid, line.uuid), params=params)
assert BasketLineItem.objects.count() == 3
item = BasketLineItem.objects.latest('pk')
assert resp.json == {'err': 0, 'data': {'item_id': str(item.uuid)}}
assert item.line == line
assert item.label == 'Repas'
assert item.subject == 'Annulation'
assert item.details == 'Jeu 09/11'
assert item.quantity == -1
assert item.unit_amount == 3
def test_close_line(app, user):
app.post('/api/regie/foo/basket/%s/line/%s/close/' % (uuid.uuid4(), uuid.uuid4()), status=403)
app.authorization = ('Basic', ('john.doe', 'password'))
app.post('/api/regie/foo/basket/%s/line/%s/close/' % (uuid.uuid4(), uuid.uuid4()), status=404)
regie = Regie.objects.create(label='Foo')
app.post('/api/regie/foo/basket/%s/line/%s/close/' % (uuid.uuid4(), uuid.uuid4()), status=404)
invoice = DraftInvoice.objects.create(
regie=regie,
date_publication=datetime.date(2023, 4, 21),
date_payment_deadline=datetime.date(2023, 4, 22),
date_due=datetime.date(2023, 4, 23),
)
basket = Basket.objects.create(regie=regie, draft_invoice=invoice)
old_expiry_at = basket.expiry_at
app.post('/api/regie/foo/basket/%s/line/%s/close/' % (basket.uuid, uuid.uuid4()), status=404)
line = BasketLine.objects.create(
basket=basket,
group_items=False,
user_external_id='user:1',
user_first_name='First1',
user_last_name='Last1',
)
app.post('/api/regie/bar/basket/%s/line/%s/close/' % (basket.uuid, line.uuid), status=404)
app.post('/api/regie/foo/basket/%s/line/%s/close/' % (uuid.uuid4(), line.uuid), status=404)
resp = app.post('/api/regie/foo/basket/%s/line/%s/close/' % (basket.uuid, line.uuid))
assert resp.json == {'err': 0, 'data': {'line_id': str(line.uuid), 'closed': True}}
line.refresh_from_db()
assert line.closed is True
basket.refresh_from_db()
assert basket.expiry_at > old_expiry_at
assert invoice.lines.count() == 0
# again, but already closed
app.post('/api/regie/foo/basket/%s/line/%s/close/' % (basket.uuid, line.uuid), status=404)
# now, with items
line.closed = False
line.save()
BasketLineItem.objects.create(
line=line,
label='Repas',
subject='Réservation',
details='Lun 6/11, Mar 7/11',
quantity=2,
unit_amount=3,
)
BasketLineItem.objects.create(
line=line,
label='Repas',
subject='Annulation',
details='Jeu 9/11',
quantity=-1,
unit_amount=3,
)
BasketLineItem.objects.create(
line=line,
label='Repas',
subject='Réservation',
details='Lun 13/11',
quantity=1,
unit_amount=3,
)
BasketLineItem.objects.create(
line=line,
label='Repas',
subject='Annulation',
details='Jeu 16/11',
quantity=-1,
unit_amount=3,
)
BasketLineItem.objects.create(
line=line,
label='Mercredi',
subject='Réservation',
details='Mer 8/11',
quantity=1,
unit_amount=5,
)
BasketLineItem.objects.create(
line=line,
label='Mercredi',
subject='Annulation',
details='Mer 15/11',
quantity=-0.5, # for decimal testing
unit_amount=5,
)
# no grouping
resp = app.post('/api/regie/foo/basket/%s/line/%s/close/' % (basket.uuid, line.uuid))
assert resp.json == {'err': 0, 'data': {'line_id': str(line.uuid), 'closed': True}}
line.refresh_from_db()
assert line.closed is True
basket.refresh_from_db()
assert invoice.lines.count() == 6
line1, line2, line3, line4, line5, line6 = invoice.lines.all().order_by('pk')
assert line1.event_date == datetime.date.today()
assert line1.slug == 'mercredi-annulation-mer-1511'
assert line1.event_slug == 'mercredi-annulation-mer-1511'
assert line1.label == 'Mercredi'
assert line1.description == 'Annulation Mer 15/11'
assert line1.quantity == -decimal.Decimal('0.5')
assert line1.unit_amount == 5
assert line1.total_amount == -decimal.Decimal('2.5')
assert line1.user_external_id == 'user:1'
assert line1.user_first_name == 'First1'
assert line1.user_last_name == 'Last1'
assert line1.payer_external_id == invoice.payer_external_id
assert line1.payer_first_name == invoice.payer_first_name
assert line1.payer_last_name == invoice.payer_last_name
assert line1.payer_address == invoice.payer_address
assert line1.payer_demat is True
assert line1.payer_direct_debit is False
assert line1.details == {}
assert line1.pool is None
assert line2.slug == 'mercredi-reservation-mer-811'
assert line2.event_slug == 'mercredi-reservation-mer-811'
assert line2.label == 'Mercredi'
assert line2.description == 'Réservation Mer 8/11'
assert line2.quantity == 1
assert line2.unit_amount == 5
assert line2.total_amount == 5
assert line2.user_external_id == 'user:1'
assert line2.user_first_name == 'First1'
assert line2.user_last_name == 'Last1'
assert line3.slug == 'repas-annulation-jeu-1611'
assert line3.event_slug == 'repas-annulation-jeu-1611'
assert line3.label == 'Repas'
assert line3.description == 'Annulation Jeu 16/11'
assert line3.quantity == -1
assert line3.unit_amount == 3
assert line3.total_amount == -3
assert line3.user_external_id == 'user:1'
assert line3.user_first_name == 'First1'
assert line3.user_last_name == 'Last1'
assert line4.slug == 'repas-annulation-jeu-911'
assert line4.event_slug == 'repas-annulation-jeu-911'
assert line4.label == 'Repas'
assert line4.description == 'Annulation Jeu 9/11'
assert line4.quantity == -1
assert line4.unit_amount == 3
assert line4.total_amount == -3
assert line4.user_external_id == 'user:1'
assert line4.user_first_name == 'First1'
assert line4.user_last_name == 'Last1'
assert line5.slug == 'repas-reservation-lun-1311'
assert line5.event_slug == 'repas-reservation-lun-1311'
assert line5.label == 'Repas'
assert line5.description == 'Réservation Lun 13/11'
assert line5.quantity == 1
assert line5.unit_amount == 3
assert line5.total_amount == 3
assert line5.user_external_id == 'user:1'
assert line5.user_first_name == 'First1'
assert line5.user_last_name == 'Last1'
assert line6.slug == 'repas-reservation-lun-611-mar-711'
assert line6.event_slug == 'repas-reservation-lun-611-mar-711'
assert line6.label == 'Repas'
assert line6.description == 'Réservation Lun 6/11, Mar 7/11'
assert line6.quantity == 2
assert line6.unit_amount == 3
assert line6.total_amount == 6
assert line6.user_external_id == 'user:1'
assert line6.user_first_name == 'First1'
assert line6.user_last_name == 'Last1'
# and with grouping
line.group_items = True
line.closed = False
line.save()
invoice.lines.all().delete()
resp = app.post('/api/regie/foo/basket/%s/line/%s/close/' % (basket.uuid, line.uuid))
assert resp.json == {'err': 0, 'data': {'line_id': str(line.uuid), 'closed': True}}
line.refresh_from_db()
assert line.closed is True
basket.refresh_from_db()
assert invoice.lines.count() == 4
line1, line2, line3, line4 = invoice.lines.all().order_by('pk')
assert line1.slug == 'mercredi-annulation-mer-1511'
assert line1.event_slug == 'mercredi-annulation-mer-1511'
assert line1.label == 'Mercredi'
assert line1.description == 'Annulation Mer 15/11'
assert line1.quantity == -decimal.Decimal('0.5')
assert line1.unit_amount == 5
assert line1.total_amount == -decimal.Decimal('2.5')
assert line1.user_external_id == 'user:1'
assert line1.user_first_name == 'First1'
assert line1.user_last_name == 'Last1'
assert line2.slug == 'mercredi-reservation-mer-811'
assert line2.event_slug == 'mercredi-reservation-mer-811'
assert line2.label == 'Mercredi'
assert line2.description == 'Réservation Mer 8/11'
assert line2.quantity == 1
assert line2.unit_amount == 5
assert line2.total_amount == 5
assert line2.user_external_id == 'user:1'
assert line2.user_first_name == 'First1'
assert line2.user_last_name == 'Last1'
assert line3.slug == 'repas-annulation-jeu-911-jeu-1611'
assert line3.event_slug == 'repas-annulation-jeu-911-jeu-1611'
assert line3.label == 'Repas'
assert line3.description == 'Annulation Jeu 9/11, Jeu 16/11'
assert line3.quantity == -2
assert line3.unit_amount == 3
assert line3.total_amount == -6
assert line3.user_external_id == 'user:1'
assert line3.user_first_name == 'First1'
assert line3.user_last_name == 'Last1'
assert line4.slug == 'repas-reservation-lun-611-mar-711-lun-1311'
assert line4.event_slug == 'repas-reservation-lun-611-mar-711-lun-1311'
assert line4.label == 'Repas'
assert line4.description == 'Réservation Lun 6/11, Mar 7/11, Lun 13/11'
assert line4.quantity == 3
assert line4.unit_amount == 3
assert line4.total_amount == 9
assert line4.user_external_id == 'user:1'
assert line4.user_first_name == 'First1'
assert line4.user_last_name == 'Last1'