Exemplo n.º 1
0
 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
Exemplo n.º 2
0
 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))
Exemplo n.º 4
0
    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))
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
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)
Exemplo n.º 7
0
 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)
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
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)
Exemplo n.º 10
0
    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))
Exemplo n.º 11
0
    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'])
Exemplo n.º 12
0
 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'])
Exemplo n.º 13
0
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())
Exemplo n.º 15
0
    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)