survey_custom_certificate_t.../tests/test_certificate_template_parser.py
2025-11-29 08:46:04 +07:00

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()