1
0
Fork 0
mirror of https://gitlab.com/bramw/baserow.git synced 2025-04-19 19:43:16 +00:00
bramw_baserow/backend/tests/baserow/api/test_api_utils.py
2020-11-30 18:52:39 +00:00

224 lines
7.9 KiB
Python

import pytest
from rest_framework import status, serializers
from rest_framework.exceptions import APIException
from rest_framework.serializers import CharField
from rest_framework.status import HTTP_404_NOT_FOUND
from baserow.core.models import Group
from baserow.core.registry import (
Instance, Registry, CustomFieldsInstanceMixin, ModelInstanceMixin
)
from baserow.api.utils import (
map_exceptions, validate_data, validate_data_custom_fields, get_serializer_class
)
class TemporaryException(Exception):
pass
class TemporaryException2(Exception):
pass
class TemporarySerializer(serializers.Serializer):
field_1 = serializers.CharField()
field_2 = serializers.ChoiceField(choices=('choice_1', 'choice_2'))
class TemporaryListSerializer(serializers.ListSerializer):
def __init__(self, *args, **kwargs):
kwargs['child'] = TemporarySerializer()
super().__init__(*args, **kwargs)
class TemporarySerializerWithList(serializers.Serializer):
field_3 = serializers.IntegerField()
field_4 = serializers.ListField(child=serializers.IntegerField())
class TemporaryInstance(CustomFieldsInstanceMixin, ModelInstanceMixin, Instance):
pass
class TemporaryInstanceType1(TemporaryInstance):
type = 'temporary_1'
model_class = Group
class TemporaryInstanceType2(TemporaryInstance):
type = 'temporary_2'
model_class = Group
serializer_field_names = ['name']
serializer_field_overrides = {
'name': serializers.IntegerField()
}
class TemporaryTypeRegistry(Registry):
name = 'temporary'
def test_map_exceptions():
with pytest.raises(APIException) as api_exception_1:
with map_exceptions({TemporaryException: 'ERROR_TEMPORARY'}):
raise TemporaryException
assert api_exception_1.value.detail['error'] == 'ERROR_TEMPORARY'
assert api_exception_1.value.detail['detail'] == ''
assert api_exception_1.value.status_code == status.HTTP_400_BAD_REQUEST
with pytest.raises(APIException) as api_exception_2:
with map_exceptions({
TemporaryException: (
'ERROR_TEMPORARY_2',
HTTP_404_NOT_FOUND,
'Another message {e.message}'
)
}):
e = TemporaryException()
e.message = 'test'
raise e
assert api_exception_2.value.detail['error'] == 'ERROR_TEMPORARY_2'
assert api_exception_2.value.detail['detail'] == 'Another message test'
assert api_exception_2.value.status_code == status.HTTP_404_NOT_FOUND
with pytest.raises(TemporaryException2):
with map_exceptions({
TemporaryException: 'ERROR_TEMPORARY_3'
}):
raise TemporaryException2
with map_exceptions({
TemporaryException: 'ERROR_TEMPORARY_4'
}):
pass
def test_validate_data():
with pytest.raises(APIException) as api_exception_1:
validate_data(TemporarySerializer, {'field_1': 'test'})
assert api_exception_1.value.detail['error'] == 'ERROR_REQUEST_BODY_VALIDATION'
assert api_exception_1.value.detail['detail']['field_2'][0]['error'] == (
'This field is required.'
)
assert api_exception_1.value.detail['detail']['field_2'][0]['code'] == 'required'
assert api_exception_1.value.status_code == status.HTTP_400_BAD_REQUEST
with pytest.raises(APIException) as api_exception_2:
validate_data(
TemporarySerializer,
{'field_1': 'test', 'field_2': 'wrong'}
)
assert api_exception_2.value.detail['error'] == 'ERROR_REQUEST_BODY_VALIDATION'
assert api_exception_2.value.detail['detail']['field_2'][0]['error'] == (
'"wrong" is not a valid choice.'
)
assert api_exception_2.value.detail['detail']['field_2'][0]['code'] == (
'invalid_choice'
)
assert api_exception_2.value.status_code == status.HTTP_400_BAD_REQUEST
validated_data = validate_data(
TemporarySerializer,
{'field_1': 'test', 'field_2': 'choice_1'}
)
assert validated_data['field_1'] == 'test'
assert validated_data['field_2'] == 'choice_1'
assert len(validated_data.items()) == 2
with pytest.raises(APIException) as api_exception_1:
validate_data(
TemporarySerializerWithList,
{'field_3': 'aaa', 'field_4': ['a', 'b']}
)
assert api_exception_1.value.status_code == status.HTTP_400_BAD_REQUEST
assert api_exception_1.value.detail['error'] == 'ERROR_REQUEST_BODY_VALIDATION'
assert api_exception_1.value.detail['detail']['field_3'][0]['error'] == (
'A valid integer is required.'
)
assert api_exception_1.value.detail['detail']['field_3'][0]['code'] == 'invalid'
assert len(api_exception_1.value.detail['detail']['field_4']) == 2
assert api_exception_1.value.detail['detail']['field_4'][0][0]['error'] == (
'A valid integer is required.'
)
assert api_exception_1.value.detail['detail']['field_4'][0][0]['code'] == (
'invalid'
)
assert api_exception_1.value.detail['detail']['field_4'][1][0]['error'] == (
'A valid integer is required.'
)
assert api_exception_1.value.detail['detail']['field_4'][1][0]['code'] == (
'invalid'
)
with pytest.raises(APIException) as api_exception_3:
validate_data(
TemporaryListSerializer,
[{'something': 'nothing'}]
)
assert api_exception_3.value.status_code == status.HTTP_400_BAD_REQUEST
assert api_exception_3.value.detail['error'] == 'ERROR_REQUEST_BODY_VALIDATION'
assert len(api_exception_3.value.detail['detail']) == 1
assert api_exception_3.value.detail['detail'][0]['field_1'][0]['code'] == 'required'
assert api_exception_3.value.detail['detail'][0]['field_2'][0]['code'] == 'required'
def test_validate_data_custom_fields():
registry = TemporaryTypeRegistry()
registry.register(TemporaryInstanceType1())
registry.register(TemporaryInstanceType2())
with pytest.raises(APIException) as api_exception:
validate_data_custom_fields('NOT_EXISTING', registry, {})
assert api_exception.value.detail['error'] == 'ERROR_REQUEST_BODY_VALIDATION'
assert api_exception.value.detail['detail']['type'][0]['error'] == (
'"NOT_EXISTING" is not a valid choice.'
)
assert api_exception.value.detail['detail']['type'][0]['code'] == 'invalid_choice'
assert api_exception.value.status_code == status.HTTP_400_BAD_REQUEST
with pytest.raises(APIException) as api_exception_2:
validate_data_custom_fields('temporary_2', registry, {})
assert api_exception_2.value.detail['error'] == 'ERROR_REQUEST_BODY_VALIDATION'
assert api_exception_2.value.detail['detail']['name'][0]['error'] == (
'This field is required.'
)
assert api_exception_2.value.detail['detail']['name'][0]['code'] == 'required'
assert api_exception_2.value.status_code == status.HTTP_400_BAD_REQUEST
with pytest.raises(APIException) as api_exception_3:
validate_data_custom_fields('temporary_2', registry, {'name': 'test1'})
assert api_exception_3.value.detail['error'] == 'ERROR_REQUEST_BODY_VALIDATION'
assert api_exception_3.value.detail['detail']['name'][0]['error'] == (
'A valid integer is required.'
)
assert api_exception_3.value.detail['detail']['name'][0]['code'] == 'invalid'
assert api_exception_3.value.status_code == status.HTTP_400_BAD_REQUEST
data = validate_data_custom_fields('temporary_2', registry, {'name': 123})
assert data['name'] == 123
@pytest.mark.django_db
def test_get_serializer_class(data_fixture):
group = data_fixture.create_group(name='Group 1')
group_serializer = get_serializer_class(Group, ['name'])(group)
assert group_serializer.data == {'name': 'Group 1'}
assert group_serializer.__class__.__name__ == 'GroupSerializer'
group_serializer_2 = get_serializer_class(Group, ['id', 'name'], {
'id': CharField()
})(group)
assert group_serializer_2.data == {'id': str(group.id), 'name': 'Group 1'}