def GetResponse(self, raw_response): mock_http = MockAsyncHTTPClient() mock_http.map(r"https://.*\.itunes\.apple\.com/verifyReceipt", functools.partial(self.VerifyReceipt, raw_response)) client = ITunesStoreClient(http_client=mock_http) client.VerifyReceipt(kReceiptData, self.stop) response = self.wait() return response
def setUp(self): super(RecordSubscriptionTestCase, self).setUp() self.mock_http = MockAsyncHTTPClient(self.io_loop) self._validate = False ITunesStoreClient.SetInstance( 'prod', ITunesStoreClient(environment='prod', http_client=self.mock_http)) ITunesStoreClient.SetInstance( 'dev', ITunesStoreClient(environment='dev', http_client=self.mock_http))
def setUp(self): super(RecordSubscriptionTestCase, self).setUp() self.mock_http = MockAsyncHTTPClient(self.io_loop) self._validate = False ITunesStoreClient.SetInstance("prod", ITunesStoreClient(environment="prod", http_client=self.mock_http)) ITunesStoreClient.SetInstance("dev", ITunesStoreClient(environment="dev", http_client=self.mock_http))
def testClickatellSMSManagerSend(self): """Test the Clickatell API.""" info_dict = { 'user': '******', 'password': '******', 'api_id': '3391545', 'to': '14257502513', 'MO': '1', 'from': '16467361610', 'text': 'this is a test text', } expected_response_dict = {'ID': '18af4edb086a15f7904a1584c7960c2a'} sms = ClickatellSMSManager() # Mock responses from Clickatell. with mock.patch('tornado.httpclient.AsyncHTTPClient', MockAsyncHTTPClient()) as mock_client: # Response to sms. _AddMockJSONResponse(mock_client, r'https://api.clickatell.com/http/sendmsg', expected_response_dict) response_dict = self._RunAsync(sms.SendSMS, number=info_dict['to'], text=info_dict['text']) self.assertEqual(expected_response_dict, response_dict)
def _TestAuthGoogleUser(action, tester, user_dict, device_dict=None, user_cookie=None): """Called by the ServiceTester in order to test login/google, link/google, and register/google calls. """ ident_dict = { 'key': 'Email:%s' % Identity.CanonicalizeEmail(user_dict['email']), 'authority': 'Google', 'refresh_token': 'refresh_token', 'access_token': 'access_token', 'expires': util._TEST_TIME + 3600 } if device_dict: device_dict.pop('device_uuid', None) device_dict.pop('test_udid', None) # Mock responses from Google. with mock.patch('tornado.httpclient.AsyncHTTPClient', MockAsyncHTTPClient()) as mock_client: # Response to request for access token. auth_test._AddMockJSONResponse( mock_client, r'https://accounts.google.com/o/oauth2/token', { 'access_token': ident_dict['access_token'], 'token_type': 'Bearer', 'expires_in': ident_dict['expires'] - util._TEST_TIME, 'id_token': 'id_token', 'refresh_token': ident_dict['refresh_token'] }) # Response to request for user info. auth_test._AddMockJSONResponse( mock_client, r'https://www.googleapis.com/oauth2/v1/userinfo\?', user_dict) # Response to request for people (i.e. contacts). auth_test._AddMockJSONResponse( mock_client, r'https://www.google.com/m8/feeds/contacts/default/full', { 'feed': { 'entry': [], 'openSearch$startIndex': { '$t': '1' }, 'openSearch$totalResults': { '$t': '0' } } }) response = auth_test._AuthFacebookOrGoogleUser(tester, action, user_dict, ident_dict, device_dict, user_cookie) return auth_test._ValidateAuthUser(tester, action, user_dict, ident_dict, device_dict, user_cookie, response)
def testTwilioSMSManagerSend(self): """Test the Twilio API.""" info_dict = { 'Body': u'this is a test text \xc9', 'To': '+14251234567', 'From': '+12061234567' } expected_response_dict = { 'account_sid': 'ACa437bddda03231c80f4c463dc51513bb', 'api_version': '2010-04-01', 'body': 'Jenny please?! I love you <3', 'date_created': 'Wed, 18 Aug 2010 20:01:40 +0000', 'date_sent': 'null', 'date_updated': 'Wed, 18 Aug 2010 20:01:40 +0000', 'direction': 'outbound-api', 'from': '+12061234567', 'price': 'null', 'sid': 'SM90c6fc909d8504d45ecdb3a3d5b3556e', 'status': 'queued', 'to': '+14151234567', 'uri': '/2010-04-01/Accounts/ACa437bddda03231c80f4c463dc51513bb/SMS/Messages/SM90c6fc909d8504d45ecdb3a3d5b3556e.json' } sms = TwilioSMSManager() # Mock responses from Twilio. with mock.patch('tornado.httpclient.AsyncHTTPClient', MockAsyncHTTPClient()) as mock_client: # Response to sms. _AddMockJSONResponse( mock_client, r'https://api.twilio.com/2010-04-01/Accounts/dummy_twilio_account_sid/SMS/Messages.json', expected_response_dict) response_dict = self._RunAsync(sms.SendSMS, number=info_dict['To'], text=info_dict['Body']) self.assertEqual(expected_response_dict, response_dict)
def test_app_redirect(self): """Follow the redirect from /app to app store and verify google analytics logging.""" requests = [] def _LogRequest(request): requests.append(request) return HTTPResponse(request, 200, buffer=StringIO('')) with mock.patch('tornado.httpclient.AsyncHTTPClient', MockAsyncHTTPClient()) as mock_client: mock_client.map('.*', _LogRequest) response = self.fetch('/app', follow_redirects=False) self.assertEqual(response.code, 302) self.assertIn('https://itunes.apple.com', response.headers['Location']) self.assertEqual(len(requests), 1) self.assertEqual('http://www.google-analytics.com/collect', requests[0].url)
def _TestAuthFacebookUser(action, tester, user_dict, device_dict=None, user_cookie=None): """Called by the ServiceTester in order to test login/facebook, link/facebook, and register/facebook calls. """ ident_dict = { 'key': 'FacebookGraph:%s' % user_dict['id'], 'authority': 'Facebook', 'access_token': 'access_token' } if device_dict: device_dict.pop('device_uuid', None) device_dict.pop('test_udid', None) # Mock responses from Facebook. with mock.patch('tornado.httpclient.AsyncHTTPClient', MockAsyncHTTPClient()) as mock_client: # Add response to request for an access token. mock_client.map( r'https://graph.facebook.com/oauth/access_token', 'access_token=%s&expires=3600' % ident_dict['access_token']) # Response to request for user info. auth_test._AddMockJSONResponse(mock_client, r'https://graph.facebook.com/me\?', user_dict) # Add empty response to request for photos and friends. auth_test._AddMockJSONResponse( mock_client, r'https://graph.facebook.com/me/photos\?', {'data': []}) auth_test._AddMockJSONResponse( mock_client, r'https://graph.facebook.com/me/friends\?', {'data': []}) response = auth_test._AuthFacebookOrGoogleUser(tester, action, user_dict, ident_dict, device_dict, user_cookie) return auth_test._ValidateAuthUser(tester, action, user_dict, ident_dict, device_dict, user_cookie, response)
def testAuthenticationFailed(self): """ERROR: Fail Facebook authentication (which returns None user_dict).""" with mock.patch('tornado.httpclient.AsyncHTTPClient', MockAsyncHTTPClient()) as mock_client: mock_client.map( r'https://graph.facebook.com/me\?', lambda request: httpclient.HTTPResponse(request, 400)) url = self.get_url('/register/facebook?access_token=access_token') self.assertRaisesHttpError( 401, auth_test._SendAuthRequest, self._tester, url, 'POST', user_cookie=self._cookie, request_dict=auth_test._CreateRegisterRequest( self._mobile_device_dict))
def testTwilioSMSManagerSendError(self): """Test the Twilio SMS Manager http error handling.""" info_dict = { 'Body': 'this is a test text', 'To': '+14251234567', 'From': '+12061234567' } sms = TwilioSMSManager() # Mock responses from Twilio. with mock.patch('tornado.httpclient.AsyncHTTPClient', MockAsyncHTTPClient()) as mock_client: # Response to sms. _AddMockJSONResponseError( mock_client, r'https://api.twilio.com/2010-04-01/Accounts/dummy_twilio_account_sid/SMS/Messages.json' ) self.assertRaises(SMSError, self._RunAsync, sms.SendSMS, number=info_dict['To'], text=info_dict['Body'])
def testClickatellSMSManagerSendError(self): """Test the Clickatell SMS Manager http error handling.""" info_dict = { 'user': '******', 'password': '******', 'api_id': '3391545', 'to': '14257502513', 'MO': '1', 'from': '16467361610', 'text': 'this is a test text', } sms = ClickatellSMSManager() # Mock responses from Twilio. with mock.patch('tornado.httpclient.AsyncHTTPClient', MockAsyncHTTPClient()) as mock_client: # Response to sms. _AddMockJSONResponseError( mock_client, r'https://api.clickatell.com/http/sendmsg') self.assertRaisesHttpError(401, self._RunAsync, sms.SendSMS, number=info_dict['to'], text=info_dict['text'])
class RecordSubscriptionTestCase(service_base_test.ServiceBaseTestCase): def setUp(self): super(RecordSubscriptionTestCase, self).setUp() self.mock_http = MockAsyncHTTPClient(self.io_loop) self._validate = False ITunesStoreClient.SetInstance("prod", ITunesStoreClient(environment="prod", http_client=self.mock_http)) ITunesStoreClient.SetInstance("dev", ITunesStoreClient(environment="dev", http_client=self.mock_http)) def tearDown(self): ITunesStoreClient.ClearInstance("prod") ITunesStoreClient.ClearInstance("dev") super(RecordSubscriptionTestCase, self).tearDown() def _CheckSubscriptionMetadata(self, json_dict, transaction_id=itunes_store_test.kTransactionId): self.assertEqual(json_dict["transaction_id"], "itunes:%s" % transaction_id) self.assertEqual(json_dict["product_type"], "vf_sub1") self.assertEqual(json_dict["quantity"], 5) self.assertEqual(json_dict["extra_info"]["transaction_id"], transaction_id) def _RecordSubscription(self, user_cookie, receipt_data): return self._SendRequest("record_subscription", self._cookie, {"receipt_data": base64.b64encode(receipt_data)}) def _GetSubscriptions(self, include_history=True): return self._RunAsync( Subscription.QueryByUser, self._client, user_id=self._user.user_id, include_history=include_history ) def testValidReceipt(self): """Valid receipts get added to the user's subscriptions.""" self.mock_http.map(".*", itunes_store_test.MakeNewResponse()) response = self._RecordSubscription(self._cookie, itunes_store_test.kReceiptData) self._CheckSubscriptionMetadata(response["subscription"]) subs = self._GetSubscriptions() self.assertEqual(1, len(subs)) self.assertEqual(subs[0].transaction_id, "itunes:%s" % itunes_store_test.kTransactionId) def testFreshReceipt(self): """Receipts with expiration in the future are returned without include_history=True.""" # Subscriptions do not currently go through the ServiceTester/DBValidator apparatus, # so validation will fail. self._validate = False self.mock_http.map(".*", itunes_store_test.MakeFreshResponse()) response = self._RecordSubscription(self._cookie, itunes_store_test.kReceiptData) self._CheckSubscriptionMetadata(response["subscription"]) subs = self._GetSubscriptions(include_history=False) self.assertEqual(1, len(subs)) self.assertEqual(subs[0].transaction_id, "itunes:%s" % itunes_store_test.kTransactionId) # query_users will return non-expired subscriptions response = self._SendRequest("query_users", self._cookie, {"user_ids": [self._user.user_id]}) json_subs = response["users"][0]["private"]["subscriptions"] self.assertEqual(len(json_subs), 1) self._CheckSubscriptionMetadata(json_subs[0]) # a notification was also sent for the user response = self._SendRequest("query_notifications", self._cookie, {}) for n in response["notifications"]: if n["name"] == "record_subscription": self.assertEqual(n["invalidate"], {"users": [self._user.user_id]}) break else: raise AssertionError("did not find record_subscription invalidation in %r" % response) def testDuplicateReceipt(self): """Repeated upload of the same receipt succeeds but doesn't create duplicate records. """ self.mock_http.map(".*", itunes_store_test.MakeNewResponse()) response = self._RecordSubscription(self._cookie, itunes_store_test.kReceiptData) self._CheckSubscriptionMetadata(response["subscription"]) response = self._RecordSubscription(self._cookie, itunes_store_test.kReceiptData) self._CheckSubscriptionMetadata(response["subscription"]) subs = self._GetSubscriptions() self.assertEqual(1, len(subs)) def testMultipleReceipts(self): """Different receipts create new records.""" self.mock_http.map(".*", itunes_store_test.MakeNewResponse()) response = self._RecordSubscription(self._cookie, "receipt1") self._CheckSubscriptionMetadata(response["subscription"]) self.mock_http.map(".*", itunes_store_test.MakeRenewedResponse()) response = self._RecordSubscription(self._cookie, "receipt2") self._CheckSubscriptionMetadata(response["subscription"], transaction_id=itunes_store_test.kTransactionId2) subs = self._GetSubscriptions() self.assertEqual(2, len(subs)) self.assertItemsEqual( ["itunes:%s" % i for i in [itunes_store_test.kTransactionId, itunes_store_test.kTransactionId2]], [sub.transaction_id for sub in subs], ) def testInvalidReceipt(self): """ERROR: an invalid signature fails cleanly with a 400 status code, indicating the retrying is futile.""" self.mock_http.map(".*", itunes_store_test.MakeBadSignatureResponse()) self.assertRaisesHttpError(400, self._RecordSubscription, self._cookie, itunes_store_test.kReceiptData) self.assertEqual([], self._GetSubscriptions()) def testServerError(self): """ERROR: server errors fail with a 500 status code, indicating that the request should be retried in the future.""" self.mock_http.map(".*", itunes_store_test.MakeServerErrorResponse()) self.assertRaisesHttpError(500, self._RecordSubscription, self._cookie, itunes_store_test.kReceiptData) self.assertEqual([], self._GetSubscriptions()) def testSandboxReceipt(self): """Receipts from the itunes sandbox are validated, but not recorded.""" self.mock_http.map( ITunesStoreClient._SETTINGS["prod"]["verify_url"], itunes_store_test.MakeSandboxOnProdResponse() ) self.mock_http.map(ITunesStoreClient._SETTINGS["dev"]["verify_url"], itunes_store_test.MakeNewResponse()) response = self._RecordSubscription(self._cookie, itunes_store_test.kReceiptData) # Metadata is returned in the response, but will not be present when queried later. self._CheckSubscriptionMetadata(response["subscription"]) self.assertEqual([], self._GetSubscriptions())
class RecordSubscriptionTestCase(service_base_test.ServiceBaseTestCase): def setUp(self): super(RecordSubscriptionTestCase, self).setUp() self.mock_http = MockAsyncHTTPClient(self.io_loop) self._validate = False ITunesStoreClient.SetInstance( 'prod', ITunesStoreClient(environment='prod', http_client=self.mock_http)) ITunesStoreClient.SetInstance( 'dev', ITunesStoreClient(environment='dev', http_client=self.mock_http)) def tearDown(self): ITunesStoreClient.ClearInstance('prod') ITunesStoreClient.ClearInstance('dev') super(RecordSubscriptionTestCase, self).tearDown() def _CheckSubscriptionMetadata(self, json_dict, transaction_id=itunes_store_test. kTransactionId): self.assertEqual(json_dict['transaction_id'], 'itunes:%s' % transaction_id) self.assertEqual(json_dict['product_type'], 'vf_sub1') self.assertEqual(json_dict['quantity'], 5) self.assertEqual(json_dict['extra_info']['transaction_id'], transaction_id) def _RecordSubscription(self, user_cookie, receipt_data): return self._SendRequest( 'record_subscription', self._cookie, {'receipt_data': base64.b64encode(receipt_data)}) def _GetSubscriptions(self, include_history=True): return self._RunAsync(Subscription.QueryByUser, self._client, user_id=self._user.user_id, include_history=include_history) def testValidReceipt(self): """Valid receipts get added to the user's subscriptions.""" self.mock_http.map('.*', itunes_store_test.MakeNewResponse()) response = self._RecordSubscription(self._cookie, itunes_store_test.kReceiptData) self._CheckSubscriptionMetadata(response['subscription']) subs = self._GetSubscriptions() self.assertEqual(1, len(subs)) self.assertEqual(subs[0].transaction_id, 'itunes:%s' % itunes_store_test.kTransactionId) def testFreshReceipt(self): """Receipts with expiration in the future are returned without include_history=True.""" # Subscriptions do not currently go through the ServiceTester/DBValidator apparatus, # so validation will fail. self._validate = False self.mock_http.map('.*', itunes_store_test.MakeFreshResponse()) response = self._RecordSubscription(self._cookie, itunes_store_test.kReceiptData) self._CheckSubscriptionMetadata(response['subscription']) subs = self._GetSubscriptions(include_history=False) self.assertEqual(1, len(subs)) self.assertEqual(subs[0].transaction_id, 'itunes:%s' % itunes_store_test.kTransactionId) # query_users will return non-expired subscriptions response = self._SendRequest('query_users', self._cookie, {'user_ids': [self._user.user_id]}) json_subs = response['users'][0]['private']['subscriptions'] self.assertEqual(len(json_subs), 1) self._CheckSubscriptionMetadata(json_subs[0]) # a notification was also sent for the user response = self._SendRequest('query_notifications', self._cookie, {}) for n in response['notifications']: if n['name'] == 'record_subscription': self.assertEqual(n['invalidate'], {'users': [self._user.user_id]}) break else: raise AssertionError( 'did not find record_subscription invalidation in %r' % response) def testDuplicateReceipt(self): """Repeated upload of the same receipt succeeds but doesn't create duplicate records. """ self.mock_http.map('.*', itunes_store_test.MakeNewResponse()) response = self._RecordSubscription(self._cookie, itunes_store_test.kReceiptData) self._CheckSubscriptionMetadata(response['subscription']) response = self._RecordSubscription(self._cookie, itunes_store_test.kReceiptData) self._CheckSubscriptionMetadata(response['subscription']) subs = self._GetSubscriptions() self.assertEqual(1, len(subs)) def testMultipleReceipts(self): """Different receipts create new records.""" self.mock_http.map('.*', itunes_store_test.MakeNewResponse()) response = self._RecordSubscription(self._cookie, 'receipt1') self._CheckSubscriptionMetadata(response['subscription']) self.mock_http.map('.*', itunes_store_test.MakeRenewedResponse()) response = self._RecordSubscription(self._cookie, 'receipt2') self._CheckSubscriptionMetadata( response['subscription'], transaction_id=itunes_store_test.kTransactionId2) subs = self._GetSubscriptions() self.assertEqual(2, len(subs)) self.assertItemsEqual([ 'itunes:%s' % i for i in [ itunes_store_test.kTransactionId, itunes_store_test.kTransactionId2 ] ], [sub.transaction_id for sub in subs]) def testInvalidReceipt(self): """ERROR: an invalid signature fails cleanly with a 400 status code, indicating the retrying is futile.""" self.mock_http.map('.*', itunes_store_test.MakeBadSignatureResponse()) self.assertRaisesHttpError(400, self._RecordSubscription, self._cookie, itunes_store_test.kReceiptData) self.assertEqual([], self._GetSubscriptions()) def testServerError(self): """ERROR: server errors fail with a 500 status code, indicating that the request should be retried in the future.""" self.mock_http.map('.*', itunes_store_test.MakeServerErrorResponse()) self.assertRaisesHttpError(500, self._RecordSubscription, self._cookie, itunes_store_test.kReceiptData) self.assertEqual([], self._GetSubscriptions()) def testSandboxReceipt(self): """Receipts from the itunes sandbox are validated, but not recorded.""" self.mock_http.map(ITunesStoreClient._SETTINGS['prod']['verify_url'], itunes_store_test.MakeSandboxOnProdResponse()) self.mock_http.map(ITunesStoreClient._SETTINGS['dev']['verify_url'], itunes_store_test.MakeNewResponse()) response = self._RecordSubscription(self._cookie, itunes_store_test.kReceiptData) # Metadata is returned in the response, but will not be present when queried later. self._CheckSubscriptionMetadata(response['subscription']) self.assertEqual([], self._GetSubscriptions())
def testRangeQuery(self): """Test DBRangeObject.RangeQuery.""" def _MakeResponse(max_index, request): # Enforce maximum limit of 2. request_dict = json.loads(request.body) limit = min(request_dict.get('Limit', 2), 2) is_count = request_dict.get('Count') if 'ExclusiveStartKey' in request_dict: start_index = int(request_dict['ExclusiveStartKey'] ['RangeKeyElement']['S']['S'][-1]) + 1 else: start_index = 0 count = min(max_index - start_index, limit) items = [] for i in xrange(start_index, start_index + count): items.append({'ei': {'S': 'e0'}, 'sk': {'S': 'p%d' % i}}) response_dict = {'Count': count, 'ConsumedCapacityUnits': 0.5} if not is_count: response_dict['Items'] = items if start_index + count < max_index: response_dict['LastEvaluatedKey'] = { 'HashKeyElement': { 'S': items[-1]['ei'] }, 'RangeKeyElement': { 'S': items[-1]['sk'] } } return httpclient.HTTPResponse( request, 200, headers={'Content-Type': 'application/json'}, buffer=StringIO(json.dumps(response_dict))) # Get session token from Amazon (no need to mock that). client = dynamodb_client.DynamoDBClient(schema=vf_schema.SCHEMA) self._RunAsync(client.GetItem, vf_schema.TEST_RENAME, DBKey('1', 1), attributes=None, must_exist=False) with mock.patch('tornado.httpclient.AsyncHTTPClient', MockAsyncHTTPClient()) as mock_client: mock_client.map(r'https://dynamodb.us-east-1.amazonaws.com', partial(_MakeResponse, 5)) # Limit = None. posts = self._RunAsync(Post.RangeQuery, client, 'e0', None, None, None) self.assertEqual(len(posts), 2) # Limit = 2. posts = self._RunAsync(Post.RangeQuery, client, 'e0', None, 2, None) self.assertEqual(len(posts), 2) # Limit = 5. posts = self._RunAsync(Post.RangeQuery, client, 'e0', None, 5, None) self.assertEqual(len(posts), 5) # Limit = 7. posts = self._RunAsync(Post.RangeQuery, client, 'e0', None, 7, None) self.assertEqual(len(posts), 5) # Limit = None, count = True. count = self._RunAsync(Post.RangeQuery, client, 'e0', None, None, None, count=True) self.assertEqual(count, 2) # Limit = 2, count = True. count = self._RunAsync(Post.RangeQuery, client, 'e0', None, 2, None, count=True) self.assertEqual(count, 2) # Limit = 5, count = True. count = self._RunAsync(Post.RangeQuery, client, 'e0', None, 5, None, count=True) self.assertEqual(count, 5) # Limit = 7, count = True. count = self._RunAsync(Post.RangeQuery, client, 'e0', None, 7, None, count=True) self.assertEqual(count, 5)