import json, tempfile, os, mock, base64 import pandas as pd from io import StringIO import time from django.test import override_settings 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.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 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, ) 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 ERROR_403_MESSAGE = "Kamu harus login untuk mengakses halaman ini" from django.test import LiveServerTestCase from selenium import webdriver 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): 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 DaftarKatalogSortingByJumlahUnduhTest(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() time.sleep(1) 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() self.last_uploaded_material = Materi.objects.last() material_unduh_url = f"/materi/{self.last_uploaded_material.id}/unduh" self.client.get(material_unduh_url) def test_sorting_by_jumlah_unduh(self): response = self.client.get("/?sort=jumlah_unduh") self.assertRegex(str(response.content), rf'.*Materi 2.*Materi 1.*') class DaftarKatalogSortingByJumlahTampilanTest(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() Materi(title="Materi 2", author="Agas", uploader=self.contributor, publisher="Kelas SC", descriptions="Deskripsi Materi 1", status="PENDING", cover=self.cover, content=self.content).save() self.materi2 = Materi.objects.last() self.url = f"/materi/{self.materi2.id}/view" def sorting_by_jumlah_tampilan(self): self.client.get(self.url) response = self.client.get("/?sort=jumlah_tampilan") self.assertRegex(str(response.content), rf'.*Materi 2.*Materi 1.*') 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") count = Category.objects.all().count() self.assertEqual(1, count) self.assertNotEqual(0, count) 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") count = Comment.objects.all().count() self.assertEqual(1, count) self.assertNotEqual(0, count) 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_comment_disliked_by_anonymous(self): url_materi = self.url self.client.get("/logout/") self.client.login(**self.anonymous_credential) self.client.post(url_materi, {"comment": "This is new comment by Anonymous"}) comment = Comment.objects.get(comment="This is new comment by Anonymous").id response = self.client.get(url_materi) session_id = response.context["session_id"] payload = {"comment": comment, "session_id": session_id} ajax_response = self.client.post("/comment/dislike/", payload) num_of_comment_dislikes = DislikeComment.objects.filter(comment=comment).count() self.assertEqual(num_of_comment_dislikes, 0) def test_comment_liked_by_anonymous(self): url_materi = self.url self.client.get("/logout/") self.client.login(**self.anonymous_credential) self.client.post(url_materi, {"comment": "This is new comment by Anonymous"}) comment = Comment.objects.get(comment="This is new comment by Anonymous").id response = self.client.get(url_materi) session_id = response.context["session_id"] payload = {"comment": comment, "session_id": session_id} ajax_response = self.client.post("/comment/like/", payload) num_of_comment_likes = LikeComment.objects.filter(comment=comment).count() self.assertEqual(num_of_comment_likes, 0) def test_comment_undisliked_by_anonymous(self): url_materi = self.url self.client.get("/logout/") self.client.login(**self.anonymous_credential) self.client.post(url_materi, {"comment": "This is new comment by Anonymous"}) comment = Comment.objects.get(comment="This is new comment by Anonymous") response = self.client.get(url_materi) session_id = response.context["session_id"] payload = {"comment": comment, "session_id": session_id} ajax_response = self.client.post("/comment/dislike/", payload) ajax_response = self.client.post("/comment/dislike/", payload) num_of_comment_dislikes = DislikeComment.objects.filter(comment=comment, session_id=session_id).count() self.assertEqual(num_of_comment_dislikes, 0) def test_comment_unliked_by_anonymous(self): url_materi = self.url self.client.get("/logout/") self.client.login(**self.anonymous_credential) self.client.post(url_materi, {"comment": "This is new comment by Anonymous"}) comment = Comment.objects.get(comment="This is new comment by Anonymous") response = self.client.get(url_materi) session_id = response.context["session_id"] payload = {"comment": comment, "session_id": session_id} ajax_response = self.client.post("/comment/like/", payload) ajax_response = self.client.post("/comment/like/", payload) num_of_comment_likes = LikeComment.objects.filter(comment=comment, session_id=session_id).count() self.assertEqual(num_of_comment_likes, 0) def test_comment_new_does_not_have_dislike(self): url_materi = self.url self.client.get("/logout/") self.client.login(**self.anonymous_credential) response = self.client.get(url_materi) session_id = response.context["session_id"] self.client.post(url_materi, {"comment": "This is new comment by Anonymous"}) comment = Comment.objects.get(comment="This is new comment by Anonymous") comment_dislike_counter = DislikeComment.objects.filter(comment=comment, session_id=session_id).count() self.assertEqual(comment_dislike_counter, 0) def test_comment_new_does_not_have_like(self): url_materi = self.url self.client.get("/logout/") self.client.login(**self.anonymous_credential) response = self.client.get(url_materi) session_id = response.context["session_id"] self.client.post(url_materi, {"comment": "This is new comment by Anonymous"}) comment = Comment.objects.get(comment="This is new comment by Anonymous") comment_like_counter = LikeComment.objects.filter(comment=comment, session_id=session_id).count() self.assertEqual(comment_like_counter, 0) def test_detail_materi_contains_comment_count(self): url = self.url self.client.login(**self.contributor_credential) response = self.client.get(url) self.assertContains(response, "Komentar (0)") self.client.post( url, {"comment": "This is new comment by Contributor"}) self.client.post( url, {"comment": "This is new comment by Contributor"}) response = self.client.get(url) self.assertContains(response, "Komentar (2)") def test_detail_materi_contains_form_comment(self): self.client.login(**self.contributor_credential) response = self.client.get(self.url) self.assertContains(response, "Beri komentar...") def test_detail_materi_not_contains_form_comment(self): response = self.client.get(self.url) self.assertNotContains(response, "Beri komentar...") self.assertContains(response, "Login terlebih dahulu untuk berkomentar") def create_and_delete_comment(self, is_admin=False, is_contributor=False): url = self.url self.client.login(**self.admin_credential) 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) if is_admin: self.client.login(**self.admin_credential) if is_contributor: self.client.login(**self.contributor_credential) if not is_admin and not is_contributor: self.client.login(**self.anonymous_credential) response = self.client.get(deleteURL) return response def test_delete_comments_by_admin(self): self.create_and_delete_comment(is_admin=True) count = Comment.objects.all().filter(comment="This is new comment by Anonymous").count() self.assertEqual(count, 0) def test_delete_comments_by_contributor(self): response = self.create_and_delete_comment(is_contributor=True) self.assertRaises(PermissionDenied) self.assertEqual(response.status_code, 403) count = Comment.objects.all().filter(comment="This is new comment by Anonymous").count() self.assertEqual(count, 1) def test_delete_comments_by_anonymous(self): response = self.create_and_delete_comment() self.assertRaises(PermissionDenied) self.assertEqual(response.status_code, 403) count = Comment.objects.all().filter(comment="This is new comment by Anonymous").count() self.assertEqual(count, 1) def test_review_models_can_create_new_object(self): test = Review.objects.create( username="saul", profile="121212", review="232323") count = Review.objects.all().count() self.assertEqual(1, count) self.assertNotEqual(0, count) self.assertEqual(test.__str__(), "saul") self.assertNotEqual(test.__str__(), "userlain") def test_post_blank_review(self): url = self.url self.client.login(**self.anonymous_credential) response = self.client.post(url, {"review": ""}) self.assertIn("error_message", response.context) self.assertIn("Anda belum menuliskan komentar", response.context["error_message"]) def test_review_rendered_to_template(self): url = self.url self.client.login(**self.contributor_credential) self.client.post(url, {"review": "This is my new review"}) response = Client().get(url) self.assertContains(response, "This is my new review") def test_review_by_admin(self): url = self.url self.client.login(**self.admin_credential) self.client.post(url, {"review": "This is new review by Admin"}) response = self.client.get(url) self.assertContains(response, "Admin") def test_review_by_kontributor(self): url = self.url self.client.login(**self.contributor_credential) self.client.post( url, {"review": "This is new review by Contributor"}) response = self.client.get(url) self.assertContains(response, "Kontributor") def test_review_by_anonymous(self): url = self.url self.client.get("/logout/") self.client.login(**self.anonymous_credential) self.client.post(url, {"review": "This is new review by Anonymous"}) response = self.client.get(url) self.assertContains(response, "Anonymous") def test_detail_materi_contains_review_count(self): url = self.url self.client.login(**self.contributor_credential) review = "This is new review by Contributor" response = self.client.get(url) self.assertContains(response, "Review (0)") self.client.post( url, {"review": review }) self.client.post( url, {"review": review}) response = self.client.get(url) self.assertContains(response, "Review (2)") def test_detail_materi_contains_form_review(self): self.client.login(**self.contributor_credential) response = self.client.get(self.url) self.assertContains(response, "Beri Review") def test_detail_materi_not_contains_form_review(self): response = self.client.get(self.url) self.assertNotContains(response, "Beri Review") self.assertContains(response, "Login terlebih dahulu untuk Membuat review") def test_tombol_citasiAPA(self): response = self.client.get(self.url) self.assertContains(response, "Citate APA") 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"]) 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.services.GoogleDriveUploadService.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.services.GoogleDriveUploadService.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'.*(
)' + \ rf'.*(
)' + \ rf'.*(
)' + \ rf'.*(
)' + \ rf'.*(
)' + \ rf'.*(
)' + \ rf'.*(
)' ) 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, '' + str(post.like_count) + '', ) 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 DeleteMateriTest(TestCase): def setUp(self): self.client = Client() self.admin_credential = { "email": "admin@gov.id", "password": id_generator() } self.superuser_credential = { "email": "superuser@gov.id", "password": id_generator() } self.contributor_credential = { "email": "contributor@gov.id", "password": id_generator() } self.admin = get_user_model().objects.create_user( **self.admin_credential, name="Admin", is_admin=True) self.superuser = get_user_model().objects.create_user( **self.superuser_credential, name="Superuser", is_admin=True, is_superuser=True) self.content = SimpleUploadedFile( "content.txt", b"Test") self.cover = SimpleUploadedFile( "flower.jpg", b"Test file") self.contributor = User.objects.create_contributor(**self.contributor_credential) 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) + "/delete" def test_url_delete_materi_is_success_as_contributor(self): self.client.login(**self.contributor_credential) response = self.client.get(self.url) self.assertEqual(response.status_code, 302) def test_url_soft_delete_materi_is_success_as_admin(self): self.client.login(**self.admin_credential) response = self.client.get(self.url) self.assertEqual(response.status_code, 302) self.materi1.refresh_from_db() self.assertNotEqual(self.materi1.deleted_at, None) def test_url_soft_delete_materi_is_success_as_superuser(self): self.client.login(**self.superuser_credential) response = self.client.get(self.url) self.assertEqual(response.status_code, 302) self.materi1.refresh_from_db() self.assertNotEqual(self.materi1.deleted_at, None) class ProfilViewTest(TestCase): @classmethod def setUpTestData(cls): cls.client = Client() cls.url = "/profil/" cls.template_name = "profil.html" cls.view = ProfilView cls.contributor_credentials = {"email": "contributor@gov.id", "password": "justpass"} cls.contributor = User.objects.create_contributor(**cls.contributor_credentials) cls.admin_credentials = {"email": "admin@gov.id", "password": "justpass"} cls.admin = User.objects.create_admin(**cls.admin_credentials) def test_returns_correct_profile_view(self): found = resolve(self.url) self.assertEqual(found.func.__name__, self.view.as_view().__name__) def _request_as_user(self, credentials): self.client = Client() self.client.login(**credentials) return self.client.get(self.url) def test_returns_correct_template(self): response = self._request_as_user(self.contributor_credentials) self.assertTemplateUsed(response, self.template_name) def test_unauthenticated_access_blocked(self): response = self._request_as_user({}) self.assertEqual(response.status_code, 403) def test_authorized_access_success(self): response = self._request_as_user(self.contributor_credentials) self.assertEqual(response.status_code, 200) self.assertIn("Profil Kontributor", response.content.decode()) response = self._request_as_user(self.admin_credentials) self.assertEqual(response.status_code, 200) self.assertIn("Profil Admin", response.content.decode()) class SuntingProfilViewTest(TestCase): @classmethod def setUpTestData(cls): cls.client = Client() cls.url = "/sunting/" cls.template_name = "sunting.html" cls.view = SuntingProfilView cls.contributor_credentials = {"email": "contributor@gov.id", "password": "justpass"} cls.contributor = User.objects.create_contributor(**cls.contributor_credentials) cls.admin_credentials = {"email": "admin@gov.id", "password": "justpass"} cls.admin = User.objects.create_admin(**cls.admin_credentials) def test_sunting_profile_view(self): found = resolve(self.url) self.assertEqual(found.func.__name__, self.view.as_view().__name__) def _request_as_user(self, credentials): self.client = Client() self.client.login(**credentials) return self.client.get(self.url) def test_returns_correct_template(self): self.client.login(**self.contributor_credentials) response = self.client.get(self.url) self.assertTemplateUsed(response, self.template_name) def test_unauthenticated_access_blocked(self): response = self._request_as_user({}) self.assertEqual(response.status_code, 403) def test_authorized_access_success(self): response = self._request_as_user(self.contributor_credentials) self.assertEqual(response.status_code, 200) self.assertIn("Sunting Profil Kontributor", response.content.decode()) response = self._request_as_user(self.admin_credentials) self.assertEqual(response.status_code, 200) self.assertIn("Sunting Profil Admin", response.content.decode()) 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) self.assertEqual(form.fields["twitter"].widget.attrs.get("autofocus"), "") self.assertEqual(form.fields["instagram"].widget.attrs.get("autofocus"), None) 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'")[0] + "" 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) class MateriFavoriteTest(TestCase): @classmethod def setUpTestData(cls): cls.url = '/favorite/' cls.user_credentials = { "email": "user@email.com", "password": "justpass" } cls.user = User.objects.create_user(**cls.user_credentials, is_contributor=True) def _request_as_user(self): self.client.login(**self.user_credentials) return self.client.get(self.url) def test_url_resolves_to_favorite_view(self): found = resolve(self.url) self.assertEqual(found.func.__name__, MateriFavorite.as_view().__name__) class RandomizedMateriTest(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="Nandhika", 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 = Materi.objects.create( title="Materi 2", author="Prayoga", uploader=self.contributor, publisher="Kelas SC", descriptions="Deskripsi Materi 2", status="APPROVE", cover=self.cover, content=self.content, date_modified=datetime.now(), date_created=datetime.now(), ) def test_randomized_materi_returns_200(self): response = Client().get("/?random=1") self.assertEqual(response.status_code, 200) def test_randomized_materi_remains_same_materi(self): response = Client().get("/?random=1") self.assertIn("Materi 1", response.content.decode()) self.assertIn("Materi 2", response.content.decode()) class YearChoicesTest(TestCase): def test_release_year_contains_the_right_current_year(self): now = dt.date.today().year choices = year_choices() self.assertEqual((now, now), choices[-1]) def test_min_release_year_is_2000(self): choices = year_choices() self.assertEqual((2000, 2000), choices[0]) TEST_IMAGE = ''' iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI WXMAAABIAAAASABGyWs+AAAACXZwQWcAAAAQAAAAEABcxq3DAAABfElEQVQ4y52TvUuCURTGf5Zg 9goR9AVlUZJ9KURuUkhIUEPQUIubRFtIJTk0NTkUFfgntAUt0eBSQwRKRFSYBYFl1GAt901eUYuw QTLM1yLPds/zPD/uPYereYjHcwD+tQ3+Uys+LwCah3g851la/lf4qwKb61Sn3z5WFUWpCHB+GUGb SCRIpVKqBkmSAMrqsViMqnIiwLx7HO/U+6+30GYyaVXBP1uHrfUAWvWMWiF4+qoOUJLJkubYcDs2 S03hvODSE7564ek5W+Kt+tloa9ax6v4OZ++jZO+jbM+pD7oE4HM1lX1vYNGoDhCyQMiCGacRm0Vf EM+uiudjke6YcRoLfiELNB2dXTkAa08LPlcT2fpJAMxWZ1H4NnKITuwD4Nl6RMgCAE1DY3PuyyQZ JLrNvZhMJgCmJwYB2A1eAHASDiFkQUr5Xn0RoJLSDg7ZCB0fVRQ29/TmP1Nf/0BFgL2dQH4LN9dR 7CMOaiXDn6FayYB9xMHeTgCz1cknd+WC3VgTorUAAAAldEVYdGNyZWF0ZS1kYXRlADIwMTAtMTIt MjZUMTQ6NDk6MjErMDk6MDAHHBB1AAAAJXRFWHRtb2RpZnktZGF0ZQAyMDEwLTEyLTI2VDE0OjQ5 OjIxKzA5OjAwWK1mQQAAAABJRU5ErkJggolQTkcNChoKAAAADUlIRFIAAAAQAAAAEAgGAAAAH/P/ YQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAASAAAAEgARslrPgAAAAl2cEFnAAAAEAAAABAA XMatwwAAAhdJREFUOMuVk81LVFEYxn/3zocfqVebUbCyTLyYRYwD0cemCIRyUVToLloERUFBbYpo E7WIFv0TLaP6C2Y17oYWWQxRMwo5OUplkR/XOefMuW8LNYyZLB94eOE5L79zzns4johIPp/n+YtX fPn6jaq1bKaI65LY3sHohXOk02mcNxMT8vjJU5TWbEUN8Ti3bl4n0tLW/qBcniW0ltBaxFrsWl3P 7IZ8PdNa82m6RPTDxyLGmLq7JDuaqVQCllbqn6I4OUU0CJYJw7BmMR6LcPvyURbLGR49q/71KlGj dV3AlbEhBnog3mo5e8Tycrz+cKPamBrAiUOdnD/ZhlFziKpw7RS8LVry01IDcI3WbHRXu8OdS524 pgx6BlkJEKW4PxrSFP2z12iNq1UFrTVaaxDNw6vttDXMg/2O2AXC5UUkWKI7vsDdM+Z3X9Ws2tXG YLTCaMWNMY8DfREAFpcUkzPC1JzL8kKAGM3xvoDD+1uJVX+ilEIptTpECUP8PXEGB/rIzw/iNPXj de1jML0Xay3l6QKfZyewP95x8dhr7r0HpSoAODt7dktoQ0SEpsZGent78f1+fN/H9/sxxlAoFCkU CxQKRUqlEkppXNddBXTv2CXrtH/JofYVoqnUQbLZ8f/+A85aFWAolYJcLiee50ksFtuSm7e1SCaT EUREcrmcnB4ZkWQyKZ7nbepEIiHDw8OSzWZFROQX6PpZFxAtS8IAAAAldEVYdGNyZWF0ZS1kYXRl ADIwMTAtMTItMjZUMTQ6NDk6MjErMDk6MDAHHBB1AAAAJXRFWHRtb2RpZnktZGF0ZQAyMDEwLTEy LTI2VDE0OjQ5OjIxKzA5OjAwWK1mQQAAAABJRU5ErkJggolQTkcNChoKAAAADUlIRFIAAAAQAAAA EAgGAAAAH/P/YQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAASAAAAEgARslrPgAAAAl2cEFn AAAAEAAAABAAXMatwwAAAo9JREFUOMuNks1rVGcUxn/ve+9kUuOdfIzamNHEMK3RVILQQAuCWURo rSAtbsV20T/EP6O7FtxkkYWQKK7F4Kb1C6yoSVrNdDIm1YTMjDP3vfc9p4ubZEYopQceDhwOD89z zmO89/rw0SNu3b5D5a8q3gv7ZXa7dkY2sIwMf8w3X3/F9PTnhL/+9oCff7nBeq2GMYb/U5sbm1TX a8TOEQwMHbq+vLKKqqIiiAh+r3tBvKBds72der1OtVolfP78BWmadmnNVKgqI0cOkiRtNrc9Zt9H x9fK6iphs/keVflAoqpSHOzjh+8maL59yk83WzRa8G8OwzRxiHQIFOjJBXw7O8b0qV50K2H1tWf+ riCiHRbNFIUucYgoZu/Yqlz44iiXzh3EpJuE0uLKl57lNc/93wVjOyYyApeguwpElTOf9HH1YkSU e0O72cC/b1DMK9/PGP5c97zaUGwXg01cjHMxcRwz0Cf8ePkAJ47U0eRvSLehtYM06pw+1OTauZje wBG7mCTJEDqX3eCjvOXqxQGmTwXUmwlxmmdrpw+z0ybiHXnbYqasvDgbcGPJEvvsHKFzDp96Tgz3 cvjwMM/efsaBwZP0D39KabKEpgnbG3/wrvaU5psnHD/6mMF8jcqWwRgwpWOjKiLkQkOhv5+xsTLl cpnR0WOUSiVEhLVKhbXXa7xcXqHyaoV6o0Hqd1MxUjqu7XYLMFkaNXtXYC09+R5UwbkYEcVaizFm P/LWGsLJydMs3VvCWkP3gzxK7OKu7Bl81/tEhKmpKVhYWNCJiQkNglDDMKdhLpf1/0AQhDo+Pq5z c3NKmqa6uLios7MXtFgsahRFGhUKHUS7KBQ0iiIdGhrS8+dndH5+XpMk0X8AMTVx/inpU4cAAAAl dEVYdGNyZWF0ZS1kYXRlADIwMTAtMTItMjZUMTQ6NDk6MjErMDk6MDAHHBB1AAAAJXRFWHRtb2Rp ZnktZGF0ZQAyMDEwLTEyLTI2VDE0OjQ5OjIxKzA5OjAwWK1mQQAAAABJRU5ErkJggg== '''.strip() class YTUrlVideoTest(TestCase): def setUp(self): self.client = Client() self.contributor_credential = {"email": "kontributor@gov.id", "password": "passwordtest"} self.contributor = get_user_model().objects.create_user( **self.contributor_credential, name="Kontributor", is_contributor=True ) self.setUpImage() self.content = SimpleUploadedFile("ExampleFile221.pdf", b"Test file") self.category = Category.objects.create(id="1", name="medis", description="kategori medis") @override_settings(MEDIA_ROOT=tempfile.gettempdir()) def setUpImage(self): from django.core.files.uploadedfile import InMemoryUploadedFile from io import BytesIO self.cover = InMemoryUploadedFile( BytesIO(base64.b64decode(TEST_IMAGE)), field_name='tempfile', name='tempfile.png', content_type='image/png', size=len(TEST_IMAGE), charset='utf-8', ) def test_yt_video_id_exists_in_Materi(self): materiTemp = Materi.objects.create() self.assertEqual(hasattr(materiTemp, 'yt_video_id'), True) def test_yt_video_id_exists_in_UploadMateri_page(self): self.client.login(**self.contributor_credential) response = self.client.get("/unggah/") html = response.content.decode("utf-8") self.assertIn('Youtube Video Id', html) def test_upload_materi_with_valid_yt_video_id(self): self.client.login(**self.contributor_credential) response = self.client.post( "/unggah/", data={"title":"Materi 1", "author":"Agas", "publisher":"Kelas SC", "release_year":"2000", "descriptions":"Deskripsi Materi 1", 'categories':"1", "cover":self.cover, "content":self.content, "yt_video_id":"jNwz4L9MGVY"} ) self.assertTrue(Materi.objects.get(title="Materi 1")) def test_upload_materi_with_invalid_yt_video_id(self): self.client.login(**self.contributor_credential) response = self.client.post( "/unggah/", data={"title":"Materi 2", "author":"Agas", "publisher":"Kelas SC", "release_year":"2000", "descriptions":"Deskripsi Materi 1", 'categories':"1", "cover":self.cover, "content":self.content, "yt_video_id":"randomId"} ) self.assertEqual(Materi.objects.filter(title="Materi 2").count(), 0) def test_detail_materi_has_video_if_yt_video_id_not_empty(self): self.test_upload_materi_with_valid_yt_video_id() pk = Materi.objects.get(title="Materi 1").pk response = self.client.get("/materi/"+str(pk)+"/") html = response.content.decode("utf-8") self.assertIn("Video", html) def test_detail_materi_has_no_video_if_yt_video_id_empty(self): self.client.login(**self.contributor_credential) response = self.client.post( "/unggah/", data={"title":"Materi 2", "author":"Agas", "publisher":"Kelas SC", "release_year":"2000", "descriptions":"Deskripsi Materi 1", 'categories':"1", "cover":self.cover, "content":self.content,} ) pk = Materi.objects.get(title="Materi 2").pk response = self.client.get("/materi/"+str(pk)+"/") html = response.content.decode("utf-8") self.assertNotIn("Video", html) class ChangePasswordTest(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 = "/change-password/" self.view = PasswordChangeViews self.template_name = "change-password.html" def test_change_password_view(self): found = resolve(self.url) self.assertEqual(found.func.__name__, self.view.as_view().__name__) def test_change_password_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_change_password_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_change_password_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 SeeRatedMateriByUser(TestCase): def setUp(self): self.client = Client() self.contributor_credential = { "email": "kontributor@gov.id", "password": id_generator() } self.admin_credential = { "email": "admin@gov.id", "password": id_generator() } self.kontributor = User.objects.create_contributor(**self.contributor_credential) self.admin = User.objects.create_admin(**self.admin_credential) self.given_rating_url = "/given-rating/" self.cover = SimpleUploadedFile( "cover.jpg", b"Test file" ) self.content = SimpleUploadedFile( "content.txt", b"Test file" ) Materi(title="Materi 2", author="Agas", uploader=self.kontributor, publisher="Kelas SC", descriptions="Deskripsi Materi 1", status="PENDING", cover=self.cover, content=self.content).save() Materi(title="Materi 3", author="Agas", uploader=self.kontributor, publisher="Kelas SC", descriptions="Deskripsi Materi 1", status="PENDING", cover=self.cover, content=self.content).save() Materi(title="Materi 1", author="Agas", uploader=self.kontributor, publisher="Kelas SC", descriptions="Deskripsi Materi 1", status="PENDING", cover=self.cover, content=self.content).save() self.materi1 = Materi.objects.all()[0] self.materi2 = Materi.objects.all()[1] self.materi3 = Materi.objects.all()[2] time.sleep(5) self.rating_test_1 = Rating(materi=self.materi1, user=self.kontributor, score=5) time.sleep(5) self.rating_test_2 = Rating(materi=self.materi2, user=self.kontributor, score=4) time.sleep(5) self.rating_test_3 = Rating(materi=self.materi3, user=self.kontributor, score=3) time.sleep(5) self.rating_test_4 = Rating(materi=self.materi3, user=self.admin, score=3) self.rating_test_1.save() self.rating_test_2.save() self.rating_test_3.save() self.rating_test_4.save() def test_authorize_template_used(self): self.client.login(**self.contributor_credential) response = self.client.get(self.given_rating_url) self.assertTemplateUsed(response, "given-rating.html") def test_unauthorized_user_shouldnt_be_able_to_access_see_rating_page(self): response = self.client.get(self.given_rating_url) self.assertEqual(response.status_code, 403) self.assertTemplateUsed(response, "error_403.html") def test_authorized_should_be_able_to_access_given_rating_page(self): self.client.login(**self.contributor_credential) response = self.client.get(self.given_rating_url) self.assertEqual(response.status_code, 200) self.client.login(**self.admin_credential) response = self.client.get(self.given_rating_url) self.assertEqual(response.status_code, 200) def test_given_rating_page_should_show_correct_rating(self): self.client.login(**self.contributor_credential) response = self.client.get(self.given_rating_url) self.assertIn(self.rating_test_1, response.context['rating_list']) self.assertIn(self.rating_test_2, response.context['rating_list']) self.assertIn(self.rating_test_3, response.context['rating_list']) def test_given_rating_page_should_not_show_others_rating(self): self.client.login(**self.contributor_credential) response = self.client.get(self.given_rating_url) self.assertNotIn(self.rating_test_4, response.context['rating_list']) def test_given_rating_page_no_rating_should_display_message(self): user_credential = {"email": "user@mail.com", "password": id_generator()} User.objects.create_contributor(**user_credential) self.client.login(**user_credential) response = self.client.get(self.given_rating_url) self.assertEqual(len(response.context['rating_list']), 0) self.assertIn("Anda belum pernah memberikan rating ke materi", response.content.decode("utf-8")) self.assertNotIn(self.materi1.title, response.content.decode("utf-8")) def test_given_rating_page_order_should_give_default_parameter(self): # No parameters order_by_key = timestamp and order_by : ascending self.client.login(**self.contributor_credential) response = self.client.get(self.given_rating_url) self.assertEqual(response.context['order_by'], 'dsc') self.assertEqual(response.context['order_by_key'], 'timestamp') # No order_by_key parameter, should default to timestamp response = self.client.get(self.given_rating_url + '?order=asc') self.assertEqual(response.context['order_by'], 'asc') self.assertEqual(response.context['order_by_key'], 'timestamp') # No order_by parameter, should default to asc response = self.client.get(self.given_rating_url + '?order_by_key=score') self.assertEqual(response.context['order_by'], 'dsc') self.assertEqual(response.context['order_by_key'], 'score') # INVALID PARAMETERS # Starts with negative response = self.client.get(self.given_rating_url + '?order_by_key=-score') self.assertEqual(response.context['order_by'], 'dsc') self.assertEqual(response.context['order_by_key'], 'score') # Invalid params response = self.client.get(self.given_rating_url + '?order_by_key=halohalohalo&order=haihaihaihai') self.assertEqual(response.context['order_by'], 'dsc') self.assertEqual(response.context['order_by_key'], 'timestamp') def test_given_rating_page_order_ascending_should_be_correct(self): self.client.login(**self.contributor_credential) response = self.client.get(self.given_rating_url + '?order_by_key=score&order=asc') # From Low to High # order key score self.assertEqual(response.context['order_by'], 'asc') self.assertEqual(response.context['order_by_key'], 'score') self.assertEqual(list(response.context['rating_list']), [self.rating_test_3, self.rating_test_2, self.rating_test_1]) # order key timestamp response = self.client.get(self.given_rating_url + '?order_by_key=timestamp&order=asc') self.assertEqual(response.context['order_by'], 'asc') self.assertEqual(response.context['order_by_key'], 'timestamp') self.assertEqual(list(response.context['rating_list']), [self.rating_test_1, self.rating_test_2, self.rating_test_3]) # order key materi title response = self.client.get(self.given_rating_url + '?order_by_key=materi__title&order=asc') self.assertEqual(response.context['order_by'], 'asc') self.assertEqual(response.context['order_by_key'], 'materi__title') self.assertEqual(list(response.context['rating_list']), [self.rating_test_3, self.rating_test_1, self.rating_test_2]) def test_given_rating_page_order_descending_should_be_correct(self): self.client.login(**self.contributor_credential) # From High to Low # order key score response = self.client.get(self.given_rating_url + '?order_by_key=score&order=dsc') self.assertEqual(response.context['order_by'], 'dsc') self.assertEqual(response.context['order_by_key'], 'score') self.assertEqual(list(response.context['rating_list']), [self.rating_test_1, self.rating_test_2, self.rating_test_3]) # order key timestamp response = self.client.get(self.given_rating_url + '?order_by_key=timestamp&order=dsc') self.assertEqual(response.context['order_by'], 'dsc') self.assertEqual(response.context['order_by_key'], 'timestamp') self.assertEqual(list(response.context['rating_list']), [self.rating_test_3, self.rating_test_2, self.rating_test_1]) # order key materi title response = self.client.get(self.given_rating_url + '?order_by_key=materi__title&order=dsc') self.assertEqual(response.context['order_by'], 'dsc') self.assertEqual(response.context['order_by_key'], 'materi__title') self.assertEqual(list(response.context['rating_list']), [self.rating_test_2, self.rating_test_1, self.rating_test_3])