Skip to content

Commit

Permalink
Merge d316f99 into cbd4d22
Browse files Browse the repository at this point in the history
  • Loading branch information
poxip committed Aug 23, 2017
2 parents cbd4d22 + d316f99 commit 76e8508
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 17 deletions.
6 changes: 6 additions & 0 deletions aa_stripe/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ class StripeCouponAdmin(admin.ModelAdmin):
form = StripeCouponForm
list_display = ("id", "coupon_id", "amount_off", "percent_off", "currency", "created", "is_deleted",
"is_created_at_stripe")
list_filter = ("coupon_id", "amount_off", "percent_off", "currency", "created", "is_deleted",
"is_created_at_stripe")
readonly_fields = ("stripe_response", "created", "updated", "is_deleted")
ordering = ("-created",)

Expand All @@ -61,6 +63,10 @@ def get_readonly_fields(self, request, obj=None):

return self.readonly_fields

def has_delete_permission(self, request, obj=None):
# allow deleting single object, but disable bulk delete (bulk delete does not call models' .delete() method)
return bool(obj)


class StripeSubscriptionAdmin(ReadOnly):
list_display = (
Expand Down
21 changes: 20 additions & 1 deletion aa_stripe/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,25 @@ class StripeCoupon(StripeBasicModel):
is_deleted = models.BooleanField(default=False)
is_created_at_stripe = models.BooleanField(default=False)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._previous_is_deleted = self.is_deleted

def __str__(self):
return self.coupon_id

def save(self, *args, **kwargs):
stripe.api_key = settings.STRIPE_API_KEY
if self._previous_is_deleted != self.is_deleted and self.is_deleted:
try:
coupon = stripe.Coupon.retrieve(self.coupon_id)
coupon.delete()
except stripe.error.InvalidRequestError:
# means that the coupon has already been removed from stripe
pass

return super(StripeCoupon, self).save(*args, **kwargs)

if self.pk:
try:
coupon = stripe.Coupon.retrieve(self.coupon_id)
Expand Down Expand Up @@ -170,6 +184,11 @@ def save(self, *args, **kwargs):
self.is_created_at_stripe = True
return super(StripeCoupon, self).save(*args, **kwargs)

def delete(self, *args, **kwargs):
self.is_deleted = True
self.save()
return 0, {self._meta.label: 0}


class StripeCharge(StripeBasicModel):
user = models.ForeignKey(USER_MODEL, on_delete=models.CASCADE, related_name='stripe_charges')
Expand All @@ -185,7 +204,7 @@ class StripeCharge(StripeBasicModel):

def charge(self):
if self.is_charged:
raise StripeMethodNotAllowed("Already charded.")
raise StripeMethodNotAllowed("Already charged.")

stripe.api_key = settings.STRIPE_API_KEY
customer = StripeCustomer.get_latest_active_customer_for_user(self.user)
Expand Down
74 changes: 58 additions & 16 deletions tests/test_coupons.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,32 @@


class TestCoupons(APITestCase):
def _create_coupon(self, coupon_id, amount_off=None, duration=StripeCoupon.DURATION_FOREVER):
with requests_mock.Mocker() as m:
# create a simple coupon which will be used for tests
stripe_response = {
"id": coupon_id,
"object": "coupon",
"amount_off": amount_off,
"created": int(time.mktime(datetime.now().timetuple())),
"currency": "usd",
"duration": duration,
"duration_in_months": None,
"livemode": False,
"max_redemptions": None,
"metadata": {},
"percent_off": 25,
"redeem_by": None,
"times_redeemed": 0,
"valid": True
}
m.register_uri("POST", "https://api.stripe.com/v1/coupons", text=json.dumps(stripe_response))
return StripeCoupon.objects.create(
coupon_id=coupon_id,
duration=duration,
amount_off=amount_off
)

@freeze_time("2016-01-01 00:00:00")
def test_create(self):
# test creating simple coupon with no coupon_id specified (will be generated by Stripe)
Expand Down Expand Up @@ -52,14 +78,13 @@ def test_create(self):

def test_update(self):
with requests_mock.Mocker() as m:
# create a simple coupon which will be used for tests
stripe_response = {
"id": "25OFF",
"object": "coupon",
"amount_off": 1,
"created": int(time.mktime(datetime.now().timetuple())),
"currency": "usd",
"duration": "forever",
"duration": StripeCoupon.DURATION_FOREVER,
"duration_in_months": None,
"livemode": False,
"max_redemptions": None,
Expand All @@ -69,11 +94,7 @@ def test_update(self):
"times_redeemed": 0,
"valid": True
}
m.register_uri("POST", "https://api.stripe.com/v1/coupons", text=json.dumps(stripe_response))
coupon = StripeCoupon.objects.create(
duration=StripeCoupon.DURATION_FOREVER,
amount_off=1
)
coupon = self._create_coupon(coupon_id="25OFF", duration=StripeCoupon.DURATION_FOREVER, amount_off=1)
self.assertFalse(coupon.is_deleted)

# try accessing coupon that does not exist - should delete the coupon from our database
Expand All @@ -90,15 +111,38 @@ def test_update(self):
# try changing other Stripe data than coupon's metadata
m.register_uri("GET", "https://api.stripe.com/v1/coupons/25OFF", text=json.dumps(stripe_response))
m.register_uri("POST", "https://api.stripe.com/v1/coupons/25OFF", text=json.dumps(stripe_response))
coupon = StripeCoupon.objects.create(
duration=StripeCoupon.DURATION_FOREVER,
amount_off=1
)
coupon = self._create_coupon(coupon_id="25OFF", duration=StripeCoupon.DURATION_FOREVER, amount_off=1)
coupon.duration = StripeCoupon.DURATION_ONCE
coupon.save()
coupon.refresh_from_db()
self.assertNotEqual(coupon.duration, StripeCoupon.DURATION_ONCE)

def test_delete(self):
coupon = self._create_coupon(coupon_id="CPON", amount_off=1, duration=StripeCoupon.DURATION_FOREVER)
self.assertFalse(coupon.is_deleted)
stripe_response = {
"id": "CPON",
"object": "coupon",
"amount_off": 1,
"created": int(time.mktime(datetime.now().timetuple())),
"currency": "usd",
"duration": StripeCoupon.DURATION_FOREVER,
"duration_in_months": None,
"livemode": False,
"max_redemptions": None,
"metadata": {},
"percent_off": 25,
"redeem_by": None,
"times_redeemed": 0,
"valid": True
}
with requests_mock.Mocker() as m:
for method in ["GET", "DELETE"]:
m.register_uri(method, "https://api.stripe.com/v1/coupons/CPON", text=json.dumps(stripe_response))
coupon.delete()
coupon.refresh_from_db()
self.assertTrue(coupon.is_deleted)

def test_admin_form(self):
# test correct creation
data = {
Expand Down Expand Up @@ -149,11 +193,9 @@ def test_admin_form(self):
"valid": True
}
with requests_mock.Mocker() as m:
m.register_uri("POST", "https://api.stripe.com/v1/coupons", text=json.dumps(stripe_response))
m.register_uri("GET", "https://api.stripe.com/v1/coupons/25OFF", text=json.dumps(stripe_response))
m.register_uri("POST", "https://api.stripe.com/v1/coupons/25OFF", text=json.dumps(stripe_response))
coupon = StripeCoupon.objects.create(
coupon_id=data["coupon_id"], duration=StripeCoupon.DURATION_FOREVER, percent_off=25)
for method in ["GET", "POST", "DELETE"]:
m.register_uri(method, "https://api.stripe.com/v1/coupons/25OFF", text=json.dumps(stripe_response))
coupon = self._create_coupon(data["coupon_id"], amount_off=1)

# test creating a new coupon, when there is one that is not deleted
self.assertTrue(StripeCoupon.objects.filter(coupon_id=data["coupon_id"], is_deleted=False).exists())
Expand Down

0 comments on commit 76e8508

Please sign in to comment.