def test_success_initial_content(self): author = ProfileFactory().user author2 = ProfileFactory().user tutorial = PublishedContentFactory(author_list=[author, author2]) gallery = GalleryFactory() image = ImageFactory(gallery=gallery) tutorial.image = image tutorial.save() staff = StaffProfileFactory() login_check = self.client.login(username=staff.user.username, password="******") self.assertTrue(login_check) response = self.client.get("{}{}".format( reverse("featured-resource-create"), "?content_type=published_content&content_id={}".format( tutorial.pk))) initial_dict = response.context["form"].initial self.assertEqual(initial_dict["title"], tutorial.title) self.assertEqual(initial_dict["authors"], "{}, {}".format(author, author2)) self.assertEqual(initial_dict["type"], _("Un tutoriel")) self.assertEqual( initial_dict["url"], "http://testserver{}".format(tutorial.get_absolute_url_online())) self.assertEqual( initial_dict["image_url"], "http://testserver{}".format(image.physical["featured"].url))
def test_success_initial_content(self): author = ProfileFactory().user author2 = ProfileFactory().user tutorial = PublishedContentFactory(author_list=[author, author2]) gallery = GalleryFactory() image = ImageFactory(gallery=gallery) tutorial.image = image tutorial.save() staff = StaffProfileFactory() login_check = self.client.login(username=staff.user.username, password='******') self.assertTrue(login_check) response = self.client.get('{}{}'.format( reverse('featured-resource-create'), '?content_type=published_content&content_id={}'.format( tutorial.pk))) initial_dict = response.context['form'].initial self.assertEqual(initial_dict['title'], tutorial.title) self.assertEqual(initial_dict['authors'], '{}, {}'.format(author, author2)) self.assertEqual(initial_dict['type'], _('Un tutoriel')) self.assertEqual( initial_dict['url'], 'http://testserver{}'.format(tutorial.get_absolute_url_online())) self.assertEqual( initial_dict['image_url'], 'http://testserver{}'.format(image.physical['featured'].url))
def test_ensure_gallery(self): content = PublishedContentFactory() content.authors.add(ProfileFactory().user) content.authors.add(ProfileFactory().user) content.save() content.ensure_author_gallery() self.assertEqual(UserGallery.objects.filter(gallery__pk=content.gallery.pk).count(), content.authors.count()) content.authors.add(ProfileFactory().user) content.save() content.ensure_author_gallery() self.assertEqual(UserGallery.objects.filter(gallery__pk=content.gallery.pk).count(), content.authors.count())
def test_only_one_notif_on_major_update(self): NewPublicationSubscription.objects.get_or_create_active(self.user1, self.user2) content = PublishedContentFactory(author_list=[self.user2]) notify_update(content, False, True) versioned = content.load_version() content.sha_draft = versioned.repo_update(introduction='new intro', conclusion='new conclusion', title=versioned.title) content.save(force_slug_update=False) publish_content(content, content.load_version(), True) notify_update(content, True, True) notifs = get_header_notifications(self.user1)['general_notifications']['list'] self.assertEqual(1, len(notifs), str(notifs))
def test_accessible_ui_for_author(self): opinion = PublishedContentFactory(author_list=[self.user_author], type='OPINION') subcategory = SubCategoryFactory() opinion.subcategory.add(subcategory) opinion.save() self.assertEqual( self.client.login(username=self.user_author.username, password='******'), True) resp = self.client.get(reverse('opinion:view', kwargs={'pk': opinion.pk, 'slug': opinion.slug})) self.assertContains(resp, 'Version brouillon', msg_prefix='Author must access their draft directly') self.assertNotContains(resp, '{}?subcategory='.format(reverse('publication:list'))) self.assertContains(resp, '{}?category='.format(reverse('opinion:list')))
def test_last_participation_is_old(self): article = PublishedContentFactory(author_list=[self.user_author], type="ARTICLE") newUser = ProfileFactory().user reac = ContentReaction(author=self.user_author, position=1, related_content=article) reac.update_content("I will find you. And I Will Kill you.") reac.save() article.last_note = reac article.save() self.assertFalse(last_participation_is_old(article, newUser)) ContentRead(user=self.user_author, note=reac, content=article).save() reac = ContentReaction(author=newUser, position=2, related_content=article) reac.update_content("I will find you. And I Will Kill you.") reac.save() article.last_note = reac article.save() ContentRead(user=newUser, note=reac, content=article).save() self.assertFalse(last_participation_is_old(article, newUser)) self.assertTrue(last_participation_is_old(article, self.user_author))
def test_last_participation_is_old(self): article = PublishedContentFactory(author_list=[self.user_author], type='ARTICLE') new_user = ProfileFactory().user reac = ContentReaction(author=self.user_author, position=1, related_content=article) reac.update_content('I will find you.') reac.save() article.last_note = reac article.save() self.assertFalse(last_participation_is_old(article, new_user)) ContentRead(user=self.user_author, note=reac, content=article).save() reac = ContentReaction(author=new_user, position=2, related_content=article) reac.update_content('I will find you.') reac.save() article.last_note = reac article.save() ContentRead(user=new_user, note=reac, content=article).save() self.assertFalse(last_participation_is_old(article, new_user)) self.assertTrue(last_participation_is_old(article, self.user_author))
def test_top_tags_content(self): tags_tuto = ['a', 'b', 'c'] tags_article = ['a', 'd', 'e'] content = PublishedContentFactory(type='TUTORIAL', author_list=[ProfileFactory().user]) content.add_tags(tags_tuto) content.save() tags_tuto = content.tags.all() content = PublishedContentFactory(type='ARTICLE', author_list=[ProfileFactory().user]) content.add_tags(tags_article) content.save() tags_article = content.tags.all() top_tags_tuto = topbar_publication_categories('TUTORIAL').get('tags') top_tags_article = topbar_publication_categories('ARTICLE').get('tags') self.assertEqual(list(top_tags_tuto), list(tags_tuto)) self.assertEqual(list(top_tags_article), list(tags_article))
def test_top_tags_content(self): tags_tuto = ["a", "b", "c"] tags_article = ["a", "d", "e"] content = PublishedContentFactory(type="TUTORIAL", author_list=[ProfileFactory().user]) content.add_tags(tags_tuto) content.save() tags_tuto = content.tags.all() content = PublishedContentFactory(type="ARTICLE", author_list=[ProfileFactory().user]) content.add_tags(tags_article) content.save() tags_article = content.tags.all() top_tags_tuto = topbar_publication_categories("TUTORIAL").get("tags") top_tags_article = topbar_publication_categories("ARTICLE").get("tags") self.assertEqual(list(top_tags_tuto), list(tags_tuto)) self.assertEqual(list(top_tags_article), list(tags_article))
def test_accessible_ui_for_author(self): opinion = PublishedContentFactory(author_list=[self.user_author], type="OPINION") subcategory = SubCategoryFactory() opinion.subcategory.add(subcategory) opinion.save() self.client.force_login(self.user_author) resp = self.client.get( reverse("opinion:view", kwargs={ "pk": opinion.pk, "slug": opinion.slug })) self.assertContains( resp, "Version brouillon", msg_prefix="Author must access their draft directly") self.assertNotContains( resp, "{}?subcategory=".format(reverse("publication:list"))) self.assertContains(resp, "{}?category=".format(reverse("opinion:list")))
def test_publication_and_attributes_consistency(self): pubdate = datetime.now() - timedelta(days=1) article = PublishedContentFactory(type="ARTICLE", author_list=[self.user_author]) public_version = article.public_version public_version.publication_date = pubdate public_version.save() # everything must come from database to have good datetime comparison article = PublishableContent.objects.get(pk=article.pk) article.public_version.load_public_version() old_date = article.public_version.publication_date old_title = article.public_version.title() old_description = article.public_version.description() article.licence = LicenceFactory() article.save() self.assertEqual( self.client.login(username=self.user_author.username, password="******"), True) self.client.post( reverse("content:edit", args=[article.pk, article.slug]), { "title": old_title + "bla", "description": old_description + "bla", "type": "ARTICLE", "licence": article.licence.pk, "subcategory": SubCategoryFactory().pk, "last_hash": article.sha_draft, }, ) article = PublishableContent.objects.prefetch_related( "public_version").get(pk=article.pk) article.public_version.load_public_version() self.assertEqual(old_title, article.public_version.title()) self.assertEqual(old_description, article.public_version.description()) self.assertEqual(old_date, article.public_version.publication_date) publish_content(article, article.load_version(), False) article = PublishableContent.objects.get(pk=article.pk) article.public_version.load_public_version() self.assertEqual(old_date, article.public_version.publication_date) self.assertNotEqual(old_date, article.public_version.update_date)
def test_success_initial_content(self): author = ProfileFactory().user author2 = ProfileFactory().user tutorial = PublishedContentFactory(author_list=[author, author2]) gallery = GalleryFactory() image = ImageFactory(gallery=gallery) tutorial.image = image tutorial.save() staff = StaffProfileFactory() login_check = self.client.login( username=staff.user.username, password='******' ) self.assertTrue(login_check) response = self.client.get('{}{}'.format(reverse('featured-resource-create'), '?content_type=published_content&content_id={}'.format(tutorial.pk))) initial_dict = response.context['form'].initial self.assertEqual(initial_dict['title'], tutorial.title) self.assertEqual(initial_dict['authors'], '{}, {}'.format(author, author2)) self.assertEqual(initial_dict['type'], _('Un tutoriel')) self.assertEqual(initial_dict['url'], 'http://testserver{}'.format(tutorial.get_absolute_url_online())) self.assertEqual(initial_dict['image_url'], image.physical.url)
def test_publication_and_attributes_consistency(self): pubdate = datetime.now() - timedelta(days=1) article = PublishedContentFactory(type='ARTICLE', author_list=[self.user_author]) public_version = article.public_version public_version.publication_date = pubdate public_version.save() # everything must come from database to have good datetime comparison article = PublishableContent.objects.get(pk=article.pk) article.public_version.load_public_version() old_date = article.public_version.publication_date old_title = article.public_version.title() old_description = article.public_version.description() article.licence = LicenceFactory() article.save() self.assertEqual( self.client.login(username=self.user_author.username, password='******'), True) self.client.post( reverse('content:edit', args=[article.pk, article.slug]), { 'title': old_title + 'bla', 'description': old_description + 'bla', 'type': 'ARTICLE', 'licence': article.licence.pk, 'subcategory': SubCategoryFactory().pk, 'last_hash': article.sha_draft }) article = PublishableContent.objects.prefetch_related( 'public_version').get(pk=article.pk) article.public_version.load_public_version() self.assertEqual(old_title, article.public_version.title()) self.assertEqual(old_description, article.public_version.description()) self.assertEqual(old_date, article.public_version.publication_date) publish_content(article, article.load_version(), False) article = PublishableContent.objects.get(pk=article.pk) article.public_version.load_public_version() self.assertEqual(old_date, article.public_version.publication_date) self.assertNotEqual(old_date, article.public_version.update_date)
def test_publication_and_attributes_consistency(self): pubdate = datetime.now() - timedelta(days=1) article = PublishedContentFactory(type='ARTICLE', author_list=[self.user_author]) public_version = article.public_version public_version.publication_date = pubdate public_version.save() # everything must come from database to have good datetime comparison article = PublishableContent.objects.get(pk=article.pk) article.public_version.load_public_version() old_date = article.public_version.publication_date old_title = article.public_version.title() old_description = article.public_version.description() article.licence = LicenceFactory() article.save() self.assertEqual( self.client.login( username=self.user_author.username, password='******'), True) self.client.post(reverse('content:edit', args=[article.pk, article.slug]), { 'title': old_title + 'bla', 'description': old_description + 'bla', 'type': 'ARTICLE', 'licence': article.licence.pk, 'subcategory': SubCategoryFactory().pk, 'last_hash': article.sha_draft }) article = PublishableContent.objects.prefetch_related('public_version').get(pk=article.pk) article.public_version.load_public_version() self.assertEqual(old_title, article.public_version.title()) self.assertEqual(old_description, article.public_version.description()) self.assertEqual(old_date, article.public_version.publication_date) publish_content(article, article.load_version(), False) article = PublishableContent.objects.get(pk=article.pk) article.public_version.load_public_version() self.assertEqual(old_date, article.public_version.publication_date) self.assertNotEqual(old_date, article.public_version.update_date)
def test_filters(self): # create topic and content and toggle request author = ProfileFactory().user category = CategoryFactory(position=1) forum = ForumFactory(category=category, position_in_category=1) topic = TopicFactory(forum=forum, author=author) FeaturedRequested.objects.toogle_request(topic, author) tutorial = PublishedContentFactory(author_list=[author]) gallery = GalleryFactory() image = ImageFactory(gallery=gallery) tutorial.image = image tutorial.save() FeaturedRequested.objects.toogle_request(tutorial, author) # without filter staff = StaffProfileFactory() login_check = self.client.login(username=staff.user.username, password='******') self.assertTrue(login_check) response = self.client.get(reverse('featured-resource-requests')) self.assertEqual(200, response.status_code) self.assertEqual(len(response.context['featured_request_list']), 2) self.assertTrue( any(r.content_object == topic for r in response.context['featured_request_list'])) self.assertTrue( any(r.content_object == tutorial for r in response.context['featured_request_list'])) # filter topic response = self.client.get( reverse('featured-resource-requests') + '?type=topic') self.assertEqual(200, response.status_code) self.assertEqual(len(response.context['featured_request_list']), 1) self.assertTrue( any(r.content_object == topic for r in response.context['featured_request_list'])) self.assertFalse( any(r.content_object == tutorial for r in response.context['featured_request_list'])) # filter tuto response = self.client.get( reverse('featured-resource-requests') + '?type=content') self.assertEqual(200, response.status_code) self.assertEqual(len(response.context['featured_request_list']), 1) self.assertFalse( any(r.content_object == topic for r in response.context['featured_request_list'])) self.assertTrue( any(r.content_object == tutorial for r in response.context['featured_request_list'])) # reject topic content_type = ContentType.objects.get_for_model(topic) q = FeaturedRequested.objects.get(object_id=topic.pk, content_type__pk=content_type.pk) q.rejected = True q.save() response = self.client.get( reverse('featured-resource-requests') + '?type=topic') self.assertEqual(200, response.status_code) self.assertEqual(len(response.context['featured_request_list']), 0) # filter ignored response = self.client.get( reverse('featured-resource-requests') + '?type=ignored') self.assertEqual(200, response.status_code) self.assertEqual(len(response.context['featured_request_list']), 1) self.assertTrue( any(r.content_object == topic for r in response.context['featured_request_list'])) # put back vote count to 0 for tutorial FeaturedRequested.objects.toogle_request(tutorial, author) response = self.client.get( reverse('featured-resource-requests') + '?type=content') self.assertEqual(200, response.status_code) self.assertEqual(len(response.context['featured_request_list']), 0) # does not appear with no votes # upvote topic other = ProfileFactory().user FeaturedRequested.objects.toogle_request(topic, other) response = self.client.get( reverse('featured-resource-requests') + '?type=topic') self.assertEqual(200, response.status_code) self.assertEqual(len(response.context['featured_request_list']), 1) # it is back!
def test_boosts(self): """Check if boosts are doing their job""" if not self.manager.connected_to_es: return # 1. Create topics (with identical titles), posts (with identical texts), an article and a tuto text = 'test' topic_1_solved_sticky = TopicFactory(forum=self.forum, author=self.user) topic_1_solved_sticky.title = text topic_1_solved_sticky.subtitle = '' topic_1_solved_sticky.solved_by = self.user topic_1_solved_sticky.is_sticky = True topic_1_solved_sticky.save() post_1 = PostFactory(topic=topic_1_solved_sticky, author=self.user, position=1) post_1.text = post_1.text_html = text post_1.save() post_2_useful = PostFactory(topic=topic_1_solved_sticky, author=self.user, position=2) post_2_useful.text = post_2_useful.text_html = text post_2_useful.is_useful = True post_2_useful.like = 5 post_2_useful.dislike = 2 # l/d ratio above 1 post_2_useful.save() topic_2_locked = TopicFactory(forum=self.forum, author=self.user, title=text) topic_2_locked.title = text topic_2_locked.subtitle = '' topic_2_locked.is_locked = True topic_2_locked.save() post_3_ld_below_1 = PostFactory(topic=topic_2_locked, author=self.user, position=1) post_3_ld_below_1.text = post_3_ld_below_1.text_html = text post_3_ld_below_1.like = 2 post_3_ld_below_1.dislike = 5 # l/d ratio below 1 post_3_ld_below_1.save() tuto = PublishableContentFactory(type='TUTORIAL') tuto_draft = tuto.load_version() tuto.title = text tuto.authors.add(self.user) tuto.save() tuto_draft.repo_update_top_container(text, tuto.slug, text, text) chapter1 = ContainerFactory(parent=tuto_draft, db_object=tuto) chapter1.repo_update(text, 'Who cares ?', 'Same here') ExtractFactory(container=chapter1, db_object=tuto) published_tuto = publish_content(tuto, tuto_draft, is_major_update=True) tuto.sha_public = tuto_draft.current_version tuto.sha_draft = tuto_draft.current_version tuto.public_version = published_tuto tuto.save() article = PublishedContentFactory(type='ARTICLE', title=text) published_article = PublishedContent.objects.get(content_pk=article.pk) opinion_not_picked = PublishedContentFactory(type='OPINION', title=text) published_opinion_not_picked = PublishedContent.objects.get(content_pk=opinion_not_picked.pk) opinion_picked = PublishedContentFactory(type='OPINION', title=text) opinion_picked.sha_picked = opinion_picked.sha_draft opinion_picked.date_picked = datetime.datetime.now() opinion_picked.save() published_opinion_picked = PublishedContent.objects.get(content_pk=opinion_picked.pk) for model in self.indexable: if model is FakeChapter: continue self.manager.es_bulk_indexing_of_model(model) self.manager.refresh_index() self.assertEqual(len(self.manager.setup_search(Search().query(MatchAll())).execute()), 10) # 2. Reset all boosts to 1 for doc_type in settings.ZDS_APP['search']['boosts']: for key in settings.ZDS_APP['search']['boosts'][doc_type]: settings.ZDS_APP['search']['boosts'][doc_type][key] = 1.0 # 3. Test posts result = self.client.get( reverse('search:query') + '?q=' + text + '&models=' + Post.get_es_document_type(), follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 3) # score are equals without boost: self.assertTrue(response[0].meta.score == response[1].meta.score == response[2].meta.score) settings.ZDS_APP['search']['boosts']['post']['if_first'] = 2.0 result = self.client.get( reverse('search:query') + '?q=' + text + '&models=' + Post.get_es_document_type(), follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 3) self.assertTrue(response[0].meta.score == response[1].meta.score > response[2].meta.score) self.assertEqual(response[2].meta.id, str(post_2_useful.pk)) # post 2 is the only one not first settings.ZDS_APP['search']['boosts']['post']['if_first'] = 1.0 settings.ZDS_APP['search']['boosts']['post']['if_useful'] = 2.0 result = self.client.get( reverse('search:query') + '?q=' + text + '&models=' + Post.get_es_document_type(), follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 3) self.assertTrue(response[0].meta.score > response[1].meta.score == response[2].meta.score) self.assertEqual(response[0].meta.id, str(post_2_useful.pk)) # post 2 is useful settings.ZDS_APP['search']['boosts']['post']['if_useful'] = 1.0 settings.ZDS_APP['search']['boosts']['post']['ld_ratio_above_1'] = 2.0 result = self.client.get( reverse('search:query') + '?q=' + text + '&models=' + Post.get_es_document_type(), follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 3) self.assertTrue(response[0].meta.score > response[1].meta.score == response[2].meta.score) self.assertEqual(response[0].meta.id, str(post_2_useful.pk)) # post 2 have a l/d ratio of 5/2 settings.ZDS_APP['search']['boosts']['post']['ld_ratio_above_1'] = 1.0 settings.ZDS_APP['search']['boosts']['post']['ld_ratio_below_1'] = 2.0 # no one would do that in real life result = self.client.get( reverse('search:query') + '?q=' + text + '&models=' + Post.get_es_document_type(), follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 3) self.assertTrue(response[0].meta.score > response[1].meta.score == response[2].meta.score) self.assertEqual(response[0].meta.id, str(post_3_ld_below_1.pk)) # post 3 have a l/d ratio of 2/5 settings.ZDS_APP['search']['boosts']['post']['ld_ratio_below_1'] = 1.0 # 4. Test topics result = self.client.get( reverse('search:query') + '?q=' + text + '&models=' + Topic.get_es_document_type(), follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 2) # score are equals without boost: self.assertTrue(response[0].meta.score == response[1].meta.score) settings.ZDS_APP['search']['boosts']['topic']['if_sticky'] = 2.0 result = self.client.get( reverse('search:query') + '?q=' + text + '&models=' + Topic.get_es_document_type(), follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 2) self.assertTrue(response[0].meta.score > response[1].meta.score) self.assertEqual(response[0].meta.id, str(topic_1_solved_sticky.pk)) # topic 1 is sticky settings.ZDS_APP['search']['boosts']['topic']['if_sticky'] = 1.0 settings.ZDS_APP['search']['boosts']['topic']['if_solved'] = 2.0 result = self.client.get( reverse('search:query') + '?q=' + text + '&models=' + Topic.get_es_document_type(), follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 2) self.assertTrue(response[0].meta.score > response[1].meta.score) self.assertEqual(response[0].meta.id, str(topic_1_solved_sticky.pk)) # topic 1 is solved settings.ZDS_APP['search']['boosts']['topic']['if_solved'] = 1.0 settings.ZDS_APP['search']['boosts']['topic']['if_locked'] = 2.0 # no one would do that in real life result = self.client.get( reverse('search:query') + '?q=' + text + '&models=' + Topic.get_es_document_type(), follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 2) self.assertTrue(response[0].meta.score > response[1].meta.score) self.assertEqual(response[0].meta.id, str(topic_2_locked.pk)) # topic 2 is locked settings.ZDS_APP['search']['boosts']['topic']['if_locked'] = 1.0 # no one would do that in real life # 5. Test published contents result = self.client.get( reverse('search:query') + '?q=' + text + '&models=content', follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 5) # score are equals without boost: self.assertTrue(response[0].meta.score == response[1].meta.score == response[2].meta.score == response[3].meta.score == response[4].meta.score) settings.ZDS_APP['search']['boosts']['publishedcontent']['if_article'] = 2.0 result = self.client.get( reverse('search:query') + '?q=' + text + '&models=content', follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 5) self.assertTrue(response[0].meta.score > response[1].meta.score) self.assertEqual(response[0].meta.id, str(published_article.pk)) # obvious settings.ZDS_APP['search']['boosts']['publishedcontent']['if_article'] = 1.0 settings.ZDS_APP['search']['boosts']['publishedcontent']['if_tutorial'] = 2.0 result = self.client.get( reverse('search:query') + '?q=' + text + '&models=content', follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 5) self.assertTrue(response[0].meta.score > response[1].meta.score) self.assertEqual(response[0].meta.id, str(published_tuto.pk)) # obvious settings.ZDS_APP['search']['boosts']['publishedcontent']['if_tutorial'] = 1.0 settings.ZDS_APP['search']['boosts']['publishedcontent']['if_opinion'] = 2.0 settings.ZDS_APP['search']['boosts']['publishedcontent']['if_opinion_not_picked'] = 4.0 # Note: in "real life", unpicked opinion would get a boost < 1. result = self.client.get( reverse('search:query') + '?q=' + text + '&models=content', follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 5) self.assertTrue(response[0].meta.score > response[1].meta.score > response[2].meta.score) self.assertEqual(response[0].meta.id, str(published_opinion_not_picked.pk)) # unpicked opinion got first self.assertEqual(response[1].meta.id, str(published_opinion_picked.pk)) settings.ZDS_APP['search']['boosts']['publishedcontent']['if_opinion'] = 1.0 settings.ZDS_APP['search']['boosts']['publishedcontent']['if_opinion_not_picked'] = 1.0 settings.ZDS_APP['search']['boosts']['publishedcontent']['if_medium_or_big_tutorial'] = 2.0 result = self.client.get( reverse('search:query') + '?q=' + text + '&models=content', follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 5) self.assertTrue(response[0].meta.score > response[1].meta.score) self.assertEqual(response[0].meta.id, str(published_tuto.pk)) # obvious settings.ZDS_APP['search']['boosts']['publishedcontent']['if_medium_or_big_tutorial'] = 1.0 # 6. Test global boosts # NOTE: score are NOT the same for all documents, no matter how hard it tries to, small differences exists for model in self.indexable: # set a huge number to overcome the small differences: settings.ZDS_APP['search']['boosts'][model.get_es_document_type()]['global'] = 10.0 result = self.client.get( reverse('search:query') + '?q=' + text, follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 10) self.assertEqual(response[0].meta.doc_type, model.get_es_document_type()) # obvious settings.ZDS_APP['search']['boosts'][model.get_es_document_type()]['global'] = 1.0
def test_unregister(self): """ To test that unregistering user is working. """ # test not logged user can't unregister. self.client.logout() result = self.client.post(reverse('member-unregister'), follow=False) self.assertEqual(result.status_code, 302) # test logged user can register. user = ProfileFactory() login_check = self.client.login(username=user.user.username, password='******') self.assertEqual(login_check, True) result = self.client.post(reverse('member-unregister'), follow=False) self.assertEqual(result.status_code, 302) self.assertEqual( User.objects.filter(username=user.user.username).count(), 0) # Attach a user at tutorials, articles, topics and private topics. After that, # unregister this user and check that he is well removed in all contents. user = ProfileFactory() user2 = ProfileFactory() alone_gallery = GalleryFactory() UserGalleryFactory(gallery=alone_gallery, user=user.user) shared_gallery = GalleryFactory() UserGalleryFactory(gallery=shared_gallery, user=user.user) UserGalleryFactory(gallery=shared_gallery, user=user2.user) # first case : a published tutorial with only one author published_tutorial_alone = PublishedContentFactory(type='TUTORIAL') published_tutorial_alone.authors.add(user.user) published_tutorial_alone.save() # second case : a published tutorial with two authors published_tutorial_2 = PublishedContentFactory(type='TUTORIAL') published_tutorial_2.authors.add(user.user) published_tutorial_2.authors.add(user2.user) published_tutorial_2.save() # third case : a private tutorial with only one author writing_tutorial_alone = PublishableContentFactory(type='TUTORIAL') writing_tutorial_alone.authors.add(user.user) writing_tutorial_alone.save() writing_tutorial_alone_galler_path = writing_tutorial_alone.gallery.get_gallery_path( ) # fourth case : a private tutorial with at least two authors writing_tutorial_2 = PublishableContentFactory(type='TUTORIAL') writing_tutorial_2.authors.add(user.user) writing_tutorial_2.authors.add(user2.user) writing_tutorial_2.save() self.client.login(username=self.staff.username, password="******") # same thing for articles published_article_alone = PublishedContentFactory(type='ARTICLE') published_article_alone.authors.add(user.user) published_article_alone.save() published_article_2 = PublishedContentFactory(type='ARTICLE') published_article_2.authors.add(user.user) published_article_2.authors.add(user2.user) published_article_2.save() writing_article_alone = PublishableContentFactory(type='ARTICLE') writing_article_alone.authors.add(user.user) writing_article_alone.save() writing_article_2 = PublishableContentFactory(type='ARTICLE') writing_article_2.authors.add(user.user) writing_article_2.authors.add(user2.user) writing_article_2.save() # beta content beta_forum = ForumFactory(category=CategoryFactory()) beta_content = BetaContentFactory(author_list=[user.user], forum=beta_forum) beta_content_2 = BetaContentFactory( author_list=[user.user, user2.user], forum=beta_forum) # about posts and topics authored_topic = TopicFactory(author=user.user, forum=self.forum11) answered_topic = TopicFactory(author=user2.user, forum=self.forum11) PostFactory(topic=answered_topic, author=user.user, position=2) edited_answer = PostFactory(topic=answered_topic, author=user.user, position=3) edited_answer.editor = user.user edited_answer.save() upvoted_answer = PostFactory(topic=answered_topic, author=user2.user, position=4) upvoted_answer.like += 1 upvoted_answer.save() CommentVote.objects.create(user=user.user, comment=upvoted_answer, positive=True) private_topic = PrivateTopicFactory(author=user.user) private_topic.participants.add(user2.user) private_topic.save() PrivatePostFactory(author=user.user, privatetopic=private_topic, position_in_topic=1) # add API key self.assertEqual(Application.objects.count(), 0) self.assertEqual(AccessToken.objects.count(), 0) api_application = Application() api_application.client_id = 'foobar' api_application.user = user.user api_application.client_type = 'confidential' api_application.authorization_grant_type = 'password' api_application.client_secret = '42' api_application.save() token = AccessToken() token.user = user.user token.token = 'r@d0m' token.application = api_application token.expires = datetime.now() token.save() self.assertEqual(Application.objects.count(), 1) self.assertEqual(AccessToken.objects.count(), 1) # login and unregister: login_check = self.client.login(username=user.user.username, password='******') self.assertEqual(login_check, True) result = self.client.post(reverse('member-unregister'), follow=False) self.assertEqual(result.status_code, 302) # check that the bot have taken authorship of tutorial: self.assertEqual(published_tutorial_alone.authors.count(), 1) self.assertEqual(published_tutorial_alone.authors.first().username, settings.ZDS_APP["member"]["external_account"]) self.assertFalse(os.path.exists(writing_tutorial_alone_galler_path)) self.assertEqual(published_tutorial_2.authors.count(), 1) self.assertEqual( published_tutorial_2.authors.filter( username=settings.ZDS_APP["member"] ["external_account"]).count(), 0) # check that published tutorials remain published and accessible self.assertIsNotNone( published_tutorial_2.public_version.get_prod_path()) self.assertTrue( os.path.exists( published_tutorial_2.public_version.get_prod_path())) self.assertIsNotNone( published_tutorial_alone.public_version.get_prod_path()) self.assertTrue( os.path.exists( published_tutorial_alone.public_version.get_prod_path())) self.assertEqual( self.client.get(reverse('tutorial:view', args=[ published_tutorial_alone.pk, published_tutorial_alone.slug ]), follow=False).status_code, 200) self.assertEqual( self.client.get(reverse( 'tutorial:view', args=[published_tutorial_2.pk, published_tutorial_2.slug]), follow=False).status_code, 200) # test that published articles remain accessible self.assertTrue( os.path.exists( published_article_alone.public_version.get_prod_path())) self.assertEqual( self.client.get(reverse('article:view', args=[ published_article_alone.pk, published_article_alone.slug ]), follow=True).status_code, 200) self.assertEqual( self.client.get(reverse( 'article:view', args=[published_article_2.pk, published_article_2.slug]), follow=True).status_code, 200) # check that the tutorial for which the author was alone does not exists anymore self.assertEqual( PublishableContent.objects.filter( pk=writing_tutorial_alone.pk).count(), 0) self.assertFalse(os.path.exists( writing_tutorial_alone.get_repo_path())) # check that bot haven't take the authorship of the tuto with more than one author self.assertEqual(writing_tutorial_2.authors.count(), 1) self.assertEqual( writing_tutorial_2.authors.filter( username=settings.ZDS_APP["member"] ["external_account"]).count(), 0) # authorship for the article for which user was the only author self.assertEqual(published_article_alone.authors.count(), 1) self.assertEqual(published_article_alone.authors.first().username, settings.ZDS_APP["member"]["external_account"]) self.assertEqual(published_article_2.authors.count(), 1) self.assertEqual( PublishableContent.objects.filter( pk=writing_article_alone.pk).count(), 0) self.assertFalse(os.path.exists(writing_article_alone.get_repo_path())) # not bot if another author: self.assertEqual( published_article_2.authors.filter( username=settings.ZDS_APP["member"] ["external_account"]).count(), 0) self.assertEqual(writing_article_2.authors.count(), 1) self.assertEqual( writing_article_2.authors.filter( username=settings.ZDS_APP["member"] ["external_account"]).count(), 0) # topics, gallery and PMs: self.assertEqual( Topic.objects.filter(author__username=user.user.username).count(), 0) self.assertEqual( Post.objects.filter(author__username=user.user.username).count(), 0) self.assertEqual( Post.objects.filter(editor__username=user.user.username).count(), 0) self.assertEqual( PrivatePost.objects.filter( author__username=user.user.username).count(), 0) self.assertEqual( PrivateTopic.objects.filter( author__username=user.user.username).count(), 0) self.assertIsNotNone(Topic.objects.get(pk=authored_topic.pk)) self.assertIsNotNone(PrivateTopic.objects.get(pk=private_topic.pk)) self.assertIsNotNone(Gallery.objects.get(pk=alone_gallery.pk)) self.assertEquals(alone_gallery.get_linked_users().count(), 1) self.assertEquals(shared_gallery.get_linked_users().count(), 1) self.assertEquals( UserGallery.objects.filter(user=user.user).count(), 0) self.assertEquals( CommentVote.objects.filter(user=user.user, positive=True).count(), 0) self.assertEquals( Post.objects.filter(pk=upvoted_answer.id).first().like, 0) # zep 12, published contents and beta self.assertIsNotNone( PublishedContent.objects.filter( content__pk=published_tutorial_alone.pk).first()) self.assertIsNotNone( PublishedContent.objects.filter( content__pk=published_tutorial_2.pk).first()) self.assertTrue( Topic.objects.get(pk=beta_content.beta_topic.pk).is_locked) self.assertFalse( Topic.objects.get(pk=beta_content_2.beta_topic.pk).is_locked) # check API self.assertEqual(Application.objects.count(), 0) self.assertEqual(AccessToken.objects.count(), 0)
class ContentReactionKarmaAPITest(TutorialTestMixin, APITestCase): def setUp(self): self.client = APIClient() caches[extensions_api_settings.DEFAULT_USE_CACHE].clear() self.content = PublishedContentFactory() self.content.save() def test_failure_reaction_karma_with_client_unauthenticated(self): author = ProfileFactory() reaction = ContentReactionFactory(author=author.user, position=1, related_content=self.content, pubdate=datetime.datetime.now()) response = self.client.put( reverse("api:content:reaction-karma", args=(reaction.pk, ))) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) def tearDown(self): if os.path.isdir(settings.ZDS_APP["content"]["repo_private_path"]): shutil.rmtree(settings.ZDS_APP["content"]["repo_private_path"]) if os.path.isdir(settings.ZDS_APP["content"]["repo_public_path"]): shutil.rmtree(settings.ZDS_APP["content"]["repo_public_path"]) if os.path.isdir(settings.MEDIA_ROOT): shutil.rmtree(settings.MEDIA_ROOT) def test_failure_reaction_karma_with_sanctioned_user(self): author = ProfileFactory() reaction = ContentReactionFactory(author=author.user, position=1, related_content=self.content) profile = ProfileFactory() profile.can_read = False profile.can_write = False profile.save() self.assertTrue( self.client.login(username=profile.user.username, password="******")) response = self.client.put( reverse("api:content:reaction-karma", args=(reaction.pk, ))) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_failure_reaction_karma_with_a_message_not_found(self): response = self.client.get( reverse("api:content:reaction-karma", args=(99999, ))) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) def test_success_reaction_karma_like(self): author = ProfileFactory() reaction = ContentReactionFactory(author=author.user, position=1, related_content=self.content) profile = ProfileFactory() self.assertTrue( self.client.login(username=profile.user.username, password="******")) response = self.client.put( reverse("api:content:reaction-karma", args=(reaction.pk, )), {"vote": "like"}) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue( CommentVote.objects.filter(user=profile.user, comment=reaction, positive=True).exists()) def test_success_reaction_karma_dislike(self): author = ProfileFactory() reaction = ContentReactionFactory(author=author.user, position=1, related_content=self.content) profile = ProfileFactory() self.assertTrue( self.client.login(username=profile.user.username, password="******")) response = self.client.put( reverse("api:content:reaction-karma", args=(reaction.pk, )), {"vote": "dislike"}) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue( CommentVote.objects.filter(user=profile.user, comment=reaction, positive=False).exists()) def test_success_reaction_karma_neutral(self): author = ProfileFactory() reaction = ContentReactionFactory(author=author.user, position=1, related_content=self.content) profile = ProfileFactory() vote = CommentVote(user=profile.user, comment=reaction, positive=True) vote.save() self.assertTrue(CommentVote.objects.filter(pk=vote.pk).exists()) self.assertTrue( self.client.login(username=profile.user.username, password="******")) response = self.client.put( reverse("api:content:reaction-karma", args=(reaction.pk, )), {"vote": "neutral"}) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertFalse(CommentVote.objects.filter(pk=vote.pk).exists()) def test_success_reaction_karma_like_already_disliked(self): author = ProfileFactory() reaction = ContentReactionFactory(author=author.user, position=1, related_content=self.content) profile = ProfileFactory() vote = CommentVote(user=profile.user, comment=reaction, positive=False) vote.save() self.assertTrue( self.client.login(username=profile.user.username, password="******")) response = self.client.put( reverse("api:content:reaction-karma", args=(reaction.pk, )), {"vote": "like"}) vote.refresh_from_db() self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue(vote.positive) def test_get_content_reaction_voters(self): author = ProfileFactory() profile = ProfileFactory() profile2 = ProfileFactory() upvoted_reaction = ContentReactionFactory(author=author.user, position=2, related_content=self.content) upvoted_reaction.like += 2 upvoted_reaction.save() CommentVote.objects.create(user=profile.user, comment=upvoted_reaction, positive=True) downvoted_reaction = ContentReactionFactory( author=author.user, position=3, related_content=self.content) downvoted_reaction.dislike += 2 downvoted_reaction.save() anon_limit = CommentVote.objects.create(user=profile.user, comment=downvoted_reaction, positive=False) CommentVote.objects.create(user=profile2.user, comment=upvoted_reaction, positive=True) CommentVote.objects.create(user=profile2.user, comment=downvoted_reaction, positive=False) equal_reaction = ContentReactionFactory(author=author.user, position=4, related_content=self.content) equal_reaction.like += 1 equal_reaction.dislike += 1 equal_reaction.save() CommentVote.objects.create(user=profile.user, comment=equal_reaction, positive=True) CommentVote.objects.create(user=profile2.user, comment=equal_reaction, positive=False) self.assertTrue( self.client.login(username=profile.user.username, password="******")) # on first message we should see 2 likes and 0 anonymous response = self.client.get( reverse("api:content:reaction-karma", args=[upvoted_reaction.pk])) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(2, len(response.data["like"]["users"])) self.assertEqual(0, len(response.data["dislike"]["users"])) self.assertEqual(2, response.data["like"]["count"]) self.assertEqual(0, response.data["dislike"]["count"]) # on second message we should see 2 dislikes and 0 anonymous response = self.client.get( reverse("api:content:reaction-karma", args=[downvoted_reaction.pk])) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(0, len(response.data["like"]["users"])) self.assertEqual(2, len(response.data["dislike"]["users"])) self.assertEqual(0, response.data["like"]["count"]) self.assertEqual(2, response.data["dislike"]["count"]) # on third message we should see 1 like and 1 dislike and 0 anonymous response = self.client.get( reverse("api:content:reaction-karma", args=[equal_reaction.pk])) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(1, len(response.data["like"]["users"])) self.assertEqual(1, len(response.data["dislike"]["users"])) self.assertEqual(1, response.data["like"]["count"]) self.assertEqual(1, response.data["dislike"]["count"]) # Now we change the settings to keep anonymous the first [dis]like settings.VOTES_ID_LIMIT = anon_limit.pk # and we run the same tests # on first message we should see 1 like and 1 anonymous response = self.client.get( reverse("api:content:reaction-karma", args=[upvoted_reaction.pk])) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(1, len(response.data["like"]["users"])) self.assertEqual(0, len(response.data["dislike"]["users"])) self.assertEqual(2, response.data["like"]["count"]) self.assertEqual(0, response.data["dislike"]["count"]) # on second message we should see 1 dislikes and 1 anonymous response = self.client.get( reverse("api:content:reaction-karma", args=[downvoted_reaction.pk])) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(0, len(response.data["like"]["users"])) self.assertEqual(1, len(response.data["dislike"]["users"])) self.assertEqual(0, response.data["like"]["count"]) self.assertEqual(2, response.data["dislike"]["count"]) # on third message we should see 1 like and 1 dislike and 0 anonymous response = self.client.get( reverse("api:content:reaction-karma", args=[equal_reaction.pk])) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(1, len(response.data["like"]["users"])) self.assertEqual(1, len(response.data["dislike"]["users"])) self.assertEqual(1, response.data["like"]["count"]) self.assertEqual(1, response.data["dislike"]["count"])
def test_boosts(self): """Check if boosts are doing their job""" if not self.manager.connected_to_es: return # 1. Create topics (with identical titles), posts (with identical texts), an article and a tuto text = 'test' topic_1_solved_sticky = TopicFactory(forum=self.forum, author=self.user) topic_1_solved_sticky.title = text topic_1_solved_sticky.subtitle = '' topic_1_solved_sticky.is_solved = True topic_1_solved_sticky.is_sticky = True topic_1_solved_sticky.save() post_1 = PostFactory(topic=topic_1_solved_sticky, author=self.user, position=1) post_1.text = post_1.text_html = text post_1.save() post_2_useful = PostFactory(topic=topic_1_solved_sticky, author=self.user, position=2) post_2_useful.text = post_2_useful.text_html = text post_2_useful.is_useful = True post_2_useful.like = 5 post_2_useful.dislike = 2 # l/d ratio above 1 post_2_useful.save() topic_2_locked = TopicFactory(forum=self.forum, author=self.user, title=text) topic_2_locked.title = text topic_2_locked.subtitle = '' topic_2_locked.is_locked = True topic_2_locked.save() post_3_ld_below_1 = PostFactory(topic=topic_2_locked, author=self.user, position=1) post_3_ld_below_1.text = post_3_ld_below_1.text_html = text post_3_ld_below_1.like = 2 post_3_ld_below_1.dislike = 5 # l/d ratio below 1 post_3_ld_below_1.save() tuto = PublishableContentFactory(type='TUTORIAL') tuto_draft = tuto.load_version() tuto.title = text tuto.authors.add(self.user) tuto.save() tuto_draft.repo_update_top_container(text, tuto.slug, text, text) chapter1 = ContainerFactory(parent=tuto_draft, db_object=tuto) chapter1.repo_update(text, 'Who cares ?', 'Same here') ExtractFactory(container=chapter1, db_object=tuto) published_tuto = publish_content(tuto, tuto_draft, is_major_update=True) tuto.sha_public = tuto_draft.current_version tuto.sha_draft = tuto_draft.current_version tuto.public_version = published_tuto tuto.save() article = PublishedContentFactory(type='ARTICLE', title=text) published_article = PublishedContent.objects.get(content_pk=article.pk) opinion_not_picked = PublishedContentFactory(type='OPINION', title=text) published_opinion_not_picked = PublishedContent.objects.get( content_pk=opinion_not_picked.pk) opinion_picked = PublishedContentFactory(type='OPINION', title=text) opinion_picked.sha_picked = opinion_picked.sha_draft opinion_picked.date_picked = datetime.datetime.now() opinion_picked.save() published_opinion_picked = PublishedContent.objects.get( content_pk=opinion_picked.pk) for model in self.indexable: if model is FakeChapter: continue self.manager.es_bulk_indexing_of_model(model) self.manager.refresh_index() self.assertEqual( len( self.manager.setup_search(Search().query( MatchAll())).execute()), 10) # 2. Reset all boosts to 1 for doc_type in settings.ZDS_APP['search']['boosts']: for key in settings.ZDS_APP['search']['boosts'][doc_type]: settings.ZDS_APP['search']['boosts'][doc_type][key] = 1.0 # 3. Test posts result = self.client.get(reverse('search:query') + '?q=' + text + '&models=' + Post.get_es_document_type(), follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 3) # score are equals without boost: self.assertTrue(response[0].meta.score == response[1].meta.score == response[2].meta.score) settings.ZDS_APP['search']['boosts']['post']['if_first'] = 2.0 result = self.client.get(reverse('search:query') + '?q=' + text + '&models=' + Post.get_es_document_type(), follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 3) self.assertTrue(response[0].meta.score == response[1].meta.score > response[2].meta.score) self.assertEqual(response[2].meta.id, str( post_2_useful.pk)) # post 2 is the only one not first settings.ZDS_APP['search']['boosts']['post']['if_first'] = 1.0 settings.ZDS_APP['search']['boosts']['post']['if_useful'] = 2.0 result = self.client.get(reverse('search:query') + '?q=' + text + '&models=' + Post.get_es_document_type(), follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 3) self.assertTrue(response[0].meta.score > response[1].meta.score == response[2].meta.score) self.assertEqual(response[0].meta.id, str(post_2_useful.pk)) # post 2 is useful settings.ZDS_APP['search']['boosts']['post']['if_useful'] = 1.0 settings.ZDS_APP['search']['boosts']['post']['ld_ratio_above_1'] = 2.0 result = self.client.get(reverse('search:query') + '?q=' + text + '&models=' + Post.get_es_document_type(), follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 3) self.assertTrue(response[0].meta.score > response[1].meta.score == response[2].meta.score) self.assertEqual(response[0].meta.id, str( post_2_useful.pk)) # post 2 have a l/d ratio of 5/2 settings.ZDS_APP['search']['boosts']['post']['ld_ratio_above_1'] = 1.0 settings.ZDS_APP['search']['boosts']['post'][ 'ld_ratio_below_1'] = 2.0 # no one would do that in real life result = self.client.get(reverse('search:query') + '?q=' + text + '&models=' + Post.get_es_document_type(), follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 3) self.assertTrue(response[0].meta.score > response[1].meta.score == response[2].meta.score) self.assertEqual(response[0].meta.id, str( post_3_ld_below_1.pk)) # post 3 have a l/d ratio of 2/5 settings.ZDS_APP['search']['boosts']['post']['ld_ratio_below_1'] = 1.0 # 4. Test topics result = self.client.get(reverse('search:query') + '?q=' + text + '&models=' + Topic.get_es_document_type(), follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 2) # score are equals without boost: self.assertTrue(response[0].meta.score == response[1].meta.score) settings.ZDS_APP['search']['boosts']['topic']['if_sticky'] = 2.0 result = self.client.get(reverse('search:query') + '?q=' + text + '&models=' + Topic.get_es_document_type(), follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 2) self.assertTrue(response[0].meta.score > response[1].meta.score) self.assertEqual(response[0].meta.id, str(topic_1_solved_sticky.pk)) # topic 1 is sticky settings.ZDS_APP['search']['boosts']['topic']['if_sticky'] = 1.0 settings.ZDS_APP['search']['boosts']['topic']['if_solved'] = 2.0 result = self.client.get(reverse('search:query') + '?q=' + text + '&models=' + Topic.get_es_document_type(), follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 2) self.assertTrue(response[0].meta.score > response[1].meta.score) self.assertEqual(response[0].meta.id, str(topic_1_solved_sticky.pk)) # topic 1 is solved settings.ZDS_APP['search']['boosts']['topic']['if_solved'] = 1.0 settings.ZDS_APP['search']['boosts']['topic'][ 'if_locked'] = 2.0 # no one would do that in real life result = self.client.get(reverse('search:query') + '?q=' + text + '&models=' + Topic.get_es_document_type(), follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 2) self.assertTrue(response[0].meta.score > response[1].meta.score) self.assertEqual(response[0].meta.id, str(topic_2_locked.pk)) # topic 2 is locked settings.ZDS_APP['search']['boosts']['topic'][ 'if_locked'] = 1.0 # no one would do that in real life # 5. Test published contents result = self.client.get(reverse('search:query') + '?q=' + text + '&models=content', follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 5) # score are equals without boost: self.assertTrue( response[0].meta.score == response[1].meta.score == response[2]. meta.score == response[3].meta.score == response[4].meta.score) settings.ZDS_APP['search']['boosts']['publishedcontent'][ 'if_article'] = 2.0 result = self.client.get(reverse('search:query') + '?q=' + text + '&models=content', follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 5) self.assertTrue(response[0].meta.score > response[1].meta.score) self.assertEqual(response[0].meta.id, str(published_article.pk)) # obvious settings.ZDS_APP['search']['boosts']['publishedcontent'][ 'if_article'] = 1.0 settings.ZDS_APP['search']['boosts']['publishedcontent'][ 'if_tutorial'] = 2.0 result = self.client.get(reverse('search:query') + '?q=' + text + '&models=content', follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 5) self.assertTrue(response[0].meta.score > response[1].meta.score) self.assertEqual(response[0].meta.id, str(published_tuto.pk)) # obvious settings.ZDS_APP['search']['boosts']['publishedcontent'][ 'if_tutorial'] = 1.0 settings.ZDS_APP['search']['boosts']['publishedcontent'][ 'if_opinion'] = 2.0 settings.ZDS_APP['search']['boosts']['publishedcontent'][ 'if_opinion_not_picked'] = 4.0 # Note: in "real life", unpicked opinion would get a boost < 1. result = self.client.get(reverse('search:query') + '?q=' + text + '&models=content', follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 5) self.assertTrue(response[0].meta.score > response[1].meta.score > response[2].meta.score) self.assertEqual( response[0].meta.id, str(published_opinion_not_picked.pk)) # unpicked opinion got first self.assertEqual(response[1].meta.id, str(published_opinion_picked.pk)) settings.ZDS_APP['search']['boosts']['publishedcontent'][ 'if_opinion'] = 1.0 settings.ZDS_APP['search']['boosts']['publishedcontent'][ 'if_opinion_not_picked'] = 1.0 settings.ZDS_APP['search']['boosts']['publishedcontent'][ 'if_medium_or_big_tutorial'] = 2.0 result = self.client.get(reverse('search:query') + '?q=' + text + '&models=content', follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 5) self.assertTrue(response[0].meta.score > response[1].meta.score) self.assertEqual(response[0].meta.id, str(published_tuto.pk)) # obvious settings.ZDS_APP['search']['boosts']['publishedcontent'][ 'if_medium_or_big_tutorial'] = 1.0 # 6. Test global boosts # NOTE: score are NOT the same for all documents, no matter how hard it tries to, small differences exists for model in self.indexable: # set a huge number to overcome the small differences: settings.ZDS_APP['search']['boosts'][ model.get_es_document_type()]['global'] = 10.0 result = self.client.get(reverse('search:query') + '?q=' + text, follow=False) self.assertEqual(result.status_code, 200) response = result.context['object_list'].execute() self.assertEqual(response.hits.total, 10) self.assertEqual(response[0].meta.doc_type, model.get_es_document_type()) # obvious settings.ZDS_APP['search']['boosts'][ model.get_es_document_type()]['global'] = 1.0
def test_toggle(self): author = ProfileFactory() login_check = self.client.login(username=author.user.username, password='******') self.assertTrue(login_check) # create topic and toggle request category = CategoryFactory(position=1) forum = ForumFactory(category=category, position_in_category=1) topic = TopicFactory(forum=forum, author=author.user) response = self.client.post(reverse('topic-edit') + '?topic={}'.format(topic.pk), {'request_featured': 1}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(200, response.status_code) self.assertEqual(FeaturedRequested.objects.count(), 1) r = FeaturedRequested.objects.last() self.assertEqual(r.content_object, topic) self.assertIn(author.user, r.users_voted.all()) # lock topic: cannot vote anymore topic.is_locked = True topic.save() response = self.client.post(reverse('topic-edit') + '?topic={}'.format(topic.pk), {'request_featured': 1}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(403, response.status_code) self.assertEqual(FeaturedRequested.objects.count(), 1) # create tutorial and toggle request tutorial = PublishedContentFactory(author_list=[author.user]) gallery = GalleryFactory() image = ImageFactory(gallery=gallery) tutorial.image = image tutorial.save() response = self.client.post(reverse('content:request-featured', kwargs={'pk': tutorial.pk}), {'request_featured': 1}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(200, response.status_code) self.assertEqual(FeaturedRequested.objects.count(), 2) r = FeaturedRequested.objects.last() self.assertEqual(r.content_object, tutorial) self.assertIn(author.user, r.users_voted.all()) # create opinion: cannot toggle request! opinion = PublishedContentFactory(type='OPINION', author_list=[author.user]) gallery = GalleryFactory() image = ImageFactory(gallery=gallery) opinion.image = image opinion.save() response = self.client.post(reverse('content:request-featured', kwargs={'pk': opinion.pk}), {'request_featured': 1}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(403, response.status_code) self.assertEqual(FeaturedRequested.objects.count(), 2) # set tutorial as obsolete: cannot toggle tutorial.is_obsolete = True tutorial.save() response = self.client.post(reverse('content:request-featured', kwargs={'pk': tutorial.pk}), {'request_featured': 1}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(403, response.status_code) r = FeaturedRequested.objects.get(pk=r.pk) self.assertEqual(r.content_object, tutorial) self.assertIn(author.user, r.users_voted.all()) # reject tutorial proposition tutorial.is_obsolete = False # can vote again tutorial.save() r = FeaturedRequested.objects.get(pk=r.pk) r.rejected = True r.save() # upvote with other user other = ProfileFactory() login_check = self.client.login(username=other.user.username, password='******') self.assertTrue(login_check) response = self.client.post(reverse('content:request-featured', kwargs={'pk': tutorial.pk}), {'request_featured': 1}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(200, response.status_code) r = FeaturedRequested.objects.get(pk=r.pk) self.assertIn(other.user, r.users_voted.all()) self.assertFalse(r.rejected) # not rejected anymore # reject for good, cannot vote anymore! r.rejected_for_good = True r.save() response = self.client.post(reverse('content:request-featured', kwargs={'pk': tutorial.pk}), {'request_featured': 1}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(403, response.status_code) r = FeaturedRequested.objects.get(pk=r.pk) self.assertIn(other.user, r.users_voted.all())
class ContentReactionKarmaAPITest(TutorialTestMixin, APITestCase): def setUp(self): self.client = APIClient() caches[extensions_api_settings.DEFAULT_USE_CACHE].clear() self.content = PublishedContentFactory() self.content.save() def test_failure_reaction_karma_with_client_unauthenticated(self): author = ProfileFactory() reaction = ContentReactionFactory(author=author.user, position=1, related_content=self.content, pubdate=datetime.datetime.now()) response = self.client.put(reverse('api:content:reaction-karma', args=(reaction.pk,))) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) def tearDown(self): if os.path.isdir(settings.ZDS_APP['content']['repo_private_path']): shutil.rmtree(settings.ZDS_APP['content']['repo_private_path']) if os.path.isdir(settings.ZDS_APP['content']['repo_public_path']): shutil.rmtree(settings.ZDS_APP['content']['repo_public_path']) if os.path.isdir(settings.MEDIA_ROOT): shutil.rmtree(settings.MEDIA_ROOT) def test_failure_reaction_karma_with_sanctioned_user(self): author = ProfileFactory() reaction = ContentReactionFactory(author=author.user, position=1, related_content=self.content) profile = ProfileFactory() profile.can_read = False profile.can_write = False profile.save() self.assertTrue(self.client.login(username=profile.user.username, password='******')) response = self.client.put(reverse('api:content:reaction-karma', args=(reaction.pk,))) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_failure_reaction_karma_with_a_message_not_found(self): response = self.client.get(reverse('api:content:reaction-karma', args=(99999,))) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) def test_success_reaction_karma_like(self): author = ProfileFactory() reaction = ContentReactionFactory(author=author.user, position=1, related_content=self.content) profile = ProfileFactory() self.assertTrue(self.client.login(username=profile.user.username, password='******')) response = self.client.put(reverse('api:content:reaction-karma', args=(reaction.pk,)), {'vote': 'like'}) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue(CommentVote.objects.filter(user=profile.user, comment=reaction, positive=True).exists()) def test_success_reaction_karma_dislike(self): author = ProfileFactory() reaction = ContentReactionFactory(author=author.user, position=1, related_content=self.content) profile = ProfileFactory() self.assertTrue(self.client.login(username=profile.user.username, password='******')) response = self.client.put(reverse('api:content:reaction-karma', args=(reaction.pk,)), {'vote': 'dislike'}) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue(CommentVote.objects.filter(user=profile.user, comment=reaction, positive=False).exists()) def test_success_reaction_karma_neutral(self): author = ProfileFactory() reaction = ContentReactionFactory(author=author.user, position=1, related_content=self.content) profile = ProfileFactory() vote = CommentVote(user=profile.user, comment=reaction, positive=True) vote.save() self.assertTrue(CommentVote.objects.filter(pk=vote.pk).exists()) self.assertTrue(self.client.login(username=profile.user.username, password='******')) response = self.client.put(reverse('api:content:reaction-karma', args=(reaction.pk,)), {'vote': 'neutral'}) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertFalse(CommentVote.objects.filter(pk=vote.pk).exists()) def test_success_reaction_karma_like_already_disliked(self): author = ProfileFactory() reaction = ContentReactionFactory(author=author.user, position=1, related_content=self.content) profile = ProfileFactory() vote = CommentVote(user=profile.user, comment=reaction, positive=False) vote.save() self.assertTrue(self.client.login(username=profile.user.username, password='******')) response = self.client.put(reverse('api:content:reaction-karma', args=(reaction.pk,)), {'vote': 'like'}) vote.refresh_from_db() self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue(vote.positive) def test_get_content_reaction_voters(self): author = ProfileFactory() profile = ProfileFactory() profile2 = ProfileFactory() upvoted_reaction = ContentReactionFactory(author=author.user, position=2, related_content=self.content) upvoted_reaction.like += 2 upvoted_reaction.save() CommentVote.objects.create(user=profile.user, comment=upvoted_reaction, positive=True) downvoted_reaction = ContentReactionFactory(author=author.user, position=3, related_content=self.content) downvoted_reaction.dislike += 2 downvoted_reaction.save() anon_limit = CommentVote.objects.create(user=profile.user, comment=downvoted_reaction, positive=False) CommentVote.objects.create(user=profile2.user, comment=upvoted_reaction, positive=True) CommentVote.objects.create(user=profile2.user, comment=downvoted_reaction, positive=False) equal_reaction = ContentReactionFactory(author=author.user, position=4, related_content=self.content) equal_reaction.like += 1 equal_reaction.dislike += 1 equal_reaction.save() CommentVote.objects.create(user=profile.user, comment=equal_reaction, positive=True) CommentVote.objects.create(user=profile2.user, comment=equal_reaction, positive=False) self.assertTrue(self.client.login(username=profile.user.username, password='******')) # on first message we should see 2 likes and 0 anonymous response = self.client.get(reverse('api:content:reaction-karma', args=[upvoted_reaction.pk])) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(2, len(response.data['like']['users'])) self.assertEqual(0, len(response.data['dislike']['users'])) self.assertEqual(2, response.data['like']['count']) self.assertEqual(0, response.data['dislike']['count']) # on second message we should see 2 dislikes and 0 anonymous response = self.client.get(reverse('api:content:reaction-karma', args=[downvoted_reaction.pk])) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(0, len(response.data['like']['users'])) self.assertEqual(2, len(response.data['dislike']['users'])) self.assertEqual(0, response.data['like']['count']) self.assertEqual(2, response.data['dislike']['count']) # on third message we should see 1 like and 1 dislike and 0 anonymous response = self.client.get(reverse('api:content:reaction-karma', args=[equal_reaction.pk])) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(1, len(response.data['like']['users'])) self.assertEqual(1, len(response.data['dislike']['users'])) self.assertEqual(1, response.data['like']['count']) self.assertEqual(1, response.data['dislike']['count']) # Now we change the settings to keep anonymous the first [dis]like settings.VOTES_ID_LIMIT = anon_limit.pk # and we run the same tests # on first message we should see 1 like and 1 anonymous response = self.client.get(reverse('api:content:reaction-karma', args=[upvoted_reaction.pk])) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(1, len(response.data['like']['users'])) self.assertEqual(0, len(response.data['dislike']['users'])) self.assertEqual(2, response.data['like']['count']) self.assertEqual(0, response.data['dislike']['count']) # on second message we should see 1 dislikes and 1 anonymous response = self.client.get(reverse('api:content:reaction-karma', args=[downvoted_reaction.pk])) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(0, len(response.data['like']['users'])) self.assertEqual(1, len(response.data['dislike']['users'])) self.assertEqual(0, response.data['like']['count']) self.assertEqual(2, response.data['dislike']['count']) # on third message we should see 1 like and 1 dislike and 0 anonymous response = self.client.get(reverse('api:content:reaction-karma', args=[equal_reaction.pk])) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(1, len(response.data['like']['users'])) self.assertEqual(1, len(response.data['dislike']['users'])) self.assertEqual(1, response.data['like']['count']) self.assertEqual(1, response.data['dislike']['count'])