modified: make_post_sell/tests/test_functional.py

This commit is contained in:
Russell Ballestrini 2025-07-27 21:32:45 -04:00
parent 7e7ccd7581
commit 1a66bd210e

View file

@ -1030,345 +1030,3 @@ class AuthenticatedFunctionalTests(FunctionalTests):
del coupon_params["code"]
res = self.make_new_coupon_for_shop(coupon_params)
self.assertIn("Please submit all required fields.", res.body.decode())
# this patch requires an argument added to test method `mock_smtp`.
@patch("make_post_sell.models.Product.is_ready")
@patch("smtplib.SMTP")
@patch("stripe.SetupIntent.retrieve")
@patch("stripe.Customer.list_payment_methods")
def test_checkout_with_coupon_code(
self,
mock_list_payment_methods,
mock_setup_intent,
mock_smtp,
mock_product_ready,
):
# Debug: Confirm mock objects
print(f"Mock SetupIntent: {mock_setup_intent}")
print(f"Mock SMTP: {mock_smtp}")
print(f"Mock Product.is_ready: {mock_product_ready}")
print(f"Mock list_payment_methods: {mock_list_payment_methods}")
# Configure mocks
mock_product_ready.return_value = True
mock_setup_intent.return_value = {
"id": "seti_123",
"status": "succeeded",
"payment_method": "pm_card_visa",
"customer": "cus_123",
"client_secret": "seti_123_secret",
"payment_method_types": ["card"],
"payment_method_options": {"card": {}},
"metadata": {"card_id": "pm_card_visa"},
}
# Mock PaymentMethod object
payment_method = MagicMock()
payment_method.id = "pm_card_visa"
payment_method.type = "card"
payment_method.card.brand = "visa"
payment_method.card.last4 = "4242"
mock_list_payment_methods.return_value = {"data": [payment_method]}
# Step 1: Create a coupon as user1
res = self.make_new_coupon_for_shop()
res = res.follow()
self.assertIn("You created a new coupon!", res.body.decode())
# Re-query users and shop
self.user1 = get_or_create_user_by_email(self.dbsession, self.user1_creds[0])
self.user2 = get_or_create_user_by_email(self.dbsession, self.user2_creds[0])
shop = get_shop_by_name(self.dbsession, self.shop1_params["name"])
# Log out user1
self.testapp.get("/log-out")
# Log in user2
self.log_in_user(self.user2_creds)
# Refresh the shop to ensure it's committed
self.dbsession.refresh(shop)
print(
f"Shop UUID: {shop.uuid_str}, Ready: {shop.is_ready}, "
f"Public key: {shop.stripe_public_api_key}, "
f"Secret key: {shop.stripe_secret_api_key}"
)
# Verify shop is ready
self.assertTrue(
shop.is_ready,
f"Shop {shop.name} is not ready. "
f"stripe_public_api_key: {shop.stripe_public_api_key}, "
f"stripe_secret_api_key: {shop.stripe_secret_api_key}",
)
# Step 2: Visit /billing to create StripeUserShop record for user2
shop_id = str(shop.uuid_str)
res_billing_init = self.testapp.get(f"/billing?shop_id={shop_id}", status=200)
print(f"Billing init response: {res_billing_init.body.decode()}") # Debug
self.assertIn(
"The active card will be charged during checkout.",
res_billing_init.body.decode(),
) # Verify billing page
# Commit transaction to persist StripeUserShop
transaction.manager.commit()
# Re-query users and shop
self.user1 = get_or_create_user_by_email(self.dbsession, self.user1_creds[0])
self.user2 = get_or_create_user_by_email(self.dbsession, self.user2_creds[0])
shop = get_shop_by_name(self.dbsession, self.shop1_params["name"])
# Step 3: Add billing details for user2
csrf_token = self.get_csrf_token(shop.uuid_str)
if not csrf_token:
self.fail("CSRF token not found in session cookie (_csrft_)")
print(f"Using shop_id for billing: {shop_id}")
res_billing_redirect = self.testapp.post(
f"/billing/add-card?shop_id={shop_id}",
{
"email": self.user2.email,
"setup_intent": "seti_123",
"setup_intent_client_secret": "seti_123_secret",
"csrf_token": csrf_token,
},
status=302,
)
res_billing = res_billing_redirect.follow()
res_billing = res_billing.follow()
print(f"Billing response: {res_billing.body.decode()}") # Debug
self.assertIn(
"You saved a new card.", res_billing.body.decode()
) # Match view's flash message
# Commit transaction to persist card
transaction.manager.commit()
# Re-query users and shop
self.user1 = get_or_create_user_by_email(self.dbsession, self.user1_creds[0])
self.user2 = get_or_create_user_by_email(self.dbsession, self.user2_creds[0])
shop = get_shop_by_name(self.dbsession, self.shop1_params["name"])
# Verify StripeUserShop and set active card
stripe_user_shop = (
self.dbsession.query(StripeUserShop)
.filter_by(user_id=self.user2.id, shop_id=shop.id)
.first()
)
print(f"StripeUserShop for {self.user2.email}: {stripe_user_shop}")
print(
f"Card IDs before: {stripe_user_shop.stripe_card_ids if stripe_user_shop else None}"
)
if stripe_user_shop and not stripe_user_shop.active_card_id:
stripe_user_shop.active_card_id = "pm_card_visa"
self.dbsession.add(stripe_user_shop)
self.dbsession.flush()
print(f"Manually set active card ID: {stripe_user_shop.active_card_id}")
print(
f"Active card ID: {stripe_user_shop.active_card_id if stripe_user_shop else None}"
)
# Commit transaction to persist StripeUserShop changes
transaction.manager.commit()
# Re-query users and shop
self.user1 = get_or_create_user_by_email(self.dbsession, self.user1_creds[0])
self.user2 = get_or_create_user_by_email(self.dbsession, self.user2_creds[0])
shop = get_shop_by_name(self.dbsession, self.shop1_params["name"])
# Re-query StripeUserShop to verify persistence
stripe_user_shop = (
self.dbsession.query(StripeUserShop)
.filter_by(user_id=self.user2.id, shop_id=shop.id)
.first()
)
print(f"StripeUserShop after commit: {stripe_user_shop}")
print(
f"Active card ID after commit: {stripe_user_shop.active_card_id if stripe_user_shop else None}"
)
print(
f"Card IDs after commit: {stripe_user_shop.stripe_card_ids if stripe_user_shop else None}"
)
# Query the coupon from the database
coupons = get_coupons_by_code(self.dbsession, self.coupon1_params["code"])
coupon = coupons[0]
# Step 4: Extract CSRF token for applying the coupon
csrf_token = self.get_csrf_token(shop.uuid_str)
if not csrf_token:
self.fail("CSRF token not found in session cookie (_csrft_)")
# Step 5: Apply coupon to user2's active cart
res_coupon_apply_redirect = self.testapp.post(
f"/coupon/apply?shop_id={shop_id}",
{
"coupon_id": coupon.id,
"shop_id": shop_id,
"csrf_token": csrf_token,
},
status=302,
)
res_coupon_apply = res_coupon_apply_redirect.follow()
res_body = res_coupon_apply.body.decode()
# Verify coupon was applied
self.assertIn("Slippery Halloween Party", res_body)
self.assertIn("3.50", res_body)
self.assertIn("camp31", res_body)
# Commit transaction to persist coupon application
transaction.manager.commit()
# Re-query users and shop
self.user1 = get_or_create_user_by_email(self.dbsession, self.user1_creds[0])
self.user2 = get_or_create_user_by_email(self.dbsession, self.user2_creds[0])
shop = get_shop_by_name(self.dbsession, self.shop1_params["name"])
# Step 6: Query the product from the database
all_products = get_all_products(self.dbsession)
product = all_products.one()
product_id = product.uuid_str
# Step 7: Extract CSRF token for adding product to cart
csrf_token = self.get_csrf_token(shop.uuid_str)
if not csrf_token:
self.fail("CSRF token not found in session cookie (_csrft_)")
# Step 8: Add product to user2's active cart
res_add_product_redirect = self.testapp.post(
f"/cart/add?shop_id={shop_id}",
{
"product_id": product_id,
"shop_id": shop_id,
"csrf_token": csrf_token,
},
status=302,
)
res_add_product = res_add_product_redirect.follow()
res_add_product = res_add_product.follow()
res_body = res_add_product.body.decode()
self.assertIn('You added "russell\'s product" to your cart.', res_body)
# Commit transaction to persist cart
transaction.manager.commit()
# Re-query users, shop, and cart
self.user1 = get_or_create_user_by_email(self.dbsession, self.user1_creds[0])
self.user2 = get_or_create_user_by_email(self.dbsession, self.user2_creds[0])
shop = get_shop_by_name(self.dbsession, self.shop1_params["name"])
user_2_cart = shop.get_active_cart_for_user(self.user2)
# Step 9: Get user2's active cart
self.assertIsNotNone(user_2_cart, "User2's active cart should not be None")
# Step 10: Attempt checkout with insufficient cart total
csrf_token = self.get_csrf_token(shop.uuid_str)
if not csrf_token:
self.fail("CSRF token not found in session cookie (_csrft_)")
res_checkout = self.testapp.post(
f"/u/cart/{user_2_cart.uuid_str}/checkout?shop_id={shop_id}",
{
"shop_id": shop_id,
"csrf_token": csrf_token,
},
status=302,
)
res_body = res_checkout.follow().body.decode()
print(f"First checkout response: {res_body}") # Debug
self.assertIn("Please review the terms for coupon", res_body)
self.assertIn("shop total not met.", res_body)
# Commit transaction to persist checkout attempt
transaction.manager.commit()
# Re-query users, shop, and cart
self.user1 = get_or_create_user_by_email(self.dbsession, self.user1_creds[0])
self.user2 = get_or_create_user_by_email(self.dbsession, self.user2_creds[0])
shop = get_shop_by_name(self.dbsession, self.shop1_params["name"])
user_2_cart = shop.get_active_cart_for_user(self.user2)
# Step 11: Add more products to meet coupon qualifier
for _ in range(2):
csrf_token = self.get_csrf_token(shop.uuid_str)
if not csrf_token:
self.fail("CSRF token not found in session cookie (_csrft_)")
res_add_product_redirect = self.testapp.post(
f"/cart/add?shop_id={shop_id}",
{
"product_id": product_id,
"shop_id": shop_id,
"csrf_token": csrf_token,
},
status=302,
)
res_add_product = res_add_product_redirect.follow()
res_add_product = res_add_product.follow()
print(f"Add product response: {res_add_product.body.decode()}") # Debug
transaction.manager.commit()
# Re-query users, shop, and cart
self.user1 = get_or_create_user_by_email(
self.dbsession, self.user1_creds[0]
)
self.user2 = get_or_create_user_by_email(
self.dbsession, self.user2_creds[0]
)
shop = get_shop_by_name(self.dbsession, self.shop1_params["name"])
user_2_cart = shop.get_active_cart_for_user(self.user2)
# Step 12: Attempt checkout again
csrf_token = self.get_csrf_token(shop.uuid_str)
if not csrf_token:
self.fail("CSRF token not found in session cookie (_csrft_)")
# Step 12: Configure Stripe keys through settings form
# Login as shop owner (user1) to access settings
self.testapp.post('/log-in', self.user1_creds_dict, status=302)
# Configure Stripe keys using proper settings form
stripe_settings_data = {
"stripe_public_api_key": environ["MPS_TEST_STRIPE_PUBLIC_API_KEY"],
"stripe_secret_api_key": environ["MPS_TEST_STRIPE_SECRET_API_KEY"],
"csrf_token": self.get_csrf_token(shop.uuid_str),
}
stripe_settings_res = self.testapp.post(f"/s/{shop.id}/settings", stripe_settings_data)
# Check if the database values actually changed despite no flash messages
self.dbsession.refresh(shop)
keys_actually_set = (shop.stripe_public_api_key == environ["MPS_TEST_STRIPE_PUBLIC_API_KEY"] and
shop.stripe_secret_api_key == environ["MPS_TEST_STRIPE_SECRET_API_KEY"])
self.assertTrue(keys_actually_set, "Stripe keys should be set in database")
self.assertTrue(shop.is_ready, "Shop should be ready for checkout after setting Stripe keys")
# Log back in as user2 (the purchaser)
self.testapp.get("/log-out")
self.testapp.post('/log-in', self.user2_creds_dict, status=302)
# Step 13: Complete checkout now that shop is ready
csrf_token = self.get_csrf_token(shop.uuid_str)
if not csrf_token:
self.fail("CSRF token not found in session cookie (_csrft_)")
print(f"Shop before checkout: UUID: {shop.uuid_str}, Ready: {shop.is_ready}")
res_checkout_final = self.testapp.post(
f"/u/cart/{user_2_cart.uuid_str}/checkout?shop_id={shop_id}",
{
"shop_id": shop_id,
"csrf_token": csrf_token,
},
status=302, # Should redirect to complete checkout since it's a free cart
)
# Follow the redirect to the invoice page
invoice_res = res_checkout_final.follow()
invoice_body = invoice_res.body.decode()
print(f"Invoice page response: {invoice_body}") # Debug
# Step 14: Verify invoice displays coupon information
self.assertIn("TESTOFF100", invoice_body, "Invoice should show coupon code")
self.assertIn("100% off test coupon", invoice_body, "Invoice should show coupon description")
self.assertIn("Total Breakdown", invoice_body, "Invoice should show pricing breakdown")
self.assertIn("Discounts Applied", invoice_body, "Invoice should show discounts section")