Repository: fossasia/open-event-server

Issue:
Add event type and topic to Event API
They were added in #813 .
Plan to use a custom field type `fields.Choice` that will allow using only one of the already predefined values. (same as what has been done in [813 (diff)](https://github.com/fossasia/open-event-orga-server/pull/813/files#diff-7043e7db96fb8828645d33ff63695cc9R352))



Discussion:

Resolving patch:
diff --git a/open_event/api/events.py b/open_event/api/events.py
--- a/open_event/api/events.py
+++ b/open_event/api/events.py
@@ -6,9 +6,11 @@
 from open_event.helpers.data import save_to_db, update_version
 
 from .helpers.helpers import get_paginated_list, requires_auth
-from .helpers.utils import PAGINATED_MODEL, PaginatedResourceBase, PAGE_PARAMS, \
-    POST_RESPONSES, PUT_RESPONSES, BaseDAO
+from .helpers.utils import PAGINATED_MODEL, PaginatedResourceBase, \
+    PAGE_PARAMS, POST_RESPONSES, PUT_RESPONSES, BaseDAO
 from .helpers import custom_fields as fields
+from helpers.special_fields import EventTypeField, EventTopicField
+
 
 api = Namespace('events', description='Events')
 
@@ -30,6 +32,8 @@
     'organizer_description': fields.String(),
     'state': fields.String(),
     'closing_datetime': fields.DateTime(),
+    'type': EventTypeField(),
+    'topic': EventTopicField()
 })
 
 EVENT_PAGINATED = api.clone('EventPaginated', PAGINATED_MODEL, {
diff --git a/open_event/api/helpers/custom_fields.py b/open_event/api/helpers/custom_fields.py
--- a/open_event/api/helpers/custom_fields.py
+++ b/open_event/api/helpers/custom_fields.py
@@ -197,3 +197,22 @@ def validate(self, value):
         except Exception:
             self.validation_error = '%s should be a Number'
             return False
+
+
+class ChoiceString(String):
+    """
+    Choice String Field. Allow only one of the given options
+    Args:
+        choice_list - List of valid choices
+    """
+    def __init__(self, **kwargs):
+        super(ChoiceString, self).__init__(**kwargs)
+        self.choice_list = kwargs.get('choice_list', [])
+
+    def validate(self, value):
+        if not value:
+            return self.validate_empty()
+        if value not in self.choice_list:
+            self.validation_error = 'Value of %s is not in available choices'
+            return False
+        return True
diff --git a/open_event/api/helpers/special_fields.py b/open_event/api/helpers/special_fields.py
new file mode 100644
--- /dev/null
+++ b/open_event/api/helpers/special_fields.py
@@ -0,0 +1,21 @@
+from open_event.helpers.data_getter import DataGetter
+
+import custom_fields as fields
+
+
+class EventTypeField(fields.ChoiceString):
+    __schema_example__ = DataGetter.get_event_types()[0]
+
+    def __init__(self, **kwargs):
+        super(EventTypeField, self).__init__(
+            choice_list=DataGetter.get_event_types(),
+            **kwargs)
+
+
+class EventTopicField(fields.ChoiceString):
+    __schema_example__ = DataGetter.get_event_topics()[0]
+
+    def __init__(self, **kwargs):
+        super(EventTopicField, self).__init__(
+            choice_list=DataGetter.get_event_topics(),
+            **kwargs)


Test patch:
diff --git a/tests/api/test_custom_fields.py b/tests/api/test_custom_fields.py
--- a/tests/api/test_custom_fields.py
+++ b/tests/api/test_custom_fields.py
@@ -1,6 +1,6 @@
 import unittest
 from open_event.api.helpers.custom_fields import Color, Email, Uri,\
-    ImageUri, DateTime, Integer, Float
+    ImageUri, DateTime, Integer, Float, ChoiceString
 
 
 class TestCustomFieldsValidation(unittest.TestCase):
@@ -64,6 +64,13 @@ def test_float_field(self):
         self._test_common(field)
         self.assertTrue(field.validate(92))
 
+    def test_choice_string_field(self):
+        field = ChoiceString(choice_list=['a', 'b', 'c'])
+        self._test_common(field)
+        self.assertTrue(field.validate('a'))
+        self.assertFalse(field.validate('d'))
+        self.assertFalse(field.validate('ab'))
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/tests/api/utils_post_data.py b/tests/api/utils_post_data.py
--- a/tests/api/utils_post_data.py
+++ b/tests/api/utils_post_data.py
@@ -15,7 +15,12 @@
     'background_url': "http://imgur.com/image.png",
     'description': "blah blah",
     "start_time": "2016-05-25 12:12:43",
-    "closing_datetime": "2016-05-22 12:12:43"
+    "closing_datetime": "2016-05-22 12:12:43",
+    "organizer_name": "FOSSASIA",
+    "organizer_description": "Promoting Open Source culture around the world",
+    "state": "TestEvent",
+    "type": "Conference",
+    "topic": "Science & Technology"
 }
 
 POST_FORMAT_DATA = {