Skip to content

Commit 5204f22

Browse files
authored
Shanbady/fix subscription groups (#2664)
* making sure query is picked from something user is a member of * adding initial solution * adding some variance in grouping * test definition * docstring updates * docstring updates
1 parent 56eac9b commit 5204f22

File tree

2 files changed

+147
-13
lines changed

2 files changed

+147
-13
lines changed

learning_resources_search/tasks.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -221,15 +221,20 @@ def _get_percolated_rows(resources, subscription_type):
221221
if percolated.count() > 0:
222222
percolated_users = set(percolated.values_list("users", flat=True))
223223
all_users.update(percolated_users)
224-
query = percolated.first()
225-
search_url = _infer_percolate_group_url(query)
226-
req = PreparedRequest()
227-
req.prepare_url(search_url, {"resource": resource.id})
228-
resource_url = req.url
229-
source_channel = query.source_channel()
230-
231-
rows.extend(
232-
[
224+
for user in percolated_users:
225+
if not user:
226+
continue
227+
user_instance = User.objects.get(id=user)
228+
user_queries = user_instance.percolate_queries.values_list(
229+
"id", flat=True
230+
)
231+
query = percolated.filter(id__in=user_queries).order_by("?").first()
232+
search_url = _infer_percolate_group_url(query)
233+
req = PreparedRequest()
234+
req.prepare_url(search_url, {"resource": resource.id})
235+
resource_url = req.url
236+
source_channel = query.source_channel()
237+
rows.append(
233238
{
234239
"resource_url": resource_url,
235240
"resource_title": resource.title,
@@ -247,10 +252,7 @@ def _get_percolated_rows(resources, subscription_type):
247252
"group": _infer_percolate_group(query),
248253
"search_url": search_url,
249254
}
250-
for user in percolated_users
251-
]
252-
)
253-
255+
)
254256
return rows
255257

256258

learning_resources_search/tasks_test.py

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
LearningResourceDepartmentFactory,
1717
LearningResourceFactory,
1818
LearningResourceOfferorFactory,
19+
LearningResourceTopicFactory,
1920
ProgramFactory,
2021
)
2122
from learning_resources.models import LearningResource
@@ -855,6 +856,137 @@ def test_infer_percolate_group(mocked_api):
855856
assert _infer_percolate_group(offerer_query) == offerer.name
856857

857858

859+
def test_percolate_user_grouping(mocked_api, mocker):
860+
"""
861+
Test that each user receives an email with resources
862+
they are supposed to recieve (based off of subscription)
863+
"""
864+
topic_name = "Mechanical Engineering"
865+
topic = LearningResourceTopicFactory.create(name=topic_name)
866+
alternate_topic = LearningResourceTopicFactory.create(
867+
name=f"{topic_name}_alternate"
868+
)
869+
offerer = LearningResourceOfferorFactory.create()
870+
department = LearningResourceDepartmentFactory.create()
871+
alternate_department = LearningResourceDepartmentFactory.create()
872+
873+
resource_a = LearningResourceFactory.create(
874+
title="resource A",
875+
topics=[topic, alternate_topic],
876+
is_course=True,
877+
offered_by=offerer,
878+
departments=[department],
879+
)
880+
881+
resource_b = LearningResourceFactory.create(
882+
title="resource B",
883+
topics=[alternate_topic],
884+
is_course=True,
885+
)
886+
resource_c = LearningResourceFactory.create(
887+
title="resource C",
888+
departments=[alternate_department],
889+
is_course=True,
890+
topics=[],
891+
)
892+
893+
user_a, user_b, user_c, user_d = UserFactory.create_batch(4)
894+
895+
topic_query = PercolateQueryFactory.create()
896+
topic_query.original_query["topic"] = [topic_name]
897+
898+
alternate_topic_query = PercolateQueryFactory.create()
899+
alternate_topic_query.original_query["topic"] = [f"{topic_name}_alternate"]
900+
901+
department_query = PercolateQueryFactory.create()
902+
department_query.original_query["department"] = [department.department_id]
903+
904+
alternate_department_query = PercolateQueryFactory.create()
905+
alternate_department_query.original_query["department"] = [
906+
alternate_department.department_id
907+
]
908+
909+
offerer_query = PercolateQueryFactory.create()
910+
offerer_query.source_type = PercolateQuery.CHANNEL_SUBSCRIPTION_TYPE
911+
offerer_query.original_query["offered_by"] = [offerer.code]
912+
913+
# user_a should have 1 percolated doc
914+
topic_query.users.add(user_a)
915+
916+
# user_b should have 3 percolated docs
917+
topic_query.users.add(user_b)
918+
alternate_topic_query.users.add(user_b)
919+
alternate_department_query.users.add(user_b)
920+
921+
# user_c should have 2 percolated doc
922+
department_query.users.add(user_c)
923+
alternate_department_query.users.add(user_c)
924+
925+
# user_d should have 1 percolated doc
926+
offerer_query.users.add(user_d)
927+
928+
# save all the queries
929+
for query in [
930+
department_query,
931+
alternate_topic_query,
932+
offerer_query,
933+
topic_query,
934+
alternate_department_query,
935+
]:
936+
query.source_type = PercolateQuery.CHANNEL_SUBSCRIPTION_TYPE
937+
query.save()
938+
939+
percolate_matches_for_document_mock = mocker.patch(
940+
"learning_resources_search.tasks.percolate_matches_for_document",
941+
)
942+
943+
def _matches_for_document(resource_id):
944+
"""
945+
Mock percolation
946+
"""
947+
if resource_id == resource_a.id:
948+
return PercolateQuery.objects.filter(
949+
id__in=[
950+
topic_query.id,
951+
alternate_topic_query.id,
952+
department_query.id,
953+
offerer_query.id,
954+
]
955+
)
956+
elif resource_id == resource_b.id:
957+
return PercolateQuery.objects.filter(
958+
id__in=[
959+
alternate_topic_query.id,
960+
]
961+
)
962+
elif resource_id == resource_c.id:
963+
return PercolateQuery.objects.filter(
964+
id__in=[
965+
alternate_department_query.id,
966+
]
967+
)
968+
else:
969+
return PercolateQuery.objects.none()
970+
971+
percolate_matches_for_document_mock.side_effect = _matches_for_document
972+
973+
rows = _get_percolated_rows(
974+
[resource_a, resource_b, resource_c], "channel_subscription_type"
975+
)
976+
grouped_by_user = _group_percolated_rows(rows)
977+
resources_by_user = {}
978+
# get the total number of resources for each user
979+
for user in [user_a, user_b, user_c, user_d]:
980+
resources_by_user[user.id] = sum(
981+
[len(items) for items in grouped_by_user[user.id].values()]
982+
)
983+
984+
assert resources_by_user[user_a.id] == 1
985+
assert resources_by_user[user_b.id] == 3
986+
assert resources_by_user[user_c.id] == 2
987+
assert resources_by_user[user_d.id] == 1
988+
989+
858990
def test_email_grouping_function(mocked_api, mocker):
859991
"""
860992
Test that template data for digest emails are grouped correctly

0 commit comments

Comments
 (0)