This commit is contained in:
Luke Rogers 2012-09-11 09:47:19 +12:00
parent fbdeacdc76
commit 48aeb9426f
26 changed files with 5550 additions and 0 deletions

View file

View file

@ -0,0 +1,29 @@
import json
from unittest import TestCase
from yql import NotOneError, YQLError
class YQLErrorTest(TestCase):
def test_error_passed_error_string(self):
error = YQLError(resp='some response', content='some content')
self.assertEqual("some content", str(error))
def test_error_passed_object(self):
error = YQLError(resp='some response', content={"foo": 1})
self.assertEqual(repr({"foo": 1}), str(error))
def test_error_passed_json(self):
content = {
'error': {
'description': 'some description',
}
}
error = YQLError(resp='some response', content=json.dumps(content))
self.assertEqual("some description", str(error))
class NotOneErrorTest(TestCase):
def test_is_represented_by_message_as_json(self):
error = NotOneError('some message')
self.assertEqual("some message", str(error))

View file

@ -0,0 +1,155 @@
"""Tests against live services.
*** SKIPPED BY DEFAULT ***
These tests won't normally be run, as part of the main test suite but are run by
our hudson instance to tell us should Yahoo's API change in some way that will
break python-yql.
Note to end-users: These tests are dependent on defining a secrets file with API
keys and other secrets which are required to carry out these tests.
If the secrets file isn't present the tests are skipped
"""
import os
import sys
from time import time
from unittest import TestCase
from nose.plugins.skip import SkipTest
import yql
from yql.storage import FileTokenStore
SECRETS_DIR = os.path.join(os.path.dirname(__file__), "../../../secrets")
CACHE_DIR = os.path.abspath(os.path.join(SECRETS_DIR, "cache"))
try:
if SECRETS_DIR not in sys.path:
sys.path.append(SECRETS_DIR)
from secrets import *
except ImportError:
raise SkipTest("Unable to find secrets directory")
class LiveTestCase(TestCase):
"""A test case containing live tests"""
def test_write_bitly_url(self):
"""Test writing bit.ly url"""
query = """USE 'http://www.datatables.org/bitly/bit.ly.shorten.xml';
SELECT * from bit.ly.shorten where login='%s' and apiKey='%s' and
longUrl='http://yahoo.com'""" % (BITLY_USER, BITLY_API_KEY)
y = yql.TwoLegged(YQL_API_KEY, YQL_SHARED_SECRET)
res = y.execute(query)
assert res.one()["data"]["url"] == "http://yhoo.it/9PPTOr"
def test_public_request(self):
"""Test public two-legged request to flickr"""
query = """select * from flickr.photos.search where
text="panda" and api_key='%s' LIMIT 3""" % FLICKR_API_KEY
y = yql.TwoLegged(YQL_API_KEY, YQL_SHARED_SECRET)
res = y.execute(query)
assert len(res.rows) == 3
def test_two_legged_weather_select(self):
"""Tests the weather tables using two-legged"""
query = """select * from weather.forecast where location in
(select id from xml where
url='http://xoap.weather.com/search/search?where=london'
and itemPath='search.loc')"""
y = yql.TwoLegged(YQL_API_KEY, YQL_SHARED_SECRET)
res = y.execute(query)
assert len(res.rows) > 1
def test_update_social_status(self):
"""Updates status"""
y = yql.ThreeLegged(YQL_API_KEY, YQL_SHARED_SECRET)
timestamp = time()
query = """UPDATE social.profile.status
SET status='Using YQL. %s Update'
WHERE guid=me""" % timestamp
token_store = FileTokenStore(CACHE_DIR, secret='gsfdsfdsfdsfs')
stored_token = token_store.get('foo')
if not stored_token:
# Do the dance
request_token, auth_url = y.get_token_and_auth_url()
print "Visit url %s and get a verifier string" % auth_url
verifier = raw_input("Enter the code: ")
token = y.get_access_token(request_token, verifier)
token_store.set('foo', token)
else:
# Check access_token is within 1hour-old and if not refresh it
# and stash it
token = y.check_token(stored_token)
if token != stored_token:
token_store.set('foo', token)
res = y.execute(query, token=token)
assert res.rows[0] == "ok"
new_query = """select message from social.profile.status where guid=me"""
res = y.execute(new_query, token=token)
assert res.rows[0].get("message") == "Using YQL. %s Update" % timestamp
def test_update_meme_status(self):
"""Updates status"""
y = yql.ThreeLegged(YQL_API_KEY, YQL_SHARED_SECRET)
query = 'INSERT INTO meme.user.posts (type, content) VALUES("text", "test with pythonyql")'
token_store = FileTokenStore(CACHE_DIR, secret='fjdsfjllds')
store_name = "meme"
stored_token = token_store.get(store_name)
if not stored_token:
# Do the dance
request_token, auth_url = y.get_token_and_auth_url()
print "Visit url %s and get a verifier string" % auth_url
verifier = raw_input("Enter the code: ")
token = y.get_access_token(request_token, verifier)
token_store.set(store_name, token)
else:
# Check access_token is within 1hour-old and if not refresh it
# and stash it
token = y.check_token(stored_token)
if token != stored_token:
token_store.set(store_name, token)
# post a meme
res = y.execute(query, token=token)
assert y.uri == "http://query.yahooapis.com/v1/yql"
assert res.rows[0].get("message") == "ok"
pubid = None
if res.rows[0].get("post") and res.rows[0]["post"].get("pubid"):
pubid = res.rows[0]["post"]["pubid"]
# Delete the post we've just created
query = 'DELETE FROM meme.user.posts WHERE pubid=@pubid'
res2 = y.execute(query, token=token, params={"pubid": pubid})
assert res2.rows[0].get("message") == "ok"
def test_check_env_var(self):
"""Testing env variable"""
y = yql.Public()
env = "http://datatables.org/alltables.env"
query = "SHOW tables;"
res = y.execute(query, env=env)
assert res.count >= 800
def test_xpath_works(self):
y = yql.Public()
query = """SELECT * FROM html
WHERE url='http://google.co.uk'
AND xpath="//input[contains(@name, 'q')]"
LIMIT 10"""
res = y.execute(query)
assert res.rows[0].get("title") == "Search"

View file

@ -0,0 +1,23 @@
import os
import shutil
from unittest import TestCase
import yql.logger
class LoggerTest(TestCase):
def setUp(self):
self._logging = os.environ.get('YQL_LOGGING', '')
def tearDown(self):
os.environ['YQL_LOGGING'] = self._logging
def test_is_instantiated_even_if_log_dir_doesnt_exist(self):
os.environ['YQL_LOGGING'] = '1'
if os.path.exists(yql.logger.LOG_DIRECTORY):
shutil.rmtree(yql.logger.LOG_DIRECTORY)
yql.logger.get_logger()
def test_logs_message_to_file(self):
os.environ['YQL_LOGGING'] = '1'
yql.logger.get_logger()

View file

@ -0,0 +1,77 @@
"""Set of tests for the placeholder checking"""
from unittest import TestCase
from nose.tools import raises
import yql
class PublicTest(TestCase):
@raises(ValueError)
def test_empty_args_raises_valueerror(self):
y = yql.Public()
query = "SELECT * from foo where dog=@dog"
params = {}
y.execute(query, params)
@raises(ValueError)
def test_incorrect_args_raises_valueerror(self):
y = yql.Public()
query = "SELECT * from foo where dog=@dog"
params = {'test': 'fail'}
y.execute(query, params)
@raises(ValueError)
def test_params_raises_when_not_dict(self):
y = yql.Public()
query = "SELECT * from foo where dog=@dog"
params = ['test']
y.execute(query, params)
@raises(ValueError)
def test_unecessary_args_raises_valueerror(self):
y = yql.Public()
query = "SELECT * from foo where dog='test'"
params = {'test': 'fail'}
y.execute(query, params)
@raises(ValueError)
def test_incorrect_type_raises_valueerror(self):
y = yql.Public()
query = "SELECT * from foo where dog=@test"
params = ('fail')
y.execute(query, params)
def test_placeholder_regex_one(self):
y = yql.Public()
query = "SELECT * from foo where email='foo@foo.com'"
placeholders = y.get_placeholder_keys(query)
self.assertEqual(placeholders, [])
def test_placeholder_regex_two(self):
y = yql.Public()
query = "SELECT * from foo where email=@foo'"
placeholders = y.get_placeholder_keys(query)
self.assertEqual(placeholders, ['foo'])
def test_placeholder_regex_three(self):
y = yql.Public()
query = "SELECT * from foo where email=@foo and test=@bar'"
placeholders = y.get_placeholder_keys(query)
self.assertEqual(placeholders, ['foo', 'bar'])
def test_placeholder_regex_four(self):
y = yql.Public()
query = "SELECT * from foo where foo='bar' LIMIT @foo"
placeholders = y.get_placeholder_keys(query)
self.assertEqual(placeholders, ['foo'])
def test_placeholder_regex_five(self):
y = yql.Public()
query = """SELECT * from foo
where foo='bar' LIMIT
@foo"""
placeholders = y.get_placeholder_keys(query)
self.assertEqual(placeholders, ['foo'])

View file

@ -0,0 +1,248 @@
from email import message_from_file
import os
from unittest import TestCase
import urlparse
from urllib import urlencode
try:
from urlparse import parse_qsl
except ImportError:
from cgi import parse_qsl
from nose.tools import raises
from nose import with_setup
import oauth2 as oauth
import httplib2
import yql
HTTP_SRC_DIR = os.path.join(os.path.dirname(__file__), "http_src/")
class FileDataHttpReplacement(object):
"""Build a stand-in for httplib2.Http that takes its
response headers and bodies from files on disk
http://bitworking.org/news/172/Test-stubbing-httplib2
"""
def __init__(self, cache=None, timeout=None):
self.hit_counter = {}
def request(self, uri, method="GET", body=None, headers=None, redirections=5):
path = urlparse.urlparse(uri)[2]
fname = os.path.join(HTTP_SRC_DIR, path[1:])
if not os.path.exists(fname):
index = self.hit_counter.get(fname, 1)
if os.path.exists(fname + "." + str(index)):
self.hit_counter[fname] = index + 1
fname = fname + "." + str(index)
if os.path.exists(fname):
f = file(fname, "r")
response = message_from_file(f)
f.close()
body = response.get_payload()
response_headers = httplib2.Response(response)
return (response_headers, body)
else:
return (httplib2.Response({"status": "404"}), "")
def add_credentials(self, name, password):
pass
class RequestDataHttpReplacement:
"""Create an httplib stub that returns request data"""
def __init__(self):
pass
def request(self, uri, *args, **kwargs):
"""return the request data"""
return uri, args, kwargs
class TestPublic(yql.Public):
"""Subclass of YQL to allow returning of the request data"""
execute = yql.Public.get_uri
class TestTwoLegged(yql.TwoLegged):
"""Subclass of YQLTwoLegged to allow returning of the request data"""
execute = yql.TwoLegged.get_uri
class TestThreeLegged(yql.ThreeLegged):
"""Subclass of YQLTwoLegged to allow returning of the request data"""
execute = yql.ThreeLegged.get_uri
class StubbedHttpTestCase(TestCase):
stub = None
def setUp(self):
self._http = httplib2.Http
httplib2.Http = self.stub
def tearDown(self):
httplib2.Http = self._http
class PublicStubbedRequestTest(StubbedHttpTestCase):
stub = RequestDataHttpReplacement
def test_urlencoding_for_public_yql(self):
query = 'SELECT * from foo'
y = TestPublic(httplib2_inst=httplib2.Http())
uri = y.execute(query)
self.assertEqual(uri, "http://query.yahooapis.com/v1/public/yql?q=SELECT+%2A+from+foo&format=json")
def test_env_for_public_yql(self):
query = 'SELECT * from foo'
y = TestPublic(httplib2_inst=httplib2.Http())
uri = y.execute(query, env="http://foo.com")
self.assertTrue(uri.find(urlencode({"env":"http://foo.com"})) > -1)
def test_name_param_inserted_for_public_yql(self):
query = 'SELECT * from foo WHERE dog=@dog'
y = TestPublic(httplib2_inst=httplib2.Http())
uri = y.execute(query, {"dog": "fifi"})
self.assertTrue(uri.find('dog=fifi') >-1)
class PublicStubbedFromFileTest(StubbedHttpTestCase):
stub = FileDataHttpReplacement
def test_json_response_from_file(self):
query = 'SELECT * from foo WHERE dog=@dog'
y = yql.Public(httplib2_inst=httplib2.Http())
content = y.execute(query, {"dog": "fifi"})
self.assertEqual(content.count, 3)
class TwoLeggedTest(TestCase):
@raises(TypeError)
def test_yql_with_2leg_auth_raises_typerror(self):
TestTwoLegged()
def test_api_key_and_secret_attrs(self):
y = yql.TwoLegged('test-api-key', 'test-secret')
self.assertEqual(y.api_key, 'test-api-key')
self.assertEqual(y.secret, 'test-secret')
def test_get_two_legged_request_keys(self):
y = yql.TwoLegged('test-api-key', 'test-secret')
# Accessed this was because it's private
request = y._TwoLegged__two_legged_request('http://google.com')
self.assertEqual(set(['oauth_nonce', 'oauth_version', 'oauth_timestamp',
'oauth_consumer_key', 'oauth_signature_method', 'oauth_body_hash',
'oauth_version', 'oauth_signature']), set(request.keys()))
def test_get_two_legged_request_values(self):
y = yql.TwoLegged('test-api-key', 'test-secret')
# Accessed this was because it's private
request = y._TwoLegged__two_legged_request('http://google.com')
self.assertEqual(request['oauth_consumer_key'], 'test-api-key')
self.assertEqual(request['oauth_signature_method'], 'HMAC-SHA1')
self.assertEqual(request['oauth_version'], '1.0')
def test_get_two_legged_request_param(self):
y = yql.TwoLegged('test-api-key', 'test-secret')
# Accessed this way because it's private
request = y._TwoLegged__two_legged_request('http://google.com',
{"test-param": "test"})
self.assertEqual(request.get('test-param'), 'test')
class TwoLeggedStubbedRequestTest(StubbedHttpTestCase):
stub = RequestDataHttpReplacement
def test_request_for_two_legged(self):
query = 'SELECT * from foo'
y = TestTwoLegged('test-api-key', 'test-secret', httplib2_inst=httplib2.Http())
signed_url = y.execute(query)
qs = dict(parse_qsl(signed_url.split('?')[1]))
self.assertEqual(qs['q'], query)
self.assertEqual(qs['format'], 'json')
class TwoLeggedStubbedFromFileTest(StubbedHttpTestCase):
stub = FileDataHttpReplacement
def test_get_two_legged_from_file(self):
query = 'SELECT * from foo'
y = yql.TwoLegged('test-api-key', 'test-secret', httplib2_inst=httplib2.Http())
# Accessed this was because it's private
self.assertTrue(y.execute(query) is not None)
class ThreeLeggedTest(TestCase):
@raises(TypeError)
def test_yql_with_3leg_auth_raises_typerror(self):
TestThreeLegged()
def test_api_key_and_secret_attrs2(self):
y = yql.ThreeLegged('test-api-key', 'test-secret')
self.assertEqual(y.api_key, 'test-api-key')
self.assertEqual(y.secret, 'test-secret')
def test_get_base_params(self):
y = yql.ThreeLegged('test-api-key', 'test-secret')
result = y.get_base_params()
self.assertEqual(set(['oauth_nonce', 'oauth_version', 'oauth_timestamp']),
set(result.keys()))
@raises(ValueError)
def test_raises_for_three_legged_with_no_token(self):
query = 'SELECT * from foo'
y = TestThreeLegged('test-api-key', 'test-secret', httplib2_inst=httplib2.Http())
y.execute(query)
class ThreeLeggedStubbedRequestTest(StubbedHttpTestCase):
stub = RequestDataHttpReplacement
def test_request_for_three_legged(self):
query = 'SELECT * from foo'
y = TestThreeLegged('test-api-key', 'test-secret',
httplib2_inst=httplib2.Http())
token = oauth.Token.from_string(
'oauth_token=foo&oauth_token_secret=bar')
signed_url = y.execute(query, token=token)
qs = dict(parse_qsl(signed_url.split('?')[1]))
self.assertEqual(qs['q'], query)
self.assertEqual(qs['format'], 'json')
class ThreeLeggedStubbedFromFileTest(StubbedHttpTestCase):
stub = FileDataHttpReplacement
def test_three_legged_execution(self):
query = 'SELECT * from foo WHERE dog=@dog'
y = yql.ThreeLegged('test','test2', httplib2_inst=httplib2.Http())
token = yql.YahooToken('test', 'test2')
content = y.execute(query, {"dog": "fifi"}, token=token)
self.assertEqual(content.count, 3)
@raises(ValueError)
def test_three_legged_execution_raises_value_error_with_invalid_uri(self):
y = yql.ThreeLegged('test','test2', httplib2_inst=httplib2.Http())
y.uri = "fail"
token = yql.YahooToken('tes1t', 'test2')
y.execute("SELECT foo meh meh ", token=token)
def test_get_access_token_request3(self):
y = yql.ThreeLegged('test', 'test-does-not-exist',
httplib2_inst=httplib2.Http())
new_token = yql.YahooToken('test', 'test2')
new_token.session_handle = 'sess_handle_test'
token = y.refresh_token(token=new_token)
self.assertTrue(hasattr(token, 'key'))
self.assertTrue(hasattr(token, 'secret'))

View file

@ -0,0 +1,12 @@
from unittest import TestCase
from nose.tools import raises
import yql
class PublicTest(TestCase):
@raises(ValueError)
def test_cannot_use_unrecognizable_endpoint(self):
y = yql.Public()
y.endpoint = 'some-strange-endpoint'

View file

@ -0,0 +1,61 @@
import os
import tempfile
from unittest import TestCase
from nose.tools import raises
from yql import YahooToken
from yql.storage import BaseTokenStore, FileTokenStore, TokenStoreError
class BaseTokenStoreTest(TestCase):
@raises(NotImplementedError)
def test_must_implement_set(self):
class FooStore(BaseTokenStore):
pass
store = FooStore()
store.set('some name', 'some token')
@raises(NotImplementedError)
def test_must_implement_get(self):
class FooStore(BaseTokenStore):
pass
store = FooStore()
store.get('some name')
class FileTokenStoreTest(TestCase):
@raises(TokenStoreError)
def test_must_be_instanced_with_an_existant_path(self):
FileTokenStore('/some/inexistant/path')
def test_saves_token_string_to_filesystem(self):
directory = tempfile.mkdtemp()
store = FileTokenStore(directory)
store.set('foo', '?key=some-token')
with open(store.get_filepath('foo')) as stored_file:
self.assertTrue('some-token' in stored_file.read())
def test_retrieves_token_from_filesystem(self):
directory = tempfile.mkdtemp()
store = FileTokenStore(directory)
store.set('foo', '?key=%s&oauth_token=some-oauth-token&'\
'oauth_token_secret=some-token-secret' % 'some-token')
token = store.get('foo')
self.assertTrue('some-token' in token.to_string())
def test_cannot_retrieve_token_if_path_doesnt_exist(self):
directory = tempfile.mkdtemp()
store = FileTokenStore(directory)
store.set('foo', '?key=%s&oauth_token=some-oauth-token&'\
'oauth_token_secret=some-token-secret' % 'some-token')
os.remove(store.get_filepath('foo'))
self.assertTrue(store.get('foo') is None)
def test_saves_token_to_filesystem(self):
directory = tempfile.mkdtemp()
store = FileTokenStore(directory)
token = YahooToken('some-token', 'some-secret')
store.set('foo', token)
with open(store.get_filepath('foo')) as stored_file:
self.assertTrue('some-token' in stored_file.read())

View file

@ -0,0 +1,40 @@
from unittest import TestCase
from yql.utils import get_http_method
class UtilitiesTest(TestCase):
def test_finds_get_method_for_select_query(self):
self.assertEqual(get_http_method("SELECT foo"), "GET")
def test_finds_get_method_for_select_query_with_leading_space(self):
self.assertEqual(get_http_method(" SELECT foo"), "GET")
def test_finds_get_method_for_lowercase_select_query(self):
self.assertEqual(get_http_method("select foo"), "GET")
def test_finds_post_method_for_insert_query(self):
self.assertEqual(get_http_method("INSERT into"), "POST")
def test_finds_post_method_for_multiline_insert_query(self):
query = """
INSERT INTO yql.queries.query (name, query)
VALUES ("weather", "SELECT * FROM weather.forecast
WHERE location=90210")
"""
self.assertEqual(get_http_method(query), "POST")
def test_finds_put_method_for_update_query(self):
self.assertEqual(get_http_method("update foo"), "PUT")
def test_finds_post_method_for_delete_query(self):
self.assertEqual(get_http_method("DELETE from"), "POST")
def test_finds_post_method_for_lowercase_delete_query(self):
self.assertEqual(get_http_method("delete from"), "POST")
def test_finds_get_method_for_show_query(self):
self.assertEqual(get_http_method("SHOW tables"), "GET")
def test_finds_get_method_for_describe_query(self):
self.assertEqual(get_http_method("DESC tablename"), "GET")

View file

@ -0,0 +1,81 @@
from unittest import TestCase
from nose.tools import raises
try:
from urlparse import parse_qs, parse_qsl
except ImportError:
from cgi import parse_qs, parse_qsl
import yql
class YahooTokenTest(TestCase):
def test_create_yahoo_token(self):
token = yql.YahooToken('test-key', 'test-secret')
self.assertEqual(token.key, 'test-key')
self.assertEqual(token.secret, 'test-secret')
def test_y_token_to_string(self):
token = yql.YahooToken('test-key', 'test-secret')
token_to_string = token.to_string()
string_data = dict(parse_qsl(token_to_string))
self.assertEqual(string_data.get('oauth_token'), 'test-key')
self.assertEqual(string_data.get('oauth_token_secret'), 'test-secret')
def test_y_token_to_string2(self):
token = yql.YahooToken('test-key', 'test-secret')
token.timestamp = '1111'
token.session_handle = 'poop'
token.callback_confirmed = 'basilfawlty'
token_to_string = token.to_string()
string_data = dict(parse_qsl(token_to_string))
self.assertEqual(string_data.get('oauth_token'), 'test-key')
self.assertEqual(string_data.get('oauth_token_secret'), 'test-secret')
self.assertEqual(string_data.get('token_creation_timestamp'), '1111')
self.assertEqual(string_data.get('oauth_callback_confirmed'), 'basilfawlty')
self.assertEqual(string_data.get('oauth_session_handle'), 'poop')
def test_y_token_from_string(self):
token_string = "oauth_token=foo&oauth_token_secret=bar&"\
"oauth_session_handle=baz&token_creation_timestamp=1111"
token_from_string = yql.YahooToken.from_string(token_string)
self.assertEqual(token_from_string.key, 'foo')
self.assertEqual(token_from_string.secret, 'bar')
self.assertEqual(token_from_string.session_handle, 'baz')
self.assertEqual(token_from_string.timestamp, '1111')
@raises(ValueError)
def test_y_token_raises_value_error(self):
yql.YahooToken.from_string('')
@raises(ValueError)
def test_y_token_raises_value_error2(self):
yql.YahooToken.from_string('foo')
@raises(ValueError)
def test_y_token_raises_value_error3(self):
yql.YahooToken.from_string('oauth_token=bar')
@raises(ValueError)
def test_y_token_raises_value_error4(self):
yql.YahooToken.from_string('oauth_token_secret=bar')
@raises(AttributeError)
def test_y_token_without_timestamp_raises(self):
token = yql.YahooToken('test', 'test2')
y = yql.ThreeLegged('test', 'test2')
y.check_token(token)
def test_y_token_without_timestamp_raises2(self):
def refresh_token_replacement(token):
return 'replaced'
y = yql.ThreeLegged('test', 'test2')
y.refresh_token = refresh_token_replacement
token = yql.YahooToken('test', 'test2')
token.timestamp = 11111
self.assertEqual(y.check_token(token), 'replaced')

View file

@ -0,0 +1,105 @@
"""Tests for the YQL object"""
import json
from unittest import TestCase
from nose.tools import raises
from yql import YQLObj, NotOneError
data_dict = json.loads("""{"query":{"count":"3","created":"2009-11-20T12:11:56Z","lang":"en-US","updated":"2009-11-20T12:11:56Z","uri":"http://query.yahooapis.com/v1/yql?q=select+*+from+flickr.photos.search+where+text%3D%22panda%22+limit+3","diagnostics":{"publiclyCallable":"true","url":{"execution-time":"742","content":"http://api.flickr.com/services/rest/?method=flickr.photos.search&text=panda&page=1&per_page=10"},"user-time":"745","service-time":"742","build-version":"3805"},"results":{"photo":[{"farm":"3","id":"4117944207","isfamily":"0","isfriend":"0","ispublic":"1","owner":"12346075@N00","secret":"ce1f6092de","server":"2510","title":"Pandas"},{"farm":"3","id":"4118710292","isfamily":"0","isfriend":"0","ispublic":"1","owner":"12346075@N00","secret":"649632a3e2","server":"2754","title":"Pandas"},{"farm":"3","id":"4118698318","isfamily":"0","isfriend":"0","ispublic":"1","owner":"28451051@N02","secret":"ec0b508684","server":"2586","title":"fuzzy flowers (Kalanchoe tomentosa)"}]}}}""")
data_dict2 = json.loads("""{"query":{"count":"1","created":"2009-11-20T12:11:56Z","lang":"en-US","updated":"2009-11-20T12:11:56Z","uri":"http://query.yahooapis.com/v1/yql?q=select+*+from+flickr.photos.search+where+text%3D%22panda%22+limit+3","diagnostics":{"publiclyCallable":"true","url":{"execution-time":"742","content":"http://api.flickr.com/services/rest/?method=flickr.photos.search&text=panda&page=1&per_page=10"},"user-time":"745","service-time":"742","build-version":"3805"},"results":{"photo":{"farm":"3","id":"4117944207","isfamily":"0","isfriend":"0","ispublic":"1","owner":"12346075@N00","secret":"ce1f6092de","server":"2510","title":"Pandas"}}}}""")
yqlobj = YQLObj(data_dict)
yqlobj2 = YQLObj({})
yqlobj3 = YQLObj(data_dict2)
class YQLObjTest(TestCase):
@raises(AttributeError)
def test_yql_object_one(self):
"""Test that invalid query raises AttributeError"""
yqlobj.query = 1
def test_yqlobj_uri(self):
"""Test that the query uri is as expected."""
self.assertEqual(yqlobj.uri, u"http://query.yahooapis.com/v1/yql?q=select+*+"\
"from+flickr.photos.search+where+text%3D%22panda%22+limit+3")
def test_yqlobj_query(self):
"""Test retrieval of the actual query"""
self.assertEqual(yqlobj.query, u'select * from flickr.photos.search '\
'where text="panda" limit 3')
def test_yqlobj_count(self):
"""Check we have 3 records"""
self.assertEqual(yqlobj.count, 3)
def test_yqlobj_lang(self):
"""Check the lang attr."""
self.assertEqual(yqlobj.lang, u"en-US")
def test_yqlobj_results(self):
"""Check the results."""
expected_results = {u'photo': [
{u'isfamily': u'0',
u'title': u'Pandas',
u'farm': u'3',
u'ispublic': u'1',
u'server': u'2510',
u'isfriend': u'0',
u'secret': u'ce1f6092de',
u'owner': u'12346075@N00',
u'id': u'4117944207'},
{u'isfamily': u'0',
u'title': u'Pandas',
u'farm': u'3',
u'ispublic': u'1',
u'server': u'2754',
u'isfriend': u'0',
u'secret': u'649632a3e2',
u'owner': u'12346075@N00',
u'id': u'4118710292'},
{u'isfamily': u'0',
u'title': u'fuzzy flowers (Kalanchoe tomentosa)',
u'farm': u'3',
u'ispublic': u'1',
u'server': u'2586',
u'isfriend': u'0',
u'secret': u'ec0b508684',
u'owner': u'28451051@N02',
u'id': u'4118698318'}
]}
self.assertEqual(yqlobj.results, expected_results)
def test_yqlobj_raw(self):
"""Check the raw attr."""
self.assertEqual(yqlobj.raw, data_dict.get('query'))
def test_yqlobj_diagnostics(self):
"""Check the diagnostics"""
self.assertEqual(yqlobj.diagnostics, data_dict.get('query').get('diagnostics'))
def test_query_is_none(self):
"""Check query is None with no data."""
self.assertTrue(yqlobj2.query is None)
def test_rows(self):
"""Test we can iterate over the rows."""
stuff = []
for row in yqlobj.rows:
stuff.append(row.get('server'))
self.assertEqual(stuff, [u'2510', u'2754', u'2586'])
@raises(NotOneError)
def test_one(self):
"""Test that accessing one result raises exception"""
yqlobj.one()
def test_one_with_one_result(self):
"""Test accessing data with one result."""
res = yqlobj3.one()
self.assertEqual(res.get("title"), "Pandas")