import json, tempfile, os, mock, base64 import pandas as pd from io import StringIO import time from django.test import override_settings from bs4 import BeautifulSoup from datetime import datetime from django.conf import settings from django.contrib import messages as dj_messages from django.contrib.auth import get_user_model from django.core import serializers from django.core.files import File from django.core.exceptions import PermissionDenied, ValidationError from django.core.files.uploadedfile import SimpleUploadedFile from django.core.management import call_command from django.test import Client, TestCase, TransactionTestCase from django.urls import resolve, reverse from django.db.utils import IntegrityError from django.test import Client, RequestFactory, TestCase, TransactionTestCase from pytz import timezone from time import sleep import datetime as dt from administration.models import VerificationSetting, VerificationReport from administration.utils import id_generator from app.views import UploadMateriHTML, add_rating_materi from authentication.models import User from digipus.settings import TIME_ZONE from .models import ( Category, Comment, Review, DislikeComment, DownloadStatistics, Materi, Like, LikeComment, Rating, ReqMaterial, RatingContributor, ViewStatistics, ) from .views import ( DaftarKatalog, DashboardKontributorView, DetailMateri, ProfilView, SuntingProfilView, SuksesLoginAdminView, SuksesLoginKontributorView, PostsView, RevisiMateriView, ReqMateriView, KatalogPerKontributorView, UploadMateriView, UploadMateriExcelView, PasswordChangeViews, password_success, MateriFavorite, ) from app.forms import SuntingProfilForm, year_choices from app.utils.fileManagementUtil import get_random_filename, remove_image_exifdata ERROR_403_MESSAGE = "Kamu harus login untuk mengakses halaman ini" from django.test import LiveServerTestCase from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.keys import Keys from webdriver_manager.chrome import ChromeDriverManager from selenium.common.exceptions import NoSuchElementException import requests from statistics import mean class DaftarKatalogTest(TestCase): def test_daftar_katalog_url_exist(self): url = "/" response = Client().get(f"{url}") self.assertEqual(response.status_code, 200) def test_daftar_katalog_using_daftar_katalog_template(self): response = Client().get("/") self.assertTemplateUsed(response, "app/katalog_materi.html") def test_daftar_katalog_using_daftar_katalog_func(self): found = resolve("/") self.assertEqual(found.func.__name__, DaftarKatalog.as_view().__name__) def test_fields(self): materi = Materi() materi.title = "tes" materi.cover = "https://cache.umusic.com/_sites/billieeilish/v2/images/pic-red.jpg" materi.author = "input" materi.save() resp = Materi.objects.get(id=materi.id) self.assertEqual(resp, materi) def test_materi_model_generate_search_vector_after_save(self): Materi(title="Eating book").save() search_vector_new_materi = list(Materi.objects.values_list("_search_vector", flat=True)) expected_search_vector = ["'book':2A 'eat':1A"] self.assertSequenceEqual(search_vector_new_materi, expected_search_vector) def test_search_text_on_empty_database(self): search_query = "test" search_result = list(Materi.objects.search(search_query)) expected_search_result = [] self.assertSequenceEqual(search_result, expected_search_result) def test_search_text_on_unmatched_data(self): Materi(title="test satu sekarang").save() Materi(title="test dua nanti").save() search_query = "besok" search_result = list(Materi.objects.search(search_query)) expected_search_result = [] self.assertSequenceEqual(search_result, expected_search_result) def test_search_text_return_list_matched_by_rank(self): materi_2 = Materi(title="ini lumayan cocok lumayan cocok") materi_2.save() materi_1 = Materi(title="ini sangat cocok sangat cocok sangat cocok") materi_1.save() materi_4 = Materi(title="ini tidak") materi_4.save() materi_3 = Materi(title="ini sedikit cocok") materi_3.save() search_query = "ini cocok" search_result = list(Materi.objects.search(search_query)) expected_search_result = [materi_1, materi_2, materi_3] self.assertSequenceEqual(search_result, expected_search_result) class DaftarKatalogSortingByJumlahUnduhTest(TestCase): def setUp(self): self.client = Client() self.contributor_credential = { "email": "kontributor@gov.id", "password": "passwordtest" } self.contributor_credential_2 = { "email": "kontributor2@gov.id", "password": "passwordtest" } self.contributor = get_user_model().objects.create_user( **self.contributor_credential, name="Kontributor 1", is_contributor=True) self.contributor2 = get_user_model().objects.create_user( **self.contributor_credential_2, name="Kontributor 2", is_contributor=True) self.cover = SimpleUploadedFile( "Cherprang_Areekul40_nJM9dGt.jpg", b"Test file") self.content = SimpleUploadedFile("Bahan_PA_RKK.pdf", b"Test file") Materi(title="Materi 1", author="Agas", uploader=self.contributor, publisher="Kelas SC", descriptions="Deskripsi Materi 1", status="APPROVE", cover=self.cover, content=self.content).save() time.sleep(1) Materi(title="Materi 2", author="Agas", uploader=self.contributor, publisher="Kelas SC", descriptions="Deskripsi Materi 2", status="APPROVE", cover=self.cover, content=self.content).save() self.last_uploaded_material = Materi.objects.last() material_unduh_url = f"/materi/{self.last_uploaded_material.id}/unduh" self.client.get(material_unduh_url) def test_sorting_by_jumlah_unduh(self): response = self.client.get("/?sort=jumlah_unduh") self.assertRegex(str(response.content), rf'.*Materi 2.*Materi 1.*') class DaftarKatalogSortingByJumlahTampilanTest(TestCase): def setUp(self): self.contributor_credential = { "email": "kontributor@gov.id", "password": id_generator() } self.contributor = get_user_model().objects.create_user( **self.contributor_credential, name="Kontributor", is_contributor=True ) self.client = Client() content = b"Test file" self.cover = SimpleUploadedFile( "cover.jpg", content ) self.content = SimpleUploadedFile( "content.txt", content ) Materi(title="Materi 1", author="Agas", uploader=self.contributor, publisher="Kelas SC", descriptions="Deskripsi Materi 1", status="PENDING", cover=self.cover, content=self.content).save() Materi(title="Materi 2", author="Agas", uploader=self.contributor, publisher="Kelas SC", descriptions="Deskripsi Materi 1", status="PENDING", cover=self.cover, content=self.content).save() self.materi2 = Materi.objects.last() self.url = f"/materi/{self.materi2.id}/view" def sorting_by_jumlah_tampilan(self): self.client.get(self.url) response = self.client.get("/?sort=jumlah_tampilan") self.assertRegex(str(response.content), rf'.*Materi 2.*Materi 1.*') class DaftarKatalogPerKontributorTest(TestCase): def setUp(self): self.client = Client() self.contributor_credential = { "email": "kontributor@gov.id", "password": "passwordtest" } self.contributor_credential_2 = { "email": "kontributor2@gov.id", "password": "passwordtest" } self.contributor = get_user_model().objects.create_user( **self.contributor_credential, name="Kontributor 1", is_contributor=True) self.contributor2 = get_user_model().objects.create_user( **self.contributor_credential_2, name="Kontributor 2", is_contributor=True) self.cover = SimpleUploadedFile( "Cherprang_Areekul40_nJM9dGt.jpg", b"Test file") self.content = SimpleUploadedFile("Bahan_PA_RKK.pdf", b"Test file") Materi(title="Materi 1", author="Agas", uploader=self.contributor, publisher="Kelas SC", descriptions="Deskripsi Materi 1", status="APPROVE", cover=self.cover, content=self.content).save() Materi(title="Materi 2", author="Agas", uploader=self.contributor, publisher="Kelas SC", descriptions="Deskripsi Materi 2", status="APPROVE", cover=self.cover, content=self.content).save() Materi(title="Materi 3", author="Agas", uploader=self.contributor2, publisher="Kelas SC", descriptions="Deskripsi Materi 3", status="APPROVE", cover=self.cover, content=self.content).save() self.url = f"/profil/{self.contributor.email}/" def test_katalog_per_kontributor_url_exist(self): response = self.client.get(self.url) self.assertEqual(response.status_code, 200) def test_katalog_per_kontributor_using_katalog_kontri_template(self): response = self.client.get(self.url) self.assertTemplateUsed(response, "app/katalog_kontri.html") def test_katalog_per_kontributor_using_katalog_per_kontributor_func(self): found = resolve(self.url) self.assertEqual(found.func.__name__, KatalogPerKontributorView.as_view().__name__) def test_katalog_per_kontributor_show_daftar_materi_kontributor(self): response = self.client.get(self.url) list_materi = Materi.objects.filter(uploader=self.contributor) data = response.context_data["materi_list"] self.assertEqual(len(list_materi), len(data)) class DetailMateriTest(TestCase): def setUp(self): self.client = Client() self.admin_credential = { "email": "admin@gov.id", "password": "passwordtest" } self.contributor_credential = { "email": "kontributor@gov.id", "password": "passwordtest" } self.anonymous_credential = { "email": "anonymous@gov.id", "password": "passwordtest" } self.admin = get_user_model().objects.create_user( **self.admin_credential, name="Admin", is_admin=True) self.contributor = get_user_model().objects.create_user( **self.contributor_credential, name="Kontributor", is_contributor=True) self.anonymous = get_user_model().objects.create_user( **self.anonymous_credential, name="Anonymous" ) self.cover = SimpleUploadedFile( "ExampleCover921.jpg", b"Test file") self.content = SimpleUploadedFile("ExampleFile921.pdf", b"Test file") Materi(title="Materi 1", author="Agas", uploader=self.contributor, publisher="Kelas SC", descriptions="Deskripsi Materi 1", status="APPROVE", cover=self.cover, content=self.content).save() self.materi1 = Materi.objects.first() self.url = "/materi/" + str(self.materi1.id) + "/" self.materi_with_published_date = Materi.objects.create(title="Materi 1", author="Agas", uploader=self.contributor, publisher="Kelas SC", descriptions="Deskripsi Materi 1", status="APPROVE", cover=self.cover, content=self.content, date_modified=datetime.now(), date_created=datetime.now()) self.materi_with_published_date_url = "/materi/" + str(self.materi_with_published_date.id) + "/" VerificationReport.objects.create(report='{"feedback": "Something", "kriteria": [{"title": "Kriteria 1", "status": true},' + \ ' {"title": "Kriteria 2", "status": true}, {"title": "Kriteria 3", "status": true}]}', \ timestamp="2020-10-09 06:21:33", status="Diterima", materi= self.materi_with_published_date, \ user=self.materi_with_published_date.uploader) def test_detail_materi_url_exist(self): response = Client().get(self.url) self.assertEqual(response.status_code, 200) self.assertNotEqual(response.status_code, 404) def test_detail_materi_using_detail_materi_template(self): response = Client().get(self.url) self.assertTemplateUsed(response, "app/detail_materi.html") def test_detail_materi_using_detail_materi_func(self): found = resolve(self.url) self.assertEqual(found.func.__name__, DetailMateri.as_view().__name__) def test_category_models_can_create_new_object(self): test = Category.objects.create( id="1", name="medis", description="kategori medis") count = Category.objects.all().count() self.assertEqual(1, count) self.assertNotEqual(0, count) self.assertEqual(test.__str__(), "medis") self.assertNotEqual(test.__str__(), "saul") def test_comment_models_can_create_new_object(self): test = Comment.objects.create( username="saul", profile="121212", comment="232323") count = Comment.objects.all().count() self.assertEqual(1, count) self.assertNotEqual(0, count) self.assertEqual(test.__str__(), "saul") self.assertNotEqual(test.__str__(), "userlain") def test_post_blank_comment(self): url = self.url self.client.login(**self.anonymous_credential) response = self.client.post(url, {"comment": ""}) self.assertIn("error_message", response.context) self.assertIn("Anda belum menuliskan komentar", response.context["error_message"]) def test_comment_rendered_to_template(self): url = self.url self.client.login(**self.contributor_credential) self.client.post(url, {"comment": "This is my new comment"}) response = Client().get(url) self.assertContains(response, "This is my new comment") def test_comment_by_admin(self): url = self.url self.client.login(**self.admin_credential) self.client.post(url, {"comment": "This is new comment by Admin"}) response = self.client.get(url) self.assertContains(response, "Admin") def test_comment_by_kontributor(self): url = self.url self.client.login(**self.contributor_credential) self.client.post( url, {"comment": "This is new comment by Contributor"}) response = self.client.get(url) self.assertContains(response, "Kontributor") def test_comment_by_anonymous(self): url = self.url self.client.get("/logout/") self.client.login(**self.anonymous_credential) self.client.post(url, {"comment": "This is new comment by Anonymous"}) response = self.client.get(url) self.assertContains(response, "Anonymous") def test_comment_disliked_by_anonymous(self): url_materi = self.url self.client.get("/logout/") self.client.login(**self.anonymous_credential) self.client.post(url_materi, {"comment": "This is new comment by Anonymous"}) comment = Comment.objects.get(comment="This is new comment by Anonymous").id response = self.client.get(url_materi) session_id = response.context["session_id"] payload = {"comment": comment, "session_id": session_id} ajax_response = self.client.post("/comment/dislike/", payload) num_of_comment_dislikes = DislikeComment.objects.filter(comment=comment).count() self.assertEqual(num_of_comment_dislikes, 0) def test_comment_liked_by_anonymous(self): url_materi = self.url self.client.get("/logout/") self.client.login(**self.anonymous_credential) self.client.post(url_materi, {"comment": "This is new comment by Anonymous"}) comment = Comment.objects.get(comment="This is new comment by Anonymous").id response = self.client.get(url_materi) session_id = response.context["session_id"] payload = {"comment": comment, "session_id": session_id} ajax_response = self.client.post("/comment/like/", payload) num_of_comment_likes = LikeComment.objects.filter(comment=comment).count() self.assertEqual(num_of_comment_likes, 0) def test_comment_undisliked_by_anonymous(self): url_materi = self.url self.client.get("/logout/") self.client.login(**self.anonymous_credential) self.client.post(url_materi, {"comment": "This is new comment by Anonymous"}) comment = Comment.objects.get(comment="This is new comment by Anonymous") response = self.client.get(url_materi) session_id = response.context["session_id"] payload = {"comment": comment, "session_id": session_id} ajax_response = self.client.post("/comment/dislike/", payload) ajax_response = self.client.post("/comment/dislike/", payload) num_of_comment_dislikes = DislikeComment.objects.filter(comment=comment, session_id=session_id).count() self.assertEqual(num_of_comment_dislikes, 0) def test_comment_unliked_by_anonymous(self): url_materi = self.url self.client.get("/logout/") self.client.login(**self.anonymous_credential) self.client.post(url_materi, {"comment": "This is new comment by Anonymous"}) comment = Comment.objects.get(comment="This is new comment by Anonymous") response = self.client.get(url_materi) session_id = response.context["session_id"] payload = {"comment": comment, "session_id": session_id} ajax_response = self.client.post("/comment/like/", payload) ajax_response = self.client.post("/comment/like/", payload) num_of_comment_likes = LikeComment.objects.filter(comment=comment, session_id=session_id).count() self.assertEqual(num_of_comment_likes, 0) def test_comment_new_does_not_have_dislike(self): url_materi = self.url self.client.get("/logout/") self.client.login(**self.anonymous_credential) response = self.client.get(url_materi) session_id = response.context["session_id"] self.client.post(url_materi, {"comment": "This is new comment by Anonymous"}) comment = Comment.objects.get(comment="This is new comment by Anonymous") comment_dislike_counter = DislikeComment.objects.filter(comment=comment, session_id=session_id).count() self.assertEqual(comment_dislike_counter, 0) def test_comment_new_does_not_have_like(self): url_materi = self.url self.client.get("/logout/") self.client.login(**self.anonymous_credential) response = self.client.get(url_materi) session_id = response.context["session_id"] self.client.post(url_materi, {"comment": "This is new comment by Anonymous"}) comment = Comment.objects.get(comment="This is new comment by Anonymous") comment_like_counter = LikeComment.objects.filter(comment=comment, session_id=session_id).count() self.assertEqual(comment_like_counter, 0) def test_detail_materi_contains_comment_count(self): url = self.url self.client.login(**self.contributor_credential) response = self.client.get(url) self.assertContains(response, "Komentar (0)") self.client.post( url, {"comment": "This is new comment by Contributor"}) self.client.post( url, {"comment": "This is new comment by Contributor"}) response = self.client.get(url) self.assertContains(response, "Komentar (2)") def test_detail_materi_contains_form_comment(self): self.client.login(**self.contributor_credential) response = self.client.get(self.url) self.assertContains(response, "Beri komentar...") def test_detail_materi_not_contains_form_comment(self): response = self.client.get(self.url) self.assertNotContains(response, "Beri komentar...") self.assertContains(response, "Login terlebih dahulu untuk berkomentar") def create_and_delete_comment(self, is_admin=False, is_contributor=False): url = self.url self.client.login(**self.admin_credential) self.client.post(url, {"comment": "This is new comment by Anonymous"}) deleteURL = "/delete/" + str(self.materi1.id) + "/" + str( Comment.objects.get(comment="This is new comment by Anonymous").id) if is_admin: self.client.login(**self.admin_credential) if is_contributor: self.client.login(**self.contributor_credential) if not is_admin and not is_contributor: self.client.login(**self.anonymous_credential) response = self.client.get(deleteURL) return response def test_delete_comments_by_admin(self): self.create_and_delete_comment(is_admin=True) count = Comment.objects.all().filter(comment="This is new comment by Anonymous").count() self.assertEqual(count, 0) def test_delete_comments_by_contributor(self): response = self.create_and_delete_comment(is_contributor=True) self.assertRaises(PermissionDenied) self.assertEqual(response.status_code, 403) count = Comment.objects.all().filter(comment="This is new comment by Anonymous").count() self.assertEqual(count, 1) def test_delete_comments_by_anonymous(self): response = self.create_and_delete_comment() self.assertRaises(PermissionDenied) self.assertEqual(response.status_code, 403) count = Comment.objects.all().filter(comment="This is new comment by Anonymous").count() self.assertEqual(count, 1) def test_review_models_can_create_new_object(self): test = Review.objects.create( username="saul", profile="121212", review="232323") count = Review.objects.all().count() self.assertEqual(1, count) self.assertNotEqual(0, count) self.assertEqual(test.__str__(), "saul") self.assertNotEqual(test.__str__(), "userlain") def test_post_blank_review(self): url = self.url self.client.login(**self.anonymous_credential) response = self.client.post(url, {"review": ""}) self.assertIn("error_message", response.context) self.assertIn("Anda belum menuliskan komentar", response.context["error_message"]) def test_review_rendered_to_template(self): url = self.url self.client.login(**self.contributor_credential) self.client.post(url, {"review": "This is my new review"}) response = Client().get(url) self.assertContains(response, "This is my new review") def test_review_by_admin(self): url = self.url self.client.login(**self.admin_credential) self.client.post(url, {"review": "This is new review by Admin"}) response = self.client.get(url) self.assertContains(response, "Admin") def test_review_by_kontributor(self): url = self.url self.client.login(**self.contributor_credential) self.client.post( url, {"review": "This is new review by Contributor"}) response = self.client.get(url) self.assertContains(response, "Kontributor") def test_review_by_anonymous(self): url = self.url self.client.get("/logout/") self.client.login(**self.anonymous_credential) self.client.post(url, {"review": "This is new review by Anonymous"}) response = self.client.get(url) self.assertContains(response, "Anonymous") def test_detail_materi_contains_review_count(self): url = self.url self.client.login(**self.contributor_credential) review = "This is new review by Contributor" response = self.client.get(url) self.assertContains(response, "Review (0)") self.client.post( url, {"review": review }) self.client.post( url, {"review": review}) response = self.client.get(url) self.assertContains(response, "Review (2)") def test_detail_materi_contains_form_review(self): self.client.login(**self.contributor_credential) response = self.client.get(self.url) self.assertContains(response, "Beri Review") def test_detail_materi_not_contains_form_review(self): response = self.client.get(self.url) self.assertNotContains(response, "Beri Review") self.assertContains(response, "Login terlebih dahulu untuk Membuat review") def test_tombol_citasiAPA(self): response = self.client.get(self.url) self.assertContains(response, "Citate APA") def test_hasil_citasi_APA_materi_has_no_published_date(self): response = self.client.get(self.url) expected = self.materi1.author + " . (n.d) . " + self.materi1.title + " . " + self.materi1.publisher self.assertIn(expected, response.context["citationAPA"]) self.assertIn(expected, response.context["citationAPA"]) def test_hasil_citasi_APA_materi_has_published_date(self): response = self.client.get(self.materi_with_published_date_url) published_date = self.materi_with_published_date.published_date.strftime("%Y-%m-%d %H:%M") expected = ( self.materi_with_published_date.author + " . (" + published_date + ") . " + self.materi_with_published_date.title + " . " + self.materi_with_published_date.publisher ) self.assertIn(expected, response.context["citationAPA"]) def test_citation_IEEE_button(self): response = self.client.get(self.url) self.assertContains(response, "Citate IEEE") def test_citation_IEEE_materi_has_no_published_date(self): response = self.client.get(self.url) current_date = datetime.now() current_day = str(current_date.day) current_month = current_date.strftime("%b") current_year = str(current_date.year) expected = ( "Agas, " + "Materi 1. " + "Kelas SC, n.d. " + "Accessed on: " + current_month + ". " + current_day + ", " + current_year + ". [Online]. " + "Available: http://testserver" + self.url ) self.assertIn(expected, response.context["citationIEEE"]) def test_citation_IEEE_materi_has_published_date(self): response = self.client.get(self.materi_with_published_date_url) current_date = datetime.now() current_day = str(current_date.day) current_month = current_date.strftime("%b") current_year = str(current_date.year) published_date = self.materi_with_published_date.published_date.strftime('%Y') expected = "Agas, " + \ "Materi 1. " + \ "Kelas SC, " + published_date + ". " +\ "Accessed on: " + current_month + ". " + current_day + ", " + current_year + \ ". [Online]. " + \ "Available: http://testserver" + self.materi_with_published_date_url self.assertIn(expected, response.context["citationIEEE"]) def test_tombol_bagikan_google_drive(self): response = Client().get(self.url) self.assertContains(response, 'Google Drive') @mock.patch("app.services.GoogleDriveUploadService.upload_to_gdrive") def test_save_to_gdrive_with_nonexistent_materi(self, mock_upload_to_gdrive): response = self.client.get('/materi/%s/save-to-gdrive/' % 0) mock_upload_to_gdrive.assert_not_called() self.assertEqual(response.status_code, 404) @mock.patch("app.services.GoogleDriveUploadService.upload_to_gdrive") def test_save_to_gdrive_with_valid_materi(self, mock_upload_to_gdrive): response = self.client.get( '/materi/%s/save-to-gdrive/' % self.materi1.id, follow=True) last_url, status_code = response.redirect_chain[-1] mock_upload_to_gdrive.assert_called_once() self.assertEqual(last_url, '/materi/%d/' % self.materi1.id) self.assertEqual(status_code, 302) class PostsViewTest(TestCase): @classmethod def generate_posts_data(cls, user): POST_COUNT = 3 COMMENTS_COUNT_PER_POST = [1, 0, 3] LIKES_COUNT_PER_POST = [5, 4, 2] assert POST_COUNT == len(COMMENTS_COUNT_PER_POST) sample_file = SimpleUploadedFile("Test.jpg", b"Test file") sample_category = Category.objects.create(name="Test Category") post_comment_group_dict = {} for i in range(POST_COUNT): post = Materi.objects.create( uploader=user, cover=sample_file, content=sample_file, ) post.categories.add(sample_category) post_comment_group_dict[post.id] = { "data": post, "comments": [], } for j in range (LIKES_COUNT_PER_POST[i]): Like.objects.create( timestamp=datetime.now(), materi=post, session_id=("dummysession-" + str(i) + '-' + str(j)) ) for i, post_id in enumerate(post_comment_group_dict): post = post_comment_group_dict[post_id]["data"] for _ in range(COMMENTS_COUNT_PER_POST[i]): comment = Comment.objects.create(materi=post) post_comment_group_dict[post_id]["comments"].append(comment) # order by latest (-timestamp) post_comment_group_dict[post_id]["comments"].reverse() return post_comment_group_dict @classmethod def setUpTestData(cls): cls.url = '/posts/' cls.user_credentials = { "email": "user@email.com", "password": "justpass" } cls.user = User.objects.create_user(**cls.user_credentials, is_contributor=True) cls.data = cls.generate_posts_data(cls.user) def _request_as_user(self): self.client.login(**self.user_credentials) return self.client.get(self.url) def test_url_resolves_to_posts_view(self): found = resolve(self.url) self.assertEqual(found.func.__name__, PostsView.as_view().__name__) def test_returns_200_on_authenticated_access(self): response = self._request_as_user() self.assertEqual(response.status_code, 200) def test_returns_403_on_unauthenticated_access(self): response = self.client.get(self.url) self.assertRaises(PermissionDenied) self.assertEqual(response.status_code, 403) html = response.content.decode("utf-8") self.assertIn(ERROR_403_MESSAGE, html) def test_returns_correct_template(self): response = self._request_as_user() self.assertTemplateUsed(response, "user_uploaded_posts.html") def test_success_returns_correct_comment_post_groupings_by_context(self): post_comment_group_dict = self.data response = self._request_as_user() response_user = response.context_data["user"] self.assertEqual(response_user, self.user) response_data = response.context_data["posts"] actual_data = post_comment_group_dict self.assertDictEqual(response_data, actual_data) def test_html_contains_grouped_posts_and_comments(self): response = self._request_as_user() posts = list(self.data.keys()) comments = { i: [comment.id for comment in self.data[post_id]["comments"]] for i, post_id in enumerate(posts) } self.assertRegex( str(response.content), rf'.*(