[BUILD-471] Set core plan for scholarship memberships (#2200)

[BUILD-471] Set core plan for scholarship memberships (#2200)

  • [BUILD-471] - create new after update life cycle hook on Membership class.

  • [BUILD-471] - create a new hook for partial scholarship membership type.

diff --git a/ankihub/conftest.py b/ankihub/conftest.py
index 1993c1d..2209c8c 100644
--- a/ankihub/conftest.py
+++ b/ankihub/conftest.py
@@ -160,6 +160,14 @@ def basic_user(faker: Faker) -> User:
 
 
 @pytest.fixture
+def basic_user_with_membership(basic_user: User):
+    MembershipFactory(
+        user=basic_user,
+        status=MembershipStatusChoices.ACTIVE,
+    )
+
+
+@pytest.fixture
 def anki_user(faker: Faker) -> User:
     user: User = User.objects.create_user(
         username=faker.name().split()[0], email=faker.email(), password="password"
diff --git a/ankihub/memberships/models.py b/ankihub/memberships/models.py
index 2450919..ae31673 100644
--- a/ankihub/memberships/models.py
+++ b/ankihub/memberships/models.py
@@ -364,6 +364,24 @@ class Membership(LifecycleModelMixin, TimeStampedModel):
             ]
         )
 
+    @hook(
+        AFTER_UPDATE,
+        when="membership_type",
+        was_not=MembershipTypesChoices.FULL_SCHOLARSHIP,
+        is_now=MembershipTypesChoices.FULL_SCHOLARSHIP,
+    )
+    def _on_after_update_set_core_plan_for_scholarship_membership(self):
+        self.assign_plan("core")
+
+    @hook(
+        AFTER_UPDATE,
+        when="membership_type",
+        was_not=MembershipTypesChoices.PARTIAL_SCHOLARSHIP,
+        is_now=MembershipTypesChoices.PARTIAL_SCHOLARSHIP,
+    )
+    def _on_after_update_set_core_plan_for_partial_scholarship_membership(self):
+        self.assign_plan("core")
+
     @property
     def membership_end_date(self) -> str:
         return self.end_date.strftime("%m/%d/%Y") if self.end_date else ""
diff --git a/ankihub/memberships/tests/test_models.py b/ankihub/memberships/tests/test_models.py
index 26e4908..90500a3 100644
--- a/ankihub/memberships/tests/test_models.py
+++ b/ankihub/memberships/tests/test_models.py
@@ -10,6 +10,7 @@ from ankihub.memberships.models import (
     Membership,
     MembershipMetrics,
     MembershipStatusChoices,
+    MembershipTypesChoices,
     Plan,
 )
 from ankihub.memberships.tests.factories import (
@@ -320,6 +321,64 @@ class TestMembership:
         membership._clear_stripe_subscriptions_cache()
         mock_cache_delete.assert_called_once_with(expected_keys)
 
+    @pytest.mark.django_db
+    def test_on_after_update_set_core_plan_for_scholarship_memberships(
+        self,
+        basic_user: User,
+        basic_user_with_membership,
+        plans_with_meta_data,
+    ):
+        membership = basic_user.memberships.first()
+        assert not membership.plan
+        assert not membership.membership_type == MembershipTypesChoices.FULL_SCHOLARSHIP
+
+        membership.membership_type = MembershipTypesChoices.FULL_SCHOLARSHIP
+        membership.save(update_fields=["membership_type"])
+
+        membership.refresh_from_db()
+
+        assert membership.plan.slug == "core"
+
+    @pytest.mark.django_db
+    def test_on_after_update_not_set_core_plan_for_other_membership_type(
+        self,
+        basic_user: User,
+        basic_user_with_membership,
+        plans_with_meta_data,
+    ):
+        membership = basic_user.memberships.first()
+
+        assert not membership.plan
+        assert not membership.membership_type == MembershipTypesChoices.FULL_SCHOLARSHIP
+
+        membership.membership_type = MembershipTypesChoices.REGULAR
+        membership.save(update_fields=["membership_type"])
+
+        membership.refresh_from_db()
+
+        assert not membership.plan
+
+    @pytest.mark.django_db
+    def test_on_after_update_not_set_core_plan_for_partial_scholarship_membership_type(
+        self,
+        basic_user: User,
+        basic_user_with_membership,
+        plans_with_meta_data,
+    ):
+        membership = basic_user.memberships.first()
+
+        assert not membership.plan
+        assert (
+            not membership.membership_type == MembershipTypesChoices.PARTIAL_SCHOLARSHIP
+        )
+
+        membership.membership_type = MembershipTypesChoices.PARTIAL_SCHOLARSHIP
+        membership.save(update_fields=["membership_type"])
+
+        membership.refresh_from_db()
+
+        assert membership.plan.slug == "core"
+
 
 class TestMembershipQueryset:
     def test_get_by_customer_id(self, user):

GitHub
sha: e2f071bec09ad99890ea20ccb22399cb4149728e