From 839b18b59eb3f867647097b4bccdc6d8d48dbba1 Mon Sep 17 00:00:00 2001 From: Ryan Bagwell Date: Sun, 21 Jun 2015 12:26:07 -0500 Subject: [PATCH 1/8] adding publish and unpublish methods --- eventbrite/apiv3_url_mapping.json | 14 +++++++++++++- eventbrite/client.py | 8 ++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/eventbrite/apiv3_url_mapping.json b/eventbrite/apiv3_url_mapping.json index 7cee173..bfd1af4 100644 --- a/eventbrite/apiv3_url_mapping.json +++ b/eventbrite/apiv3_url_mapping.json @@ -17,6 +17,18 @@ "serializer": "Event", "url_regexp": "^events/(?P\\d+)/$" }, + { + "data_type": "serialized", + "response_type": "single_response", + "serializer": "Event", + "url_regexp": "^events/(?P\\d+)/publish/$" + }, + { + "data_type": "serialized", + "response_type": "single_response", + "serializer": "Event", + "url_regexp": "^events/(?P\\d+)/unpublish/$" + }, { "data_type": "serialized", "response_type": "paginated_response", @@ -366,4 +378,4 @@ "serializer": "MobileDevice", "url_regexp": "^devices/me/$" } -] \ No newline at end of file +] diff --git a/eventbrite/client.py b/eventbrite/client.py index 241d692..094caa9 100755 --- a/eventbrite/client.py +++ b/eventbrite/client.py @@ -209,6 +209,14 @@ def post_event(self, data): return self.post("/events/", data=data) + def publish_event(self, event_id): + + return self.post("/events/%s/publish/" % event_id) + + def unpublish_event(self, event_id): + + return self.post("/events/%s/unpublish/" % event_id) + def event_search(self, **data): # Resolves the search result response problem return self.get("/events/search/", data=data) From 715c2417409dc52939806d910cbccf327ef422ec Mon Sep 17 00:00:00 2001 From: Ryan Bagwell Date: Sun, 21 Jun 2015 12:28:08 -0500 Subject: [PATCH 2/8] testing post_event method instead of bypassing post_event method --- tests/integration/test_events.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/test_events.py b/tests/integration/test_events.py index 416855e..9b7d2ae 100644 --- a/tests/integration/test_events.py +++ b/tests/integration/test_events.py @@ -55,7 +55,7 @@ def test_post_event(self): 'event.password': "test", 'event.capacity': 10, } - event = self.eventbrite.post('/events/', data=event_data) + event = self.eventbrite.post_event(event_data) self.assertEqual(event_name, event['name']['text']) self.assertEqual(event_name, event['name']['html']) # Just for access to see the event, not full authentication From 48c028e6a612a50b8183f14a4b1a0aaad511bd59 Mon Sep 17 00:00:00 2001 From: Ryan Bagwell Date: Sun, 21 Jun 2015 12:43:14 -0500 Subject: [PATCH 3/8] creating common method for generating event data, and making event dates in the future --- tests/integration/test_events.py | 54 +++++++++++++++++++------------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/tests/integration/test_events.py b/tests/integration/test_events.py index 9b7d2ae..5a041e5 100644 --- a/tests/integration/test_events.py +++ b/tests/integration/test_events.py @@ -2,7 +2,8 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from datetime import datetime +from datetime import datetime, timedelta +from time import strftime import os from eventbrite import Eventbrite @@ -21,6 +22,8 @@ except KeyError: skip_user_id_tests = True +EB_ISO_FORMAT = '%Y-%m-%dT%H:%M:%SZ' + class TestEvents(unittest.TestCase): @@ -32,19 +35,43 @@ def setUp(self): condition=skip_integration_tests, reason='Needs an OAUTH_TOKEN') def test_post_event(self): - event_name = 'client_test_{0}'.format(datetime.now()) + event_data = self._get_event_data(event_name) + event = self.eventbrite.post_event(event_data) + self.assertEqual(event_name, event['name']['text']) + self.assertEqual(event_name, event['name']['html']) + # Just for access to see the event, not full authentication + self.assertEqual(event['password'], "test") + + @unittest.skipIf(condition=skip_user_id_tests, reason='Needs a USER_ID') + @unittest.skipIf( + condition=skip_integration_tests, reason='Needs an OAUTH_TOKEN') + def test_search_events(self): + data = { + 'location.latitude': '40.4313684', + 'start_date.keyword': 'today', + 'location.longitude': '-79.9805005', + 'location.within': '10km' + } + events = self.eventbrite.event_search(**data) + self.assertLess(events['pagination'][u'object_count'], 1000) + + def _get_event_data(self, event_name=None): + """ Returns a dictionary representing a valid event """ + + if not event_name: + event_name = 'client_test_{0}'.format(datetime.now()) event_data = { 'event.name': { 'html': event_name, }, 'event.start': { - 'utc': '2015-03-07T20:00:00Z', + 'utc': (datetime.now() + timedelta(days=1)).strftime(EB_ISO_FORMAT), 'timezone': 'America/Los_Angeles', }, 'event.end': { - 'utc': '2015-03-07T23:00:00Z', + 'utc': (datetime.now() + timedelta(days=1,hours=1)).strftime(EB_ISO_FORMAT), 'timezone': 'America/Los_Angeles', }, 'event.currency': 'USD', @@ -55,24 +82,9 @@ def test_post_event(self): 'event.password': "test", 'event.capacity': 10, } - event = self.eventbrite.post_event(event_data) - self.assertEqual(event_name, event['name']['text']) - self.assertEqual(event_name, event['name']['html']) - # Just for access to see the event, not full authentication - self.assertEqual(event['password'], "test") - @unittest.skipIf(condition=skip_user_id_tests, reason='Needs a USER_ID') - @unittest.skipIf( - condition=skip_integration_tests, reason='Needs an OAUTH_TOKEN') - def test_search_events(self): - data = { - 'location.latitude': '40.4313684', - 'start_date.keyword': 'today', - 'location.longitude': '-79.9805005', - 'location.within': '10km' - } - events = self.eventbrite.event_search(**data) - self.assertLess(events['pagination'][u'object_count'], 1000) + return event_data + if __name__ == '__main__': unittest.main() From 80ba3ebba59ae1bbc774831863b41b89a2b72b90 Mon Sep 17 00:00:00 2001 From: Ryan Bagwell Date: Sun, 21 Jun 2015 13:25:34 -0500 Subject: [PATCH 4/8] adding post_event_ticket_class_method --- eventbrite/client.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/eventbrite/client.py b/eventbrite/client.py index 094caa9..0123a4e 100755 --- a/eventbrite/client.py +++ b/eventbrite/client.py @@ -217,6 +217,9 @@ def unpublish_event(self, event_id): return self.post("/events/%s/unpublish/" % event_id) + def post_event_ticket_class(self, event_id, data): + return self.post("/events/{0}/ticket_classes/".format(event_id), data=data) + def event_search(self, **data): # Resolves the search result response problem return self.get("/events/search/", data=data) From 89eb0ad0f27b3f899c8d5705a6dc19130eaa958d Mon Sep 17 00:00:00 2001 From: Ryan Bagwell Date: Sun, 21 Jun 2015 13:26:53 -0500 Subject: [PATCH 5/8] adding tests for publish_event, unpublish_event and post_event_ticket_class methods --- tests/integration/test_events.py | 57 ++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/tests/integration/test_events.py b/tests/integration/test_events.py index 5a041e5..e5ff3e6 100644 --- a/tests/integration/test_events.py +++ b/tests/integration/test_events.py @@ -56,13 +56,60 @@ def test_search_events(self): events = self.eventbrite.event_search(**data) self.assertLess(events['pagination'][u'object_count'], 1000) - def _get_event_data(self, event_name=None): + def test_publish_unpublish_event(self): + + """ First, creat a draft event """ + event_data = self._get_event_data() + event = self.eventbrite.post_event(event_data) + self.assertTrue(event.ok, + msg=event.get('error_description', None)) + + """ Next, create a ticket class for the event, because an event + can't be published without one """ + ticket_data = self._get_ticket_data() + response = self.eventbrite.post_event_ticket_class(event['id'], + data=ticket_data) + + """Finally, try to publish the event""" + response = self.eventbrite.publish_event(event['id']) + self.assertTrue(response.ok, + msg=response.get('error_description', None)) + + """Now try to unpublish the event""" + response = self.eventbrite.unpublish_event(event['id']) + self.assertTrue(response.ok, + msg=response.get('error_description', None)) + + def test_create_ticket_class(self): + + event_data = self._get_event_data() + event = self.eventbrite.post_event(event_data) + + ticket_data = self._get_ticket_data() + response = self.eventbrite.post_event_ticket_class(event['id'], + data=ticket_data) + self.assertTrue(response.ok, + msg=response.get('error_description', None)) + + def _get_ticket_data(self): + + return { + 'ticket_class.name': 'client_test_ticket_{0}'.format(datetime.now()), + 'ticket_class.description': 'Python API Client testing', + 'ticket_class.quantity_total': 100, + 'ticket_class.cost': { + "currency": 'USD', + 'value': 200, + } + } + + def _get_event_data(self, event_name='client_test_{0}'.format(datetime.now())): """ Returns a dictionary representing a valid event """ - if not event_name: - event_name = 'client_test_{0}'.format(datetime.now()) + # if not event_name: + # event_name = 'client_test_{0}'.format(datetime.now()) - event_data = { + return { 'event.name': { 'html': event_name, }, @@ -83,8 +130,6 @@ def _get_event_data(self, event_name=None): 'event.capacity': 10, } - return event_data - if __name__ == '__main__': unittest.main() From 3bc031b257f7c940bf1de0afc77e44b34a1a79e9 Mon Sep 17 00:00:00 2001 From: Ryan Bagwell Date: Sun, 21 Jun 2015 13:59:23 -0500 Subject: [PATCH 6/8] adding missing key from response dictionary so get_api test passes --- tests/integration/test_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/test_client.py b/tests/integration/test_client.py index 5c8cdc8..1db601a 100644 --- a/tests/integration/test_client.py +++ b/tests/integration/test_client.py @@ -37,7 +37,7 @@ def test_api_get(self): payload = eventbrite.api("get", "/users/me/", {}) self.assertEqual( - sorted([u'id', u'first_name', u'last_name', u'emails', u'name']), + sorted([u'id', u'image_id', u'first_name', u'last_name', u'emails', u'name']), sorted(payload.keys()) ) From 715711eb84b9aa69ee9c1bc48386ea1bd26b5103 Mon Sep 17 00:00:00 2001 From: Daniel Greenfeld Date: Mon, 29 Jun 2015 10:43:49 -0700 Subject: [PATCH 7/8] Added URL --- HISTORY.rst | 19 ++++++++++++------- eventbrite/client.py | 4 ++-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 0452e3e..a40806d 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -3,42 +3,47 @@ History ------- -3.1.0 (2014-05-11) +3.2.0 (2015-06-28) +------------------- + +* Eventbrite client now accepts an ``eventbrite_api_url`` argument. + +3.1.0 (2015-05-11) ------------------ * Added control over expansion of response. Documentation at http://www.eventbrite.com/developer/v3/reference/expansions/ -3.0.5 (2014-04-24) +3.0.5 (2015-04-24) ------------------ * Removed 'content-type' header from all GET requests. Thank you @xxv for identifying the problem and contributing code. -3.0.4 (2014-03-12) +3.0.4 (2015-03-12) ------------------ * Resolved the search result response problem where filtering did not work. -3.0.3 (2014-03-02) +3.0.3 (2015-03-02) ------------------ * Fixed import issue with ``__version__``. Thank you @meshy and @longjos for identifying the problem. -3.0.2 (2014-01-30) +3.0.2 (2015-01-30) ------------------ * Event creation now working. * Added feature allowing the use of Eventbrite API url at test servers. Should expedite development of tricky post actions. -3.0.1 (2014-01-30) +3.0.1 (2015-01-30) ------------------ * Added reverse mapping for ``get_event_ticket_class()`` method. * Added ``events`` mapping to provide GET access to the Event endpoint. * Removed several deprecated JSON mappings. -3.0.0 (2014-01-28) +3.0.0 (2015-01-28) ------------------ * Initial release of 3.0.0 client diff --git a/eventbrite/client.py b/eventbrite/client.py index 0123a4e..2ce28f1 100755 --- a/eventbrite/client.py +++ b/eventbrite/client.py @@ -23,11 +23,11 @@ class Eventbrite(AccessMethodsMixin): allowed_methods = ['post', 'get', 'delete'] - eventbrite_api_url = EVENTBRITE_API_URL content_type_specified = True - def __init__(self, oauth_token): + def __init__(self, oauth_token, eventbrite_api_url=EVENTBRITE_API_URL): self.oauth_token = oauth_token + self.eventbrite_api_url = EVENTBRITE_API_URL @property def headers(self): From fff2c368aa4e57ba40b8c899a84d4738398c8fd0 Mon Sep 17 00:00:00 2001 From: Daniel Greenfeld Date: Tue, 7 Jul 2015 16:28:49 -0700 Subject: [PATCH 8/8] Fix borked unit tests --- tests/integration/test_events.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/integration/test_events.py b/tests/integration/test_events.py index e5ff3e6..3207749 100644 --- a/tests/integration/test_events.py +++ b/tests/integration/test_events.py @@ -10,10 +10,10 @@ from ..base import unittest -try: - OAUTH_TOKEN = os.environ[u'EVENTBRITE_OAUTH_TOKEN'] +OAUTH_TOKEN = os.environ.get('EVENTBRITE_OAUTH_TOKEN', '') +if OAUTH_TOKEN: skip_integration_tests = False -except KeyError: +else: skip_integration_tests = True try: @@ -56,6 +56,8 @@ def test_search_events(self): events = self.eventbrite.event_search(**data) self.assertLess(events['pagination'][u'object_count'], 1000) + @unittest.skipIf( + condition=skip_integration_tests, reason='Needs an OAUTH_TOKEN') def test_publish_unpublish_event(self): """ First, creat a draft event """ @@ -80,6 +82,8 @@ def test_publish_unpublish_event(self): self.assertTrue(response.ok, msg=response.get('error_description', None)) + @unittest.skipIf( + condition=skip_integration_tests, reason='Needs an OAUTH_TOKEN') def test_create_ticket_class(self): event_data = self._get_event_data()