Fakultas Ilmu Komputer UI

Commit 6dd73e98 authored by Nabila Febri Viola's avatar Nabila Febri Viola
Browse files

Merge branch 'PBI-6-ajukan-acara-donor-fix' into 'staging'

Pbi 6 ajukan acara donor fix

Closes #67

See merge request !114
parents f685381c 4cfd418a
Pipeline #48936 passed with stages
in 18 minutes and 50 seconds
......@@ -31,14 +31,16 @@ download_acara_donor.short_description = 'Download Acara Donor as Excel Workbook
@admin.register(AcaraDonor)
class AcaraDonorAdmin(admin.ModelAdmin):
list_filter = ('status', AcaraDonorFilter, 'alamat_lokasi_donor')
list_filter = ('status', AcaraDonorFilter, 'kecamatan', 'kategori')
search_fields = ('waktu_mulai',)
readonly_fields = ('nomor',
'user',
'nama_institusi',
'alamat_institusi',
'no_telp_kantor',
'email_kantor',
'no_telp_kantor',
'nama_koor',
'email_koor',
'no_telp_koor')
actions = [download_acara_donor]
'no_telp_koor',
'keterangan',
'foto_lokasi')
import factory
import dateutil.tz
from datetime import timedelta
from django.utils import timezone
from random import choice, randint
from acara_donor.models import AcaraDonor
from donor.models import JadwalDonor
from main.factories import UserFactory
......@@ -14,14 +17,27 @@ class AcaraDonorFactory(factory.DjangoModelFactory):
nomor = factory.Faker('uuid4')
user = factory.SubFactory(UserFactory)
status = factory.Faker('boolean', chance_of_getting_true=66)
nama_institusi = factory.Faker('company')
alamat_institusi = factory.Faker('address', locale=LOCALE)
alamat_lokasi_donor = factory.Faker('address', locale=LOCALE)
no_telp_kantor = factory.Faker('phone_number')
email_kantor = factory.Faker('company_email', locale=LOCALE)
no_telp_kantor = factory.Faker('phone_number')
nama_koor = factory.Faker('name', locale=LOCALE)
email_koor = factory.Faker('free_email', locale=LOCALE)
no_telp_koor = factory.Faker('phone_number')
waktu_donor = factory.Faker('future_datetime', tzinfo=dateutil.tz.gettz('Asia/Jakarta'))
kategori = factory.LazyAttribute(lambda _:
choice(JadwalDonor.Category.choices)[0])
alamat_lokasi_donor = factory.Faker('address', locale=LOCALE)
kecamatan = factory.LazyAttribute(lambda _:
choice(JadwalDonor.Kecamatan.choices)[0])
waktu_mulai = factory.LazyAttribute(lambda _: timezone.now()
+ timedelta(
days=randint(1, 66),
hours=randint(1, 23))) # NOSONAR
waktu_berakhir = factory.LazyAttribute(lambda t: t.waktu_mulai
+ timedelta(
hours=randint(2, 6))) # NOSONAR
perkiraan_jumlah_donor = factory.fuzzy.FuzzyInteger(low=33, high=666)
keterangan = factory.Faker('text')
......@@ -7,7 +7,7 @@ from django.utils.translation import gettext_lazy as _
class AcaraDonorFilter(admin.SimpleListFilter):
title = _('waktu donor')
parameter_name = 'waktu_donor'
parameter_name = 'waktu_mulai'
def lookups(self, request, model_admin):
return (
......@@ -24,33 +24,34 @@ class AcaraDonorFilter(admin.SimpleListFilter):
def __last_day_of_month(self, any_day):
next_month = any_day.replace(day=28) + datetime.timedelta(days=4)
return next_month - datetime.timedelta(days=next_month.day) + datetime.timedelta(days=1)
return next_month - datetime.timedelta(days=next_month.day) \
+ datetime.timedelta(days=1)
def queryset(self, request, queryset):
today = localtime(now()).replace(hour=0, minute=0, second=0, microsecond=0)
tomorrow = today + datetime.timedelta(days=1)
today = localtime(now()).replace(
hour=0, minute=0, second=0, microsecond=0)
next_seven_days = today + datetime.timedelta(days=8)
this_month = today.replace(day=1)
end_of_this_month = self.__last_day_of_month(today)
start_of_next_month = today.replace(year=today.year, month=today.month + 1, day=1)
start_of_next_month = today.replace(year=today.year,
month=today.month + 1, day=1)
end_of_next_month = self.__last_day_of_month(start_of_next_month)
this_year = today.replace(month=1, day=1)
next_year = today.replace(year=today.year + 1, month=1, day=1)
if self.value() == 'today':
return queryset.filter(waktu_donor__range=[today, tomorrow])
return queryset.filter(waktu_mulai__date=today)
if self.value() == 'next_seven_days':
return queryset.filter(waktu_donor__range=[today, next_seven_days])
return queryset.filter(waktu_mulai__range=[today, next_seven_days])
if self.value() == 'this_month':
return queryset.filter(waktu_donor__range=[this_month, end_of_this_month])
return queryset.filter(
waktu_mulai__range=[this_month, end_of_this_month])
if self.value() == 'next_month':
return queryset.filter(waktu_donor__range=[start_of_next_month, end_of_next_month])
return queryset.filter(waktu_mulai__range=[start_of_next_month,
end_of_next_month])
if self.value() == 'this_year':
return queryset.filter(waktu_donor__range=[this_year, next_year])
return queryset.filter(waktu_mulai__year=today.year)
import random
from django.core.management.base import BaseCommand
from django.core.management.base import BaseCommand, CommandError
from main.models import User
from acara_donor.factories import AcaraDonorFactory
from main.factories import UserFactory
class Command(BaseCommand):
help = 'Seeds the database.'
help = 'Seeds the database with dummy acara donor.'
def add_arguments(self, parser):
parser.add_argument('--users_emails', nargs='+', type=str)
def handle(self, *args, **options):
list_user = []
for _ in range(33):
user = UserFactory()
user.save()
list_user.append(user)
for _ in range(123):
i = random.randint(0, 32) # NOSONAR
AcaraDonorFactory(user=list_user[i])
self.stdout.write(self.style.SUCCESS("Successfully seeds the database with dummy acara donor."))
if not options['users_emails']:
for _ in range(33):
user = UserFactory()
user.save()
list_user.append(user)
else:
for email in options['users_emails']:
try:
list_user.append(User.objects.get(email=email))
except User.DoesNotExist:
raise CommandError(f"User {email} does not exist.")
for i in range(len(list_user)):
amount = random.randint(0, 32) # NOSONAR
for _ in range(amount):
AcaraDonorFactory(user=list_user[i])
self.stdout.write(
self.style.SUCCESS(
"Successfully seeds the database with dummy acara donor."))
# Generated by Django 3.0.5 on 2020-05-04 08:29
# Generated by Django 3.0.5 on 2020-06-01 19:27
from django.conf import settings
import django.core.validators
......@@ -28,14 +28,18 @@ class Migration(migrations.Migration):
('nama_koor', models.CharField(max_length=70)),
('email_koor', models.EmailField(max_length=254)),
('no_telp_koor', models.CharField(max_length=20)),
('kategori', models.CharField(choices=[('Terbuka', 'Public'), ('Tertutup', 'Private')], max_length=20)),
('alamat_lokasi_donor', models.CharField(max_length=140)),
('waktu_donor', models.DateTimeField()),
('kecamatan', models.CharField(choices=[('Beji', 'Beji'), ('Pancoran Mas', 'Pancoran Mas'), ('Cipayung', 'Cipayung'), ('Sukmajaya', 'Sukmajaya'), ('Cilodong', 'Cilodong'), ('Limo', 'Limo'), ('Cinere', 'Cinere'), ('Cimanggis', 'Cimanggis'), ('Tapos', 'Tapos'), ('Sawangan', 'Sawangan'), ('Bojong Sari', 'Bojong Sari')], max_length=20)),
('waktu_mulai', models.DateTimeField()),
('waktu_berakhir', models.DateTimeField()),
('perkiraan_jumlah_donor', models.IntegerField(validators=[django.core.validators.MinValueValidator(11)])),
('keterangan', models.TextField(blank=True)),
('foto_lokasi', models.ImageField(blank=True, upload_to='images')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'ordering': ['waktu_donor'],
'ordering': ['-waktu_mulai'],
},
),
]
# Generated by Django 3.0.5 on 2020-05-04 20:32
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('acara_donor', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='acaradonor',
options={'ordering': ['-waktu_donor']},
),
]
from django.db import models
from django.core.validators import MinValueValidator
from django.utils.timezone import localtime
from main.models import User
from donor.models import JadwalDonor
import uuid
......@@ -8,21 +10,35 @@ class AcaraDonor(models.Model):
nomor = models.UUIDField(primary_key=True, default=uuid.uuid4)
user = models.ForeignKey(User, on_delete=models.CASCADE)
status = models.BooleanField(null=True)
nama_institusi = models.CharField(max_length=95)
alamat_institusi = models.CharField(max_length=140)
email_kantor = models.EmailField()
no_telp_kantor = models.CharField(max_length=20)
nama_koor = models.CharField(max_length=70)
email_koor = models.EmailField()
no_telp_koor = models.CharField(max_length=20)
kategori = models.CharField(max_length=20,
choices=JadwalDonor.Category.choices)
alamat_lokasi_donor = models.CharField(max_length=140)
waktu_donor = models.DateTimeField()
perkiraan_jumlah_donor = models.IntegerField(validators=[MinValueValidator(11)])
kecamatan = models.CharField(max_length=20,
choices=JadwalDonor.Kecamatan.choices)
waktu_mulai = models.DateTimeField()
waktu_berakhir = models.DateTimeField()
perkiraan_jumlah_donor = models.IntegerField(
validators=[MinValueValidator(11)])
keterangan = models.TextField(blank=True)
foto_lokasi = models.ImageField(upload_to='images', blank=True)
def __str__(self):
waktu_donor = self.waktu_donor.strftime("%d/%m/%Y, %H:%M")
return f"{self.nama_institusi}: {self.alamat_lokasi_donor}, {waktu_donor}"
waktu_mulai = localtime(self.waktu_mulai)
waktu_berakhir = localtime(self.waktu_berakhir)
return f"{self.nama_institusi}: {self.alamat_lokasi_donor}, \
{waktu_mulai.date()} \
({waktu_mulai.hour:02d}:{waktu_mulai.minute:02d} \
- {waktu_berakhir.hour:02d}:{waktu_berakhir.minute:02d})"
class Meta:
ordering = ['-waktu_donor']
ordering = ['-waktu_mulai']
......@@ -5,15 +5,25 @@ from acara_donor.models import AcaraDonor
class AcaraDonorSerializer(serializers.ModelSerializer):
def validate(self, data):
queryset = AcaraDonor.objects.filter(nama_institusi=data['nama_institusi'],
alamat_lokasi_donor=data['alamat_lokasi_donor'],
waktu_donor=data['waktu_donor'])
queryset = AcaraDonor.objects.filter(
nama_institusi=data['nama_institusi'],
alamat_lokasi_donor=data['alamat_lokasi_donor'],
waktu_mulai=data['waktu_mulai'])
if queryset.exists():
raise serializers.ValidationError("Acara donor darah ini sudah diajukan.")
if data['waktu_donor'] < timezone.now():
raise serializers.ValidationError("Tanggal acara donor darah tidak boleh di masa lalu.")
raise serializers.ValidationError(
"Acara donor darah ini sudah diajukan.")
if data['waktu_mulai'] < timezone.now():
raise serializers.ValidationError(
"Pelaksanaan acara donor darah tidak boleh di masa lalu.")
if data['waktu_berakhir'] < data['waktu_mulai']:
raise serializers.ValidationError(
"Jam pelaksanaan acara donor darah tidak valid.")
return data
class Meta:
model = AcaraDonor
exclude = ["user", "status"]
exclude = ["user", "nomor", "status"]
extra_kwargs = {'foto_lokasi': {'required': False}}
from io import StringIO
from django.core.management import call_command
from django.core.management import call_command, CommandError
from django.test import TestCase
from main.factories import UserFactory
class SeedAcaraDonorTest(TestCase):
......@@ -9,3 +10,22 @@ class SeedAcaraDonorTest(TestCase):
out = StringIO()
call_command('acara_donor_seeder', stdout=out)
self.assertIn('Success', out.getvalue())
def test_command_with_email_provided_success(self):
user1 = UserFactory(email="tes1@gmail.com")
user2 = UserFactory(email="tes2@gmail.com")
user1.save()
user2.save()
out = StringIO()
call_command(
'acara_donor_seeder', users_emails=["tes1@gmail.com",
"tes2@gmail.com"],
stdout=out)
self.assertIn('Success', out.getvalue())
def test_command_with_email_provided_failed(self):
out = StringIO()
with self.assertRaisesMessage(CommandError,
'User bities@gmail.com does not exist.'):
call_command('acara_donor_seeder',
users_emails=["bities@gmail.com", ], stdout=out)
......@@ -2,8 +2,8 @@ import datetime
from unittest.mock import patch
from django.contrib.auth import get_user_model
from django.test import TestCase
from django.urls import reverse
from django.utils import timezone
from django.utils.timezone import localtime
from rest_framework import status
from rest_framework.test import APITestCase
from rest_framework_authlib.tokens import AccessToken
......@@ -24,13 +24,18 @@ class AcaraDonorTest(TestCase):
user = UserFactory()
user.save()
acara_donor = AcaraDonorFactory(user=user)
waktu_donor = acara_donor.waktu_donor.strftime("%d/%m/%Y, %H:%M")
waktu_mulai = localtime(acara_donor.waktu_mulai)
waktu_berakhir = localtime(acara_donor.waktu_berakhir)
self.assertTrue(isinstance(acara_donor, AcaraDonor))
self.assertEqual((str(acara_donor.nama_institusi) + ': ' +
str(acara_donor.alamat_lokasi_donor) + ", " + waktu_donor),
self.assertEqual((f"{acara_donor.nama_institusi}: {acara_donor.alamat_lokasi_donor}, \
{waktu_mulai.date()} \
({waktu_mulai.hour:02d}:{waktu_mulai.minute:02d} \
- {waktu_berakhir.hour:02d}:{waktu_berakhir.minute:02d})"),
str(acara_donor))
@patch('django.utils.timezone.now', return_value=datetime.datetime(
2020, 6, 12, 9, 0, tzinfo=datetime.timezone.utc))
class AcaraDonorSerializerTest(TestCase):
""" Test module for Acara Donor serializer"""
......@@ -38,62 +43,94 @@ class AcaraDonorSerializerTest(TestCase):
self.user = UserFactory()
self.user.save()
self.acara_donor = AcaraDonorFactory(user=self.user)
base_time = timezone.localtime(
datetime.datetime(2020, 6, 12, 9, 18,
tzinfo=datetime.timezone.utc))
self.acara_donor_attr = {"alamat_institusi": "Pacilkom",
"alamat_lokasi_donor": "Sekre Pacil",
"email_kantor": "pacil@cs.ui.ac.id",
"email_koor": "pacilia@gmail.com",
"kategori": "Terbuka",
"kecamatan": "Beji",
"keterangan": "",
"nama_institusi": "Pacilkom",
"nama_koor": "dr. Pacilia",
"no_telp_kantor": "08165342342",
"no_telp_koor": "08167021743",
"nomor": "ea582779-fdfc-444e-ad03-4084e715af0a",
"perkiraan_jumlah_donor": 455,
"waktu_donor": timezone.now() + timezone.timedelta(days=3)}
"waktu_berakhir": base_time
+ timezone.timedelta(hours=5),
"waktu_mulai": base_time
+ timezone.timedelta(hours=3)}
def test_create_acara_donor_failed_due_to_duplication(self,
mock_timezone):
serializer = AcaraDonorSerializer(instance=self.acara_donor,
data=self.acara_donor_attr)
def test_create_acara_donor_failed_due_to_duplication(self):
serializer = AcaraDonorSerializer(instance=self.acara_donor, data=self.acara_donor_attr)
serializer.is_valid()
new_acara_donor = serializer.save()
new_acara_donor.refresh_from_db()
serializer = AcaraDonorSerializer(instance=self.acara_donor, data=self.acara_donor_attr)
serializer = AcaraDonorSerializer(instance=self.acara_donor,
data=self.acara_donor_attr)
self.assertFalse(serializer.is_valid())
def test_create_acara_donor_failed_because_time_has_passed(self,
mock_timezone):
self.acara_donor_attr['waktu_mulai'] = timezone.now() \
- timezone.timedelta(days=3)
serializer = AcaraDonorSerializer(instance=self.acara_donor,
data=self.acara_donor_attr)
self.assertFalse(serializer.is_valid())
def test_create_acara_donor_failed_because_time_has_passed(self):
self.acara_donor_attr['waktu_donor'] = timezone.now() - timezone.timedelta(days=3)
serializer = AcaraDonorSerializer(instance=self.acara_donor, data=self.acara_donor_attr)
def test_create_acara_donor_failed_because_end_time_is_before_start_time(
self, mock_timezone):
self.acara_donor_attr['waktu_mulai'] = timezone.now() \
+ timezone.timedelta(hours=5)
self.acara_donor_attr['waktu_berakhir'] = timezone.now() \
+ timezone.timedelta(hours=3)
serializer = AcaraDonorSerializer(instance=self.acara_donor,
data=self.acara_donor_attr)
self.assertFalse(serializer.is_valid())
@patch('django.utils.timezone.now', return_value=datetime.datetime(
2020, 6, 12, 9, 0, tzinfo=datetime.timezone.utc))
class AcaraDonorCreateViewTest(APITestCase):
""" Test module for Acara Donor API"""
def setUp(self):
self.user = UserFactory()
self.user.save()
self.client.credentials(HTTP_AUTHORIZATION='Bearer ' + str(AccessToken.for_user(self.user)))
self.client.credentials(HTTP_AUTHORIZATION='Bearer ' +
str(AccessToken.for_user(self.user)))
def test_create_acara_donor(self):
def test_create_acara_donor_with_post_request(self, mock_timezone):
response = self.client.post('/acara-donor/pengajuan/',
{"alamat_institusi": "Pacilkom",
"alamat_lokasi_donor": "Sekre Pacil",
"email_kantor": "pacil@cs.ui.ac.id",
"email_koor": "pacilia@gmail.com",
"foto_lokasi": "",
"kategori": "Terbuka",
"kecamatan": "Beji",
"keterangan": "",
"nama_institusi": "Pacilkom",
"nama_koor": "dr. Pacilia",
"no_telp_kantor": "08165342342",
"no_telp_koor": "08167021743",
"nomor": "ea582779-fdfc-444e-ad03-4084e715af0a",
"perkiraan_jumlah_donor": 455,
"waktu_donor": timezone.now() + timezone.timedelta(days=3)},
format='json')
"waktu_berakhir": timezone.now()
+ timezone.timedelta(hours=7),
"waktu_mulai": timezone.now()
+ timezone.timedelta(hours=5)},
format='multipart')
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
@patch('acara_donor.filters.now',
new=lambda: datetime.datetime(2020, 5, 10, 9, 0, tzinfo=datetime.timezone.utc))
@patch('acara_donor.filters.now', new=lambda:
datetime.datetime(2020, 5, 10, 9, 0, tzinfo=datetime.timezone.utc))
class AcaraDonorFilterTest(TestCase):
""" Test module for Acara Donor filter"""
......@@ -101,63 +138,61 @@ class AcaraDonorFilterTest(TestCase):
self.user = UserFactory()
self.user.save()
base_time = timezone.localtime(datetime.datetime(2020, 5, 10, 9, 14,
tzinfo=datetime.timezone.utc))
base_time = timezone.localtime(datetime.datetime(
2020, 5, 10, 9, 14, tzinfo=datetime.timezone.utc))
self.acara_donor_today = AcaraDonorFactory(user=self.user,
waktu_donor=base_time + timezone.timedelta(hours=3))
self.acara_donor_today = AcaraDonorFactory(
user=self.user,
waktu_mulai=base_time + timezone.timedelta(hours=3))
self.acara_donor_today.save()
self.acara_donor_overmorrow = AcaraDonorFactory(user=self.user,
waktu_donor=base_time + timezone.timedelta(days=2))
self.acara_donor_overmorrow = AcaraDonorFactory(
user=self.user,
waktu_mulai=base_time + timezone.timedelta(days=2))
self.acara_donor_overmorrow.save()
self.acara_donor_next_month = AcaraDonorFactory(user=self.user,
waktu_donor=base_time + timezone.timedelta(days=33))
self.acara_donor_next_month = AcaraDonorFactory(
user=self.user,
waktu_mulai=base_time + timezone.timedelta(days=33))
self.acara_donor_next_month.save()
def test_filter_acara_donor_today_success(self):
filter_today = AcaraDonorFilter(None, {'waktu_donor': 'today'}, AcaraDonor, AcaraDonorAdmin)
acara_donor_filtered = filter_today.queryset(None, AcaraDonor.objects.all())[0]
self.assertEqual(acara_donor_filtered.waktu_donor, self.acara_donor_today.waktu_donor)
filter_today = AcaraDonorFilter(None, {'waktu_mulai': 'today'},
AcaraDonor, AcaraDonorAdmin)
acara_donor_filtered = filter_today.queryset(
None, AcaraDonor.objects.all())[0]
self.assertEqual(acara_donor_filtered.waktu_mulai,
self.acara_donor_today.waktu_mulai)
def test_filter_acara_donor_next_seven_days_success(self):
filter_seven_days = AcaraDonorFilter(None, {'waktu_donor': 'next_seven_days'}, AcaraDonor, AcaraDonorAdmin)
acara_donor_filtered = filter_seven_days.queryset(None, AcaraDonor.objects.all())[0]
self.assertEqual(acara_donor_filtered.waktu_donor, self.acara_donor_overmorrow.waktu_donor)
filter_seven_days = AcaraDonorFilter(
None, {'waktu_mulai': 'next_seven_days'},
AcaraDonor, AcaraDonorAdmin)
acara_donor_filtered = filter_seven_days.queryset(
None, AcaraDonor.objects.all())[0]
self.assertEqual(acara_donor_filtered.waktu_mulai,
self.acara_donor_overmorrow.waktu_mulai)
def test_filter_acara_donor_this_month_success(self):
filter_this_month = AcaraDonorFilter(None, {'waktu_donor': 'this_month'}, AcaraDonor, AcaraDonorAdmin)
acara_donor_filtered = filter_this_month.queryset(None, AcaraDonor.objects.all())[0]
self.assertEqual(acara_donor_filtered.waktu_donor, self.acara_donor_overmorrow.waktu_donor)
filter_this_month = AcaraDonorFilter(
None, {'waktu_mulai': 'this_month'}, AcaraDonor, AcaraDonorAdmin)
acara_donor_filtered = filter_this_month.queryset(
None, AcaraDonor.objects.all())[0]
self.assertEqual(acara_donor_filtered.waktu_mulai,
self.acara_donor_overmorrow.waktu_mulai)
def test_filter_acara_donor_next_month_success(self):
filter_next_month = AcaraDonorFilter(None, {'waktu_donor': 'next_month'}, AcaraDonor, AcaraDonorAdmin)
acara_donor_filtered = filter_next_month.queryset(None, AcaraDonor.objects.all())[0]
self.assertEqual(acara_donor_filtered.waktu_donor, self.acara_donor_next_month.waktu_donor)
filter_next_month = AcaraDonorFilter(
None, {'waktu_mulai': 'next_month'}, AcaraDonor, AcaraDonorAdmin)
acara_donor_filtered = filter_next_month.queryset(
None, AcaraDonor.objects.all())[0]
self.assertEqual(acara_donor_filtered.waktu_mulai,
self.acara_donor_next_month.waktu_mulai)
def test_filter_acara_donor_this_year_success(self):
filter_this_year = AcaraDonorFilter(None, {'waktu_donor': 'this_year'}, AcaraDonor, AcaraDonorAdmin)
acara_donor_filtered = filter_this_year.queryset(None, AcaraDonor.objects.all())[0]
self.assertEqual(acara_donor_filtered.waktu_donor, self.acara_donor_next_month.waktu_donor)
class AcaraDonorAdminTest(TestCase):
def setUp(self):
username = 'admin@host'
password = 'secretsauce'
User.objects.create_superuser(username, password)
self.client.login(username=username, password=password)
def test_action_download_acaradonor(self):
user = UserFactory()
user.save()
acara_donor = AcaraDonorFactory(user=user)
acara_donor.save()
endpoint = reverse('admin:acara_donor_acaradonor_changelist')
data = {'action': 'download_acara_donor', '_selected_action': [acara_donor.nomor]}
response = self.client.post(endpoint, data=data)
self.assertEqual(response['content-type'], 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
filter_this_year = AcaraDonorFilter(None, {'waktu_mulai': 'this_year'},
AcaraDonor, AcaraDonorAdmin)