Skip to content

feat: add CalculateEnterpriseDiscountedPrice pipeline step for course mode checkout - #2556

Merged
kiram15 merged 1 commit into
masterfrom
pwnage101/ENT-11573
Jul 16, 2026
Merged

feat: add CalculateEnterpriseDiscountedPrice pipeline step for course mode checkout#2556
kiram15 merged 1 commit into
masterfrom
pwnage101/ENT-11573

Conversation

@pwnage101

@pwnage101 pwnage101 commented Mar 5, 2026

Copy link
Copy Markdown
Contributor

https://2u-internal.atlassian.net/browse/ENT-11573

openedx-filters #338 — CourseModePriceRequested filter definition
edx-enterprise #2556 — CalculateEnterpriseDiscountedPrice pipeline step
edx-platform #365 — view wired to invoke the filter

Prerequisites: local devstack running with all three branches installed (Runbook); an enterprise customer, an enterprise learner, and a course with a verified mode that has a non-empty SKU and a future expiration date.

E2E Testing Instructions:

Note: replace any enterprise customer uuids, users, or course keys with your own applicable local data.

In lms/envs/devstack.py, confirm/add, then restart after to capture changes:

AUTOMATIC_AUTH_FOR_TESTING = True
RESTRICT_AUTOMATIC_AUTH = False

Test 1: Check if pipeline correctly hooked up, and then check against control user with no enterprise link
Write the test file in lms-shell

cat > /tmp/test1.py << 'EOF'
from django.test import Client

client = Client()
response = client.get(
    '/auto_auth',
    {'username': 'e2e_control_user', 'password': 'testpass123'},
    follow=True,
)
print("auto_auth status:", response.status_code)

course_id = "course-v1:edX+DemoX+Demo_Course"
response = client.get(f"/course_modes/choose/{course_id}/", follow=True)
print("choose status:", response.status_code)
content = response.content.decode()
print("contains '149':", "149" in content)
EOF

Then execute the file in the bash script exec(open('/tmp/test1.py').read())

Expected: choose status: 200, contains '149': True.

Test 2: Check against enterprise-linked user with SKU present on course

cat > /tmp/test2.py << 'EOF'
from django.test import Client

client = Client()
client.get('/auto_auth', {'username': 'e2e_enterprise_user', 'password': 'testpass123'}, follow=True)

enterprise_uuid = "8400978a-7eb5-43a8-8a02-aa6063e842e2"
course_id = "course-v1:edX+DemoX+Demo_Course"

# The 'new_enterprise_login=yes' param bypasses RouterView's force_fresh_session
# check, which otherwise logs out any session not flagged as freshly SSO'd
r1 = client.get(
    f"/enterprise/{enterprise_uuid}/course/{course_id}/enroll/",
    {"new_enterprise_login": "yes"},
    follow=True,
)
print("landing hit status:", r1.status_code)

r2 = client.get(f"/course_modes/choose/{course_id}/", follow=True)
print("choose status:", r2.status_code)
content = r2.content.decode()
print("contains '149':", "149" in content)
EOF

Expected: no /logout in the log, choose status: 200, log line [e-commerce calculate endpoint] The discounted price for sku [8CF08E5]... is [149.0] confirming the ecommerce call happened and returned the (undiscounted) price.

Test 3: Check against enterprise-linked user, verified mode with no SKU

Create a no-SKU verified mode on a second course — inside make lms-shell, at >>>:

from common.djangoapps.course_modes.models import CourseMode

CourseMode.objects.create(
    course_id="course-v1:edX+E202+3T2025",
    mode_slug="verified",
    mode_display_name="Verified Certificate",
    min_price=100,
    currency="usd",
    sku="",
)
cat > /tmp/test3.py << 'EOF'
from django.test import Client

client = Client()
client.get('/auto_auth', {'username': 'e2e_enterprise_user', 'password': 'testpass123'}, follow=True)

enterprise_uuid = "8400978a-7eb5-43a8-8a02-aa6063e842e2"
course_id = "course-v1:edX+E202+3T2025"

# This course isn't seeded in the discovery service, so the landing page 500s
# on a pre-existing edx-enterprise bug (discovery.py:251) — but the enterprise
# customer is written to session before that crash, so we catch it and proceed
try:
    r1 = client.get(
        f"/enterprise/{enterprise_uuid}/course/{course_id}/enroll/",
        {"new_enterprise_login": "yes"},
        follow=True,
    )
    print("landing hit status:", r1.status_code)
except Exception as e:
    print("landing hit raised (expected, discovery API 404):", type(e).__name__)

r2 = client.get(f"/course_modes/choose/{course_id}/", follow=True)
print("choose status:", r2.status_code)
content = r2.content.decode()
print("contains '100':", "100" in content)
EOF

Expected: choose status: 200, contains '100': True, and — the key check — no [e-commerce calculate endpoint] log line, confirming the SKU guard blocked the ecommerce call entirely.

@codecov

codecov Bot commented Jun 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.72%. Comparing base (2f9c450) to head (d234402).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2556      +/-   ##
==========================================
+ Coverage   86.70%   86.72%   +0.01%     
==========================================
  Files         259      260       +1     
  Lines       17017    17041      +24     
  Branches     1681     1683       +2     
==========================================
+ Hits        14754    14778      +24     
  Misses       1927     1927              
  Partials      336      336              
Flag Coverage Δ
unittests 86.72% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@kiram15
kiram15 force-pushed the pwnage101/ENT-11573 branch 4 times, most recently from 82cfc44 to 6aede7d Compare June 26, 2026 23:31
@kiram15
kiram15 marked this pull request as ready for review June 29, 2026 20:31

@pwnage101 pwnage101 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kiram15
kiram15 force-pushed the pwnage101/ENT-11573 branch 3 times, most recently from e7d3244 to b33c2df Compare July 8, 2026 06:15
@kiram15 kiram15 changed the title feat: add CheckoutEnterpriseContextInjector pipeline step for course mode checkout feat: add CalculateEnterpriseDiscountedPrice pipeline step for course mode checkout Jul 8, 2026
Comment thread enterprise/filters/course_modes.py Outdated
Comment thread enterprise/filters/course_modes.py
Comment thread CHANGELOG.rst
@kiram15
kiram15 force-pushed the pwnage101/ENT-11573 branch from 4c59c7a to 9f16204 Compare July 14, 2026 20:11
Comment thread enterprise/filters/course_modes.py Outdated
Comment thread enterprise/filters/course_modes.py Outdated
Comment thread enterprise/filters/course_modes.py Outdated
Comment thread enterprise/filters/course_modes.py Outdated
Comment thread enterprise/filters/course_modes.py Outdated
Comment thread tests/filters/test_course_modes.py Outdated
Comment thread tests/filters/test_course_modes.py Outdated
Comment thread tests/filters/test_course_modes.py
@kiram15
kiram15 force-pushed the pwnage101/ENT-11573 branch 3 times, most recently from 2707576 to a34f7ab Compare July 15, 2026 22:16

@pwnage101 pwnage101 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM!

@kiram15
kiram15 force-pushed the pwnage101/ENT-11573 branch 2 times, most recently from 401d2fc to 726bcd1 Compare July 15, 2026 23:20
@kiram15
kiram15 force-pushed the pwnage101/ENT-11573 branch from 726bcd1 to d234402 Compare July 16, 2026 15:27
@kiram15
kiram15 merged commit f67c5ba into master Jul 16, 2026
11 checks passed
@kiram15
kiram15 deleted the pwnage101/ENT-11573 branch July 16, 2026 15:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants