mirror of
https://github.com/pretix/pretix.git
synced 2026-05-04 15:04:03 +00:00
Gift cards: Improved support for cross-organizer acceptance (#3311)
Co-authored-by: Martin Gross <martin@pc-coholic.de>
This commit is contained in:
@@ -293,6 +293,19 @@ def test_giftcard_transact_cross_organizer(token_client, organizer, event, other
|
||||
assert other_giftcard.transactions.last().acceptor == organizer
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_giftcard_transact_cross_organizer_inactive(token_client, organizer, event, other_giftcard):
|
||||
organizer.gift_card_issuer_acceptance.update(active=False)
|
||||
resp = token_client.post(
|
||||
'/api/v1/organizers/{}/giftcards/{}/transact/?include_accepted=true'.format(organizer.slug, other_giftcard.pk),
|
||||
{
|
||||
'value': '10.00',
|
||||
},
|
||||
format='json'
|
||||
)
|
||||
assert resp.status_code == 404
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_giftcard_transact_min_zero(token_client, organizer, event, giftcard):
|
||||
resp = token_client.post(
|
||||
|
||||
@@ -19,14 +19,16 @@
|
||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
from datetime import timedelta
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from decimal import Decimal
|
||||
|
||||
import pytest
|
||||
from django.utils.timezone import now
|
||||
from django_scopes import scopes_disabled
|
||||
|
||||
from pretix.base.models import Order, Organizer, ReusableMedium
|
||||
from pretix.base.models import (
|
||||
Event, GiftCardAcceptance, Order, Organizer, ReusableMedium,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -49,11 +51,28 @@ def organizer2():
|
||||
|
||||
@pytest.fixture
|
||||
def giftcard2(organizer2):
|
||||
gc = organizer2.issued_gift_cards.create(secret="ABCDEF", currency="EUR")
|
||||
gc = organizer2.issued_gift_cards.create(secret="IJKLMNOP", currency="EUR")
|
||||
gc.transactions.create(value=Decimal('23.00'), acceptor=organizer2)
|
||||
return gc
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def medium2(organizer2):
|
||||
m = organizer2.reusable_media.create(identifier="ABCDEFGH", type="barcode", active=True)
|
||||
return m
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@scopes_disabled()
|
||||
def org2_event(organizer2):
|
||||
e = Event.objects.create(
|
||||
organizer=organizer2, name='Dummy2', slug='dummy2',
|
||||
date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc),
|
||||
plugins='pretix.plugins.banktransfer,pretix.plugins.ticketoutputpdf'
|
||||
)
|
||||
return e
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def customer(organizer, event):
|
||||
return organizer.customers.create(
|
||||
@@ -67,6 +86,7 @@ def customer(organizer, event):
|
||||
|
||||
TEST_MEDIUM_RES = {
|
||||
"id": 1,
|
||||
"organizer": "dummy",
|
||||
"identifier": "ABCDEFGH",
|
||||
"type": "barcode",
|
||||
"active": True,
|
||||
@@ -357,3 +377,64 @@ def test_medium_autocreate(token_client, organizer):
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
assert resp.data["result"] is None
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_medium_lookup_cross_organizer(token_client, organizer, organizer2, org2_event, medium2, giftcard2):
|
||||
with scopes_disabled():
|
||||
o = Order.objects.create(
|
||||
code='FOO', event=org2_event, email='dummy@dummy.test',
|
||||
status=Order.STATUS_PENDING, datetime=now(), expires=now() + timedelta(days=10),
|
||||
total=14, locale='en'
|
||||
)
|
||||
ticket = org2_event.items.create(name='Early-bird ticket', category=None, default_price=23, admission=True,
|
||||
personalized=True)
|
||||
op = o.positions.create(item=ticket, price=Decimal("14"))
|
||||
medium2.linked_orderposition = op
|
||||
medium2.linked_giftcard = giftcard2
|
||||
medium2.save()
|
||||
|
||||
resp = token_client.post(
|
||||
'/api/v1/organizers/{}/reusablemedia/lookup/'.format(organizer.slug),
|
||||
{
|
||||
"type": medium2.type,
|
||||
"identifier": medium2.identifier,
|
||||
},
|
||||
format='json'
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
assert resp.data["result"] is None
|
||||
|
||||
gca = GiftCardAcceptance.objects.create(
|
||||
issuer=organizer2,
|
||||
acceptor=organizer,
|
||||
active=True,
|
||||
reusable_media=False
|
||||
)
|
||||
|
||||
resp = token_client.post(
|
||||
'/api/v1/organizers/{}/reusablemedia/lookup/'.format(organizer.slug),
|
||||
{
|
||||
"type": medium2.type,
|
||||
"identifier": medium2.identifier,
|
||||
},
|
||||
format='json'
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
assert resp.data["result"] is None
|
||||
|
||||
gca.reusable_media = True
|
||||
gca.save()
|
||||
resp = token_client.post(
|
||||
'/api/v1/organizers/{}/reusablemedia/lookup/'.format(organizer.slug),
|
||||
{
|
||||
"type": medium2.type,
|
||||
"identifier": medium2.identifier,
|
||||
},
|
||||
format='json'
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
assert resp.data["result"] is not None
|
||||
assert resp.data["result"]["organizer"] == "partner"
|
||||
assert resp.data["result"]["linked_giftcard"] is not None
|
||||
assert resp.data["result"]["linked_orderposition"] is None
|
||||
|
||||
@@ -51,7 +51,8 @@ def gift_card(organizer):
|
||||
@pytest.fixture
|
||||
def admin_user(organizer):
|
||||
u = User.objects.create_user('dummy@dummy.dummy', 'dummy')
|
||||
admin_team = Team.objects.create(organizer=organizer, can_manage_gift_cards=True, name='Admin team')
|
||||
admin_team = Team.objects.create(organizer=organizer, can_manage_gift_cards=True, name='Admin team',
|
||||
can_change_organizer_settings=True)
|
||||
admin_team.members.add(u)
|
||||
return u
|
||||
|
||||
@@ -174,24 +175,29 @@ def test_card_detail_view_transact_invalid_value(organizer, admin_user, gift_car
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_manage_acceptance(organizer, organizer2, admin_user, gift_card, client, team2):
|
||||
gca = organizer.gift_card_issuer_acceptance.create(issuer=organizer2, active=False)
|
||||
|
||||
client.login(email='dummy@dummy.dummy', password='dummy')
|
||||
client.post('/control/organizer/dummy/giftcards', {
|
||||
'add': organizer2.slug
|
||||
client.post('/control/organizer/dummy/giftcards/acceptance', {
|
||||
'accept_issuer': organizer2.slug
|
||||
})
|
||||
assert organizer.gift_card_issuer_acceptance.filter(issuer=organizer2).exists()
|
||||
client.post('/control/organizer/dummy/giftcards', {
|
||||
'del': organizer2.slug
|
||||
|
||||
gca.refresh_from_db()
|
||||
assert gca.active
|
||||
|
||||
client.post('/control/organizer/dummy/giftcards/acceptance', {
|
||||
'delete_issuer': organizer2.slug
|
||||
})
|
||||
assert not organizer.gift_card_issuer_acceptance.filter(issuer=organizer2).exists()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_manage_acceptance_permission_required(organizer, organizer2, admin_user, gift_card, client):
|
||||
client.login(email='dummy@dummy.dummy', password='dummy')
|
||||
client.post('/control/organizer/dummy/giftcards', {
|
||||
'add': organizer2.slug
|
||||
client.post('/control/organizer/dummy/giftcards/acceptance/invite', {
|
||||
'acceptor': organizer2.slug
|
||||
})
|
||||
assert not organizer.gift_card_issuer_acceptance.filter(issuer=organizer2).exists()
|
||||
assert organizer.gift_card_acceptor_acceptance.filter(acceptor=organizer2).exists()
|
||||
client.post('/control/organizer/dummy/giftcards/acceptance', {
|
||||
'delete_acceptor': organizer2.slug
|
||||
})
|
||||
assert not organizer.gift_card_acceptor_acceptance.filter(acceptor=organizer2).exists()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
|
||||
@@ -219,6 +219,8 @@ organizer_urls = [
|
||||
'organizer/abc/giftcard/add',
|
||||
'organizer/abc/giftcard/1/',
|
||||
'organizer/abc/giftcard/1/edit',
|
||||
'organizer/abc/giftcards/acceptance',
|
||||
'organizer/abc/giftcards/acceptance/invite',
|
||||
]
|
||||
|
||||
|
||||
@@ -552,6 +554,8 @@ organizer_permission_urls = [
|
||||
("can_manage_gift_cards", "organizer/dummy/giftcard/add", 200),
|
||||
("can_manage_gift_cards", "organizer/dummy/giftcard/1/", 404),
|
||||
("can_manage_gift_cards", "organizer/dummy/giftcard/1/edit", 404),
|
||||
("can_change_organizer_settings", "organizer/dummy/giftcards/acceptance", 200),
|
||||
("can_change_organizer_settings", "organizer/dummy/giftcards/acceptance/invite", 200),
|
||||
|
||||
# bank transfer
|
||||
("can_change_orders", "organizer/dummy/banktransfer/import/", 200),
|
||||
|
||||
@@ -1676,6 +1676,24 @@ class CheckoutTestCase(BaseCheckoutTestCase, TestCase):
|
||||
assert gc.issuer == orga2
|
||||
assert gc.transactions.last().acceptor == self.orga
|
||||
|
||||
def test_giftcard_cross_organizer_inactive(self):
|
||||
self.orga.issued_gift_cards.create(currency="EUR")
|
||||
orga2 = Organizer.objects.create(slug="foo2", name="foo2")
|
||||
gc = orga2.issued_gift_cards.create(currency="EUR")
|
||||
gc.transactions.create(value=23, acceptor=orga2)
|
||||
self.orga.gift_card_issuer_acceptance.create(issuer=orga2, active=False)
|
||||
self.event.settings.set('payment_banktransfer__enabled', True)
|
||||
with scopes_disabled():
|
||||
CartPosition.objects.create(
|
||||
event=self.event, cart_id=self.session_key, item=self.ticket,
|
||||
price=23, expires=now() + timedelta(minutes=10)
|
||||
)
|
||||
response = self.client.post('/%s/%s/checkout/payment/' % (self.orga.slug, self.event.slug), {
|
||||
'payment': 'giftcard',
|
||||
'giftcard': gc.secret
|
||||
}, follow=True)
|
||||
assert 'This gift card is not known.' in response.content.decode()
|
||||
|
||||
def test_giftcard_in_test_mode(self):
|
||||
gc = self.orga.issued_gift_cards.create(currency="EUR")
|
||||
gc.transactions.create(value=20, acceptor=self.orga)
|
||||
|
||||
Reference in New Issue
Block a user