Skip to content

Commit 6d0f957

Browse files
shreyanshdwivedimariobehling
authored andcommitted
fix: add checks for discount value (#5880)
added tests Updated tests adds check for negative discount amount and percent removes validation for event discount code adds check for free tickets
1 parent 1400605 commit 6d0f957

File tree

3 files changed

+162
-2
lines changed

3 files changed

+162
-2
lines changed

app/api/schema/discount_codes.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from app.api.helpers.utilities import dasherize
99
from app.api.schema.base import SoftDeletionSchema
1010
from app.models.discount_code import DiscountCode
11+
from app.models.ticket import Ticket
1112

1213

1314
class DiscountCodeSchemaPublic(SoftDeletionSchema):
@@ -153,6 +154,55 @@ def validate_quantity(self, data, original_data):
153154
raise UnprocessableEntity({'pointer': '/data/attributes/tickets-number'},
154155
"tickets-number should be greater than max-quantity")
155156

157+
@validates_schema(pass_original=True)
158+
def validate_value(self, data, original_data):
159+
if 'id' in original_data['data']:
160+
try:
161+
discount_code = DiscountCode.query.filter_by(id=original_data['data']['id']).one()
162+
except NoResultFound:
163+
raise ObjectNotFound({'parameter': '{code}'}, "DiscountCode: not found")
164+
165+
if 'type' not in data:
166+
data['type'] = discount_code.type
167+
168+
if 'value' not in data:
169+
data['value'] = discount_code.value
170+
171+
if data['type'] == "percent":
172+
if 'tickets' in data:
173+
for ticket in data['tickets']:
174+
ticket_object = Ticket.query.filter_by(id=ticket).one()
175+
if not ticket_object.price:
176+
raise UnprocessableEntity(
177+
{'pointer': '/data/attributes/tickets'},
178+
"discount code cannot be applied on free tickets"
179+
)
180+
if data['value'] < 0 or data['value'] > 100:
181+
raise UnprocessableEntity(
182+
{'pointer': '/data/attributes/value'},
183+
"discount percent must be within range of 0 and 100"
184+
)
185+
186+
if data['type'] == "amount":
187+
if 'tickets' in data:
188+
for ticket in data['tickets']:
189+
ticket_object = Ticket.query.filter_by(id=ticket).one()
190+
if not ticket_object.price:
191+
raise UnprocessableEntity(
192+
{'pointer': '/data/attributes/tickets'},
193+
"discount code cannot be applied on free tickets"
194+
)
195+
if ticket_object.price < data['value']:
196+
raise UnprocessableEntity(
197+
{'pointer': '/data/attributes/value'},
198+
"discount amount cannot be more than ticket amount"
199+
)
200+
if data['value'] < 0:
201+
raise UnprocessableEntity(
202+
{'pointer': '/data/attributes/value'},
203+
"discount amount cannot be less than zero"
204+
)
205+
156206
@validates_schema(pass_original=True)
157207
def validate_date(self, data, original_data):
158208
if 'id' in original_data['data']:

tests/all/integration/api/validation/test_discount_codes.py

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
from tests.all.integration.utils import OpenEventTestCase
55
from app.api.helpers.exceptions import UnprocessableEntity
66
from app.api.schema.discount_codes import DiscountCodeSchemaTicket
7-
from app.factories.discount_code import DiscountCodeFactory
8-
from app.models import db
97
from app.api.helpers.db import save_to_db
8+
from app.factories.discount_code import DiscountCodeFactory
9+
from app.factories.ticket import TicketFactory
1010
from tests.all.integration.setup_database import Setup
1111

1212

@@ -64,6 +64,71 @@ def test_quantity_max_gt_tickets_number(self):
6464
with self.assertRaises(UnprocessableEntity):
6565
DiscountCodeSchemaTicket.validate_quantity(schema, data, original_data)
6666

67+
def test_amount_lte_ticket_price(self):
68+
"""
69+
Discount Code Validate Amount Value - Tests if function runs without an exception
70+
:return:
71+
"""
72+
with app.test_request_context():
73+
ticket = TicketFactory()
74+
ticket.price = 100
75+
save_to_db(ticket)
76+
77+
schema = DiscountCodeSchemaTicket()
78+
original_data = {
79+
'data': {}
80+
}
81+
data = {
82+
'type': 'amount',
83+
'value': 70,
84+
'tickets': ['1']
85+
}
86+
DiscountCodeSchemaTicket.validate_value(schema, data, original_data)
87+
88+
def test_amount_gt_ticket_price(self):
89+
"""
90+
Discount Code Validate Amount Value - Tests if exception is raised when discount value is gt ticket price
91+
:return:
92+
"""
93+
with app.test_request_context():
94+
ticket = TicketFactory()
95+
ticket.price = 100
96+
save_to_db(ticket)
97+
98+
schema = DiscountCodeSchemaTicket()
99+
original_data = {
100+
'data': {}
101+
}
102+
data = {
103+
'type': 'amount',
104+
'value': 150,
105+
'tickets': ['1']
106+
}
107+
with self.assertRaises(UnprocessableEntity):
108+
DiscountCodeSchemaTicket.validate_value(schema, data, original_data)
109+
110+
def test_free_ticket(self):
111+
"""
112+
Discount Code Validate Amount Value - Tests exception when discount code is created for free ticket
113+
:return:
114+
"""
115+
with app.test_request_context():
116+
ticket = TicketFactory()
117+
ticket.price = 0
118+
save_to_db(ticket)
119+
120+
schema = DiscountCodeSchemaTicket()
121+
original_data = {
122+
'data': {}
123+
}
124+
data = {
125+
'type': 'amount',
126+
'value': 150,
127+
'tickets': ['1']
128+
}
129+
with self.assertRaises(UnprocessableEntity):
130+
DiscountCodeSchemaTicket.validate_value(schema, data, original_data)
131+
67132
def test_quantity_db_populate(self):
68133
"""
69134
Discount Code Validate Quantity - Tests if validation works on values stored in db and not given in 'data'
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import unittest
2+
3+
from tests.all.integration.utils import OpenEventTestCase
4+
from app.api.helpers.exceptions import UnprocessableEntity
5+
from app.api.schema.discount_codes import DiscountCodeSchemaTicket
6+
7+
8+
class TestDiscountCodeValidation(OpenEventTestCase):
9+
10+
def test_percent_value_lte_hundred(self):
11+
"""
12+
Discount Code Validate Percentage Value - Tests if function runs without an exception
13+
:return:
14+
"""
15+
schema = DiscountCodeSchemaTicket()
16+
original_data = {
17+
'data': {}
18+
}
19+
data = {
20+
'type': 'percent',
21+
'value': 90,
22+
'tickets': []
23+
}
24+
DiscountCodeSchemaTicket.validate_value(schema, data, original_data)
25+
26+
def test_percent_value_gt_hundred(self):
27+
"""
28+
Discount Code Validate Percentage Value - Tests if exception is raised when percentage value is greater than 100
29+
:return:
30+
"""
31+
schema = DiscountCodeSchemaTicket()
32+
original_data = {
33+
'data': {}
34+
}
35+
data = {
36+
'type': 'percent',
37+
'value': 110,
38+
'tickets': []
39+
}
40+
with self.assertRaises(UnprocessableEntity):
41+
DiscountCodeSchemaTicket.validate_value(schema, data, original_data)
42+
43+
44+
if __name__ == '__main__':
45+
unittest.main()

0 commit comments

Comments
 (0)