From 94348c5bb80fdd791d225d3ede95180021c6d1cb Mon Sep 17 00:00:00 2001 From: Marti Raudsepp Date: Thu, 5 Oct 2023 15:53:58 +0300 Subject: [PATCH] Avoid duplicate enum values for allow_null, allow_blank --- drf_spectacular/plumbing.py | 4 ++-- tests/test_plumbing.py | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/drf_spectacular/plumbing.py b/drf_spectacular/plumbing.py index 85b61e96..95154759 100644 --- a/drf_spectacular/plumbing.py +++ b/drf_spectacular/plumbing.py @@ -410,9 +410,9 @@ def build_choice_field(field): else: type = None - if field.allow_blank: + if field.allow_blank and '' not in choices: choices.append('') - if field.allow_null: + if field.allow_null and None not in choices: choices.append(None) schema = { diff --git a/tests/test_plumbing.py b/tests/test_plumbing.py index d2ca7ef5..711d77b3 100644 --- a/tests/test_plumbing.py +++ b/tests/test_plumbing.py @@ -6,6 +6,8 @@ from datetime import datetime from enum import Enum +from rest_framework.fields import ChoiceField + if sys.version_info >= (3, 8): from typing import TypedDict else: @@ -21,7 +23,7 @@ from drf_spectacular.openapi import AutoSchema from drf_spectacular.plumbing import ( analyze_named_regex_pattern, build_basic_type, detype_pattern, follow_field_source, - force_instance, get_list_serializer, is_field, is_serializer, resolve_type_hint, + force_instance, get_list_serializer, is_field, is_serializer, resolve_type_hint, build_choice_field, ) from drf_spectacular.validation import validate_schema from tests import generate_schema @@ -358,3 +360,21 @@ def test_analyze_named_regex_pattern(no_warnings, pattern, output): def test_unknown_basic_type(capsys): build_basic_type(object) assert 'could not resolve type for "' in capsys.readouterr().err + + +def test_choicefield_choices_enum(): + schema = build_choice_field(ChoiceField(['bluepill', 'redpill'])) + assert schema['enum'] == ['bluepill', 'redpill'] + assert schema['type'] == 'string' + + schema = build_choice_field( + ChoiceField(['bluepill', 'redpill'], allow_null=True, allow_blank=True) + ) + assert schema['enum'] == ['bluepill', 'redpill', '', None] + assert schema['type'] == 'string' + + schema = build_choice_field( + ChoiceField(['bluepill', 'redpill', '', None], allow_null=True, allow_blank=True) + ) + assert schema['enum'] == ['bluepill', 'redpill', '', None] + assert 'type' not in schema