From 8d3c3f868c73331c7a8760e57dce39576f3cab61 Mon Sep 17 00:00:00 2001 From: Harsh Kashyap Date: Thu, 25 Jun 2026 16:59:12 +0530 Subject: [PATCH] fix(api): validate immutable document fields when value is zero (#16309) --- api/utils/validation_utils.py | 6 +-- .../api/utils/test_doc_validation.py | 53 +++++++++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/api/utils/validation_utils.py b/api/utils/validation_utils.py index b200e5014e..4eccd09692 100644 --- a/api/utils/validation_utils.py +++ b/api/utils/validation_utils.py @@ -1041,13 +1041,13 @@ def validate_immutable_fields(update_doc_req: UpdateDocumentReq, doc): A tuple of (error_message, error_code) if validation fails, or (None, None) if validation passes. """ - if update_doc_req.chunk_count and update_doc_req.chunk_count != int(getattr(doc, "chunk_num", -1)): + if update_doc_req.chunk_count is not None and update_doc_req.chunk_count != int(getattr(doc, "chunk_num", -1)): return "Can't change `chunk_count`.", RetCode.DATA_ERROR - if update_doc_req.token_count and update_doc_req.token_count != int(getattr(doc, "token_num", -1)): + if update_doc_req.token_count is not None and update_doc_req.token_count != int(getattr(doc, "token_num", -1)): return "Can't change `token_count`.", RetCode.DATA_ERROR - if update_doc_req.progress: + if update_doc_req.progress is not None: progress_from_db = float(getattr(doc, "progress", -1.0)) # should not use "==" to compare two float values if not math.isclose(update_doc_req.progress, progress_from_db): diff --git a/test/unit_test/api/utils/test_doc_validation.py b/test/unit_test/api/utils/test_doc_validation.py index 31ce591ed5..aa3deb6102 100644 --- a/test/unit_test/api/utils/test_doc_validation.py +++ b/test/unit_test/api/utils/test_doc_validation.py @@ -175,6 +175,59 @@ def test_validate_immutable_fields_none_values(): assert error_code is None +@pytest.mark.p2 +def test_validate_immutable_fields_zero_values_must_match(): + """Regression: falsy zero values must still be validated, not skipped.""" + update_doc_req = UpdateDocumentReq(chunk_count=0, token_count=0, progress=0.0) + doc = Mock() + doc.chunk_num = 10 + doc.token_num = 100 + doc.progress = 0.5 + + error_msg, error_code = validate_immutable_fields(update_doc_req, doc) + assert error_msg == "Can't change `chunk_count`." + assert error_code == RetCode.DATA_ERROR + + +@pytest.mark.p2 +def test_validate_immutable_fields_zero_token_count_mismatch_when_chunk_count_matches(): + update_doc_req = UpdateDocumentReq(chunk_count=0, token_count=0, progress=0.0) + doc = Mock() + doc.chunk_num = 0 + doc.token_num = 100 + doc.progress = 0.0 + + error_msg, error_code = validate_immutable_fields(update_doc_req, doc) + assert error_msg == "Can't change `token_count`." + assert error_code == RetCode.DATA_ERROR + + +@pytest.mark.p2 +def test_validate_immutable_fields_zero_progress_mismatch_when_counts_match(): + update_doc_req = UpdateDocumentReq(chunk_count=0, token_count=0, progress=0.0) + doc = Mock() + doc.chunk_num = 0 + doc.token_num = 0 + doc.progress = 0.5 + + error_msg, error_code = validate_immutable_fields(update_doc_req, doc) + assert error_msg == "Can't change `progress`." + assert error_code == RetCode.DATA_ERROR + + +@pytest.mark.p2 +def test_validate_immutable_fields_zero_values_matching_doc(): + update_doc_req = UpdateDocumentReq(chunk_count=0, token_count=0, progress=0.0) + doc = Mock() + doc.chunk_num = 0 + doc.token_num = 0 + doc.progress = 0.0 + + error_msg, error_code = validate_immutable_fields(update_doc_req, doc) + assert error_msg is None + assert error_code is None + + def test_validate_document_name_valid(): """Test valid document name update.""" req_doc_name = "new_document.pdf"