def test_get_subscriptions(self): mlist = MailingList.objects.create(name="*****@*****.**") self.mm_user.subscriptions = [ FakeMMMember("test.example.com", self.user.email), ] self.client.login(username='******', password='******') response = self.client.get(reverse("hk_user_subscriptions")) self.assertEqual(response.context["subscriptions"], [{ 'first_post': None, 'posts_count': 0, 'likes': 0, 'dislikes': 0, 'likestatus': 'neutral', 'mlist': mlist, 'list_name': "*****@*****.**", 'all_posts_url': "%[email protected]" % reverse("hk_user_posts", args=[self.mm_user.user_id]), }]) self.assertContains(response, "*****@*****.**", status_code=200)
def test_votes(self): self.client.login(username='******', password='******') msg_hash = self._send_message() email = Email.objects.get(message_id="msg") email.vote(user=self.user, value=1) try: response = self.client.get(reverse("hk_user_votes")) except AttributeError: self.fail("Getting the votes should not fail if " "the user has never voted yet\n%s" % format_exc()) self.assertEqual(response.status_code, 200) self.assertContains(response, '<a href="{}">Dummy message</a>'.format( reverse("hk_message_index", args=("*****@*****.**", msg_hash))), count=2, html=True) self.assertContains(response, 'action="{}">'.format( reverse("hk_message_vote", args=("*****@*****.**", msg_hash))), count=2, html=False) self.assertContains(response, "Dummy Sender", count=2, html=False)
def test_registration_redirect(self): self.client.login(username='******', password='******') # If the user if already logged in, redirect to index page... # Don't let him register again response = self.client.get(reverse('account_signup')) self.assertRedirects(response, reverse('hk_root')) # Access the user registration page after logging out and try to # register now self.client.logout() response = self.client.get(reverse('account_signup')) self.assertEqual(response.status_code, 200)
def test_redirect_month(self): url_list = [ "pipermail/list/2015-February/", "list/[email protected]/2015-February/" ] expected_url = reverse('hk_archives_with_month', kwargs={ 'mlist_fqdn': '*****@*****.**', 'year': '2015', 'month': '02' }) for url in url_list: response = self.client.get(reverse("hk_root") + url) self.assertRedirects(response, expected_url)
def test_reattach(self): threadid1 = self.messages[0]["Message-ID-Hash"] threadid2 = self.messages[1]["Message-ID-Hash"] response = self.client.post(reverse( 'hk_thread_reattach', args=["*****@*****.**", threadid2]), data={"parent": threadid1}) threads = Thread.objects.order_by("id") self.assertEqual(len(threads), 1) self.assertEqual(threads[0].thread_id, threadid1) expected_url = reverse('hk_thread', args=["*****@*****.**", threadid1]) self.assertRedirects(response, expected_url) messages = get_flash_messages(response) self.assertEqual(len(messages), 1) self.assertEqual(messages[0].tags, "success")
def test_replies_without_thread_order_show_in_ui(self): # In certain cases, emails without thread_order should show up in UI, # even though they are somewhat staggered in order. # See https://gitlab.com/mailman/hyperkitty/issues/151 msg = self._make_msg("id1", {"Subject": "Starting email"}) threadid = msg["Message-ID-Hash"] self._make_msg("id2", {"In-Reply-To": "<id1>", "Subject": "A reply"}) with patch("hyperkitty.tasks.compute_thread_order_and_depth") as ctoad: self._make_msg("id3", { "In-Reply-To": "<id2>", "Subject": "A reply" }) self._make_msg("id4", { "In-Reply-To": "<id3>", "Subject": "A reply" }) self.assertEqual(ctoad.call_count, 2) self.assertIsNone(Email.objects.get(message_id="id3").thread_order) self.assertIsNone(Email.objects.get(message_id="id4").thread_order) # All set. Now test. url = reverse('hk_thread_replies', args=["*****@*****.**", threadid]) response = self.client.get(url) self.assertEqual(response.status_code, 200) resp = json.loads(response.content.decode(response.charset)) self.assertNotIn("Starting email", resp["replies_html"]) # Make sure there are three emails in the reply. self.assertEqual( resp["replies_html"].count('div class="email unread">'), 3) self.assertFalse(resp["more_pending"]) self.assertIsNone(resp["next_offset"])
def test_subject_changed(self): # Test the detection of subject change self._make_msg("msgid2", { "In-Reply-To": "<msgid>", "Subject": "Re: Dummy message" }) self._make_msg("msgid3", { "In-Reply-To": "<msgid2>", "Subject": "Re: Re: Dummy message" }) self._make_msg("msgid4", { "In-Reply-To": "<msgid3>", "Subject": "Re: Re: Re: Dummy message" }) self._make_msg("msgid5", { "In-Reply-To": "<msgid4>", "Subject": "[example] Re: Dummy message" }) self._make_msg("msgid6", { "In-Reply-To": "<msgid5>", "Subject": "Re: [example] Dummy message" }) self._make_msg( "msgid7", { "In-Reply-To": "<msgid6>", "Subject": "Re: [example] Re: Dummy message" }) url = reverse('hk_thread', args=["*****@*****.**", self.threadid]) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.context["replies"]), 6) for email in response.context["replies"]: self.assertFalse(email.changed_subject, "Message %s changed subject" % email.message_id)
def test_reply_button(self): def check_mailto(link): self.assertTrue(link is not None) link_mo = re.match(r'mailto:[email protected]\?(.+)', link["href"]) self.assertTrue(link_mo is not None) params = urllib.parse.parse_qs(link_mo.group(1)) self.assertEqual(params, { 'In-Reply-To': ['<msgid>'], 'Subject': ['Re: Dummy message'] }) url = reverse('hk_thread', args=["*****@*****.**", self.threadid]) # Authenticated request response = self.client.get(url) soup = BeautifulSoup(response.content, "html.parser") self.assertEqual(len(soup.find_all("a", class_="reply-mailto")), 1) self.assertTrue(soup.find("a", class_="reply") is not None) link = soup.find(class_="reply-tools").find("a", class_="reply-mailto") check_mailto(link) # Anonymous request self.client.logout() response = self.client.get(url) soup = BeautifulSoup(response.content, "html.parser") self.assertEqual(len(soup.find_all("a", class_="reply-mailto")), 1) link = soup.find("a", class_="reply") self.assertTrue(link is not None) self.assertTrue("reply-mailto" in link["class"]) check_mailto(link)
def test_tag_removal_form(self): user_2 = User.objects.create_user('testuser_2', '*****@*****.**', 'testPass') user_3 = User.objects.create_user('testuser_3', '*****@*****.**', 'testPass') User.objects.create_user('testuser_4', '*****@*****.**', 'testPass') url = reverse('hk_thread', args=["*****@*****.**", self.threadid]) thread = Thread.objects.get(thread_id=self.threadid) # Create tags t1 = Tag.objects.create(name="t1") t2 = Tag.objects.create(name="t2") Tagging.objects.create(tag=t1, thread=thread, user=self.user) Tagging.objects.create(tag=t1, thread=thread, user=user_2) Tagging.objects.create(tag=t2, thread=thread, user=user_3) def check_page(username, expected_num_form): self.client.logout() self.client.login(username=username, password='******') response = self.client.get(url) soup = BeautifulSoup(response.content, "html.parser") tags = soup.find("div", id="tags") self.assertIsNotNone(tags) self.assertEqual(len(tags.find_all("li")), 2) self.assertEqual(len(tags.find_all("form")), expected_num_form) # self.user, user_2 and user_3 should see one removal form check_page("testuser", 1) check_page("testuser_2", 1) check_page("testuser_3", 1) # user_4 should see no removal form check_page("testuser_4", 0)
def test_public_profile(self): user_id = uuid.uuid1() self.client.login(username='******', password='******') response = self.client.get( reverse("hk_public_user_profile", args=[user_id.int])) self.assertEqual(response.status_code, 200) self.assertNotContains(response, "Email addresses:")
def test_find(self): response = self.client.get("%s?term=one" % reverse("hk_find_list")) self.assertEqual(json.loads(response.content.decode(response.charset)), [{ 'label': '*****@*****.**', 'value': '*****@*****.**' }])
def test_get_url_default_domain(self): self.assertEqual( _get_url("*****@*****.**", "<message-id>"), "https://example.com" + reverse('hk_message_index', kwargs={ "mlist_fqdn": "*****@*****.**", "message_id_hash": "3F32NJAOW2XVHJWKZ73T2EPICEIAB3LI" }))
def test_show_inactive_list_true(self): response = self.client.get(reverse("hk_root")) self.assertTrue(settings.SHOW_INACTIVE_LISTS_DEFAULT) self.assertEqual(response.status_code, 200) self.assertTrue( '<label><input type="checkbox" value="inactive" checked="checked"' '/>Hide inactive</label>' in str(response.content))
def test_wrong_message_number(self): url_list = [ "pipermail/list/2015-February/000000.html", "list/[email protected]/2015-February/000000.html" ] for url in url_list: response = self.client.get(reverse("hk_root") + url) self.assertEqual(response.status_code, 404)
def test_wrong_date(self): response = self.client.get(reverse( 'hk_archives_with_month', kwargs={ 'mlist_fqdn': '*****@*****.**', 'year': '9999', 'month': '0', })) self.assertEqual(response.status_code, 404)
def test_latest_archives(self): response = self.client.get( reverse('hk_archives_latest', args=['*****@*****.**'])) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.context["threads"]), 1) self.assertEqual(response.context["no_results_text"], "for this MailingList") self.assertEqual(response.context["list_title"], "")
def test_thread_list(self): now = datetime.datetime.now() response = self.client.get( reverse('hk_archives_with_month', args=("*****@*****.**", now.year, now.month))) # Two count comes from the keyboard shortcut models and two should come # from here. self.assertContains(response, "unread", count=4, status_code=200)
def test_display_name(self): ml = MailingList.objects.get(name="*****@*****.**") ml.display_name = "Test Value" ml.save() response = self.client.get("%s?term=value" % reverse("hk_find_list")) self.assertEqual( json.loads(response.content.decode(response.charset)), [{'label': 'Test Value', 'value': '*****@*****.**'}] )
def test_num_comments(self): self._make_msg("msgid2", {"In-Reply-To": "<msgid>"}) self._make_msg("msgid3", {"In-Reply-To": "<msgid2>"}) self._make_msg("msgid4", {"In-Reply-To": "<msgid3>"}) url = reverse('hk_thread', args=["*****@*****.**", self.threadid]) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertTrue("num_comments" in response.context) self.assertEqual(response.context["num_comments"], 3)
def test_get_url_with_domain(self): site = Site.objects.create(name="Example", domain="lists.example.org") MailDomain.objects.create(site=site, mail_domain="example.com") self.assertEqual( _get_url("*****@*****.**", "<message-id>"), "https://lists.example.org" + reverse('hk_message_index', kwargs={ "mlist_fqdn": "*****@*****.**", "message_id_hash": "3F32NJAOW2XVHJWKZ73T2EPICEIAB3LI" }))
def test_month_list(self): response = self.client.get(reverse( 'hk_archives_with_month', kwargs={ 'mlist_fqdn': '*****@*****.**', 'year': '2011', 'month': '1', })) self.assertEqual(response.status_code, 200) self._assertActivePanel(response.content, -2)
def test_bogus_dates(self): base_url = reverse("hk_list_export_mbox", args=["*****@*****.**", "dummy"]) url = "{}?start=invalid".format(base_url) response = self.client.get(url) self.assertEqual(response.status_code, 400) url = "{}?end=2017-01-01/".format(base_url) response = self.client.get(url) self.assertEqual(response.status_code, 400)
def test_posts(self): self.client.login(username='******', password='******') msg_hash = self._send_message() email = Email.objects.get(message_id="msg") email.sender.mailman_id = "dummy_user_id" email.sender.save() response = self.client.get( reverse("hk_user_posts", args=("dummy_user_id", )) + "[email protected]") self.assertEqual(response.status_code, 200) self.assertContains(response, "Dummy content", count=1, html=False) self.assertContains(response, "Dummy Sender", count=5, html=False) self.assertContains(response, '<a name="{}" href="{}">Dummy message</a>'.format( msg_hash, reverse("hk_message_index", args=("*****@*****.**", msg_hash))), count=1, html=True)
def test_favorites(self): self.client.login(username='******', password='******') threadid = self._send_message() thread = Thread.objects.get(thread_id=threadid) self.client.post( reverse("hk_favorite", args=("*****@*****.**", threadid)), {"action": "add"}) self.assertEqual( Favorite.objects.filter(thread=thread, user=self.user).count(), 1) response = self.client.get(reverse("hk_user_favorites")) self.assertEqual(response.status_code, 200) self.assertNotContains(response, "No favorites yet") self.assertContains(response, '<a href="{}">Dummy message</a>'.format( reverse("hk_thread", args=("*****@*****.**", threadid))), count=2, html=True) self.assertContains(response, "Dummy Sender", count=2, html=False)
def test_overview_cleaned_cache(self): # Test the overview page with a clean cache (different code path for # MailingList.recent_threads) mlist = MailingList.objects.get(name="*****@*****.**") cache.delete("MailingList:%s:recent_threads" % mlist.pk) response = self.client.get( reverse('hk_list_overview', args=["*****@*****.**"])) self.assertEqual(response.status_code, 200) response = self.client.get(reverse( 'hk_list_overview_top_threads', args=["*****@*****.**"])) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.context["threads"]), 1) response = self.client.get(reverse( 'hk_list_overview_recent_threads', args=["*****@*****.**"])) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.context["threads"]), 1) response = self.client.get(reverse( 'hk_list_overview_pop_threads', args=["*****@*****.**"])) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.context["threads"]), 0)
def test_search_basic(self): mlist = MailingList.objects.create( name="*****@*****.**", ) mm_mlist = FakeMMList("*****@*****.**") self.mailman_client.get_list.side_effect = lambda name: mm_mlist self._send_message(mlist) response = self.client.get( reverse("hk_search"), {"q": "dummy", "mlist": "*****@*****.**"}) self.assertContains(response, "Dummy message")
def test_reattach_invalid(self): threadid = self.messages[0]["Message-ID-Hash"] response = self.client.post(reverse( 'hk_thread_reattach', args=["*****@*****.**", threadid]), data={"parent": "invalid-data"}) self.assertEqual(Thread.objects.count(), 2) for thread in Thread.objects.all(): self.assertEqual(thread.emails.count(), 1) messages = list(response.context["messages"]) self.assertEqual(len(messages), 1) self.assertEqual(messages[0].tags, "warning") self.assertIn("Invalid thread id, it should look", str(messages[0]))
def test_reattach_on_itself(self): threadid = self.messages[0]["Message-ID-Hash"] response = self.client.post(reverse( 'hk_thread_reattach', args=["*****@*****.**", threadid]), data={"parent": threadid}) self.assertEqual(Thread.objects.count(), 2) for thread in Thread.objects.all(): self.assertEqual(thread.emails.count(), 1) messages = list(response.context["messages"]) self.assertEqual(len(messages), 1) self.assertEqual(messages[0].tags, "warning") self.assertIn("Can't re-attach a thread to itself", str(messages[0]))
def test_email_escaped_body(self): msg = EmailMessage() msg["From"] = "Dummy Sender <*****@*****.**>" msg["Subject"] = "Dummy Subject" msg["Date"] = "Mon, 02 Feb 2015 13:00:00 +0300" msg["Message-ID"] = "<msgid2>" msg["In-Reply-To"] = "<msgid>" msg.set_payload("Email address: [email protected]") add_to_list("*****@*****.**", msg) url = reverse('hk_thread', args=["*****@*****.**", self.threadid]) response = self.client.get(url) self.assertNotContains(response, "*****@*****.**", status_code=200)
def setUp(self): msg = EmailMessage() msg["From"] = "*****@*****.**" msg["Subject"] = "Fake Subject" msg["Message-ID"] = "<dummy>" msg["Date"] = "Fri, 02 Nov 2012 16:07:54" msg.set_payload("Fake Message") self.message = BytesIO(msg.as_string().encode("utf-8")) self.url = "{}?key={}".format( reverse('hk_mailman_archive'), settings.MAILMAN_ARCHIVER_KEY, )