Skip to content

Commit

Permalink
Merge pull request #3177 from mathesar-foundation/3176-update-constra…
Browse files Browse the repository at this point in the history
…ints-for-positive-integers-in-oid-and-column_order

Updated `oid` and `column_order` fields to only allow positive integers
  • Loading branch information
Anish9901 committed Jan 3, 2024
2 parents 38cdbe8 + 384f564 commit 596e756
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 6 deletions.
1 change: 1 addition & 0 deletions mathesar/api/exceptions/error_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class ErrorCodes(Enum):
URLNotReachableError = 4405
URLInvalidContentType = 4406
UnknownDBType = 4408
InvalidColumnOrder = 4430
InvalidDateError = 4413
InvalidDateFormatError = 4414
InvalidLinkChoice = 4409
Expand Down
11 changes: 11 additions & 0 deletions mathesar/api/exceptions/validation_exceptions/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,14 @@ def __init__(
field=None,
):
super().__init__(None, self.error_code, message, field)


class InvalidColumnOrder(MathesarValidationException):
error_code = ErrorCodes.InvalidColumnOrder.value

def __init__(
self,
message="Invalid column order.",
field=None,
):
super().__init__(None, self.error_code, message, field, None)
11 changes: 7 additions & 4 deletions mathesar/api/serializers/table_settings.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from rest_framework import serializers

from mathesar.api.exceptions.mixins import MathesarErrorMessageMixin

from mathesar.models.base import PreviewColumnSettings, TableSettings, compute_default_preview_template
from mathesar.api.exceptions.validation_exceptions.exceptions import InvalidColumnOrder
from mathesar.models.base import PreviewColumnSettings, TableSettings, compute_default_preview_template, ValidationError


class PreviewColumnSerializer(MathesarErrorMessageMixin, serializers.ModelSerializer):
Expand Down Expand Up @@ -37,6 +37,9 @@ def update(self, instance, validated_data):

column_order_data = validated_data.pop('column_order', None)
if column_order_data is not None:
instance.column_order = column_order_data
instance.save()
try:
instance.column_order = column_order_data
instance.save()
except ValidationError:
raise InvalidColumnOrder()
return instance
34 changes: 34 additions & 0 deletions mathesar/migrations/0011_auto_20240103_2120.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Generated by Django 3.1.14 on 2024-01-03 21:20

from django.db import migrations, models
import mathesar.models.base


class Migration(migrations.Migration):

dependencies = [
('mathesar', '0010_remove_editable'),
]

operations = [
migrations.AlterField(
model_name='constraint',
name='oid',
field=models.PositiveIntegerField(),
),
migrations.AlterField(
model_name='schema',
name='oid',
field=models.PositiveIntegerField(),
),
migrations.AlterField(
model_name='table',
name='oid',
field=models.PositiveIntegerField(),
),
migrations.AlterField(
model_name='tablesettings',
name='column_order',
field=models.JSONField(blank=True, default=None, null=True, validators=[mathesar.models.base.validate_column_order]),
),
]
20 changes: 18 additions & 2 deletions mathesar/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class DatabaseObject(ReflectionManagerMixin, BaseModel):
"""
Objects that can be referenced using a database identifier
"""
oid = models.IntegerField()
oid = models.PositiveIntegerField()

class Meta:
abstract = True
Expand Down Expand Up @@ -920,10 +920,26 @@ class PreviewColumnSettings(BaseModel):
template = models.CharField(max_length=255)


def validate_column_order(value):
"""
Custom validator to ensure that all elements in the list are positive integers.
"""
if not all(isinstance(item, int) and item > 0 for item in value):
raise ValidationError("All elements of column order must be positive integers.")


class TableSettings(ReflectionManagerMixin, BaseModel):
preview_settings = models.OneToOneField(PreviewColumnSettings, on_delete=models.CASCADE)
table = models.OneToOneField(Table, on_delete=models.CASCADE, related_name="settings")
column_order = JSONField(null=True, default=None)
column_order = JSONField(null=True, blank=True, default=None, validators=[validate_column_order])

def save(self, **kwargs):
# Cleans the fields before saving by running respective field validator(s)
try:
self.clean_fields()
except ValidationError as e:
raise e
super().save(**kwargs)


def _create_table_settings(tables):
Expand Down
17 changes: 17 additions & 0 deletions mathesar/tests/api/test_table_settings_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from db.tables.operations.select import get_oid_from_table
from mathesar.models import base as models_base
from mathesar.api.exceptions.error_codes import ErrorCodes


@pytest.fixture
Expand Down Expand Up @@ -133,3 +134,19 @@ def test_update_table_settings_string_in_column_order(client, column_test_table)
assert response.status_code == 200
response_data = response.json()
assert response_data['column_order'] == column_order_as_ints


def test_update_table_settings_negative_column_order(client, column_test_table):
column_order = [-4, 5, 6]
data = {
"column_order": column_order
}
response = client.patch(
f"/api/db/v0/tables/{column_test_table.id}/settings/{column_test_table.settings.id}/",
data=data,
)
response_data = response.json()[0]
print(response_data)
assert response.status_code == 400
assert response_data['code'] == ErrorCodes.InvalidColumnOrder.value
assert response_data['message'] == 'Invalid column order.'

0 comments on commit 596e756

Please sign in to comment.