blob: 4bdff209e2d10b0fcabfc2f7cf946291795db6ed [file] [log] [blame]
Joe Gregorioba9ea7f2010-08-19 15:49:04 -04001#!/usr/bin/python2.4
Joe Gregoriof863f7a2011-02-24 03:24:44 -05002# -*- coding: utf-8 -*-
Joe Gregorioba9ea7f2010-08-19 15:49:04 -04003#
Joe Gregorio6d5e94f2010-08-25 23:49:30 -04004# Copyright 2010 Google Inc.
5#
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040018
19"""Discovery document tests
20
21Unit tests for objects created from discovery documents.
22"""
23
24__author__ = 'jcgregorio@google.com (Joe Gregorio)'
25
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040026import httplib2
27import os
28import unittest
Joe Gregorio00cf1d92010-09-27 09:22:03 -040029import urlparse
ade@google.comc5eb46f2010-09-27 23:35:39 +010030try:
31 from urlparse import parse_qs
32except ImportError:
33 from cgi import parse_qs
Joe Gregorio00cf1d92010-09-27 09:22:03 -040034
35from apiclient.discovery import build, key2param
Joe Gregoriocb8103d2011-02-11 23:20:52 -050036from apiclient.http import HttpMock
Joe Gregoriof4153422011-03-18 22:45:18 -040037from apiclient.http import tunnel_patch
38from apiclient.http import HttpMockSequence
Joe Gregorioc0e0fe92011-03-04 16:16:55 -050039from apiclient.errors import HttpError
Joe Gregorio49396552011-03-08 10:39:00 -050040from apiclient.errors import InvalidJsonError
Joe Gregoriocb8103d2011-02-11 23:20:52 -050041
42
43DATA_DIR = os.path.join(os.path.dirname(__file__), 'data')
44
45def datafile(filename):
46 return os.path.join(DATA_DIR, filename)
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040047
48
Joe Gregorioc5c5a372010-09-22 11:42:32 -040049class Utilities(unittest.TestCase):
50 def test_key2param(self):
51 self.assertEqual('max_results', key2param('max-results'))
52 self.assertEqual('x007_bond', key2param('007-bond'))
53
54
Joe Gregorioc0e0fe92011-03-04 16:16:55 -050055class DiscoveryErrors(unittest.TestCase):
56
57 def test_failed_to_parse_discovery_json(self):
58 self.http = HttpMock(datafile('malformed.json'), {'status': '200'})
59 try:
60 buzz = build('buzz', 'v1', self.http)
61 self.fail("should have raised an exception over malformed JSON.")
Joe Gregorio49396552011-03-08 10:39:00 -050062 except InvalidJsonError:
63 pass
Joe Gregorioc0e0fe92011-03-04 16:16:55 -050064
65
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040066class Discovery(unittest.TestCase):
Joe Gregorio2379ecc2010-10-26 10:51:28 -040067
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040068 def test_method_error_checking(self):
Joe Gregoriocb8103d2011-02-11 23:20:52 -050069 self.http = HttpMock(datafile('buzz.json'), {'status': '200'})
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040070 buzz = build('buzz', 'v1', self.http)
71
72 # Missing required parameters
73 try:
74 buzz.activities().list()
75 self.fail()
76 except TypeError, e:
77 self.assertTrue('Missing' in str(e))
78
79 # Parameter doesn't match regex
80 try:
Joe Gregoriobee86832011-02-22 10:00:19 -050081 buzz.activities().list(scope='@myself', userId='me')
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040082 self.fail()
83 except TypeError, e:
Joe Gregorioca876e42011-02-22 19:39:42 -050084 self.assertTrue('not an allowed value' in str(e))
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040085
86 # Parameter doesn't match regex
87 try:
88 buzz.activities().list(scope='not@', userId='foo')
89 self.fail()
90 except TypeError, e:
Joe Gregorioca876e42011-02-22 19:39:42 -050091 self.assertTrue('not an allowed value' in str(e))
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040092
93 # Unexpected parameter
94 try:
95 buzz.activities().list(flubber=12)
96 self.fail()
97 except TypeError, e:
98 self.assertTrue('unexpected' in str(e))
99
Joe Gregoriobee86832011-02-22 10:00:19 -0500100 def _check_query_types(self, request):
101 parsed = urlparse.urlparse(request.uri)
102 q = parse_qs(parsed[4])
103 self.assertEqual(q['q'], ['foo'])
104 self.assertEqual(q['i'], ['1'])
105 self.assertEqual(q['n'], ['1.0'])
106 self.assertEqual(q['b'], ['false'])
107 self.assertEqual(q['a'], ['[1, 2, 3]'])
108 self.assertEqual(q['o'], ['{\'a\': 1}'])
109 self.assertEqual(q['e'], ['bar'])
110
111 def test_type_coercion(self):
Joe Gregoriof4153422011-03-18 22:45:18 -0400112 http = HttpMock(datafile('zoo.json'), {'status': '200'})
113 zoo = build('zoo', 'v1', http)
Joe Gregoriobee86832011-02-22 10:00:19 -0500114
115 request = zoo.query(q="foo", i=1.0, n=1.0, b=0, a=[1,2,3], o={'a':1}, e='bar')
116 self._check_query_types(request)
117 request = zoo.query(q="foo", i=1, n=1, b=False, a=[1,2,3], o={'a':1}, e='bar')
118 self._check_query_types(request)
Joe Gregoriof863f7a2011-02-24 03:24:44 -0500119
Joe Gregoriobee86832011-02-22 10:00:19 -0500120 request = zoo.query(q="foo", i="1", n="1", b="", a=[1,2,3], o={'a':1}, e='bar')
121 self._check_query_types(request)
122
Joe Gregorio13217952011-02-22 15:37:38 -0500123 def test_optional_stack_query_parameters(self):
Joe Gregoriof4153422011-03-18 22:45:18 -0400124 http = HttpMock(datafile('zoo.json'), {'status': '200'})
125 zoo = build('zoo', 'v1', http)
126 request = zoo.query(trace='html', fields='description')
Joe Gregorio13217952011-02-22 15:37:38 -0500127
Joe Gregorioca876e42011-02-22 19:39:42 -0500128 parsed = urlparse.urlparse(request.uri)
129 q = parse_qs(parsed[4])
130 self.assertEqual(q['trace'], ['html'])
Joe Gregoriof4153422011-03-18 22:45:18 -0400131 self.assertEqual(q['fields'], ['description'])
132
133 def test_patch(self):
134 http = HttpMock(datafile('zoo.json'), {'status': '200'})
135 zoo = build('zoo', 'v1', http)
136 request = zoo.animals().patch(name='lion', body='{"description": "foo"}')
137
138 self.assertEqual(request.method, 'PATCH')
139
140 def test_tunnel_patch(self):
141 http = HttpMockSequence([
142 ({'status': '200'}, file(datafile('zoo.json'), 'r').read()),
143 ({'status': '200'}, 'echo_request_headers_as_json'),
144 ])
145 http = tunnel_patch(http)
146 zoo = build('zoo', 'v1', http)
147 resp = zoo.animals().patch(name='lion', body='{"description": "foo"}').execute()
148
149 self.assertTrue('x-http-method-override' in resp)
Joe Gregorioca876e42011-02-22 19:39:42 -0500150
ade@google.com850cf552010-08-20 23:24:56 +0100151 def test_buzz_resources(self):
Joe Gregoriocb8103d2011-02-11 23:20:52 -0500152 self.http = HttpMock(datafile('buzz.json'), {'status': '200'})
Joe Gregorioba9ea7f2010-08-19 15:49:04 -0400153 buzz = build('buzz', 'v1', self.http)
154 self.assertTrue(getattr(buzz, 'activities'))
Joe Gregorioba9ea7f2010-08-19 15:49:04 -0400155 self.assertTrue(getattr(buzz, 'photos'))
156 self.assertTrue(getattr(buzz, 'people'))
157 self.assertTrue(getattr(buzz, 'groups'))
158 self.assertTrue(getattr(buzz, 'comments'))
159 self.assertTrue(getattr(buzz, 'related'))
160
Joe Gregorioc5c5a372010-09-22 11:42:32 -0400161 def test_auth(self):
Joe Gregoriocb8103d2011-02-11 23:20:52 -0500162 self.http = HttpMock(datafile('buzz.json'), {'status': '200'})
Joe Gregorioc5c5a372010-09-22 11:42:32 -0400163 buzz = build('buzz', 'v1', self.http)
164 auth = buzz.auth_discovery()
165 self.assertTrue('request' in auth)
166
Joe Gregorio2379ecc2010-10-26 10:51:28 -0400167 def test_full_featured(self):
168 # Zoo should exercise all discovery facets
169 # and should also have no future.json file.
Joe Gregoriocb8103d2011-02-11 23:20:52 -0500170 self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
Joe Gregorio2379ecc2010-10-26 10:51:28 -0400171 zoo = build('zoo', 'v1', self.http)
172 self.assertTrue(getattr(zoo, 'animals'))
Joe Gregoriof863f7a2011-02-24 03:24:44 -0500173
Joe Gregoriof4153422011-03-18 22:45:18 -0400174 request = zoo.animals().list(name='bat', projection="full")
Joe Gregorio2379ecc2010-10-26 10:51:28 -0400175 parsed = urlparse.urlparse(request.uri)
176 q = parse_qs(parsed[4])
177 self.assertEqual(q['name'], ['bat'])
Joe Gregoriof4153422011-03-18 22:45:18 -0400178 self.assertEqual(q['projection'], ['full'])
Joe Gregorio2379ecc2010-10-26 10:51:28 -0400179
Joe Gregorio3fada332011-01-07 17:07:45 -0500180 def test_nested_resources(self):
Joe Gregoriocb8103d2011-02-11 23:20:52 -0500181 self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
Joe Gregorio3fada332011-01-07 17:07:45 -0500182 zoo = build('zoo', 'v1', self.http)
183 self.assertTrue(getattr(zoo, 'animals'))
184 request = zoo.my().favorites().list(max_results="5")
185 parsed = urlparse.urlparse(request.uri)
186 q = parse_qs(parsed[4])
187 self.assertEqual(q['max-results'], ['5'])
188
Joe Gregorio7a6df3a2011-01-31 21:55:21 -0500189 def test_top_level_functions(self):
Joe Gregoriocb8103d2011-02-11 23:20:52 -0500190 self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
Joe Gregorio7a6df3a2011-01-31 21:55:21 -0500191 zoo = build('zoo', 'v1', self.http)
192 self.assertTrue(getattr(zoo, 'query'))
193 request = zoo.query(q="foo")
194 parsed = urlparse.urlparse(request.uri)
195 q = parse_qs(parsed[4])
196 self.assertEqual(q['q'], ['foo'])
Joe Gregorio2379ecc2010-10-26 10:51:28 -0400197
Joe Gregorioc5c5a372010-09-22 11:42:32 -0400198
199class Next(unittest.TestCase):
Joe Gregorioc9359072010-10-25 15:26:13 -0400200 def test_next_for_people_liked(self):
Joe Gregoriocb8103d2011-02-11 23:20:52 -0500201 self.http = HttpMock(datafile('buzz.json'), {'status': '200'})
Joe Gregorioc9359072010-10-25 15:26:13 -0400202 buzz = build('buzz', 'v1', self.http)
203 people = {'links':
Joe Gregorioc5c5a372010-09-22 11:42:32 -0400204 {'next':
205 [{'href': 'http://www.googleapis.com/next-link'}]}}
Joe Gregorioc9359072010-10-25 15:26:13 -0400206 request = buzz.people().liked_next(people)
207 self.assertEqual(request.uri, 'http://www.googleapis.com/next-link')
Joe Gregorio00cf1d92010-09-27 09:22:03 -0400208
209
210class DeveloperKey(unittest.TestCase):
211 def test_param(self):
Joe Gregoriocb8103d2011-02-11 23:20:52 -0500212 self.http = HttpMock(datafile('buzz.json'), {'status': '200'})
Joe Gregorio00cf1d92010-09-27 09:22:03 -0400213 buzz = build('buzz', 'v1', self.http, developerKey='foobie_bletch')
214 activities = {'links':
215 {'next':
216 [{'href': 'http://www.googleapis.com/next-link'}]}}
217 request = buzz.activities().list_next(activities)
218 parsed = urlparse.urlparse(request.uri)
ade@google.comc5eb46f2010-09-27 23:35:39 +0100219 q = parse_qs(parsed[4])
Joe Gregorio00cf1d92010-09-27 09:22:03 -0400220 self.assertEqual(q['key'], ['foobie_bletch'])
221
Joe Gregorioc9359072010-10-25 15:26:13 -0400222 def test_next_for_activities_list(self):
Joe Gregoriocb8103d2011-02-11 23:20:52 -0500223 self.http = HttpMock(datafile('buzz.json'), {'status': '200'})
Joe Gregorioc9359072010-10-25 15:26:13 -0400224 buzz = build('buzz', 'v1', self.http, developerKey='foobie_bletch')
225 activities = {'links':
ade@google.com2ab0de72010-09-27 23:26:54 +0100226 {'next':
227 [{'href': 'http://www.googleapis.com/next-link'}]}}
Joe Gregorioc9359072010-10-25 15:26:13 -0400228 request = buzz.activities().list_next(activities)
229 self.assertEqual(request.uri,
230 'http://www.googleapis.com/next-link?key=foobie_bletch')
231
Joe Gregorioba9ea7f2010-08-19 15:49:04 -0400232
233if __name__ == '__main__':
234 unittest.main()