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