# -*- coding: utf-8 -*- import json import base64 from unittest.mock import patch, MagicMock from odoo.tests.common import TransactionCase class TestSurveyCompletion(TransactionCase): """Test certificate generation on survey completion.""" def setUp(self): super(TestSurveyCompletion, self).setUp() # Create a test survey self.survey = self.env['survey.survey'].create({ 'title': 'Test Survey for Certificate', 'certification': True, 'has_custom_certificate': True, }) # Create a test partner self.partner = self.env['res.partner'].create({ 'name': 'Test Participant', 'email': 'test@example.com', }) # Create a test user input self.user_input = self.env['survey.user_input'].create({ 'survey_id': self.survey.id, 'partner_id': self.partner.id, 'email': 'test@example.com', 'state': 'in_progress', }) # Mock template and mappings self.mock_template = b'mock_docx_content' self.mock_mappings = { 'placeholders': [ { 'key': '{key.name}', 'value_type': 'user_field', 'value_field': 'partner_name' } ] } self.survey.write({ 'custom_cert_template': base64.b64encode(self.mock_template), 'custom_cert_mappings': json.dumps(self.mock_mappings), }) def test_certificate_generation_on_completion(self): """Test that certificate is generated when survey is completed.""" mock_pdf = b'mock_pdf_content' # Mock the certificate generation with patch.object( type(self.survey), '_generate_custom_certificate', return_value=mock_pdf ) as mock_generate: # Mark the survey as done self.user_input._mark_done() # Verify certificate generation was called mock_generate.assert_called_once_with(self.user_input.id) # Verify attachment was created attachments = self.env['ir.attachment'].search([ ('res_model', '=', 'survey.user_input'), ('res_id', '=', self.user_input.id), ]) self.assertEqual(len(attachments), 1, "Should create one attachment") self.assertEqual( attachments[0].mimetype, 'application/pdf', "Attachment should be PDF" ) self.assertEqual( base64.b64decode(attachments[0].datas), mock_pdf, "Attachment should contain the generated PDF" ) def test_no_certificate_when_not_configured(self): """Test that no certificate is generated when not configured.""" # Disable custom certificate self.survey.write({ 'has_custom_certificate': False, }) # Mark the survey as done self.user_input._mark_done() # Verify no attachment was created attachments = self.env['ir.attachment'].search([ ('res_model', '=', 'survey.user_input'), ('res_id', '=', self.user_input.id), ]) self.assertEqual(len(attachments), 0, "Should not create attachment") def test_no_certificate_when_certification_disabled(self): """Test that no certificate is generated when certification is disabled.""" # Disable certification self.survey.write({ 'certification': False, }) # Mark the survey as done self.user_input._mark_done() # Verify no attachment was created attachments = self.env['ir.attachment'].search([ ('res_model', '=', 'survey.user_input'), ('res_id', '=', self.user_input.id), ]) self.assertEqual(len(attachments), 0, "Should not create attachment") def test_certificate_storage_with_proper_filename(self): """Test that certificate is stored with a proper filename.""" mock_pdf = b'mock_pdf_content' # Mock the certificate generation with patch.object( type(self.survey), '_generate_custom_certificate', return_value=mock_pdf ): # Mark the survey as done self.user_input._mark_done() # Verify attachment filename attachments = self.env['ir.attachment'].search([ ('res_model', '=', 'survey.user_input'), ('res_id', '=', self.user_input.id), ]) self.assertEqual(len(attachments), 1) self.assertIn('Certificate', attachments[0].name) self.assertIn('Test Survey for Certificate', attachments[0].name) self.assertIn('Test Participant', attachments[0].name) self.assertTrue(attachments[0].name.endswith('.pdf')) def test_error_handling_during_generation(self): """Test that errors during generation don't break survey completion.""" # Mock the certificate generation to raise an error with patch.object( type(self.survey), '_generate_custom_certificate', side_effect=Exception('Test error') ): # Mark the survey as done - should not raise exception try: self.user_input._mark_done() except Exception as e: self.fail(f"Survey completion should not fail: {e}") # Verify no attachment was created attachments = self.env['ir.attachment'].search([ ('res_model', '=', 'survey.user_input'), ('res_id', '=', self.user_input.id), ]) self.assertEqual(len(attachments), 0, "Should not create attachment on error") def test_attachment_linked_to_user_input(self): """Test that attachment is properly linked to user_input.""" mock_pdf = b'mock_pdf_content' # Mock the certificate generation with patch.object( type(self.survey), '_generate_custom_certificate', return_value=mock_pdf ): # Mark the survey as done self.user_input._mark_done() # Verify attachment is linked correctly attachments = self.env['ir.attachment'].search([ ('res_model', '=', 'survey.user_input'), ('res_id', '=', self.user_input.id), ]) self.assertEqual(len(attachments), 1) self.assertEqual(attachments[0].res_model, 'survey.user_input') self.assertEqual(attachments[0].res_id, self.user_input.id)