aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Lemon <y@yulqen.org>2024-09-09 08:57:00 +0100
committerMatthew Lemon <y@yulqen.org>2024-09-09 08:57:00 +0100
commit31966b6cbef88006056db44448cdaf59ba40533e (patch)
tree4ef34346feb14d689e3bb0c3a1b6098d30936077
parent63461fb0b86a8f4a1422673626311d0979cd1077 (diff)
Test passing: signal sent on sign-up to create subscription
- user signs up - signal sent which creates Subscription based on SubscriptionPlan allowing 10 downloads initially. Plan lasts 365 days at present
-rw-r--r--pyblackbird_cc/payments/apps.py3
-rw-r--r--pyblackbird_cc/payments/migrations/0005_remove_subscriptionplan_stripe_plan_id.py17
-rw-r--r--pyblackbird_cc/payments/migrations/0006_subscription_plan.py24
-rw-r--r--pyblackbird_cc/payments/models.py2
-rw-r--r--pyblackbird_cc/payments/signals.py31
-rw-r--r--pyblackbird_cc/payments/tests/__init__.py0
-rw-r--r--pyblackbird_cc/payments/tests/test_models.py41
7 files changed, 117 insertions, 1 deletions
diff --git a/pyblackbird_cc/payments/apps.py b/pyblackbird_cc/payments/apps.py
index 99c845f..89e29f4 100644
--- a/pyblackbird_cc/payments/apps.py
+++ b/pyblackbird_cc/payments/apps.py
@@ -4,3 +4,6 @@ from django.apps import AppConfig
class PaymentsConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "pyblackbird_cc.payments"
+
+ def ready(self):
+ import pyblackbird_cc.payments.signals # noqa: F401
diff --git a/pyblackbird_cc/payments/migrations/0005_remove_subscriptionplan_stripe_plan_id.py b/pyblackbird_cc/payments/migrations/0005_remove_subscriptionplan_stripe_plan_id.py
new file mode 100644
index 0000000..1e642b4
--- /dev/null
+++ b/pyblackbird_cc/payments/migrations/0005_remove_subscriptionplan_stripe_plan_id.py
@@ -0,0 +1,17 @@
+# Generated by Django 5.0.4 on 2024-09-08 19:23
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("payments", "0004_rename_stripe_product_id_price_stripe_price_id"),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name="subscriptionplan",
+ name="stripe_plan_id",
+ ),
+ ]
diff --git a/pyblackbird_cc/payments/migrations/0006_subscription_plan.py b/pyblackbird_cc/payments/migrations/0006_subscription_plan.py
new file mode 100644
index 0000000..f54b5f9
--- /dev/null
+++ b/pyblackbird_cc/payments/migrations/0006_subscription_plan.py
@@ -0,0 +1,24 @@
+# Generated by Django 5.0.4 on 2024-09-08 20:21
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("payments", "0005_remove_subscriptionplan_stripe_plan_id"),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name="subscription",
+ name="plan",
+ field=models.ForeignKey(
+ default=1,
+ on_delete=django.db.models.deletion.CASCADE,
+ to="payments.subscriptionplan",
+ ),
+ preserve_default=False,
+ ),
+ ]
diff --git a/pyblackbird_cc/payments/models.py b/pyblackbird_cc/payments/models.py
index 2b66c14..cbf462c 100644
--- a/pyblackbird_cc/payments/models.py
+++ b/pyblackbird_cc/payments/models.py
@@ -48,11 +48,11 @@ class SubscriptionPlan(models.Model):
price = models.DecimalField(max_digits=6, decimal_places=2)
description = models.TextField()
allowed_downloads = models.PositiveIntegerField()
- stripe_plan_id = models.CharField(max_length=255)
class Subscription(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
+ plan = models.ForeignKey(SubscriptionPlan, on_delete=models.CASCADE)
is_active = models.BooleanField(default=False)
start_date = models.DateTimeField(null=True, blank=True)
end_date = models.DateTimeField(null=True, blank=True)
diff --git a/pyblackbird_cc/payments/signals.py b/pyblackbird_cc/payments/signals.py
new file mode 100644
index 0000000..c4cdf1a
--- /dev/null
+++ b/pyblackbird_cc/payments/signals.py
@@ -0,0 +1,31 @@
+from datetime import timedelta
+
+from allauth.account.signals import user_signed_up
+from django.dispatch import receiver
+from django.db import transaction
+from django.utils import timezone
+
+from .models import SubscriptionPlan, Subscription
+
+
+@receiver(user_signed_up)
+def assign_default_subscription(sender, request, user, **kwargs):
+ with transaction.atomic():
+ # Get or create the free plan subscription
+ free_plan, _ = SubscriptionPlan.objects.get_or_create(
+ name="Free Plan",
+ defaults={
+ "price": 0,
+ "description": "Free plan description",
+ "allowed_downloads": 10,
+ }
+ )
+
+ # Create a SubscriptionPlan for the new user
+ Subscription.objects.create(
+ user=user,
+ plan=free_plan,
+ is_active=True,
+ start_date=timezone.now(),
+ end_date=timezone.now() + timedelta(days=365), # Example: 30 days
+ )
diff --git a/pyblackbird_cc/payments/tests/__init__.py b/pyblackbird_cc/payments/tests/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pyblackbird_cc/payments/tests/__init__.py
diff --git a/pyblackbird_cc/payments/tests/test_models.py b/pyblackbird_cc/payments/tests/test_models.py
new file mode 100644
index 0000000..342ff14
--- /dev/null
+++ b/pyblackbird_cc/payments/tests/test_models.py
@@ -0,0 +1,41 @@
+import pytest
+from allauth.account.signals import user_signed_up
+from django.contrib.auth import get_user_model
+from django.test import RequestFactory
+
+from pyblackbird_cc.payments.models import SubscriptionPlan, Subscription
+
+User = get_user_model()
+
+@pytest.fixture
+def user_data():
+ return {
+ 'email': 'testuser@example.com',
+ 'password': 'testpassword123'
+ }
+
+@pytest.mark.django_db
+def test_user_signup_assigns_free_subscription(user_data):
+ # Ensure the free plan exists
+ free_plan, _ = SubscriptionPlan.objects.get_or_create(
+ name="Free Plan",
+ defaults={
+ "price": 0,
+ "description": "Free plan description",
+ "allowed_downloads": 10,
+ }
+ ) # Create a new user
+ user = User.objects.create_user(**user_data)
+ # Manually trigger the user_signed_up signal
+ request = RequestFactory().get('/')
+ user_signed_up.send(sender=user.__class__, request=request, user=user)
+
+ # Check if a SubscriptionPlan was created for the user
+ subscription = Subscription.objects.filter(user=user).first()
+ assert subscription is not None
+
+ # Check if the assigned plan is the free plan
+ assert subscription.plan == free_plan
+
+ # Additional assertions can be added here to check other properties
+ # of the SubscriptionPlan or Subscription as needed \ No newline at end of file