Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions app/api/schema/discount_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from app.api.helpers.utilities import dasherize
from app.api.schema.base import SoftDeletionSchema
from app.models.discount_code import DiscountCode
from app.models.ticket import Ticket


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

@validates_schema(pass_original=True)
def validate_value(self, data, original_data):
if 'id' in original_data['data']:
try:
discount_code = DiscountCode.query.filter_by(id=original_data['data']['id']).one()
except NoResultFound:
raise ObjectNotFound({'parameter': '{code}'}, "DiscountCode: not found")

if 'type' not in data:
data['type'] = discount_code.type

if 'value' not in data:
data['value'] = discount_code.value

if data['type'] == "percent":
if 'tickets' in data:
for ticket in data['tickets']:
ticket_object = Ticket.query.filter_by(id=ticket).one()
if not ticket_object.price:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't it be compared to zero ? for clarity?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CosmicCoder96 actually we are allowing none for price attribute of ticket. Though for front-end we send 0 in case ticket price is not set but server is also for android. Maybe there are tickets present with None as ticket price so it may cause discrepancies
price = fields.Float(validate=lambda n: n >= 0, allow_none=True)
I checked it just now. Should I compare explicitly?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shreyanshdwivedi okay, cool then don't change it.

raise UnprocessableEntity(
{'pointer': '/data/attributes/tickets'},
"discount code cannot be applied on free tickets"
)
if data['value'] < 0 or data['value'] > 100:
raise UnprocessableEntity(
{'pointer': '/data/attributes/value'},
"discount percent must be within range of 0 and 100"
)

if data['type'] == "amount":
if 'tickets' in data:
for ticket in data['tickets']:
ticket_object = Ticket.query.filter_by(id=ticket).one()
if not ticket_object.price:
raise UnprocessableEntity(
{'pointer': '/data/attributes/tickets'},
"discount code cannot be applied on free tickets"
)
if ticket_object.price < data['value']:
raise UnprocessableEntity(
{'pointer': '/data/attributes/value'},
"discount amount cannot be more than ticket amount"
)
if data['value'] < 0:
raise UnprocessableEntity(
{'pointer': '/data/attributes/value'},
"discount amount cannot be less than zero"
)

@validates_schema(pass_original=True)
def validate_date(self, data, original_data):
if 'id' in original_data['data']:
Expand Down
69 changes: 67 additions & 2 deletions tests/all/integration/api/validation/test_discount_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
from tests.all.integration.utils import OpenEventTestCase
from app.api.helpers.exceptions import UnprocessableEntity
from app.api.schema.discount_codes import DiscountCodeSchemaTicket
from app.factories.discount_code import DiscountCodeFactory
from app.models import db
from app.api.helpers.db import save_to_db
from app.factories.discount_code import DiscountCodeFactory
from app.factories.ticket import TicketFactory
from tests.all.integration.setup_database import Setup


Expand Down Expand Up @@ -64,6 +64,71 @@ def test_quantity_max_gt_tickets_number(self):
with self.assertRaises(UnprocessableEntity):
DiscountCodeSchemaTicket.validate_quantity(schema, data, original_data)

def test_amount_lte_ticket_price(self):
"""
Discount Code Validate Amount Value - Tests if function runs without an exception
:return:
"""
with app.test_request_context():
ticket = TicketFactory()
ticket.price = 100
save_to_db(ticket)

schema = DiscountCodeSchemaTicket()
original_data = {
'data': {}
}
data = {
'type': 'amount',
'value': 70,
'tickets': ['1']
}
DiscountCodeSchemaTicket.validate_value(schema, data, original_data)

def test_amount_gt_ticket_price(self):
"""
Discount Code Validate Amount Value - Tests if exception is raised when discount value is gt ticket price
:return:
"""
with app.test_request_context():
ticket = TicketFactory()
ticket.price = 100
save_to_db(ticket)

schema = DiscountCodeSchemaTicket()
original_data = {
'data': {}
}
data = {
'type': 'amount',
'value': 150,
'tickets': ['1']
}
with self.assertRaises(UnprocessableEntity):
DiscountCodeSchemaTicket.validate_value(schema, data, original_data)

def test_free_ticket(self):
"""
Discount Code Validate Amount Value - Tests exception when discount code is created for free ticket
:return:
"""
with app.test_request_context():
ticket = TicketFactory()
ticket.price = 0
save_to_db(ticket)

schema = DiscountCodeSchemaTicket()
original_data = {
'data': {}
}
data = {
'type': 'amount',
'value': 150,
'tickets': ['1']
}
with self.assertRaises(UnprocessableEntity):
DiscountCodeSchemaTicket.validate_value(schema, data, original_data)

def test_quantity_db_populate(self):
"""
Discount Code Validate Quantity - Tests if validation works on values stored in db and not given in 'data'
Expand Down
45 changes: 45 additions & 0 deletions tests/all/unit/api/validation/test_discount_codes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import unittest

from tests.all.integration.utils import OpenEventTestCase
from app.api.helpers.exceptions import UnprocessableEntity
from app.api.schema.discount_codes import DiscountCodeSchemaTicket


class TestDiscountCodeValidation(OpenEventTestCase):

def test_percent_value_lte_hundred(self):
"""
Discount Code Validate Percentage Value - Tests if function runs without an exception
:return:
"""
schema = DiscountCodeSchemaTicket()
original_data = {
'data': {}
}
data = {
'type': 'percent',
'value': 90,
'tickets': []
}
DiscountCodeSchemaTicket.validate_value(schema, data, original_data)

def test_percent_value_gt_hundred(self):
"""
Discount Code Validate Percentage Value - Tests if exception is raised when percentage value is greater than 100
:return:
"""
schema = DiscountCodeSchemaTicket()
original_data = {
'data': {}
}
data = {
'type': 'percent',
'value': 110,
'tickets': []
}
with self.assertRaises(UnprocessableEntity):
DiscountCodeSchemaTicket.validate_value(schema, data, original_data)


if __name__ == '__main__':
unittest.main()