Ejemplo n.º 1
0
def test_rotate_token_key(data_fixture):
    user = data_fixture.create_user()
    token_1 = data_fixture.create_token(user=user)
    token_2 = data_fixture.create_token()

    handler = TokenHandler()

    with pytest.raises(TokenDoesNotBelongToUser):
        handler.rotate_token_key(user=user, token=token_2)

    old_key = token_1.key
    new_token = handler.rotate_token_key(user=user, token=token_1)
    assert len(new_token.key) == 32
    assert old_key != new_token.key
Ejemplo n.º 2
0
def test_update_token(data_fixture):
    user = data_fixture.create_user()
    token_1 = data_fixture.create_token(user=user)
    token_2 = data_fixture.create_token()

    handler = TokenHandler()

    with pytest.raises(TokenDoesNotBelongToUser):
        handler.update_token(user=user, token=token_2, name='New')

    token_1 = handler.update_token(user=user, token=token_1, name='New')
    assert token_1.name == 'New'

    token_1 = Token.objects.get(pk=token_1.id)
    assert token_1.name == 'New'
Ejemplo n.º 3
0
    def patch(self, request, table_id, row_id):
        """
        Updates the row with the given row_id for the table with the given
        table_id. Also the post data is validated according to the tables field types.
        """

        table = TableHandler().get_table(request.user, table_id)
        TokenHandler().check_table_permissions(request, 'update', table, False)

        # Small side effect of generating the model for only the fields that need to
        # change is that the response it not going to contain the other fields. It is
        # however much faster because it doesn't need to get the specific version of
        # all the field objects.
        field_ids = RowHandler().extract_field_ids_from_dict(request.data)
        model = table.get_model(field_ids=field_ids)

        validation_serializer = get_row_serializer_class(model)
        data = validate_data(validation_serializer, request.data)

        row = RowHandler().update_row(request.user, table, row_id, data, model)

        serializer_class = get_row_serializer_class(model,
                                                    RowSerializer,
                                                    is_response=True)
        serializer = serializer_class(row)

        return Response(serializer.data)
Ejemplo n.º 4
0
    def post(self, request, table_id):
        """
        Creates a new row for the given table_id. Also the post data is validated
        according to the tables field types.
        """

        table = TableHandler().get_table(table_id)
        TokenHandler().check_table_permissions(request, 'create', table, False)
        model = table.get_model()

        validation_serializer = get_row_serializer_class(model)
        data = validate_data(validation_serializer, request.data)

        before_id = request.GET.get('before')
        before = (RowHandler().get_row(request.user, table, before_id, model)
                  if before_id else None)

        row = RowHandler().create_row(request.user,
                                      table,
                                      data,
                                      model,
                                      before=before)
        serializer_class = get_row_serializer_class(model,
                                                    RowSerializer,
                                                    is_response=True)
        serializer = serializer_class(row)

        return Response(serializer.data)
Ejemplo n.º 5
0
    def get(self, request, table_id):
        """
        Lists all the rows of the given table id paginated. It is also possible to
        provide a search query.
        """

        table = TableHandler().get_table(request.user, table_id)
        TokenHandler().check_table_permissions(request, 'read', table, False)

        model = table.get_model()
        search = request.GET.get('search')
        order_by = request.GET.get('order_by')

        queryset = model.objects.all().enhance_by_fields().order_by('id')

        if search:
            queryset = queryset.search_all_fields(search)

        if order_by:
            queryset = queryset.order_by_fields_string(order_by)

        paginator = PageNumberPagination(
            limit_page_size=settings.ROW_PAGE_SIZE_LIMIT)
        page = paginator.paginate_queryset(queryset, request, self)
        serializer_class = get_row_serializer_class(model,
                                                    RowSerializer,
                                                    is_response=True)
        serializer = serializer_class(page, many=True)

        return paginator.get_paginated_response(serializer.data)
Ejemplo n.º 6
0
    def post(self, request, data):
        """Creates a new token for the authorized user."""

        data['group'] = CoreHandler().get_group(data.pop('group'))
        token = TokenHandler().create_token(request.user, **data)
        serializer = TokenSerializer(token)
        return Response(serializer.data)
Ejemplo n.º 7
0
def test_get_by_key(data_fixture):
    user = data_fixture.create_user()
    data_fixture.create_user()
    group_1 = data_fixture.create_group(user=user)
    group_2 = data_fixture.create_group()
    token = data_fixture.create_token(user=user, group=group_1)
    data_fixture.create_token(user=user, group=group_2)

    handler = TokenHandler()

    with pytest.raises(TokenDoesNotExist):
        handler.get_by_key(key='abc')

    token_tmp = handler.get_by_key(key=token.key)
    assert token_tmp.id == token.id
    assert token.group_id == group_1.id
    assert isinstance(token_tmp, Token)
Ejemplo n.º 8
0
def test_update_token_usage(data_fixture):
    token_1 = data_fixture.create_token()

    handler = TokenHandler()

    assert token_1.handled_calls == 0
    assert token_1.last_call is None

    with freeze_time('2020-01-01 12:00'):
        token_1 = handler.update_token_usage(token_1)

    assert token_1.handled_calls == 1
    assert token_1.last_call == datetime(2020,
                                         1,
                                         1,
                                         12,
                                         00,
                                         tzinfo=timezone('UTC'))
Ejemplo n.º 9
0
    def patch(self, request, data, token_id):
        """Updates the values of a token."""

        token = TokenHandler().get_token(request.user, token_id)
        permissions = data.pop('permissions', None)
        rotate_key = data.pop('rotate_key', False)

        if len(data) > 0:
            token = TokenHandler().update_token(request.user, token, **data)

        if permissions:
            TokenHandler().update_token_permissions(request.user, token, **permissions)

        if rotate_key:
            token = TokenHandler().rotate_token_key(request.user, token)

        serializer = TokenSerializer(token)
        return Response(serializer.data)
Ejemplo n.º 10
0
    def authenticate(self, request):
        auth = get_authorization_header(request).split()

        if not auth or auth[0].lower() != b"token":
            return None

        if len(auth) == 1:
            msg = _("Invalid token header. No token provided.")
            raise AuthenticationFailed(
                {"detail": msg, "error": "ERROR_INVALID_TOKEN_HEADER"}
            )
        elif len(auth) > 2:
            msg = _("Invalid token header. Token string should not contain spaces.")
            raise AuthenticationFailed(
                {"detail": msg, "error": "ERROR_INVALID_TOKEN_HEADER"}
            )

        decoded_key = auth[1].decode(HTTP_HEADER_ENCODING)
        handler = TokenHandler()

        try:
            token = handler.get_by_key(decoded_key)
        except UserNotInGroup:
            msg = _("The token's user does not belong to the group anymore.")
            raise AuthenticationFailed(
                {"detail": msg, "error": "ERROR_TOKEN_GROUP_MISMATCH"}
            )
        except TokenDoesNotExist:
            msg = _("The provided token does not exist.")
            raise AuthenticationFailed(
                {"detail": msg, "error": "ERROR_TOKEN_DOES_NOT_EXIST"}
            )

        if not token.user.is_active:
            raise AuthenticationFailed(
                {
                    "detail": "The user related to the token is disabled.",
                    "error": "ERROR_USER_NOT_ACTIVE",
                }
            )

        token = handler.update_token_usage(token)
        request.user_token = token
        return token.user, token
Ejemplo n.º 11
0
    def authenticate(self, request):
        auth = get_authorization_header(request).split()

        if not auth or auth[0].lower() != b'token':
            return None

        if len(auth) == 1:
            msg = _('Invalid token header. No token provided.')
            raise AuthenticationFailed({
                'detail': msg,
                'error': 'ERROR_INVALID_TOKEN_HEADER'
            })
        elif len(auth) > 2:
            msg = _(
                'Invalid token header. Token string should not contain spaces.'
            )
            raise AuthenticationFailed({
                'detail': msg,
                'error': 'ERROR_INVALID_TOKEN_HEADER'
            })

        decoded_key = auth[1].decode(HTTP_HEADER_ENCODING)
        handler = TokenHandler()

        try:
            token = handler.get_by_key(decoded_key)
        except UserNotInGroupError:
            msg = _('The token\'s user does not belong to the group anymore.')
            raise AuthenticationFailed({
                'detail': msg,
                'error': 'ERROR_TOKEN_GROUP_MISMATCH'
            })
        except TokenDoesNotExist:
            msg = _('The provided token does not exist.')
            raise AuthenticationFailed({
                'detail': msg,
                'error': 'ERROR_TOKEN_DOES_NOT_EXIST'
            })

        token = handler.update_token_usage(token)
        request.user_token = token
        return token.user, token
Ejemplo n.º 12
0
    def delete(self, request, table_id, row_id):
        """
        Deletes an existing row with the given row_id for table with the given
        table_id.
        """

        table = TableHandler().get_table(table_id)
        TokenHandler().check_table_permissions(request, 'delete', table, False)
        RowHandler().delete_row(request.user, table, row_id)

        return Response(status=204)
Ejemplo n.º 13
0
def test_create_token(data_fixture):
    user = data_fixture.create_user()
    data_fixture.create_user()
    group_1 = data_fixture.create_group(user=user)
    group_2 = data_fixture.create_group()

    handler = TokenHandler()

    with pytest.raises(UserNotInGroupError):
        handler.create_token(user=user, group=group_2, name='Test')

    token = handler.create_token(user=user, group=group_1, name='Test')
    assert token.user_id == user.id
    assert token.group_id == group_1.id
    assert token.name == 'Test'
    assert len(token.key) == 32

    assert Token.objects.all().count() == 1

    permissions = TokenPermission.objects.all()
    assert permissions.count() == 4

    assert permissions[0].token_id == token.id
    assert permissions[0].type == 'create'
    assert permissions[0].database_id is None
    assert permissions[0].table_id is None

    assert permissions[1].token_id == token.id
    assert permissions[1].type == 'read'
    assert permissions[1].database_id is None
    assert permissions[1].table_id is None

    assert permissions[2].token_id == token.id
    assert permissions[2].type == 'update'
    assert permissions[2].database_id is None
    assert permissions[2].table_id is None

    assert permissions[3].token_id == token.id
    assert permissions[3].type == 'delete'
    assert permissions[3].database_id is None
    assert permissions[3].table_id is None
Ejemplo n.º 14
0
    def patch(self, request, data, token_id):
        """Updates the values of a token."""

        token = TokenHandler().get_token(
            request.user,
            token_id,
            base_queryset=Token.objects.select_for_update())
        permissions = data.pop("permissions", None)
        rotate_key = data.pop("rotate_key", False)

        if len(data) > 0:
            token = TokenHandler().update_token(request.user, token, **data)

        if permissions:
            TokenHandler().update_token_permissions(request.user, token,
                                                    **permissions)

        if rotate_key:
            token = TokenHandler().rotate_token_key(request.user, token)

        serializer = TokenSerializer(token)
        return Response(serializer.data)
Ejemplo n.º 15
0
def test_delete_token(data_fixture):
    user = data_fixture.create_user()
    token_1 = data_fixture.create_token(user=user)
    token_2 = data_fixture.create_token()

    handler = TokenHandler()

    with pytest.raises(TokenDoesNotBelongToUser):
        handler.delete_token(user=user, token=token_2)

    handler.update_token_permissions(user, token_1, create=True, read=True,
                                     update=True, delete=True)
    handler.delete_token(user=user, token=token_1)

    assert Token.objects.all().count() == 1
    assert Token.objects.all().first().id == token_2.id
Ejemplo n.º 16
0
def test_generate_token(data_fixture):
    user = data_fixture.create_user()
    group = data_fixture.create_group(user=user)
    handler = TokenHandler()

    assert len(handler.generate_unique_key(32)) == 32
    assert len(handler.generate_unique_key(10)) == 10
    assert handler.generate_unique_key(32) != handler.generate_unique_key(32)

    key = handler.generate_unique_key(32)
    assert not Token.objects.filter(key=key).exists()

    for char in string.ascii_letters + string.digits:
        data_fixture.create_token(key=char, user=user, group=group)

    with pytest.raises(MaximumUniqueTokenTriesError):
        handler.generate_unique_key(1, 3)
Ejemplo n.º 17
0
    def get(self, request, table_id, row_id):
        """
        Responds with a serializer version of the row related to the provided row_id
        and table_id.
        """

        table = TableHandler().get_table(table_id)
        TokenHandler().check_table_permissions(request, 'read', table, False)

        model = table.get_model()
        row = RowHandler().get_row(request.user, table, row_id, model)
        serializer_class = get_row_serializer_class(model,
                                                    RowSerializer,
                                                    is_response=True)
        serializer = serializer_class(row)

        return Response(serializer.data)
Ejemplo n.º 18
0
    def get(self, request, table_id):
        """
        Lists all the rows of the given table id paginated. It is also possible to
        provide a search query.
        """

        table = TableHandler().get_table(table_id)
        table.database.group.has_user(request.user, raise_error=True)

        TokenHandler().check_table_permissions(request, 'read', table, False)
        search = request.GET.get('search')
        order_by = request.GET.get('order_by')
        include = request.GET.get('include')
        exclude = request.GET.get('exclude')
        fields = RowHandler().get_include_exclude_fields(
            table, include, exclude)

        model = table.get_model(fields=fields,
                                field_ids=[] if fields else None)
        queryset = model.objects.all().enhance_by_fields()

        if search:
            queryset = queryset.search_all_fields(search)

        if order_by:
            queryset = queryset.order_by_fields_string(order_by)

        filter_type = (FILTER_TYPE_OR
                       if str(request.GET.get('filter_type')).upper() == 'OR'
                       else FILTER_TYPE_AND)
        filter_object = {
            key: request.GET.getlist(key)
            for key in request.GET.keys()
        }
        queryset = queryset.filter_by_fields_object(filter_object, filter_type)

        paginator = PageNumberPagination(
            limit_page_size=settings.ROW_PAGE_SIZE_LIMIT)
        page = paginator.paginate_queryset(queryset, request, self)
        serializer_class = get_row_serializer_class(model,
                                                    RowSerializer,
                                                    is_response=True)
        serializer = serializer_class(page, many=True)

        return paginator.get_paginated_response(serializer.data)
Ejemplo n.º 19
0
    def patch(self, request, table_id, row_id):
        """Moves the row to another position."""

        table = TableHandler().get_table(table_id)
        TokenHandler().check_table_permissions(request, "update", table, False)

        model = table.get_model()
        before_id = request.GET.get("before_id")
        before = (
            RowHandler().get_row(request.user, table, before_id, model)
            if before_id
            else None
        )
        row = RowHandler().move_row(
            request.user, table, row_id, before=before, model=model
        )

        serializer_class = get_row_serializer_class(
            model, RowSerializer, is_response=True
        )
        serializer = serializer_class(row)
        return Response(serializer.data)
Ejemplo n.º 20
0
    def patch(self, request, table_id, row_id):
        """
        Updates the row with the given row_id for the table with the given
        table_id. Also the post data is validated according to the tables field types.
        """

        table = TableHandler().get_table(table_id)
        TokenHandler().check_table_permissions(request, "update", table, False)

        field_ids = RowHandler().extract_field_ids_from_dict(request.data)
        model = table.get_model()
        validation_serializer = get_row_serializer_class(model, field_ids=field_ids)
        data = validate_data(validation_serializer, request.data)

        row = RowHandler().update_row(request.user, table, row_id, data, model)

        serializer_class = get_row_serializer_class(
            model, RowSerializer, is_response=True
        )
        serializer = serializer_class(row)

        return Response(serializer.data)
Ejemplo n.º 21
0
    def delete(self, request, token_id):
        """Deletes an existing token."""

        token = TokenHandler().get_token(request.user, token_id)
        TokenHandler().delete_token(request.user, token)
        return Response(status=204)
Ejemplo n.º 22
0
    def get(self, request, token_id):
        """Responds with a serialized token instance."""

        token = TokenHandler().get_token(request.user, token_id)
        serializer = TokenSerializer(token)
        return Response(serializer.data)
Ejemplo n.º 23
0
def test_get_token(api_client, data_fixture):
    user, token = data_fixture.create_user_and_token()
    group_1 = data_fixture.create_group(user=user)
    group_2 = data_fixture.create_group()
    token_1 = data_fixture.create_token(user=user, group=group_1)
    token_2 = data_fixture.create_token(user=user, group=group_2)
    token_3 = data_fixture.create_token()

    database_1 = data_fixture.create_database_application(group=group_1)
    database_2 = data_fixture.create_database_application(group=group_1)
    data_fixture.create_database_table(database=database_1, create_table=False)
    data_fixture.create_database_table(database=database_1, create_table=False)
    table_3 = data_fixture.create_database_table(database=database_2,
                                                 create_table=False)

    url = reverse('api:database:tokens:item', kwargs={'token_id': token_1.id})
    response = api_client.get(url,
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT random')
    assert response.status_code == HTTP_401_UNAUTHORIZED

    url = reverse('api:database:tokens:item', kwargs={'token_id': 99999})
    response = api_client.get(url,
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {token}')
    assert response.status_code == HTTP_404_NOT_FOUND
    assert response.json()['error'] == 'ERROR_TOKEN_DOES_NOT_EXIST'

    url = reverse('api:database:tokens:item', kwargs={'token_id': token_3.id})
    response = api_client.get(url,
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {token}')
    assert response.status_code == HTTP_404_NOT_FOUND
    assert response.json()['error'] == 'ERROR_TOKEN_DOES_NOT_EXIST'

    url = reverse('api:database:tokens:item', kwargs={'token_id': token_2.id})
    response = api_client.get(url,
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {token}')
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response.json()['error'] == 'ERROR_USER_NOT_IN_GROUP'

    url = reverse('api:database:tokens:item', kwargs={'token_id': token_1.id})
    response = api_client.get(url,
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json['id'] == token_1.id
    assert response_json['name'] == token_1.name
    assert response_json['group'] == token_1.group_id
    assert response_json['key'] == token_1.key
    assert len(response_json['key']) == 32
    assert response_json['permissions'] == {
        'create': False,
        'read': False,
        'update': False,
        'delete': False
    }

    TokenHandler().update_token_permissions(user,
                                            token_1,
                                            create=True,
                                            read=[database_2],
                                            update=[database_1, table_3],
                                            delete=False)

    url = reverse('api:database:tokens:item', kwargs={'token_id': token_1.id})
    response = api_client.get(url,
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json['permissions']['create'] is True
    assert len(response_json['permissions']['read']) == 1
    assert response_json['permissions']['read'][0] == [
        'database', database_2.id
    ]
    assert len(response_json['permissions']['update']) == 2
    assert response_json['permissions']['update'][0] == [
        'database', database_1.id
    ]
    assert response_json['permissions']['update'][1] == ['table', table_3.id]
    assert response_json['permissions']['delete'] is False

    TokenHandler().update_token_permissions(user,
                                            token_1,
                                            create=[database_1, database_2],
                                            read=False,
                                            update=True,
                                            delete=[table_3])

    url = reverse('api:database:tokens:item', kwargs={'token_id': token_1.id})
    response = api_client.get(url,
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert len(response_json['permissions']['create']) == 2
    assert response_json['permissions']['create'][0] == [
        'database', database_1.id
    ]
    assert response_json['permissions']['create'][1] == [
        'database', database_2.id
    ]
    assert response_json['permissions']['read'] is False
    assert response_json['permissions']['update'] is True
    assert len(response_json['permissions']['delete']) == 1
    assert response_json['permissions']['delete'][0] == ['table', table_3.id]
Ejemplo n.º 24
0
def test_delete_token(api_client, data_fixture):
    user, token = data_fixture.create_user_and_token()
    group_1 = data_fixture.create_group(user=user)
    group_2 = data_fixture.create_group()
    token_1 = data_fixture.create_token(user=user, group=group_1)
    token_2 = data_fixture.create_token(user=user, group=group_2)
    token_3 = data_fixture.create_token()

    TokenHandler().update_token_permissions(user,
                                            token_1,
                                            create=True,
                                            read=True,
                                            update=True,
                                            delete=True)

    url = reverse('api:database:tokens:item', kwargs={'token_id': token_1.id})
    response = api_client.delete(url,
                                 format='json',
                                 HTTP_AUTHORIZATION=f'JWT random')
    assert response.status_code == HTTP_401_UNAUTHORIZED

    url = reverse('api:database:tokens:item', kwargs={'token_id': 99999})
    response = api_client.delete(url,
                                 format='json',
                                 HTTP_AUTHORIZATION=f'JWT {token}')
    assert response.status_code == HTTP_404_NOT_FOUND
    assert response.json()['error'] == 'ERROR_TOKEN_DOES_NOT_EXIST'

    url = reverse('api:database:tokens:item', kwargs={'token_id': token_3.id})
    response = api_client.delete(url,
                                 format='json',
                                 HTTP_AUTHORIZATION=f'JWT {token}')
    assert response.status_code == HTTP_404_NOT_FOUND
    assert response.json()['error'] == 'ERROR_TOKEN_DOES_NOT_EXIST'

    url = reverse('api:database:tokens:item', kwargs={'token_id': token_2.id})
    response = api_client.delete(url,
                                 format='json',
                                 HTTP_AUTHORIZATION=f'JWT {token}')
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response.json()['error'] == 'ERROR_USER_NOT_IN_GROUP'

    url = reverse('api:database:tokens:item', kwargs={'token_id': token_3.id})
    response = api_client.delete(url,
                                 format='json',
                                 HTTP_AUTHORIZATION=f'JWT {token}')
    response_json = response.json()
    assert response.status_code == HTTP_404_NOT_FOUND
    assert response_json['error'] == 'ERROR_TOKEN_DOES_NOT_EXIST'

    assert Token.objects.all().count() == 3
    assert TokenPermission.objects.all().count() == 4

    url = reverse('api:database:tokens:item', kwargs={'token_id': token_1.id})
    response = api_client.delete(url,
                                 format='json',
                                 HTTP_AUTHORIZATION=f'JWT {token}')
    assert response.status_code == HTTP_204_NO_CONTENT

    assert Token.objects.all().count() == 2
    assert TokenPermission.objects.all().count() == 0
Ejemplo n.º 25
0
def test_delete_row(api_client, data_fixture):
    user, jwt_token = data_fixture.create_user_and_token()
    table = data_fixture.create_database_table(user=user)
    table_2 = data_fixture.create_database_table()
    data_fixture.create_text_field(table=table,
                                   order=0,
                                   name='Color',
                                   text_default='white')
    data_fixture.create_number_field(table=table, order=1, name='Horsepower')
    data_fixture.create_boolean_field(table=table, order=2, name='For sale')

    token = TokenHandler().create_token(user, table.database.group, 'Good')
    wrong_token = TokenHandler().create_token(user, table.database.group,
                                              'Wrong')
    TokenHandler().update_token_permissions(user, wrong_token, True, True,
                                            True, False)

    model = table.get_model()
    row_1 = model.objects.create()
    row_2 = model.objects.create()
    row_3 = model.objects.create()

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': 9999,
                      'row_id': 9999
                  })
    response = api_client.delete(url, HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    assert response.status_code == HTTP_404_NOT_FOUND
    assert response.json()['error'] == 'ERROR_TABLE_DOES_NOT_EXIST'

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': 9999
                  })
    response = api_client.delete(url, HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    assert response.status_code == HTTP_404_NOT_FOUND
    assert response.json()['error'] == 'ERROR_ROW_DOES_NOT_EXIST'

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': row_1.id
                  })
    response = api_client.delete(url, HTTP_AUTHORIZATION=f'Token abc123')
    assert response.status_code == HTTP_401_UNAUTHORIZED
    assert response.json()['error'] == 'ERROR_TOKEN_DOES_NOT_EXIST'

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': row_1.id
                  })
    response = api_client.delete(url,
                                 HTTP_AUTHORIZATION=f'Token {wrong_token.key}')
    assert response.status_code == HTTP_401_UNAUTHORIZED
    assert response.json()['error'] == 'ERROR_NO_PERMISSION_TO_TABLE'

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table_2.id,
                      'row_id': row_1.id
                  })
    response = api_client.delete(url, HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response.json()['error'] == 'ERROR_USER_NOT_IN_GROUP'

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': row_1.id
                  })
    response = api_client.delete(url, HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    assert response.status_code == 204

    assert model.objects.count() == 2
    assert model.objects.all()[0].id == row_2.id

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': row_2.id
                  })
    response = api_client.delete(url, HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    assert response.status_code == 204
    assert model.objects.count() == 1

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': row_3.id
                  })
    response = api_client.delete(url, HTTP_AUTHORIZATION=f'Token {token.key}')
    assert response.status_code == 204
    assert model.objects.count() == 0
Ejemplo n.º 26
0
def test_update_row(api_client, data_fixture):
    user, jwt_token = data_fixture.create_user_and_token()
    table = data_fixture.create_database_table(user=user)
    table_2 = data_fixture.create_database_table()
    text_field = data_fixture.create_text_field(table=table,
                                                order=0,
                                                name='Color',
                                                text_default='white')
    number_field = data_fixture.create_number_field(table=table,
                                                    order=1,
                                                    name='Horsepower')
    boolean_field = data_fixture.create_boolean_field(table=table,
                                                      order=2,
                                                      name='For sale')

    token = TokenHandler().create_token(user, table.database.group, 'Good')
    wrong_token = TokenHandler().create_token(user, table.database.group,
                                              'Wrong')
    TokenHandler().update_token_permissions(user, wrong_token, True, True,
                                            False, True)

    model = table.get_model()
    row_1 = model.objects.create()
    row_2 = model.objects.create()

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': 9999,
                      'row_id': 9999
                  })
    response = api_client.patch(url, {f'field_{text_field.id}': 'Orange'},
                                format='json',
                                HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    assert response.status_code == HTTP_404_NOT_FOUND
    assert response.json()['error'] == 'ERROR_TABLE_DOES_NOT_EXIST'

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table_2.id,
                      'row_id': row_1.id
                  })
    response = api_client.patch(url, {f'field_{text_field.id}': 'Orange'},
                                format='json',
                                HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response.json()['error'] == 'ERROR_USER_NOT_IN_GROUP'

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': row_1.id
                  })
    response = api_client.patch(url, {f'field_{text_field.id}': 'Orange'},
                                format='json',
                                HTTP_AUTHORIZATION='Token abc123')
    assert response.status_code == HTTP_401_UNAUTHORIZED
    assert response.json()['error'] == 'ERROR_TOKEN_DOES_NOT_EXIST'

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': row_1.id
                  })
    response = api_client.patch(url, {f'field_{text_field.id}': 'Orange'},
                                format='json',
                                HTTP_AUTHORIZATION=f'Token {wrong_token.key}')
    assert response.status_code == HTTP_401_UNAUTHORIZED
    assert response.json()['error'] == 'ERROR_NO_PERMISSION_TO_TABLE'

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': 99999
                  })
    response = api_client.patch(url, {f'field_{text_field.id}': 'Orange'},
                                format='json',
                                HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    assert response.status_code == HTTP_404_NOT_FOUND
    assert response.json()['error'] == 'ERROR_ROW_DOES_NOT_EXIST'

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': row_1.id
                  })
    response = api_client.patch(url, {
        f'field_{text_field.id}': 'Green',
        f'field_{number_field.id}': -10,
        f'field_{boolean_field.id}': None
    },
                                format='json',
                                HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json = response.json()
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response_json['error'] == 'ERROR_REQUEST_BODY_VALIDATION'
    assert len(response_json['detail']) == 2
    assert response_json['detail'][f'field_{number_field.id}'][0][
        'code'] == 'min_value'
    assert response_json['detail'][f'field_{boolean_field.id}'][0][
        'code'] == 'null'

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': row_1.id
                  })
    response = api_client.patch(url, {
        f'field_{text_field.id}': 'Green',
        f'field_{number_field.id}': 120,
        f'field_{boolean_field.id}': True
    },
                                format='json',
                                HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json_row_1 = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json_row_1['id'] == row_1.id
    assert response_json_row_1[f'field_{text_field.id}'] == 'Green'
    assert response_json_row_1[f'field_{number_field.id}'] == 120
    assert response_json_row_1[f'field_{boolean_field.id}'] is True

    row_1.refresh_from_db()
    assert getattr(row_1, f'field_{text_field.id}') == 'Green'
    assert getattr(row_1, f'field_{number_field.id}') == 120
    assert getattr(row_1, f'field_{boolean_field.id}') is True

    response = api_client.patch(url, {f'field_{text_field.id}': 'Purple'},
                                format='json',
                                HTTP_AUTHORIZATION=f'Token {token.key}')
    response_json_row_1 = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json_row_1[f'field_{text_field.id}'] == 'Purple'
    row_1.refresh_from_db()
    assert getattr(row_1, f'field_{text_field.id}') == 'Purple'

    response = api_client.patch(url, {f'field_{text_field.id}': 'Orange'},
                                format='json',
                                HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json_row_1 = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json_row_1[f'field_{text_field.id}'] == 'Orange'
    # Because the model is generated only for the field we want to change the other
    # fields are not included in the serializer.
    assert f'field_{number_field.id}' not in response_json_row_1
    assert f'field_{boolean_field.id}' not in response_json_row_1

    row_1.refresh_from_db()
    assert getattr(row_1, f'field_{text_field.id}') == 'Orange'
    assert getattr(row_1, f'field_{number_field.id}') == 120
    assert getattr(row_1, f'field_{boolean_field.id}') is True

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': row_2.id
                  })
    response = api_client.patch(url, {
        f'field_{text_field.id}': 'Blue',
        f'field_{number_field.id}': 50,
        f'field_{boolean_field.id}': False
    },
                                format='json',
                                HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json_row_2 = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json_row_2['id'] == row_2.id
    assert response_json_row_2[f'field_{text_field.id}'] == 'Blue'
    assert response_json_row_2[f'field_{number_field.id}'] == 50
    assert response_json_row_2[f'field_{boolean_field.id}'] is False

    row_2.refresh_from_db()
    assert getattr(row_2, f'field_{text_field.id}') == 'Blue'
    assert getattr(row_2, f'field_{number_field.id}') == 50
    assert getattr(row_2, f'field_{boolean_field.id}') is False

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': row_2.id
                  })
    response = api_client.patch(url, {
        f'field_{text_field.id}': None,
        f'field_{number_field.id}': None,
        f'field_{boolean_field.id}': False
    },
                                format='json',
                                HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json_row_2 = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json_row_2['id'] == row_2.id
    assert response_json_row_2[f'field_{text_field.id}'] is None
    assert response_json_row_2[f'field_{number_field.id}'] is None
    assert response_json_row_2[f'field_{boolean_field.id}'] is False

    row_2.refresh_from_db()
    assert getattr(row_2, f'field_{text_field.id}') is None
    assert getattr(row_2, f'field_{number_field.id}') is None
    assert getattr(row_2, f'field_{boolean_field.id}') is False

    table_3 = data_fixture.create_database_table(user=user)
    decimal_field = data_fixture.create_number_field(table=table_3,
                                                     order=0,
                                                     name='Price',
                                                     number_type='DECIMAL',
                                                     number_decimal_places=2)
    model_3 = table_3.get_model()
    row_3 = model_3.objects.create()

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table_3.id,
                      'row_id': row_3.id
                  })
    response = api_client.patch(url, {f'field_{decimal_field.id}': 10.22},
                                format='json',
                                HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json[f'field_{decimal_field.id}'] == '10.22'

    row_3.refresh_from_db()
    assert getattr(row_3, f'field_{decimal_field.id}') == Decimal('10.22')
Ejemplo n.º 27
0
def test_get_row(api_client, data_fixture):
    user, jwt_token = data_fixture.create_user_and_token()
    table = data_fixture.create_database_table(user=user)
    table_2 = data_fixture.create_database_table()
    text_field = data_fixture.create_text_field(table=table,
                                                order=0,
                                                name='Color',
                                                text_default='white')
    number_field = data_fixture.create_number_field(table=table,
                                                    order=1,
                                                    name='Horsepower')
    boolean_field = data_fixture.create_boolean_field(table=table,
                                                      order=2,
                                                      name='For sale')

    token = TokenHandler().create_token(user, table.database.group, 'Good')
    wrong_token = TokenHandler().create_token(user, table.database.group,
                                              'Wrong')
    TokenHandler().update_token_permissions(user, wrong_token, True, False,
                                            True, True)

    model = table.get_model()
    row_1 = model.objects.create(
        **{
            f'field_{text_field.id}': 'Green',
            f'field_{number_field.id}': 120,
            f'field_{boolean_field.id}': False
        })
    row_2 = model.objects.create(
        **{
            f'field_{text_field.id}': 'Purple',
            f'field_{number_field.id}': 240,
            f'field_{boolean_field.id}': True
        })

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': 9999,
                      'row_id': 9999
                  })
    response = api_client.get(url,
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    assert response.status_code == HTTP_404_NOT_FOUND
    assert response.json()['error'] == 'ERROR_TABLE_DOES_NOT_EXIST'

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table_2.id,
                      'row_id': row_1.id
                  })
    response = api_client.get(url,
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response.json()['error'] == 'ERROR_USER_NOT_IN_GROUP'

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': row_1.id
                  })
    response = api_client.get(url,
                              format='json',
                              HTTP_AUTHORIZATION='Token abc123')
    assert response.status_code == HTTP_401_UNAUTHORIZED
    assert response.json()['error'] == 'ERROR_TOKEN_DOES_NOT_EXIST'

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': row_1.id
                  })
    response = api_client.get(url,
                              format='json',
                              HTTP_AUTHORIZATION=f'Token {wrong_token.key}')
    assert response.status_code == HTTP_401_UNAUTHORIZED
    assert response.json()['error'] == 'ERROR_NO_PERMISSION_TO_TABLE'

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': 99999
                  })
    response = api_client.get(url, {f'field_{text_field.id}': 'Orange'},
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    assert response.status_code == HTTP_404_NOT_FOUND
    assert response.json()['error'] == 'ERROR_ROW_DOES_NOT_EXIST'

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': row_1.id
                  })
    response = api_client.get(url,
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json['id'] == row_1.id
    assert response_json[f'field_{text_field.id}'] == 'Green'
    assert response_json[f'field_{number_field.id}'] == 120
    assert response_json[f'field_{boolean_field.id}'] is False

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': row_2.id
                  })
    response = api_client.get(url,
                              format='json',
                              HTTP_AUTHORIZATION=f'Token {token.key}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json['id'] == row_2.id
    assert response_json[f'field_{text_field.id}'] == 'Purple'
    assert response_json[f'field_{number_field.id}'] == 240
    assert response_json[f'field_{boolean_field.id}'] is True
Ejemplo n.º 28
0
def test_create_row(api_client, data_fixture):
    user, jwt_token = data_fixture.create_user_and_token()
    table = data_fixture.create_database_table(user=user)
    table_2 = data_fixture.create_database_table()
    text_field = data_fixture.create_text_field(table=table,
                                                order=0,
                                                name='Color',
                                                text_default='white')
    number_field = data_fixture.create_number_field(table=table,
                                                    order=1,
                                                    name='Horsepower')
    boolean_field = data_fixture.create_boolean_field(table=table,
                                                      order=2,
                                                      name='For sale')
    text_field_2 = data_fixture.create_text_field(table=table,
                                                  order=3,
                                                  name='Description')

    token = TokenHandler().create_token(user, table.database.group, 'Good')
    wrong_token = TokenHandler().create_token(user, table.database.group,
                                              'Wrong')
    TokenHandler().update_token_permissions(user, wrong_token, False, True,
                                            True, True)

    response = api_client.post(reverse('api:database:rows:list',
                                       kwargs={'table_id': 99999}),
                               {f'field_{text_field.id}': 'Test 1'},
                               format='json',
                               HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    assert response.status_code == HTTP_404_NOT_FOUND
    assert response.json()['error'] == 'ERROR_TABLE_DOES_NOT_EXIST'

    response = api_client.post(reverse('api:database:rows:list',
                                       kwargs={'table_id': table.id}),
                               {f'field_{text_field.id}': 'Test 1'},
                               format='json',
                               HTTP_AUTHORIZATION='Token abc123')
    assert response.status_code == HTTP_401_UNAUTHORIZED
    assert response.json()['error'] == 'ERROR_TOKEN_DOES_NOT_EXIST'

    response = api_client.post(reverse('api:database:rows:list',
                                       kwargs={'table_id': table.id}),
                               {f'field_{text_field.id}': 'Test 1'},
                               format='json',
                               HTTP_AUTHORIZATION=f'Token {wrong_token.key}')
    assert response.status_code == HTTP_401_UNAUTHORIZED
    assert response.json()['error'] == 'ERROR_NO_PERMISSION_TO_TABLE'

    response = api_client.post(reverse('api:database:rows:list',
                                       kwargs={'table_id': table_2.id}),
                               {f'field_{text_field.id}': 'Green'},
                               format='json',
                               HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response.json()['error'] == 'ERROR_USER_NOT_IN_GROUP'

    response = api_client.post(reverse('api:database:rows:list',
                                       kwargs={'table_id': table.id}), {
                                           f'field_{text_field.id}': 'Green',
                                           f'field_{number_field.id}': -10,
                                           f'field_{boolean_field.id}': None,
                                           f'field_{text_field_2.id}': None
                                       },
                               format='json',
                               HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json = response.json()
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response_json['error'] == 'ERROR_REQUEST_BODY_VALIDATION'
    assert len(response_json['detail']) == 2
    assert response_json['detail'][f'field_{number_field.id}'][0][
        'code'] == 'min_value'
    assert response_json['detail'][f'field_{boolean_field.id}'][0][
        'code'] == 'null'

    response = api_client.post(reverse('api:database:rows:list',
                                       kwargs={'table_id': table.id}), {},
                               format='json',
                               HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json_row_1 = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json_row_1[f'field_{text_field.id}'] == 'white'
    assert not response_json_row_1[f'field_{number_field.id}']
    assert response_json_row_1[f'field_{boolean_field.id}'] is False
    assert response_json_row_1[f'field_{text_field_2.id}'] is None

    response = api_client.post(reverse('api:database:rows:list',
                                       kwargs={'table_id': table.id}), {
                                           f'field_{number_field.id}': None,
                                           f'field_{boolean_field.id}': False,
                                           f'field_{text_field_2.id}': '',
                                       },
                               format='json',
                               HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json_row_2 = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json_row_2[f'field_{text_field.id}'] == 'white'
    assert not response_json_row_2[f'field_{number_field.id}']
    assert response_json_row_2[f'field_{boolean_field.id}'] is False
    assert response_json_row_2[f'field_{text_field_2.id}'] == ''

    response = api_client.post(reverse('api:database:rows:list',
                                       kwargs={'table_id': table.id}),
                               {
                                   f'field_{text_field.id}': 'Green',
                                   f'field_{number_field.id}': 120,
                                   f'field_{boolean_field.id}': True,
                                   f'field_{text_field_2.id}': 'Not important',
                               },
                               format='json',
                               HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json_row_3 = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json_row_3[f'field_{text_field.id}'] == 'Green'
    assert response_json_row_3[f'field_{number_field.id}'] == 120
    assert response_json_row_3[f'field_{boolean_field.id}']
    assert response_json_row_3[f'field_{text_field_2.id}'] == 'Not important'

    response = api_client.post(reverse('api:database:rows:list',
                                       kwargs={'table_id': table.id}), {
                                           f'field_{text_field.id}': 'Purple',
                                           f'field_{number_field.id}': 240,
                                           f'field_{boolean_field.id}': True,
                                           f'field_{text_field_2.id}': ''
                                       },
                               format='json',
                               HTTP_AUTHORIZATION=f'Token {token.key}')
    response_json_row_4 = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json_row_4[f'field_{text_field.id}'] == 'Purple'
    assert response_json_row_4[f'field_{number_field.id}'] == 240
    assert response_json_row_4[f'field_{boolean_field.id}']
    assert response_json_row_4[f'field_{text_field_2.id}'] == ''

    model = table.get_model()
    assert model.objects.all().count() == 4
    rows = model.objects.all().order_by('id')

    row_1 = rows[0]
    assert row_1.id == response_json_row_1['id']
    assert getattr(row_1, f'field_{text_field.id}') == 'white'
    assert getattr(row_1, f'field_{number_field.id}') is None
    assert getattr(row_1, f'field_{boolean_field.id}') is False
    assert getattr(row_1, f'field_{text_field_2.id}') is None

    row_2 = rows[1]
    assert row_2.id == response_json_row_2['id']
    assert getattr(row_2, f'field_{text_field.id}') == 'white'
    assert getattr(row_2, f'field_{number_field.id}') is None
    assert getattr(row_2, f'field_{boolean_field.id}') is False
    assert getattr(row_1, f'field_{text_field_2.id}') is None

    row_3 = rows[2]
    assert row_3.id == response_json_row_3['id']
    assert getattr(row_3, f'field_{text_field.id}') == 'Green'
    assert getattr(row_3, f'field_{number_field.id}') == 120
    assert getattr(row_3, f'field_{boolean_field.id}') is True
    assert getattr(row_3, f'field_{text_field_2.id}') == 'Not important'

    row_4 = rows[3]
    assert row_4.id == response_json_row_4['id']
    assert getattr(row_4, f'field_{text_field.id}') == 'Purple'
    assert getattr(row_4, f'field_{number_field.id}') == 240
    assert getattr(row_4, f'field_{boolean_field.id}') is True
    assert getattr(row_4, f'field_{text_field_2.id}') == ''
Ejemplo n.º 29
0
def test_list_rows(api_client, data_fixture):
    user, jwt_token = data_fixture.create_user_and_token(email='*****@*****.**',
                                                         password='******',
                                                         first_name='Test1')
    table = data_fixture.create_database_table(user=user)
    table_2 = data_fixture.create_database_table()
    field_1 = data_fixture.create_text_field(name='Name',
                                             table=table,
                                             primary=True)
    field_2 = data_fixture.create_number_field(name='Price', table=table)

    token = TokenHandler().create_token(user, table.database.group, 'Good')
    wrong_token = TokenHandler().create_token(user, table.database.group,
                                              'Wrong')
    TokenHandler().update_token_permissions(user, wrong_token, True, False,
                                            True, True)

    model = table.get_model(attribute_names=True)
    row_1 = model.objects.create(name='Product 1', price=50)
    row_2 = model.objects.create(name='Product 2/3', price=100)
    row_3 = model.objects.create(name='Product 3', price=150)
    row_4 = model.objects.create(name='Last product', price=200)

    response = api_client.get(reverse('api:database:rows:list',
                                      kwargs={'table_id': 999999}),
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    assert response.status_code == HTTP_404_NOT_FOUND
    assert response.json()['error'] == 'ERROR_TABLE_DOES_NOT_EXIST'

    response = api_client.get(reverse('api:database:rows:list',
                                      kwargs={'table_id': table_2.id}),
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response.json()['error'] == 'ERROR_USER_NOT_IN_GROUP'

    response = api_client.get(reverse('api:database:rows:list',
                                      kwargs={'table_id': table.id}),
                              format='json',
                              HTTP_AUTHORIZATION='Token abc123')
    assert response.status_code == HTTP_401_UNAUTHORIZED
    assert response.json()['error'] == 'ERROR_TOKEN_DOES_NOT_EXIST'

    response = api_client.get(reverse('api:database:rows:list',
                                      kwargs={'table_id': table.id}),
                              format='json',
                              HTTP_AUTHORIZATION=f'Token {wrong_token.key}')
    assert response.status_code == HTTP_401_UNAUTHORIZED
    assert response.json()['error'] == 'ERROR_NO_PERMISSION_TO_TABLE'

    response = api_client.get(reverse('api:database:rows:list',
                                      kwargs={'table_id': table.id}),
                              format='json',
                              HTTP_AUTHORIZATION=f'Token {token.key}')
    assert response.status_code == HTTP_200_OK

    response = api_client.get(reverse('api:database:rows:list',
                                      kwargs={'table_id': table.id}),
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json['count'] == 4
    assert len(response_json['results']) == 4
    assert response_json['results'][0]['id'] == row_1.id
    assert response_json['results'][0][f'field_{field_1.id}'] == 'Product 1'
    assert response_json['results'][0][f'field_{field_2.id}'] == 50

    url = reverse('api:database:rows:list', kwargs={'table_id': table.id})
    response = api_client.get(f'{url}?size=2&page=1',
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json['count'] == 4
    assert len(response_json['results']) == 2
    assert response_json['results'][0]['id'] == row_1.id
    assert response_json['results'][1]['id'] == row_2.id

    url = reverse('api:database:rows:list', kwargs={'table_id': table.id})
    response = api_client.get(f'{url}?size=2&page=2',
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json['count'] == 4
    assert len(response_json['results']) == 2
    assert response_json['results'][0]['id'] == row_3.id
    assert response_json['results'][1]['id'] == row_4.id

    url = reverse('api:database:rows:list', kwargs={'table_id': table.id})
    response = api_client.get(f'{url}?size=2&page=3',
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json = response.json()
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response_json['error'] == 'ERROR_INVALID_PAGE'

    url = reverse('api:database:rows:list', kwargs={'table_id': table.id})
    response = api_client.get(f'{url}?size=201',
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json = response.json()
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response_json['error'] == 'ERROR_PAGE_SIZE_LIMIT'

    url = reverse('api:database:rows:list', kwargs={'table_id': table.id})
    response = api_client.get(f'{url}?search=Product 1',
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json['count'] == 1
    assert len(response_json['results']) == 1
    assert response_json['results'][0]['id'] == row_1.id

    url = reverse('api:database:rows:list', kwargs={'table_id': table.id})
    response = api_client.get(f'{url}?search=1',
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json['count'] == 1
    assert len(response_json['results']) == 1
    assert response_json['results'][0]['id'] == row_1.id

    url = reverse('api:database:rows:list', kwargs={'table_id': table.id})
    response = api_client.get(f'{url}?search=3',
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json['count'] == 2
    assert len(response_json['results']) == 2
    assert response_json['results'][0]['id'] == row_2.id
    assert response_json['results'][1]['id'] == row_3.id

    url = reverse('api:database:rows:list', kwargs={'table_id': table.id})
    response = api_client.get(f'{url}?search=200',
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json['count'] == 1
    assert len(response_json['results']) == 1
    assert response_json['results'][0]['id'] == row_4.id

    url = reverse('api:database:rows:list', kwargs={'table_id': table.id})
    response = api_client.get(f'{url}?order_by=field_999999',
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    assert response.status_code == HTTP_400_BAD_REQUEST
    response_json = response.json()
    assert response_json['error'] == 'ERROR_ORDER_BY_FIELD_NOT_FOUND'
    assert response_json['detail'] == (
        'The field field_999999 was not found in the table.')

    number_field_type = field_type_registry.get('number')
    old_can_order_by = number_field_type.can_order_by
    number_field_type.can_order_by = False
    url = reverse('api:database:rows:list', kwargs={'table_id': table.id})
    response = api_client.get(f'{url}?order_by=-field_{field_2.id}',
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    assert response.status_code == HTTP_400_BAD_REQUEST
    response_json = response.json()
    assert response_json['error'] == 'ERROR_ORDER_BY_FIELD_NOT_POSSIBLE'
    assert response_json['detail'] == (
        f'It is not possible to order by field_{field_2.id} because the field type '
        f'number does not support filtering.')
    number_field_type.can_order_by = old_can_order_by

    url = reverse('api:database:rows:list', kwargs={'table_id': table.id})
    response = api_client.get(f'{url}?order_by=-field_{field_2.id}',
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {jwt_token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json['count'] == 4
    assert len(response_json['results']) == 4
    assert response_json['results'][0]['id'] == row_4.id
    assert response_json['results'][1]['id'] == row_3.id
    assert response_json['results'][2]['id'] == row_2.id
    assert response_json['results'][3]['id'] == row_1.id
Ejemplo n.º 30
0
def test_move_row(api_client, data_fixture):
    user, jwt_token = data_fixture.create_user_and_token()
    table = data_fixture.create_database_table(user=user)
    table_2 = data_fixture.create_database_table()

    token = TokenHandler().create_token(user, table.database.group, "Good")
    wrong_token = TokenHandler().create_token(user, table.database.group,
                                              "Wrong")
    TokenHandler().update_token_permissions(user, wrong_token, True, True,
                                            False, True)

    handler = RowHandler()
    row_1 = handler.create_row(user=user, table=table)
    row_2 = handler.create_row(user=user, table=table)
    row_3 = handler.create_row(user=user, table=table)

    url = reverse("api:database:rows:move",
                  kwargs={
                      "table_id": 9999,
                      "row_id": 9999
                  })
    response = api_client.patch(
        url,
        format="json",
        HTTP_AUTHORIZATION=f"JWT {jwt_token}",
    )
    assert response.status_code == HTTP_404_NOT_FOUND
    assert response.json()["error"] == "ERROR_TABLE_DOES_NOT_EXIST"

    url = reverse("api:database:rows:move",
                  kwargs={
                      "table_id": table_2.id,
                      "row_id": row_1.id
                  })
    response = api_client.patch(
        url,
        format="json",
        HTTP_AUTHORIZATION=f"JWT {jwt_token}",
    )
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response.json()["error"] == "ERROR_USER_NOT_IN_GROUP"

    url = reverse("api:database:rows:move",
                  kwargs={
                      "table_id": table.id,
                      "row_id": row_1.id
                  })
    response = api_client.patch(
        url,
        format="json",
        HTTP_AUTHORIZATION="Token abc123",
    )
    assert response.status_code == HTTP_401_UNAUTHORIZED
    assert response.json()["error"] == "ERROR_TOKEN_DOES_NOT_EXIST"

    url = reverse("api:database:rows:move",
                  kwargs={
                      "table_id": table.id,
                      "row_id": row_1.id
                  })
    response = api_client.patch(
        url,
        format="json",
        HTTP_AUTHORIZATION=f"Token {wrong_token.key}",
    )
    assert response.status_code == HTTP_401_UNAUTHORIZED
    assert response.json()["error"] == "ERROR_NO_PERMISSION_TO_TABLE"

    url = reverse("api:database:rows:move",
                  kwargs={
                      "table_id": table.id,
                      "row_id": 99999
                  })
    response = api_client.patch(
        url,
        format="json",
        HTTP_AUTHORIZATION=f"JWT {jwt_token}",
    )
    assert response.status_code == HTTP_404_NOT_FOUND
    assert response.json()["error"] == "ERROR_ROW_DOES_NOT_EXIST"

    url = reverse("api:database:rows:move",
                  kwargs={
                      "table_id": table.id,
                      "row_id": row_1.id
                  })
    response = api_client.patch(
        f"{url}?before_id=-1",
        format="json",
        HTTP_AUTHORIZATION=f"JWT {jwt_token}",
    )
    assert response.status_code == HTTP_404_NOT_FOUND
    assert response.json()["error"] == "ERROR_ROW_DOES_NOT_EXIST"

    url = reverse("api:database:rows:move",
                  kwargs={
                      "table_id": table.id,
                      "row_id": row_1.id
                  })
    response = api_client.patch(
        url,
        format="json",
        HTTP_AUTHORIZATION=f"JWT {jwt_token}",
    )
    response_json_row_1 = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json_row_1["id"] == row_1.id
    assert response_json_row_1["order"] == "4.00000000000000000000"

    row_1.refresh_from_db()
    row_2.refresh_from_db()
    row_3.refresh_from_db()
    assert row_1.order == Decimal("4.00000000000000000000")
    assert row_2.order == Decimal("2.00000000000000000000")
    assert row_3.order == Decimal("3.00000000000000000000")

    url = reverse("api:database:rows:move",
                  kwargs={
                      "table_id": table.id,
                      "row_id": row_1.id
                  })
    response = api_client.patch(
        f"{url}?before_id={row_3.id}",
        format="json",
        HTTP_AUTHORIZATION=f"Token {token.key}",
    )
    response_json_row_1 = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json_row_1["id"] == row_1.id
    assert response_json_row_1["order"] == "2.99999999999999999999"

    row_1.refresh_from_db()
    row_2.refresh_from_db()
    row_3.refresh_from_db()
    assert row_1.order == Decimal("2.99999999999999999999")
    assert row_2.order == Decimal("2.00000000000000000000")
    assert row_3.order == Decimal("3.00000000000000000000")