Skip to content
Prev Previous commit
Next Next commit
Move 'list_topics' from 'Connection' to '_PublisherAPI'.
  • Loading branch information
tseaver committed Apr 22, 2016
commit 2c7c58b12c21872725f4573c41d39c10552d6acb
4 changes: 2 additions & 2 deletions gcloud/pubsub/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ def list_topics(self, page_size=None, page_token=None):
more topics can be retrieved with another call (pass that
value as ``page_token``).
"""
conn = self.connection
resources, next_token = conn.list_topics(
api = self.publisher_api
resources, next_token = api.list_topics(
self.project, page_size, page_token)
topics = [Topic.from_api_repr(resource, self)
for resource in resources]
Expand Down
73 changes: 37 additions & 36 deletions gcloud/pubsub/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,42 +89,6 @@ def build_api_url(self, path, query_params=None,
path, query_params=query_params,
api_base_url=api_base_url, api_version=api_version)

def list_topics(self, project, page_size=None, page_token=None):
"""List topics for the project associated with this client.

See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/list

:type project: string
:param project: project ID

:type page_size: int
:param page_size: maximum number of topics to return, If not passed,
defaults to a value set by the API.

:type page_token: string
:param page_token: opaque marker for the next "page" of topics. If not
passed, the API will return the first page of
topics.

:rtype: tuple, (list, str)
:returns: list of ``Topic`` resource dicts, plus a
"next page token" string: if not None, indicates that
more topics can be retrieved with another call (pass that
value as ``page_token``).
"""
params = {}

if page_size is not None:
params['pageSize'] = page_size

if page_token is not None:
params['pageToken'] = page_token

path = '/projects/%s/topics' % (project,)
resp = self.api_request(method='GET', path=path, query_params=params)
return resp.get('topics', ()), resp.get('nextPageToken')

def list_subscriptions(self, project, page_size=None, page_token=None):
"""List subscriptions for the project associated with this client.

Expand Down Expand Up @@ -498,6 +462,43 @@ class _PublisherAPI(object):
def __init__(self, connection):
self._connection = connection

def list_topics(self, project, page_size=None, page_token=None):
"""List topics for the project associated with this API.

See:
https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/list

:type project: string
:param project: project ID

:type page_size: int
:param page_size: maximum number of topics to return, If not passed,
defaults to a value set by the API.

:type page_token: string
:param page_token: opaque marker for the next "page" of topics. If not
passed, the API will return the first page of
topics.

:rtype: tuple, (list, str)
:returns: list of ``Topic`` resource dicts, plus a
"next page token" string: if not None, indicates that
more topics can be retrieved with another call (pass that
value as ``page_token``).
"""
conn = self._connection
params = {}

if page_size is not None:
params['pageSize'] = page_size

if page_token is not None:
params['pageToken'] = page_token

path = '/projects/%s/topics' % (project,)
resp = conn.api_request(method='GET', path=path, query_params=params)
return resp.get('topics', ()), resp.get('nextPageToken')


class _SubscriberAPI(object):
"""Helper mapping subscriber-related APIs.
Expand Down
26 changes: 16 additions & 10 deletions gcloud/pubsub/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ def test_list_topics_no_paging(self):
creds = _Credentials()
client = self._makeOne(project=self.PROJECT, credentials=creds)
conn = client.connection = _Connection()
conn._list_topics_response = [{'name': self.TOPIC_PATH}], None
api = client._publisher_api = _FauxPublisherAPI()
api._list_topics_response = [{'name': self.TOPIC_PATH}], None

topics, next_page_token = client.list_topics()

Expand All @@ -80,7 +81,7 @@ def test_list_topics_no_paging(self):
self.assertEqual(next_page_token, None)

self.assertEqual(len(conn._requested), 0)

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

self.assertEqual(conn._listed_topics, (self.PROJECT, None, None))
self.assertEqual(api._listed_topics, (self.PROJECT, None, None))

def test_list_topics_with_paging(self):
from gcloud.pubsub.topic import Topic
Expand All @@ -90,7 +91,8 @@ def test_list_topics_with_paging(self):
creds = _Credentials()
client = self._makeOne(project=self.PROJECT, credentials=creds)
conn = client.connection = _Connection()
conn._list_topics_response = [{'name': self.TOPIC_PATH}], TOKEN2
api = client._publisher_api = _FauxPublisherAPI()
api._list_topics_response = [{'name': self.TOPIC_PATH}], TOKEN2

topics, next_page_token = client.list_topics(SIZE, TOKEN1)

Expand All @@ -100,21 +102,22 @@ def test_list_topics_with_paging(self):
self.assertEqual(next_page_token, TOKEN2)

self.assertEqual(len(conn._requested), 0)
self.assertEqual(conn._listed_topics, (self.PROJECT, 1, TOKEN1))
self.assertEqual(api._listed_topics, (self.PROJECT, 1, TOKEN1))

def test_list_topics_missing_key(self):
creds = _Credentials()
client = self._makeOne(project=self.PROJECT, credentials=creds)
conn = client.connection = _Connection()
conn._list_topics_response = (), None
api = client._publisher_api = _FauxPublisherAPI()
api._list_topics_response = (), None

topics, next_page_token = client.list_topics()

self.assertEqual(len(topics), 0)
self.assertEqual(next_page_token, None)

self.assertEqual(len(conn._requested), 0)
self.assertEqual(conn._listed_topics, (self.PROJECT, None, None))
self.assertEqual(api._listed_topics, (self.PROJECT, None, None))

def test_list_subscriptions_no_paging(self):
from gcloud.pubsub.subscription import Subscription
Expand Down Expand Up @@ -213,16 +216,19 @@ def create_scoped(self, scope):
return self


class _FauxPublisherAPI(object):

def list_topics(self, project, page_size, page_token):
self._listed_topics = (project, page_size, page_token)
return self._list_topics_response


class _Connection(object):

def __init__(self, *responses):
self._responses = responses
self._requested = []

def list_topics(self, project, page_size, page_token):
self._listed_topics = (project, page_size, page_token)
return self._list_topics_response

def list_subscriptions(self, project, page_size, page_token):
self._listed_subscriptions = (project, page_size, page_token)
return self._list_subscriptions_response
155 changes: 74 additions & 81 deletions gcloud/pubsub/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import unittest2


class TestConnection(unittest2.TestCase):
class _Base(unittest2.TestCase):
PROJECT = 'PROJECT'
LIST_TOPICS_PATH = 'projects/%s/topics' % (PROJECT,)
LIST_SUBSCRIPTIONS_PATH = 'projects/%s/subscriptions' % (PROJECT,)
Expand All @@ -25,13 +25,16 @@ class TestConnection(unittest2.TestCase):
SUB_NAME = 'subscription_name'
SUB_PATH = 'projects/%s/subscriptions/%s' % (PROJECT, SUB_NAME)

def _makeOne(self, *args, **kw):
return self._getTargetClass()(*args, **kw)


class TestConnection(_Base):

def _getTargetClass(self):
from gcloud.pubsub.connection import Connection
return Connection

def _makeOne(self, *args, **kw):
return self._getTargetClass()(*args, **kw)

def test_default_url(self):
conn = self._makeOne()
klass = self._getTargetClass()
Expand Down Expand Up @@ -119,77 +122,6 @@ def _verify_uri(self, uri, expected_path, **expected_qs):
qs = dict(parse.parse_qsl(query))
self.assertEqual(qs, expected_qs)

def test_list_topics_no_paging(self):
import json
RETURNED = {'topics': [{'name': self.TOPIC_PATH}]}
HEADERS = {
'status': '200',
'content-type': 'application/json',
}
http = _Http(HEADERS, json.dumps(RETURNED))
conn = self._makeOne(http=http)

topics, next_token = conn.list_topics(self.PROJECT)

self.assertEqual(len(topics), 1)
topic = topics[0]
self.assertTrue(isinstance(topic, dict))
self.assertEqual(topic['name'], self.TOPIC_PATH)
self.assertEqual(next_token, None)

self.assertEqual(http._called_with['method'], 'GET')
self._verify_uri(http._called_with['uri'], self.LIST_TOPICS_PATH)
self.assertEqual(http._called_with['body'], None)

def test_list_topics_with_paging(self):
import json
TOKEN1 = 'TOKEN1'
TOKEN2 = 'TOKEN2'
SIZE = 1
RETURNED = {
'topics': [{'name': self.TOPIC_PATH}],
'nextPageToken': 'TOKEN2',
}
HEADERS = {
'status': '200',
'content-type': 'application/json',
}
http = _Http(HEADERS, json.dumps(RETURNED))
conn = self._makeOne(http=http)

topics, next_token = conn.list_topics(
self.PROJECT, page_token=TOKEN1, page_size=SIZE)

self.assertEqual(len(topics), 1)
topic = topics[0]
self.assertTrue(isinstance(topic, dict))
self.assertEqual(topic['name'], self.TOPIC_PATH)
self.assertEqual(next_token, TOKEN2)

self.assertEqual(http._called_with['method'], 'GET')
self._verify_uri(http._called_with['uri'], self.LIST_TOPICS_PATH,
pageToken=TOKEN1, pageSize=str(SIZE))
self.assertEqual(http._called_with['body'], None)

def test_list_topics_missing_key(self):
import json
RETURNED = {}
HEADERS = {
'status': '200',
'content-type': 'application/json',
}
http = _Http(HEADERS, json.dumps(RETURNED))
conn = self._makeOne(http=http)

topics, next_token = conn.list_topics(self.PROJECT)

self.assertEqual(len(topics), 0)
self.assertEqual(next_token, None)

self.assertEqual(http._called_with['method'], 'GET')
self._verify_uri(http._called_with['uri'], self.LIST_TOPICS_PATH)
self.assertEqual(http._called_with['body'], None)

def test_list_subscriptions_no_paging(self):
import json
SUB_INFO = {'name': self.SUB_PATH, 'topic': self.TOPIC_PATH}
Expand Down Expand Up @@ -751,7 +683,7 @@ def test_subscription_modify_ack_deadline(self):
self.assertEqual(http._called_with['body'], json.dumps(BODY))


class Test_PublisherAPI(unittest2.TestCase):
class Test_PublisherAPI(_Base):

def _getTargetClass(self):
from gcloud.pubsub.connection import _PublisherAPI
Expand All @@ -765,8 +697,67 @@ def test_ctor(self):
api = self._makeOne(connection)
self.assertTrue(api._connection is connection)

def test_list_topics_no_paging(self):
RETURNED = {'topics': [{'name': self.TOPIC_PATH}]}
connection = _Connection(RETURNED)
api = self._makeOne(connection)

topics, next_token = api.list_topics(self.PROJECT)

class Test_SubscriberAPI(unittest2.TestCase):
self.assertEqual(len(topics), 1)
topic = topics[0]
self.assertTrue(isinstance(topic, dict))
self.assertEqual(topic['name'], self.TOPIC_PATH)
self.assertEqual(next_token, None)

self.assertEqual(connection._called_with['method'], 'GET')
path = '/%s' % (self.LIST_TOPICS_PATH,)
self.assertEqual(connection._called_with['path'], path)
self.assertEqual(connection._called_with['query_params'], {})

def test_list_topics_with_paging(self):
TOKEN1 = 'TOKEN1'
TOKEN2 = 'TOKEN2'
SIZE = 1
RETURNED = {
'topics': [{'name': self.TOPIC_PATH}],
'nextPageToken': 'TOKEN2',
}
connection = _Connection(RETURNED)
api = self._makeOne(connection)

topics, next_token = api.list_topics(
self.PROJECT, page_token=TOKEN1, page_size=SIZE)

self.assertEqual(len(topics), 1)
topic = topics[0]
self.assertTrue(isinstance(topic, dict))
self.assertEqual(topic['name'], self.TOPIC_PATH)
self.assertEqual(next_token, TOKEN2)

self.assertEqual(connection._called_with['method'], 'GET')
path = '/%s' % (self.LIST_TOPICS_PATH,)
self.assertEqual(connection._called_with['path'], path)
self.assertEqual(connection._called_with['query_params'],
{'pageToken': TOKEN1, 'pageSize': SIZE})

def test_list_topics_missing_key(self):
RETURNED = {}
connection = _Connection(RETURNED)
api = self._makeOne(connection)

topics, next_token = api.list_topics(self.PROJECT)

self.assertEqual(len(topics), 0)
self.assertEqual(next_token, None)

self.assertEqual(connection._called_with['method'], 'GET')
path = '/%s' % (self.LIST_TOPICS_PATH,)
self.assertEqual(connection._called_with['path'], path)
self.assertEqual(connection._called_with['query_params'], {})


class Test_SubscriberAPI(_Base):

def _getTargetClass(self):
from gcloud.pubsub.connection import _SubscriberAPI
Expand All @@ -781,15 +772,12 @@ def test_ctor(self):
self.assertTrue(api._connection is connection)


class Test_IAMPolicyAPI(unittest2.TestCase):
class Test_IAMPolicyAPI(_Base):

def _getTargetClass(self):
from gcloud.pubsub.connection import _IAMPolicyAPI
return _IAMPolicyAPI

def _makeOne(self, *args, **kw):
return self._getTargetClass()(*args, **kw)

def test_ctor(self):
connection = _Connection()
api = self._makeOne(connection)
Expand All @@ -816,3 +804,8 @@ class _Connection(object):

def __init__(self, *responses):
self._responses = responses

def api_request(self, **kw):
self._called_with = kw
response, self._responses = self._responses[0], self._responses[1:]
return response