Skip to content

add a "tie breaker" if all enrollments have no certificate or grade#3599

Open
gumaerc wants to merge 3 commits into
mainfrom
cg/fix-current-run-selection
Open

add a "tie breaker" if all enrollments have no certificate or grade#3599
gumaerc wants to merge 3 commits into
mainfrom
cg/fix-current-run-selection

Conversation

@gumaerc

@gumaerc gumaerc commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

What are the relevant tickets?

Closes https://github.com/mitodl/hq/issues/12243

Description (What does it do?)

This PR fixes the above bug by adding another phase of tie breaking to pickDisplayedEnrollmentForLegacyDashboard. If all enrollments have no grades or certificates, previously the first enrollment in database order would be selected. Instead of database order, we now try the following:

  • Any enrollment who's run matches next_run_id of the course
  • The latest enrollment by start_date

Screenshots (if appropriate):

image image image

How can this be tested?

  • Ensure you have an instance of MITx Online up and running and connected to Learn as described in the readme
  • Run this script in a Django shell to create the appropriate test data on the admin@odl.local test user:
    from django.contrib.auth import get_user_model                                                                                                                                                                                                                       
    from django.core.management import call_command                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                         
    from courses.api import create_program_enrollments, create_run_enrollments                                                                                                                                                                                           
    from courses.models import Course, CourseRun, Program                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                         
    User = get_user_model()                                                                                                                                                                                                                                              
    user = User.objects.get(email="admin@odl.local")  # swap for your test user                                                                                                                                                                                          
                                                                                                                                                                                                                                                                         
    COURSE_ID = "course-v1:QADEMO+MULTIRUN"                                                                                                                                                                                                                              
    PROGRAM_ID = "program-v1:QADEMO+MULTIRUNPROG"                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                         
    # --- Course with a past run ---                                                                                                                                                                                                                                     
    call_command(                                                                                                                                                                                                                                                        
        "create_courseware", "course", COURSE_ID, "QA Demo - Multi-Run Enrollment Course",                                                                                                                                                                               
        live=True, create_run="R1_OLD",                                                                                                                                                                                                                                  
        start="2025-04-01", end="2025-07-01",                                                                                                                                                                                                                            
        enrollment_start="2025-03-15", enrollment_end="2025-06-15",                                                                                                                                                                                                      
        depts=["QA Demo"], create_depts=True,                                                                                                                                                                                                                            
        create_page=True, create_certificate_page=True, create_signatory=True,                                                                                                                                                                                           
        mode_audit=True, mode_verified=True, primary_lang=True,                                                                                                                                                                                                          
    )                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                         
    # --- Add a currently in-progress run ---                                                                                                                                                                                                                            
    call_command(                                                                                                                                                                                                                                                        
        "create_courseware", "courserun", COURSE_ID, "QA Demo - Multi-Run Enrollment Course",                                                                                                                                                                            
        live=True, create_run="R2_CURRENT",                                                                                                                                                                                                                              
        start="2026-06-01", end="2026-09-01",                                                                                                                                                                                                                            
        enrollment_start="2026-05-15", enrollment_end="2026-08-15",                                                                                                                                                                                                      
        mode_audit=True, mode_verified=True,                                                                                                                                                                                                                             
    )                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                         
    # --- Add an upcoming run ---                                                                                                                                                                                                                                        
    call_command(                                                                                                                                                                                                                                                        
        "create_courseware", "courserun", COURSE_ID, "QA Demo - Multi-Run Enrollment Course",                                                                                                                                                                            
        live=True, create_run="R3_FUTURE",                                                                                                                                                                                                                               
        start="2026-09-15", end="2026-12-15",                                                                                                                                                                                                                            
        enrollment_start="2026-08-01", enrollment_end="2026-09-10",                                                                                                                                                                                                      
        mode_audit=True, mode_verified=True,                                                                                                                                                                                                                             
    )                                                                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                                         
    # --- Enroll the user in all 3 runs, oldest first (no grades/certificates) ---                                                                                                                                                                                       
    course = Course.objects.get(readable_id=COURSE_ID)                                                                                                                                                                                                                   
    runs = list(CourseRun.objects.filter(course=course).order_by("id"))                                                                                                                                                                                                  
    create_run_enrollments(user, runs, mode="audit", keep_failed_enrollments=True)                                                                                                                                                                                       
                                                                                                                                                                                                                                                                         
    # --- Wrap the course in its own program so it renders on a program dashboard ---                                                                                                                                                                                    
    call_command(                                                                                                                                                                                                                                                        
        "create_courseware", "program", PROGRAM_ID, "QA Demo - Multi-Run Bug Repro Program",                                                                                                                                                                             
        live=True, depts=["QA Demo"], create_depts=True,                                                                                                                                                                                                                 
        create_page=True, create_certificate_page=True, create_signatory=True,                                                                                                                                                                                           
    )                                                                                                                                                                                                                                                                    
    program = Program.objects.get(readable_id=PROGRAM_ID)                                                                                                                                                                                                                
    program.add_requirement(course)                                                                                                                                                                                                                                      
    create_program_enrollments(user, [program], enrollment_mode="verified")                                                                                                                                                                                              
                                                                                                                                                                                                                                                                         
    print("Program:", program.pk, program.readable_id)                                                                                                                                                                                                                   
  • Browse to the program it created and view the course card, expanding the course runs accordion
  • Verify that the "current run" is the actual current run

Copilot AI review requested due to automatic review settings July 9, 2026 21:37
@gumaerc gumaerc added the Needs Review An open Pull Request that is ready for review label Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

OpenAPI Changes

No changes detected

View full changelog

Unexpected changes? Ensure your branch is up-to-date with main (consider rebasing).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the dashboard’s legacy “displayed enrollment” selection logic to avoid falling back to arbitrary (database-order) enrollments when certificates and grades don’t distinguish between multiple enrollments for the same course. It adds deterministic tie-breaking consistent with the existing getBestRun policy.

Changes:

  • Extend pickDisplayedEnrollmentForLegacyDashboard tie-breaking to prefer an enrollment whose run matches course.next_run_id.
  • Add a further tie-breaker to prefer the enrollment with the later run.start_date, sorting missing/invalid dates last.
  • Add unit tests covering both new tie-break scenarios and ensuring selection is order-independent.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
frontends/main/src/app-pages/DashboardPage/CoursewareDisplay/model/dashboardViewModel.ts Adds deterministic tie-breakers (next_run_id, then start_date recency) when cert/grade are tied.
frontends/main/src/app-pages/DashboardPage/CoursewareDisplay/model/dashboardViewModel.test.ts Adds tests verifying the new tie-break behavior and independence from input ordering.

@gumaerc gumaerc force-pushed the cg/fix-current-run-selection branch from aa1ac0b to b732506 Compare July 10, 2026 14:25
@zamanafzal zamanafzal self-assigned this Jul 13, 2026

@zamanafzal zamanafzal left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I've tested the changes locally and they look good.

Image

@zamanafzal zamanafzal added Waiting on author and removed Needs Review An open Pull Request that is ready for review labels Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants