blob: 7c5ce0d21b6cf9656c2c8535e15aa212728385ea [file] [log] [blame]
Ali Afshar164f37e2013-01-07 14:05:45 -08001# Licensed under the Apache License, Version 2.0 (the "License");
2# you may not use this file except in compliance with the License.
3# You may obtain a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS,
9# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10# See the License for the specific language governing permissions and
11# limitations under the License.
12
13"""Push notifications tests."""
14
15__author__ = 'afshar@google.com (Ali Afshar)'
16
17import unittest
18
19from apiclient import push
20from apiclient import model
21from apiclient import http
Joe Gregorio003b6e42013-02-13 15:42:19 -050022from test_discovery import assertUrisEqual
Ali Afshar164f37e2013-01-07 14:05:45 -080023
24
25class ClientTokenGeneratorTest(unittest.TestCase):
26
27 def test_next(self):
28 t = push.new_token()
29 self.assertTrue(t)
30
31
32class ChannelTest(unittest.TestCase):
33
34 def test_creation_noargs(self):
35 c = push.Channel(channel_type='my_channel_type', channel_args={})
36 self.assertEqual('my_channel_type', c.channel_type)
37 self.assertEqual({}, c.channel_args)
38
39 def test_creation_args(self):
40 c = push.Channel(channel_type='my_channel_type',
41 channel_args={'a': 'b'})
42 self.assertEqual('my_channel_type', c.channel_type)
43 self.assertEqual({'a':'b'}, c.channel_args)
44
45 def test_as_header_value_noargs(self):
46 c = push.Channel(channel_type='my_channel_type', channel_args={})
47 self.assertEqual('my_channel_type?', c.as_header_value())
48
49 def test_as_header_value_args(self):
50 c = push.Channel(channel_type='my_channel_type',
51 channel_args={'a': 'b'})
52 self.assertEqual('my_channel_type?a=b', c.as_header_value())
53
54 def test_as_header_value_args_space(self):
55 c = push.Channel(channel_type='my_channel_type',
56 channel_args={'a': 'b c'})
57 self.assertEqual('my_channel_type?a=b+c', c.as_header_value())
58
59 def test_as_header_value_args_escape(self):
60 c = push.Channel(channel_type='my_channel_type',
61 channel_args={'a': 'b%c'})
62 self.assertEqual('my_channel_type?a=b%25c', c.as_header_value())
63
64 def test_write_header_noargs(self):
65 c = push.Channel(channel_type='my_channel_type', channel_args={})
66 headers = {}
67 c.write_header(headers)
68 self.assertEqual('my_channel_type?', headers['X-GOOG-SUBSCRIBE'])
69
70 def test_write_header_args(self):
71 c = push.Channel(channel_type='my_channel_type',
72 channel_args={'a': 'b'})
73 headers = {}
74 c.write_header(headers)
75 self.assertEqual('my_channel_type?a=b', headers['X-GOOG-SUBSCRIBE'])
76
77 def test_write_header_args_space(self):
78 c = push.Channel(channel_type='my_channel_type',
79 channel_args={'a': 'b c'})
80 headers = {}
81 c.write_header(headers)
82 self.assertEqual('my_channel_type?a=b+c', headers['X-GOOG-SUBSCRIBE'])
83
84 def test_write_header_args_escape(self):
85 c = push.Channel(channel_type='my_channel_type',
86 channel_args={'a': 'b%c'})
87 headers = {}
88 c.write_header(headers)
89 self.assertEqual('my_channel_type?a=b%25c', headers['X-GOOG-SUBSCRIBE'])
90
91
92class WebhookChannelTest(unittest.TestCase):
93
94 def test_creation_no_appengine(self):
95 c = push.WebhookChannel('http://example.org')
Joe Gregorio003b6e42013-02-13 15:42:19 -050096 assertUrisEqual(self,
97 'web_hook?url=http%3A%2F%2Fexample.org&app_engine=false',
98 c.as_header_value())
Ali Afshar164f37e2013-01-07 14:05:45 -080099
100 def test_creation_appengine(self):
101 c = push.WebhookChannel('http://example.org', app_engine=True)
Joe Gregorio003b6e42013-02-13 15:42:19 -0500102 assertUrisEqual(self,
103 'web_hook?url=http%3A%2F%2Fexample.org&app_engine=true',
104 c.as_header_value())
Ali Afshar164f37e2013-01-07 14:05:45 -0800105
106
107class HeadersTest(unittest.TestCase):
108
109 def test_creation(self):
110 h = push.Headers()
111 self.assertEqual('', h[push.SUBSCRIBE])
112
113 def test_items(self):
114 h = push.Headers()
115 h[push.SUBSCRIBE] = 'my_channel_type'
116 self.assertEqual([(push.SUBSCRIBE, 'my_channel_type')], list(h.items()))
117
118 def test_items_non_whitelisted(self):
119 h = push.Headers()
120 def set_bad_header(h=h):
121 h['X-Banana'] = 'my_channel_type'
122 self.assertRaises(ValueError, set_bad_header)
123
124 def test_read(self):
125 h = push.Headers()
126 h.read({'x-goog-subscribe': 'my_channel_type'})
127 self.assertEqual([(push.SUBSCRIBE, 'my_channel_type')], list(h.items()))
128
129 def test_read_non_whitelisted(self):
130 h = push.Headers()
131 h.read({'X-Banana': 'my_channel_type'})
132 self.assertEqual([], list(h.items()))
133
134 def test_write(self):
135 h = push.Headers()
136 h[push.SUBSCRIBE] = 'my_channel_type'
137 headers = {}
138 h.write(headers)
139 self.assertEqual({'x-goog-subscribe': 'my_channel_type'}, headers)
140
141
142class SubscriptionTest(unittest.TestCase):
143
144 def test_create(self):
145 s = push.Subscription()
146 self.assertEqual('', s.client_token)
147
148 def test_create_for_channnel(self):
149 c = push.WebhookChannel('http://example.org')
150 s = push.Subscription.for_channel(c)
151 self.assertTrue(s.client_token)
Joe Gregorio003b6e42013-02-13 15:42:19 -0500152 assertUrisEqual(self,
153 'web_hook?url=http%3A%2F%2Fexample.org&app_engine=false',
154 s.subscribe)
Ali Afshar164f37e2013-01-07 14:05:45 -0800155
156 def test_create_for_channel_client_token(self):
157 c = push.WebhookChannel('http://example.org')
158 s = push.Subscription.for_channel(c, client_token='my_token')
159 self.assertEqual('my_token', s.client_token)
Joe Gregorio003b6e42013-02-13 15:42:19 -0500160 assertUrisEqual(self,
161 'web_hook?url=http%3A%2F%2Fexample.org&app_engine=false',
162 s.subscribe)
Ali Afshar164f37e2013-01-07 14:05:45 -0800163
164 def test_subscribe(self):
165 s = push.Subscription()
166 s.headers[push.SUBSCRIBE] = 'my_header'
167 self.assertEqual('my_header', s.subscribe)
168
169 def test_subscription_id(self):
170 s = push.Subscription()
171 s.headers[push.SUBSCRIPTION_ID] = 'my_header'
172 self.assertEqual('my_header', s.subscription_id)
173
174 def test_subscription_id_set(self):
175 c = push.WebhookChannel('http://example.org')
176 s = push.Subscription.for_channel(c)
177 self.assertTrue(s.subscription_id)
178
179 def test_topic_id(self):
180 s = push.Subscription()
181 s.headers[push.TOPIC_ID] = 'my_header'
182 self.assertEqual('my_header', s.topic_id)
183
184 def test_topic_uri(self):
185 s = push.Subscription()
186 s.headers[push.TOPIC_URI] = 'my_header'
187 self.assertEqual('my_header', s.topic_uri)
188
189 def test_client_token(self):
190 s = push.Subscription()
191 s.headers[push.CLIENT_TOKEN] = 'my_header'
192 self.assertEqual('my_header', s.client_token)
193
194 def test_event_type(self):
195 s = push.Subscription()
196 s.headers[push.EVENT_TYPE] = 'my_header'
197 self.assertEqual('my_header', s.event_type)
198
199 def test_unsubscribe(self):
200 s = push.Subscription()
201 s.headers[push.UNSUBSCRIBE] = 'my_header'
202 self.assertEqual('my_header', s.unsubscribe)
203
204 def test_do_subscribe(self):
205 m = model.JsonModel()
206 request = http.HttpRequest(
207 None,
208 m.response,
209 'https://www.googleapis.com/someapi/v1/collection/?foo=bar',
210 method='GET',
211 body='{}',
212 headers={'content-type': 'application/json'})
213 h = http.HttpMockSequence([
214 ({'status': 200,
215 'X-Goog-Subscription-ID': 'my_subscription'},
216 '{}')])
217 c = push.Channel('my_channel', {})
218 s = push.Subscription.for_request(request, c)
219 request.execute(http=h)
220 self.assertEqual('my_subscription', s.subscription_id)
221
222 def test_subscribe_with_token(self):
223 m = model.JsonModel()
224 request = http.HttpRequest(
225 None,
226 m.response,
227 'https://www.googleapis.com/someapi/v1/collection/?foo=bar',
228 method='GET',
229 body='{}',
230 headers={'content-type': 'application/json'})
231 h = http.HttpMockSequence([
232 ({'status': 200,
233 'X-Goog-Subscription-ID': 'my_subscription'},
234 '{}')])
235 c = push.Channel('my_channel', {})
236 s = push.Subscription.for_request(request, c, client_token='my_token')
237 request.execute(http=h)
238 self.assertEqual('my_subscription', s.subscription_id)
239 self.assertEqual('my_token', s.client_token)
240
241 def test_verify_good_token(self):
242 s = push.Subscription()
243 s.headers['X-Goog-Client-Token'] = '123'
244 notification_headers = {'x-goog-client-token': '123'}
245 self.assertTrue(s.verify(notification_headers))
246
247 def test_verify_bad_token(self):
248 s = push.Subscription()
249 s.headers['X-Goog-Client-Token'] = '321'
250 notification_headers = {'x-goog-client-token': '123'}
251 self.assertFalse(s.verify(notification_headers))
252
253 def test_request_is_post(self):
254 m = model.JsonModel()
255 request = http.HttpRequest(
256 None,
257 m.response,
258 'https://www.googleapis.com/someapi/v1/collection/?foo=bar',
259 method='GET',
260 body='{}',
261 headers={'content-type': 'application/json'})
262 c = push.Channel('my_channel', {})
263 push.Subscription.for_request(request, c)
264 self.assertEqual('POST', request.method)
265
266 def test_non_get_error(self):
267 m = model.JsonModel()
268 request = http.HttpRequest(
269 None,
270 m.response,
271 'https://www.googleapis.com/someapi/v1/collection/?foo=bar',
272 method='POST',
273 body='{}',
274 headers={'content-type': 'application/json'})
275 c = push.Channel('my_channel', {})
276 self.assertRaises(push.InvalidSubscriptionRequestError,
277 push.Subscription.for_request, request, c)