diff --git a/rdmo/projects/static/projects/js/project_questions/services.js b/rdmo/projects/static/projects/js/project_questions/services.js index f98236b6f9..f7079016d5 100644 --- a/rdmo/projects/static/projects/js/project_questions/services.js +++ b/rdmo/projects/static/projects/js/project_questions/services.js @@ -796,9 +796,11 @@ angular.module('project_questions') if (question === null) { // this is the id of a new valueset value.value_type = 'text'; + value.widget_type = 'text'; value.unit = ''; } else { value.value_type = question.value_type; + value.widget_type = question.widget_type; value.unit = question.unit; } diff --git a/rdmo/projects/tests/test_validator_conflict.py b/rdmo/projects/tests/test_validator_conflict.py index e48191c6ce..c6b97761b4 100644 --- a/rdmo/projects/tests/test_validator_conflict.py +++ b/rdmo/projects/tests/test_validator_conflict.py @@ -13,11 +13,15 @@ def test_serializer_create(db): + value = Value.objects.get(project_id=project_id, snapshot=None, attribute__path=attribute_path) + + class MockedRequest: + data = {} + class MockedView: + request = MockedRequest() project = Project.objects.get(id=project_id) - value = Value.objects.get(project_id=project_id, snapshot=None, attribute__path=attribute_path) - validator = ValueConflictValidator() serializer = ValueSerializer() serializer.context['view'] = MockedView() @@ -31,11 +35,15 @@ class MockedView: def test_serializer_create_error(db): + value = Value.objects.get(project_id=project_id, snapshot=None, attribute__path=attribute_path) + + class MockedRequest: + data = {} + class MockedView: + request = MockedRequest() project = Project.objects.get(id=project_id) - value = Value.objects.get(project_id=project_id, snapshot=None, attribute__path=attribute_path) - validator = ValueConflictValidator() serializer = ValueSerializer() serializer.context['view'] = MockedView() @@ -121,3 +129,100 @@ class MockedView: 'set_index': value.set_index, 'collection_index': value.collection_index, }, serializer) + + +def test_serializer_create_checkbox(db): + value = Value.objects.get( + project_id=project_id, + snapshot=None, + attribute__path='individual/collection/checkbox', + collection_index=0 + ) + value2 = Value.objects.get( + project_id=project_id, + snapshot=None, + attribute__path='individual/collection/checkbox', + collection_index=2 + ) + + class MockedRequest: + data = { + 'widget_type': 'checkbox' + } + + class MockedView: + request = MockedRequest() + project = Project.objects.get(id=project_id) + + validator = ValueConflictValidator() + serializer = ValueSerializer() + serializer.context['view'] = MockedView() + + validator({ + 'attribute': value.attribute, + 'set_prefix': value.set_prefix, + 'set_index': value.set_index, + 'collection_index': value.collection_index, + 'option': value2.option + }, serializer) + + +def test_serializer_create_checkbox_error(db): + value = Value.objects.get( + project_id=project_id, + snapshot=None, + attribute__path='individual/collection/checkbox', + collection_index=0 + ) + + class MockedRequest: + data = { + 'widget_type': 'checkbox' + } + + class MockedView: + request = MockedRequest() + project = Project.objects.get(id=project_id) + + validator = ValueConflictValidator() + serializer = ValueSerializer() + serializer.context['view'] = MockedView() + + with pytest.raises(RestFameworkValidationError): + validator({ + 'attribute': value.attribute, + 'set_prefix': value.set_prefix, + 'set_index': value.set_index, + 'collection_index': value.collection_index, + 'option': value.option + }, serializer) + + +def test_serializer_create_checkbox_text(db): + value = Value.objects.get( + project_id=project_id, + snapshot=None, + attribute__path='individual/collection/checkbox', + collection_index=0 + ) + + class MockedRequest: + data = { + 'widget_type': 'text' + } + + class MockedView: + request = MockedRequest() + project = Project.objects.get(id=project_id) + + validator = ValueConflictValidator() + serializer = ValueSerializer() + serializer.context['view'] = MockedView() + + with pytest.raises(RestFameworkValidationError): + validator({ + 'attribute': value.attribute, + 'set_prefix': value.set_prefix, + 'set_index': value.set_index, + 'collection_index': value.collection_index + }, serializer) diff --git a/rdmo/projects/validators.py b/rdmo/projects/validators.py index 77c7495f3f..714b1c1287 100644 --- a/rdmo/projects/validators.py +++ b/rdmo/projects/validators.py @@ -28,13 +28,21 @@ def __call__(self, data, serializer): }) else: # for a new value, check if there is already a value with the same attribute and indexes + get_kwargs = { + 'attribute': data.get('attribute'), + 'set_prefix': data.get('set_prefix'), + 'set_index': data.get('set_index'), + 'collection_index': data.get('collection_index') + } + + # for checkboxes, check only values with the same option + # get the widget_type from the put request + widget_type = serializer.context['view'].request.data.get('widget_type') + if widget_type == 'checkbox': + get_kwargs['option'] = data.get('option') + try: - serializer.context['view'].project.values.filter(snapshot=None).get( - attribute=data.get('attribute'), - set_prefix=data.get('set_prefix'), - set_index=data.get('set_index'), - collection_index=data.get('collection_index') - ) + serializer.context['view'].project.values.filter(snapshot=None).get(**get_kwargs) except ObjectDoesNotExist: return except MultipleObjectsReturned: