diff --git a/app/services.py b/app/services.py index 300dbf45b0873615d1d1586a7dd788038eafc4d6..7ea312c8994282b062e98e49280da85d4758354d 100644 --- a/app/services.py +++ b/app/services.py @@ -4,21 +4,24 @@ import random import shutil from functools import cmp_to_key +import requests +from administration.models import VerificationReport +from digipus import settings from django.contrib import messages from django.contrib.auth.models import AnonymousUser from django.core.exceptions import ValidationError -from django.db.models import Case, When, Count, Q +from django.db.models import Case, Count, Q, When from django.shortcuts import get_object_or_404 +from django.utils import timezone from pydrive.auth import GoogleAuth from pydrive.drive import GoogleDrive -from administration.models import VerificationReport from app.forms import SuntingProfilForm -from app.models import Category, Like, LikeComment, DislikeComment, Materi, Comment, Rating, DownloadStatistics, \ - ViewStatistics, ReadLater -from app.utils.fileManagementUtil import get_random_filename, remove_image_exifdata -from digipus import settings -import requests +from app.models import (Category, Comment, DislikeComment, DownloadStatistics, + Like, LikeComment, Materi, Rating, ReadLater, + ViewStatistics) +from app.utils.fileManagementUtil import (get_random_filename, + remove_image_exifdata) class DafterKatalogService: @@ -160,7 +163,7 @@ class CitationService: @staticmethod def get_citation_ieee(request, materi): - current_date = datetime.datetime.now() + current_date = timezone.now() current_day = str(current_date.day) current_month = current_date.strftime("%b") current_year = str(current_date.year) @@ -483,4 +486,4 @@ class ReadLaterService: else: ReadLater(materi=materi, user=current_user).save() response = {"success": True, "read_later_checked": True} - return response \ No newline at end of file + return response diff --git a/app/tests.py b/app/tests.py index 5b83a94176217c709516472a1584b0b800e4c7b6..02f8e1fb666e89e5a1319b20398e06da1682957e 100644 --- a/app/tests.py +++ b/app/tests.py @@ -1,87 +1,65 @@ -import json, tempfile, os, mock, base64 -import pandas as pd -from io import StringIO +import base64 +import datetime as dt +import json +import os +import random import re +import tempfile import time -import random -from django.test import override_settings +from datetime import datetime +from io import StringIO +from time import sleep +import mock +import pandas as pd +import pytz +from administration.models import VerificationReport, VerificationSetting +from administration.utils import id_generator +from authentication.models import User from bs4 import BeautifulSoup -from datetime import datetime +from digipus.settings import TIME_ZONE 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 mail, serializers -from django.core.files import File from django.core.exceptions import PermissionDenied, ValidationError +from django.core.files import File 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 django.test import (Client, RequestFactory, TestCase, TransactionTestCase, + override_settings) +from django.urls import resolve, reverse +from django.utils import timezone -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, - ReadLater -) - -from .services import ( - DetailMateriService, -) - -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 +from app.utils.fileManagementUtil import (get_random_filename, + remove_image_exifdata) from app.utils.PasswordValidator import PasswordPolicyValidator +from app.views import UploadMateriHTML, add_rating_materi + +from .models import (Category, Comment, DislikeComment, DownloadStatistics, + Like, LikeComment, Materi, Rating, RatingContributor, + ReadLater, ReqMaterial, Review, ViewStatistics) +from .services import DetailMateriService +from .views import (DaftarKatalog, DashboardKontributorView, DetailMateri, + KatalogPerKontributorView, MateriFavorite, + PasswordChangeViews, PostsView, ProfilView, ReqMateriView, + RevisiMateriView, SuksesLoginAdminView, + SuksesLoginKontributorView, SuntingProfilView, + UploadMateriExcelView, UploadMateriView, password_success) ERROR_403_MESSAGE = "Kamu harus login untuk mengakses halaman ini" +from statistics import mean + +import requests from django.test import LiveServerTestCase from selenium import webdriver +from selenium.common.exceptions import NoSuchElementException 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): @@ -343,7 +321,7 @@ class DetailMateriTest(TestCase): 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()) + date_modified=timezone.now(), date_created=timezone.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}]}', \ @@ -758,7 +736,7 @@ class DetailMateriTest(TestCase): def test_citation_IEEE_materi_has_no_published_date(self): response = self.client.get(self.url) - current_date = datetime.now() + current_date = timezone.now() current_day = str(current_date.day) current_month = current_date.strftime("%b") current_year = str(current_date.year) @@ -781,7 +759,7 @@ class DetailMateriTest(TestCase): def test_citation_IEEE_materi_has_published_date(self): response = self.client.get(self.materi_with_published_date_url) - current_date = datetime.now() + current_date = timezone.now() current_day = str(current_date.day) current_month = current_date.strftime("%b") current_year = str(current_date.year) @@ -983,7 +961,7 @@ class PostsViewTest(TestCase): for j in range (LIKES_COUNT_PER_POST[i]): Like.objects.create( - timestamp=datetime.now(), + timestamp=timezone.now(), materi=post, session_id=("dummysession-" + str(i) + '-' + str(j)) ) @@ -1050,6 +1028,8 @@ class PostsViewTest(TestCase): response = self._request_as_user() posts = list(self.data.keys()) + posts.sort() + comments = { i: [comment.id for comment in self.data[post_id]["comments"]] for i, post_id in enumerate(posts) @@ -2740,7 +2720,7 @@ class DownloadHistoryViewTest(TestCase): self.client.get(self.download_url2) self.client.get(self.download_url1) - jkt_timezone = timezone(TIME_ZONE) + jkt_timezone = pytz.timezone(TIME_ZONE) download_history = self.user_anonim.riwayat_unduh.all() response = self.client.get(self.history_url) @@ -2760,7 +2740,7 @@ class DownloadHistoryViewTest(TestCase): self.client.get(self.download_url2) self.client.get(self.download_url1) - jkt_timezone = timezone(TIME_ZONE) + jkt_timezone = pytz.timezone(TIME_ZONE) response = self.client.get(self.history_url) resp_html = response.content.decode('utf8') @@ -2780,7 +2760,7 @@ class DownloadHistoryViewTest(TestCase): self.client.logout() - jkt_timezone = timezone(TIME_ZONE) + jkt_timezone = pytz.timezone(TIME_ZONE) download_history = self.user_anonim.riwayat_unduh.all() response = self.client.get(self.history_url) @@ -2856,16 +2836,16 @@ class MateriModelTest(TestCase): self.materi = 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()) + date_modified=timezone.now(), date_created=timezone.now()) def test_like_count_return_zero_when_there_is_no_like(self): self.assertEqual(0, self.materi.like_count) def test_like_count_return_right_value_when_there_is_like(self): - Like.objects.create(timestamp=datetime.now(), materi=self.materi, session_id="dummysessionid1") + Like.objects.create(timestamp=timezone.now(), materi=self.materi, session_id="dummysessionid1") self.assertEqual(1, self.materi.like_count) - Like.objects.create(timestamp=datetime.now(), materi=self.materi, session_id="dummysessionid2") + Like.objects.create(timestamp=timezone.now(), materi=self.materi, session_id="dummysessionid2") self.assertEqual(2, self.materi.like_count) class MateriFavoriteTest(TestCase): @@ -2904,8 +2884,8 @@ class RandomizedMateriTest(TestCase): status="APPROVE", cover=self.cover, content=self.content, - date_modified=datetime.now(), - date_created=datetime.now(), + date_modified=timezone.now(), + date_created=timezone.now(), ) self.materi = Materi.objects.create( @@ -2917,8 +2897,8 @@ class RandomizedMateriTest(TestCase): status="APPROVE", cover=self.cover, content=self.content, - date_modified=datetime.now(), - date_created=datetime.now(), + date_modified=timezone.now(), + date_created=timezone.now(), ) def test_randomized_materi_returns_200(self): @@ -2998,8 +2978,9 @@ class YTUrlVideoTest(TestCase): @override_settings(MEDIA_ROOT=tempfile.gettempdir()) def setUpImage(self): - from django.core.files.uploadedfile import InMemoryUploadedFile from io import BytesIO + + from django.core.files.uploadedfile import InMemoryUploadedFile self.cover = InMemoryUploadedFile( BytesIO(base64.b64decode(TEST_IMAGE)), field_name='tempfile', @@ -3367,8 +3348,8 @@ class MateriRecommendationTest(TestCase): status="APPROVE", cover=self.cover, content=self.content, - date_modified=datetime.now(), - date_created=datetime.now(), + date_modified=timezone.now(), + date_created=timezone.now(), ) Like.objects.create(materi=materi1) @@ -3383,8 +3364,8 @@ class MateriRecommendationTest(TestCase): status="APPROVE", cover=self.cover, content=self.content, - date_modified=datetime.now(), - date_created=datetime.now(), + date_modified=timezone.now(), + date_created=timezone.now(), ) Like.objects.create(materi=materi2) @@ -3400,8 +3381,8 @@ class MateriRecommendationTest(TestCase): status="APPROVE", cover=self.cover, content=self.content, - date_modified=datetime.now(), - date_created=datetime.now(), + date_modified=timezone.now(), + date_created=timezone.now(), ) response = Client().get("/?recommendation=1") @@ -3418,8 +3399,8 @@ class MateriRecommendationTest(TestCase): status="APPROVE", cover=self.cover, content=self.content, - date_modified=datetime.now(), - date_created=datetime.now(), + date_modified=timezone.now(), + date_created=timezone.now(), ) Like.objects.create(materi=materi2) @@ -3434,8 +3415,8 @@ class MateriRecommendationTest(TestCase): status="APPROVE", cover=self.cover, content=self.content, - date_modified=datetime.now(), - date_created=datetime.now(), + date_modified=timezone.now(), + date_created=timezone.now(), ) Like.objects.create(materi=materi1) diff --git a/app/tests.py.56b44c7bd7ec54dbc681b2c3905ccac9.tmp b/app/tests.py.56b44c7bd7ec54dbc681b2c3905ccac9.tmp deleted file mode 100644 index a5a4db8e0ff4e2768425b836bee6e0d3b9996f77..0000000000000000000000000000000000000000 --- a/app/tests.py.56b44c7bd7ec54dbc681b2c3905ccac9.tmp +++ /dev/null @@ -1,2108 +0,0 @@ -import json, tempfile, os, mock -import pandas as pd -from io import StringIO - -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.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 - -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, - DownloadStatistics, - Materi, - Like, - Rating, - ReqMaterial, - RatingContributor, - ViewStatistics, -) - -from .views import ( - DaftarKatalog, - DashboardKontributorView, - DetailMateri, - ProfilKontributorView, - SuksesLoginAdminView, - SuksesLoginKontributorView, - SuntingProfilView, - ProfilAdminView, - PostsView, - SuntingProfilAdminView, - RevisiMateriView, - ReqMateriView, - KatalogPerKontributorView, - UploadMateriView, - UploadMateriExcelView, -) -from app.forms import SuntingProfilForm -from app.utils.fileManagementUtil import get_random_filename, remove_image_exifdata - -ERROR_403_MESSAGE = "Kamu harus login untuk mengakses halaman ini" - -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 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") - countData = Category.objects.all().count() - self.assertEqual(1, countData) - self.assertNotEqual(0, countData) - 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") - countData = Comment.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_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_detail_materi_contains_form_comment(self): - response = self.client.get(self.url) - self.assertContains(response, "Beri komentar...") - - def test_delete_comments_by_admin(self): - url = self.url - 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) - ) - self.client.get(deleteURL) - self.assertEqual(Comment.objects.all().filter(comment="This is new comment by Anonymous").count(), 0) - - 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"]) - - 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.views.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.views.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'.*(<div id="post-{posts[2]}">)' - + rf'.*(<div id="post-{posts[2]}-comment-{comments[2][0]}">)' - + rf'.*(<div id="post-{posts[2]}-comment-{comments[2][1]}">)' - + rf'.*(<div id="post-{posts[2]}-comment-{comments[2][2]}">)' - + rf'.*(<div id="post-{posts[1]}">)' - + rf'.*(<div id="post-{posts[0]}">)' - + rf'.*(<div id="post-{posts[0]}-comment-{comments[0][0]}">)', - ) - - def test_like_count_written_correctly_on_template(self): - response = self._request_as_user() - - for _, post_id in enumerate(self.data): - post = self.data[post_id]["data"] - - self.assertContains( - response, '<span id="post-like-count-' + str(post.id) + '">' + str(post.like_count) + "</span>", - ) - - -class TemplateLoaderTest(TestCase): - def test_template_loader_url_exist(self): - url = "/test-page.html" - response = Client().get(url) - self.assertEqual(response.status_code, 200) - - def test_template_loader_using_template_loader_template(self): - url = "/test-page.html" - response = Client().get(url) - expected_template_name = "test-page.html" - self.assertTemplateUsed(response, expected_template_name) - - def test_template_loader_using_template_loader_func(self): - url = "/test-page.html" - found = resolve(url) - expected_view_name = "pages" - self.assertEqual(found.func.__name__, expected_view_name) - - def test_template_loader_handle_non_existent_html(self): - url = "/test.html" - expected_template_name = "error-404.html" - response = Client().get(url) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, expected_template_name) - - -class UploadPageTest(TestCase): - def setUp(self): - self.client = Client() - self.user = User.objects._create_user(email="kontributor@gov.id", password="kontributor", is_contributor=True) - self.admin = User.objects.create_admin(email="admin@gov.id", password="admin") - - def test_upload_page_using_login_func(self): - found = resolve("/unggah/") - self.assertEqual(found.func.__name__, UploadMateriView.as_view().__name__) - - def test_upload_page_url_is_exist(self): - # Positive test - self.client.login(email="kontributor@gov.id", password="kontributor") - response = self.client.get("/unggah/") - self.assertEqual(response.status_code, 200) - - # Negative tests - self.client.login(email="kontributor@gov.id", password="kontributor") - response = Client().get("/fake/") - self.assertEqual(response.status_code, 404) - - def test_upload_page_url_admin_doesnt_exist(self): - self.client.login(email="admin@gov.id", password="admin") - response = self.client.get("/unggah/") - self.assertEqual(response.status_code, 403) - - def test_upload_page_url_admin_cant_upload(self): - self.client.login(email="admin@gov.id", password="admin") - response = self.client.post("/unggah/") - self.assertEqual(response.status_code, 403) - - def test_upload_page_template(self): - url = "/unggah/" - self.client.login(email="kontributor@gov.id", password="kontributor") - response = self.client.get(url) - expected_template_name = "unggah.html" - self.assertTemplateUsed(response, expected_template_name) - - def test_upload_page_title(self): - self.client.login(email="kontributor@gov.id", password="kontributor") - response = self.client.get("/unggah/") - - # Positive tests - self.assertContains(response, "Unggah Materi") - - # Negative tests - self.assertNotContains(response, "Anything") - - def test_upload_page_form_field(self): - self.client.login(email="kontributor@gov.id", password="kontributor") - response = self.client.get("/unggah/") - - # Positive tests - self.assertContains(response, "title") - - # Negative tests - self.assertNotContains(response, "anything") - - -class UploadExcelPageTest(TestCase): - def setUp(self): - self.client = Client() - self.user = User.objects._create_user(email="kontributor@gov.id", password="kontributor", is_contributor=True) - - def test_upload_excel_page_using_login_func(self): - found = resolve("/unggah_excel/") - self.assertEqual(found.func.__name__, UploadMateriExcelView.as_view().__name__) - - def test_uplaod_excel_page_url_is_exist(self): - # Positive test - self.client.login(email="kontributor@gov.id", password="kontributor") - response = self.client.get("/unggah_excel/") - self.assertEqual(response.status_code, 200) - - # Negative tests - self.client.login(email="kontributor@gov.id", password="kontributor") - response = Client().get("/fake/") - self.assertEqual(response.status_code, 404) - - def test_upload_excel_page_template(self): - url = "/unggah_excel/" - self.client.login(email="kontributor@gov.id", password="kontributor") - response = self.client.get(url) - expected_template_name = "unggah_excel.html" - self.assertTemplateUsed(response, expected_template_name) - - def test_upload_excel_page_title(self): - self.client.login(email="kontributor@gov.id", password="kontributor") - response = self.client.get("/unggah_excel/") - - # Positive tests - self.assertContains(response, "Unggah Materi dari Excel") - - # Negative tests - self.assertNotContains(response, "Anything") - - def test_upload_excel_page_form_field(self): - self.client.login(email="kontributor@gov.id", password="kontributor") - response = self.client.get("/unggah_excel/") - - # Positive tests - self.assertContains(response, "File (*.xlsx)") - - # Negative tests - self.assertNotContains(response, "anything") - - def create_dummy_excel(self, field_lengths={}, categories=[]): - title1 = "Hands-On Machine Learning with Scikit-Learn and TensorFlow: Concepts, Tools, and Techniques to Build Intelligent Systems" - author1 = "Aurelien Geron, Aurelien Geron, Aurelien Geron" - publisher1 = "O'Reilly Media, O'Reilly Media, O'Reilly Media" - categories1 = "Machine Learning,Deep Learning,Computer Science" - description1 = "A series of Deep Learning breakthroughs have boosted the whole field of machine learning over the last decade. Now that machine learning is thriving, even programmers who know close to nothing about this technology can use simple, efficient tools to implement programs capable of learning from data. This practical book shows you how." - - if "title" in field_lengths: - title1 = title1[: field_lengths["title"]] - - if "author" in field_lengths: - author1 = author1[: field_lengths["author"]] - - if "publisher" in field_lengths: - publisher1 = publisher1[: field_lengths["publisher"]] - - if len(categories) > 0: - categories1 = ",".join(categories) - - data_frame = pd.DataFrame( - { - "Title": [title1], - "Author": [author1], - "Publisher": [publisher1], - "Categories": [categories1], - "Description": [description1], - } - ) - - file_path = os.path.join(settings.MEDIA_ROOT, "dummy.xlsx") - - writer = pd.ExcelWriter(file_path, engine="xlsxwriter") # pylint: disable=abstract-class-instantiated - data_frame.to_excel(writer, index=0) - writer.save() - - return file_path, data_frame - - def test_upload_excel_upload_file_title_error(self): - self.client.login(email="kontributor@gov.id", password="kontributor") - - field_lengths = { - "author": 30, - "publisher": 30, - } - file_name, data_frame = self.create_dummy_excel(field_lengths=field_lengths) - - with open(file_name, "rb") as fp: - response = self.client.post("/unggah_excel/", {"excel": fp}) - - messages = list(dj_messages.get_messages(response.wsgi_request)) - msg_text = messages[0].message - - self.assertIn("Title", msg_text) - - def test_upload_excel_upload_file_author_error(self): - self.client.login(email="kontributor@gov.id", password="kontributor") - - field_lengths = { - "title": 50, - "publisher": 30, - } - file_name, data_frame = self.create_dummy_excel(field_lengths=field_lengths) - - with open(file_name, "rb") as fp: - response = self.client.post("/unggah_excel/", {"excel": fp}) - - messages = list(dj_messages.get_messages(response.wsgi_request)) - msg_text = messages[0].message - - self.assertIn("Author", msg_text) - - def test_upload_excel_upload_file_publisher_error(self): - self.client.login(email="kontributor@gov.id", password="kontributor") - - field_lengths = { - "title": 50, - "author": 30, - } - file_name, data_frame = self.create_dummy_excel(field_lengths=field_lengths) - - with open(file_name, "rb") as fp: - response = self.client.post("/unggah_excel/", {"excel": fp}) - - messages = list(dj_messages.get_messages(response.wsgi_request)) - msg_text = messages[0].message - - self.assertIn("Publisher", msg_text) - - def test_upload_excel_upload_file_categories_error(self): - self.client.login(email="kontributor@gov.id", password="kontributor") - - field_lengths = { - "title": 50, - "author": 30, - "publisher": 30, - } - file_name, data_frame = self.create_dummy_excel(field_lengths=field_lengths) - - with open(file_name, "rb") as fp: - response = self.client.post("/unggah_excel/", {"excel": fp}) - - messages = list(dj_messages.get_messages(response.wsgi_request)) - msg_text = messages[0].message - - self.assertIn("Kategori", msg_text) - - def test_upload_excel_upload_file_success(self): - self.client.login(email="kontributor@gov.id", password="kontributor") - - Category(name="Computer Science").save() - Category(name="Machine Learning").save() - Category(name="Deep Learning").save() - - field_lengths = { - "title": 50, - "author": 30, - "publisher": 30, - } - - categories = ["Computer Science", "Machine Learning", "Deep Learning"] - - file_name, data_frame = self.create_dummy_excel(field_lengths=field_lengths, categories=categories) - - with open(file_name, "rb") as fp: - response = self.client.post("/unggah_excel/", {"excel": fp}) - - title = data_frame["Title"][0] - self.assertTrue(Materi.objects.get(title=title)) - - def test_upload_excel_download_template(self): - self.client.login(email="kontributor@gov.id", password="kontributor") - - response = self.client.get("/unggah_excel/?template=1") - - self.assertEquals( - response["Content-Type"], "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" - ) - self.assertEquals(response["Content-Disposition"], "attachment; filename=template.xlsx") - - -class DashboardKontributorViewTest(TestCase): - def setUp(self): - self.client = Client() - self.kontributor = User.objects.create_contributor(email="kontributor@gov.id", password="kontributor") - self.admin = User.objects.create_admin(email="admin@gov.id", password="admin") - self.url = "/dashboard/" - self.view = DashboardKontributorView - self.template_name = "dashboard.html" - - def test_dashboard_kontributor_view(self): - found = resolve(self.url) - self.assertEqual(found.func.__name__, self.view.as_view().__name__) - - def test_dashboard_kontributor_template(self): - # Login - self.client.login(email="kontributor@gov.id", password="kontributor") - # Test - response = self.client.get(self.url) - self.assertTemplateUsed(response, self.template_name) - # Logout - self.client.logout() - - def test_dashboard_kontributor_url(self): - # Login - self.client.login(email="kontributor@gov.id", password="kontributor") - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - # Logout - self.client.logout() - - def test_dashboard_kontributor_access(self): - # Kontributor - # Login - self.client.login(email="kontributor@gov.id", password="kontributor") - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - # Logout - self.client.logout() - - # Admin - # Login - self.client.login(email="admin@gov.id", password="admin") - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 403) - - html = response.content.decode("utf-8") - self.assertIn(ERROR_403_MESSAGE, html) - # Logout - self.client.logout() - - # Anonim - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 403) - - html = response.content.decode("utf-8") - self.assertIn(ERROR_403_MESSAGE, html) - - -class ProfilAdminTest(TestCase): - def setUp(self): - self.client = Client() - self.kontributor = User.objects.create_contributor(email="kontributor@gov.id", password="kontributor") - self.admin = User.objects.create_admin(email="admin@gov.id", password="admin") - self.url = "/profil-admin/" - self.view = ProfilAdminView - self.template_name = "profil-admin.html" - - def test_profil_Admin_view(self): - found = resolve(self.url) - self.assertEqual(found.func.__name__, self.view.as_view().__name__) - - def test_profil_admin_template(self): - # Login - self.client.login(email="admin@gov.id", password="admin") - # Test - response = self.client.get(self.url) - self.assertTemplateUsed(response, self.template_name) - # Logout - self.client.logout() - - def test_profil_admin_url(self): - # Login - response = self.client.get(self.url) - self.assertNotEqual(response.status_code, 200) - - self.client.login(email="admin@gov.id", password="admin") - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - # Logout - self.client.logout() - - -class ProfilKontributorTest(TestCase): - def setUp(self): - self.client = Client() - self.kontributor = User.objects.create_contributor(email="kontributor@gov.id", password="kontributor") - self.admin = User.objects.create_admin(email="admin@gov.id", password="admin") - self.url = "/profil/" - self.view = ProfilKontributorView - self.template_name = "profil.html" - - def test_profil_kontributor_view(self): - found = resolve(self.url) - self.assertEqual(found.func.__name__, self.view.as_view().__name__) - - def test_profil_kontributor_template(self): - # Login - self.client.login(email="kontributor@gov.id", password="kontributor") - # Test - response = self.client.get(self.url) - self.assertTemplateUsed(response, self.template_name) - # Logout - self.client.logout() - - def test_profil_kontributor_url(self): - # Login - self.client.login(email="kontributor@gov.id", password="kontributor") - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - # Logout - self.client.logout() - - def test_profil_kontributor_access(self): - # Kontributor - # Login - self.client.login(email="kontributor@gov.id", password="kontributor") - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - # Logout - self.client.logout() - - # Admin - # Login - self.client.login(email="admin@gov.id", password="admin") - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 403) - - html = response.content.decode("utf-8") - self.assertIn(ERROR_403_MESSAGE, html) - # Logout - self.client.logout() - - # Anonim - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 403) - - html = response.content.decode("utf-8") - self.assertIn(ERROR_403_MESSAGE, html) - - -class SuntingProfilTest(TestCase): - def setUp(self): - self.client = Client() - self.kontributor = User.objects.create_contributor(email="kontributor@gov.id", password="kontributor") - self.admin = User.objects.create_admin(email="admin@gov.id", password="admin") - self.url = "/sunting/" - self.view = SuntingProfilView - self.template_name = "sunting.html" - - def test_sunting_profile_view(self): - found = resolve(self.url) - self.assertEqual(found.func.__name__, self.view.as_view().__name__) - - def test_sunting_profile_template(self): - # Login - self.client.login(email="kontributor@gov.id", password="kontributor") - # Test - response = self.client.get(self.url) - self.assertTemplateUsed(response, self.template_name) - # Logout - self.client.logout() - - def test_sunting_profile_url(self): - # Login - self.client.login(email="kontributor@gov.id", password="kontributor") - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - # Logout - self.client.logout() - - def test_sunting_profile_access(self): - # Kontributor - # Login - self.client.login(email="kontributor@gov.id", password="kontributor") - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - # Logout - self.client.logout() - - def test_sunting_profile_access_anonymous(self): - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 403) - - def test_sunting_profile_autofocus(self): - form_data = { - "email": "kontributor@gov.id", - "name": "kontributor", - "instansi": "instansi", - "nik": "nik", - "alamat": "alamat", - "nomor_telpon": "123456789", - "twitter": "Twit", - "instagram": "https://instagram.com/test_ig", - } - form = SuntingProfilForm(data=form_data) - - # Test - self.assertEqual(form.fields["twitter"].widget.attrs.get("autofocus"), "") - self.assertEqual(form.fields["instagram"].widget.attrs.get("autofocus"), None) - - -class SuntingProfilAdminTest(TestCase): - def setUp(self): - self.client = Client() - self.kontributor = User.objects.create_contributor(email="kontributor@gov.id", password="kontributor") - self.admin = User.objects.create_admin(email="admin@gov.id", password="admin") - self.url = "/sunting-admin/" - self.view = SuntingProfilAdminView - self.template_name = "sunting_admin.html" - - def test_sunting_profile_admin_view(self): - found = resolve(self.url) - self.assertEqual(found.func.__name__, self.view.as_view().__name__) - - def test_sunting_profile_admin_template(self): - # Login - self.client.login(email="admin@gov.id", password="admin") - # Test - response = self.client.get(self.url) - self.assertTemplateUsed(response, self.template_name) - # Logout - self.client.logout() - - def test_sunting_profile_admin_url(self): - # Login - self.client.login(email="admin@gov.id", password="admin") - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - # Logout - self.client.logout() - - def test_sunting_profile_admin_access(self): - # Kontributor - # Login - self.client.login(email="admin@gov.id", password="admin") - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - # Logout - self.client.logout() - - -class SuksesLoginKontributorTest(TestCase): - def setUp(self): - self.client = Client() - self.kontributor = User.objects.create_contributor(email="kontributor@gov.id", password="kontributor") - self.admin = User.objects.create_admin(email="admin@gov.id", password="admin") - self.url = "/sukses-kontributor/" - self.view = SuksesLoginKontributorView - self.template_name = "sukses_kontri.html" - - def test_sukses_login_kontributor_view(self): - found = resolve(self.url) - self.assertEqual(found.func.__name__, self.view.as_view().__name__) - - def test_sukses_login_kontributor_template(self): - # Login - self.client.login(email="kontributor@gov.id", password="kontributor") - # Test - response = self.client.get(self.url) - self.assertTemplateUsed(response, self.template_name) - # Logout - self.client.logout() - - def test_sukses_login_kontributor_url(self): - # Login - self.client.login(email="kontributor@gov.id", password="kontributor") - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - # Logout - self.client.logout() - - def test_sukses_login_kontributor_access(self): - # Kontributor - # Login - self.client.login(email="kontributor@gov.id", password="kontributor") - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - # Logout - self.client.logout() - - -class SuksesLoginAdminTest(TestCase): - def setUp(self): - self.client = Client() - self.kontributor = User.objects.create_contributor(email="kontributor@gov.id", password="kontributor") - self.admin = User.objects.create_admin(email="admin@gov.id", password="admin") - self.url = "/sukses-admin/" - self.view = SuksesLoginAdminView - self.template_name = "sukses_admin.html" - - def test_sukses_login_admin_view(self): - found = resolve(self.url) - self.assertEqual(found.func.__name__, self.view.as_view().__name__) - - def test_sukses_login_admin_template(self): - # Login - self.client.login(email="admin@gov.id", password="admin") - # Test - response = self.client.get(self.url) - self.assertTemplateUsed(response, self.template_name) - # Logout - self.client.logout() - - def test_sukses_login_admin_url(self): - # Login - self.client.login(email="admin@gov.id", password="admin") - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - # Logout - self.client.logout() - - def test_sukses_login_admin_access(self): - # Kontributor - # Login - self.client.login(email="admin@gov.id", password="admin") - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - # Logout - self.client.logout() - - -class LikeMateriTest(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() - self.url_like = "/materi/like/" - 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() - self.materi1 = Materi.objects.first() - self.url_materi = f"/materi/{self.materi1.id}/" - - def test_get_method(self): - response = self.client.get(self.url_like) - response = json.loads(response.content) - self.assertEqual(response.get("success", None), False) - - def test_like_materi(self): - # Verify that materi doesn't have any like to start with - num_of_likes = Like.objects.filter(materi=self.materi1).count() - self.assertEqual(num_of_likes, 0) - - # Like a materi - response = self.client.get(self.url_materi) - session_id = response.context["session_id"] - materi_id = response.context["materi_data"].id - payload = {"materi_id": materi_id, "session_id": session_id} - ajax_response = Client().post(self.url_like, payload) - num_of_likes = Like.objects.filter(materi=self.materi1).count() - self.assertEqual(num_of_likes, 1) - - def test_unlike_materi(self): - # Verify that materi doesn't have any like to start with - num_of_likes = Like.objects.filter(materi=self.materi1).count() - self.assertEqual(num_of_likes, 0) - - # Like a materi - response = self.client.get(self.url_materi) - session_id = response.context["session_id"] - materi_id = response.context["materi_data"].id - payload = {"materi_id": materi_id, "session_id": session_id} - ajax_response = Client().post(self.url_like, payload) - num_of_likes = Like.objects.filter(materi=self.materi1).count() - self.assertEqual(num_of_likes, 1) - - # Unlike a materi - response = self.client.get(self.url_materi) - session_id = response.context["session_id"] - materi_id = response.context["materi_data"].id - payload = {"materi_id": materi_id, "session_id": session_id} - ajax_response = Client().post(self.url_like, payload) - num_of_likes = Like.objects.filter(materi=self.materi1).count() - self.assertEqual(num_of_likes, 0) - - def test_2_client_like_materi(self): - # Verify that materi doesn't have any like to start with - num_of_likes = Like.objects.filter(materi=self.materi1).count() - self.assertEqual(num_of_likes, 0) - - # Client 1 like a materi - response = self.client.get(self.url_materi) - session_id = response.context["session_id"] - materi_id = response.context["materi_data"].id - payload = {"materi_id": materi_id, "session_id": session_id} - ajax_response = Client().post(self.url_like, payload) - num_of_likes = Like.objects.filter(materi=self.materi1).count() - self.assertEqual(num_of_likes, 1) - - # Client 2 like a materi - response = Client().get(self.url_materi) - session_id = response.context["session_id"] - materi_id = response.context["materi_data"].id - payload = {"materi_id": materi_id, "session_id": session_id} - ajax_response = Client().post(self.url_like, payload) - num_of_likes = Like.objects.filter(materi=self.materi1).count() - self.assertEqual(num_of_likes, 2) - - def test_incomplete_like_parameter(self): - # Verify that materi doesn't have any like to start with - num_of_likes = Like.objects.filter(materi=self.materi1).count() - self.assertEqual(num_of_likes, 0) - - # missing session id - response = self.client.get(self.url_materi) - materi_id = response.context["materi_data"].id - payload = { - "materi_id": materi_id, - } - ajax_response = Client().post(self.url_like, payload) - ajax_response = json.loads(ajax_response.content) - num_of_likes = Like.objects.filter(materi=self.materi1).count() - self.assertEqual(num_of_likes, 0) - self.assertEqual(ajax_response.get("success", None), False) - - # missing materi id - response = self.client.get(self.url_materi) - session_id = response.context["session_id"] - payload = {"session_id": session_id} - ajax_response = Client().post(self.url_like, payload) - ajax_response = json.loads(ajax_response.content) - num_of_likes = Like.objects.filter(materi=self.materi1).count() - self.assertEqual(num_of_likes, 0) - self.assertEqual(ajax_response.get("success", None), False) - - -class ViewMateriStatissticsTest(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() - self.materi1 = Materi.objects.first() - self.url = f"/materi/{self.materi1.id}/view" - - # Test single view - def test_count_one_materi_view(self): - response = self.client.get(self.url) - num_of_views = self.materi1.baca.all().count() - self.assertEqual(num_of_views, 1) - - # Test more than one view - def test_count_more_than_one_materi_view(self): - response = self.client.get(self.url) - num_of_views = self.materi1.baca.all().count() - self.assertEqual(num_of_views, 1) - - response = Client().get(self.url) - num_of_views = self.materi1.baca.all().count() - self.assertEqual(num_of_views, 2) - - -class DownloadMateriStatissticsTest(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() - self.materi1 = Materi.objects.first() - self.url = f"/materi/{self.materi1.id}/unduh" - - # Test single download - def test_count_one_materi_download(self): - response = self.client.get(self.url) - num_of_downloads = self.materi1.unduh.all().count() - self.assertEqual(num_of_downloads, 1) - - # Test more than one download - def test_count_more_than_one_materi_download(self): - response = self.client.get(self.url) - num_of_downloads = self.materi1.unduh.all().count() - self.assertEqual(num_of_downloads, 1) - - response = Client().get(self.url) - num_of_downloads = self.materi1.unduh.all().count() - self.assertEqual(num_of_downloads, 2) - - -class RevisiMateriTest(TestCase): - def setUp(self): - self.client = Client() - self.view = RevisiMateriView - self.template_name = "revisi.html" - - 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.cover = SimpleUploadedFile("cover.jpg", b"Test file") - self.content = SimpleUploadedFile("content.txt", b"Test file") - Materi( - title="Materi 1", - author="Agas", - uploader=self.contributor, - publisher="Kelas SC", - descriptions="Deskripsi Materi 1", - status="REVISION", - cover=self.cover, - content=self.content, - ).save() - - self.materi1 = Materi.objects.first() - self.url = "/revisi/materi/" + str(self.materi1.id) + "/" - - def test_revisi_materi_view(self): - found = resolve(self.url) - self.assertEqual(found.func.__name__, self.view.as_view().__name__) - - def test_revisi_materi_template(self): - # Login - self.client.login(**self.contributor_credential) - # Test - response = self.client.get(self.url) - self.assertTemplateUsed(response, self.template_name) - # Logout - self.client.logout() - - def test_revisi_materi_url(self): - # Login - self.client.login(**self.contributor_credential) - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - # Logout - self.client.logout() - - def test_revisi_materi_access(self): - # Kontributor - # Login - self.client.login(**self.contributor_credential) - # Test - response = self.client.get(self.url) - self.assertEqual(response.status_code, 200) - # Logout - self.client.logout() - - -class GenerateDummyCommandTest(TestCase): - def setUp(self): - self.material_numbers = [5, 10, 25, 100] - self.invalid_material_numbers = [-100, -10, -1, 0, 1, 2, 3, 4] - self.stdout = StringIO() - - def test_command_output_with_given_num_of_materi(self): - for num_of_materi in self.material_numbers: - call_command("generatedummy", num_of_materi, stdout=self.stdout) - self.assertIn(f"Successfully created {num_of_materi} materi", self.stdout.getvalue()) - - def test_command_should_generate_materi_objects(self): - for num_of_materi in self.material_numbers: - call_command("generatedummy", num_of_materi, stdout=self.stdout) - self.assertEqual(Materi.objects.count(), num_of_materi) - Materi.objects.all().delete() - - def test_command_should_raise_exception_if_invalid_values_are_given(self): - with self.assertRaises(IndexError): - for num_of_materi in self.invalid_material_numbers: - call_command("generatedummy", num_of_materi) - - -class RemoveDummyCommandTest(TestCase): - def test_calling_remove_dummy_command_should_remove_generated_dummy_objects(self): - stdout = StringIO() - call_command("generatedummy", 50) - - call_command("removedummy", stdout=stdout) - - self.assertIn("Successfully remove all dummy object", stdout.getvalue()) - self.assertEqual(User.objects.count(), 0) - self.assertEqual(Category.objects.count(), 0) - self.assertEqual(Materi.objects.count(), 0) - self.assertEqual(VerificationSetting.objects.count(), 0) - self.assertEqual(VerificationReport.objects.count(), 0) - - -class RatingMateriTest(TestCase): - def setUp(self): - self.contributor_credential = {"email": "kontributor@gov.id", "password": id_generator()} - self.user_one_credential = {"email": "user_one@user.id", "password": id_generator()} - self.user_two_credential = {"email": "user_two@user.id", "password": id_generator()} - self.contributor = get_user_model().objects.create_user( - **self.contributor_credential, name="Kontributor", is_contributor=True - ) - self.user_one = get_user_model().objects.create_user(**self.user_one_credential, name="User One") - self.user_two = get_user_model().objects.create_user(**self.user_two_credential, name="User Two") - self.cover = SimpleUploadedFile("cover.jpg", b"Test file") - self.content = SimpleUploadedFile("content.txt", b"Test file") - 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 Dua", - author="Author", - uploader=self.contributor, - publisher="Publisher", - descriptions="Deskripsi Materi Dua", - status="APPROVE", - cover=self.cover, - content=self.content, - ).save() - self.materi1 = Materi.objects.all()[0] - self.materi2 = Materi.objects.all()[1] - self.url_rate = "/materi/rate/" - self.url_materi = "/materi/{}/".format(self.materi1.id) - - def test_rating_model_can_be_created_with_proper_parameter(self): - Rating(materi=self.materi1, user=self.user_one, score=5).save() - rating = Rating.objects.first() - self.assertEqual(rating.materi, self.materi1) - self.assertEqual(rating.user, self.user_one) - self.assertTrue(0 < rating.score < 6) - self.assertEqual(rating.__str__(), "Material:Materi 1 | User:User One | Rating:5") - - def test_rating_model_should_not_be_created_with_rating_more_than_5(self): - with self.assertRaises(ValidationError) as context: - Rating(materi=self.materi1, user=self.user_one, score=6).save() - self.assertTrue("Rating score must be integer between 1-5" in str(context.exception)) - - def test_rating_model_should_not_be_created_with_rating_less_than_1(self): - with self.assertRaises(ValidationError) as context: - Rating(materi=self.materi1, user=self.user_one, score=0).save() - self.assertTrue("Rating score must be integer between 1-5" in str(context.exception)) - - def test_one_materi_should_be_able_to_be_related_to_multiple_rating(self): - Rating(materi=self.materi1, user=self.user_one, score=1).save() - Rating(materi=self.materi1, user=self.user_two, score=2).save() - rating_one = Rating.objects.get(user=self.user_one) - rating_two = Rating.objects.get(user=self.user_two) - self.assertEqual(rating_one.materi, self.materi1) - self.assertEqual(rating_two.materi, self.materi1) - self.assertEqual(rating_one.user, self.user_one) - self.assertEqual(rating_two.user, self.user_two) - - def test_one_user_should_be_able_to_be_related_to_two_rating(self): - Rating(materi=self.materi1, user=self.user_one, score=3).save() - Rating(materi=self.materi2, user=self.user_one, score=3).save() - rating_one = Rating.objects.filter(materi=self.materi1).first() - rating_two = Rating.objects.filter(materi=self.materi2).first() - self.assertEqual(rating_one.materi, self.materi1) - self.assertEqual(rating_two.materi, self.materi2) - self.assertEqual(rating_one.user, self.user_one) - self.assertEqual(rating_two.user, self.user_one) - - def test_two_rating_should_not_have_same_user_and_materi(self): - with self.assertRaises(IntegrityError) as context: - Rating(materi=self.materi1, user=self.user_one, score=1).save() - Rating(materi=self.materi1, user=self.user_one, score=2).save() - self.assertTrue("already exists" in str(context.exception)) - - def test_materi_in_rating_should_not_be_null(self): - with self.assertRaises(IntegrityError): - Rating(user=self.user_one, score=1).save() - - def test_user_in_rating_should_not_be_null(self): - with self.assertRaises(IntegrityError): - Rating(materi=self.materi1, score=1).save() - - def test_score_in_rating_should_not_be_null(self): - with self.assertRaises(TypeError): - Rating(materi=self.materi1, user=self.user_one).save() - - def test_rating_materi_url_use_add_rating_materi_function(self): - found = resolve(self.url_rate) - self.assertEqual(found.func, add_rating_materi) - - def test_rating_materi_get_method_should_return_403_forbidden(self): - response = self.client.get(self.url_rate) - response_json = json.loads(response.content) - self.assertEqual(response_json.get("success", None), False) - self.assertEqual(response_json.get("msg", None), "Forbidden") - self.assertEqual(response.status_code, 403) - - def test_rating_materi_post_not_authenticated_should_return_403_forbidden(self): - response = self.client.post(self.url_rate, {"materi_id": 1, "rating_score": 5}) - response_json = json.loads(response.content) - self.assertEqual(response_json.get("success", None), False) - self.assertEqual(response_json.get("msg", None), "Forbidden") - self.assertEqual(response.status_code, 403) - - def test_rating_materi_not_authenticated_post_wrong_param_should_return_403_forbidden(self): - for data in [{}, {"materi_id": 1}, {"rating_score": 1}, {"rating_score": "STRING", "materi_id": "STRING"}]: - response = self.client.post(self.url_rate, data) - response_json = json.loads(response.content) - self.assertEqual(response_json.get("success", None), False) - self.assertEqual(response_json.get("msg", None), "Forbidden") - self.assertEqual(response.status_code, 403) - - def test_rating_materi_authenticated_post_missing_param(self): - self.client.login(**self.user_one_credential) - for data in [{"rating_score": 1}, {"materi_id": 1}, {}]: - response = self.client.post(self.url_rate, data) - response_json = json.loads(response.content) - self.assertEqual(response_json.get("success", None), False) - self.assertEqual(response_json.get("msg", None), "Missing param") - self.assertEqual(response.status_code, 422) - - def test_rating_materi_authenticated_materi_id_doesnt_exist_should_return_422(self): - self.client.login(**self.user_one_credential) - response = self.client.post(self.url_rate, {"materi_id": 123456, "rating_score": 5}) - response_json = json.loads(response.content) - self.assertEqual(response_json.get("success", None), False) - self.assertEqual(response_json.get("msg", None), "Materi does not exist") - self.assertEqual(response.status_code, 422) - - def test_rating_materi_authenticated_param_wrong_data_type_should_return_422(self): - self.client.login(**self.user_one_credential) - response = self.client.post(self.url_rate, {"materi_id": "STRING", "rating_score": 5}) - response_json = json.loads(response.content) - self.assertEqual(response_json.get("success", None), False) - self.assertEqual(response_json.get("msg", None), "materi_id must be an integer") - self.assertEqual(response.status_code, 422) - - response = self.client.post(self.url_rate, {"materi_id": 1, "rating_score": "STRING"}) - response_json = json.loads(response.content) - self.assertEqual(response_json.get("success", None), False) - self.assertEqual(response_json.get("msg", None), "rating_score must be an integer") - self.assertEqual(response.status_code, 422) - - def test_rating_score_should_be_between_1_and_5(self): - self.client.login(**self.user_one_credential) - for i in range(1, 6): - Rating.objects.all().delete() - response = self.client.post(self.url_rate, {"materi_id": self.materi1.id, "rating_score": i}) - response_json = json.loads(response.content) - # self.assertEqual(response_json.get("success", None), True) - self.assertEqual(response_json.get("msg", None), "Rating successfully created") - self.assertEqual(response.status_code, 201) - - for i in [-100, -7, -6, -1, 0, 6, 7, 100]: - Rating.objects.all().delete() - response = self.client.post(self.url_rate, {"materi_id": self.materi1.id, "rating_score": i}) - response_json = json.loads(response.content) - # self.assertEqual(response_json.get("success", None), False) - self.assertEqual(response_json.get("msg", None), "Rating must be an integer from 1 to 5") - self.assertEqual(response.status_code, 422) - - def test_user_should_not_able_to_rate_materi_twice(self): - self.client.login(**self.user_one_credential) - Rating.objects.all().delete() - self.client.post(self.url_rate, {"materi_id": self.materi1.id, "rating_score": 1}) - response = self.client.post(self.url_rate, {"materi_id": self.materi1.id, "rating_score": 2}) - response_json = json.loads(response.content) - # self.assertEqual(response_json.get("success", None), False) - self.assertEqual(response_json.get("msg", None), "Rating already exist") - self.assertEqual(response.status_code, 409) - - def test_user_authenticated_visit_unrated_should_get_0_materi_rating_score_context(self): - self.client.login(**self.user_one_credential) - response = self.client.get(self.url_materi) - self.assertEqual(0, response.context.get("materi_rating_score")) - - def test_user_not_authenticated_visit_unrated_should_get_0_materi_rating_score_context(self): - response = self.client.get(self.url_materi) - self.assertEqual(0, response.context.get("materi_rating_score")) - - def test_user_authenticated_visit_rated_should_get_correct_materi_rating_score_context(self): - self.client.login(**self.user_one_credential) - Rating(materi=self.materi1, user=self.user_one, score=1).save() - response = self.client.get(self.url_materi) - self.assertEqual(1, response.context.get("materi_rating_score")) - - -class fileManagementUtilTest(TestCase): - def setUp(self): - self.filename = "image_with_exif_data.gif" - self.file_content = open(settings.BASE_DIR + "/app/test_files/" + self.filename, "rb").read() - - def test_get_random_filename_isCorrect(self): - generated_name = get_random_filename(self.filename) - - self.assertTrue(generated_name != self.filename) - # 40 from 36 expected name length + 4 from extension - self.assertEqual(len(generated_name), 40) - self.assertTrue(generated_name[-4:] == ".gif") - - def test_remove_image_exifdata_isCorrect(self): - with tempfile.TemporaryDirectory() as d: - image_with_exif_data_path = os.path.join(d, self.filename) - img = open(image_with_exif_data_path, "wb") - img.write(self.file_content) - img.close() - - remove_image_exifdata(image_with_exif_data_path) - sanitized_img = open(image_with_exif_data_path, "rb").read() - - self.assertTrue(len(sanitized_img) < len(self.file_content)) - self.assertTrue(b"<exif:" not in sanitized_img) - - -class RequestMateriTest(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.url = "/req-materi/" - self.template_name = "req_materi.html" - - def test_req_materi_url_resolves_to_get_req_materi_view(self): - found = resolve(self.url) - self.assertEqual(found.func.__name__, ReqMateriView.as_view().__name__) - - def test_uses_req_material_template(self): - self.client.login(**self.contributor_credential) - response = self.client.get(self.url) - self.assertTemplateUsed(response, self.template_name) - self.client.logout() - - def test_redirect_to_login_page_is_not_authenticated(self): - response = self.client.get(self.url) - - self.assertEqual(response.status_code, 302) - self.assertEqual(response["location"], "/login/") - - def test_saving_and_retrieving_material_requests(self): - first_material_request = ReqMaterial(title="Material 1").save() - second_material_request = ReqMaterial(title="Material 2").save() - saved_material_request = ReqMaterial.objects.all() - self.assertEqual(saved_material_request.count(), 2) - - def test_can_save_a_POST_request_and_return_correct_response_message(self): - self.client.login(**self.contributor_credential) - - response = self.client.post(self.url, data={"title": "Requested Material"}) - self.assertEqual(ReqMaterial.objects.count(), 1) - - new_material_request = ReqMaterial.objects.first() - self.assertEqual(new_material_request.title, "Requested Material") - - self.assertIn("Permintaan materi berhasil dikirimkan", response.content.decode()) - self.client.logout() - - def test_given_no_title_should_not_save_request_and_return_correct_response_message(self): - self.client.login(**self.contributor_credential) - - response = self.client.post(self.url) - self.assertEqual(ReqMaterial.objects.count(), 0) - - self.assertIn("Missing parameter", response.content.decode()) - self.client.logout() - - -class RatingContributorTest(TransactionTestCase): - 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 - ) - - def test_add_rating_contributor(self): - RatingContributor.objects.create(score=3, user=self.contributor) - self.assertEqual(1, RatingContributor.objects.count()) - - def test_add_rating_contributor_should_failed_when_negative(self): - with self.assertRaises(ValidationError): - RatingContributor.objects.create(score=-1, user=self.contributor) - self.assertEqual(0, RatingContributor.objects.count()) - - def test_add_rating_contributor_should_failed_when_bigger_than_five(self): - with self.assertRaises(ValidationError): - RatingContributor.objects.create(score=6, user=self.contributor) - self.assertEqual(0, RatingContributor.objects.count()) - - def test_submit_form_correct_rating_contributor_should_added(self): - url = f"/profil/{self.contributor.email}/" - self.client.post(url, data={"user": self.contributor.id, "score": 5}) - self.assertEqual(1, RatingContributor.objects.filter(user=self.contributor.id).count()) - self.client.post(url, data={"user": self.contributor.id, "score": 1}) - self.assertEqual(2, RatingContributor.objects.filter(user=self.contributor.id).count()) - - def test_submit_form_not_correct_rating_contributor_should__not_added(self): - url = f"/profil/{self.contributor.email}/" - self.client.post(url, data={"user": self.contributor.id, "score": 6}) - self.assertEqual(0, RatingContributor.objects.filter(user=self.contributor.id).count()) - self.client.post(url, data={"user": self.contributor.id, "score": 0}) - self.assertEqual(0, RatingContributor.objects.filter(user=self.contributor.id).count()) - - -class UserDownloadHistoryTest(TestCase): - def setUp(self): - self.user1_credential = {"email": "anonim1@gov.id", "password": id_generator()} - self.user1_anonim = get_user_model().objects.create_user(**self.user1_credential, name="Anonim1") - self.user2_credential = {"email": "anonim2@gov.id", "password": id_generator()} - self.user2_anonim = get_user_model().objects.create_user(**self.user2_credential, name="Anonim2") - 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() - self.materi1 = Materi.objects.first() - self.download_url = f"/materi/{self.materi1.id}/unduh" - self.history_url = "/download-history/" - - def test_multiple_insert_download_statistic_with_user(self): - DownloadStatistics(materi=self.materi1, downloader=self.user1_anonim).save() - num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() - self.assertEqual(num_of_downloads, 1) - - DownloadStatistics(materi=self.materi1, downloader=self.user1_anonim).save() - num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() - self.assertEqual(num_of_downloads, 2) - - def test_download_statistics_bound_to_specific_user(self): - DownloadStatistics(materi=self.materi1, downloader=self.user1_anonim).save() - num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() - self.assertEqual(num_of_downloads, 1) - - DownloadStatistics(materi=self.materi1).save() - num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() - self.assertEqual(num_of_downloads, 1) - - DownloadStatistics(materi=self.materi1, downloader=self.user2_anonim).save() - user1_num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() - user2_num_of_downloads = self.user2_anonim.riwayat_unduh.all().count() - self.assertEqual(user1_num_of_downloads, 1) - self.assertEqual(user2_num_of_downloads, 1) - - def test_registered_user_download(self): - # Login - self.client.login(**self.user1_credential) - - self.client.get(self.download_url) - num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() - self.assertEqual(num_of_downloads, 1) - - # Logout - self.client.logout() - - def test_unregistered_user_download(self): - self.client.get(self.download_url) - downloaded_materi = self.client.session["downloaded_materi"] - num_of_downloads = DownloadStatistics.objects.filter(pk__in=downloaded_materi).count() - self.assertEqual(num_of_downloads, 1) - - def test_registered_user_multiple_download(self): - # Login - self.client.login(**self.user1_credential) - self.client.get(self.download_url) - num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() - self.assertEqual(num_of_downloads, 1) - - self.client.get(self.download_url) - num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() - self.assertEqual(num_of_downloads, 2) - - # Logout - self.client.logout() - - def test_unregistered_user_multiple_download(self): - self.client.get(self.download_url) - downloaded_materi = self.client.session["downloaded_materi"] - num_of_downloads = DownloadStatistics.objects.filter(pk__in=downloaded_materi).count() - self.assertEqual(num_of_downloads, 1) - - self.client.get(self.download_url) - downloaded_materi = self.client.session["downloaded_materi"] - num_of_downloads = DownloadStatistics.objects.filter(pk__in=downloaded_materi).count() - self.assertEqual(num_of_downloads, 2) - - def test_registered_user_doesnt_use_session_when_download(self): - # Login - self.client.login(**self.user1_credential) - - self.client.get(self.download_url) - self.assertFalse("downloaded_materi" in self.client.session) - - # Logout - self.client.logout() - - def test_download_history_bound_to_specific_user(self): - # Login Anonym 1 - self.client.login(**self.user1_credential) - self.client.get(self.download_url) - num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() - self.assertEqual(num_of_downloads, 1) - - # Logout Anonym 1 - self.client.logout() - - # Unregistered User download - self.client.get(self.download_url) - user1_num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() - downloaded_materi = self.client.session["downloaded_materi"] - guest_num_of_downloads = DownloadStatistics.objects.filter(pk__in=downloaded_materi).count() - self.assertEqual(user1_num_of_downloads, 1) - self.assertEqual(guest_num_of_downloads, 1) - - # Login Anonym 2 - self.client.login(**self.user2_credential) - self.client.get(self.download_url) - user1_num_of_downloads = self.user1_anonim.riwayat_unduh.all().count() - user2_num_of_downloads = self.user2_anonim.riwayat_unduh.all().count() - self.assertEqual(user1_num_of_downloads, 1) - self.assertEqual(guest_num_of_downloads, 1) - self.assertEqual(user2_num_of_downloads, 1) - - # Logout Anonym 2 - self.client.logout() - - -class DownloadHistoryViewTest(TestCase): - def setUp(self): - self.user_credential = {"email": "anonim1@gov.id", "password": id_generator()} - self.user_anonim = get_user_model().objects.create_user(**self.user_credential, name="Anonim") - 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() - - content1 = b"Test file" - content2 = b"File Test" - - self.cover1 = SimpleUploadedFile("cover1.jpg", content1) - self.content1 = SimpleUploadedFile("content1.txt", content1) - - self.cover2 = SimpleUploadedFile("cover2.jpg", content2) - self.content2 = SimpleUploadedFile("content2.txt", content2) - - self.materi1 = Materi.objects.create( - title="Materi 1", - author="Agas", - uploader=self.contributor, - publisher="Kelas SC", - descriptions="Deskripsi Materi 1", - status="PENDING", - cover=self.cover1, - content=self.content1, - ) - self.materi2 = Materi.objects.create( - title="Materi 2", - author="Danin", - uploader=self.contributor, - publisher="Kelas DDP", - descriptions="Deskripsi Materi 2", - status="PENDING", - cover=self.cover2, - content=self.content2, - ) - - self.download_url1 = f"/materi/{self.materi1.id}/unduh" - self.download_url2 = f"/materi/{self.materi2.id}/unduh" - self.history_url = "/download-history/" - - # Login - self.client.login(**self.user_credential) - - def tearDown(self): - # Logout - self.client.logout() - - def test_allow_registered_user(self): - response = self.client.get(self.history_url) - self.assertEqual(response.status_code, 200) - - def test_allow_unregistered_user(self): - # Forced Logout - self.client.logout() - - response = self.client.get(self.history_url) - self.assertEqual(response.status_code, 200) - - def test_download_history_using_correct_template(self): - response = self.client.get(self.history_url) - self.assertTemplateUsed(response, "download_history.html") - - def test_download_history_has_user_name(self): - response = self.client.get(self.history_url) - resp_html = response.content.decode("utf8") - self.assertIn(self.user_anonim.name, resp_html) - - def test_registered_user_download_history_correctly_displayed(self): - self.client.get(self.download_url1) - self.client.get(self.download_url2) - self.client.get(self.download_url1) - - jkt_timezone = timezone(TIME_ZONE) - - download_history = self.user_anonim.riwayat_unduh.all() - response = self.client.get(self.history_url) - resp_html = response.content.decode("utf8") - for riwayat in download_history: - downloaded_materi = riwayat.materi - self.assertIn(downloaded_materi.title, resp_html) - self.assertIn(downloaded_materi.author, resp_html) - - jkt_timestamp = riwayat.timestamp.astimezone(jkt_timezone) - self.assertIn(jkt_timestamp.strftime("%d %B %Y %H:%M:%S"), resp_html) - - def test_unregistered_user_download_history_correctly_displayed(self): - self.client.logout() - - self.client.get(self.download_url1) - self.client.get(self.download_url2) - self.client.get(self.download_url1) - - jkt_timezone = timezone(TIME_ZONE) - - response = self.client.get(self.history_url) - resp_html = response.content.decode("utf8") - for riwayat_id in self.client.session["downloaded_materi"]: - riwayat = DownloadStatistics.objects.get(pk=riwayat_id) - downloaded_materi = riwayat.materi - self.assertIn(downloaded_materi.title, resp_html) - self.assertIn(downloaded_materi.author, resp_html) - - jkt_timestamp = riwayat.timestamp.astimezone(jkt_timezone) - self.assertIn(jkt_timestamp.strftime("%d %B %Y %H:%M:%S"), resp_html) - - def test_download_history_not_display_if_user_changed(self): - self.client.get(self.download_url1) - self.client.get(self.download_url2) - self.client.get(self.download_url1) - - self.client.logout() - - jkt_timezone = timezone(TIME_ZONE) - - download_history = self.user_anonim.riwayat_unduh.all() - response = self.client.get(self.history_url) - resp_html = response.content.decode("utf8") - for riwayat in download_history: - downloaded_materi = riwayat.materi - self.assertNotIn(downloaded_materi.title, resp_html) - self.assertNotIn(downloaded_materi.author, resp_html) - - jkt_timestamp = riwayat.timestamp.astimezone(jkt_timezone) - self.assertNotIn(jkt_timestamp.strftime("%d %B %Y %H:%M:%S"), resp_html) - - def test_unregistered_user_download_history_wont_be_saved_if_user_changes(self): - self.client.logout() - - self.client.get(self.download_url1) - self.client.get(self.download_url2) - self.client.get(self.download_url1) - - self.client.get(self.history_url) - - self.client.login(**self.user_credential) - self.client.logout() - self.assertFalse("downloaded_materi" in self.client.session) - - def test_download_history_sorted_by_download_time(self): - # download with 1 second interval to differ download time - self.client.get(self.download_url1) - sleep(1) - self.client.get(self.download_url2) - sleep(1) - self.client.get(self.download_url1) - sleep(1) - self.client.get(self.download_url2) - - response = self.client.get(self.history_url) - resp_html = response.content.decode("utf8") - - table_html = ("<table" + resp_html.split("<table")[1]).split("</table>")[0] + "</table>" - soup = BeautifulSoup(table_html, "html.parser") - histories_html = soup.find("tbody").find_all("tr") - prev_timestamp = None - - for riwayat_html in histories_html: - materi_data = riwayat_html.find_all("td") - date_format = "%d %B %Y %H:%M:%S" - materi_timestamp = datetime.strptime(materi_data[2].get_text(), date_format) - if prev_timestamp: - self.assertTrue(prev_timestamp > materi_timestamp) - prev_timestamp = materi_timestamp - - def test_no_history_display_message(self): - no_history_msg = "Anda belum mengunduh materi. Silahkan unduh materi yang anda butuhkan" - response = self.client.get(self.history_url) - resp_html = response.content.decode("utf8") - self.assertIn(no_history_msg, resp_html) - - -class MateriModelTest(TestCase): - def setUp(self): - self.contributor = User.objects.create( - email="kontributor@gov.id", password="passwordtest", name="kontributor", is_contributor=True - ) - - self.cover = SimpleUploadedFile("ExampleCover221.jpg", b"Test file") - self.content = SimpleUploadedFile("ExampleFile221.pdf", b"Test file") - - self.materi = 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(), - ) - - def test_like_count_return_zero_when_there_is_no_like(self): - self.assertEqual(0, self.materi.like_count) - - def test_like_count_return_right_value_when_there_is_like(self): - Like.objects.create(timestamp=datetime.now(), materi=self.materi, session_id="dummysessionid1") - self.assertEqual(1, self.materi.like_count) - - Like.objects.create(timestamp=datetime.now(), materi=self.materi, session_id="dummysessionid2") - self.assertEqual(2, self.materi.like_count) diff --git a/app/views.py b/app/views.py index 233bd53d4547d2f212c8db0629c8d3c85ff3e10c..111af970028dd6e774194920e61ac9950817f006 100644 --- a/app/views.py +++ b/app/views.py @@ -346,6 +346,7 @@ def delete_materi(request, pk): class UploadMateriView(TemplateView): template_name = UNGGAH_HTML context = {} + redirect_path = "/unggah/" def get_context_data(self, **kwargs): context = super(UploadMateriView, self).get_context_data(**kwargs)