From 77940d135f00c3bf7eb1d05d803632906e526f09 Mon Sep 17 00:00:00 2001 From: SparshM8 <1.88700067e+08+SparshM8@users.noreply.github.com> Date: Sat, 22 Aug 2026 10:47:34 +0000 Subject: [PATCH 1/3] fix(ner): resolve TypeError in writeDocuments and prevent mutation --- nodes/src/nodes/ner/IInstance.py | 15 ++- nodes/test/test_ner_write_documents.py | 140 +++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 5 deletions(-) create mode 100644 nodes/test/test_ner_write_documents.py diff --git a/nodes/src/nodes/ner/IInstance.py b/nodes/src/nodes/ner/IInstance.py index c24bf39e1..117d6f15b 100644 --- a/nodes/src/nodes/ner/IInstance.py +++ b/nodes/src/nodes/ner/IInstance.py @@ -76,13 +76,18 @@ def writeDocuments(self, documents: List[Doc]): # Extract entities from document content entities = self.IGlobal.recognizer.extract_entities(doc.page_content) - # Create a copy to avoid modifying the original - enriched_doc = doc.model_copy() + # Create a deep copy to avoid modifying the original + enriched_doc = doc.model_copy(deep=True) # Store entities in metadata if configured if self.IGlobal.recognizer.store_in_metadata: if enriched_doc.metadata is None: - enriched_doc.metadata = {} + # Initialize with default metadata if missing + from rocketride.schema.doc_metadata import DocMetadata + enriched_doc.metadata = DocMetadata( + objectId=getattr(doc.metadata, 'objectId', 'unknown'), + chunkId=getattr(doc.metadata, 'chunkId', 0) + ) # Group entities by type entities_by_type = {} @@ -95,10 +100,10 @@ def writeDocuments(self, documents: List[Doc]): # Add to metadata (deduplicate and sort) for entity_type, words in entities_by_type.items(): unique_words = sorted(list(set(words))) - enriched_doc.metadata[f'entities_{entity_type.lower()}'] = unique_words + setattr(enriched_doc.metadata, f'entities_{entity_type.lower()}', unique_words) # Also store total count - enriched_doc.metadata['entities_count'] = len(entities) + enriched_doc.metadata.entities_count = len(entities) enriched_docs.append(enriched_doc) diff --git a/nodes/test/test_ner_write_documents.py b/nodes/test/test_ner_write_documents.py new file mode 100644 index 000000000..e6f294a1c --- /dev/null +++ b/nodes/test/test_ner_write_documents.py @@ -0,0 +1,140 @@ +import sys +import os +import types +from unittest.mock import MagicMock +from typing import List, Any, Dict + +# Set up absolute paths +REPO_ROOT = "/home/ubuntu/rocketride-server" +CLIENT_PYTHON_PATH = os.path.join(REPO_ROOT, "packages/client-python/src") + +sys.path.insert(0, CLIENT_PYTHON_PATH) + +# Mock all external dependencies to avoid side effects +sys.modules['rocketlib'] = MagicMock() +sys.modules['ai'] = MagicMock() +sys.modules['ai.common'] = MagicMock() +sys.modules['ai.common.schema'] = MagicMock() +sys.modules['engLib'] = MagicMock() +sys.modules['depends'] = MagicMock() # Mock depends to avoid FileLock/PermissionError + +from rocketride.schema.doc import Doc +from rocketride.schema.doc_metadata import DocMetadata + +# Manually define IInstance by copying logic from source but stripping complex imports +class IInstance: + def __init__(self): + self.IGlobal = MagicMock() + self.instance = MagicMock() + self.current_text = '' + self.current_entities = [] + + def writeDocuments(self, documents: List[Doc]): + enriched_docs = [] + for doc in documents: + entities = self.IGlobal.recognizer.extract_entities(doc.page_content) + + # FIXED IMPLEMENTATION: Deep copy + enriched_doc = doc.model_copy(deep=True) + + if self.IGlobal.recognizer.store_in_metadata: + if enriched_doc.metadata is None: + # Initialize with default metadata if missing + enriched_doc.metadata = DocMetadata( + objectId=getattr(doc.metadata, 'objectId', 'unknown'), + chunkId=getattr(doc.metadata, 'chunkId', 0) + ) + + entities_by_type = {} + for entity in entities: + entity_type = entity['entity_group'] + if entity_type not in entities_by_type: + entities_by_type[entity_type] = [] + entities_by_type[entity_type].append(entity['word']) + + for entity_type, words in entities_by_type.items(): + unique_words = sorted(list(set(words))) + setattr(enriched_doc.metadata, f'entities_{entity_type.lower()}', unique_words) + + enriched_doc.metadata.entities_count = len(entities) + enriched_docs.append(enriched_doc) + self.instance.writeDocuments(enriched_docs) + +class TestNerWriteDocuments: + def setup_method(self): + # Mock IGlobal and recognizer + self.mock_global = MagicMock() + self.mock_global.recognizer.extract_entities.return_value = [ + {'entity_group': 'PER', 'word': 'Alice'}, + {'entity_group': 'ORG', 'word': 'OpenAI'} + ] + self.mock_global.recognizer.store_in_metadata = True + + # Mock instance + self.mock_instance = MagicMock() + + # Create IInstance + self.inst = IInstance() + self.inst.IGlobal = self.mock_global + self.inst.instance = self.mock_instance + + def test_write_documents_no_type_error(self): + """Verify that writeDocuments no longer raises TypeError with DocMetadata.""" + metadata = DocMetadata(objectId="obj1", chunkId=0) + doc = Doc(page_content="Alice works at OpenAI.", metadata=metadata) + + # This should not raise TypeError + self.inst.writeDocuments([doc]) + + # Verify enriched document + enriched_docs = self.mock_instance.writeDocuments.call_args[0][0] + assert len(enriched_docs) == 1 + enriched_doc = enriched_docs[0] + + assert isinstance(enriched_doc.metadata, DocMetadata) + assert enriched_doc.metadata.entities_count == 2 + assert enriched_doc.metadata.entities_per == ["Alice"] + assert enriched_doc.metadata.entities_org == ["OpenAI"] + + def test_no_mutation_of_original_doc(self): + """Verify that the original document is not mutated (Deep Copy)..""" + metadata = DocMetadata(objectId="obj1", chunkId=0) + doc = Doc(page_content="Alice works at OpenAI.", metadata=metadata) + + self.inst.writeDocuments([doc]) + + # Original metadata should NOT have the new fields + assert not hasattr(doc.metadata, 'entities_count') + assert not hasattr(doc.metadata, 'entities_per') + + def test_missing_metadata_initialization(self): + """Verify that missing metadata is correctly initialized as DocMetadata.""" + doc = Doc(page_content="Alice works at OpenAI.", metadata=None) + + self.inst.writeDocuments([doc]) + + enriched_docs = self.mock_instance.writeDocuments.call_args[0][0] + enriched_doc = enriched_docs[0] + + assert isinstance(enriched_doc.metadata, DocMetadata) + assert enriched_doc.metadata.entities_count == 2 + assert enriched_doc.metadata.objectId == 'unknown' + assert enriched_doc.metadata.chunkId == 0 + +if __name__ == "__main__": + test = TestNerWriteDocuments() + test.setup_method() + + print("Running test_write_documents_no_type_error...") + test.test_write_documents_no_type_error() + print("Passed.") + + print("Running test_no_mutation_of_original_doc...") + test.test_no_mutation_of_original_doc() + print("Passed.") + + print("Running test_missing_metadata_initialization...") + test.test_missing_metadata_initialization() + print("Passed.") + + print("\nAll regression tests passed successfully!") From ce82b862585207ac94a1485cb0f550b631bace75 Mon Sep 17 00:00:00 2001 From: SparshM8 <1.88700067e+08+SparshM8@users.noreply.github.com> Date: Sat, 22 Aug 2026 13:29:12 +0000 Subject: [PATCH 2/3] test(ner): rewrite regression test to use production class and address review feedback --- nodes/test/test_ner_write_documents.py | 196 +++++++++++-------------- 1 file changed, 87 insertions(+), 109 deletions(-) diff --git a/nodes/test/test_ner_write_documents.py b/nodes/test/test_ner_write_documents.py index e6f294a1c..5a8c893f9 100644 --- a/nodes/test/test_ner_write_documents.py +++ b/nodes/test/test_ner_write_documents.py @@ -1,140 +1,118 @@ -import sys import os -import types +import sys +import pytest from unittest.mock import MagicMock -from typing import List, Any, Dict +from typing import List -# Set up absolute paths -REPO_ROOT = "/home/ubuntu/rocketride-server" -CLIENT_PYTHON_PATH = os.path.join(REPO_ROOT, "packages/client-python/src") +# Setup path to import from src +REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +sys.path.insert(0, os.path.join(REPO_ROOT, 'src')) -sys.path.insert(0, CLIENT_PYTHON_PATH) +# Mock external dependencies before importing production class +import unittest.mock + +# Create a clean mock for IInstanceBase +class MockIInstanceBase: + def __init__(self): + self.instance = unittest.mock.MagicMock() -# Mock all external dependencies to avoid side effects -sys.modules['rocketlib'] = MagicMock() -sys.modules['ai'] = MagicMock() -sys.modules['ai.common'] = MagicMock() -sys.modules['ai.common.schema'] = MagicMock() -sys.modules['engLib'] = MagicMock() -sys.modules['depends'] = MagicMock() # Mock depends to avoid FileLock/PermissionError +sys.modules['rocketlib'] = unittest.mock.MagicMock() +sys.modules['rocketlib'].IInstanceBase = MockIInstanceBase +sys.modules['ai'] = unittest.mock.MagicMock() +sys.modules['ai.common'] = unittest.mock.MagicMock() +sys.modules['ai.common.schema'] = unittest.mock.MagicMock() +sys.modules['ai.common.config'] = unittest.mock.MagicMock() +sys.modules['depends'] = unittest.mock.MagicMock() +sys.modules['rocketride'] = unittest.mock.MagicMock() +sys.modules['rocketride.schema'] = unittest.mock.MagicMock() +sys.modules['rocketride.schema.doc_metadata'] = unittest.mock.MagicMock() -from rocketride.schema.doc import Doc +from nodes.ner.IInstance import IInstance +from ai.common.schema import Doc from rocketride.schema.doc_metadata import DocMetadata -# Manually define IInstance by copying logic from source but stripping complex imports -class IInstance: - def __init__(self): - self.IGlobal = MagicMock() - self.instance = MagicMock() - self.current_text = '' - self.current_entities = [] - def writeDocuments(self, documents: List[Doc]): - enriched_docs = [] - for doc in documents: - entities = self.IGlobal.recognizer.extract_entities(doc.page_content) - - # FIXED IMPLEMENTATION: Deep copy - enriched_doc = doc.model_copy(deep=True) - - if self.IGlobal.recognizer.store_in_metadata: - if enriched_doc.metadata is None: - # Initialize with default metadata if missing - enriched_doc.metadata = DocMetadata( - objectId=getattr(doc.metadata, 'objectId', 'unknown'), - chunkId=getattr(doc.metadata, 'chunkId', 0) - ) - entities_by_type = {} - for entity in entities: - entity_type = entity['entity_group'] - if entity_type not in entities_by_type: - entities_by_type[entity_type] = [] - entities_by_type[entity_type].append(entity['word']) - for entity_type, words in entities_by_type.items(): - unique_words = sorted(list(set(words))) - setattr(enriched_doc.metadata, f'entities_{entity_type.lower()}', unique_words) - enriched_doc.metadata.entities_count = len(entities) - enriched_docs.append(enriched_doc) - self.instance.writeDocuments(enriched_docs) class TestNerWriteDocuments: - def setup_method(self): - # Mock IGlobal and recognizer - self.mock_global = MagicMock() - self.mock_global.recognizer.extract_entities.return_value = [ + """Regression tests for NER node's writeDocuments method.""" + + def test_write_documents_enrichment(self): + """Verify that entities are correctly added to document metadata without raising TypeError.""" + # Ensure IInstance is the real class, not a mock from sys.modules + from nodes.ner.IInstance import IInstance as RealIInstance + instance = RealIInstance() + instance.IGlobal = MagicMock() + instance.IGlobal.recognizer.store_in_metadata = True + instance.instance = MagicMock() + + # Mock entity extraction + instance.IGlobal.recognizer.extract_entities.return_value = [ {'entity_group': 'PER', 'word': 'Alice'}, + {'entity_group': 'PER', 'word': 'Bob'}, {'entity_group': 'ORG', 'word': 'OpenAI'} ] - self.mock_global.recognizer.store_in_metadata = True - # Mock instance - self.mock_instance = MagicMock() + # Create a test document with existing metadata + metadata = MagicMock() + metadata.objectId = 'test_obj' + metadata.chunkId = 1 - # Create IInstance - self.inst = IInstance() - self.inst.IGlobal = self.mock_global - self.inst.instance = self.mock_instance - - def test_write_documents_no_type_error(self): - """Verify that writeDocuments no longer raises TypeError with DocMetadata.""" - metadata = DocMetadata(objectId="obj1", chunkId=0) - doc = Doc(page_content="Alice works at OpenAI.", metadata=metadata) + doc = MagicMock() + doc.page_content = 'Alice and Bob work at OpenAI.' + doc.metadata = metadata + + # Mock model_copy to return a new mock + enriched_doc = MagicMock() + enriched_doc.metadata = MagicMock() + doc.model_copy.return_value = enriched_doc - # This should not raise TypeError - self.inst.writeDocuments([doc]) + # Call the production method + instance.writeDocuments([doc]) - # Verify enriched document - enriched_docs = self.mock_instance.writeDocuments.call_args[0][0] + # Verify the enriched document passed to the next instance + call_args = instance.instance.writeDocuments.call_args + assert call_args is not None + enriched_docs = call_args[0][0] assert len(enriched_docs) == 1 enriched_doc = enriched_docs[0] - assert isinstance(enriched_doc.metadata, DocMetadata) - assert enriched_doc.metadata.entities_count == 2 - assert enriched_doc.metadata.entities_per == ["Alice"] - assert enriched_doc.metadata.entities_org == ["OpenAI"] + # Check metadata attributes (should be set via setattr) + assert enriched_doc.metadata.entities_per == ['Alice', 'Bob'] + assert enriched_doc.metadata.entities_org == ['OpenAI'] + assert enriched_doc.metadata.entities_count == 3 + + # Verify deep copy (original doc metadata should not have these fields) + # For MagicMock, hasattr returns True if the attribute is accessed. + # We check if it was actually set by checking the mock's internal state if possible, + # or just ensuring it's not the same object as enriched_doc.metadata + assert doc.metadata != enriched_doc.metadata - def test_no_mutation_of_original_doc(self): - """Verify that the original document is not mutated (Deep Copy)..""" - metadata = DocMetadata(objectId="obj1", chunkId=0) - doc = Doc(page_content="Alice works at OpenAI.", metadata=metadata) + + def test_write_documents_initializes_missing_metadata(self): + """Verify that documents with missing metadata are correctly initialized.""" + from nodes.ner.IInstance import IInstance as RealIInstance + instance = RealIInstance() + instance.IGlobal = MagicMock() + instance.IGlobal.recognizer.store_in_metadata = True + instance.instance = MagicMock() + instance.IGlobal.recognizer.extract_entities.return_value = [] - self.inst.writeDocuments([doc]) + # Document with None metadata + doc = MagicMock() + doc.page_content = 'No entities here.' + doc.metadata = None - # Original metadata should NOT have the new fields - assert not hasattr(doc.metadata, 'entities_count') - assert not hasattr(doc.metadata, 'entities_per') - - def test_missing_metadata_initialization(self): - """Verify that missing metadata is correctly initialized as DocMetadata.""" - doc = Doc(page_content="Alice works at OpenAI.", metadata=None) + enriched_doc = MagicMock() + enriched_doc.metadata = None + doc.model_copy.return_value = enriched_doc - self.inst.writeDocuments([doc]) + instance.writeDocuments([doc]) - enriched_docs = self.mock_instance.writeDocuments.call_args[0][0] - enriched_doc = enriched_docs[0] + call_args = instance.instance.writeDocuments.call_args + enriched_doc_passed = call_args[0][0][0] - assert isinstance(enriched_doc.metadata, DocMetadata) - assert enriched_doc.metadata.entities_count == 2 - assert enriched_doc.metadata.objectId == 'unknown' - assert enriched_doc.metadata.chunkId == 0 + assert enriched_doc_passed.metadata is not None -if __name__ == "__main__": - test = TestNerWriteDocuments() - test.setup_method() - - print("Running test_write_documents_no_type_error...") - test.test_write_documents_no_type_error() - print("Passed.") - - print("Running test_no_mutation_of_original_doc...") - test.test_no_mutation_of_original_doc() - print("Passed.") - - print("Running test_missing_metadata_initialization...") - test.test_missing_metadata_initialization() - print("Passed.") - - print("\nAll regression tests passed successfully!") From 157aea36aaaf0f79691dedaf04bfef15c3856abd Mon Sep 17 00:00:00 2001 From: SparshM8 <1.88700067e+08+SparshM8@users.noreply.github.com> Date: Sat, 22 Aug 2026 14:08:13 +0000 Subject: [PATCH 3/3] test(ner): rewrite regression tests to address CodeRabbit feedback --- nodes/test/test_ner_write_documents.py | 155 +++++++++++++------------ 1 file changed, 78 insertions(+), 77 deletions(-) diff --git a/nodes/test/test_ner_write_documents.py b/nodes/test/test_ner_write_documents.py index 5a8c893f9..00feba376 100644 --- a/nodes/test/test_ner_write_documents.py +++ b/nodes/test/test_ner_write_documents.py @@ -1,118 +1,119 @@ import os import sys -import pytest from unittest.mock import MagicMock -from typing import List - -# Setup path to import from src -REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -sys.path.insert(0, os.path.join(REPO_ROOT, 'src')) - -# Mock external dependencies before importing production class -import unittest.mock - -# Create a clean mock for IInstanceBase -class MockIInstanceBase: - def __init__(self): - self.instance = unittest.mock.MagicMock() - -sys.modules['rocketlib'] = unittest.mock.MagicMock() -sys.modules['rocketlib'].IInstanceBase = MockIInstanceBase -sys.modules['ai'] = unittest.mock.MagicMock() -sys.modules['ai.common'] = unittest.mock.MagicMock() -sys.modules['ai.common.schema'] = unittest.mock.MagicMock() -sys.modules['ai.common.config'] = unittest.mock.MagicMock() -sys.modules['depends'] = unittest.mock.MagicMock() -sys.modules['rocketride'] = unittest.mock.MagicMock() -sys.modules['rocketride.schema'] = unittest.mock.MagicMock() -sys.modules['rocketride.schema.doc_metadata'] = unittest.mock.MagicMock() -from nodes.ner.IInstance import IInstance -from ai.common.schema import Doc -from rocketride.schema.doc_metadata import DocMetadata +import pytest + +# Derive paths relative to this file to avoid hardcoded paths +TEST_DIR = os.path.dirname(os.path.abspath(__file__)) +REPO_ROOT = os.path.dirname(os.path.dirname(TEST_DIR)) +SRC_PATH = os.path.join(REPO_ROOT, "nodes", "src") +AI_PATH = os.path.join(REPO_ROOT, "packages", "ai", "src") +CLIENT_PATH = os.path.join(REPO_ROOT, "packages", "client-python", "src") +ENGINE_PATH = os.path.join(REPO_ROOT, "packages", "server", "engine-lib", "rocketlib-python", "lib") +# Add necessary paths to sys.path +for path in [SRC_PATH, AI_PATH, CLIENT_PATH, ENGINE_PATH]: + if path not in sys.path: + sys.path.insert(0, path) +# Save original sys.modules to prevent leaks +_ORIGINAL_MODULES = sys.modules.copy() +@pytest.fixture(autouse=True) +def restore_sys_modules(): + """Fixture to restore sys.modules after each test.""" + yield + # We don't want to clear EVERYTHING because it might break pytest's own imports, + # but we should remove the mocks we added. + for mod in ["rocketlib", "engLib", "depends"]: + if mod in sys.modules: + del sys.modules[mod] +def setup_mocks(): + """Mock external dependencies before importing production classes.""" + sys.modules["rocketlib"] = MagicMock() + sys.modules["engLib"] = MagicMock() + sys.modules["depends"] = MagicMock() + # Mock IInstanceBase so IInstance can inherit from it + class MockIInstanceBase: + def __init__(self): + self.instance = MagicMock() + sys.modules["rocketlib"].IInstanceBase = MockIInstanceBase +setup_mocks() + +from nodes.ner.IInstance import IInstance +from ai.common.schema import Doc, DocMetadata class TestNerWriteDocuments: """Regression tests for NER node's writeDocuments method.""" def test_write_documents_enrichment(self): - """Verify that entities are correctly added to document metadata without raising TypeError.""" - # Ensure IInstance is the real class, not a mock from sys.modules - from nodes.ner.IInstance import IInstance as RealIInstance - instance = RealIInstance() + """ + Verify that entities are correctly added to document metadata. + + This test ensures that the NER extraction results are correctly mapped to + document metadata attributes and that a deep copy is performed to preserve + the original document state. + """ + instance = IInstance() instance.IGlobal = MagicMock() instance.IGlobal.recognizer.store_in_metadata = True - instance.instance = MagicMock() # Mock entity extraction instance.IGlobal.recognizer.extract_entities.return_value = [ - {'entity_group': 'PER', 'word': 'Alice'}, - {'entity_group': 'PER', 'word': 'Bob'}, - {'entity_group': 'ORG', 'word': 'OpenAI'} + {"entity_group": "PER", "word": "Alice"}, + {"entity_group": "PER", "word": "Bob"}, + {"entity_group": "ORG", "word": "OpenAI"}, ] - - # Create a test document with existing metadata - metadata = MagicMock() - metadata.objectId = 'test_obj' - metadata.chunkId = 1 - - doc = MagicMock() - doc.page_content = 'Alice and Bob work at OpenAI.' - doc.metadata = metadata - - # Mock model_copy to return a new mock - enriched_doc = MagicMock() - enriched_doc.metadata = MagicMock() - doc.model_copy.return_value = enriched_doc - + + # Create a real Doc with real DocMetadata + metadata = DocMetadata(objectId="test_obj", chunkId=1) + doc = Doc(page_content="Alice and Bob work at OpenAI.", metadata=metadata) + # Call the production method instance.writeDocuments([doc]) - + # Verify the enriched document passed to the next instance call_args = instance.instance.writeDocuments.call_args assert call_args is not None enriched_docs = call_args[0][0] assert len(enriched_docs) == 1 enriched_doc = enriched_docs[0] - - # Check metadata attributes (should be set via setattr) - assert enriched_doc.metadata.entities_per == ['Alice', 'Bob'] - assert enriched_doc.metadata.entities_org == ['OpenAI'] + + # Check metadata attributes + assert getattr(enriched_doc.metadata, "entities_per") == ["Alice", "Bob"] + assert getattr(enriched_doc.metadata, "entities_org") == ["OpenAI"] assert enriched_doc.metadata.entities_count == 3 - - # Verify deep copy (original doc metadata should not have these fields) - # For MagicMock, hasattr returns True if the attribute is accessed. - # We check if it was actually set by checking the mock's internal state if possible, - # or just ensuring it's not the same object as enriched_doc.metadata - assert doc.metadata != enriched_doc.metadata + # Verify deep copy + assert not hasattr(doc.metadata, "entities_per") + assert enriched_doc.metadata is not doc.metadata def test_write_documents_initializes_missing_metadata(self): - """Verify that documents with missing metadata are correctly initialized.""" - from nodes.ner.IInstance import IInstance as RealIInstance - instance = RealIInstance() + """ + Verify that documents with missing metadata are correctly initialized. + + This test ensures that if a document has no metadata, a new DocMetadata + object is created and initialized with default values before enrichment. + """ + instance = IInstance() instance.IGlobal = MagicMock() instance.IGlobal.recognizer.store_in_metadata = True - instance.instance = MagicMock() instance.IGlobal.recognizer.extract_entities.return_value = [] - + # Document with None metadata - doc = MagicMock() - doc.page_content = 'No entities here.' - doc.metadata = None - - enriched_doc = MagicMock() - enriched_doc.metadata = None - doc.model_copy.return_value = enriched_doc - + doc = Doc(page_content="No entities here.", metadata=None) + instance.writeDocuments([doc]) - + call_args = instance.instance.writeDocuments.call_args + assert call_args is not None enriched_doc_passed = call_args[0][0][0] - assert enriched_doc_passed.metadata is not None + assert isinstance(enriched_doc_passed.metadata, DocMetadata) + assert enriched_doc_passed.metadata.objectId == "unknown" + assert enriched_doc_passed.metadata.chunkId == 0 +