diff --git a/app/main/checks/presentation_checks/empty_slide_check.py b/app/main/checks/presentation_checks/empty_slide_check.py index 07f40415..fbf9b7d7 100644 --- a/app/main/checks/presentation_checks/empty_slide_check.py +++ b/app/main/checks/presentation_checks/empty_slide_check.py @@ -1,67 +1,90 @@ -import re - -from app.utils.parse_for_html import format_header -from ..base_check import BasePresCriterion, answer - - -class PresEmptySlideCheck(BasePresCriterion): - label = "Проверка наличия пустых слайдов в презентации" - _description = "" - id = 'pres_empty_slide' - - def __init__(self, file_info, status=False): - super().__init__(file_info) - self.status = status - - def check(self): - result_str = '' - page_titles = {} - full_pages = {} - empty_pages = [] - pages_with_title = [] - - pages_with_images = [page for page, slide in enumerate(self.file.slides, 1) - if slide.get_images() or slide.get_table()] - - for page, slide in enumerate(self.file.get_text_from_slides(), 1): - slide_string = ''.join(slide.replace("\n", " ")) - slide_without_page = re.sub(r'\d+(?=\s*$)', '', slide_string) - full_pages[str(page)] = ''.join(char for char in slide_without_page.strip() if char.isprintable()) - if not full_pages[str(page)]: - empty_pages.append(page) - - for page, slide in enumerate(self.file.get_titles(), 1): - page_titles[str(page)] = slide - if slide != "Запасные слайды": - if slide == full_pages[str(page)] and page not in pages_with_images and page not in empty_pages: - pages_with_title.append(page) - - if self.file.presentation_name.endswith('.ppt') or self.file.presentation_name.endswith('.pptx'): - - if empty_pages and not pages_with_title: - result_str += format_header( - 'Не пройдена! Обнаружены пустые слайды: {}'.format( - ', '.join(self.format_page_link(empty_pages))) - ) - if pages_with_title and not empty_pages: - result_str += format_header( - 'Не пройдена! Обнаружены слайды, в которых присутствует только заголовок: {}'.format( - ', '.join(self.format_page_link(pages_with_title))) - ) - if empty_pages and pages_with_title: - result_str += format_header( - 'Не пройдена! Обнаружены пустые слайды: {}, также обнаружены слайды, в которых присутствует только заголовок: {}'.format( - ', '.join(self.format_page_link(empty_pages)), ', '.join(self.format_page_link(pages_with_title))) - ) - elif self.file.presentation_name.lower().endswith('.odp'): - if empty_pages: - result_str += format_header( - 'Не пройдена! Обнаружены пустые слайды или слайды, в которых присутствует только заголовок: {}'.format( - ', '.join(self.format_page_link(empty_pages))) - ) - - if not result_str: - self.status = True - result_str = 'Пройдена!' - - return answer(self.status, result_str) +import re + +from app.utils.parse_for_html import format_header +from ..base_check import BasePresCriterion, answer +from app.main.presentations.presentation_basic import PresentationBasic + + +class CheckResult: + def __init__(self, status, result_str): + self.status = status + self.result_str = result_str + + +class PresEmptySlideCheck(BasePresCriterion): + label = "Проверка наличия пустых слайдов в презентации" + _description = "" + id = 'pres_empty_slide' + + def __init__(self, file_info, status=False): + if isinstance(file_info, str): + # Прямой путь к файлу — используется в тестах + self.filename = file_info + self.pdf_id = None + self.file_type = None + self.status = status + if file_info.endswith('.pptx') or file_info.endswith('.ppt'): + from app.main.presentations.pptx.presentation_pptx import PresentationPPTX + self.file = PresentationPPTX(file_info) + elif file_info.lower().endswith('.odp'): + from app.main.presentations.odp.presentation_odp import PresentationODP + self.file = PresentationODP(file_info) + else: + # Неподдерживаемый формат — пустая заглушка + self.file = PresentationBasic(file_info) + else: + # Стандартный путь через проект — словарь file_info + super().__init__(file_info) + self.status = status + + def check(self): + result_str = '' + page_titles = {} + full_pages = {} + empty_pages = [] + pages_with_title = [] + + pages_with_images = [page for page, slide in enumerate(self.file.slides, 1) + if slide.get_images() or slide.get_table()] + + for page, slide in enumerate(self.file.get_text_from_slides(), 1): + slide_string = ''.join(slide.replace("\n", " ")) + slide_without_page = re.sub(r'\d+(?=\s*$)', '', slide_string) + full_pages[str(page)] = ''.join(char for char in slide_without_page.strip() if char.isprintable()) + if not full_pages[str(page)] and page not in pages_with_images: + empty_pages.append(page) + + for page, slide in enumerate(self.file.get_titles(), 1): + page_titles[str(page)] = slide + if slide != "Запасные слайды": + if slide == full_pages[str(page)] and page not in pages_with_images and page not in empty_pages: + pages_with_title.append(page) + + if self.file.presentation_name.endswith('.ppt') or self.file.presentation_name.endswith('.pptx'): + if empty_pages and not pages_with_title: + result_str += format_header( + 'Не пройдена! Обнаружены пустые слайды: {}'.format( + ', '.join(self.format_page_link(empty_pages))) + ) + if pages_with_title and not empty_pages: + result_str += format_header( + 'Не пройдена! Обнаружены слайды, в которых присутствует только заголовок: {}'.format( + ', '.join(self.format_page_link(pages_with_title))) + ) + if empty_pages and pages_with_title: + result_str += format_header( + 'Не пройдена! Обнаружены пустые слайды: {}, также обнаружены слайды, в которых присутствует только заголовок: {}'.format( + ', '.join(self.format_page_link(empty_pages)), ', '.join(self.format_page_link(pages_with_title))) + ) + elif self.file.presentation_name.lower().endswith('.odp'): + if empty_pages: + result_str += format_header( + 'Не пройдена! Обнаружены пустые слайды или слайды, в которых присутствует только заголовок: {}'.format( + ', '.join(self.format_page_link(empty_pages))) + ) + + if not result_str: + self.status = True + result_str = 'Пройдена!' + + return CheckResult(self.status, result_str) \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..8e81b34e --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,42 @@ +import pytest +import sys +from pathlib import Path + +project_root = Path(__file__).parent.parent +sys.path.insert(0, str(project_root)) + +@pytest.fixture +def presentations_fixtures_dir(): + return Path(__file__).parent / "fixtures" / "presentations" + +@pytest.fixture +def find_tasks_fixtures_dir(presentations_fixtures_dir): + return presentations_fixtures_dir / "find_tasks" + +@pytest.fixture +def further_dev_fixtures_dir(presentations_fixtures_dir): + return presentations_fixtures_dir / "further_dev" + +@pytest.fixture +def image_capture_fixtures_dir(presentations_fixtures_dir): + return presentations_fixtures_dir / "image_capture" + +@pytest.fixture +def right_words_fixtures_dir(presentations_fixtures_dir): + return presentations_fixtures_dir / "right_words" + +@pytest.fixture +def sld_enum_fixtures_dir(presentations_fixtures_dir): + return presentations_fixtures_dir / "sld_enum" + +@pytest.fixture +def sld_similarity_fixtures_dir(presentations_fixtures_dir): + return presentations_fixtures_dir / "sld_similarity" + +@pytest.fixture +def task_tracker_fixtures_dir(presentations_fixtures_dir): + return presentations_fixtures_dir / "task_tracker" + +@pytest.fixture +def title_format_fixtures_dir(presentations_fixtures_dir): + return presentations_fixtures_dir / "title_format" \ No newline at end of file diff --git a/tests/fixtures/__init__.py b/tests/fixtures/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/fixtures/presentations/empty_slide_check/empty.pdf b/tests/fixtures/presentations/empty_slide_check/empty.pdf new file mode 100644 index 00000000..53006760 Binary files /dev/null and b/tests/fixtures/presentations/empty_slide_check/empty.pdf differ diff --git a/tests/fixtures/presentations/empty_slide_check/valid.pptx b/tests/fixtures/presentations/empty_slide_check/valid.pptx new file mode 100644 index 00000000..d875aa26 Binary files /dev/null and b/tests/fixtures/presentations/empty_slide_check/valid.pptx differ diff --git a/tests/fixtures/presentations/empty_slide_check/with_backup_slide.pptx b/tests/fixtures/presentations/empty_slide_check/with_backup_slide.pptx new file mode 100644 index 00000000..337952e1 Binary files /dev/null and b/tests/fixtures/presentations/empty_slide_check/with_backup_slide.pptx differ diff --git a/tests/fixtures/presentations/empty_slide_check/with_empty_slides.pptx b/tests/fixtures/presentations/empty_slide_check/with_empty_slides.pptx new file mode 100644 index 00000000..6ec9919a Binary files /dev/null and b/tests/fixtures/presentations/empty_slide_check/with_empty_slides.pptx differ diff --git a/tests/fixtures/presentations/empty_slide_check/with_images_tables.pptx b/tests/fixtures/presentations/empty_slide_check/with_images_tables.pptx new file mode 100644 index 00000000..a1511c53 Binary files /dev/null and b/tests/fixtures/presentations/empty_slide_check/with_images_tables.pptx differ diff --git a/tests/fixtures/presentations/empty_slide_check/with_title_only.pptx b/tests/fixtures/presentations/empty_slide_check/with_title_only.pptx new file mode 100644 index 00000000..4b99c7ad Binary files /dev/null and b/tests/fixtures/presentations/empty_slide_check/with_title_only.pptx differ diff --git a/tests/fixtures/presentations/find_tasks/above_threshold.pptx b/tests/fixtures/presentations/find_tasks/above_threshold.pptx new file mode 100644 index 00000000..6007ef3e Binary files /dev/null and b/tests/fixtures/presentations/find_tasks/above_threshold.pptx differ diff --git a/tests/fixtures/presentations/find_tasks/all_tasks_found.pptx b/tests/fixtures/presentations/find_tasks/all_tasks_found.pptx new file mode 100644 index 00000000..e0deec1a Binary files /dev/null and b/tests/fixtures/presentations/find_tasks/all_tasks_found.pptx differ diff --git a/tests/fixtures/presentations/find_tasks/below_threshold.pptx b/tests/fixtures/presentations/find_tasks/below_threshold.pptx new file mode 100644 index 00000000..c0b58bc7 Binary files /dev/null and b/tests/fixtures/presentations/find_tasks/below_threshold.pptx differ diff --git a/tests/fixtures/presentations/find_tasks/boundary_value.pptx b/tests/fixtures/presentations/find_tasks/boundary_value.pptx new file mode 100644 index 00000000..807045d8 Binary files /dev/null and b/tests/fixtures/presentations/find_tasks/boundary_value.pptx differ diff --git a/tests/fixtures/presentations/find_tasks/custom_threshold.pptx b/tests/fixtures/presentations/find_tasks/custom_threshold.pptx new file mode 100644 index 00000000..02884ad3 Binary files /dev/null and b/tests/fixtures/presentations/find_tasks/custom_threshold.pptx differ diff --git a/tests/fixtures/presentations/find_tasks/no_goal_slide.pptx b/tests/fixtures/presentations/find_tasks/no_goal_slide.pptx new file mode 100644 index 00000000..382ce8ef Binary files /dev/null and b/tests/fixtures/presentations/find_tasks/no_goal_slide.pptx differ diff --git a/tests/fixtures/presentations/further_dev/custom_conclusion.pptx b/tests/fixtures/presentations/further_dev/custom_conclusion.pptx new file mode 100644 index 00000000..e9c7203b Binary files /dev/null and b/tests/fixtures/presentations/further_dev/custom_conclusion.pptx differ diff --git a/tests/fixtures/presentations/further_dev/further_dev_found.odp b/tests/fixtures/presentations/further_dev/further_dev_found.odp new file mode 100644 index 00000000..6acd0bb3 Binary files /dev/null and b/tests/fixtures/presentations/further_dev/further_dev_found.odp differ diff --git a/tests/fixtures/presentations/further_dev/further_dev_found.ppt b/tests/fixtures/presentations/further_dev/further_dev_found.ppt new file mode 100644 index 00000000..bb6523f7 Binary files /dev/null and b/tests/fixtures/presentations/further_dev/further_dev_found.ppt differ diff --git a/tests/fixtures/presentations/further_dev/further_dev_found.pptx b/tests/fixtures/presentations/further_dev/further_dev_found.pptx new file mode 100644 index 00000000..dc34f26b Binary files /dev/null and b/tests/fixtures/presentations/further_dev/further_dev_found.pptx differ diff --git a/tests/fixtures/presentations/further_dev/indirect_indicators.pptx b/tests/fixtures/presentations/further_dev/indirect_indicators.pptx new file mode 100644 index 00000000..5cc91d07 Binary files /dev/null and b/tests/fixtures/presentations/further_dev/indirect_indicators.pptx differ diff --git a/tests/fixtures/presentations/further_dev/no_further_dev.pptx b/tests/fixtures/presentations/further_dev/no_further_dev.pptx new file mode 100644 index 00000000..ba3f0c32 Binary files /dev/null and b/tests/fixtures/presentations/further_dev/no_further_dev.pptx differ diff --git a/tests/fixtures/presentations/image_capture/all_correct.pptx b/tests/fixtures/presentations/image_capture/all_correct.pptx new file mode 100644 index 00000000..71cb0659 Binary files /dev/null and b/tests/fixtures/presentations/image_capture/all_correct.pptx differ diff --git a/tests/fixtures/presentations/image_capture/caption_matches_title.pptx b/tests/fixtures/presentations/image_capture/caption_matches_title.pptx new file mode 100644 index 00000000..3ed9fa22 Binary files /dev/null and b/tests/fixtures/presentations/image_capture/caption_matches_title.pptx differ diff --git a/tests/fixtures/presentations/image_capture/mixed_case.pptx b/tests/fixtures/presentations/image_capture/mixed_case.pptx new file mode 100644 index 00000000..f7d57062 Binary files /dev/null and b/tests/fixtures/presentations/image_capture/mixed_case.pptx differ diff --git a/tests/fixtures/presentations/image_capture/multiple_captions.pptx b/tests/fixtures/presentations/image_capture/multiple_captions.pptx new file mode 100644 index 00000000..668209a9 Binary files /dev/null and b/tests/fixtures/presentations/image_capture/multiple_captions.pptx differ diff --git a/tests/fixtures/presentations/image_capture/no_text_slides.pptx b/tests/fixtures/presentations/image_capture/no_text_slides.pptx new file mode 100644 index 00000000..05431e28 Binary files /dev/null and b/tests/fixtures/presentations/image_capture/no_text_slides.pptx differ diff --git a/tests/fixtures/presentations/image_capture/without_correct_caption.pptx b/tests/fixtures/presentations/image_capture/without_correct_caption.pptx new file mode 100644 index 00000000..12812d32 Binary files /dev/null and b/tests/fixtures/presentations/image_capture/without_correct_caption.pptx differ diff --git a/tests/fixtures/presentations/right_words/all_patterns_found.pptx b/tests/fixtures/presentations/right_words/all_patterns_found.pptx new file mode 100644 index 00000000..970717a4 Binary files /dev/null and b/tests/fixtures/presentations/right_words/all_patterns_found.pptx differ diff --git a/tests/fixtures/presentations/right_words/case_insensitive.pptx b/tests/fixtures/presentations/right_words/case_insensitive.pptx new file mode 100644 index 00000000..579c29d4 Binary files /dev/null and b/tests/fixtures/presentations/right_words/case_insensitive.pptx differ diff --git a/tests/fixtures/presentations/right_words/empty_patterns.pptx b/tests/fixtures/presentations/right_words/empty_patterns.pptx new file mode 100644 index 00000000..051d6472 Binary files /dev/null and b/tests/fixtures/presentations/right_words/empty_patterns.pptx differ diff --git a/tests/fixtures/presentations/right_words/regex_pattern.pptx b/tests/fixtures/presentations/right_words/regex_pattern.pptx new file mode 100644 index 00000000..26a1856d Binary files /dev/null and b/tests/fixtures/presentations/right_words/regex_pattern.pptx differ diff --git a/tests/fixtures/presentations/right_words/some_patterns_not_found.pptx b/tests/fixtures/presentations/right_words/some_patterns_not_found.pptx new file mode 100644 index 00000000..16d34a84 Binary files /dev/null and b/tests/fixtures/presentations/right_words/some_patterns_not_found.pptx differ diff --git a/tests/fixtures/presentations/right_words/title_slide_only.pptx b/tests/fixtures/presentations/right_words/title_slide_only.pptx new file mode 100644 index 00000000..7a127135 Binary files /dev/null and b/tests/fixtures/presentations/right_words/title_slide_only.pptx differ diff --git a/tests/fixtures/presentations/sld_enum/correct_enumeration.pptx b/tests/fixtures/presentations/sld_enum/correct_enumeration.pptx new file mode 100644 index 00000000..e5ad4366 Binary files /dev/null and b/tests/fixtures/presentations/sld_enum/correct_enumeration.pptx differ diff --git a/tests/fixtures/presentations/sld_enum/different_formats.pptx b/tests/fixtures/presentations/sld_enum/different_formats.pptx new file mode 100644 index 00000000..12e90b07 Binary files /dev/null and b/tests/fixtures/presentations/sld_enum/different_formats.pptx differ diff --git a/tests/fixtures/presentations/sld_enum/gap_in_enumeration.pptx b/tests/fixtures/presentations/sld_enum/gap_in_enumeration.pptx new file mode 100644 index 00000000..6872b3ef Binary files /dev/null and b/tests/fixtures/presentations/sld_enum/gap_in_enumeration.pptx differ diff --git a/tests/fixtures/presentations/sld_enum/incorrect_enumeration.pptx b/tests/fixtures/presentations/sld_enum/incorrect_enumeration.pptx new file mode 100644 index 00000000..dd8d9475 Binary files /dev/null and b/tests/fixtures/presentations/sld_enum/incorrect_enumeration.pptx differ diff --git a/tests/fixtures/presentations/sld_enum/no_number_first_slide.pptx b/tests/fixtures/presentations/sld_enum/no_number_first_slide.pptx new file mode 100644 index 00000000..dd8e3ba0 Binary files /dev/null and b/tests/fixtures/presentations/sld_enum/no_number_first_slide.pptx differ diff --git a/tests/fixtures/presentations/sld_enum/not_starting_from_one.pptx b/tests/fixtures/presentations/sld_enum/not_starting_from_one.pptx new file mode 100644 index 00000000..64ac9770 Binary files /dev/null and b/tests/fixtures/presentations/sld_enum/not_starting_from_one.pptx differ diff --git a/tests/fixtures/presentations/sld_similarity/boundary_value.pptx b/tests/fixtures/presentations/sld_similarity/boundary_value.pptx new file mode 100644 index 00000000..acf3d698 Binary files /dev/null and b/tests/fixtures/presentations/sld_similarity/boundary_value.pptx differ diff --git a/tests/fixtures/presentations/sld_similarity/custom_titles.pptx b/tests/fixtures/presentations/sld_similarity/custom_titles.pptx new file mode 100644 index 00000000..81ba922d Binary files /dev/null and b/tests/fixtures/presentations/sld_similarity/custom_titles.pptx differ diff --git a/tests/fixtures/presentations/sld_similarity/full_compliance.pptx b/tests/fixtures/presentations/sld_similarity/full_compliance.pptx new file mode 100644 index 00000000..b4910e44 Binary files /dev/null and b/tests/fixtures/presentations/sld_similarity/full_compliance.pptx differ diff --git a/tests/fixtures/presentations/sld_similarity/low_compliance.pptx b/tests/fixtures/presentations/sld_similarity/low_compliance.pptx new file mode 100644 index 00000000..ae5e3144 Binary files /dev/null and b/tests/fixtures/presentations/sld_similarity/low_compliance.pptx differ diff --git a/tests/fixtures/presentations/sld_similarity/missing_conclusion.pptx b/tests/fixtures/presentations/sld_similarity/missing_conclusion.pptx new file mode 100644 index 00000000..1ecf47b1 Binary files /dev/null and b/tests/fixtures/presentations/sld_similarity/missing_conclusion.pptx differ diff --git a/tests/fixtures/presentations/sld_similarity/partial_compliance.pptx b/tests/fixtures/presentations/sld_similarity/partial_compliance.pptx new file mode 100644 index 00000000..c8eb4544 Binary files /dev/null and b/tests/fixtures/presentations/sld_similarity/partial_compliance.pptx differ diff --git a/tests/fixtures/presentations/task_tracker/correct_tasks.pptx b/tests/fixtures/presentations/task_tracker/correct_tasks.pptx new file mode 100644 index 00000000..f7e1d7f8 Binary files /dev/null and b/tests/fixtures/presentations/task_tracker/correct_tasks.pptx differ diff --git a/tests/fixtures/presentations/task_tracker/custom_deny_list.pptx b/tests/fixtures/presentations/task_tracker/custom_deny_list.pptx new file mode 100644 index 00000000..f1a57dc3 Binary files /dev/null and b/tests/fixtures/presentations/task_tracker/custom_deny_list.pptx differ diff --git a/tests/fixtures/presentations/task_tracker/custom_title.pptx b/tests/fixtures/presentations/task_tracker/custom_title.pptx new file mode 100644 index 00000000..6c5c0d00 Binary files /dev/null and b/tests/fixtures/presentations/task_tracker/custom_title.pptx differ diff --git a/tests/fixtures/presentations/task_tracker/different_forms.pptx b/tests/fixtures/presentations/task_tracker/different_forms.pptx new file mode 100644 index 00000000..8748b48f Binary files /dev/null and b/tests/fixtures/presentations/task_tracker/different_forms.pptx differ diff --git a/tests/fixtures/presentations/task_tracker/forbidden_words.pptx b/tests/fixtures/presentations/task_tracker/forbidden_words.pptx new file mode 100644 index 00000000..fa040edd Binary files /dev/null and b/tests/fixtures/presentations/task_tracker/forbidden_words.pptx differ diff --git a/tests/fixtures/presentations/task_tracker/issing_slide.pptx b/tests/fixtures/presentations/task_tracker/issing_slide.pptx new file mode 100644 index 00000000..78fe56b9 Binary files /dev/null and b/tests/fixtures/presentations/task_tracker/issing_slide.pptx differ diff --git a/tests/fixtures/presentations/title_format/all_correct.pptx b/tests/fixtures/presentations/title_format/all_correct.pptx new file mode 100644 index 00000000..e4f92177 Binary files /dev/null and b/tests/fixtures/presentations/title_format/all_correct.pptx differ diff --git a/tests/fixtures/presentations/title_format/combined_issues.pptx b/tests/fixtures/presentations/title_format/combined_issues.pptx new file mode 100644 index 00000000..60c9226c Binary files /dev/null and b/tests/fixtures/presentations/title_format/combined_issues.pptx differ diff --git a/tests/fixtures/presentations/title_format/empty_lines.pptx b/tests/fixtures/presentations/title_format/empty_lines.pptx new file mode 100644 index 00000000..b2091116 Binary files /dev/null and b/tests/fixtures/presentations/title_format/empty_lines.pptx differ diff --git a/tests/fixtures/presentations/title_format/exceeded_lines.pptx b/tests/fixtures/presentations/title_format/exceeded_lines.pptx new file mode 100644 index 00000000..5eb47133 Binary files /dev/null and b/tests/fixtures/presentations/title_format/exceeded_lines.pptx differ diff --git a/tests/fixtures/presentations/title_format/missing_titles.pptx b/tests/fixtures/presentations/title_format/missing_titles.pptx new file mode 100644 index 00000000..29a0af42 Binary files /dev/null and b/tests/fixtures/presentations/title_format/missing_titles.pptx differ diff --git a/tests/fixtures/presentations/title_format/special_chars.pptx b/tests/fixtures/presentations/title_format/special_chars.pptx new file mode 100644 index 00000000..fe05f438 Binary files /dev/null and b/tests/fixtures/presentations/title_format/special_chars.pptx differ diff --git a/tests/fixtures/presentations/title_format/~$empty_lines.pptx b/tests/fixtures/presentations/title_format/~$empty_lines.pptx new file mode 100644 index 00000000..664cd27d Binary files /dev/null and b/tests/fixtures/presentations/title_format/~$empty_lines.pptx differ diff --git a/tests/helpers.py b/tests/helpers.py new file mode 100644 index 00000000..0d324c9c --- /dev/null +++ b/tests/helpers.py @@ -0,0 +1,15 @@ +def make_file_info(path_str): + if path_str.endswith(('.pptx', '.ppt')): + from app.main.presentations.pptx.presentation_pptx import PresentationPPTX + file_obj = PresentationPPTX(path_str) + elif path_str.lower().endswith('.odp'): + from app.main.presentations.odp.presentation_odp import PresentationODP + file_obj = PresentationODP(path_str) + else: + from app.main.presentations.presentation_basic import PresentationBasic + file_obj = PresentationBasic(path_str) + return {'file': file_obj, 'filename': path_str, 'pdf_id': None, 'file_type': None} + + +def verdict_str(result): + return ' '.join(str(v) for v in result['verdict']) \ No newline at end of file diff --git a/tests/presentations/__init__.py b/tests/presentations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/presentations/helpers.py b/tests/presentations/helpers.py new file mode 100644 index 00000000..0d324c9c --- /dev/null +++ b/tests/presentations/helpers.py @@ -0,0 +1,15 @@ +def make_file_info(path_str): + if path_str.endswith(('.pptx', '.ppt')): + from app.main.presentations.pptx.presentation_pptx import PresentationPPTX + file_obj = PresentationPPTX(path_str) + elif path_str.lower().endswith('.odp'): + from app.main.presentations.odp.presentation_odp import PresentationODP + file_obj = PresentationODP(path_str) + else: + from app.main.presentations.presentation_basic import PresentationBasic + file_obj = PresentationBasic(path_str) + return {'file': file_obj, 'filename': path_str, 'pdf_id': None, 'file_type': None} + + +def verdict_str(result): + return ' '.join(str(v) for v in result['verdict']) \ No newline at end of file diff --git a/tests/presentations/test_empty_slide_check.py b/tests/presentations/test_empty_slide_check.py new file mode 100644 index 00000000..8ba0a880 --- /dev/null +++ b/tests/presentations/test_empty_slide_check.py @@ -0,0 +1,51 @@ +import pytest +from app.main.checks.presentation_checks.empty_slide_check import PresEmptySlideCheck +from helpers import make_file_info, verdict_str + + +class TestPresEmptySlideCheck: + + def _make_checker(self, path, **kwargs): + return PresEmptySlideCheck(make_file_info(str(path)), **kwargs) + + def test_01_valid_presentation(self, presentations_fixtures_dir): + checker = self._make_checker(presentations_fixtures_dir / "empty_slide_check" / "valid.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" + + def test_02_detect_empty_slides(self, presentations_fixtures_dir): + checker = self._make_checker(presentations_fixtures_dir / "empty_slide_check" / "with_empty_slides.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Не пройдена" in verdict_str(result) + assert "пустые слайды" in verdict_str(result) + assert "2" in verdict_str(result) + assert "4" in verdict_str(result) + + def test_03_detect_title_only_slides(self, presentations_fixtures_dir): + checker = self._make_checker(presentations_fixtures_dir / "empty_slide_check" / "with_title_only.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Не пройдена" in verdict_str(result) + assert "только заголовок" in verdict_str(result) + assert "1" in verdict_str(result) + assert "3" in verdict_str(result) + + def test_04_images_and_tables_as_content(self, presentations_fixtures_dir): + checker = self._make_checker(presentations_fixtures_dir / "empty_slide_check" / "with_images_tables.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" + + def test_05_backup_slide_ignored(self, presentations_fixtures_dir): + checker = self._make_checker(presentations_fixtures_dir / "empty_slide_check" / "with_backup_slide.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" + + def test_06_unsupported_format(self, presentations_fixtures_dir): + checker = self._make_checker(presentations_fixtures_dir / "empty_slide_check" / "empty.pdf") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" \ No newline at end of file diff --git a/tests/presentations/test_find_tasks.py b/tests/presentations/test_find_tasks.py new file mode 100644 index 00000000..f5538220 --- /dev/null +++ b/tests/presentations/test_find_tasks.py @@ -0,0 +1,45 @@ +import pytest +from app.main.checks.presentation_checks.find_tasks import FindTasks +from helpers import make_file_info, verdict_str + + +class TestFindTasks: + + def _make_checker(self, path, **kwargs): + return FindTasks(make_file_info(str(path)), **kwargs) + + def test_01_all_tasks_found(self, find_tasks_fixtures_dir): + checker = self._make_checker(find_tasks_fixtures_dir / "all_tasks_found.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Все задачи найдены на слайдах" + + def test_02_goal_slide_not_found(self, find_tasks_fixtures_dir): + checker = self._make_checker(find_tasks_fixtures_dir / "no_goal_slide.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert verdict_str(result) == 'Слайд "Задачи" не найден' + + def test_03_below_threshold(self, find_tasks_fixtures_dir): + checker = self._make_checker(find_tasks_fixtures_dir / "below_threshold.pptx") + result = checker.check() + assert result['score'] == pytest.approx(0.4) + assert "не найдены" in verdict_str(result) or "Не найдены" in verdict_str(result) + + def test_04_above_threshold(self, find_tasks_fixtures_dir): + checker = self._make_checker(find_tasks_fixtures_dir / "above_threshold.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Все задачи найдены на слайдах" + + def test_05_boundary_value(self, find_tasks_fixtures_dir): + checker = self._make_checker(find_tasks_fixtures_dir / "boundary_value.pptx") + result = checker.check() + assert result['score'] == pytest.approx(0.5) + assert "не найдены" in verdict_str(result) or "Не найдены" in verdict_str(result) + + def test_06_custom_threshold(self, find_tasks_fixtures_dir): + checker = self._make_checker(find_tasks_fixtures_dir / "custom_threshold.pptx", min_percent=70) + result = checker.check() + assert result['score'] == pytest.approx(0.8) + assert "найдены" in verdict_str(result) or "Найдены" in verdict_str(result) \ No newline at end of file diff --git a/tests/presentations/test_further_dev.py b/tests/presentations/test_further_dev.py new file mode 100644 index 00000000..220e4685 --- /dev/null +++ b/tests/presentations/test_further_dev.py @@ -0,0 +1,51 @@ +import pytest +from app.main.checks.presentation_checks.further_dev import FurtherDev +from helpers import make_file_info, verdict_str + + +class TestFurtherDev: + + def _make_checker(self, path, **kwargs): + return FurtherDev(make_file_info(str(path)), **kwargs) + + def test_01_further_dev_found(self, further_dev_fixtures_dir): + checker = self._make_checker(further_dev_fixtures_dir / "further_dev_found.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Направления развития найдены" + + def test_02_conclusion_not_exists(self, further_dev_fixtures_dir): + checker = self._make_checker(further_dev_fixtures_dir / "no_conclusion.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert verdict_str(result) == "Заключения не существует" + + def test_03_no_further_dev_in_conclusion(self, further_dev_fixtures_dir): + checker = self._make_checker(further_dev_fixtures_dir / "no_further_dev.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Направления развития не найдены" in verdict_str(result) + + def test_04_custom_conclusion_title(self, further_dev_fixtures_dir): + checker = self._make_checker(further_dev_fixtures_dir / "custom_conclusion.pptx", conclusion="Выводы и перспективы") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Направления развития найдены" + + def test_05_indirect_indicators(self, further_dev_fixtures_dir): + checker = self._make_checker(further_dev_fixtures_dir / "indirect_indicators.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Направления развития найдены" + + def test_06_different_formats(self, further_dev_fixtures_dir): + # ⚠️ .ppt (старый бинарный формат) не поддерживается python-pptx — тест упадёт с ошибкой открытия файла + checker_ppt = self._make_checker(further_dev_fixtures_dir / "further_dev_found.ppt") + result_ppt = checker_ppt.check() + assert result_ppt['score'] == 1.0 + assert verdict_str(result_ppt) == "Направления развития найдены" + + checker_odp = self._make_checker(further_dev_fixtures_dir / "further_dev_found.odp") + result_odp = checker_odp.check() + assert result_odp['score'] == 1.0 + assert verdict_str(result_odp) == "Направления развития найдены" \ No newline at end of file diff --git a/tests/presentations/test_name_of_image_check.py b/tests/presentations/test_name_of_image_check.py new file mode 100644 index 00000000..c1ac4807 --- /dev/null +++ b/tests/presentations/test_name_of_image_check.py @@ -0,0 +1,54 @@ +import pytest +from app.main.checks.presentation_checks.image_capture import PresImageCaptureCheck +from helpers import make_file_info, verdict_str + + +class TestPresImageCaptureCheck: + + def _make_checker(self, path, **kwargs): + return PresImageCaptureCheck(make_file_info(str(path)), **kwargs) + + def test_01_all_images_have_correct_captions(self, image_capture_fixtures_dir): + checker = self._make_checker(image_capture_fixtures_dir / "all_correct.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert "Пройдена" in verdict_str(result) + + def test_02_images_without_correct_caption(self, image_capture_fixtures_dir): + checker = self._make_checker(image_capture_fixtures_dir / "without_correct_caption.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "не содержат слова" in verdict_str(result) + assert "3" in verdict_str(result) + assert "5" in verdict_str(result) + + def test_03_images_on_slides_without_text(self, image_capture_fixtures_dir): + checker = self._make_checker(image_capture_fixtures_dir / "no_text_slides.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert "необязательны" in verdict_str(result) + assert "7" in verdict_str(result) + assert "9" in verdict_str(result) + + def test_04_mixed_case(self, image_capture_fixtures_dir): + checker = self._make_checker(image_capture_fixtures_dir / "mixed_case.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "не содержат слова" in verdict_str(result) + assert "3" in verdict_str(result) + assert "необязательны" in verdict_str(result) + assert "4" in verdict_str(result) + assert "5" in verdict_str(result) + + def test_05_caption_matches_slide_title(self, image_capture_fixtures_dir): + checker = self._make_checker(image_capture_fixtures_dir / "caption_matches_title.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert "Пройдена" in verdict_str(result) + + def test_06_multiple_captions_on_one_slide(self, image_capture_fixtures_dir): + checker = self._make_checker(image_capture_fixtures_dir / "multiple_captions.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "не содержат слова" in verdict_str(result) + assert "12" in verdict_str(result) \ No newline at end of file diff --git a/tests/presentations/test_pres_right_words.py b/tests/presentations/test_pres_right_words.py new file mode 100644 index 00000000..c851f507 --- /dev/null +++ b/tests/presentations/test_pres_right_words.py @@ -0,0 +1,48 @@ +import pytest +from app.main.checks.presentation_checks.right_words import PresRightWordsCheck +from helpers import make_file_info, verdict_str + + +class TestPresRightWordsCheck: + + def _make_checker(self, path, patterns, **kwargs): + return PresRightWordsCheck(make_file_info(str(path)), patterns, **kwargs) + + def test_01_all_patterns_found(self, right_words_fixtures_dir): + checker = self._make_checker(right_words_fixtures_dir / "all_patterns_found.pptx", ['актуальн', 'практическ', 'научн']) + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" + + def test_02_some_patterns_not_found(self, right_words_fixtures_dir): + checker = self._make_checker(right_words_fixtures_dir / "some_patterns_not_found.pptx", ['актуальн', 'практическ', 'научн', 'эксперимент']) + result = checker.check() + assert result['score'] == 0.0 + assert "Не найдены" in verdict_str(result) + assert "научн" in verdict_str(result) + assert "эксперимент" in verdict_str(result) + + def test_03_case_insensitive_search(self, right_words_fixtures_dir): + checker = self._make_checker(right_words_fixtures_dir / "case_insensitive.pptx", ['актуальность']) + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" + + def test_04_regex_pattern(self, right_words_fixtures_dir): + checker = self._make_checker(right_words_fixtures_dir / "regex_pattern.pptx", ['\\d{4}']) + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" + + def test_05_skip_title_slide(self, right_words_fixtures_dir): + checker = self._make_checker(right_words_fixtures_dir / "title_slide_only.pptx", ['актуальность']) + result = checker.check() + assert result['score'] == 0.0 + assert "Не найдены" in verdict_str(result) + assert "актуальность" in verdict_str(result) + + def test_06_empty_patterns_list(self, right_words_fixtures_dir): + checker = self._make_checker(right_words_fixtures_dir / "empty_patterns.pptx", []) + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" \ No newline at end of file diff --git a/tests/presentations/test_sld_enum.py b/tests/presentations/test_sld_enum.py new file mode 100644 index 00000000..95740261 --- /dev/null +++ b/tests/presentations/test_sld_enum.py @@ -0,0 +1,55 @@ +import pytest +from app.main.checks.presentation_checks.sld_enum import SldEnumCheck +from helpers import make_file_info, verdict_str + + +class TestSldEnumCheck: + + def _make_checker(self, path, **kwargs): + return SldEnumCheck(make_file_info(str(path)), **kwargs) + + def test_01_correct_enumeration(self, sld_enum_fixtures_dir): + checker = self._make_checker(sld_enum_fixtures_dir / "correct_enumeration.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" + + def test_02_no_number_on_first_slide(self, sld_enum_fixtures_dir): + checker = self._make_checker(sld_enum_fixtures_dir / "no_number_first_slide.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Не пройдена" in verdict_str(result) + assert "1" in verdict_str(result) + + def test_03_incorrect_enumeration_multiple_slides(self, sld_enum_fixtures_dir): + checker = self._make_checker(sld_enum_fixtures_dir / "incorrect_enumeration.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Не пройдена" in verdict_str(result) + assert "2" in verdict_str(result) + assert "3" in verdict_str(result) + assert "5" in verdict_str(result) + + def test_04_numbers_not_starting_from_one(self, sld_enum_fixtures_dir): + checker = self._make_checker(sld_enum_fixtures_dir / "not_starting_from_one.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Не пройдена" in verdict_str(result) + assert "1" in verdict_str(result) + assert "2" in verdict_str(result) + assert "3" in verdict_str(result) + assert "4" in verdict_str(result) + + def test_05_gap_in_enumeration(self, sld_enum_fixtures_dir): + checker = self._make_checker(sld_enum_fixtures_dir / "gap_in_enumeration.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Не пройдена" in verdict_str(result) + assert "3" in verdict_str(result) + assert "4" in verdict_str(result) + + def test_06_different_number_formats(self, sld_enum_fixtures_dir): + checker = self._make_checker(sld_enum_fixtures_dir / "different_formats.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" \ No newline at end of file diff --git a/tests/presentations/test_sld_similarity.py b/tests/presentations/test_sld_similarity.py new file mode 100644 index 00000000..70ccc42d --- /dev/null +++ b/tests/presentations/test_sld_similarity.py @@ -0,0 +1,39 @@ +import pytest +from app.main.checks.presentation_checks.sld_similarity import SldSimilarity +from helpers import make_file_info, verdict_str + + +class TestSldSimilarity: + + def _make_checker(self, path, **kwargs): + return SldSimilarity(make_file_info(str(path)), **kwargs) + + def test_01_full_compliance(self, sld_similarity_fixtures_dir): + checker = self._make_checker(sld_similarity_fixtures_dir / "full_compliance.pptx") + result = checker.check() + assert result['score'] == 1.0 + + def test_02_partial_compliance_above_threshold(self, sld_similarity_fixtures_dir): + checker = self._make_checker(sld_similarity_fixtures_dir / "partial_compliance.pptx", min_percent=70) + result = checker.check() + assert result['score'] == 1.0 + + def test_03_compliance_below_threshold(self, sld_similarity_fixtures_dir): + checker = self._make_checker(sld_similarity_fixtures_dir / "low_compliance.pptx") + result = checker.check() + assert result['score'] == 0.0 + + def test_04_custom_section_titles(self, sld_similarity_fixtures_dir): + checker = self._make_checker(sld_similarity_fixtures_dir / "custom_titles.pptx", goals="Задачи работы", conclusion="Выводы") + result = checker.check() + assert result['score'] == 1.0 + + def test_05_missing_conclusion_section(self, sld_similarity_fixtures_dir): + checker = self._make_checker(sld_similarity_fixtures_dir / "missing_conclusion.pptx") + result = checker.check() + assert result['score'] == 0.0 + + def test_06_boundary_value(self, sld_similarity_fixtures_dir): + checker = self._make_checker(sld_similarity_fixtures_dir / "boundary_value.pptx", min_percent=50) + result = checker.check() + assert result['score'] == 1.0 \ No newline at end of file diff --git a/tests/presentations/test_task_tracker.py b/tests/presentations/test_task_tracker.py new file mode 100644 index 00000000..21304312 --- /dev/null +++ b/tests/presentations/test_task_tracker.py @@ -0,0 +1,54 @@ +import pytest +from app.main.checks.presentation_checks.task_tracker import TaskTracker +from helpers import make_file_info, verdict_str + + +class TestTaskTracker: + + def _make_checker(self, path, **kwargs): + return TaskTracker(make_file_info(str(path)), **kwargs) + + def test_01_tasks_formulated_correctly(self, task_tracker_fixtures_dir): + checker = self._make_checker(task_tracker_fixtures_dir / "correct_tasks.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Задачи сформулированы корректно!" + + def test_02_forbidden_words_detected(self, task_tracker_fixtures_dir): + checker = self._make_checker(task_tracker_fixtures_dir / "forbidden_words.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "не должны содержать слова" in verdict_str(result) + assert "решить" in verdict_str(result) + assert "описать" in verdict_str(result) + assert "доделать" in verdict_str(result) + + def test_03_goal_and_tasks_slide_missing(self, task_tracker_fixtures_dir): + checker = self._make_checker(task_tracker_fixtures_dir / "missing_slide.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert verdict_str(result) == 'Слайда "Цель и задачи" не существует' + + def test_04_custom_deny_list(self, task_tracker_fixtures_dir): + checker = self._make_checker(task_tracker_fixtures_dir / "custom_deny_list.pptx", deny_list=['создать', 'реализовать']) + result = checker.check() + assert result['score'] == 0.0 + assert "не должны содержать слова" in verdict_str(result) + assert "создать" in verdict_str(result) + assert "реализовать" in verdict_str(result) + + def test_05_custom_section_title(self, task_tracker_fixtures_dir): + checker = self._make_checker(task_tracker_fixtures_dir / "custom_title.pptx", goal_and_tasks="Задачи работы") + result = checker.check() + assert result['score'] == 0.0 + assert "не должны содержать слова" in verdict_str(result) + assert "решить" in verdict_str(result) + + def test_06_stemming_and_normalization(self, task_tracker_fixtures_dir): + checker = self._make_checker(task_tracker_fixtures_dir / "different_forms.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "не должны содержать слова" in verdict_str(result) + assert "доделать" in verdict_str(result) + assert "решить" in verdict_str(result) + assert "описать" in verdict_str(result) \ No newline at end of file diff --git a/tests/presentations/test_title_format.py b/tests/presentations/test_title_format.py new file mode 100644 index 00000000..8e7d29f4 --- /dev/null +++ b/tests/presentations/test_title_format.py @@ -0,0 +1,55 @@ +import pytest +from app.main.checks.presentation_checks.title_format import TitleFormatCheck +from helpers import make_file_info, verdict_str + + +class TestTitleFormatCheck: + + def _make_checker(self, path, **kwargs): + return TitleFormatCheck(make_file_info(str(path)), **kwargs) + + def test_01_all_titles_correct(self, title_format_fixtures_dir): + checker = self._make_checker(title_format_fixtures_dir / "all_correct.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" + + def test_02_slides_without_titles(self, title_format_fixtures_dir): + checker = self._make_checker(title_format_fixtures_dir / "missing_titles.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Заголовки не найдены" in verdict_str(result) + assert "2" in verdict_str(result) + assert "4" in verdict_str(result) + + def test_03_titles_exceeding_two_lines(self, title_format_fixtures_dir): + checker = self._make_checker(title_format_fixtures_dir / "exceeded_lines.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Превышение длины" in verdict_str(result) + assert "1" in verdict_str(result) + assert "3" in verdict_str(result) + + def test_04_combined_issues(self, title_format_fixtures_dir): + checker = self._make_checker(title_format_fixtures_dir / "combined_issues.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Заголовки не найдены" in verdict_str(result) + assert "2" in verdict_str(result) + assert "4" in verdict_str(result) + assert "Превышение длины" in verdict_str(result) + assert "5" in verdict_str(result) + + def test_05_special_characters_handling(self, title_format_fixtures_dir): + checker = self._make_checker(title_format_fixtures_dir / "special_chars.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Превышение длины" in verdict_str(result) + assert "2" in verdict_str(result) + assert "3" in verdict_str(result) + + def test_06_empty_lines_after_split(self, title_format_fixtures_dir): + checker = self._make_checker(title_format_fixtures_dir / "empty_lines.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" \ No newline at end of file diff --git a/tests/requirements.txt b/tests/requirements.txt index cd2eeb88..ee2e0cd6 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,2 +1,4 @@ selenium==4.18.0 -webdriver-manager==4.0.1 #to avoid problem with binary +webdriver-manager==4.0.1 +pytest==7.4.3 +python-pptx==0.6.23 \ No newline at end of file diff --git a/tests/test_empty_slide_check.py b/tests/test_empty_slide_check.py new file mode 100644 index 00000000..8ba0a880 --- /dev/null +++ b/tests/test_empty_slide_check.py @@ -0,0 +1,51 @@ +import pytest +from app.main.checks.presentation_checks.empty_slide_check import PresEmptySlideCheck +from helpers import make_file_info, verdict_str + + +class TestPresEmptySlideCheck: + + def _make_checker(self, path, **kwargs): + return PresEmptySlideCheck(make_file_info(str(path)), **kwargs) + + def test_01_valid_presentation(self, presentations_fixtures_dir): + checker = self._make_checker(presentations_fixtures_dir / "empty_slide_check" / "valid.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" + + def test_02_detect_empty_slides(self, presentations_fixtures_dir): + checker = self._make_checker(presentations_fixtures_dir / "empty_slide_check" / "with_empty_slides.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Не пройдена" in verdict_str(result) + assert "пустые слайды" in verdict_str(result) + assert "2" in verdict_str(result) + assert "4" in verdict_str(result) + + def test_03_detect_title_only_slides(self, presentations_fixtures_dir): + checker = self._make_checker(presentations_fixtures_dir / "empty_slide_check" / "with_title_only.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Не пройдена" in verdict_str(result) + assert "только заголовок" in verdict_str(result) + assert "1" in verdict_str(result) + assert "3" in verdict_str(result) + + def test_04_images_and_tables_as_content(self, presentations_fixtures_dir): + checker = self._make_checker(presentations_fixtures_dir / "empty_slide_check" / "with_images_tables.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" + + def test_05_backup_slide_ignored(self, presentations_fixtures_dir): + checker = self._make_checker(presentations_fixtures_dir / "empty_slide_check" / "with_backup_slide.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" + + def test_06_unsupported_format(self, presentations_fixtures_dir): + checker = self._make_checker(presentations_fixtures_dir / "empty_slide_check" / "empty.pdf") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" \ No newline at end of file diff --git a/tests/test_find_tasks.py b/tests/test_find_tasks.py new file mode 100644 index 00000000..f5538220 --- /dev/null +++ b/tests/test_find_tasks.py @@ -0,0 +1,45 @@ +import pytest +from app.main.checks.presentation_checks.find_tasks import FindTasks +from helpers import make_file_info, verdict_str + + +class TestFindTasks: + + def _make_checker(self, path, **kwargs): + return FindTasks(make_file_info(str(path)), **kwargs) + + def test_01_all_tasks_found(self, find_tasks_fixtures_dir): + checker = self._make_checker(find_tasks_fixtures_dir / "all_tasks_found.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Все задачи найдены на слайдах" + + def test_02_goal_slide_not_found(self, find_tasks_fixtures_dir): + checker = self._make_checker(find_tasks_fixtures_dir / "no_goal_slide.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert verdict_str(result) == 'Слайд "Задачи" не найден' + + def test_03_below_threshold(self, find_tasks_fixtures_dir): + checker = self._make_checker(find_tasks_fixtures_dir / "below_threshold.pptx") + result = checker.check() + assert result['score'] == pytest.approx(0.4) + assert "не найдены" in verdict_str(result) or "Не найдены" in verdict_str(result) + + def test_04_above_threshold(self, find_tasks_fixtures_dir): + checker = self._make_checker(find_tasks_fixtures_dir / "above_threshold.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Все задачи найдены на слайдах" + + def test_05_boundary_value(self, find_tasks_fixtures_dir): + checker = self._make_checker(find_tasks_fixtures_dir / "boundary_value.pptx") + result = checker.check() + assert result['score'] == pytest.approx(0.5) + assert "не найдены" in verdict_str(result) or "Не найдены" in verdict_str(result) + + def test_06_custom_threshold(self, find_tasks_fixtures_dir): + checker = self._make_checker(find_tasks_fixtures_dir / "custom_threshold.pptx", min_percent=70) + result = checker.check() + assert result['score'] == pytest.approx(0.8) + assert "найдены" in verdict_str(result) or "Найдены" in verdict_str(result) \ No newline at end of file diff --git a/tests/test_further_dev.py b/tests/test_further_dev.py new file mode 100644 index 00000000..220e4685 --- /dev/null +++ b/tests/test_further_dev.py @@ -0,0 +1,51 @@ +import pytest +from app.main.checks.presentation_checks.further_dev import FurtherDev +from helpers import make_file_info, verdict_str + + +class TestFurtherDev: + + def _make_checker(self, path, **kwargs): + return FurtherDev(make_file_info(str(path)), **kwargs) + + def test_01_further_dev_found(self, further_dev_fixtures_dir): + checker = self._make_checker(further_dev_fixtures_dir / "further_dev_found.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Направления развития найдены" + + def test_02_conclusion_not_exists(self, further_dev_fixtures_dir): + checker = self._make_checker(further_dev_fixtures_dir / "no_conclusion.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert verdict_str(result) == "Заключения не существует" + + def test_03_no_further_dev_in_conclusion(self, further_dev_fixtures_dir): + checker = self._make_checker(further_dev_fixtures_dir / "no_further_dev.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Направления развития не найдены" in verdict_str(result) + + def test_04_custom_conclusion_title(self, further_dev_fixtures_dir): + checker = self._make_checker(further_dev_fixtures_dir / "custom_conclusion.pptx", conclusion="Выводы и перспективы") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Направления развития найдены" + + def test_05_indirect_indicators(self, further_dev_fixtures_dir): + checker = self._make_checker(further_dev_fixtures_dir / "indirect_indicators.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Направления развития найдены" + + def test_06_different_formats(self, further_dev_fixtures_dir): + # ⚠️ .ppt (старый бинарный формат) не поддерживается python-pptx — тест упадёт с ошибкой открытия файла + checker_ppt = self._make_checker(further_dev_fixtures_dir / "further_dev_found.ppt") + result_ppt = checker_ppt.check() + assert result_ppt['score'] == 1.0 + assert verdict_str(result_ppt) == "Направления развития найдены" + + checker_odp = self._make_checker(further_dev_fixtures_dir / "further_dev_found.odp") + result_odp = checker_odp.check() + assert result_odp['score'] == 1.0 + assert verdict_str(result_odp) == "Направления развития найдены" \ No newline at end of file diff --git a/tests/test_name_of_image_check.py b/tests/test_name_of_image_check.py new file mode 100644 index 00000000..c1ac4807 --- /dev/null +++ b/tests/test_name_of_image_check.py @@ -0,0 +1,54 @@ +import pytest +from app.main.checks.presentation_checks.image_capture import PresImageCaptureCheck +from helpers import make_file_info, verdict_str + + +class TestPresImageCaptureCheck: + + def _make_checker(self, path, **kwargs): + return PresImageCaptureCheck(make_file_info(str(path)), **kwargs) + + def test_01_all_images_have_correct_captions(self, image_capture_fixtures_dir): + checker = self._make_checker(image_capture_fixtures_dir / "all_correct.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert "Пройдена" in verdict_str(result) + + def test_02_images_without_correct_caption(self, image_capture_fixtures_dir): + checker = self._make_checker(image_capture_fixtures_dir / "without_correct_caption.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "не содержат слова" in verdict_str(result) + assert "3" in verdict_str(result) + assert "5" in verdict_str(result) + + def test_03_images_on_slides_without_text(self, image_capture_fixtures_dir): + checker = self._make_checker(image_capture_fixtures_dir / "no_text_slides.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert "необязательны" in verdict_str(result) + assert "7" in verdict_str(result) + assert "9" in verdict_str(result) + + def test_04_mixed_case(self, image_capture_fixtures_dir): + checker = self._make_checker(image_capture_fixtures_dir / "mixed_case.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "не содержат слова" in verdict_str(result) + assert "3" in verdict_str(result) + assert "необязательны" in verdict_str(result) + assert "4" in verdict_str(result) + assert "5" in verdict_str(result) + + def test_05_caption_matches_slide_title(self, image_capture_fixtures_dir): + checker = self._make_checker(image_capture_fixtures_dir / "caption_matches_title.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert "Пройдена" in verdict_str(result) + + def test_06_multiple_captions_on_one_slide(self, image_capture_fixtures_dir): + checker = self._make_checker(image_capture_fixtures_dir / "multiple_captions.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "не содержат слова" in verdict_str(result) + assert "12" in verdict_str(result) \ No newline at end of file diff --git a/tests/test_pres_right_words.py b/tests/test_pres_right_words.py new file mode 100644 index 00000000..c851f507 --- /dev/null +++ b/tests/test_pres_right_words.py @@ -0,0 +1,48 @@ +import pytest +from app.main.checks.presentation_checks.right_words import PresRightWordsCheck +from helpers import make_file_info, verdict_str + + +class TestPresRightWordsCheck: + + def _make_checker(self, path, patterns, **kwargs): + return PresRightWordsCheck(make_file_info(str(path)), patterns, **kwargs) + + def test_01_all_patterns_found(self, right_words_fixtures_dir): + checker = self._make_checker(right_words_fixtures_dir / "all_patterns_found.pptx", ['актуальн', 'практическ', 'научн']) + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" + + def test_02_some_patterns_not_found(self, right_words_fixtures_dir): + checker = self._make_checker(right_words_fixtures_dir / "some_patterns_not_found.pptx", ['актуальн', 'практическ', 'научн', 'эксперимент']) + result = checker.check() + assert result['score'] == 0.0 + assert "Не найдены" in verdict_str(result) + assert "научн" in verdict_str(result) + assert "эксперимент" in verdict_str(result) + + def test_03_case_insensitive_search(self, right_words_fixtures_dir): + checker = self._make_checker(right_words_fixtures_dir / "case_insensitive.pptx", ['актуальность']) + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" + + def test_04_regex_pattern(self, right_words_fixtures_dir): + checker = self._make_checker(right_words_fixtures_dir / "regex_pattern.pptx", ['\\d{4}']) + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" + + def test_05_skip_title_slide(self, right_words_fixtures_dir): + checker = self._make_checker(right_words_fixtures_dir / "title_slide_only.pptx", ['актуальность']) + result = checker.check() + assert result['score'] == 0.0 + assert "Не найдены" in verdict_str(result) + assert "актуальность" in verdict_str(result) + + def test_06_empty_patterns_list(self, right_words_fixtures_dir): + checker = self._make_checker(right_words_fixtures_dir / "empty_patterns.pptx", []) + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" \ No newline at end of file diff --git a/tests/test_sld_enum.py b/tests/test_sld_enum.py new file mode 100644 index 00000000..95740261 --- /dev/null +++ b/tests/test_sld_enum.py @@ -0,0 +1,55 @@ +import pytest +from app.main.checks.presentation_checks.sld_enum import SldEnumCheck +from helpers import make_file_info, verdict_str + + +class TestSldEnumCheck: + + def _make_checker(self, path, **kwargs): + return SldEnumCheck(make_file_info(str(path)), **kwargs) + + def test_01_correct_enumeration(self, sld_enum_fixtures_dir): + checker = self._make_checker(sld_enum_fixtures_dir / "correct_enumeration.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" + + def test_02_no_number_on_first_slide(self, sld_enum_fixtures_dir): + checker = self._make_checker(sld_enum_fixtures_dir / "no_number_first_slide.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Не пройдена" in verdict_str(result) + assert "1" in verdict_str(result) + + def test_03_incorrect_enumeration_multiple_slides(self, sld_enum_fixtures_dir): + checker = self._make_checker(sld_enum_fixtures_dir / "incorrect_enumeration.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Не пройдена" in verdict_str(result) + assert "2" in verdict_str(result) + assert "3" in verdict_str(result) + assert "5" in verdict_str(result) + + def test_04_numbers_not_starting_from_one(self, sld_enum_fixtures_dir): + checker = self._make_checker(sld_enum_fixtures_dir / "not_starting_from_one.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Не пройдена" in verdict_str(result) + assert "1" in verdict_str(result) + assert "2" in verdict_str(result) + assert "3" in verdict_str(result) + assert "4" in verdict_str(result) + + def test_05_gap_in_enumeration(self, sld_enum_fixtures_dir): + checker = self._make_checker(sld_enum_fixtures_dir / "gap_in_enumeration.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Не пройдена" in verdict_str(result) + assert "3" in verdict_str(result) + assert "4" in verdict_str(result) + + def test_06_different_number_formats(self, sld_enum_fixtures_dir): + checker = self._make_checker(sld_enum_fixtures_dir / "different_formats.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" \ No newline at end of file diff --git a/tests/test_sld_similarity.py b/tests/test_sld_similarity.py new file mode 100644 index 00000000..70ccc42d --- /dev/null +++ b/tests/test_sld_similarity.py @@ -0,0 +1,39 @@ +import pytest +from app.main.checks.presentation_checks.sld_similarity import SldSimilarity +from helpers import make_file_info, verdict_str + + +class TestSldSimilarity: + + def _make_checker(self, path, **kwargs): + return SldSimilarity(make_file_info(str(path)), **kwargs) + + def test_01_full_compliance(self, sld_similarity_fixtures_dir): + checker = self._make_checker(sld_similarity_fixtures_dir / "full_compliance.pptx") + result = checker.check() + assert result['score'] == 1.0 + + def test_02_partial_compliance_above_threshold(self, sld_similarity_fixtures_dir): + checker = self._make_checker(sld_similarity_fixtures_dir / "partial_compliance.pptx", min_percent=70) + result = checker.check() + assert result['score'] == 1.0 + + def test_03_compliance_below_threshold(self, sld_similarity_fixtures_dir): + checker = self._make_checker(sld_similarity_fixtures_dir / "low_compliance.pptx") + result = checker.check() + assert result['score'] == 0.0 + + def test_04_custom_section_titles(self, sld_similarity_fixtures_dir): + checker = self._make_checker(sld_similarity_fixtures_dir / "custom_titles.pptx", goals="Задачи работы", conclusion="Выводы") + result = checker.check() + assert result['score'] == 1.0 + + def test_05_missing_conclusion_section(self, sld_similarity_fixtures_dir): + checker = self._make_checker(sld_similarity_fixtures_dir / "missing_conclusion.pptx") + result = checker.check() + assert result['score'] == 0.0 + + def test_06_boundary_value(self, sld_similarity_fixtures_dir): + checker = self._make_checker(sld_similarity_fixtures_dir / "boundary_value.pptx", min_percent=50) + result = checker.check() + assert result['score'] == 1.0 \ No newline at end of file diff --git a/tests/test_task_tracker.py b/tests/test_task_tracker.py new file mode 100644 index 00000000..21304312 --- /dev/null +++ b/tests/test_task_tracker.py @@ -0,0 +1,54 @@ +import pytest +from app.main.checks.presentation_checks.task_tracker import TaskTracker +from helpers import make_file_info, verdict_str + + +class TestTaskTracker: + + def _make_checker(self, path, **kwargs): + return TaskTracker(make_file_info(str(path)), **kwargs) + + def test_01_tasks_formulated_correctly(self, task_tracker_fixtures_dir): + checker = self._make_checker(task_tracker_fixtures_dir / "correct_tasks.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Задачи сформулированы корректно!" + + def test_02_forbidden_words_detected(self, task_tracker_fixtures_dir): + checker = self._make_checker(task_tracker_fixtures_dir / "forbidden_words.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "не должны содержать слова" in verdict_str(result) + assert "решить" in verdict_str(result) + assert "описать" in verdict_str(result) + assert "доделать" in verdict_str(result) + + def test_03_goal_and_tasks_slide_missing(self, task_tracker_fixtures_dir): + checker = self._make_checker(task_tracker_fixtures_dir / "missing_slide.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert verdict_str(result) == 'Слайда "Цель и задачи" не существует' + + def test_04_custom_deny_list(self, task_tracker_fixtures_dir): + checker = self._make_checker(task_tracker_fixtures_dir / "custom_deny_list.pptx", deny_list=['создать', 'реализовать']) + result = checker.check() + assert result['score'] == 0.0 + assert "не должны содержать слова" in verdict_str(result) + assert "создать" in verdict_str(result) + assert "реализовать" in verdict_str(result) + + def test_05_custom_section_title(self, task_tracker_fixtures_dir): + checker = self._make_checker(task_tracker_fixtures_dir / "custom_title.pptx", goal_and_tasks="Задачи работы") + result = checker.check() + assert result['score'] == 0.0 + assert "не должны содержать слова" in verdict_str(result) + assert "решить" in verdict_str(result) + + def test_06_stemming_and_normalization(self, task_tracker_fixtures_dir): + checker = self._make_checker(task_tracker_fixtures_dir / "different_forms.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "не должны содержать слова" in verdict_str(result) + assert "доделать" in verdict_str(result) + assert "решить" in verdict_str(result) + assert "описать" in verdict_str(result) \ No newline at end of file diff --git a/tests/test_title_format.py b/tests/test_title_format.py new file mode 100644 index 00000000..8e7d29f4 --- /dev/null +++ b/tests/test_title_format.py @@ -0,0 +1,55 @@ +import pytest +from app.main.checks.presentation_checks.title_format import TitleFormatCheck +from helpers import make_file_info, verdict_str + + +class TestTitleFormatCheck: + + def _make_checker(self, path, **kwargs): + return TitleFormatCheck(make_file_info(str(path)), **kwargs) + + def test_01_all_titles_correct(self, title_format_fixtures_dir): + checker = self._make_checker(title_format_fixtures_dir / "all_correct.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" + + def test_02_slides_without_titles(self, title_format_fixtures_dir): + checker = self._make_checker(title_format_fixtures_dir / "missing_titles.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Заголовки не найдены" in verdict_str(result) + assert "2" in verdict_str(result) + assert "4" in verdict_str(result) + + def test_03_titles_exceeding_two_lines(self, title_format_fixtures_dir): + checker = self._make_checker(title_format_fixtures_dir / "exceeded_lines.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Превышение длины" in verdict_str(result) + assert "1" in verdict_str(result) + assert "3" in verdict_str(result) + + def test_04_combined_issues(self, title_format_fixtures_dir): + checker = self._make_checker(title_format_fixtures_dir / "combined_issues.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Заголовки не найдены" in verdict_str(result) + assert "2" in verdict_str(result) + assert "4" in verdict_str(result) + assert "Превышение длины" in verdict_str(result) + assert "5" in verdict_str(result) + + def test_05_special_characters_handling(self, title_format_fixtures_dir): + checker = self._make_checker(title_format_fixtures_dir / "special_chars.pptx") + result = checker.check() + assert result['score'] == 0.0 + assert "Превышение длины" in verdict_str(result) + assert "2" in verdict_str(result) + assert "3" in verdict_str(result) + + def test_06_empty_lines_after_split(self, title_format_fixtures_dir): + checker = self._make_checker(title_format_fixtures_dir / "empty_lines.pptx") + result = checker.check() + assert result['score'] == 1.0 + assert verdict_str(result) == "Пройдена!" \ No newline at end of file