Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_finds_run_nodes_in_complex_fields_correctly(self):
document = Document(docx_path('three_props_in_same_paragraph.docx'))
properties = CustomProperties(document).find_docprops_in_document()
assert 3 == len(properties), \
'input should contain three complex field docproperties'
# In the first field, there are the following runs: begin, docprop,
# a separate, 3 runs for the value (because of spellcheck) and end
prop = properties[0]
assert 3 == len(prop.get_runs_for_update())
# when dissolving a property the runs that have to be removed
# are the begin, docprop, and from separate to end (here just
# separate and end)
runs = prop.get_runs_to_replace_field_with_value()
assert 4 == len(runs)
assert runs[0] == prop.begin_run
assert runs[1] == prop.w_r
assert 6 == len(document.paragraphs), 'input file should contain 6 paragraphs'
properties = xpath(document.element.body, './/w:instrText')
assert 5 == len(properties),\
'input should contain five complex field docproperties'
expected_paragraphs = [u'Custom Doc Properties',
u'Text: Foo Bar',
u'Number: 123',
u'Boolean: Y',
u'Date: 11.06.2019',
u'Float: 1.1']
actual_paragraphs = [paragraph.text for paragraph in document.paragraphs]
assert actual_paragraphs == expected_paragraphs
CustomProperties(document).dissolve_fields("Number Property")
actual_paragraphs = [paragraph.text for paragraph in document.paragraphs]
assert actual_paragraphs == expected_paragraphs
properties = xpath(document.element.body, './/w:instrText')
assert 4 == len(properties),\
'only 4 fields should remain after removal of one'
def test_simple_field_gets_updated(self):
document = Document(docx_path('outdated_docproperty_with_umlauts.docx'))
assert_simple_field_value(
u'xxx', document.element.body, u"F\xfc\xfc")
CustomProperties(document).update(u"F\xfc\xfc", u"new v\xe4lue")
assert_simple_field_value(
u"new v\xe4lue", document.element.body, u"F\xfc\xfc")
def test_complex_docprop_with_multiple_textnode_in_same_run_are_updated(self):
document = Document(docx_path('two_textnodes_in_run_docproperty.docx'))
paragraphs = xpath(document.element.body, '//w:p')
assert 1 == len(paragraphs), 'input file contains one paragraph'
assert 1 == len(xpath(document.element.body, '//w:instrText')), \
'input contains one complex field docproperty'
w_p = paragraphs[0]
cached_values = cached_complex_field_values(w_p)
assert 2 == len(cached_values), \
'doc property value is scattered over 2 parts'
assert 'Hello there' == ''.join(cached_values)
CustomProperties(document).update_all()
w_p = xpath(document.element.body, '//w:p')[0]
cached_values = cached_complex_field_values(w_p)
assert 1 == len(cached_values), \
'doc property value has been reset to one cached value'
assert 'i will be spllchecked!' == cached_values[0]
def test_doc_properties_values():
document = Document(docx_path('docproperties.docx'))
props = CustomProperties(document)
assert props.values() == [
'Foo Bar', 123, True, datetime(2019, 6, 11, 10, 0), 1.1]
u'shared.header')
footer_1 = document.sections[0].footer
footer_2 = document.sections[1].footer
assert not footer_1.is_linked_to_previous
assert not footer_2.is_linked_to_previous
assert_complex_field_value(
u'123',
footer_1.part.element,
u'section1.footer')
assert_complex_field_value(
u'yyy',
footer_2.part.element,
u'section2.footer')
CustomProperties(document).update_all()
# the same header should be referenced by both sections
assert_complex_field_value(
u'sh\xe4red',
header_1.part.element,
u'shared.header')
assert_complex_field_value(
u'sh\xe4red',
header_2.part.element,
u'shared.header')
footer_1 = document.sections[0].footer
footer_2 = document.sections[1].footer
assert_complex_field_value(
u'-1.0',
footer_1.part.element,
def test_removes_simple_field_but_keeps_value(self):
document = Document(docx_path('outdated_docproperty_with_umlauts.docx'))
assert 1 == len(document.paragraphs), 'input file should contain 1 paragraph'
fields = xpath(
document.element.body,
simple_field_expression(u"F\xfc\xfc"))
assert 1 == len(fields), 'should contain one simple field docproperty'
assert u'Hie chund ds property: ' == document.paragraphs[0].text
assert u'xxx' == fields[0].text
CustomProperties(document).dissolve_fields(u"F\xfc\xfc")
fields = xpath(
document.element.body,
simple_field_expression(u"F\xfc\xfc"))
assert 0 == len(fields), 'should not contain any docproperties anymore'
# when simple field is removed, the value is moved one up in the hierarchy
assert u'Hie chund ds property: xxx' == document.paragraphs[0].text
def test_set_doc_properties():
document = Document(docx_path('docproperties.docx'))
props = CustomProperties(document)
props['Text Property'] = 'baz'
assert props['Text Property'] == 'baz'
props['Boolean Property'] = False
assert props['Boolean Property'] is False
props['Number Property'] = 456
assert props['Number Property'] == 456
props['Date Property'] = datetime(2019, 10, 20, 12, 0)
assert props['Date Property'] == datetime(2019, 10, 20, 12, 0)
def test_dissolves_all_instances_of_given_field(self):
document = Document(docx_path('multiple_identical_properties.docx'))
assert 3 == len(document.paragraphs), 'input file should contain 3 paragraphs'
assert 3 == len(xpath(document.element.body, './/w:instrText')), \
'document should contain three complex field docproperties'
for paragraph in document.paragraphs:
assert u'Foo' == paragraph.text
CustomProperties(document).dissolve_fields("Text Property")
assert 3 == len(document.paragraphs)
assert 0 == len(xpath(document.element.body, './/w:instrText')), \
'document should not contain any complex field anymore'
for paragraph in document.paragraphs:
assert u'Foo' == paragraph.text, "value should have been kept in document"
def insert(self, index, doc, remove_property_fields=True):
"""Insert the given document at the given index."""
self.reset_reference_mapping()
# Remove custom property fields but keep the values
if remove_property_fields:
cprops = CustomProperties(doc)
for name in cprops.keys():
cprops.dissolve_fields(name)
self._create_style_id_mapping(doc)
for element in doc.element.body:
if isinstance(element, CT_SectPr):
continue
element = deepcopy(element)
self.doc.element.body.insert(index, element)
self.add_referenced_parts(doc.part, self.doc.part, element)
self.add_styles(doc, element)
self.add_numberings(doc, element)
self.restart_first_numbering(doc, element)
self.add_images(doc, element)
self.add_shapes(doc, element)