def test_signals_persons_publish(self, mock_bulk, *_): """ Publishing a person should update its document in the Elasticsearch persons index, and the documents for published courses to which it is related, excluding snapshots. """ person = PersonFactory() published_course, _unpublished_course = CourseFactory.create_batch( 2, fill_team=[person]) self.assertTrue(published_course.extended_object.publish("en")) published_course.refresh_from_db() self.run_commit_hooks() mock_bulk.reset_mock() self.assertTrue(person.extended_object.publish("en")) person.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"]), 2) actions = list(mock_bulk.call_args[1]["actions"]) self.assertEqual(actions[0]["_id"], published_course.get_es_id()) self.assertEqual(actions[0]["_op_type"], "index") self.assertEqual(actions[0]["_index"], "test_courses") self.assertEqual(actions[1]["_id"], person.get_es_id()) self.assertEqual(actions[1]["_op_type"], "index") self.assertEqual(actions[1]["_index"], "richie_persons")
def test_signals_persons_unpublish(self, mock_bulk, *_): """ Unpublishing a person in a language should update its document in the Elasticsearch persons index or delete it if there is no language published anymore. It should also reindex the documents for published courses to which it is related, excluding snapshots. """ person = PersonFactory(page_languages=["en", "fr"], should_publish=True) published_course, _unpublished_course = CourseFactory.create_batch( 2, fill_team=[person]) self.assertTrue(published_course.extended_object.publish("en")) published_course.refresh_from_db() self.run_commit_hooks() mock_bulk.reset_mock() # - Unpublish the first language self.assertTrue(person.extended_object.unpublish("en")) person.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"]), 2) actions = list(mock_bulk.call_args[1]["actions"]) self.assertEqual(actions[0]["_id"], published_course.get_es_id()) self.assertEqual(actions[0]["_op_type"], "index") self.assertEqual(actions[0]["_index"], "test_courses") self.assertEqual(actions[1]["_id"], person.get_es_id()) self.assertEqual(actions[1]["_op_type"], "index") self.assertEqual(actions[1]["_index"], "richie_persons") mock_bulk.reset_mock() # - Unpublish the second language self.assertTrue(person.extended_object.unpublish("fr")) person.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"]), 2) actions = list(mock_bulk.call_args[1]["actions"]) self.assertEqual(actions[0]["_id"], published_course.get_es_id()) self.assertEqual(actions[0]["_op_type"], "index") self.assertEqual(actions[0]["_index"], "test_courses") self.assertEqual(actions[1]["_id"], person.get_es_id()) self.assertEqual(actions[1]["_op_type"], "delete") self.assertEqual(actions[1]["_index"], "richie_persons")
def test_cms_plugins_person_render_on_public_page(self): """ The person plugin should render as expected on a public page. """ # Create a Person person = PersonFactory( page_title={ "en": "person title", "fr": "titre personne" }, fill_portrait={ "original_filename": "portrait.jpg", "default_alt_text": "my portrait", }, ) person_page = person.extended_object # Add bio to related placeholder bio_placeholder = person_page.placeholders.get(slot="bio") bio_en = add_plugin(bio_placeholder, PlainTextPlugin, "en", **{"body": "public bio"}) add_plugin(bio_placeholder, PlainTextPlugin, "fr", **{"body": "résumé public"}) # Create a page to add the plugin to page = create_i18n_page({"en": "A page", "fr": "Une page"}) placeholder = page.placeholders.get(slot="maincontent") add_plugin(placeholder, PersonPlugin, "en", **{"page": person.extended_object}) add_plugin(placeholder, PersonPlugin, "fr", **{"page": person.extended_object}) person_page.publish("en") person_page.publish("fr") person.refresh_from_db() page.publish("en") page.publish("fr") url = page.get_absolute_url(language="en") # The person plugin should not be visible on the public page before it is published person_page.unpublish("en") response = self.client.get(url) self.assertNotContains(response, "person title") # Republishing the plugin should not make it public person_page.publish("en") response = self.client.get(url) self.assertNotContains(response, "person title") # Now modify the person to have a draft different from the public version person_title = person.extended_object.title_set.get(language="en") person_title.title = "Jiji" person_title.save() bio_en.body = "draft bio" bio_en.save() # Publishing the page again should make the plugin public page.publish("en") # Check the page content in English response = self.client.get(url) # Person's name should be present as a link to the cms page self.assertContains(response, '<a href="/en/person-title/">', status_code=200) # The person's full name should be wrapped in a h2 person_title = person.public_extension.extended_object.get_title() self.assertContains( response, f'<h2 class="person-glimpse__title">{person_title:s}</h2>', html=True, ) self.assertContains(response, "person title") self.assertNotContains(response, "Jiji") # Person's portrait should be present href = person_page.get_absolute_url() pattern = ( fr'<a class="person-glimpse__media" href="{href:s}" tabindex="-1" aria-hidden="true" ' r'property="url">' r'<img src="/media/filer_public_thumbnails/filer_public/.*portrait\.jpg__200x200' r'.*alt="" property="image"') content = (htmlmin.minify( response.content.decode("UTF-8"), reduce_empty_attributes=False, remove_optional_attribute_quotes=False, ), ) self.assertIsNotNone(re.search(pattern, str(content))) # Short bio should be present self.assertContains( response, '<div class="person-glimpse__bio" property="description">public bio</div>', html=True, ) self.assertNotContains(response, "draft bio") # Same checks in French url = page.get_absolute_url(language="fr") response = self.client.get(url) self.assertContains(response, '<a href="/fr/titre-personne/">', status_code=200) href = person_page.get_absolute_url() pattern = ( fr'<a class="person-glimpse__media" href="{href:s}" tabindex="-1" aria-hidden="true" ' r'property="url">' r'<img src="/media/filer_public_thumbnails/filer_public/.*portrait\.jpg__200x200' r'.*alt="" property="image"') content = (htmlmin.minify( response.content.decode("UTF-8"), reduce_empty_attributes=False, remove_optional_attribute_quotes=False, ), ) self.assertIsNotNone(re.search(pattern, str(content))) self.assertContains( response, '<div class="person-glimpse__bio" property="description">résumé public</div>', html=True, )