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'.*(