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)