Skip to content

Commit c56bbfb

Browse files
Merge pull request #695 from rgopalrao-sonata-png/rgopalrao/ENT-10867
fix: Fix is added to remove the unlinked users from LPR
2 parents 2e0cb1a + 46a483a commit c56bbfb

5 files changed

Lines changed: 70 additions & 5 deletions

File tree

CHANGELOG.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ Change Log
1313
1414
Unreleased
1515
----------
16+
[10.22.10] - 2026-07-16
17+
-----------------------
18+
* fix: Remove unlinked users from Learner Progress Report
19+
1620
[10.22.9] - 2026-06-17
1721
-----------------------
1822
* feat: Remove deprecated analytics filter

enterprise_data/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
Enterprise data api application. This Django app exposes API endpoints used by enterprises.
33
"""
44

5-
__version__ = "10.22.9"
5+
__version__ = "10.22.10"

enterprise_data/api/v1/views/enterprise_learner.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ def get_queryset(self):
101101
# always includes `course_progress` and `course_passing_grade`; real
102102
# values are merged in later from Snowflake during enrichment.
103103
enrollments = EnterpriseLearnerEnrollment.objects.filter(
104-
enterprise_customer_uuid=enterprise_customer_uuid
104+
enterprise_customer_uuid=enterprise_customer_uuid,
105+
enterprise_user__is_linked=True,
105106
).extra(select={
106107
'course_progress': 'NULL',
107108
'course_passing_grade': 'NULL',
@@ -396,7 +397,10 @@ def filter_number_of_users(self):
396397
"""
397398
Returns number of enterprise users (enrolled AND not enrolled learners)
398399
"""
399-
return EnterpriseLearner.objects.filter(enterprise_customer_uuid=self.kwargs['enterprise_id'])
400+
return EnterpriseLearner.objects.filter(
401+
enterprise_customer_uuid=self.kwargs['enterprise_id'],
402+
is_linked=True,
403+
)
400404

401405
def get_max_created_date(self, queryset):
402406
"""

enterprise_data/tests/api/v1/test_views.py

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,60 @@ def test_list_enriches_course_progress_from_snowflake(self, mock_source_cls):
237237
self.assertEqual(response.data['results'][0]['enrollment_id'], enrollment.enrollment_id)
238238
self.assertEqual(response.data['results'][0]['course_progress'], 0.87)
239239

240+
def test_list_excludes_enrollments_of_unlinked_learners(self):
241+
"""
242+
Test that the enrollment list endpoint excludes enrollments belonging to unlinked learners.
243+
"""
244+
linked_learner = EnterpriseLearnerFactory(
245+
enterprise_customer_uuid=self.enterprise_id,
246+
is_linked=True,
247+
)
248+
unlinked_learner = EnterpriseLearnerFactory(
249+
enterprise_customer_uuid=self.enterprise_id,
250+
is_linked=False,
251+
)
252+
linked_enrollment = EnterpriseLearnerEnrollmentFactory(
253+
enterprise_customer_uuid=self.enterprise_id,
254+
is_consent_granted=True,
255+
enterprise_user_id=linked_learner.enterprise_user_id,
256+
)
257+
EnterpriseLearnerEnrollmentFactory(
258+
enterprise_customer_uuid=self.enterprise_id,
259+
is_consent_granted=True,
260+
enterprise_user_id=unlinked_learner.enterprise_user_id,
261+
)
262+
263+
url = reverse('v1:enterprise-learner-enrollment-list', kwargs={'enterprise_id': self.enterprise_id})
264+
response = self.client.get(url)
265+
266+
self.assertEqual(response.status_code, status.HTTP_200_OK)
267+
results = response.json()['results']
268+
self.assertEqual(len(results), 1)
269+
self.assertEqual(results[0]['enrollment_id'], linked_enrollment.enrollment_id)
270+
271+
def test_overview_number_of_users_excludes_unlinked_learners(self):
272+
"""
273+
Test that `number_of_users` in the overview response only counts learners with `is_linked=True`.
274+
"""
275+
EnterpriseLearnerFactory(
276+
enterprise_customer_uuid=self.enterprise_id,
277+
is_linked=True,
278+
)
279+
EnterpriseLearnerFactory(
280+
enterprise_customer_uuid=self.enterprise_id,
281+
is_linked=True,
282+
)
283+
EnterpriseLearnerFactory(
284+
enterprise_customer_uuid=self.enterprise_id,
285+
is_linked=False,
286+
)
287+
288+
url = reverse('v1:enterprise-learner-enrollment-overview', kwargs={'enterprise_id': self.enterprise_id})
289+
response = self.client.get(url)
290+
291+
self.assertEqual(response.status_code, status.HTTP_200_OK)
292+
self.assertEqual(response.json()['number_of_users'], 2)
293+
240294
@mock.patch('enterprise_data.api.v1.views.enterprise_learner.SnowflakeCourseProgressSource')
241295
def test_list_returns_200_when_snowflake_enrichment_fails(self, mock_source_cls):
242296
enterprise_learner = EnterpriseLearnerFactory(
@@ -334,7 +388,10 @@ def test_get_queryset_adds_placeholder_metadata_columns(self, mock_apply_filters
334388

335389
result = viewset.get_queryset()
336390

337-
mock_filter.assert_called_once_with(enterprise_customer_uuid=self.enterprise_id)
391+
mock_filter.assert_called_once_with(
392+
enterprise_customer_uuid=self.enterprise_id,
393+
enterprise_user__is_linked=True,
394+
)
338395
enrollments.extra.assert_called_once_with(select={
339396
'course_progress': 'NULL',
340397
'course_passing_grade': 'NULL',

enterprise_data/tests/test_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ class Meta:
135135
lms_user_id = factory.lazy_attribute(
136136
lambda x: FAKER.random_int(min=1, max=999999) # pylint: disable=no-member
137137
)
138-
is_linked = FAKER.pybool()
138+
is_linked = True
139139
user_username = factory.Sequence('robot{}'.format)
140140
user_email = factory.lazy_attribute(lambda x: FAKER.email()) # pylint: disable=no-member
141141
lms_user_created = FAKER.past_datetime(start_date='-60d')

0 commit comments

Comments
 (0)