blob: 29130d27cf35f412438e0f5c1e0525a079b864b0 [file] [log] [blame]
Joe Gregorioba9ea7f2010-08-19 15:49:04 -04001#!/usr/bin/python2.4
2#
Joe Gregorio6d5e94f2010-08-25 23:49:30 -04003# Copyright 2010 Google Inc.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040016
Joe Gregorio6d5e94f2010-08-25 23:49:30 -040017"""JSON Model tests
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040018
Joe Gregorio6d5e94f2010-08-25 23:49:30 -040019Unit tests for the JSON model.
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040020"""
21
22__author__ = 'jcgregorio@google.com (Joe Gregorio)'
23
Joe Gregorio34044bc2011-03-07 16:58:33 -050024import copy
25import gflags
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040026import os
27import unittest
Joe Gregorioc5c5a372010-09-22 11:42:32 -040028import httplib2
Joe Gregorio34044bc2011-03-07 16:58:33 -050029import apiclient.model
ade@google.comd69e5e42010-08-31 15:28:20 +010030
Joe Gregorio34044bc2011-03-07 16:58:33 -050031from apiclient.anyjson import simplejson
Joe Gregorioe1de4162011-02-23 11:30:29 -050032from apiclient.errors import HttpError
Joe Gregorio34044bc2011-03-07 16:58:33 -050033from apiclient.model import JsonModel
34from apiclient.model import LoggingJsonModel
35
36FLAGS = gflags.FLAGS
Joe Gregorioe1de4162011-02-23 11:30:29 -050037
ade@google.comd69e5e42010-08-31 15:28:20 +010038# Python 2.5 requires different modules
39try:
40 from urlparse import parse_qs
41except ImportError:
42 from cgi import parse_qs
43
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040044
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040045class Model(unittest.TestCase):
46 def test_json_no_body(self):
Joe Gregoriod433b2a2011-02-22 10:51:51 -050047 model = JsonModel(data_wrapper=False)
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040048
49 headers = {}
ade@google.com850cf552010-08-20 23:24:56 +010050 path_params = {}
51 query_params = {}
52 body = None
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040053
ade@google.com850cf552010-08-20 23:24:56 +010054 headers, params, query, body = model.request(headers, path_params, query_params, body)
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040055
56 self.assertEqual(headers['accept'], 'application/json')
57 self.assertTrue('content-type' not in headers)
58 self.assertNotEqual(query, '')
59 self.assertEqual(body, None)
60
61 def test_json_body(self):
Joe Gregoriod433b2a2011-02-22 10:51:51 -050062 model = JsonModel(data_wrapper=False)
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040063
64 headers = {}
ade@google.com850cf552010-08-20 23:24:56 +010065 path_params = {}
66 query_params = {}
67 body = {}
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040068
ade@google.com850cf552010-08-20 23:24:56 +010069 headers, params, query, body = model.request(headers, path_params, query_params, body)
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040070
71 self.assertEqual(headers['accept'], 'application/json')
72 self.assertEqual(headers['content-type'], 'application/json')
73 self.assertNotEqual(query, '')
Joe Gregorio913e70d2010-11-05 15:38:23 -040074 self.assertEqual(body, '{}')
Joe Gregorioba9ea7f2010-08-19 15:49:04 -040075
Joe Gregoriod433b2a2011-02-22 10:51:51 -050076 def test_json_body_data_wrapper(self):
77 model = JsonModel(data_wrapper=True)
78
79 headers = {}
80 path_params = {}
81 query_params = {}
82 body = {}
83
84 headers, params, query, body = model.request(headers, path_params, query_params, body)
85
86 self.assertEqual(headers['accept'], 'application/json')
87 self.assertEqual(headers['content-type'], 'application/json')
88 self.assertNotEqual(query, '')
89 self.assertEqual(body, '{"data": {}}')
90
Joe Gregorio8963ff92010-10-11 13:14:43 -040091 def test_json_body_default_data(self):
92 """Test that a 'data' wrapper doesn't get added if one is already present."""
Joe Gregoriod433b2a2011-02-22 10:51:51 -050093 model = JsonModel(data_wrapper=True)
Joe Gregorio8963ff92010-10-11 13:14:43 -040094
95 headers = {}
96 path_params = {}
97 query_params = {}
98 body = {'data': 'foo'}
99
100 headers, params, query, body = model.request(headers, path_params, query_params, body)
101
102 self.assertEqual(headers['accept'], 'application/json')
103 self.assertEqual(headers['content-type'], 'application/json')
104 self.assertNotEqual(query, '')
105 self.assertEqual(body, '{"data": "foo"}')
106
Joe Gregoriofe695fb2010-08-30 12:04:04 -0400107 def test_json_build_query(self):
Joe Gregoriod433b2a2011-02-22 10:51:51 -0500108 model = JsonModel(data_wrapper=False)
Joe Gregoriofe695fb2010-08-30 12:04:04 -0400109
110 headers = {}
111 path_params = {}
Joe Gregorio61d7e962011-02-22 22:52:07 -0500112 query_params = {'foo': 1, 'bar': u'\N{COMET}',
113 'baz': ['fe', 'fi', 'fo', 'fum'], # Repeated parameters
114 'qux': []}
Joe Gregoriofe695fb2010-08-30 12:04:04 -0400115 body = {}
116
117 headers, params, query, body = model.request(headers, path_params, query_params, body)
118
119 self.assertEqual(headers['accept'], 'application/json')
120 self.assertEqual(headers['content-type'], 'application/json')
121
Joe Gregorio61d7e962011-02-22 22:52:07 -0500122 query_dict = parse_qs(query[1:])
Joe Gregoriofe695fb2010-08-30 12:04:04 -0400123 self.assertEqual(query_dict['foo'], ['1'])
124 self.assertEqual(query_dict['bar'], [u'\N{COMET}'.encode('utf-8')])
Joe Gregorio61d7e962011-02-22 22:52:07 -0500125 self.assertEqual(query_dict['baz'], ['fe', 'fi', 'fo', 'fum'])
126 self.assertTrue('qux' not in query_dict)
Joe Gregorio913e70d2010-11-05 15:38:23 -0400127 self.assertEqual(body, '{}')
Joe Gregoriofe695fb2010-08-30 12:04:04 -0400128
Joe Gregorioc5c5a372010-09-22 11:42:32 -0400129 def test_user_agent(self):
Joe Gregoriod433b2a2011-02-22 10:51:51 -0500130 model = JsonModel(data_wrapper=False)
Joe Gregorioc5c5a372010-09-22 11:42:32 -0400131
132 headers = {'user-agent': 'my-test-app/1.23.4'}
133 path_params = {}
134 query_params = {}
135 body = {}
136
137 headers, params, query, body = model.request(headers, path_params, query_params, body)
138
139 self.assertEqual(headers['user-agent'], 'my-test-app/1.23.4 google-api-python-client/1.0')
140
141 def test_bad_response(self):
Joe Gregoriod433b2a2011-02-22 10:51:51 -0500142 model = JsonModel(data_wrapper=False)
Joe Gregorioc5c5a372010-09-22 11:42:32 -0400143 resp = httplib2.Response({'status': '401'})
144 resp.reason = 'Unauthorized'
Joe Gregoriod4e14562011-01-04 09:51:45 -0500145 content = '{"error": {"message": "not authorized"}}'
Joe Gregorioc5c5a372010-09-22 11:42:32 -0400146
147 try:
148 content = model.response(resp, content)
149 self.fail('Should have thrown an exception')
150 except HttpError, e:
151 self.assertTrue('Unauthorized' in str(e))
152
153 resp['content-type'] = 'application/json'
154
155 try:
156 content = model.response(resp, content)
157 self.fail('Should have thrown an exception')
158 except HttpError, e:
159 self.assertTrue('not authorized' in str(e))
160
161
162 def test_good_response(self):
Joe Gregoriod433b2a2011-02-22 10:51:51 -0500163 model = JsonModel(data_wrapper=True)
Joe Gregorioc5c5a372010-09-22 11:42:32 -0400164 resp = httplib2.Response({'status': '200'})
165 resp.reason = 'OK'
166 content = '{"data": "is good"}'
167
168 content = model.response(resp, content)
169 self.assertEqual(content, 'is good')
Joe Gregoriofe695fb2010-08-30 12:04:04 -0400170
Joe Gregorio78a508d2010-10-26 16:36:36 -0400171 def test_good_response_wo_data(self):
Joe Gregoriod433b2a2011-02-22 10:51:51 -0500172 model = JsonModel(data_wrapper=False)
Joe Gregorio78a508d2010-10-26 16:36:36 -0400173 resp = httplib2.Response({'status': '200'})
174 resp.reason = 'OK'
175 content = '{"foo": "is good"}'
176
177 content = model.response(resp, content)
178 self.assertEqual(content, {'foo': 'is good'})
179
180 def test_good_response_wo_data_str(self):
Joe Gregoriod433b2a2011-02-22 10:51:51 -0500181 model = JsonModel(data_wrapper=False)
Joe Gregorio78a508d2010-10-26 16:36:36 -0400182 resp = httplib2.Response({'status': '200'})
183 resp.reason = 'OK'
184 content = '"data goes here"'
185
186 content = model.response(resp, content)
187 self.assertEqual(content, 'data goes here')
188
Joe Gregorio34044bc2011-03-07 16:58:33 -0500189
190class LoggingModel(unittest.TestCase):
191
192 def test_logging_json_model(self):
193 class MockLogging(object):
194 def __init__(self):
195 self.info_record = []
196 self.debug_record = []
197 def info(self, message, *args):
198 self.info_record.append(message % args)
199
200 def debug(self, message, *args):
201 self.debug_record.append(message % args)
202
203 class MockResponse(dict):
204 def __init__(self, items):
205 super(MockResponse, self).__init__()
206 self.status = items['status']
207 for key, value in items.iteritems():
208 self[key] = value
209 apiclient.model.logging = MockLogging()
210 apiclient.model.FLAGS = copy.deepcopy(FLAGS)
Joe Gregorioafdf50b2011-03-08 09:41:52 -0500211 apiclient.model.FLAGS.dump_request_response = True
Joe Gregorio34044bc2011-03-07 16:58:33 -0500212 model = LoggingJsonModel()
213 request_body = {
214 'field1': 'value1',
215 'field2': 'value2'
216 }
217 body_string = model.request({}, {}, {}, request_body)[-1]
218 json_body = simplejson.loads(body_string)
219 self.assertEqual(request_body, json_body)
220
221 response = {'status': 200,
222 'response_field_1': 'response_value_1',
223 'response_field_2': 'response_value_2'}
224 response_body = model.response(MockResponse(response), body_string)
225 self.assertEqual(request_body, response_body)
Joe Gregorioafdf50b2011-03-08 09:41:52 -0500226 self.assertEqual(apiclient.model.logging.info_record[:2],
227 ['--request-start--',
228 '-headers-start-'])
229 self.assertTrue('response_field_1: response_value_1' in
230 apiclient.model.logging.info_record)
231 self.assertTrue('response_field_2: response_value_2' in
232 apiclient.model.logging.info_record)
Joe Gregorio34044bc2011-03-07 16:58:33 -0500233 self.assertEqual(simplejson.loads(apiclient.model.logging.info_record[-2]),
234 request_body)
235 self.assertEqual(apiclient.model.logging.info_record[-1],
236 '--response-end--')
237
238
239
Joe Gregorioba9ea7f2010-08-19 15:49:04 -0400240if __name__ == '__main__':
241 unittest.main()