diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5f0ec1999dd165cbc01a41c31cdc71ecd410cc1a..701d1d019d3a83e423a159ecd1108814b477fb66 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,7 +10,6 @@ UnitTest: coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+)%/' before_script: - pip install -r requirements.txt - - python manage.py makemigrations - python manage.py migrate - python manage.py collectstatic --no-input when: on_success diff --git a/README.md b/README.md index 2400a58a04790629705a2a7afb630243b90f2163..f158d434f2b414cb11dfbcdf66521f33026382b0 100644 --- a/README.md +++ b/README.md @@ -169,8 +169,6 @@ It requires a request with the following key: * `no_telp`: the description Make sure you have token it your request header. Add this to your request header. `Authorization` with value `token *your_token_from_request*` -This token is also used to authorize whether you are the creator of the location or not, since only the creator -of the location could update the location ### 12. To like / dislike a facility: Make `PUT` request to API endpoint `/informasi-lokasi/lokasi/like-facility/*nama-lokasi*/*operation*/`.
@@ -251,3 +249,20 @@ Make `POST` request to API endpoint `/layanan-khusus/penyandang/register/` with * `nama_wali` : name of parent/guardian * `alamat_wali` : address of parent/guardian * `telp_wali` : phone number of parent/guardian + +### 17. To add a comment an a facility: +Make `POST` request to API endpoint `/informasi-fasilitas/lokasi/add-komentar/*nama_lokasi*/*id_fasilitas*/`.
+with key: +* `deskripsi` : The comment message +Make sure you have token it your request header. +Add this to your request header. `Authorization` with value `token *your_token_from_request*` + + +### 18. To view a comment list on a facility: +Make `GET` request to API endpoint `/informasi-fasilitas/lokasi/list-komentar/*nama_lokasi*/*id_fasilitas*/`.
+It will return a json with these key: +* `*int*` : The index of the model, with dictionary of Komentar model with key below +* `id` : The id of the comment +* `deskripsi` : The description of the comment +* `creator` : The last name of the commentator +* `date_time` : The time when the comment was posted diff --git a/coverage.xml b/coverage.xml deleted file mode 100644 index 7dacca4f7237345a9a223c6088a76d27450e7133..0000000000000000000000000000000000000000 --- a/coverage.xml +++ /dev/null @@ -1,185 +0,0 @@ - - - - - - D:\Arato\Documents\unistuff\class\ppl\poipole-dtb-beasiswa-miskin-dan-disabilitas - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/deployment.sh b/deployment.sh index c03974f20847c7fabedd8c58ead59d269eca7869..b5cba14e4f58b047835df92f8a187928c82f022b 100644 --- a/deployment.sh +++ b/deployment.sh @@ -1,3 +1,2 @@ #!/bin/bash -python manage.py makemigrations python manage.py migrate diff --git a/informasi_fasilitas/models.py b/informasi_fasilitas/models.py index 6bf478358e13879a50d154010a39faf9ad996c93..f5af7129cf7fa65f694ff5812175ed79f859c642 100644 --- a/informasi_fasilitas/models.py +++ b/informasi_fasilitas/models.py @@ -41,13 +41,14 @@ class Lokasi(models.Model): alamat = models.CharField(max_length=100) no_telp = models.CharField(max_length=16) image = models.ImageField(upload_to="static/img", null=True) - + objects = models.Manager() POINT_FIELD = ""+str(latitude)+","+str(longitude) def __str__(self): return self.name class Fasilitas(models.Model): + objects = models.Manager() lokasi = models.ForeignKey(Lokasi, on_delete=models.CASCADE) user = models.ForeignKey(User, on_delete=models.CASCADE) date_time = models.DateTimeField(auto_now_add=True) @@ -60,17 +61,20 @@ class Fasilitas(models.Model): is_verified = models.BooleanField(default=False) class Komentar(models.Model): - fasilitas =models.ForeignKey(Fasilitas, on_delete=models.CASCADE) + objects = models.Manager() + fasilitas = models.ForeignKey(Fasilitas, on_delete=models.CASCADE) user = models.ForeignKey(User, on_delete=models.CASCADE) date_time = models.DateTimeField(auto_now_add=True) deskripsi = models.TextField() class Likes(models.Model): + objects = models.Manager() user = models.ForeignKey(User, on_delete=models.CASCADE) fasilitas = models.ForeignKey(Fasilitas, on_delete=models.CASCADE) created = models.DateTimeField(auto_now_add=True) class Dislikes(models.Model): + objects = models.Manager() user = models.ForeignKey(User, on_delete=models.CASCADE) fasilitas = models.ForeignKey(Fasilitas, on_delete=models.CASCADE) created = models.DateTimeField(auto_now_add=True) diff --git a/informasi_fasilitas/serializers.py b/informasi_fasilitas/serializers.py index 9aa45f24d7c70ff6c92cd2f00d009d10eeee1d9f..5f5229030f1d85fa3fbe2e707636ecd571ca358d 100644 --- a/informasi_fasilitas/serializers.py +++ b/informasi_fasilitas/serializers.py @@ -5,4 +5,5 @@ from .models import Lokasi class LokasiSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Lokasi - fields = ('id', 'name', 'latitude', 'longitude', 'alamat', 'no_telp', 'image') \ No newline at end of file + fields = ('id', 'name', 'latitude', 'longitude', 'alamat', 'no_telp', 'image') + \ No newline at end of file diff --git a/informasi_fasilitas/test_base.py b/informasi_fasilitas/test_base.py new file mode 100644 index 0000000000000000000000000000000000000000..1a5afcee5d36e6da756c08333208817dc840c92f --- /dev/null +++ b/informasi_fasilitas/test_base.py @@ -0,0 +1,180 @@ +import json +import tempfile +from http import HTTPStatus +from django.test import TestCase, Client +from django.db.utils import IntegrityError +from django.contrib.auth.models import User +from django.urls import reverse, path, include + +from registrasi.models import BisaGoUser +from .models import Lokasi, Fasilitas, Komentar, KURSI_RODA, RUNNING_TEXT, Likes, Dislikes +from .serializers import LokasiSerializer + +not_null_constraint_failed_message = 'NOT NULL constraint failed' + + +class InformasiFasilitasTest(TestCase): + default_username_email = "user_test@gmail.com" + default_last_name = "name" + default_password = "hahagotim" + default_lokasi_name = "Mall" + default_latitude = 0.0 + default_longitude = 0.0 + default_alamat = "Jl. Raya Bogor no.1 Jakarta" + default_no_telp = "08123456789" + default_image = tempfile.NamedTemporaryFile(suffix=".jpg").name + default_like = 0 + default_dislike = 0 + default_tag = [KURSI_RODA, RUNNING_TEXT] + default_rating = 3 + default_deskripsi = "penjelasan" + + user_post = {'name': 'name', + 'email': "self.user_post@gmail.com", + 'phone_number': 000000000, + 'password': "hahagotim"} + + lokasi_test_1 = {'name': 'Ma Homie', + 'latitude': 0.1, + 'longitude': 0.1, + 'alamat': 'Jl. Raya Bogor no.2, Jakarta', + 'no_telp': '081212123132', + } + + def create_user_test(self, username=default_username_email, + last_name=default_last_name, + password=default_password): + user_test = User(username=username, + last_name=last_name, + email=username, + password=password) + user_test.save() + return user_test + + def create_lokasi_test(self, name=default_lokasi_name, + latitude=default_latitude, + longitude=default_longitude, + alamat=default_alamat, + no_telp=default_no_telp, + image=default_image): + + lokasi_test = Lokasi(name=name, + latitude=latitude, + longitude=longitude, + alamat=alamat, + no_telp=no_telp, + image=image) + lokasi_test.save() + return lokasi_test + + def create_fasilitas_test(self, deskripsi=default_deskripsi, + like=default_like, + dislike=default_dislike, + rating=default_rating, + tag=default_tag, + image=default_image, + lokasi=None, + user=None): + if (user == None): + user = self.create_user_test() + if (lokasi == None): + lokasi = self.create_lokasi_test() + fasilitas_test = Fasilitas(lokasi=lokasi, + user=user, + deskripsi=deskripsi, + like=like, + dislike=dislike, + rating=rating, + tag=tag, + image=image) + fasilitas_test.save() + return fasilitas_test + + def create_komentar_test(self, deskripsi=default_deskripsi, + user=None, + fasilitas=None): + if (user == None): + user = self.create_user_test() + if (fasilitas == None): + lokasi = self.create_lokasi_test() + fasilitas = self.create_fasilitas_test(user=user, lokasi=lokasi) + komentar_test = Komentar(deskripsi=deskripsi, + user=user, + fasilitas=fasilitas) + komentar_test.save() + return komentar_test + + def create_likes_test(self, user=None, + fasilitas=None): + if (user == None): + user = self.create_user_test() + if (fasilitas == None): + lokasi = self.create_lokasi_test(user) + fasilitas = self.create_fasilitas_test(user=user, lokasi=lokasi) + like_test = Likes(user=user, + fasilitas=fasilitas) + like_test.save() + return like_test + + def create_dislikes_test(self, user=None, + fasilitas=None): + if (user == None): + user = self.create_user_test() + if (fasilitas == None): + lokasi = self.create_lokasi_test(user) + fasilitas = self.create_fasilitas_test(user=user, lokasi=lokasi) + dislike_test = Dislikes(user=user, + fasilitas=fasilitas) + dislike_test.save() + return dislike_test + + def client_user_token(self): + Client().post('/api/register/', self.user_post) + test_user = User.objects.get(username=self.user_post["email"]) + test_user.is_active = True + test_user.save() + token_response = Client().post('/api-token-auth/', {'username': self.user_post["email"], + 'password': self.user_post["password"]}) + content = json.loads(token_response.content.decode('utf-8')) + token = content['token'] + client = Client(HTTP_AUTHORIZATION='token '+token) + return client + + def client_user_token2(self): + Client().post('/api/register/', self.user_post) + test_user = User.objects.get(username=self.default_username_email) + test_user.is_active = True + test_user.save() + token_response = Client().post('/api-token-auth/', {'username': self.default_username_email, + 'password': self.default_password}) + content = json.loads(token_response.content.decode('utf-8')) + token = content['token'] + client = Client(HTTP_AUTHORIZATION='token '+token) + return client + + +class InformasiFasilitasViewTest(InformasiFasilitasTest): + urlpatterns = [ + path('informasi-fasilitas/', include('informasi_fasilitas.urls')), + ] + + def setUp(self): + email = 'usersetup@gmail.com' + password = 'hahagotim' + Client().post('/api/register/', + {'name': 'name', + 'email': email, + 'phone_number': 1000000, + 'password': password}) + test_user = User.objects.get(username=email) + test_user.is_active = True + test_user.save() + token_response = Client().post('/api-token-auth/', + {'username': email, + 'password': password}) + content = json.loads(token_response.content.decode('utf-8')) + token = content['token'] + client = Client(HTTP_AUTHORIZATION='token '+token) + + client.post(reverse('add-lokasi'), + self.lokasi_test_1) diff --git a/informasi_fasilitas/test_models.py b/informasi_fasilitas/test_models.py new file mode 100644 index 0000000000000000000000000000000000000000..df72c8219252e57ca5f9135ff7d7085c2d01ce4d --- /dev/null +++ b/informasi_fasilitas/test_models.py @@ -0,0 +1,80 @@ +import json +import tempfile +from http import HTTPStatus +from django.test import TestCase, Client +from django.db.utils import IntegrityError +from django.contrib.auth.models import User +from django.urls import reverse, path, include + +from .test_base import InformasiFasilitasTest +from .models import Lokasi, Fasilitas, Komentar, Likes, Dislikes +from .serializers import LokasiSerializer + +NOT_NULL_CONSTRAINT_FAILED_MESSAGE = 'NOT NULL constraint failed' + + +class InformasiFasilitasModelTest(InformasiFasilitasTest): + + def test_models_lokasi_not_created(self): + with self.assertRaises(IntegrityError) as err_message: + obj = Lokasi(name=None) + obj.save() + self.assertTrue(str(err_message.exception).startswith( + NOT_NULL_CONSTRAINT_FAILED_MESSAGE)) + + def test_models_create_new_lokasi(self): + self.create_lokasi_test() + count = Lokasi.objects.all().count() + self.assertNotEqual(count, 0) + + def test_models_lokasi_string(self): + lokasi = self.create_lokasi_test() + self.assertEqual(str(lokasi), lokasi.name) + + def test_models_fasilitas_not_created(self): + with self.assertRaises(IntegrityError) as err_message: + obj = Fasilitas(lokasi=None) + obj.save() + self.assertTrue(str(err_message.exception).startswith( + NOT_NULL_CONSTRAINT_FAILED_MESSAGE)) + + def test_models_create_new_fasilitas(self): + self.create_fasilitas_test() + count = Fasilitas.objects.all().count() + self.assertNotEqual(count, 0) + + def test_models_komentar_not_created(self): + with self.assertRaises(IntegrityError) as err_message: + obj = Komentar(fasilitas=None) + obj.save() + self.assertTrue(str(err_message.exception).startswith( + NOT_NULL_CONSTRAINT_FAILED_MESSAGE)) + + def test_models_create_new_komentar(self): + self.create_komentar_test() + count = Komentar.objects.all().count() + self.assertNotEqual(count, 0) + + def test_models_dislikes_not_created(self): + with self.assertRaises(IntegrityError) as err_message: + obj = Dislikes(fasilitas=None) + obj.save() + self.assertTrue(str(err_message.exception).startswith( + NOT_NULL_CONSTRAINT_FAILED_MESSAGE)) + + def test_models_create_new_dislikes(self): + self.create_dislikes_test() + count = Dislikes.objects.all().count() + self.assertNotEqual(count, 0) + + def test_models_likes_not_created(self): + with self.assertRaises(IntegrityError) as err_message: + obj = Likes(fasilitas=None) + obj.save() + self.assertTrue(str(err_message.exception).startswith( + NOT_NULL_CONSTRAINT_FAILED_MESSAGE)) + + def test_models_create_new_likes(self): + self.create_likes_test() + count = Likes.objects.all().count() + self.assertNotEqual(count, 0) diff --git a/informasi_fasilitas/test_views_fasilitas.py b/informasi_fasilitas/test_views_fasilitas.py new file mode 100644 index 0000000000000000000000000000000000000000..b4be413891f0441c7eb33e452584e03646d7f2ee --- /dev/null +++ b/informasi_fasilitas/test_views_fasilitas.py @@ -0,0 +1,137 @@ +import json +import tempfile +import copy +from django.utils.http import urlencode +from http import HTTPStatus +from datetime import datetime +from django.test import TestCase, Client +from django.db.utils import IntegrityError +from django.contrib.auth.models import User +from django.urls import reverse, path, include + +from .test_base import InformasiFasilitasViewTest +from .models import Lokasi, Fasilitas, Komentar, Likes, Dislikes +from .serializers import LokasiSerializer + + +class FasilitasRelatedViewTest(InformasiFasilitasViewTest): + + def test_can_get_list_fasilitas(self): + self.create_fasilitas_test() + response = Client().get( + reverse('list-fasilitas', kwargs={'nama_lokasi': self.default_lokasi_name})) + self.assertEqual(response.status_code, HTTPStatus.OK) + + def test_can_get_list_fasilitas_json(self): + fasilitas = self.create_fasilitas_test() + response = Client().get( + reverse('list-fasilitas', kwargs={'nama_lokasi': self.default_lokasi_name})) + content = json.loads(response.content.decode('utf-8')) + expected_json = {'1': {'id': 1, + 'nama_lokasi': self.default_lokasi_name, + 'deskripsi': self.default_deskripsi, + 'creator': self.default_last_name, + 'like': self.default_like, + 'dislike': self.default_dislike, + 'rating': self.default_rating, + 'tag': ['KR', 'RT'], + 'image': str(fasilitas.image), + 'is_verified': False} + } + + time = fasilitas.date_time.strftime("%d-%m-%Y %H:%M:%S") + expected_json["1"]['date_time'] = time + self.assertEqual(content, expected_json) + + def test_cannot_post_list_fasilitas(self): + response = Client().post( + reverse('list-fasilitas', kwargs={'nama_lokasi': self.lokasi_test_1["name"]})) + self.assertEqual(response.status_code, HTTPStatus.METHOD_NOT_ALLOWED) + + def test_get_list_fasilitas_not_found(self): + response = Client().get( + reverse('list-fasilitas', kwargs={'nama_lokasi': 'Mall'})) + self.assertEqual(response.status_code, HTTPStatus.NOT_FOUND) + + def test_can_get_detail_fasilitas(self): + self.create_fasilitas_test() + response = Client().get(reverse('detail-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1})) + self.assertEqual(response.status_code, HTTPStatus.OK) + + def test_can_get_detail_fasilitas_json(self): + # TODO + self.create_fasilitas_test() + response = Client().get(reverse('detail-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1})) + self.assertEqual(response.status_code, HTTPStatus.OK) + + def test_cannot_post_detail_fasilitas(self): + fasilitas = self.create_fasilitas_test() + response = Client().post(reverse('detail-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': fasilitas.id})) + self.assertEqual(response.status_code, HTTPStatus.METHOD_NOT_ALLOWED) + + def test_get_detail_fasilitas_not_found(self): + response = Client().get(reverse('detail-fasilitas', + kwargs={'nama_lokasi': 'Mall', 'id': 0})) + self.assertEqual(response.status_code, HTTPStatus.NOT_FOUND) + + def test_can_post_add_fasilitas(self): + client = self.client_user_token() + self.create_lokasi_test() + urls = reverse('add-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name}) + response = client.post(urls, {'deskripsi': 'penjelasan fasilitas', + 'rating': 2, + 'tag': 'KR RT'}) + self.assertEqual(response.status_code, HTTPStatus.CREATED) + + def test_cannot_get_add_fasilitas(self): + client = self.client_user_token() + self.create_lokasi_test() + response = client.get( + reverse('add-fasilitas', kwargs={'nama_lokasi': self.default_lokasi_name})) + self.assertEqual(response.status_code, HTTPStatus.METHOD_NOT_ALLOWED) + + def test_post_add_fasilitas_not_found(self): + client = self.client_user_token() + urls = reverse('add-fasilitas', kwargs={'nama_lokasi': 'Mall'}) + response = client.post(urls, {'deskripsi': 'penjelasan fasilitas', + 'rating': 2}) + self.assertEqual(response.status_code, HTTPStatus.NOT_FOUND) + + def test_post_add_fasilitas_cannot_authorized(self): + client = Client() + self.create_lokasi_test() + urls = reverse('add-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name}) + response = client.post(urls, {'deskripsi': 'penjelasan fasilitas', + 'rating': 2, + 'tag': 'KR RT'}) + self.assertEqual(response.status_code, HTTPStatus.UNAUTHORIZED) + + def test_put_update_detail_fasilitas_success(self): + client = self.client_user_token() + self.create_lokasi_test() + urls_post = reverse( + 'add-fasilitas', kwargs={'nama_lokasi': self.default_lokasi_name}) + data_post = {'deskripsi': 'penjelasan fasilitas', + 'rating': 2, + 'tag': 'KR RT'} + response = client.post(urls_post, data=data_post) + + response_json = json.loads(response.content.decode("utf-8")) + fasilitas_id = response_json["id"] + urls_put = reverse('update-fasilitas', + kwargs={'nama_lokasi': 'Mall', "id": fasilitas_id}) + send_data = {'deskripsi': 'penjelasan fasilitases', + 'rating': 3, + 'tag': 'KR'} + response = client.put(urls_put, data=send_data, + content_type="multipart/form-data") + response_json = json.loads(response.content.decode("utf-8")) + self.assertEqual(response.status_code, HTTPStatus.ACCEPTED) diff --git a/informasi_fasilitas/test_views_komentar.py b/informasi_fasilitas/test_views_komentar.py new file mode 100644 index 0000000000000000000000000000000000000000..774b184fe5d1ba97bab1a521dced5976d79d49e0 --- /dev/null +++ b/informasi_fasilitas/test_views_komentar.py @@ -0,0 +1,80 @@ +import json +import tempfile +import copy +from django.utils.http import urlencode +from http import HTTPStatus +from datetime import datetime +from django.test import TestCase, Client +from django.db.utils import IntegrityError +from django.contrib.auth.models import User +from django.urls import reverse, path, include + +from .test_base import InformasiFasilitasViewTest +from .models import Lokasi, Fasilitas, Komentar, Likes, Dislikes +from .serializers import LokasiSerializer + + +class KomentarRelatedViewTest(InformasiFasilitasViewTest): + + def test_can_comment_facility(self): + client = self.client_user_token() + fasilitas = self.create_fasilitas_test() + urls = reverse('add-komentar', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + }) + comment_data = {"deskripsi": "halo saya komen"} + client.post(urls, comment_data) + count = Komentar.objects.filter(fasilitas=fasilitas).count() + self.assertEqual(count, 1) + + def test_can_comment_facility_status_code(self): + client = self.client_user_token() + self.create_fasilitas_test() + urls = reverse('add-komentar', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + }) + comment_data = {"deskripsi": "halo saya komen"} + response = client.post(urls, comment_data) + self.assertEqual(response.status_code, HTTPStatus.CREATED) + + def test_not_comment_facility_empty(self): + client = self.client_user_token() + self.create_fasilitas_test() + urls = reverse('add-komentar', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + }) + comment_data = {} + response = client.post(urls, comment_data) + self.assertEqual(response.status_code, HTTPStatus.BAD_REQUEST) + + def test_not_comment_facility_empty_response(self): + client = self.client_user_token() + self.create_fasilitas_test() + urls = reverse('add-komentar', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + }) + comment_data = {} + response = client.post(urls, comment_data) + response_json = json.loads(response.content.decode('utf-8')) + expected_json = {"response": "Bad Request. 'deskripsi' key is needed"} + self.assertEqual(expected_json, response_json) + + def test_get_list_komentar(self): + client = self.client_user_token() + self.create_fasilitas_test() + urls = reverse('add-komentar', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + }) + comment_data = {"deskripsi": "halo saya komen"} + client.post(urls, comment_data) + urls_get = reverse('list-komentar', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + }) + response = client.get(urls_get) + self.assertEqual(response.status_code, HTTPStatus.OK) diff --git a/informasi_fasilitas/test_views_like_dislike.py b/informasi_fasilitas/test_views_like_dislike.py new file mode 100644 index 0000000000000000000000000000000000000000..567c8ff147735feea947b7aa5f67e3890749a51a --- /dev/null +++ b/informasi_fasilitas/test_views_like_dislike.py @@ -0,0 +1,180 @@ +import json +import tempfile +import copy +from django.utils.http import urlencode +from http import HTTPStatus +from datetime import datetime +from django.test import TestCase, Client +from django.db.utils import IntegrityError +from django.contrib.auth.models import User +from django.urls import reverse, path, include + +from .test_base import InformasiFasilitasViewTest +from .models import Lokasi, Fasilitas, Komentar, Likes, Dislikes +from .serializers import LokasiSerializer + + +class LikeDislikeRelatedViewTest(InformasiFasilitasViewTest): + + def test_can_like_facility(self): + client = self.client_user_token() + fasilitas = self.create_fasilitas_test() + urls = reverse('update-like-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + 'operation': "like" + }) + client.put(urls) + count = Likes.objects.filter(fasilitas=fasilitas).count() + self.assertEqual(count, 1) + + def test_can_like_facility_status_code(self): + client = self.client_user_token() + self.create_fasilitas_test() + urls = reverse('update-like-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + 'operation': "like" + }) + response = client.put(urls) + self.assertEqual(response.status_code, HTTPStatus.CREATED) + + def test_like_like_facility_status_code(self): + client = self.client_user_token() + self.create_fasilitas_test() + urls = reverse('update-like-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + 'operation': "like" + }) + response = client.put(urls) + response = client.put(urls) # like and like + self.assertEqual(response.status_code, HTTPStatus.NOT_ACCEPTABLE) + + def test_like_like_facility_response(self): + client = self.client_user_token() + self.create_fasilitas_test() + urls = reverse('update-like-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + 'operation': "like" + }) + response = client.put(urls) + response = client.put(urls) # like and like + json_response = json.loads(response.content.decode("utf-8")) + expected_json = {"response": "You have already liked this facility"} + self.assertEqual(json_response, expected_json) + + def test_like_like_facility_only_count_one(self): + client = self.client_user_token() + fasilitas = self.create_fasilitas_test() + urls = reverse('update-like-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + 'operation': "like" + }) + client.put(urls) + client.put(urls) # like and like + count = Likes.objects.filter(fasilitas=fasilitas).count() + self.assertEqual(count, 1) + + def test_like_dislike_facility_count_like(self): + client = self.client_user_token() + fasilitas = self.create_fasilitas_test() + urls_like = reverse('update-like-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + 'operation': "like" + }) + urls_dislike = reverse('update-like-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + 'operation': "dislike" + }) + client.put(urls_like) + + client.put(urls_dislike) # like and dislike + count = Likes.objects.filter(fasilitas=fasilitas).count() + self.assertEqual(count, 0) + + def test_can_dislike_facility(self): + client = self.client_user_token() + fasilitas = self.create_fasilitas_test() + urls = reverse('update-like-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + 'operation': "dislike" + }) + client.put(urls) + count = Dislikes.objects.filter(fasilitas=fasilitas).count() + self.assertEqual(count, 1) + + def test_can_dislike_facility_status_code(self): + client = self.client_user_token() + self.create_fasilitas_test() + urls = reverse('update-like-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + 'operation': "dislike" + }) + response = client.put(urls) + self.assertEqual(response.status_code, HTTPStatus.CREATED) + + def test_dislike_dislike_facility_status_code(self): + client = self.client_user_token() + self.create_fasilitas_test() + urls = reverse('update-like-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + 'operation': "dislike" + }) + response = client.put(urls) + response = client.put(urls) # Dislike and dislike + self.assertEqual(response.status_code, HTTPStatus.NOT_ACCEPTABLE) + + def test_dislike_dislike_facility_response(self): + client = self.client_user_token() + self.create_fasilitas_test() + urls = reverse('update-like-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + 'operation': "dislike" + }) + response = client.put(urls) + response = client.put(urls) # Dislike and dislike + json_response = json.loads(response.content.decode("utf-8")) + expected_json = {"response": "You have already disliked this facility"} + self.assertEqual(json_response, expected_json) + + def test_dislike_dislike_facility_only_count_one(self): + client = self.client_user_token() + fasilitas = self.create_fasilitas_test() + urls = reverse('update-like-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + 'operation': "dislike" + }) + client.put(urls) + client.put(urls) # Dislike and dislike + count = Dislikes.objects.filter(fasilitas=fasilitas).count() + self.assertEqual(count, 1) + + def test_dislike_like_facility_count_dislike(self): + client = self.client_user_token() + fasilitas = self.create_fasilitas_test() + urls_like = reverse('update-like-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + 'operation': "like" + }) + urls_dislike = reverse('update-like-fasilitas', + kwargs={'nama_lokasi': self.default_lokasi_name, + 'id': 1, + 'operation': "dislike" + }) + + client.put(urls_dislike) + client.put(urls_like) + + count = Dislikes.objects.filter(fasilitas=fasilitas).count() + self.assertEqual(count, 0) diff --git a/informasi_fasilitas/test_views_lokasi.py b/informasi_fasilitas/test_views_lokasi.py new file mode 100644 index 0000000000000000000000000000000000000000..19e260d3b6112295561f566689682bf029ca0254 --- /dev/null +++ b/informasi_fasilitas/test_views_lokasi.py @@ -0,0 +1,120 @@ +import json +import tempfile +import copy +from django.utils.http import urlencode +from http import HTTPStatus +from django.test import TestCase, Client +from django.db.utils import IntegrityError +from django.contrib.auth.models import User +from django.urls import reverse, path, include +from django.core.files import File + +from .test_base import InformasiFasilitasViewTest +from .models import Lokasi, Fasilitas, Komentar, Likes, Dislikes +from .serializers import LokasiSerializer + + +class LokasiRelatedViewTest(InformasiFasilitasViewTest): + + def test_LokasiSerializer_valid(self): + serializer = LokasiSerializer(data=self.lokasi_test_1) + self.assertTrue(serializer.is_valid) + + def test_amount_lokasi(self): + count = Lokasi.objects.all().count() + self.assertEqual(count, 1) + + def test_can_get_lokasi_list_url(self): + response = Client().get(reverse('lokasi-list')) + self.assertEqual(response.status_code, HTTPStatus.OK) + + def test_get_lokasi_list_json(self): + response = Client().get(reverse('lokasi-list')) + content = json.loads(response.content.decode('utf-8')) + expected_first_entry = copy.deepcopy(self.lokasi_test_1) + expected_first_entry["id"] = 1 + expected_first_entry["image"] = None + expected_json = [expected_first_entry] + self.assertEqual(content, expected_json) + + def test_cannot_post_lokasi_list_url(self): + response = Client().post(reverse('lokasi-list')) + self.assertEqual(response.status_code, HTTPStatus.METHOD_NOT_ALLOWED) + + def test_can_get_lokasi_details(self): + response = Client().get( + reverse('lokasi-details', kwargs={'nama_lokasi': self.lokasi_test_1["name"]})) + self.assertEqual(response.status_code, HTTPStatus.OK) + + def test_can_get_lokasi_details_json(self): + response = Client().get( + reverse('lokasi-details', kwargs={'nama_lokasi': self.lokasi_test_1["name"]})) + content = json.loads(response.content.decode('utf-8')) + expected_json = copy.deepcopy(self.lokasi_test_1) + expected_json["image"] = None + expected_json["id"] = 1 + self.assertEqual(content, expected_json) + + def test_cannot_post_lokasi_details(self): + response = Client().post( + reverse('lokasi-details', kwargs={'nama_lokasi': self.lokasi_test_1["name"]})) + self.assertEqual(response.status_code, HTTPStatus.METHOD_NOT_ALLOWED) + + def test_get_lokasi_details_not_found(self): + response = Client().get( + reverse('lokasi-details', kwargs={'nama_lokasi': 'Mall'})) + self.assertEqual(response.status_code, HTTPStatus.NOT_FOUND) + + def test_cannot_get_add_lokasi(self): + client = self.client_user_token() + response = client.get(reverse('add-lokasi')) + self.assertEqual(response.status_code, HTTPStatus.METHOD_NOT_ALLOWED) + + def test_can_post_add_lokasi(self): + client = self.client_user_token() + response = client.post(reverse('add-lokasi'), self.lokasi_test_1) + self.assertEqual(response.status_code, HTTPStatus.CREATED) + + def test_post_add_lokasi_missing_key(self): + test_lokasi = copy.deepcopy(self.lokasi_test_1) + del test_lokasi["name"] + client = self.client_user_token() + response = client.post(reverse('add-lokasi'), test_lokasi) + self.assertEqual(response.status_code, HTTPStatus.BAD_REQUEST) + + def test_post_add_lokasi_missing_key_return_message(self): + test_lokasi = copy.deepcopy(self.lokasi_test_1) + del test_lokasi["name"] + client = self.client_user_token() + response = client.post(reverse('add-lokasi'), test_lokasi) + response_json = json.loads(response.content.decode('utf-8')) + expected_json = {"name": ["This field is required."]} + self.assertEqual(response_json, expected_json) + + def test_can_post_add_lokasi_json(self): + client = self.client_user_token() + response = client.post(reverse('add-lokasi'), + self.lokasi_test_1) + response_json = json.loads(response.content.decode("utf-8")) + + expected_json = copy.deepcopy(self.lokasi_test_1) + expected_json["id"] = 2 + expected_json["image"] = None + self.assertEqual(response_json, expected_json) + + def test_put_update_detail_lokasi_success(self): + client = self.client_user_token() + urls = reverse('update-lokasi', + kwargs={'nama_lokasi': self.lokasi_test_1["name"]}) + response = client.put(urls, data=urlencode({'no_telp': '0000000121', }), + content_type="application/x-www-form-urlencoded") + self.assertEqual(response.status_code, HTTPStatus.ACCEPTED) + + def test_put_update_detail_lokasi_missing_key(self): + client = self.client_user_token() + + urls = reverse('update-lokasi', + kwargs={'nama_lokasi': self.lokasi_test_1["name"]}) + response = client.put(urls, data={"latitude": 100}, + content_type="multipart/form-data") + self.assertEqual(response.status_code, HTTPStatus.BAD_REQUEST) diff --git a/informasi_fasilitas/tests.py b/informasi_fasilitas/tests.py deleted file mode 100644 index c4cd4a4157d646f5fb51a3938b88b1158cf59f03..0000000000000000000000000000000000000000 --- a/informasi_fasilitas/tests.py +++ /dev/null @@ -1,552 +0,0 @@ -from django.test import TestCase, Client -from django.db.utils import IntegrityError -from .models import Lokasi, Fasilitas, Komentar, KURSI_RODA, RUNNING_TEXT, Likes, Dislikes -from .serializers import LokasiSerializer -from registrasi.models import BisaGoUser -from django.contrib.auth.models import User -from django.urls import reverse, path, include -from http import HTTPStatus -import json -import tempfile - -not_null_constraint_failed_message = 'NOT NULL constraint failed' -user_test = User(username='user@gmail.com', - last_name='name', - email='user@gmail.com', - password='hahagotim' - ) -lokasi_test = Lokasi(name='Mall', - latitude=0.0, - longitude=0.0, - alamat='Jl. Raya Bogor no.1, Jakarta', - no_telp='081212123131', - image= tempfile.NamedTemporaryFile(suffix=".jpg").name - ) - -class InformasiFasilitasModelTest(TestCase): - - def test_models_lokasi_not_created(self): - with self.assertRaises(IntegrityError) as cm: - obj = Lokasi(name=None) - obj.save() - self.assertTrue(str(cm.exception).startswith( - not_null_constraint_failed_message)) - - def test_models_create_new_lokasi(self): - image = tempfile.NamedTemporaryFile(suffix=".jpg").name - Lokasi.objects.create( - name='Mall', - latitude=0.0, - longitude=0.0, - alamat='Jl. Raya Bogor no.1, Jakarta', - no_telp='081212123131', - image=image - ) - count = Lokasi.objects.all().count() - self.assertNotEqual(count, 0) - - def test_models_fasilitas_not_created(self): - with self.assertRaises(IntegrityError) as cm: - obj = Fasilitas(lokasi=None) - obj.save() - self.assertTrue(str(cm.exception).startswith( - not_null_constraint_failed_message)) - - def test_models_create_new_fasilitas(self): - image = tempfile.NamedTemporaryFile(suffix=".jpg").name - user=user_test - user.save() - lokasi=lokasi_test - lokasi.save() - Fasilitas.objects.create( - lokasi=lokasi, - user=user, - deskripsi="penjelasan panjang", - like=0, - dislike=0, - rating=5, - tag={KURSI_RODA, RUNNING_TEXT}, - image=image - ) - count = Fasilitas.objects.all().count() - self.assertNotEqual(count, 0) - - def test_models_komentar_not_created(self): - with self.assertRaises(IntegrityError) as cm: - obj = Komentar(fasilitas=None) - obj.save() - self.assertTrue(str(cm.exception).startswith( - not_null_constraint_failed_message)) - - def test_models_create_new_komentar(self): - image = tempfile.NamedTemporaryFile(suffix=".jpg").name - user=user_test - user.save() - lokasi=lokasi_test - lokasi.save() - fasilitas=Fasilitas( - lokasi=lokasi, - user=user, - deskripsi="penjelasan panjang", - like=0, - dislike=0, - rating=5, - tag={KURSI_RODA, RUNNING_TEXT}, - image=image - ) - fasilitas.save() - Komentar.objects.create( - user=user, - fasilitas=fasilitas, - deskripsi="penjelasan panjang" - ) - count = Komentar.objects.all().count() - self.assertNotEqual(count, 0) - - def test_models_dislikes_not_created(self): - with self.assertRaises(IntegrityError) as cm: - obj = Dislikes(fasilitas=None) - obj.save() - self.assertTrue(str(cm.exception).startswith( - not_null_constraint_failed_message)) - - def test_models_create_new_dislikes(self): - image = tempfile.NamedTemporaryFile(suffix=".jpg").name - user=user_test - user.save() - lokasi=lokasi_test - lokasi.save() - fasilitas=Fasilitas( - lokasi=lokasi, - user=user, - deskripsi="penjelasan panjang", - like=0, - dislike=0, - rating=5, - tag={KURSI_RODA, RUNNING_TEXT}, - image=image - ) - fasilitas.save() - Dislikes.objects.create(user=user, - fasilitas=fasilitas, - ) - count = Dislikes.objects.all().count() - self.assertNotEqual(count, 0) - - def test_models_likes_not_created(self): - with self.assertRaises(IntegrityError) as cm: - obj = Likes(fasilitas=None) - obj.save() - self.assertTrue(str(cm.exception).startswith( - not_null_constraint_failed_message)) - - def test_models_create_new_likes(self): - image = tempfile.NamedTemporaryFile(suffix=".jpg").name - user=user_test - user.save() - lokasi=lokasi_test - lokasi.save() - fasilitas=Fasilitas( - lokasi=lokasi, - user=user, - deskripsi="penjelasan panjang", - like=0, - dislike=0, - rating=5, - tag={KURSI_RODA, RUNNING_TEXT}, - image=image - ) - fasilitas.save() - Likes.objects.create(user=user, - fasilitas=fasilitas, - ) - count = Likes.objects.all().count() - self.assertNotEqual(count, 0) - - -class InformasiFasilitasViewTest(TestCase): - urlpatterns = [ - path('informasi-fasilitas/', include('informasi_fasilitas.urls')), - ] - - def setUp(self): - email='usersetup@gmail.com' - password='hahagotim' - Client().post('/api/register/', - {'name':'name', - 'email':email, - 'phone_number':1000000, - 'password':password}) - token_response = Client().post('/api-token-auth/', - {'username' : email, 'password' : password}) - content = json.loads(token_response.content.decode('utf-8')) - token = content['token'] - client = Client(HTTP_AUTHORIZATION='token '+token) - - client.post(reverse('add-lokasi'), - {'name' : 'Ma Homie', - 'latitude' : 0.1, - 'longitude' : 0.1, - 'alamat' : 'Jl. Raya Bogor no.2, Jakarta', - 'no_telp' : '081212123132'}) - - client.post(reverse('add-lokasi'), - {'name' : 'Ma Homies', - 'latitude' : 0.2, - 'longitude' : 0.1, - 'alamat' : 'Jl. Raya Bogor no.3, Jakarta', - 'no_telp' : '081212123134'}) - - client.post(reverse('add-fasilitas', kwargs={"nama_lokasi":"Ma Homie"}), - {'deskripsi' : 'kayaknya deskrispi', - 'rating' : 3, - 'tag' : "KR RT", - 'image' : 'gambar.jpg', - }) - - -class LokasiRelatedViewTest(InformasiFasilitasViewTest): - - def test_LokasiSerializer_valid(self): - serializer = LokasiSerializer(data = { - 'name' : 'Mall1', - 'latitude' : 0.0, - 'longitude' : 0.0, - 'alamat' : 'Jl. Raya Bogor no.1, Jakarta', - 'no_telp' : '081212123131' - }) - self.assertTrue(serializer.is_valid) - - def test_can_get_lokasi_list_url(self): - response = Client().get(reverse('lokasi-list')) - self.assertEqual(response.status_code, HTTPStatus.OK) - - def test_get_lokasi_list_json(self): - response = Client().get(reverse('lokasi-list')) - content = json.loads(response.content.decode('utf-8')) - expected_json = [{'id': 1, - 'name':'Ma Homie', - 'latitude' : 0.1, - 'longitude' : 0.1, - 'alamat' : 'Jl. Raya Bogor no.2, Jakarta', - 'no_telp' : '081212123132', - 'image':None}, - {'id': 2, - 'name':'Ma Homies', - 'latitude' : 0.2, - 'longitude' : 0.1, - 'alamat' : 'Jl. Raya Bogor no.3, Jakarta', - 'no_telp' : '081212123134', - 'image':None} - ] - self.assertEqual(content, expected_json) - - def test_cannot_post_lokasi_list_url(self): - response = Client().post(reverse('lokasi-list')) - self.assertEqual(response.status_code, HTTPStatus.METHOD_NOT_ALLOWED) - - def test_can_get_lokasi_details(self): - lokasi=lokasi_test - lokasi.save() - response = Client().get(reverse('lokasi-details', kwargs={'nama_lokasi':'Mall'})) - self.assertEqual(response.status_code, HTTPStatus.OK) - - def test_can_get_lokasi_details_json(self): - response = Client().get(reverse('lokasi-details', kwargs={'nama_lokasi':'Ma Homie'})) - content = json.loads(response.content.decode('utf-8')) - expected_json = {'id': 1, - 'name':'Ma Homie', - 'latitude' : 0.1, - 'longitude' : 0.1, - 'alamat' : 'Jl. Raya Bogor no.2, Jakarta', - 'no_telp' : '081212123132', - 'image':None} - self.assertEqual(content, expected_json) - - def test_cannot_post_lokasi_details(self): - lokasi=lokasi_test - lokasi.save() - response = Client().post(reverse('lokasi-details', kwargs={'nama_lokasi':'Mall'})) - self.assertEqual(response.status_code, HTTPStatus.METHOD_NOT_ALLOWED) - - def test_get_lokasi_details_not_found(self): - response = Client().get(reverse('lokasi-details', kwargs={'nama_lokasi':'Mall'})) - self.assertEqual(response.status_code, HTTPStatus.NOT_FOUND) - - def test_can_post_add_lokasi(self): - email='user@gmail.com' - password='hahagotim' - Client().post('/api/register/', - {'name':'name', - 'email':email, - 'phone_number':000000000, - 'password':password}) - token_response = Client().post('/api-token-auth/', - {'username' : email, 'password' : password}) - content = json.loads(token_response.content.decode('utf-8')) - token = content['token'] - client = Client(HTTP_AUTHORIZATION='token '+token) - - response = client.post(reverse('add-lokasi'), - {'name' : 'Mall', - 'latitude' : 0.0, - 'longitude' : 0.0, - 'alamat' : 'Jl. Raya Bogor no.1, Jakarta', - 'no_telp' : '081212123131'}) - self.assertEqual(response.status_code, HTTPStatus.CREATED) - - def test_can_post_add_json(self): - email='user@gmail.com' - password='hahagotim' - Client().post('/api/register/', - {'name':'name', - 'email':email, - 'phone_number':000000000, - 'password':password}) - token_response = Client().post('/api-token-auth/', - {'username' : email, 'password' : password}) - content = json.loads(token_response.content.decode('utf-8')) - token = content['token'] - client = Client(HTTP_AUTHORIZATION='token '+token) - - response = client.post(reverse('add-lokasi'), - {'name' : 'Mall', - 'latitude' : 0.0, - 'longitude' : 0.0, - 'alamat' : 'Jl. Raya Bogor no.1, Jakarta', - 'no_telp' : '081212123131'}) - response_json = json.loads(response.content.decode("utf-8")) - - expected_json = { - "id": 3, - 'name' : 'Mall', - 'latitude' : 0.0, - 'longitude' : 0.0, - 'alamat' : 'Jl. Raya Bogor no.1, Jakarta', - 'no_telp' : '081212123131', - "image" : None - } - - self.assertEqual(response_json, expected_json) - - def test_put_update_detail_lokasi_success(self): - email='user@gmail.com' - password='hahagotim' - Client().post('/api/register/', - {'name':'name', - 'email':email, - 'phone_number':000000000, - 'password':password}) - token_response = Client().post('/api-token-auth/', - {'username' : email, 'password' : password}) - content = json.loads(token_response.content.decode('utf-8')) - token = content['token'] - client = Client(HTTP_AUTHORIZATION='token '+token) - - lokasi=lokasi_test - lokasi.save() - - response = client.put(reverse('update-lokasi', kwargs={'nama_lokasi':'Mall'}), - data={'no_telp' : '0000000121',}, - content_type="multipart/form-data") - self.assertEqual(response.status_code, HTTPStatus.ACCEPTED) - - - def test_cannot_get_add_lokasi(self): - email='user@gmail.com' - password='hahagotim' - Client().post('/api/register/', - {'name':'name', - 'email':email, - 'phone_number':000000000, - 'password':password}) - token_response = Client().post('/api-token-auth/', - {'username' : email, 'password' : password}) - content = json.loads(token_response.content.decode('utf-8')) - token = content['token'] - client = Client(HTTP_AUTHORIZATION='token '+token) - - response = client.get(reverse('add-lokasi')) - self.assertEqual(response.status_code, HTTPStatus.METHOD_NOT_ALLOWED) - -class FasilitasRelatedViewTest(InformasiFasilitasViewTest): - - def test_can_get_list_fasilitas(self): - image = tempfile.NamedTemporaryFile(suffix=".jpg").name - user=user_test - user.save() - lokasi=lokasi_test - lokasi.save() - fasilitas=Fasilitas( - lokasi=lokasi, - user=user, - deskripsi="penjelasan panjang", - like=0, - dislike=0, - rating=5, - tag={KURSI_RODA, RUNNING_TEXT}, - image=image - ) - fasilitas.save() - response = Client().get(reverse('list-fasilitas', kwargs={'nama_lokasi':'Mall'})) - self.assertEqual(response.status_code, HTTPStatus.OK) - - def test_cannot_post_list_fasilitas(self): - image = tempfile.NamedTemporaryFile(suffix=".jpg").name - lokasi=Lokasi( - name='Mall', - latitude=0.0, - longitude=0.0, - alamat='Jl. Raya Bogor no.1, Jakarta', - no_telp='081212123131', - image=image - ) - lokasi.save() - response = Client().post(reverse('list-fasilitas', kwargs={'nama_lokasi':'Mall'})) - self.assertEqual(response.status_code, 405) - - def test_get_list_fasilitas_not_found(self): - response = Client().get(reverse('list-fasilitas', kwargs={'nama_lokasi':'Mall'})) - self.assertEqual(response.status_code, 404) - - def test_can_get_detail_fasilitas(self): - image = tempfile.NamedTemporaryFile(suffix=".jpg").name - user=user_test - user.save() - lokasi=lokasi_test - lokasi.save() - fasilitas=Fasilitas( - lokasi=lokasi, - user=user, - deskripsi="penjelasan panjang", - like=0, - dislike=0, - rating=5, - tag={KURSI_RODA, RUNNING_TEXT}, - image=image - ) - fasilitas.save() - id = fasilitas.id - response = Client().get(reverse('detail-fasilitas', kwargs={'nama_lokasi':'Mall', 'id':id})) - self.assertEqual(response.status_code, 200) - - def test_cannot_post_detail_fasilitas(self): - image = tempfile.NamedTemporaryFile(suffix=".jpg").name - user=user_test - user.save() - lokasi=lokasi_test - lokasi.save() - fasilitas=Fasilitas( - lokasi=lokasi, - user=user, - deskripsi="penjelasan panjang", - like=0, - dislike=0, - rating=5, - tag={KURSI_RODA, RUNNING_TEXT}, - image=image - ) - fasilitas.save() - id = fasilitas.id - response = Client().post(reverse('detail-fasilitas', kwargs={'nama_lokasi':'Mall', 'id':id})) - self.assertEqual(response.status_code, 405) - - def test_get_detail_fasilitas_not_found(self): - response = Client().get(reverse('detail-fasilitas', kwargs={'nama_lokasi':'Mall', 'id':0})) - self.assertEqual(response.status_code, 404) - - def test_can_post_add_fasilitas(self): - email='user@gmail.com' - password='hahagotim' - Client().post('/api/register/', - {'name':'name', - 'email':email, - 'phone_number':000000000, - 'password':password}) - token_response = Client().post('/api-token-auth/', - {'username' : email, 'password' : password}) - content = json.loads(token_response.content.decode('utf-8')) - token = content['token'] - client = Client(HTTP_AUTHORIZATION='token '+token) - - lokasi=lokasi_test - lokasi.save() - - response = client.post(reverse('add-fasilitas', kwargs={'nama_lokasi':'Mall'}), - {'deskripsi' : 'penjelasan fasilitas', - 'rating' : 2, - 'tag' : 'KR RT'}) - self.assertEqual(response.status_code, 201) - - def test_cannot_get_add_fasilitas(self): - email='user@gmail.com' - password='hahagotim' - Client().post('/api/register/', - {'name':'name', - 'email':email, - 'phone_number':000000000, - 'password':password}) - token_response = Client().post('/api-token-auth/', - {'username' : email, 'password' : password}) - content = json.loads(token_response.content.decode('utf-8')) - token = content['token'] - client = Client(HTTP_AUTHORIZATION='token '+token) - - lokasi=lokasi_test - lokasi.save() - - response = client.get(reverse('add-fasilitas', kwargs={'nama_lokasi':'Mall'})) - self.assertEqual(response.status_code, 405) - - def test_post_add_fasilitas_not_found(self): - email='user@gmail.com' - password='hahagotim' - Client().post('/api/register/', - {'name':'name', - 'email':email, - 'phone_number':000000000, - 'password':password}) - token_response = Client().post('/api-token-auth/', - {'username' : email, 'password' : password}) - content = json.loads(token_response.content.decode('utf-8')) - token = content['token'] - client = Client(HTTP_AUTHORIZATION='token '+token) - - response = client.post(reverse('add-fasilitas', kwargs={'nama_lokasi':'Mall'}), - {'deskripsi' : 'penjelasan fasilitas', - 'rating' : 2}) - self.assertEqual(response.status_code, HTTPStatus.NOT_FOUND) - - def test_put_update_detail_fasilitas_success(self): - email='user@gmail.com' - password='hahagotim' - Client().post('/api/register/', - {'name':'name', - 'email':email, - 'phone_number':000000000, - 'password':password}) - token_response = Client().post('/api-token-auth/', - {'username' : email, 'password' : password}) - content = json.loads(token_response.content.decode('utf-8')) - token = content['token'] - client = Client(HTTP_AUTHORIZATION='token '+token) - - lokasi=lokasi_test - lokasi.save() - - response = client.post(reverse('add-fasilitas', kwargs={'nama_lokasi':'Mall'}), - {'deskripsi' : 'penjelasan fasilitas', - 'rating' : 2, - 'tag' : 'KR RT'}) - - response_json = json.loads(response.content.decode("utf-8")) - fasilitas_id = response_json["id"] - response = client.put(reverse('update-fasilitas', kwargs={'nama_lokasi':'Mall',"id":fasilitas_id}), - data={'deskripsi' : 'penjelasan fasilitases', - 'rating' : 3, - 'tag' : 'KR'}, content_type="multipart/form-data") - response_json = json.loads(response.content.decode("utf-8")) - self.assertEqual(response.status_code, HTTPStatus.ACCEPTED) - - - \ No newline at end of file diff --git a/informasi_fasilitas/urls.py b/informasi_fasilitas/urls.py index c8995c5b5d289856ce78bb6f5bada4c1ce444853..4a7949045b198b23998b38547e8529a4e575dd76 100644 --- a/informasi_fasilitas/urls.py +++ b/informasi_fasilitas/urls.py @@ -1,19 +1,35 @@ -from django.urls import path, include -from rest_framework import routers +from django.urls import path from . import views urlpatterns = [ - path('lokasi/list/', views.lokasi_list,name='lokasi-list'), - path('lokasi/detail//', views.lokasi_details,name='lokasi-details'), - path('lokasi/update-detail//', views.update_lokasi_details,name='update-lokasi'), - path('lokasi/add/', views.add_lokasi,name='add-lokasi'), - path('lokasi/add-fasilitas//', views.add_fasilitas, name='add-fasilitas'), - path('lokasi/list-fasilitas//', views.list_fasilitas, name='list-fasilitas'), - path('lokasi/detail-fasilitas///', views.detail_fasilitas, name='detail-fasilitas'), - path('lokasi/add-komentar//', views.add_komentar, name='add-komentar'), - path('lokasi/list-komentar///', views.list_komentar, name='list-komentar'), - path('lokasi/update-fasilitas///', views.update_fasilitas, name='update-fasilitas'), - path('lokasi/like-fasilitas////', views.update_like_fasilitas, name='update-like-fasilitas'), - path('lokasi/add-komentar///', views.add_komentar, name='add-komentar'), - path('lokasi/list-komentar///', views.list_komentar, name='list-komentar'), -] \ No newline at end of file + path('lokasi/list/', views.lokasi_list, name='lokasi-list'), + + path('lokasi/detail//', + views.lokasi_details, name='lokasi-details'), + + path('lokasi/update-detail//', + views.update_lokasi_details, name='update-lokasi'), + + path('lokasi/add/', views.add_lokasi, name='add-lokasi'), + + path('lokasi/add-fasilitas//', + views.add_fasilitas, name='add-fasilitas'), + + path('lokasi/list-fasilitas//', + views.list_fasilitas, name='list-fasilitas'), + + path('lokasi/detail-fasilitas///', + views.detail_fasilitas, name='detail-fasilitas'), + + path('lokasi/add-komentar///', + views.add_komentar, name='add-komentar'), + + path('lokasi/list-komentar///', + views.list_komentar, name='list-komentar'), + + path('lokasi/update-fasilitas///', + views.update_fasilitas, name='update-fasilitas'), + + path('lokasi/like-fasilitas////', + views.update_like_fasilitas, name='update-like-fasilitas'), +] diff --git a/informasi_fasilitas/views.py b/informasi_fasilitas/views.py index aa0f32fa9b734432b336bb8f0ada7273b30bc225..bf454de74b2a8be38054cd6e8e63c766da909194 100644 --- a/informasi_fasilitas/views.py +++ b/informasi_fasilitas/views.py @@ -1,21 +1,22 @@ -from django.shortcuts import render -from django.http import HttpResponse, JsonResponse +from http import HTTPStatus +from datetime import datetime +from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt from django.contrib.auth.models import User +from django.core.exceptions import ObjectDoesNotExist from rest_framework import viewsets from rest_framework.decorators import api_view, permission_classes, authentication_classes from rest_framework.authentication import TokenAuthentication -from rest_framework.permissions import IsAuthenticated +from rest_framework.permissions import IsAuthenticated from .serializers import LokasiSerializer from .models import Lokasi, Fasilitas, Komentar, Likes, Dislikes -def request_error_message(request_kind): - return "get {} request instead".format(request_kind) def missing_key_message(key): - return "bad request. {} key needed".format(key) + return "Bad Request. {} key is needed".format(key) + @csrf_exempt @api_view(['GET']) @@ -25,25 +26,21 @@ def lokasi_list(request): if request.method == 'GET': lokasi_list = Lokasi.objects.all() serializer = LokasiSerializer(lokasi_list, many=True) - return JsonResponse(serializer.data, safe=False, status = 200) - else: - return JsonResponse({'response' : request_error_message("get")}, status = 400) + return JsonResponse(serializer.data, safe=False, status=HTTPStatus.OK) + @api_view(['GET']) @authentication_classes([]) @permission_classes([]) -def lokasi_details(request,nama_lokasi): +def lokasi_details(request, nama_lokasi): try: if request.method == 'GET': - lokasi = Lokasi.objects.get(name = nama_lokasi) + lokasi = Lokasi.objects.get(name=nama_lokasi) serializer = LokasiSerializer(lokasi) - return JsonResponse(serializer.data, safe=False, status = 200) - else: - return JsonResponse({'response' : request_error_message("get")}, status = 400) - except KeyError as e: - return JsonResponse({'response': missing_key_message(str(e))}, status = 500) - except: - return JsonResponse({'response':'lokasi not found'}, status = 404) + return JsonResponse(serializer.data, safe=False, status=HTTPStatus.OK) + except ObjectDoesNotExist as err: + return JsonResponse({'response': str(err)}, status=HTTPStatus.NOT_FOUND) + @api_view(['POST']) @authentication_classes([TokenAuthentication]) @@ -51,18 +48,16 @@ def lokasi_details(request,nama_lokasi): def add_lokasi(request): try: if request.method == 'POST': - data = request.POST serializer = LokasiSerializer(data=data) if serializer.is_valid(): serializer.save() - return JsonResponse(serializer.data, status=201) + return JsonResponse(serializer.data, status=HTTPStatus.CREATED) else: - return JsonResponse(serializer.errors, status=400) - else: - return JsonResponse({'response' : request_error_message("post")}, status = 400) - except KeyError as e: - return JsonResponse({'response': missing_key_message(str(e))}, status = 500) + return JsonResponse(serializer.errors, status=HTTPStatus.BAD_REQUEST) + except Exception as err: + return JsonResponse({'response': str(err)}, status=HTTPStatus.NOT_FOUND) + @api_view(['PUT']) @authentication_classes([TokenAuthentication]) @@ -70,15 +65,14 @@ def add_lokasi(request): def update_lokasi_details(request, nama_lokasi): try: if request.method == 'PUT': - lokasi = Lokasi.objects.get(name = nama_lokasi) - if 'no_telp' in request.data.keys(): - lokasi.no_telp = request.data['no_telp'] + lokasi = Lokasi.objects.get(name=nama_lokasi) + lokasi.no_telp = request.data['no_telp'] lokasi.save() - return JsonResponse({'response' : "phone changed to {}".format(lokasi.no_telp)}, status = 202) - else: - return JsonResponse({'response' : request_error_message("put")}, status = 400) - except KeyError as e: - return JsonResponse({'response': missing_key_message(str(e))}, status = 500) + return JsonResponse({'response': "phone changed to {}".format(lokasi.no_telp)}, + status=HTTPStatus.ACCEPTED) + except KeyError as missing_key: + return JsonResponse({'response': missing_key_message(str(missing_key))}, + status=HTTPStatus.BAD_REQUEST) @api_view(['GET']) @@ -87,28 +81,32 @@ def update_lokasi_details(request, nama_lokasi): def list_fasilitas(request, nama_lokasi): try: if request.method == 'GET': - lokasi = Lokasi.objects.get(name = nama_lokasi) + lokasi = Lokasi.objects.get(name=nama_lokasi) list_fasilitas = Fasilitas.objects.filter(lokasi=lokasi) return_json = {} for fasilitas in list_fasilitas: + fasilitas.like = Likes.objects.filter( + fasilitas=fasilitas).count() + fasilitas.dislike = Dislikes.objects.filter( + fasilitas=fasilitas).count() return_json[fasilitas.id] = {} fasilitas_details = return_json[fasilitas.id] fasilitas_details["id"] = fasilitas.id fasilitas_details["nama_lokasi"] = fasilitas.lokasi.name fasilitas_details["deskripsi"] = fasilitas.deskripsi fasilitas_details["creator"] = fasilitas.user.last_name - fasilitas_details["date_time"] = fasilitas.date_time + fasilitas_details["date_time"] = fasilitas.date_time.strftime( + "%d-%m-%Y %H:%M:%S") fasilitas_details["like"] = fasilitas.like fasilitas_details["dislike"] = fasilitas.dislike fasilitas_details["rating"] = fasilitas.rating fasilitas_details["tag"] = fasilitas.tag fasilitas_details["image"] = str(fasilitas.image) fasilitas_details["is_verified"] = fasilitas.is_verified - return JsonResponse(return_json, status = 200) - except KeyError as e: - return JsonResponse({'response': missing_key_message(str(e))}, status = 500) - except Exception as e: - return JsonResponse({'response': str(e)}, status = 404) + return JsonResponse(return_json, status=HTTPStatus.OK) + except Exception as error: + return JsonResponse({'response': str(error)}, status=HTTPStatus.NOT_FOUND) + @api_view(['POST']) @authentication_classes([TokenAuthentication]) @@ -125,18 +123,19 @@ def add_fasilitas(request, nama_lokasi): if 'image' in request.POST.keys(): image = str(request.POST['image']) fasilitas = Fasilitas.objects.create(lokasi=lokasi, - user=user, - deskripsi=deskripsi, - rating=rating, - tag=tag, - image = image) - return JsonResponse({'response' : 'fasilitas added', 'id':fasilitas.id}, status = 201) - else: - return JsonResponse({'response' : request_error_message("post")}, status = 400) - except KeyError as e: - return JsonResponse({'response': missing_key_message(str(e))}, status = 500) - except Exception as e: - return JsonResponse({'response': str(e)}, status = 404) + user=user, + deskripsi=deskripsi, + rating=rating, + tag=tag, + image=image) + return JsonResponse({'response': 'fasilitas added', 'id': fasilitas.id}, + status=HTTPStatus.CREATED) + except KeyError as missing_key: + return JsonResponse({'response': missing_key_message(str(missing_key))}, + status=HTTPStatus.BAD_REQUEST) + except Exception as error: + return JsonResponse({'response': str(error)}, status=HTTPStatus.NOT_FOUND) + @api_view(['GET']) @authentication_classes([]) @@ -144,29 +143,30 @@ def add_fasilitas(request, nama_lokasi): def detail_fasilitas(request, nama_lokasi, id): try: if request.method == 'GET': - lokasi = Lokasi.objects.get(name = nama_lokasi) + lokasi = Lokasi.objects.get(name=nama_lokasi) fasilitas = Fasilitas.objects.get(lokasi=lokasi, id=id) user = fasilitas.user - fasilitas.like = Likes.objects.filter(fasilitas = fasilitas).count() - fasilitas.dislike = Dislikes.objects.filter(fasilitas = fasilitas).count() - return_json = {"nama_lokasi": lokasi.name, - "deskripsi":fasilitas.deskripsi, - "creator":user.last_name, - "creator_email": user.email, - "date_time":fasilitas.date_time, - "like":fasilitas.like, - "dislike":fasilitas.dislike, - "rating":fasilitas.rating, - "tag":fasilitas.tag, - "image":str(fasilitas.image), - "is_verified":fasilitas.is_verified} - return JsonResponse(return_json, status = 200) - else: - return JsonResponse({'response' : request_error_message("get")}, status = 400) - except KeyError as e: - return JsonResponse({'response': missing_key_message(str(e))}, status = 500) - except Exception as e: - return JsonResponse({'response': str(e)}, status = 404) + fasilitas.like = Likes.objects.filter(fasilitas=fasilitas).count() + fasilitas.dislike = Dislikes.objects.filter( + fasilitas=fasilitas).count() + return_json = {"nama_lokasi": lokasi.name, + "deskripsi": fasilitas.deskripsi, + "creator": user.last_name, + "creator_email": user.email, + "date_time": fasilitas.date_time, + "like": fasilitas.like, + "dislike": fasilitas.dislike, + "rating": fasilitas.rating, + "tag": fasilitas.tag, + "image": str(fasilitas.image), + "is_verified": fasilitas.is_verified} + return JsonResponse(return_json, status=HTTPStatus.OK) + except KeyError as missing_key: + return JsonResponse({'response': missing_key_message(str(missing_key))}, + status=HTTPStatus.BAD_REQUEST) + except Exception as error: + return JsonResponse({'response': str(error)}, status=HTTPStatus.NOT_FOUND) + @api_view(['PUT']) @authentication_classes([TokenAuthentication]) @@ -174,7 +174,7 @@ def detail_fasilitas(request, nama_lokasi, id): def update_fasilitas(request, nama_lokasi, id): try: if request.method == "PUT": - lokasi = Lokasi.objects.get(name = nama_lokasi) + lokasi = Lokasi.objects.get(name=nama_lokasi) fasilitas = Fasilitas.objects.get(lokasi=lokasi, id=id) user_creator = fasilitas.user desc = fasilitas.deskripsi @@ -187,12 +187,16 @@ def update_fasilitas(request, nama_lokasi, id): fasilitas.deskripsi = desc fasilitas.tag = tag fasilitas.save() - return JsonResponse({'response' : '{} in fasilitas edited'.format(str(request.data.keys())), }, status = 202) - return JsonResponse({'response' : 'Authentication failed'}, status = 502) - except KeyError as e: - return JsonResponse({'response': missing_key_message(str(e))}, status = 500) - except Exception as e: - return JsonResponse({'response': str(e)}, status = 404) + return JsonResponse({'response': '{} in fasilitas edited'.format(str(request.data.keys())), }, + status=HTTPStatus.ACCEPTED) + return JsonResponse({'response': 'Authentication failed'}, + status=HTTPStatus.UNAUTHORIZED) + except KeyError as missing_key: + return JsonResponse({'response': missing_key_message(str(missing_key))}, + status=HTTPStatus.BAD_REQUEST) + except Exception as error: + return JsonResponse({'response': str(error)}, status=HTTPStatus.NOT_FOUND) + @api_view(['PUT']) @authentication_classes([TokenAuthentication]) @@ -200,41 +204,41 @@ def update_fasilitas(request, nama_lokasi, id): def update_like_fasilitas(request, nama_lokasi, id, operation): try: if request.method == "PUT": - lokasi = Lokasi.objects.get(name = nama_lokasi) + lokasi = Lokasi.objects.get(name=nama_lokasi) fasilitas = Fasilitas.objects.get(lokasi=lokasi, id=id) user = request.user try: - like = Likes.objects.get(fasilitas=fasilitas, user = user) + like = Likes.objects.get(fasilitas=fasilitas, user=user) except Likes.DoesNotExist: like = None try: - dislike = Dislikes.objects.get(fasilitas=fasilitas, user = user) + dislike = Dislikes.objects.get(fasilitas=fasilitas, user=user) except Dislikes.DoesNotExist: dislike = None - if operation == "like": if like != None: - return JsonResponse({'response': "you've already liked this facility"}) + return JsonResponse({'response': "You have already liked this facility"}, status=HTTPStatus.NOT_ACCEPTABLE) else: - Likes.objects.create(fasilitas = fasilitas, user = user) + Likes.objects.create(fasilitas=fasilitas, user=user) if dislike != None: dislike.delete() elif operation == "dislike": if dislike != None: - return JsonResponse({'response': "you've already disliked this facility"}) + return JsonResponse({'response': "You have already disliked this facility"}, status=HTTPStatus.NOT_ACCEPTABLE) else: - Dislikes.objects.create(fasilitas = fasilitas, user = user) + Dislikes.objects.create(fasilitas=fasilitas, user=user) if like != None: like.delete() - - fasilitas.like = Likes.objects.filter(fasilitas = fasilitas).count() - fasilitas.dislike = Dislikes.objects.filter(fasilitas = fasilitas).count() - return JsonResponse({'response': "you've successfuly {}d this facility".format(operation)}, status = 201) - except KeyError as e: - return JsonResponse({'response': missing_key_message(str(e))}, status = 500) - except Exception as e: - return JsonResponse({'response': str(e)}, status = 404) + fasilitas.like = Likes.objects.filter(fasilitas=fasilitas).count() + fasilitas.dislike = Dislikes.objects.filter( + fasilitas=fasilitas).count() + return JsonResponse({'response': "You have successfuly {}d this facility".format(operation)}, status=HTTPStatus.CREATED) + except KeyError as missing_key: + return JsonResponse({'response': missing_key_message(str(missing_key))}, status=HTTPStatus.BAD_REQUEST) + except Exception as error: + return JsonResponse({'response': str(error)}, status=HTTPStatus.NOT_FOUND) + @api_view(['POST']) @authentication_classes([TokenAuthentication]) @@ -242,20 +246,18 @@ def update_like_fasilitas(request, nama_lokasi, id, operation): def add_komentar(request, nama_lokasi, id): try: if request.method == 'POST': - lokasi = Lokasi.objects.get(name = nama_lokasi) + lokasi = Lokasi.objects.get(name=nama_lokasi) fasilitas = Fasilitas.objects.get(lokasi=lokasi, id=id) user = User.objects.get(email=str(request.user)) deskripsi = request.POST['deskripsi'] komentar = Komentar.objects.create(fasilitas=fasilitas, - user=user, - deskripsi=deskripsi) - return JsonResponse({'response' : 'komentar added', 'id':komentar.id}, status = 201) - else: - return JsonResponse({'response' : request_error_message("post")}, status = 400) + user=user, + deskripsi=deskripsi) + return JsonResponse({'response': 'komentar added', 'id': komentar.id}, status=HTTPStatus.CREATED) except KeyError as e: - return JsonResponse({'response': missing_key_message(str(e))}, status = 500) + return JsonResponse({'response': missing_key_message(str(e))}, status=HTTPStatus.BAD_REQUEST) except Exception as e: - return JsonResponse({'response': str(e)}, status = 404) + return JsonResponse({'response': str(e)}, status=HTTPStatus.NOT_FOUND) @api_view(['GET']) @@ -275,8 +277,8 @@ def list_komentar(request, nama_lokasi, id): komentar_details["deskripsi"] = komentar.deskripsi komentar_details["creator"] = komentar.user.last_name komentar_details["date_time"] = komentar.date_time - return JsonResponse(return_json, status = 200) + return JsonResponse(return_json, status=200) except KeyError as e: - return JsonResponse({'response': missing_key_message(str(e))}, status = 500) + return JsonResponse({'response': missing_key_message(str(e))}, status=500) except Exception as e: - return JsonResponse({'response': str(e)}, status = 404) \ No newline at end of file + return JsonResponse({'response': str(e)}, status=404) diff --git a/layanan_khusus/admin.py b/layanan_khusus/admin.py index 15bf57aeb2f4c5058ad74c910a193dd9b2a9862d..2e3a9d4ecc666bf33955e72b6a13fc3508901cba 100644 --- a/layanan_khusus/admin.py +++ b/layanan_khusus/admin.py @@ -1,6 +1,5 @@ from django.contrib import admin -from .models import Sekolah, Penyandang +from .models import Sekolah # Register your models here. admin.site.register(Sekolah) -admin.site.register(Penyandang) diff --git a/layanan_khusus/migrations/0012_auto_20200503_1113.py b/layanan_khusus/migrations/0012_auto_20200505_0314.py similarity index 60% rename from layanan_khusus/migrations/0012_auto_20200503_1113.py rename to layanan_khusus/migrations/0012_auto_20200505_0314.py index c2864ff0ffacdd69b11a64317f5a77a496563a8c..778bd2182f90b4ab4928ea8d3d9450ec8508f371 100644 --- a/layanan_khusus/migrations/0012_auto_20200503_1113.py +++ b/layanan_khusus/migrations/0012_auto_20200505_0314.py @@ -1,4 +1,4 @@ -# Generated by Django 2.1.5 on 2020-05-03 04:13 +# Generated by Django 2.1.5 on 2020-05-04 20:14 from django.db import migrations, models @@ -10,12 +10,6 @@ class Migration(migrations.Migration): ] operations = [ - migrations.CreateModel( - name='Penyandang', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ], - ), migrations.AlterField( model_name='sekolah', name='jenis_sekolah', diff --git a/layanan_khusus/migrations/0013_auto_20200503_1134.py b/layanan_khusus/migrations/0013_auto_20200503_1134.py deleted file mode 100644 index 533ba8e653c11e6795d6595173de80f453c87da9..0000000000000000000000000000000000000000 --- a/layanan_khusus/migrations/0013_auto_20200503_1134.py +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by Django 2.1.5 on 2020-05-03 04:34 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('layanan_khusus', '0012_auto_20200503_1113'), - ] - - operations = [ - migrations.AddField( - model_name='penyandang', - name='alamat', - field=models.CharField(default='empty', max_length=100), - preserve_default=False, - ), - migrations.AddField( - model_name='penyandang', - name='name', - field=models.CharField(default='empty', max_length=50), - preserve_default=False, - ), - migrations.AddField( - model_name='penyandang', - name='no_telp', - field=models.CharField(default='empty', max_length=16), - preserve_default=False, - ), - ] diff --git a/layanan_khusus/migrations/0014_auto_20200503_2044.py b/layanan_khusus/migrations/0014_auto_20200503_2044.py deleted file mode 100644 index accd03fead3c1435bc4de8037ab636872f9d3638..0000000000000000000000000000000000000000 --- a/layanan_khusus/migrations/0014_auto_20200503_2044.py +++ /dev/null @@ -1,26 +0,0 @@ -# Generated by Django 2.1.5 on 2020-05-03 13:44 - -from django.db import migrations, models -import django.utils.timezone - - -class Migration(migrations.Migration): - - dependencies = [ - ('layanan_khusus', '0013_auto_20200503_1134'), - ] - - operations = [ - migrations.AddField( - model_name='penyandang', - name='tanggal_lahir', - field=models.DateField(default=django.utils.timezone.now), - preserve_default=False, - ), - migrations.AddField( - model_name='penyandang', - name='tempat_lahir', - field=models.CharField(default='empty', max_length=50), - preserve_default=False, - ), - ] diff --git a/layanan_khusus/migrations/0015_auto_20200504_0116.py b/layanan_khusus/migrations/0015_auto_20200504_0116.py deleted file mode 100644 index c70aed7fb3dc0cd53e3f21b2dfdbb6affc3f0d33..0000000000000000000000000000000000000000 --- a/layanan_khusus/migrations/0015_auto_20200504_0116.py +++ /dev/null @@ -1,28 +0,0 @@ -# Generated by Django 2.1.5 on 2020-05-03 18:16 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('layanan_khusus', '0014_auto_20200503_2044'), - ] - - operations = [ - migrations.AddField( - model_name='penyandang', - name='kategori', - field=models.CharField(choices=[('FS', 'Fisik'), ('IN', 'Intelektual'), ('MN', 'Mental'), ('SN', 'Sensorik')], default='FS', max_length=2), - ), - migrations.AddField( - model_name='penyandang', - name='pekerjaan', - field=models.CharField(choices=[('PT', 'Petani'), ('BR', 'Buruh'), ('WS', 'Pedagang/Wiraswasta'), ('JS', 'Jasa'), ('PN', 'PNS/TNI/POLRI'), ('SN', 'Pensiunan'), ('IR', 'Ibu Rumah Tangga'), ('PL', 'Pelajar'), ('LA', 'Lainnya'), ('NA', 'Tidak Bekerja')], default='NA', max_length=2), - ), - migrations.AddField( - model_name='penyandang', - name='pendidikan', - field=models.CharField(choices=[('SD', 'SD'), ('MP', 'SMP/SLTP'), ('MA', 'SMA/SLTA'), ('D1', 'Diploma 1'), ('D2', 'Diploma 2'), ('D3', 'Diploma 3'), ('S1', 'Sarjana'), ('S2', 'Magister'), ('S3', 'Doktor'), ('NF', 'Non-Formal/Lainnya'), ('NA', 'Tidak Sekolah')], default='NA', max_length=2), - ), - ] diff --git a/layanan_khusus/migrations/0016_penyandang_jenis_kelamin.py b/layanan_khusus/migrations/0016_penyandang_jenis_kelamin.py deleted file mode 100644 index 14e2e53df7638e744cb681e0be15d35b39873a41..0000000000000000000000000000000000000000 --- a/layanan_khusus/migrations/0016_penyandang_jenis_kelamin.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 2.1.5 on 2020-05-03 18:36 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('layanan_khusus', '0015_auto_20200504_0116'), - ] - - operations = [ - migrations.AddField( - model_name='penyandang', - name='jenis_kelamin', - field=models.CharField(choices=[('LAKI-LAKI', 'Laki-Laki'), ('PEREMPUAN', 'Perempuan')], default='LAKI-LAkI', max_length=9), - ), - ] diff --git a/layanan_khusus/migrations/0017_auto_20200504_0151.py b/layanan_khusus/migrations/0017_auto_20200504_0151.py deleted file mode 100644 index 5a4e4fdf79aa8ee86121834576d7baa020fca2c7..0000000000000000000000000000000000000000 --- a/layanan_khusus/migrations/0017_auto_20200504_0151.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 2.1.5 on 2020-05-03 18:51 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('layanan_khusus', '0016_penyandang_jenis_kelamin'), - ] - - operations = [ - migrations.AddField( - model_name='penyandang', - name='email', - field=models.CharField(max_length=50, null=True), - ), - migrations.AlterField( - model_name='penyandang', - name='no_telp', - field=models.CharField(max_length=16, null=True), - ), - ] diff --git a/layanan_khusus/migrations/0018_auto_20200504_0208.py b/layanan_khusus/migrations/0018_auto_20200504_0208.py deleted file mode 100644 index a8e08f976e676d113a835fa9e0918499fe769ec9..0000000000000000000000000000000000000000 --- a/layanan_khusus/migrations/0018_auto_20200504_0208.py +++ /dev/null @@ -1,28 +0,0 @@ -# Generated by Django 2.1.5 on 2020-05-03 19:08 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('layanan_khusus', '0017_auto_20200504_0151'), - ] - - operations = [ - migrations.AddField( - model_name='penyandang', - name='alamat_wali', - field=models.CharField(max_length=100, null=True), - ), - migrations.AddField( - model_name='penyandang', - name='nama_wali', - field=models.CharField(max_length=50, null=True), - ), - migrations.AddField( - model_name='penyandang', - name='telp_wali', - field=models.CharField(max_length=16, null=True), - ), - ] diff --git a/layanan_khusus/models.py b/layanan_khusus/models.py index 9e892e4cba86319814a499706eeeb8befcbe7f29..d44572da5e956dfcb9ddf47f8146c4721d861884 100644 --- a/layanan_khusus/models.py +++ b/layanan_khusus/models.py @@ -2,14 +2,19 @@ from django.db import models class Sekolah(models.Model): + SWASTA = "SW" + NEGRI = "NG" + INTERNASIONAL = "IT" + INKLUSI = "IK" + SEGREGASI = "SG" STATUS_SEKOLAH = ( - ("SW", "Swasta"), - ("NG", "Negri"), - ("IT", "Internasional") + (SWASTA, "Swasta"), + (NEGRI, "Negri"), + (INTERNASIONAL, "Internasional") ) JENIS = ( - ("IK", "Inklusi"), - ("SG", "Segregasi") + (INKLUSI, "Inklusi"), + (SEGREGASI, "Segregasi") ) name = models.CharField(max_length=50) alamat = models.CharField(max_length=100) @@ -19,79 +24,11 @@ class Sekolah(models.Model): status = models.CharField( max_length=2, choices=STATUS_SEKOLAH, - default="SW" + default=SWASTA ) jenis_sekolah = models.CharField( max_length=2, choices=JENIS, - default="IK" + default=INKLUSI ) akreditasi = models.CharField(max_length=1, null=True, default=None) - - -class Penyandang(models.Model): - JENIS_KELAMIN_OPTION = ( - ("LAKI-LAKI", "Laki-Laki"), - ("PEREMPUAN", "Perempuan") - ) - PENDIDIKAN_TERAKHIR = ( - ("SD", "SD"), - ("MP", "SMP/SLTP"), - ("MA", "SMA/SLTA"), - ("D1", "Diploma 1"), - ("D2", "Diploma 2"), - ("D3", "Diploma 3"), - ("S1", "Sarjana"), - ("S2", "Magister"), - ("S3", "Doktor"), - ("NF", "Non-Formal/Lainnya"), - ("NA", "Tidak Sekolah") - ) - PEKERJAAN_OPTION = ( - ("PT", "Petani"), - ("BR", "Buruh"), - ("WS", "Pedagang/Wiraswasta"), - ("JS", "Jasa"), - ("PN", "PNS/TNI/POLRI"), - ("SN", "Pensiunan"), - ("IR", "Ibu Rumah Tangga"), - ("PL", "Pelajar"), - ("LA", "Lainnya"), - ("NA", "Tidak Bekerja") - ) - KATEGORI_DISABILITAS = ( - ("FS", "Fisik"), - ("IN", "Intelektual"), - ("MN", "Mental"), - ("SN", "Sensorik") - ) - name = models.CharField(max_length=50) - alamat = models.CharField(max_length=100) - tempat_lahir = models.CharField(max_length=50) - tanggal_lahir = models.DateField() - jenis_kelamin = models.CharField( - max_length=9, - choices=JENIS_KELAMIN_OPTION, - default="LAKI-LAkI" - ) - pendidikan = models.CharField( - max_length=2, - choices=PENDIDIKAN_TERAKHIR, - default="NA" - ) - pekerjaan = models.CharField( - max_length=2, - choices=PEKERJAAN_OPTION, - default="NA" - ) - kategori = models.CharField( - max_length=2, - choices=KATEGORI_DISABILITAS, - default="FS" - ) - no_telp = models.CharField(max_length=16, null=True) - email = models.CharField(max_length=50, null=True) - - nama_wali = models.CharField(max_length=50, null=True) - alamat_wali = models.CharField(max_length=100, null=True) - telp_wali = models.CharField(max_length=16, null=True) diff --git a/layanan_khusus/serializers.py b/layanan_khusus/serializers.py index 1a80fd513f01a5f6f1c48931f211664451084fb2..8f9775731bd19db78037fccbbc6024c000bb7eb4 100644 --- a/layanan_khusus/serializers.py +++ b/layanan_khusus/serializers.py @@ -1,5 +1,5 @@ from rest_framework import serializers -from .models import Sekolah, Penyandang +from .models import Sekolah class SekolahSerializer(serializers.HyperlinkedModelSerializer): @@ -16,24 +16,3 @@ class SekolahSerializer(serializers.HyperlinkedModelSerializer): 'jenis_sekolah', 'akreditasi' ) - - -class PenyandangSerializer(serializers.HyperlinkedModelSerializer): - class Meta: - model = Penyandang - fields = ( - 'id', - 'name', - 'alamat', - 'tempat_lahir', - 'tanggal_lahir', - 'jenis_kelamin', - 'pendidikan', - 'pekerjaan', - 'kategori', - 'no_telp', - 'email', - 'nama_wali', - 'alamat_wali', - 'telp_wali' - ) diff --git a/layanan_khusus/tests.py b/layanan_khusus/tests.py index df5520775de7938b0e3741655f3971d8b65c91d9..8e6f3f895ddcd2d6dfa05133d6d3f281295129fe 100644 --- a/layanan_khusus/tests.py +++ b/layanan_khusus/tests.py @@ -3,111 +3,45 @@ from http import HTTPStatus from django.test import TestCase, Client from django.db.utils import IntegrityError from django.urls import path, include, reverse -from .models import Sekolah, Penyandang +from .models import Sekolah from .serializers import SekolahSerializer NOT_NULL_CONSTRAINT_FAILED_MESSAGE = 'NOT NULL constraint failed' - ID = 'id' NAME = 'name' ALAMAT = 'alamat' NO_TELP = 'no_telp' - WEBSITE = 'website' JUMLAH_SISWA = 'jumlah_siswa' STATUS = 'status' JENIS_SEKOLAH = 'jenis_sekolah' AKREDITASI = 'akreditasi' - -MOCK_SEKOLAH = { +MOCK_DATA = { ID: 1, NAME: 'Sekolah Cita Buana', ALAMAT: 'Jl. Paso No.84, Jagakarsa, Jakarta Selatan', NO_TELP: '(021)7820088', - WEBSITE: 'https://www.sekolahcitabuana.com', + WEBSITE: 'http://www.sekolahcitabuana.com', JUMLAH_SISWA: 250, STATUS: 'SW', JENIS_SEKOLAH: 'IK', AKREDITASI: 'B' } -TEMPAT_LAHIR = 'tempat_lahir' -TANGGAL_LAHIR = 'tanggal_lahir' -JENIS_KELAMIN = 'jenis_kelamin' -PENDIDIKAN = 'pendidikan' -PEKERJAAN = 'pekerjaan' -KATEGORI = 'kategori' -EMAIL = 'email' - -NAMA_WALI = 'nama_wali' -ALAMAT_WALI = 'alamat_wali' -TELP_WALI = 'telp_wali' - -MOCK_PENYANDANG = { - ID: 1, - NAME: 'Nadia Anggraini', - ALAMAT: 'Depok, Jawa Barat', - TEMPAT_LAHIR: 'Depok', - TANGGAL_LAHIR: '1999-02-01', - JENIS_KELAMIN: 'PEREMPUAN', - PENDIDIKAN: 'S1', - PEKERJAAN: 'PL', - KATEGORI: 'FS', - NO_TELP: '082577776666', - EMAIL: 'nadiaag@email.com', - NAMA_WALI: 'wali', - ALAMAT_WALI: 'sama', - TELP_WALI: 'sama' -} - -def sekolah_setup(): +def setup(): Sekolah.objects.create( - name=MOCK_SEKOLAH[NAME], - alamat=MOCK_SEKOLAH[ALAMAT], - no_telp=MOCK_SEKOLAH[NO_TELP], - website=MOCK_SEKOLAH[WEBSITE], - jumlah_siswa=MOCK_SEKOLAH[JUMLAH_SISWA], - status=MOCK_SEKOLAH[STATUS], - jenis_sekolah=MOCK_SEKOLAH[JENIS_SEKOLAH], - akreditasi=MOCK_SEKOLAH[AKREDITASI] - ) - - -def penyandang_setup(): - Penyandang.objects.create( - name=MOCK_PENYANDANG[NAME], - alamat=MOCK_PENYANDANG[ALAMAT], - tempat_lahir=MOCK_PENYANDANG[TEMPAT_LAHIR], - tanggal_lahir=MOCK_PENYANDANG[TANGGAL_LAHIR], - jenis_kelamin=MOCK_PENYANDANG[JENIS_KELAMIN], - pendidikan=MOCK_PENYANDANG[PENDIDIKAN], - pekerjaan=MOCK_PENYANDANG[PEKERJAAN], - kategori=MOCK_PENYANDANG[KATEGORI], - no_telp=MOCK_PENYANDANG[NO_TELP], - email=MOCK_PENYANDANG[EMAIL], - nama_wali=MOCK_PENYANDANG[NAMA_WALI], - alamat_wali=MOCK_PENYANDANG[ALAMAT_WALI], - telp_wali=MOCK_PENYANDANG[TELP_WALI] + name=MOCK_DATA[NAME], + alamat=MOCK_DATA[ALAMAT], + no_telp=MOCK_DATA[NO_TELP], + website=MOCK_DATA[WEBSITE], + jumlah_siswa=MOCK_DATA[JUMLAH_SISWA], + status=MOCK_DATA[STATUS], + jenis_sekolah=MOCK_DATA[JENIS_SEKOLAH], + akreditasi=MOCK_DATA[AKREDITASI] ) -def auth_setup(): - email = 'mock_user@email.com' - passcode = 'pass12345' - Client().post('/api/register/', { - 'name': 'name', - 'email': email, - 'phone_number': 000000000, - 'password': passcode - }) - token_response = Client().post('/api-token-auth/', - {'username': email, 'password': passcode}) - content = json.loads(token_response.content.decode('utf-8')) - token = content['token'] - return Client(HTTP_AUTHORIZATION='token '+token) - - class LayananKhususModelTest(TestCase): def test_models_sekolah_not_created(self): @@ -118,22 +52,10 @@ class LayananKhususModelTest(TestCase): NOT_NULL_CONSTRAINT_FAILED_MESSAGE)) def test_models_create_new_sekolah(self): - sekolah_setup() + setup() count = Sekolah.objects.all().count() self.assertNotEqual(count, 0) - def test_models_penyandang_not_created(self): - with self.assertRaises(IntegrityError) as ex: - obj = Penyandang(name=None) - obj.save() - self.assertTrue(str(ex.exception).startswith( - NOT_NULL_CONSTRAINT_FAILED_MESSAGE)) - - def test_models_create_new_penyandang(self): - penyandang_setup() - count = Penyandang.objects.all().count() - self.assertNotEqual(count, 0) - class LayananKhususViewsTest(TestCase): urlpatterns = [ @@ -141,23 +63,19 @@ class LayananKhususViewsTest(TestCase): ] def test_sekolah_serializer_valid(self): - serializer = SekolahSerializer(data=MOCK_SEKOLAH) - self.assertTrue(serializer.is_valid) - - def test_penyandang_serializer_valid(self): - serializer = SekolahSerializer(data=MOCK_PENYANDANG) + serializer = SekolahSerializer(data=MOCK_DATA) self.assertTrue(serializer.is_valid) def test_can_get_list_sekolah(self): - sekolah_setup() + setup() response = Client().get(reverse('list-sekolah')) self.assertEqual(response.status_code, HTTPStatus.OK) def test_get_lokasi_list_json(self): - sekolah_setup() + setup() response = Client().get(reverse('list-sekolah')) content = json.loads(response.content.decode('utf-8')) - expected_json = [MOCK_SEKOLAH] + expected_json = [MOCK_DATA] self.assertEqual(content, expected_json) def test_cannot_post_list_sekolah(self): @@ -165,23 +83,23 @@ class LayananKhususViewsTest(TestCase): self.assertEqual(response.status_code, HTTPStatus.METHOD_NOT_ALLOWED) def test_can_get_detail_sekolah(self): - sekolah_setup() + setup() response = Client().get( reverse('detail-sekolah', kwargs={'id_sekolah': 1}) ) self.assertEqual(response.status_code, HTTPStatus.OK) - def test_get_details_detail_json(self): - sekolah_setup() + def test_can_get_lokasi_details_json(self): + setup() response = Client().get( reverse('detail-sekolah', kwargs={'id_sekolah': 1}) ) content = json.loads(response.content.decode('utf-8')) - expected_json = MOCK_SEKOLAH + expected_json = MOCK_DATA self.assertEqual(content, expected_json) def test_cannot_post_detail_sekolah(self): - sekolah_setup() + setup() response = Client().post( reverse('detail-sekolah', kwargs={'id_sekolah': 1}) ) @@ -191,28 +109,3 @@ class LayananKhususViewsTest(TestCase): response = Client().get( reverse('detail-sekolah', kwargs={'id_sekolah': 1})) self.assertEqual(response.status_code, HTTPStatus.NOT_FOUND) - - def test_can_post_register_penyandang(self): - client = auth_setup() - response = client.post(reverse('register-penyandang-disabilitas'), - MOCK_PENYANDANG) - self.assertEqual(response.status_code, HTTPStatus.CREATED) - - def test_post_register_penyandang_json(self): - client = auth_setup() - response = client.post(reverse('register-penyandang-disabilitas'), - MOCK_PENYANDANG) - content = json.loads(response.content.decode("utf-8")) - expected_json = MOCK_PENYANDANG - self.assertEqual(content, expected_json) - - def test_cannot_get_register_penyandang(self): - client = auth_setup() - response = client.get(reverse('register-penyandang-disabilitas'), - MOCK_PENYANDANG) - self.assertEqual(response.status_code, HTTPStatus.METHOD_NOT_ALLOWED) - - def test_post_bad_request_register_penyandang(self): - client = auth_setup() - response = client.post(reverse('register-penyandang-disabilitas')) - self.assertEqual(response.status_code, HTTPStatus.BAD_REQUEST) diff --git a/layanan_khusus/urls.py b/layanan_khusus/urls.py index b2b3a0409a3d7d535478aee3f8e0155ad882b047..9655653fc47431bf0ce7b9d419b9b2391347011f 100644 --- a/layanan_khusus/urls.py +++ b/layanan_khusus/urls.py @@ -4,7 +4,5 @@ from . import views urlpatterns = [ path('sekolah/list/', views.list_sekolah, name='list-sekolah'), path('sekolah/detail//', views.detail_sekolah, - name='detail-sekolah'), - path('penyandang/register/', views.register_penyandang, - name='register-penyandang-disabilitas') + name='detail-sekolah') ] diff --git a/layanan_khusus/views.py b/layanan_khusus/views.py index d23d6fe8a18a1a526cf4865e07b5ef3448a0b3f2..388629dae34e82970592d79762de15cc872446ee 100644 --- a/layanan_khusus/views.py +++ b/layanan_khusus/views.py @@ -3,43 +3,46 @@ from django.http import JsonResponse from django.core.exceptions import ObjectDoesNotExist from rest_framework.decorators import api_view, permission_classes,\ authentication_classes -from rest_framework.authentication import TokenAuthentication -from rest_framework.permissions import IsAuthenticated from .models import Sekolah -from .serializers import SekolahSerializer, PenyandangSerializer +from .serializers import SekolahSerializer +def request_error_message(request_kind): + return "get {} request instead".format(request_kind) + + +def missing_key_message(key): + return "bad request. {} key needed".format(key) + @api_view(['GET']) @authentication_classes([]) @permission_classes([]) def list_sekolah(request): - sekolah_list = Sekolah.objects.all() - serializer = SekolahSerializer(sekolah_list, many=True) - return JsonResponse(serializer.data, safe=False, status=HTTPStatus.OK) - + if request.method == 'GET': + sekolah_list = Sekolah.objects.all() + serializer = SekolahSerializer(sekolah_list, many=True) + return JsonResponse(serializer.data, safe=False, status=HTTPStatus.OK) + else: + return JsonResponse( + {'response': request_error_message("get")}, + status=HTTPStatus.METHOD_NOT_ALLOWED + ) @api_view(['GET']) @authentication_classes([]) @permission_classes([]) def detail_sekolah(request, id_sekolah): try: - sekolah = Sekolah.objects.get(id=id_sekolah) - serializer = SekolahSerializer(sekolah) - return JsonResponse(serializer.data, safe=False, - status=HTTPStatus.OK) + if request.method == 'GET': + sekolah = Sekolah.objects.get(id=id_sekolah) + serializer = SekolahSerializer(sekolah) + return JsonResponse(serializer.data, safe=False, status=HTTPStatus.OK) + else: + return JsonResponse({'response': request_error_message("get")}, + status=HTTPStatus.METHOD_NOT_ALLOWED) + except KeyError as ex: + return JsonResponse({'response': missing_key_message(str(ex))}, + status=HTTPStatus.BAD_REQUEST) except ObjectDoesNotExist: return JsonResponse({'response': 'sekolah not found'}, status=HTTPStatus.NOT_FOUND) - - -@api_view(['POST']) -@authentication_classes([TokenAuthentication]) -@permission_classes([IsAuthenticated]) -def register_penyandang(request): - data = request.POST - serializer = PenyandangSerializer(data=data) - if serializer.is_valid(): - serializer.save() - return JsonResponse(serializer.data, status=HTTPStatus.CREATED) - else: - return JsonResponse(serializer.errors, status=HTTPStatus.BAD_REQUEST) diff --git a/new_rest_api/tests.py b/new_rest_api/tests.py index 5c8807b1410ecba10cc91e73897ffb555eeea1d9..793663471a280208dde202acef8d2668b52533f6 100644 --- a/new_rest_api/tests.py +++ b/new_rest_api/tests.py @@ -1,10 +1,13 @@ # Create your tests here. +import json from rest_framework.test import APIRequestFactory, APITestCase, URLPatternsTestCase from rest_framework import status from django.test import TestCase, SimpleTestCase, Client from django.urls import include, path, reverse from registrasi.models import BisaGoUser -import json +from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode +from .tokens import account_activation_token +from django.utils.encoding import force_bytes, force_text class UserTests(APITestCase): urlpatterns = [ @@ -13,10 +16,10 @@ class UserTests(APITestCase): def setUp(self): url = reverse('create-user') - data = {'name': 'Astraykai', + data = {'name': 'Astraykai', 'email':'astraykai@gmail.com', 'phone_number':'089892218567', - 'password':'chingchenghanji',} + 'password':'chingchenghanji'} self.client.post(url, data) def test_create_user(self): @@ -24,26 +27,27 @@ class UserTests(APITestCase): Ensure we can create a new account object. """ url = reverse('create-user') - data = {'name': 'Astray', + data = {'name': 'Astray', 'email':'astrayyahoo@gmail.com', 'phone_number':'08989221856', - 'password':'chingchenghanji',} + 'password':'chingchenghanji', + 'is_active': True} response = self.client.post(url, data) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(BisaGoUser.objects.count(), 2) user = BisaGoUser.objects.get(phone_number='08989221856').user self.assertEqual(user.last_name, 'Astray') - + url = reverse('user-details', kwargs={'email':'astrayyahoo@gmail.com'}) response = self.client.get(url, format='json') - self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.status_code, status.HTTP_200_OK) json_test = json.loads(response.content) self.assertEqual(len(json_test), 4) #JSON Attribute def test_account_details(self): url = reverse('user-details', kwargs={'email':'astraykai@gmail.com'}) response = self.client.get(url, format='json') - self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.status_code, status.HTTP_200_OK) json_test = json.loads(response.content) self.assertEqual(len(json_test), 4) #JSON Attribute @@ -53,11 +57,60 @@ class UserTests(APITestCase): self.assertEqual(response.status_code, status.HTTP_200_OK) json_test = json.loads(response.content) self.assertEqual(len(json_test), 1) - + + def test_incomplete_create_user(self): + url = reverse('create-user') + data = {'name': 'Astray', + 'email':'astrayyahoo@gmail.com', + 'password':'chingchenghanji', + 'is_active': True} + response = self.client.post(url, data) + self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) + json_response = json.loads(response.content) + self.assertEqual(json_response['response'], 'bad request. \'phone_number\' key needed') + + def test_user_already_exist(self): + url = reverse('create-user') + data = {'name': 'Astraykai', + 'email':'astraykai@gmail.com', + 'phone_number':'089892218567', + 'password':'chingchenghanji', + 'is_active': True} + response = self.client.post(url, data) + self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) + json_response = json.loads(response.content) + self.assertEqual(json_response['response'], 'User is already exist') + + def test_invalid_request(self): + url = reverse('user-list') + data = {'name': 'Astraykai', + 'email':'astraykai@gmail.com', + 'phone_number':'089892218567', + 'password':'chingchenghanji', + 'is_active': True} + response = self.client.post(url, data) + self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) + json_response = json.loads(response.content) + def test_account_login(self): pass + def test_without_verification(self): + url = reverse('api-token-auth') + data = {'username': 'astraykai@gmail.com', + 'password':'chingchenghanji'} + response = self.client.post(url, data) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + + def test_activation_function(self): + user = BisaGoUser.objects.get(phone_number='089892218567').user + uid = urlsafe_base64_encode(force_bytes(user.pk)).decode() + token = account_activation_token.make_token(user) + url = reverse('activate', kwargs={'uidb64' : uid, 'token' : token}) + response = self.client.get(url) + json_response = json.loads(response.content) + self.assertEqual(json_response['response'], 'User activated') class InfoTests(APITestCase, URLPatternsTestCase): - pass \ No newline at end of file + pass diff --git a/new_rest_api/tokens.py b/new_rest_api/tokens.py new file mode 100644 index 0000000000000000000000000000000000000000..06aee6aa494febae370768bdcc2ea72425cd881d --- /dev/null +++ b/new_rest_api/tokens.py @@ -0,0 +1,9 @@ +from django.contrib.auth.tokens import PasswordResetTokenGenerator +from django.utils import six +class TokenGenerator(PasswordResetTokenGenerator): + def _make_hash_value(self, user, timestamp): + return ( + six.text_type(user.pk) + six.text_type(timestamp) + + six.text_type(user.is_active) + ) +account_activation_token = TokenGenerator() \ No newline at end of file diff --git a/new_rest_api/urls.py b/new_rest_api/urls.py index 091ab95c4c2dc8fa9bdd697d7d319dfff7237313..ce0969864c20f786757312511eba5a5007beb7c6 100644 --- a/new_rest_api/urls.py +++ b/new_rest_api/urls.py @@ -1,5 +1,5 @@ from django.contrib import admin -from django.urls import path,include +from django.urls import path from rest_framework import routers from rest_framework.authtoken import views import new_rest_api.views @@ -11,4 +11,6 @@ urlpatterns = [ path('user-detail/', new_rest_api.views.user_details,name='user-details'), path('user-detail/?email=', new_rest_api.views.user_details,name='user-details-get'), path('register/', new_rest_api.views.register_user,name='create-user'), -] \ No newline at end of file + path(r'^activate/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', + new_rest_api.views.activate, name='activate'), +] diff --git a/new_rest_api/views.py b/new_rest_api/views.py index ff35abc32570c43a894576e7d14a1b1ffd917a97..383c9fe93b4ddbc7c66e4918f72c9c328a67b95d 100644 --- a/new_rest_api/views.py +++ b/new_rest_api/views.py @@ -1,8 +1,6 @@ -from django.shortcuts import render -from django.contrib.auth.models import User, Group -from django.http import HttpResponse, JsonResponse +from django.contrib.auth.models import User +from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt -from django.contrib.auth.hashers import make_password, check_password from allauth.socialaccount.providers.oauth2.client import OAuth2Client @@ -16,6 +14,15 @@ from rest_framework.decorators import api_view, permission_classes, authenticati from registrasi.models import BisaGoUser +from django.db.utils import IntegrityError +from http import HTTPStatus as status +from django.contrib.sites.models import Site +from django.utils.encoding import force_bytes, force_text +from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode +from django.template.loader import render_to_string +from .tokens import account_activation_token +from django.core.mail import EmailMessage + def request_error_message(request_kind): return "get {} request instead".format(request_kind) @@ -33,25 +40,25 @@ def user_list(request): json_return = [] for user in user_list: json_return.append({"username":user.user.email, - "name": user.user.last_name, - "email": user.user.email, - "phone_number": user.phone_number}) - return JsonResponse(json_return, safe=False) + "name": user.user.last_name, + "email": user.user.email, + "phone_number": user.phone_number}) + return JsonResponse(json_return, safe=False, status=status.OK) else: - return JsonResponse({'response' : request_error_message("get")}, status = 400) + return JsonResponse({'response' : request_error_message("get")}, status=status.METHOD_NOT_ALLOWED) @api_view(['GET']) @authentication_classes([]) @permission_classes([]) -def user_details(request,email): +def user_details(request, email): if request.method == 'GET': - user = User.objects.get(username = email) + user = User.objects.get(username=email) bisa_go_user = BisaGoUser.objects.get(user=user) json_return = {"username":user.email, "name": user.last_name, "email": user.email, "phone_number": bisa_go_user.phone_number} - return JsonResponse(json_return, safe=False) + return JsonResponse(json_return, safe=False, status=status.OK) @api_view(['POST']) @@ -65,8 +72,43 @@ def register_user(request): email = request.POST['email'] password = request.POST['password'] user = User.objects.create_user(username=email, email=email, password=password, last_name=name) + user.is_active = False + user.save() + mail_subject = "Activate your account" + message = render_to_string('acc_active_email.html', { + 'user' : user, + 'domain' : request.get_host, + 'uid' : urlsafe_base64_encode(force_bytes(user.pk)).decode(), + 'token' : account_activation_token.make_token(user), + }) + mail = EmailMessage(mail_subject, message, to=[email]) + mail.send() BisaGoUser.objects.create(user= user, phone_number=phone_number) - return JsonResponse({'response' : 'User created', 'email':email, 'name':name}, status = 201) + return JsonResponse({'response' : 'User created', 'email':email, 'name':name}, status = status.CREATED) except KeyError as e: - return JsonResponse({'response':missing_key_message(str(e))}, status = 500) - \ No newline at end of file + return JsonResponse({'response' : missing_key_message(str(e))}, status = status.INTERNAL_SERVER_ERROR) + except IntegrityError as e: + return JsonResponse({'response' : 'User is already exist'}, status = status.INTERNAL_SERVER_ERROR) + except MethodNotAllowed : + return JsonResponse({'response' : request_error_message("post")}, status=status.METHOD_NOT_ALLOWED) + +@api_view(['GET']) +@authentication_classes([]) +@permission_classes([]) +def activate(request, uidb64, token): + if request.method == 'GET': + try: + uid = force_text(urlsafe_base64_decode(uidb64)) + user = User.objects.get(pk=uid) + except(TypeError, ValueError, OverflowError, User.DoesNotExist): + user = None + if user is not None and account_activation_token.check_token(user, token): + user.is_active = True + user.save() + # login(request, user) + # return redirect('home') + return JsonResponse({'response' : 'User activated'}, status = status.CREATED) + else: + return JsonResponse({'response' : request_error_message('get')}, status = status.BAD_REQUEST) + else : + return JsonResponse({'response' : request_error_message("get")}, status = BAD_REQUEST) diff --git a/pplbackend/settings.py b/pplbackend/settings.py index 694845585dd591a30447a65092dd250baa32b672..1c437c79a56af355c6fb51677da7654e6b109d12 100644 --- a/pplbackend/settings.py +++ b/pplbackend/settings.py @@ -71,10 +71,11 @@ MIDDLEWARE = [ ROOT_URLCONF = 'pplbackend.urls' +TEMPLATES_ROOT = os.path.join(BASE_DIR, "templates") TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], + 'DIRS': [TEMPLATES_ROOT], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ @@ -201,3 +202,9 @@ PASSWORD_HASHERS = [ 'django.contrib.auth.hashers.Argon2PasswordHasher', 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher', ] + +EMAIL_USE_TLS = True +EMAIL_HOST = 'smtp.gmail.com' +EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER") +EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD") +EMAIL_PORT = 587 \ No newline at end of file diff --git a/registrasi/admin.py b/registrasi/admin.py index 6f4b91c578603df6ec01e36d5922acdcc3396d65..50d71ff84176e53a446e34f5d7cad863a1a83cbd 100644 --- a/registrasi/admin.py +++ b/registrasi/admin.py @@ -1,4 +1,4 @@ from django.contrib import admin # Register your models here. from .models import BisaGoUser -admin.site.register(BisaGoUser) \ No newline at end of file +admin.site.register(BisaGoUser) diff --git a/registrasi/managers.py b/registrasi/managers.py index c7a590fa103606df9a4aacdeb9ee51d27b75e9c8..10657bac7bc8a66dbcce8112318be121299491cb 100644 --- a/registrasi/managers.py +++ b/registrasi/managers.py @@ -25,4 +25,5 @@ class UserManager(BaseUserManager): if extra_fields.get('is_superuser') is not True: raise ValueError('Superuser must have is_superuser=True.') - return self._create_user(email, password, **extra_fields) \ No newline at end of file + return self._create_user(email, password, **extra_fields) + \ No newline at end of file diff --git a/registrasi/models.py b/registrasi/models.py index 1b13a469a100a65a9ed125a654efa324c91c1635..af0e5f0fa2563f91c7978fdf6d28641548aaa66e 100644 --- a/registrasi/models.py +++ b/registrasi/models.py @@ -5,9 +5,7 @@ from django.contrib.auth.models import User class BisaGoUser(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="phone_number") - phone_number = models.CharField('Nomor Telepon',max_length=15, unique=True) - + phone_number = models.CharField('Nomor Telepon', max_length=15, unique=True) + def __str__(self): return self.user.username - - diff --git a/registrasi/tests.py b/registrasi/tests.py index 2a300a5ce75a4a1807f0491b5c8c2ccb2a39e84f..0bef2cbfcf30219a31c56766b7d0a3fbe5e9e46f 100644 --- a/registrasi/tests.py +++ b/registrasi/tests.py @@ -1,9 +1,9 @@ from django.test import TestCase -from .models import BisaGoUser from django.contrib.auth.models import User -from django.test import TestCase from django.db.utils import IntegrityError -import tempfile +from .models import BisaGoUser + + class RegistrationTest(TestCase): @@ -11,10 +11,10 @@ class RegistrationTest(TestCase): user = User.objects.create(username="hoho", email="user@gmail.com", password="hohoho") BisaGoUser.objects.create(user=user, phone_number='081278787878') count = BisaGoUser.objects.all().count() - self.assertNotEqual(count,0) + self.assertNotEqual(count, 0) def test_user_model_not_created(self): - with self.assertRaises(IntegrityError) as cm: + with self.assertRaises(IntegrityError) as error: obj = BisaGoUser(user=None) - obj.save(); - self.assertTrue(str(cm.exception).startswith('NOT NULL constraint failed')) \ No newline at end of file + obj.save() + self.assertTrue(str(error.exception).startswith('NOT NULL constraint failed')) diff --git a/requirements.txt b/requirements.txt index 68d246239df6eac306421a981f387a943fe6e6b3..6d16f60573589603a8dec805b6404be6cd7344b5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ argon2-cffi==19.2.0 -astroid==2.4.0 +astroid==2.0.4 cachetools==4.0.0 certifi==2018.8.24 cffi==1.14.0 diff --git a/templates/acc_active_email.html b/templates/acc_active_email.html new file mode 100644 index 0000000000000000000000000000000000000000..fa5f16d71d18468f274be6aa520b121d6a48490a --- /dev/null +++ b/templates/acc_active_email.html @@ -0,0 +1,5 @@ +{% autoescape off %} +Hi {{ user.username }}, +Please click on the link to confirm your registration, +http://{{ domain }}{% url 'activate' uidb64=uid token=token %} +{% endautoescape %} \ No newline at end of file