Ejemplo 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
Ejemplo 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
Ejemplo n.º 3
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())