def test_user_fails_to_subscribe_no_card(self, _sf, _ss, _sfa, session):
        """ User couldn't subscribe because they didn't setup a
            card or stripe account"""
        user = UnstripedUserFactory()
        plan = Plan.paid()
        uss = UserStripe(user)
        session.add(user)
        session.flush()

        with pytest.raises(AssertionError):
            uss.link_to_plan(plan)
    def test_user_unlink_from_plan_via_subscription(self):
        """Unlink a User from a plan based on change in their stripe subscription"""
        user = StripedUserFactory(tier="paid",
                                  stripe__payment_method="pm_card_visa")
        subscription = UserStripe(user)._retrieve_users_subscriptions(
            Plan.paid())

        UserStripe(user).unlink_from_plan_via_subscription(subscription.id)

        assert UserStripe(user)._retrieve_users_subscriptions(
            Plan.paid()) is None
        assert user.plan == Plan.free()
    def test_update_customer_changes_account_id(self, unsubscribe_required,
                                                session,
                                                attach_payment_method):
        """ A user cannot change their stripe id without
        cancelling their subscription first """

        # This is to prevent a refund redirection attack
        # User Alice has an Account
        # Hacker Bob has an Account
        # Hacker Bob gains access to User Alice's account
        # He updates Alice's stripe id to his stripe id
        # He then cancels Alice's subscription, recieving her pro-rated refund

        hacker = StripedUserFactory(
            email="*****@*****.**",
            tier="paid",
            stripe__payment_method="pm_card_mastercard",
        )
        user = StripedUserFactory(tier="paid",
                                  stripe__payment_method="pm_card_visa")
        temp_id = hacker.stripe_id
        hacker.stripe_id = None
        session.add(user)
        session.flush()

        user.stripe_id = temp_id
        assert UserStripe(user).update_stripe_customer("stripe_id") is False
        assert unsubscribe_required.called_once
    def test_create_customer(self):
        """ Create a Stripe Customer for a User """

        # NOTE This is recorded - if you re-record you'll have to modify the stripe_id
        user = UserFactory()
        assert UserStripe(user).create_customer()
        assert user.stripe_id == "cus_FPz8Z3uTNswpjq"
    def test_delete_customer(self, app):
        """ Delete a Stripe Customer """

        user = StripedUserFactory(tier="paid",
                                  email="*****@*****.**",
                                  stripe__payment_method="pm_card_visa")
        uss = UserStripe(user)
        uss.link_to_plan(Plan.paid())

        customer_id = user.stripe_id

        UserStripe(user).delete_stripe_customer()

        cus = stripe.Customer.retrieve(customer_id)
        assert cus.deleted is True
        assert user.plan == Plan.free()
    def test_user_from_customer_id(self, session):
        """Create a UserStripe interactor via Stripe Customer ID"""
        user = StripedUserFactory(tier="paid",
                                  stripe__payment_method="pm_card_visa")
        session.add(user)
        session.flush()

        uss = UserStripe.from_customer_id(user.stripe_id)

        assert uss.user == user
    def test_update_customer(self, unsubscribe_required, session,
                             attach_payment_method):
        """ Update a Stripe Customers Payment Method Id """
        user = StripedUserFactory(tier="paid",
                                  stripe__payment_method="pm_card_visa")
        session.add(user)
        session.flush()

        attach_payment_method(user, "pm_card_mastercard")
        assert UserStripe(user).update_stripe_customer(
            "stripe_payment_method") is True
        assert not unsubscribe_required.called
    def test_user_unsubscribed(self, unsubscribe_successful,
                               unsubscribe_not_required, session):
        """ User unsubscribes successfully """
        user = SubscribedUserFactory(tier="paid",
                                     stripe__payment_method="pm_card_visa")
        user.plan = Plan.free()
        session.add(user)
        session.flush()

        UserStripe(user).unlink_from_plan(Plan.paid())

        assert unsubscribe_successful.called_once
        assert not unsubscribe_not_required.called
    def test_user_link_to_plan_via_subscription(self):
        """Link a User to a Plan based on a change in their stripe subscription"""
        user = StripedUserFactory(
            tier="paid",
            stripe__payment_method="pm_card_threeDSecure2Required")

        subscriptions = stripe.Subscription.list(plan=Plan.paid().stripe_id,
                                                 customer=user.stripe_id)

        # this subscription is _NOT_ actually paid now, but we check in the event
        # listener - this method just makes sure the User's plan reflects the
        # subscription they'r paying for
        UserStripe(user).link_to_plan_via_subscription(
            subscriptions.data[0].id)

        assert user.plan == Plan.paid()
    def test_user_unsubscribed_but_didnt_need_to(self, unsubscribe_successful,
                                                 unsubscribe_not_required,
                                                 session):
        """User can't unsubscribe if they're not subscribed in the first place
        <taps forehead>"""

        user = StripedUserFactory(tier="free",
                                  stripe__payment_method="pm_card_visa")
        user.plan = Plan.free()
        session.add(user)
        session.flush()

        UserStripe(user).unlink_from_plan(Plan.paid())

        assert not unsubscribe_successful.called
        assert unsubscribe_not_required.called_once
    def test_user_fails_to_subscribe_decline(
        self,
        subscribed_successfully,
        subscribed_failed,
        subscription_requires_action,
        session,
    ):
        """ User's card was declined when paying """
        # This is the 40000000341 card that will fail when a charge is initiated
        user = StripedUserFactory(
            tier="paid", stripe__payment_method="pm_card_chargeCustomerFail")
        session.add(user)
        session.flush()

        UserStripe(user).link_to_plan(user.plan)

        assert not subscribed_successfully.called
        assert not subscription_requires_action.called
        assert subscribed_failed.called_once
        assert user.plan == Plan.free()
    def test_user_fails_to_subscribe_security(
        self,
        subscribed_failed,
        subscribed_successfully,
        subscription_requires_action,
        session,
    ):
        """ User payment failed becaues of additional security
            measures on their account """
        user = StripedUserFactory(
            tier="paid",
            stripe__payment_method="pm_card_threeDSecure2Required")
        session.add(user)
        session.flush()

        UserStripe(user).link_to_plan(user.plan)

        assert not subscribed_successfully.called
        assert not subscribed_failed.called
        assert subscription_requires_action.called
        assert user.plan == Plan.free()
    def test_user_subscribed_successfully(
        self,
        subscribed_successfully,
        subscribed_failed,
        subscription_requires_action,
        session,
    ):
        """ User subscribed sucessfully """
        user = StripedUserFactory(tier="paid",
                                  stripe__payment_method="pm_card_visa")
        session.add(user)
        session.flush()
        # the user is a paid user when it is submitted to this job
        # immediately after a commit which changes it's plan_id
        # NOTE: this test does not actually change the user's plan
        UserStripe(user).link_to_plan(user.plan)

        assert not subscribed_failed.called
        assert not subscription_requires_action.called
        assert subscribed_successfully.called_once
        assert user.plan == Plan.paid()
Example #14
0
def user_subscribed(user_id: int, plan_id: int) -> None:
    plan = Plan.query.get(plan_id)
    user = User.query.get(user_id)
    UserStripe(user).link_to_plan(plan)
Example #15
0
def user_async_unsubscribe(event: StripeObject):
    UserStripe.from_customer_id(
        event.data.object.customer
    ).unlink_from_plan_via_subscription(event.data.object.subscription)
Example #16
0
def user_unsubscribed(user_id, old_plan_id):
    user = User.query.get(user_id)
    plan = Plan.query.get(old_plan_id)
    UserStripe(user).unlink_from_plan(plan)