def test_attribution_atomic_transaction(self): """ Verify that an IntegrityError raised while creating a referral does not prevent a basket from being created. """ self._setup_request_cookie() product = ProductFactory() existing_basket = Basket.get_basket(self.request.user, self.request.site) existing_referral = Referral(basket=existing_basket, site=self.request.site) # Let's save an existing referral object to force the duplication happen in database existing_referral.save() with transaction.atomic(): with mock.patch( 'ecommerce.extensions.basket.utils._referral_from_basket_site' ) as mock_get_referral: # Mock to return a duplicated referral object, so when saved, a DB integrity error is raised # Mocking with side_effect to raise IntegrityError will not roll back the DB transaction # We actually would handle the exception in the attribute_cookie_data method. # Only causing the true database conflict like what we are doing here, would cause the roll back mock_get_referral.return_value = Referral( basket=existing_basket, site=self.request.site) basket = prepare_basket(self.request, [product]) referral = Referral.objects.filter(basket=basket) self.assertEqual(len(referral), 1) self.assertIsNotNone(basket) self.assertTrue(basket.id > 0) self.assertEqual(basket.status, Basket.OPEN) self.assertEqual(basket.lines.count(), 1) self.assertEqual(basket.lines.first().product, product)
def _referral_from_basket_site(basket, site): try: # There should be only 1 referral instance for one basket. # Referral and basket has a one to one relationship referral = Referral.objects.get(basket=basket) except Referral.DoesNotExist: referral = Referral(basket=basket, site=site) return referral
def _referral_from_basket_site(basket, site): try: referral = Referral.objects.get(basket=basket, site=site) except Referral.DoesNotExist: referral = Referral(basket=basket, site=site) return referral