Skip to content

Commit

Permalink
add DRF validation with JSON Schema
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkAmi committed Dec 25, 2023
1 parent 287eb80 commit 134af38
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 0 deletions.
16 changes: 16 additions & 0 deletions api/serializers.py
@@ -1,12 +1,28 @@
import json
import traceback
from copy import deepcopy

from django.conf import settings
from jsonschema.validators import Draft7Validator
from rest_framework import serializers
from jsonschema import validate, ValidationError

from diary.models import Diary


class DiarySerializer(serializers.ModelSerializer):
def validate(self, attrs):
with open(settings.BASE_DIR / 'frontend' / 'src' / 'jsonSchemas' / 'diary.json') as f:
json_schema = json.load(f)

errors = Draft7Validator(json_schema).iter_errors(attrs)
messages = [e.message for e in errors]

if messages:
raise serializers.ValidationError(messages)

return attrs

def create(self, validated_data):
ModelClass = self.Meta.model

Expand Down
Empty file added api/tests/__init__.py
Empty file.
81 changes: 81 additions & 0 deletions api/tests/test_serializers.py
@@ -0,0 +1,81 @@
from api.serializers import DiarySerializer


def test_JSONSchemaの仕様を満たす():
input_data = {
'content': {
'name': '3文字',
'note': '5文字です'
}
}

serializer = DiarySerializer(data=input_data)
assert serializer.is_valid()
assert serializer.errors == {}


def test_nameが2文字():
input_data = {
'content': {
'name': '2字',
'note': '5文字です'
}
}

serializer = DiarySerializer(data=input_data)
assert serializer.is_valid() is False
assert serializer.errors['non_field_errors'] == ["'2字' is too short"]


def test_noteが4文字():
input_data = {
'content': {
'name': '3文字',
'note': '4文字だ'
}
}

serializer = DiarySerializer(data=input_data)
assert serializer.is_valid() is False
assert serializer.errors['non_field_errors'] == ["'4文字だ' is too short"]


def test_nameとnoteが短すぎる():
input_data = {
'content': {
'name': '2字',
'note': '4文字だ'
}
}

serializer = DiarySerializer(data=input_data)
assert serializer.is_valid() is False
assert serializer.errors['non_field_errors'] == ["'2字' is too short", "'4文字だ' is too short"]


def test_nameとnoteが数字():
input_data = {
'content': {
'name': 123,
'note': 12345
}
}

serializer = DiarySerializer(data=input_data)
assert serializer.is_valid() is False
assert serializer.errors['non_field_errors'] == ["123 is not of type 'string'", "12345 is not of type 'string'"]


def test_追加のプロパティが存在するためNG():
input_data = {
'content': {
'name': '3文字',
'note': '5文字です',
'additional': '追加したデータ'
}
}

serializer = DiarySerializer(data=input_data)
assert serializer.is_valid() is False
assert serializer.errors['non_field_errors'] \
== ["Additional properties are not allowed ('additional' was unexpected)"]
1 change: 1 addition & 0 deletions config/test_settings.py
@@ -0,0 +1 @@
from .settings import *
2 changes: 2 additions & 0 deletions pyproject.toml
@@ -0,0 +1,2 @@
[tool.pytest.ini_options]
DJANGO_SETTINGS_MODULE = "config.test_settings"

0 comments on commit 134af38

Please sign in to comment.