Skip to content

fix(spp_programs): handle state=None in enroll eligible async dispatch#173

Merged
gonzalesedwin1123 merged 2 commits into19.0from
fix/enroll-eligible-async-none-state
Apr 27, 2026
Merged

fix(spp_programs): handle state=None in enroll eligible async dispatch#173
gonzalesedwin1123 merged 2 commits into19.0from
fix/enroll-eligible-async-none-state

Conversation

@gonzalesedwin1123
Copy link
Copy Markdown
Member

Summary

  • The Enroll Eligible button (programs.py:399) calls enroll_eligible_registrants() with no argument, so state defaults to None. When the program has >= MIN_ROW_JOB_QUEUE (200) beneficiaries, dispatch goes through _enroll_eligible_registrants_async, which called tuple(states) on None and raised TypeError: 'NoneType' object is not iterable.
  • The synchronous path tolerated None because program.get_beneficiaries(state=None, ...) already treats it as "all states" — only the async path crashed, which is why this only reproduced on programs with many registrants.
  • Fix: mirror get_beneficiaries semantics — when states is None/empty, build the SQL where-clause without the state IN %s filter and pass only (program.id,) to compute_id_ranges.

Traceback (before fix)

File ".../spp_programs/models/managers/program_manager.py", line 195, in _enroll_eligible_registrants_async
    (program.id, tuple(states)),
                 ~~~~~^^^^^^^^
TypeError: 'NoneType' object is not iterable

Test plan

  • New regression test test_enroll_eligible_async_handles_none_state fails before the fix and passes after — verifies no TypeError, and that compute_id_ranges is called with a where-clause that omits state IN and params equal to (program.id,).
  • Full spp_programs test suite passes: 637/637.
  • Existing test_enroll_eligible_async_handles_string_state and test_enroll_eligible_async_uses_compute_id_ranges still pass (states-as-string and states-as-list paths unaffected).
  • pre-commit clean on changed files.

The "Enroll Eligible" button calls enroll_eligible_registrants() with no
argument, so state defaults to None. When the program has at least
MIN_ROW_JOB_QUEUE (200) beneficiaries, the async path runs and called
tuple(states) on None, raising TypeError.

Mirror get_beneficiaries semantics: when states is None/empty, omit the
"state IN %s" filter from the SQL where-clause so all states are
considered. Add a regression test that covers state=None.
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 71.48%. Comparing base (2e377b6) to head (adcaa4a).
⚠️ Report is 5 commits behind head on 19.0.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             19.0     #173   +/-   ##
=======================================
  Coverage   71.47%   71.48%           
=======================================
  Files         932      932           
  Lines       54835    54840    +5     
=======================================
+ Hits        39196    39201    +5     
  Misses      15639    15639           
Flag Coverage Δ
spp_api_v2 80.10% <ø> (ø)
spp_api_v2_change_request 66.85% <ø> (ø)
spp_api_v2_cycles 71.12% <ø> (ø)
spp_api_v2_data 64.41% <ø> (ø)
spp_api_v2_entitlements 70.19% <ø> (ø)
spp_api_v2_gis 71.52% <ø> (ø)
spp_api_v2_products 66.27% <ø> (ø)
spp_api_v2_service_points 70.94% <ø> (ø)
spp_api_v2_simulation 71.12% <ø> (ø)
spp_api_v2_vocabulary 57.26% <ø> (ø)
spp_audit 72.60% <ø> (ø)
spp_base_common 90.26% <ø> (ø)
spp_case_entitlements 97.61% <ø> (ø)
spp_case_programs 97.14% <ø> (ø)
spp_cel_event 85.11% <ø> (ø)
spp_claim_169 58.11% <ø> (ø)
spp_dci_client_dr 55.87% <ø> (ø)
spp_dci_client_ibr 60.17% <ø> (ø)
spp_programs 64.51% <100.00%> (+0.02%) ⬆️
spp_security 66.66% <ø> (ø)

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

Files with missing lines Coverage Δ
spp_programs/__manifest__.py 0.00% <ø> (ø)
spp_programs/models/managers/program_manager.py 93.02% <100.00%> (+0.28%) ⬆️

... and 1 file with indirect coverage changes

🚀 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.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request updates the _enroll_eligible_registrants_async method to handle cases where the states parameter is None or empty. It dynamically adjusts the SQL where_clause and parameters to avoid a TypeError when attempting to convert None to a tuple. A new test case has been added to verify that the method correctly omits the state filter when no states are provided. I have no feedback to provide.

@gonzalesedwin1123 gonzalesedwin1123 merged commit 98a45a9 into 19.0 Apr 27, 2026
35 checks passed
@gonzalesedwin1123 gonzalesedwin1123 deleted the fix/enroll-eligible-async-none-state branch April 27, 2026 09:34
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.

1 participant