mirror of
https://github.com/pretix/pretix.git
synced 2026-08-17 11:56:27 +00:00
Check-in API: Add reusable media exchange (#6115)
* Add Reusable Media Exchange to Checkin API * isort * Remove debugging leftover * Apply suggestions from code review Co-authored-by: robbi5 <maxi@richt.name> * Add media_exchange_supported to CheckinRPCRedeemInputSerializer * SecurityProfiles: Add api-v1:reusablemedia-lookup and -detail for SCAN * Simplify media exchange checks * Apply suggestions from code review Co-authored-by: Raphael Michel <mail@raphaelmichel.de> * Wording: re-usable --> reusable * Deny checkins if media-exchange is required but device does not support it. * Remove media_exchange_supported-Flag: Checkin will always be denied if media needs to be exchanged; apps will fall back to explanation text * CheckinRPC: Also perform media exchange * Use media_policy from item, not as a checkinrpc parameter * my own review notes * Fixes, cleanup, rebase * block expired media * Fix query * add logging * Refactor link_action into media policy, gift card support * Block illegal policy-type combination * Drop add_to_reusable_medium, decide all by policy * Fix test failure * fix test on postgres * Expose reusable_media_usage_enforced to devies * Explicitly set update view --------- Co-authored-by: robbi5 <maxi@richt.name> Co-authored-by: Maximilian Richt <richt@pretix.eu> Co-authored-by: Raphael Michel <mail@raphaelmichel.de> Co-authored-by: Raphael Michel <michel@rami.io> Co-authored-by: Raphael Michel <michel@pretix.eu>
This commit is contained in:
co-authored by
robbi5
Raphael Michel
Maximilian Richt
Raphael Michel
Raphael Michel
parent
784577d86f
commit
775fdd1ccb
@@ -34,7 +34,7 @@ from tests.const import SAMPLE_PNG
|
||||
|
||||
from pretix.api.serializers.item import QuestionSerializer
|
||||
from pretix.base.models import (
|
||||
Checkin, InvoiceAddress, Order, OrderPosition, ReusableMedium,
|
||||
Checkin, InvoiceAddress, Item, Order, OrderPosition, ReusableMedium,
|
||||
)
|
||||
|
||||
# Lots of this code is overlapping with test_checkin.py, and some of it is arguably redundant since it's triggering
|
||||
@@ -1253,3 +1253,489 @@ def test_annul_failures(device_client, team, organizer, clist, clist_event2, eve
|
||||
with scopes_disabled():
|
||||
ci = p.all_checkins.get()
|
||||
assert ci.successful
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchange_incomplete_body(token_client, organizer, clist, event, order):
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"exchange_medium_type": "nfc_uid"
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
assert resp.data == {
|
||||
'non_field_errors': ['If you set any of exchange_medium_type or exchange_medium_identifier, you need to set both of them.']
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchange_medium_for_medium(token_client, organizer, clist, event, order):
|
||||
with scopes_disabled():
|
||||
rm = ReusableMedium.objects.create(
|
||||
type="barcode",
|
||||
identifier="abcdef",
|
||||
organizer=organizer,
|
||||
)
|
||||
rm.linked_orderpositions.add(order.positions.first())
|
||||
resp = _redeem(token_client, organizer, clist, "abcdef", {
|
||||
"source_type": "barcode",
|
||||
"exchange_medium_type": "barcode",
|
||||
"exchange_medium_identifier": "hijkl",
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
assert resp.data['status'] == 'error'
|
||||
assert resp.data['reason'] == 'error'
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchange_unknown_media_type(token_client, organizer, clist, event, order):
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"exchange_medium_type": "unknown",
|
||||
"exchange_medium_identifier": "hijkl",
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
assert resp.data == {"exchange_medium_type": ["\"unknown\" is not a valid choice."]}
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchange_disabled_media_type(token_client, organizer, clist, event, order):
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"exchange_medium_type": "nfc_uid",
|
||||
"exchange_medium_identifier": "hijkl",
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
assert resp.data['status'] == 'error'
|
||||
assert resp.data['reason'] == 'error'
|
||||
assert resp.data['reason_explanation'] == 'Medium type is not enabled for organizer.'
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchange_mismatch_media_type(token_client, organizer, clist, event, order, item):
|
||||
organizer.settings.reusable_media_type_nfc_uid = True
|
||||
item.media_type = "barcode"
|
||||
item.save()
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"exchange_medium_type": "nfc_uid",
|
||||
"exchange_medium_identifier": "12345678",
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
assert resp.data['status'] == 'error'
|
||||
assert resp.data['reason'] == 'product'
|
||||
assert resp.data['reason_explanation'] == 'Incorrect medium type for product.'
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchange_no_item_policy(token_client, organizer, clist, event, order, item):
|
||||
organizer.settings.reusable_media_type_nfc_uid = True
|
||||
item.media_type = "nfc_uid"
|
||||
item.save()
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"exchange_medium_type": "nfc_uid",
|
||||
"exchange_medium_identifier": "12345678",
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
assert resp.data['status'] == 'error'
|
||||
assert resp.data['reason'] == 'product'
|
||||
assert resp.data['reason_explanation'] == 'Product does not support medium exchange.'
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchange_reuse_or_new_new(token_client, organizer, clist, event, order, item):
|
||||
organizer.settings.reusable_media_type_nfc_uid = True
|
||||
item.media_type = "nfc_uid"
|
||||
item.media_policy = Item.MEDIA_POLICY_REUSE_OR_NEW
|
||||
item.save()
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"exchange_medium_type": "nfc_uid",
|
||||
"exchange_medium_identifier": "12345678",
|
||||
})
|
||||
assert resp.status_code == 201
|
||||
assert resp.data['status'] == 'ok'
|
||||
with scopes_disabled():
|
||||
rm = ReusableMedium.objects.get(
|
||||
type="nfc_uid",
|
||||
identifier="12345678",
|
||||
organizer=organizer,
|
||||
)
|
||||
assert rm.linked_orderpositions.get().secret == "z3fsn8jyufm5kpk768q69gkbyr5f4h6w"
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchange_reuse_or_new_reuse_replace(token_client, organizer, clist, event, order, item):
|
||||
organizer.settings.reusable_media_type_nfc_uid = True
|
||||
item.media_type = "nfc_uid"
|
||||
item.media_policy = Item.MEDIA_POLICY_REUSE_OR_NEW
|
||||
item.save()
|
||||
with scopes_disabled():
|
||||
rm = ReusableMedium.objects.create(
|
||||
type="nfc_uid",
|
||||
identifier="12345678",
|
||||
organizer=organizer,
|
||||
)
|
||||
rm.linked_orderpositions.add(order.positions.last())
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"exchange_medium_type": "nfc_uid",
|
||||
"exchange_medium_identifier": "12345678",
|
||||
})
|
||||
assert resp.status_code == 201
|
||||
assert resp.data['status'] == 'ok'
|
||||
rm.refresh_from_db()
|
||||
with scopes_disabled():
|
||||
assert rm.linked_orderpositions.get().secret == "z3fsn8jyufm5kpk768q69gkbyr5f4h6w"
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchange_reuse_or_new_reuse_append(token_client, organizer, clist, event, order, item):
|
||||
organizer.settings.reusable_media_type_nfc_uid = True
|
||||
item.media_type = "nfc_uid"
|
||||
item.media_policy = Item.MEDIA_POLICY_APPEND_OR_NEW
|
||||
item.save()
|
||||
with scopes_disabled():
|
||||
rm = ReusableMedium.objects.create(
|
||||
type="nfc_uid",
|
||||
identifier="12345678",
|
||||
organizer=organizer,
|
||||
)
|
||||
rm.linked_orderpositions.add(order.positions.last())
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"exchange_medium_type": "nfc_uid",
|
||||
"exchange_medium_identifier": "12345678",
|
||||
})
|
||||
assert resp.status_code == 201
|
||||
assert resp.data['status'] == 'ok'
|
||||
rm.refresh_from_db()
|
||||
with scopes_disabled():
|
||||
assert rm.linked_orderpositions.count() == 2
|
||||
assert rm.linked_orderpositions.filter(secret="z3fsn8jyufm5kpk768q69gkbyr5f4h6w").exists()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchange_reuse_exists_append(token_client, organizer, clist, event, order, item):
|
||||
organizer.settings.reusable_media_type_nfc_uid = True
|
||||
item.media_type = "nfc_uid"
|
||||
item.media_policy = Item.MEDIA_POLICY_APPEND_OR_NEW
|
||||
item.save()
|
||||
with scopes_disabled():
|
||||
rm = ReusableMedium.objects.create(
|
||||
type="nfc_uid",
|
||||
identifier="12345678",
|
||||
organizer=organizer,
|
||||
)
|
||||
rm.linked_orderpositions.add(order.positions.last())
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"exchange_medium_type": "nfc_uid",
|
||||
"exchange_medium_identifier": "12345678",
|
||||
})
|
||||
assert resp.status_code == 201
|
||||
assert resp.data['status'] == 'ok'
|
||||
rm.refresh_from_db()
|
||||
with scopes_disabled():
|
||||
assert rm.linked_orderpositions.count() == 2
|
||||
assert rm.linked_orderpositions.filter(secret="z3fsn8jyufm5kpk768q69gkbyr5f4h6w").exists()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchange_reuse_expired(token_client, organizer, clist, event, order, item):
|
||||
organizer.settings.reusable_media_type_nfc_uid = True
|
||||
item.media_type = "nfc_uid"
|
||||
item.media_policy = Item.MEDIA_POLICY_REUSE
|
||||
item.save()
|
||||
with scopes_disabled():
|
||||
rm = ReusableMedium.objects.create(
|
||||
type="nfc_uid",
|
||||
identifier="12345678",
|
||||
organizer=organizer,
|
||||
expires=now() - datetime.timedelta(hours=2),
|
||||
)
|
||||
rm.linked_orderpositions.add(order.positions.last())
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"exchange_medium_type": "nfc_uid",
|
||||
"exchange_medium_identifier": "12345678",
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
assert resp.data['status'] == 'error'
|
||||
assert resp.data['reason'] == 'medium_invalid'
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchange_reuse_not_exists(token_client, organizer, clist, event, order, item):
|
||||
organizer.settings.reusable_media_type_nfc_uid = True
|
||||
item.media_type = "nfc_uid"
|
||||
item.media_policy = Item.MEDIA_POLICY_REUSE
|
||||
item.save()
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"exchange_medium_type": "nfc_uid",
|
||||
"exchange_medium_identifier": "12345678",
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
assert resp.data['status'] == 'error'
|
||||
assert resp.data['reason'] == 'medium_invalid'
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchange_new_exists(token_client, organizer, clist, event, order, item):
|
||||
organizer.settings.reusable_media_type_nfc_uid = True
|
||||
item.media_type = "nfc_uid"
|
||||
item.media_policy = Item.MEDIA_POLICY_NEW
|
||||
item.save()
|
||||
with scopes_disabled():
|
||||
rm = ReusableMedium.objects.create(
|
||||
type="nfc_uid",
|
||||
identifier="12345678",
|
||||
organizer=organizer,
|
||||
)
|
||||
rm.linked_orderpositions.add(order.positions.last())
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"exchange_medium_type": "nfc_uid",
|
||||
"exchange_medium_identifier": "12345678",
|
||||
"exchange_link_action": "append",
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
assert resp.data['status'] == 'error'
|
||||
assert resp.data['reason'] == 'medium_exists'
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchange_new_not_exists(token_client, organizer, clist, event, order, item):
|
||||
organizer.settings.reusable_media_type_nfc_uid = True
|
||||
item.media_type = "nfc_uid"
|
||||
item.media_policy = Item.MEDIA_POLICY_NEW
|
||||
item.save()
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"exchange_medium_type": "nfc_uid",
|
||||
"exchange_medium_identifier": "12345678",
|
||||
"exchange_link_action": "replace",
|
||||
})
|
||||
assert resp.status_code == 201
|
||||
assert resp.data['status'] == 'ok'
|
||||
with scopes_disabled():
|
||||
rm = ReusableMedium.objects.get(
|
||||
type="nfc_uid",
|
||||
identifier="12345678",
|
||||
organizer=organizer,
|
||||
)
|
||||
assert rm.linked_orderpositions.get().secret == "z3fsn8jyufm5kpk768q69gkbyr5f4h6w"
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchange_required(token_client, organizer, clist, event, order, item):
|
||||
organizer.settings.reusable_media_type_nfc_uid = True
|
||||
item.media_type = "nfc_uid"
|
||||
item.media_policy = Item.MEDIA_POLICY_NEW
|
||||
item.save()
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
assert resp.data['status'] == 'exchange'
|
||||
assert resp.data['media_policy'] == 'new'
|
||||
assert resp.data['media_type'] == 'nfc_uid'
|
||||
|
||||
with scopes_disabled():
|
||||
rm = ReusableMedium.objects.create(
|
||||
type="nfc_uid",
|
||||
identifier="12345678",
|
||||
organizer=organizer,
|
||||
)
|
||||
rm.linked_orderpositions.add(order.positions.first())
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
})
|
||||
assert resp.status_code == 201
|
||||
assert resp.data['status'] == 'ok'
|
||||
# Force works
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"force": True,
|
||||
})
|
||||
assert resp.status_code == 201
|
||||
assert resp.data['status'] == 'ok'
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchanged_original_barcode_ok(token_client, organizer, clist, event, order, item):
|
||||
organizer.settings.reusable_media_type_nfc_uid = True
|
||||
item.media_type = "nfc_uid"
|
||||
item.media_policy = Item.MEDIA_POLICY_NEW
|
||||
item.save()
|
||||
|
||||
with scopes_disabled():
|
||||
rm = ReusableMedium.objects.create(
|
||||
type="nfc_uid",
|
||||
identifier="12345678",
|
||||
organizer=organizer,
|
||||
)
|
||||
rm.linked_orderpositions.add(order.positions.first())
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
})
|
||||
assert resp.status_code == 201
|
||||
assert resp.data['status'] == 'ok'
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchanged_original_barcode_not_ok(token_client, organizer, clist, event, order, item):
|
||||
organizer.settings.reusable_media_type_nfc_uid = True
|
||||
organizer.settings.reusable_media_usage_enforced = True
|
||||
item.media_type = "nfc_uid"
|
||||
item.media_policy = Item.MEDIA_POLICY_NEW
|
||||
item.save()
|
||||
|
||||
with scopes_disabled():
|
||||
rm = ReusableMedium.objects.create(
|
||||
type="nfc_uid",
|
||||
identifier="12345678",
|
||||
organizer=organizer,
|
||||
)
|
||||
rm.linked_orderpositions.add(order.positions.first())
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
assert resp.data['status'] == 'error'
|
||||
assert resp.data['reason'] == 'already_exchanged'
|
||||
# Force works
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"force": True,
|
||||
})
|
||||
assert resp.status_code == 201
|
||||
assert resp.data['status'] == 'ok'
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchanged_scan_medium_ok(token_client, organizer, clist, event, order, item):
|
||||
organizer.settings.reusable_media_type_nfc_uid = True
|
||||
organizer.settings.reusable_media_usage_enforced = True
|
||||
item.media_type = "nfc_uid"
|
||||
item.media_policy = Item.MEDIA_POLICY_NEW
|
||||
item.save()
|
||||
|
||||
with scopes_disabled():
|
||||
rm = ReusableMedium.objects.create(
|
||||
type="nfc_uid",
|
||||
identifier="12345678",
|
||||
organizer=organizer,
|
||||
)
|
||||
rm.linked_orderpositions.add(order.positions.first())
|
||||
resp = _redeem(token_client, organizer, clist, "12345678", {
|
||||
"source_type": "nfc_uid",
|
||||
})
|
||||
assert resp.status_code == 201
|
||||
assert resp.data['status'] == 'ok'
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_exchanged_double_exchange(token_client, organizer, clist, event, order, item):
|
||||
organizer.settings.reusable_media_type_nfc_uid = True
|
||||
organizer.settings.reusable_media_usage_enforced = False
|
||||
item.media_type = "nfc_uid"
|
||||
item.media_policy = Item.MEDIA_POLICY_NEW
|
||||
item.save()
|
||||
|
||||
with scopes_disabled():
|
||||
rm = ReusableMedium.objects.create(
|
||||
type="nfc_uid",
|
||||
identifier="12345678",
|
||||
organizer=organizer,
|
||||
)
|
||||
rm.linked_orderpositions.add(order.positions.first())
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"exchange_medium_type": "nfc_uid",
|
||||
"exchange_medium_identifier": "87654321",
|
||||
"exchange_link_action": "replace",
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
assert resp.data['status'] == 'error'
|
||||
assert resp.data['reason'] == 'already_exchanged'
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.parametrize(
|
||||
"media_policy,media_type",
|
||||
[
|
||||
(Item.MEDIA_POLICY_NEW, "nfc_mf0aes"),
|
||||
(Item.MEDIA_POLICY_REUSE_OR_NEW, "nfc_mf0aes"),
|
||||
(Item.MEDIA_POLICY_APPEND_OR_NEW, "nfc_mf0aes"),
|
||||
(Item.MEDIA_POLICY_NEW, "barcode"),
|
||||
(Item.MEDIA_POLICY_REUSE_OR_NEW, "barcode"),
|
||||
(Item.MEDIA_POLICY_APPEND_OR_NEW, "barcode"),
|
||||
]
|
||||
)
|
||||
def test_exchange_unsupported_media_type_for_new(token_client, organizer, clist, event, order, item, media_policy, media_type):
|
||||
organizer.settings.set(f'reusable_media_type_{media_type}', True)
|
||||
# Shouldn't be configurable, but test that the logic is solid anyway
|
||||
item.media_type = media_type
|
||||
item.media_policy = media_policy
|
||||
item.save()
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"exchange_medium_type": media_type,
|
||||
"exchange_medium_identifier": "12345678",
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
assert resp.data['status'] == 'error'
|
||||
assert resp.data['reason'] == 'medium_invalid'
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.parametrize(
|
||||
"media_policy",
|
||||
[
|
||||
Item.MEDIA_POLICY_NEW,
|
||||
Item.MEDIA_POLICY_REUSE_OR_NEW,
|
||||
Item.MEDIA_POLICY_APPEND_OR_NEW,
|
||||
]
|
||||
)
|
||||
def test_exchange_rejected_media_identifier(token_client, organizer, clist, event, order, item, media_policy):
|
||||
organizer.settings.reusable_media_type_nfc_uid = True
|
||||
item.media_type = "nfc_uid"
|
||||
item.media_policy = media_policy
|
||||
item.save()
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"exchange_medium_type": "nfc_uid",
|
||||
"exchange_medium_identifier": "08RANDOM",
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
assert resp.data['status'] == 'error'
|
||||
assert resp.data['reason'] == 'medium_invalid'
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.parametrize(
|
||||
"media_policy",
|
||||
[
|
||||
Item.MEDIA_POLICY_NEW,
|
||||
Item.MEDIA_POLICY_REUSE_OR_NEW,
|
||||
Item.MEDIA_POLICY_APPEND_OR_NEW,
|
||||
]
|
||||
)
|
||||
def test_exchange_create_gift_card(token_client, organizer, clist, event, order, item, media_policy):
|
||||
organizer.settings.reusable_media_type_nfc_uid = True
|
||||
organizer.settings.reusable_media_type_nfc_uid_autocreate_giftcard = True
|
||||
organizer.settings.reusable_media_type_nfc_uid_autocreate_giftcard_currency = "EUR"
|
||||
item.media_type = "nfc_uid"
|
||||
item.media_policy = media_policy
|
||||
item.save()
|
||||
resp = _redeem(token_client, organizer, clist, "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", {
|
||||
"source_type": "barcode",
|
||||
"exchange_medium_type": "nfc_uid",
|
||||
"exchange_medium_identifier": "0412345",
|
||||
})
|
||||
assert resp.status_code == 201
|
||||
with scopes_disabled():
|
||||
rm = ReusableMedium.objects.get(identifier="0412345")
|
||||
assert rm.linked_giftcard.currency == "EUR"
|
||||
|
||||
@@ -3141,24 +3141,13 @@ def test_order_create_use_medium(token_client, organizer, event, item, quota, qu
|
||||
@pytest.mark.django_db
|
||||
def test_order_create_add_to_medium(token_client, organizer, event, item, quota, question, medium):
|
||||
item.media_type = medium.type
|
||||
item.media_policy = Item.MEDIA_POLICY_REUSE_OR_NEW
|
||||
item.media_policy = Item.MEDIA_POLICY_APPEND_OR_NEW
|
||||
item.save()
|
||||
res = copy.deepcopy(ORDER_CREATE_PAYLOAD)
|
||||
res['positions'][0]['item'] = item.pk
|
||||
res['positions'][0]['use_reusable_medium'] = medium.pk
|
||||
res['positions'][0]['add_to_reusable_medium'] = medium.pk
|
||||
res['positions'][0]['answers'][0]['question'] = question.pk
|
||||
|
||||
# do not use use_reusable_medium and add_to_reusable_medium
|
||||
resp = token_client.post(
|
||||
'/api/v1/organizers/{}/events/{}/orders/?pdf_data=true'.format(
|
||||
organizer.slug, event.slug
|
||||
), format='json', data=res
|
||||
)
|
||||
assert resp.status_code == 400
|
||||
|
||||
del res['positions'][0]['use_reusable_medium']
|
||||
|
||||
resp = token_client.post(
|
||||
'/api/v1/organizers/{}/events/{}/orders/?pdf_data=true'.format(
|
||||
organizer.slug, event.slug
|
||||
@@ -3179,8 +3168,9 @@ def test_order_create_add_to_medium(token_client, organizer, event, item, quota,
|
||||
medium.refresh_from_db()
|
||||
assert medium.linked_orderpositions.count() == 2
|
||||
|
||||
item.media_policy = Item.MEDIA_POLICY_REUSE_OR_NEW
|
||||
item.save()
|
||||
res['positions'][0]['use_reusable_medium'] = medium.pk
|
||||
del res['positions'][0]['add_to_reusable_medium']
|
||||
resp = token_client.post(
|
||||
'/api/v1/organizers/{}/events/{}/orders/?pdf_data=true'.format(
|
||||
organizer.slug, event.slug
|
||||
|
||||
Reference in New Issue
Block a user