Fixing version validation when the parameter isn't used in the patch

remotes/origin/enhancement/email-actions
Alejandro Alonso 2015-06-02 12:14:11 +02:00
parent 21f847f5ca
commit 03f395a384
2 changed files with 41 additions and 17 deletions

View File

@ -37,7 +37,9 @@ class OCCResourceMixin(object):
return param_version return param_version
def _validate_param_version(self, param_version, current_version): def _validate_param_version(self, param_version, current_version):
if param_version is not None: if param_version is None:
return False
else:
if param_version < 0: if param_version < 0:
return False return False
if current_version is not None and param_version > current_version: if current_version is not None and param_version > current_version:
@ -50,28 +52,27 @@ class OCCResourceMixin(object):
if obj.id: if obj.id:
current_version = type(obj).objects.model.objects.get(id=obj.id).version current_version = type(obj).objects.model.objects.get(id=obj.id).version
# Extract param version # Extract param version
param_version = self._extract_param_version() param_version = self._extract_param_version()
if not self._validate_param_version(param_version, current_version): if not self._validate_param_version(param_version, current_version):
raise exc.WrongArguments({"version": _("The version is not valid")}) raise exc.WrongArguments({"version": _("The version parameter is not valid")})
if current_version != param_version: if current_version != param_version:
diff_versions = current_version - param_version diff_versions = current_version - param_version
modifying_fields = set(self.request.DATA.keys()) modifying_fields = set(self.request.DATA.keys())
if "version" in modifying_fields: if "version" in modifying_fields:
modifying_fields.remove("version") modifying_fields.remove("version")
modified_fields = set(get_modified_fields(obj, diff_versions)) modified_fields = set(get_modified_fields(obj, diff_versions))
if "version" in modifying_fields: if "version" in modifying_fields:
modified_fields.remove("version") modified_fields.remove("version")
both_modified = modifying_fields & modified_fields both_modified = modifying_fields & modified_fields
if both_modified: if both_modified:
raise exc.WrongArguments({"version": _("The version doesn't match with the current one")}) raise exc.WrongArguments({"version": _("The version doesn't match with the current one")})
if obj.id:
obj.version = models.F('version') + 1 obj.version = models.F('version') + 1
def pre_save(self, obj): def pre_save(self, obj):

View File

@ -333,3 +333,26 @@ def test_valid_concurrent_save_for_task_different_fields(client):
data = {"version": 1, "description": "test 2"} data = {"version": 1, "description": "test 2"}
response = client.patch(url, json.dumps(data), content_type="application/json") response = client.patch(url, json.dumps(data), content_type="application/json")
assert response.status_code == 200 assert response.status_code == 200
def test_invalid_save_without_version_parameter(client):
user = f.UserFactory.create()
project = f.ProjectFactory.create(owner=user)
f.MembershipFactory.create(project=project, user=user, is_owner=True)
client.login(user)
mock_path = "taiga.projects.tasks.api.TaskViewSet.pre_conditions_on_save"
with patch(mock_path):
url = reverse("tasks-list")
data = {"subject": "test",
"project": project.id,
"status": f.TaskStatusFactory.create(project=project).id}
response = client.json.post(url, json.dumps(data))
assert response.status_code == 201
task_id = json.loads(response.content)["id"]
url = reverse("tasks-detail", args=(task_id,))
data = {"subject": "test 1"}
response = client.patch(url, json.dumps(data), content_type="application/json")
assert response.status_code == 400