Fakultas Ilmu Komputer UI

Commit 726f232a authored by Muzaki Azami's avatar Muzaki Azami

Merge branch 'PBI-13-ProgressDietClient' into 'staging'

Pbi 13 progress diet client

See merge request !76
parents b2d4288d 3fa9683a
Pipeline #80551 passed with stages
in 16 minutes and 53 seconds
......@@ -18,7 +18,7 @@ UnitTest:
stage: test
before_script:
- pip install -r requirements.txt
- python manage.py makemigrations
- python manage.py makemigrations authentication diet_progress diet_questionnaire dietela_program dietela_quiz nutritionists payment profile_dietku
- python manage.py migrate
- python manage.py collectstatic --no-input
- python manage.py runserver 8000 &
......
# Generated by Django 3.1 on 2021-04-07 15:21
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
('dietela_quiz', '__first__'),
]
operations = [
migrations.CreateModel(
name='CustomUser',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('email', models.EmailField(max_length=254, unique=True, verbose_name='email address')),
('is_staff', models.BooleanField(default=False)),
('is_active', models.BooleanField(default=True)),
('date_joined', models.DateTimeField(default=django.utils.timezone.now)),
('diet_profile', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='user', to='dietela_quiz.dietprofile')),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
],
options={
'abstract': False,
},
),
]
# Generated by Django 3.1 on 2021-04-24 06:55
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('authentication', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='customuser',
name='name',
field=models.CharField(default='tes', max_length=100),
preserve_default=False,
),
]
# Generated by Django 3.1 on 2021-05-08 02:07
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('nutritionists', '0002_nutritionist_profile_picture'),
('authentication', '0002_customuser_name'),
]
operations = [
migrations.AddField(
model_name='customuser',
name='nutritionist',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='nutritionists.nutritionist'),
),
]
# Generated by Django 3.1 on 2021-05-08 02:20
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('nutritionists', '0002_nutritionist_profile_picture'),
('authentication', '0003_customuser_nutritionist'),
]
operations = [
migrations.AlterField(
model_name='customuser',
name='nutritionist',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='clients', to='nutritionists.nutritionist'),
),
]
# Generated by Django 3.1 on 2021-05-29 13:24
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('authentication', '0004_auto_20210508_0920'),
]
operations = [
migrations.AddField(
model_name='customuser',
name='first_deadline',
field=models.DateField(default=django.utils.timezone.now),
),
]
# Generated by Django 3.1 on 2021-05-29 15:40
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('authentication', '0005_customuser_first_deadline'),
]
operations = [
migrations.RenameField(
model_name='customuser',
old_name='first_deadline',
new_name='deadline',
),
]
......@@ -239,12 +239,12 @@ class Hunger(models.IntegerChoices):
CHANGES_10 = 10, '10'
class ConsumptionInOneDay(models.IntegerChoices):
NO_GLASS = 1, '0 gelas'
ONE_GLASS = 2, '1 gelas'
TWO_GLASSES = 3, '2 gelas'
THREE_GLASSES = 4, '3 gelas'
FOUR_GLASSES = 5, '4 gelas'
MORE_GLASSES = 6, 'Lebih dari 4 gelas'
NO_GLASS = 1, '0'
ONE_GLASS = 2, '1'
TWO_GLASSES = 3, '2'
THREE_GLASSES = 4, '3'
FOUR_GLASSES = 5, '4'
MORE_GLASSES = 6, 'Lebih dari 4'
class PhysicalActivity(models.IntegerChoices):
ACTIVITY_1 = 1, 'Hampir tidak pernah olahraga dan/atau duduk lebih dari 9 jam perhari'
......
# Generated by Django 3.1 on 2021-05-29 13:24
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('nutritionists', '0002_nutritionist_profile_picture'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='WeeklyReport',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('weight', models.PositiveIntegerField()),
('height', models.PositiveIntegerField()),
('waist_size', models.PositiveIntegerField()),
('changes_felt', models.IntegerField(choices=[(1, '1'), (2, '2'), (3, '3'), (4, '4'), (5, '5')])),
('hunger_level', models.IntegerField(choices=[(1, '1'), (2, '2'), (3, '3'), (4, '4'), (5, '5'), (6, '6'), (7, '7'), (8, '8'), (9, '9'), (10, '10')])),
('fullness_level', models.IntegerField(choices=[(1, '1'), (2, '2'), (3, '3'), (4, '4'), (5, '5'), (6, '6'), (7, '7'), (8, '8'), (9, '9'), (10, '10')])),
('heavy_meal', models.IntegerField(choices=[(1, '1 kali'), (2, '2 kali'), (3, '3 kali'), (4, 'Lebih dari 3 kali')])),
('snacks', models.IntegerField(choices=[(1, 'Tidak pernah'), (2, '1 kali'), (3, '2 kali'), (4, '3 kali'), (5, 'Lebih dari 3 kali')])),
('sweet_beverages', models.IntegerField(choices=[(1, '0 gelas'), (2, '1 gelas'), (3, '2 gelas'), (4, '3 gelas'), (5, '4 gelas'), (6, 'Lebih dari 4 gelas')])),
('nutritional_advice', models.TextField(blank=True, null=True)),
('lifestyle_advice', models.TextField(blank=True, null=True)),
('client', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='weekly_report', to=settings.AUTH_USER_MODEL)),
('nutritionist', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='weekly_report', to='nutritionists.nutritionist')),
],
),
]
# Generated by Django 3.1 on 2021-05-29 15:40
from django.db import migrations, models
import multiselectfield.db.fields
class Migration(migrations.Migration):
dependencies = [
('diet_progress', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='weeklyreport',
name='feeling_rating',
field=models.IntegerField(choices=[(1, 'Rasanya mau menyerah saja'), (2, 'Capek, susah, bosen, males, repot, sibuk'), (3, 'Biasa aja, meski ada kendala tapi semua bisa diatur'), (4, 'Lancar terus, semangat cukup stabil, gak ada masalah'), (5, 'Super seneng, semangat banget, worry-free lah')], default=1),
preserve_default=False,
),
migrations.AddField(
model_name='weeklyreport',
name='fried_snacks',
field=models.IntegerField(choices=[(1, '0 gelas'), (2, '1 gelas'), (3, '2 gelas'), (4, '3 gelas'), (5, '4 gelas'), (6, 'Lebih dari 4 gelas')], default=1),
preserve_default=False,
),
migrations.AddField(
model_name='weeklyreport',
name='fruits_portion',
field=models.IntegerField(choices=[(1, '0 gelas'), (2, '1 gelas'), (3, '2 gelas'), (4, '3 gelas'), (5, '4 gelas'), (6, 'Lebih dari 4 gelas')], default=1),
preserve_default=False,
),
migrations.AddField(
model_name='weeklyreport',
name='lesson_learned',
field=models.TextField(default=1),
preserve_default=False,
),
migrations.AddField(
model_name='weeklyreport',
name='physical_activity',
field=multiselectfield.db.fields.MultiSelectField(choices=[(1, 'Tidak ada'), (2, 'Mual'), (3, 'Muntah'), (4, 'Susah buang air besar dalam 3 hari terakhir'), (5, 'Kesulitan mengunyah'), (6, 'Kesulitan menelan')], default=1, max_length=11),
preserve_default=False,
),
migrations.AddField(
model_name='weeklyreport',
name='physical_activity_other',
field=models.TextField(default=1),
preserve_default=False,
),
migrations.AddField(
model_name='weeklyreport',
name='problem_faced_and_feedbacks',
field=models.TextField(default=1),
preserve_default=False,
),
migrations.AddField(
model_name='weeklyreport',
name='sweet_snacks',
field=models.IntegerField(choices=[(1, '0 gelas'), (2, '1 gelas'), (3, '2 gelas'), (4, '3 gelas'), (5, '4 gelas'), (6, 'Lebih dari 4 gelas')], default=1),
preserve_default=False,
),
migrations.AddField(
model_name='weeklyreport',
name='time_for_activity',
field=models.IntegerField(choices=[(1, '0 - 60 menit'), (2, '60 - 100 menit'), (3, '100 - 120 menit'), (4, '100 - 120 menit'), (5, '120 - 150 menit'), (6, '150 - 175 menit'), (7, '175 - 200 menit'), (8, '200 - 250 menit'), (9, 'Lebih dari 250 menit')], default=1),
preserve_default=False,
),
migrations.AddField(
model_name='weeklyreport',
name='umami_snacks',
field=models.IntegerField(choices=[(1, '0 gelas'), (2, '1 gelas'), (3, '2 gelas'), (4, '3 gelas'), (5, '4 gelas'), (6, 'Lebih dari 4 gelas')], default=1),
preserve_default=False,
),
migrations.AddField(
model_name='weeklyreport',
name='vegetables_portion',
field=models.IntegerField(choices=[(1, '0 gelas'), (2, '1 gelas'), (3, '2 gelas'), (4, '3 gelas'), (5, '4 gelas'), (6, 'Lebih dari 4 gelas')], default=1),
preserve_default=False,
),
migrations.AddField(
model_name='weeklyreport',
name='water_consumption',
field=models.TextField(default=1),
preserve_default=False,
),
migrations.AddField(
model_name='weeklyreport',
name='week_num',
field=models.PositiveIntegerField(default=1),
preserve_default=False,
),
]
# Generated by Django 3.1 on 2021-05-29 16:08
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('diet_progress', '0002_auto_20210529_2240'),
]
operations = [
migrations.RemoveField(
model_name='weeklyreport',
name='lifestyle_advice',
),
migrations.RemoveField(
model_name='weeklyreport',
name='nutritional_advice',
),
]
# Generated by Django 3.1 on 2021-05-30 01:18
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import multiselectfield.db.fields
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('diet_progress', '0003_auto_20210529_2308'),
]
operations = [
migrations.AlterField(
model_name='weeklyreport',
name='client',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='weekly_report', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='weeklyreport',
name='physical_activity',
field=multiselectfield.db.fields.MultiSelectField(choices=[(1, 'Hampir tidak pernah olahraga dan/atau duduk lebih dari 9 jam perhari'), (2, 'Jalan kaki santai'), (3, 'Jalan kaki cepat'), (4, 'Pemanasan'), (5, 'Naik turun tangga'), (6, 'Jogging'), (7, 'Treadmill'), (8, 'Senam Aerobic/cardio, Recovery/Scratching, Dance dll'), (9, 'Latihan penguatan otot (strength workout, weight workout)'), (10, 'Other')], max_length=20),
),
]
# Generated by Django 3.1 on 2021-05-30 14:01
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('diet_progress', '0004_auto_20210530_0818'),
]
operations = [
migrations.CreateModel(
name='WeeklyReportComment',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('weight', models.TextField()),
('height', models.TextField()),
('waist_size', models.TextField()),
('changes_felt', models.TextField()),
('hunger_level', models.TextField()),
('fullness_level', models.TextField()),
('heavy_meal', models.TextField()),
('snacks', models.TextField()),
('average_consumption', models.TextField()),
('water_consumption', models.TextField()),
('physical_activity', models.TextField()),
('time_for_activity', models.TextField()),
('feeling_rating', models.TextField()),
('lesson_learned', models.TextField()),
('problem_faced_and_feedbacks', models.TextField()),
('weekly_report', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='weekly_report_comment', to='diet_progress.weeklyreport')),
],
),
]
......@@ -31,8 +31,6 @@ class WeeklyReport(models.Model):
weight = models.PositiveIntegerField()
height = models.PositiveIntegerField()
waist_size = models.PositiveIntegerField()
# This belongs to ONE field on gform
changes_felt = models.IntegerField(
choices=Changes.choices)
hunger_level = models.IntegerField(
......@@ -43,8 +41,11 @@ class WeeklyReport(models.Model):
choices=LargeMealInOneDay.choices)
snacks = models.IntegerField(
choices=SnacksInOneDay.choices)
# This belongs to ONE field on gform
sweet_beverages = models.IntegerField(
choices=ConsumptionInOneDay.choices)
sugary_ingredients = models.IntegerField(
choices=ConsumptionInOneDay.choices)
fried_snacks = models.IntegerField(
choices=ConsumptionInOneDay.choices)
umami_snacks = models.IntegerField(
......@@ -57,7 +58,7 @@ class WeeklyReport(models.Model):
choices=ConsumptionInOneDay.choices)
#########################################
water_consumption = models.TextField()
water_consumption = models.PositiveIntegerField()
physical_activity = MultiSelectField(
choices = PhysicalActivity.choices)
physical_activity_other = models.TextField()
......@@ -68,6 +69,8 @@ class WeeklyReport(models.Model):
lesson_learned = models.TextField()
problem_faced_and_feedbacks = models.TextField()
def __str__(self):
return f"{self.client} - {self.nutritionist} - Week {self.week_num}"
class WeeklyReportComment(models.Model):
weekly_report = models.OneToOneField(
......
from rest_framework import serializers, fields
from constants.model_choices import PhysicalActivity
from authentication.serializers import CustomUserDetailsSerializer
from .models import WeeklyReport, WeeklyReportComment
class WeeklyReportSerializer(serializers.ModelSerializer):
physical_activity = fields.MultipleChoiceField(
choices=PhysicalActivity.choices)
......@@ -11,6 +11,10 @@ class WeeklyReportSerializer(serializers.ModelSerializer):
model = WeeklyReport
fields = "__all__"
def to_representation(self, instance):
result = super().to_representation(instance)
result['client'] = CustomUserDetailsSerializer(instance.client).data
return result
class WeeklyReportCommentSerializer(serializers.ModelSerializer):
class Meta:
......
import json
import datetime
from unittest.mock import patch
from django.contrib.auth.models import Group
from rest_framework.test import APITestCase
from django.utils.encoding import force_text
from rest_framework import status
from rest_framework.response import Response
from dietela_program.models import DietelaProgram
from nutritionists.models import Nutritionist
from payment.models import Cart
from authentication.models import CustomUser
from .models import WeeklyReport, WeeklyReportComment
from .serializers import WeeklyReportSerializer, WeeklyReportCommentSerializer
......@@ -16,6 +19,12 @@ class WeeklyReportTest(APITestCase):
def setUpTestData(cls):
cls.BASE_URL = "/progress/user_report/"
cls.dietela_program_1 = DietelaProgram.objects.create(
unique_code="PRG1",
name="Program 1",
price=350000.00,
)
cls.nutritionist_1 = Nutritionist.objects.create(
id=1,
full_name_and_degree="Test, S.Gz",
......@@ -43,6 +52,62 @@ class WeeklyReportTest(APITestCase):
deadline = (datetime.date.today() + datetime.timedelta(days=3)),
)
cls.custom_user_3 = CustomUser.objects.create_user(
name='nutrijel',
email='e2mail2@email.com',
password='abc',
nutritionist=cls.nutritionist_1,
deadline = (datetime.date.today() + datetime.timedelta(days=32)),
)
cls.g0 = Group.objects.get(name='client')
cls.g0.user_set.remove(cls.custom_user_3)
cls.g1 = Group.objects.create(name='nutritionist')
cls.g1.user_set.add(cls.custom_user_3)
cls.cart_1 = Cart.objects.create(
user = cls.custom_user_1,
program = cls.dietela_program_1,
nutritionist = cls.nutritionist_1,
program_end_date = datetime.date.today() + datetime.timedelta(days=53),
)
cls.cart_2 = Cart.objects.create(
user = cls.custom_user_2,
program = cls.dietela_program_1,
nutritionist = cls.nutritionist_1,
program_end_date = datetime.date.today() + datetime.timedelta(days=13),
)
cls.weekly_report_1 = WeeklyReport.objects.create(
client = cls.custom_user_2,
nutritionist = cls.nutritionist_1,
week_num = 1,
weight= 155,
height= 188,
waist_size= 100,
changes_felt= 1,
hunger_level = 1,
fullness_level= 1,
heavy_meal= 1,
snacks= 1,
sweet_beverages=1,
sugary_ingredients=1,
fried_snacks=1,
umami_snacks=1,
sweet_snacks=1,
fruits_portion=1,
vegetables_portion=1,
water_consumption = 3,
physical_activity= [1,2],
physical_activity_other = "n",
time_for_activity=1,
feeling_rating=2,
lesson_learned="a",
problem_faced_and_feedbacks="x"
)
def test_post_reports_api_success(self):
url = f"{self.BASE_URL}"
......@@ -67,12 +132,13 @@ class WeeklyReportTest(APITestCase):
"heavy_meal": 1,
"snacks": 1,
"sweet_beverages":1,
"sugary_ingredients":1,
"fried_snacks":1,
"umami_snacks":1,
"sweet_snacks":1,
"fruits_portion":1,
"vegetables_portion":1,
"water_consumption" : "aw",
"water_consumption" : 3,
"physical_activity": [1,2],
"physical_activity_other" : "n",
"time_for_activity":1,
......@@ -121,6 +187,56 @@ class WeeklyReportTest(APITestCase):
self.assertEqual(response.data, serializer.data)
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_get_specific_weekly_report(self):
response = self.client.get("/progress/user_report/?client_id=" + str(self.custom_user_2.id))
reports = WeeklyReport.objects.filter(client=self.custom_user_2)
reports = reports.order_by('week_num')
serializer = WeeklyReportSerializer(reports, many=True)
self.assertEqual(response.data, serializer.data)
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_get_user_weekly_report_belonging_to_a_nutritionist(self):
data = {
'email': 'email@email.com',
'password': 'abc',
'role': 'client',
}
response = self.client.post('/auth/user-login/', data, format='json')
json_response = json.loads(response.content)
self.client.credentials(HTTP_AUTHORIZATION='Bearer ' + json_response['access_token'])
response = self.client.get("/progress/user_report/?client_id=" + str(self.custom_user_2.id))
reports = WeeklyReport.objects.filter(client=self.custom_user_2)
reports = reports.order_by('week_num')
serializer = WeeklyReportSerializer(reports, many=True)
self.assertEqual(response.data, serializer.data)
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_get_user_weekly_report_belonging_to_non_nutritionist(self):
data = {
'email': 'e2mail2@email.com',
'password': 'abc',
'role': 'nutritionist',
}