204 lines
7.3 KiB
Python
204 lines
7.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
import unittest
|
|
from io import BytesIO
|
|
from docx import Document
|
|
|
|
from odoo.addons.survey_custom_certificate_template.services.certificate_template_parser import (
|
|
CertificateTemplateParser,
|
|
)
|
|
|
|
|
|
class TestCertificateTemplateParser(unittest.TestCase):
|
|
"""Test cases for CertificateTemplateParser service"""
|
|
|
|
def setUp(self):
|
|
"""Set up test fixtures"""
|
|
self.parser = CertificateTemplateParser()
|
|
|
|
def _create_test_docx(self, text_content):
|
|
"""
|
|
Helper method to create a DOCX file with given text content.
|
|
|
|
Args:
|
|
text_content: String or list of strings to add as paragraphs
|
|
|
|
Returns:
|
|
bytes: Binary content of the created DOCX file
|
|
"""
|
|
doc = Document()
|
|
|
|
if isinstance(text_content, str):
|
|
text_content = [text_content]
|
|
|
|
for text in text_content:
|
|
doc.add_paragraph(text)
|
|
|
|
# Save to BytesIO
|
|
doc_stream = BytesIO()
|
|
doc.save(doc_stream)
|
|
doc_stream.seek(0)
|
|
return doc_stream.read()
|
|
|
|
def test_get_placeholder_pattern(self):
|
|
"""Test that get_placeholder_pattern returns the correct regex pattern"""
|
|
pattern = self.parser.get_placeholder_pattern()
|
|
self.assertEqual(pattern, r'\{key\.[a-zA-Z0-9_]+\}')
|
|
|
|
def test_validate_template_valid_docx(self):
|
|
"""Test validation of a valid DOCX file"""
|
|
docx_binary = self._create_test_docx("Test content")
|
|
is_valid, error_msg = self.parser.validate_template(docx_binary)
|
|
|
|
self.assertTrue(is_valid)
|
|
self.assertEqual(error_msg, "")
|
|
|
|
def test_validate_template_empty_file(self):
|
|
"""Test validation of an empty file"""
|
|
is_valid, error_msg = self.parser.validate_template(b"")
|
|
|
|
self.assertFalse(is_valid)
|
|
self.assertEqual(error_msg, "Template file is empty")
|
|
|
|
def test_validate_template_invalid_type(self):
|
|
"""Test validation with non-binary input"""
|
|
is_valid, error_msg = self.parser.validate_template("not bytes")
|
|
|
|
self.assertFalse(is_valid)
|
|
self.assertEqual(error_msg, "Template must be provided as binary data")
|
|
|
|
def test_validate_template_corrupted_file(self):
|
|
"""Test validation of a corrupted DOCX file"""
|
|
corrupted_data = b"This is not a valid DOCX file"
|
|
is_valid, error_msg = self.parser.validate_template(corrupted_data)
|
|
|
|
self.assertFalse(is_valid)
|
|
self.assertIn("not a valid DOCX file", error_msg)
|
|
|
|
def test_parse_template_single_placeholder(self):
|
|
"""Test parsing a template with a single placeholder"""
|
|
docx_binary = self._create_test_docx("Hello {key.name}, welcome!")
|
|
placeholders = self.parser.parse_template(docx_binary)
|
|
|
|
self.assertEqual(placeholders, ["{key.name}"])
|
|
|
|
def test_parse_template_multiple_placeholders(self):
|
|
"""Test parsing a template with multiple placeholders"""
|
|
text = "Certificate for {key.name} who completed {key.course_name} on {key.date}"
|
|
docx_binary = self._create_test_docx(text)
|
|
placeholders = self.parser.parse_template(docx_binary)
|
|
|
|
expected = ["{key.course_name}", "{key.date}", "{key.name}"]
|
|
self.assertEqual(placeholders, expected)
|
|
|
|
def test_parse_template_no_placeholders(self):
|
|
"""Test parsing a template with no placeholders"""
|
|
docx_binary = self._create_test_docx("This is a static certificate")
|
|
placeholders = self.parser.parse_template(docx_binary)
|
|
|
|
self.assertEqual(placeholders, [])
|
|
|
|
def test_parse_template_duplicate_placeholders(self):
|
|
"""Test that duplicate placeholders are only returned once"""
|
|
text_content = [
|
|
"Hello {key.name}",
|
|
"Welcome {key.name}",
|
|
"Course: {key.course_name}"
|
|
]
|
|
docx_binary = self._create_test_docx(text_content)
|
|
placeholders = self.parser.parse_template(docx_binary)
|
|
|
|
expected = ["{key.course_name}", "{key.name}"]
|
|
self.assertEqual(placeholders, expected)
|
|
|
|
def test_parse_template_with_table(self):
|
|
"""Test parsing placeholders from tables"""
|
|
doc = Document()
|
|
doc.add_paragraph("Header text with {key.header}")
|
|
|
|
# Add a table with placeholders
|
|
table = doc.add_table(rows=2, cols=2)
|
|
table.cell(0, 0).text = "Name: {key.name}"
|
|
table.cell(0, 1).text = "Date: {key.date}"
|
|
table.cell(1, 0).text = "Course: {key.course_name}"
|
|
table.cell(1, 1).text = "Score: {key.score}"
|
|
|
|
# Save to bytes
|
|
doc_stream = BytesIO()
|
|
doc.save(doc_stream)
|
|
doc_stream.seek(0)
|
|
docx_binary = doc_stream.read()
|
|
|
|
placeholders = self.parser.parse_template(docx_binary)
|
|
|
|
expected = [
|
|
"{key.course_name}",
|
|
"{key.date}",
|
|
"{key.header}",
|
|
"{key.name}",
|
|
"{key.score}"
|
|
]
|
|
self.assertEqual(placeholders, expected)
|
|
|
|
def test_parse_template_invalid_placeholder_format(self):
|
|
"""Test that invalid placeholder formats are not extracted"""
|
|
text = "Valid: {key.name}, Invalid: {invalid}, {key}, {key.}"
|
|
docx_binary = self._create_test_docx(text)
|
|
placeholders = self.parser.parse_template(docx_binary)
|
|
|
|
# Only the valid placeholder should be extracted
|
|
self.assertEqual(placeholders, ["{key.name}"])
|
|
|
|
def test_parse_template_with_underscores_and_numbers(self):
|
|
"""Test placeholders with underscores and numbers in field names"""
|
|
text = "Fields: {key.field_1} and {key.field_name_2} and {key.field123}"
|
|
docx_binary = self._create_test_docx(text)
|
|
placeholders = self.parser.parse_template(docx_binary)
|
|
|
|
expected = ["{key.field123}", "{key.field_1}", "{key.field_name_2}"]
|
|
self.assertEqual(placeholders, expected)
|
|
|
|
def test_parse_template_raises_on_invalid_file(self):
|
|
"""Test that parse_template raises ValueError for invalid files"""
|
|
corrupted_data = b"This is not a valid DOCX file"
|
|
|
|
with self.assertRaises(ValueError) as context:
|
|
self.parser.parse_template(corrupted_data)
|
|
|
|
self.assertIn("not a valid DOCX file", str(context.exception))
|
|
|
|
def test_parse_template_with_headers_and_footers(self):
|
|
"""Test parsing placeholders from headers and footers"""
|
|
doc = Document()
|
|
|
|
# Add content to body
|
|
doc.add_paragraph("Body: {key.body_field}")
|
|
|
|
# Add header
|
|
section = doc.sections[0]
|
|
header = section.header
|
|
header.paragraphs[0].text = "Header: {key.header_field}"
|
|
|
|
# Add footer
|
|
footer = section.footer
|
|
footer.paragraphs[0].text = "Footer: {key.footer_field}"
|
|
|
|
# Save to bytes
|
|
doc_stream = BytesIO()
|
|
doc.save(doc_stream)
|
|
doc_stream.seek(0)
|
|
docx_binary = doc_stream.read()
|
|
|
|
placeholders = self.parser.parse_template(docx_binary)
|
|
|
|
expected = [
|
|
"{key.body_field}",
|
|
"{key.footer_field}",
|
|
"{key.header_field}"
|
|
]
|
|
self.assertEqual(placeholders, expected)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|