Repository: fossasia/open-event-server

Issue:
Add unit tests for validation functions of each schema 
Add unit tests for validation functions of each schema


Discussion:

Resolving patch:
diff --git a/app/api/discount_codes.py b/app/api/discount_codes.py
--- a/app/api/discount_codes.py
+++ b/app/api/discount_codes.py
@@ -46,9 +46,9 @@ def validate_quantity(self, data, original_data):
                                           "min-quantity should be less than max-quantity")
 
         if 'tickets_number' in data and 'max_quantity' in data:
-            if data['tickets_number'] < data['min_quantity']:
+            if data['tickets_number'] < data['max_quantity']:
                     raise UnprocessableEntity({'pointer': '/data/attributes/tickets-number'},
-                                              "tickets-number should be greater than min-quantity")
+                                              "tickets-number should be greater than max-quantity")
 
     id = fields.Integer()
     code = fields.Str(required=True)
@@ -103,9 +103,9 @@ def validate_quantity(self, data, original_data):
                                           "min-quantity should be less than max-quantity")
 
         if 'tickets_number' in data and 'max_quantity' in data:
-            if data['tickets_number'] < data['min_quantity']:
+            if data['tickets_number'] < data['max_quantity']:
                     raise UnprocessableEntity({'pointer': '/data/attributes/tickets-number'},
-                                              "tickets-number should be greater than min-quantity")
+                                              "tickets-number should be greater than max-quantity")
 
     id = fields.Integer()
     code = fields.Str(required=True)
diff --git a/app/api/tickets.py b/app/api/tickets.py
--- a/app/api/tickets.py
+++ b/app/api/tickets.py
@@ -37,7 +37,7 @@ def validate_date(self, data, original_data):
                                       "sales-ends-at should be after sales-starts-at")
 
     @validates_schema
-    def validate_order_quantity(self, data):
+    def validate_quantity(self, data):
         if 'max_order' in data and 'min_order' in data:
             if data['max_order'] < data['min_order']:
                 raise UnprocessableEntity({'pointer': '/data/attributes/max-order'},
diff --git a/app/factories/discount_code.py b/app/factories/discount_code.py
--- a/app/factories/discount_code.py
+++ b/app/factories/discount_code.py
@@ -15,9 +15,9 @@ class Meta:
     value = common.float_
     type = "amount"
     is_active = True
-    tickets_number = 10
+    tickets_number = 30
     min_quantity = 10
-    max_quantity = 10
+    max_quantity = 20
     valid_from = common.date_
     valid_till = common.dateEnd_
     used_for = "event"


Test patch:
diff --git a/tests/unittests/api/__init__.py b/tests/unittests/api/__init__.py
new file mode 100644
diff --git a/tests/unittests/api/validation/__init__.py b/tests/unittests/api/validation/__init__.py
new file mode 100644
diff --git a/tests/unittests/api/validation/test_discount_codes.py b/tests/unittests/api/validation/test_discount_codes.py
new file mode 100644
--- /dev/null
+++ b/tests/unittests/api/validation/test_discount_codes.py
@@ -0,0 +1,86 @@
+import unittest
+
+from app import current_app as app
+from tests.unittests.utils import OpenEventTestCase
+from app.api.discount_codes import DiscountCodeSchemaTicket, UnprocessableEntity
+from app.factories.discount_code import DiscountCodeFactory
+from app.models import db
+from tests.unittests.setup_database import Setup
+
+
+class TestDiscountCodeValidation(OpenEventTestCase):
+    def setUp(self):
+        self.app = Setup.create_app()
+
+    def test_quantity_pass(self):
+        """
+        Discount Code Validate Quantity - Tests if the function runs without an exception
+        :return:
+        """
+        schema = DiscountCodeSchemaTicket()
+        original_data = {
+            'data': {}
+        }
+        data = {
+            'min_quantity': 10,
+            'max_quantity': 20,
+            'tickets_number': 30
+        }
+        DiscountCodeSchemaTicket.validate_quantity(schema, data, original_data)
+
+    def test_quantity_min_gt_max(self):
+        """
+        Discount Code Validate Quantity - Tests if exception is raised when min_quantity greater than max
+        :return:
+        """
+        schema = DiscountCodeSchemaTicket()
+        original_data = {
+            'data': {}
+        }
+        data = {
+            'min_quantity': 20,
+            'max_quantity': 10,
+            'tickets_number': 30
+        }
+        with self.assertRaises(UnprocessableEntity):
+            DiscountCodeSchemaTicket.validate_quantity(schema, data, original_data)
+
+    def test_quantity_max_gt_tickets_number(self):
+        """
+        Discount Code Validate Quantity - Tests if exception is raised when min_quantity greater than max
+        :return:
+        """
+        schema = DiscountCodeSchemaTicket()
+        original_data = {
+            'data': {}
+        }
+        data = {
+            'min_quantity': 10,
+            'max_quantity': 30,
+            'tickets_number': 20
+        }
+        with self.assertRaises(UnprocessableEntity):
+            DiscountCodeSchemaTicket.validate_quantity(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'
+        :return:
+        """
+        with app.test_request_context():
+            schema = DiscountCodeSchemaTicket()
+            obj = DiscountCodeFactory()
+            db.session.add(obj)
+            db.session.commit()
+
+            original_data = {
+                'data': {
+                    'id': 1
+                }
+            }
+            data = {}
+            DiscountCodeSchemaTicket.validate_quantity(schema, data, original_data)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/unittests/api/validation/test_events.py b/tests/unittests/api/validation/test_events.py
new file mode 100644
--- /dev/null
+++ b/tests/unittests/api/validation/test_events.py
@@ -0,0 +1,96 @@
+import unittest
+from datetime import datetime
+from pytz import timezone
+
+from app import current_app as app
+from tests.unittests.utils import OpenEventTestCase
+from app.api.events import EventSchema, UnprocessableEntity
+from app.factories.event import EventFactoryBasic
+from app.models import db
+from tests.unittests.setup_database import Setup
+
+
+class TestEventValidation(OpenEventTestCase):
+    def setUp(self):
+        self.app = Setup.create_app()
+
+    def test_date_pass(self):
+        """
+        Events Validate Date - Tests if the function runs without an exception
+        :return:
+        """
+        schema = EventSchema()
+        original_data = {
+            'data': {}
+        }
+        data = {
+            'starts_at': datetime(2003, 8, 4, 12, 30, 45).replace(tzinfo=timezone('UTC')),
+            'ends_at': datetime(2003, 9, 4, 12, 30, 45).replace(tzinfo=timezone('UTC'))
+        }
+        EventSchema.validate_date(schema, data, original_data)
+
+    def test_date_start_gt_end(self):
+        """
+        Events Validate Date - Tests if exception is raised when ends_at is before starts_at
+        :return:
+        """
+        schema = EventSchema()
+        original_data = {
+            'data': {}
+        }
+        data = {
+            'starts_at': datetime(2003, 9, 4, 12, 30, 45).replace(tzinfo=timezone('UTC')),
+            'ends_at': datetime(2003, 8, 4, 12, 30, 45).replace(tzinfo=timezone('UTC'))
+        }
+        with self.assertRaises(UnprocessableEntity):
+            EventSchema.validate_date(schema, data, original_data)
+
+    def test_date_db_populate(self):
+        """
+        Events Validate Date - Tests if validation works on values stored in db and not given in 'data'
+        :return:
+        """
+        with app.test_request_context():
+            schema = EventSchema()
+            obj = EventFactoryBasic()
+            db.session.add(obj)
+            db.session.commit()
+
+            original_data = {
+                'data': {
+                    'id': 1
+                }
+            }
+            data = {}
+            EventSchema.validate_date(schema, data, original_data)
+
+    def test_timezone_pass(self):
+        """
+        Events Validate Timezone - Tests if the function runs without an exception
+        :return:
+        """
+        schema = EventSchema()
+        data = {
+            'starts_at': datetime(2003, 8, 4, 12, 30, 45).replace(tzinfo=timezone('UTC')),
+            'ends_at': datetime(2003, 9, 4, 12, 30, 45).replace(tzinfo=timezone('UTC')),
+            'timezone': 'UTC'
+        }
+        EventSchema.validate_timezone(schema, data)
+
+    def test_timezone_fail(self):
+        """
+        Events Validate Timezone - Tests if the function raises an exception
+        :return:
+        """
+        schema = EventSchema()
+        data = {
+            'starts_at': datetime(2003, 8, 4, 12, 30, 45).replace(tzinfo=timezone('UTC')),
+            'ends_at': datetime(2003, 9, 4, 12, 30, 45).replace(tzinfo=timezone('UTC')),
+            'timezone': 'Asia/Kolkata'
+        }
+        with self.assertRaises(UnprocessableEntity):
+            EventSchema.validate_timezone(schema, data)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/unittests/api/validation/test_sessions.py b/tests/unittests/api/validation/test_sessions.py
new file mode 100644
--- /dev/null
+++ b/tests/unittests/api/validation/test_sessions.py
@@ -0,0 +1,69 @@
+import unittest
+from datetime import datetime
+from pytz import timezone
+
+from app import current_app as app
+from tests.unittests.utils import OpenEventTestCase
+from app.api.sessions import SessionSchema, UnprocessableEntity
+from app.factories.session import SessionFactory
+from app.models import db
+from tests.unittests.setup_database import Setup
+
+
+class TestSessionValidation(OpenEventTestCase):
+    def setUp(self):
+        self.app = Setup.create_app()
+
+    def test_date_pass(self):
+        """
+        Sessions Validate Date - Tests if the function runs without an exception
+        :return:
+        """
+        schema = SessionSchema()
+        original_data = {
+            'data': {}
+        }
+        data = {
+            'starts_at': datetime(2003, 8, 4, 12, 30, 45).replace(tzinfo=timezone('UTC')),
+            'ends_at': datetime(2003, 9, 4, 12, 30, 45).replace(tzinfo=timezone('UTC'))
+        }
+        SessionSchema.validate_date(schema, data, original_data)
+
+    def test_date_start_gt_end(self):
+        """
+        Sessions Validate Date - Tests if exception is raised when ends_at is before starts_at
+        :return:
+        """
+        schema = SessionSchema()
+        original_data = {
+            'data': {}
+        }
+        data = {
+            'starts_at': datetime(2003, 9, 4, 12, 30, 45).replace(tzinfo=timezone('UTC')),
+            'ends_at': datetime(2003, 8, 4, 12, 30, 45).replace(tzinfo=timezone('UTC'))
+        }
+        with self.assertRaises(UnprocessableEntity):
+            SessionSchema.validate_date(schema, data, original_data)
+
+    def test_date_db_populate(self):
+        """
+        Sessions Validate Date - Tests if validation works on values stored in db and not given in 'data'
+        :return:
+        """
+        with app.test_request_context():
+            schema = SessionSchema()
+            obj = SessionFactory()
+            db.session.add(obj)
+            db.session.commit()
+
+            original_data = {
+                'data': {
+                    'id': 1
+                }
+            }
+            data = {}
+            SessionSchema.validate_date(schema, data, original_data)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/unittests/api/validation/test_speakers_call.py b/tests/unittests/api/validation/test_speakers_call.py
new file mode 100644
--- /dev/null
+++ b/tests/unittests/api/validation/test_speakers_call.py
@@ -0,0 +1,69 @@
+import unittest
+from datetime import datetime
+from pytz import timezone
+
+from app import current_app as app
+from tests.unittests.utils import OpenEventTestCase
+from app.api.speakers_calls import SpeakersCallSchema, UnprocessableEntity
+from app.factories.speakers_call import SpeakersCallFactory
+from app.models import db
+from tests.unittests.setup_database import Setup
+
+
+class TestSpeakersCallValidation(OpenEventTestCase):
+    def setUp(self):
+        self.app = Setup.create_app()
+
+    def test_date_pass(self):
+        """
+        Speakers Call Validate Date - Tests if the function runs without an exception
+        :return:
+        """
+        schema = SpeakersCallSchema()
+        original_data = {
+            'data': {}
+        }
+        data = {
+            'starts_at': datetime(2003, 8, 4, 12, 30, 45).replace(tzinfo=timezone('UTC')),
+            'ends_at': datetime(2003, 9, 4, 12, 30, 45).replace(tzinfo=timezone('UTC'))
+        }
+        SpeakersCallSchema.validate_date(schema, data, original_data)
+
+    def test_date_start_gt_end(self):
+        """
+        Speakers Call Validate Date - Tests if exception is raised when ends_at is before starts_at
+        :return:
+        """
+        schema = SpeakersCallSchema()
+        original_data = {
+            'data': {}
+        }
+        data = {
+            'starts_at': datetime(2003, 9, 4, 12, 30, 45).replace(tzinfo=timezone('UTC')),
+            'ends_at': datetime(2003, 8, 4, 12, 30, 45).replace(tzinfo=timezone('UTC'))
+        }
+        with self.assertRaises(UnprocessableEntity):
+            SpeakersCallSchema.validate_date(schema, data, original_data)
+
+    def test_date_db_populate(self):
+        """
+        Speakers Call Validate Date - Tests if validation works on values stored in db and not given in 'data'
+        :return:
+        """
+        with app.test_request_context():
+            schema = SpeakersCallSchema()
+            obj = SpeakersCallFactory()
+            db.session.add(obj)
+            db.session.commit()
+
+            original_data = {
+                'data': {
+                    'id': 1
+                }
+            }
+            data = {}
+            SpeakersCallSchema.validate_date(schema, data, original_data)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/unittests/api/validation/test_tickets.py b/tests/unittests/api/validation/test_tickets.py
new file mode 100644
--- /dev/null
+++ b/tests/unittests/api/validation/test_tickets.py
@@ -0,0 +1,110 @@
+import unittest
+from datetime import datetime
+from pytz import timezone
+
+from app import current_app as app
+from tests.unittests.utils import OpenEventTestCase
+from app.api.tickets import TicketSchema, UnprocessableEntity
+from app.factories.ticket import TicketFactory
+from app.models import db
+from tests.unittests.setup_database import Setup
+
+
+class TestTicketValidation(OpenEventTestCase):
+    def setUp(self):
+        self.app = Setup.create_app()
+
+    def test_date_pass(self):
+        """
+        Tickets Validate Date - Tests if the function runs without an exception
+        :return:
+        """
+        schema = TicketSchema()
+        original_data = {
+            'data': {}
+        }
+        data = {
+            'sales_starts_at': datetime(2003, 8, 4, 12, 30, 45).replace(tzinfo=timezone('UTC')),
+            'sales_ends_at': datetime(2003, 9, 4, 12, 30, 45).replace(tzinfo=timezone('UTC'))
+        }
+        TicketSchema.validate_date(schema, data, original_data)
+
+    def test_date_start_gt_end(self):
+        """
+        Tickets Validate Date - Tests if exception is raised when sales_ends_at is before sales_starts_at
+        :return:
+        """
+        schema = TicketSchema()
+        original_data = {
+            'data': {}
+        }
+        data = {
+            'sales_starts_at': datetime(2003, 9, 4, 12, 30, 45).replace(tzinfo=timezone('UTC')),
+            'sales_ends_at': datetime(2003, 8, 4, 12, 30, 45).replace(tzinfo=timezone('UTC'))
+        }
+        with self.assertRaises(UnprocessableEntity):
+            TicketSchema.validate_date(schema, data, original_data)
+
+    def test_date_db_populate(self):
+        """
+        Tickets Validate Date - Tests if validation works on values stored in db and not given in 'data'
+        :return:
+        """
+        with app.test_request_context():
+            schema = TicketSchema()
+            obj = TicketFactory()
+            db.session.add(obj)
+            db.session.commit()
+
+            original_data = {
+                'data': {
+                    'id': 1
+                }
+            }
+            data = {}
+            TicketSchema.validate_date(schema, data, original_data)
+
+    def test_quantity_pass(self):
+        """
+        Tickets Validate Quantity - Tests if the function runs without an exception
+        :return:
+        """
+        schema = TicketSchema()
+        data = {
+            'min_order': 10,
+            'max_order': 20,
+            'quantity': 30
+        }
+        TicketSchema.validate_quantity(schema, data)
+
+    def test_quantity_min_gt_max(self):
+        """
+        Tickets Validate Quantity - Tests if exception is raised when min_order greater than max
+        :return:
+        """
+        schema = TicketSchema()
+        data = {
+            'min_order': 20,
+            'max_order': 10,
+            'quantity': 30
+        }
+        with self.assertRaises(UnprocessableEntity):
+            TicketSchema.validate_quantity(schema, data)
+
+    def test_quantity_quantity_gt_min(self):
+        """
+        Tickets Validate Quantity - Tests if exception is raised when quantity less than max_order
+        :return:
+        """
+        schema = TicketSchema()
+        data = {
+            'min_order': 10,
+            'max_order': 20,
+            'quantity': 5
+        }
+        with self.assertRaises(UnprocessableEntity):
+            TicketSchema.validate_quantity(schema, data)
+
+
+if __name__ == '__main__':
+    unittest.main()