Skip to content

Commit

Permalink
Merge pull request #1083 from akvo/feature/1082-datapoint-download-li…
Browse files Browse the repository at this point in the history
…st-for-mobile

[#1082] Datapoint Download endpoint tests
  • Loading branch information
dedenbangkit authored Jan 25, 2024
2 parents 54cda70 + 4b29c31 commit 3d2253e
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 2 deletions.
14 changes: 14 additions & 0 deletions backend/api/v1/v1_mobile/serializers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Any, Dict
from rtmis.settings import WEBDOMAIN
from rest_framework import serializers
from drf_spectacular.utils import extend_schema_field
from api.v1.v1_forms.models import Forms
Expand All @@ -10,6 +11,19 @@
from utils.custom_helper import CustomPasscode, generate_random_string


class MobileDataPointDownloadListSerializer(serializers.Serializer):
id = serializers.IntegerField()
name = serializers.CharField()
url = serializers.SerializerMethodField()

@extend_schema_field(OpenApiTypes.URI)
def get_url(self, obj):
return f"{WEBDOMAIN}/datapoints/{obj.get('uuid')}.json"

class Meta:
fields = ["id", "name", "url"]


class MobileAssignmentAdministrationSerializer(serializers.ModelSerializer):
id = serializers.IntegerField()
name = serializers.SerializerMethodField()
Expand Down
84 changes: 84 additions & 0 deletions backend/api/v1/v1_mobile/tests/tests_mobile_datapoint_sync.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from rtmis.settings import WEBDOMAIN
from django.test import TestCase
from api.v1.v1_mobile.models import MobileAssignment
from api.v1.v1_profile.models import Administration, Access
from api.v1.v1_profile.constants import UserRoleTypes
from api.v1.v1_forms.models import Forms
from api.v1.v1_forms.constants import FormTypes
from api.v1.v1_data.models import FormData
from api.v1.v1_users.models import SystemUser
from django.core.management import call_command
from rest_framework import status


class MobileDataPointDownloadListTestCase(TestCase):
def setUp(self):
call_command('administration_seeder', '--test')
call_command('form_seeder', '--test')

self.user = SystemUser.objects.create_user(
email='[email protected]',
password='test1234',
first_name='test',
last_name='testing',
)
self.administration = Administration.objects.filter(
parent__isnull=True
).first()
role = UserRoleTypes.user
self.user_access = Access.objects.create(
user=self.user, role=role, administration=self.administration
)
self.forms = Forms.objects.filter(
type=FormTypes.county
).all()
self.uuid = '1234'
self.form_data = FormData.objects.create(
name="TEST",
geo=None,
form=self.forms[0],
administration=self.administration,
created_by=self.user,
uuid=self.uuid,
)
self.passcode = 'passcode1234'
self.mobile_assignment = MobileAssignment.objects.create_assignment(
user=self.user, name='test', passcode=self.passcode
)
self.administration_children = Administration.objects.filter(
parent=self.administration
).all()
self.mobile_assignment.administrations.add(
*self.administration_children
)
self.mobile_assignment = MobileAssignment.objects.get(user=self.user)
self.mobile_assignment.forms.add(*self.forms)

def test_get_datapoints_list_url(self):
code = {'code': self.passcode}
response = self.client.post(
'/api/v1/device/auth',
code,
content_type='application/json',
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
token = response.data['syncToken']
url = (
"/api/v1/device/datapoint-list/?administration={}&form={}"
).format(self.administration.id, self.forms[0].id)
response = self.client.get(
url,
follow=True,
content_type='application/json',
**{'HTTP_AUTHORIZATION': f'Bearer {token}'},
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
data = response.json()
self.assertEqual(data["total"], 1)
self.assertEqual(data["data"][0]["id"], self.form_data.id)
self.assertEqual(data["data"][0]["name"], self.form_data.name)
# test if url is correct
self.assertEqual(
data["data"][0]["url"],
f"{WEBDOMAIN}/datapoints/{self.uuid}.json"
)
5 changes: 5 additions & 0 deletions backend/api/v1/v1_mobile/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
download_sqlite_file,
upload_apk_file,
download_apk_file,
get_datapoint_download_list,
MobileAssignmentViewSet,
)

Expand All @@ -32,4 +33,8 @@
re_path(r'^(?P<version>(v1))/device/images', upload_image_form_device),
re_path(r'^(?P<version>(v1))/device/apk/upload', upload_apk_file),
re_path(r'^(?P<version>(v1))/device/apk/download', download_apk_file),
re_path(
r'^(?P<version>(v1))/device/datapoint-list',
get_datapoint_download_list,
)
]
55 changes: 53 additions & 2 deletions backend/api/v1/v1_mobile/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
APK_UPLOAD_SECRET,
WEBDOMAIN
)
from drf_spectacular.utils import extend_schema
from django.http import HttpResponse
from rest_framework import status, serializers
from rest_framework.response import Response
Expand All @@ -26,17 +25,22 @@
from rest_framework.generics import get_object_or_404
from rest_framework.permissions import IsAuthenticated
from rest_framework.parsers import MultiPartParser
from drf_spectacular.utils import inline_serializer

from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import (
OpenApiParameter, extend_schema, inline_serializer)

from utils.custom_pagination import Pagination
from .serializers import (
MobileAssignmentFormsSerializer,
MobileApkSerializer,
MobileAssignmentSerializer,
MobileDataPointDownloadListSerializer
)
from .models import MobileAssignment, MobileApk
from api.v1.v1_forms.models import Forms, Questions, QuestionTypes
from api.v1.v1_profile.models import Access
from api.v1.v1_data.models import FormData
from api.v1.v1_forms.serializers import WebFormDetailSerializer
from api.v1.v1_data.serializers import SubmitPendingFormSerializer
from api.v1.v1_files.serializers import UploadImagesSerializer
Expand Down Expand Up @@ -345,3 +349,50 @@ def get_queryset(self):
.prefetch_related('administrations', 'forms')\
.filter(user=user)\
.order_by('id')


@extend_schema(
responses={
(200, 'application/json'): inline_serializer(
'MobileDeviceDownloadDatapointListResponse',
fields={
"total": serializers.IntegerField(),
"data": MobileDataPointDownloadListSerializer(many=True),
"page": serializers.IntegerField(),
"current": serializers.IntegerField(),
}
)
},
parameters=[
OpenApiParameter(
name='form',
required=True,
type=OpenApiTypes.NUMBER,
location=OpenApiParameter.QUERY),
OpenApiParameter(
name='page',
required=True,
type=OpenApiTypes.NUMBER,
location=OpenApiParameter.QUERY),
OpenApiParameter(
name='administration',
required=False,
type=OpenApiTypes.NUMBER,
location=OpenApiParameter.QUERY),
],
tags=['Mobile Device Form'],
summary='GET Download List for Syncing Datapoints',
)
@api_view(['GET'])
@permission_classes([IsMobileAssignment])
def get_datapoint_download_list(request, version):
paginator = Pagination()
# select only uuid and datapoint id
queryset = FormData.objects.filter(
administration_id=request.query_params.get('administration'),
form_id=request.query_params.get('form')
).values('uuid', 'id', 'name').order_by('id')
instance = paginator.paginate_queryset(queryset, request)
return paginator.get_paginated_response(
MobileDataPointDownloadListSerializer(instance, many=True).data
)

0 comments on commit 3d2253e

Please sign in to comment.