Fakultas Ilmu Komputer UI

Commit defcd506 authored by Edward Partogi Gembira Abyatar's avatar Edward Partogi Gembira Abyatar
Browse files

Merge branch '1706979215-129' into 'master'

[#129] Added notification for Kontributor when a Materi has been verified

See merge request !108
parents 521ecd68 7a79208e
Pipeline #60182 passed with stages
in 24 minutes and 41 seconds
...@@ -12,6 +12,7 @@ from administration.services import StatisticService, DetailVerificationService, ...@@ -12,6 +12,7 @@ from administration.services import StatisticService, DetailVerificationService,
from app.models import Category, Materi, ViewStatistics, DownloadStatistics, Comment, Like, LaporanMateri, AdminNotification from app.models import Category, Materi, ViewStatistics, DownloadStatistics, Comment, Like, LaporanMateri, AdminNotification
from authentication.models import User from authentication.models import User
from datetime import datetime from datetime import datetime
from app.models import NotifikasiKontributor
from administration.utils import generate_time_step from administration.utils import generate_time_step
...@@ -82,6 +83,10 @@ class DetailVerificationView(TemplateView): ...@@ -82,6 +83,10 @@ class DetailVerificationView(TemplateView):
verif_report = VerificationReport( verif_report = VerificationReport(
report=report, materi=materi, user=self.request.user, status=materi.get_status_display()) report=report, materi=materi, user=self.request.user, status=materi.get_status_display())
verif_report.save() verif_report.save()
new_kontributor_notif = NotifikasiKontributor(materi=materi, user=materi.uploader, feedback=materi.get_status_display())
new_kontributor_notif.save()
return HttpResponseRedirect("/administration/") return HttpResponseRedirect("/administration/")
...@@ -585,6 +590,8 @@ def blok_materi(request, *args, **kwargs): ...@@ -585,6 +590,8 @@ def blok_materi(request, *args, **kwargs):
if materi.status == "APPROVE" and LaporanMateri.objects.filter(is_rejected=False, materi_id=materi.id): if materi.status == "APPROVE" and LaporanMateri.objects.filter(is_rejected=False, materi_id=materi.id):
materi.status = "BLOCKED" materi.status = "BLOCKED"
materi.save() materi.save()
new_kontributor_notif = NotifikasiKontributor(materi=materi, user=materi.uploader, feedback=materi.get_status_display())
new_kontributor_notif.save()
return HttpResponseRedirect(ADMINISTRATION_REPORT) return HttpResponseRedirect(ADMINISTRATION_REPORT)
......
# Generated by Django 3.1 on 2020-10-31 16:29
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('app', '0027_readlater'),
]
operations = [
migrations.CreateModel(
name='NotifikasiKontributor',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('feedback', models.CharField(default='', max_length=20)),
('materi', models.ForeignKey(max_length=120, on_delete=django.db.models.deletion.CASCADE, to='app.materi')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
# Generated by Django 3.1 on 2020-10-31 19:17
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('app', '0028_notifikasikontributor'),
('app', '0028_adminnotification'),
]
operations = [
]
...@@ -331,5 +331,13 @@ class ReadLater(models.Model): ...@@ -331,5 +331,13 @@ class ReadLater(models.Model):
class Meta: class Meta:
unique_together = ["materi", "user"] unique_together = ["materi", "user"]
class NotifikasiKontributor(models.Model):
materi = models.ForeignKey(Materi, on_delete=models.CASCADE, max_length=120)
user = models.ForeignKey(User, on_delete=models.CASCADE)
feedback = models.CharField(max_length=20, default="")
def __str__(self):
return "Status: {}".format(self.feedback)
class AdminNotification(models.Model): class AdminNotification(models.Model):
materi = models.ForeignKey(Materi, on_delete=models.CASCADE) materi = models.ForeignKey(Materi, on_delete=models.CASCADE)
...@@ -11,6 +11,21 @@ ...@@ -11,6 +11,21 @@
<ul class="navbar-nav ml-auto"> <ul class="navbar-nav ml-auto">
{% if request.user.is_contributor %} {% if request.user.is_contributor %}
<li class="nav-item dropdown">
<a id="notifBtn" class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">Notifikasi</a>
<div class="dropdown-menu show" aria-labelledby="notifBtn">
{% if kontributor_notif %}
{% for notif in kontributor_notif %}
<a class="dropdown-item" style="white-space: break-spaces;" href="{% url 'dashboard' %}">Materi "{{notif.materi.title}}" <br>{{ notif }}</a>
<div class="dropdown-divider"></div>
{% endfor %}
{% else %}
<a class="dropdown-item disabled" href="#" style="white-space: break-spaces;">Anda tidak memiliki notifikasi baru</a>
{% endif %}
</div>
</a>
</li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="/dashboard/"> <a class="nav-link" href="/dashboard/">
<span class="mr-2 d-none d-lg-inline text-gray-600 small">Dasbor</span> <span class="mr-2 d-none d-lg-inline text-gray-600 small">Dasbor</span>
......
...@@ -45,7 +45,7 @@ from app.views import UploadMateriHTML, add_rating_materi ...@@ -45,7 +45,7 @@ from app.views import UploadMateriHTML, add_rating_materi
from .models import (Category, Comment, DislikeComment, DownloadStatistics, from .models import (Category, Comment, DislikeComment, DownloadStatistics,
Like, LikeComment, Materi, Rating, RatingContributor, Like, LikeComment, Materi, Rating, RatingContributor,
ReadLater, ReqMaterial, Review, ViewStatistics, AdminNotification) ReadLater, ReqMaterial, Review, ViewStatistics, AdminNotification, NotifikasiKontributor)
from .services import DetailMateriService from .services import DetailMateriService
from .views import (DaftarKatalog, DashboardKontributorView, DetailMateri, from .views import (DaftarKatalog, DashboardKontributorView, DetailMateri,
KatalogPerKontributorView, MateriFavorite, KatalogPerKontributorView, MateriFavorite,
...@@ -4024,6 +4024,77 @@ class UploadMateriTest(TestCase): ...@@ -4024,6 +4024,77 @@ class UploadMateriTest(TestCase):
self.assertEqual(Materi.objects.count(), 1) self.assertEqual(Materi.objects.count(), 1)
class NotifikasiKontributorTest(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.admin_credential = {
"email": "admin@gov.id",
"password": "passwordtest"
}
self.admin = get_user_model().objects.create_user(
**self.admin_credential, name="Admin", is_admin=True)
self.setUpImage()
self.content = SimpleUploadedFile("ExampleFile221.pdf", b"Test file")
self.category = Category.objects.create(id="1", name="medis", description="kategori medis")
VerificationSetting.objects.create(title="Kriteria 1", description="memenuhi kriteria 1", archived=False, pk=1)
@override_settings(MEDIA_ROOT=tempfile.gettempdir())
def setUpImage(self):
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_no_notification(self):
self.client.login(**self.contributor_credential)
notifs = NotifikasiKontributor.objects.filter(user=self.contributor)
self.assertEqual(notifs.count(), 0)
self.client.logout()
def test_notification(self):
# Client as Kontributor posting new Materi
self.client.login(**self.contributor_credential)
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.client.logout()
# Client as Admin disapproving the Materi
self.client.login(**self.admin_credential)
materi = Materi.objects.get(title="Materi 1", uploader=self.contributor)
pk_new_materi = materi.id
self.client.post(
"/administration/detail-verif/"+str(pk_new_materi)+"/", data={
'kriteria-1':'0','feedback':"a", 'action':"disapprove"
}
)
self.client.logout()
self.assertEqual(NotifikasiKontributor.objects.filter(materi=materi, user=self.contributor).count(), 1)
# Client as Kontributor get notifications
self.client.login(**self.contributor_credential)
notif = NotifikasiKontributor.objects.get(materi=materi, user=self.contributor)
html = self.client.get("/dashboard/").content.decode("utf-8")
self.assertIn(str(notif), html)
# Client as Kontributor check Materi detail, and the notification should be gone
self.client.get("/materi/"+str(materi.id)+"/")
self.assertEqual(NotifikasiKontributor.objects.filter(materi=materi, user=self.contributor).count(), 0)
class AdminNotificationTest(TestCase): class AdminNotificationTest(TestCase):
def setUp(self): def setUp(self):
......
...@@ -35,6 +35,7 @@ from app.models import ( ...@@ -35,6 +35,7 @@ from app.models import (
Rating, RatingContributor, Rating, RatingContributor,
SubmitVisitor, SubmitVisitor,
ReadLater, ReadLater,
NotifikasiKontributor,
AdminNotification AdminNotification
) )
from authentication.models import User from authentication.models import User
...@@ -185,6 +186,9 @@ class DetailMateri(TemplateView): ...@@ -185,6 +186,9 @@ class DetailMateri(TemplateView):
context["review_data"] = query_set_for_review context["review_data"] = query_set_for_review
context["has_liked_comment"] = has_liked context["has_liked_comment"] = has_liked
context["has_disliked_comment"] = has_disliked context["has_disliked_comment"] = has_disliked
if request.user.is_authenticated and request.user.is_contributor:
opened_notif = NotifikasiKontributor.objects.filter(user=request.user, materi=context["materi_data"])
opened_notif.delete()
return self.render_to_response(context=context) return self.render_to_response(context=context)
......
...@@ -77,3 +77,12 @@ class Login(TemplateView): ...@@ -77,3 +77,12 @@ class Login(TemplateView):
return self.do_login(context, email, password, request, result) return self.do_login(context, email, password, request, result)
from app.models import NotifikasiKontributor
def kontributor_notif_context(request):
if request.user.is_authenticated and request.user.is_contributor:
notifs = NotifikasiKontributor.objects.filter(user=request.user)
return {
'kontributor_notif':notifs
}
else:
return {}
\ No newline at end of file
...@@ -81,6 +81,8 @@ TEMPLATES = [ ...@@ -81,6 +81,8 @@ TEMPLATES = [
"django.template.context_processors.request", "django.template.context_processors.request",
"django.contrib.auth.context_processors.auth", "django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages", "django.contrib.messages.context_processors.messages",
"authentication.views.kontributor_notif_context"
], ],
}, },
}, },
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment