From afd96e587c1d414e7dffa38cbce968e9ad8ecab2 Mon Sep 17 00:00:00 2001
From: Samuel Tupa Febrian <samuel.febrian@gmail.com>
Date: Wed, 21 Oct 2020 21:26:48 +0700
Subject: [PATCH 01/10] [#107][RED] Create test for download count context

---
 app/tests.py | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/app/tests.py b/app/tests.py
index 653a373..508fcc6 100644
--- a/app/tests.py
+++ b/app/tests.py
@@ -40,6 +40,10 @@ from .models import (
     ViewStatistics,
 )
 
+from .services import (
+    DetailMateriService,
+)
+
 from .views import (
     DaftarKatalog,
     DashboardKontributorView,
@@ -576,6 +580,16 @@ class DetailMateriTest(TestCase):
         self.assertEqual(last_url, '/materi/%d/' % self.materi1.id)
         self.assertEqual(status_code, 302)
 
+    def test_download_count_is_in_init_context(self):
+        context = {}
+        DetailMateriService.init_materi_download_count(context, self.materi1)
+        self.assertIn('materi_download_count', context.keys())
+
+    def test_download_count_is_integer(self):
+        context = {}
+        DetailMateriService.init_materi_download_count(context, self.materi1)
+        self.assertEqual(type(context['materi_download_count']), int)
+
 class PostsViewTest(TestCase):
 
     @classmethod
-- 
GitLab


From 8391904b378298841a384f787332b7e7e9731191 Mon Sep 17 00:00:00 2001
From: Samuel Tupa Febrian <samuel.febrian@gmail.com>
Date: Wed, 21 Oct 2020 21:33:13 +0700
Subject: [PATCH 02/10] [#107][GREEN] Implement context initializer for
 download count with constant value

---
 app/services.py | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/app/services.py b/app/services.py
index 65199ff..7e3ba9e 100644
--- a/app/services.py
+++ b/app/services.py
@@ -131,6 +131,10 @@ class DetailMateriService:
             user_name = request.user.name
         return user_name
 
+    @staticmethod
+    def init_materi_download_count(context, materi):
+        context["materi_download_count"] = 0
+
 class CitationService:
 
     @staticmethod
-- 
GitLab


From a8b300cf67ee73876fd3b6001e6656adea4dd78c Mon Sep 17 00:00:00 2001
From: Samuel Tupa Febrian <samuel.febrian@gmail.com>
Date: Fri, 23 Oct 2020 00:18:56 +0700
Subject: [PATCH 03/10] [RED] Create testcase to test download count when
 material is downloaded

---
 app/tests.py | 49 +++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 45 insertions(+), 4 deletions(-)

diff --git a/app/tests.py b/app/tests.py
index 508fcc6..f25773e 100644
--- a/app/tests.py
+++ b/app/tests.py
@@ -270,11 +270,17 @@ class DetailMateriTest(TestCase):
             "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.materi1 = 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)
+        self.materi2 = Materi.objects.create(title="Materi 2", author="Agad", 
+                        uploader=self.contributor, publisher="Kelas SM", 
+                        descriptions="Deskripsi Materi 2", status="APPROVE", 
+                        cover=self.cover, content=self.content)
         self.url = "/materi/" + str(self.materi1.id) + "/"
+        self.download_url1 = self.url + "unduh"
+        self.download_url2 = "/materi/" + str(self.materi2.id) + "/unduh"
 
         self.materi_with_published_date = Materi.objects.create(title="Materi 1", author="Agas", uploader=self.contributor,
                                                  publisher="Kelas SC", descriptions="Deskripsi Materi 1",
@@ -590,6 +596,41 @@ class DetailMateriTest(TestCase):
         DetailMateriService.init_materi_download_count(context, self.materi1)
         self.assertEqual(type(context['materi_download_count']), int)
 
+    def test_download_count_when_no_download(self):
+        context = {}
+        DetailMateriService.init_materi_download_count(context, self.materi1)
+        self.assertEqual(context['materi_download_count'], 0)
+
+    def test_download_count_when_single_download(self):
+        self.client.get(self.download_url1)
+        context = {}
+        DetailMateriService.init_materi_download_count(context, self.materi1)
+        self.assertEqual(context['materi_download_count'], 1)
+
+    def test_download_count_when_multiple_download(self):
+        self.client.get(self.download_url1)
+        self.client.get(self.download_url1)
+        self.client.get(self.download_url1)
+        context = {}
+        DetailMateriService.init_materi_download_count(context, self.materi1)
+        self.assertEqual(context['materi_download_count'], 3)
+
+    def test_different_material_has_different_download_count(self):
+        self.client.get(self.download_url1)
+        self.client.get(self.download_url1)
+        self.client.get(self.download_url1)
+
+        self.client.get(self.download_url2)
+        self.client.get(self.download_url2)
+
+        context1 = {}
+        context2 = {}
+        DetailMateriService.init_materi_download_count(context1, self.materi1)
+        DetailMateriService.init_materi_download_count(context2, self.materi2)
+        self.assertNotEqual(context1['materi_download_count'], context2['materi_download_count'])
+        self.assertEqual(context1['materi_download_count'], 3)
+        self.assertEqual(context2['materi_download_count'], 2)
+
 class PostsViewTest(TestCase):
 
     @classmethod
-- 
GitLab


From 62d654aad836d3abb920fbd7a44f33f0d4a3122f Mon Sep 17 00:00:00 2001
From: Samuel Tupa Febrian <samuel.febrian@gmail.com>
Date: Fri, 23 Oct 2020 00:23:36 +0700
Subject: [PATCH 04/10] [GREEN] Replace constant value with material download
 count

---
 app/services.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/services.py b/app/services.py
index 7e3ba9e..962fb6b 100644
--- a/app/services.py
+++ b/app/services.py
@@ -133,7 +133,7 @@ class DetailMateriService:
 
     @staticmethod
     def init_materi_download_count(context, materi):
-        context["materi_download_count"] = 0
+        context["materi_download_count"] = materi.unduh.all().count()
 
 class CitationService:
 
-- 
GitLab


From a8784cbd8fb432fe6189ca95b9c47f4951266b65 Mon Sep 17 00:00:00 2001
From: Samuel Tupa Febrian <samuel.febrian@gmail.com>
Date: Wed, 28 Oct 2020 19:56:55 +0700
Subject: [PATCH 05/10] [RED] Create test for download count info view with
 constant value

---
 app/tests.py | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/app/tests.py b/app/tests.py
index f25773e..cfb5e51 100644
--- a/app/tests.py
+++ b/app/tests.py
@@ -1,6 +1,7 @@
 import json, tempfile, os, mock
 import pandas as pd
 from io import StringIO
+import re
 import time
 
 from bs4 import BeautifulSoup
@@ -245,6 +246,12 @@ class DaftarKatalogPerKontributorTest(TestCase):
 
 
 class DetailMateriTest(TestCase):
+    def check_materi_info_in_html(self, info_name, info_value, html_content):
+        expected_content = '<div class="info" id="1"><dl class="col col-4">'
+        expected_content += f'<dt class="info-name">{info_name}</dt>' + '</dl><dd>'
+        expected_content += f'<p class="info-content">{info_value}</p>' + '</dd></div>'
+        self.assertIn(expected_content, re.sub(">\s*<","><", html_content))
+
     def setUp(self):
         self.client = Client()
         self.admin_credential = {
@@ -630,6 +637,11 @@ class DetailMateriTest(TestCase):
         self.assertNotEqual(context1['materi_download_count'], context2['materi_download_count'])
         self.assertEqual(context1['materi_download_count'], 3)
         self.assertEqual(context2['materi_download_count'], 2)
+    
+    def test_download_count_displayed_on_template_when_no_download(self):
+        response = self.client.get(self.url)
+        html = response.content.decode("utf-8")
+        self.check_materi_info_in_html("Jumlah Download", 0, html)
 
 class PostsViewTest(TestCase):
 
-- 
GitLab


From 9e7ba243d9b4ca429dafb8fb1e21fffc58e05187 Mon Sep 17 00:00:00 2001
From: Samuel Tupa Febrian <samuel.febrian@gmail.com>
Date: Wed, 28 Oct 2020 20:48:43 +0700
Subject: [PATCH 06/10] [RED] Implement constant download count on context

---
 app/views.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/app/views.py b/app/views.py
index b0f703e..b0f2ea6 100644
--- a/app/views.py
+++ b/app/views.py
@@ -108,6 +108,7 @@ class DetailMateri(TemplateView):
         DetailMateriService.init_context_data(context, materi, self.request.session)
         published_date = DetailMateriService.set_published_date(materi)
         DetailMateriService.init_citation_and_materi_rating(context, materi, published_date, self.request)
+        context["materi_download_count"] = 0
 
         if self.request.user.is_authenticated:
             materi_rating = Rating.objects.filter(materi=materi, user=self.request.user).first()
-- 
GitLab


From 1d684e106be0ac8bb7c852d80bb32e2bf5296b56 Mon Sep 17 00:00:00 2001
From: Samuel Tupa Febrian <samuel.febrian@gmail.com>
Date: Wed, 28 Oct 2020 21:06:50 +0700
Subject: [PATCH 07/10] [GREEN] Implement download count info on views

---
 app/templates/app/detail_materi.html | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/app/templates/app/detail_materi.html b/app/templates/app/detail_materi.html
index 577e65b..b834cb5 100644
--- a/app/templates/app/detail_materi.html
+++ b/app/templates/app/detail_materi.html
@@ -160,6 +160,14 @@
                         <p class="info-content">{{materi_data.content.size|filesizeformat}}</p>
                     </dd>
                 </div>
+                <div class="info" id="1">
+                    <dl class="col col-4">
+                        <dt class="info-name">Jumlah Download</dt>
+                    </dl>
+                    <dd>
+                        <p class="info-content">{{materi_download_count}}</p>
+                    </dd>
+                </div>
             </div>
             <div class="buttons d-flex flex-row bd-highlight mb-1">
                 <a href="{% url 'view-materi' materi_data.id %}"
-- 
GitLab


From 552787c2a15f835d3fb8242e03830f39bd10d7d9 Mon Sep 17 00:00:00 2001
From: Samuel Tupa Febrian <samuel.febrian@gmail.com>
Date: Wed, 28 Oct 2020 21:59:59 +0700
Subject: [PATCH 08/10] [RED] Create test for real and dynamic download count
 view

---
 app/tests.py | 60 +++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 55 insertions(+), 5 deletions(-)

diff --git a/app/tests.py b/app/tests.py
index cfb5e51..b15dae8 100644
--- a/app/tests.py
+++ b/app/tests.py
@@ -246,12 +246,20 @@ class DaftarKatalogPerKontributorTest(TestCase):
 
 
 class DetailMateriTest(TestCase):
+    def _get_materi_info_html(self, info_name, info_value):
+        info_html = '<div class="info" id="1"><dl class="col col-4">'
+        info_html += f'<dt class="info-name">{info_name}</dt>' + '</dl><dd>'
+        info_html += f'<p class="info-content">{info_value}</p>' + '</dd></div>'
+        return info_html
+
     def check_materi_info_in_html(self, info_name, info_value, html_content):
-        expected_content = '<div class="info" id="1"><dl class="col col-4">'
-        expected_content += f'<dt class="info-name">{info_name}</dt>' + '</dl><dd>'
-        expected_content += f'<p class="info-content">{info_value}</p>' + '</dd></div>'
+        expected_content = self._get_materi_info_html(info_name, info_value)
         self.assertIn(expected_content, re.sub(">\s*<","><", html_content))
 
+    def check_materi_info_not_in_html(self, info_name, info_value, html_content):
+        expected_content = self._get_materi_info_html(info_name, info_value)
+        self.assertNotIn(expected_content, re.sub(">\s*<","><", html_content))
+
     def setUp(self):
         self.client = Client()
         self.admin_credential = {
@@ -287,7 +295,9 @@ class DetailMateriTest(TestCase):
                         cover=self.cover, content=self.content)
         self.url = "/materi/" + str(self.materi1.id) + "/"
         self.download_url1 = self.url + "unduh"
-        self.download_url2 = "/materi/" + str(self.materi2.id) + "/unduh"
+        self.url2 = "/materi/" + str(self.materi2.id) + "/"
+        self.download_url2 = self.url2 + "unduh"
+        self.dcount_info_name = "Jumlah Download"
 
         self.materi_with_published_date = Materi.objects.create(title="Materi 1", author="Agas", uploader=self.contributor,
                                                  publisher="Kelas SC", descriptions="Deskripsi Materi 1",
@@ -641,7 +651,47 @@ class DetailMateriTest(TestCase):
     def test_download_count_displayed_on_template_when_no_download(self):
         response = self.client.get(self.url)
         html = response.content.decode("utf-8")
-        self.check_materi_info_in_html("Jumlah Download", 0, html)
+        self.check_materi_info_in_html(self.dcount_info_name, 0, html)
+
+    def test_download_count_displayed_on_template_when_single_download(self):
+        self.client.get(self.download_url1)
+
+        response = self.client.get(self.url)
+        html = response.content.decode("utf-8")
+        self.check_materi_info_in_html(self.dcount_info_name, 1, html)
+
+    def test_download_count_displayed_on_template_when_multiple_download(self):
+        self.client.get(self.download_url1)
+        self.client.get(self.download_url1)
+        self.client.get(self.download_url1)
+        self.client.get(self.download_url1)
+
+        response = self.client.get(self.url)
+        html = response.content.decode("utf-8")
+        self.check_materi_info_in_html(self.dcount_info_name, 4, html)
+
+    def test_different_material_has_different_download_count_on_templates(self):
+        self.client.get(self.download_url1)
+        self.client.get(self.download_url1)
+
+        self.client.get(self.download_url2)
+        self.client.get(self.download_url2)
+        self.client.get(self.download_url2)
+        self.client.get(self.download_url2)
+
+        response = self.client.get(self.url)
+        response2 = self.client.get(self.url2)
+
+        html = response.content.decode("utf-8")
+        html2 = response2.content.decode("utf-8")
+
+        dcount_materi1 = self.materi1.unduh.all().count()
+        dcount_materi2 = self.materi2.unduh.all().count()
+
+        self.check_materi_info_in_html(self.dcount_info_name, dcount_materi1, html)
+        self.check_materi_info_not_in_html(self.dcount_info_name, dcount_materi2, html)
+        self.check_materi_info_in_html(self.dcount_info_name, dcount_materi2, html2)
+        self.check_materi_info_not_in_html(self.dcount_info_name, dcount_materi1, html2)
 
 class PostsViewTest(TestCase):
 
-- 
GitLab


From d5c45f4567ad06a76540ada7dff5e28d56f2f1d5 Mon Sep 17 00:00:00 2001
From: Samuel Tupa Febrian <samuel.febrian@gmail.com>
Date: Wed, 28 Oct 2020 22:20:58 +0700
Subject: [PATCH 09/10] [GREEN] Implement download count on views with service
 method

---
 app/views.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/views.py b/app/views.py
index b0f2ea6..eea6f49 100644
--- a/app/views.py
+++ b/app/views.py
@@ -108,7 +108,7 @@ class DetailMateri(TemplateView):
         DetailMateriService.init_context_data(context, materi, self.request.session)
         published_date = DetailMateriService.set_published_date(materi)
         DetailMateriService.init_citation_and_materi_rating(context, materi, published_date, self.request)
-        context["materi_download_count"] = 0
+        DetailMateriService.init_materi_download_count(context, materi)
 
         if self.request.user.is_authenticated:
             materi_rating = Rating.objects.filter(materi=materi, user=self.request.user).first()
-- 
GitLab


From feb1993cbf62474a38515d001c0d24600a1c255f Mon Sep 17 00:00:00 2001
From: Samuel Tupa Febrian <samuel.febrian@gmail.com>
Date: Thu, 29 Oct 2020 18:33:44 +0700
Subject: [PATCH 10/10] [#107][REFACTOR] Resolve conflict from master again

---
 app/migrations/0025_review.py | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 app/migrations/0025_review.py

diff --git a/app/migrations/0025_review.py b/app/migrations/0025_review.py
new file mode 100644
index 0000000..79b7b89
--- /dev/null
+++ b/app/migrations/0025_review.py
@@ -0,0 +1,30 @@
+# Generated by Django 3.1 on 2020-10-29 11:22
+
+import app.models
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ('app', '0024_merge_20201026_0812'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Review',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('username', models.CharField(max_length=100)),
+                ('profile', models.CharField(default=app.models.getRandomColor, max_length=100)),
+                ('review', models.TextField(default='review')),
+                ('timestamp', models.DateTimeField(default=django.utils.timezone.now)),
+                ('materi', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='app.materi')),
+                ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
+            ],
+        ),
+    ]
-- 
GitLab