Fakultas Ilmu Komputer UI

Commit 40ea5598 authored by Mutia Rahmatun Husna's avatar Mutia Rahmatun Husna
Browse files

[#39]Material: Like/Favorite (User View)

parent 9eb16994
......@@ -100,6 +100,12 @@ class Materi(models.Model):
count = Like.objects.filter(materi=self).count()
return count
@property
def is_like(self):
like = False
if Like.objects.filter(materi=self).exists():
like = True
class Comment(models.Model):
username = models.CharField(max_length=100)
......
......@@ -31,6 +31,11 @@
<span>Statisik Materi</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'favorite' %}">
<span>Favorite Materi</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'posts' %}">
<span>Materi Diunggah</span></a>
......
{% extends 'app/base_dashboard.html' %}
{% load static %}
{% block title %}
<title>Materi Favorite | Digipus</title>
{% endblock %}
{% block stylesheets %}
<link rel="stylesheet" type="text/css" href="{% static 'app/css/user_uploaded_posts.css' %}"/>
{% endblock %}
{% block content %}
<div style="padding: 1rem 0" id="like">
{% if materi %}
{% for _, mat in materi.items %}
<div id="mat-{{ mat.data.id }}">
<div class="posts-space-between-container bg-white rounded shadow" style="margin: 0.5rem 2rem; padding: 1rem;">
<div id="posts-user-profile">
{% if mat.data.cover %}
<img id="posts-img" src="{{ post.data.cover.url }}" alt="profile-picture"/>
{% else %}
</div style="background-color: grey; width: 100px; height: 100px;">
{% endif %}
<div id="posts-info">
<span><a class="ml-auto p-1 link" style="text-align: left; font-size: 2rem;" href="{% url 'detail-materi' post.data.id %}">
{{ mat.data.title }}
</a></span>
<span style="font-size: 0.75rem; padding-left: 0.3rem;">{{ mat.data.date_created }}</span>
</div>
</div>
<div class="posts-vertically-centered ml-auto pr-4">
<span id="post-like-count-{{post.data.id}}">{{ mat.data.like_count }}</span>
<span>Like</span>
</div>
<div class="posts-vertically-centered">
<span>{{ mat.comments|length }}</span>
<span>Komentar</span>
</div>
</div>
{% for comment in mat.comments %}
<div id="post-{{ post.data.id }}-comment-{{ comment.id }}">
<div id="posts-comment-info" class="bg-white rounded shadow" >
<img id="posts-profile-picture" src="{{ comment.user.profile_picture.url }}" alt="profile-picture" width="40px" height="40px" style="margin: 18px"/>
<div style="display: flex; align-items: center;">
<div style="display: flex; flex-direction: column;">
<span style="font-size: 0.9rem;"><strong>{{ comment.user.name }}</strong> - {{ comment.timestamp }}</span>
{{ comment.comment }}
</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% endfor %}
{% else %}
<div class="text-center h5">
Anda belum memiliki materi yang disukai
</div>
{% endif %}
</div>
{% endblock %}
......@@ -14,7 +14,7 @@ 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
from django.urls import resolve, reverse
from django.db.utils import IntegrityError
from django.test import Client, RequestFactory, TestCase, TransactionTestCase
from pytz import timezone
......@@ -58,6 +58,7 @@ from .views import (
UploadMateriExcelView,
PasswordChangeViews,
password_success,
MateriFavorite,
)
from app.forms import SuntingProfilForm, year_choices
from app.utils.fileManagementUtil import get_random_filename, remove_image_exifdata
......@@ -72,6 +73,7 @@ from webdriver_manager.chrome import ChromeDriverManager
from selenium.common.exceptions import NoSuchElementException
class DaftarKatalogTest(TestCase):
def test_daftar_katalog_url_exist(self):
url = "/"
......@@ -187,50 +189,34 @@ class DaftarKatalogPerKontributorTest(TestCase):
def setUp(self):
self.client = Client()
self.contributor_credential = {"email": "kontributor@gov.id", "password": "passwordtest"}
self.contributor_credential = {
"email": "kontributor@gov.id",
"password": "passwordtest"
}
self.contributor_credential_2 = {"email": "kontributor2@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.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.contributor_credential_2, name="Kontributor 2", is_contributor=True)
self.cover = SimpleUploadedFile("Cherprang_Areekul40_nJM9dGt.jpg", b"Test file")
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()
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}/"
......@@ -257,51 +243,44 @@ class DaftarKatalogPerKontributorTest(TestCase):
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.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.contributor_credential, name="Kontributor", is_contributor=True)
self.anonymous = get_user_model().objects.create_user(
**self.anonymous_credential, name="Anonymous"
)
self.anonymous = get_user_model().objects.create_user(**self.anonymous_credential, name="Anonymous")
self.cover = SimpleUploadedFile("ExampleCover921.jpg", b"Test file")
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()
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 = 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,
)
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)
......@@ -317,7 +296,8 @@ class DetailMateriTest(TestCase):
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")
test = Category.objects.create(
id="1", name="medis", description="kategori medis")
countData = Category.objects.all().count()
self.assertEqual(1, countData)
self.assertNotEqual(0, countData)
......@@ -325,7 +305,8 @@ class DetailMateriTest(TestCase):
self.assertNotEqual(test.__str__(), "saul")
def test_comment_models_can_create_new_object(self):
test = Comment.objects.create(username="saul", profile="121212", comment="232323")
test = Comment.objects.create(
username="saul", profile="121212", comment="232323")
countData = Comment.objects.all().count()
self.assertEqual(1, countData)
self.assertNotEqual(0, countData)
......@@ -337,7 +318,8 @@ class DetailMateriTest(TestCase):
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"])
self.assertIn("Anda belum menuliskan komentar",
response.context["error_message"])
def test_comment_rendered_to_template(self):
url = self.url
......@@ -356,7 +338,8 @@ class DetailMateriTest(TestCase):
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"})
self.client.post(
url, {"comment": "This is new comment by Contributor"})
response = self.client.get(url)
self.assertContains(response, "Kontributor")
......@@ -514,6 +497,8 @@ class DetailMateriTest(TestCase):
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)
......@@ -562,45 +547,37 @@ class DetailMateriTest(TestCase):
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
)
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")
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)
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)
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(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
......@@ -614,7 +591,11 @@ class PostsViewTest(TestCase):
post_comment_group_dict = {}
for i in range(POST_COUNT):
post = Materi.objects.create(uploader=user, cover=sample_file, content=sample_file,)
post = Materi.objects.create(
uploader=user,
cover=sample_file,
content=sample_file,
)
post.categories.add(sample_category)
post_comment_group_dict[post.id] = {
......@@ -622,9 +603,11 @@ class PostsViewTest(TestCase):
"comments": [],
}
for j in range(LIKES_COUNT_PER_POST[i]):
for j in range (LIKES_COUNT_PER_POST[i]):
Like.objects.create(
timestamp=datetime.now(), materi=post, session_id=("dummysession-" + str(i) + "-" + str(j))
timestamp=datetime.now(),
materi=post,
session_id=("dummysession-" + str(i) + '-' + str(j))
)
for i, post_id in enumerate(post_comment_group_dict):
......@@ -641,8 +624,11 @@ class PostsViewTest(TestCase):
@classmethod
def setUpTestData(cls):
cls.url = "/posts/"
cls.user_credentials = {"email": "user@email.com", "password": "justpass"}
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)
......@@ -686,17 +672,20 @@ class PostsViewTest(TestCase):
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)}
comments = {
i: [comment.id for comment in self.data[post_id]["comments"]]
for i, post_id in enumerate(posts)
}
self.assertRegex(
str(response.content),
rf'.*(<div id="post-{posts[2]}">)'
+ rf'.*(<div id="post-{posts[2]}-comment-{comments[2][0]}">)'
+ rf'.*(<div id="post-{posts[2]}-comment-{comments[2][1]}">)'
+ rf'.*(<div id="post-{posts[2]}-comment-{comments[2][2]}">)'
+ rf'.*(<div id="post-{posts[1]}">)'
+ rf'.*(<div id="post-{posts[0]}">)'
+ rf'.*(<div id="post-{posts[0]}-comment-{comments[0][0]}">)',
rf'.*(<div id="post-{posts[2]}">)' + \
rf'.*(<div id="post-{posts[2]}-comment-{comments[2][0]}">)' + \
rf'.*(<div id="post-{posts[2]}-comment-{comments[2][1]}">)' + \
rf'.*(<div id="post-{posts[2]}-comment-{comments[2][2]}">)' + \
rf'.*(<div id="post-{posts[1]}">)' + \
rf'.*(<div id="post-{posts[0]}">)' + \
rf'.*(<div id="post-{posts[0]}-comment-{comments[0][0]}">)'
)
def test_like_count_written_correctly_on_template(self):
......@@ -706,10 +695,10 @@ class PostsViewTest(TestCase):
post = self.data[post_id]["data"]
self.assertContains(
response, '<span id="post-like-count-' + str(post.id) + '">' + str(post.like_count) + "</span>",
response,
'<span id="post-like-count-' + str(post.id) + '">' + str(post.like_count) + '</span>',
)
class TemplateLoaderTest(TestCase):
def test_template_loader_url_exist(self):
url = "/test-page.html"
......@@ -739,43 +728,52 @@ class TemplateLoaderTest(TestCase):
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")
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__)
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")
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")
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")
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")
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")
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")
self.client.login(email="kontributor@gov.id",
password="kontributor")
response = self.client.get("/unggah/")
# Positive tests
......@@ -785,7 +783,8 @@ class UploadPageTest(TestCase):
self.assertNotContains(response, "Anything")
def test_upload_page_form_field(self):
self.client.login(email="kontributor@gov.id", password="kontributor")
self.client.login(email="kontributor@gov.id",
password="kontributor")
response = self.client.get("/unggah/")
# Positive tests
......@@ -798,32 +797,38 @@ class UploadPageTest(TestCase):
class UploadExcelPageTest(TestCase):
def setUp(self):
self.client = Client()
self.user = User.objects._create_user(email="kontributor@gov.id", password="kontributor", is_contributor=True)
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__)
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")
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")
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")
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")
self.client.login(email="kontributor@gov.id",
password="kontributor")
response = self.client.get("/unggah_excel/")
# Positive tests
......@@ -833,7 +838,8 @@ class UploadExcelPageTest(TestCase):
self.assertNotContains(response, "Anything")
def test_upload_excel_page_form_field(self):
self.client.login(email="kontributor@gov.id", password="kontributor")
self.client.login(email="kontributor@gov.id",
password="kontributor")
response = self.client.get("/unggah_excel/")
# Positive tests
......@@ -849,144 +855,150 @@ class UploadExcelPageTest(TestCase):
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 'title' in field_lengths:
title1 = title1[:field_lengths['title']]
if "author" in field_lengths:
author1 = author1[: field_lengths["author"]]
if 'author' in field_lengths:
author1 = author1[:field_lengths['author']]
if "publisher" in field_lengths:
publisher1 = publisher1[: field_lengths["publisher"]]
if 'publisher' in field_lengths:
publisher1 = publisher1[:field_lengths['publisher']]
if len(categories) > 0:
categories1 = ",".join(categories)
data_frame = pd.DataFrame(