diff --git a/app/models.py b/app/models.py index 380f751af661b8866ef2033b51b5a48a0a3811d1..da7ee4c437b7774855f2ce326184011467ca351d 100644 --- a/app/models.py +++ b/app/models.py @@ -130,6 +130,11 @@ class Materi(SoftDeleteModel): count = Comment.objects.filter(materi=self).count() return count + @property + def review_count(self): + count = Review.objects.filter(materi=self).count() + return count + @property def is_like(self): like = False @@ -158,6 +163,17 @@ class Comment(models.Model): count = DislikeComment.objects.filter(comment=self).count() return count +class Review(models.Model): + username = models.CharField(max_length=100) + profile = models.CharField(max_length=100, default=getRandomColor) + review = models.TextField(default="review") + materi = models.ForeignKey(Materi, models.SET_NULL, null=True) + user = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True) + timestamp = models.DateTimeField(default=timezone.now) + + def __str__(self): + return self.username + class LikeComment(models.Model): comment = models.ForeignKey(Comment, models.SET_NULL, null=True) diff --git a/app/templates/app/detail_materi.html b/app/templates/app/detail_materi.html index 98f60bd7ea1100bfbf3421abcaaee2c4e9f7f215..fb1b1d031eb7d3dc493ca716b83bfafbb1233a78 100644 --- a/app/templates/app/detail_materi.html +++ b/app/templates/app/detail_materi.html @@ -8,8 +8,12 @@ <script async defer crossorigin="anonymous" src="https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v6.0"></script> <script src="{% static 'js/detail_materi.js'%}"></script> +<style> +div.review { + overflow: auto; +} +</style> {% endblock header %} - {% block title %} {{materi_data.title}} | Digipus {% endblock title %} @@ -257,6 +261,9 @@ <li class="nav-item"> <a class="nav-link" href="#komentar">Komentar</a> </li> + <li class="nav-item"> + <a class="nav-link" href="#review">Review</a> + </li> {% endif %} </ul> </nav> @@ -347,6 +354,52 @@ </div> {% endfor %} </div> + + <div id="review" class="container-fluid comments-wrapper p-0"> + <h1>Review ({{ materi_data.review_count }})</h1> + {% if is_authenticated %} + <div class="add-comments col col-8 bg-white shadow-sm rounded p-3 mb-3"> + <form method="POST"> + {% csrf_token %} + <h1>Review</h1> + <div class="form-group"> + <textarea placeholder="Beri Review" class="form-control" id="exampleFormControlTextarea1" + rows="10" name="review" required></textarea> + <button type="submit" + class="btn btn-link btn-book shadow-sm p-2 mt-2 bg-white rounded">Kirim</button> + </div> + </form> + </div> + {% else %} + <h3>Login terlebih dahulu untuk Membuat review</h3> + {% endif %} + </div> + {% for review in review_data %} + <div class="col col-8 comment shadow-sm p-3 mb-1 bg-white rounded"> + <div class="d-flex bd-highlight mb-3 align-items-center user"> + {% if review.user != Null %} + {% if not user.default_profile_picture %} + <img class="profile" src="https://i.ibb.co/9wgPzyZ/default-image.png" alt="profile-picture"> + {% else %} + <img class="profile" src="{{ review.user.profile_picture.url }}" alt="profile-picture"> + {% endif %} + {% else %} + <span style="background-color: #{{review.profile}}" class="profile p-1 bd-highligh"></span> + {% endif %} + <div class="d-flex flex-row justify-content-end"> + <p class="p-1 bd-highligh m-0"><strong>{{review.user.name}}</strong></p> + <p class="p-1 bd-highligh m-0">•</p> + <p class="timestamp p-1 bd-highligh m-0 text-muted"> + {{ review.timestamp|naturaltime }} + </p> + </div> + </div> + <div class = 'review'> + <p class="paragraph">{{review.review}}</p> + </div> + </div> + {% endfor %} + </div> {% endif %} </div> </div> diff --git a/app/tests.py b/app/tests.py index 5c645df2dd7c5a3044be1e669a0d88de97da53b9..d790674c2d71c70593c379edf4f3fc65a51a5c32 100644 --- a/app/tests.py +++ b/app/tests.py @@ -30,6 +30,7 @@ from digipus.settings import TIME_ZONE from .models import ( Category, Comment, + Review, DislikeComment, DownloadStatistics, Materi, @@ -538,6 +539,78 @@ class DetailMateriTest(TestCase): 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") + countData = Review.objects.all().count() + self.assertEqual(1, countData) + self.assertNotEqual(0, countData) + 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) + + response = self.client.get(url) + self.assertContains(response, "Review (0)") + + self.client.post( + url, {"review": "This is new review by Contributor"}) + self.client.post( + url, {"review": "This is new review by Contributor"}) + 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") @@ -625,6 +698,7 @@ class DetailMateriTest(TestCase): self.assertEqual(last_url, '/materi/%d/' % self.materi1.id) self.assertEqual(status_code, 302) + class PostsViewTest(TestCase): @classmethod diff --git a/app/views.py b/app/views.py index abc583f5cc191b45aafce0be112bd776e4c42790..ea48cd4bcfdfbc912e44194d7e6166af15eab178 100644 --- a/app/views.py +++ b/app/views.py @@ -25,6 +25,7 @@ from app.forms import SuntingProfilForm, UploadMateriForm, RatingContributorForm from app.models import ( Category, Comment, + Review, Materi, ReqMaterial, Rating, RatingContributor, @@ -125,8 +126,10 @@ class DetailMateri(TemplateView): def get(self, request, *args, **kwargs): context = self.get_context_data(**kwargs) query_set_for_comment = Comment.objects.filter(materi=context["materi_data"]) + query_set_for_review = Review.objects.filter(materi=context["materi_data"]) has_disliked, has_liked = DetailMateriService.find_comment_like_dislike(query_set_for_comment, self.request.session) context["comment_data"] = query_set_for_comment + context["review_data"] = query_set_for_review context["has_liked"] = has_liked context["has_disliked"] = has_disliked return self.render_to_response(context=context) @@ -135,21 +138,30 @@ class DetailMateri(TemplateView): def post(self, request, *args, **kwargs): commentText = request.POST.get("comment", None) - if commentText == None or commentText == "": + reviewText = request.POST.get("review", None) + if ((commentText == None or commentText == "" )and (reviewText == None or reviewText == "")): context = self.get_context_data(*args, **kwargs) context["error_message"] = "Anda belum menuliskan komentar" context["materi_data"] = get_object_or_404(Materi, pk=kwargs["pk"]) query_set_for_comment = Comment.objects.filter(materi=context["materi_data"]) context["comment_data"] = query_set_for_comment + query_set_for_review = Review.objects.filter(materi=context["materi_data"]) + context["review_data"] = query_set_for_review return self.render_to_response(context=context) materi = get_object_or_404(Materi, pk=kwargs["pk"]) user_obj = request.user if request.user.is_authenticated else None if user_obj: - comment = Comment.objects.create( - comment=commentText, username=DetailMateriService.get_user_name(request), materi=materi, user=user_obj - ) - comment.save() + if (commentText != None ): + comment = Comment.objects.create( + comment=commentText, username=DetailMateriService.get_user_name(request), materi=materi, user=user_obj + ) + comment.save() + elif (reviewText != None): + review = Review.objects.create( + review=reviewText, username=DetailMateriService.get_user_name(request), materi=materi, user=user_obj + ) + review.save() return HttpResponseRedirect(request.path)