def test_signals_courses_unpublish(self, mock_bulk, *_): """ Unpublishing a course in a language should update its document in the Elasticsearch courses index or delete it if there is no language published anymore. """ course = CourseFactory(page_languages=["en", "fr"], should_publish=True) self.run_commit_hooks() mock_bulk.reset_mock() # - Unpublish the first language self.assertTrue(course.extended_object.unpublish("en")) course.refresh_from_db() # Elasticsearch should not be called before the db transaction is successful self.assertFalse(mock_bulk.called) self.run_commit_hooks() self.assertEqual(mock_bulk.call_count, 1) self.assertEqual(len(mock_bulk.call_args[1]["actions"]), 1) action = mock_bulk.call_args[1]["actions"][0] self.assertEqual(action["_id"], course.get_es_id()) self.assertEqual(action["_op_type"], "index") self.assertEqual(action["_index"], "test_courses") mock_bulk.reset_mock() # - Unpublish the second language self.assertTrue(course.extended_object.unpublish("fr")) course.refresh_from_db() # Elasticsearch should not be called before the db transaction is successful self.assertFalse(mock_bulk.called) self.run_commit_hooks() self.assertEqual(mock_bulk.call_count, 1) self.assertEqual(len(mock_bulk.call_args[1]["actions"]), 1) action = mock_bulk.call_args[1]["actions"][0] self.assertEqual(action["_id"], course.get_es_id()) self.assertEqual(action["_op_type"], "delete") self.assertEqual(action["_index"], "test_courses")
def test_indexers_courses_get_es_documents_snapshots(self): """ Course snapshots should not get indexed. """ course = CourseFactory(should_publish=True) CourseFactory(page_parent=course.extended_object, should_publish=True) indexed_courses = list( CoursesIndexer.get_es_documents(index="some_index", action="some_action") ) self.assertEqual(len(indexed_courses), 1) self.assertEqual(indexed_courses[0]["_id"], course.get_es_id())
def test_signals_courses_publish(self, mock_bulk, *_): """ Publishing a course should update its document in the Elasticsearch courses index. """ course = CourseFactory() self.run_commit_hooks() # Elasticsearch should not be called until the course is published self.assertFalse(mock_bulk.called) self.assertTrue(course.extended_object.publish("en")) course.refresh_from_db() # Elasticsearch should not be called before the db transaction is successful self.assertFalse(mock_bulk.called) self.run_commit_hooks() self.assertEqual(mock_bulk.call_count, 1) self.assertEqual(len(mock_bulk.call_args[1]["actions"]), 1) action = mock_bulk.call_args[1]["actions"][0] self.assertEqual(action["_id"], course.get_es_id()) self.assertEqual(action["_op_type"], "index") self.assertEqual(action["_index"], "test_courses")
def test_indexers_courses_get_es_documents_from_models(self, _mock_picture): """ Happy path: the data is retrieved from the models properly formatted """ # Create a course with a page in both english and french published_categories = [ CategoryFactory( fill_icon=True, page_title={"en": "Title cat 1", "fr": "Titre cat 1"}, should_publish=True, ), CategoryFactory( fill_icon=True, page_title={"en": "Title cat 2", "fr": "Titre cat 2"}, should_publish=True, ), ] draft_category = CategoryFactory(fill_icon=True) main_organization = OrganizationFactory( page_title={ "en": "english main organization title", "fr": "titre organisation principale français", }, should_publish=True, ) other_draft_organization = OrganizationFactory( page_title={ "en": "english other organization title", "fr": "titre autre organisation français", } ) other_published_organization = OrganizationFactory( page_title={ "en": "english other organization title", "fr": "titre autre organisation français", }, should_publish=True, ) person1 = PersonFactory( page_title={"en": "Eugène Delacroix", "fr": "Eugène Delacroix"}, should_publish=True, ) person2 = PersonFactory( page_title={"en": "Comte de Saint-Germain", "fr": "Earl of Saint-Germain"}, should_publish=True, ) person_draft = PersonFactory( page_title={"en": "Jules de Polignac", "fr": "Jules de Polignac"} ) course = CourseFactory( duration=[3, WEEK], effort=[2, HOUR], fill_categories=published_categories + [draft_category], fill_cover=True, fill_icons=published_categories + [draft_category], fill_organizations=[ main_organization, other_draft_organization, other_published_organization, ], fill_team=[person1, person_draft, person2], page_title={ "en": "an english course title", "fr": "un titre cours français", }, ) CourseRunFactory.create_batch(2, direct_course=course) course.extended_object.publish("en") course.extended_object.publish("fr") course.refresh_from_db() # Add a description in several languages placeholder = course.public_extension.extended_object.placeholders.get( slot="course_description" ) plugin_params = {"placeholder": placeholder, "plugin_type": "CKEditorPlugin"} add_plugin(body="english description line 1.", language="en", **plugin_params) add_plugin(body="english description line 2.", language="en", **plugin_params) add_plugin(body="a propos français ligne 1.", language="fr", **plugin_params) add_plugin(body="a propos français ligne 2.", language="fr", **plugin_params) # Add an introduction in several languages placeholder = course.public_extension.extended_object.placeholders.get( slot="course_introduction" ) plugin_params = {"placeholder": placeholder, "plugin_type": "PlainTextPlugin"} add_plugin(body="english introduction.", language="en", **plugin_params) add_plugin(body="introduction française.", language="fr", **plugin_params) # The results were properly formatted and passed to the consumer expected_course = { "_id": course.get_es_id(), "_index": "some_index", "_op_type": "some_action", "absolute_url": { "en": "/en/an-english-course-title/", "fr": "/fr/un-titre-cours-francais/", }, "categories": [ published_categories[0].get_es_id(), published_categories[1].get_es_id(), ], "categories_names": { "en": ["Title cat 1", "Title cat 2"], "fr": ["Titre cat 1", "Titre cat 2"], }, "code": course.code, "complete": { "en": [ "an english course title", "english course title", "course title", "title", ], "fr": [ "un titre cours français", "titre cours français", "cours français", "français", ], }, "course_runs": [ { "start": course_run.public_course_run.start, "end": course_run.public_course_run.end, "enrollment_start": course_run.public_course_run.enrollment_start, "enrollment_end": course_run.public_course_run.enrollment_end, "languages": course_run.public_course_run.languages, } for course_run in course.course_runs.order_by("-end") ], "cover_image": { "en": {"info": "picture info"}, "fr": {"info": "picture info"}, }, "description": { "en": "english description line 1. english description line 2.", "fr": "a propos français ligne 1. a propos français ligne 2.", }, "duration": {"en": "3 weeks", "fr": "3 semaines"}, "effort": {"en": "2 hours", "fr": "2 heures"}, "icon": { "en": { "color": published_categories[0].color, "info": "picture info", "title": "Title cat 1", }, "fr": { "color": published_categories[0].color, "info": "picture info", "title": "Titre cat 1", }, }, "introduction": { "en": "english introduction.", "fr": "introduction française.", }, "is_new": False, "is_listed": True, "organization_highlighted": { "en": "english main organization title", "fr": "titre organisation principale français", }, "organization_highlighted_cover_image": {}, "organizations": [ main_organization.get_es_id(), other_published_organization.get_es_id(), ], "organizations_names": { "en": [ "english main organization title", "english other organization title", ], "fr": [ "titre organisation principale français", "titre autre organisation français", ], }, "persons": [ person1.get_es_id(), person2.get_es_id(), ], "persons_names": { "en": ["Eugène Delacroix", "Comte de Saint-Germain"], "fr": ["Eugène Delacroix", "Earl of Saint-Germain"], }, "title": {"fr": "un titre cours français", "en": "an english course title"}, } indexed_courses = list( CoursesIndexer.get_es_documents(index="some_index", action="some_action") ) self.assertEqual(len(indexed_courses), 1) self.assertEqual(indexed_courses[0], expected_course)