def setUpTestData(cls): super().setUpTestData() cls.program_enrollment_unsent = ProgramEnrollmentFactory.create() cls.program_enrollment_sent = ProgramEnrollmentFactory.create() cls.automatic_email = AutomaticEmailFactory.create(enabled=True) cls.percolate_query = cls.automatic_email.query cls.other_query = PercolateQueryFactory.create( source_type=PercolateQuery.DISCUSSION_CHANNEL_TYPE) cls.percolate_queries = [cls.percolate_query, cls.other_query] cls.automatic_email_disabled = AutomaticEmailFactory.create( enabled=False) cls.percolate_query_disabled = cls.automatic_email_disabled.query SentAutomaticEmail.objects.create( automatic_email=cls.automatic_email, user=cls.program_enrollment_sent.user, status=SentAutomaticEmail.SENT, ) # User was sent email connected to a different AutomaticEmail SentAutomaticEmail.objects.create( user=cls.program_enrollment_unsent.user, automatic_email=AutomaticEmailFactory.create(enabled=True), status=SentAutomaticEmail.SENT, ) with mute_signals(post_save): cls.staff_user = UserFactory.create()
def test_populate_query_memberships(self, source_type, is_member, query_matches, mock_on_commit): """ Tests that existing memberships are updated where appropriate """ with mute_signals(post_save): query = PercolateQueryFactory.create(source_type=source_type) profiles = [ ProfileFactory.create(filled_out=True) for _ in range(3) ] program_enrollments = [ ProgramEnrollmentFactory.create(user=profile.user) for profile in profiles ] with patch('search.api._search_percolate_queries', return_value=[query.id] if query_matches else []) as search_percolate_queries_mock: populate_query_memberships(query.id) assert search_percolate_queries_mock.call_count == len( program_enrollments) for program_enrollment in program_enrollments: search_percolate_queries_mock.assert_any_call(program_enrollment) for profile in profiles: membership = PercolateQueryMembership.objects.get( user=profile.user, query=query) assert membership.is_member is query_matches assert membership.needs_update is True
def test_update_percolate_memberships(self, source_type, is_member, query_matches, mock_on_commit): """ Tests that existing memberships are updated where appropriate """ with mute_signals(post_save): query = PercolateQueryFactory.create(source_type=source_type) profile = ProfileFactory.create(filled_out=True) program_enrollment = ProgramEnrollmentFactory.create( user=profile.user) membership = PercolateQueryMembershipFactory.create( user=profile.user, query=query, is_member=is_member, needs_update=False) with patch('search.api._search_percolate_queries', return_value=[query.id] if query_matches else []) as search_percolate_queries_mock: update_percolate_memberships(profile.user, source_type) search_percolate_queries_mock.assert_called_once_with( program_enrollment) membership.refresh_from_db() assert membership.needs_update is (is_member is not query_matches)
def test_index_create_percolate_query(self): """When a new PercolateQuery is created we should index it""" with patch('search.signals.transaction', on_commit=lambda callback: callback()): percolate_query = PercolateQueryFactory.create() assert self.mocked_index_percolate_queries.call_count == 1 assert len(self.mocked_index_percolate_queries.call_args[0]) == 1 assert list(self.mocked_index_percolate_queries.call_args[0][0])[0].id == percolate_query.id
def test_update_percolate_memberships(self, source_type, is_member, query_matches, mock_on_commit): """ Tests that existing memberships are updated where appropriate """ with mute_signals(post_save): query = PercolateQueryFactory.create(source_type=source_type) profile = ProfileFactory.create(filled_out=True) program_enrollment = ProgramEnrollmentFactory.create(user=profile.user) membership = PercolateQueryMembershipFactory.create( user=profile.user, query=query, is_member=is_member, needs_update=False ) with patch( 'search.api._search_percolate_queries', return_value=[query.id] if query_matches else [] ) as search_percolate_queries_mock: update_percolate_memberships(profile.user, source_type) search_percolate_queries_mock.assert_called_once_with(program_enrollment) membership.refresh_from_db() assert membership.needs_update is (is_member is not query_matches)
def test_fix_percolate_query(self): """ Make sure all nested -> filter are replaced with nested -> query """ input_query = { "query": { "bool": { "filter": [ { "bool": { "must": [ { "term": { "program.is_learner": True } } ], "should": [ { "term": { "program.id": 34 } } ], "minimum_should_match": 1 } }, { "term": { "profile.filled_out": True } }, { "bool": { "must": [ { "nested": { "path": "program.course_runs", "filter": { "term": { "program.course_runs.semester": "2015 - Summer" } } } }, { "term": { "program.id": 34 } } ] } } ] } } } query = PercolateQueryFactory.create(query=input_query) assert index_percolate_queries([query]) == 1
def test_index_delete_percolate_query(self): """When a PercolateQuery is deleted we should delete it from the index too""" with patch('search.signals.transaction', on_commit=lambda callback: callback()): percolate_query = PercolateQueryFactory.create() percolate_query_id = percolate_query.id percolate_query.delete() assert self.mocked_delete_percolate_query.call_count == 1 assert len(self.mocked_delete_percolate_query.call_args[0]) == 1 assert self.mocked_delete_percolate_query.call_args[0][0] == percolate_query_id
def test_index_update_percolate_query(self): """When a PercolateQuery is updated we should index it""" with patch('search.signals.transaction', on_commit=lambda callback: callback()): percolate_query = PercolateQueryFactory.create() self.mocked_index_percolate_queries.reset_mock() with patch('search.tasks._index_percolate_queries') as mocked_index_percolate_queries: percolate_query.save() assert mocked_index_percolate_queries.call_count == 1 assert len(mocked_index_percolate_queries.call_args[0]) == 1 assert list(mocked_index_percolate_queries.call_args[0][0])[0].id == percolate_query.id
def test_fix_percolate_query(self): """ Make sure all nested -> filter are replaced with nested -> query """ input_query = { "query": { "bool": { "filter": [{ "bool": { "must": [{ "term": { "program.is_learner": True } }], "should": [{ "term": { "program.id": 34 } }], "minimum_should_match": 1 } }, { "term": { "profile.filled_out": True } }, { "bool": { "must": [{ "nested": { "path": "program.course_runs", "filter": { "term": { "program.course_runs.semester": "2015 - Summer" } } } }, { "term": { "program.id": 34 } }] } }] } } } query = PercolateQueryFactory.create(query=input_query) assert index_percolate_queries([query]) == 1
def test_populate_query_inactive_memberships(self, is_active, has_profile, mock_on_commit): """ Tests that memberships are handled correctly for users who are inactive or have no profiles """ with mute_signals(post_save): query = PercolateQueryFactory.create(source_type=PercolateQuery.DISCUSSION_CHANNEL_TYPE) user = UserFactory.create(is_active=is_active) if has_profile: ProfileFactory.create(user=user, filled_out=True) ProgramEnrollmentFactory.create(user=user) with patch('search.api.get_conn') as es_mock: populate_query_memberships(query.id) assert es_mock.return_value.percolate.call_count == (1 if has_profile and is_active else 0) assert PercolateQueryMembership.objects.filter(user=user, query=query).count() == ( 1 if is_active else 0 )
def test_index_percolate_query(self): """Test that we index the percolate query""" query = {"query": {"match": {"profile.first_name": "here"}}} percolate_query = PercolateQueryFactory.create(query=query, original_query="original") percolate_query_id = 123 percolate_query.id = percolate_query_id # Don't save since that will trigger a signal which will update the index with self.assertRaises(NotFoundError): es.get_percolate_query(percolate_query_id) index_percolate_queries([percolate_query]) assert es.get_percolate_query(percolate_query_id) == { '_id': str(percolate_query_id), '_index': es.get_default_backing_index(PERCOLATE_INDEX_TYPE), '_source': query, '_type': GLOBAL_DOC_TYPE, '_version': 1, 'found': True, }
def test_delete_percolate_queries(self): """Test that we delete the percolate query from the index""" query = {"query": {"match": {"profile.first_name": "here"}}} with patch('search.signals.transaction', on_commit=lambda callback: callback()): percolate_query = PercolateQueryFactory.create(query=query, original_query="original") assert es.get_percolate_query(percolate_query.id) == { '_id': str(percolate_query.id), '_index': es.get_default_backing_index(PERCOLATE_INDEX_TYPE), '_source': query, '_type': GLOBAL_DOC_TYPE, '_version': 1, 'found': True, } delete_percolate_query(percolate_query.id) with self.assertRaises(NotFoundError): es.get_percolate_query(percolate_query.id) # If we delete it again there should be no exception delete_percolate_query(percolate_query.id) with self.assertRaises(NotFoundError): es.get_percolate_query(percolate_query.id)
def test_populate_query_inactive_memberships(self, is_active, has_profile, mock_on_commit): """ Tests that memberships are handled correctly for users who are inactive or have no profiles """ with mute_signals(post_save): query = PercolateQueryFactory.create( source_type=PercolateQuery.DISCUSSION_CHANNEL_TYPE) user = UserFactory.create(is_active=is_active) if has_profile: ProfileFactory.create(user=user, filled_out=True) ProgramEnrollmentFactory.create(user=user) with patch('search.api.get_conn') as es_mock: populate_query_memberships(query.id) assert es_mock.return_value.search.call_count == ( 1 if has_profile and is_active else 0) assert PercolateQueryMembership.objects.filter( user=user, query=query).count() == (1 if is_active else 0)
def test_index_percolate_query(self): """Test that we index the percolate query""" query = {"query": {"match": {"profile.first_name": "here"}}} percolate_query = PercolateQueryFactory.create( query=query, original_query="original") percolate_query_id = 123 percolate_query.id = percolate_query_id # Don't save since that will trigger a signal which will update the index with self.assertRaises(NotFoundError): es.get_percolate_query(percolate_query_id) index_percolate_queries([percolate_query]) assert es.get_percolate_query(percolate_query_id) == { '_id': str(percolate_query_id), '_index': es.get_default_backing_index(PERCOLATE_INDEX_TYPE), '_source': query, '_seq_no': 0, '_primary_term': 1, '_type': GLOBAL_DOC_TYPE, '_version': 1, 'found': True, }
def test_populate_query_memberships(self, source_type, is_member, query_matches, mock_on_commit): """ Tests that existing memberships are updated where appropriate """ with mute_signals(post_save): query = PercolateQueryFactory.create(source_type=source_type) profiles = [ProfileFactory.create(filled_out=True) for _ in range(3)] program_enrollments = [ProgramEnrollmentFactory.create(user=profile.user) for profile in profiles] with patch( 'search.api._search_percolate_queries', return_value=[query.id] if query_matches else [] ) as search_percolate_queries_mock: populate_query_memberships(query.id) assert search_percolate_queries_mock.call_count == len(program_enrollments) for program_enrollment in program_enrollments: search_percolate_queries_mock.assert_any_call(program_enrollment) for profile in profiles: membership = PercolateQueryMembership.objects.get(user=profile.user, query=query) assert membership.is_member is query_matches assert membership.needs_update is True
def setUpTestData(cls): super().setUpTestData() cls.program_enrollment_unsent = ProgramEnrollmentFactory.create() cls.program_enrollment_sent = ProgramEnrollmentFactory.create() cls.automatic_email = AutomaticEmailFactory.create(enabled=True) cls.percolate_query = cls.automatic_email.query cls.other_query = PercolateQueryFactory.create(source_type=PercolateQuery.DISCUSSION_CHANNEL_TYPE) cls.percolate_queries = [cls.percolate_query, cls.other_query] cls.automatic_email_disabled = AutomaticEmailFactory.create(enabled=False) cls.percolate_query_disabled = cls.automatic_email_disabled.query SentAutomaticEmail.objects.create( automatic_email=cls.automatic_email, user=cls.program_enrollment_sent.user, status=SentAutomaticEmail.SENT, ) # User was sent email connected to a different AutomaticEmail SentAutomaticEmail.objects.create( user=cls.program_enrollment_unsent.user, automatic_email=AutomaticEmailFactory.create(enabled=True), status=SentAutomaticEmail.SENT, ) with mute_signals(post_save): cls.staff_user = UserFactory.create()
def test_delete_percolate_queries(self): """Test that we delete the percolate query from the index""" query = {"query": {"match": {"profile.first_name": "here"}}} with patch('search.signals.transaction', on_commit=lambda callback: callback()): percolate_query = PercolateQueryFactory.create( query=query, original_query="original") assert es.get_percolate_query(percolate_query.id) == { '_id': str(percolate_query.id), '_index': es.get_default_backing_index(PERCOLATE_INDEX_TYPE), '_source': query, '_seq_no': 0, '_primary_term': 1, '_type': GLOBAL_DOC_TYPE, '_version': 1, 'found': True, } delete_percolate_query(percolate_query.id) with self.assertRaises(NotFoundError): es.get_percolate_query(percolate_query.id) # If we delete it again there should be no exception delete_percolate_query(percolate_query.id) with self.assertRaises(NotFoundError): es.get_percolate_query(percolate_query.id)