From b67061f5f8cab09fd38077813de15c04ec0d55ba Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Thu, 16 Jul 2020 10:48:30 +0700 Subject: [PATCH 01/41] membuat class mustahik --- sizakat/apps/mustahik/models.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sizakat/apps/mustahik/models.py b/sizakat/apps/mustahik/models.py index fd18c6e..a85d999 100644 --- a/sizakat/apps/mustahik/models.py +++ b/sizakat/apps/mustahik/models.py @@ -1,3 +1,7 @@ from django.db import models # Create your models here. + + +class Mustahik(models.Model): + pass -- GitLab From 265a05bfdfd94e2570f9f68f4ede2e7b29dca42f Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Thu, 16 Jul 2020 10:54:16 +0700 Subject: [PATCH 02/41] [RED] membuat test_mustahik_model --- sizakat/apps/mustahik/tests.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/sizakat/apps/mustahik/tests.py b/sizakat/apps/mustahik/tests.py index de8bdc0..4997f5a 100644 --- a/sizakat/apps/mustahik/tests.py +++ b/sizakat/apps/mustahik/tests.py @@ -1,3 +1,26 @@ +from datetime import date from django.test import TestCase -# Create your tests here. +from .models import Mustahik + + +class MustahikModelTestCase(TestCase): + def setUp(self): + Mustahik.objects.create( + name='mustahik', + no_ktp='31751234567890', + phone='081234567890', + address='Jalan raya depok', + province='Jawa Barat', + regency='Depok', + rt='003', + rw='002', + birthdate=date(1987, 6, 5), + status=Mustahik.Status.MISKIN, + family_size=4, + description='desc' + ) + + def test_mustahik_creation(self): + mustahik = Mustahik.objects.get(no_ktp='31751234567890') + self.assertTrue(isinstance(mustahik, Mustahik)) -- GitLab From acdd7f6dd78a82497b4247c070ad2b0d85c2d97d Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Thu, 16 Jul 2020 11:18:34 +0700 Subject: [PATCH 03/41] [GREEN] implementasi model mustahik --- sizakat/apps/mustahik/models.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/sizakat/apps/mustahik/models.py b/sizakat/apps/mustahik/models.py index a85d999..81316b7 100644 --- a/sizakat/apps/mustahik/models.py +++ b/sizakat/apps/mustahik/models.py @@ -4,4 +4,25 @@ from django.db import models class Mustahik(models.Model): - pass + + class Status(models.TextChoices): + JANDA = ('JANDA', 'Janda') + MISKIN = ('MISKIN', 'Miskin') + YATIM = ('YATIM', 'Yatim') + + name = models.CharField(max_length=32) + no_ktp = models.CharField(max_length=32) + phone = models.CharField(max_length=32, blank=True) + address = models.TextField() + province = models.CharField(max_length=32) + regency = models.CharField(max_length=32) + rt = models.CharField(max_length=4) + rw = models.CharField(max_length=4) + birthdate = models.DateField() + status = models.CharField( + max_length=32, + choices=Status.choices, + default=Status.MISKIN, + ) + family_size = models.PositiveSmallIntegerField() + description = models.TextField() -- GitLab From c6fa6cb0fa624a98e12991ce3cea832f37bf4166 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Thu, 16 Jul 2020 11:19:31 +0700 Subject: [PATCH 04/41] [CHORES] penambahan app mustahik --- sizakat/settings.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sizakat/settings.py b/sizakat/settings.py index f2caf3f..0d410ec 100644 --- a/sizakat/settings.py +++ b/sizakat/settings.py @@ -38,6 +38,7 @@ INSTALLED_APPS = [ 'django.contrib.messages', 'django.contrib.staticfiles', 'graphene_django', + 'sizakat.apps.mustahik' ] GRAPHENE = { -- GitLab From 1c941264e8d14219da069a3fd9d4b38363d94646 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Thu, 16 Jul 2020 13:59:34 +0700 Subject: [PATCH 05/41] [RED] membuat test_no_ktp_mustahik_is_unique --- sizakat/apps/mustahik/tests.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/sizakat/apps/mustahik/tests.py b/sizakat/apps/mustahik/tests.py index 4997f5a..1dffa8b 100644 --- a/sizakat/apps/mustahik/tests.py +++ b/sizakat/apps/mustahik/tests.py @@ -1,4 +1,5 @@ from datetime import date +from django.db.utils import IntegrityError from django.test import TestCase from .models import Mustahik @@ -24,3 +25,20 @@ class MustahikModelTestCase(TestCase): def test_mustahik_creation(self): mustahik = Mustahik.objects.get(no_ktp='31751234567890') self.assertTrue(isinstance(mustahik, Mustahik)) + + def test_no_ktp_mustahik_is_unique(self): + with self.assertRaises(IntegrityError): + Mustahik.objects.create( + name='kihatsum', + no_ktp='31751234567890', + phone='08987654321', + address='Jalan raya bogor', + province='Jawa Barat', + regency='Bogor', + rt='002', + rw='003', + birthdate=date(1987, 4, 3), + status=Mustahik.Status.MISKIN, + family_size=1, + description='no_ktp is unique' + ) -- GitLab From bcfc1ad825fdab651588cd264170ff73ba06e2bd Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Thu, 16 Jul 2020 14:00:19 +0700 Subject: [PATCH 06/41] [GREEN] menambahkan constraint unique pada attribute no_ktp --- sizakat/apps/mustahik/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sizakat/apps/mustahik/models.py b/sizakat/apps/mustahik/models.py index 81316b7..0468613 100644 --- a/sizakat/apps/mustahik/models.py +++ b/sizakat/apps/mustahik/models.py @@ -11,7 +11,7 @@ class Mustahik(models.Model): YATIM = ('YATIM', 'Yatim') name = models.CharField(max_length=32) - no_ktp = models.CharField(max_length=32) + no_ktp = models.CharField(max_length=32, unique=True) phone = models.CharField(max_length=32, blank=True) address = models.TextField() province = models.CharField(max_length=32) -- GitLab From 083aa62d6b4b42b56275eebcdf18c3f629a13959 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Fri, 17 Jul 2020 09:41:06 +0700 Subject: [PATCH 07/41] [RED] membuat test mutasi tambah dan ubah mustahik --- sizakat/apps/mustahik/tests.py | 117 +++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/sizakat/apps/mustahik/tests.py b/sizakat/apps/mustahik/tests.py index 1dffa8b..6b0c259 100644 --- a/sizakat/apps/mustahik/tests.py +++ b/sizakat/apps/mustahik/tests.py @@ -1,6 +1,10 @@ +import json + from datetime import date from django.db.utils import IntegrityError from django.test import TestCase +from graphene_django.utils.testing import GraphQLTestCase +from sizakat.schema import schema from .models import Mustahik @@ -42,3 +46,116 @@ class MustahikModelTestCase(TestCase): family_size=1, description='no_ktp is unique' ) + + +class MustahikGraphQLTestCase(GraphQLTestCase): + GRAPHQL_SCHEMA = schema + + def setUp(self): + Mustahik.objects.create( + name='mustahik', + no_ktp='31751234567890', + phone='081234567890', + address='Jalan raya depok', + province='Jawa Barat', + regency='Depok', + rt='003', + rw='002', + birthdate=date(1987, 6, 5), + status=Mustahik.Status.MISKIN, + family_size=4, + description='desc' + ) + + def test_mustahik_mutation_can_add_new_mustahik(self): + no_ktp = '123891210121' + response = self.query( + ''' + mutation mustahikMutation($input: MustahikMutationInput!) { + mustahikMutation(input: $input) { + mustahik { + id + name + noKtp + status + description + } + errors { + field + messages + } + } + } + ''', + op_name='mustahikMutation', + input_data={ + "name": "jumat", + "noKtp": no_ktp, + "phone": "02132132180", + "address": "jalan swadaya", + "province": "jakarta", + "regency": "manggarai", + "rt": "001", + "rw": "001", + "birthdate": "1998-03-12", + "status": "YATIM", + "familySize": 3, + "description": "anak yatim" + } + ) + + # This validates the status code and if you get errors + self.assertResponseNoErrors(response) + + # Validate content + content = json.loads(response.content) + self.assertEqual(content['data']['mustahikMutation'] + ['mustahik']['status'], 'YATIM') + + # Validate success save to db + self.assertNotEqual(Mustahik.objects.count(), 0) + mustahik = Mustahik.objects.get(no_ktp=no_ktp) + self.assertEqual(mustahik.name, 'jumat') + + def test_mustahik_mutation_can_update_mustahik(self): + mustahik = Mustahik.objects.get(no_ktp='31751234567890') + mustahik_id = mustahik.pk + old_desc = mustahik.description + new_desc = 'keluarga tidak mampu' + response = self.query( + ''' + mutation mustahikMutation($input: MustahikMutationInput!) { + mustahikMutation(input: $input) { + mustahik { + id + description + } + errors { + field + messages + } + } + } + ''', + op_name='mustahikMutation', + input_data={ + "name": "mustahik", + "noKtp": "31751234567890", + "phone": "081234567890", + "address": "Jalan raya depok", + "province": "Jawa Barat", + "regency": "Depok", + "rt": "003", + "rw": "002", + "birthdate": "1987-06-05", + "status": "MISKIN", + "familySize": 4, + "description": new_desc, + "id": mustahik.pk + } + ) + + # Validate success update desc mustahik + mustahik = Mustahik.objects.get(no_ktp='31751234567890') + self.assertNotEqual(mustahik.description, old_desc) + self.assertEqual(mustahik.description, new_desc) -- GitLab From 493026c6c0f2d84fc8bff353a13ebd125a5159b9 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Fri, 17 Jul 2020 09:41:53 +0700 Subject: [PATCH 08/41] [GREEN] membuat mutasi tambah dan ubah mustahik --- sizakat/apps/mustahik/models.py | 4 ++-- sizakat/apps/mustahik/mutations.py | 35 ++++++++++++++++++++++++++++++ sizakat/apps/mustahik/types.py | 10 +++++++++ sizakat/schema.py | 12 ++++++++-- 4 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 sizakat/apps/mustahik/mutations.py create mode 100644 sizakat/apps/mustahik/types.py diff --git a/sizakat/apps/mustahik/models.py b/sizakat/apps/mustahik/models.py index 0468613..267fdaa 100644 --- a/sizakat/apps/mustahik/models.py +++ b/sizakat/apps/mustahik/models.py @@ -12,7 +12,7 @@ class Mustahik(models.Model): name = models.CharField(max_length=32) no_ktp = models.CharField(max_length=32, unique=True) - phone = models.CharField(max_length=32, blank=True) + phone = models.CharField(max_length=32, blank=True, null=True) address = models.TextField() province = models.CharField(max_length=32) regency = models.CharField(max_length=32) @@ -25,4 +25,4 @@ class Mustahik(models.Model): default=Status.MISKIN, ) family_size = models.PositiveSmallIntegerField() - description = models.TextField() + description = models.TextField(blank=True, null=True) diff --git a/sizakat/apps/mustahik/mutations.py b/sizakat/apps/mustahik/mutations.py new file mode 100644 index 0000000..ee12875 --- /dev/null +++ b/sizakat/apps/mustahik/mutations.py @@ -0,0 +1,35 @@ +import graphene + +from django import forms +from graphene_django.forms.mutation import DjangoModelFormMutation + +from .models import Mustahik +from .types import MustahikType + + +class MustahikForm(forms.ModelForm): + + class Meta: + model = Mustahik + fields = [ + 'name', + 'no_ktp', + 'phone', + 'address', + 'province', + 'regency', + 'rt', + 'rw', + 'birthdate', + 'status', + 'family_size', + 'description', + ] + + +class MustahikMutation(DjangoModelFormMutation): + + mustahik = graphene.Field(MustahikType) + + class Meta: + form_class = MustahikForm diff --git a/sizakat/apps/mustahik/types.py b/sizakat/apps/mustahik/types.py new file mode 100644 index 0000000..cf9dba9 --- /dev/null +++ b/sizakat/apps/mustahik/types.py @@ -0,0 +1,10 @@ +import graphene + +from graphene_django.types import DjangoObjectType +from .models import Mustahik + + +class MustahikType(DjangoObjectType): + + class Meta: + model = Mustahik diff --git a/sizakat/schema.py b/sizakat/schema.py index 642be04..3737a29 100644 --- a/sizakat/schema.py +++ b/sizakat/schema.py @@ -1,14 +1,22 @@ -from graphene_django import DjangoObjectType import graphene +from graphene_django import DjangoObjectType +from .apps.mustahik.mutations import MustahikMutation + ABOUT = 'Si Zakat merupakan sistem informasi untuk membantu masjid dalam \ mengelola transaksi zakat. Sistem ini dibuat oleh tim lab 1231, \ yang dipimpin oleh Prof. Dr. Wisnu Jatmiko.' + class Query(graphene.ObjectType): about = graphene.String() def resolve_about(self, info): return ABOUT -schema = graphene.Schema(query=Query) + +class Mutation(graphene.ObjectType): + mustahik_mutation = MustahikMutation.Field() + + +schema = graphene.Schema(query=Query, mutation=Mutation) -- GitLab From c5737f806f0f98dacd2ebb2165279bf2d720414f Mon Sep 17 00:00:00 2001 From: Naufal Alauddin Hilmi <naufalauddin@gmail.com> Date: Fri, 17 Jul 2020 17:25:21 +0700 Subject: [PATCH 09/41] [RED] test for mustahik filter query --- sizakat/apps/mustahik/tests.py | 74 ++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/sizakat/apps/mustahik/tests.py b/sizakat/apps/mustahik/tests.py index 6b0c259..7bfe64c 100644 --- a/sizakat/apps/mustahik/tests.py +++ b/sizakat/apps/mustahik/tests.py @@ -159,3 +159,77 @@ class MustahikGraphQLTestCase(GraphQLTestCase): mustahik = Mustahik.objects.get(no_ktp='31751234567890') self.assertNotEqual(mustahik.description, old_desc) self.assertEqual(mustahik.description, new_desc) + + def test_query_mustahik_should_return_list_of_mustahiks(self): + response = self.query( + ''' + query mustahiksQuery{ + mustahiks { + id, + name + } + } + ''', + op_name='mustahiksQuery' + ) + + self.assertResponseNoErrors(response) + + content = json.loads(response.content) + self.assertEqual(len(content['data']['mustahiks']), 1) + self.assertEqual(content['data']['mustahiks'][0]['name'], 'mustahik') + + def test_query_mustahiks_if_statuses_is_set_should_return_list_of_mustahiks_with_coresponding_status(self): + Mustahik.objects.create( + name='test', + no_ktp='11751234567890', + phone='081234567890', + address='Jalan raya depok', + province='Jawa Barat', + regency='Depok', + rt='003', + rw='002', + birthdate=date(1987, 6, 5), + status=Mustahik.Status.YATIM, + family_size=4, + description='desc' + ) + + response = self.query( + ''' + query mustahiksQuery($statuses: [String]) { + mustahiks(statuses: $statuses) { + id, + name, + status + } + } + ''', + op_name='mustahiksQuery', + variables={'statuses': [Mustahik.Status.MISKIN]} + ) + + content = json.loads(response.content) + self.assertEqual(len(content['data']['mustahiks']), 1) + + for mustahik in content['data']['mustahiks']: + self.assertEqual(mustahik['status'], Mustahik.Status.MISKIN) + + def test_query_mustahiks_if_statuses_is_provided_and_no_mustahiks_are_qualified_it_should_return_empty_list(self): + response = self.query( + ''' + query mustahiksQuery($statuses: [String]) { + mustahiks(statuses: $statuses) { + id, + name, + status + } + } + ''', + op_name='mustahiksQuery', + variables={'statuses': [Mustahik.Status.JANDA]} + ) + + content = json.loads(response.content) + self.assertEqual(len(content['data']['mustahiks']), 0) + -- GitLab From fd19d39d3d7125c1b7232db07e94b6f58f477769 Mon Sep 17 00:00:00 2001 From: Naufal Alauddin Hilmi <naufalauddin@gmail.com> Date: Fri, 17 Jul 2020 17:27:13 +0700 Subject: [PATCH 10/41] [GREEN] create query for filter and get mustahik --- sizakat/apps/mustahik/query.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 sizakat/apps/mustahik/query.py diff --git a/sizakat/apps/mustahik/query.py b/sizakat/apps/mustahik/query.py new file mode 100644 index 0000000..70df3e5 --- /dev/null +++ b/sizakat/apps/mustahik/query.py @@ -0,0 +1,17 @@ +import graphene +from django.db.models import Q + +from .models import Mustahik +from .types import MustahikType + +class MustahikQuery(graphene.ObjectType): + mustahiks = graphene.List(MustahikType, statuses=graphene.List(graphene.String)) + + def resolve_mustahiks(self, info, statuses=[], **kwargs): + if statuses and len(statuses) > 0: + filter = Q(status=statuses[0]) + for status in statuses: + filter = filter | Q(status=status) + return Mustahik.objects.filter(filter) + + return Mustahik.objects.all() -- GitLab From a3a0f3f9fc40e71c1f526b3d680ef815ba77d9a3 Mon Sep 17 00:00:00 2001 From: Naufal Alauddin Hilmi <naufalauddin@gmail.com> Date: Fri, 17 Jul 2020 17:28:23 +0700 Subject: [PATCH 11/41] [GREEN] add Mustahik query to the schema --- sizakat/schema.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sizakat/schema.py b/sizakat/schema.py index 3737a29..93b39bb 100644 --- a/sizakat/schema.py +++ b/sizakat/schema.py @@ -2,13 +2,14 @@ import graphene from graphene_django import DjangoObjectType from .apps.mustahik.mutations import MustahikMutation +from .apps.mustahik.query import MustahikQuery ABOUT = 'Si Zakat merupakan sistem informasi untuk membantu masjid dalam \ mengelola transaksi zakat. Sistem ini dibuat oleh tim lab 1231, \ yang dipimpin oleh Prof. Dr. Wisnu Jatmiko.' -class Query(graphene.ObjectType): +class Query(MustahikQuery, graphene.ObjectType): about = graphene.String() def resolve_about(self, info): -- GitLab From 3c759810210a041bccc5bb5963437ffc1be504a1 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Fri, 17 Jul 2020 20:16:40 +0700 Subject: [PATCH 12/41] [CHORES] update cors in settings and fix path migrations in .gitignore --- .gitignore | 2 +- sizakat/settings.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index db16b24..31d9ad9 100644 --- a/.gitignore +++ b/.gitignore @@ -67,7 +67,7 @@ coverage.xml staticfiles/ # migrations file -*/migrations/ +/**/migrations/ # Jupyter Notebook .ipynb_checkpoints diff --git a/sizakat/settings.py b/sizakat/settings.py index 0d410ec..105329d 100644 --- a/sizakat/settings.py +++ b/sizakat/settings.py @@ -38,6 +38,7 @@ INSTALLED_APPS = [ 'django.contrib.messages', 'django.contrib.staticfiles', 'graphene_django', + 'corsheaders', 'sizakat.apps.mustahik' ] @@ -48,6 +49,7 @@ GRAPHENE = { MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', + 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', @@ -55,6 +57,8 @@ MIDDLEWARE = [ 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] +CORS_ORIGIN_WHITELIST = os.environ.get('CORS_ORIGIN_WHITELIST').split() + ROOT_URLCONF = 'sizakat.urls' TEMPLATES = [ -- GitLab From d8009e5fbd49b5f3f5338e2be26d73c62091f4a9 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Fri, 17 Jul 2020 20:21:08 +0700 Subject: [PATCH 13/41] [REFACTOR] change django apps structure --- sizakat/apps/mustahik/migrations/__init__.py | 0 sizakat/{apps => }/mustahik/__init__.py | 0 sizakat/{apps => }/mustahik/admin.py | 0 sizakat/{apps => }/mustahik/apps.py | 0 sizakat/{apps => }/mustahik/models.py | 0 sizakat/{apps => }/mustahik/mutations.py | 0 sizakat/{apps => }/mustahik/query.py | 0 sizakat/{apps => }/mustahik/tests.py | 0 sizakat/{apps => }/mustahik/types.py | 0 sizakat/schema.py | 5 +++-- sizakat/settings.py | 2 +- 11 files changed, 4 insertions(+), 3 deletions(-) delete mode 100644 sizakat/apps/mustahik/migrations/__init__.py rename sizakat/{apps => }/mustahik/__init__.py (100%) rename sizakat/{apps => }/mustahik/admin.py (100%) rename sizakat/{apps => }/mustahik/apps.py (100%) rename sizakat/{apps => }/mustahik/models.py (100%) rename sizakat/{apps => }/mustahik/mutations.py (100%) rename sizakat/{apps => }/mustahik/query.py (100%) rename sizakat/{apps => }/mustahik/tests.py (100%) rename sizakat/{apps => }/mustahik/types.py (100%) diff --git a/sizakat/apps/mustahik/migrations/__init__.py b/sizakat/apps/mustahik/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/sizakat/apps/mustahik/__init__.py b/sizakat/mustahik/__init__.py similarity index 100% rename from sizakat/apps/mustahik/__init__.py rename to sizakat/mustahik/__init__.py diff --git a/sizakat/apps/mustahik/admin.py b/sizakat/mustahik/admin.py similarity index 100% rename from sizakat/apps/mustahik/admin.py rename to sizakat/mustahik/admin.py diff --git a/sizakat/apps/mustahik/apps.py b/sizakat/mustahik/apps.py similarity index 100% rename from sizakat/apps/mustahik/apps.py rename to sizakat/mustahik/apps.py diff --git a/sizakat/apps/mustahik/models.py b/sizakat/mustahik/models.py similarity index 100% rename from sizakat/apps/mustahik/models.py rename to sizakat/mustahik/models.py diff --git a/sizakat/apps/mustahik/mutations.py b/sizakat/mustahik/mutations.py similarity index 100% rename from sizakat/apps/mustahik/mutations.py rename to sizakat/mustahik/mutations.py diff --git a/sizakat/apps/mustahik/query.py b/sizakat/mustahik/query.py similarity index 100% rename from sizakat/apps/mustahik/query.py rename to sizakat/mustahik/query.py diff --git a/sizakat/apps/mustahik/tests.py b/sizakat/mustahik/tests.py similarity index 100% rename from sizakat/apps/mustahik/tests.py rename to sizakat/mustahik/tests.py diff --git a/sizakat/apps/mustahik/types.py b/sizakat/mustahik/types.py similarity index 100% rename from sizakat/apps/mustahik/types.py rename to sizakat/mustahik/types.py diff --git a/sizakat/schema.py b/sizakat/schema.py index 93b39bb..f287b17 100644 --- a/sizakat/schema.py +++ b/sizakat/schema.py @@ -1,8 +1,9 @@ import graphene from graphene_django import DjangoObjectType -from .apps.mustahik.mutations import MustahikMutation -from .apps.mustahik.query import MustahikQuery + +from .mustahik.mutations import MustahikMutation +from .mustahik.query import MustahikQuery ABOUT = 'Si Zakat merupakan sistem informasi untuk membantu masjid dalam \ mengelola transaksi zakat. Sistem ini dibuat oleh tim lab 1231, \ diff --git a/sizakat/settings.py b/sizakat/settings.py index 105329d..1658e6d 100644 --- a/sizakat/settings.py +++ b/sizakat/settings.py @@ -39,7 +39,7 @@ INSTALLED_APPS = [ 'django.contrib.staticfiles', 'graphene_django', 'corsheaders', - 'sizakat.apps.mustahik' + 'sizakat.mustahik' ] GRAPHENE = { -- GitLab From 549622a50ab2289d5c86ff48081581bf18d88395 Mon Sep 17 00:00:00 2001 From: Ilma Ainur Rohma <ilma13rohma@gmail.com> Date: Sat, 18 Jul 2020 14:42:00 +0700 Subject: [PATCH 14/41] [RED] add test for read detail and delete --- sizakat/mustahik/mutations.py | 2 +- sizakat/mustahik/query.py | 1 + sizakat/mustahik/tests.py | 52 +++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/sizakat/mustahik/mutations.py b/sizakat/mustahik/mutations.py index ee12875..62c6266 100644 --- a/sizakat/mustahik/mutations.py +++ b/sizakat/mustahik/mutations.py @@ -32,4 +32,4 @@ class MustahikMutation(DjangoModelFormMutation): mustahik = graphene.Field(MustahikType) class Meta: - form_class = MustahikForm + form_class = MustahikForm \ No newline at end of file diff --git a/sizakat/mustahik/query.py b/sizakat/mustahik/query.py index 70df3e5..57a1583 100644 --- a/sizakat/mustahik/query.py +++ b/sizakat/mustahik/query.py @@ -15,3 +15,4 @@ class MustahikQuery(graphene.ObjectType): return Mustahik.objects.filter(filter) return Mustahik.objects.all() + diff --git a/sizakat/mustahik/tests.py b/sizakat/mustahik/tests.py index 7bfe64c..54d63c6 100644 --- a/sizakat/mustahik/tests.py +++ b/sizakat/mustahik/tests.py @@ -233,3 +233,55 @@ class MustahikGraphQLTestCase(GraphQLTestCase): content = json.loads(response.content) self.assertEqual(len(content['data']['mustahiks']), 0) + def test_mustahik_mutation_can_delete_mustahik(self): + count = Mustahik.objects.count() + response = self.query( + ''' + mutation{ + deleteMustahik(id: 3) { + mustahik { + id + name + } + } + } + ''', + ) + self.assertResponseNoErrors(response) + + content = json.loads(response.content) + self.assertIsNone(content['data']['deleteMustahik']) + self.assertEquals(Mustahik.objects.count(), count-1) + + def test_mustahik_query_can_read_detail_mustahik(self): + mustahik = Mustahik.objects.get(no_ktp='31751234567890') + mustahik_id = mustahik.pk + response = self.query( + ''' + query detailMustahikQuery($id:ID){ + mustahik(id:$id){ + id + name + noKtp + phone + address + province + regency + rt + rw + birthdate + status + familySize + description + } + } + ''', + op_name='detailMustahikQuery', + variables={'id':mustahik_id} + ) + content = json.loads(response.content) + self.assertEqual(len(content['data']), 1) + self.assertEqual(content['data']['mustahik']['name'], 'mustahik') + self.assertEqual(content['data']['mustahik']['noKtp'], '31751234567890') + self.assertEqual(content['data']['mustahik']['address'], 'Jalan raya depok') + \ No newline at end of file -- GitLab From db50eef5e695eab538d731fc11cd1762ca015fd1 Mon Sep 17 00:00:00 2001 From: Ilma Ainur Rohma <ilma13rohma@gmail.com> Date: Sat, 18 Jul 2020 15:02:56 +0700 Subject: [PATCH 15/41] [GREEN] add read detail query and delete mutation --- sizakat/mustahik/mutations.py | 13 ++++++++++++- sizakat/mustahik/query.py | 6 ++++++ sizakat/mustahik/tests.py | 2 ++ sizakat/schema.py | 3 ++- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/sizakat/mustahik/mutations.py b/sizakat/mustahik/mutations.py index 62c6266..4cf800b 100644 --- a/sizakat/mustahik/mutations.py +++ b/sizakat/mustahik/mutations.py @@ -32,4 +32,15 @@ class MustahikMutation(DjangoModelFormMutation): mustahik = graphene.Field(MustahikType) class Meta: - form_class = MustahikForm \ No newline at end of file + form_class = MustahikForm + +class DeleteMustahik(graphene.Mutation): + class Arguments: + id = graphene.ID() + + mustahik = graphene.Field(MustahikType) + + def mutate(self, info, id): + mustahik = Mustahik.objects.get(pk=id) + if mustahik is not None: + mustahik.delete() diff --git a/sizakat/mustahik/query.py b/sizakat/mustahik/query.py index 57a1583..be7accf 100644 --- a/sizakat/mustahik/query.py +++ b/sizakat/mustahik/query.py @@ -6,6 +6,7 @@ from .types import MustahikType class MustahikQuery(graphene.ObjectType): mustahiks = graphene.List(MustahikType, statuses=graphene.List(graphene.String)) + mustahik = graphene.Field(MustahikType, id=graphene.ID()) def resolve_mustahiks(self, info, statuses=[], **kwargs): if statuses and len(statuses) > 0: @@ -16,3 +17,8 @@ class MustahikQuery(graphene.ObjectType): return Mustahik.objects.all() + def resolve_mustahik(self, info, id): + mustahik = Mustahik.objects.get(pk=id) + if mustahik is not None: + return mustahik + diff --git a/sizakat/mustahik/tests.py b/sizakat/mustahik/tests.py index 54d63c6..372a8d1 100644 --- a/sizakat/mustahik/tests.py +++ b/sizakat/mustahik/tests.py @@ -279,6 +279,8 @@ class MustahikGraphQLTestCase(GraphQLTestCase): op_name='detailMustahikQuery', variables={'id':mustahik_id} ) + self.assertResponseNoErrors(response) + content = json.loads(response.content) self.assertEqual(len(content['data']), 1) self.assertEqual(content['data']['mustahik']['name'], 'mustahik') diff --git a/sizakat/schema.py b/sizakat/schema.py index f287b17..f7d47ba 100644 --- a/sizakat/schema.py +++ b/sizakat/schema.py @@ -2,7 +2,7 @@ import graphene from graphene_django import DjangoObjectType -from .mustahik.mutations import MustahikMutation +from .mustahik.mutations import MustahikMutation, DeleteMustahik from .mustahik.query import MustahikQuery ABOUT = 'Si Zakat merupakan sistem informasi untuk membantu masjid dalam \ @@ -19,6 +19,7 @@ class Query(MustahikQuery, graphene.ObjectType): class Mutation(graphene.ObjectType): mustahik_mutation = MustahikMutation.Field() + delete_mustahik = DeleteMustahik.Field() schema = graphene.Schema(query=Query, mutation=Mutation) -- GitLab From 847daff12f48b1c55edfcd41f4a7395085bb25d7 Mon Sep 17 00:00:00 2001 From: Ilma Ainur Rohma <ilma13rohma@gmail.com> Date: Thu, 23 Jul 2020 15:40:41 +0700 Subject: [PATCH 16/41] [REFACTOR] add message in delete mutation --- sizakat/mustahik/mutations.py | 10 ++++++++-- sizakat/mustahik/tests.py | 7 ++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/sizakat/mustahik/mutations.py b/sizakat/mustahik/mutations.py index 4cf800b..7d352ca 100644 --- a/sizakat/mustahik/mutations.py +++ b/sizakat/mustahik/mutations.py @@ -38,9 +38,15 @@ class DeleteMustahik(graphene.Mutation): class Arguments: id = graphene.ID() + message = graphene.String() + idMustahik = graphene.ID() + nama = graphene.String() + noKtp = graphene.String() mustahik = graphene.Field(MustahikType) def mutate(self, info, id): mustahik = Mustahik.objects.get(pk=id) - if mustahik is not None: - mustahik.delete() + _nama = mustahik.name + _no_ktp = mustahik.no_ktp + mustahik.delete() + return DeleteMustahik(message = "Success", idMustahik=id, nama=_nama, noKtp=_no_ktp) \ No newline at end of file diff --git a/sizakat/mustahik/tests.py b/sizakat/mustahik/tests.py index 372a8d1..e87f6eb 100644 --- a/sizakat/mustahik/tests.py +++ b/sizakat/mustahik/tests.py @@ -243,6 +243,10 @@ class MustahikGraphQLTestCase(GraphQLTestCase): id name } + message + idMustahik + nama + noKtp } } ''', @@ -250,7 +254,8 @@ class MustahikGraphQLTestCase(GraphQLTestCase): self.assertResponseNoErrors(response) content = json.loads(response.content) - self.assertIsNone(content['data']['deleteMustahik']) + self.assertIsNone(content['data']['deleteMustahik']['mustahik']) + self.assertEquals(content['data']['deleteMustahik']['message'], "Success") self.assertEquals(Mustahik.objects.count(), count-1) def test_mustahik_query_can_read_detail_mustahik(self): -- GitLab From d85ecd8be1d1a0f7b137179a3ab5d8b528792951 Mon Sep 17 00:00:00 2001 From: abdurrafiarief <abdurrafiarief@gmail.com> Date: Fri, 24 Jul 2020 16:45:40 +0700 Subject: [PATCH 17/41] [RED] test for search mustahik with name --- sizakat/mustahik/mutations.py | 11 +++- sizakat/mustahik/query.py | 7 +++ sizakat/mustahik/tests.py | 109 ++++++++++++++++++++++++++++++++-- sizakat/settings.py | 2 +- 4 files changed, 122 insertions(+), 7 deletions(-) diff --git a/sizakat/mustahik/mutations.py b/sizakat/mustahik/mutations.py index 4cf800b..55fd8ef 100644 --- a/sizakat/mustahik/mutations.py +++ b/sizakat/mustahik/mutations.py @@ -38,9 +38,16 @@ class DeleteMustahik(graphene.Mutation): class Arguments: id = graphene.ID() + message = graphene.String() + idMustahik = graphene.ID() + nama = graphene.String() + noKtp = graphene.String() mustahik = graphene.Field(MustahikType) def mutate(self, info, id): mustahik = Mustahik.objects.get(pk=id) - if mustahik is not None: - mustahik.delete() + _nama = mustahik.name + _no_ktp = mustahik.no_ktp + mustahik.delete() + return DeleteMustahik(message = "Success", idMustahik=id, nama=_nama, noKtp=_no_ktp) + diff --git a/sizakat/mustahik/query.py b/sizakat/mustahik/query.py index be7accf..be4165c 100644 --- a/sizakat/mustahik/query.py +++ b/sizakat/mustahik/query.py @@ -4,9 +4,11 @@ from django.db.models import Q from .models import Mustahik from .types import MustahikType + class MustahikQuery(graphene.ObjectType): mustahiks = graphene.List(MustahikType, statuses=graphene.List(graphene.String)) mustahik = graphene.Field(MustahikType, id=graphene.ID()) + mustahikWithName = graphene.Field(lambda: graphene.List(MustahikType), name=graphene.String()) def resolve_mustahiks(self, info, statuses=[], **kwargs): if statuses and len(statuses) > 0: @@ -22,3 +24,8 @@ class MustahikQuery(graphene.ObjectType): if mustahik is not None: return mustahik + def resolve_mustahikWithName(self, info, name=""): + return + + + diff --git a/sizakat/mustahik/tests.py b/sizakat/mustahik/tests.py index 372a8d1..ea9a47e 100644 --- a/sizakat/mustahik/tests.py +++ b/sizakat/mustahik/tests.py @@ -235,24 +235,35 @@ class MustahikGraphQLTestCase(GraphQLTestCase): def test_mustahik_mutation_can_delete_mustahik(self): count = Mustahik.objects.count() + mustahik = Mustahik.objects.get(no_ktp='31751234567890') + mustahik_id = mustahik.pk response = self.query( ''' - mutation{ - deleteMustahik(id: 3) { + mutation deleteMustahik($id: ID) { + deleteMustahik(id: $id) { mustahik { id name } + message + idMustahik + nama + noKtp } } ''', + op_name='deleteMustahik', + variables={'id':mustahik_id} ) + self.assertResponseNoErrors(response) content = json.loads(response.content) - self.assertIsNone(content['data']['deleteMustahik']) + self.assertIsNone(content['data']['deleteMustahik']['mustahik']) + self.assertEquals(content['data']['deleteMustahik']['message'], "Success") self.assertEquals(Mustahik.objects.count(), count-1) + def test_mustahik_query_can_read_detail_mustahik(self): mustahik = Mustahik.objects.get(no_ktp='31751234567890') mustahik_id = mustahik.pk @@ -286,4 +297,94 @@ class MustahikGraphQLTestCase(GraphQLTestCase): self.assertEqual(content['data']['mustahik']['name'], 'mustahik') self.assertEqual(content['data']['mustahik']['noKtp'], '31751234567890') self.assertEqual(content['data']['mustahik']['address'], 'Jalan raya depok') - \ No newline at end of file + + def test_mustahikWithName_should_return_list_of_mustahik(self): + response = self.query( + ''' + query mustahikWithName($name:String){ + mustahikWithName(name: $name){ + id, + name + } + + } + ''', + op_name='mustahikWithName', + ) + + content = json.loads(response.content) + self.assertEqual(len(content['data']['mustahikWithName']),1) + self.assertEqual(content['data']['mustahikWithName'][0]['name'], 'mustahik') + + def test_mustahikWithName_if_name_is_set_should_return_list_of_mustahiks_with_contain_the_name(self): + Mustahik.objects.create( + name='test', + no_ktp='11751234567890', + phone='081234567890', + address='Jalan raya depok', + province='Jawa Barat', + regency='Depok', + rt='003', + rw='002', + birthdate=date(1987, 6, 5), + status=Mustahik.Status.YATIM, + family_size=4, + description='desc' + ) + + Mustahik.objects.create( + name='eslu', + no_ktp='22751234337899', + phone='081234567890', + address='Jalan depok', + province='Jawa Timur', + regency='Bondo', + rt='003', + rw='002', + birthdate=date(1987, 6, 5), + status=Mustahik.Status.YATIM, + family_size=4, + description='desc' + ) + + response = self.query( + ''' + query mustahikWithName($name:String){ + mustahikWithName(name: $name){ + id, + name + } + + } + ''', + op_name='mustahikWithName', + variables={'name':'es'} + ) + + content = json.loads(response.content) + self.assertEqual(len(content['data']['mustahikWithName']), 2) + self.assertEqual(content['data']['mustahikWithName'][0]['name'], 'test') + self.assertEqual(content['data']['mustahikWithName'][1]['name'], 'eslu') + + def test_mustahikWithName_if_name_is_not_available_should_return_empty_list(self): + response = self.query( + ''' + query mustahikWithName($name:String){ + mustahikWithName(name: $name){ + id, + name + } + + } + ''', + op_name='mustahikWithName', + variables={'name':'#'} + ) + + content = json.loads(response.content) + self.assertEqual(len(content['data']['mustahikWithName']), 0) + + + + + diff --git a/sizakat/settings.py b/sizakat/settings.py index 1658e6d..6ede7a0 100644 --- a/sizakat/settings.py +++ b/sizakat/settings.py @@ -39,7 +39,7 @@ INSTALLED_APPS = [ 'django.contrib.staticfiles', 'graphene_django', 'corsheaders', - 'sizakat.mustahik' + 'sizakat.mustahik', ] GRAPHENE = { -- GitLab From 97b8548393dc655cc38008c2aedab9c187fcabec Mon Sep 17 00:00:00 2001 From: abdurrafiarief <abdurrafiarief@gmail.com> Date: Fri, 24 Jul 2020 16:47:51 +0700 Subject: [PATCH 18/41] [GREEN] complete task for search mustahik with name --- sizakat/mustahik/query.py | 4 +++- sizakat/mustahik/tests.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/sizakat/mustahik/query.py b/sizakat/mustahik/query.py index be4165c..f78221c 100644 --- a/sizakat/mustahik/query.py +++ b/sizakat/mustahik/query.py @@ -25,7 +25,9 @@ class MustahikQuery(graphene.ObjectType): return mustahik def resolve_mustahikWithName(self, info, name=""): - return + if name != "": + return Mustahik.objects.filter(name__icontains=name) + return Mustahik.objects.all() diff --git a/sizakat/mustahik/tests.py b/sizakat/mustahik/tests.py index ea9a47e..ceeba11 100644 --- a/sizakat/mustahik/tests.py +++ b/sizakat/mustahik/tests.py @@ -316,7 +316,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase): self.assertEqual(len(content['data']['mustahikWithName']),1) self.assertEqual(content['data']['mustahikWithName'][0]['name'], 'mustahik') - def test_mustahikWithName_if_name_is_set_should_return_list_of_mustahiks_with_contain_the_name(self): + def test_mustahikWithName_if_name_is_set_should_return_list_of_mustahiks_that_contain_the_name(self): Mustahik.objects.create( name='test', no_ktp='11751234567890', -- GitLab From dc10a586c8424a5c5947bb1a23f5d489242f6238 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Sun, 26 Jul 2020 14:06:32 +0700 Subject: [PATCH 19/41] [REFACTOR] refactor fungsi-fungsi sesuai dengan panduan dan kesepakatan --- sizakat/mustahik/forms.py | 22 +++++++++ sizakat/mustahik/models.py | 23 +++++---- sizakat/mustahik/mutations.py | 46 +++++------------- sizakat/mustahik/query.py | 42 +++++++++-------- sizakat/mustahik/tests.py | 87 +++++++++++++---------------------- sizakat/mustahik/types.py | 1 - 6 files changed, 102 insertions(+), 119 deletions(-) create mode 100644 sizakat/mustahik/forms.py diff --git a/sizakat/mustahik/forms.py b/sizakat/mustahik/forms.py new file mode 100644 index 0000000..4a6ddae --- /dev/null +++ b/sizakat/mustahik/forms.py @@ -0,0 +1,22 @@ +from django import forms + +from .models import Mustahik + + +class MustahikForm(forms.ModelForm): + class Meta: + model = Mustahik + fields = [ + 'name', + 'no_ktp', + 'phone', + 'address', + 'province', + 'regency', + 'rt', + 'rw', + 'birthdate', + 'status', + 'family_size', + 'description', + ] diff --git a/sizakat/mustahik/models.py b/sizakat/mustahik/models.py index 267fdaa..5083d9b 100644 --- a/sizakat/mustahik/models.py +++ b/sizakat/mustahik/models.py @@ -1,23 +1,30 @@ from django.db import models -# Create your models here. +from django.core.validators import RegexValidator +numeric_only = RegexValidator(r'^[0-9]*$', 'Numeric only.') -class Mustahik(models.Model): +class Mustahik(models.Model): class Status(models.TextChoices): JANDA = ('JANDA', 'Janda') MISKIN = ('MISKIN', 'Miskin') YATIM = ('YATIM', 'Yatim') - name = models.CharField(max_length=32) - no_ktp = models.CharField(max_length=32, unique=True) - phone = models.CharField(max_length=32, blank=True, null=True) + name = models.CharField(max_length=150) + no_ktp = models.CharField( + max_length=32, unique=True, + validators=[numeric_only] + ) + phone = models.CharField( + max_length=32, blank=True, null=True, + validators=[numeric_only] + ) address = models.TextField() province = models.CharField(max_length=32) - regency = models.CharField(max_length=32) - rt = models.CharField(max_length=4) - rw = models.CharField(max_length=4) + regency = models.CharField(max_length=50) + rt = models.CharField(max_length=4, validators=[numeric_only]) + rw = models.CharField(max_length=4, validators=[numeric_only]) birthdate = models.DateField() status = models.CharField( max_length=32, diff --git a/sizakat/mustahik/mutations.py b/sizakat/mustahik/mutations.py index 93db912..48f21d9 100644 --- a/sizakat/mustahik/mutations.py +++ b/sizakat/mustahik/mutations.py @@ -1,54 +1,32 @@ import graphene -from django import forms from graphene_django.forms.mutation import DjangoModelFormMutation +from .forms import MustahikForm from .models import Mustahik from .types import MustahikType -class MustahikForm(forms.ModelForm): - - class Meta: - model = Mustahik - fields = [ - 'name', - 'no_ktp', - 'phone', - 'address', - 'province', - 'regency', - 'rt', - 'rw', - 'birthdate', - 'status', - 'family_size', - 'description', - ] - - class MustahikMutation(DjangoModelFormMutation): - mustahik = graphene.Field(MustahikType) class Meta: form_class = MustahikForm -class DeleteMustahik(graphene.Mutation): + +class DeleteMustahik(graphene.Mutation): class Arguments: id = graphene.ID() - - message = graphene.String() - idMustahik = graphene.ID() - nama = graphene.String() - noKtp = graphene.String() - mustahik = graphene.Field(MustahikType) + + deleted = graphene.Boolean() + id_mustahik = graphene.ID() + name = graphene.String() + no_ktp = graphene.String() def mutate(self, info, id): mustahik = Mustahik.objects.get(pk=id) - _nama = mustahik.name - _no_ktp = mustahik.no_ktp + name = mustahik.name + no_ktp = mustahik.no_ktp mustahik.delete() - return DeleteMustahik(message = "Success", idMustahik=id, nama=_nama, noKtp=_no_ktp) - - + deleted = True + return DeleteMustahik(deleted=deleted, id_mustahik=id, name=name, no_ktp=no_ktp) diff --git a/sizakat/mustahik/query.py b/sizakat/mustahik/query.py index f78221c..38d987e 100644 --- a/sizakat/mustahik/query.py +++ b/sizakat/mustahik/query.py @@ -1,33 +1,35 @@ import graphene + from django.db.models import Q +from functools import reduce from .models import Mustahik from .types import MustahikType class MustahikQuery(graphene.ObjectType): - mustahiks = graphene.List(MustahikType, statuses=graphene.List(graphene.String)) - mustahik = graphene.Field(MustahikType, id=graphene.ID()) - mustahikWithName = graphene.Field(lambda: graphene.List(MustahikType), name=graphene.String()) + mustahiks = graphene.List( + MustahikType, + statuses=graphene.List(graphene.String), + name_contains=graphene.String() + ) + mustahik = graphene.Field(MustahikType, id=graphene.ID(required=True)) + + def resolve_mustahiks(self, info, **kwargs): + statuses = kwargs.get('statuses', None) + name_contains = kwargs.get('name_contains', None) + mustahiks = Mustahik.objects.all() - def resolve_mustahiks(self, info, statuses=[], **kwargs): if statuses and len(statuses) > 0: - filter = Q(status=statuses[0]) - for status in statuses: - filter = filter | Q(status=status) - return Mustahik.objects.filter(filter) + mustahiks = mustahiks.filter(reduce( + lambda a, b: a | b, + list(map(lambda s: Q(status=s), statuses)) + )) + + if name_contains: + mustahiks = mustahiks.filter(name__icontains=name_contains) - return Mustahik.objects.all() + return mustahiks def resolve_mustahik(self, info, id): - mustahik = Mustahik.objects.get(pk=id) - if mustahik is not None: - return mustahik - - def resolve_mustahikWithName(self, info, name=""): - if name != "": - return Mustahik.objects.filter(name__icontains=name) - return Mustahik.objects.all() - - - + return Mustahik.objects.get(pk=id) diff --git a/sizakat/mustahik/tests.py b/sizakat/mustahik/tests.py index ceeba11..577bb1f 100644 --- a/sizakat/mustahik/tests.py +++ b/sizakat/mustahik/tests.py @@ -162,15 +162,15 @@ class MustahikGraphQLTestCase(GraphQLTestCase): def test_query_mustahik_should_return_list_of_mustahiks(self): response = self.query( - ''' + ''' query mustahiksQuery{ mustahiks { id, name } } - ''', - op_name='mustahiksQuery' + ''', + op_name='mustahiksQuery' ) self.assertResponseNoErrors(response) @@ -241,35 +241,29 @@ class MustahikGraphQLTestCase(GraphQLTestCase): ''' mutation deleteMustahik($id: ID) { deleteMustahik(id: $id) { - mustahik { - id - name - } - message + deleted idMustahik - nama + name noKtp } } ''', op_name='deleteMustahik', - variables={'id':mustahik_id} + variables={'id': mustahik_id} ) - + self.assertResponseNoErrors(response) content = json.loads(response.content) - self.assertIsNone(content['data']['deleteMustahik']['mustahik']) - self.assertEquals(content['data']['deleteMustahik']['message'], "Success") + self.assertTrue(content['data']['deleteMustahik']['deleted']) self.assertEquals(Mustahik.objects.count(), count-1) - def test_mustahik_query_can_read_detail_mustahik(self): mustahik = Mustahik.objects.get(no_ktp='31751234567890') mustahik_id = mustahik.pk response = self.query( ''' - query detailMustahikQuery($id:ID){ + query detailMustahikQuery($id:ID!){ mustahik(id:$id){ id name @@ -288,35 +282,19 @@ class MustahikGraphQLTestCase(GraphQLTestCase): } ''', op_name='detailMustahikQuery', - variables={'id':mustahik_id} + variables={'id': mustahik_id} ) self.assertResponseNoErrors(response) - + content = json.loads(response.content) self.assertEqual(len(content['data']), 1) self.assertEqual(content['data']['mustahik']['name'], 'mustahik') - self.assertEqual(content['data']['mustahik']['noKtp'], '31751234567890') - self.assertEqual(content['data']['mustahik']['address'], 'Jalan raya depok') + self.assertEqual(content['data']['mustahik'] + ['noKtp'], '31751234567890') + self.assertEqual(content['data']['mustahik'] + ['address'], 'Jalan raya depok') - def test_mustahikWithName_should_return_list_of_mustahik(self): - response = self.query( - ''' - query mustahikWithName($name:String){ - mustahikWithName(name: $name){ - id, - name - } - - } - ''', - op_name='mustahikWithName', - ) - - content = json.loads(response.content) - self.assertEqual(len(content['data']['mustahikWithName']),1) - self.assertEqual(content['data']['mustahikWithName'][0]['name'], 'mustahik') - - def test_mustahikWithName_if_name_is_set_should_return_list_of_mustahiks_that_contain_the_name(self): + def test_mustahiks_if_name_is_set_should_return_list_of_mustahiks_that_contain_the_name(self): Mustahik.objects.create( name='test', no_ktp='11751234567890', @@ -349,42 +327,39 @@ class MustahikGraphQLTestCase(GraphQLTestCase): response = self.query( ''' - query mustahikWithName($name:String){ - mustahikWithName(name: $name){ + query mustahiks($nameContains:String){ + mustahiks(nameContains: $nameContains){ id, name } } ''', - op_name='mustahikWithName', - variables={'name':'es'} + op_name='mustahiks', + variables={'nameContains': 'es'} ) content = json.loads(response.content) - self.assertEqual(len(content['data']['mustahikWithName']), 2) - self.assertEqual(content['data']['mustahikWithName'][0]['name'], 'test') - self.assertEqual(content['data']['mustahikWithName'][1]['name'], 'eslu') + self.assertEqual(len(content['data']['mustahiks']), 2) + self.assertEqual( + content['data']['mustahiks'][0]['name'], 'test') + self.assertEqual( + content['data']['mustahiks'][1]['name'], 'eslu') - def test_mustahikWithName_if_name_is_not_available_should_return_empty_list(self): + def test_mustahiks_if_name_is_not_available_should_return_empty_list(self): response = self.query( ''' - query mustahikWithName($name:String){ - mustahikWithName(name: $name){ + query mustahiks($nameContains:String){ + mustahiks(nameContains: $nameContains){ id, name } } ''', - op_name='mustahikWithName', - variables={'name':'#'} + op_name='mustahiks', + variables={'nameContains': '#'} ) content = json.loads(response.content) - self.assertEqual(len(content['data']['mustahikWithName']), 0) - - - - - + self.assertEqual(len(content['data']['mustahiks']), 0) diff --git a/sizakat/mustahik/types.py b/sizakat/mustahik/types.py index cf9dba9..da1ff91 100644 --- a/sizakat/mustahik/types.py +++ b/sizakat/mustahik/types.py @@ -5,6 +5,5 @@ from .models import Mustahik class MustahikType(DjangoObjectType): - class Meta: model = Mustahik -- GitLab From 9a667dff6b34533b12acfc5b4382b9b7bdbfbc49 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Sun, 26 Jul 2020 16:57:29 +0700 Subject: [PATCH 20/41] change multiple line of string styling --- sizakat/schema.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sizakat/schema.py b/sizakat/schema.py index f7d47ba..683f54f 100644 --- a/sizakat/schema.py +++ b/sizakat/schema.py @@ -5,9 +5,9 @@ from graphene_django import DjangoObjectType from .mustahik.mutations import MustahikMutation, DeleteMustahik from .mustahik.query import MustahikQuery -ABOUT = 'Si Zakat merupakan sistem informasi untuk membantu masjid dalam \ -mengelola transaksi zakat. Sistem ini dibuat oleh tim lab 1231, \ -yang dipimpin oleh Prof. Dr. Wisnu Jatmiko.' +ABOUT = ('Si Zakat merupakan sistem informasi untuk membantu masjid dalam ' + 'mengelola transaksi zakat. Sistem ini dibuat oleh tim lab 1231, ' + 'yang dipimpin oleh Prof. Dr. Wisnu Jatmiko.') class Query(MustahikQuery, graphene.ObjectType): -- GitLab From 0785106fd946331906c0ede59c35e5ae882d348f Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Sun, 26 Jul 2020 21:09:47 +0700 Subject: [PATCH 21/41] [REFACTOR] refactor query dan validator --- sizakat/mustahik/models.py | 16 +++++++++------- sizakat/mustahik/query.py | 12 ++++++------ sizakat/settings.py | 3 ++- sizakat/validators.py | 5 +++++ 4 files changed, 22 insertions(+), 14 deletions(-) create mode 100644 sizakat/validators.py diff --git a/sizakat/mustahik/models.py b/sizakat/mustahik/models.py index 5083d9b..f66a5fb 100644 --- a/sizakat/mustahik/models.py +++ b/sizakat/mustahik/models.py @@ -1,8 +1,6 @@ from django.db import models -from django.core.validators import RegexValidator - -numeric_only = RegexValidator(r'^[0-9]*$', 'Numeric only.') +from sizakat.validators import validate_numeric_character class Mustahik(models.Model): @@ -14,17 +12,21 @@ class Mustahik(models.Model): name = models.CharField(max_length=150) no_ktp = models.CharField( max_length=32, unique=True, - validators=[numeric_only] + validators=[validate_numeric_character] ) phone = models.CharField( max_length=32, blank=True, null=True, - validators=[numeric_only] + validators=[validate_numeric_character] ) address = models.TextField() province = models.CharField(max_length=32) regency = models.CharField(max_length=50) - rt = models.CharField(max_length=4, validators=[numeric_only]) - rw = models.CharField(max_length=4, validators=[numeric_only]) + rt = models.CharField( + max_length=4, validators=[validate_numeric_character] + ) + rw = models.CharField( + max_length=4, validators=[validate_numeric_character] + ) birthdate = models.DateField() status = models.CharField( max_length=32, diff --git a/sizakat/mustahik/query.py b/sizakat/mustahik/query.py index 38d987e..e7e8036 100644 --- a/sizakat/mustahik/query.py +++ b/sizakat/mustahik/query.py @@ -18,18 +18,18 @@ class MustahikQuery(graphene.ObjectType): def resolve_mustahiks(self, info, **kwargs): statuses = kwargs.get('statuses', None) name_contains = kwargs.get('name_contains', None) - mustahiks = Mustahik.objects.all() + filter_query = Q() if statuses and len(statuses) > 0: - mustahiks = mustahiks.filter(reduce( + filter_query |= reduce( lambda a, b: a | b, - list(map(lambda s: Q(status=s), statuses)) - )) + [Q(status=status) for status in statuses] + ) if name_contains: - mustahiks = mustahiks.filter(name__icontains=name_contains) + filter_query &= Q(name__icontains=name_contains) - return mustahiks + return Mustahik.objects.filter(filter_query) def resolve_mustahik(self, info, id): return Mustahik.objects.get(pk=id) diff --git a/sizakat/settings.py b/sizakat/settings.py index 6ede7a0..0a90bcb 100644 --- a/sizakat/settings.py +++ b/sizakat/settings.py @@ -57,7 +57,8 @@ MIDDLEWARE = [ 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] -CORS_ORIGIN_WHITELIST = os.environ.get('CORS_ORIGIN_WHITELIST').split() +CORS_ORIGIN_WHITELIST = os.environ.get( + 'CORS_ORIGIN_WHITELIST', 'http://localhost:3000').split() ROOT_URLCONF = 'sizakat.urls' diff --git a/sizakat/validators.py b/sizakat/validators.py new file mode 100644 index 0000000..7b55e88 --- /dev/null +++ b/sizakat/validators.py @@ -0,0 +1,5 @@ +from django.core.validators import RegexValidator + +validate_numeric_character = RegexValidator( + r'^[0-9]*$', 'Numeric character only.' +) -- GitLab From f12debca43b147f6dade86e0a15785edf5f49b8a Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Mon, 27 Jul 2020 08:13:53 +0700 Subject: [PATCH 22/41] [RED] membuat test gender pada model mustahik --- sizakat/mustahik/tests.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/sizakat/mustahik/tests.py b/sizakat/mustahik/tests.py index 577bb1f..1b39071 100644 --- a/sizakat/mustahik/tests.py +++ b/sizakat/mustahik/tests.py @@ -23,7 +23,8 @@ class MustahikModelTestCase(TestCase): birthdate=date(1987, 6, 5), status=Mustahik.Status.MISKIN, family_size=4, - description='desc' + description='desc', + gender=Mustahik.Gender.LAKILAKI ) def test_mustahik_creation(self): @@ -44,7 +45,8 @@ class MustahikModelTestCase(TestCase): birthdate=date(1987, 4, 3), status=Mustahik.Status.MISKIN, family_size=1, - description='no_ktp is unique' + description='no_ktp is unique', + gender=Mustahik.Gender.PEREMPUAN ) @@ -64,7 +66,8 @@ class MustahikGraphQLTestCase(GraphQLTestCase): birthdate=date(1987, 6, 5), status=Mustahik.Status.MISKIN, family_size=4, - description='desc' + description='desc', + gender=Mustahik.Gender.LAKILAKI ) def test_mustahik_mutation_can_add_new_mustahik(self): @@ -100,7 +103,8 @@ class MustahikGraphQLTestCase(GraphQLTestCase): "birthdate": "1998-03-12", "status": "YATIM", "familySize": 3, - "description": "anak yatim" + "description": "anak yatim", + "gender": "L" } ) @@ -151,6 +155,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase): "status": "MISKIN", "familySize": 4, "description": new_desc, + "gender": "L", "id": mustahik.pk } ) @@ -192,7 +197,8 @@ class MustahikGraphQLTestCase(GraphQLTestCase): birthdate=date(1987, 6, 5), status=Mustahik.Status.YATIM, family_size=4, - description='desc' + description='desc', + gender=Mustahik.Gender.LAKILAKI ) response = self.query( @@ -278,6 +284,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase): status familySize description + gender } } ''', @@ -307,7 +314,8 @@ class MustahikGraphQLTestCase(GraphQLTestCase): birthdate=date(1987, 6, 5), status=Mustahik.Status.YATIM, family_size=4, - description='desc' + description='desc', + gender=Mustahik.Gender.LAKILAKI ) Mustahik.objects.create( @@ -322,7 +330,8 @@ class MustahikGraphQLTestCase(GraphQLTestCase): birthdate=date(1987, 6, 5), status=Mustahik.Status.YATIM, family_size=4, - description='desc' + description='desc', + gender=Mustahik.Gender.LAKILAKI ) response = self.query( -- GitLab From de78763f079d8b349c8fa69d368eda10da2f6c82 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Mon, 27 Jul 2020 08:14:20 +0700 Subject: [PATCH 23/41] [GREEN] menambahkan gender ke model mustahik --- sizakat/mustahik/forms.py | 1 + sizakat/mustahik/models.py | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/sizakat/mustahik/forms.py b/sizakat/mustahik/forms.py index 4a6ddae..c0862ef 100644 --- a/sizakat/mustahik/forms.py +++ b/sizakat/mustahik/forms.py @@ -19,4 +19,5 @@ class MustahikForm(forms.ModelForm): 'status', 'family_size', 'description', + 'gender', ] diff --git a/sizakat/mustahik/models.py b/sizakat/mustahik/models.py index f66a5fb..081f064 100644 --- a/sizakat/mustahik/models.py +++ b/sizakat/mustahik/models.py @@ -9,6 +9,10 @@ class Mustahik(models.Model): MISKIN = ('MISKIN', 'Miskin') YATIM = ('YATIM', 'Yatim') + class Gender(models.TextChoices): + LAKILAKI = ('L', 'Laki-Laki') + PEREMPUAN = ('P', 'Perempuan') + name = models.CharField(max_length=150) no_ktp = models.CharField( max_length=32, unique=True, @@ -35,3 +39,4 @@ class Mustahik(models.Model): ) family_size = models.PositiveSmallIntegerField() description = models.TextField(blank=True, null=True) + gender = models.CharField(max_length=1, choices=Gender.choices) -- GitLab From f846900670a0584ee5b305963a4e011fef9fdec8 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Mon, 27 Jul 2020 09:07:30 +0700 Subject: [PATCH 24/41] [RED] membuat test hitung umur mustahik --- sizakat/mustahik/tests.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sizakat/mustahik/tests.py b/sizakat/mustahik/tests.py index 1b39071..52ccc6b 100644 --- a/sizakat/mustahik/tests.py +++ b/sizakat/mustahik/tests.py @@ -3,6 +3,7 @@ import json from datetime import date from django.db.utils import IntegrityError from django.test import TestCase +from django.utils import timezone from graphene_django.utils.testing import GraphQLTestCase from sizakat.schema import schema @@ -49,6 +50,13 @@ class MustahikModelTestCase(TestCase): gender=Mustahik.Gender.PEREMPUAN ) + def test_calculate_mustahik_age(self): + mustahik = Mustahik.objects.get(no_ktp='31751234567890') + self.assertEqual( + mustahik.calculate_age(), + timezone.now().year - mustahik.birthdate.year + ) + class MustahikGraphQLTestCase(GraphQLTestCase): GRAPHQL_SCHEMA = schema -- GitLab From 41e23466436575c0eabec3bc1765e4e8d18d90c0 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Mon, 27 Jul 2020 09:17:13 +0700 Subject: [PATCH 25/41] [GREEN] menambahkan fungsi hitung umur mustahik --- sizakat/mustahik/models.py | 4 ++++ sizakat/mustahik/tests.py | 11 ++++++----- sizakat/mustahik/types.py | 2 ++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/sizakat/mustahik/models.py b/sizakat/mustahik/models.py index 081f064..f9e8978 100644 --- a/sizakat/mustahik/models.py +++ b/sizakat/mustahik/models.py @@ -1,4 +1,5 @@ from django.db import models +from django.utils import timezone from sizakat.validators import validate_numeric_character @@ -40,3 +41,6 @@ class Mustahik(models.Model): family_size = models.PositiveSmallIntegerField() description = models.TextField(blank=True, null=True) gender = models.CharField(max_length=1, choices=Gender.choices) + + def calculate_age(self): + return timezone.now().year - self.birthdate.year diff --git a/sizakat/mustahik/tests.py b/sizakat/mustahik/tests.py index 52ccc6b..2c8d705 100644 --- a/sizakat/mustahik/tests.py +++ b/sizakat/mustahik/tests.py @@ -293,6 +293,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase): familySize description gender + age } } ''', @@ -302,12 +303,12 @@ class MustahikGraphQLTestCase(GraphQLTestCase): self.assertResponseNoErrors(response) content = json.loads(response.content) + data_mustahik = content['data']['mustahik'] self.assertEqual(len(content['data']), 1) - self.assertEqual(content['data']['mustahik']['name'], 'mustahik') - self.assertEqual(content['data']['mustahik'] - ['noKtp'], '31751234567890') - self.assertEqual(content['data']['mustahik'] - ['address'], 'Jalan raya depok') + self.assertEqual(data_mustahik['name'], 'mustahik') + self.assertEqual(data_mustahik['noKtp'], '31751234567890') + self.assertEqual(data_mustahik['address'], 'Jalan raya depok') + self.assertEqual(data_mustahik['age'], mustahik.calculate_age()) def test_mustahiks_if_name_is_set_should_return_list_of_mustahiks_that_contain_the_name(self): Mustahik.objects.create( diff --git a/sizakat/mustahik/types.py b/sizakat/mustahik/types.py index da1ff91..d1d87cb 100644 --- a/sizakat/mustahik/types.py +++ b/sizakat/mustahik/types.py @@ -7,3 +7,5 @@ from .models import Mustahik class MustahikType(DjangoObjectType): class Meta: model = Mustahik + + age = graphene.Int(source='calculate_age') -- GitLab From 3376c4674a97ff003137f27a1b1e627b3537e81f Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Mon, 27 Jul 2020 11:25:24 +0700 Subject: [PATCH 26/41] [CHORES] menambahkan migrations ke commit --- .gitignore | 3 -- sizakat/mustahik/migrations/0001_initial.py | 34 +++++++++++++++++++++ sizakat/mustahik/migrations/__init__.py | 0 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 sizakat/mustahik/migrations/0001_initial.py create mode 100644 sizakat/mustahik/migrations/__init__.py diff --git a/.gitignore b/.gitignore index 31d9ad9..e6dcff9 100644 --- a/.gitignore +++ b/.gitignore @@ -66,9 +66,6 @@ coverage.xml # staticfiles staticfiles/ -# migrations file -/**/migrations/ - # Jupyter Notebook .ipynb_checkpoints diff --git a/sizakat/mustahik/migrations/0001_initial.py b/sizakat/mustahik/migrations/0001_initial.py new file mode 100644 index 0000000..c098adf --- /dev/null +++ b/sizakat/mustahik/migrations/0001_initial.py @@ -0,0 +1,34 @@ +# Generated by Django 3.0.7 on 2020-07-27 04:24 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Mustahik', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=150)), + ('no_ktp', models.CharField(max_length=32, unique=True, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), + ('phone', models.CharField(blank=True, max_length=32, null=True, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), + ('address', models.TextField()), + ('province', models.CharField(max_length=32)), + ('regency', models.CharField(max_length=50)), + ('rt', models.CharField(max_length=4, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), + ('rw', models.CharField(max_length=4, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), + ('birthdate', models.DateField()), + ('status', models.CharField(choices=[('JANDA', 'Janda'), ('MISKIN', 'Miskin'), ('YATIM', 'Yatim')], default='MISKIN', max_length=32)), + ('family_size', models.PositiveSmallIntegerField()), + ('description', models.TextField(blank=True, null=True)), + ('gender', models.CharField(choices=[('L', 'Laki-Laki'), ('P', 'Perempuan')], max_length=1)), + ], + ), + ] diff --git a/sizakat/mustahik/migrations/__init__.py b/sizakat/mustahik/migrations/__init__.py new file mode 100644 index 0000000..e69de29 -- GitLab From c48bbb3c317c58d7f69db18ad17fa90977522de4 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Tue, 28 Jul 2020 17:48:17 +0700 Subject: [PATCH 27/41] [RED] membuat test model mustahik terbaru --- sizakat/mustahik/tests.py | 234 +++++++++++++++++--------------------- 1 file changed, 103 insertions(+), 131 deletions(-) diff --git a/sizakat/mustahik/tests.py b/sizakat/mustahik/tests.py index 2c8d705..543c738 100644 --- a/sizakat/mustahik/tests.py +++ b/sizakat/mustahik/tests.py @@ -7,48 +7,85 @@ from django.utils import timezone from graphene_django.utils.testing import GraphQLTestCase from sizakat.schema import schema -from .models import Mustahik +from .models import DataSource, DataSourceInstitusi, DataSourcePekerja, DataSourceWarga, Mustahik class MustahikModelTestCase(TestCase): def setUp(self): - Mustahik.objects.create( + data_source_institusi = DataSource.objects.create( + pic_name='pic test', + pic_ktp='1234567890', + pic_phone='0812389120', + pic_position='test', + category=DataSource.Category.INSTITUSI + ) + institusi_detail = DataSourceInstitusi.objects.create( + name='lembaga test', + address='jl test', + data_source=data_source_institusi, + province='jakarta', + regency='jakarta timur', + sub_district='makasar', + village='pinangranti', + rt='001', + rw='001' + ) + data_source_pekerja = DataSource.objects.create( + pic_name='pic test', + pic_ktp='1234567891', + pic_phone='0812389121', + pic_position='test', + category=DataSource.Category.PEKERJA + ) + pekerja_detail = DataSourcePekerja.objects.create( + data_source=data_source_pekerja, + profession='tester', + location='jl tester' + ) + data_source_warga = DataSource.objects.create( + pic_name='pic test', + pic_ktp='1234567892', + pic_phone='0812389122', + pic_position='test', + category=DataSource.Category.WARGA + ) + institusi_detail = DataSourceWarga.objects.create( + data_source=data_source_warga, + province='jakarta', + regency='jakarta timur', + sub_district='makasar', + village='pinangranti', + rt='001', + rw='001' + ) + mustahik = Mustahik.objects.create( name='mustahik', no_ktp='31751234567890', phone='081234567890', address='Jalan raya depok', - province='Jawa Barat', - regency='Depok', - rt='003', - rw='002', birthdate=date(1987, 6, 5), status=Mustahik.Status.MISKIN, - family_size=4, - description='desc', - gender=Mustahik.Gender.LAKILAKI + gender=Mustahik.Gender.LAKILAKI, + data_source=data_source_warga ) - def test_mustahik_creation(self): + def test_mustahik_creation_from_datasource_institusi(self): mustahik = Mustahik.objects.get(no_ktp='31751234567890') self.assertTrue(isinstance(mustahik, Mustahik)) - def test_no_ktp_mustahik_is_unique(self): - with self.assertRaises(IntegrityError): - Mustahik.objects.create( - name='kihatsum', - no_ktp='31751234567890', - phone='08987654321', - address='Jalan raya bogor', - province='Jawa Barat', - regency='Bogor', - rt='002', - rw='003', - birthdate=date(1987, 4, 3), - status=Mustahik.Status.MISKIN, - family_size=1, - description='no_ktp is unique', - gender=Mustahik.Gender.PEREMPUAN - ) + def test_mustahik_change_datasource_to_datasource_pekerja(self): + data_source_pekerja = DataSource.objects.get(pic_ktp='1234567891') + mustahik = Mustahik.objects.get(no_ktp='31751234567890') + mustahik.data_source = data_source_pekerja + mustahik.save() + self.assertEqual(mustahik.data_source.category, DataSource.Category.PEKERJA) + + def test_mustahik_change_datasource_to_datasource_warga(self): + data_source_warga = DataSource.objects.get(pic_ktp='1234567892') + mustahik = Mustahik.objects.get(no_ktp='31751234567890') + mustahik.data_source = data_source_warga + mustahik.save() + self.assertEqual(mustahik.data_source.category, DataSource.Category.WARGA) def test_calculate_mustahik_age(self): mustahik = Mustahik.objects.get(no_ktp='31751234567890') @@ -62,38 +99,44 @@ class MustahikGraphQLTestCase(GraphQLTestCase): GRAPHQL_SCHEMA = schema def setUp(self): - Mustahik.objects.create( + data_source_warga = DataSource.objects.create( + pic_name='pic test', + pic_ktp='1234567892', + pic_phone='0812389122', + pic_position='test', + category=DataSource.Category.WARGA + ) + institusi_detail = DataSourceWarga.objects.create( + data_source=data_source_warga, + province='jakarta', + regency='jakarta timur', + sub_district='makasar', + village='pinangranti', + rt='001', + rw='001' + ) + mustahik = Mustahik.objects.create( name='mustahik', no_ktp='31751234567890', phone='081234567890', address='Jalan raya depok', - province='Jawa Barat', - regency='Depok', - rt='003', - rw='002', birthdate=date(1987, 6, 5), status=Mustahik.Status.MISKIN, - family_size=4, - description='desc', - gender=Mustahik.Gender.LAKILAKI + gender=Mustahik.Gender.LAKILAKI, + data_source=data_source_warga ) def test_mustahik_mutation_can_add_new_mustahik(self): no_ktp = '123891210121' + data_source = DataSource.objects.get(pic_ktp='1234567892') response = self.query( ''' mutation mustahikMutation($input: MustahikMutationInput!) { mustahikMutation(input: $input) { mustahik { - id name noKtp status - description - } - errors { - field - messages } } } @@ -104,15 +147,10 @@ class MustahikGraphQLTestCase(GraphQLTestCase): "noKtp": no_ktp, "phone": "02132132180", "address": "jalan swadaya", - "province": "jakarta", - "regency": "manggarai", - "rt": "001", - "rw": "001", "birthdate": "1998-03-12", - "status": "YATIM", - "familySize": 3, - "description": "anak yatim", - "gender": "L" + "status": "MISKIN", + "gender": "L", + "dataSource": data_source.pk } ) @@ -122,25 +160,26 @@ class MustahikGraphQLTestCase(GraphQLTestCase): # Validate content content = json.loads(response.content) self.assertEqual(content['data']['mustahikMutation'] - ['mustahik']['status'], 'YATIM') + ['mustahik']['status'], 'MISKIN') # Validate success save to db - self.assertNotEqual(Mustahik.objects.count(), 0) + self.assertEqual(Mustahik.objects.count(), 2) mustahik = Mustahik.objects.get(no_ktp=no_ktp) self.assertEqual(mustahik.name, 'jumat') def test_mustahik_mutation_can_update_mustahik(self): mustahik = Mustahik.objects.get(no_ktp='31751234567890') + data_source = mustahik.data_source mustahik_id = mustahik.pk - old_desc = mustahik.description - new_desc = 'keluarga tidak mampu' + old_status = mustahik.status + new_status = 'MUSAFIR' response = self.query( ''' mutation mustahikMutation($input: MustahikMutationInput!) { mustahikMutation(input: $input) { mustahik { id - description + status } errors { field @@ -155,23 +194,17 @@ class MustahikGraphQLTestCase(GraphQLTestCase): "noKtp": "31751234567890", "phone": "081234567890", "address": "Jalan raya depok", - "province": "Jawa Barat", - "regency": "Depok", - "rt": "003", - "rw": "002", "birthdate": "1987-06-05", - "status": "MISKIN", - "familySize": 4, - "description": new_desc, + "status": "MUSAFIR", "gender": "L", - "id": mustahik.pk + "id": mustahik.pk, + "dataSource": data_source.pk } ) # Validate success update desc mustahik mustahik = Mustahik.objects.get(no_ktp='31751234567890') - self.assertNotEqual(mustahik.description, old_desc) - self.assertEqual(mustahik.description, new_desc) + self.assertEqual(mustahik.status, new_status) def test_query_mustahik_should_return_list_of_mustahiks(self): response = self.query( @@ -193,22 +226,6 @@ class MustahikGraphQLTestCase(GraphQLTestCase): self.assertEqual(content['data']['mustahiks'][0]['name'], 'mustahik') def test_query_mustahiks_if_statuses_is_set_should_return_list_of_mustahiks_with_coresponding_status(self): - Mustahik.objects.create( - name='test', - no_ktp='11751234567890', - phone='081234567890', - address='Jalan raya depok', - province='Jawa Barat', - regency='Depok', - rt='003', - rw='002', - birthdate=date(1987, 6, 5), - status=Mustahik.Status.YATIM, - family_size=4, - description='desc', - gender=Mustahik.Gender.LAKILAKI - ) - response = self.query( ''' query mustahiksQuery($statuses: [String]) { @@ -241,7 +258,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase): } ''', op_name='mustahiksQuery', - variables={'statuses': [Mustahik.Status.JANDA]} + variables={'statuses': [Mustahik.Status.GHARIM]} ) content = json.loads(response.content) @@ -279,20 +296,9 @@ class MustahikGraphQLTestCase(GraphQLTestCase): ''' query detailMustahikQuery($id:ID!){ mustahik(id:$id){ - id name noKtp - phone address - province - regency - rt - rw - birthdate - status - familySize - description - gender age } } @@ -311,38 +317,6 @@ class MustahikGraphQLTestCase(GraphQLTestCase): self.assertEqual(data_mustahik['age'], mustahik.calculate_age()) def test_mustahiks_if_name_is_set_should_return_list_of_mustahiks_that_contain_the_name(self): - Mustahik.objects.create( - name='test', - no_ktp='11751234567890', - phone='081234567890', - address='Jalan raya depok', - province='Jawa Barat', - regency='Depok', - rt='003', - rw='002', - birthdate=date(1987, 6, 5), - status=Mustahik.Status.YATIM, - family_size=4, - description='desc', - gender=Mustahik.Gender.LAKILAKI - ) - - Mustahik.objects.create( - name='eslu', - no_ktp='22751234337899', - phone='081234567890', - address='Jalan depok', - province='Jawa Timur', - regency='Bondo', - rt='003', - rw='002', - birthdate=date(1987, 6, 5), - status=Mustahik.Status.YATIM, - family_size=4, - description='desc', - gender=Mustahik.Gender.LAKILAKI - ) - response = self.query( ''' query mustahiks($nameContains:String){ @@ -350,19 +324,17 @@ class MustahikGraphQLTestCase(GraphQLTestCase): id, name } - + } ''', op_name='mustahiks', - variables={'nameContains': 'es'} + variables={'nameContains': 'hik'} ) content = json.loads(response.content) - self.assertEqual(len(content['data']['mustahiks']), 2) - self.assertEqual( - content['data']['mustahiks'][0]['name'], 'test') + self.assertEqual(len(content['data']['mustahiks']), 1) self.assertEqual( - content['data']['mustahiks'][1]['name'], 'eslu') + content['data']['mustahiks'][0]['name'], 'mustahik') def test_mustahiks_if_name_is_not_available_should_return_empty_list(self): response = self.query( @@ -372,7 +344,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase): id, name } - + } ''', op_name='mustahiks', -- GitLab From 6fad5cec4b3b48702481064d77e262c3c1d5d8b5 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Tue, 28 Jul 2020 17:49:34 +0700 Subject: [PATCH 28/41] [GREEN] implementasi model mustahik baru --- sizakat/mustahik/forms.py | 7 +- sizakat/mustahik/migrations/0001_initial.py | 66 ++++++++++++-- sizakat/mustahik/models.py | 96 +++++++++++++++++---- 3 files changed, 138 insertions(+), 31 deletions(-) diff --git a/sizakat/mustahik/forms.py b/sizakat/mustahik/forms.py index c0862ef..485c70e 100644 --- a/sizakat/mustahik/forms.py +++ b/sizakat/mustahik/forms.py @@ -11,13 +11,8 @@ class MustahikForm(forms.ModelForm): 'no_ktp', 'phone', 'address', - 'province', - 'regency', - 'rt', - 'rw', 'birthdate', 'status', - 'family_size', - 'description', 'gender', + 'data_source', ] diff --git a/sizakat/mustahik/migrations/0001_initial.py b/sizakat/mustahik/migrations/0001_initial.py index c098adf..b14b749 100644 --- a/sizakat/mustahik/migrations/0001_initial.py +++ b/sizakat/mustahik/migrations/0001_initial.py @@ -1,7 +1,8 @@ -# Generated by Django 3.0.7 on 2020-07-27 04:24 +# Generated by Django 3.0.7 on 2020-07-28 10:47 import django.core.validators from django.db import migrations, models +import django.db.models.deletion class Migration(migrations.Migration): @@ -12,6 +13,20 @@ class Migration(migrations.Migration): ] operations = [ + migrations.CreateModel( + name='DataSource', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('pic_name', models.CharField(max_length=150)), + ('pic_ktp', models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), + ('pic_phone', models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), + ('pic_position', models.CharField(max_length=50)), + ('category', models.CharField(choices=[('WARGA', 'Warga'), ('INSTITUSI', 'Institusi'), ('PEKERJA', 'Pekerja')], max_length=32)), + ], + options={ + 'unique_together': {('pic_ktp', 'category')}, + }, + ), migrations.CreateModel( name='Mustahik', fields=[ @@ -19,16 +34,49 @@ class Migration(migrations.Migration): ('name', models.CharField(max_length=150)), ('no_ktp', models.CharField(max_length=32, unique=True, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), ('phone', models.CharField(blank=True, max_length=32, null=True, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), - ('address', models.TextField()), - ('province', models.CharField(max_length=32)), - ('regency', models.CharField(max_length=50)), - ('rt', models.CharField(max_length=4, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), - ('rw', models.CharField(max_length=4, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), + ('address', models.CharField(max_length=255)), ('birthdate', models.DateField()), - ('status', models.CharField(choices=[('JANDA', 'Janda'), ('MISKIN', 'Miskin'), ('YATIM', 'Yatim')], default='MISKIN', max_length=32)), - ('family_size', models.PositiveSmallIntegerField()), - ('description', models.TextField(blank=True, null=True)), + ('status', models.CharField(choices=[('FAKIR', 'Fakir'), ('MISKIN', 'Miskin'), ('AMIL', 'Amil'), ('MUALAF', 'Mualaf'), ('GHARIM', 'Gharim'), ('FISABILILLAH', 'Fisabilillah'), ('MUSAFIR', 'Musafir')], max_length=32)), ('gender', models.CharField(choices=[('L', 'Laki-Laki'), ('P', 'Perempuan')], max_length=1)), + ('photo', models.FileField(default='images/default_photo.jpg', upload_to='images/mustahik')), + ('data_source', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mustahik.DataSource')), + ], + ), + migrations.CreateModel( + name='DataSourceWarga', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('province', models.CharField(max_length=50)), + ('regency', models.CharField(max_length=50)), + ('sub_district', models.CharField(max_length=50)), + ('village', models.CharField(max_length=50)), + ('rt', models.CharField(max_length=3, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), + ('rw', models.CharField(max_length=3, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), + ('data_source', models.OneToOneField(limit_choices_to={'category': 'WARGA'}, on_delete=django.db.models.deletion.CASCADE, to='mustahik.DataSource')), + ], + ), + migrations.CreateModel( + name='DataSourcePekerja', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('profession', models.CharField(max_length=50)), + ('location', models.CharField(max_length=50)), + ('data_source', models.OneToOneField(limit_choices_to={'category': 'PEKERJA'}, on_delete=django.db.models.deletion.CASCADE, to='mustahik.DataSource')), + ], + ), + migrations.CreateModel( + name='DataSourceInstitusi', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=150)), + ('province', models.CharField(max_length=50)), + ('regency', models.CharField(max_length=50)), + ('sub_district', models.CharField(max_length=50)), + ('village', models.CharField(max_length=50)), + ('rt', models.CharField(max_length=3, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), + ('rw', models.CharField(max_length=3, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), + ('address', models.CharField(max_length=255)), + ('data_source', models.OneToOneField(limit_choices_to={'category': 'INSTITUSI'}, on_delete=django.db.models.deletion.CASCADE, to='mustahik.DataSource')), ], ), ] diff --git a/sizakat/mustahik/models.py b/sizakat/mustahik/models.py index f9e8978..18067f0 100644 --- a/sizakat/mustahik/models.py +++ b/sizakat/mustahik/models.py @@ -1,3 +1,5 @@ +import os + from django.db import models from django.utils import timezone @@ -6,9 +8,13 @@ from sizakat.validators import validate_numeric_character class Mustahik(models.Model): class Status(models.TextChoices): - JANDA = ('JANDA', 'Janda') + FAKIR = ('FAKIR', 'Fakir') MISKIN = ('MISKIN', 'Miskin') - YATIM = ('YATIM', 'Yatim') + AMIL = ('AMIL', 'Amil') + MUALAF = ('MUALAF', 'Mualaf') + GHARIM = ('GHARIM', 'Gharim') + FISABILILLAH = ('FISABILILLAH', 'Fisabilillah') + MUSAFIR = ('MUSAFIR', 'Musafir') class Gender(models.TextChoices): LAKILAKI = ('L', 'Laki-Laki') @@ -23,24 +29,82 @@ class Mustahik(models.Model): max_length=32, blank=True, null=True, validators=[validate_numeric_character] ) - address = models.TextField() - province = models.CharField(max_length=32) + address = models.CharField(max_length=255) + birthdate = models.DateField() + status = models.CharField(max_length=32, choices=Status.choices) + gender = models.CharField(max_length=1, choices=Gender.choices) + photo = models.FileField( + upload_to=os.path.join('images', 'mustahik'), + default=os.path.join('images', 'default_photo.jpg') + ) + data_source = models.ForeignKey('DataSource', on_delete=models.CASCADE) + + def calculate_age(self): + return timezone.now().year - self.birthdate.year + + +class DataSource(models.Model): + class Category(models.TextChoices): + WARGA = ('WARGA', 'Warga') + INSTITUSI = ('INSTITUSI', 'Institusi') + PEKERJA = ('PEKERJA', 'Pekerja') + + pic_name = models.CharField(max_length=150) + pic_ktp = models.CharField( + max_length=32, + validators=[validate_numeric_character] + ) + pic_phone = models.CharField( + max_length=32, + validators=[validate_numeric_character] + ) + pic_position = models.CharField(max_length=50) + category = models.CharField(max_length=32, choices=Category.choices) + + class Meta: + unique_together = ('pic_ktp', 'category',) + + +class DataSourceWarga(models.Model): + province = models.CharField(max_length=50) regency = models.CharField(max_length=50) + sub_district = models.CharField(max_length=50) + village = models.CharField(max_length=50) rt = models.CharField( - max_length=4, validators=[validate_numeric_character] + max_length=3, validators=[validate_numeric_character] ) rw = models.CharField( - max_length=4, validators=[validate_numeric_character] + max_length=3, validators=[validate_numeric_character] ) - birthdate = models.DateField() - status = models.CharField( - max_length=32, - choices=Status.choices, - default=Status.MISKIN, + data_source = models.OneToOneField( + 'DataSource', on_delete=models.CASCADE, + limit_choices_to={'category': DataSource.Category.WARGA} ) - family_size = models.PositiveSmallIntegerField() - description = models.TextField(blank=True, null=True) - gender = models.CharField(max_length=1, choices=Gender.choices) - def calculate_age(self): - return timezone.now().year - self.birthdate.year + +class DataSourceInstitusi(models.Model): + name = models.CharField(max_length=150) + province = models.CharField(max_length=50) + regency = models.CharField(max_length=50) + sub_district = models.CharField(max_length=50) + village = models.CharField(max_length=50) + rt = models.CharField( + max_length=3, validators=[validate_numeric_character] + ) + rw = models.CharField( + max_length=3, validators=[validate_numeric_character] + ) + address = models.CharField(max_length=255) + data_source = models.OneToOneField( + 'DataSource', on_delete=models.CASCADE, + limit_choices_to={'category': DataSource.Category.INSTITUSI} + ) + + +class DataSourcePekerja(models.Model): + profession = models.CharField(max_length=50) + location = models.CharField(max_length=50) + data_source = models.OneToOneField( + 'DataSource', on_delete=models.CASCADE, + limit_choices_to={'category': DataSource.Category.PEKERJA} + ) -- GitLab From 550096b988193b0932f596caf977b540f863288d Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Wed, 29 Jul 2020 11:14:04 +0700 Subject: [PATCH 29/41] [RED] membuat test query data source --- sizakat/mustahik/tests.py | 72 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/sizakat/mustahik/tests.py b/sizakat/mustahik/tests.py index 543c738..fabe5d0 100644 --- a/sizakat/mustahik/tests.py +++ b/sizakat/mustahik/tests.py @@ -106,7 +106,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase): pic_position='test', category=DataSource.Category.WARGA ) - institusi_detail = DataSourceWarga.objects.create( + data_source_detail = DataSourceWarga.objects.create( data_source=data_source_warga, province='jakarta', regency='jakarta timur', @@ -353,3 +353,73 @@ class MustahikGraphQLTestCase(GraphQLTestCase): content = json.loads(response.content) self.assertEqual(len(content['data']['mustahiks']), 0) + + def test_data_sources_query_should_return_list_data_sources(self): + response = self.query( + ''' + query dataSourcesQuery{ + dataSources { + id + category + dataSourceDetail { + __typename + ... on DataSourceWargaType { + rt + } + ... on DataSourcePekerjaType { + profession + } + ... on DataSourceInstitusiType { + name + } + } + } + } + ''', + op_name='dataSourcesQuery' + ) + + self.assertResponseNoErrors(response) + + content = json.loads(response.content) + self.assertEqual(len(content['data']['dataSources']), 1) + self.assertEqual(content['data']['dataSources'][0]['category'], 'WARGA') + + first_data_source = content['data']['dataSources'][0]['dataSourceDetail'] + self.assertEqual(first_data_source['__typename'], 'DataSourceWargaType') + self.assertTrue('rt' in first_data_source.keys()) + + def test_data_sources_query_with_category_selection(self): + response = self.query( + ''' + query dataSourcesQuery($category: String) { + dataSources(category: $category) { + id + category + } + } + ''', + op_name='dataSourcesQuery', + variables={'category': DataSource.Category.WARGA} + ) + + content = json.loads(response.content) + categories = [source['category'] for source in content['data']['dataSources']] + self.assertTrue(all([category == DataSource.Category.WARGA for category in categories])) + + def test_data_source_query_detail_with_given_id(self): + response = self.query( + ''' + query dataSourceQuery($id: ID!) { + dataSource(id: $id) { + id + picName + } + } + ''', + op_name='dataSourceQuery', + variables={'id': 1} + ) + content = json.loads(response.content) + self.assertEqual(content['data']['dataSource']['id'], '1') + self.assertEqual(content['data']['dataSource']['picName'], 'pic test') -- GitLab From c0e8839725a9f8989017adf307cbafa2925ffd87 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Wed, 29 Jul 2020 11:33:35 +0700 Subject: [PATCH 30/41] [GREEN] implementasi query data source model --- sizakat/mustahik/query.py | 17 ++++++++++++-- sizakat/mustahik/types.py | 47 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/sizakat/mustahik/query.py b/sizakat/mustahik/query.py index e7e8036..95f8c37 100644 --- a/sizakat/mustahik/query.py +++ b/sizakat/mustahik/query.py @@ -3,8 +3,8 @@ import graphene from django.db.models import Q from functools import reduce -from .models import Mustahik -from .types import MustahikType +from .models import Mustahik, DataSource +from .types import MustahikType, DataSourceType class MustahikQuery(graphene.ObjectType): @@ -14,6 +14,8 @@ class MustahikQuery(graphene.ObjectType): name_contains=graphene.String() ) mustahik = graphene.Field(MustahikType, id=graphene.ID(required=True)) + data_sources = graphene.List(DataSourceType, category=graphene.String()) + data_source = graphene.Field(DataSourceType, id=graphene.ID(required=True)) def resolve_mustahiks(self, info, **kwargs): statuses = kwargs.get('statuses', None) @@ -33,3 +35,14 @@ class MustahikQuery(graphene.ObjectType): def resolve_mustahik(self, info, id): return Mustahik.objects.get(pk=id) + + def resolve_data_sources(self, info, **kwargs): + category = kwargs.get('category') + filter_query = Q() + if category: + filter_query &= Q(category=category) + + return DataSource.objects.filter(filter_query) + + def resolve_data_source(self, info, id): + return DataSource.objects.get(pk=id) diff --git a/sizakat/mustahik/types.py b/sizakat/mustahik/types.py index d1d87cb..fdb73dc 100644 --- a/sizakat/mustahik/types.py +++ b/sizakat/mustahik/types.py @@ -1,7 +1,10 @@ import graphene from graphene_django.types import DjangoObjectType -from .models import Mustahik +from .models import ( + Mustahik, DataSource, DataSourceInstitusi, + DataSourcePekerja, DataSourceWarga +) class MustahikType(DjangoObjectType): @@ -9,3 +12,45 @@ class MustahikType(DjangoObjectType): model = Mustahik age = graphene.Int(source='calculate_age') + + +class DataSourceInstitusiType(DjangoObjectType): + class Meta: + model = DataSourceInstitusi + + +class DataSourcePekerjaType(DjangoObjectType): + class Meta: + model = DataSourcePekerja + + +class DataSourceWargaType(DjangoObjectType): + class Meta: + model = DataSourceWarga + + +class DataSourceDetailType(graphene.Union): + class Meta: + types = ( + DataSourceInstitusiType, DataSourcePekerjaType, + DataSourceWargaType + ) + my_attr = True + + +class DataSourceType(DjangoObjectType): + class Meta: + model = DataSource + exclude = ( + 'datasourceinstitusi', 'datasourcepekerja', 'datasourcewarga' + ) + + data_source_detail = graphene.Field(DataSourceDetailType) + + def resolve_data_source_detail(self, info): + if self.category == DataSource.Category.INSTITUSI: + return DataSourceInstitusi.objects.get(data_source__pk=self.pk) + if self.category == DataSource.Category.PEKERJA: + return DataSourcePekerja.objects.get(data_source__pk=self.pk) + if self.category == DataSource.Category.WARGA: + return DataSourceWarga.objects.get(data_source__pk=self.pk) -- GitLab From d022550de6376e563410183e959fc360b27dd1ae Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Wed, 29 Jul 2020 16:45:40 +0700 Subject: [PATCH 31/41] [REFACTOR] memindahkan atribut model data source ke model detail data source --- sizakat/mustahik/models.py | 17 ++-- sizakat/mustahik/tests.py | 155 +++++++++++++++++++------------------ 2 files changed, 90 insertions(+), 82 deletions(-) diff --git a/sizakat/mustahik/models.py b/sizakat/mustahik/models.py index 18067f0..be83d10 100644 --- a/sizakat/mustahik/models.py +++ b/sizakat/mustahik/models.py @@ -49,6 +49,13 @@ class DataSource(models.Model): INSTITUSI = ('INSTITUSI', 'Institusi') PEKERJA = ('PEKERJA', 'Pekerja') + category = models.CharField(max_length=32, choices=Category.choices) + + +class DataSourceDetail(models.Model): + class Meta: + abstract = True + pic_name = models.CharField(max_length=150) pic_ktp = models.CharField( max_length=32, @@ -59,13 +66,9 @@ class DataSource(models.Model): validators=[validate_numeric_character] ) pic_position = models.CharField(max_length=50) - category = models.CharField(max_length=32, choices=Category.choices) - - class Meta: - unique_together = ('pic_ktp', 'category',) -class DataSourceWarga(models.Model): +class DataSourceWarga(DataSourceDetail): province = models.CharField(max_length=50) regency = models.CharField(max_length=50) sub_district = models.CharField(max_length=50) @@ -82,7 +85,7 @@ class DataSourceWarga(models.Model): ) -class DataSourceInstitusi(models.Model): +class DataSourceInstitusi(DataSourceDetail): name = models.CharField(max_length=150) province = models.CharField(max_length=50) regency = models.CharField(max_length=50) @@ -101,7 +104,7 @@ class DataSourceInstitusi(models.Model): ) -class DataSourcePekerja(models.Model): +class DataSourcePekerja(DataSourceDetail): profession = models.CharField(max_length=50) location = models.CharField(max_length=50) data_source = models.OneToOneField( diff --git a/sizakat/mustahik/tests.py b/sizakat/mustahik/tests.py index fabe5d0..d85d0f8 100644 --- a/sizakat/mustahik/tests.py +++ b/sizakat/mustahik/tests.py @@ -12,29 +12,13 @@ from .models import DataSource, DataSourceInstitusi, DataSourcePekerja, DataSour class MustahikModelTestCase(TestCase): def setUp(self): - data_source_institusi = DataSource.objects.create( - pic_name='pic test', - pic_ktp='1234567890', - pic_phone='0812389120', - pic_position='test', - category=DataSource.Category.INSTITUSI - ) - institusi_detail = DataSourceInstitusi.objects.create( - name='lembaga test', - address='jl test', - data_source=data_source_institusi, - province='jakarta', - regency='jakarta timur', - sub_district='makasar', - village='pinangranti', - rt='001', - rw='001' - ) + data_source_detail = { + 'pic_name': 'pic test', + 'pic_ktp': '1234567890', + 'pic_phone': '0812389120', + 'pic_position': 'test', + } data_source_pekerja = DataSource.objects.create( - pic_name='pic test', - pic_ktp='1234567891', - pic_phone='0812389121', - pic_position='test', category=DataSource.Category.PEKERJA ) pekerja_detail = DataSourcePekerja.objects.create( @@ -42,53 +26,26 @@ class MustahikModelTestCase(TestCase): profession='tester', location='jl tester' ) - data_source_warga = DataSource.objects.create( - pic_name='pic test', - pic_ktp='1234567892', - pic_phone='0812389122', - pic_position='test', - category=DataSource.Category.WARGA - ) - institusi_detail = DataSourceWarga.objects.create( - data_source=data_source_warga, - province='jakarta', - regency='jakarta timur', - sub_district='makasar', - village='pinangranti', - rt='001', - rw='001' - ) + mustahik_base = { + 'phone': '081234567890', + 'address': 'Jalan raya depok', + 'birthdate': date(1987, 6, 5), + 'status': Mustahik.Status.MISKIN, + 'gender': Mustahik.Gender.LAKILAKI, + } mustahik = Mustahik.objects.create( - name='mustahik', - no_ktp='31751234567890', - phone='081234567890', - address='Jalan raya depok', - birthdate=date(1987, 6, 5), - status=Mustahik.Status.MISKIN, - gender=Mustahik.Gender.LAKILAKI, - data_source=data_source_warga + name='mustahik1', + no_ktp='31751234567891', + data_source=data_source_pekerja, + **mustahik_base ) - def test_mustahik_creation_from_datasource_institusi(self): - mustahik = Mustahik.objects.get(no_ktp='31751234567890') + def test_mustahik_creation(self): + mustahik = Mustahik.objects.get(no_ktp='31751234567891') self.assertTrue(isinstance(mustahik, Mustahik)) - def test_mustahik_change_datasource_to_datasource_pekerja(self): - data_source_pekerja = DataSource.objects.get(pic_ktp='1234567891') - mustahik = Mustahik.objects.get(no_ktp='31751234567890') - mustahik.data_source = data_source_pekerja - mustahik.save() - self.assertEqual(mustahik.data_source.category, DataSource.Category.PEKERJA) - - def test_mustahik_change_datasource_to_datasource_warga(self): - data_source_warga = DataSource.objects.get(pic_ktp='1234567892') - mustahik = Mustahik.objects.get(no_ktp='31751234567890') - mustahik.data_source = data_source_warga - mustahik.save() - self.assertEqual(mustahik.data_source.category, DataSource.Category.WARGA) - def test_calculate_mustahik_age(self): - mustahik = Mustahik.objects.get(no_ktp='31751234567890') + mustahik = Mustahik.objects.get(no_ktp='31751234567891') self.assertEqual( mustahik.calculate_age(), timezone.now().year - mustahik.birthdate.year @@ -100,14 +57,14 @@ class MustahikGraphQLTestCase(GraphQLTestCase): def setUp(self): data_source_warga = DataSource.objects.create( - pic_name='pic test', - pic_ktp='1234567892', - pic_phone='0812389122', - pic_position='test', category=DataSource.Category.WARGA ) data_source_detail = DataSourceWarga.objects.create( data_source=data_source_warga, + pic_name='pic test', + pic_ktp='1234567892', + pic_phone='0812389122', + pic_position='test', province='jakarta', regency='jakarta timur', sub_district='makasar', @@ -126,9 +83,14 @@ class MustahikGraphQLTestCase(GraphQLTestCase): data_source=data_source_warga ) + def test_about_query(self): + response = self.query('{ about }') + self.assertResponseNoErrors(response) + def test_mustahik_mutation_can_add_new_mustahik(self): no_ktp = '123891210121' - data_source = DataSource.objects.get(pic_ktp='1234567892') + data_source_warga = DataSourceWarga.objects.get(pic_ktp='1234567892') + data_source = data_source_warga.data_source response = self.query( ''' mutation mustahikMutation($input: MustahikMutationInput!) { @@ -169,7 +131,8 @@ class MustahikGraphQLTestCase(GraphQLTestCase): def test_mustahik_mutation_can_update_mustahik(self): mustahik = Mustahik.objects.get(no_ktp='31751234567890') - data_source = mustahik.data_source + data_source_warga = DataSourceWarga.objects.get(pic_ktp='1234567892') + data_source = data_source_warga.data_source mustahik_id = mustahik.pk old_status = mustahik.status new_status = 'MUSAFIR' @@ -408,18 +371,60 @@ class MustahikGraphQLTestCase(GraphQLTestCase): self.assertTrue(all([category == DataSource.Category.WARGA for category in categories])) def test_data_source_query_detail_with_given_id(self): + data_source_detail = { + 'pic_name': 'pic test', + 'pic_ktp': '1234567890', + 'pic_phone': '0812389120', + 'pic_position': 'test', + } + data_source_pekerja = DataSource.objects.create( + category=DataSource.Category.PEKERJA + ) + pekerja_detail = DataSourcePekerja.objects.create( + data_source=data_source_pekerja, + profession='tester', + location='jl tester', + **data_source_detail + ) + data_source_institusi = DataSource.objects.create( + category=DataSource.Category.INSTITUSI + ) + pekerja_detail = DataSourceInstitusi.objects.create( + data_source=data_source_institusi, + name='test', + province='test', + regency='test', + sub_district='test', + village='test', + rw='01', + rt='01', + address='test', + **data_source_detail + ) response = self.query( ''' - query dataSourceQuery($id: ID!) { - dataSource(id: $id) { + query dataSourceQuery($id1: ID!, $id2: ID!, $id3: ID!) { + q1: dataSource(id: $id1) { + id + detail: dataSourceDetail { __typename } + } + q2: dataSource(id: $id2) { + id + detail: dataSourceDetail { __typename } + } + q3: dataSource(id: $id3) { id - picName + detail: dataSourceDetail { __typename } } } ''', op_name='dataSourceQuery', - variables={'id': 1} + variables={'id1': 2, 'id2': 3, 'id3': 4} ) content = json.loads(response.content) - self.assertEqual(content['data']['dataSource']['id'], '1') - self.assertEqual(content['data']['dataSource']['picName'], 'pic test') + self.assertEqual(content['data']['q1']['id'], '2') + self.assertEqual(content['data']['q1']['detail']['__typename'], 'DataSourceWargaType') + self.assertEqual(content['data']['q2']['id'], '3') + self.assertEqual(content['data']['q2']['detail']['__typename'], 'DataSourcePekerjaType') + self.assertEqual(content['data']['q3']['id'], '4') + self.assertEqual(content['data']['q3']['detail']['__typename'], 'DataSourceInstitusiType') -- GitLab From daef951e435926ce25bdba0c037fcd3fa8579fac Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Wed, 29 Jul 2020 16:56:34 +0700 Subject: [PATCH 32/41] [GREEN] update migrations file --- sizakat/mustahik/migrations/0001_initial.py | 30 +++++++++++++++------ 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/sizakat/mustahik/migrations/0001_initial.py b/sizakat/mustahik/migrations/0001_initial.py index b14b749..c0e1595 100644 --- a/sizakat/mustahik/migrations/0001_initial.py +++ b/sizakat/mustahik/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.0.7 on 2020-07-28 10:47 +# Generated by Django 3.0.7 on 2020-07-29 08:26 import django.core.validators from django.db import migrations, models @@ -17,15 +17,8 @@ class Migration(migrations.Migration): name='DataSource', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('pic_name', models.CharField(max_length=150)), - ('pic_ktp', models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), - ('pic_phone', models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), - ('pic_position', models.CharField(max_length=50)), ('category', models.CharField(choices=[('WARGA', 'Warga'), ('INSTITUSI', 'Institusi'), ('PEKERJA', 'Pekerja')], max_length=32)), ], - options={ - 'unique_together': {('pic_ktp', 'category')}, - }, ), migrations.CreateModel( name='Mustahik', @@ -46,6 +39,10 @@ class Migration(migrations.Migration): name='DataSourceWarga', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('pic_name', models.CharField(max_length=150)), + ('pic_ktp', models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), + ('pic_phone', models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), + ('pic_position', models.CharField(max_length=50)), ('province', models.CharField(max_length=50)), ('regency', models.CharField(max_length=50)), ('sub_district', models.CharField(max_length=50)), @@ -54,20 +51,34 @@ class Migration(migrations.Migration): ('rw', models.CharField(max_length=3, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), ('data_source', models.OneToOneField(limit_choices_to={'category': 'WARGA'}, on_delete=django.db.models.deletion.CASCADE, to='mustahik.DataSource')), ], + options={ + 'abstract': False, + }, ), migrations.CreateModel( name='DataSourcePekerja', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('pic_name', models.CharField(max_length=150)), + ('pic_ktp', models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), + ('pic_phone', models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), + ('pic_position', models.CharField(max_length=50)), ('profession', models.CharField(max_length=50)), ('location', models.CharField(max_length=50)), ('data_source', models.OneToOneField(limit_choices_to={'category': 'PEKERJA'}, on_delete=django.db.models.deletion.CASCADE, to='mustahik.DataSource')), ], + options={ + 'abstract': False, + }, ), migrations.CreateModel( name='DataSourceInstitusi', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('pic_name', models.CharField(max_length=150)), + ('pic_ktp', models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), + ('pic_phone', models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9]*$', 'Numeric character only.')])), + ('pic_position', models.CharField(max_length=50)), ('name', models.CharField(max_length=150)), ('province', models.CharField(max_length=50)), ('regency', models.CharField(max_length=50)), @@ -78,5 +89,8 @@ class Migration(migrations.Migration): ('address', models.CharField(max_length=255)), ('data_source', models.OneToOneField(limit_choices_to={'category': 'INSTITUSI'}, on_delete=django.db.models.deletion.CASCADE, to='mustahik.DataSource')), ], + options={ + 'abstract': False, + }, ), ] -- GitLab From 7d4254e8b4b5f0d8c9c80ebfc41faf52fef35bb2 Mon Sep 17 00:00:00 2001 From: abdurrafiarief <abdurrafiarief@gmail.com> Date: Thu, 30 Jul 2020 20:10:20 +0700 Subject: [PATCH 33/41] [RED] data source mutation tests --- sizakat/mustahik/forms.py | 57 ++++- sizakat/mustahik/mutations.py | 28 ++- sizakat/mustahik/tests.py | 428 ++++++++++++++++++++++++++++++++-- sizakat/schema.py | 4 +- 4 files changed, 496 insertions(+), 21 deletions(-) diff --git a/sizakat/mustahik/forms.py b/sizakat/mustahik/forms.py index 485c70e..11351c7 100644 --- a/sizakat/mustahik/forms.py +++ b/sizakat/mustahik/forms.py @@ -1,6 +1,6 @@ from django import forms -from .models import Mustahik +from .models import Mustahik, DataSource, DataSourceWarga, DataSourceInstitusi, DataSourcePekerja class MustahikForm(forms.ModelForm): @@ -16,3 +16,58 @@ class MustahikForm(forms.ModelForm): 'gender', 'data_source', ] + +class DataSourceForm(forms.ModelForm): + class Meta: + model = DataSource + fields = [ + 'category', + ] + +class DataSourceWargaForm(forms.ModelForm): + class Meta: + model = DataSourceWarga + fields = [ + 'pic_name', + 'pic_ktp', + 'pic_phone', + 'pic_position', + 'province', + 'regency', + 'sub_district', + 'village', + 'rt', + 'rw', + 'data_source', + ] + +class DataSourceInstitusiForm(forms.ModelForm): + class Meta: + model = DataSourceInstitusi + fields = [ + 'pic_name', + 'pic_ktp', + 'pic_phone', + 'pic_position', + 'name', + 'province', + 'sub_district', + 'village', + 'rt', + 'rw', + 'address', + 'data_source', + ] + +class DataSourcePekerjaForm(forms.ModelForm): + class Meta: + model = DataSourcePekerja + fields = [ + 'pic_name', + 'pic_ktp', + 'pic_phone', + 'pic_position', + 'profession', + 'location', + 'data_source', + ] \ No newline at end of file diff --git a/sizakat/mustahik/mutations.py b/sizakat/mustahik/mutations.py index 48f21d9..439afef 100644 --- a/sizakat/mustahik/mutations.py +++ b/sizakat/mustahik/mutations.py @@ -2,9 +2,9 @@ import graphene from graphene_django.forms.mutation import DjangoModelFormMutation -from .forms import MustahikForm +from .forms import MustahikForm, DataSourceForm, DataSourceWargaForm, DataSourceInstitusiForm, DataSourcePekerjaForm from .models import Mustahik -from .types import MustahikType +from .types import MustahikType, DataSourceInstitusiType, DataSourcePekerjaType, DataSourceWargaType, DataSourceType class MustahikMutation(DjangoModelFormMutation): @@ -30,3 +30,27 @@ class DeleteMustahik(graphene.Mutation): mustahik.delete() deleted = True return DeleteMustahik(deleted=deleted, id_mustahik=id, name=name, no_ktp=no_ktp) + +class DataSourceMutation(DjangoModelFormMutation): + dataSource = graphene.Field(DataSourceType) + + class Meta: + form_class = DataSourceForm + +class DataSourceWargaMutation(DjangoModelFormMutation): + dataSourceWarga = graphene.Field(DataSourceWargaType) + + class Meta: + form_class = DataSourceWargaForm + +class DataSourceInstitusiMutation(DjangoModelFormMutation): + dataSourceInstitusi = graphene.Field(DataSourceInstitusiType) + + class Meta: + form_class = DataSourceInstitusiForm + +class DataSourcePekerjaMutation(DjangoModelFormMutation): + dataSourcePekerja = graphene.Field(DataSourcePekerjaType) + + class Meta: + form_class = DataSourcePekerjaForm diff --git a/sizakat/mustahik/tests.py b/sizakat/mustahik/tests.py index d85d0f8..b41b715 100644 --- a/sizakat/mustahik/tests.py +++ b/sizakat/mustahik/tests.py @@ -40,6 +40,43 @@ class MustahikModelTestCase(TestCase): **mustahik_base ) + data_source_institusi = DataSource.objects.create( + category=DataSource.Category.INSTITUSI + ) + + institusi_detail = DataSourceInstitusi.objects.create( + pic_ktp = '12345678901234', + pic_name = 'instisusi', + pic_phone = '123456789012', + pic_position = 'Head', + name = 'Institusi Bandung', + province = 'Jawa Barat', + sub_district = 'Bogor', + village = 'Desa', + rt = '001', + rw = '001', + address = 'Jalan suatu desa no 1', + data_source = data_source_institusi, + ) + + data_source_warga = DataSource.objects.create( + category=DataSource.Category.WARGA + ) + + warga_detail = DataSourceWarga.objects.create( + pic_ktp = '12345678901111', + pic_name = 'wargai', + pic_phone = '123456789012', + pic_position = 'Ketua RT', + province = 'Test Barat', + regency = 'Kabupaten test', + sub_district = 'Testmatan', + village = 'Desa tes', + rt = '001', + rw = '002', + data_source = data_source_warga + ) + def test_mustahik_creation(self): mustahik = Mustahik.objects.get(no_ktp='31751234567891') self.assertTrue(isinstance(mustahik, Mustahik)) @@ -51,6 +88,14 @@ class MustahikModelTestCase(TestCase): timezone.now().year - mustahik.birthdate.year ) + def test_data_source_warga_creation(self): + data_source_warga = DataSourceWarga.objects.get(pic_ktp='12345678901111') + self.assertTrue(isinstance(data_source_warga, DataSourceWarga)) + + def test_data_source_institusi_creation(self): + data_source_institusi = DataSourceInstitusi.objects.get(pic_ktp='12345678901234') + self.assertTrue(isinstance(data_source_institusi, DataSourceInstitusi)) + class MustahikGraphQLTestCase(GraphQLTestCase): GRAPHQL_SCHEMA = schema @@ -83,6 +128,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase): data_source=data_source_warga ) + def test_about_query(self): response = self.query('{ about }') self.assertResponseNoErrors(response) @@ -371,35 +417,36 @@ class MustahikGraphQLTestCase(GraphQLTestCase): self.assertTrue(all([category == DataSource.Category.WARGA for category in categories])) def test_data_source_query_detail_with_given_id(self): - data_source_detail = { - 'pic_name': 'pic test', - 'pic_ktp': '1234567890', - 'pic_phone': '0812389120', - 'pic_position': 'test', - } + warga_detail = DataSourceWarga.objects.get(pic_ktp='1234567892') + data_source_pekerja = DataSource.objects.create( category=DataSource.Category.PEKERJA ) pekerja_detail = DataSourcePekerja.objects.create( - data_source=data_source_pekerja, + pic_name='pic test', + pic_ktp='1234567890', + pic_phone='0812389120', + pic_position='test', profession='tester', location='jl tester', - **data_source_detail + data_source=data_source_pekerja, ) data_source_institusi = DataSource.objects.create( category=DataSource.Category.INSTITUSI ) - pekerja_detail = DataSourceInstitusi.objects.create( - data_source=data_source_institusi, + institusi_detail = DataSourceInstitusi.objects.create( + pic_name='pic test', + pic_ktp='1234567891', + pic_phone='0812389120', + pic_position='test', name='test', province='test', - regency='test', sub_district='test', village='test', rw='01', rt='01', address='test', - **data_source_detail + data_source=data_source_institusi, ) response = self.query( ''' @@ -419,12 +466,361 @@ class MustahikGraphQLTestCase(GraphQLTestCase): } ''', op_name='dataSourceQuery', - variables={'id1': 2, 'id2': 3, 'id3': 4} + variables={'id1': warga_detail.data_source.pk, + 'id2': pekerja_detail.data_source.pk, + 'id3': institusi_detail.data_source.pk} ) + + self.assertResponseNoErrors(response) + content = json.loads(response.content) - self.assertEqual(content['data']['q1']['id'], '2') + self.assertEqual(content['data']['q1']['id'], str(warga_detail.data_source.pk)) self.assertEqual(content['data']['q1']['detail']['__typename'], 'DataSourceWargaType') - self.assertEqual(content['data']['q2']['id'], '3') + self.assertEqual(content['data']['q2']['id'], str(pekerja_detail.data_source.pk)) self.assertEqual(content['data']['q2']['detail']['__typename'], 'DataSourcePekerjaType') - self.assertEqual(content['data']['q3']['id'], '4') + self.assertEqual(content['data']['q3']['id'], str(institusi_detail.data_source.pk)) self.assertEqual(content['data']['q3']['detail']['__typename'], 'DataSourceInstitusiType') + + + def test_data_source_mutation_can_add_new_data_source(self): + existing_data_source_ammount = DataSource.objects.count() + response = self.query( + ''' + mutation dataSourceMutation($input: DataSourceMutationInput!){ + dataSourceMutation(input: $input){ + dataSource{ + category + } + } + } + ''', + op_name='dataSourceMutation', + input_data={ + 'category':'WARGA', + } + ) + + #This validates the status code and if you get errors + self.assertResponseNoErrors(response) + + #Validate content + content = json.loads(response.content) + self.assertEqual(content['data']['dataSourceMutation']['dataSource']['category'], "WARGA") + + #Validate successful save to db + new_ammount = existing_data_source_ammount + 1 + self.assertEqual(DataSource.objects.count(), new_ammount) + + def test_data_source_warga_mutation_can_add_new_data_source_warga(self): + pic_ktp = "123456789012" + old_ammount = DataSourceWarga.objects.count() + data_source_warga = DataSource.objects.create(category=DataSource.Category.WARGA) + + response = self.query( + ''' + mutation dataSourceWargaMutation($input: DataSourceWargaMutationInput!){ + dataSourceWargaMutation(input: $input){ + dataSourceWarga{ + picName + picKtp + picPhone + picPosition + province + regency + subDistrict + village + rt + rw + dataSource{id} + } + } + } + ''', + op_name='dataSourceWargaMutation', + input_data={ + "picName": "Anjay", + "picKtp": pic_ktp, + "picPhone": "1231231234", + "picPosition": "Head", + "province": "Jawa Barat", + "regency": "Kebumen", + "subDistrict": "Anjaydsitrict", + "village": "Desa dusun", + "rt": "001", + "rw": "002", + "dataSource":data_source_warga.pk + } + ) + # This validates the status code and if you get errors + self.assertResponseNoErrors(response) + + # Validate content + content = json.loads(response.content) + self.assertEqual(content['data']['dataSourceWargaMutation'] + ['dataSourceWarga']['picKtp'], pic_ktp) + + # Validate successful save to db + new_ammount = old_ammount + 1 + self.assertEqual(DataSourceWarga.objects.count(), new_ammount) + source_warga = DataSourceWarga.objects.get(pic_ktp=pic_ktp) + self.assertEqual(source_warga.pic_name, "Anjay") + + def test_data_source_warga_mutation_can_update_data_source_warga(self): + pic_ktp = "123456789012" + new_pic_name = "Aryo" + data_source_warga = DataSource.objects.create( + category=DataSource.Category.WARGA + ) + + warga_detail = DataSourceWarga.objects.create( + pic_ktp = pic_ktp, + pic_name = 'wargai', + pic_phone = '123456789012', + pic_position = 'Ketua RT', + province = 'Test Barat', + regency = 'Kabupaten test', + sub_district = 'Testmatan', + village = 'Desa tes', + rt = '001', + rw = '002', + data_source = data_source_warga + ) + + response = self.query( + ''' + mutation dataSourceWargaMutation($input: DataSourceWargaMutationInput!){ + dataSourceWargaMutation(input: $input){ + dataSourceWarga{ + picName + } + } + } + ''', + op_name='dataSourceWargaMutation', + input_data={ + "picName": new_pic_name, + "picKtp": pic_ktp, + "picPhone": "1231231234", + "picPosition": "Head", + "province": "Jawa Barat", + "regency": "Kebumen", + "subDistrict": "Anjaydsitrict", + "village": "Desa dusun", + "rt": "001", + "rw": "002", + "dataSource":data_source_warga.pk, + "id": warga_detail.pk + } + ) + + #Validate success update data source warga + source = DataSourceWarga.objects.get(pic_ktp=pic_ktp) + self.assertEqual(source.pic_name, new_pic_name) + + def test_data_source_pekerja_mutation_can_add_new_data_source_pekerja(self): + pic_ktp = "123456789012" + pic_name = "lulu" + old_ammount = DataSourcePekerja.objects.count() + data_source_pekerja = DataSource.objects.create( + category=DataSource.Category.PEKERJA + ) + + response = self.query( + ''' + mutation dataSourcePekerjaMutation($input: DataSourcePekerjaMutationInput!){ + dataSourcePekerjaMutation(input: $input){ + dataSourcePekerja{ + picName + picKtp + picPhone + picPosition + profession + location + dataSource{id} + } + } + } + + ''', + op_name='dataSourcePekerjaMutation', + input_data={ + "picName": pic_name, + "picKtp": pic_ktp, + "picPhone": "098765432123", + "picPosition": "Leader", + "profession": "Programmer", + "location": "Bogor", + "dataSource": data_source_pekerja.pk, + } + ) + + # This validates the status code and if you get errors + self.assertResponseNoErrors(response) + + # Validate content + content = json.loads(response.content) + self.assertEqual(content['data']['dataSourcePekerjaMutation'] + ['dataSourcePekerja']['picKtp'], pic_ktp) + + # Validate successful save to db + new_ammount = old_ammount + 1 + self.assertEqual(DataSourcePekerja.objects.count(), new_ammount) + source = DataSourcePekerja.objects.get(pic_ktp=pic_ktp) + self.assertEqual(source.pic_name, pic_name) + + + def test_data_source_pekerja_mutation_can_update_data_source_pekerja(self): + pic_ktp = "123456789012" + new_pic_name = "Aryo" + + data_source_pekerja = DataSource.objects.create( + category=DataSource.Category.PEKERJA + ) + source_pekerja = DataSourcePekerja.objects.create( + pic_name = 'wargai', + pic_ktp = pic_ktp, + pic_phone = '123456789012', + pic_position = 'Ketua RT', + profession = 'tester', + location = 'jl tester', + data_source=data_source_pekerja, + ) + + response = self.query( + ''' + mutation dataSourcePekerjaMutation($input: DataSourcePekerjaMutationInput!){ + dataSourcePekerjaMutation(input: $input){ + dataSourcePekerja{ + picName + } + } + } + ''', + op_name = "dataSourcePekerjaMutation", + input_data={ + "picName": new_pic_name, + "picKtp": pic_ktp, + "picPhone": '123456789012', + "picPosition": 'Ketua RT', + "profession": 'tester', + "location": 'jl tester', + "dataSource": data_source_pekerja.pk, + "id": source_pekerja.pk + } + ) + + #Validate successful update to data source pekerja + source = DataSourcePekerja.objects.get(pic_ktp=pic_ktp) + self.assertEqual(source.pic_name, new_pic_name) + + def test_data_source_institusi_mutation_can_add_new_data_source_institusi(self): + pic_ktp = "109872901098" + pic_name = "Susi" + old_ammount = DataSourceInstitusi.objects.count() + data_source_institusi = DataSource.objects.create( + category=DataSource.Category.INSTITUSI + ) + + response = self.query( + ''' + mutation dataSourceInstitusiMutation($input: DataSourceInstitusiMutationInput!){ + dataSourceInstitusiMutation(input: $input){ + dataSourceInstitusi{ + picName + picKtp + picPhone + picPosition + } + } + } + + ''', + op_name="dataSourceInstitusiMutation", + input_data={ + "picName": pic_name, + "picKtp": pic_ktp, + "picPhone": "09876544323", + "picPosition": "Vice", + "name": "Pesantren Yatim", + "province": "Jawa Barat", + "subDistrict": "Dusun", + "village": "desa", + "rt": "002", + "rw": "001", + "address": "Jalan duku empat 1", + "dataSource": data_source_institusi.pk, + } + ) + + # This validates the status code and if you get errors + self.assertResponseNoErrors(response) + + #Validate content + content = json.loads(response.content) + self.assertEqual(content['data']['dataSourceInstitusiMutation'] + ['dataSourceInstitusi']['picKtp'], pic_ktp) + + #Validate success save to db + new_ammount = old_ammount + 1 + self.assertEqual(DataSourceInstitusi.objects.count(), new_ammount) + source = DataSourceInstitusi.objects.get(pic_ktp=pic_ktp) + self.assertEqual(source.pic_name, pic_name) + + + def test_data_source_institusi_mutation_can_update_data_source_institusi(self): + pic_ktp = '12345678901234' + new_pic_name = 'Rofi Arief' + + data_source_institusi = DataSource.objects.create( + category=DataSource.Category.INSTITUSI + ) + + source_institusi = DataSourceInstitusi.objects.create( + pic_ktp = pic_ktp, + pic_name = 'Rofi', + pic_phone = '123456789012', + pic_position = 'Head', + name = 'Institusi Bandung', + province = 'Jawa Barat', + sub_district = 'Bogor', + village = 'Desa', + rt = '001', + rw = '001', + address = 'Jalan suatu desa no 1', + data_source = data_source_institusi, + ) + + response = self.query( + ''' + mutation dataSourceInstitusiMutation($input: DataSourceInstitusiMutationInput!){ + dataSourceInstitusiMutation(input: $input){ + dataSourceInstitusi{ + picName + picKtp + picPhone + picPosition + } + } + } + ''', + op_name = 'dataSourceInstitusiMutation', + input_data = { + "picKtp": pic_ktp, + "picName": new_pic_name, + "picPhone": "123456789012", + "picPosition": "Head", + "name": "Institusi Bandung", + "province": "Jawa Barat", + "subDistrict": "Bogor", + "village": "Desa", + "rt": "001", + "rw": "001", + "address": "Jalan suatu desa no 1", + "dataSource": data_source_institusi.pk, + "id": source_institusi.pk, + } + ) + + #Validate success update data source institusi + source = DataSourceInstitusi.objects.get(pic_ktp=pic_ktp) + self.assertEqual(source.pic_name, new_pic_name) diff --git a/sizakat/schema.py b/sizakat/schema.py index 683f54f..9dcc6cd 100644 --- a/sizakat/schema.py +++ b/sizakat/schema.py @@ -2,7 +2,7 @@ import graphene from graphene_django import DjangoObjectType -from .mustahik.mutations import MustahikMutation, DeleteMustahik +from .mustahik.mutations import MustahikMutation, DeleteMustahik, DataSourceMutation, DataSourceWargaMutation, DataSourceInstitusiMutation, DataSourcePekerjaMutation from .mustahik.query import MustahikQuery ABOUT = ('Si Zakat merupakan sistem informasi untuk membantu masjid dalam ' @@ -20,6 +20,6 @@ class Query(MustahikQuery, graphene.ObjectType): class Mutation(graphene.ObjectType): mustahik_mutation = MustahikMutation.Field() delete_mustahik = DeleteMustahik.Field() - + schema = graphene.Schema(query=Query, mutation=Mutation) -- GitLab From b752cb6c8d671a0796cc62240307868ac56480e3 Mon Sep 17 00:00:00 2001 From: abdurrafiarief <abdurrafiarief@gmail.com> Date: Thu, 30 Jul 2020 20:11:24 +0700 Subject: [PATCH 34/41] [GREEN]Implemented mutation for data sources --- sizakat/schema.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sizakat/schema.py b/sizakat/schema.py index 9dcc6cd..fddb2fa 100644 --- a/sizakat/schema.py +++ b/sizakat/schema.py @@ -20,6 +20,10 @@ class Query(MustahikQuery, graphene.ObjectType): class Mutation(graphene.ObjectType): mustahik_mutation = MustahikMutation.Field() delete_mustahik = DeleteMustahik.Field() - + dataSource_mutation = DataSourceMutation.Field() + dataSourceWarga_mutation = DataSourceWargaMutation.Field() + dataSourceInstitusi_mutation = DataSourceInstitusiMutation.Field() + dataSourcePekerja_mutation = DataSourcePekerjaMutation.Field() + schema = graphene.Schema(query=Query, mutation=Mutation) -- GitLab From 6f594867cb8bcba231b40861f046dae6bd0a5b55 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Sat, 1 Aug 2020 20:27:34 +0700 Subject: [PATCH 35/41] [REFACTOR] memindahkan fungsi get detil ke model --- sizakat/mustahik/models.py | 8 ++++++++ sizakat/mustahik/types.py | 12 +++--------- sizakat/schema.py | 6 +++++- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/sizakat/mustahik/models.py b/sizakat/mustahik/models.py index be83d10..bf21785 100644 --- a/sizakat/mustahik/models.py +++ b/sizakat/mustahik/models.py @@ -51,6 +51,14 @@ class DataSource(models.Model): category = models.CharField(max_length=32, choices=Category.choices) + def get_source_detail(self): + if self.category == DataSource.Category.INSTITUSI: + return DataSourceInstitusi.objects.get(data_source=self) + if self.category == DataSource.Category.PEKERJA: + return DataSourcePekerja.objects.get(data_source=self) + if self.category == DataSource.Category.WARGA: + return DataSourceWarga.objects.get(data_source=self) + class DataSourceDetail(models.Model): class Meta: diff --git a/sizakat/mustahik/types.py b/sizakat/mustahik/types.py index fdb73dc..2b1a7a2 100644 --- a/sizakat/mustahik/types.py +++ b/sizakat/mustahik/types.py @@ -45,12 +45,6 @@ class DataSourceType(DjangoObjectType): 'datasourceinstitusi', 'datasourcepekerja', 'datasourcewarga' ) - data_source_detail = graphene.Field(DataSourceDetailType) - - def resolve_data_source_detail(self, info): - if self.category == DataSource.Category.INSTITUSI: - return DataSourceInstitusi.objects.get(data_source__pk=self.pk) - if self.category == DataSource.Category.PEKERJA: - return DataSourcePekerja.objects.get(data_source__pk=self.pk) - if self.category == DataSource.Category.WARGA: - return DataSourceWarga.objects.get(data_source__pk=self.pk) + data_source_detail = graphene.Field( + DataSourceDetailType, source='get_source_detail' + ) diff --git a/sizakat/schema.py b/sizakat/schema.py index fddb2fa..bd0198b 100644 --- a/sizakat/schema.py +++ b/sizakat/schema.py @@ -2,7 +2,11 @@ import graphene from graphene_django import DjangoObjectType -from .mustahik.mutations import MustahikMutation, DeleteMustahik, DataSourceMutation, DataSourceWargaMutation, DataSourceInstitusiMutation, DataSourcePekerjaMutation +from .mustahik.mutations import ( + MustahikMutation, DeleteMustahik, DataSourceMutation, + DataSourceWargaMutation, DataSourceInstitusiMutation, + DataSourcePekerjaMutation +) from .mustahik.query import MustahikQuery ABOUT = ('Si Zakat merupakan sistem informasi untuk membantu masjid dalam ' -- GitLab From 503ec723ed42c380e06798b08d391777fcf3d896 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Sat, 1 Aug 2020 20:39:06 +0700 Subject: [PATCH 36/41] [RED] membuat test delete data source mutation --- sizakat/mustahik/tests.py | 173 +++++++++++++++++++++----------------- 1 file changed, 94 insertions(+), 79 deletions(-) diff --git a/sizakat/mustahik/tests.py b/sizakat/mustahik/tests.py index b41b715..e5d262d 100644 --- a/sizakat/mustahik/tests.py +++ b/sizakat/mustahik/tests.py @@ -45,18 +45,18 @@ class MustahikModelTestCase(TestCase): ) institusi_detail = DataSourceInstitusi.objects.create( - pic_ktp = '12345678901234', - pic_name = 'instisusi', - pic_phone = '123456789012', - pic_position = 'Head', - name = 'Institusi Bandung', - province = 'Jawa Barat', - sub_district = 'Bogor', - village = 'Desa', - rt = '001', - rw = '001', - address = 'Jalan suatu desa no 1', - data_source = data_source_institusi, + pic_ktp='12345678901234', + pic_name='instisusi', + pic_phone='123456789012', + pic_position='Head', + name='Institusi Bandung', + province='Jawa Barat', + sub_district='Bogor', + village='Desa', + rt='001', + rw='001', + address='Jalan suatu desa no 1', + data_source=data_source_institusi, ) data_source_warga = DataSource.objects.create( @@ -64,17 +64,17 @@ class MustahikModelTestCase(TestCase): ) warga_detail = DataSourceWarga.objects.create( - pic_ktp = '12345678901111', - pic_name = 'wargai', - pic_phone = '123456789012', - pic_position = 'Ketua RT', - province = 'Test Barat', - regency = 'Kabupaten test', - sub_district = 'Testmatan', - village = 'Desa tes', - rt = '001', - rw = '002', - data_source = data_source_warga + pic_ktp='12345678901111', + pic_name='wargai', + pic_phone='123456789012', + pic_position='Ketua RT', + province='Test Barat', + regency='Kabupaten test', + sub_district='Testmatan', + village='Desa tes', + rt='001', + rw='002', + data_source=data_source_warga ) def test_mustahik_creation(self): @@ -91,7 +91,7 @@ class MustahikModelTestCase(TestCase): def test_data_source_warga_creation(self): data_source_warga = DataSourceWarga.objects.get(pic_ktp='12345678901111') self.assertTrue(isinstance(data_source_warga, DataSourceWarga)) - + def test_data_source_institusi_creation(self): data_source_institusi = DataSourceInstitusi.objects.get(pic_ktp='12345678901234') self.assertTrue(isinstance(data_source_institusi, DataSourceInstitusi)) @@ -128,7 +128,6 @@ class MustahikGraphQLTestCase(GraphQLTestCase): data_source=data_source_warga ) - def test_about_query(self): response = self.query('{ about }') self.assertResponseNoErrors(response) @@ -466,9 +465,9 @@ class MustahikGraphQLTestCase(GraphQLTestCase): } ''', op_name='dataSourceQuery', - variables={'id1': warga_detail.data_source.pk, - 'id2': pekerja_detail.data_source.pk, - 'id3': institusi_detail.data_source.pk} + variables={'id1': warga_detail.data_source.pk, + 'id2': pekerja_detail.data_source.pk, + 'id3': institusi_detail.data_source.pk} ) self.assertResponseNoErrors(response) @@ -481,7 +480,6 @@ class MustahikGraphQLTestCase(GraphQLTestCase): self.assertEqual(content['data']['q3']['id'], str(institusi_detail.data_source.pk)) self.assertEqual(content['data']['q3']['detail']['__typename'], 'DataSourceInstitusiType') - def test_data_source_mutation_can_add_new_data_source(self): existing_data_source_ammount = DataSource.objects.count() response = self.query( @@ -496,18 +494,18 @@ class MustahikGraphQLTestCase(GraphQLTestCase): ''', op_name='dataSourceMutation', input_data={ - 'category':'WARGA', + 'category': 'WARGA', } ) - #This validates the status code and if you get errors + # This validates the status code and if you get errors self.assertResponseNoErrors(response) - #Validate content + # Validate content content = json.loads(response.content) self.assertEqual(content['data']['dataSourceMutation']['dataSource']['category'], "WARGA") - - #Validate successful save to db + + # Validate successful save to db new_ammount = existing_data_source_ammount + 1 self.assertEqual(DataSource.objects.count(), new_ammount) @@ -548,7 +546,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase): "village": "Desa dusun", "rt": "001", "rw": "002", - "dataSource":data_source_warga.pk + "dataSource": data_source_warga.pk } ) # This validates the status code and if you get errors @@ -557,7 +555,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase): # Validate content content = json.loads(response.content) self.assertEqual(content['data']['dataSourceWargaMutation'] - ['dataSourceWarga']['picKtp'], pic_ktp) + ['dataSourceWarga']['picKtp'], pic_ktp) # Validate successful save to db new_ammount = old_ammount + 1 @@ -573,17 +571,17 @@ class MustahikGraphQLTestCase(GraphQLTestCase): ) warga_detail = DataSourceWarga.objects.create( - pic_ktp = pic_ktp, - pic_name = 'wargai', - pic_phone = '123456789012', - pic_position = 'Ketua RT', - province = 'Test Barat', - regency = 'Kabupaten test', - sub_district = 'Testmatan', - village = 'Desa tes', - rt = '001', - rw = '002', - data_source = data_source_warga + pic_ktp=pic_ktp, + pic_name='wargai', + pic_phone='123456789012', + pic_position='Ketua RT', + province='Test Barat', + regency='Kabupaten test', + sub_district='Testmatan', + village='Desa tes', + rt='001', + rw='002', + data_source=data_source_warga ) response = self.query( @@ -608,12 +606,12 @@ class MustahikGraphQLTestCase(GraphQLTestCase): "village": "Desa dusun", "rt": "001", "rw": "002", - "dataSource":data_source_warga.pk, + "dataSource": data_source_warga.pk, "id": warga_detail.pk } ) - #Validate success update data source warga + # Validate success update data source warga source = DataSourceWarga.objects.get(pic_ktp=pic_ktp) self.assertEqual(source.pic_name, new_pic_name) @@ -624,7 +622,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase): data_source_pekerja = DataSource.objects.create( category=DataSource.Category.PEKERJA ) - + response = self.query( ''' mutation dataSourcePekerjaMutation($input: DataSourcePekerjaMutationInput!){ @@ -660,7 +658,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase): # Validate content content = json.loads(response.content) self.assertEqual(content['data']['dataSourcePekerjaMutation'] - ['dataSourcePekerja']['picKtp'], pic_ktp) + ['dataSourcePekerja']['picKtp'], pic_ktp) # Validate successful save to db new_ammount = old_ammount + 1 @@ -668,7 +666,6 @@ class MustahikGraphQLTestCase(GraphQLTestCase): source = DataSourcePekerja.objects.get(pic_ktp=pic_ktp) self.assertEqual(source.pic_name, pic_name) - def test_data_source_pekerja_mutation_can_update_data_source_pekerja(self): pic_ktp = "123456789012" new_pic_name = "Aryo" @@ -677,12 +674,12 @@ class MustahikGraphQLTestCase(GraphQLTestCase): category=DataSource.Category.PEKERJA ) source_pekerja = DataSourcePekerja.objects.create( - pic_name = 'wargai', - pic_ktp = pic_ktp, - pic_phone = '123456789012', - pic_position = 'Ketua RT', - profession = 'tester', - location = 'jl tester', + pic_name='wargai', + pic_ktp=pic_ktp, + pic_phone='123456789012', + pic_position='Ketua RT', + profession='tester', + location='jl tester', data_source=data_source_pekerja, ) @@ -696,7 +693,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase): } } ''', - op_name = "dataSourcePekerjaMutation", + op_name="dataSourcePekerjaMutation", input_data={ "picName": new_pic_name, "picKtp": pic_ktp, @@ -709,7 +706,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase): } ) - #Validate successful update to data source pekerja + # Validate successful update to data source pekerja source = DataSourcePekerja.objects.get(pic_ktp=pic_ktp) self.assertEqual(source.pic_name, new_pic_name) @@ -755,18 +752,17 @@ class MustahikGraphQLTestCase(GraphQLTestCase): # This validates the status code and if you get errors self.assertResponseNoErrors(response) - #Validate content + # Validate content content = json.loads(response.content) self.assertEqual(content['data']['dataSourceInstitusiMutation'] - ['dataSourceInstitusi']['picKtp'], pic_ktp) + ['dataSourceInstitusi']['picKtp'], pic_ktp) - #Validate success save to db + # Validate success save to db new_ammount = old_ammount + 1 self.assertEqual(DataSourceInstitusi.objects.count(), new_ammount) source = DataSourceInstitusi.objects.get(pic_ktp=pic_ktp) self.assertEqual(source.pic_name, pic_name) - def test_data_source_institusi_mutation_can_update_data_source_institusi(self): pic_ktp = '12345678901234' new_pic_name = 'Rofi Arief' @@ -776,18 +772,18 @@ class MustahikGraphQLTestCase(GraphQLTestCase): ) source_institusi = DataSourceInstitusi.objects.create( - pic_ktp = pic_ktp, - pic_name = 'Rofi', - pic_phone = '123456789012', - pic_position = 'Head', - name = 'Institusi Bandung', - province = 'Jawa Barat', - sub_district = 'Bogor', - village = 'Desa', - rt = '001', - rw = '001', - address = 'Jalan suatu desa no 1', - data_source = data_source_institusi, + pic_ktp=pic_ktp, + pic_name='Rofi', + pic_phone='123456789012', + pic_position='Head', + name='Institusi Bandung', + province='Jawa Barat', + sub_district='Bogor', + village='Desa', + rt='001', + rw='001', + address='Jalan suatu desa no 1', + data_source=data_source_institusi, ) response = self.query( @@ -803,8 +799,8 @@ class MustahikGraphQLTestCase(GraphQLTestCase): } } ''', - op_name = 'dataSourceInstitusiMutation', - input_data = { + op_name='dataSourceInstitusiMutation', + input_data={ "picKtp": pic_ktp, "picName": new_pic_name, "picPhone": "123456789012", @@ -821,6 +817,25 @@ class MustahikGraphQLTestCase(GraphQLTestCase): } ) - #Validate success update data source institusi + # Validate success update data source institusi source = DataSourceInstitusi.objects.get(pic_ktp=pic_ktp) self.assertEqual(source.pic_name, new_pic_name) + + def test_delete_datasource_mutations_can_delete_datasource(self): + count = DataSource.objects.count() + datasource = DataSource.objects.all()[0] + response = self.query( + ''' + mutation deleteDataSource($id: ID) { + deleteDataSource(id: $id) { + deleted + } + } + ''', + op_name='deleteDataSource', + variables={'id': datasource.pk} + ) + self.assertResponseNoErrors(response) + content = json.loads(response.content) + self.assertTrue(content['data']['deleteDataSource']['deleted']) + self.assertEquals(DataSource.objects.count(), count-1) -- GitLab From 3b25d162688daf1d4adab77ace6bb7358dde94c3 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Sat, 1 Aug 2020 20:39:49 +0700 Subject: [PATCH 37/41] [GREEN] implementasi delete datasource mutation --- sizakat/mustahik/mutations.py | 27 ++++++++++++++++++++++++--- sizakat/schema.py | 11 ++++++----- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/sizakat/mustahik/mutations.py b/sizakat/mustahik/mutations.py index 439afef..1b0b6ab 100644 --- a/sizakat/mustahik/mutations.py +++ b/sizakat/mustahik/mutations.py @@ -2,9 +2,15 @@ import graphene from graphene_django.forms.mutation import DjangoModelFormMutation -from .forms import MustahikForm, DataSourceForm, DataSourceWargaForm, DataSourceInstitusiForm, DataSourcePekerjaForm -from .models import Mustahik -from .types import MustahikType, DataSourceInstitusiType, DataSourcePekerjaType, DataSourceWargaType, DataSourceType +from .forms import ( + MustahikForm, DataSourceForm, DataSourceWargaForm, + DataSourceInstitusiForm, DataSourcePekerjaForm +) +from .models import Mustahik, DataSource +from .types import ( + MustahikType, DataSourceInstitusiType, + DataSourcePekerjaType, DataSourceWargaType, DataSourceType +) class MustahikMutation(DjangoModelFormMutation): @@ -31,24 +37,39 @@ class DeleteMustahik(graphene.Mutation): deleted = True return DeleteMustahik(deleted=deleted, id_mustahik=id, name=name, no_ktp=no_ktp) + class DataSourceMutation(DjangoModelFormMutation): dataSource = graphene.Field(DataSourceType) class Meta: form_class = DataSourceForm + +class DeleteDataSource(graphene.Mutation): + class Arguments: + id = graphene.ID() + + deleted = graphene.Boolean() + + def mutate(self, info, id): + DataSource.objects.get(pk=id).delete() + return DeleteDataSource(deleted=True) + + class DataSourceWargaMutation(DjangoModelFormMutation): dataSourceWarga = graphene.Field(DataSourceWargaType) class Meta: form_class = DataSourceWargaForm + class DataSourceInstitusiMutation(DjangoModelFormMutation): dataSourceInstitusi = graphene.Field(DataSourceInstitusiType) class Meta: form_class = DataSourceInstitusiForm + class DataSourcePekerjaMutation(DjangoModelFormMutation): dataSourcePekerja = graphene.Field(DataSourcePekerjaType) diff --git a/sizakat/schema.py b/sizakat/schema.py index bd0198b..9c8325d 100644 --- a/sizakat/schema.py +++ b/sizakat/schema.py @@ -5,7 +5,7 @@ from graphene_django import DjangoObjectType from .mustahik.mutations import ( MustahikMutation, DeleteMustahik, DataSourceMutation, DataSourceWargaMutation, DataSourceInstitusiMutation, - DataSourcePekerjaMutation + DataSourcePekerjaMutation, DeleteDataSource ) from .mustahik.query import MustahikQuery @@ -24,10 +24,11 @@ class Query(MustahikQuery, graphene.ObjectType): class Mutation(graphene.ObjectType): mustahik_mutation = MustahikMutation.Field() delete_mustahik = DeleteMustahik.Field() - dataSource_mutation = DataSourceMutation.Field() - dataSourceWarga_mutation = DataSourceWargaMutation.Field() - dataSourceInstitusi_mutation = DataSourceInstitusiMutation.Field() - dataSourcePekerja_mutation = DataSourcePekerjaMutation.Field() + data_source_mutation = DataSourceMutation.Field() + data_source_warga_mutation = DataSourceWargaMutation.Field() + data_source_institusi_mutation = DataSourceInstitusiMutation.Field() + data_source_pekerja_mutation = DataSourcePekerjaMutation.Field() + delete_data_source = DeleteDataSource.Field() schema = graphene.Schema(query=Query, mutation=Mutation) -- GitLab From 6d9d07531ff7f6901daff4db2cef0e80abaeafcd Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Sat, 1 Aug 2020 20:54:21 +0700 Subject: [PATCH 38/41] [REFACTOR] revisi fungsi delete mutation --- sizakat/mustahik/mutations.py | 15 ++++----------- sizakat/mustahik/tests.py | 7 ++----- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/sizakat/mustahik/mutations.py b/sizakat/mustahik/mutations.py index 1b0b6ab..f3a993c 100644 --- a/sizakat/mustahik/mutations.py +++ b/sizakat/mustahik/mutations.py @@ -22,20 +22,13 @@ class MustahikMutation(DjangoModelFormMutation): class DeleteMustahik(graphene.Mutation): class Arguments: - id = graphene.ID() + id = graphene.ID(required=True) deleted = graphene.Boolean() - id_mustahik = graphene.ID() - name = graphene.String() - no_ktp = graphene.String() def mutate(self, info, id): - mustahik = Mustahik.objects.get(pk=id) - name = mustahik.name - no_ktp = mustahik.no_ktp - mustahik.delete() - deleted = True - return DeleteMustahik(deleted=deleted, id_mustahik=id, name=name, no_ktp=no_ktp) + Mustahik.objects.get(pk=id).delete() + return DeleteMustahik(deleted=True) class DataSourceMutation(DjangoModelFormMutation): @@ -47,7 +40,7 @@ class DataSourceMutation(DjangoModelFormMutation): class DeleteDataSource(graphene.Mutation): class Arguments: - id = graphene.ID() + id = graphene.ID(required=True) deleted = graphene.Boolean() diff --git a/sizakat/mustahik/tests.py b/sizakat/mustahik/tests.py index e5d262d..bf74be9 100644 --- a/sizakat/mustahik/tests.py +++ b/sizakat/mustahik/tests.py @@ -278,12 +278,9 @@ class MustahikGraphQLTestCase(GraphQLTestCase): mustahik_id = mustahik.pk response = self.query( ''' - mutation deleteMustahik($id: ID) { + mutation deleteMustahik($id: ID!) { deleteMustahik(id: $id) { deleted - idMustahik - name - noKtp } } ''', @@ -826,7 +823,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase): datasource = DataSource.objects.all()[0] response = self.query( ''' - mutation deleteDataSource($id: ID) { + mutation deleteDataSource($id: ID!) { deleteDataSource(id: $id) { deleted } -- GitLab From 6123747aa5e11ab7807dee145edb75d9bbe754d7 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Sun, 2 Aug 2020 22:50:01 +0700 Subject: [PATCH 39/41] [GREEN] implementasi upload photo --- sizakat/mustahik/forms.py | 9 +++++++-- sizakat/mustahik/mutations.py | 19 +++++++++++++++++++ sizakat/validators.py | 6 ++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/sizakat/mustahik/forms.py b/sizakat/mustahik/forms.py index 11351c7..9af65d6 100644 --- a/sizakat/mustahik/forms.py +++ b/sizakat/mustahik/forms.py @@ -1,6 +1,6 @@ from django import forms -from .models import Mustahik, DataSource, DataSourceWarga, DataSourceInstitusi, DataSourcePekerja +from .models import Mustahik, DataSource, DataSourceWarga, DataSourceInstitusi, DataSourcePekerja class MustahikForm(forms.ModelForm): @@ -15,8 +15,10 @@ class MustahikForm(forms.ModelForm): 'status', 'gender', 'data_source', + 'photo', ] + class DataSourceForm(forms.ModelForm): class Meta: model = DataSource @@ -24,6 +26,7 @@ class DataSourceForm(forms.ModelForm): 'category', ] + class DataSourceWargaForm(forms.ModelForm): class Meta: model = DataSourceWarga @@ -41,6 +44,7 @@ class DataSourceWargaForm(forms.ModelForm): 'data_source', ] + class DataSourceInstitusiForm(forms.ModelForm): class Meta: model = DataSourceInstitusi @@ -59,6 +63,7 @@ class DataSourceInstitusiForm(forms.ModelForm): 'data_source', ] + class DataSourcePekerjaForm(forms.ModelForm): class Meta: model = DataSourcePekerja @@ -70,4 +75,4 @@ class DataSourcePekerjaForm(forms.ModelForm): 'profession', 'location', 'data_source', - ] \ No newline at end of file + ] diff --git a/sizakat/mustahik/mutations.py b/sizakat/mustahik/mutations.py index f3a993c..46375b9 100644 --- a/sizakat/mustahik/mutations.py +++ b/sizakat/mustahik/mutations.py @@ -1,6 +1,8 @@ import graphene from graphene_django.forms.mutation import DjangoModelFormMutation +from graphene_django.types import ErrorType +from sizakat.validators import validate_photo from .forms import ( MustahikForm, DataSourceForm, DataSourceWargaForm, @@ -19,6 +21,23 @@ class MustahikMutation(DjangoModelFormMutation): class Meta: form_class = MustahikForm + @classmethod + def mutate_and_get_payload(cls, root, info, **input): + form = cls.get_form(root, info, **input) + photo = info.context.FILES['photo'] + if not validate_photo(photo): + form.add_error('photo', 'invalid photo format') + + if form.is_valid(): + mustahik = form.save(commit=False) + mustahik.photo = photo + mustahik.save() + kwargs = {cls._meta.return_field_name: mustahik} + return cls(errors=[], **kwargs) + else: + errors = ErrorType.from_errors(form.errors) + return cls(errors=errors) + class DeleteMustahik(graphene.Mutation): class Arguments: diff --git a/sizakat/validators.py b/sizakat/validators.py index 7b55e88..0d042ed 100644 --- a/sizakat/validators.py +++ b/sizakat/validators.py @@ -3,3 +3,9 @@ from django.core.validators import RegexValidator validate_numeric_character = RegexValidator( r'^[0-9]*$', 'Numeric character only.' ) + + +def validate_photo(photo): + valid_extensions = ['jpg', 'png'] + photo_extension = photo.name.split('.')[-1] + return photo_extension in valid_extensions -- GitLab From 92fe44bacf0767502558d58291732314540198a8 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Mon, 3 Aug 2020 08:34:53 +0700 Subject: [PATCH 40/41] [REFACTOR] mengubah mutasi upload photo --- sizakat/mustahik/mutations.py | 7 ++++--- sizakat/mustahik/tests.py | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/sizakat/mustahik/mutations.py b/sizakat/mustahik/mutations.py index 46375b9..166bb3a 100644 --- a/sizakat/mustahik/mutations.py +++ b/sizakat/mustahik/mutations.py @@ -24,13 +24,14 @@ class MustahikMutation(DjangoModelFormMutation): @classmethod def mutate_and_get_payload(cls, root, info, **input): form = cls.get_form(root, info, **input) - photo = info.context.FILES['photo'] - if not validate_photo(photo): + photo = info.context.FILES.get('photo', None) + if photo and not validate_photo(photo): form.add_error('photo', 'invalid photo format') if form.is_valid(): mustahik = form.save(commit=False) - mustahik.photo = photo + if photo: + mustahik.photo = photo mustahik.save() kwargs = {cls._meta.return_field_name: mustahik} return cls(errors=[], **kwargs) diff --git a/sizakat/mustahik/tests.py b/sizakat/mustahik/tests.py index bf74be9..efb4698 100644 --- a/sizakat/mustahik/tests.py +++ b/sizakat/mustahik/tests.py @@ -157,6 +157,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase): "birthdate": "1998-03-12", "status": "MISKIN", "gender": "L", + "photo": "", "dataSource": data_source.pk } ) @@ -205,6 +206,7 @@ class MustahikGraphQLTestCase(GraphQLTestCase): "birthdate": "1987-06-05", "status": "MUSAFIR", "gender": "L", + "photo": "", "id": mustahik.pk, "dataSource": data_source.pk } -- GitLab From a7529d0a8cdaa433fe1fcfcfe8f85c6f2409d4a4 Mon Sep 17 00:00:00 2001 From: addffa <adli.daffa5@gmail.com> Date: Mon, 3 Aug 2020 08:35:32 +0700 Subject: [PATCH 41/41] [CHORES] menambahkan konfigurasi media file --- sizakat/settings.py | 4 +++- sizakat/urls.py | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/sizakat/settings.py b/sizakat/settings.py index 9f583db..0e562c2 100644 --- a/sizakat/settings.py +++ b/sizakat/settings.py @@ -139,4 +139,6 @@ USE_TZ = True # https://docs.djangoproject.com/en/3.0/howto/static-files/ STATIC_URL = '/static/' -STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles") +STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') +MEDIA_URL = '/img/' +MEDIA_ROOT = os.path.join(BASE_DIR, 'images') diff --git a/sizakat/urls.py b/sizakat/urls.py index b1ae6ca..7b47e4e 100644 --- a/sizakat/urls.py +++ b/sizakat/urls.py @@ -13,6 +13,8 @@ Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ +from django.conf import settings +from django.conf.urls.static import static from django.contrib import admin from django.urls import path from django.views.decorators.csrf import csrf_exempt @@ -22,3 +24,8 @@ urlpatterns = [ path('admin/', admin.site.urls), path('graphql/', csrf_exempt(GraphQLView.as_view(graphiql=True))), ] + +if settings.DEBUG: + urlpatterns += static( + settings.MEDIA_URL, document_root=settings.MEDIA_ROOT + ) -- GitLab