From 698b44e9e60ca2028b25d27c7313685edb8905c3 Mon Sep 17 00:00:00 2001 From: Russell Ballestrini Date: Sun, 27 Jul 2025 20:33:00 -0400 Subject: [PATCH] Expand groupr regression test to verify invoice coupon display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extended the free coupon checkout test to also verify that: - Checkout completion creates an invoice with coupon redemptions - Invoice page displays discount breakdown with coupon information - Coupon codes and descriptions appear on invoice - Discount amounts are calculated correctly This ensures the invoice discount display enhancement works end-to-end. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- make_post_sell/tests/test_functional.py | 66 +++++++++++++++++++------ 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/make_post_sell/tests/test_functional.py b/make_post_sell/tests/test_functional.py index ac21c8f..6429f2a 100644 --- a/make_post_sell/tests/test_functional.py +++ b/make_post_sell/tests/test_functional.py @@ -713,25 +713,63 @@ class AuthenticatedFunctionalTests(FunctionalTests): # 6. SUCCESS! We reached the checkout page without AttributeError crash # This validates that the original bug (stripe_user_shop.active_card AttributeError) is fixed - # The bug occurred when stripe_user_shop was None for free carts, causing: - # AttributeError: 'NoneType' object has no attribute 'active_card' - # - # By reaching this point, we've proven the code properly handles stripe_user_shop=None - - # NOTE: We intentionally stop here rather than completing the full checkout because: - # 1. The core AttributeError bug fix has been validated - # 2. Complete checkout has transaction management issues in the test environment - # 3. groupr's actual error was hitting the checkout page, not completing the transaction print("✓ REGRESSION TEST PASSED: Free coupon checkout reaches confirmation without AttributeError") print("✓ Core bug fix validated: stripe_user_shop=None properly handled in cart.py:712") - # 7. Complete the download flow after free coupon checkout - # Simulate successful purchase by creating user-product relationship + # 7. Complete the actual checkout to create a real invoice + # Now that transaction management is fixed, we can safely complete checkout + complete_checkout_res = self.testapp.post( + f"/u/cart/{user_cart.id}/complete/checkout", + { + "csrf_token": self.get_csrf_token(shop.uuid_str), + }, + ) + + # Should redirect after successful completion + self.assertEqual(complete_checkout_res.status_int, 302) + print(f"✓ CHECKOUT COMPLETED: Redirected to {complete_checkout_res.location}") + + # Transaction should have committed successfully + + # 8. Find and verify the invoice shows coupon information + # Get the created invoice from the database + from ..models.invoice import Invoice + invoice = self.dbsession.query(Invoice).first() + self.assertIsNotNone(invoice, "Invoice should be created after checkout completion") + + # Verify invoice has the coupon redemption + coupon_redemptions = list(invoice.coupon_redemptions) + self.assertEqual(len(coupon_redemptions), 1, "Invoice should have one coupon redemption") + self.assertEqual(coupon_redemptions[0].coupon.code, self.coupon2_params["code"]) + + # 9. Test the invoice page displays coupon information + invoice_res = self.testapp.get(f"/i/{invoice.id}") + self.assertEqual(invoice_res.status_int, 200) + invoice_body = invoice_res.body.decode() + + # Verify coupon information appears on invoice + self.assertIn("Discounts Applied", invoice_body) + self.assertIn(self.coupon2_params["code"], invoice_body) # Coupon code + self.assertIn(self.coupon2_params["description"], invoice_body) # Coupon description + self.assertIn("Total Discounts:", invoice_body) # Discount section + self.assertIn("Subtotal:", invoice_body) # Subtotal before discount + + # Verify the discount amount calculation + self.assertGreater(invoice.discount_amount_in_cents, 0, "Should have discount applied") + self.assertEqual(invoice.total_in_cents, 0, "Total should be $0 after $6 discount on $6 product") + + print("✓ INVOICE VERIFICATION: Coupon information correctly displayed on invoice page") + print(f"✓ Coupon applied: {self.coupon2_params['code']} - {self.coupon2_params['description']}") + print(f"✓ Discount amount: ${invoice.discount_amount_in_cents / 100:.2f}") + + # Create the user-product relationship for download testing from ..models.user_product import UserProduct - user_product = UserProduct(user=self.user2, product=product) - self.dbsession.add(user_product) - self.dbsession.flush() + # Check if relationship already exists from checkout completion + if not self.user2.can_download_product(product): + user_product = UserProduct(user=self.user2, product=product) + self.dbsession.add(user_product) + self.dbsession.flush() # Verify user can now download the product self.assertTrue(self.user2.can_download_product(product))