def test_forum_search_only_topics(self): """ If the "search only topics" checkbox is ticked, matching content elsewhere should not return any result. """ post1 = PostFactory(subject="497jk1sav", text="497jk1sav") forum = post1.topic.forum post2 = PostFactory(topic__subject="497jk1sav", topic__forum=forum) user = UserFactory() assign_perm("can_read_forum", user, forum) # Index the post in Elasticsearch call_command("rebuild_index", interactive=False) self.client.force_login(user) # Searching without the "search_topics" flag returns post1 because it contains # the search string in its text body. response = self.client.get("/forum/search/?q=497jk") self.assertContains(response, "Your search has returned <b>1</b> result", html=True) self.assertContains(response, post1.topic.slug) # Searching with the "search_topics" flag returns post2 because it contains # the search string in the related topic subject. response = self.client.get("/forum/search/?q=497jk&search_topics=on") self.assertContains(response, "Your search has returned <b>1</b> result", html=True) self.assertContains(response, post2.topic.slug)
def test_forum_search_with_unautorized_forum_from_other_lti_context(self): """ Try to search in a forum that is not part of our LTIContext by submitting in the search form a forum from another LTIContext. """ user = UserFactory() lti_context = LTIContextFactory(lti_consumer=user.lti_consumer) lti_context2 = LTIContextFactory(lti_consumer=user.lti_consumer) forum = ForumFactory() forum2 = ForumFactory() forum.lti_contexts.add(lti_context) forum2.lti_contexts.add(lti_context2) PostFactory( topic=TopicFactory(forum=forum), text="Good morning world", ) PostFactory( topic=TopicFactory(forum=forum2), text="Hello world", ) # Index posts in Elasticsearch call_command("rebuild_index", interactive=False) # Connects and gets acces to the forum self.client.force_login(user, "ashley.auth.backend.LTIBackend") assign_perm("can_read_forum", user, forum) assign_perm("can_read_forum", user, forum2) session = self.client.session session[SESSION_LTI_CONTEXT_ID] = lti_context.id session.save() form = SearchForm(user=user, lti_context=lti_context) # Checks that only the forum that is allowed is proposed as choice self.assertEqual( form.fields["search_forums"].choices, [(forum.id, "{} {}".format("-" * forum.margin_level, forum.name))], ) # Despite that, we force the request on the forum that is not allowed response = self.client.get( f"/forum/search/?q=world&search_forums={forum2.id}") self.assertEqual(response.status_code, 200) # Controls that we get an error and the search is not executed self.assertContains( response, f"Select a valid choice. {forum2.id} is not one of the available choices.", html=True, ) # Valid request, we search on the forum that is allowed, we get only one result # as forum2 is ignored response = self.client.get( f"/forum/search/?q=world&search_forums={forum.id}") self.assertEqual(response.status_code, 200) self.assertContains(response, "Your search has returned <b>1</b> result", html=True)
def test_forum_search_post_poster_restrict_forums(self): """ Forum searches can be restricted to only one forum when searching for a specific poster. """ post1 = PostFactory() post2 = PostFactory(poster=post1.poster, topic__forum=post1.topic.forum) post3 = PostFactory(poster=post1.poster) user = UserFactory() assign_perm("can_read_forum", user, post1.topic.forum) assign_perm("can_read_forum", user, post3.topic.forum) # Index the post in Elasticsearch call_command("rebuild_index", interactive=False) self.client.force_login(user) response = self.client.get( f"/forum/search/?q=&search_poster_name={post1.poster.public_username}\ &search_forums={post1.topic.forum.pk}") self.assertContains(response, "Your search has returned <b>2</b> results", html=True) self.assertContains(response, post1.subject) self.assertContains(response, post2.subject) response = self.client.get( f"/forum/search/?q=&search_poster_name={post1.poster.public_username}\ &search_forums={post3.topic.forum.pk}") self.assertContains(response, "Your search has returned <b>1</b> result", html=True) self.assertContains(response, post3.subject)
def _get_url_list_topic_with_three_topics(self): """Creates a forum with three topics and a user to access the forum that has the permission to access it. It's a shortcut used in all the tests below.""" forum = ForumFactory() # create 3 topics with distinct subject, views_count and date PostFactory( topic=TopicFactory(forum=forum, views_count=9), subject="TOPIC B the eldest with 9 views_count", ) PostFactory( topic=TopicFactory(forum=forum, views_count=6), subject="TOPIC A created second with 6 views_count", ) PostFactory( topic=TopicFactory(forum=forum, views_count=12), subject="TOPIC C the newest one with 12 views_count", ) user = UserFactory() assign_perm("can_read_forum", user, forum) self.client.force_login(user) # Setup url_list_topic = f"/forum/forum/{forum.slug}-{forum.pk}/" return forum, url_list_topic
def test_forum_search_several_forums_restrict_to_one(self): """Forum searches can be restricted to only one forum.""" post1 = PostFactory(text="Hello world", subject="a5g3g6k75") post2 = PostFactory(text="Good morning world", subject="497jk1sav") user = UserFactory() assign_perm("can_read_forum", user, post1.topic.forum) assign_perm("can_read_forum", user, post2.topic.forum) # Index the post in Elasticsearch call_command("rebuild_index", interactive=False) self.client.force_login(user) response = self.client.get( f"/forum/search/?q=world&search_forums={post1.topic.forum.pk}") self.assertContains(response, "Your search has returned <b>1</b> result", html=True) self.assertContains(response, post1.subject) response = self.client.get( f"/forum/search/?q=world&search_forums={post2.topic.forum.pk}") self.assertContains(response, "Your search has returned <b>1</b> result", html=True) self.assertContains(response, post2.subject)
def test_testing_topic_announce(self): """Controls topics that are of type announcement don't have sorted options""" # Creates posts for announcement topics forum = ForumFactory() PostFactory(topic=TopicFactory(forum=forum, type=Topic.TOPIC_ANNOUNCE)) PostFactory(topic=TopicFactory(forum=forum, type=Topic.TOPIC_ANNOUNCE)) user = UserFactory() assign_perm("can_read_forum", user, forum) self.client.force_login(user) response = self.client.get(f"/forum/forum/{forum.slug}-{forum.pk}/") html = lxml.html.fromstring(response.content) # Select the header block of the announcement block, the first block announce_block = str( etree.tostring(html.cssselect(".topiclist .card-header")[0])) # Controls that announce_block is about announcements and not topics self.assertIn("Announcements", announce_block) self.assertNotIn("Topics", announce_block) self.assertIn("Replies", announce_block) self.assertIn("Views", announce_block) self.assertIn("Last post", announce_block) # There's no sortable informations self.assertNotIn("sortable sorted", announce_block) # There's no column that has a sorting link on self.assertNotIn("<a href=", announce_block) # There's no toggle sorting self.assertNotIn("Toggle sorting", announce_block)
def test_testing_topic_announce_dont_get_ordered(self): """ Controls topics that are of type announcement don't get ordered if sorting is submitted in url. Orders are only applied to Topic posts. """ forum = ForumFactory() user = UserFactory() assign_perm("can_read_forum", user, forum) self.client.force_login(user) # Creates posts for announcement topics topicAnnounce1 = TopicFactory(forum=forum, type=Topic.TOPIC_ANNOUNCE, views_count=100) topicAnnounce2 = TopicFactory(forum=forum, type=Topic.TOPIC_ANNOUNCE, views_count=200) PostFactory( topic=topicAnnounce1, subject="TOPIC A TYPE ANNOUNCED", ) PostFactory( topic=topicAnnounce2, subject="TOPIC B TYPE ANNOUNCED", ) # Post of topicAnnounce2 has been created last, it should be the first one on the list self.assertLess(topicAnnounce1.last_post_on, topicAnnounce2.last_post_on) # Orders on column view_post response = self.client.get( f"/forum/forum/{forum.slug}-{forum.pk}/?o=2") # Orders is respected on default creation order self.assertContentBefore(response, "TOPIC B TYPE ANNOUNCED", "TOPIC A TYPE ANNOUNCED") # Reverses order response = self.client.get( f"/forum/forum/{forum.slug}-{forum.pk}/?o=-2") # Orders of announcement topics stays the same self.assertContentBefore(response, "TOPIC B TYPE ANNOUNCED", "TOPIC A TYPE ANNOUNCED") # Orders on replies column response = self.client.get( f"/forum/forum/{forum.slug}-{forum.pk}/?o=-1") # Shows order is respected on default creation order self.assertContentBefore(response, "TOPIC B TYPE ANNOUNCED", "TOPIC A TYPE ANNOUNCED") # Reverses order response = self.client.get( f"/forum/forum/{forum.slug}-{forum.pk}/?o=1") # Orders of announcement topics stays the same self.assertContentBefore(response, "TOPIC B TYPE ANNOUNCED", "TOPIC A TYPE ANNOUNCED")
def test_forum_search_authorized(self): """A user with the rights to read a forum should be able to search.""" created_on = datetime(2020, 10, 5, 8, 13, tzinfo=timezone.utc) with mock.patch.object(timezone, "now", return_value=created_on): post = PostFactory() poster = post.poster user = UserFactory() assign_perm("can_read_forum", user, post.topic.forum) # Index the post in Elasticsearch call_command("rebuild_index", interactive=False) self.client.force_login(user) response = self.client.get("/forum/search/?q=*") # Check the format of the results self.assertContains(response, "Your search has returned <b>1</b> result", html=True) self.assertContains(response, post.subject) self.assertContains(response, post.topic.subject) self.assertContains( response, f'By: <a href="/forum/member/profile/{poster.id:d}/">{poster.public_username:s}</a>', ) self.assertContains( response, "on Oct. 5, 2020, 8:13 a.m.", )
def test_forum_search_archived_forum(self): """Content of an archived forum should not be indexed""" post = PostFactory(text="yah7Eo0A") forum = post.topic.forum user = UserFactory() assign_perm("can_read_forum", user, forum) # Index the post in Elasticsearch call_command("rebuild_index", interactive=False) self.client.force_login(user) response = self.client.get("/forum/search/?q=yah7") self.assertContains(response, "Your search has returned <b>1</b> result", html=True) self.assertContains(response, post, html=True) # Archive the forum forum.archived = True forum.save() # Re-build the index call_command("rebuild_index", interactive=False) # The same search should return nothing response = self.client.get("/forum/search/?q=yah7") self.assertContains(response, "Your search has returned <b>0</b> results", html=True)
def test_access_topic_reply_form(self): """ The post form in a created topic is overridden from django_machina, we control it still loads as expected """ user = UserFactory(lti_consumer=self.lti_consumer) assign_perm("can_read_forum", user, self.forum) assign_perm("can_reply_to_topics", user, self.forum) # Set up topic and initial post topic = TopicFactory(forum=self.forum, poster=user) PostFactory(topic=topic) # authenticate the user related to consumer self.client.force_login(user) url_topic_reply = ( f"/forum/forum/{self.forum.slug}-{self.forum.pk}" f"/topic/{topic.slug}-{topic.pk}/post/create/" ) # Run response = self.client.get(url_topic_reply, follow=True) # Check assert response.status_code == 200
def test_forum_search_post_topic_partial(self): """ The topic subject is not directly indexed but Django Machina forces it with the post subject when creating the first post of a topic: # see: apps/forum_conversation/abstract_models.py#L314 So in the end, searching for a topic subject will return the first post as result. """ # First, let's secure Django Machina's overriding mechanism topic = TopicFactory(subject="5f3gh8ka1") forum = topic.forum self.assertEqual(topic.subject, "5f3gh8ka1") # When we create the first post for this topic... post = PostFactory(subject="497jk1sav", topic=topic) # The topic subject should be overriden topic.refresh_from_db() self.assertEqual(topic.subject, "497jk1sav") PostFactory(topic=topic) # Creating a second post does not change the topic subject again topic.refresh_from_db() self.assertEqual(topic.subject, "497jk1sav") # A third post in the same forum with a different topic PostFactory(topic__forum=forum) user = UserFactory() assign_perm("can_read_forum", user, forum) # Index the post in Elasticsearch call_command("rebuild_index", interactive=False) self.client.force_login(user) response = self.client.get("/forum/search/?q=497jk1sav") self.assertContains(response, "Your search has returned <b>1</b> result", html=True) self.assertContains( response, (f'<a href="/forum/forum/{forum.slug:s}-{forum.id:d}/topic/{topic.slug:s}-' f'{topic.id:d}/?post={ post.pk }#{ post.pk }" ' f'class="topic-name-link">{topic.subject:s}</a>'), html=True, )
def test_list_active_users_only_concerns_active_users(self): """ The form loads the list of active users for the current topic. We control that the list only concerns users that have the status active """ user1 = UserFactory( lti_consumer=self.lti_consumer, public_username="******", ) user2 = UserFactory( lti_consumer=self.lti_consumer, public_username="******", ) self.context.sync_user_groups(user1, ["student"]) self.context.sync_user_groups(user2, ["student"]) topic = TopicFactory(forum=self.forum, poster=user1) # controls form topic, the one loaded when there's no post form = TopicForm(user=user2, forum=self.forum, topic=topic) assert form.fields["content"].widget.attrs.get("mentions", None) is None # controls post topic PostFactory(topic=topic, poster=user1) form = PostForm(user=user2, forum=self.forum, topic=topic) assert form.fields["content"].widget.attrs["mentions"] == [ { "name": "Benoit", "user": user1.id, } ] # user1 becomes inactive user1.is_active = False user1.save() # Add another post to load the list in topic form PostFactory(topic=topic, poster=user1) # user3 loads the form for topic form = PostForm(user=user2, forum=self.forum, topic=topic) # We should only see user1 in the list of active users for this topic assert form.fields["content"].widget.attrs["mentions"] == [] # user3 loads the form for first post, topic form is loaded form = TopicForm(user=user2, forum=self.forum, topic=topic) # mention param exist now but it's empty assert form.fields["content"].widget.attrs["mentions"] == []
def test_forum_search_paginated_links(self): """ Check pagination has well formed links """ user = UserFactory() post = PostFactory(text="a5g3g6k75") PostFactory.create_batch(100, text="a5g3g6k75", topic=post.topic) assign_perm("can_read_forum", user, post.topic.forum) # Index 101 posts in Elasticsearch call_command("rebuild_index", interactive=False) self.client.force_login(user) response = self.client.get("/forum/search/?q=a5g3") self.assertContains(response, "Your search has returned <b>101</b> results", html=True) self.assertContains(response, post, html=True) # 20 results per page and 2 panels of pagination # check all li tags are well closed self.assertContains(response, '<li class="page-item">', 12) self.assertContains(response, '<li class="page-item active">', 2) self.assertContains(response, '<li class="page-item disabled">', 4) # check all links are well formed self.assertContains( response, '<li class="page-item active">' '<a href="?q=a5g3&page=1" class="page-link">1</a>' "</li>", ) for page in range(2, 6): self.assertContains(response, f"?q=a5g3&page={page}") self.assertContains( response, f'<li class="page-item"><a href="?q=a5g3&page={page}" ' f'class="page-link">{page}</a></li>', ) self.assertNotContains(response, "?q=a5g3&page=7")
def test_forum_search_anonymous(self): """Anonymous users should not get any results.""" PostFactory() # Index the post in Elasticsearch call_command("rebuild_index", interactive=False) response = self.client.get("/forum/search/?q=*") self.assertContains(response, "Your search has returned <b>0</b> results", html=True)
def test_params_form_user_current_topic(self): """ The form send forum and poster information to the editor """ user1 = UserFactory(lti_consumer=self.lti_consumer) user2 = UserFactory(lti_consumer=self.lti_consumer) self.context.sync_user_groups(user1, ["student"]) self.context.sync_user_groups(user1, ["student"]) # Set up topic and initial post topic = TopicFactory(forum=self.forum, poster=user1) PostFactory(topic=topic, poster=user1) PostFactory(topic=topic, poster=user2) # Load TopicForm form = TopicForm(user=user1, forum=self.forum, topic=topic) assert form.fields["content"].widget.attrs["forum"] == topic.forum.id # PostForm has the parameters as well form = PostForm(user=user2, forum=self.forum, topic=topic) assert form.fields["content"].widget.attrs["forum"] == topic.forum.id
def test_forum_search_unauthorized(self): """A user missing the rights to read a forum should not get any results.""" PostFactory() user = UserFactory() # Index the post in Elasticsearch call_command("rebuild_index", interactive=False) self.client.force_login(user) response = self.client.get("/forum/search/?q=*") self.assertContains(response, "Your search has returned <b>0</b> results", html=True)
def test_forum_search_restrict_poster_topic_forums(self): """Forum searches can be restricted to forums, topic names, and posters""" post1 = PostFactory(poster__public_username="******", subject="a1b2c3") # Same forum, different subject, same poster PostFactory(poster=post1.poster, topic__forum=post1.topic.forum, subject="d4e5f6") # Different forum, same subject, same poster post3 = PostFactory(poster=post1.poster, subject="a1b2c3") # Same forum, same subject, different poster PostFactory(topic__forum=post1.topic.forum, subject="a1b2c3") # Same forum, subject starts similarly, same poster post5 = PostFactory(poster=post1.poster, topic__forum=post1.topic.forum, subject="a1b2d4") user = UserFactory() assign_perm("can_read_forum", user, post1.topic.forum) assign_perm("can_read_forum", user, post3.topic.forum) # Index the post in Elasticsearch call_command("rebuild_index", interactive=False) self.client.force_login(user) response = self.client.get(f"/forum/search/?q=a1b2&search_topics=on\ &search_poster_name={post1.poster.public_username}\ &search_forums={post1.topic.forum.pk}") self.assertContains(response, "Your search has returned <b>2</b> results", html=True) self.assertContains(response, post1.topic.slug) self.assertContains(response, post5.topic.slug)
def test_list_active_users_only_concerns_users_with_approved_posts(self): """ The form loads the list of active users for the current topic. We control that the list only concerns users that have approved posts """ user1 = UserFactory( lti_consumer=self.lti_consumer, public_username="******", ) user2 = UserFactory( lti_consumer=self.lti_consumer, public_username="******", ) self.context.sync_user_groups(user1, ["student"]) self.context.sync_user_groups(user2, ["student"]) topic = TopicFactory(forum=self.forum, poster=user1) post = PostFactory(topic=topic, poster=user1) form = PostForm(user=user2, forum=self.forum, topic=topic) assert form.fields["content"].widget.attrs["mentions"] == [ { "name": "Benoit", "user": user1.id, } ] # Post of user1 gets unapproved post.approved = False post.save() # Load form from user2 form = PostForm( user=user2, forum=self.forum, topic=topic, ) # List of active users should be empty assert form.fields["content"].widget.attrs["mentions"] == []
def test_sorting_by_posts_count_desc(self): """Test sorting by posts count desc.""" forum, url_list_topic = self._get_url_list_topic_with_three_topics() topicA = forum.topics.get(subject__startswith="TOPIC A") topicB = forum.topics.get(subject__startswith="TOPIC B") topicC = forum.topics.get(subject__startswith="TOPIC C") # 2 extra posts in topic B PostFactory(topic=topicB) PostFactory(topic=topicB) # 1 extra posts in topic C PostFactory(topic=topicC) # Controls order of posts self.assertTrue( topicB.posts.count() > topicC.posts.count() > topicA.posts.count()) url = f"{url_list_topic}?o=-1" response = self.client.get(url) # Topic with the highest number of post should be first self.assertContentBefore(response, "TOPIC B", "TOPIC C") self.assertContentBefore(response, "TOPIC C", "TOPIC A") # Should have 1 sorted column and it should be descending self.assertContains(response, "sortable sorted descending", count=1) self.assertContains(response, "sortable sorted ascending", count=0) # Check we have expected links to order columns in html self.assertContains(response, '<a href="?o=-0">Topics</a>') self.assertContains(response, '<a href="?o=1">Replies</a>') self.assertContains( response, '<a href="?o=1" class="toggle descending" title="Toggle sorting"></a>', ) self.assertContains(response, '<a href="?o=-2">Views</a>') self.assertContains(response, '<a href="?o=-3">Last post</a>')
def test_forum_search_post_failure(self): """Searching for a word not present in post, topic or username should return no result.""" post = PostFactory(text="a5g3g6k75", subject="497jk1sav") user = UserFactory() assign_perm("can_read_forum", user, post.topic.forum) # Index the post in Elasticsearch call_command("rebuild_index", interactive=False) self.client.force_login(user) response = self.client.get("/forum/search/?q=blabla") self.assertContains(response, "Your search has returned <b>0</b> results", html=True)
def test_forum_search_several_forums_cross_search(self): """By default, forum searches span several forums.""" post1 = PostFactory(text="Hello world", subject="a5g3g6k75") post2 = PostFactory(text="Good morning world", subject="497jk1sav") user = UserFactory() assign_perm("can_read_forum", user, post1.topic.forum) assign_perm("can_read_forum", user, post2.topic.forum) # Index the post in Elasticsearch call_command("rebuild_index", interactive=False) self.client.force_login(user) response = self.client.get("/forum/search/?q=world") self.assertContains(response, "Your search has returned <b>2</b> results", html=True) self.assertContains(response, post1.subject) self.assertContains(response, post2.subject) # Search for the first post response = self.client.get("/forum/search/?q=hello") self.assertContains(response, "Your search has returned <b>1</b> result", html=True) self.assertContains(response, post1.subject) # Search for the second post response = self.client.get("/forum/search/?q=morning") self.assertContains(response, "Your search has returned <b>1</b> result", html=True) self.assertContains(response, post2.subject)
def test_forum_search_restrict_poster_name(self): """Forum searches can be restricted to a poster""" # Make sure public user names on post1 and post2 are orthogonal post1 = PostFactory(subject="x45g87", poster__public_username="******") forum = post1.topic.forum PostFactory(subject="x45g87", topic__forum=forum, poster__public_username="******") user = UserFactory() assign_perm("can_read_forum", user, forum) # Index the post in Elasticsearch call_command("rebuild_index", interactive=False) self.client.force_login(user) response = self.client.get( f"/forum/search/?q=x45g87&search_poster_name={post1.poster.public_username}" ) self.assertContains(response, "Your search has returned <b>1</b> result", html=True) self.assertContains(response, post1.poster.public_username)
def test_forum_search_post_poster_partial_public_username(self): """Searching for part of the poster public username should find the post.""" post = PostFactory(poster__public_username="******") user = UserFactory() assign_perm("can_read_forum", user, post.topic.forum) # Index the post in Elasticsearch call_command("rebuild_index", interactive=False) self.client.force_login(user) response = self.client.get( "/forum/search/?q=&search_poster_name=3vj9t") self.assertContains(response, "Your search has returned <b>1</b> result", html=True) self.assertContains(response, post.subject)
def test_forum_search_post_content_partial(self): """Searching for part of a word contained in the post content should find it.""" post = PostFactory(text="a5g3g6k75") user = UserFactory() assign_perm("can_read_forum", user, post.topic.forum) # Index the post in Elasticsearch call_command("rebuild_index", interactive=False) self.client.force_login(user) response = self.client.get("/forum/search/?q=a5g3") self.assertContains(response, "Your search has returned <b>1</b> result", html=True) self.assertContains(response, post, html=True)
def test_course_info_course_student_cant_locked(self): """ User is a student, he shouldn't see the CTA to lock the course and he can't lock a course using the url. As a student he can create new topic or new post. """ forum = self._connects("student") # A LTIContext and a Forum should have been created post = PostFactory(topic=TopicFactory(forum=forum)) url = f"/forum/forum/{forum.slug}-{forum.pk}/" response = self.client.get(url) url_topic_create = f"{url}topic/create/" # user is a student and he can create a new topic self.assertContains( response, f'<a href="{url_topic_create}" class="btn btn-primary btn-sm">' '<i class="fa fa-comments fa-lg"></i> New topic</a>', html=True, ) response = self.client.get(url_topic_create, follow=True) self.assertEqual(200, response.status_code) # user has no button to lock the course self.assertNotContains(response, "Lock forums") # user can answer a post url_topic = f"{url}topic/{post.topic.slug}-{post.topic.pk}/" response = self.client.get(url_topic, follow=True) url_topic_reply = f"{url_topic}post/create/" self.assertContains( response, f'<a href="{url_topic_reply}" class="btn btn-primary btn-sm">' '<i class="fa fa-comment fa-lg"></i> Post reply</a>', html=True, ) response = self.client.get(url_topic_reply, follow=True) self.assertEqual(200, response.status_code) # user can't access the view to lock the course response = self.client.get(f"/forum/admin/lock-course/{forum.id}/") self.assertEqual(403, response.status_code) # user can't post to activate the lock on the course response = self.client.post(f"/forum/admin/lock-course/{forum.id}/") self.assertEqual(403, response.status_code)
def test_forum_search_empty_public_username(self): """ A topic posted by a user that has not defined a public_username should be indexed with no error. """ user = UserFactory(public_username="") forum = ForumFactory() # Create a topic and a post topic = TopicFactory(subject="yahl2vooPh", poster=user, forum=forum) post = PostFactory(subject="dooV7ei3ju", topic=topic, poster=user) # Index the post in Elasticsearch call_command("rebuild_index", interactive=False) user2 = UserFactory() assign_perm("can_read_forum", user2, post.topic.forum) self.client.force_login(user2) response = self.client.get( f"/forum/search/?q=dooV7ei3ju&search_poster_name={post.poster.get_public_username()}\ &search_forums={post.topic.forum.pk}") self.assertContains(response, "Your search has returned <b>1</b> result", html=True) # Ensure that the default display name is present user_profile_url = reverse("forum_member:profile", kwargs={"pk": user.id}) self.assertContains(response, f'<a href="{user_profile_url}">Anonymous</a>', html=True) # Ensure that the default display name is not indexed response = self.client.get( f"/forum/search/?q=dooV7ei3ju&search_poster_name={post.poster.get_public_username()}\ &search_forums={post.topic.forum.pk}&search_poster_name=Anonymous" ) self.assertContains(response, "Your search has returned <b>0</b> results", html=True)
def test_testing_topic_is_sticky_stay_sticky_other_column_than_default( self): """ Request page with a sticky topic and check that the sticky topic is always the first result even if it's sorted on column other than default one. The order will be done on view counts column. """ forum, url_list_topic = self._get_url_list_topic_with_three_topics() # Creates a post for the sticky topic PostFactory( topic=TopicFactory(forum=forum, type=Topic.TOPIC_STICKY, views_count=7), subject="TOPIC STICKY ONE", ) topic12 = forum.topics.get(subject__contains="12 views_count") topic9 = forum.topics.get(subject__contains="9 views_count") topic6 = forum.topics.get(subject__contains="6 views_count") topicSticky = forum.topics.get(subject__startswith="TOPIC STICKY ONE") # Confirms that the sticky topic has neither max or lowest view_count self.assertGreater(topic12.views_count, topic9.views_count) self.assertGreater(topic9.views_count, topicSticky.views_count) self.assertGreater(topicSticky.views_count, topic6.views_count) # Orders on column view_post response = self.client.get(f"{url_list_topic}?o=2") # Sticky should stay first, we compare it with the max and the min views_count self.assertContentBefore(response, "TOPIC STICKY ONE", "12 views_count") self.assertContentBefore(response, "TOPIC STICKY ONE", "6 views_count") # Reverses the order and confirms sticky topic stays on top response = self.client.get(f"{url_list_topic}?o=-2") # Sticky should stay first, we compare it with the max and the min views_count self.assertContentBefore(response, "TOPIC STICKY ONE", "6 views_count") self.assertContentBefore(response, "TOPIC STICKY ONE", "12 views_count")
def test_testing_topic_is_sticky_stay_sticky_default_order(self): """ Request page with a sticky topic and check that the sticky topic is always the first result on default order """ forum, url_list_topic = self._get_url_list_topic_with_three_topics() # Creates a post for sticky topic PostFactory( topic=TopicFactory(forum=forum, type=Topic.TOPIC_STICKY), subject="TOPIC STICKY ONE", ) # Calls page with default order response = self.client.get(url_list_topic) topicC = forum.topics.get(subject__startswith="TOPIC C the newest") topicB = forum.topics.get(subject__startswith="TOPIC B the eldest") topicA = forum.topics.get(subject__startswith="TOPIC A created second") topicSticky = forum.topics.get(subject__startswith="TOPIC STICKY ONE") # Controls topics have been created in the order assumed in their titles self.assertGreater(topicSticky.last_post_on, topicC.last_post_on) self.assertGreater(topicC.last_post_on, topicA.last_post_on) self.assertGreater(topicA.last_post_on, topicB.last_post_on) # Should be ordered by date by default with the sticky topic shown first self.assertContentBefore(response, "TOPIC STICKY ONE", "TOPIC C the newest") self.assertContentBefore(response, "TOPIC C the newest", "TOPIC A created second") self.assertContentBefore(response, "TOPIC A created second", "TOPIC B the eldest") # Reverses the order, the sticky topic should remain first response = self.client.get(f"{url_list_topic}?o=-0") self.assertContentBefore(response, "TOPIC STICKY ONE", "TOPIC B") self.assertContentBefore(response, "TOPIC B", "TOPIC A ") self.assertContentBefore(response, "TOPIC C", "TOPIC A")
def test_course_connection_no_lti(self): """ LTI session is not set then page can still be viewed, the notice about the course being locked won't appear """ forum = self._connects("instructor") post = PostFactory(topic=TopicFactory(forum=forum)) # instructor locks the forum response = self.client.get(f"/forum/admin/lock-course/{forum.id}/") self.assertEqual(200, response.status_code) # user connected without LTI Session user = UserFactory() assign_perm("can_read_forum", user, forum) self.client.force_login(user) # info is not present even if the course is locked # - in forums view but page is available response = self.client.get("/forum/") self.assertNotContains( response, "This course has locked forums, non admin users can only read the history.", ) # - in the forum view response = self.client.get(f"/forum/forum/{forum.slug}-{forum.pk}/") self.assertNotContains( response, "This course has locked forums, non admin users can only read the history.", ) # - in topic view response = self.client.get( f"/forum/forum/{forum.slug}-{forum.pk}/topic/{post.topic.slug}-{post.topic.pk}/" ) self.assertNotContains( response, "This course has locked forums, non admin users can only read the history.", )
def test_list_active_users_ignore_current_user(self): """ The form loads the list of active users for the current topic. We control that the list ignores the current user """ # Setup user1 = UserFactory( lti_consumer=self.lti_consumer, public_username="******", ) user2 = UserFactory( lti_consumer=self.lti_consumer, public_username="******", ) self.context.sync_user_groups(user1, ["student"]) self.context.sync_user_groups(user2, ["student"]) # Set up topic and initial post topic = TopicFactory(forum=self.forum, poster=user1) # Add a Post for user1 PostFactory(topic=topic, poster=user1) # User2 loads the form form = PostForm(user=user2, forum=self.forum, topic=topic) # User1 must be listed in users assert form.fields["content"].widget.attrs["mentions"] == [ { "name": "Benoit", "user": user1.id, } ] # User1 loads the form form = PostForm(user=user1, forum=self.forum, topic=topic) # Check current user is ignored in the list assert form.fields["content"].widget.attrs["mentions"] == []