Beispiel #1
0
class Login(generics.CreateAPIView):
    """
  An endpoint to login a user.
  """
    permission_classes = []
    authentication_classes = [
        CsrfExemptSessionAuthentication, BasicAuthentication
    ]
    serializer_class = LoginSerializer
    queryset = User.objects.all()
    schema = AutoSchema(operation_id_base='LoginUser', tags=['Auth'])

    def post(self, request, *args, **kwargs):
        email = request.data.get('email')
        password = request.data.get('password')
        user = authenticate(email=email, password=password)

        if user is not None:
            try:
                login(request, user)
                user_type = user.get_user_type()
                data = {
                    'status': 200,
                    'message': 'User authenticated',
                    'data': {
                        'id': user.id,
                        'user_type': user_type,
                    },
                }
                return Response(data=data, status=200)
            except Exception as e:
                return Response(data=AUTH_FAILED_RESPONSE, status=401)

        return Response(data=AUTH_FAILED_RESPONSE, status=401)
    def test_path_with_id_parameter(self):
        path = '/example/{id}/'
        method = 'GET'

        view = create_view(views.DocStringExampleDetailView, method,
                           create_request(path))
        inspector = AutoSchema()
        inspector.view = view

        operation = inspector.get_operation(path, method)
        assert operation == {
            'operationId':
            'RetrieveDocStringExampleDetail',
            'description':
            'A description of my GET operation.',
            'parameters': [{
                'description': '',
                'in': 'path',
                'name': 'id',
                'required': True,
                'schema': {
                    'type': 'string',
                },
            }],
            'responses': {
                '200': {
                    'description': '',
                    'content': {
                        'application/json': {
                            'schema': {},
                        },
                    },
                },
            },
        }
    def get_field_info(self, field):
        field_info = super().get_field_info(field)

        # Add extra validators using the OpenAPI schema generator
        validators = {}
        AutoSchema()._map_field_validators(field, validators)
        extra_validators = ['format', 'pattern']
        for validator in extra_validators:
            if validators.get(validator, None):
                field_info[validator] = validators[validator]

        # Add additional data from serializer
        field_info['initial'] = field.initial
        field_info['field_name'] = field.field_name
        field_info['write_only'] = field.write_only

        return field_info

    # >> > import json
    # >> > from your_app.serializers import UserSerializer
    # >> > metadata_generator = APIMetadata()
    # >> > metadata = metadata_generator.get_serializer_info(UserSerializer())
    # >> > with open('User.json', 'w') as json_file:
    #     ...
    #     json.dump(metadata, json_file, indent=2, sort_keys=True)
    def test_renderer_mapping(self):
        """Test that view's renderers are mapped to OA media types"""
        path = '/{id}/'
        method = 'GET'

        class CustomBrowsableAPIRenderer(BrowsableAPIRenderer):
            media_type = 'image/jpeg'  # that's a wild API renderer

        class TextRenderer(BaseRenderer):
            media_type = 'text/plain'
            format = 'text'

        class View(generics.CreateAPIView):
            serializer_class = views.ExampleSerializer
            renderer_classes = [
                JSONRenderer, TextRenderer, BrowsableAPIRenderer,
                CustomBrowsableAPIRenderer
            ]

        view = create_view(
            View,
            method,
            create_request(path),
        )
        inspector = AutoSchema()
        inspector.view = view

        responses = inspector.get_responses(path, method)
        # TODO this should be changed once the multiple response
        # schema support is there
        success_response = responses['200']

        # Check that the API renderers aren't included, but custom renderers are
        assert set(
            success_response['content']) == {'application/json', 'text/plain'}
    def test_empty_required_with_patch_method(self):
        path = '/'
        method = 'PATCH'

        class ItemSerializer(serializers.Serializer):
            read_only = serializers.CharField(read_only=True)
            write_only = serializers.CharField(write_only=True, required=False)

        class View(generics.GenericAPIView):
            serializer_class = ItemSerializer

        view = create_view(
            View,
            method,
            create_request(path)
        )
        inspector = AutoSchema()
        inspector.view = view

        components = inspector.get_components(path, method)
        component = components['Item']
        # there should be no empty 'required' property, see #6834
        assert 'required' not in component
        for response in inspector.get_responses(path, method).values():
            assert 'required' not in component
    def test_response_body_nested_serializer(self):
        path = '/'
        method = 'POST'

        class NestedSerializer(serializers.Serializer):
            number = serializers.IntegerField()

        class Serializer(serializers.Serializer):
            text = serializers.CharField()
            nested = NestedSerializer()

        class View(generics.GenericAPIView):
            serializer_class = Serializer

        view = create_view(
            View,
            method,
            create_request(path),
        )
        inspector = AutoSchema()
        inspector.view = view

        responses = inspector._get_responses(path, method)
        schema = responses['200']['content']['application/json']['schema']
        assert sorted(schema['required']) == ['nested', 'text']
        assert sorted(list(schema['properties'].keys())) == ['nested', 'text']
        assert schema['properties']['nested']['type'] == 'object'
        assert list(
            schema['properties']['nested']['properties'].keys()) == ['number']
        assert schema['properties']['nested']['required'] == ['number']
    def test_path_without_parameters(self):
        path = '/example/'
        method = 'GET'

        view = create_view(views.DocStringExampleListView, method,
                           create_request(path))
        inspector = AutoSchema()
        inspector.view = view

        operation = inspector.get_operation(path, method)
        assert operation == {
            'operationId': 'listDocStringExamples',
            'description': 'A description of my GET operation.',
            'parameters': [],
            'responses': {
                '200': {
                    'description': '',
                    'content': {
                        'application/json': {
                            'schema': {
                                'type': 'array',
                                'items': {},
                            },
                        },
                    },
                },
            },
        }
 def test_list_field_mapping(self):
     inspector = AutoSchema()
     cases = [
         (serializers.ListField(), {
             'items': {},
             'type': 'array'
         }),
         (serializers.ListField(child=serializers.BooleanField()), {
             'items': {
                 'type': 'boolean'
             },
             'type': 'array'
         }),
         (serializers.ListField(child=serializers.FloatField()), {
             'items': {
                 'type': 'number'
             },
             'type': 'array'
         }),
         (serializers.ListField(child=serializers.CharField()), {
             'items': {
                 'type': 'string'
             },
             'type': 'array'
         }),
     ]
     for field, mapping in cases:
         with self.subTest(field=field):
             assert inspector._map_field(field) == mapping
    def test_response_body_generation(self):
        path = '/'
        method = 'POST'

        class ItemSerializer(serializers.Serializer):
            text = serializers.CharField()
            write_only = serializers.CharField(write_only=True)

        class View(generics.GenericAPIView):
            serializer_class = ItemSerializer

        view = create_view(View, method, create_request(path))
        inspector = AutoSchema()
        inspector.view = view

        responses = inspector.get_responses(path, method)
        assert responses['201']['content']['application/json']['schema'][
            '$ref'] == '#/components/schemas/Item'

        components = inspector.get_components(path, method)
        assert sorted(components['Item']['required']) == ['text', 'write_only']
        assert sorted(list(components['Item']['properties'].keys())) == [
            'text', 'write_only'
        ]
        assert 'description' in responses['201']
Beispiel #10
0
class Tugasharian_list(generics.ListCreateAPIView):
    queryset = Ms_tugas_harian.objects.all()
    serializer_class = TugasHarianSerializer
    schema = AutoSchema(
        tags=['API Tugas Harian'],
        component_name='tgs_harian',
        operation_id_base='tgs_harian',
    )
Beispiel #11
0
class TaskSummary(generics.RetrieveAPIView):
    schema = AutoSchema(
        component_name="TaskSummary",
        operation_id_base="TaskSummary",
    )
    queryset = models.Task.objects.all()
    serializer_class = serializers.TaskSummarySerializer
    permission_classes = (HasTaskAccess, )
Beispiel #12
0
class Absensi_Detail(generics.RetrieveUpdateAPIView):
    queryset = Absensi.objects.all()
    serializer_class = AbsensiSerializer
    schema = AutoSchema(
        tags=['API Daftar Absensi Pegawai Detail'],
        component_name='absensi_dtl',
        operation_id_base='absensi_dtl',
    )
Beispiel #13
0
class Tugasharian_Detail(generics.RetrieveUpdateAPIView):
    queryset = Ms_tugas_harian.objects.all()
    serializer_class = TugasHarianSerializer
    schema = AutoSchema(
        tags=['API Tugas Harian Detail'],
        component_name='tgs_harian_dtl',
        operation_id_base='tgs_harian_dtl',
    )
    def test_lazy_string_field(self):
        class Serializer(serializers.Serializer):
            text = serializers.CharField(help_text=_('lazy string'))

        inspector = AutoSchema()

        data = inspector._map_serializer(Serializer())
        assert isinstance(data['properties']['text']['description'], str), "description must be str"
    def test_paginated_list_response_body_generation(self):
        """Test that pagination properties are added for a paginated list view."""
        path = '/'
        method = 'GET'

        class Pagination(pagination.BasePagination):
            def get_paginated_response_schema(self, schema):
                return {
                    'type': 'object',
                    'item': schema,
                }

        class ItemSerializer(serializers.Serializer):
            text = serializers.CharField()

        class View(generics.GenericAPIView):
            serializer_class = ItemSerializer
            pagination_class = Pagination

        view = create_view(
            View,
            method,
            create_request(path),
        )
        inspector = AutoSchema()
        inspector.view = view

        responses = inspector._get_responses(path, method)
        assert responses == {
            '200': {
                'description': '',
                'content': {
                    'application/json': {
                        'schema': {
                            'type': 'object',
                            'item': {
                                'type': 'array',
                                'items': {
                                    '$ref': '#/components/schemas/Item'
                                },
                            },
                        },
                    },
                },
            },
        }
        components = inspector.get_components(path, method)
        assert components == {
            'Item': {
                'type': 'object',
                'properties': {
                    'text': {
                        'type': 'string',
                    },
                },
                'required': ['text'],
            }
        }
Beispiel #16
0
    def test_serializer_validators(self):
        path = '/'
        method = 'GET'
        view = create_view(
            views.ExampleValidatedAPIView,
            method,
            create_request(path),
        )
        inspector = AutoSchema()
        inspector.view = view

        responses = inspector._get_responses(path, method)
        response_schema = responses['200']['content']['application/json'][
            'schema']
        properties = response_schema['items']['properties']

        assert properties['integer']['type'] == 'integer'
        assert properties['integer']['maximum'] == 99
        assert properties['integer']['minimum'] == -11

        assert properties['string']['minLength'] == 2
        assert properties['string']['maxLength'] == 10

        assert properties['lst']['minItems'] == 2
        assert properties['lst']['maxItems'] == 10

        assert properties['regex']['pattern'] == r'[ABC]12{3}'
        assert properties['regex'][
            'description'] == 'must have an A, B, or C followed by 1222'

        assert properties['decimal1']['type'] == 'number'
        assert properties['decimal1']['multipleOf'] == .01
        assert properties['decimal1']['maximum'] == 10000
        assert properties['decimal1']['minimum'] == -10000

        assert properties['decimal2']['type'] == 'number'
        assert properties['decimal2']['multipleOf'] == .0001

        assert properties['email']['type'] == 'string'
        assert properties['email']['format'] == 'email'
        assert properties['email']['default'] == '*****@*****.**'

        assert properties['url']['type'] == 'string'
        assert properties['url']['nullable'] is True
        assert properties['url']['default'] == 'http://www.example.com'

        assert properties['uuid']['type'] == 'string'
        assert properties['uuid']['format'] == 'uuid'

        assert properties['ip4']['type'] == 'string'
        assert properties['ip4']['format'] == 'ipv4'

        assert properties['ip6']['type'] == 'string'
        assert properties['ip6']['format'] == 'ipv6'

        assert properties['ip']['type'] == 'string'
        assert 'format' not in properties['ip']
Beispiel #17
0
class Absensi_list(generics.ListCreateAPIView):
    queryset = Absensi.objects.all()
    serializer_class = AbsensiSerializer
    name = "Daftar Absensi"
    schema = AutoSchema(
        tags=['API Daftar Absensi Pegawai'],
        component_name='absensi_list',
        operation_id_base='absensi_list',
    )
Beispiel #18
0
class ExampleAutoSchemaDuplicate2(generics.GenericAPIView):
    serializer_class = ExampleSerializerModel
    schema = AutoSchema(component_name="Duplicate")

    def get(self, *args, **kwargs):
        from datetime import datetime
        now = datetime.now()

        serializer = self.get_serializer(data=now.date(), datetime=now)
        return Response(serializer.data)
Beispiel #19
0
class CommentViewSet(CreateModelMixin, GenericViewSet):
    schema = AutoSchema(tags=['comment'])
    throttle_classes = [UserRateThrottle] if not DEBUG else []
    serializer_class = CommentSerializer
    queryset = Comment.objects.all()

    def create(self, request, *args, **kwargs):
        try:
            return super().create(request, *args, **kwargs)
        except RestFrameworkValidationError as e:
            return Response(e.detail, status.HTTP_400_BAD_REQUEST)
    def test_boolean_default_field(self):
        class Serializer(serializers.Serializer):
            default_true = serializers.BooleanField(default=True)
            default_false = serializers.BooleanField(default=False)
            without_default = serializers.BooleanField()

        inspector = AutoSchema()

        data = inspector._map_serializer(Serializer())
        assert data['properties']['default_true']['default'] is True, "default must be true"
        assert data['properties']['default_false']['default'] is False, "default must be false"
        assert 'default' not in data['properties']['without_default'], "default must not be defined"
Beispiel #21
0
    def test_min_and_max_validators(self):
        inspector = AutoSchema()
        positive_cases = [
            ({},
             serializers.DecimalField(
                 validators=[MinValueValidator(limit_value=1)],
                 decimal_places=2,
                 max_digits=5), {
                     'minimum': 1
                 }),
            ({},
             serializers.DecimalField(
                 validators=[MaxValueValidator(limit_value=1)],
                 decimal_places=2,
                 max_digits=5), {
                     'maximum': 1
                 }),
            ({
                'COERCE_DECIMAL_TO_STRING': False
            },
             serializers.DecimalField(
                 validators=[MinValueValidator(limit_value=Decimal('1'))],
                 decimal_places=2,
                 max_digits=5), {
                     'minimum': 1.0
                 }),
            ({
                'COERCE_DECIMAL_TO_STRING': False
            },
             serializers.DecimalField(
                 validators=[MaxValueValidator(limit_value=Decimal('1'))],
                 decimal_places=2,
                 max_digits=5), {
                     'maximum': 1.0
                 }),
            ({},
             serializers.DecimalField(
                 validators=[MinValueValidator(limit_value=Decimal('1'))],
                 decimal_places=2,
                 max_digits=5), {}),
            ({},
             serializers.DecimalField(
                 validators=[MaxValueValidator(limit_value=Decimal('1'))],
                 decimal_places=2,
                 max_digits=5), {}),
        ]

        for overriden_settings, field, mapping in positive_cases:
            with override_settings(REST_FRAMEWORK=overriden_settings):
                with self.subTest(field=field):
                    schema = {}
                    inspector.map_field_validators(field, schema)
                    assert schema == mapping
Beispiel #22
0
class CreateReportFlag(generics.CreateAPIView):
    """Create 'removal suggestion' flags."""

    serializer_class = serializers.FlagSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly, )

    schema = AutoSchema(operation_id_base="ReportFlag")

    def post(self, request, *args, **kwargs):
        return super(CreateReportFlag, self).post(request, *args, **kwargs)

    def perform_create(self, serializer):
        perform_flag(self.request, serializer.validated_data['comment'])
    def test_operation_id_custom_name(self):
        path = '/'
        method = 'GET'

        view = create_view(
            views.ExampleGenericAPIView,
            method,
            create_request(path),
        )
        inspector = AutoSchema(operation_id_base='Ulysse')
        inspector.view = view

        operationId = inspector.get_operation_id(path, method)
        assert operationId == 'listUlysses'
Beispiel #24
0
class UserDetail(generics.RetrieveAPIView):
    """Detalhes do usuário."""

    schema = AutoSchema(tags=["Usuários"])

    authentication_classes = [SessionAuthentication, BasicAuthentication]
    permission_classes = [IsAuthenticated]
    
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def dispatch(self, request, *args, **kwargs):
        logger.info(f"UserDetail {request.method} ({request.user.username})")
        return super().dispatch(request, *args, **kwargs)
Beispiel #25
0
    def test_retrieve_response_body_generation(self):
        """
        Test that a list of properties is returned for retrieve item views.

        Pagination properties should not be added as the view represents a single item.
        """
        path = '/{id}/'
        method = 'GET'

        class Pagination(pagination.BasePagination):
            def get_paginated_response_schema(self, schema):
                return {
                    'type': 'object',
                    'item': schema,
                }

        class ItemSerializer(serializers.Serializer):
            text = serializers.CharField()

        class View(generics.GenericAPIView):
            serializer_class = ItemSerializer
            pagination_class = Pagination

        view = create_view(
            View,
            method,
            create_request(path),
        )
        inspector = AutoSchema()
        inspector.view = view

        responses = inspector._get_responses(path, method)
        assert responses == {
            '200': {
                'description': '',
                'content': {
                    'application/json': {
                        'schema': {
                            'type': 'object',
                            'properties': {
                                'text': {
                                    'type': 'string',
                                },
                            },
                            'required': ['text'],
                        },
                    },
                },
            },
        }
Beispiel #26
0
    def test_operation_id_generation(self):
        path = '/'
        method = 'GET'

        view = create_view(
            views.ExampleGenericAPIView,
            method,
            create_request(path),
        )
        inspector = AutoSchema()
        inspector.view = view

        operationId = inspector._get_operation_id(path, method)
        assert operationId == 'ListExamples'
 def test_list_field_mapping(self):
     inspector = AutoSchema()
     cases = [
         (serializers.ListField(), {
             'items': {},
             'type': 'array'
         }),
         (serializers.ListField(child=serializers.BooleanField()), {
             'items': {
                 'type': 'boolean'
             },
             'type': 'array'
         }),
         (serializers.ListField(child=serializers.FloatField()), {
             'items': {
                 'type': 'number'
             },
             'type': 'array'
         }),
         (serializers.ListField(child=serializers.CharField()), {
             'items': {
                 'type': 'string'
             },
             'type': 'array'
         }),
         (serializers.ListField(child=serializers.IntegerField(
             max_value=4294967295)), {
                 'items': {
                     'type': 'integer',
                     'maximum': 4294967295,
                     'format': 'int64'
                 },
                 'type': 'array'
             }),
         (serializers.ListField(child=serializers.ChoiceField(
             choices=[('a', 'Choice A'), ('b', 'Choice B')])), {
                 'items': {
                     'enum': ['a', 'b']
                 },
                 'type': 'array'
             }),
         (serializers.IntegerField(min_value=2147483648), {
             'type': 'integer',
             'minimum': 2147483648,
             'format': 'int64'
         }),
     ]
     for field, mapping in cases:
         with self.subTest(field=field):
             assert inspector._map_field(field) == mapping
Beispiel #28
0
class MembershipApprovalViewSet(ModelViewSet):

    permission_classes = (IsAuthenticated, )
    schema = AutoSchema(tags=["Membership Applications"])
    serializer_class = MembershipApprovalSerializer

    def get_queryset(self):
        if not self.request.user:
            queryset = MembershipApproval.objects.none()
        else:
            queryset = MembershipApproval.objects.filter(
                applicant=self.request.user.id)

        return queryset
    def test_serializer_hstorefield(self):
        path = '/'
        method = 'GET'
        view = create_view(
            views.ExampleGenericAPIView,
            method,
            create_request(path),
        )
        inspector = AutoSchema()
        inspector.view = view

        responses = inspector._get_responses(path, method)
        response_schema = responses['200']['content']['application/json']['schema']
        properties = response_schema['items']['properties']
        assert properties['hstore']['type'] == 'object'
    def test_serializer_callable_default(self):
        path = '/'
        method = 'GET'
        view = create_view(
            views.ExampleGenericAPIView,
            method,
            create_request(path),
        )
        inspector = AutoSchema()
        inspector.view = view

        responses = inspector._get_responses(path, method)
        response_schema = responses['200']['content']['application/json']['schema']
        properties = response_schema['items']['properties']
        assert 'default' not in properties['uuid_field']