Fakultas Ilmu Komputer UI

Commit 2ef0ec65 authored by Ami's avatar Ami
Browse files

resolving merge conflict between PBI-12 and other PBIs

parents f18b2f8b 7e768657
...@@ -2,22 +2,48 @@ from django.contrib.auth.models import Group ...@@ -2,22 +2,48 @@ from django.contrib.auth.models import Group
from rest_framework import serializers, exceptions from rest_framework import serializers, exceptions
from dj_rest_auth.serializers import LoginSerializer from dj_rest_auth.serializers import LoginSerializer
from dj_rest_auth.registration.serializers import RegisterSerializer from dj_rest_auth.registration.serializers import RegisterSerializer
from payment.serializers import CartSerializer
from .models import CustomUser from .models import CustomUser
class CustomUserDetailsSerializer(serializers.ModelSerializer): class UserAuthSerializer(serializers.ModelSerializer):
def to_representation(self, instance): def to_representation(self, instance):
result = super().to_representation(instance) result = super().to_representation(instance)
result['is_finished_onboarding'] = True
if instance.groups.exists(): if instance.groups.exists():
result['role'] = instance.groups.first().name result['role'] = instance.groups.first().name
if result['role'] == 'client':
if hasattr(instance, 'diet_questionnaire'):
result['is_finished_onboarding'] = \
(len(instance.diet_questionnaire.finished_steps) == 6)
else:
result['is_finished_onboarding'] = False
if instance.is_staff: if instance.is_staff:
result['role'] = 'admin' result['role'] = 'admin'
if instance.cart.exists(): if instance.cart.exists():
result['cart'] = CartSerializer(instance.cart.last()).data result['transaction_status'] = instance.cart.last().transaction_status
else: else:
result['cart'] = {} result['transaction_status'] = None
return result
class Meta:
model = CustomUser
fields = ('id', 'name', 'email',)
read_only_fields = ('id', 'email',)
class CustomUserDetailsSerializer(serializers.ModelSerializer):
def to_representation(self, instance):
result = super().to_representation(instance)
if instance.groups.exists():
result['role'] = instance.groups.first().name
if instance.is_staff:
result['role'] = 'admin'
return result return result
class Meta: class Meta:
......
...@@ -10,7 +10,10 @@ from dietela_program.models import DietelaProgram ...@@ -10,7 +10,10 @@ from dietela_program.models import DietelaProgram
from nutritionists.models import Nutritionist from nutritionists.models import Nutritionist
from .models import CustomUser from .models import CustomUser
from .serializers import ( from .serializers import (
CustomLoginSerializer, CustomRegisterSerializer,CustomUserDetailsSerializer CustomLoginSerializer,
CustomRegisterSerializer,
CustomUserDetailsSerializer,
UserAuthSerializer,
) )
from .google_utils import validate_google_token from .google_utils import validate_google_token
...@@ -93,7 +96,11 @@ class UserModelTests(APITestCase): ...@@ -93,7 +96,11 @@ class UserModelTests(APITestCase):
languages="Bahasa Indonesia, Bahasa Inggris", languages="Bahasa Indonesia, Bahasa Inggris",
) )
cls.cart = Cart.objects.create(program=cls.dietela_program, nutritionist=cls.nutritionist) cls.cart = Cart.objects.create(
program=cls.dietela_program,
nutritionist=cls.nutritionist,
user=cls.custom_user_1
)
def test_create_user(self): def test_create_user(self):
user = CustomUser.objects.create_user(name='tes', email='email2@email.com', user = CustomUser.objects.create_user(name='tes', email='email2@email.com',
...@@ -353,6 +360,25 @@ class UserModelTests(APITestCase): ...@@ -353,6 +360,25 @@ class UserModelTests(APITestCase):
serializer = CustomLoginSerializer() serializer = CustomLoginSerializer()
self.assertEqual(serializer.update(None, {}), None) self.assertEqual(serializer.update(None, {}), None)
def test_user_auth_serializer(self):
user_data = UserAuthSerializer(self.custom_user_1).data
self.assertIn('email', user_data)
self.assertIn('name', user_data)
self.assertEqual('client', user_data.get('role'))
self.assertIn('id', user_data)
user_no_role = CustomUser()
user_no_role.name = 'no role'
user_no_role.email = 'norole@norole.com'
user_no_role.password = 'norole2404'
user_no_role.save()
user_no_role_data = UserAuthSerializer(user_no_role).data
self.assertTrue('role' not in user_no_role_data)
admin_user = CustomUser.objects.create_superuser('super2@user.com', 'foo')
admin_user_data = UserAuthSerializer(admin_user).data
self.assertEqual('admin', admin_user_data.get('role'))
@patch('authentication.google_utils.requests.get') @patch('authentication.google_utils.requests.get')
@patch('authentication.google_utils.json.loads') @patch('authentication.google_utils.json.loads')
class TestValidateGoogleToken(TestCase): class TestValidateGoogleToken(TestCase):
......
...@@ -45,10 +45,10 @@ def get_diet_questionnaire_payload_sample_with_step(): ...@@ -45,10 +45,10 @@ def get_diet_questionnaire_payload_sample_with_step():
], ],
"multivitamin_tablet_suplement": "-", "multivitamin_tablet_suplement": "-",
"physical_activity": [ "physical_activity": [
"jogging", 1,
"basket", 7
"apa aja boleh"
], ],
"other_physical_activity": "workout",
"diet_and_life_style_story": "-", "diet_and_life_style_story": "-",
"disease": [ "disease": [
18 18
...@@ -69,7 +69,7 @@ def get_diet_questionnaire_payload_sample_with_step(): ...@@ -69,7 +69,7 @@ def get_diet_questionnaire_payload_sample_with_step():
"step": 1 "step": 1
} }
def get_diet_questionnaire_response_sample_with_step(id, user_id): def get_diet_questionnaire_response_sample_with_step(id, user):
return { return {
"id": id, "id": id,
...@@ -120,20 +120,15 @@ def get_diet_questionnaire_response_sample_with_step(id, user_id): ...@@ -120,20 +120,15 @@ def get_diet_questionnaire_response_sample_with_step(id, user_id):
"night_snack_explanation": "indomi", "night_snack_explanation": "indomi",
"food_alergies": "-", "food_alergies": "-",
"diet_drinks": "-", "diet_drinks": "-",
"meal_provider": [
1,
2,
3
],
"cigarette_alcohol_condition": [ "cigarette_alcohol_condition": [
4 4
], ],
"multivitamin_tablet_suplement": "-", "multivitamin_tablet_suplement": "-",
"physical_activity": [ "physical_activity": [
"jogging", 1,
"basket", 7
"apa aja boleh"
], ],
"other_physical_activity": "workout",
"diet_and_life_style_story": "-", "diet_and_life_style_story": "-",
"disease": [ "disease": [
18 18
...@@ -146,7 +141,7 @@ def get_diet_questionnaire_response_sample_with_step(id, user_id): ...@@ -146,7 +141,7 @@ def get_diet_questionnaire_response_sample_with_step(id, user_id):
"finished_steps": [ "finished_steps": [
1 1
], ],
"user": user_id "user": user
} }
def get_diet_questionnaire_payload_sample_without_step(): def get_diet_questionnaire_payload_sample_without_step():
...@@ -196,10 +191,10 @@ def get_diet_questionnaire_payload_sample_without_step(): ...@@ -196,10 +191,10 @@ def get_diet_questionnaire_payload_sample_without_step():
], ],
"multivitamin_tablet_suplement": "-", "multivitamin_tablet_suplement": "-",
"physical_activity": [ "physical_activity": [
"jogging", 1,
"basket", 7
"apa aja boleh"
], ],
"other_physical_activity": "workout",
"diet_and_life_style_story": "-", "diet_and_life_style_story": "-",
"disease": [ "disease": [
18 18
...@@ -219,7 +214,7 @@ def get_diet_questionnaire_payload_sample_without_step(): ...@@ -219,7 +214,7 @@ def get_diet_questionnaire_payload_sample_without_step():
"dietela_program_expectation": "-", "dietela_program_expectation": "-",
} }
def get_diet_questionnaire_response_sample_without_step(id, user_id): def get_diet_questionnaire_response_sample_without_step(id, user):
return { return {
"id": id, "id": id,
...@@ -270,20 +265,15 @@ def get_diet_questionnaire_response_sample_without_step(id, user_id): ...@@ -270,20 +265,15 @@ def get_diet_questionnaire_response_sample_without_step(id, user_id):
"night_snack_explanation": "indomi", "night_snack_explanation": "indomi",
"food_alergies": "-", "food_alergies": "-",
"diet_drinks": "-", "diet_drinks": "-",
"meal_provider": [
1,
2,
3
],
"cigarette_alcohol_condition": [ "cigarette_alcohol_condition": [
4 4
], ],
"multivitamin_tablet_suplement": "-", "multivitamin_tablet_suplement": "-",
"physical_activity": [ "physical_activity": [
"jogging", 1,
"basket", 7
"apa aja boleh"
], ],
"other_physical_activity": "workout",
"diet_and_life_style_story": "-", "diet_and_life_style_story": "-",
"disease": [ "disease": [
18 18
...@@ -294,5 +284,5 @@ def get_diet_questionnaire_response_sample_without_step(id, user_id): ...@@ -294,5 +284,5 @@ def get_diet_questionnaire_response_sample_without_step(id, user_id):
"dietela_nutritionist_expectation": "-", "dietela_nutritionist_expectation": "-",
"dietela_program_expectation": "-", "dietela_program_expectation": "-",
"finished_steps": [], "finished_steps": [],
"user": user_id "user": user
} }
...@@ -180,6 +180,17 @@ class CigaretteAlcoholCondition(models.IntegerChoices): ...@@ -180,6 +180,17 @@ class CigaretteAlcoholCondition(models.IntegerChoices):
CONDITION_3 = 3, 'Terkadang mengkonsumsi salah satu jenis minuman beralkohol (contoh: bir, vodka, wine)' CONDITION_3 = 3, 'Terkadang mengkonsumsi salah satu jenis minuman beralkohol (contoh: bir, vodka, wine)'
CONDITION_4 = 4, 'Tidak termasuk salah satu diatas' CONDITION_4 = 4, 'Tidak termasuk salah satu diatas'
class PhysicalActivity(models.IntegerChoices):
ACTIVITY_1 = 1, 'Hampir tidak pernah olahraga'
ACTIVITY_2 = 2, 'Jogging'
ACTIVITY_3 = 3, 'Senam aerobic, zumba, yoga, dan sejenisnya'
ACTIVITY_4 = 4, 'Sepak bola/Futsal'
ACTIVITY_5 = 5, 'Renang'
ACTIVITY_6 = 6, 'Basket'
ACTIVITY_7 = 7, 'Bulutangkis'
ACTIVITY_8 = 8, 'Voli'
ACTIVITY_9 = 9, 'Lainnya'
class Disease(models.IntegerChoices): class Disease(models.IntegerChoices):
DISEASE_1 = 1, 'Tidak ada' DISEASE_1 = 1, 'Tidak ada'
DISEASE_2 = 2, 'Diabetes Melitus Tipe II (Kencing Manis)' DISEASE_2 = 2, 'Diabetes Melitus Tipe II (Kencing Manis)'
......
...@@ -3,7 +3,7 @@ from django.utils.translation import gettext_lazy as _ ...@@ -3,7 +3,7 @@ from django.utils.translation import gettext_lazy as _
class TransactionStatus(models.TextChoices): class TransactionStatus(models.TextChoices):
SUCCESS = "success", _("Sucess") SUCCESS = "success", _("Success")
PENDING = "pending", _("Pending") PENDING = "pending", _("Pending")
UNPAID = "unpaid", _("Unpaid") UNPAID = "unpaid", _("Unpaid")
ERROR = "error", _("Error") ERROR = "error", _("Error")
# Generated by Django 3.1 on 2021-05-10 18:04
from django.db import migrations, models
import multiselectfield.db.fields
class Migration(migrations.Migration):
dependencies = [
('diet_questionnaire', '0006_auto_20210509_2113'),
]
operations = [
migrations.AddField(
model_name='dietquestionnaire',
name='other_physical_activity',
field=models.CharField(blank=True, max_length=200, null=True),
),
migrations.AlterField(
model_name='dietquestionnaire',
name='physical_activity',
field=multiselectfield.db.fields.MultiSelectField(blank=True, choices=[(1, 'Hampir tidak pernah olahraga'), (2, 'Jogging'), (3, 'Senam aerobic, zumba, yoga, dan sejenisnya'), (4, 'Sepak bola/Futsal'), (5, 'Renang'), (6, 'Basket'), (7, 'Bulutangkis'), (8, 'Voli')], max_length=15, null=True),
),
]
...@@ -16,6 +16,7 @@ from constants.model_choices import ( ...@@ -16,6 +16,7 @@ from constants.model_choices import (
LiquidConsumptionFrequency, LiquidConsumptionFrequency,
MealProvider, MealProvider,
CigaretteAlcoholCondition, CigaretteAlcoholCondition,
PhysicalActivity,
Disease, Disease,
Complaint, Complaint,
) )
...@@ -103,7 +104,10 @@ class DietQuestionnaire(models.Model): ...@@ -103,7 +104,10 @@ class DietQuestionnaire(models.Model):
choices = CigaretteAlcoholCondition.choices, null=True, blank=True choices = CigaretteAlcoholCondition.choices, null=True, blank=True
) )
multivitamin_tablet_suplement = models.CharField(max_length=200, null=True, blank=True) multivitamin_tablet_suplement = models.CharField(max_length=200, null=True, blank=True)
physical_activity = ArrayField(models.CharField(max_length=200), null=True, blank=True) physical_activity = MultiSelectField(
choices = PhysicalActivity.choices, null=True, blank=True
)
other_physical_activity = models.CharField(max_length=200, null=True, blank=True)
diet_and_life_style_story = models.TextField(null=True, blank=True) diet_and_life_style_story = models.TextField(null=True, blank=True)
disease = MultiSelectField( disease = MultiSelectField(
choices = Disease.choices, null=True, blank=True choices = Disease.choices, null=True, blank=True
...@@ -117,3 +121,6 @@ class DietQuestionnaire(models.Model): ...@@ -117,3 +121,6 @@ class DietQuestionnaire(models.Model):
dietela_nutritionist_expectation = models.TextField(null=True, blank=True) dietela_nutritionist_expectation = models.TextField(null=True, blank=True)
dietela_program_expectation = models.TextField(null=True, blank=True) dietela_program_expectation = models.TextField(null=True, blank=True)
finished_steps = ArrayField(models.PositiveIntegerField(), null=True, blank=True, default=list) finished_steps = ArrayField(models.PositiveIntegerField(), null=True, blank=True, default=list)
def __str__(self):
return str(self.user)
...@@ -3,12 +3,15 @@ from constants.model_choices import ( ...@@ -3,12 +3,15 @@ from constants.model_choices import (
MealProvider, MealProvider,
Complaint, Complaint,
CigaretteAlcoholCondition, CigaretteAlcoholCondition,
PhysicalActivity,
Disease Disease
) )
from authentication.serializers import CustomUserDetailsSerializer
from .models import DietQuestionnaire from .models import DietQuestionnaire
class DietQuestionnaireSerializer(serializers.ModelSerializer): class DietQuestionnaireSerializer(serializers.ModelSerializer):
meal_provider = fields.MultipleChoiceField( meal_provider = fields.MultipleChoiceField(
choices = MealProvider.choices, required=False choices = MealProvider.choices, required=False
) )
...@@ -21,10 +24,16 @@ class DietQuestionnaireSerializer(serializers.ModelSerializer): ...@@ -21,10 +24,16 @@ class DietQuestionnaireSerializer(serializers.ModelSerializer):
choices = CigaretteAlcoholCondition.choices, required=False choices = CigaretteAlcoholCondition.choices, required=False
) )
physical_activity = fields.MultipleChoiceField(
choices = PhysicalActivity.choices, required=False
)
disease = fields.MultipleChoiceField( disease = fields.MultipleChoiceField(
choices = Disease.choices, required=False choices = Disease.choices, required=False
) )
user = CustomUserDetailsSerializer(read_only=True)
class Meta: class Meta:
model = DietQuestionnaire model = DietQuestionnaire
fields = "__all__" fields = "__all__"
......
...@@ -5,6 +5,7 @@ from rest_framework.test import APITestCase, APIClient ...@@ -5,6 +5,7 @@ from rest_framework.test import APITestCase, APIClient
from rest_framework import status from rest_framework import status
from .models import DietQuestionnaire from .models import DietQuestionnaire
from authentication.models import CustomUser from authentication.models import CustomUser
from authentication.serializers import CustomUserDetailsSerializer
from constants.diet_questionnaire_sample import ( from constants.diet_questionnaire_sample import (
get_diet_questionnaire_payload_sample_with_step, get_diet_questionnaire_payload_sample_with_step,
get_diet_questionnaire_response_sample_with_step, get_diet_questionnaire_response_sample_with_step,
...@@ -42,7 +43,7 @@ class DietQuestionnaireTests(APITestCase): ...@@ -42,7 +43,7 @@ class DietQuestionnaireTests(APITestCase):
cls.login_credentials = "Bearer " + cls.json_login_response['access_token'] cls.login_credentials = "Bearer " + cls.json_login_response['access_token']
cls.diet_questionnaire = DietQuestionnaire.objects.create( cls.diet_questionnaire = DietQuestionnaire.objects.create(
user_id = cls.custom_user_1.id user = cls.custom_user_1
) )
cls.SPECIFIC_URL = f"{cls.BASE_URL}{cls.diet_questionnaire.id}/" cls.SPECIFIC_URL = f"{cls.BASE_URL}{cls.diet_questionnaire.id}/"
...@@ -51,17 +52,20 @@ class DietQuestionnaireTests(APITestCase): ...@@ -51,17 +52,20 @@ class DietQuestionnaireTests(APITestCase):
cls.sample_response_with_step = \ cls.sample_response_with_step = \
get_diet_questionnaire_response_sample_with_step( get_diet_questionnaire_response_sample_with_step(
cls.diet_questionnaire.id, cls.diet_questionnaire.id,
cls.custom_user_1.id CustomUserDetailsSerializer(cls.custom_user_1).data
) )
cls.sample_payload_without_step = get_diet_questionnaire_payload_sample_without_step() cls.sample_payload_without_step = get_diet_questionnaire_payload_sample_without_step()
cls.sample_response_without_step = \ cls.sample_response_without_step = \
get_diet_questionnaire_response_sample_without_step( get_diet_questionnaire_response_sample_without_step(
cls.diet_questionnaire.id, cls.diet_questionnaire.id,
cls.custom_user_1.id CustomUserDetailsSerializer(cls.custom_user_1).data
) )
def test_string_representation(self):
self.assertEqual(str(self.diet_questionnaire), 'email@email.com')
def test_create_diet_questionnaire(self): def test_create_diet_questionnaire(self):
login_data = { login_data = {
'email': 'email2@email.com', 'email': 'email2@email.com',
...@@ -76,20 +80,20 @@ class DietQuestionnaireTests(APITestCase): ...@@ -76,20 +80,20 @@ class DietQuestionnaireTests(APITestCase):
response = self.client.post(self.BASE_URL, {}, format='json') response = self.client.post(self.BASE_URL, {}, format='json')
json_response = json.loads(response.content) json_response = json.loads(response.content)
self.assertEqual(DietQuestionnaire.objects.count(), 2) self.assertEqual(DietQuestionnaire.objects.count(), 2)
self.assertEqual(json_response.get('user'), self.custom_user_2.id) self.assertEqual(json_response.get('user'), CustomUserDetailsSerializer(self.custom_user_2).data)
def test_get_all_diet_questionnaire(self): def test_get_all_diet_questionnaire(self):
self.client.credentials(HTTP_AUTHORIZATION=self.login_credentials) self.client.credentials(HTTP_AUTHORIZATION=self.login_credentials)
response = self.client.get(self.BASE_URL) response = self.client.get(self.BASE_URL)
json_response = json.loads(response.content) json_response = json.loads(response.content)
self.assertEqual(len(json_response), 1) self.assertEqual(len(json_response), 1)
self.assertEqual(json_response[0].get('user'), self.custom_user_1.id) self.assertEqual(json_response[0].get('user'), CustomUserDetailsSerializer(self.custom_user_1).data)
def test_get_single_diet_questionnaire_succeed(self): def test_get_single_diet_questionnaire_succeed(self):
self.client.credentials(HTTP_AUTHORIZATION=self.login_credentials) self.client.credentials(HTTP_AUTHORIZATION=self.login_credentials)
response = self.client.get(f"{self.BASE_URL}{self.diet_questionnaire.id}/") response = self.client.get(f"{self.BASE_URL}{self.diet_questionnaire.id}/")
json_response = json.loads(response.content) json_response = json.loads(response.content)
self.assertEqual(json_response.get('user'), self.custom_user_1.id) self.assertEqual(json_response.get('user'), CustomUserDetailsSerializer(self.custom_user_1).data)
def test_get_single_diet_questionnaire_failed(self): def test_get_single_diet_questionnaire_failed(self):
self.client.credentials(HTTP_AUTHORIZATION=self.login_credentials) self.client.credentials(HTTP_AUTHORIZATION=self.login_credentials)
......
...@@ -21,7 +21,7 @@ class DietQuestionnaireViewSet(viewsets.ModelViewSet): ...@@ -21,7 +21,7 @@ class DietQuestionnaireViewSet(viewsets.ModelViewSet):
return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.data, status=status.HTTP_200_OK)
def retrieve(self, request, pk=None): def retrieve(self, request, pk=None):
instance = get_object_or_404(self.get_queryset(), pk=pk) instance = get_object_or_404(DietQuestionnaire.objects.all(), pk=pk)
serializer = DietQuestionnaireSerializer(instance) serializer = DietQuestionnaireSerializer(instance)
return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.data, status=status.HTTP_200_OK)
......
...@@ -204,7 +204,7 @@ AUTHENTICATION_BACKENDS = ( ...@@ -204,7 +204,7 @@ AUTHENTICATION_BACKENDS = (
AUTH_USER_MODEL = 'authentication.CustomUser' AUTH_USER_MODEL = 'authentication.CustomUser'
REST_AUTH_SERIALIZERS = { REST_AUTH_SERIALIZERS = {
'USER_DETAILS_SERIALIZER':'authentication.serializers.CustomUserDetailsSerializer' 'USER_DETAILS_SERIALIZER':'authentication.serializers.UserAuthSerializer'
} }
REST_AUTH_REGISTER_SERIALIZERS = { REST_AUTH_REGISTER_SERIALIZERS = {
...@@ -212,3 +212,4 @@ REST_AUTH_REGISTER_SERIALIZERS = { ...@@ -212,3 +212,4 @@ REST_AUTH_REGISTER_SERIALIZERS = {
} }
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
from django.contrib import admin from django.contrib import admin
from django.urls import path, include from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
...@@ -10,4 +13,4 @@ urlpatterns = [ ...@@ -10,4 +13,4 @@ urlpatterns = [
path('', include('authentication.urls')), path('', include('authentication.urls')),
path('', include('diet_questionnaire.urls')), path('', include('diet_questionnaire.urls')),
path('', include('profile_dietku.urls')), path('', include('profile_dietku.urls')),
] ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)