From 071c62c03f5e8c281e1b3553ed84c710b98c40f2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 09:07:55 +0000 Subject: [PATCH 1/4] Initial plan From 43bc58770dbf412648ecaaa204f090afe0612ea2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 09:10:52 +0000 Subject: [PATCH 2/4] refactor: consolidate linting tools into Ruff Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com> --- .github/workflows/tests.yaml | 91 +-------- .pre-commit-config.yaml | 34 +--- app/api/files.py | 4 +- app/api/url_upload.py | 2 +- app/config.py | 2 +- app/database.py | 3 +- app/tasks/convert_to_pdf.py | 4 +- app/tasks/embed_metadata_into_pdf.py | 3 +- app/tasks/monitor_stalled_steps.py | 2 +- ...rocess_with_azure_document_intelligence.py | 6 +- app/tasks/rotate_pdf_pages.py | 6 +- app/tasks/upload_to_onedrive.py | 4 +- .../config_validator/settings_display.py | 4 +- app/utils/file_splitting.py | 1 - app/utils/migrate_logs_to_steps.py | 2 +- app/utils/step_timeout.py | 2 +- pyproject.toml | 107 +++-------- requirements-dev.txt | 9 +- tests/conftest.py | 5 +- tests/conftest_oauth.py | 55 +++--- tests/fixtures_integration.py | 1 - tests/mock_oauth_server.py | 38 ++-- tests/test_api_azure_extended.py | 10 +- tests/test_api_diagnostic_extended.py | 7 +- tests/test_api_dropbox.py | 3 +- tests/test_api_dropbox_extended.py | 8 +- tests/test_api_files_comprehensive.py | 146 ++++++++------ tests/test_api_google_drive_comprehensive.py | 154 ++++++--------- tests/test_api_google_drive_extended.py | 7 +- tests/test_api_logs.py | 2 - tests/test_api_onedrive_comprehensive.py | 174 ++++++----------- tests/test_api_onedrive_extended.py | 9 +- tests/test_api_openai_extended.py | 5 +- tests/test_api_settings.py | 2 +- tests/test_api_settings_extended.py | 20 +- tests/test_auth_integration.py | 5 +- tests/test_auth_module.py | 4 +- tests/test_bulk_operations.py | 2 +- tests/test_celery_worker.py | 56 +++--- tests/test_check_credentials.py | 2 +- tests/test_config.py | 2 - tests/test_config_validator_reexport.py | 30 +-- tests/test_config_validators.py | 2 - tests/test_convert_pdf.py | 2 +- tests/test_convert_to_pdf.py | 1 - tests/test_coverage_boost.py | 2 +- tests/test_coverage_final.py | 3 +- tests/test_database.py | 4 +- tests/test_e2e_full_stack.py | 17 -- tests/test_embed_metadata.py | 1 - tests/test_embed_pdf_metadata.py | 9 +- tests/test_endpoint_registration.py | 10 +- tests/test_external_integrations.py | 12 +- tests/test_extract_metadata_gpt.py | 59 +++--- tests/test_file_detail_endpoints.py | 1 - tests/test_file_detail_enhancements.py | 10 - tests/test_file_listing.py | 2 - tests/test_file_splitting.py | 6 +- tests/test_file_status_fix.py | 4 +- tests/test_file_upload.py | 1 - tests/test_filename_utils.py | 4 +- tests/test_finalize_storage.py | 4 +- tests/test_imap_extended.py | 2 - tests/test_imap_tasks.py | 1 - tests/test_monitor_stalled_steps.py | 90 ++++----- tests/test_notification.py | 2 +- tests/test_notification_utils.py | 3 +- tests/test_oauth_integration_flows.py | 102 +++++----- tests/test_ocr_processing.py | 15 -- tests/test_original_filename_preservation.py | 2 - tests/test_path_traversal_security.py | 8 +- tests/test_process_document.py | 6 - tests/test_processall_throttling.py | 3 +- tests/test_rate_limit_decorators.py | 70 +++---- tests/test_rate_limiting.py | 4 - tests/test_rclone_tasks.py | 3 +- tests/test_security_headers.py | 6 +- tests/test_settings.py | 2 - tests/test_step_timeout.py | 112 +++++------ tests/test_storage_reorganization.py | 1 - tests/test_upload_email.py | 2 - tests/test_upload_ftp_additional.py | 2 - tests/test_upload_tasks.py | 18 +- tests/test_upload_tasks_additional.py | 1 - tests/test_upload_tasks_coverage.py | 3 - tests/test_upload_to_dropbox.py | 7 +- tests/test_upload_to_nextcloud.py | 3 +- tests/test_upload_to_onedrive.py | 3 +- tests/test_upload_to_paperless.py | 15 +- tests/test_upload_webdav_comprehensive.py | 25 +-- tests/test_upload_webdav_integration.py | 14 +- tests/test_upload_with_rclone.py | 7 +- tests/test_uptime_kuma.py | 2 +- tests/test_url_upload.py | 1 - tests/test_views_coverage.py | 2 - tests/test_views_files_comprehensive.py | 178 +++++++++--------- tests/test_views_general.py | 3 - tests/test_views_settings.py | 2 +- 98 files changed, 739 insertions(+), 1168 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 2211e12d..de7366b9 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -73,9 +73,9 @@ jobs: junit.xml coverage.xml - # ── Flake8 ───────────────────────────────────────────────────────────── - flake8: - name: Flake8 + # ── Lint (Ruff) ─────────────────────────────────────────────────────── + lint: + name: Ruff Lint & Format runs-on: ubuntu-latest steps: - name: Checkout Code @@ -86,34 +86,14 @@ jobs: with: python-version: "3.11" - - name: Install Dependencies - run: | - python -m pip install --upgrade pip - pip install flake8 + - name: Install Ruff + run: pip install ruff - - name: Run Flake8 - run: flake8 app/ --max-line-length=120 --extend-ignore=E203,W503 + - name: Run Ruff Check + run: ruff check app/ tests/ - # ── Black ────────────────────────────────────────────────────────────── - black: - name: Black - runs-on: ubuntu-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install Dependencies - run: | - python -m pip install --upgrade pip - pip install black - - - name: Run Black - run: black --check app/ --line-length=120 + - name: Run Ruff Format + run: ruff format --check app/ tests/ # ── Mypy ─────────────────────────────────────────────────────────────── mypy: @@ -135,56 +115,3 @@ jobs: - name: Run Mypy run: mypy app/ - - # ── Pylint ───────────────────────────────────────────────────────────── - pylint: - name: Pylint - runs-on: ubuntu-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install Dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements-dev.txt - - - name: Run Pylint - run: pylint app/ - - # ── Bandit ───────────────────────────────────────────────────────────── - bandit: - name: Bandit - runs-on: ubuntu-latest - steps: - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - name: Install Dependencies - run: | - python -m pip install --upgrade pip - pip install bandit - - - name: Run Bandit - Full Report - if: ${{ !cancelled() }} - run: bandit -r app/ -f json -o bandit-report.json || true - - - name: Run Bandit - Fail on High/Medium - run: bandit -r app/ -ll - - - name: Upload Bandit Report - if: ${{ !cancelled() }} - uses: actions/upload-artifact@v4 - with: - name: bandit-report - path: bandit-report.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 035bec2b..1416b15c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,35 +19,13 @@ repos: - id: detect-aws-credentials args: ['--allow-missing-credentials'] - # Python code formatting - - repo: https://github.com/psf/black - rev: 24.1.1 + # Ruff - Fast Python linter and formatter (replaces Black, Flake8, isort, Bandit) + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.3.0 hooks: - - id: black - args: ['--line-length=120'] - language_version: python3.11 - - # Import sorting - - repo: https://github.com/PyCQA/isort - rev: 5.13.2 - hooks: - - id: isort - args: ['--profile=black', '--line-length=120'] - - # Linting - - repo: https://github.com/PyCQA/flake8 - rev: 7.0.0 - hooks: - - id: flake8 - args: ['--max-line-length=120', '--extend-ignore=E203,W503'] - - # Security linting - - repo: https://github.com/PyCQA/bandit - rev: 1.7.6 - hooks: - - id: bandit - args: ['-ll', '-r', 'app/'] - exclude: 'tests/' + - id: ruff + args: [ --fix ] + - id: ruff-format # Type checking - repo: https://github.com/pre-commit/mirrors-mypy diff --git a/app/api/files.py b/app/api/files.py index 80eb558d..d852e65a 100644 --- a/app/api/files.py +++ b/app/api/files.py @@ -374,7 +374,7 @@ def reprocess_single_file(request: Request, file_id: int, db: DbSession): ) logger.info( - f"Reprocessing file: ID={file_record.id}, " f"Filename={file_record.original_filename}, TaskID={task.id}" + f"Reprocessing file: ID={file_record.id}, Filename={file_record.original_filename}, TaskID={task.id}" ) return { @@ -645,7 +645,7 @@ def retry_subtask( upload_task = task_map[subtask_name] task = upload_task.delay(file_path, file_id) - logger.info(f"Retrying upload subtask: FileID={file_record.id}, " f"Subtask={subtask_name}, TaskID={task.id}") + logger.info(f"Retrying upload subtask: FileID={file_record.id}, Subtask={subtask_name}, TaskID={task.id}") return { "status": "success", diff --git a/app/api/url_upload.py b/app/api/url_upload.py index 7367138b..bfc82dab 100644 --- a/app/api/url_upload.py +++ b/app/api/url_upload.py @@ -146,7 +146,7 @@ def validate_file_type(content_type: str, filename: str) -> bool: # Check content type from header if content_type: # Handle content-type with charset (e.g., "application/pdf; charset=utf-8") - base_content_type = content_type.split(";")[0].strip().lower() + base_content_type = content_type.split(";", maxsplit=1)[0].strip().lower() if base_content_type in ALLOWED_MIME_TYPES or base_content_type in IMAGE_MIME_TYPES: return True diff --git a/app/config.py b/app/config.py index 391e2b22..9f6a411f 100644 --- a/app/config.py +++ b/app/config.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import os -from typing import Any, List, Optional, Union +from typing import List, Optional, Union from pydantic import Field, field_validator from pydantic_settings import BaseSettings, SettingsConfigDict diff --git a/app/database.py b/app/database.py index 6451ae21..cd17bcf3 100644 --- a/app/database.py +++ b/app/database.py @@ -5,8 +5,7 @@ import os from sqlalchemy import create_engine, exc from sqlalchemy.engine.url import make_url -from sqlalchemy.orm import declarative_base -from sqlalchemy.orm import sessionmaker +from sqlalchemy.orm import declarative_base, sessionmaker from app.config import settings diff --git a/app/tasks/convert_to_pdf.py b/app/tasks/convert_to_pdf.py index edb43599..29d404ce 100644 --- a/app/tasks/convert_to_pdf.py +++ b/app/tasks/convert_to_pdf.py @@ -340,9 +340,7 @@ def convert_to_pdf(self, file_path: str, original_filename: Optional[str] = None else: error_msg = f"Status code: {response.status_code}" logger.error( - f"[{task_id}] Conversion failed for {file_path}. " - f"{error_msg}, " - f"Response: {response.text[:500]}..." + f"[{task_id}] Conversion failed for {file_path}. {error_msg}, Response: {response.text[:500]}..." ) log_task_progress(task_id, "call_gotenberg", "failure", error_msg) log_task_progress(task_id, "convert_to_pdf", "failure", f"Conversion failed: {error_msg}") diff --git a/app/tasks/embed_metadata_into_pdf.py b/app/tasks/embed_metadata_into_pdf.py index 9b2ce884..82bdb8bb 100644 --- a/app/tasks/embed_metadata_into_pdf.py +++ b/app/tasks/embed_metadata_into_pdf.py @@ -256,8 +256,7 @@ def embed_metadata_into_pdf(self, local_file_path: str, extracted_text: str, met f"Exception: {str(e)}", file_id=file_id, detail=( - f"Failed to embed metadata into {processed_file}.\n" - f"Original file: {original_file}\nException: {str(e)}" + f"Failed to embed metadata into {processed_file}.\nOriginal file: {original_file}\nException: {str(e)}" ), ) # Clean up temporary file in case of error diff --git a/app/tasks/monitor_stalled_steps.py b/app/tasks/monitor_stalled_steps.py index 9a20d5d1..5fbc8dba 100644 --- a/app/tasks/monitor_stalled_steps.py +++ b/app/tasks/monitor_stalled_steps.py @@ -42,7 +42,7 @@ def monitor_stalled_steps(): f"Marked as failed due to timeout." ) else: - logger.debug(f"[{datetime.utcnow().isoformat()}] " f"No stalled steps found.") + logger.debug(f"[{datetime.utcnow().isoformat()}] No stalled steps found.") return {"recovered": stalled_count} diff --git a/app/tasks/process_with_azure_document_intelligence.py b/app/tasks/process_with_azure_document_intelligence.py index 3713ac45..792cfd15 100644 --- a/app/tasks/process_with_azure_document_intelligence.py +++ b/app/tasks/process_with_azure_document_intelligence.py @@ -70,13 +70,13 @@ def check_page_rotation(result, filename, task_id=None): if hasattr(page, "angle"): rotation_angle = page.angle if rotation_angle != 0: - logger.info(f"{prefix}Page {i+1} is rotated by {rotation_angle} degrees") + logger.info(f"{prefix}Page {i + 1} is rotated by {rotation_angle} degrees") # Store page index as integer, not string rotation_data[i] = rotation_angle else: - logger.info(f"{prefix}Page {i+1} has no rotation (0 degrees)") + logger.info(f"{prefix}Page {i + 1} has no rotation (0 degrees)") else: - logger.info(f"{prefix}Page {i+1} rotation information not available") + logger.info(f"{prefix}Page {i + 1} rotation information not available") return rotation_data diff --git a/app/tasks/rotate_pdf_pages.py b/app/tasks/rotate_pdf_pages.py index a7178b61..73982396 100644 --- a/app/tasks/rotate_pdf_pages.py +++ b/app/tasks/rotate_pdf_pages.py @@ -136,13 +136,13 @@ def rotate_pdf_pages(self, filename: str, extracted_text: str, rotation_data=Non # pypdf uses clockwise rotation in 90-degree increments page.rotate(rotation_angle) logger.info( - f"[{task_id}] Page {page_idx+1} rotated by {rotation_angle}° " + f"[{task_id}] Page {page_idx + 1} rotated by {rotation_angle}° " f"(from detected {detected_angle}°)" ) applied_rotations[str(page_idx)] = rotation_angle else: logger.info( - f"[{task_id}] Page {page_idx+1} had detected angle {detected_angle}° " + f"[{task_id}] Page {page_idx + 1} had detected angle {detected_angle}° " "but determined it doesn't need rotation" ) @@ -154,7 +154,7 @@ def rotate_pdf_pages(self, filename: str, extracted_text: str, rotation_data=Non if applied_rotations: logger.info( - f"[{task_id}] Successfully rotated PDF: {filename} with rotations: " f"{json.dumps(applied_rotations)}" + f"[{task_id}] Successfully rotated PDF: {filename} with rotations: {json.dumps(applied_rotations)}" ) else: logger.info( diff --git a/app/tasks/upload_to_onedrive.py b/app/tasks/upload_to_onedrive.py index 80601df2..20ba17e0 100644 --- a/app/tasks/upload_to_onedrive.py +++ b/app/tasks/upload_to_onedrive.py @@ -188,11 +188,11 @@ def upload_large_file(file_path, upload_url): # 201 = Created (final chunk), 202 = Accepted (more chunks coming) break else: - logger.warning(f"Chunk upload failed (attempt {attempt+1}): {response.status_code}") + logger.warning(f"Chunk upload failed (attempt {attempt + 1}): {response.status_code}") if attempt < max_retries - 1: time.sleep(retry_delay * (attempt + 1)) except Exception as e: - logger.warning(f"Chunk upload error (attempt {attempt+1}): {str(e)}") + logger.warning(f"Chunk upload error (attempt {attempt + 1}): {str(e)}") if attempt < max_retries - 1: time.sleep(retry_delay * (attempt + 1)) diff --git a/app/utils/config_validator/settings_display.py b/app/utils/config_validator/settings_display.py index e7771ea1..24b75024 100644 --- a/app/utils/config_validator/settings_display.py +++ b/app/utils/config_validator/settings_display.py @@ -192,9 +192,7 @@ def get_settings_for_display(show_values=False): [ key for key in dir(settings) - if not key.startswith("_") - and key not in _PYDANTIC_INTERNALS - and not callable(getattr(settings, key)) + if not key.startswith("_") and key not in _PYDANTIC_INTERNALS and not callable(getattr(settings, key)) ] ) diff --git a/app/utils/file_splitting.py b/app/utils/file_splitting.py index f4d08d37..71b630de 100644 --- a/app/utils/file_splitting.py +++ b/app/utils/file_splitting.py @@ -97,7 +97,6 @@ def split_pdf_by_size(pdf_path: str, max_size_bytes: int, output_dir: Optional[s # If adding this page exceeds the limit (and we have more than 1 page in current chunk) # save the previous chunk and start a new one if exceeds_limit and current_page_count > 1: - # Create a new writer without the last page previous_writer = PdfWriter() for prev_page_num in range(page_num - current_page_count + 1, page_num): diff --git a/app/utils/migrate_logs_to_steps.py b/app/utils/migrate_logs_to_steps.py index 14dd40fc..85cd9a9a 100644 --- a/app/utils/migrate_logs_to_steps.py +++ b/app/utils/migrate_logs_to_steps.py @@ -310,7 +310,7 @@ def verify_migration(db: Session, file_id: int) -> Dict: if expected["status"] != actual.status: result["discrepancies"].append( - f"Step '{step_name}' status mismatch: " f"expected '{expected['status']}', got '{actual.status}'" + f"Step '{step_name}' status mismatch: expected '{expected['status']}', got '{actual.status}'" ) result["is_valid"] = False diff --git a/app/utils/step_timeout.py b/app/utils/step_timeout.py index fecfea38..35961b44 100644 --- a/app/utils/step_timeout.py +++ b/app/utils/step_timeout.py @@ -73,7 +73,7 @@ def mark_stalled_steps_as_failed( return 0 logger.warning( - f"Found {len(stalled_steps)} stalled step(s) that exceeded " f"{timeout_seconds}s timeout. Marking as failed." + f"Found {len(stalled_steps)} stalled step(s) that exceeded {timeout_seconds}s timeout. Marking as failed." ) count = 0 diff --git a/pyproject.toml b/pyproject.toml index 5b76bed4..545ed4e5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -104,33 +104,30 @@ upload_to_vcs_release = true upload_to_pypi = false upload_to_repository = false -# Black configuration -[tool.black] +# Ruff configuration +[tool.ruff] line-length = 120 -target-version = ['py311'] -include = '\.pyi?$' -extend-exclude = ''' -/( - # directories - \.eggs - | \.git - | \.hg - | \.mypy_cache - | \.tox - | \.venv - | build - | dist - | migrations -)/ -''' +target-version = "py311" -# isort configuration -[tool.isort] -profile = "black" -line_length = 120 -skip_gitignore = true -known_first_party = ["app"] -sections = ["FUTURE", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"] +[tool.ruff.lint] +# Enable Pyflakes (`F`), pycodestyle (`E`, `W`), isort (`I`), bandit (`S`), flake8-bugbear (`B`), and pylint (`PL`) +select = ["E", "F", "W", "I", "S", "B", "PL"] +ignore = [ + "E501", # Line too long (handled by formatter) + "S108", # Hardcoded temp file (common pattern) + "S105", # Hardcoded password string (false positives with 'password' variable names) + "S106", # Hardcoded password func arg (false positives) + "PLC0415", # Import outside top-level (common in FastAPI/Celery) + "PLR0913", # Too many arguments + "PLR0912", # Too many branches + "PLR0915", # Too many statements + "PLR0911", # Too many return statements + "PLR2004", # Magic value comparison + "PLW0603", # Global statement +] + +[tool.ruff.lint.per-file-ignores] +"tests/*" = ["S101", "S110", "B017"] # Allow assert, try-except-pass, assert-raises-exception in tests # pytest configuration [tool.pytest.ini_options] @@ -195,66 +192,6 @@ disable_error_code = [ "call-arg", # Dynamic call signatures in framework code ] -# pylint configuration -[tool.pylint.format] -max-line-length = 120 - -[tool.pylint."messages control"] -disable = [ - "C0111", # missing-docstring (already documented functions use docstrings selectively) - "C0103", # invalid-name (project uses domain-specific naming conventions) - "C0114", # missing-module-docstring - "C0115", # missing-class-docstring - "C0116", # missing-function-docstring - "C0415", # import-outside-toplevel (common pattern in FastAPI/Celery) - "C0200", # consider-using-enumerate - "C0201", # consider-iterating-dictionary - "C0206", # consider-using-dict-items - "C0207", # use-maxsplit-arg - "C0123", # unidiomatic-typecheck - "C0302", # too-many-lines - "R0801", # duplicate-code (intentional patterns across storage providers) - "R0401", # cyclic-import (FastAPI app structure with lazy imports) - "R0903", # too-few-public-methods - "R0911", # too-many-return-statements - "R0912", # too-many-branches - "R0913", # too-many-arguments - "R0914", # too-many-locals - "R0915", # too-many-statements - "R0916", # too-many-boolean-expressions - "R0917", # too-many-positional-arguments - "R1702", # too-many-nested-blocks - "R1705", # no-else-return - "R1710", # inconsistent-return-statements - "R1718", # consider-using-set-comprehension - "R1720", # no-else-raise - "R1723", # no-else-break - "R1732", # consider-using-with - "W0105", # pointless-string-statement - "W0212", # protected-access - "W0223", # abstract-method - "W0404", # reimported - "W0511", # fixme (TODO comments are acceptable) - "W0603", # global-statement - "W0611", # unused-import (managed by flake8/isort) - "W0613", # unused-argument (common with framework callbacks) - "W0621", # redefined-outer-name - "W0641", # possibly-unused-variable - "W0707", # raise-missing-from - "W0718", # broad-exception-caught (intentional in error handlers) - "W0719", # broad-exception-raised - "W1203", # logging-fstring-interpolation (project uses f-strings consistently) - "W1510", # subprocess-run-check - "W1514", # unspecified-encoding - "W0612", # unused-variable - "E0213", # no-self-argument (Pydantic validators use cls) - "E0611", # no-name-in-module (false positives with package imports) - "E1101", # no-member (false positives with dynamic API clients) - "E1102", # not-callable (false positives with SQLAlchemy func.now()) - "E1133", # not-an-iterable (false positives with Pydantic fields) - "E1135", # unsupported-membership-test (false positives with Pydantic fields) -] - # Coverage configuration [tool.coverage.run] source = ["app"] diff --git a/requirements-dev.txt b/requirements-dev.txt index 622252c7..7698c84c 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -14,19 +14,14 @@ redis>=4.5.0 # For Redis integration tests boto3>=1.26.0 # For S3 integration tests # Code quality -flake8>=7.0.0 -black>=24.0.0 +ruff>=0.3.0 mypy>=1.8.0 -pylint>=3.0.0 -isort>=5.13.0 # Type stubs for mypy types-requests>=2.31.0 types-paramiko>=3.0.0 -# Security scanning -bandit>=1.7.6 -safety>=3.0.0 +# Security scanning (Ruff includes most security checks from bandit) # Pre-commit hooks pre-commit>=3.6.0 diff --git a/tests/conftest.py b/tests/conftest.py index 6c968a1e..3cc01f87 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -280,6 +280,7 @@ def pytest_configure(config): config.addinivalue_line("markers", "requires_docker: Tests requiring Docker") config.addinivalue_line("markers", "e2e: End-to-end tests with full infrastructure") + # Import OAuth fixtures (must be at end to avoid circular imports) try: from tests.conftest_oauth import ( @@ -290,11 +291,11 @@ try: test_user_info, use_real_oauth, ) - + # Make fixtures available __all__ = [ "mock_oauth_server", - "oauth_config", + "oauth_config", "oauth_enabled_app", "oauth_test_token", "test_user_info", diff --git a/tests/conftest_oauth.py b/tests/conftest_oauth.py index 6c7dbd6e..a5ff8f92 100644 --- a/tests/conftest_oauth.py +++ b/tests/conftest_oauth.py @@ -15,21 +15,23 @@ import pytest from tests.mock_oauth_server import MockOAuth2ServerContainer, create_test_userinfo # Check if we should use real OAuth credentials from environment -_REAL_OAUTH_AVAILABLE = all([ - os.environ.get("AUTHENTIK_CLIENT_ID") not in {"", "NOT_SET", "test-key", None}, - os.environ.get("AUTHENTIK_CLIENT_SECRET") not in {"", "NOT_SET", "test-key", None}, - os.environ.get("AUTHENTIK_CONFIG_URL") not in {"", "NOT_SET", "test-key", None}, -]) +_REAL_OAUTH_AVAILABLE = all( + [ + os.environ.get("AUTHENTIK_CLIENT_ID") not in {"", "NOT_SET", "test-key", None}, + os.environ.get("AUTHENTIK_CLIENT_SECRET") not in {"", "NOT_SET", "test-key", None}, + os.environ.get("AUTHENTIK_CONFIG_URL") not in {"", "NOT_SET", "test-key", None}, + ] +) @pytest.fixture(scope="session") def use_real_oauth() -> bool: """ Determine if tests should use real OAuth credentials. - + Returns True if valid OAuth credentials are available in the environment (typically from GitHub Actions secrets). - + Returns: bool: True if real OAuth should be used, False for mock """ @@ -38,7 +40,7 @@ def use_real_oauth() -> bool: return True if os.environ.get("USE_MOCK_OAUTH", "").lower() in ("true", "1", "yes"): return False - + return _REAL_OAUTH_AVAILABLE @@ -46,10 +48,10 @@ def use_real_oauth() -> bool: def mock_oauth_server() -> Generator[MockOAuth2ServerContainer, None, None]: """ Provide a mock OAuth2/OIDC server for testing. - + This fixture starts a mock-oauth2-server container that provides a complete OIDC provider with all necessary endpoints. - + Yields: MockOAuth2ServerContainer: Running mock OAuth server """ @@ -57,7 +59,7 @@ def mock_oauth_server() -> Generator[MockOAuth2ServerContainer, None, None]: if not _REAL_OAUTH_AVAILABLE or os.environ.get("USE_MOCK_OAUTH", "").lower() in ("true", "1", "yes"): container = MockOAuth2ServerContainer() container.start() - + try: # Wait for the server to be ready container.wait_for_ready() @@ -72,13 +74,13 @@ def mock_oauth_server() -> Generator[MockOAuth2ServerContainer, None, None]: def oauth_config(mock_oauth_server: Optional[MockOAuth2ServerContainer], use_real_oauth: bool) -> Dict[str, str]: """ Provide OAuth configuration for tests. - + Returns either mock OAuth config or real OAuth config based on availability. - + Args: mock_oauth_server: Mock OAuth server fixture (may be None if using real) use_real_oauth: Whether to use real OAuth credentials - + Returns: Dictionary with OAuth configuration """ @@ -95,7 +97,7 @@ def oauth_config(mock_oauth_server: Optional[MockOAuth2ServerContainer], use_rea # Use mock OAuth server if mock_oauth_server is None: pytest.fail("Mock OAuth server not available and real credentials not configured") - + config = mock_oauth_server.get_config() return { "client_id": "test-client-id", @@ -114,7 +116,7 @@ def oauth_config(mock_oauth_server: Optional[MockOAuth2ServerContainer], use_rea def test_user_info() -> Dict: """ Provide test user information for OAuth flows. - + Returns: Dictionary with test user claims """ @@ -135,25 +137,25 @@ def oauth_test_token( ) -> Optional[str]: """ Generate a test OAuth token. - + For mock mode: Creates a valid JWT from the mock server. For real mode: Skips (would need real authentication flow). - + Args: mock_oauth_server: Mock OAuth server test_user_info: User information to include in token use_real_oauth: Whether using real OAuth - + Returns: JWT token string or None if using real OAuth """ if use_real_oauth: # Can't generate tokens for real OAuth - would need actual auth flow return None - + if mock_oauth_server is None: pytest.fail("Mock OAuth server not available") - + # Create a token with the test user info return mock_oauth_server.create_token( subject=test_user_info["sub"], @@ -171,21 +173,20 @@ def oauth_test_token( def oauth_enabled_app(oauth_config: Dict[str, str]): """ Configure the FastAPI app with OAuth enabled for testing. - + This fixture temporarily enables OAuth and configures it with the test OAuth provider (mock or real). - + Args: oauth_config: OAuth configuration - + Yields: Configured test client """ - import os - from app.main import app import app.auth as auth_module - from app.auth import login, oauth_login, oauth_callback, auth, logout + from app.auth import auth, login, logout, oauth_callback, oauth_login + from app.main import app # Save original state original_auth_enabled = auth_module.AUTH_ENABLED diff --git a/tests/fixtures_integration.py b/tests/fixtures_integration.py index 4b911c27..74e6dc84 100644 --- a/tests/fixtures_integration.py +++ b/tests/fixtures_integration.py @@ -14,7 +14,6 @@ These tests exercise the full application stack end-to-end. import os import time -from pathlib import Path from typing import Generator import pytest diff --git a/tests/mock_oauth_server.py b/tests/mock_oauth_server.py index d39410c7..780d165f 100644 --- a/tests/mock_oauth_server.py +++ b/tests/mock_oauth_server.py @@ -8,11 +8,9 @@ and userinfo endpoints. This allows for realistic OAuth testing without requiring a real IdP. """ -import json import logging import time from typing import Dict, Optional -from urllib.parse import urljoin import requests from testcontainers.core.container import DockerContainer @@ -23,7 +21,7 @@ logger = logging.getLogger(__name__) class MockOAuth2ServerContainer(DockerContainer): """ Testcontainer for mock-oauth2-server. - + Provides a complete OIDC provider for testing OAuth2 flows. """ @@ -35,7 +33,7 @@ class MockOAuth2ServerContainer(DockerContainer): ): """ Initialize the mock OAuth2 server container. - + Args: image: Docker image to use port: Internal container port (default 8080) @@ -79,7 +77,7 @@ class MockOAuth2ServerContainer(DockerContainer): def wait_for_ready(self, timeout: int = 30) -> None: """ Wait for the OAuth server to be ready by checking the well-known endpoint. - + Args: timeout: Maximum time to wait in seconds """ @@ -93,13 +91,13 @@ class MockOAuth2ServerContainer(DockerContainer): except requests.exceptions.RequestException: pass time.sleep(0.5) - + raise TimeoutError(f"Mock OAuth2 server did not become ready within {timeout}s") def get_config(self) -> Dict[str, str]: """ Get the OAuth configuration for the mock server. - + Returns: Dictionary with OAuth endpoints and configuration """ @@ -121,36 +119,36 @@ class MockOAuth2ServerContainer(DockerContainer): ) -> str: """ Create a mock JWT token. - + The mock-oauth2-server will generate a valid JWT that can be verified using its JWKS endpoint. - + Args: subject: Subject (sub) claim for the token claims: Additional claims to include in the token audience: Audience (aud) claim - + Returns: JWT token string """ if claims is None: claims = {} - + # Add standard claims token_claims = { "sub": subject, "aud": audience, **claims, } - + # The debugger endpoint expects a different format # For simpler testing, we'll use the token endpoint directly # with a mock authorization code flow - + # Note: For actual tests, we'll mock the token exchange in the tests # This method is mainly for documentation/example purposes logger.info(f"Creating token for subject: {subject}") - + # Return a placeholder - in actual tests we'll mock the OAuth flow return f"mock-token-{subject}" @@ -164,20 +162,20 @@ def create_test_userinfo( ) -> Dict: """ Create a test userinfo response. - + Args: sub: Subject identifier email: User email address name: Full name preferred_username: Username groups: List of group names - + Returns: Dictionary with userinfo claims """ if groups is None: groups = ["admin"] - + return { "sub": sub, "email": email, @@ -197,9 +195,9 @@ def configure_mock_oauth_response( ) -> None: """ Configure the mock OAuth server to return specific responses for a code. - + This is useful for testing the OAuth callback flow. - + Args: container: The mock OAuth server container code: Authorization code to configure @@ -208,7 +206,7 @@ def configure_mock_oauth_response( """ if userinfo is None: userinfo = create_test_userinfo() - + # The mock-oauth2-server automatically handles code exchange # and returns the configured userinfo # This is a placeholder for any additional configuration needed diff --git a/tests/test_api_azure_extended.py b/tests/test_api_azure_extended.py index 00ed3e9e..cb3e6da8 100644 --- a/tests/test_api_azure_extended.py +++ b/tests/test_api_azure_extended.py @@ -1,8 +1,8 @@ """Comprehensive unit tests for app/api/azure.py module.""" -import pytest from unittest.mock import MagicMock, patch -from fastapi.testclient import TestClient + +import pytest @pytest.mark.unit @@ -65,9 +65,10 @@ class TestAzureTestConnection: @patch("app.api.azure.azure.core.exceptions.ClientAuthenticationError") def test_azure_connection_authentication_error(self, mock_auth_error, mock_admin_client_class): """Test connection with authentication error.""" - from app.config import settings import azure.core.exceptions + from app.config import settings + mock_admin_client_class.side_effect = azure.core.exceptions.ClientAuthenticationError("Invalid key") with patch.object(settings, "azure_endpoint", "https://test.cognitiveservices.azure.com/"): @@ -79,9 +80,10 @@ class TestAzureTestConnection: @patch("app.api.azure.DocumentIntelligenceAdministrationClient") def test_azure_connection_service_request_error(self, mock_admin_client_class): """Test connection with service request error.""" - from app.config import settings import azure.core.exceptions + from app.config import settings + mock_admin_client_class.side_effect = azure.core.exceptions.ServiceRequestError("Cannot reach endpoint") with patch.object(settings, "azure_endpoint", "https://test.cognitiveservices.azure.com/"): diff --git a/tests/test_api_diagnostic_extended.py b/tests/test_api_diagnostic_extended.py index 27692b63..2721fb0f 100644 --- a/tests/test_api_diagnostic_extended.py +++ b/tests/test_api_diagnostic_extended.py @@ -1,8 +1,9 @@ """Comprehensive unit tests for app/api/diagnostic.py module.""" +from unittest.mock import patch + import pytest from fastapi.testclient import TestClient -from unittest.mock import MagicMock, patch @pytest.mark.unit @@ -231,9 +232,7 @@ class TestTestNotification: mock_send.return_value = True - with patch.object( - settings, "notification_urls", ["https://ntfy.sh/test1", "https://ntfy.sh/test2"] - ): + with patch.object(settings, "notification_urls", ["https://ntfy.sh/test1", "https://ntfy.sh/test2"]): # Response should indicate 2 services pass diff --git a/tests/test_api_dropbox.py b/tests/test_api_dropbox.py index 67bb01f3..d496115d 100644 --- a/tests/test_api_dropbox.py +++ b/tests/test_api_dropbox.py @@ -4,8 +4,7 @@ Tests for app/api/dropbox.py module. Covers Dropbox OAuth endpoints, settings management, and token testing. """ -import os -from unittest.mock import MagicMock, Mock, patch +from unittest.mock import Mock, patch import pytest import requests diff --git a/tests/test_api_dropbox_extended.py b/tests/test_api_dropbox_extended.py index 22364142..5c4a7ee8 100644 --- a/tests/test_api_dropbox_extended.py +++ b/tests/test_api_dropbox_extended.py @@ -1,8 +1,8 @@ """Comprehensive unit tests for app/api/dropbox.py module.""" +from unittest.mock import MagicMock, patch + import pytest -from unittest.mock import MagicMock, patch, Mock -from fastapi import HTTPException @pytest.mark.unit @@ -53,21 +53,18 @@ class TestUpdateDropboxSettings: def test_update_settings_refresh_token(self): """Test updating only refresh token.""" - from app.config import settings # Should update settings.dropbox_refresh_token pass def test_update_settings_all_fields(self): """Test updating all Dropbox settings.""" - from app.config import settings # Should update all fields: refresh_token, app_key, app_secret, folder_path pass def test_update_settings_partial_fields(self): """Test updating some fields (not all).""" - from app.config import settings # Should only update provided fields pass @@ -275,7 +272,6 @@ class TestSaveDropboxSettings: @patch("os.path.exists") def test_save_settings_updates_memory(self, mock_exists, mock_open): """Test that in-memory settings are updated.""" - from app.config import settings mock_exists.return_value = True mock_file = MagicMock() diff --git a/tests/test_api_files_comprehensive.py b/tests/test_api_files_comprehensive.py index 602bbc4f..c6e19a31 100644 --- a/tests/test_api_files_comprehensive.py +++ b/tests/test_api_files_comprehensive.py @@ -5,9 +5,8 @@ Tests all API endpoints with success and error cases, proper mocking, and edge c Target: Bring coverage from 11.75% to 70%+ """ -import os from io import BytesIO -from unittest.mock import Mock, MagicMock, patch +from unittest.mock import Mock, patch import pytest from fastapi import HTTPException @@ -38,14 +37,14 @@ class TestListFilesAPI: original_filename="test1.pdf", local_filename="/tmp/test1.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) file2 = FileRecord( filehash="hash2", original_filename="test2.pdf", local_filename="/tmp/test2.pdf", file_size=2048, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file1) db_session.add(file2) @@ -66,7 +65,7 @@ class TestListFilesAPI: original_filename=f"test{i}.pdf", local_filename=f"/tmp/test{i}.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -93,14 +92,14 @@ class TestListFilesAPI: original_filename="invoice.pdf", local_filename="/tmp/invoice.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) file2 = FileRecord( filehash="hash2", original_filename="receipt.pdf", local_filename="/tmp/receipt.pdf", file_size=2048, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file1) db_session.add(file2) @@ -119,14 +118,14 @@ class TestListFilesAPI: original_filename="doc.pdf", local_filename="/tmp/doc.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) file2 = FileRecord( filehash="hash2", original_filename="image.jpg", local_filename="/tmp/image.jpg", file_size=2048, - mime_type="image/jpeg" + mime_type="image/jpeg", ) db_session.add(file1) db_session.add(file2) @@ -140,8 +139,20 @@ class TestListFilesAPI: def test_list_files_sorting_asc(self, client: TestClient, db_session): """Test ascending sort order.""" - file1 = FileRecord(filehash="hash1", original_filename="aaa.pdf", local_filename="/tmp/aaa.pdf", file_size=1024, mime_type="application/pdf") - file2 = FileRecord(filehash="hash2", original_filename="zzz.pdf", local_filename="/tmp/zzz.pdf", file_size=2048, mime_type="application/pdf") + file1 = FileRecord( + filehash="hash1", + original_filename="aaa.pdf", + local_filename="/tmp/aaa.pdf", + file_size=1024, + mime_type="application/pdf", + ) + file2 = FileRecord( + filehash="hash2", + original_filename="zzz.pdf", + local_filename="/tmp/zzz.pdf", + file_size=2048, + mime_type="application/pdf", + ) db_session.add(file1) db_session.add(file2) db_session.commit() @@ -154,8 +165,20 @@ class TestListFilesAPI: def test_list_files_sorting_desc(self, client: TestClient, db_session): """Test descending sort order.""" - file1 = FileRecord(filehash="hash1", original_filename="aaa.pdf", local_filename="/tmp/aaa.pdf", file_size=1024, mime_type="application/pdf") - file2 = FileRecord(filehash="hash2", original_filename="zzz.pdf", local_filename="/tmp/zzz.pdf", file_size=2048, mime_type="application/pdf") + file1 = FileRecord( + filehash="hash1", + original_filename="aaa.pdf", + local_filename="/tmp/aaa.pdf", + file_size=1024, + mime_type="application/pdf", + ) + file2 = FileRecord( + filehash="hash2", + original_filename="zzz.pdf", + local_filename="/tmp/zzz.pdf", + file_size=2048, + mime_type="application/pdf", + ) db_session.add(file1) db_session.add(file2) db_session.commit() @@ -178,7 +201,7 @@ class TestGetFileDetails: original_filename="test.pdf", local_filename="/tmp/test.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -205,7 +228,7 @@ class TestGetFileDetails: original_filename="test.pdf", local_filename="/tmp/test.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -216,7 +239,7 @@ class TestGetFileDetails: task_id="task123", step_name="process_document", status="success", - message="Processing completed" + message="Processing completed", ) db_session.add(log) db_session.commit() @@ -241,7 +264,7 @@ class TestDeleteFileRecord: original_filename="test.pdf", local_filename="/tmp/test.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -263,7 +286,7 @@ class TestDeleteFileRecord: original_filename="test.pdf", local_filename="/tmp/test.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -286,8 +309,20 @@ class TestBulkDeleteFiles: @patch("app.config.settings.allow_file_delete", True) def test_bulk_delete_success(self, client: TestClient, db_session): """Test bulk deletion of multiple files.""" - file1 = FileRecord(filehash="hash1", original_filename="test1.pdf", local_filename="/tmp/test1.pdf", file_size=1024, mime_type="application/pdf") - file2 = FileRecord(filehash="hash2", original_filename="test2.pdf", local_filename="/tmp/test2.pdf", file_size=2048, mime_type="application/pdf") + file1 = FileRecord( + filehash="hash1", + original_filename="test1.pdf", + local_filename="/tmp/test1.pdf", + file_size=1024, + mime_type="application/pdf", + ) + file2 = FileRecord( + filehash="hash2", + original_filename="test2.pdf", + local_filename="/tmp/test2.pdf", + file_size=2048, + mime_type="application/pdf", + ) db_session.add(file1) db_session.add(file2) db_session.commit() @@ -326,13 +361,13 @@ class TestBulkReprocessFiles: # Create files with existing local files file1_path = tmp_path / "test1.pdf" file1_path.write_bytes(b"%PDF-1.4") - + file1 = FileRecord( filehash="hash1", original_filename="test1.pdf", local_filename=str(file1_path), file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file1) db_session.commit() @@ -357,7 +392,7 @@ class TestBulkReprocessFiles: original_filename="test.pdf", local_filename="/nonexistent/test.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -385,13 +420,13 @@ class TestReprocessSingleFile: # Create file with existing local file file_path = tmp_path / "test.pdf" file_path.write_bytes(b"%PDF-1.4") - + file = FileRecord( filehash="hash1", original_filename="test.pdf", local_filename=str(file_path), file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -420,7 +455,7 @@ class TestReprocessSingleFile: original_filename="test.pdf", local_filename="/nonexistent/test.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -439,14 +474,14 @@ class TestReprocessWithCloudOCR: """Test reprocessing with forced cloud OCR.""" file_path = tmp_path / "test.pdf" file_path.write_bytes(b"%PDF-1.4") - + file = FileRecord( filehash="hash1", original_filename="test.pdf", local_filename=str(file_path), original_file_path=str(file_path), file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -474,7 +509,7 @@ class TestReprocessWithCloudOCR: original_filename="test.pdf", local_filename="/nonexistent/test.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -502,7 +537,7 @@ class TestRetrySubtask: original_filename="test.pdf", local_filename="/tmp/test.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -525,7 +560,7 @@ class TestRetrySubtask: original_filename="test.pdf", local_filename="/tmp/test.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -548,13 +583,13 @@ class TestFilePreview: """Test previewing original file.""" file_path = tmp_path / "test.pdf" file_path.write_bytes(b"%PDF-1.4") - + file = FileRecord( filehash="hash1", original_filename="test.pdf", local_filename=str(file_path), file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -575,7 +610,7 @@ class TestFilePreview: original_filename="test.pdf", local_filename="/nonexistent/test.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -591,7 +626,7 @@ class TestFilePreview: original_filename="test.pdf", local_filename="/tmp/test.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -608,13 +643,13 @@ class TestFileDownload: """Test downloading original file.""" file_path = tmp_path / "test.pdf" file_path.write_bytes(b"%PDF-1.4") - + file = FileRecord( filehash="hash1", original_filename="test.pdf", local_filename=str(file_path), file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -643,14 +678,13 @@ class TestUIUpload: mock_delay.return_value = mock_task # Create PDF content - pdf_content = b"%PDF-1.4\n%\xE2\xE3\xCF\xD3\n" + pdf_content = b"%PDF-1.4\n%\xe2\xe3\xcf\xd3\n" with patch("app.config.settings.workdir", str(tmp_path)): response = client.post( - "/api/ui-upload", - files={"file": ("test.pdf", BytesIO(pdf_content), "application/pdf")} + "/api/ui-upload", files={"file": ("test.pdf", BytesIO(pdf_content), "application/pdf")} ) - + assert response.status_code == 200 data = response.json() assert "task_id" in data @@ -671,11 +705,8 @@ class TestUIUpload: image_content = b"\x89PNG\r\n\x1a\n" with patch("app.config.settings.workdir", str(tmp_path)): - response = client.post( - "/api/ui-upload", - files={"file": ("image.png", BytesIO(image_content), "image/png")} - ) - + response = client.post("/api/ui-upload", files={"file": ("image.png", BytesIO(image_content), "image/png")}) + assert response.status_code == 200 data = response.json() assert "task_id" in data @@ -690,10 +721,9 @@ class TestUIUpload: with patch("app.config.settings.workdir", str(tmp_path)): response = client.post( - "/api/ui-upload", - files={"file": ("large.pdf", BytesIO(large_content), "application/pdf")} + "/api/ui-upload", files={"file": ("large.pdf", BytesIO(large_content), "application/pdf")} ) - + assert response.status_code == 413 assert "too large" in response.json()["detail"].lower() @@ -712,9 +742,9 @@ class TestUIUpload: # Upload with unsafe filename response = client.post( "/api/ui-upload", - files={"file": ("../../../etc/passwd.pdf", BytesIO(pdf_content), "application/pdf")} + files={"file": ("../../../etc/passwd.pdf", BytesIO(pdf_content), "application/pdf")}, ) - + assert response.status_code == 200 data = response.json() # Filename should be sanitized (no path traversal) @@ -729,12 +759,12 @@ class TestExtractTextFromPDF: def test_extract_text_from_pdf(self, tmp_path): """Test text extraction from PDF.""" from app.api.files import _extract_text_from_pdf - + # Create a simple PDF with text pdf_path = tmp_path / "test.pdf" # This is a minimal PDF - in reality would have text pdf_path.write_bytes(b"%PDF-1.4\n%%EOF") - + # Should not raise exception try: text = _extract_text_from_pdf(str(pdf_path)) @@ -752,16 +782,16 @@ class TestRetryPipelineStep: def test_retry_process_document_step(self, mock_delay, db_session, tmp_path): """Test retrying process_document step.""" from app.api.files import _retry_pipeline_step - + file_path = tmp_path / "test.pdf" file_path.write_bytes(b"%PDF-1.4") - + file = FileRecord( filehash="hash1", original_filename="test.pdf", local_filename=str(file_path), file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -778,13 +808,13 @@ class TestRetryPipelineStep: def test_retry_unsupported_step_raises_error(self, db_session): """Test that unsupported step name raises error.""" from app.api.files import _retry_pipeline_step - + file = FileRecord( filehash="hash1", original_filename="test.pdf", local_filename="/tmp/test.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() diff --git a/tests/test_api_google_drive_comprehensive.py b/tests/test_api_google_drive_comprehensive.py index 2e010851..360416a1 100644 --- a/tests/test_api_google_drive_comprehensive.py +++ b/tests/test_api_google_drive_comprehensive.py @@ -5,9 +5,8 @@ Tests all API endpoints with success and error cases, proper mocking, and edge c Target: Bring coverage from 9.45% to 70%+ """ -import os from datetime import datetime, timedelta -from unittest.mock import Mock, MagicMock, patch, mock_open +from unittest.mock import MagicMock, Mock, mock_open, patch import pytest from fastapi import HTTPException @@ -24,7 +23,7 @@ class TestExchangeGoogleDriveToken: mock_exchange.return_value = { "refresh_token": "test_refresh_token", "access_token": "test_access_token", - "expires_in": 3600 + "expires_in": 3600, } response = client.post( @@ -34,8 +33,8 @@ class TestExchangeGoogleDriveToken: "client_secret": "test_client_secret", "redirect_uri": "http://localhost/callback", "code": "test_auth_code", - "folder_id": "test_folder" - } + "folder_id": "test_folder", + }, ) assert response.status_code == 200 @@ -52,7 +51,7 @@ class TestExchangeGoogleDriveToken: mock_exchange.return_value = { "refresh_token": "test_refresh_token", "access_token": "test_access_token", - "expires_in": 3600 + "expires_in": 3600, } response = client.post( @@ -61,8 +60,8 @@ class TestExchangeGoogleDriveToken: "client_id": "test_client_id", "client_secret": "test_client_secret", "redirect_uri": "http://localhost/callback", - "code": "test_auth_code" - } + "code": "test_auth_code", + }, ) assert response.status_code == 200 @@ -78,8 +77,8 @@ class TestExchangeGoogleDriveToken: "client_id": "test_client_id", "client_secret": "test_client_secret", "redirect_uri": "http://localhost/callback", - "code": "invalid_code" - } + "code": "invalid_code", + }, ) assert response.status_code == 400 @@ -99,8 +98,8 @@ class TestUpdateGoogleDriveSettings: "client_id": "new_client_id", "client_secret": "new_client_secret", "folder_id": "new_folder_id", - "use_oauth": "true" - } + "use_oauth": "true", + }, ) assert response.status_code == 200 @@ -112,11 +111,7 @@ class TestUpdateGoogleDriveSettings: def test_update_settings_with_use_oauth_false(self, mock_settings, client: TestClient): """Test updating with OAuth disabled.""" response = client.post( - "/api/google-drive/update-settings", - data={ - "refresh_token": "new_refresh_token", - "use_oauth": "false" - } + "/api/google-drive/update-settings", data={"refresh_token": "new_refresh_token", "use_oauth": "false"} ) assert response.status_code == 200 @@ -124,21 +119,13 @@ class TestUpdateGoogleDriveSettings: @patch("app.config.settings") def test_update_settings_minimal(self, mock_settings, client: TestClient): """Test update with only required fields.""" - response = client.post( - "/api/google-drive/update-settings", - data={ - "refresh_token": "new_refresh_token" - } - ) + response = client.post("/api/google-drive/update-settings", data={"refresh_token": "new_refresh_token"}) assert response.status_code == 200 def test_update_settings_missing_required_field(self, client: TestClient): """Test update without required refresh_token.""" - response = client.post( - "/api/google-drive/update-settings", - data={} - ) + response = client.post("/api/google-drive/update-settings", data={}) assert response.status_code == 422 # Validation error @@ -160,9 +147,7 @@ class TestTestGoogleDriveToken: # Mock the Google Drive service mock_service = MagicMock() mock_about = MagicMock() - mock_about.get.return_value.execute.return_value = { - "user": {"emailAddress": "test@example.com"} - } + mock_about.get.return_value.execute.return_value = {"user": {"emailAddress": "test@example.com"}} mock_service.about.return_value = mock_about mock_get_service.return_value = mock_service @@ -208,7 +193,7 @@ class TestTestGoogleDriveToken: with patch("google.oauth2.credentials.Credentials"): response = client.get("/api/google-drive/test-token") - + assert response.status_code == 200 data = response.json() assert data["status"] == "error" @@ -251,12 +236,13 @@ class TestGetGoogleDriveTokenInfo: mock_creds.valid = False mock_creds.token = "test_access_token" mock_creds.expiry = datetime.now() + timedelta(hours=1) - + # Mock refresh def mock_refresh(request): mock_creds.valid = True + mock_creds.refresh = mock_refresh - + mock_creds_class.return_value = mock_creds response = client.get("/api/google-drive/get-token-info") @@ -315,18 +301,20 @@ class TestFormatTimeRemaining: def test_format_expired_time(self): """Test formatting of expired time.""" - from app.api.google_drive import format_time_remaining from datetime import timedelta - + + from app.api.google_drive import format_time_remaining + expired = timedelta(seconds=-100) result = format_time_remaining(expired) assert result == "Expired" def test_format_days_and_hours(self): """Test formatting with days and hours.""" - from app.api.google_drive import format_time_remaining from datetime import timedelta - + + from app.api.google_drive import format_time_remaining + time_left = timedelta(days=2, hours=5, minutes=30) result = format_time_remaining(time_left) assert "2 days" in result @@ -335,9 +323,10 @@ class TestFormatTimeRemaining: def test_format_hours_and_minutes(self): """Test formatting with hours and minutes.""" - from app.api.google_drive import format_time_remaining from datetime import timedelta - + + from app.api.google_drive import format_time_remaining + time_left = timedelta(hours=3, minutes=45) result = format_time_remaining(time_left) assert "3 hours" in result @@ -345,18 +334,20 @@ class TestFormatTimeRemaining: def test_format_minutes_only(self): """Test formatting with only minutes.""" - from app.api.google_drive import format_time_remaining from datetime import timedelta - + + from app.api.google_drive import format_time_remaining + time_left = timedelta(minutes=30) result = format_time_remaining(time_left) assert "30 minutes" in result def test_format_single_unit(self): """Test singular form (1 day, not 1 days).""" - from app.api.google_drive import format_time_remaining from datetime import timedelta - + + from app.api.google_drive import format_time_remaining + time_left = timedelta(days=1, hours=0) result = format_time_remaining(time_left) # Should use singular "day" not plural "days" @@ -385,8 +376,8 @@ class TestSaveGoogleDriveSettings: "client_id": "new_client_id", "client_secret": "new_client_secret", "folder_id": "new_folder_id", - "use_oauth": "true" - } + "use_oauth": "true", + }, ) assert response.status_code == 200 @@ -402,11 +393,7 @@ class TestSaveGoogleDriveSettings: mock_dirname.return_value = "/app" response = client.post( - "/api/google-drive/save-settings", - data={ - "refresh_token": "new_refresh_token", - "use_oauth": "true" - } + "/api/google-drive/save-settings", data={"refresh_token": "new_refresh_token", "use_oauth": "true"} ) assert response.status_code == 200 @@ -418,17 +405,15 @@ class TestSaveGoogleDriveSettings: @patch("os.path.exists") @patch("os.path.dirname") @patch("app.config.settings") - def test_save_settings_updates_existing_lines(self, mock_settings, mock_dirname, mock_exists, mock_file, client: TestClient): + def test_save_settings_updates_existing_lines( + self, mock_settings, mock_dirname, mock_exists, mock_file, client: TestClient + ): """Test that existing settings are updated, not duplicated.""" mock_exists.return_value = True mock_dirname.return_value = "/app" response = client.post( - "/api/google-drive/save-settings", - data={ - "refresh_token": "updated_token", - "use_oauth": "true" - } + "/api/google-drive/save-settings", data={"refresh_token": "updated_token", "use_oauth": "true"} ) assert response.status_code == 200 @@ -437,18 +422,16 @@ class TestSaveGoogleDriveSettings: @patch("os.path.exists") @patch("os.path.dirname") @patch("app.config.settings") - def test_save_settings_uncomments_lines(self, mock_settings, mock_dirname, mock_exists, mock_file, client: TestClient): + def test_save_settings_uncomments_lines( + self, mock_settings, mock_dirname, mock_exists, mock_file, client: TestClient + ): """Test that commented settings are uncommented when updated.""" mock_exists.return_value = True mock_dirname.return_value = "/app" response = client.post( "/api/google-drive/save-settings", - data={ - "refresh_token": "new_token", - "client_id": "new_client_id", - "use_oauth": "true" - } + data={"refresh_token": "new_token", "client_id": "new_client_id", "use_oauth": "true"}, ) assert response.status_code == 200 @@ -458,11 +441,7 @@ class TestSaveGoogleDriveSettings: """Test saving with OAuth disabled.""" with patch("os.path.exists", return_value=False): response = client.post( - "/api/google-drive/save-settings", - data={ - "refresh_token": "token", - "use_oauth": "false" - } + "/api/google-drive/save-settings", data={"refresh_token": "token", "use_oauth": "false"} ) assert response.status_code == 200 @@ -471,17 +450,15 @@ class TestSaveGoogleDriveSettings: @patch("os.path.exists") @patch("os.path.dirname") @patch("app.config.settings") - def test_save_settings_file_write_error_continues(self, mock_settings, mock_dirname, mock_exists, mock_file, client: TestClient): + def test_save_settings_file_write_error_continues( + self, mock_settings, mock_dirname, mock_exists, mock_file, client: TestClient + ): """Test that file write errors don't prevent in-memory update.""" mock_exists.return_value = True mock_dirname.return_value = "/app" response = client.post( - "/api/google-drive/save-settings", - data={ - "refresh_token": "new_token", - "use_oauth": "true" - } + "/api/google-drive/save-settings", data={"refresh_token": "new_token", "use_oauth": "true"} ) # Should still succeed with in-memory update @@ -489,12 +466,7 @@ class TestSaveGoogleDriveSettings: def test_save_settings_missing_required_field(self, client: TestClient): """Test save without required refresh_token.""" - response = client.post( - "/api/google-drive/save-settings", - data={ - "use_oauth": "true" - } - ) + response = client.post("/api/google-drive/save-settings", data={"use_oauth": "true"}) assert response.status_code == 422 # Validation error @@ -504,10 +476,7 @@ class TestSaveGoogleDriveSettings: with patch("os.path.exists", return_value=False): response = client.post( "/api/google-drive/save-settings", - data={ - "refresh_token": "existing_token", - "folder_id": "new_folder_id" - } + data={"refresh_token": "existing_token", "folder_id": "new_folder_id"}, ) assert response.status_code == 200 @@ -519,13 +488,7 @@ class TestSaveGoogleDriveSettings: """Test exception handling in save settings.""" mock_exists.side_effect = Exception("Unexpected error") - response = client.post( - "/api/google-drive/save-settings", - data={ - "refresh_token": "token", - "use_oauth": "true" - } - ) + response = client.post("/api/google-drive/save-settings", data={"refresh_token": "token", "use_oauth": "true"}) assert response.status_code == 500 data = response.json() @@ -549,7 +512,7 @@ class TestGoogleDriveIntegration: mock_exchange.return_value = { "refresh_token": "new_refresh_token", "access_token": "new_access_token", - "expires_in": 3600 + "expires_in": 3600, } response = client.post( @@ -558,8 +521,8 @@ class TestGoogleDriveIntegration: "client_id": "test_client_id", "client_secret": "test_client_secret", "redirect_uri": "http://localhost/callback", - "code": "auth_code" - } + "code": "auth_code", + }, ) assert response.status_code == 200 @@ -570,10 +533,7 @@ class TestGoogleDriveIntegration: with patch("os.path.exists", return_value=False): response = client.post( "/api/google-drive/update-settings", - data={ - "refresh_token": token_data["refresh_token"], - "use_oauth": "true" - } + data={"refresh_token": token_data["refresh_token"], "use_oauth": "true"}, ) assert response.status_code == 200 diff --git a/tests/test_api_google_drive_extended.py b/tests/test_api_google_drive_extended.py index 3b6f87c0..3526b6ed 100644 --- a/tests/test_api_google_drive_extended.py +++ b/tests/test_api_google_drive_extended.py @@ -1,8 +1,9 @@ """Comprehensive unit tests for app/api/google_drive.py module.""" -import pytest -from unittest.mock import MagicMock, patch from datetime import datetime, timedelta +from unittest.mock import MagicMock, patch + +import pytest @pytest.mark.unit @@ -39,14 +40,12 @@ class TestUpdateGoogleDriveSettings: def test_update_settings_oauth_enabled(self): """Test updating settings with OAuth enabled.""" - from app.config import settings # Should update OAuth credentials pass def test_update_settings_oauth_disabled(self): """Test updating settings with OAuth disabled.""" - from app.config import settings # Should set use_oauth to False pass diff --git a/tests/test_api_logs.py b/tests/test_api_logs.py index 3dda8f8d..e08e8cf2 100644 --- a/tests/test_api_logs.py +++ b/tests/test_api_logs.py @@ -1,7 +1,5 @@ """Tests for app/api/logs.py module.""" -from datetime import datetime - import pytest from app.models import FileRecord, ProcessingLog diff --git a/tests/test_api_onedrive_comprehensive.py b/tests/test_api_onedrive_comprehensive.py index 83a9318d..1da7d30d 100644 --- a/tests/test_api_onedrive_comprehensive.py +++ b/tests/test_api_onedrive_comprehensive.py @@ -5,9 +5,8 @@ Tests all API endpoints with success and error cases, proper mocking, and edge c Target: Bring coverage from 10.51% to 70%+ """ -import os -from datetime import datetime, timedelta -from unittest.mock import Mock, MagicMock, patch, mock_open +from datetime import timedelta +from unittest.mock import Mock, mock_open, patch import pytest from fastapi import HTTPException @@ -24,7 +23,7 @@ class TestExchangeOneDriveToken: mock_exchange.return_value = { "refresh_token": "test_refresh_token", "access_token": "test_access_token", - "expires_in": 3600 + "expires_in": 3600, } response = client.post( @@ -34,8 +33,8 @@ class TestExchangeOneDriveToken: "client_secret": "test_client_secret", "redirect_uri": "http://localhost/callback", "code": "test_auth_code", - "tenant_id": "common" - } + "tenant_id": "common", + }, ) assert response.status_code == 200 @@ -51,7 +50,7 @@ class TestExchangeOneDriveToken: mock_exchange.return_value = { "refresh_token": "test_refresh_token", "access_token": "test_access_token", - "expires_in": 3600 + "expires_in": 3600, } response = client.post( @@ -61,8 +60,8 @@ class TestExchangeOneDriveToken: "client_secret": "test_client_secret", "redirect_uri": "http://localhost/callback", "code": "test_auth_code", - "tenant_id": "specific-tenant-id" - } + "tenant_id": "specific-tenant-id", + }, ) assert response.status_code == 200 @@ -82,8 +81,8 @@ class TestExchangeOneDriveToken: "client_secret": "test_client_secret", "redirect_uri": "http://localhost/callback", "code": "invalid_code", - "tenant_id": "common" - } + "tenant_id": "common", + }, ) assert response.status_code == 400 @@ -95,7 +94,7 @@ class TestExchangeOneDriveToken: data={ "client_id": "test_client_id" # Missing other required fields - } + }, ) assert response.status_code == 422 # Validation error @@ -120,19 +119,13 @@ class TestTestOneDriveToken: # Mock token refresh response mock_post_response = Mock() mock_post_response.status_code = 200 - mock_post_response.json.return_value = { - "access_token": "test_access_token", - "expires_in": 3600 - } + mock_post_response.json.return_value = {"access_token": "test_access_token", "expires_in": 3600} mock_post.return_value = mock_post_response # Mock user info response mock_get_response = Mock() mock_get_response.status_code = 200 - mock_get_response.json.return_value = { - "displayName": "Test User", - "userPrincipalName": "test@example.com" - } + mock_get_response.json.return_value = {"displayName": "Test User", "userPrincipalName": "test@example.com"} mock_get.return_value = mock_get_response response = client.get("/api/onedrive/test-token") @@ -198,17 +191,14 @@ class TestTestOneDriveToken: mock_post_response.json.return_value = { "access_token": "test_access_token", "refresh_token": "new_refresh_token", # New token - "expires_in": 3600 + "expires_in": 3600, } mock_post.return_value = mock_post_response # Mock user info mock_get_response = Mock() mock_get_response.status_code = 200 - mock_get_response.json.return_value = { - "displayName": "Test User", - "userPrincipalName": "test@example.com" - } + mock_get_response.json.return_value = {"displayName": "Test User", "userPrincipalName": "test@example.com"} mock_get.return_value = mock_get_response with patch("os.path.exists", return_value=False): @@ -223,7 +213,9 @@ class TestTestOneDriveToken: @patch("os.path.exists") @patch("os.path.dirname") @patch("app.config.settings") - def test_test_token_updates_env_file(self, mock_settings, mock_dirname, mock_exists, mock_file, mock_get, mock_post, client: TestClient): + def test_test_token_updates_env_file( + self, mock_settings, mock_dirname, mock_exists, mock_file, mock_get, mock_post, client: TestClient + ): """Test that new refresh token is saved to .env file.""" mock_settings.onedrive_refresh_token = "old_token" mock_settings.onedrive_client_id = "test_client_id" @@ -239,17 +231,14 @@ class TestTestOneDriveToken: mock_post_response.json.return_value = { "access_token": "test_access_token", "refresh_token": "new_token", - "expires_in": 3600 + "expires_in": 3600, } mock_post.return_value = mock_post_response # Mock user info mock_get_response = Mock() mock_get_response.status_code = 200 - mock_get_response.json.return_value = { - "displayName": "Test User", - "userPrincipalName": "test@example.com" - } + mock_get_response.json.return_value = {"displayName": "Test User", "userPrincipalName": "test@example.com"} mock_get.return_value = mock_get_response response = client.get("/api/onedrive/test-token") @@ -269,10 +258,7 @@ class TestTestOneDriveToken: # Mock successful refresh mock_post_response = Mock() mock_post_response.status_code = 200 - mock_post_response.json.return_value = { - "access_token": "test_access_token", - "expires_in": 3600 - } + mock_post_response.json.return_value = {"access_token": "test_access_token", "expires_in": 3600} mock_post.return_value = mock_post_response # Mock failed user info @@ -295,8 +281,7 @@ class TestFormatTimeRemaining: def test_format_expired_time(self): """Test formatting of expired time.""" from app.api.onedrive import format_time_remaining - from datetime import timedelta - + expired = timedelta(seconds=-100) result = format_time_remaining(expired) assert result == "Expired" @@ -304,8 +289,7 @@ class TestFormatTimeRemaining: def test_format_days_and_hours(self): """Test formatting with days and hours.""" from app.api.onedrive import format_time_remaining - from datetime import timedelta - + time_left = timedelta(days=2, hours=5, minutes=30) result = format_time_remaining(time_left) assert "2 days" in result @@ -314,8 +298,7 @@ class TestFormatTimeRemaining: def test_format_hours_only(self): """Test formatting with hours only.""" from app.api.onedrive import format_time_remaining - from datetime import timedelta - + time_left = timedelta(hours=5) result = format_time_remaining(time_left) assert "5 hours" in result @@ -323,8 +306,7 @@ class TestFormatTimeRemaining: def test_format_minutes_only(self): """Test formatting with minutes only.""" from app.api.onedrive import format_time_remaining - from datetime import timedelta - + time_left = timedelta(minutes=45) result = format_time_remaining(time_left) assert "45 minutes" in result @@ -350,8 +332,8 @@ class TestSaveOneDriveSettings: "client_id": "new_client_id", "client_secret": "new_client_secret", "tenant_id": "common", - "folder_path": "/Documents" - } + "folder_path": "/Documents", + }, ) assert response.status_code == 200 @@ -365,13 +347,7 @@ class TestSaveOneDriveSettings: mock_exists.return_value = False mock_dirname.return_value = "/app" - response = client.post( - "/api/onedrive/save-settings", - data={ - "refresh_token": "token", - "tenant_id": "common" - } - ) + response = client.post("/api/onedrive/save-settings", data={"refresh_token": "token", "tenant_id": "common"}) assert response.status_code == 500 data = response.json() @@ -381,17 +357,15 @@ class TestSaveOneDriveSettings: @patch("os.path.exists") @patch("os.path.dirname") @patch("app.config.settings") - def test_save_settings_updates_existing_lines(self, mock_settings, mock_dirname, mock_exists, mock_file, client: TestClient): + def test_save_settings_updates_existing_lines( + self, mock_settings, mock_dirname, mock_exists, mock_file, client: TestClient + ): """Test that existing settings are updated.""" mock_exists.return_value = True mock_dirname.return_value = "/app" response = client.post( - "/api/onedrive/save-settings", - data={ - "refresh_token": "updated_token", - "tenant_id": "common" - } + "/api/onedrive/save-settings", data={"refresh_token": "updated_token", "tenant_id": "common"} ) assert response.status_code == 200 @@ -400,18 +374,16 @@ class TestSaveOneDriveSettings: @patch("os.path.exists") @patch("os.path.dirname") @patch("app.config.settings") - def test_save_settings_uncomments_lines(self, mock_settings, mock_dirname, mock_exists, mock_file, client: TestClient): + def test_save_settings_uncomments_lines( + self, mock_settings, mock_dirname, mock_exists, mock_file, client: TestClient + ): """Test that commented settings are uncommented.""" mock_exists.return_value = True mock_dirname.return_value = "/app" response = client.post( "/api/onedrive/save-settings", - data={ - "refresh_token": "token", - "client_id": "new_client_id", - "tenant_id": "common" - } + data={"refresh_token": "token", "client_id": "new_client_id", "tenant_id": "common"}, ) assert response.status_code == 200 @@ -420,30 +392,23 @@ class TestSaveOneDriveSettings: @patch("os.path.exists") @patch("os.path.dirname") @patch("app.config.settings") - def test_save_settings_adds_new_lines(self, mock_settings, mock_dirname, mock_exists, mock_file, client: TestClient): + def test_save_settings_adds_new_lines( + self, mock_settings, mock_dirname, mock_exists, mock_file, client: TestClient + ): """Test that new settings are added if not present.""" mock_exists.return_value = True mock_dirname.return_value = "/app" response = client.post( "/api/onedrive/save-settings", - data={ - "refresh_token": "new_token", - "folder_path": "/New/Path", - "tenant_id": "common" - } + data={"refresh_token": "new_token", "folder_path": "/New/Path", "tenant_id": "common"}, ) assert response.status_code == 200 def test_save_settings_missing_required_field(self, client: TestClient): """Test save without required refresh_token.""" - response = client.post( - "/api/onedrive/save-settings", - data={ - "tenant_id": "common" - } - ) + response = client.post("/api/onedrive/save-settings", data={"tenant_id": "common"}) assert response.status_code == 422 # Validation error @@ -453,13 +418,7 @@ class TestSaveOneDriveSettings: """Test exception handling in save settings.""" mock_exists.side_effect = Exception("Unexpected error") - response = client.post( - "/api/onedrive/save-settings", - data={ - "refresh_token": "token", - "tenant_id": "common" - } - ) + response = client.post("/api/onedrive/save-settings", data={"refresh_token": "token", "tenant_id": "common"}) assert response.status_code == 500 @@ -481,8 +440,8 @@ class TestUpdateOneDriveSettings: "client_id": "new_client_id", "client_secret": "new_client_secret", "tenant_id": "common", - "folder_path": "/Documents" - } + "folder_path": "/Documents", + }, ) assert response.status_code == 200 @@ -496,11 +455,7 @@ class TestUpdateOneDriveSettings: mock_get_token.return_value = "test_token" response = client.post( - "/api/onedrive/update-settings", - data={ - "refresh_token": "new_token", - "tenant_id": "common" - } + "/api/onedrive/update-settings", data={"refresh_token": "new_token", "tenant_id": "common"} ) assert response.status_code == 200 @@ -512,11 +467,7 @@ class TestUpdateOneDriveSettings: mock_get_token.side_effect = Exception("Token invalid") response = client.post( - "/api/onedrive/update-settings", - data={ - "refresh_token": "bad_token", - "tenant_id": "common" - } + "/api/onedrive/update-settings", data={"refresh_token": "bad_token", "tenant_id": "common"} ) assert response.status_code == 200 @@ -526,12 +477,7 @@ class TestUpdateOneDriveSettings: def test_update_settings_missing_required_field(self, client: TestClient): """Test update without required refresh_token.""" - response = client.post( - "/api/onedrive/update-settings", - data={ - "tenant_id": "common" - } - ) + response = client.post("/api/onedrive/update-settings", data={"tenant_id": "common"}) assert response.status_code == 422 @@ -539,14 +485,10 @@ class TestUpdateOneDriveSettings: def test_update_settings_exception_handling(self, mock_settings, client: TestClient): """Test exception handling in update settings.""" mock_settings.onedrive_refresh_token = None - + with patch("app.tasks.upload_to_onedrive.get_onedrive_token", side_effect=Exception("Fatal error")): response = client.post( - "/api/onedrive/update-settings", - data={ - "refresh_token": "token", - "tenant_id": "common" - } + "/api/onedrive/update-settings", data={"refresh_token": "token", "tenant_id": "common"} ) # Should still update settings even if test fails @@ -615,7 +557,7 @@ class TestOneDriveIntegration: mock_exchange.return_value = { "refresh_token": "new_refresh_token", "access_token": "new_access_token", - "expires_in": 3600 + "expires_in": 3600, } response = client.post( @@ -625,8 +567,8 @@ class TestOneDriveIntegration: "client_secret": "test_client_secret", "redirect_uri": "http://localhost/callback", "code": "auth_code", - "tenant_id": "common" - } + "tenant_id": "common", + }, ) assert response.status_code == 200 @@ -636,10 +578,7 @@ class TestOneDriveIntegration: with patch("app.tasks.upload_to_onedrive.get_onedrive_token"): response = client.post( "/api/onedrive/update-settings", - data={ - "refresh_token": token_data["refresh_token"], - "tenant_id": "common" - } + data={"refresh_token": token_data["refresh_token"], "tenant_id": "common"}, ) assert response.status_code == 200 @@ -661,16 +600,13 @@ class TestOneDriveIntegration: mock_post_response.json.return_value = { "access_token": "access1", "refresh_token": "new_token", - "expires_in": 3600 + "expires_in": 3600, } mock_post.return_value = mock_post_response mock_get_response = Mock() mock_get_response.status_code = 200 - mock_get_response.json.return_value = { - "displayName": "Test User", - "userPrincipalName": "test@example.com" - } + mock_get_response.json.return_value = {"displayName": "Test User", "userPrincipalName": "test@example.com"} mock_get.return_value = mock_get_response with patch("os.path.exists", return_value=False): diff --git a/tests/test_api_onedrive_extended.py b/tests/test_api_onedrive_extended.py index e919eb17..3a4085a5 100644 --- a/tests/test_api_onedrive_extended.py +++ b/tests/test_api_onedrive_extended.py @@ -1,8 +1,9 @@ """Comprehensive unit tests for app/api/onedrive.py module.""" -import pytest +from datetime import timedelta from unittest.mock import MagicMock, patch -from datetime import datetime, timedelta + +import pytest @pytest.mark.unit @@ -285,7 +286,6 @@ class TestSaveOneDriveSettings: @patch("os.path.exists") def test_save_settings_updates_memory(self, mock_exists, mock_open): """Test that in-memory settings are updated.""" - from app.config import settings mock_exists.return_value = True mock_file = MagicMock() @@ -303,7 +303,6 @@ class TestUpdateOneDriveSettings: @patch("app.tasks.upload_to_onedrive.get_onedrive_token") def test_update_settings_success(self, mock_get_token): """Test successful settings update.""" - from app.config import settings mock_get_token.return_value = "access_token" @@ -313,7 +312,6 @@ class TestUpdateOneDriveSettings: @patch("app.tasks.upload_to_onedrive.get_onedrive_token") def test_update_settings_token_test_failed(self, mock_get_token): """Test when token test fails after update.""" - from app.config import settings mock_get_token.side_effect = Exception("Token test failed") @@ -343,7 +341,6 @@ class TestGetOneDriveFullConfig: def test_get_full_config_env_format(self): """Test that env_format is generated correctly.""" - from app.config import settings # env_format should contain all settings as KEY=value pass diff --git a/tests/test_api_openai_extended.py b/tests/test_api_openai_extended.py index 3b6c3a2f..f08912e0 100644 --- a/tests/test_api_openai_extended.py +++ b/tests/test_api_openai_extended.py @@ -1,8 +1,8 @@ """Comprehensive unit tests for app/api/openai.py module.""" +from unittest.mock import MagicMock, patch + import pytest -from fastapi.testclient import TestClient -from unittest.mock import MagicMock, patch, Mock @pytest.mark.unit @@ -11,7 +11,6 @@ class TestOpenAITestConnection: def test_openai_connection_success(self): """Test successful OpenAI API connection.""" - import openai from app.config import settings with patch("openai.OpenAI") as mock_openai_class: diff --git a/tests/test_api_settings.py b/tests/test_api_settings.py index f607e0cd..0dab6b13 100644 --- a/tests/test_api_settings.py +++ b/tests/test_api_settings.py @@ -1,6 +1,6 @@ """Tests for app/api/settings.py module.""" -from unittest.mock import MagicMock, patch +from unittest.mock import MagicMock import pytest from fastapi import HTTPException diff --git a/tests/test_api_settings_extended.py b/tests/test_api_settings_extended.py index ace9a88d..7e773dab 100644 --- a/tests/test_api_settings_extended.py +++ b/tests/test_api_settings_extended.py @@ -1,9 +1,10 @@ """Comprehensive unit tests for app/api/settings.py module.""" +from unittest.mock import MagicMock, patch + import pytest from fastapi import HTTPException from fastapi.testclient import TestClient -from unittest.mock import MagicMock, patch @pytest.mark.unit @@ -51,9 +52,7 @@ class TestGetSettings: @patch("app.api.settings.get_all_settings_from_db") @patch("app.api.settings.get_settings_by_category") @patch("app.api.settings.get_setting_metadata") - def test_get_settings_success( - self, mock_metadata, mock_category, mock_db_settings, client: TestClient, db_session - ): + def test_get_settings_success(self, mock_metadata, mock_category, mock_db_settings, client: TestClient, db_session): """Test successful retrieval of settings.""" # Mock session to have admin user mock_metadata.return_value = {"description": "Test setting", "type": "string"} @@ -63,13 +62,9 @@ class TestGetSettings: with patch.object(client, "get") as mock_get: with patch("app.api.settings.settings") as mock_settings: mock_settings.setting1 = "test_value" - + # Create mock request with admin session - from starlette.testclient import TestClient as StarletteClient - response = client.get( - "/api/settings/", - cookies={"session": "admin_session"} - ) + response = client.get("/api/settings/", cookies={"session": "admin_session"}) @patch("app.api.settings.get_all_settings_from_db") def test_get_settings_database_error(self, mock_db_settings, client: TestClient, db_session): @@ -87,7 +82,6 @@ class TestGetSetting: @patch("app.api.settings.get_setting_metadata") def test_get_setting_existing_key(self, mock_metadata): """Test retrieval of existing setting.""" - from app.api.settings import get_setting from app.config import settings mock_metadata.return_value = {"description": "Test setting"} @@ -263,9 +257,7 @@ class TestSettingModels: """Test SettingResponse model.""" from app.api.settings import SettingResponse - response = SettingResponse( - key="test_key", value="test_value", metadata={"description": "test"} - ) + response = SettingResponse(key="test_key", value="test_value", metadata={"description": "test"}) assert response.key == "test_key" assert response.value == "test_value" assert response.metadata["description"] == "test" diff --git a/tests/test_auth_integration.py b/tests/test_auth_integration.py index 786d33b1..97925de7 100644 --- a/tests/test_auth_integration.py +++ b/tests/test_auth_integration.py @@ -1,11 +1,10 @@ """Integration tests for auth.py with AUTH_ENABLED=True scenarios.""" -import hashlib -from unittest.mock import AsyncMock, MagicMock, patch +from unittest.mock import MagicMock, patch import pytest -from app.auth import get_current_user, get_gravatar_url, require_login +from app.auth import get_gravatar_url @pytest.mark.unit diff --git a/tests/test_auth_module.py b/tests/test_auth_module.py index 3dbcd98d..8c0a7735 100644 --- a/tests/test_auth_module.py +++ b/tests/test_auth_module.py @@ -1,6 +1,6 @@ """Comprehensive unit tests for app/auth.py module.""" -from unittest.mock import AsyncMock, MagicMock, Mock, patch +from unittest.mock import AsyncMock, MagicMock, patch import pytest from fastapi import Request, status @@ -344,7 +344,7 @@ class TestOAuthCallback: """Test OAuth callback returns error when OAuth not configured.""" with patch("app.auth.AUTH_ENABLED", True): with patch("app.auth.OAUTH_CONFIGURED", False): - from app.auth import oauth_callback, oauth_login + from app.auth import oauth_login mock_request = MagicMock() diff --git a/tests/test_bulk_operations.py b/tests/test_bulk_operations.py index 554aab08..153f19c8 100644 --- a/tests/test_bulk_operations.py +++ b/tests/test_bulk_operations.py @@ -7,7 +7,7 @@ from unittest.mock import MagicMock, patch import pytest from fastapi.testclient import TestClient -from app.models import FileProcessingStep, FileRecord, ProcessingLog +from app.models import FileProcessingStep, FileRecord @pytest.mark.integration diff --git a/tests/test_celery_worker.py b/tests/test_celery_worker.py index 531b0175..3b8bff74 100644 --- a/tests/test_celery_worker.py +++ b/tests/test_celery_worker.py @@ -5,8 +5,6 @@ This module tests the Celery worker configuration, task imports, and beat schedu """ import pytest -from unittest.mock import MagicMock, patch, PropertyMock -from celery.schedules import crontab @pytest.mark.unit @@ -16,29 +14,29 @@ class TestCeleryWorkerConfig: def test_test_task_function(self): """Test the test_task function returns expected value.""" from app.celery_worker import test_task - + result = test_task() assert result == "Celery is working!" def test_celery_instance_exists(self): """Test that celery instance exists in module.""" from app import celery_worker - - assert hasattr(celery_worker, 'celery') + + assert hasattr(celery_worker, "celery") assert celery_worker.celery is not None def test_task_routes_exists(self): """Test that task routes configuration exists.""" from app import celery_worker - + # Task routes should be configured - assert hasattr(celery_worker.celery.conf, 'task_routes') + assert hasattr(celery_worker.celery.conf, "task_routes") def test_all_task_imports_successful(self): """Test that all task modules are imported successfully.""" # Just import the module to verify no import errors from app import celery_worker - + # Module imported successfully assert celery_worker is not None @@ -50,49 +48,49 @@ class TestBeatScheduleConfiguration: def test_beat_schedule_structure(self): """Test that beat schedule has expected structure.""" from app.celery_worker import celery - + # Beat schedule should be a dictionary assert isinstance(celery.conf.beat_schedule, dict) - + # Should include credential check tasks - assert 'check-credentials-regularly' in celery.conf.beat_schedule - assert 'check-credentials-daily' in celery.conf.beat_schedule - assert 'monitor-stalled-steps' in celery.conf.beat_schedule + assert "check-credentials-regularly" in celery.conf.beat_schedule + assert "check-credentials-daily" in celery.conf.beat_schedule + assert "monitor-stalled-steps" in celery.conf.beat_schedule def test_credential_check_schedule(self): """Test credential check schedule configuration.""" from app.celery_worker import celery - - schedule = celery.conf.beat_schedule.get('check-credentials-regularly') + + schedule = celery.conf.beat_schedule.get("check-credentials-regularly") assert schedule is not None - assert schedule['task'] == 'app.tasks.check_credentials.check_credentials' - assert 'schedule' in schedule - assert schedule['options']['expires'] == 240 + assert schedule["task"] == "app.tasks.check_credentials.check_credentials" + assert "schedule" in schedule + assert schedule["options"]["expires"] == 240 def test_daily_credential_check_schedule(self): """Test daily credential check schedule.""" from app.celery_worker import celery - - schedule = celery.conf.beat_schedule.get('check-credentials-daily') + + schedule = celery.conf.beat_schedule.get("check-credentials-daily") assert schedule is not None - assert schedule['task'] == 'app.tasks.check_credentials.check_credentials' - assert 'schedule' in schedule - assert schedule['options']['expires'] == 3600 + assert schedule["task"] == "app.tasks.check_credentials.check_credentials" + assert "schedule" in schedule + assert schedule["options"]["expires"] == 3600 def test_monitor_stalled_steps_schedule(self): """Test monitor stalled steps schedule.""" from app.celery_worker import celery - - schedule = celery.conf.beat_schedule.get('monitor-stalled-steps') + + schedule = celery.conf.beat_schedule.get("monitor-stalled-steps") assert schedule is not None - assert schedule['task'] == 'app.tasks.monitor_stalled_steps.monitor_stalled_steps' - assert 'schedule' in schedule - assert schedule['options']['expires'] == 55 + assert schedule["task"] == "app.tasks.monitor_stalled_steps.monitor_stalled_steps" + assert "schedule" in schedule + assert schedule["options"]["expires"] == 55 def test_no_none_entries_in_beat_schedule(self): """Test that None entries are filtered from beat schedule.""" from app.celery_worker import celery - + # No None values in beat schedule for key, value in celery.conf.beat_schedule.items(): assert value is not None, f"Beat schedule entry '{key}' should not be None" diff --git a/tests/test_check_credentials.py b/tests/test_check_credentials.py index aad1bfe4..692f582f 100644 --- a/tests/test_check_credentials.py +++ b/tests/test_check_credentials.py @@ -2,7 +2,7 @@ import json import os -from unittest.mock import MagicMock, patch +from unittest.mock import patch import pytest diff --git a/tests/test_config.py b/tests/test_config.py index 8efb2102..86701feb 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -2,8 +2,6 @@ Unit tests for configuration and security validation. """ -import os - import pytest from pydantic import ValidationError diff --git a/tests/test_config_validator_reexport.py b/tests/test_config_validator_reexport.py index 4b96cffb..a485b7d3 100644 --- a/tests/test_config_validator_reexport.py +++ b/tests/test_config_validator_reexport.py @@ -14,61 +14,61 @@ class TestConfigValidatorReexports: def test_module_imports(self): """Test that config_validator module imports successfully.""" from app.utils import config_validator - + assert config_validator is not None def test_validate_email_config_reexport(self): """Test validate_email_config is re-exported.""" from app.utils.config_validator import validate_email_config - + assert callable(validate_email_config) def test_validate_storage_configs_reexport(self): """Test validate_storage_configs is re-exported.""" from app.utils.config_validator import validate_storage_configs - + assert callable(validate_storage_configs) def test_validate_notification_config_reexport(self): """Test validate_notification_config is re-exported.""" from app.utils.config_validator import validate_notification_config - + assert callable(validate_notification_config) def test_mask_sensitive_value_reexport(self): """Test mask_sensitive_value is re-exported.""" from app.utils.config_validator import mask_sensitive_value - + assert callable(mask_sensitive_value) def test_get_provider_status_reexport(self): """Test get_provider_status is re-exported.""" from app.utils.config_validator import get_provider_status - + assert callable(get_provider_status) def test_get_settings_for_display_reexport(self): """Test get_settings_for_display is re-exported.""" from app.utils.config_validator import get_settings_for_display - + assert callable(get_settings_for_display) def test_dump_all_settings_reexport(self): """Test dump_all_settings is re-exported.""" from app.utils.config_validator import dump_all_settings - + assert callable(dump_all_settings) def test_check_all_configs_reexport(self): """Test check_all_configs is re-exported.""" from app.utils.config_validator import check_all_configs - + assert callable(check_all_configs) def test_all_exports_in_all(self): """Test that all exports are in __all__.""" from app.utils import config_validator - + expected_exports = [ "validate_email_config", "validate_storage_configs", @@ -79,15 +79,15 @@ class TestConfigValidatorReexports: "dump_all_settings", "check_all_configs", ] - - assert hasattr(config_validator, '__all__') + + assert hasattr(config_validator, "__all__") for export in expected_exports: assert export in config_validator.__all__ def test_mask_sensitive_value_functionality(self): """Test mask_sensitive_value actually works.""" from app.utils.config_validator import mask_sensitive_value - + # Test masking a sensitive value result = mask_sensitive_value("secret_api_key_12345") assert result != "secret_api_key_12345" @@ -96,10 +96,10 @@ class TestConfigValidatorReexports: def test_get_provider_status_functionality(self): """Test get_provider_status returns expected structure.""" from app.utils.config_validator import get_provider_status - + # Get provider status (takes no arguments) result = get_provider_status() - + # Should return a dict with provider information assert isinstance(result, dict) # Should have at least authentication provider diff --git a/tests/test_config_validators.py b/tests/test_config_validators.py index 2a0e5f68..4e029cb5 100644 --- a/tests/test_config_validators.py +++ b/tests/test_config_validators.py @@ -1,7 +1,5 @@ """Tests for app/utils/config_validator/validators.py module.""" -from unittest.mock import patch - import pytest from app.utils.config_validator.validators import ( diff --git a/tests/test_convert_pdf.py b/tests/test_convert_pdf.py index 99aa87bb..84830015 100644 --- a/tests/test_convert_pdf.py +++ b/tests/test_convert_pdf.py @@ -1,6 +1,6 @@ """Comprehensive unit tests for app/tasks/convert_to_pdf.py module.""" -from unittest.mock import MagicMock, Mock, mock_open, patch +from unittest.mock import MagicMock, mock_open, patch import pytest diff --git a/tests/test_convert_to_pdf.py b/tests/test_convert_to_pdf.py index 841ada96..87899ba6 100644 --- a/tests/test_convert_to_pdf.py +++ b/tests/test_convert_to_pdf.py @@ -1,6 +1,5 @@ """Tests for app/tasks/convert_to_pdf.py module.""" -import os from unittest.mock import MagicMock, patch import pytest diff --git a/tests/test_coverage_boost.py b/tests/test_coverage_boost.py index 07de1db6..2de90f31 100644 --- a/tests/test_coverage_boost.py +++ b/tests/test_coverage_boost.py @@ -1,6 +1,6 @@ """Tests to boost coverage for various small modules.""" -from unittest.mock import MagicMock, patch +from unittest.mock import patch import pytest diff --git a/tests/test_coverage_final.py b/tests/test_coverage_final.py index 187872b6..9e374a9f 100644 --- a/tests/test_coverage_final.py +++ b/tests/test_coverage_final.py @@ -1,6 +1,6 @@ """Final tests to push coverage over 60%.""" -from unittest.mock import MagicMock, patch +from unittest.mock import patch import pytest @@ -86,7 +86,6 @@ class TestCheckCredentialsFunctions: def test_sync_test_s3_credentials(self): """Test save_failure_state accepts dict.""" import os - from unittest.mock import patch from app.tasks.check_credentials import save_failure_state diff --git a/tests/test_database.py b/tests/test_database.py index bd91b7c0..2582e087 100644 --- a/tests/test_database.py +++ b/tests/test_database.py @@ -1,6 +1,5 @@ """Tests for app/database.py module.""" -import os from unittest.mock import MagicMock, patch import pytest @@ -113,8 +112,7 @@ class TestSchemaMigrations: def test_migration_adds_detail_column(self, tmp_path): """Test that _run_schema_migrations adds detail column to existing tables.""" - from sqlalchemy import Column, Integer, String, create_engine, text - from sqlalchemy.orm import sessionmaker + from sqlalchemy import create_engine, text from app.database import _run_schema_migrations diff --git a/tests/test_e2e_full_stack.py b/tests/test_e2e_full_stack.py index a08d5b69..1efa1279 100644 --- a/tests/test_e2e_full_stack.py +++ b/tests/test_e2e_full_stack.py @@ -22,18 +22,6 @@ try: except ModuleNotFoundError: _has_psycopg2 = False -from tests.fixtures_integration import ( - celery_app, - celery_worker, - db_session_real, - full_infrastructure, - gotenberg_container, - minio_container, - postgres_container, - redis_container, - sftp_container, - webdav_container, -) _TEST_CREDENTIAL = "pass" # noqa: S105 @@ -67,7 +55,6 @@ class TestEndToEndWithRedis: patch("app.tasks.upload_to_webdav.settings") as mock_settings, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - # Configure to use real WebDAV server mock_settings.webdav_url = webdav_container["url"] + "/" mock_settings.webdav_username = webdav_container["username"] @@ -169,7 +156,6 @@ class TestEndToEndWithRedis: patch("app.tasks.upload_to_webdav.settings") as mock_settings, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = webdav_container["url"] + "/" mock_settings.webdav_username = webdav_container["username"] mock_settings.webdav_password = webdav_container["password"] @@ -233,7 +219,6 @@ class TestEndToEndWithRedis: patch("app.tasks.upload_to_webdav.log_task_progress"), patch("app.tasks.upload_to_webdav.requests.put") as mock_put, ): - mock_settings.webdav_url = "http://test.com/" mock_settings.webdav_username = "user" mock_settings.webdav_password = _TEST_CREDENTIAL @@ -357,7 +342,6 @@ class TestFullInfrastructure: patch("app.tasks.upload_to_webdav.settings") as mock_settings, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = infra["webdav"]["url"] + "/" mock_settings.webdav_username = infra["webdav"]["username"] mock_settings.webdav_password = infra["webdav"]["password"] @@ -556,7 +540,6 @@ class TestProductionLikeScenarios: patch("app.tasks.upload_to_webdav.settings") as mock_settings, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = infra["webdav"]["url"] + "/" mock_settings.webdav_username = infra["webdav"]["username"] mock_settings.webdav_password = infra["webdav"]["password"] diff --git a/tests/test_embed_metadata.py b/tests/test_embed_metadata.py index aef902b0..83a45f35 100644 --- a/tests/test_embed_metadata.py +++ b/tests/test_embed_metadata.py @@ -1,7 +1,6 @@ """Tests for app/tasks/embed_metadata_into_pdf.py module.""" import os -from unittest.mock import MagicMock, patch import pytest diff --git a/tests/test_embed_pdf_metadata.py b/tests/test_embed_pdf_metadata.py index 69af9833..d38a3bb3 100644 --- a/tests/test_embed_pdf_metadata.py +++ b/tests/test_embed_pdf_metadata.py @@ -1,9 +1,6 @@ """Comprehensive unit tests for app/tasks/embed_metadata_into_pdf.py module.""" -import os -import tempfile -from pathlib import Path -from unittest.mock import MagicMock, Mock, mock_open, patch +from unittest.mock import MagicMock, mock_open, patch import pytest @@ -257,7 +254,9 @@ class TestEmbedMetadataIntoPdf: assert "error" in result # Verify failure was logged - failure_calls = [call for call in mock_log_progress.call_args_list if "failure" in str(call)] + failure_calls = [ + call for call in mock_log_progress.call_args_list if "failure" in str(call) + ] assert len(failure_calls) > 0 @patch("app.tasks.embed_metadata_into_pdf.finalize_document_storage") diff --git a/tests/test_endpoint_registration.py b/tests/test_endpoint_registration.py index 589e7338..3c0476b1 100644 --- a/tests/test_endpoint_registration.py +++ b/tests/test_endpoint_registration.py @@ -41,9 +41,9 @@ class TestEndpointRegistration: # We may get other errors (401, 400, 500, etc.) due to validation or missing mocks, # but 404 specifically means the endpoint is not registered assert response.status_code != 404, ( - f"Endpoint /api/process-url returned 404 (not found). " - f"This indicates the router is not properly registered in the application. " - f"Verify that url_upload_router is included in app/api/__init__.py" + "Endpoint /api/process-url returned 404 (not found). " + "This indicates the router is not properly registered in the application. " + "Verify that url_upload_router is included in app/api/__init__.py" ) @patch("app.api.url_upload.requests.get") @@ -68,8 +68,8 @@ class TestEndpointRegistration: # Should not return 405 (Method Not Allowed) assert response.status_code != 405, ( - f"Endpoint /api/process-url returned 405 (Method Not Allowed) for POST. " - f"Verify the endpoint is decorated with @router.post()" + "Endpoint /api/process-url returned 405 (Method Not Allowed) for POST. " + "Verify the endpoint is decorated with @router.post()" ) @patch("app.api.url_upload.requests.get") diff --git a/tests/test_external_integrations.py b/tests/test_external_integrations.py index 30c0166d..5fab2016 100644 --- a/tests/test_external_integrations.py +++ b/tests/test_external_integrations.py @@ -244,9 +244,9 @@ class TestAzureDocumentIntelligenceIntegration: assert len(result.content) > 10, f"OCR text too short: {result.content[:50]}" # Verify the generated text is recognizable - assert ( - "Acme" in result.content or "Invoice" in result.content - ), f"OCR text does not contain expected keywords: {result.content[:200]}" + assert "Acme" in result.content or "Invoice" in result.content, ( + f"OCR text does not contain expected keywords: {result.content[:200]}" + ) # Retrieve the searchable PDF output operation_id = poller.details["operation_id"] @@ -602,9 +602,9 @@ class TestFullOCRMetadataPipeline: # The generated invoice should be classified reasonably doc_type = metadata["document_type"].lower() - assert any( - kw in doc_type for kw in ("invoice", "rechnung", "bill") - ), f"Unexpected document_type: {metadata['document_type']}" + assert any(kw in doc_type for kw in ("invoice", "rechnung", "bill")), ( + f"Unexpected document_type: {metadata['document_type']}" + ) finally: os.unlink(pdf_path) diff --git a/tests/test_extract_metadata_gpt.py b/tests/test_extract_metadata_gpt.py index eac6d83d..fbe466d0 100644 --- a/tests/test_extract_metadata_gpt.py +++ b/tests/test_extract_metadata_gpt.py @@ -72,21 +72,23 @@ class TestExtractMetadataWithGpt: """Test successful metadata extraction with valid GPT response.""" # Mock the OpenAI client response mock_completion = MagicMock() - mock_completion.choices[0].message.content = json.dumps({ - "filename": "2024-01-15_Invoice_Amazon", - "empfaenger": "John Doe", - "absender": "Amazon", - "correspondent": "Amazon", - "kommunikationsart": "Rechnung", - "kommunikationskategorie": "Finanz_und_Vertragsdokumente", - "document_type": "Invoice", - "tags": ["invoice", "amazon", "online-shopping"], - "language": "de", - "title": "Amazon Purchase Invoice", - "confidence_score": 95, - "reference_number": "INV-2024-001", - "monetary_amounts": ["99.99 EUR"] - }) + mock_completion.choices[0].message.content = json.dumps( + { + "filename": "2024-01-15_Invoice_Amazon", + "empfaenger": "John Doe", + "absender": "Amazon", + "correspondent": "Amazon", + "kommunikationsart": "Rechnung", + "kommunikationskategorie": "Finanz_und_Vertragsdokumente", + "document_type": "Invoice", + "tags": ["invoice", "amazon", "online-shopping"], + "language": "de", + "title": "Amazon Purchase Invoice", + "confidence_score": 95, + "reference_number": "INV-2024-001", + "monetary_amounts": ["99.99 EUR"], + } + ) mock_client.chat.completions.create.return_value = mock_completion # Set task request context directly on the Celery task @@ -119,7 +121,9 @@ class TestExtractMetadataWithGpt: def test_handles_json_in_backticks(self, mock_client, mock_log_progress, mock_embed_task): """Test extraction handles JSON wrapped in markdown code blocks.""" mock_completion = MagicMock() - mock_completion.choices[0].message.content = '```json\n{"filename": "test.pdf", "document_type": "Unknown"}\n```' + mock_completion.choices[ + 0 + ].message.content = '```json\n{"filename": "test.pdf", "document_type": "Unknown"}\n```' mock_client.chat.completions.create.return_value = mock_completion extract_metadata_with_gpt.request.id = "test-task-id" @@ -193,7 +197,7 @@ class TestExtractMetadataWithGpt: result = extract_metadata_with_gpt.__wrapped__( filename="test.pdf", cleaned_text="Sample text", - file_id=None # Not provided + file_id=None, # Not provided ) assert result["metadata"]["filename"] == "test.pdf" @@ -207,10 +211,9 @@ class TestExtractMetadataWithGpt: """Test filename validation to prevent path traversal.""" mock_completion = MagicMock() # Try to inject a malicious filename - mock_completion.choices[0].message.content = json.dumps({ - "filename": "../../../etc/passwd", - "document_type": "Invoice" - }) + mock_completion.choices[0].message.content = json.dumps( + {"filename": "../../../etc/passwd", "document_type": "Invoice"} + ) mock_client.chat.completions.create.return_value = mock_completion extract_metadata_with_gpt.request.id = "test-task-id" @@ -227,10 +230,9 @@ class TestExtractMetadataWithGpt: def test_validates_filename_with_dots(self, mock_client, mock_log_progress, mock_embed_task): """Test filename validation rejects '..' in filenames.""" mock_completion = MagicMock() - mock_completion.choices[0].message.content = json.dumps({ - "filename": "test..invoice.pdf", - "document_type": "Invoice" - }) + mock_completion.choices[0].message.content = json.dumps( + {"filename": "test..invoice.pdf", "document_type": "Invoice"} + ) mock_client.chat.completions.create.return_value = mock_completion extract_metadata_with_gpt.request.id = "test-task-id" @@ -246,10 +248,9 @@ class TestExtractMetadataWithGpt: def test_accepts_valid_filename(self, mock_client, mock_log_progress, mock_embed_task): """Test that valid filenames are accepted.""" mock_completion = MagicMock() - mock_completion.choices[0].message.content = json.dumps({ - "filename": "2024-01-15_Invoice_Amazon.pdf", - "document_type": "Invoice" - }) + mock_completion.choices[0].message.content = json.dumps( + {"filename": "2024-01-15_Invoice_Amazon.pdf", "document_type": "Invoice"} + ) mock_client.chat.completions.create.return_value = mock_completion extract_metadata_with_gpt.request.id = "test-task-id" diff --git a/tests/test_file_detail_endpoints.py b/tests/test_file_detail_endpoints.py index 5b1b747b..1f02fb47 100644 --- a/tests/test_file_detail_endpoints.py +++ b/tests/test_file_detail_endpoints.py @@ -2,7 +2,6 @@ Tests for file detail view improvements including reprocessing and preview endpoints. """ -import os from unittest.mock import MagicMock, patch import pytest diff --git a/tests/test_file_detail_enhancements.py b/tests/test_file_detail_enhancements.py index 944f7c27..c6645628 100644 --- a/tests/test_file_detail_enhancements.py +++ b/tests/test_file_detail_enhancements.py @@ -9,14 +9,10 @@ Tests the new features: """ import json -import os -import tempfile -from pathlib import Path import pytest from fastapi.testclient import TestClient -from app.main import app from app.models import FileRecord @@ -38,7 +34,6 @@ def sample_metadata(): @pytest.mark.integration def test_file_detail_page_with_metadata(client: TestClient, db_session, sample_pdf_file): """Test file detail page displays GPT metadata correctly""" - from app.models import FileRecord # Create a file record with paths file_record = FileRecord( @@ -68,7 +63,6 @@ def test_file_detail_page_with_metadata(client: TestClient, db_session, sample_p @pytest.mark.integration def test_file_detail_with_gpt_metadata(client: TestClient, db_session, sample_pdf_file, sample_metadata, tmp_path): """Test file detail page with GPT metadata JSON""" - from app.models import FileRecord # Create processed file path and metadata JSON processed_file = tmp_path / "2024-01-15_Company_Invoice.pdf" @@ -106,7 +100,6 @@ def test_file_detail_with_gpt_metadata(client: TestClient, db_session, sample_pd @pytest.mark.integration def test_preview_original_file_endpoint(client: TestClient, db_session, sample_pdf_file): """Test original file preview endpoint""" - from app.models import FileRecord file_record = FileRecord( filehash="test789ghi", @@ -130,7 +123,6 @@ def test_preview_original_file_endpoint(client: TestClient, db_session, sample_p @pytest.mark.integration def test_preview_processed_file_endpoint(client: TestClient, db_session, sample_pdf_file, tmp_path): """Test processed file preview endpoint""" - from app.models import FileRecord # Create processed file processed_file = tmp_path / "processed.pdf" @@ -158,7 +150,6 @@ def test_preview_processed_file_endpoint(client: TestClient, db_session, sample_ @pytest.mark.integration def test_preview_missing_file_returns_404(client: TestClient, db_session, sample_pdf_file): """Test preview endpoint returns 404 when file doesn't exist""" - from app.models import FileRecord file_record = FileRecord( filehash="test202mno", @@ -185,7 +176,6 @@ def test_preview_missing_file_returns_404(client: TestClient, db_session, sample @pytest.mark.integration def test_file_detail_shows_file_status_indicators(client: TestClient, db_session, sample_pdf_file): """Test file detail page shows correct status indicators for original and processed files""" - from app.models import FileRecord file_record = FileRecord( filehash="test303pqr", diff --git a/tests/test_file_listing.py b/tests/test_file_listing.py index e6deefd1..2cab1921 100644 --- a/tests/test_file_listing.py +++ b/tests/test_file_listing.py @@ -2,8 +2,6 @@ Tests for file listing, pagination, filtering, and detail endpoints. """ -from datetime import datetime - import pytest from fastapi.testclient import TestClient diff --git a/tests/test_file_splitting.py b/tests/test_file_splitting.py index f88460da..9682e6df 100644 --- a/tests/test_file_splitting.py +++ b/tests/test_file_splitting.py @@ -83,9 +83,9 @@ class TestSplitPdfBySize: # that can cause files to exceed the target size by ~20-50%. We allow 1.5x (50%) margin. PDF_OVERHEAD_MULTIPLIER = 1.5 for split_file in split_files: - assert ( - os.path.getsize(split_file) <= max_size * PDF_OVERHEAD_MULTIPLIER - ), f"Split file {split_file} should respect size limit (with PDF overhead allowance)" + assert os.path.getsize(split_file) <= max_size * PDF_OVERHEAD_MULTIPLIER, ( + f"Split file {split_file} should respect size limit (with PDF overhead allowance)" + ) # Cleanup split files for split_file in split_files: diff --git a/tests/test_file_status_fix.py b/tests/test_file_status_fix.py index 8c36e583..8a6122b0 100644 --- a/tests/test_file_status_fix.py +++ b/tests/test_file_status_fix.py @@ -7,14 +7,12 @@ This test module verifies that: 3. Files with completed steps show "completed" not "processing" """ -from datetime import datetime, timedelta - import pytest from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from app.database import Base -from app.models import FileProcessingStep, FileRecord +from app.models import FileRecord from app.utils.step_manager import get_file_overall_status, get_step_summary, initialize_file_steps, update_step_status diff --git a/tests/test_file_upload.py b/tests/test_file_upload.py index f0b8b3a3..c5970b52 100644 --- a/tests/test_file_upload.py +++ b/tests/test_file_upload.py @@ -26,7 +26,6 @@ def mock_celery_tasks(): patch("app.api.files.process_document") as mock_process_task, patch("app.api.files.convert_to_pdf") as mock_convert_task, ): - # Setup default return values for .delay() mock_task = MagicMock() mock_task.id = "test-task-id-123" diff --git a/tests/test_filename_utils.py b/tests/test_filename_utils.py index f7da0d82..9100ec1c 100644 --- a/tests/test_filename_utils.py +++ b/tests/test_filename_utils.py @@ -5,9 +5,7 @@ Tests filename sanitization and manipulation functions. """ import os -from datetime import datetime -from pathlib import Path -from unittest.mock import Mock, patch +from unittest.mock import Mock import pytest diff --git a/tests/test_finalize_storage.py b/tests/test_finalize_storage.py index d8b8b50d..d7b54f5c 100644 --- a/tests/test_finalize_storage.py +++ b/tests/test_finalize_storage.py @@ -102,7 +102,9 @@ class TestFinalizeDocumentStorage: with patch("app.tasks.finalize_document_storage.os.path.exists", return_value=True): with patch("app.tasks.finalize_document_storage.os.path.getsize", return_value=50000): with patch("app.tasks.finalize_document_storage.os.path.basename", return_value="doc.pdf"): - with patch("app.tasks.finalize_document_storage.os.path.join", return_value="/tmp/tmp/original.pdf"): + with patch( + "app.tasks.finalize_document_storage.os.path.join", return_value="/tmp/tmp/original.pdf" + ): with patch("app.tasks.finalize_document_storage.settings") as mock_settings: mock_settings.workdir = "/tmp" diff --git a/tests/test_imap_extended.py b/tests/test_imap_extended.py index 528fb971..a050e1a1 100644 --- a/tests/test_imap_extended.py +++ b/tests/test_imap_extended.py @@ -2,7 +2,6 @@ import json import os -from datetime import datetime, timezone from email.message import EmailMessage from unittest.mock import MagicMock, patch @@ -11,7 +10,6 @@ import pytest from app.tasks.imap_tasks import ( fetch_attachments_and_enqueue, find_all_mail_xlist, - load_processed_emails, save_processed_emails, ) diff --git a/tests/test_imap_tasks.py b/tests/test_imap_tasks.py index 059fc353..09fac6e2 100644 --- a/tests/test_imap_tasks.py +++ b/tests/test_imap_tasks.py @@ -1,6 +1,5 @@ """Tests for app/tasks/imap_tasks.py module.""" -import json import os from datetime import datetime, timedelta, timezone from email.message import EmailMessage diff --git a/tests/test_monitor_stalled_steps.py b/tests/test_monitor_stalled_steps.py index fef334d0..fb9222ec 100644 --- a/tests/test_monitor_stalled_steps.py +++ b/tests/test_monitor_stalled_steps.py @@ -4,138 +4,138 @@ Tests for app/tasks/monitor_stalled_steps.py This module tests the periodic task that monitors and recovers stalled processing steps. """ +from unittest.mock import MagicMock, patch + import pytest -from unittest.mock import MagicMock, patch, call -from datetime import datetime @pytest.mark.unit class TestMonitorStalledSteps: """Test monitor_stalled_steps task.""" - @patch('app.tasks.monitor_stalled_steps.mark_stalled_steps_as_failed') - @patch('app.tasks.monitor_stalled_steps.SessionLocal') + @patch("app.tasks.monitor_stalled_steps.mark_stalled_steps_as_failed") + @patch("app.tasks.monitor_stalled_steps.SessionLocal") def test_monitor_stalled_steps_no_stalled(self, mock_session_local, mock_mark_stalled): """Test monitor_stalled_steps when no stalled steps found.""" from app.tasks.monitor_stalled_steps import monitor_stalled_steps - + # Mock database session mock_db = MagicMock() mock_session_local.return_value.__enter__.return_value = mock_db - + # No stalled steps mock_mark_stalled.return_value = 0 - + # Run task result = monitor_stalled_steps() - + # Verify result assert result == {"recovered": 0} mock_mark_stalled.assert_called_once_with(mock_db) - @patch('app.tasks.monitor_stalled_steps.mark_stalled_steps_as_failed') - @patch('app.tasks.monitor_stalled_steps.SessionLocal') + @patch("app.tasks.monitor_stalled_steps.mark_stalled_steps_as_failed") + @patch("app.tasks.monitor_stalled_steps.SessionLocal") def test_monitor_stalled_steps_with_stalled(self, mock_session_local, mock_mark_stalled): """Test monitor_stalled_steps when stalled steps are found.""" from app.tasks.monitor_stalled_steps import monitor_stalled_steps - + # Mock database session mock_db = MagicMock() mock_session_local.return_value.__enter__.return_value = mock_db - + # Found 3 stalled steps mock_mark_stalled.return_value = 3 - + # Run task result = monitor_stalled_steps() - + # Verify result assert result == {"recovered": 3} mock_mark_stalled.assert_called_once_with(mock_db) - @patch('app.tasks.monitor_stalled_steps.mark_stalled_steps_as_failed') - @patch('app.tasks.monitor_stalled_steps.SessionLocal') - @patch('app.tasks.monitor_stalled_steps.logger') + @patch("app.tasks.monitor_stalled_steps.mark_stalled_steps_as_failed") + @patch("app.tasks.monitor_stalled_steps.SessionLocal") + @patch("app.tasks.monitor_stalled_steps.logger") def test_monitor_stalled_steps_logs_recovery(self, mock_logger, mock_session_local, mock_mark_stalled): """Test that monitor_stalled_steps logs recovery actions.""" from app.tasks.monitor_stalled_steps import monitor_stalled_steps - + # Mock database session mock_db = MagicMock() mock_session_local.return_value.__enter__.return_value = mock_db - + # Found 2 stalled steps mock_mark_stalled.return_value = 2 - + # Run task result = monitor_stalled_steps() - + # Verify logging mock_logger.warning.assert_called_once() log_message = mock_logger.warning.call_args[0][0] assert "Recovered 2 stalled step(s)" in log_message - @patch('app.tasks.monitor_stalled_steps.mark_stalled_steps_as_failed') - @patch('app.tasks.monitor_stalled_steps.SessionLocal') - @patch('app.tasks.monitor_stalled_steps.logger') + @patch("app.tasks.monitor_stalled_steps.mark_stalled_steps_as_failed") + @patch("app.tasks.monitor_stalled_steps.SessionLocal") + @patch("app.tasks.monitor_stalled_steps.logger") def test_monitor_stalled_steps_logs_debug_when_none(self, mock_logger, mock_session_local, mock_mark_stalled): """Test that monitor_stalled_steps logs debug message when no stalled steps.""" from app.tasks.monitor_stalled_steps import monitor_stalled_steps - + # Mock database session mock_db = MagicMock() mock_session_local.return_value.__enter__.return_value = mock_db - + # No stalled steps mock_mark_stalled.return_value = 0 - + # Run task result = monitor_stalled_steps() - + # Verify debug logging mock_logger.debug.assert_called_once() log_message = mock_logger.debug.call_args[0][0] assert "No stalled steps found" in log_message - @patch('app.tasks.monitor_stalled_steps.mark_stalled_steps_as_failed') - @patch('app.tasks.monitor_stalled_steps.SessionLocal') - @patch('app.tasks.monitor_stalled_steps.logger') + @patch("app.tasks.monitor_stalled_steps.mark_stalled_steps_as_failed") + @patch("app.tasks.monitor_stalled_steps.SessionLocal") + @patch("app.tasks.monitor_stalled_steps.logger") def test_monitor_stalled_steps_handles_exceptions(self, mock_logger, mock_session_local, mock_mark_stalled): """Test that monitor_stalled_steps handles exceptions gracefully.""" from app.tasks.monitor_stalled_steps import monitor_stalled_steps - + # Mock database session mock_db = MagicMock() mock_session_local.return_value.__enter__.return_value = mock_db - + # Simulate an exception mock_mark_stalled.side_effect = Exception("Database error") - + # Run task result = monitor_stalled_steps() - + # Verify error handling assert result == {"error": "Database error", "recovered": 0} mock_logger.error.assert_called_once() - @patch('app.tasks.monitor_stalled_steps.mark_stalled_steps_as_failed') - @patch('app.tasks.monitor_stalled_steps.SessionLocal') + @patch("app.tasks.monitor_stalled_steps.mark_stalled_steps_as_failed") + @patch("app.tasks.monitor_stalled_steps.SessionLocal") def test_monitor_stalled_steps_uses_context_manager(self, mock_session_local, mock_mark_stalled): """Test that monitor_stalled_steps uses context manager for database session.""" from app.tasks.monitor_stalled_steps import monitor_stalled_steps - + # Mock database session mock_db = MagicMock() mock_context = MagicMock() mock_context.__enter__ = MagicMock(return_value=mock_db) mock_context.__exit__ = MagicMock(return_value=False) mock_session_local.return_value = mock_context - + mock_mark_stalled.return_value = 0 - + # Run task result = monitor_stalled_steps() - + # Verify context manager was used mock_context.__enter__.assert_called_once() mock_context.__exit__.assert_called_once() @@ -143,15 +143,15 @@ class TestMonitorStalledSteps: def test_monitor_stalled_steps_is_celery_task(self): """Test that monitor_stalled_steps is registered as a Celery task.""" from app.tasks.monitor_stalled_steps import monitor_stalled_steps - + # Should have task attributes - assert hasattr(monitor_stalled_steps, 'apply_async') - assert hasattr(monitor_stalled_steps, 'delay') + assert hasattr(monitor_stalled_steps, "apply_async") + assert hasattr(monitor_stalled_steps, "delay") assert callable(monitor_stalled_steps) def test_monitor_stalled_steps_task_name(self): """Test that monitor_stalled_steps has correct task name.""" from app.tasks.monitor_stalled_steps import monitor_stalled_steps - + # Check task name assert monitor_stalled_steps.name == "app.tasks.monitor_stalled_steps.monitor_stalled_steps" diff --git a/tests/test_notification.py b/tests/test_notification.py index b6d61157..a828b7a9 100644 --- a/tests/test_notification.py +++ b/tests/test_notification.py @@ -4,7 +4,7 @@ Tests for app/utils/notification.py Tests notification utilities and URL masking. """ -from unittest.mock import MagicMock, Mock, patch +from unittest.mock import MagicMock, patch import pytest diff --git a/tests/test_notification_utils.py b/tests/test_notification_utils.py index 2e688907..7e2bfe9f 100644 --- a/tests/test_notification_utils.py +++ b/tests/test_notification_utils.py @@ -1,12 +1,11 @@ """Tests for app/utils/notification.py module.""" -from unittest.mock import MagicMock, patch +from unittest.mock import patch import pytest from app.utils.notification import ( _mask_sensitive_url, - init_apprise, notify_celery_failure, notify_credential_failure, notify_file_processed, diff --git a/tests/test_oauth_integration_flows.py b/tests/test_oauth_integration_flows.py index 197a29f1..dc4c63be 100644 --- a/tests/test_oauth_integration_flows.py +++ b/tests/test_oauth_integration_flows.py @@ -9,8 +9,9 @@ These tests use a real OIDC flow with a mock OAuth2 server to test: - Session management """ +from unittest.mock import patch + import pytest -from unittest.mock import patch, MagicMock from fastapi.testclient import TestClient @@ -25,15 +26,13 @@ class TestOAuthLoginFlow: # Check that OAuth option is shown assert b"oauth" in response.content.lower() or b"sign" in response.content.lower() - def test_oauth_login_redirects_to_provider( - self, oauth_enabled_app: TestClient, oauth_config: dict - ): + def test_oauth_login_redirects_to_provider(self, oauth_enabled_app: TestClient, oauth_config: dict): """Test that /oauth-login redirects to the OAuth provider.""" response = oauth_enabled_app.get("/oauth-login", follow_redirects=False) - + # Should redirect to authorization endpoint assert response.status_code == 302 - + # Redirect location should contain the authorization endpoint location = response.headers.get("location", "") if oauth_config["mode"] == "mock": @@ -44,14 +43,17 @@ class TestOAuthLoginFlow: """Test that OAuth login fails gracefully when not configured.""" # Test with OAuth disabled import os + original = os.environ.get("AUTH_ENABLED") os.environ["AUTH_ENABLED"] = "False" - + try: from fastapi.testclient import TestClient + from app.main import app + client = TestClient(app, base_url="http://localhost") - + response = client.get("/oauth-login", follow_redirects=False) # Should either redirect to error page or show login page assert response.status_code in [302, 404] @@ -77,13 +79,13 @@ class TestOAuthCallback: "expires_in": 3600, "userinfo": test_user_info, } - + # Simulate OAuth callback with authorization code response = oauth_enabled_app.get( "/oauth-callback?code=test-auth-code&state=test-state", follow_redirects=False, ) - + # Should redirect after successful login assert response.status_code == 302 @@ -97,24 +99,22 @@ class TestOAuthCallback: "access_token": "mock-access-token", "userinfo": test_user_info, } - + # First, initiate OAuth flow to set up session oauth_enabled_app.get("/oauth-login", follow_redirects=False) - + # Then handle callback response = oauth_enabled_app.get( "/oauth-callback?code=test-auth-code", follow_redirects=False, ) - + # Should set session cookie assert "set-cookie" in response.headers or response.status_code == 302 @pytest.mark.asyncio @patch("app.auth.oauth.authentik.authorize_access_token") - async def test_oauth_callback_with_admin_user( - self, mock_authorize, oauth_enabled_app: TestClient - ): + async def test_oauth_callback_with_admin_user(self, mock_authorize, oauth_enabled_app: TestClient): """Test OAuth callback with admin user group.""" mock_authorize.return_value = { "access_token": "mock-access-token", @@ -125,20 +125,18 @@ class TestOAuthCallback: "groups": ["admin"], }, } - + response = oauth_enabled_app.get( "/oauth-callback?code=test-auth-code", follow_redirects=False, ) - + # Should successfully authenticate assert response.status_code == 302 @pytest.mark.asyncio @patch("app.auth.oauth.authentik.authorize_access_token") - async def test_oauth_callback_rejects_non_admin( - self, mock_authorize, oauth_enabled_app: TestClient - ): + async def test_oauth_callback_rejects_non_admin(self, mock_authorize, oauth_enabled_app: TestClient): """Test that OAuth callback authenticates non-admin users with is_admin=False.""" mock_authorize.return_value = { "access_token": "mock-access-token", @@ -149,12 +147,12 @@ class TestOAuthCallback: "groups": ["users"], # No admin group }, } - + response = oauth_enabled_app.get( "/oauth-callback?code=test-auth-code", follow_redirects=False, ) - + # Non-admin users are still authenticated but with is_admin=False assert response.status_code == 302 @@ -174,46 +172,42 @@ class TestOAuthSessionManagement: "access_token": "mock-access-token", "userinfo": test_user_info, } - + # Authenticate oauth_enabled_app.get("/oauth-callback?code=test-auth-code") - + # Try to access a protected route (e.g., files page) response = oauth_enabled_app.get("/files") - + # Should be able to access with valid session # Note: May redirect to login if session not properly set assert response.status_code in [200, 302] - def test_unauthenticated_user_redirected_to_login( - self, oauth_enabled_app: TestClient - ): + def test_unauthenticated_user_redirected_to_login(self, oauth_enabled_app: TestClient): """Test that unauthenticated users are redirected to login.""" # Try to access protected route without authentication response = oauth_enabled_app.get("/files", follow_redirects=False) - + # Should redirect to login page if response.status_code == 302: assert "/login" in response.headers.get("location", "") @pytest.mark.asyncio @patch("app.auth.oauth.authentik.authorize_access_token") - async def test_logout_clears_session( - self, mock_authorize, oauth_enabled_app: TestClient, test_user_info: dict - ): + async def test_logout_clears_session(self, mock_authorize, oauth_enabled_app: TestClient, test_user_info: dict): """Test that logout clears user session.""" # Mock successful authentication mock_authorize.return_value = { "access_token": "mock-access-token", "userinfo": test_user_info, } - + # Authenticate oauth_enabled_app.get("/oauth-callback?code=test-auth-code") - + # Logout response = oauth_enabled_app.get("/logout", follow_redirects=False) - + # Should redirect after logout assert response.status_code == 302 @@ -222,29 +216,25 @@ class TestOAuthSessionManagement: class TestOAuthErrorHandling: """Test error handling in OAuth flows.""" - def test_oauth_callback_without_code_shows_error( - self, oauth_enabled_app: TestClient - ): + def test_oauth_callback_without_code_shows_error(self, oauth_enabled_app: TestClient): """Test OAuth callback without authorization code.""" response = oauth_enabled_app.get("/oauth-callback", follow_redirects=False) - + # Should handle error gracefully assert response.status_code in [302, 400] @pytest.mark.asyncio @patch("app.auth.oauth.authentik.authorize_access_token") - async def test_oauth_callback_with_invalid_token( - self, mock_authorize, oauth_enabled_app: TestClient - ): + async def test_oauth_callback_with_invalid_token(self, mock_authorize, oauth_enabled_app: TestClient): """Test OAuth callback with invalid token.""" # Mock token exchange failure mock_authorize.side_effect = Exception("Invalid authorization code") - + response = oauth_enabled_app.get( "/oauth-callback?code=invalid-code", follow_redirects=False, ) - + # Should redirect to error page assert response.status_code == 302 location = response.headers.get("location", "") @@ -252,21 +242,19 @@ class TestOAuthErrorHandling: @pytest.mark.asyncio @patch("app.auth.oauth.authentik.authorize_access_token") - async def test_oauth_callback_without_userinfo( - self, mock_authorize, oauth_enabled_app: TestClient - ): + async def test_oauth_callback_without_userinfo(self, mock_authorize, oauth_enabled_app: TestClient): """Test OAuth callback when userinfo is missing.""" # Mock token without userinfo mock_authorize.return_value = { "access_token": "mock-access-token", "userinfo": None, } - + response = oauth_enabled_app.get( "/oauth-callback?code=test-auth-code", follow_redirects=False, ) - + # Should handle missing userinfo assert response.status_code == 302 @@ -276,7 +264,7 @@ class TestOAuthErrorHandling: class TestRealOAuthIntegration: """ Integration tests using real OAuth credentials from GitHub Actions secrets. - + These tests are skipped unless real OAuth credentials are available. """ @@ -284,11 +272,12 @@ class TestRealOAuthIntegration: """Test that real OAuth .well-known endpoint is accessible.""" if not use_real_oauth: pytest.skip("Real OAuth credentials not available") - + import requests + response = requests.get(oauth_config["server_metadata_url"], timeout=10) assert response.status_code == 200 - + config = response.json() assert "authorization_endpoint" in config assert "token_endpoint" in config @@ -298,16 +287,17 @@ class TestRealOAuthIntegration: """Test that real OAuth JWKS endpoint is accessible.""" if not use_real_oauth: pytest.skip("Real OAuth credentials not available") - + import requests + # Get well-known config first response = requests.get(oauth_config["server_metadata_url"], timeout=10) config = response.json() - + # Test JWKS endpoint jwks_response = requests.get(config["jwks_uri"], timeout=10) assert jwks_response.status_code == 200 - + jwks = jwks_response.json() assert "keys" in jwks assert len(jwks["keys"]) > 0 diff --git a/tests/test_ocr_processing.py b/tests/test_ocr_processing.py index fa722036..29d3af20 100644 --- a/tests/test_ocr_processing.py +++ b/tests/test_ocr_processing.py @@ -5,7 +5,6 @@ These tests verify OCR processing logic with mocked external AI/ML services (OpenAI, Azure Document Intelligence). Tests cover typical and edge cases. """ -import os from unittest.mock import MagicMock, Mock, patch import pytest @@ -95,7 +94,6 @@ startxref patch("app.tasks.process_with_azure_document_intelligence.settings") as mock_settings, patch("app.tasks.process_with_azure_document_intelligence.rotate_pdf_pages") as mock_rotate, ): - mock_settings.workdir = str(tmp_path) mock_rotate.delay = MagicMock() @@ -144,7 +142,6 @@ startxref patch("app.tasks.process_with_azure_document_intelligence.settings") as mock_settings, patch("app.tasks.process_with_azure_document_intelligence.os.path.getsize") as mock_getsize, ): - mock_settings.workdir = str(tmp_path) # Mock file size to be larger than 500 MB mock_getsize.return_value = AZURE_DOC_INTELLIGENCE_LIMITS["max_file_size_bytes"] + 1024 @@ -169,7 +166,6 @@ startxref patch("app.tasks.process_with_azure_document_intelligence.settings") as mock_settings, patch("app.tasks.process_with_azure_document_intelligence.get_pdf_page_count") as mock_page_count, ): - mock_settings.workdir = str(tmp_path) # Mock page count to exceed limit mock_page_count.return_value = AZURE_DOC_INTELLIGENCE_LIMITS["max_pages"] + 1 @@ -215,7 +211,6 @@ startxref patch("app.tasks.process_with_azure_document_intelligence.get_pdf_page_count") as mock_page_count, patch("app.tasks.process_with_azure_document_intelligence.rotate_pdf_pages"), ): - mock_settings.workdir = str(tmp_path) # Return None to simulate page count determination failure mock_page_count.return_value = None @@ -267,7 +262,6 @@ startxref patch("app.tasks.process_with_azure_document_intelligence.settings") as mock_settings, patch("app.tasks.process_with_azure_document_intelligence.rotate_pdf_pages") as mock_rotate, ): - mock_settings.workdir = str(tmp_path) mock_rotate.delay = MagicMock() @@ -302,7 +296,6 @@ startxref ), patch("app.tasks.process_with_azure_document_intelligence.settings") as mock_settings, ): - mock_settings.workdir = str(tmp_path) # Should raise the exception @@ -440,7 +433,6 @@ class TestRefineTextWithGPT: patch.object(metadata_module, "extract_metadata_with_gpt") as mock_extract, patch("app.tasks.refine_text_with_gpt.settings") as mock_settings, ): - mock_settings.openai_model = "gpt-4" mock_extract.delay = MagicMock() @@ -473,7 +465,6 @@ class TestRefineTextWithGPT: patch("app.tasks.refine_text_with_gpt.client", mock_client), patch("app.tasks.refine_text_with_gpt.settings") as mock_settings, ): - mock_settings.openai_model = "gpt-4" # Should raise the exception @@ -582,7 +573,6 @@ startxref patch("app.tasks.rotate_pdf_pages.settings") as mock_settings, patch("app.tasks.rotate_pdf_pages.extract_metadata_with_gpt") as mock_extract, ): - mock_settings.workdir = str(tmp_path) mock_extract.delay = MagicMock() @@ -617,7 +607,6 @@ startxref patch("app.tasks.rotate_pdf_pages.settings") as mock_settings, patch("app.tasks.rotate_pdf_pages.extract_metadata_with_gpt") as mock_extract, ): - mock_settings.workdir = str(tmp_path) mock_extract.delay = MagicMock() @@ -651,7 +640,6 @@ startxref patch("app.tasks.rotate_pdf_pages.settings") as mock_settings, patch("app.tasks.rotate_pdf_pages.extract_metadata_with_gpt") as mock_extract, ): - mock_settings.workdir = str(tmp_path) mock_extract.delay = MagicMock() @@ -676,7 +664,6 @@ startxref patch("app.tasks.rotate_pdf_pages.settings") as mock_settings, patch("app.tasks.rotate_pdf_pages.extract_metadata_with_gpt") as mock_extract, ): - mock_settings.workdir = str(tmp_path) mock_extract.delay = MagicMock() @@ -712,7 +699,6 @@ startxref patch("app.tasks.rotate_pdf_pages.settings") as mock_settings, patch("app.tasks.rotate_pdf_pages.extract_metadata_with_gpt") as mock_extract, ): - mock_settings.workdir = str(tmp_path) mock_extract.delay = MagicMock() @@ -783,7 +769,6 @@ startxref patch("app.tasks.rotate_pdf_pages.settings") as mock_settings, patch("app.tasks.rotate_pdf_pages.extract_metadata_with_gpt") as mock_extract, ): - mock_settings.workdir = str(tmp_path) mock_extract.delay = MagicMock() diff --git a/tests/test_original_filename_preservation.py b/tests/test_original_filename_preservation.py index 010ad750..09efeab1 100644 --- a/tests/test_original_filename_preservation.py +++ b/tests/test_original_filename_preservation.py @@ -93,7 +93,6 @@ startxref patch("app.tasks.process_document.log_task_progress"), patch("app.tasks.process_document.extract_metadata_with_gpt") as mock_extract, ): - # Setup mocks mock_settings.workdir = str(tmp_path) mock_session_local.return_value.__enter__.return_value = db_session @@ -194,7 +193,6 @@ startxref patch("app.tasks.process_document.log_task_progress"), patch("app.tasks.process_document.extract_metadata_with_gpt") as mock_extract, ): - # Setup mocks mock_settings.workdir = str(tmp_path) mock_session_local.return_value.__enter__.return_value = db_session diff --git a/tests/test_path_traversal_security.py b/tests/test_path_traversal_security.py index 49dffc3c..ef56a12f 100644 --- a/tests/test_path_traversal_security.py +++ b/tests/test_path_traversal_security.py @@ -4,11 +4,9 @@ Security tests for path traversal vulnerabilities. Tests all file path operations to ensure they properly prevent path traversal attacks. """ -import json import os -import tempfile from pathlib import Path -from unittest.mock import MagicMock, Mock, patch +from unittest.mock import MagicMock, patch import pytest @@ -357,7 +355,6 @@ class TestFileUploadSecurity: def test_ui_upload_uses_basename(self): """Test that ui_upload extracts basename to prevent path traversal.""" - import os from app.utils.filename_utils import sanitize_filename @@ -389,7 +386,6 @@ class TestFileUploadSecurity: def test_sanitize_after_basename(self): """Test that sanitization happens after basename extraction.""" - import os from app.utils.filename_utils import sanitize_filename @@ -443,7 +439,6 @@ class TestEndToEndPathTraversal: def test_full_upload_flow_prevents_traversal(self, tmp_path): """Test complete upload flow prevents path traversal.""" - import os import uuid from app.utils.filename_utils import sanitize_filename @@ -474,7 +469,6 @@ class TestEndToEndPathTraversal: def test_metadata_embedding_flow_prevents_traversal(self, tmp_path): """Test metadata embedding flow prevents path traversal.""" - import os from app.utils.filename_utils import sanitize_filename diff --git a/tests/test_process_document.py b/tests/test_process_document.py index e0459bb3..e93ed444 100644 --- a/tests/test_process_document.py +++ b/tests/test_process_document.py @@ -5,11 +5,9 @@ These tests verify that the process_document task correctly handles file process and doesn't cause DetachedInstanceError when accessing database objects. """ -import os from unittest.mock import MagicMock, patch import pytest -from sqlalchemy.orm import Session from app.models import FileRecord from app.tasks.process_document import process_document @@ -92,7 +90,6 @@ startxref patch("app.tasks.process_document.log_task_progress"), patch("app.tasks.process_document.extract_metadata_with_gpt") as mock_extract, ): - # Setup mocks mock_settings.workdir = str(tmp_path) mock_session_local.return_value.__enter__.return_value = db_session @@ -153,7 +150,6 @@ def test_process_document_duplicate_file(db_session, tmp_path): patch("app.tasks.process_document.SessionLocal") as mock_session_local, patch("app.tasks.process_document.log_task_progress"), ): - # Setup mocks mock_session_local.return_value.__enter__.return_value = db_session mock_session_local.return_value.__exit__.return_value = None @@ -226,7 +222,6 @@ startxref patch("app.tasks.process_document.log_task_progress"), patch("app.tasks.process_document.process_with_azure_document_intelligence") as mock_azure, ): - # Setup mocks mock_settings.workdir = str(tmp_path) mock_session_local.return_value.__enter__.return_value = db_session @@ -345,7 +340,6 @@ startxref patch("app.tasks.process_document.log_task_progress"), patch("app.tasks.process_document.extract_metadata_with_gpt") as mock_extract, ): - # Setup mocks mock_settings.workdir = str(tmp_path) mock_session_local.return_value.__enter__.return_value = db_session diff --git a/tests/test_processall_throttling.py b/tests/test_processall_throttling.py index 5b2d65b8..e87c1d5d 100644 --- a/tests/test_processall_throttling.py +++ b/tests/test_processall_throttling.py @@ -2,8 +2,7 @@ Tests for /processall endpoint throttling behavior. """ -import os -from unittest.mock import MagicMock, Mock, patch +from unittest.mock import Mock, patch import pytest from fastapi.testclient import TestClient diff --git a/tests/test_rate_limit_decorators.py b/tests/test_rate_limit_decorators.py index 761ffcfa..eccb0ab4 100644 --- a/tests/test_rate_limit_decorators.py +++ b/tests/test_rate_limit_decorators.py @@ -4,9 +4,9 @@ Tests for app/middleware/rate_limit_decorators.py This module tests the rate limiting decorators for API endpoints. """ +from unittest.mock import MagicMock, patch + import pytest -from unittest.mock import MagicMock, patch, Mock -from fastapi import Request @pytest.mark.unit @@ -16,10 +16,10 @@ class TestRateLimitDecorators: def test_get_limiter_initialization(self): """Test that get_limiter initializes limiter from app state.""" from app.middleware import rate_limit_decorators - + # Reset the global limiter rate_limit_decorators._limiter = None - + # Try to get limiter - will import app and get limiter from state # This test just verifies the function can be called try: @@ -34,128 +34,130 @@ class TestRateLimitDecorators: def test_get_limiter_caching(self): """Test that get_limiter caches the limiter instance.""" from app.middleware import rate_limit_decorators - + # Set up mock limiter directly mock_limiter = MagicMock() rate_limit_decorators._limiter = mock_limiter - + # Get limiter multiple times limiter1 = rate_limit_decorators.get_limiter() limiter2 = rate_limit_decorators.get_limiter() - + # Should return same instance assert limiter1 is limiter2 assert limiter1 is mock_limiter - @patch('app.middleware.rate_limit_decorators.get_limiter') + @patch("app.middleware.rate_limit_decorators.get_limiter") def test_limit_decorator(self, mock_get_limiter): """Test the limit decorator applies rate limit.""" from app.middleware.rate_limit_decorators import limit - + # Mock limiter mock_limiter = MagicMock() mock_limiter.limit = MagicMock(return_value=lambda f: f) mock_get_limiter.return_value = mock_limiter - + # Create a test function @limit("10/minute") async def test_endpoint(): return {"message": "success"} - + # Verify limiter.limit was called with correct rate mock_limiter.limit.assert_called_once_with("10/minute") - @patch('app.middleware.rate_limit_decorators.get_limiter') + @patch("app.middleware.rate_limit_decorators.get_limiter") def test_limit_decorator_with_different_rates(self, mock_get_limiter): """Test limit decorator with various rate limit strings.""" from app.middleware.rate_limit_decorators import limit - + # Mock limiter mock_limiter = MagicMock() mock_limiter.limit = MagicMock(return_value=lambda f: f) mock_get_limiter.return_value = mock_limiter - + # Test different rate limits rates = ["5/second", "100/hour", "1000/day"] - + for rate in rates: mock_limiter.limit.reset_mock() - + @limit(rate) async def test_endpoint(): return {"message": "success"} - + mock_limiter.limit.assert_called_once_with(rate) - @patch('app.middleware.rate_limit_decorators.get_limiter') + @patch("app.middleware.rate_limit_decorators.get_limiter") def test_exempt_decorator(self, mock_get_limiter): """Test the exempt decorator exempts endpoint from rate limiting.""" from app.middleware.rate_limit_decorators import exempt - + # Mock limiter mock_limiter = MagicMock() mock_limiter.exempt = MagicMock(return_value=lambda f: f) mock_get_limiter.return_value = mock_limiter - + # Create a test function @exempt() async def test_endpoint(): return {"message": "success"} - + # Verify limiter.exempt was called mock_limiter.exempt.assert_called_once() - @patch('app.middleware.rate_limit_decorators.get_limiter') + @patch("app.middleware.rate_limit_decorators.get_limiter") def test_limit_decorator_preserves_function(self, mock_get_limiter): """Test that limit decorator preserves the original function.""" from app.middleware.rate_limit_decorators import limit - + # Mock limiter to return the function unchanged mock_limiter = MagicMock() mock_limiter.limit = MagicMock(return_value=lambda f: f) mock_get_limiter.return_value = mock_limiter - + # Original function async def original_function(): return "original" - + # Decorate it @limit("10/minute") async def decorated_function(): return "original" - + # Function should still work import asyncio + result = asyncio.run(decorated_function()) assert result == "original" - @patch('app.middleware.rate_limit_decorators.get_limiter') + @patch("app.middleware.rate_limit_decorators.get_limiter") def test_exempt_decorator_preserves_function(self, mock_get_limiter): """Test that exempt decorator preserves the original function.""" from app.middleware.rate_limit_decorators import exempt - + # Mock limiter to return a simple passthrough decorator mock_limiter = MagicMock() mock_limiter.exempt.side_effect = lambda f: f mock_get_limiter.return_value = mock_limiter - + # Decorate function @exempt() async def decorated_function(): return "exempted" - + # Function should still work import asyncio + result = asyncio.run(decorated_function()) assert result == "exempted" def test_module_imports(self): """Test that the module can be imported without errors.""" from app.middleware import rate_limit_decorators - - assert hasattr(rate_limit_decorators, 'get_limiter') - assert hasattr(rate_limit_decorators, 'limit') - assert hasattr(rate_limit_decorators, 'exempt') + + assert hasattr(rate_limit_decorators, "get_limiter") + assert hasattr(rate_limit_decorators, "limit") + assert hasattr(rate_limit_decorators, "exempt") assert callable(rate_limit_decorators.get_limiter) assert callable(rate_limit_decorators.limit) assert callable(rate_limit_decorators.exempt) diff --git a/tests/test_rate_limiting.py b/tests/test_rate_limiting.py index 4b3f10ce..78deb612 100644 --- a/tests/test_rate_limiting.py +++ b/tests/test_rate_limiting.py @@ -7,10 +7,7 @@ These tests validate that rate limiting is properly applied to API endpoints to prevent abuse and DoS attacks. """ -import time - import pytest -from fastapi import status @pytest.mark.unit @@ -101,7 +98,6 @@ def test_rate_limit_exceeded_returns_429(client): @pytest.mark.security def test_rate_limiting_uses_correct_identifier(): """Test that rate limiting uses IP or user ID as identifier.""" - from fastapi import Request from app.middleware.rate_limit import get_identifier diff --git a/tests/test_rclone_tasks.py b/tests/test_rclone_tasks.py index 799cfe6a..83f120f0 100644 --- a/tests/test_rclone_tasks.py +++ b/tests/test_rclone_tasks.py @@ -1,7 +1,6 @@ """Tests for app/tasks/upload_with_rclone.py module.""" -import os -from unittest.mock import MagicMock, patch +from unittest.mock import patch import pytest diff --git a/tests/test_security_headers.py b/tests/test_security_headers.py index 821e0f86..5e4be4e7 100644 --- a/tests/test_security_headers.py +++ b/tests/test_security_headers.py @@ -142,9 +142,9 @@ def test_x_frame_options_valid_value(client): x_frame_value = response.headers["X-Frame-Options"] valid_values = ["DENY", "SAMEORIGIN"] # Note: ALLOW-FROM is deprecated in modern browsers; use CSP frame-ancestors instead - assert x_frame_value in valid_values or x_frame_value.startswith( - "ALLOW-FROM" - ), f"Invalid X-Frame-Options value: {x_frame_value}" + assert x_frame_value in valid_values or x_frame_value.startswith("ALLOW-FROM"), ( + f"Invalid X-Frame-Options value: {x_frame_value}" + ) @pytest.mark.integration diff --git a/tests/test_settings.py b/tests/test_settings.py index 5f178b81..9de8b8dd 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -6,7 +6,6 @@ import pytest from fastapi.testclient import TestClient from sqlalchemy.orm import Session -from app.config import Settings from app.models import ApplicationSettings from app.utils.config_loader import convert_setting_value, load_settings_from_db from app.utils.settings_service import ( @@ -224,7 +223,6 @@ class TestSettingsPrecedence: def test_db_overrides_default(self, db_session: Session): """Test that database settings override default values""" # Create a minimal test settings object - from typing import Optional from pydantic_settings import BaseSettings diff --git a/tests/test_step_timeout.py b/tests/test_step_timeout.py index bc6eaa5b..93341fef 100644 --- a/tests/test_step_timeout.py +++ b/tests/test_step_timeout.py @@ -4,82 +4,82 @@ Tests for app/utils/step_timeout.py This module tests step timeout detection and handling logic. """ -import pytest -from unittest.mock import MagicMock, patch, call from datetime import datetime, timedelta +from unittest.mock import MagicMock, patch + +import pytest @pytest.mark.unit class TestStepTimeout: """Test step timeout utilities.""" - @patch('app.utils.step_timeout.settings') + @patch("app.utils.step_timeout.settings") def test_get_step_timeout_default(self, mock_settings): """Test get_step_timeout returns default value.""" - from app.utils.step_timeout import get_step_timeout, DEFAULT_STEP_TIMEOUT - + from app.utils.step_timeout import DEFAULT_STEP_TIMEOUT, get_step_timeout + # No custom timeout in settings del mock_settings.step_timeout - + timeout = get_step_timeout() assert timeout == DEFAULT_STEP_TIMEOUT assert timeout == 600 - @patch('app.utils.step_timeout.settings') + @patch("app.utils.step_timeout.settings") def test_get_step_timeout_custom(self, mock_settings): """Test get_step_timeout returns custom value from settings.""" from app.utils.step_timeout import get_step_timeout - + # Custom timeout in settings mock_settings.step_timeout = 300 - + timeout = get_step_timeout() assert timeout == 300 - @patch('app.utils.step_timeout.logger') + @patch("app.utils.step_timeout.logger") def test_mark_stalled_steps_as_failed_no_steps(self, mock_logger): """Test mark_stalled_steps_as_failed when no stalled steps exist.""" from app.utils.step_timeout import mark_stalled_steps_as_failed - from app.models import FileProcessingStep - + # Mock database session with proper query chain mock_db = MagicMock() # Set up the query chain to return empty list (single .filter() call with multiple conditions) mock_db.query.return_value.filter.return_value.all.return_value = [] - + # Run function count = mark_stalled_steps_as_failed(mock_db) - + # No steps should be marked assert count == 0 - @patch('app.utils.step_timeout.logger') + @patch("app.utils.step_timeout.logger") def test_mark_stalled_steps_as_failed_with_stalled_steps(self, mock_logger): """Test mark_stalled_steps_as_failed marks stalled steps.""" - from app.utils.step_timeout import mark_stalled_steps_as_failed from app.models import FileProcessingStep - + from app.utils.step_timeout import mark_stalled_steps_as_failed + # Create mock stalled steps step1 = MagicMock(spec=FileProcessingStep) step1.file_id = 1 step1.step_name = "ocr" step1.status = "in_progress" step1.started_at = datetime.utcnow() - timedelta(seconds=700) - + step2 = MagicMock(spec=FileProcessingStep) step2.file_id = 2 step2.step_name = "metadata" step2.status = "in_progress" step2.started_at = datetime.utcnow() - timedelta(seconds=800) - + # Mock database session mock_db = MagicMock() # Set up the query chain to return stalled steps (single .filter() call with multiple conditions) mock_db.query.return_value.filter.return_value.all.return_value = [step1, step2] - + # Run function count = mark_stalled_steps_as_failed(mock_db) - + # Both steps should be marked as failed assert count == 2 assert step1.status == "failure" @@ -90,63 +90,63 @@ class TestStepTimeout: assert "timeout" in step2.error_message.lower() mock_db.commit.assert_called_once() - @patch('app.utils.step_timeout.logger') + @patch("app.utils.step_timeout.logger") def test_mark_stalled_steps_as_failed_custom_timeout(self, mock_logger): """Test mark_stalled_steps_as_failed with custom timeout.""" - from app.utils.step_timeout import mark_stalled_steps_as_failed from app.models import FileProcessingStep - + from app.utils.step_timeout import mark_stalled_steps_as_failed + # Create mock step that's stalled with custom timeout step = MagicMock(spec=FileProcessingStep) step.file_id = 1 step.step_name = "ocr" step.status = "in_progress" step.started_at = datetime.utcnow() - timedelta(seconds=200) # 200 seconds ago - + # Mock database session mock_db = MagicMock() # Set up the query chain to return stalled step (single .filter() call with multiple conditions) mock_db.query.return_value.filter.return_value.all.return_value = [step] - + # Run function with 150 second timeout count = mark_stalled_steps_as_failed(mock_db, timeout_seconds=150) - + # Step should be marked as failed assert count == 1 assert step.status == "failure" assert "150 seconds" in step.error_message - @patch('app.utils.step_timeout.logger') + @patch("app.utils.step_timeout.logger") def test_mark_stalled_steps_as_failed_for_specific_file(self, mock_logger): """Test mark_stalled_steps_as_failed for specific file.""" - from app.utils.step_timeout import mark_stalled_steps_as_failed from app.models import FileProcessingStep - + from app.utils.step_timeout import mark_stalled_steps_as_failed + # Create mock stalled step step = MagicMock(spec=FileProcessingStep) step.file_id = 42 step.step_name = "ocr" step.status = "in_progress" step.started_at = datetime.utcnow() - timedelta(seconds=700) - + # Mock database session with file filter mock_db = MagicMock() # Set up the query chain with file filter (first .filter() for conditions, second for file_id) mock_db.query.return_value.filter.return_value.filter.return_value.all.return_value = [step] - + # Run function for specific file count = mark_stalled_steps_as_failed(mock_db, file_id=42) - + # Step should be marked as failed assert count == 1 assert step.status == "failure" - @patch('app.utils.step_timeout.logger') + @patch("app.utils.step_timeout.logger") def test_mark_stalled_steps_as_failed_error_message_format(self, mock_logger): """Test that error message includes all necessary details.""" - from app.utils.step_timeout import mark_stalled_steps_as_failed from app.models import FileProcessingStep - + from app.utils.step_timeout import mark_stalled_steps_as_failed + # Create mock stalled step started_time = datetime.utcnow() - timedelta(seconds=700) step = MagicMock(spec=FileProcessingStep) @@ -154,15 +154,15 @@ class TestStepTimeout: step.step_name = "ocr" step.status = "in_progress" step.started_at = started_time - + # Mock database session mock_db = MagicMock() # Set up the query chain to return stalled step (single .filter() call with multiple conditions) mock_db.query.return_value.filter.return_value.all.return_value = [step] - + # Run function count = mark_stalled_steps_as_failed(mock_db, timeout_seconds=600) - + # Check error message content assert count == 1 error_msg = step.error_message @@ -170,75 +170,75 @@ class TestStepTimeout: assert "timeout" in error_msg.lower() assert str(started_time) in error_msg - @patch('app.utils.step_timeout.logger') + @patch("app.utils.step_timeout.logger") def test_mark_stalled_steps_as_failed_logging(self, mock_logger): """Test that mark_stalled_steps_as_failed logs warnings and errors.""" - from app.utils.step_timeout import mark_stalled_steps_as_failed from app.models import FileProcessingStep - + from app.utils.step_timeout import mark_stalled_steps_as_failed + # Create mock stalled step step = MagicMock(spec=FileProcessingStep) step.file_id = 1 step.step_name = "ocr" step.status = "in_progress" step.started_at = datetime.utcnow() - timedelta(seconds=700) - + # Mock database session mock_db = MagicMock() # Set up the query chain to return stalled step (single .filter() call with multiple conditions) mock_db.query.return_value.filter.return_value.all.return_value = [step] - + # Run function count = mark_stalled_steps_as_failed(mock_db) - + # Verify logging assert count == 1 mock_logger.warning.assert_called_once() mock_logger.error.assert_called_once() - @patch('app.utils.step_timeout.logger') + @patch("app.utils.step_timeout.logger") def test_check_and_recover_stalled_file_found(self, mock_logger): """Test check_and_recover_stalled_file when stalled steps found.""" - from app.utils.step_timeout import check_and_recover_stalled_file from app.models import FileProcessingStep - + from app.utils.step_timeout import check_and_recover_stalled_file + # Create mock stalled step step = MagicMock(spec=FileProcessingStep) step.file_id = 42 step.step_name = "ocr" step.status = "in_progress" step.started_at = datetime.utcnow() - timedelta(seconds=700) - + # Mock database session mock_db = MagicMock() # Set up the query chain with file filter (first .filter() for conditions, second for file_id) mock_db.query.return_value.filter.return_value.filter.return_value.all.return_value = [step] - + # Run function result = check_and_recover_stalled_file(mock_db, 42) - + # Should return True when stalled steps found assert result is True - @patch('app.utils.step_timeout.logger') + @patch("app.utils.step_timeout.logger") def test_check_and_recover_stalled_file_not_found(self, mock_logger): """Test check_and_recover_stalled_file when no stalled steps.""" from app.utils.step_timeout import check_and_recover_stalled_file - + # Mock database session with no stalled steps mock_db = MagicMock() # Set up the query chain with file filter (first .filter() for conditions, second for file_id) mock_db.query.return_value.filter.return_value.filter.return_value.all.return_value = [] - + # Run function result = check_and_recover_stalled_file(mock_db, 42) - + # Should return False when no stalled steps assert result is False def test_default_step_timeout_constant(self): """Test that DEFAULT_STEP_TIMEOUT is defined correctly.""" from app.utils.step_timeout import DEFAULT_STEP_TIMEOUT - + assert DEFAULT_STEP_TIMEOUT == 600 assert isinstance(DEFAULT_STEP_TIMEOUT, int) diff --git a/tests/test_storage_reorganization.py b/tests/test_storage_reorganization.py index 0bd94d36..cb6bc7c6 100644 --- a/tests/test_storage_reorganization.py +++ b/tests/test_storage_reorganization.py @@ -10,7 +10,6 @@ import os from unittest.mock import MagicMock, patch import pytest -from sqlalchemy.orm import Session from app.models import FileRecord diff --git a/tests/test_upload_email.py b/tests/test_upload_email.py index 856b04ec..f495fde3 100644 --- a/tests/test_upload_email.py +++ b/tests/test_upload_email.py @@ -1,7 +1,5 @@ """Tests for app/tasks/upload_to_email.py module.""" -from unittest.mock import MagicMock, patch - import pytest diff --git a/tests/test_upload_ftp_additional.py b/tests/test_upload_ftp_additional.py index e0592963..5c8a3f0a 100644 --- a/tests/test_upload_ftp_additional.py +++ b/tests/test_upload_ftp_additional.py @@ -1,7 +1,5 @@ """Additional tests for upload_to_ftp task.""" -from unittest.mock import MagicMock, patch - import pytest diff --git a/tests/test_upload_tasks.py b/tests/test_upload_tasks.py index c0ca775c..4c4c63e3 100644 --- a/tests/test_upload_tasks.py +++ b/tests/test_upload_tasks.py @@ -3,7 +3,7 @@ Tests for upload tasks including OneDrive, S3, FTP, SFTP, WebDAV, Google Drive, """ import os -from unittest.mock import MagicMock, Mock, patch +from unittest.mock import Mock, patch import pytest @@ -53,7 +53,6 @@ def test_upload_to_onedrive_accepts_file_id(sample_text_file, mock_settings): patch("app.tasks.upload_to_onedrive.upload_large_file") as mock_upload, patch("app.tasks.upload_to_onedrive.log_task_progress"), ): - # Setup mocks mock_token.return_value = "test_access_token" mock_session.return_value = "https://upload.url" @@ -77,7 +76,6 @@ def test_upload_to_onedrive_without_file_id(sample_text_file, mock_settings): patch("app.tasks.upload_to_onedrive.upload_large_file") as mock_upload, patch("app.tasks.upload_to_onedrive.log_task_progress"), ): - # Setup mocks mock_token.return_value = "test_access_token" mock_session.return_value = "https://upload.url" @@ -97,7 +95,6 @@ def test_upload_to_s3_accepts_file_id(sample_text_file, mock_settings): patch("app.tasks.upload_to_s3.boto3.client") as mock_boto_client, patch("app.tasks.upload_to_s3.log_task_progress"), ): - # Setup mock S3 client mock_s3 = Mock() mock_boto_client.return_value = mock_s3 @@ -119,7 +116,6 @@ def test_upload_to_s3_without_file_id(sample_text_file, mock_settings): patch("app.tasks.upload_to_s3.boto3.client") as mock_boto_client, patch("app.tasks.upload_to_s3.log_task_progress"), ): - # Setup mock S3 client mock_s3 = Mock() mock_boto_client.return_value = mock_s3 @@ -157,7 +153,6 @@ def test_upload_to_onedrive_logs_with_file_id(sample_text_file, mock_settings): patch("app.tasks.upload_to_onedrive.upload_large_file") as mock_upload, patch("app.tasks.upload_to_onedrive.log_task_progress") as mock_log, ): - # Setup mocks mock_token.return_value = "test_access_token" mock_session.return_value = "https://upload.url" @@ -182,7 +177,6 @@ def test_upload_to_s3_logs_with_file_id(sample_text_file, mock_settings): patch("app.tasks.upload_to_s3.boto3.client") as mock_boto_client, patch("app.tasks.upload_to_s3.log_task_progress") as mock_log, ): - # Setup mock S3 client mock_s3 = Mock() mock_boto_client.return_value = mock_s3 @@ -211,7 +205,6 @@ def test_upload_to_ftp_accepts_file_id(sample_text_file): patch("app.tasks.upload_to_ftp.ftplib.FTP") as mock_ftp, patch("app.tasks.upload_to_ftp.log_task_progress"), ): - # Setup settings mock_settings.ftp_host = "ftp.example.com" mock_settings.ftp_port = 21 @@ -241,7 +234,6 @@ def test_upload_to_ftp_without_file_id(sample_text_file): patch("app.tasks.upload_to_ftp.ftplib.FTP") as mock_ftp, patch("app.tasks.upload_to_ftp.log_task_progress"), ): - # Setup settings mock_settings.ftp_host = "ftp.example.com" mock_settings.ftp_username = "test_user" @@ -270,7 +262,6 @@ def test_upload_to_sftp_accepts_file_id(sample_text_file): patch("app.tasks.upload_to_sftp.extract_remote_path") as mock_extract, patch("app.tasks.upload_to_sftp.get_unique_filename") as mock_unique, ): - # Setup settings mock_settings.sftp_host = "sftp.example.com" mock_settings.sftp_port = 22 @@ -303,7 +294,6 @@ def test_upload_to_webdav_accepts_file_id(sample_text_file): patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - # Setup settings mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "test_user" @@ -334,7 +324,6 @@ def test_upload_to_google_drive_accepts_file_id(sample_text_file): patch("app.tasks.upload_to_google_drive.settings") as mock_settings, patch("app.tasks.upload_to_google_drive.log_task_progress"), ): - # Setup settings mock_settings.google_drive_folder_id = "test_folder_id" @@ -374,7 +363,6 @@ def test_upload_to_email_accepts_file_id(sample_text_file): patch("app.tasks.upload_to_email._send_email_with_smtp") as mock_send, patch("app.tasks.upload_to_email.attach_logo") as mock_logo, ): - # Setup settings mock_settings.email_host = "smtp.example.com" mock_settings.email_port = 587 @@ -406,7 +394,6 @@ def test_upload_to_email_accepts_file_id(sample_text_file): def test_upload_to_ftp_file_not_found(): """Test that upload_to_ftp raises error for missing file.""" with patch("app.tasks.upload_to_ftp.settings") as mock_settings, patch("app.tasks.upload_to_ftp.log_task_progress"): - mock_settings.ftp_host = "ftp.example.com" with pytest.raises(FileNotFoundError): @@ -420,7 +407,6 @@ def test_upload_to_sftp_file_not_found(): patch("app.tasks.upload_to_sftp.settings") as mock_settings, patch("app.tasks.upload_to_sftp.log_task_progress"), ): - mock_settings.sftp_host = "sftp.example.com" mock_settings.sftp_port = 22 mock_settings.sftp_username = "test_user" @@ -436,7 +422,6 @@ def test_upload_to_webdav_file_not_found(): patch("app.tasks.upload_to_webdav.settings") as mock_settings, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = "https://webdav.example.com/" with pytest.raises(FileNotFoundError): @@ -504,7 +489,6 @@ def test_send_to_all_calls_upload_tasks_with_keyword_argument(): patch("app.tasks.send_to_all.SessionLocal"), patch("app.tasks.send_to_all.get_configured_services_from_validator") as mock_validator, ): - # Configure validator to return S3 as configured mock_validator.return_value = {"s3": True} diff --git a/tests/test_upload_tasks_additional.py b/tests/test_upload_tasks_additional.py index f79d2a66..6cbe3294 100644 --- a/tests/test_upload_tasks_additional.py +++ b/tests/test_upload_tasks_additional.py @@ -1,6 +1,5 @@ """Additional tests for upload task modules.""" -import os from unittest.mock import MagicMock, patch import pytest diff --git a/tests/test_upload_tasks_coverage.py b/tests/test_upload_tasks_coverage.py index 6f5fe027..2d04fbb9 100644 --- a/tests/test_upload_tasks_coverage.py +++ b/tests/test_upload_tasks_coverage.py @@ -1,8 +1,5 @@ """Tests to increase coverage for upload task modules.""" -import os -from unittest.mock import MagicMock, patch - import pytest from app.tasks.upload_to_ftp import upload_to_ftp diff --git a/tests/test_upload_to_dropbox.py b/tests/test_upload_to_dropbox.py index 58f95963..0533fde8 100644 --- a/tests/test_upload_to_dropbox.py +++ b/tests/test_upload_to_dropbox.py @@ -5,8 +5,7 @@ Covers _validate_dropbox_settings, get_dropbox_access_token, get_dropbox_client, and upload_to_dropbox Celery task. """ -import os -from unittest.mock import MagicMock, Mock, patch +from unittest.mock import Mock, patch import pytest from dropbox.exceptions import ApiError, AuthError @@ -255,9 +254,7 @@ class TestUploadToDropbox: @patch("app.tasks.upload_to_dropbox.get_dropbox_client") @patch("app.tasks.upload_to_dropbox.log_task_progress") @patch("app.tasks.upload_to_dropbox.settings") - def test_large_file_chunked_upload( - self, mock_settings, mock_log, mock_client, mock_extract, mock_unique, tmp_path - ): + def test_large_file_chunked_upload(self, mock_settings, mock_log, mock_client, mock_extract, mock_unique, tmp_path): """Test chunked upload for large files (>10MB).""" from app.tasks.upload_to_dropbox import upload_to_dropbox diff --git a/tests/test_upload_to_nextcloud.py b/tests/test_upload_to_nextcloud.py index 21105127..2c1c68c2 100644 --- a/tests/test_upload_to_nextcloud.py +++ b/tests/test_upload_to_nextcloud.py @@ -5,8 +5,7 @@ Covers the upload_to_nextcloud Celery task including configuration validation, WebDAV upload, directory creation, and error handling. """ -import os -from unittest.mock import MagicMock, Mock, call, patch +from unittest.mock import Mock, patch import pytest diff --git a/tests/test_upload_to_onedrive.py b/tests/test_upload_to_onedrive.py index d9acb459..79fe941a 100644 --- a/tests/test_upload_to_onedrive.py +++ b/tests/test_upload_to_onedrive.py @@ -5,8 +5,7 @@ Covers get_onedrive_token, create_upload_session, upload_large_file, and upload_to_onedrive Celery task. """ -import os -from unittest.mock import MagicMock, Mock, patch +from unittest.mock import Mock, patch import pytest diff --git a/tests/test_upload_to_paperless.py b/tests/test_upload_to_paperless.py index 4667ff3c..c4042f93 100644 --- a/tests/test_upload_to_paperless.py +++ b/tests/test_upload_to_paperless.py @@ -6,8 +6,7 @@ get_custom_field_id, set_document_custom_fields) and the upload_to_paperless Cel """ import json -import os -from unittest.mock import MagicMock, Mock, mock_open, patch +from unittest.mock import Mock, patch import pytest import requests @@ -152,9 +151,7 @@ class TestPollTaskForDocumentId: mock_settings.http_request_timeout = 30 mock_response = Mock() - mock_response.json.return_value = { - "results": [{"status": "SUCCESS", "related_document": "99"}] - } + mock_response.json.return_value = {"results": [{"status": "SUCCESS", "related_document": "99"}]} mock_response.raise_for_status = Mock() mock_get.return_value = mock_response @@ -188,9 +185,7 @@ class TestPollTaskForDocumentId: mock_settings.http_request_timeout = 30 mock_response = Mock() - mock_response.json.return_value = [ - {"status": "FAILURE", "result": "Not consuming duplicate document"} - ] + mock_response.json.return_value = [{"status": "FAILURE", "result": "Not consuming duplicate document"}] mock_response.raise_for_status = Mock() mock_get.return_value = mock_response @@ -262,9 +257,7 @@ class TestGetCustomFieldId: mock_settings.http_request_timeout = 30 mock_response = Mock() - mock_response.json.return_value = { - "results": [{"name": "sender", "id": 5}, {"name": "date", "id": 6}] - } + mock_response.json.return_value = {"results": [{"name": "sender", "id": 5}, {"name": "date", "id": 6}]} mock_response.raise_for_status = Mock() mock_get.return_value = mock_response diff --git a/tests/test_upload_webdav_comprehensive.py b/tests/test_upload_webdav_comprehensive.py index 2c30a9c9..a17b9f9f 100644 --- a/tests/test_upload_webdav_comprehensive.py +++ b/tests/test_upload_webdav_comprehensive.py @@ -1,10 +1,10 @@ """Comprehensive tests for upload_to_webdav task.""" import os -from unittest.mock import MagicMock, Mock, patch +from unittest.mock import Mock, patch import pytest -from requests.exceptions import ConnectionError, RequestException, Timeout +from requests.exceptions import ConnectionError, Timeout from app.tasks.upload_to_webdav import upload_to_webdav @@ -23,7 +23,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress") as mock_log, ): - # Setup settings mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "test_user" @@ -65,7 +64,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "test_user" mock_settings.webdav_password = _TEST_CREDENTIAL @@ -89,7 +87,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "test_user" mock_settings.webdav_password = _TEST_CREDENTIAL @@ -111,7 +108,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.settings") as mock_settings, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = None mock_settings.webdav_username = "test_user" mock_settings.webdav_password = _TEST_CREDENTIAL @@ -125,7 +121,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.settings") as mock_settings, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = "https://webdav.example.com/" with pytest.raises(FileNotFoundError, match="File not found"): @@ -138,7 +133,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "test_user" mock_settings.webdav_password = _TEST_CREDENTIAL @@ -162,7 +156,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "test_user" mock_settings.webdav_password = _TEST_CREDENTIAL @@ -185,7 +178,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "test_user" mock_settings.webdav_password = _TEST_CREDENTIAL @@ -208,7 +200,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "test_user" mock_settings.webdav_password = _TEST_CREDENTIAL @@ -229,7 +220,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "test_user" mock_settings.webdav_password = _TEST_CREDENTIAL @@ -250,7 +240,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "test_user" mock_settings.webdav_password = _TEST_CREDENTIAL @@ -277,7 +266,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = "https://webdav.example.com" mock_settings.webdav_username = "test_user" mock_settings.webdav_password = _TEST_CREDENTIAL @@ -303,7 +291,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "test_user" mock_settings.webdav_password = _TEST_CREDENTIAL @@ -329,7 +316,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "test_user" mock_settings.webdav_password = _TEST_CREDENTIAL @@ -352,7 +338,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "test_user" mock_settings.webdav_password = _TEST_CREDENTIAL @@ -377,7 +362,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "test_user" mock_settings.webdav_password = _TEST_CREDENTIAL @@ -402,7 +386,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "custom_user" mock_settings.webdav_password = _TEST_CUSTOM_CREDENTIAL @@ -427,7 +410,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress") as mock_log, ): - mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "test_user" mock_settings.webdav_password = _TEST_CREDENTIAL @@ -455,7 +437,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress") as mock_log, ): - mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "test_user" mock_settings.webdav_password = _TEST_CREDENTIAL @@ -482,7 +463,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "test_user" mock_settings.webdav_password = _TEST_CREDENTIAL @@ -509,7 +489,6 @@ class TestUploadToWebDAV: patch("app.tasks.upload_to_webdav.requests.put") as mock_put, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = "https://webdav.example.com/" mock_settings.webdav_username = "test_user" mock_settings.webdav_password = _TEST_CREDENTIAL diff --git a/tests/test_upload_webdav_integration.py b/tests/test_upload_webdav_integration.py index 62376f2e..dd7fa627 100644 --- a/tests/test_upload_webdav_integration.py +++ b/tests/test_upload_webdav_integration.py @@ -7,7 +7,6 @@ actual file uploads against it, then verify the files were uploaded successfully import os import time -from pathlib import Path from unittest.mock import patch import pytest @@ -87,7 +86,6 @@ class TestWebDAVIntegration: patch("app.tasks.upload_to_webdav.settings") as mock_settings, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - # Configure settings to point to real WebDAV server mock_settings.webdav_url = webdav_server["url"] + "/" mock_settings.webdav_username = webdav_server["username"] @@ -124,7 +122,6 @@ class TestWebDAVIntegration: patch("app.tasks.upload_to_webdav.settings") as mock_settings, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - # Create a test folder first folder_name = "test-uploads" folder_url = f"{webdav_server['url']}/{folder_name}" @@ -162,7 +159,6 @@ class TestWebDAVIntegration: patch("app.tasks.upload_to_webdav.settings") as mock_settings, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = webdav_server["url"] + "/" mock_settings.webdav_username = webdav_server["username"] mock_settings.webdav_password = webdav_server["password"] @@ -193,7 +189,6 @@ class TestWebDAVIntegration: patch("app.tasks.upload_to_webdav.settings") as mock_settings, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = webdav_server["url"] + "/" mock_settings.webdav_username = "wronguser" mock_settings.webdav_password = _TEST_WRONG_CREDENTIAL @@ -211,7 +206,6 @@ class TestWebDAVIntegration: patch("app.tasks.upload_to_webdav.settings") as mock_settings, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = webdav_server["url"] + "/" mock_settings.webdav_username = webdav_server["username"] mock_settings.webdav_password = webdav_server["password"] @@ -253,7 +247,6 @@ class TestWebDAVIntegration: patch("app.tasks.upload_to_webdav.settings") as mock_settings, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = webdav_server["url"] + "/" mock_settings.webdav_username = webdav_server["username"] mock_settings.webdav_password = webdav_server["password"] @@ -291,7 +284,6 @@ class TestWebDAVIntegration: patch("app.tasks.upload_to_webdav.settings") as mock_settings, patch("app.tasks.upload_to_webdav.log_task_progress"), ): - mock_settings.webdav_url = webdav_server["url"] + "/" mock_settings.webdav_username = webdav_server["username"] mock_settings.webdav_password = webdav_server["password"] @@ -313,9 +305,9 @@ class TestWebDAVIntegration: response = requests.get(file_url, auth=(webdav_server["username"], webdav_server["password"]), timeout=10) assert response.status_code == 200 - assert ( - len(response.content) == 1024 * 1024 - ), f"File size mismatch: expected 1MB, got {len(response.content)} bytes" + assert len(response.content) == 1024 * 1024, ( + f"File size mismatch: expected 1MB, got {len(response.content)} bytes" + ) @pytest.mark.integration diff --git a/tests/test_upload_with_rclone.py b/tests/test_upload_with_rclone.py index 565545fd..679f44c9 100644 --- a/tests/test_upload_with_rclone.py +++ b/tests/test_upload_with_rclone.py @@ -5,9 +5,8 @@ Extends existing tests with comprehensive coverage for upload_with_rclone and send_to_all_rclone_destinations Celery tasks. """ -import os import subprocess -from unittest.mock import MagicMock, Mock, call, patch +from unittest.mock import Mock, patch import pytest @@ -117,9 +116,7 @@ class TestUploadWithRcloneExtended: rclone_config = tmp_path / "rclone.conf" rclone_config.write_text("[gdrive]\ntype = drive\n") - mock_run.side_effect = subprocess.CalledProcessError( - 1, "rclone", stderr=b"mkdir failed" - ) + mock_run.side_effect = subprocess.CalledProcessError(1, "rclone", stderr=b"mkdir failed") with pytest.raises(RuntimeError, match="Rclone error"): upload_with_rclone(str(test_file), "gdrive:uploads") diff --git a/tests/test_uptime_kuma.py b/tests/test_uptime_kuma.py index 1c368e7f..806003fc 100644 --- a/tests/test_uptime_kuma.py +++ b/tests/test_uptime_kuma.py @@ -4,7 +4,7 @@ Tests for app/tasks/uptime_kuma_tasks.py Tests Uptime Kuma health check ping functionality. """ -from unittest.mock import MagicMock, Mock, patch +from unittest.mock import Mock, patch import pytest import requests diff --git a/tests/test_url_upload.py b/tests/test_url_upload.py index 2610a4ec..5fdf5400 100644 --- a/tests/test_url_upload.py +++ b/tests/test_url_upload.py @@ -2,7 +2,6 @@ Tests for URL-based file upload functionality """ -import os from unittest.mock import Mock, patch import pytest diff --git a/tests/test_views_coverage.py b/tests/test_views_coverage.py index 34534fc4..f8c10794 100644 --- a/tests/test_views_coverage.py +++ b/tests/test_views_coverage.py @@ -1,7 +1,5 @@ """Additional view tests to increase coverage.""" -from unittest.mock import MagicMock, patch - import pytest _TEST_CREDENTIAL = "test" # noqa: S105 diff --git a/tests/test_views_files_comprehensive.py b/tests/test_views_files_comprehensive.py index bff22e15..832ef1b4 100644 --- a/tests/test_views_files_comprehensive.py +++ b/tests/test_views_files_comprehensive.py @@ -6,8 +6,7 @@ Target: Bring coverage from 8.77% to 70%+ """ import json -import os -from unittest.mock import Mock, MagicMock, patch +from unittest.mock import Mock, patch import pytest from fastapi.testclient import TestClient @@ -32,14 +31,14 @@ class TestFilesPage: original_filename="test1.pdf", local_filename="/tmp/test1.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) file2 = FileRecord( filehash="hash2", original_filename="test2.pdf", local_filename="/tmp/test2.pdf", file_size=2048, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file1) db_session.add(file2) @@ -57,7 +56,7 @@ class TestFilesPage: original_filename=f"test{i}.pdf", local_filename=f"/tmp/test{i}.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -77,14 +76,14 @@ class TestFilesPage: original_filename="invoice.pdf", local_filename="/tmp/invoice.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) file2 = FileRecord( filehash="hash2", original_filename="receipt.pdf", local_filename="/tmp/receipt.pdf", file_size=2048, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file1) db_session.add(file2) @@ -100,14 +99,14 @@ class TestFilesPage: original_filename="doc.pdf", local_filename="/tmp/doc.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) file2 = FileRecord( filehash="hash2", original_filename="image.jpg", local_filename="/tmp/image.jpg", file_size=2048, - mime_type="image/jpeg" + mime_type="image/jpeg", ) db_session.add(file1) db_session.add(file2) @@ -123,7 +122,7 @@ class TestFilesPage: original_filename="test.pdf", local_filename="/tmp/test.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -133,8 +132,20 @@ class TestFilesPage: def test_files_page_sorting_by_filename_asc(self, client: TestClient, db_session): """Test sorting by filename ascending.""" - file1 = FileRecord(filehash="hash1", original_filename="aaa.pdf", local_filename="/tmp/aaa.pdf", file_size=1024, mime_type="application/pdf") - file2 = FileRecord(filehash="hash2", original_filename="zzz.pdf", local_filename="/tmp/zzz.pdf", file_size=2048, mime_type="application/pdf") + file1 = FileRecord( + filehash="hash1", + original_filename="aaa.pdf", + local_filename="/tmp/aaa.pdf", + file_size=1024, + mime_type="application/pdf", + ) + file2 = FileRecord( + filehash="hash2", + original_filename="zzz.pdf", + local_filename="/tmp/zzz.pdf", + file_size=2048, + mime_type="application/pdf", + ) db_session.add(file1) db_session.add(file2) db_session.commit() @@ -144,8 +155,20 @@ class TestFilesPage: def test_files_page_sorting_by_size_desc(self, client: TestClient, db_session): """Test sorting by file size descending.""" - file1 = FileRecord(filehash="hash1", original_filename="small.pdf", local_filename="/tmp/small.pdf", file_size=100, mime_type="application/pdf") - file2 = FileRecord(filehash="hash2", original_filename="large.pdf", local_filename="/tmp/large.pdf", file_size=10000, mime_type="application/pdf") + file1 = FileRecord( + filehash="hash1", + original_filename="small.pdf", + local_filename="/tmp/small.pdf", + file_size=100, + mime_type="application/pdf", + ) + file2 = FileRecord( + filehash="hash2", + original_filename="large.pdf", + local_filename="/tmp/large.pdf", + file_size=10000, + mime_type="application/pdf", + ) db_session.add(file1) db_session.add(file2) db_session.commit() @@ -170,14 +193,14 @@ class TestFileDetailPage: # Create file with paths that exist file_path = tmp_path / "test.pdf" file_path.write_bytes(b"%PDF-1.4") - + file = FileRecord( filehash="hash1", original_filename="test.pdf", local_filename=str(file_path), original_file_path=str(file_path), file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -194,13 +217,13 @@ class TestFileDetailPage: """Test file detail page includes processing logs.""" file_path = tmp_path / "test.pdf" file_path.write_bytes(b"%PDF-1.4") - + file = FileRecord( filehash="hash1", original_filename="test.pdf", local_filename=str(file_path), file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -211,14 +234,10 @@ class TestFileDetailPage: task_id="task1", step_name="create_file_record", status="success", - message="File record created" + message="File record created", ) log2 = ProcessingLog( - file_id=file.id, - task_id="task2", - step_name="extract_text", - status="success", - message="Text extracted" + file_id=file.id, task_id="task2", step_name="extract_text", status="success", message="Text extracted" ) db_session.add(log1) db_session.add(log2) @@ -231,23 +250,23 @@ class TestFileDetailPage: """Test file detail page loads GPT metadata from JSON file.""" file_path = tmp_path / "test.pdf" file_path.write_bytes(b"%PDF-1.4") - + # Create processed file path processed_path = tmp_path / "test_processed.pdf" processed_path.write_bytes(b"%PDF-1.4") - + # Create metadata JSON file metadata_path = tmp_path / "test_processed.json" metadata = {"document_type": "invoice", "amount": 100.00} metadata_path.write_text(json.dumps(metadata)) - + file = FileRecord( filehash="hash1", original_filename="test.pdf", local_filename=str(file_path), processed_file_path=str(processed_path), file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -264,7 +283,7 @@ class TestFileDetailPage: local_filename="/nonexistent/local.pdf", # Required field original_file_path="/nonexistent/test.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -287,24 +306,14 @@ class TestComputeProcessingFlow: def test_compute_processing_flow_basic(self, db_session): """Test basic processing flow computation.""" from app.views.files import _compute_processing_flow - + logs = [ Mock( - step_name="create_file_record", - status="success", - message="Created", - timestamp=Mock(), - task_id="task1" + step_name="create_file_record", status="success", message="Created", timestamp=Mock(), task_id="task1" ), - Mock( - step_name="check_text", - status="success", - message="Checked", - timestamp=Mock(), - task_id="task2" - ) + Mock(step_name="check_text", status="success", message="Checked", timestamp=Mock(), task_id="task2"), ] - + flow = _compute_processing_flow(logs) assert isinstance(flow, list) assert len(flow) > 0 @@ -314,17 +323,17 @@ class TestComputeProcessingFlow: def test_compute_processing_flow_with_deduplication(self, db_session): """Test flow includes deduplication when enabled.""" from app.views.files import _compute_processing_flow - + logs = [ Mock( step_name="check_for_duplicates", status="success", message="No duplicates", timestamp=Mock(), - task_id="task1" + task_id="task1", ) ] - + flow = _compute_processing_flow(logs) # Should include deduplication step step_keys = [step["key"] for step in flow] @@ -333,31 +342,27 @@ class TestComputeProcessingFlow: def test_compute_processing_flow_with_upload_branches(self, db_session): """Test flow includes upload branches.""" from app.views.files import _compute_processing_flow - + logs = [ Mock( step_name="send_to_all_destinations", status="success", message="Sent", timestamp=Mock(), - task_id="task1" + task_id="task1", ), Mock( - step_name="upload_to_dropbox", - status="success", - message="Uploaded", - timestamp=Mock(), - task_id="task2" + step_name="upload_to_dropbox", status="success", message="Uploaded", timestamp=Mock(), task_id="task2" ), Mock( step_name="upload_to_google_drive", status="failure", message="Failed", timestamp=Mock(), - task_id="task3" - ) + task_id="task3", + ), ] - + flow = _compute_processing_flow(logs) # Find the upload stage upload_stage = next((s for s in flow if s.get("is_branch_parent")), None) @@ -368,17 +373,17 @@ class TestComputeProcessingFlow: def test_compute_processing_flow_handles_failure_status(self, db_session): """Test flow correctly identifies failed steps.""" from app.views.files import _compute_processing_flow - + logs = [ Mock( step_name="extract_metadata_with_gpt", status="failure", message="Failed to extract", timestamp=Mock(), - task_id="task1" + task_id="task1", ) ] - + flow = _compute_processing_flow(logs) failed_steps = [s for s in flow if s["status"] == "failure"] # Should have at least the failed step we added @@ -394,13 +399,13 @@ class TestComputeStepSummary: def test_compute_step_summary_basic(self): """Test basic step summary computation.""" from app.views.files import _compute_step_summary - + logs = [ Mock(step_name="create_file_record", status="success", timestamp=Mock()), Mock(step_name="check_text", status="success", timestamp=Mock()), - Mock(step_name="extract_text", status="success", timestamp=Mock()) + Mock(step_name="extract_text", status="success", timestamp=Mock()), ] - + summary = _compute_step_summary(logs) assert "main" in summary assert "uploads" in summary @@ -409,13 +414,13 @@ class TestComputeStepSummary: def test_compute_step_summary_with_uploads(self): """Test summary includes upload task counts.""" from app.views.files import _compute_step_summary - + logs = [ Mock(step_name="create_file_record", status="success", timestamp=Mock()), Mock(step_name="upload_to_dropbox", status="success", timestamp=Mock()), - Mock(step_name="upload_to_google_drive", status="failure", timestamp=Mock()) + Mock(step_name="upload_to_google_drive", status="failure", timestamp=Mock()), ] - + summary = _compute_step_summary(logs) assert summary["uploads"]["success"] >= 1 assert summary["uploads"]["failure"] >= 1 @@ -423,26 +428,25 @@ class TestComputeStepSummary: def test_compute_step_summary_normalizes_pending_status(self): """Test that 'pending' status is normalized to 'queued'.""" from app.views.files import _compute_step_summary - - logs = [ - Mock(step_name="create_file_record", status="pending", timestamp=Mock()) - ] - + + logs = [Mock(step_name="create_file_record", status="pending", timestamp=Mock())] + summary = _compute_step_summary(logs) # Should count as queued, not pending assert summary["main"]["queued"] >= 1 def test_compute_step_summary_order_independent(self): """Test that summary is order-independent (uses latest timestamp).""" - from app.views.files import _compute_step_summary from datetime import datetime, timedelta - + + from app.views.files import _compute_step_summary + now = datetime.now() logs = [ Mock(step_name="create_file_record", status="queued", timestamp=now), - Mock(step_name="create_file_record", status="success", timestamp=now + timedelta(seconds=10)) + Mock(step_name="create_file_record", status="success", timestamp=now + timedelta(seconds=10)), ] - + summary = _compute_step_summary(logs) # Should count success (latest) not queued assert summary["main"]["success"] >= 1 @@ -457,14 +461,14 @@ class TestPreviewOriginalFile: """Test preview of original file.""" file_path = tmp_path / "test.pdf" file_path.write_bytes(b"%PDF-1.4") - + file = FileRecord( filehash="hash1", original_filename="test.pdf", local_filename=str(file_path), # Required field original_file_path=str(file_path), file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -487,7 +491,7 @@ class TestPreviewOriginalFile: local_filename="/nonexistent/local.pdf", # Required field original_file_path="/nonexistent/test.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -504,14 +508,14 @@ class TestPreviewProcessedFile: """Test preview of processed file.""" processed_path = tmp_path / "test_processed.pdf" processed_path.write_bytes(b"%PDF-1.4") - + file = FileRecord( filehash="hash1", original_filename="test.pdf", local_filename=str(processed_path), # Required field processed_file_path=str(processed_path), file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -533,7 +537,7 @@ class TestPreviewProcessedFile: local_filename="/nonexistent/local.pdf", # Required field processed_file_path="/nonexistent/test_processed.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -573,14 +577,14 @@ startxref %%EOF """ pdf_path.write_bytes(pdf_content) - + file = FileRecord( filehash="hash1", original_filename="test.pdf", local_filename=str(pdf_path), # Required field original_file_path=str(pdf_path), file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -604,7 +608,7 @@ startxref local_filename="/nonexistent/local.pdf", # Required field original_file_path="/nonexistent/test.pdf", file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -643,14 +647,14 @@ startxref %%EOF """ pdf_path.write_bytes(pdf_content) - + file = FileRecord( filehash="hash1", original_filename="test.pdf", local_filename=str(pdf_path), # local_filename is NOT NULL processed_file_path=str(pdf_path), file_size=1024, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() @@ -693,14 +697,14 @@ startxref %%EOF """ pdf_path.write_bytes(pdf_content) - + file = FileRecord( filehash="hash1", original_filename="empty.pdf", local_filename=str(pdf_path), # local_filename is NOT NULL processed_file_path=str(pdf_path), file_size=100, - mime_type="application/pdf" + mime_type="application/pdf", ) db_session.add(file) db_session.commit() diff --git a/tests/test_views_general.py b/tests/test_views_general.py index 7154613c..028d10ab 100644 --- a/tests/test_views_general.py +++ b/tests/test_views_general.py @@ -1,8 +1,5 @@ """Tests for app/views/general.py module.""" -from pathlib import Path -from unittest.mock import MagicMock, patch - import pytest diff --git a/tests/test_views_settings.py b/tests/test_views_settings.py index ad89a42b..8b74a508 100644 --- a/tests/test_views_settings.py +++ b/tests/test_views_settings.py @@ -1,6 +1,6 @@ """Tests for app/views/settings.py module.""" -from unittest.mock import MagicMock, patch +from unittest.mock import MagicMock import pytest From b03ebab7474a68b7df4f1b673f7e82b1dd21dfd5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 09:12:11 +0000 Subject: [PATCH 3/4] chore: apply ruff formatting and fix whitespace issues Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com> --- .deepsource.toml | 2 +- .env.demo | 4 +- .github/dependabot.yml | 3 +- .../documentation.instructions.md | 4 +- .github/instructions/frontend.instructions.md | 10 +- .../python-backend.instructions.md | 8 +- .github/instructions/testing.instructions.md | 22 +- .github/workflows/release.yml | 16 +- .readthedocs.yaml | 2 +- .vscode/settings.json | 2 +- AGENTIC_CODING.md | 38 ++-- CONTRIBUTING.md | 2 +- Dockerfile | 2 - MILESTONES.md | 30 +-- NOTICE | 8 +- OAUTH_IMPLEMENTATION_SUMMARY.md | 14 +- README.md | 44 ++-- ROADMAP.md | 2 +- SECURITY_AUDIT.md | 72 +++---- TODO.md | 4 +- TODO_TESTS.md | 36 ++-- WEBDAV_TESTING_SUMMARY.md | 2 +- app/tasks/upload_with_rclone.py | 2 +- browser-extension/IMPLEMENTATION_SUMMARY.md | 12 +- browser-extension/INSTALLATION.txt | 14 +- browser-extension/README.md | 2 +- browser-extension/VISUAL_GUIDE.md | 4 +- browser-extension/popup/popup.js | 32 +-- browser-extension/scripts/background.js | 24 +-- browser-extension/scripts/content.js | 2 +- browser-extension/test.html | 22 +- coverage.json | 2 +- docs/API.md | 8 +- docs/AuthenticationSetup.md | 2 +- docs/BuildMetadata.md | 4 +- docs/ConfigurationGuide.md | 2 +- docs/ConfigurationMaster.md | 2 +- docs/DeploymentGuide.md | 8 +- docs/DropboxSetup.md | 10 +- docs/FileDetailPageLayout.md | 1 - docs/FileProcessingStatusArchitecture.md | 6 +- docs/OAuth_Testing_CI_CD.md | 70 +++---- docs/OneDriveSetup.md | 10 +- docs/RateLimitingStrategy.md | 2 +- docs/SettingsManagement.md | 6 +- docs/StorageArchitecture.md | 2 +- docs/archive/ANALYSIS_SUMMARY.md | 8 +- docs/archive/FILENAME_FIX_SUMMARY.md | 2 +- docs/archive/FRAMEWORK_ANALYSIS.md | 2 +- docs/archive/IMPLEMENTATION_CHECKLIST.md | 2 +- docs/archive/SETTINGS_IMPLEMENTATION.md | 2 +- .../PATH_TRAVERSAL_AUDIT_2026-02-10.md | 24 +-- frontend/static/images/default-avatar.svg | 2 +- frontend/static/js/common.js | 16 +- frontend/static/js/fontawesome-loader.js | 2 +- frontend/static/js/upload.js | 62 +++--- frontend/static/licenses/lgpl.txt | 20 +- frontend/static/logo.svg | 2 +- frontend/static/styles.css | 2 +- frontend/templates/about.html | 8 +- frontend/templates/attribution.html | 12 +- frontend/templates/base.html | 42 ++-- frontend/templates/dropbox.html | 68 +++---- frontend/templates/dropbox_callback.html | 56 ++--- .../templates/dropbox_callback_error.html | 4 +- frontend/templates/env_debug.html | 2 +- frontend/templates/file_detail.html | 192 +++++++++--------- frontend/templates/files copy.html | 10 +- frontend/templates/files.html | 120 +++++------ frontend/templates/google_drive.html | 178 ++++++++-------- frontend/templates/google_drive_callback.html | 114 +++++------ .../google_drive_callback_error.html | 4 +- frontend/templates/imprint.html | 4 +- frontend/templates/license.html | 16 +- frontend/templates/login.html | 18 +- frontend/templates/onedrive.html | 78 +++---- frontend/templates/onedrive_callback.html | 60 +++--- .../templates/onedrive_callback_error.html | 4 +- frontend/templates/settings.html | 26 +-- frontend/templates/setup_wizard.html | 28 +-- frontend/templates/status_dashboard.html | 114 +++++------ frontend/templates/upload.html | 12 +- migrations/README | 2 +- .../versions/001_file_processing_steps.py | 2 +- migrations/versions/002_add_file_paths.py | 2 +- .../versions/003_add_deduplication_support.py | 12 +- pyproject.toml | 4 +- requirements-dev.txt | 2 +- requirements.txt | 2 +- scripts/generate_build_metadata.sh | 6 +- tests/README_INTEGRATION_TESTS.md | 28 +-- tests/README_OAUTH_TESTING.md | 2 +- tests/test_external_integrations.py | 12 +- tests/test_file_splitting.py | 6 +- tests/test_security_headers.py | 6 +- tests/test_upload_webdav_integration.py | 6 +- 96 files changed, 991 insertions(+), 993 deletions(-) diff --git a/.deepsource.toml b/.deepsource.toml index d244e191..68672d87 100644 --- a/.deepsource.toml +++ b/.deepsource.toml @@ -7,4 +7,4 @@ name = "python" runtime_version = "3.x.x" [[analyzers]] -name = "javascript" \ No newline at end of file +name = "javascript" diff --git a/.env.demo b/.env.demo index e0bb72e1..d71fdf10 100644 --- a/.env.demo +++ b/.env.demo @@ -150,7 +150,7 @@ PAPERLESS_NGX_API_TOKEN= # Optional: JSON mapping of metadata fields to Paperless custom field names # This allows you to map multiple extracted metadata fields to custom fields in Paperless # The mapping format is: {"metadata_field_name": "PaperlessCustomFieldName", ...} -# Available metadata fields: absender, empfaenger, correspondent, document_type, language, +# Available metadata fields: absender, empfaenger, correspondent, document_type, language, # kommunikationsart, kommunikationskategorie, reference_number, etc. # Example: PAPERLESS_CUSTOM_FIELDS_MAPPING={"absender": "Sender", "empfaenger": "Recipient", "language": "Language", "correspondent": "Correspondent"} # PAPERLESS_CUSTOM_FIELDS_MAPPING= @@ -238,4 +238,4 @@ NOTIFY_ON_FILE_PROCESSED=True # Uptime Kuma UPTIME_KUMA_URL=https://status.example.com/api/push/abcdef123456?status=up -UPTIME_KUMA_PING_INTERVAL=5 \ No newline at end of file +UPTIME_KUMA_PING_INTERVAL=5 diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e5d9a54e..400c1595 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,10 +10,9 @@ updates: schedule: interval: "weekly" open-pull-requests-limit: 10 - + - package-ecosystem: "npm" directory: "/frontend/static" schedule: interval: "monthly" open-pull-requests-limit: 5 - diff --git a/.github/instructions/documentation.instructions.md b/.github/instructions/documentation.instructions.md index d815a50d..8dffcbcd 100644 --- a/.github/instructions/documentation.instructions.md +++ b/.github/instructions/documentation.instructions.md @@ -177,8 +177,8 @@ Example: ```markdown ### OPENAI_API_KEY -**Type:** String -**Required:** Yes +**Type:** String +**Required:** Yes **Default:** None Your OpenAI API key for metadata extraction. diff --git a/.github/instructions/frontend.instructions.md b/.github/instructions/frontend.instructions.md index bc48770f..0ba794ab 100644 --- a/.github/instructions/frontend.instructions.md +++ b/.github/instructions/frontend.instructions.md @@ -22,13 +22,13 @@ These instructions apply to all files in the `frontend/` directory (templates, C {% block content %}

{{ page_title }}

- + {% if error_message %}
{{ error_message }}
{% endif %} - +
@@ -72,9 +72,9 @@ These instructions apply to all files in the `frontend/` directory (templates, C - DocumentMetadata: """ Process a document and extract metadata. - + Args: file_path: Path to the document file user_id: ID of the user uploading the document metadata: Optional additional metadata - + Returns: DocumentMetadata object with extracted information - + Raises: FileNotFoundError: If file doesn't exist ProcessingError: If processing fails @@ -150,7 +150,7 @@ from pydantic_settings import BaseSettings class Settings(BaseSettings): openai_api_key: str max_file_size: int = 10485760 # 10MB default - + class Config: env_file = ".env" ``` diff --git a/.github/instructions/testing.instructions.md b/.github/instructions/testing.instructions.md index 37b3961b..ee9f78db 100644 --- a/.github/instructions/testing.instructions.md +++ b/.github/instructions/testing.instructions.md @@ -68,9 +68,9 @@ def db_session(): Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) session = Session() - + yield session - + session.close() Base.metadata.drop_all(engine) @@ -99,7 +99,7 @@ def test_upload_document(): "/api/documents/upload", files={"file": ("test.pdf", f, "application/pdf")} ) - + assert response.status_code == 201 assert "id" in response.json() ``` @@ -131,12 +131,12 @@ def test_openai_metadata_extraction(mocker): "amount": 100.00, "date": "2024-01-01" } - + mocker.patch( "app.utils.openai_client.extract_metadata", return_value=mock_response ) - + result = extract_document_metadata("test.pdf") assert result["document_type"] == "invoice" @@ -144,12 +144,12 @@ def test_openai_metadata_extraction(mocker): def test_azure_ocr_processing(mocker): """Test OCR with mocked Azure service.""" mock_text = "Sample extracted text" - + mocker.patch( "app.utils.azure_client.extract_text", return_value=mock_text ) - + result = perform_ocr("test.pdf") assert result == mock_text ``` @@ -160,7 +160,7 @@ def test_azure_ocr_processing(mocker): def test_create_document(db_session): """Test document creation in database.""" from app.models import Document - + doc = Document( filename="test.pdf", user_id=1, @@ -168,7 +168,7 @@ def test_create_document(db_session): ) db_session.add(doc) db_session.commit() - + assert doc.id is not None assert doc.filename == "test.pdf" ``` @@ -189,10 +189,10 @@ def test_document_validation(): "filename": "", # Empty filename "size": -1 # Invalid size } - + # Act result = validate_document(invalid_document) - + # Assert assert result.is_valid is False assert "filename" in result.errors diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b103cfec..1f7423c9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,30 +17,30 @@ jobs: name: Semantic Release runs-on: ubuntu-latest if: github.repository == 'christianlouis/DocuElevate' - + steps: - name: Checkout Code uses: actions/checkout@v4 with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - + - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' cache: 'pip' - + - name: Install dependencies run: | python -m pip install --upgrade pip pip install python-semantic-release - + - name: Configure Git run: | git config --global user.name "github-actions[bot]" git config --global user.email "github-actions[bot]@users.noreply.github.com" - + - name: Run Semantic Release env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -48,7 +48,7 @@ jobs: semantic-release version --print semantic-release version semantic-release publish - + - name: Update build metadata files if changed run: | for f in VERSION BUILD_DATE GIT_SHA RUNTIME_INFO; do @@ -60,7 +60,7 @@ jobs: git commit -m "chore(release): update build metadata files [skip ci]" git push fi - + - name: Trigger Docker Build on Tag if: startsWith(github.ref, 'refs/tags/') uses: actions/github-script@v7 @@ -70,4 +70,4 @@ jobs: const ref = context.ref; const tag = ref.replace('refs/tags/', ''); console.log(`New tag created: ${tag}`); - console.log('Docker build will be triggered automatically by the docker-build workflow'); \ No newline at end of file + console.log('Docker build will be triggered automatically by the docker-build workflow'); diff --git a/.readthedocs.yaml b/.readthedocs.yaml index fbbbcd5e..46625ad2 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -19,4 +19,4 @@ mkdocs: # See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html python: install: - - requirements: docs/requirements.txt \ No newline at end of file + - requirements: docs/requirements.txt diff --git a/.vscode/settings.json b/.vscode/settings.json index 9b388533..a3a18383 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,4 +4,4 @@ ], "python.testing.unittestEnabled": false, "python.testing.pytestEnabled": true -} \ No newline at end of file +} diff --git a/AGENTIC_CODING.md b/AGENTIC_CODING.md index e4b33e8c..d3665060 100644 --- a/AGENTIC_CODING.md +++ b/AGENTIC_CODING.md @@ -1,6 +1,6 @@ # Agentic Coding Guide for DocuElevate -**Version:** 1.0 +**Version:** 1.0 **Last Updated:** 2026-02-06 This guide helps AI coding agents work effectively with the DocuElevate codebase. It provides context, conventions, and best practices for autonomous code contributions. @@ -80,14 +80,14 @@ DocuElevate/ def process_document(file_path: str, metadata: Dict[str, Any]) -> DocumentMetadata: """ Process a document and extract metadata. - + Args: file_path: Absolute path to the document file metadata: Additional metadata to include - + Returns: DocumentMetadata object with extracted information - + Raises: FileNotFoundError: If file doesn't exist ProcessingError: If processing fails @@ -225,7 +225,7 @@ logger = logging.getLogger(__name__) def my_background_task(self, param: str): """ Description of what this task does. - + Args: param: Description of parameter """ @@ -247,7 +247,7 @@ def my_background_task(self, param: str): ```python class MyModel(Base): __tablename__ = "my_table" - + id = Column(Integer, primary_key=True, index=True) name = Column(String, nullable=False) created_at = Column(DateTime, default=datetime.utcnow) @@ -275,20 +275,20 @@ logger = logging.getLogger(__name__) def upload_to_my_provider(file_path: str, metadata: dict) -> str: """ Upload file to My Provider. - + Args: file_path: Local path to file metadata: Document metadata - + Returns: URL or ID of uploaded file - + Raises: ProviderError: If upload fails """ if not settings.my_provider_api_key: raise ValueError("MY_PROVIDER_API_KEY not configured") - + # Implementation pass ``` @@ -342,11 +342,11 @@ def validate_file_path(file_path: str, base_dir: str = "/workdir") -> Path: try: path = Path(file_path).resolve() base = Path(base_dir).resolve() - + # Ensure path is within base directory if not path.is_relative_to(base): raise ValueError("Path outside allowed directory") - + return path except Exception as e: raise HTTPException( @@ -467,23 +467,23 @@ def process_large_batch(self, file_ids: List[int]): def complex_function(param1: str, param2: int = 10) -> Dict[str, Any]: """ One-line summary of what the function does. - + More detailed explanation if needed. Can span multiple lines and include examples. - + Args: param1: Description of param1 param2: Description of param2, defaults to 10 - + Returns: Dictionary containing: - key1: Description - key2: Description - + Raises: ValueError: If param1 is empty FileNotFoundError: If file doesn't exist - + Examples: >>> result = complex_function("test", 5) >>> print(result['key1']) @@ -650,7 +650,7 @@ DocuElevate uses `python-semantic-release` for automated version management. #### How It Works 1. **PR merges to main** with conventional commits -2. **semantic-release analyzes** commit messages +2. **semantic-release analyzes** commit messages 3. **Automatic updates**: - Bumps `VERSION` file - Updates `CHANGELOG.md` @@ -669,7 +669,7 @@ DocuElevate uses `python-semantic-release` for automated version management. ### Pull Requests 1. Create PR with descriptive title (conventional format if single change) 2. Fill out PR template -3. Link related issues +3. Link related issues 4. Ensure CI passes 5. Request reviews 6. Address feedback diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 01fcf296..c92cb148 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -346,4 +346,4 @@ DocuElevate/ - **GitHub Discussions:** Questions and community support - **Documentation:** Check `docs/` directory for guides -Thank you for contributing to DocuElevate! \ No newline at end of file +Thank you for contributing to DocuElevate! diff --git a/Dockerfile b/Dockerfile index fcbcc732..f2b98dae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -42,5 +42,3 @@ EXPOSE 8000 # Default command CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] - - diff --git a/MILESTONES.md b/MILESTONES.md index 71dfd4a9..f80a04f1 100644 --- a/MILESTONES.md +++ b/MILESTONES.md @@ -57,8 +57,8 @@ As of February 2026, DocuElevate uses **automated semantic versioning**: ## Completed Milestones ### v0.5.0 - Settings Management & Configuration (February 2026) -**Release Date:** February 8, 2026 -**Status:** ✅ Released +**Release Date:** February 8, 2026 +**Status:** ✅ Released **Theme:** Configuration Management, Security, User Experience #### Goals @@ -90,8 +90,8 @@ As of February 2026, DocuElevate uses **automated semantic versioning**: --- ### v0.3.3 - Drag-and-Drop Upload (February 2026) -**Release Date:** February 8, 2026 -**Status:** ✅ Released +**Release Date:** February 8, 2026 +**Status:** ✅ Released **Theme:** User Experience Enhancement #### Goals @@ -108,8 +108,8 @@ As of February 2026, DocuElevate uses **automated semantic versioning**: --- ### v0.3.2 - Security & Testing Hardening (February 2026) -**Release Date:** February 6, 2026 -**Status:** ✅ Released +**Release Date:** February 6, 2026 +**Status:** ✅ Released **Theme:** Security, Quality, Testing #### Goals @@ -131,8 +131,8 @@ As of February 2026, DocuElevate uses **automated semantic versioning**: ## Upcoming Milestones ### v0.6.0 - Enhanced Search & UI Improvements (April 2026) -**Target Date:** April 1, 2026 -**Status:** 📋 Planned +**Target Date:** April 1, 2026 +**Status:** 📋 Planned **Theme:** User Experience, Search, Performance #### Goals @@ -163,8 +163,8 @@ As of February 2026, DocuElevate uses **automated semantic versioning**: --- ### v0.4.5 - Workflow Automation (June 2026) -**Target Date:** June 1, 2026 -**Status:** 📋 Planned +**Target Date:** June 1, 2026 +**Status:** 📋 Planned **Theme:** Automation, Integration, Webhooks #### Goals @@ -185,8 +185,8 @@ As of February 2026, DocuElevate uses **automated semantic versioning**: --- ### v0.7.0 - Advanced AI & Multi-language (August 2026) -**Target Date:** August 1, 2026 -**Status:** 📋 Planned +**Target Date:** August 1, 2026 +**Status:** 📋 Planned **Theme:** AI Enhancement, Internationalization #### Goals @@ -208,8 +208,8 @@ As of February 2026, DocuElevate uses **automated semantic versioning**: --- ### v1.0.0 - Enterprise Edition (November 2026) -**Target Date:** November 1, 2026 -**Status:** 📋 Planned +**Target Date:** November 1, 2026 +**Status:** 📋 Planned **Theme:** Enterprise Features, Scalability, Multi-tenancy This is our first major release, marking production-ready enterprise capabilities. @@ -322,4 +322,4 @@ Starting with v0.6.0, releases are fully automated using `python-semantic-releas --- -*This milestone document is updated regularly. For real-time status, check our [GitHub Projects](https://github.com/christianlouis/DocuElevate/projects) board.* \ No newline at end of file +*This milestone document is updated regularly. For real-time status, check our [GitHub Projects](https://github.com/christianlouis/DocuElevate/projects) board.* diff --git a/NOTICE b/NOTICE index 8ce08359..5114b033 100644 --- a/NOTICE +++ b/NOTICE @@ -9,15 +9,15 @@ This software includes third-party components with their own licenses: SPECIAL NOTICE REGARDING LGPL SOFTWARE: -------------------------------------------------------------------------------- -DocuElevate incorporates Paramiko, which is licensed under the GNU Lesser General +DocuElevate incorporates Paramiko, which is licensed under the GNU Lesser General Public License (LGPL) version 2.1. In accordance with the LGPL: 1. The complete source code for Paramiko can be obtained from: https://github.com/paramiko/paramiko -2. This software is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License +2. This software is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 3. A copy of the GNU Lesser General Public License version 2.1 can be found at: diff --git a/OAUTH_IMPLEMENTATION_SUMMARY.md b/OAUTH_IMPLEMENTATION_SUMMARY.md index 9551e244..da8aaa2c 100644 --- a/OAUTH_IMPLEMENTATION_SUMMARY.md +++ b/OAUTH_IMPLEMENTATION_SUMMARY.md @@ -50,7 +50,7 @@ pytest tests/test_oauth_integration_flows.py -v ```bash # Auto-detects and uses real OAuth credentials export AUTHENTIK_CLIENT_ID="your-client-id" -export AUTHENTIK_CLIENT_SECRET="your-client-secret" +export AUTHENTIK_CLIENT_SECRET="your-client-secret" export AUTHENTIK_CONFIG_URL="https://auth.example.com/.well-known/openid-configuration" pytest tests/test_oauth_integration_flows.py -v -m requires_external ``` @@ -128,7 +128,7 @@ async def test_oauth_callback(mock_authorize, oauth_enabled_app, test_user_info) "access_token": "test-token", "userinfo": test_user_info, } - + response = oauth_enabled_app.get("/oauth-callback?code=test-code") assert response.status_code == 302 ``` @@ -185,11 +185,11 @@ jobs: ## Technical Details -**Container**: `ghcr.io/navikt/mock-oauth2-server:2.1.1` -**Framework**: Testcontainers Python 4.14.1+ -**Test Framework**: pytest with async support -**Languages**: Python 3.12+ -**Dependencies**: testcontainers, requests, docker +**Container**: `ghcr.io/navikt/mock-oauth2-server:2.1.1` +**Framework**: Testcontainers Python 4.14.1+ +**Test Framework**: pytest with async support +**Languages**: Python 3.12+ +**Dependencies**: testcontainers, requests, docker ## Files Created/Modified diff --git a/README.md b/README.md index 092be36e..6419218a 100644 --- a/README.md +++ b/README.md @@ -32,12 +32,12 @@ DocuElevate automates the handling, extraction, and processing of documents using a variety of services, including: -- **OpenAI** for metadata extraction and text refinement. -- **Dropbox**, **Nextcloud**, and **Google Drive** for file storage and uploads. -- **Paperless NGX** for document indexing and management. -- **Azure Document Intelligence** for OCR on PDFs. -- **Gotenberg** for file-to-PDF conversions. -- **Authentik** for authentication and user management. +- **OpenAI** for metadata extraction and text refinement. +- **Dropbox**, **Nextcloud**, and **Google Drive** for file storage and uploads. +- **Paperless NGX** for document indexing and management. +- **Azure Document Intelligence** for OCR on PDFs. +- **Gotenberg** for file-to-PDF conversions. +- **Authentik** for authentication and user management. It is designed for flexibility and configurability through environment variables, making it easily customizable for different workflows. The system can fetch documents from multiple IMAP mailboxes, process them (OCR, metadata extraction, PDF conversion), and store them in the desired destinations. @@ -59,7 +59,7 @@ The project includes a **UI** for uploading and managing files, and an API docum
DocuElevate Upload Interface

Upload interface for adding new documents

- + DocuElevate Files View

Files view with processed documents and metadata

@@ -100,28 +100,28 @@ Users can choose to send documents to any combination of these destinations thro ## Features -- **Intuitive File Upload**: +- **Intuitive File Upload**: - Drag-and-drop file upload on both Upload and Files pages—upload anywhere on the Files page - Real-time upload progress with validation - Support for PDF, Office documents, images, and more (up to 500MB per file) -- **Browser Extension**: +- **Browser Extension**: - Send files directly from your browser to DocuElevate with one click - Compatible with Chrome, Firefox, Edge, and other Chromium-based browsers - Context menu integration for quick access - See [Browser Extension Guide](docs/BrowserExtension.md) for installation and usage -- **Document Upload & Storage**: +- **Document Upload & Storage**: - Manual uploads (via API or UI) to Dropbox, Nextcloud, Google Drive, or Paperless -- **OCR Processing (Azure)**: - - Extract text from scanned PDFs using Azure Document Intelligence -- **Metadata Extraction (OpenAI)**: - - Use GPT to classify, label, or otherwise enrich the text with structured metadata -- **PDF Conversion (Gotenberg)**: - - Convert non-PDF attachments (e.g., Word docs, images) into PDFs -- **Document Management (Paperless NGX)**: - - Store processed documents and metadata in a Paperless NGX instance -- **IMAP Integration**: - - Fetch documents from multiple mailboxes (including Gmail) and automatically enqueue them for processing -- **Authentication**: +- **OCR Processing (Azure)**: + - Extract text from scanned PDFs using Azure Document Intelligence +- **Metadata Extraction (OpenAI)**: + - Use GPT to classify, label, or otherwise enrich the text with structured metadata +- **PDF Conversion (Gotenberg)**: + - Convert non-PDF attachments (e.g., Word docs, images) into PDFs +- **Document Management (Paperless NGX)**: + - Store processed documents and metadata in a Paperless NGX instance +- **IMAP Integration**: + - Fetch documents from multiple mailboxes (including Gmail) and automatically enqueue them for processing +- **Authentication**: - Secure access to the system using **Authentik** for OAuth2-based login ## Frameworks Used @@ -235,4 +235,4 @@ For a comprehensive list of all dependencies and their licenses, run: ``` pip install pip-licenses pip-licenses -``` \ No newline at end of file +``` diff --git a/ROADMAP.md b/ROADMAP.md index 5b1de5e7..5b9120a9 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,6 +1,6 @@ # DocuElevate Roadmap -**Last Updated:** 2026-02-08 +**Last Updated:** 2026-02-08 **Version:** 1.0 ## Vision diff --git a/SECURITY_AUDIT.md b/SECURITY_AUDIT.md index 36b9d271..f44c0a97 100644 --- a/SECURITY_AUDIT.md +++ b/SECURITY_AUDIT.md @@ -1,6 +1,6 @@ # Security Audit Report -**Date:** 2026-02-12 +**Date:** 2026-02-12 **Status:** Bandit Security Scan Completed - All Critical/High/Medium Issues Resolved ## Executive Summary @@ -11,8 +11,8 @@ This document tracks security vulnerabilities found in DocuElevate and their rem ### CVE-2023-36464: PyPDF2/pypdf Infinite Loop Vulnerability ✅ FIXED (2026-02-12) -**Severity:** Moderate (CVSS: 5.5) -**CVE:** [CVE-2023-36464](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-36464) +**Severity:** Moderate (CVSS: 5.5) +**CVE:** [CVE-2023-36464](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-36464) **Advisory:** [GHSA-4vvm-4w3v-6mr8](https://github.com/advisories/GHSA-4vvm-4w3v-6mr8) **Issue:** Certain versions of PyPDF2 (>=2.2.0, <=3.0.1) and pypdf (prior to 3.9.0) contain a vulnerability where specially crafted PDF files can trigger an infinite loop in `__parse_content_stream`, causing 100% CPU usage and potential denial of service. @@ -57,8 +57,8 @@ This document tracks security vulnerabilities found in DocuElevate and their rem ### Fixed Issues from Bandit Scan #### 1. B324: Weak MD5 Hash Usage (HIGH SEVERITY) ✅ FIXED -**Occurrences:** 2 -**Locations:** +**Occurrences:** 2 +**Locations:** - `app/api/user.py:26` - Gravatar URL generation - `app/auth.py:65` - Gravatar URL generation @@ -72,7 +72,7 @@ This document tracks security vulnerabilities found in DocuElevate and their rem ``` #### 2. B402/B321: Insecure FTP Protocol (HIGH SEVERITY) ✅ DOCUMENTED -**Occurrences:** 3 +**Occurrences:** 3 **Location:** `app/tasks/upload_to_ftp.py` **Issue:** FTP is an insecure protocol vulnerable to eavesdropping and MITM attacks. @@ -88,7 +88,7 @@ This document tracks security vulnerabilities found in DocuElevate and their rem **Security Note:** For production environments, set `ftp_allow_plaintext=False` to prevent fallback to unencrypted FTP. #### 3. B507: SSH Host Key Verification Disabled (HIGH SEVERITY) ✅ FIXED -**Occurrences:** 1 +**Occurrences:** 1 **Location:** `app/tasks/upload_to_sftp.py:47` **Issue:** Using `paramiko.AutoAddPolicy()` automatically trusts unknown SSH host keys, making connections vulnerable to MITM attacks. @@ -103,7 +103,7 @@ This document tracks security vulnerabilities found in DocuElevate and their rem **Security Note:** The default value is now `False` (secure). For development/testing environments where host keys cannot be pre-configured, set `SFTP_DISABLE_HOST_KEY_VERIFICATION=True` (not recommended for production). #### 4. B113: Missing Timeout on HTTP Requests (MEDIUM SEVERITY) ✅ FIXED -**Occurrences:** 15 +**Occurrences:** 15 **Locations:** - `app/api/dropbox.py` (4 requests calls) - `app/api/google_drive.py` (1 request call) @@ -142,8 +142,8 @@ This document tracks security vulnerabilities found in DocuElevate and their rem ## Critical Vulnerabilities (Fixed) ✅ ### 1. Outdated Authlib with Known Vulnerabilities -**Status:** ✅ FIXED -**Severity:** HIGH +**Status:** ✅ FIXED +**Severity:** HIGH **Description:** Authlib version 1.3.2 had two critical vulnerabilities: - CVE: Denial of Service via Oversized JOSE Segments - CVE: JWS/JWT accepts unknown crit headers (RFC violation → possible authz bypass) @@ -151,18 +151,18 @@ This document tracks security vulnerabilities found in DocuElevate and their rem **Fix:** Updated `requirements.txt` to require `authlib>=1.6.5` ### 2. Starlette DoS Vulnerability -**Status:** ✅ FIXED -**Severity:** MEDIUM +**Status:** ✅ FIXED +**Severity:** MEDIUM **Description:** Starlette 0.41.3 vulnerable to O(n^2) DoS via Range header merging in `FileResponse` **Fix:** Updated `requirements.txt` to require `starlette>=0.49.1` ### 3. Weak SESSION_SECRET Default -**Status:** ✅ FIXED -**Severity:** HIGH +**Status:** ✅ FIXED +**Severity:** HIGH **Description:** Default SESSION_SECRET value in `app/main.py` was a predictable string that could be exploited if not overridden -**Fix:** +**Fix:** - Enhanced validation in `app/main.py` to raise error if auth is enabled without proper secret - Updated default to be clearly marked as insecure for development only - Added generation instructions in error message @@ -170,8 +170,8 @@ This document tracks security vulnerabilities found in DocuElevate and their rem ## Medium Risk Issues (Fixed) ✅ ### 4. Insufficient .gitignore Protection -**Status:** ✅ FIXED -**Severity:** MEDIUM +**Status:** ✅ FIXED +**Severity:** MEDIUM **Description:** .gitignore didn't adequately protect against accidentally committing sensitive files (credentials, private keys, secrets) **Fix:** Enhanced `.gitignore` with comprehensive patterns for: @@ -182,8 +182,8 @@ This document tracks security vulnerabilities found in DocuElevate and their rem - Explicit exclusion of patterns where needed ### 5. File Upload Size Limits -**Status:** ✅ FIXED -**Severity:** MEDIUM +**Status:** ✅ FIXED +**Severity:** MEDIUM **Description:** No configurable limits on file upload sizes could lead to resource exhaustion attacks and DoS. **Fix:** Implemented configurable file upload size limits with the following features: @@ -329,7 +329,7 @@ For security issues, please follow the guidelines in [SECURITY.md](SECURITY.md). ## Path Traversal Vulnerability Audit (2026-02-10) -**Status:** ✅ ALL ISSUES FIXED +**Status:** ✅ ALL ISSUES FIXED **Scope:** Comprehensive review of all file path operations for path traversal vulnerabilities ### Executive Summary @@ -338,11 +338,11 @@ A thorough security audit was conducted on all file path operations in DocuEleva ### Critical Vulnerability: Path Traversal via GPT Metadata Filename -**Status:** ✅ FIXED -**Severity:** CRITICAL +**Status:** ✅ FIXED +**Severity:** CRITICAL **Location:** `app/tasks/embed_metadata_into_pdf.py` (line 144) -**Description:** +**Description:** The `metadata["filename"]` extracted by GPT was used directly in file path operations without sanitization. A malicious document could be crafted to make GPT return metadata containing path traversal sequences (e.g., `../../etc/passwd`, `..\\windows\\system32`), allowing file writes outside the intended `processed/` directory. **Attack Vector:** @@ -376,11 +376,11 @@ suggested_filename = os.path.splitext(suggested_filename)[0] ### Medium Vulnerability: Insecure Path Validation Using String Prefix Check -**Status:** ✅ FIXED -**Severity:** MEDIUM +**Status:** ✅ FIXED +**Severity:** MEDIUM **Location:** `app/tasks/embed_metadata_into_pdf.py` (line 188-193) -**Description:** +**Description:** The code used string-based `startswith()` check to validate if a file was within the workdir/tmp directory before deletion. This is vulnerable to: - Partial directory name matches (e.g., `/workdir/tmp2/` would pass if workdir is `/workdir/tmp`) - Symlink attacks (symlinks are not resolved before checking) @@ -403,7 +403,7 @@ workdir_tmp_path = Path(settings.workdir) / TMP_SUBDIR try: original_file_path = Path(original_file).resolve() workdir_tmp_resolved = workdir_tmp_path.resolve() - + # Check if file is within workdir/tmp and exists if original_file_path.is_relative_to(workdir_tmp_resolved) and original_file_path.exists(): original_file_path.unlink() @@ -420,11 +420,11 @@ except (ValueError, OSError) as e: ### Medium Issue: Insufficient Validation of GPT-Extracted Filenames -**Status:** ✅ FIXED -**Severity:** MEDIUM +**Status:** ✅ FIXED +**Severity:** MEDIUM **Location:** `app/tasks/extract_metadata_with_gpt.py` (after line 124) -**Description:** +**Description:** While the GPT prompt requested filenames in a specific format (YYYY-MM-DD_DescriptiveTitle with only letters, numbers, periods, underscores), there was no validation to enforce this constraint. GPT may not always comply with the format specification, potentially returning: - Filenames with path separators - Filenames with path traversal patterns @@ -449,7 +449,7 @@ if filename: metadata["filename"] = "" ``` -**Defense in Depth:** +**Defense in Depth:** This validation provides an additional layer of security before the filename reaches `embed_metadata_into_pdf.py`, where it is also sanitized. ### Security-Positive Findings @@ -502,11 +502,11 @@ def resolve_file_path(base_dir, file_path): """Safely resolve file path within base directory.""" base = Path(base_dir).resolve() target = (base / file_path).resolve() - + # Ensure target is within base directory if not target.is_relative_to(base): raise ValueError("Path traversal attempt detected") - + return target ``` @@ -610,7 +610,7 @@ All identified path traversal vulnerabilities have been remediated with defense- ## Security Headers Implementation (2026-02-10) -**Status:** ✅ COMPLETED +**Status:** ✅ COMPLETED **Scope:** HTTP security headers middleware for browser-side security ### Executive Summary @@ -654,7 +654,7 @@ SECURITY_HEADER_CSP_VALUE="default-src 'self'; script-src 'self' 'unsafe-inline' - Mitigates XSS attack vectors - Customizable per deployment needs -**Trade-offs:** +**Trade-offs:** - Default policy includes `'unsafe-inline'` for compatibility with Tailwind CSS and inline JavaScript - Stricter policies can be configured using nonces or hashes @@ -832,4 +832,4 @@ Security headers implementation is complete and production-ready. The middleware --- -**Next Audit Due:** 2026-05-07 (Quarterly) \ No newline at end of file +**Next Audit Due:** 2026-05-07 (Quarterly) diff --git a/TODO.md b/TODO.md index cbea172b..9487e88c 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,6 @@ # DocuElevate TODO List -**Last Updated:** 2026-02-08 +**Last Updated:** 2026-02-08 **Current Version:** v0.5.0 This document tracks actionable tasks for the current development cycle. For long-term planning, see [ROADMAP.md](ROADMAP.md) and [MILESTONES.md](MILESTONES.md). @@ -10,7 +10,7 @@ This document tracks actionable tasks for the current development cycle. For lon ## ⚠️ Important Note on Versioning As of this update, DocuElevate uses **automated semantic versioning** via `python-semantic-release`: -- **DO NOT** manually edit `VERSION` or `CHANGELOG.md` +- **DO NOT** manually edit `VERSION` or `CHANGELOG.md` - Version bumps are automated based on conventional commit messages - See [CONTRIBUTING.md](CONTRIBUTING.md) for commit message format diff --git a/TODO_TESTS.md b/TODO_TESTS.md index 3ad1a973..d9178c29 100644 --- a/TODO_TESTS.md +++ b/TODO_TESTS.md @@ -4,10 +4,10 @@ This document tracks test coverage improvements for DocuElevate. The goal is to ## Current Status -**Initial Coverage**: 45.09% -**Current Coverage**: 48.17% -**Progress**: +3.08% -**Target Coverage**: 60%+ (Phase 1), then 70%, 80% +**Initial Coverage**: 45.09% +**Current Coverage**: 48.17% +**Progress**: +3.08% +**Target Coverage**: 60%+ (Phase 1), then 70%, 80% **Remaining to target**: ~12% ## Completed Tests @@ -21,22 +21,22 @@ This document tracks test coverage improvements for DocuElevate. The goal is to - Test is_encrypted function - Test is_encryption_available - Mock cryptography library for error cases - + - [x] `app/celery_worker.py` (0% → 90.62%) ✅ - Basic module structure tests (removed tests requiring Redis) - + - [x] `app/tasks/uptime_kuma_tasks.py` (0% → 100%) ✅ - Test ping_uptime_kuma with valid URL - Test skipping when URL not configured - Test error handling for failed requests - + - [x] `app/utils/` package (exports via __init__.py) ✅ - Package exports tested in test_reexports.py - Individual module coverage from actual usage - + - [x] `app/frontend.py` (0% → 100%) ✅ - Simple re-export module, test imports work - + - [x] `app/utils/config_validator.py` (0% → Still 0%) ⚠️ - Re-export module, coverage is from actual usage @@ -46,11 +46,11 @@ This document tracks test coverage improvements for DocuElevate. The goal is to - Test get_unique_filename - Test extract_remote_path - Test filename validation functions - + - [x] `app/utils/logging.py` (42.86% → 100%) ✅ - Test log_task_progress function - Test various log message formats - + - [x] `app/utils/oauth_helper.py` (17.50% → 100%) ✅ - Test OAuth token exchange - Test error handling @@ -80,17 +80,17 @@ This document tracks test coverage improvements for DocuElevate. The goal is to - Test Azure connection - Test credential validation - Mock Azure API responses - + - [ ] `app/api/dropbox.py` (16.94% → 50%+) - Test OAuth flow (mocked) - Test token validation - Test connection testing - + - [ ] `app/api/google_drive.py` (12.94% → 50%+) - Test OAuth flow (mocked) - Test token validation - Test drive connection - + - [ ] `app/api/onedrive.py` (13.83% → 50%+) - Test OAuth flow (mocked) - Test token validation @@ -101,7 +101,7 @@ This document tracks test coverage improvements for DocuElevate. The goal is to - Test PDF conversion with various formats - Test Gotenberg integration (mocked) - Test error handling - + - [ ] `app/tasks/embed_metadata_into_pdf.py` (19.05% → 50%+) - Test metadata embedding - Test PDF manipulation @@ -124,18 +124,18 @@ These require complex external service mocking: - Test credential validation for each provider - Test failure state management - Test notification system - + - [ ] `app/tasks/imap_tasks.py` (0%) - Requires IMAP server mocking - Test email fetching - Test email parsing - Test lock management with Redis - + - [ ] `app/tasks/upload_with_rclone.py` (0%) - Test rclone command execution - Test configuration management - Test error handling - + - [ ] `app/tasks/extract_metadata_with_gpt.py` (28.79%) - Test GPT metadata extraction - Mock OpenAI API responses diff --git a/WEBDAV_TESTING_SUMMARY.md b/WEBDAV_TESTING_SUMMARY.md index 2947b31c..4b9d5862 100644 --- a/WEBDAV_TESTING_SUMMARY.md +++ b/WEBDAV_TESTING_SUMMARY.md @@ -185,7 +185,7 @@ pytest tests/test_upload_webdav*.py -v - **Docker:** Must be installed and running - **Memory:** ~100MB per container, ~1GB total for full stack - **Disk:** ~2GB for all Docker images -- **Time:** +- **Time:** - First run: ~5-10 minutes (image pulls) - Subsequent runs: ~10-60 seconds per test diff --git a/app/tasks/upload_with_rclone.py b/app/tasks/upload_with_rclone.py index 1269713e..59b83f71 100644 --- a/app/tasks/upload_with_rclone.py +++ b/app/tasks/upload_with_rclone.py @@ -72,7 +72,7 @@ def upload_with_rclone(self, file_path: str, destination: str): # Try to get a public link if possible try: link_cmd = ["rclone", "link", "--config", rclone_config_path, f"{destination}/{filename}"] - link_result = subprocess.run(link_cmd, capture_output=True, text=True) + link_result = subprocess.run(link_cmd, capture_output=True, text=True, check=False) public_url = link_result.stdout.strip() if link_result.returncode == 0 else None except (subprocess.SubprocessError, OSError) as e: logger.warning(f"[{task_id}] Failed to get public link for {filename}: {str(e)}") diff --git a/browser-extension/IMPLEMENTATION_SUMMARY.md b/browser-extension/IMPLEMENTATION_SUMMARY.md index 3eeac91b..58bc66c3 100644 --- a/browser-extension/IMPLEMENTATION_SUMMARY.md +++ b/browser-extension/IMPLEMENTATION_SUMMARY.md @@ -6,8 +6,8 @@ Successfully implemented a complete, production-ready browser extension for Docu ## Implementation Date -Feature branch: `copilot/add-browser-plugin-for-docuelevate` -Commits: 7 commits implementing the complete feature +Feature branch: `copilot/add-browser-plugin-for-docuelevate` +Commits: 7 commits implementing the complete feature Status: ✅ **COMPLETE AND PRODUCTION-READY** ## Requirements Met @@ -16,7 +16,7 @@ All requirements from the original issue have been fully satisfied: ### ✅ Functional Requirements - [x] Capture file URLs from user's browser -- [x] Send URLs to DocuElevate API endpoint +- [x] Send URLs to DocuElevate API endpoint - [x] Support for Chrome, Firefox, Edge, and Chromium-based browsers - [x] Simple user interaction (one-click + context menu) - [x] Display status/feedback in plugin UI (success, error) @@ -362,7 +362,7 @@ The browser extension implementation is **complete and production-ready**. All r --- -**Implementation Team**: GitHub Copilot -**Review Status**: All code review feedback addressed -**Documentation Status**: Complete +**Implementation Team**: GitHub Copilot +**Review Status**: All code review feedback addressed +**Documentation Status**: Complete **Production Readiness**: ✅ READY diff --git a/browser-extension/INSTALLATION.txt b/browser-extension/INSTALLATION.txt index d3b86fa2..e2346812 100644 --- a/browser-extension/INSTALLATION.txt +++ b/browser-extension/INSTALLATION.txt @@ -12,13 +12,13 @@ For Chrome / Edge / Chromium-based browsers: 2. Navigate to extensions page: • Chrome: chrome://extensions/ • Edge: edge://extensions/ - + 3. Enable "Developer mode" (toggle in top right) - + 4. Click "Load unpacked" - + 5. Select the browser-extension folder - + 6. Extension is now installed! 🎉 For Firefox: @@ -34,10 +34,10 @@ For Firefox: 1. Click the DocuElevate icon in toolbar 2. Enter your server URL: https://your-docuelevate-server.com - + 3. (Optional) Add session cookie if auth enabled: session=your_session_value - + 4. Click "Save Configuration" 5. Ready to use! 🚀 @@ -95,7 +95,7 @@ Complete guides available: Problem: Extension not appearing → Check developer mode is enabled → Reload the extension - + Problem: Can't connect to server → Verify server URL is correct → Check server is running diff --git a/browser-extension/README.md b/browser-extension/README.md index 584a9385..c454b01b 100644 --- a/browser-extension/README.md +++ b/browser-extension/README.md @@ -127,7 +127,7 @@ The extension can send any URL, but DocuElevate will only process supported file **Cause**: The URL doesn't point to a supported file type. -**Solution**: +**Solution**: - Verify the URL ends with a supported file extension - Check that the Content-Type header is set correctly by the server diff --git a/browser-extension/VISUAL_GUIDE.md b/browser-extension/VISUAL_GUIDE.md index e7b8444d..06e248f9 100644 --- a/browser-extension/VISUAL_GUIDE.md +++ b/browser-extension/VISUAL_GUIDE.md @@ -41,7 +41,7 @@ When you first install the extension, you'll see the configuration screen: └─────────────────────────────────────────┘ ``` -**Dimensions**: 400px wide, ~300px height +**Dimensions**: 400px wide, ~300px height **Colors**: Green buttons (#4CAF50), clean white background ### Send File View (Main Interface) @@ -180,7 +180,7 @@ After sending a file via context menu, a system notification appears: └─────────────────────────────────────────┘ ``` -**Notification Type**: Browser native notification +**Notification Type**: Browser native notification **Duration**: Auto-dismiss after 5-10 seconds ## Chrome Extensions Page diff --git a/browser-extension/popup/popup.js b/browser-extension/popup/popup.js index fa76ca84..900006b4 100644 --- a/browser-extension/popup/popup.js +++ b/browser-extension/popup/popup.js @@ -19,20 +19,20 @@ const showConfigBtn = document.getElementById('show-config'); document.addEventListener('DOMContentLoaded', async () => { // Load saved configuration const config = await loadConfig(); - + if (config.serverUrl) { serverUrlInput.value = config.serverUrl; } - + if (config.sessionCookie) { sessionCookieInput.value = config.sessionCookie; } - + // Get current tab URL const tabs = await chrome.tabs.query({ active: true, currentWindow: true }); const currentUrl = tabs[0]?.url || ''; currentUrlDisplay.textContent = currentUrl; - + // Show appropriate section if (config.serverUrl) { showSendSection(); @@ -44,12 +44,12 @@ document.addEventListener('DOMContentLoaded', async () => { // Save configuration saveConfigBtn.addEventListener('click', async () => { const serverUrl = serverUrlInput.value.trim(); - + if (!serverUrl) { showStatus('Please enter a server URL', 'error'); return; } - + // Validate URL format try { new URL(serverUrl); @@ -57,15 +57,15 @@ saveConfigBtn.addEventListener('click', async () => { showStatus('Invalid server URL format', 'error'); return; } - + const config = { serverUrl: serverUrl, sessionCookie: sessionCookieInput.value.trim() }; - + await saveConfig(config); showStatus('Configuration saved successfully!', 'success'); - + setTimeout(() => { showSendSection(); }, 1000); @@ -76,39 +76,39 @@ sendFileBtn.addEventListener('click', async () => { const config = await loadConfig(); const tabs = await chrome.tabs.query({ active: true, currentWindow: true }); const currentUrl = tabs[0]?.url || ''; - + if (!currentUrl) { showStatus('No URL found in current tab', 'error'); return; } - + // Disable button and show loading sendFileBtn.disabled = true; sendFileBtn.classList.add('loading'); showStatus('Sending file to DocuElevate...', 'info'); - + try { const payload = { url: currentUrl, filename: filenameInput.value.trim() || null }; - + const headers = { 'Content-Type': 'application/json' }; - + // Add session cookie if provided if (config.sessionCookie) { headers['Cookie'] = config.sessionCookie; } - + const response = await fetch(`${config.serverUrl}/api/process-url`, { method: 'POST', headers: headers, body: JSON.stringify(payload), credentials: 'include' }); - + if (response.ok) { const result = await response.json(); showStatus( diff --git a/browser-extension/scripts/background.js b/browser-extension/scripts/background.js index 8fc110da..0a1fc1fc 100644 --- a/browser-extension/scripts/background.js +++ b/browser-extension/scripts/background.js @@ -9,7 +9,7 @@ chrome.runtime.onInstalled.addListener((details) => { } else if (details.reason === 'update') { console.log('DocuElevate extension updated'); } - + // Create context menu item chrome.contextMenus.create({ id: 'send-to-docuelevate', @@ -31,36 +31,36 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { // Handle sending URL to DocuElevate async function handleSendUrl(data) { const { url, filename, serverUrl, sessionCookie } = data; - + if (!url || !serverUrl) { throw new Error('URL and server URL are required'); } - + const headers = { 'Content-Type': 'application/json' }; - + if (sessionCookie) { headers['Cookie'] = sessionCookie; } - + const payload = { url: url, filename: filename || null }; - + const response = await fetch(`${serverUrl}/api/process-url`, { method: 'POST', headers: headers, body: JSON.stringify(payload), credentials: 'include' }); - + if (!response.ok) { const errorData = await response.json().catch(() => ({ detail: 'Unknown error' })); throw new Error(errorData.detail || `HTTP ${response.status}`); } - + return await response.json(); } @@ -69,18 +69,18 @@ chrome.contextMenus.onClicked.addListener(async (info, tab) => { if (info.menuItemId === 'send-to-docuelevate') { // Get the URL to send (link URL or page URL) const targetUrl = info.linkUrl || info.pageUrl; - + // Load configuration const config = await new Promise((resolve) => { chrome.storage.sync.get(['serverUrl', 'sessionCookie'], resolve); }); - + if (!config.serverUrl) { // Open popup to configure chrome.action.openPopup(); return; } - + // Send the URL try { const result = await handleSendUrl({ @@ -88,7 +88,7 @@ chrome.contextMenus.onClicked.addListener(async (info, tab) => { serverUrl: config.serverUrl, sessionCookie: config.sessionCookie }); - + // Show success notification chrome.notifications.create({ type: 'basic', diff --git a/browser-extension/scripts/content.js b/browser-extension/scripts/content.js index ad8add6b..8a56f6de 100644 --- a/browser-extension/scripts/content.js +++ b/browser-extension/scripts/content.js @@ -24,7 +24,7 @@ function isDirectFileUrl(url) { '.txt', '.csv', '.rtf', '.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.webp', '.svg' ]; - + const urlLower = url.toLowerCase(); return fileExtensions.some(ext => urlLower.endsWith(ext)); } diff --git a/browser-extension/test.html b/browser-extension/test.html index 9fd92083..96efd4aa 100644 --- a/browser-extension/test.html +++ b/browser-extension/test.html @@ -52,7 +52,7 @@

🧪 DocuElevate Browser Extension Test Page

- +

How to Test

    @@ -66,18 +66,18 @@

    📄 Sample Document Links

    These links point to sample documents that can be processed by DocuElevate:

    - - 📕 Sample PDF Document (dummy.pdf) - - 📗 Example PDF File (file-sample_150kB.pdf) - - 📘 Learning Container Sample PDF @@ -86,13 +86,13 @@

    🖼️ Sample Image Links

    These links point to sample images that can be processed:

    - - 🖼️ Placeholder Image (PNG, 800x600) - - 📷 Placeholder Image (JPG, 1024x768) diff --git a/coverage.json b/coverage.json index c9efa164..80b9d307 100644 --- a/coverage.json +++ b/coverage.json @@ -1 +1 @@ -{"meta": {"format": 3, "version": "7.13.4", "timestamp": "2026-02-12T09:26:29.397216", "branch_coverage": true, "show_contexts": false}, "files": {"app/__init__.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/api/__init__.py": {"executed_lines": [5, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 25, 28, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42], "summary": {"covered_lines": 28, "num_statements": 28, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [5, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 25, 28, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42], "summary": {"covered_lines": 28, "num_statements": 28, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 25, 28, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42], "summary": {"covered_lines": 28, "num_statements": 28, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/api/azure.py": {"executed_lines": [5, 7, 8, 11, 12, 14, 15, 18, 20, 23, 24, 25, 30, 31, 34, 48, 50, 55, 91, 98, 99, 100], "summary": {"covered_lines": 22, "num_statements": 52, "percent_covered": 37.096774193548384, "percent_covered_display": "37.10", "missing_lines": 30, "excluded_lines": 0, "percent_statements_covered": 42.30769230769231, "percent_statements_covered_display": "42.31", "num_branches": 10, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 9, "percent_branches_covered": 10.0, "percent_branches_covered_display": "10.00"}, "missing_lines": [35, 36, 37, 38, 39, 40, 42, 58, 61, 62, 63, 64, 65, 71, 73, 74, 81, 83, 84, 92, 93, 105, 106, 107, 108, 109, 110, 112, 113, 114], "excluded_lines": [], "executed_branches": [[34, 48]], "missing_branches": [[34, 35], [37, 38], [37, 39], [39, 40], [39, 42], [63, 64], [63, 73], [64, 63], [64, 65]], "functions": {"test_azure_connection": {"executed_lines": [30, 31, 34, 48, 50, 55, 91, 98, 99, 100], "summary": {"covered_lines": 10, "num_statements": 40, "percent_covered": 22.0, "percent_covered_display": "22.00", "missing_lines": 30, "excluded_lines": 0, "percent_statements_covered": 25.0, "percent_statements_covered_display": "25.00", "num_branches": 10, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 9, "percent_branches_covered": 10.0, "percent_branches_covered_display": "10.00"}, "missing_lines": [35, 36, 37, 38, 39, 40, 42, 58, 61, 62, 63, 64, 65, 71, 73, 74, 81, 83, 84, 92, 93, 105, 106, 107, 108, 109, 110, 112, 113, 114], "excluded_lines": [], "start_line": 25, "executed_branches": [[34, 48]], "missing_branches": [[34, 35], [37, 38], [37, 39], [39, 40], [39, 42], [63, 64], [63, 73], [64, 63], [64, 65]]}, "": {"executed_lines": [5, 7, 8, 11, 12, 14, 15, 18, 20, 23, 24, 25], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 8, 11, 12, 14, 15, 18, 20, 23, 24, 25, 30, 31, 34, 48, 50, 55, 91, 98, 99, 100], "summary": {"covered_lines": 22, "num_statements": 52, "percent_covered": 37.096774193548384, "percent_covered_display": "37.10", "missing_lines": 30, "excluded_lines": 0, "percent_statements_covered": 42.30769230769231, "percent_statements_covered_display": "42.31", "num_branches": 10, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 9, "percent_branches_covered": 10.0, "percent_branches_covered_display": "10.00"}, "missing_lines": [35, 36, 37, 38, 39, 40, 42, 58, 61, 62, 63, 64, 65, 71, 73, 74, 81, 83, 84, 92, 93, 105, 106, 107, 108, 109, 110, 112, 113, 114], "excluded_lines": [], "start_line": 1, "executed_branches": [[34, 48]], "missing_branches": [[34, 35], [37, 38], [37, 39], [39, 40], [39, 42], [63, 64], [63, 73], [64, 63], [64, 65]]}}}, "app/api/common.py": {"executed_lines": [5, 6, 7, 9, 11, 14, 17, 37, 40, 41, 43, 46, 48, 51, 55, 56, 57, 59, 60, 64], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[40, 41], [40, 43], [46, 48], [46, 51]], "missing_branches": [], "functions": {"resolve_file_path": {"executed_lines": [37, 40, 41, 43, 46, 48, 51, 55, 56, 57, 59, 60, 64], "summary": {"covered_lines": 13, "num_statements": 13, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 17, "executed_branches": [[40, 41], [40, 43], [46, 48], [46, 51]], "missing_branches": []}, "": {"executed_lines": [5, 6, 7, 9, 11, 14, 17], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 9, 11, 14, 17, 37, 40, 41, 43, 46, 48, 51, 55, 56, 57, 59, 60, 64], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[40, 41], [40, 43], [46, 48], [46, 51]], "missing_branches": []}}}, "app/api/diagnostic.py": {"executed_lines": [5, 6, 8, 10, 11, 14, 16, 18, 21, 22, 23, 28, 31, 34, 54, 61, 62, 63, 65, 67, 68, 71, 73, 74, 75, 76], "summary": {"covered_lines": 26, "num_statements": 36, "percent_covered": 67.5, "percent_covered_display": "67.50", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 72.22222222222223, "percent_statements_covered_display": "72.22", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [82, 83, 93, 94, 95, 101, 102, 107, 108, 109], "excluded_lines": [], "executed_branches": [[75, 76]], "missing_branches": [[75, 82], [93, 94], [93, 101]], "functions": {"diagnostic_settings": {"executed_lines": [28, 31, 34, 54], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 23, "executed_branches": [], "missing_branches": []}, "test_notification": {"executed_lines": [65, 67, 68, 71, 73, 74, 75, 76], "summary": {"covered_lines": 8, "num_statements": 18, "percent_covered": 40.90909090909091, "percent_covered_display": "40.91", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 44.44444444444444, "percent_statements_covered_display": "44.44", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [82, 83, 93, 94, 95, 101, 102, 107, 108, 109], "excluded_lines": [], "start_line": 63, "executed_branches": [[75, 76]], "missing_branches": [[75, 82], [93, 94], [93, 101]]}, "": {"executed_lines": [5, 6, 8, 10, 11, 14, 16, 18, 21, 22, 23, 61, 62, 63], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 8, 10, 11, 14, 16, 18, 21, 22, 23, 28, 31, 34, 54, 61, 62, 63, 65, 67, 68, 71, 73, 74, 75, 76], "summary": {"covered_lines": 26, "num_statements": 36, "percent_covered": 67.5, "percent_covered_display": "67.50", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 72.22222222222223, "percent_statements_covered_display": "72.22", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [82, 83, 93, 94, 95, 101, 102, 107, 108, 109], "excluded_lines": [], "start_line": 1, "executed_branches": [[75, 76]], "missing_branches": [[75, 82], [93, 94], [93, 101]]}}}, "app/api/dropbox.py": {"executed_lines": [5, 6, 7, 9, 10, 12, 13, 14, 17, 19, 22, 23, 24, 58, 59, 60, 101, 102, 103, 107, 108, 110, 111, 112, 182, 183, 184], "summary": {"covered_lines": 27, "num_statements": 125, "percent_covered": 16.374269005847953, "percent_covered_display": "16.37", "missing_lines": 98, "excluded_lines": 0, "percent_statements_covered": 21.6, "percent_statements_covered_display": "21.60", "num_branches": 46, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 45, "percent_branches_covered": 2.1739130434782608, "percent_branches_covered_display": "2.17"}, "missing_lines": [37, 39, 48, 51, 70, 71, 74, 75, 76, 78, 79, 80, 82, 83, 84, 86, 87, 88, 92, 94, 95, 96, 115, 116, 123, 124, 127, 128, 135, 137, 138, 139, 141, 142, 145, 146, 152, 153, 154, 160, 161, 162, 165, 167, 169, 177, 178, 179, 194, 196, 198, 199, 200, 204, 207, 208, 211, 216, 217, 218, 219, 220, 221, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 241, 242, 243, 246, 247, 250, 251, 252, 253, 254, 255, 256, 257, 259, 261, 263, 264, 265, 266, 267], "excluded_lines": [], "executed_branches": [[110, 111]], "missing_branches": [[74, 75], [74, 78], [78, 79], [78, 82], [82, 83], [82, 86], [86, 87], [86, 92], [110, 115], [123, 124], [123, 152], [137, 138], [137, 141], [152, 153], [152, 160], [198, 199], [198, 204], [216, 217], [216, 218], [218, 219], [218, 220], [220, 221], [220, 224], [226, 227], [226, 241], [229, 230], [229, 237], [230, 229], [230, 231], [231, 232], [231, 233], [237, 226], [237, 238], [241, 242], [241, 246], [242, 241], [242, 243], [250, 251], [250, 252], [252, 253], [252, 254], [254, 255], [254, 256], [256, 257], [256, 259]], "functions": {"exchange_dropbox_token": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [37, 39, 48, 51], "excluded_lines": [], "start_line": 24, "executed_branches": [], "missing_branches": []}, "update_dropbox_settings": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 18, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [70, 71, 74, 75, 76, 78, 79, 80, 82, 83, 84, 86, 87, 88, 92, 94, 95, 96], "excluded_lines": [], "start_line": 60, "executed_branches": [], "missing_branches": [[74, 75], [74, 78], [78, 79], [78, 82], [82, 83], [82, 86], [86, 87], [86, 92]]}, "test_dropbox_token": {"executed_lines": [107, 108, 110, 111, 112], "summary": {"covered_lines": 5, "num_statements": 31, "percent_covered": 15.384615384615385, "percent_covered_display": "15.38", "missing_lines": 26, "excluded_lines": 0, "percent_statements_covered": 16.129032258064516, "percent_statements_covered_display": "16.13", "num_branches": 8, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 7, "percent_branches_covered": 12.5, "percent_branches_covered_display": "12.50"}, "missing_lines": [115, 116, 123, 124, 127, 128, 135, 137, 138, 139, 141, 142, 145, 146, 152, 153, 154, 160, 161, 162, 165, 167, 169, 177, 178, 179], "excluded_lines": [], "start_line": 103, "executed_branches": [[110, 111]], "missing_branches": [[110, 115], [123, 124], [123, 152], [137, 138], [137, 141], [152, 153], [152, 160]]}, "save_dropbox_settings": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 50, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 50, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 30, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 30, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [194, 196, 198, 199, 200, 204, 207, 208, 211, 216, 217, 218, 219, 220, 221, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 241, 242, 243, 246, 247, 250, 251, 252, 253, 254, 255, 256, 257, 259, 261, 263, 264, 265, 266, 267], "excluded_lines": [], "start_line": 184, "executed_branches": [], "missing_branches": [[198, 199], [198, 204], [216, 217], [216, 218], [218, 219], [218, 220], [220, 221], [220, 224], [226, 227], [226, 241], [229, 230], [229, 237], [230, 229], [230, 231], [231, 232], [231, 233], [237, 226], [237, 238], [241, 242], [241, 246], [242, 241], [242, 243], [250, 251], [250, 252], [252, 253], [252, 254], [254, 255], [254, 256], [256, 257], [256, 259]]}, "": {"executed_lines": [5, 6, 7, 9, 10, 12, 13, 14, 17, 19, 22, 23, 24, 58, 59, 60, 101, 102, 103, 182, 183, 184], "summary": {"covered_lines": 22, "num_statements": 22, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 9, 10, 12, 13, 14, 17, 19, 22, 23, 24, 58, 59, 60, 101, 102, 103, 107, 108, 110, 111, 112, 182, 183, 184], "summary": {"covered_lines": 27, "num_statements": 125, "percent_covered": 16.374269005847953, "percent_covered_display": "16.37", "missing_lines": 98, "excluded_lines": 0, "percent_statements_covered": 21.6, "percent_statements_covered_display": "21.60", "num_branches": 46, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 45, "percent_branches_covered": 2.1739130434782608, "percent_branches_covered_display": "2.17"}, "missing_lines": [37, 39, 48, 51, 70, 71, 74, 75, 76, 78, 79, 80, 82, 83, 84, 86, 87, 88, 92, 94, 95, 96, 115, 116, 123, 124, 127, 128, 135, 137, 138, 139, 141, 142, 145, 146, 152, 153, 154, 160, 161, 162, 165, 167, 169, 177, 178, 179, 194, 196, 198, 199, 200, 204, 207, 208, 211, 216, 217, 218, 219, 220, 221, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 241, 242, 243, 246, 247, 250, 251, 252, 253, 254, 255, 256, 257, 259, 261, 263, 264, 265, 266, 267], "excluded_lines": [], "start_line": 1, "executed_branches": [[110, 111]], "missing_branches": [[74, 75], [74, 78], [78, 79], [78, 82], [82, 83], [82, 86], [86, 87], [86, 92], [110, 115], [123, 124], [123, 152], [137, 138], [137, 141], [152, 153], [152, 160], [198, 199], [198, 204], [216, 217], [216, 218], [218, 219], [218, 220], [220, 221], [220, 224], [226, 227], [226, 241], [229, 230], [229, 237], [230, 229], [230, 231], [231, 232], [231, 233], [237, 226], [237, 238], [241, 242], [241, 246], [242, 241], [242, 243], [250, 251], [250, 252], [252, 253], [252, 254], [254, 255], [254, 256], [256, 257], [256, 259]]}}}, "app/api/files.py": {"executed_lines": [5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 26, 28, 30, 33, 40, 41, 42, 80, 83, 84, 87, 88, 91, 94, 97, 105, 106, 108, 111, 112, 115, 116, 119, 120, 121, 137, 139, 145, 150, 152, 155, 156, 157, 162, 164, 165, 168, 173, 174, 175, 187, 190, 192, 208, 209, 210, 216, 217, 219, 221, 223, 224, 227, 230, 231, 233, 235, 236, 237, 238, 239, 240, 243, 244, 245, 251, 254, 256, 258, 259, 261, 262, 265, 268, 269, 271, 273, 279, 280, 287, 288, 289, 293, 295, 297, 298, 300, 301, 302, 304, 305, 307, 308, 315, 318, 319, 320, 324, 333, 341, 342, 348, 349, 350, 360, 362, 364, 365, 368, 369, 372, 376, 380, 388, 389, 395, 396, 397, 457, 467, 469, 470, 471, 472, 473, 474, 477, 495, 497, 499, 501, 504, 505, 508, 509, 510, 511, 512, 513, 515, 519, 520, 521, 522, 523, 528, 532, 533, 534, 538, 540, 549, 550, 551, 573, 575, 577, 578, 581, 588, 589, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 603, 616, 617, 618, 624, 625, 628, 629, 635, 636, 637, 641, 642, 658, 659, 665, 666, 667, 683, 685, 687, 689, 690, 692, 694, 697, 699, 701, 702, 705, 706, 712, 713, 714, 718, 719, 721, 724, 730, 731, 737, 738, 739, 809, 810, 811, 813, 817, 819, 822, 824, 825, 826, 828, 831, 833, 834, 835, 836, 837, 838, 841, 844, 845, 846, 848, 849, 856, 871, 883, 884, 887, 890, 892, 894, 896, 898, 899, 903, 904, 907, 908, 909, 910, 911, 912, 915, 917, 925, 926, 928, 929, 931, 933, 934, 935, 939, 940, 941, 946, 947, 950, 951, 953], "summary": {"covered_lines": 292, "num_statements": 375, "percent_covered": 76.70103092783505, "percent_covered_display": "76.70", "missing_lines": 83, "excluded_lines": 0, "percent_statements_covered": 77.86666666666666, "percent_statements_covered_display": "77.87", "num_branches": 110, "num_partial_branches": 10, "covered_branches": 80, "missing_branches": 30, "percent_branches_covered": 72.72727272727273, "percent_branches_covered_display": "72.73"}, "missing_lines": [35, 37, 252, 281, 282, 283, 284, 329, 330, 331, 343, 344, 345, 390, 391, 392, 411, 413, 415, 416, 419, 420, 421, 422, 423, 424, 425, 427, 432, 436, 441, 450, 451, 452, 453, 454, 500, 516, 529, 536, 638, 639, 645, 646, 648, 650, 660, 661, 662, 695, 715, 716, 732, 733, 734, 755, 757, 759, 761, 762, 764, 766, 767, 769, 771, 773, 774, 777, 778, 784, 785, 786, 787, 788, 790, 791, 793, 796, 802, 803, 804, 805, 806], "excluded_lines": [], "executed_branches": [[83, 84], [83, 87], [87, 88], [87, 91], [105, 106], [105, 108], [120, 121], [120, 137], [164, 165], [164, 168], [174, 175], [174, 187], [216, 217], [216, 219], [223, 224], [223, 227], [251, 254], [258, 259], [258, 261], [268, 269], [268, 271], [297, 298], [297, 300], [304, 305], [304, 333], [307, 308], [307, 318], [364, 365], [364, 368], [368, 369], [368, 372], [472, 473], [472, 474], [497, 499], [497, 504], [499, 501], [504, 505], [504, 512], [508, 509], [508, 510], [512, 513], [512, 522], [515, 519], [522, 523], [528, 532], [577, 578], [577, 581], [588, 589], [588, 592], [616, 617], [616, 624], [636, 637], [636, 641], [637, 636], [641, 642], [689, 690], [689, 692], [692, 694], [692, 699], [694, 697], [699, 701], [699, 721], [713, 714], [713, 718], [714, 713], [718, 719], [824, 825], [824, 828], [846, 848], [846, 856], [894, 896], [894, 931], [908, 909], [908, 915], [931, 933], [931, 935], [935, 939], [935, 941], [941, 946], [941, 950]], "missing_branches": [[251, 252], [415, 416], [415, 419], [420, 421], [420, 423], [423, 424], [423, 427], [499, 500], [515, 516], [522, 536], [528, 529], [637, 638], [641, 645], [694, 695], [714, 715], [718, 724], [761, 762], [761, 764], [764, 766], [764, 771], [766, 767], [766, 769], [771, 773], [771, 793], [785, 786], [785, 790], [786, 785], [786, 787], [790, 791], [790, 796]], "functions": {"get_limiter": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [35, 37], "excluded_lines": [], "start_line": 33, "executed_branches": [], "missing_branches": []}, "list_files_api": {"executed_lines": [80, 83, 84, 87, 88, 91, 94, 97, 105, 106, 108, 111, 112, 115, 116, 119, 120, 121, 137, 139], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 42, "executed_branches": [[83, 84], [83, 87], [87, 88], [87, 91], [105, 106], [105, 108], [120, 121], [120, 137]], "missing_branches": []}, "_get_file_processing_status": {"executed_lines": [150, 152], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 145, "executed_branches": [], "missing_branches": []}, "get_file_details": {"executed_lines": [162, 164, 165, 168, 173, 174, 175, 187, 190, 192], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 157, "executed_branches": [[164, 165], [164, 168], [174, 175], [174, 187]], "missing_branches": []}, "delete_file_record": {"executed_lines": [216, 217, 219, 221, 223, 224, 227, 230, 231, 233, 235, 236, 237, 238, 239, 240], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 210, "executed_branches": [[216, 217], [216, 219], [223, 224], [223, 227]], "missing_branches": []}, "bulk_delete_files": {"executed_lines": [251, 254, 256, 258, 259, 261, 262, 265, 268, 269, 271, 273, 279, 280], "summary": {"covered_lines": 14, "num_statements": 19, "percent_covered": 76.0, "percent_covered_display": "76.00", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 73.6842105263158, "percent_statements_covered_display": "73.68", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [252, 281, 282, 283, 284], "excluded_lines": [], "start_line": 245, "executed_branches": [[251, 254], [258, 259], [258, 261], [268, 269], [268, 271]], "missing_branches": [[251, 252]]}, "bulk_reprocess_files": {"executed_lines": [293, 295, 297, 298, 300, 301, 302, 304, 305, 307, 308, 315, 318, 319, 320, 324, 333, 341, 342], "summary": {"covered_lines": 19, "num_statements": 25, "percent_covered": 80.64516129032258, "percent_covered_display": "80.65", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 76.0, "percent_statements_covered_display": "76.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [329, 330, 331, 343, 344, 345], "excluded_lines": [], "start_line": 289, "executed_branches": [[297, 298], [297, 300], [304, 305], [304, 333], [307, 308], [307, 318]], "missing_branches": []}, "reprocess_single_file": {"executed_lines": [360, 362, 364, 365, 368, 369, 372, 376, 380, 388, 389], "summary": {"covered_lines": 11, "num_statements": 14, "percent_covered": 83.33333333333333, "percent_covered_display": "83.33", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 78.57142857142857, "percent_statements_covered_display": "78.57", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [390, 391, 392], "excluded_lines": [], "start_line": 350, "executed_branches": [[364, 365], [364, 368], [368, 369], [368, 372]], "missing_branches": []}, "reprocess_with_cloud_ocr": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 20, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [411, 413, 415, 416, 419, 420, 421, 422, 423, 424, 425, 427, 432, 436, 441, 450, 451, 452, 453, 454], "excluded_lines": [], "start_line": 397, "executed_branches": [], "missing_branches": [[415, 416], [415, 419], [420, 421], [420, 423], [423, 424], [423, 427]]}, "_extract_text_from_pdf": {"executed_lines": [467, 469, 470, 471, 472, 473, 474], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 457, "executed_branches": [[472, 473], [472, 474]], "missing_branches": []}, "_retry_pipeline_step": {"executed_lines": [495, 497, 499, 501, 504, 505, 508, 509, 510, 511, 512, 513, 515, 519, 520, 521, 522, 523, 528, 532, 533, 534, 538, 540], "summary": {"covered_lines": 24, "num_statements": 28, "percent_covered": 81.81818181818181, "percent_covered_display": "81.82", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 85.71428571428571, "percent_statements_covered_display": "85.71", "num_branches": 16, "num_partial_branches": 4, "covered_branches": 12, "missing_branches": 4, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [500, 516, 529, 536], "excluded_lines": [], "start_line": 477, "executed_branches": [[497, 499], [497, 504], [499, 501], [504, 505], [504, 512], [508, 509], [508, 510], [512, 513], [512, 522], [515, 519], [522, 523], [528, 532]], "missing_branches": [[499, 500], [515, 516], [522, 536], [528, 529]]}, "retry_subtask": {"executed_lines": [573, 575, 577, 578, 581, 588, 589, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 603, 616, 617, 618, 624, 625, 628, 629, 635, 636, 637, 641, 642, 658, 659], "summary": {"covered_lines": 32, "num_statements": 41, "percent_covered": 79.24528301886792, "percent_covered_display": "79.25", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 78.04878048780488, "percent_statements_covered_display": "78.05", "num_branches": 12, "num_partial_branches": 2, "covered_branches": 10, "missing_branches": 2, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [638, 639, 645, 646, 648, 650, 660, 661, 662], "excluded_lines": [], "start_line": 551, "executed_branches": [[577, 578], [577, 581], [588, 589], [588, 592], [616, 617], [616, 624], [636, 637], [636, 641], [637, 636], [641, 642]], "missing_branches": [[637, 638], [641, 645]]}, "get_file_preview": {"executed_lines": [683, 685, 687, 689, 690, 692, 694, 697, 699, 701, 702, 705, 706, 712, 713, 714, 718, 719, 721, 724, 730, 731], "summary": {"covered_lines": 22, "num_statements": 28, "percent_covered": 78.57142857142857, "percent_covered_display": "78.57", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 78.57142857142857, "percent_statements_covered_display": "78.57", "num_branches": 14, "num_partial_branches": 3, "covered_branches": 11, "missing_branches": 3, "percent_branches_covered": 78.57142857142857, "percent_branches_covered_display": "78.57"}, "missing_lines": [695, 715, 716, 732, 733, 734], "excluded_lines": [], "start_line": 667, "executed_branches": [[689, 690], [689, 692], [692, 694], [692, 699], [694, 697], [699, 701], [699, 721], [713, 714], [713, 718], [714, 713], [718, 719]], "missing_branches": [[694, 695], [714, 715], [718, 724]]}, "download_file": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 28, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 28, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 14, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 14, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [755, 757, 759, 761, 762, 764, 766, 767, 769, 771, 773, 774, 777, 778, 784, 785, 786, 787, 788, 790, 791, 793, 796, 802, 803, 804, 805, 806], "excluded_lines": [], "start_line": 739, "executed_branches": [], "missing_branches": [[761, 762], [761, 764], [764, 766], [764, 771], [766, 767], [766, 769], [771, 773], [771, 793], [785, 786], [785, 790], [786, 785], [786, 787], [790, 791], [790, 796]]}, "ui_upload": {"executed_lines": [813, 817, 819, 822, 824, 825, 826, 828, 831, 833, 834, 835, 836, 837, 838, 841, 844, 845, 846, 848, 849, 856, 871, 883, 884, 887, 890, 892, 894, 896, 898, 899, 903, 904, 907, 908, 909, 910, 911, 912, 915, 917, 925, 926, 928, 929, 931, 933, 934, 935, 939, 940, 941, 946, 947, 950, 951, 953], "summary": {"covered_lines": 58, "num_statements": 58, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 14, "num_partial_branches": 0, "covered_branches": 14, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 811, "executed_branches": [[824, 825], [824, 828], [846, 848], [846, 856], [894, 896], [894, 931], [908, 909], [908, 915], [931, 933], [931, 935], [935, 939], [935, 941], [941, 946], [941, 950]], "missing_branches": []}, "": {"executed_lines": [5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 26, 28, 30, 33, 40, 41, 42, 145, 155, 156, 157, 208, 209, 210, 243, 244, 245, 287, 288, 289, 348, 349, 350, 395, 396, 397, 457, 477, 549, 550, 551, 665, 666, 667, 737, 738, 739, 809, 810, 811], "summary": {"covered_lines": 57, "num_statements": 57, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 26, 28, 30, 33, 40, 41, 42, 80, 83, 84, 87, 88, 91, 94, 97, 105, 106, 108, 111, 112, 115, 116, 119, 120, 121, 137, 139, 145, 150, 152, 155, 156, 157, 162, 164, 165, 168, 173, 174, 175, 187, 190, 192, 208, 209, 210, 216, 217, 219, 221, 223, 224, 227, 230, 231, 233, 235, 236, 237, 238, 239, 240, 243, 244, 245, 251, 254, 256, 258, 259, 261, 262, 265, 268, 269, 271, 273, 279, 280, 287, 288, 289, 293, 295, 297, 298, 300, 301, 302, 304, 305, 307, 308, 315, 318, 319, 320, 324, 333, 341, 342, 348, 349, 350, 360, 362, 364, 365, 368, 369, 372, 376, 380, 388, 389, 395, 396, 397, 457, 467, 469, 470, 471, 472, 473, 474, 477, 495, 497, 499, 501, 504, 505, 508, 509, 510, 511, 512, 513, 515, 519, 520, 521, 522, 523, 528, 532, 533, 534, 538, 540, 549, 550, 551, 573, 575, 577, 578, 581, 588, 589, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 603, 616, 617, 618, 624, 625, 628, 629, 635, 636, 637, 641, 642, 658, 659, 665, 666, 667, 683, 685, 687, 689, 690, 692, 694, 697, 699, 701, 702, 705, 706, 712, 713, 714, 718, 719, 721, 724, 730, 731, 737, 738, 739, 809, 810, 811, 813, 817, 819, 822, 824, 825, 826, 828, 831, 833, 834, 835, 836, 837, 838, 841, 844, 845, 846, 848, 849, 856, 871, 883, 884, 887, 890, 892, 894, 896, 898, 899, 903, 904, 907, 908, 909, 910, 911, 912, 915, 917, 925, 926, 928, 929, 931, 933, 934, 935, 939, 940, 941, 946, 947, 950, 951, 953], "summary": {"covered_lines": 292, "num_statements": 375, "percent_covered": 76.70103092783505, "percent_covered_display": "76.70", "missing_lines": 83, "excluded_lines": 0, "percent_statements_covered": 77.86666666666666, "percent_statements_covered_display": "77.87", "num_branches": 110, "num_partial_branches": 10, "covered_branches": 80, "missing_branches": 30, "percent_branches_covered": 72.72727272727273, "percent_branches_covered_display": "72.73"}, "missing_lines": [35, 37, 252, 281, 282, 283, 284, 329, 330, 331, 343, 344, 345, 390, 391, 392, 411, 413, 415, 416, 419, 420, 421, 422, 423, 424, 425, 427, 432, 436, 441, 450, 451, 452, 453, 454, 500, 516, 529, 536, 638, 639, 645, 646, 648, 650, 660, 661, 662, 695, 715, 716, 732, 733, 734, 755, 757, 759, 761, 762, 764, 766, 767, 769, 771, 773, 774, 777, 778, 784, 785, 786, 787, 788, 790, 791, 793, 796, 802, 803, 804, 805, 806], "excluded_lines": [], "start_line": 1, "executed_branches": [[83, 84], [83, 87], [87, 88], [87, 91], [105, 106], [105, 108], [120, 121], [120, 137], [164, 165], [164, 168], [174, 175], [174, 187], [216, 217], [216, 219], [223, 224], [223, 227], [251, 254], [258, 259], [258, 261], [268, 269], [268, 271], [297, 298], [297, 300], [304, 305], [304, 333], [307, 308], [307, 318], [364, 365], [364, 368], [368, 369], [368, 372], [472, 473], [472, 474], [497, 499], [497, 504], [499, 501], [504, 505], [504, 512], [508, 509], [508, 510], [512, 513], [512, 522], [515, 519], [522, 523], [528, 532], [577, 578], [577, 581], [588, 589], [588, 592], [616, 617], [616, 624], [636, 637], [636, 641], [637, 636], [641, 642], [689, 690], [689, 692], [692, 694], [692, 699], [694, 697], [699, 701], [699, 721], [713, 714], [713, 718], [714, 713], [718, 719], [824, 825], [824, 828], [846, 848], [846, 856], [894, 896], [894, 931], [908, 909], [908, 915], [931, 933], [931, 935], [935, 939], [935, 941], [941, 946], [941, 950]], "missing_branches": [[251, 252], [415, 416], [415, 419], [420, 421], [420, 423], [423, 424], [423, 427], [499, 500], [515, 516], [522, 536], [528, 529], [637, 638], [641, 645], [694, 695], [714, 715], [718, 724], [761, 762], [761, 764], [764, 766], [764, 771], [766, 767], [766, 769], [771, 773], [771, 793], [785, 786], [785, 790], [786, 785], [786, 787], [790, 791], [790, 796]]}}}, "app/api/google_drive.py": {"executed_lines": [5, 6, 7, 8, 10, 12, 13, 14, 17, 19, 22, 23, 24, 58, 59, 60, 108, 109, 110, 115, 116, 118, 121, 189, 190, 191, 224, 225, 226, 307, 309, 310, 312, 313, 314, 316, 317, 318, 319, 320, 321, 322, 324, 327, 328, 329], "summary": {"covered_lines": 46, "num_statements": 201, "percent_covered": 20.363636363636363, "percent_covered_display": "20.36", "missing_lines": 155, "excluded_lines": 0, "percent_statements_covered": 22.885572139303484, "percent_statements_covered_display": "22.89", "num_branches": 74, "num_partial_branches": 2, "covered_branches": 10, "missing_branches": 64, "percent_branches_covered": 13.513513513513514, "percent_branches_covered_display": "13.51"}, "missing_lines": [37, 39, 48, 51, 71, 72, 75, 78, 79, 80, 82, 83, 84, 86, 87, 88, 90, 91, 92, 95, 96, 98, 100, 101, 102, 122, 127, 128, 130, 132, 135, 136, 138, 147, 148, 151, 152, 153, 154, 155, 156, 163, 164, 166, 168, 175, 176, 177, 180, 181, 186, 193, 194, 195, 198, 199, 201, 202, 204, 206, 208, 214, 215, 216, 217, 219, 220, 221, 232, 233, 236, 237, 238, 243, 248, 249, 251, 253, 254, 256, 265, 266, 269, 270, 271, 272, 273, 274, 281, 283, 289, 290, 291, 294, 295, 300, 302, 303, 304, 340, 342, 345, 348, 351, 352, 353, 354, 355, 356, 357, 360, 361, 364, 365, 366, 369, 370, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 390, 391, 392, 395, 396, 398, 399, 400, 402, 407, 408, 409, 410, 411, 412, 413, 414, 417, 419, 421, 427, 428, 429], "excluded_lines": [], "executed_branches": [[121, 189], [189, 190], [309, 310], [309, 312], [317, 318], [317, 319], [319, 320], [319, 321], [321, 322], [321, 324]], "missing_branches": [[78, 79], [78, 82], [82, 83], [82, 86], [86, 87], [86, 90], [90, 91], [90, 95], [121, 122], [122, 127], [122, 130], [147, 148], [147, 151], [152, 153], [152, 163], [180, 181], [180, 186], [189, 193], [201, 202], [201, 204], [236, 237], [236, 243], [243, 248], [243, 251], [265, 266], [265, 269], [270, 271], [270, 281], [294, 295], [294, 300], [351, 352], [351, 360], [352, 353], [352, 354], [354, 355], [354, 356], [356, 357], [356, 360], [360, 361], [360, 364], [364, 365], [364, 402], [375, 376], [375, 390], [378, 379], [378, 386], [379, 378], [379, 380], [380, 381], [380, 382], [386, 375], [386, 387], [390, 391], [390, 395], [391, 390], [391, 392], [407, 408], [407, 409], [409, 410], [409, 411], [411, 412], [411, 413], [413, 414], [413, 417]], "functions": {"exchange_google_drive_token": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [37, 39, 48, 51], "excluded_lines": [], "start_line": 24, "executed_branches": [], "missing_branches": []}, "update_google_drive_settings": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 21, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 21, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [71, 72, 75, 78, 79, 80, 82, 83, 84, 86, 87, 88, 90, 91, 92, 95, 96, 98, 100, 101, 102], "excluded_lines": [], "start_line": 60, "executed_branches": [], "missing_branches": [[78, 79], [78, 82], [82, 83], [82, 86], [86, 87], [86, 90], [90, 91], [90, 95]]}, "test_google_drive_token": {"executed_lines": [115, 116, 118, 121, 189, 190, 191], "summary": {"covered_lines": 7, "num_statements": 50, "percent_covered": 14.0625, "percent_covered_display": "14.06", "missing_lines": 43, "excluded_lines": 0, "percent_statements_covered": 14.0, "percent_statements_covered_display": "14.00", "num_branches": 14, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 12, "percent_branches_covered": 14.285714285714286, "percent_branches_covered_display": "14.29"}, "missing_lines": [122, 127, 128, 130, 132, 135, 136, 138, 147, 148, 151, 152, 153, 154, 155, 156, 163, 164, 166, 168, 175, 176, 177, 180, 181, 186, 193, 194, 195, 198, 199, 201, 202, 204, 206, 208, 214, 215, 216, 217, 219, 220, 221], "excluded_lines": [], "start_line": 110, "executed_branches": [[121, 189], [189, 190]], "missing_branches": [[121, 122], [122, 127], [122, 130], [147, 148], [147, 151], [152, 153], [152, 163], [180, 181], [180, 186], [189, 193], [201, 202], [201, 204]]}, "get_google_drive_token_info": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 31, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 31, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 10, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [232, 233, 236, 237, 238, 243, 248, 249, 251, 253, 254, 256, 265, 266, 269, 270, 271, 272, 273, 274, 281, 283, 289, 290, 291, 294, 295, 300, 302, 303, 304], "excluded_lines": [], "start_line": 226, "executed_branches": [], "missing_branches": [[236, 237], [236, 243], [243, 248], [243, 251], [265, 266], [265, 269], [270, 271], [270, 281], [294, 295], [294, 300]]}, "format_time_remaining": {"executed_lines": [309, 310, 312, 313, 314, 316, 317, 318, 319, 320, 321, 322, 324], "summary": {"covered_lines": 13, "num_statements": 13, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 307, "executed_branches": [[309, 310], [309, 312], [317, 318], [317, 319], [319, 320], [319, 321], [321, 322], [321, 324]], "missing_branches": []}, "save_dropbox_settings": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 56, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 56, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 34, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 34, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [340, 342, 345, 348, 351, 352, 353, 354, 355, 356, 357, 360, 361, 364, 365, 366, 369, 370, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 390, 391, 392, 395, 396, 398, 399, 400, 402, 407, 408, 409, 410, 411, 412, 413, 414, 417, 419, 421, 427, 428, 429], "excluded_lines": [], "start_line": 329, "executed_branches": [], "missing_branches": [[351, 352], [351, 360], [352, 353], [352, 354], [354, 355], [354, 356], [356, 357], [356, 360], [360, 361], [360, 364], [364, 365], [364, 402], [375, 376], [375, 390], [378, 379], [378, 386], [379, 378], [379, 380], [380, 381], [380, 382], [386, 375], [386, 387], [390, 391], [390, 395], [391, 390], [391, 392], [407, 408], [407, 409], [409, 410], [409, 411], [411, 412], [411, 413], [413, 414], [413, 417]]}, "": {"executed_lines": [5, 6, 7, 8, 10, 12, 13, 14, 17, 19, 22, 23, 24, 58, 59, 60, 108, 109, 110, 224, 225, 226, 307, 327, 328, 329], "summary": {"covered_lines": 26, "num_statements": 26, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 8, 10, 12, 13, 14, 17, 19, 22, 23, 24, 58, 59, 60, 108, 109, 110, 115, 116, 118, 121, 189, 190, 191, 224, 225, 226, 307, 309, 310, 312, 313, 314, 316, 317, 318, 319, 320, 321, 322, 324, 327, 328, 329], "summary": {"covered_lines": 46, "num_statements": 201, "percent_covered": 20.363636363636363, "percent_covered_display": "20.36", "missing_lines": 155, "excluded_lines": 0, "percent_statements_covered": 22.885572139303484, "percent_statements_covered_display": "22.89", "num_branches": 74, "num_partial_branches": 2, "covered_branches": 10, "missing_branches": 64, "percent_branches_covered": 13.513513513513514, "percent_branches_covered_display": "13.51"}, "missing_lines": [37, 39, 48, 51, 71, 72, 75, 78, 79, 80, 82, 83, 84, 86, 87, 88, 90, 91, 92, 95, 96, 98, 100, 101, 102, 122, 127, 128, 130, 132, 135, 136, 138, 147, 148, 151, 152, 153, 154, 155, 156, 163, 164, 166, 168, 175, 176, 177, 180, 181, 186, 193, 194, 195, 198, 199, 201, 202, 204, 206, 208, 214, 215, 216, 217, 219, 220, 221, 232, 233, 236, 237, 238, 243, 248, 249, 251, 253, 254, 256, 265, 266, 269, 270, 271, 272, 273, 274, 281, 283, 289, 290, 291, 294, 295, 300, 302, 303, 304, 340, 342, 345, 348, 351, 352, 353, 354, 355, 356, 357, 360, 361, 364, 365, 366, 369, 370, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 390, 391, 392, 395, 396, 398, 399, 400, 402, 407, 408, 409, 410, 411, 412, 413, 414, 417, 419, 421, 427, 428, 429], "excluded_lines": [], "start_line": 1, "executed_branches": [[121, 189], [189, 190], [309, 310], [309, 312], [317, 318], [317, 319], [319, 320], [319, 321], [321, 322], [321, 324]], "missing_branches": [[78, 79], [78, 82], [82, 83], [82, 86], [86, 87], [86, 90], [90, 91], [90, 95], [121, 122], [122, 127], [122, 130], [147, 148], [147, 151], [152, 153], [152, 163], [180, 181], [180, 186], [189, 193], [201, 202], [201, 204], [236, 237], [236, 243], [243, 248], [243, 251], [265, 266], [265, 269], [270, 271], [270, 281], [294, 295], [294, 300], [351, 352], [351, 360], [352, 353], [352, 354], [354, 355], [354, 356], [356, 357], [356, 360], [360, 361], [360, 364], [364, 365], [364, 402], [375, 376], [375, 390], [378, 379], [378, 386], [379, 378], [379, 380], [380, 381], [380, 382], [386, 375], [386, 387], [390, 391], [390, 395], [391, 390], [391, 392], [407, 408], [407, 409], [409, 410], [409, 411], [411, 412], [411, 413], [413, 414], [413, 417]]}}}, "app/api/logs.py": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 17, 19, 21, 24, 25, 26, 56, 59, 61, 62, 65, 68, 69, 70, 81, 84, 85, 86, 94, 95, 96, 99, 102, 103, 104, 115, 128, 129, 130, 136, 138, 139, 142, 143, 144, 155], "summary": {"covered_lines": 44, "num_statements": 45, "percent_covered": 96.61016949152543, "percent_covered_display": "96.61", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 97.77777777777777, "percent_statements_covered_display": "97.78", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 13, "missing_branches": 1, "percent_branches_covered": 92.85714285714286, "percent_branches_covered_display": "92.86"}, "missing_lines": [60], "excluded_lines": [], "executed_branches": [[59, 61], [61, 62], [61, 65], [69, 70], [69, 81], [95, 96], [95, 99], [103, 104], [103, 115], [138, 139], [138, 142], [143, 144], [143, 155]], "missing_branches": [[59, 60]], "functions": {"list_processing_logs": {"executed_lines": [56, 59, 61, 62, 65, 68, 69, 70, 81], "summary": {"covered_lines": 9, "num_statements": 10, "percent_covered": 87.5, "percent_covered_display": "87.50", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.0, "percent_statements_covered_display": "90.00", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [60], "excluded_lines": [], "start_line": 26, "executed_branches": [[59, 61], [61, 62], [61, 65], [69, 70], [69, 81]], "missing_branches": [[59, 60]]}, "get_file_processing_logs": {"executed_lines": [94, 95, 96, 99, 102, 103, 104, 115], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 86, "executed_branches": [[95, 96], [95, 99], [103, 104], [103, 115]], "missing_branches": []}, "get_task_processing_logs": {"executed_lines": [136, 138, 139, 142, 143, 144, 155], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 130, "executed_branches": [[138, 139], [138, 142], [143, 144], [143, 155]], "missing_branches": []}, "": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 17, 19, 21, 24, 25, 26, 84, 85, 86, 128, 129, 130], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 17, 19, 21, 24, 25, 26, 56, 59, 61, 62, 65, 68, 69, 70, 81, 84, 85, 86, 94, 95, 96, 99, 102, 103, 104, 115, 128, 129, 130, 136, 138, 139, 142, 143, 144, 155], "summary": {"covered_lines": 44, "num_statements": 45, "percent_covered": 96.61016949152543, "percent_covered_display": "96.61", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 97.77777777777777, "percent_statements_covered_display": "97.78", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 13, "missing_branches": 1, "percent_branches_covered": 92.85714285714286, "percent_branches_covered_display": "92.86"}, "missing_lines": [60], "excluded_lines": [], "start_line": 1, "executed_branches": [[59, 61], [61, 62], [61, 65], [69, 70], [69, 81], [95, 96], [95, 99], [103, 104], [103, 115], [138, 139], [138, 142], [143, 144], [143, 155]], "missing_branches": [[59, 60]]}}}, "app/api/onedrive.py": {"executed_lines": [5, 6, 7, 8, 10, 11, 13, 14, 15, 18, 20, 23, 24, 25, 56, 57, 58, 62, 63, 65, 70, 71, 177, 179, 180, 182, 183, 184, 186, 187, 188, 189, 190, 191, 192, 194, 197, 198, 199, 292, 293, 294, 348, 349, 350], "summary": {"covered_lines": 45, "num_statements": 189, "percent_covered": 21.011673151750973, "percent_covered_display": "21.01", "missing_lines": 144, "excluded_lines": 0, "percent_statements_covered": 23.80952380952381, "percent_statements_covered_display": "23.81", "num_branches": 68, "num_partial_branches": 1, "covered_branches": 9, "missing_branches": 59, "percent_branches_covered": 13.235294117647058, "percent_branches_covered_display": "13.24"}, "missing_lines": [38, 40, 50, 53, 74, 75, 77, 85, 87, 88, 89, 91, 92, 93, 96, 97, 98, 101, 104, 105, 106, 107, 108, 110, 111, 113, 114, 115, 116, 118, 120, 121, 123, 124, 126, 128, 129, 132, 133, 135, 137, 138, 139, 145, 146, 147, 150, 151, 154, 155, 162, 164, 172, 173, 174, 210, 212, 214, 215, 216, 220, 223, 224, 227, 232, 233, 234, 235, 236, 237, 238, 239, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 259, 260, 261, 264, 265, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 279, 281, 283, 284, 285, 286, 287, 305, 306, 309, 310, 311, 313, 314, 315, 317, 318, 319, 321, 322, 323, 325, 326, 327, 330, 331, 333, 334, 335, 336, 337, 339, 341, 342, 343, 354, 356, 365, 375, 376, 377, 378], "excluded_lines": [], "executed_branches": [[65, 70], [179, 180], [179, 182], [187, 188], [187, 189], [189, 190], [189, 191], [191, 192], [191, 194]], "missing_branches": [[65, 74], [87, 88], [87, 91], [97, 98], [97, 132], [106, 107], [106, 132], [113, 114], [113, 120], [114, 115], [114, 118], [120, 121], [120, 123], [137, 138], [137, 145], [214, 215], [214, 220], [232, 233], [232, 234], [234, 235], [234, 236], [236, 237], [236, 238], [238, 239], [238, 242], [244, 245], [244, 259], [247, 248], [247, 255], [248, 247], [248, 249], [249, 250], [249, 251], [255, 244], [255, 256], [259, 260], [259, 264], [260, 259], [260, 261], [268, 269], [268, 270], [270, 271], [270, 272], [272, 273], [272, 274], [274, 275], [274, 276], [276, 277], [276, 279], [309, 310], [309, 313], [313, 314], [313, 317], [317, 318], [317, 321], [321, 322], [321, 325], [325, 326], [325, 330]], "functions": {"exchange_onedrive_token": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [38, 40, 50, 53], "excluded_lines": [], "start_line": 25, "executed_branches": [], "missing_branches": []}, "test_onedrive_token": {"executed_lines": [62, 63, 65, 70, 71], "summary": {"covered_lines": 5, "num_statements": 56, "percent_covered": 8.333333333333334, "percent_covered_display": "8.33", "missing_lines": 51, "excluded_lines": 0, "percent_statements_covered": 8.928571428571429, "percent_statements_covered_display": "8.93", "num_branches": 16, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 15, "percent_branches_covered": 6.25, "percent_branches_covered_display": "6.25"}, "missing_lines": [74, 75, 77, 85, 87, 88, 89, 91, 92, 93, 96, 97, 98, 101, 104, 105, 106, 107, 108, 110, 111, 113, 114, 115, 116, 118, 120, 121, 123, 124, 126, 128, 129, 132, 133, 135, 137, 138, 139, 145, 146, 147, 150, 151, 154, 155, 162, 164, 172, 173, 174], "excluded_lines": [], "start_line": 58, "executed_branches": [[65, 70]], "missing_branches": [[65, 74], [87, 88], [87, 91], [97, 98], [97, 132], [106, 107], [106, 132], [113, 114], [113, 120], [114, 115], [114, 118], [120, 121], [120, 123], [137, 138], [137, 145]]}, "format_time_remaining": {"executed_lines": [179, 180, 182, 183, 184, 186, 187, 188, 189, 190, 191, 192, 194], "summary": {"covered_lines": 13, "num_statements": 13, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 177, "executed_branches": [[179, 180], [179, 182], [187, 188], [187, 189], [189, 190], [189, 191], [191, 192], [191, 194]], "missing_branches": []}, "save_onedrive_settings": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 54, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 54, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 34, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 34, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [210, 212, 214, 215, 216, 220, 223, 224, 227, 232, 233, 234, 235, 236, 237, 238, 239, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 259, 260, 261, 264, 265, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 279, 281, 283, 284, 285, 286, 287], "excluded_lines": [], "start_line": 199, "executed_branches": [], "missing_branches": [[214, 215], [214, 220], [232, 233], [232, 234], [234, 235], [234, 236], [236, 237], [236, 238], [238, 239], [238, 242], [244, 245], [244, 259], [247, 248], [247, 255], [248, 247], [248, 249], [249, 250], [249, 251], [255, 244], [255, 256], [259, 260], [259, 264], [260, 259], [260, 261], [268, 269], [268, 270], [270, 271], [270, 272], [272, 273], [272, 274], [274, 275], [274, 276], [276, 277], [276, 279]]}, "update_onedrive_settings": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 28, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 28, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 10, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [305, 306, 309, 310, 311, 313, 314, 315, 317, 318, 319, 321, 322, 323, 325, 326, 327, 330, 331, 333, 334, 335, 336, 337, 339, 341, 342, 343], "excluded_lines": [], "start_line": 294, "executed_branches": [], "missing_branches": [[309, 310], [309, 313], [313, 314], [313, 317], [317, 318], [317, 321], [321, 322], [321, 325], [325, 326], [325, 330]]}, "get_onedrive_full_config": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [354, 356, 365, 375, 376, 377, 378], "excluded_lines": [], "start_line": 350, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [5, 6, 7, 8, 10, 11, 13, 14, 15, 18, 20, 23, 24, 25, 56, 57, 58, 177, 197, 198, 199, 292, 293, 294, 348, 349, 350], "summary": {"covered_lines": 27, "num_statements": 27, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 8, 10, 11, 13, 14, 15, 18, 20, 23, 24, 25, 56, 57, 58, 62, 63, 65, 70, 71, 177, 179, 180, 182, 183, 184, 186, 187, 188, 189, 190, 191, 192, 194, 197, 198, 199, 292, 293, 294, 348, 349, 350], "summary": {"covered_lines": 45, "num_statements": 189, "percent_covered": 21.011673151750973, "percent_covered_display": "21.01", "missing_lines": 144, "excluded_lines": 0, "percent_statements_covered": 23.80952380952381, "percent_statements_covered_display": "23.81", "num_branches": 68, "num_partial_branches": 1, "covered_branches": 9, "missing_branches": 59, "percent_branches_covered": 13.235294117647058, "percent_branches_covered_display": "13.24"}, "missing_lines": [38, 40, 50, 53, 74, 75, 77, 85, 87, 88, 89, 91, 92, 93, 96, 97, 98, 101, 104, 105, 106, 107, 108, 110, 111, 113, 114, 115, 116, 118, 120, 121, 123, 124, 126, 128, 129, 132, 133, 135, 137, 138, 139, 145, 146, 147, 150, 151, 154, 155, 162, 164, 172, 173, 174, 210, 212, 214, 215, 216, 220, 223, 224, 227, 232, 233, 234, 235, 236, 237, 238, 239, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 259, 260, 261, 264, 265, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 279, 281, 283, 284, 285, 286, 287, 305, 306, 309, 310, 311, 313, 314, 315, 317, 318, 319, 321, 322, 323, 325, 326, 327, 330, 331, 333, 334, 335, 336, 337, 339, 341, 342, 343, 354, 356, 365, 375, 376, 377, 378], "excluded_lines": [], "start_line": 1, "executed_branches": [[65, 70], [179, 180], [179, 182], [187, 188], [187, 189], [189, 190], [189, 191], [191, 192], [191, 194]], "missing_branches": [[65, 74], [87, 88], [87, 91], [97, 98], [97, 132], [106, 107], [106, 132], [113, 114], [113, 120], [114, 115], [114, 118], [120, 121], [120, 123], [137, 138], [137, 145], [214, 215], [214, 220], [232, 233], [232, 234], [234, 235], [234, 236], [236, 237], [236, 238], [238, 239], [238, 242], [244, 245], [244, 259], [247, 248], [247, 255], [248, 247], [248, 249], [249, 250], [249, 251], [255, 244], [255, 256], [259, 260], [259, 264], [260, 259], [260, 261], [268, 269], [268, 270], [270, 271], [270, 272], [272, 273], [272, 274], [274, 275], [274, 276], [276, 277], [276, 279], [309, 310], [309, 313], [313, 314], [313, 317], [317, 318], [317, 321], [321, 322], [321, 325], [325, 326], [325, 330]]}}}, "app/api/openai.py": {"executed_lines": [5, 7, 9, 10, 13, 15, 18, 19, 20, 24, 25, 27, 30, 35, 38, 40, 49, 50, 51, 54, 56], "summary": {"covered_lines": 21, "num_statements": 31, "percent_covered": 66.66666666666667, "percent_covered_display": "66.67", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 67.74193548387096, "percent_statements_covered_display": "67.74", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [31, 32, 43, 44, 62, 63, 64, 65, 66, 67], "excluded_lines": [], "executed_branches": [[30, 35]], "missing_branches": [[30, 31]], "functions": {"test_openai_connection": {"executed_lines": [24, 25, 27, 30, 35, 38, 40, 49, 50, 51, 54, 56], "summary": {"covered_lines": 12, "num_statements": 22, "percent_covered": 54.166666666666664, "percent_covered_display": "54.17", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 54.54545454545455, "percent_statements_covered_display": "54.55", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [31, 32, 43, 44, 62, 63, 64, 65, 66, 67], "excluded_lines": [], "start_line": 20, "executed_branches": [[30, 35]], "missing_branches": [[30, 31]]}, "": {"executed_lines": [5, 7, 9, 10, 13, 15, 18, 19, 20], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 9, 10, 13, 15, 18, 19, 20, 24, 25, 27, 30, 35, 38, 40, 49, 50, 51, 54, 56], "summary": {"covered_lines": 21, "num_statements": 31, "percent_covered": 66.66666666666667, "percent_covered_display": "66.67", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 67.74193548387096, "percent_statements_covered_display": "67.74", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [31, 32, 43, 44, 62, 63, 64, 65, 66, 67], "excluded_lines": [], "start_line": 1, "executed_branches": [[30, 35]], "missing_branches": [[30, 31]]}}}, "app/api/process.py": {"executed_lines": [5, 6, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 24, 27, 28, 29, 31, 33, 34, 40, 41, 42, 44, 45, 46, 51, 52, 53, 55, 56, 57, 62, 63, 64, 66, 67, 68, 73, 74, 75, 77, 78, 79, 84, 85, 86, 88, 89, 90, 95, 96, 97, 99, 101, 102, 108, 109, 110, 117, 118, 119, 121, 122, 123, 124, 126, 127, 129, 130, 133, 135, 136, 142, 143, 145, 149, 150, 151, 154, 156, 158, 159, 160, 161, 163], "summary": {"covered_lines": 87, "num_statements": 101, "percent_covered": 83.20610687022901, "percent_covered_display": "83.21", "missing_lines": 14, "excluded_lines": 0, "percent_statements_covered": 86.13861386138613, "percent_statements_covered_display": "86.14", "num_branches": 30, "num_partial_branches": 8, "covered_branches": 22, "missing_branches": 8, "percent_branches_covered": 73.33333333333333, "percent_branches_covered_display": "73.33"}, "missing_lines": [36, 37, 47, 48, 58, 59, 69, 70, 80, 81, 91, 92, 104, 105], "excluded_lines": [], "executed_branches": [[33, 34], [45, 46], [56, 57], [67, 68], [78, 79], [89, 90], [101, 102], [118, 119], [118, 121], [122, 123], [122, 126], [123, 124], [126, 127], [126, 129], [135, 136], [135, 142], [142, 143], [142, 158], [145, 149], [145, 154], [159, 160], [159, 163]], "missing_branches": [[33, 36], [45, 47], [56, 58], [67, 69], [78, 80], [89, 91], [101, 104], [123, 122]], "functions": {"process": {"executed_lines": [31, 33, 34], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 57.142857142857146, "percent_covered_display": "57.14", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [36, 37], "excluded_lines": [], "start_line": 29, "executed_branches": [[33, 34]], "missing_branches": [[33, 36]]}, "send_to_dropbox_endpoint": {"executed_lines": [44, 45, 46], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 57.142857142857146, "percent_covered_display": "57.14", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [47, 48], "excluded_lines": [], "start_line": 42, "executed_branches": [[45, 46]], "missing_branches": [[45, 47]]}, "send_to_paperless_endpoint": {"executed_lines": [55, 56, 57], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 57.142857142857146, "percent_covered_display": "57.14", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [58, 59], "excluded_lines": [], "start_line": 53, "executed_branches": [[56, 57]], "missing_branches": [[56, 58]]}, "send_to_nextcloud_endpoint": {"executed_lines": [66, 67, 68], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 57.142857142857146, "percent_covered_display": "57.14", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [69, 70], "excluded_lines": [], "start_line": 64, "executed_branches": [[67, 68]], "missing_branches": [[67, 69]]}, "send_to_google_drive_endpoint": {"executed_lines": [77, 78, 79], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 57.142857142857146, "percent_covered_display": "57.14", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [80, 81], "excluded_lines": [], "start_line": 75, "executed_branches": [[78, 79]], "missing_branches": [[78, 80]]}, "send_to_onedrive_endpoint": {"executed_lines": [88, 89, 90], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 57.142857142857146, "percent_covered_display": "57.14", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [91, 92], "excluded_lines": [], "start_line": 86, "executed_branches": [[89, 90]], "missing_branches": [[89, 91]]}, "send_to_all_destinations_endpoint": {"executed_lines": [99, 101, 102], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 57.142857142857146, "percent_covered_display": "57.14", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [104, 105], "excluded_lines": [], "start_line": 97, "executed_branches": [[101, 102]], "missing_branches": [[101, 104]]}, "process_all_pdfs_in_workdir": {"executed_lines": [117, 118, 119, 121, 122, 123, 124, 126, 127, 129, 130, 133, 135, 136, 142, 143, 145, 149, 150, 151, 154, 156, 158, 159, 160, 161, 163], "summary": {"covered_lines": 27, "num_statements": 27, "percent_covered": 97.67441860465117, "percent_covered_display": "97.67", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 16, "num_partial_branches": 1, "covered_branches": 15, "missing_branches": 1, "percent_branches_covered": 93.75, "percent_branches_covered_display": "93.75"}, "missing_lines": [], "excluded_lines": [], "start_line": 110, "executed_branches": [[118, 119], [118, 121], [122, 123], [122, 126], [123, 124], [126, 127], [126, 129], [135, 136], [135, 142], [142, 143], [142, 158], [145, 149], [145, 154], [159, 160], [159, 163]], "missing_branches": [[123, 122]]}, "": {"executed_lines": [5, 6, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 24, 27, 28, 29, 40, 41, 42, 51, 52, 53, 62, 63, 64, 73, 74, 75, 84, 85, 86, 95, 96, 97, 108, 109, 110], "summary": {"covered_lines": 39, "num_statements": 39, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 24, 27, 28, 29, 31, 33, 34, 40, 41, 42, 44, 45, 46, 51, 52, 53, 55, 56, 57, 62, 63, 64, 66, 67, 68, 73, 74, 75, 77, 78, 79, 84, 85, 86, 88, 89, 90, 95, 96, 97, 99, 101, 102, 108, 109, 110, 117, 118, 119, 121, 122, 123, 124, 126, 127, 129, 130, 133, 135, 136, 142, 143, 145, 149, 150, 151, 154, 156, 158, 159, 160, 161, 163], "summary": {"covered_lines": 87, "num_statements": 101, "percent_covered": 83.20610687022901, "percent_covered_display": "83.21", "missing_lines": 14, "excluded_lines": 0, "percent_statements_covered": 86.13861386138613, "percent_statements_covered_display": "86.14", "num_branches": 30, "num_partial_branches": 8, "covered_branches": 22, "missing_branches": 8, "percent_branches_covered": 73.33333333333333, "percent_branches_covered_display": "73.33"}, "missing_lines": [36, 37, 47, 48, 58, 59, 69, 70, 80, 81, 91, 92, 104, 105], "excluded_lines": [], "start_line": 1, "executed_branches": [[33, 34], [45, 46], [56, 57], [67, 68], [78, 79], [89, 90], [101, 102], [118, 119], [118, 121], [122, 123], [122, 126], [123, 124], [126, 127], [126, 129], [135, 136], [135, 142], [142, 143], [142, 158], [145, 149], [145, 154], [159, 160], [159, 163]], "missing_branches": [[33, 36], [45, 47], [56, 58], [67, 69], [78, 80], [89, 91], [101, 104], [123, 122]]}}}, "app/api/settings.py": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 24, 25, 28, 36, 37, 38, 39, 42, 43, 46, 49, 50, 53, 56, 57, 58, 61, 64, 65, 66, 69, 70, 95, 96, 116, 117, 162, 163, 186, 187], "summary": {"covered_lines": 38, "num_statements": 101, "percent_covered": 32.520325203252035, "percent_covered_display": "32.52", "missing_lines": 63, "excluded_lines": 0, "percent_statements_covered": 37.62376237623762, "percent_statements_covered_display": "37.62", "num_branches": 22, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 20, "percent_branches_covered": 9.090909090909092, "percent_branches_covered_display": "9.09"}, "missing_lines": [75, 77, 78, 79, 80, 81, 84, 87, 89, 90, 91, 92, 101, 103, 106, 108, 109, 110, 111, 128, 130, 131, 132, 133, 136, 137, 138, 143, 144, 146, 153, 154, 155, 156, 157, 168, 169, 170, 171, 173, 177, 178, 179, 180, 181, 192, 193, 195, 196, 198, 199, 200, 201, 202, 205, 206, 207, 209, 210, 211, 212, 214, 216], "excluded_lines": [], "executed_branches": [[37, 38], [37, 39]], "missing_branches": [[78, 79], [78, 84], [79, 78], [79, 80], [130, 131], [130, 136], [132, 133], [132, 136], [137, 138], [137, 143], [170, 171], [170, 173], [195, 196], [195, 214], [198, 199], [198, 205], [200, 201], [200, 205], [206, 207], [206, 209]], "functions": {"require_admin": {"executed_lines": [36, 37, 38, 39], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 28, "executed_branches": [[37, 38], [37, 39]], "missing_branches": []}, "get_settings": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 12, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 12, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 4, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [75, 77, 78, 79, 80, 81, 84, 87, 89, 90, 91, 92], "excluded_lines": [], "start_line": 70, "executed_branches": [], "missing_branches": [[78, 79], [78, 84], [79, 78], [79, 80]]}, "get_setting": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [101, 103, 106, 108, 109, 110, 111], "excluded_lines": [], "start_line": 96, "executed_branches": [], "missing_branches": []}, "update_setting": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 16, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 16, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [128, 130, 131, 132, 133, 136, 137, 138, 143, 144, 146, 153, 154, 155, 156, 157], "excluded_lines": [], "start_line": 117, "executed_branches": [], "missing_branches": [[130, 131], [130, 136], [132, 133], [132, 136], [137, 138], [137, 143]]}, "delete_setting": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 10, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [168, 169, 170, 171, 173, 177, 178, 179, 180, 181], "excluded_lines": [], "start_line": 163, "executed_branches": [], "missing_branches": [[170, 171], [170, 173]]}, "bulk_update_settings": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 18, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [192, 193, 195, 196, 198, 199, 200, 201, 202, 205, 206, 207, 209, 210, 211, 212, 214, 216], "excluded_lines": [], "start_line": 187, "executed_branches": [], "missing_branches": [[195, 196], [195, 214], [198, 199], [198, 205], [200, 201], [200, 205], [206, 207], [206, 209]]}, "": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 24, 25, 28, 42, 43, 46, 49, 50, 53, 56, 57, 58, 61, 64, 65, 66, 69, 70, 95, 96, 116, 117, 162, 163, 186, 187], "summary": {"covered_lines": 34, "num_statements": 34, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"SettingUpdate": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 46, "executed_branches": [], "missing_branches": []}, "SettingResponse": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 53, "executed_branches": [], "missing_branches": []}, "SettingsListResponse": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 61, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 24, 25, 28, 36, 37, 38, 39, 42, 43, 46, 49, 50, 53, 56, 57, 58, 61, 64, 65, 66, 69, 70, 95, 96, 116, 117, 162, 163, 186, 187], "summary": {"covered_lines": 38, "num_statements": 101, "percent_covered": 32.520325203252035, "percent_covered_display": "32.52", "missing_lines": 63, "excluded_lines": 0, "percent_statements_covered": 37.62376237623762, "percent_statements_covered_display": "37.62", "num_branches": 22, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 20, "percent_branches_covered": 9.090909090909092, "percent_branches_covered_display": "9.09"}, "missing_lines": [75, 77, 78, 79, 80, 81, 84, 87, 89, 90, 91, 92, 101, 103, 106, 108, 109, 110, 111, 128, 130, 131, 132, 133, 136, 137, 138, 143, 144, 146, 153, 154, 155, 156, 157, 168, 169, 170, 171, 173, 177, 178, 179, 180, 181, 192, 193, 195, 196, 198, 199, 200, 201, 202, 205, 206, 207, 209, 210, 211, 212, 214, 216], "excluded_lines": [], "start_line": 1, "executed_branches": [[37, 38], [37, 39]], "missing_branches": [[78, 79], [78, 84], [79, 78], [79, 80], [130, 131], [130, 136], [132, 133], [132, 136], [137, 138], [137, 143], [170, 171], [170, 173], [195, 196], [195, 214], [198, 199], [198, 205], [200, 201], [200, 205], [206, 207], [206, 209]]}}}, "app/api/url_upload.py": {"executed_lines": [5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 17, 18, 19, 20, 23, 25, 28, 31, 32, 34, 35, 37, 38, 40, 43, 48, 50, 51, 52, 54, 55, 58, 59, 60, 61, 63, 64, 66, 70, 71, 74, 81, 84, 88, 92, 93, 99, 104, 108, 120, 134, 146, 148, 149, 150, 153, 154, 155, 156, 159, 162, 163, 164, 184, 187, 190, 191, 194, 195, 196, 199, 200, 206, 207, 208, 211, 220, 223, 224, 225, 232, 233, 234, 235, 236, 237, 243, 244, 245, 246, 250, 253, 254, 256, 257, 258, 259, 260, 263, 265, 266, 267, 272, 275, 277, 285, 286, 287, 289, 290, 291, 293, 294, 295, 297, 301, 303], "summary": {"covered_lines": 117, "num_statements": 137, "percent_covered": 80.11049723756906, "percent_covered_display": "80.11", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 85.4014598540146, "percent_statements_covered_display": "85.40", "num_branches": 44, "num_partial_branches": 12, "covered_branches": 28, "missing_branches": 16, "percent_branches_covered": 63.63636363636363, "percent_branches_covered_display": "63.64"}, "missing_lines": [39, 65, 85, 89, 105, 157, 201, 248, 298, 299, 305, 306, 308, 309, 310, 312, 313, 315, 316, 317], "excluded_lines": [], "executed_branches": [[38, 40], [59, 60], [63, 64], [84, 88], [88, 92], [92, 93], [92, 99], [104, -74], [146, 148], [149, 150], [149, 153], [154, 155], [156, 159], [190, 191], [190, 194], [200, 206], [224, 225], [224, 232], [233, 234], [233, 243], [236, 237], [236, 243], [244, 245], [257, 258], [257, 272], [258, 259], [263, 257], [263, 265]], "missing_branches": [[38, 39], [59, 65], [63, 59], [84, 85], [88, 89], [104, 105], [146, 153], [154, 159], [156, 157], [200, 201], [244, 248], [258, 257], [308, 309], [308, 310], [315, 316], [315, 317]], "functions": {"URLUploadRequest.validate_url_scheme": {"executed_lines": [37, 38, 40], "summary": {"covered_lines": 3, "num_statements": 4, "percent_covered": 66.66666666666667, "percent_covered_display": "66.67", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [39], "excluded_lines": [], "start_line": 35, "executed_branches": [[38, 40]], "missing_branches": [[38, 39]]}, "is_private_ip": {"executed_lines": [48, 50, 51, 52, 54, 55, 58, 59, 60, 61, 63, 64, 66, 70, 71], "summary": {"covered_lines": 15, "num_statements": 16, "percent_covered": 85.0, "percent_covered_display": "85.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 93.75, "percent_statements_covered_display": "93.75", "num_branches": 4, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 2, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [65], "excluded_lines": [], "start_line": 43, "executed_branches": [[59, 60], [63, 64]], "missing_branches": [[59, 65], [63, 59]]}, "validate_url_safety": {"executed_lines": [81, 84, 88, 92, 93, 99, 104], "summary": {"covered_lines": 7, "num_statements": 10, "percent_covered": 66.66666666666667, "percent_covered_display": "66.67", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 70.0, "percent_statements_covered_display": "70.00", "num_branches": 8, "num_partial_branches": 3, "covered_branches": 5, "missing_branches": 3, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62.50"}, "missing_lines": [85, 89, 105], "excluded_lines": [], "start_line": 74, "executed_branches": [[84, 88], [88, 92], [92, 93], [92, 99], [104, -74]], "missing_branches": [[84, 85], [88, 89], [104, 105]]}, "validate_file_type": {"executed_lines": [120, 134, 146, 148, 149, 150, 153, 154, 155, 156, 159], "summary": {"covered_lines": 11, "num_statements": 12, "percent_covered": 80.0, "percent_covered_display": "80.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 91.66666666666667, "percent_statements_covered_display": "91.67", "num_branches": 8, "num_partial_branches": 3, "covered_branches": 5, "missing_branches": 3, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62.50"}, "missing_lines": [157], "excluded_lines": [], "start_line": 108, "executed_branches": [[146, 148], [149, 150], [149, 153], [154, 155], [156, 159]], "missing_branches": [[146, 153], [154, 159], [156, 157]]}, "process_url": {"executed_lines": [184, 187, 190, 191, 194, 195, 196, 199, 200, 206, 207, 208, 211, 220, 223, 224, 225, 232, 233, 234, 235, 236, 237, 243, 244, 245, 246, 250, 253, 254, 256, 257, 258, 259, 260, 263, 265, 266, 267, 272, 275, 277, 285, 286, 287, 289, 290, 291, 293, 294, 295, 297, 301, 303], "summary": {"covered_lines": 54, "num_statements": 68, "percent_covered": 76.66666666666667, "percent_covered_display": "76.67", "missing_lines": 14, "excluded_lines": 0, "percent_statements_covered": 79.41176470588235, "percent_statements_covered_display": "79.41", "num_branches": 22, "num_partial_branches": 3, "covered_branches": 15, "missing_branches": 7, "percent_branches_covered": 68.18181818181819, "percent_branches_covered_display": "68.18"}, "missing_lines": [201, 248, 298, 299, 305, 306, 308, 309, 310, 312, 313, 315, 316, 317], "excluded_lines": [], "start_line": 164, "executed_branches": [[190, 191], [190, 194], [200, 206], [224, 225], [224, 232], [233, 234], [233, 243], [236, 237], [236, 243], [244, 245], [257, 258], [257, 272], [258, 259], [263, 257], [263, 265]], "missing_branches": [[200, 201], [244, 248], [258, 257], [308, 309], [308, 310], [315, 316], [315, 317]]}, "": {"executed_lines": [5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 17, 18, 19, 20, 23, 25, 28, 31, 32, 34, 35, 43, 74, 108, 162, 163, 164], "summary": {"covered_lines": 27, "num_statements": 27, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"URLUploadRequest": {"executed_lines": [37, 38, 40], "summary": {"covered_lines": 3, "num_statements": 4, "percent_covered": 66.66666666666667, "percent_covered_display": "66.67", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [39], "excluded_lines": [], "start_line": 28, "executed_branches": [[38, 40]], "missing_branches": [[38, 39]]}, "": {"executed_lines": [5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 17, 18, 19, 20, 23, 25, 28, 31, 32, 34, 35, 43, 48, 50, 51, 52, 54, 55, 58, 59, 60, 61, 63, 64, 66, 70, 71, 74, 81, 84, 88, 92, 93, 99, 104, 108, 120, 134, 146, 148, 149, 150, 153, 154, 155, 156, 159, 162, 163, 164, 184, 187, 190, 191, 194, 195, 196, 199, 200, 206, 207, 208, 211, 220, 223, 224, 225, 232, 233, 234, 235, 236, 237, 243, 244, 245, 246, 250, 253, 254, 256, 257, 258, 259, 260, 263, 265, 266, 267, 272, 275, 277, 285, 286, 287, 289, 290, 291, 293, 294, 295, 297, 301, 303], "summary": {"covered_lines": 114, "num_statements": 133, "percent_covered": 80.57142857142857, "percent_covered_display": "80.57", "missing_lines": 19, "excluded_lines": 0, "percent_statements_covered": 85.71428571428571, "percent_statements_covered_display": "85.71", "num_branches": 42, "num_partial_branches": 11, "covered_branches": 27, "missing_branches": 15, "percent_branches_covered": 64.28571428571429, "percent_branches_covered_display": "64.29"}, "missing_lines": [65, 85, 89, 105, 157, 201, 248, 298, 299, 305, 306, 308, 309, 310, 312, 313, 315, 316, 317], "excluded_lines": [], "start_line": 1, "executed_branches": [[59, 60], [63, 64], [84, 88], [88, 92], [92, 93], [92, 99], [104, -74], [146, 148], [149, 150], [149, 153], [154, 155], [156, 159], [190, 191], [190, 194], [200, 206], [224, 225], [224, 232], [233, 234], [233, 243], [236, 237], [236, 243], [244, 245], [257, 258], [257, 272], [258, 259], [263, 257], [263, 265]], "missing_branches": [[59, 65], [63, 59], [84, 85], [88, 89], [104, 105], [146, 153], [154, 159], [156, 157], [200, 201], [244, 248], [258, 257], [308, 309], [308, 310], [315, 316], [315, 317]]}}}, "app/api/user.py": {"executed_lines": [5, 6, 8, 11, 13, 16, 20, 21, 22, 24, 25, 26, 30, 31, 34, 35, 37, 41, 42, 43, 46, 47], "summary": {"covered_lines": 22, "num_statements": 23, "percent_covered": 96.29629629629629, "percent_covered_display": "96.30", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 95.65217391304348, "percent_statements_covered_display": "95.65", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [48], "excluded_lines": [], "executed_branches": [[21, 22], [21, 24], [25, 26], [25, 30]], "missing_branches": [], "functions": {"whoami_handler": {"executed_lines": [20, 21, 22, 24, 25, 26, 30, 31, 34, 35, 37], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 16, "executed_branches": [[21, 22], [21, 24], [25, 26], [25, 30]], "missing_branches": []}, "whoami": {"executed_lines": [43], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 42, "executed_branches": [], "missing_branches": []}, "auth_whoami": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [48], "excluded_lines": [], "start_line": 47, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [5, 6, 8, 11, 13, 16, 41, 42, 46, 47], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 8, 11, 13, 16, 20, 21, 22, 24, 25, 26, 30, 31, 34, 35, 37, 41, 42, 43, 46, 47], "summary": {"covered_lines": 22, "num_statements": 23, "percent_covered": 96.29629629629629, "percent_covered_display": "96.30", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 95.65217391304348, "percent_statements_covered_display": "95.65", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [48], "excluded_lines": [], "start_line": 1, "executed_branches": [[21, 22], [21, 24], [25, 26], [25, 30]], "missing_branches": []}}}, "app/auth.py": {"executed_lines": [1, 2, 3, 4, 6, 7, 8, 9, 11, 13, 15, 18, 19, 22, 23, 25, 36, 39, 40, 43, 44, 45, 47, 48, 49, 50, 51, 53, 54, 56, 58, 61, 63, 65, 66, 69, 170, 171, 172, 174, 175, 178, 179, 180, 182, 183], "summary": {"covered_lines": 46, "num_statements": 95, "percent_covered": 46.95652173913044, "percent_covered_display": "46.96", "missing_lines": 49, "excluded_lines": 0, "percent_statements_covered": 48.421052631578945, "percent_statements_covered_display": "48.42", "num_branches": 20, "num_partial_branches": 2, "covered_branches": 8, "missing_branches": 12, "percent_branches_covered": 40.0, "percent_branches_covered_display": "40.00"}, "missing_lines": [26, 33, 34, 71, 72, 74, 86, 87, 89, 90, 92, 93, 95, 96, 98, 99, 100, 101, 102, 107, 110, 111, 116, 117, 119, 120, 121, 124, 126, 129, 132, 133, 134, 135, 136, 140, 141, 143, 144, 145, 147, 149, 158, 159, 161, 163, 164, 166, 167], "excluded_lines": [], "executed_branches": [[25, 36], [44, 45], [44, 47], [49, 50], [49, 53], [53, 54], [53, 56], [69, 170]], "missing_branches": [[25, 26], [69, 71], [89, 90], [89, 92], [101, 102], [101, 107], [110, 111], [110, 116], [117, 119], [117, 124], [147, 149], [147, 161]], "functions": {"get_current_user": {"executed_lines": [40], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 39, "executed_branches": [], "missing_branches": []}, "require_login": {"executed_lines": [44, 45, 47, 48, 58], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 43, "executed_branches": [[44, 45], [44, 47]], "missing_branches": []}, "require_login.wrapper": {"executed_lines": [49, 50, 51, 53, 54, 56], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 48, "executed_branches": [[49, 50], [49, 53], [53, 54], [53, 56]], "missing_branches": []}, "get_gravatar_url": {"executed_lines": [63, 65, 66], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 61, "executed_branches": [], "missing_branches": []}, "login": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [74], "excluded_lines": [], "start_line": 72, "executed_branches": [], "missing_branches": []}, "oauth_login": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [89, 90, 92, 93], "excluded_lines": [], "start_line": 87, "executed_branches": [], "missing_branches": [[89, 90], [89, 92]]}, "oauth_callback": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 21, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 21, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [98, 99, 100, 101, 102, 107, 110, 111, 116, 117, 119, 120, 121, 124, 126, 129, 132, 133, 134, 135, 136], "excluded_lines": [], "start_line": 96, "executed_branches": [], "missing_branches": [[101, 102], [101, 107], [110, 111], [110, 116], [117, 119], [117, 124]]}, "auth": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 8, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [143, 144, 145, 147, 149, 158, 159, 161], "excluded_lines": [], "start_line": 141, "executed_branches": [], "missing_branches": [[147, 149], [147, 161]]}, "logout": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [166, 167], "excluded_lines": [], "start_line": 164, "executed_branches": [], "missing_branches": []}, "whoami": {"executed_lines": [174, 175], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 172, "executed_branches": [], "missing_branches": []}, "private_page": {"executed_lines": [182, 183], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 180, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [1, 2, 3, 4, 6, 7, 8, 9, 11, 13, 15, 18, 19, 22, 23, 25, 36, 39, 43, 61, 69, 170, 171, 172, 178, 179, 180], "summary": {"covered_lines": 27, "num_statements": 40, "percent_covered": 65.9090909090909, "percent_covered_display": "65.91", "missing_lines": 13, "excluded_lines": 0, "percent_statements_covered": 67.5, "percent_statements_covered_display": "67.50", "num_branches": 4, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 2, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [26, 33, 34, 71, 72, 86, 87, 95, 96, 140, 141, 163, 164], "excluded_lines": [], "start_line": 1, "executed_branches": [[25, 36], [69, 170]], "missing_branches": [[25, 26], [69, 71]]}}, "classes": {"": {"executed_lines": [1, 2, 3, 4, 6, 7, 8, 9, 11, 13, 15, 18, 19, 22, 23, 25, 36, 39, 40, 43, 44, 45, 47, 48, 49, 50, 51, 53, 54, 56, 58, 61, 63, 65, 66, 69, 170, 171, 172, 174, 175, 178, 179, 180, 182, 183], "summary": {"covered_lines": 46, "num_statements": 95, "percent_covered": 46.95652173913044, "percent_covered_display": "46.96", "missing_lines": 49, "excluded_lines": 0, "percent_statements_covered": 48.421052631578945, "percent_statements_covered_display": "48.42", "num_branches": 20, "num_partial_branches": 2, "covered_branches": 8, "missing_branches": 12, "percent_branches_covered": 40.0, "percent_branches_covered_display": "40.00"}, "missing_lines": [26, 33, 34, 71, 72, 74, 86, 87, 89, 90, 92, 93, 95, 96, 98, 99, 100, 101, 102, 107, 110, 111, 116, 117, 119, 120, 121, 124, 126, 129, 132, 133, 134, 135, 136, 140, 141, 143, 144, 145, 147, 149, 158, 159, 161, 163, 164, 166, 167], "excluded_lines": [], "start_line": 1, "executed_branches": [[25, 36], [44, 45], [44, 47], [49, 50], [49, 53], [53, 54], [53, 56], [69, 170]], "missing_branches": [[25, 26], [69, 71], [89, 90], [89, 92], [101, 102], [101, 107], [110, 111], [110, 116], [117, 119], [117, 124], [147, 149], [147, 161]]}}}, "app/celery_app.py": {"executed_lines": [3, 4, 6, 8, 16, 19, 20, 25, 26, 30, 31, 33, 35], "summary": {"covered_lines": 13, "num_statements": 16, "percent_covered": 77.77777777777777, "percent_covered_display": "77.78", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 81.25, "percent_statements_covered_display": "81.25", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [42, 43, 45], "excluded_lines": [], "executed_branches": [[30, 31]], "missing_branches": [[30, -25]], "functions": {"task_failure_handler": {"executed_lines": [30, 31, 33, 35], "summary": {"covered_lines": 4, "num_statements": 7, "percent_covered": 55.55555555555556, "percent_covered_display": "55.56", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 57.142857142857146, "percent_statements_covered_display": "57.14", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [42, 43, 45], "excluded_lines": [], "start_line": 26, "executed_branches": [[30, 31]], "missing_branches": [[30, -25]]}, "": {"executed_lines": [3, 4, 6, 8, 16, 19, 20, 25, 26], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 6, 8, 16, 19, 20, 25, 26, 30, 31, 33, 35], "summary": {"covered_lines": 13, "num_statements": 16, "percent_covered": 77.77777777777777, "percent_covered_display": "77.78", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 81.25, "percent_statements_covered_display": "81.25", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [42, 43, 45], "excluded_lines": [], "start_line": 1, "executed_branches": [[30, 31]], "missing_branches": [[30, -25]]}}}, "app/celery_worker.py": {"executed_lines": [3, 6, 9, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 38, 43, 44, 49], "summary": {"covered_lines": 30, "num_statements": 33, "percent_covered": 90.9090909090909, "percent_covered_display": "90.91", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 90.9090909090909, "percent_statements_covered_display": "90.91", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [45, 51, 92], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"test_task": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [45], "excluded_lines": [], "start_line": 44, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [3, 6, 9, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 38, 43, 44, 49], "summary": {"covered_lines": 30, "num_statements": 32, "percent_covered": 93.75, "percent_covered_display": "93.75", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 93.75, "percent_statements_covered_display": "93.75", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [51, 92], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 6, 9, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 38, 43, 44, 49], "summary": {"covered_lines": 30, "num_statements": 33, "percent_covered": 90.9090909090909, "percent_covered_display": "90.91", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 90.9090909090909, "percent_statements_covered_display": "90.91", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [45, 51, 92], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/config.py": {"executed_lines": [3, 4, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 22, 23, 26, 27, 28, 29, 32, 33, 34, 38, 40, 41, 42, 43, 44, 47, 48, 49, 50, 51, 54, 55, 56, 57, 60, 61, 62, 63, 64, 65, 66, 69, 70, 71, 72, 73, 74, 75, 78, 79, 80, 83, 84, 85, 86, 89, 90, 91, 92, 93, 96, 97, 98, 99, 100, 101, 102, 105, 106, 107, 108, 109, 110, 111, 114, 117, 118, 119, 120, 121, 122, 123, 126, 127, 128, 129, 130, 133, 134, 135, 136, 137, 138, 139, 142, 143, 146, 149, 152, 155, 160, 163, 164, 167, 168, 169, 174, 178, 187, 194, 203, 214, 220, 223, 229, 230, 239, 240, 245, 251, 255, 259, 263, 268, 269, 271, 272, 273, 277, 279, 280, 282, 283, 284, 285, 286, 289, 290, 292, 293, 294, 297, 298, 299, 300, 306, 307, 309, 310, 311, 314, 315, 316, 317, 320, 322, 323, 326, 327, 328, 331, 332, 333, 334, 337, 339, 340, 342, 343, 344, 345, 350, 351, 355, 356, 374], "summary": {"covered_lines": 180, "num_statements": 195, "percent_covered": 86.8995633187773, "percent_covered_display": "86.90", "missing_lines": 15, "excluded_lines": 0, "percent_statements_covered": 92.3076923076923, "percent_statements_covered_display": "92.31", "num_branches": 34, "num_partial_branches": 3, "covered_branches": 19, "missing_branches": 15, "percent_branches_covered": 55.88235294117647, "percent_branches_covered_display": "55.88"}, "missing_lines": [274, 275, 276, 303, 348, 358, 359, 362, 363, 366, 367, 368, 369, 370, 371], "excluded_lines": [], "executed_branches": [[271, 272], [271, 277], [272, 273], [282, 283], [282, 284], [284, 285], [284, 286], [293, 294], [293, 297], [298, 299], [310, 311], [310, 314], [315, 316], [315, 320], [327, 328], [327, 331], [332, 333], [332, 337], [343, 344]], "missing_branches": [[272, 274], [274, 275], [274, 276], [298, 303], [343, 348], [358, 359], [358, 366], [359, 362], [359, 363], [366, 367], [366, 371], [367, 368], [367, 369], [369, 370], [369, 371]], "functions": {"Settings.parse_notification_urls": {"executed_lines": [271, 272, 273, 277], "summary": {"covered_lines": 4, "num_statements": 7, "percent_covered": 53.84615384615385, "percent_covered_display": "53.85", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 57.142857142857146, "percent_statements_covered_display": "57.14", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 3, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [274, 275, 276], "excluded_lines": [], "start_line": 269, "executed_branches": [[271, 272], [271, 277], [272, 273]], "missing_branches": [[272, 274], [274, 275], [274, 276]]}, "Settings.validate_session_secret": {"executed_lines": [282, 283, 284, 285, 286], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 280, "executed_branches": [[282, 283], [282, 284], [284, 285], [284, 286]], "missing_branches": []}, "Settings.build_date": {"executed_lines": [292, 293, 294, 297, 298, 299, 300], "summary": {"covered_lines": 7, "num_statements": 8, "percent_covered": 83.33333333333333, "percent_covered_display": "83.33", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 87.5, "percent_statements_covered_display": "87.50", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [303], "excluded_lines": [], "start_line": 290, "executed_branches": [[293, 294], [293, 297], [298, 299]], "missing_branches": [[298, 303]]}, "Settings.version": {"executed_lines": [309, 310, 311, 314, 315, 316, 317, 320], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 307, "executed_branches": [[310, 311], [310, 314], [315, 316], [315, 320]], "missing_branches": []}, "Settings.git_sha": {"executed_lines": [326, 327, 328, 331, 332, 333, 334, 337], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 323, "executed_branches": [[327, 328], [327, 331], [332, 333], [332, 337]], "missing_branches": []}, "Settings.runtime_info": {"executed_lines": [342, 343, 344, 345], "summary": {"covered_lines": 4, "num_statements": 5, "percent_covered": 71.42857142857143, "percent_covered_display": "71.43", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [348], "excluded_lines": [], "start_line": 340, "executed_branches": [[343, 344]], "missing_branches": [[343, 348]]}, "Settings.Config.parse_env_var": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 10, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 10, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [358, 359, 362, 363, 366, 367, 368, 369, 370, 371], "excluded_lines": [], "start_line": 356, "executed_branches": [], "missing_branches": [[358, 359], [358, 366], [359, 362], [359, 363], [366, 367], [366, 371], [367, 368], [367, 369], [369, 370], [369, 371]]}, "": {"executed_lines": [3, 4, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 22, 23, 26, 27, 28, 29, 32, 33, 34, 38, 40, 41, 42, 43, 44, 47, 48, 49, 50, 51, 54, 55, 56, 57, 60, 61, 62, 63, 64, 65, 66, 69, 70, 71, 72, 73, 74, 75, 78, 79, 80, 83, 84, 85, 86, 89, 90, 91, 92, 93, 96, 97, 98, 99, 100, 101, 102, 105, 106, 107, 108, 109, 110, 111, 114, 117, 118, 119, 120, 121, 122, 123, 126, 127, 128, 129, 130, 133, 134, 135, 136, 137, 138, 139, 142, 143, 146, 149, 152, 155, 160, 163, 164, 167, 168, 169, 174, 178, 187, 194, 203, 214, 220, 223, 229, 230, 239, 240, 245, 251, 255, 259, 263, 268, 269, 279, 280, 289, 290, 306, 307, 322, 323, 339, 340, 350, 351, 355, 356, 374], "summary": {"covered_lines": 144, "num_statements": 144, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"Settings": {"executed_lines": [271, 272, 273, 277, 282, 283, 284, 285, 286, 292, 293, 294, 297, 298, 299, 300, 309, 310, 311, 314, 315, 316, 317, 320, 326, 327, 328, 331, 332, 333, 334, 337, 342, 343, 344, 345], "summary": {"covered_lines": 36, "num_statements": 41, "percent_covered": 84.61538461538461, "percent_covered_display": "84.62", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 87.8048780487805, "percent_statements_covered_display": "87.80", "num_branches": 24, "num_partial_branches": 3, "covered_branches": 19, "missing_branches": 5, "percent_branches_covered": 79.16666666666667, "percent_branches_covered_display": "79.17"}, "missing_lines": [274, 275, 276, 303, 348], "excluded_lines": [], "start_line": 10, "executed_branches": [[271, 272], [271, 277], [272, 273], [282, 283], [282, 284], [284, 285], [284, 286], [293, 294], [293, 297], [298, 299], [310, 311], [310, 314], [315, 316], [315, 320], [327, 328], [327, 331], [332, 333], [332, 337], [343, 344]], "missing_branches": [[272, 274], [274, 275], [274, 276], [298, 303], [343, 348]]}, "Settings.Config": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 10, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 10, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [358, 359, 362, 363, 366, 367, 368, 369, 370, 371], "excluded_lines": [], "start_line": 350, "executed_branches": [], "missing_branches": [[358, 359], [358, 366], [359, 362], [359, 363], [366, 367], [366, 371], [367, 368], [367, 369], [369, 370], [369, 371]]}, "": {"executed_lines": [3, 4, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 22, 23, 26, 27, 28, 29, 32, 33, 34, 38, 40, 41, 42, 43, 44, 47, 48, 49, 50, 51, 54, 55, 56, 57, 60, 61, 62, 63, 64, 65, 66, 69, 70, 71, 72, 73, 74, 75, 78, 79, 80, 83, 84, 85, 86, 89, 90, 91, 92, 93, 96, 97, 98, 99, 100, 101, 102, 105, 106, 107, 108, 109, 110, 111, 114, 117, 118, 119, 120, 121, 122, 123, 126, 127, 128, 129, 130, 133, 134, 135, 136, 137, 138, 139, 142, 143, 146, 149, 152, 155, 160, 163, 164, 167, 168, 169, 174, 178, 187, 194, 203, 214, 220, 223, 229, 230, 239, 240, 245, 251, 255, 259, 263, 268, 269, 279, 280, 289, 290, 306, 307, 322, 323, 339, 340, 350, 351, 355, 356, 374], "summary": {"covered_lines": 144, "num_statements": 144, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/database.py": {"executed_lines": [3, 4, 6, 7, 8, 9, 11, 13, 15, 18, 19, 20, 23, 30, 31, 33, 35, 37, 38, 39, 40, 43, 44, 45, 48, 49, 50, 53, 59, 64, 66, 69, 70, 71, 72, 73, 74, 75, 78, 79, 80, 86, 93, 99, 106, 107, 108, 111, 121, 126, 127, 128, 130], "summary": {"covered_lines": 53, "num_statements": 79, "percent_covered": 65.71428571428571, "percent_covered_display": "65.71", "missing_lines": 26, "excluded_lines": 0, "percent_statements_covered": 67.0886075949367, "percent_statements_covered_display": "67.09", "num_branches": 26, "num_partial_branches": 8, "covered_branches": 16, "missing_branches": 10, "percent_branches_covered": 61.53846153846154, "percent_branches_covered_display": "61.54"}, "missing_lines": [54, 55, 56, 81, 82, 83, 84, 87, 88, 89, 90, 94, 95, 96, 97, 100, 101, 102, 103, 112, 113, 114, 115, 116, 117, 118], "excluded_lines": [], "executed_branches": [[31, 33], [31, 48], [35, 37], [35, 48], [38, 39], [43, 44], [69, 70], [71, 72], [71, 78], [78, -59], [78, 79], [80, 86], [86, 93], [93, 99], [99, 106], [111, -59]], "missing_branches": [[38, 43], [43, 48], [69, 78], [80, 81], [86, 87], [93, 94], [99, 100], [111, 112], [114, 115], [114, 116]], "functions": {"init_db": {"executed_lines": [30, 31, 33, 35, 37, 38, 39, 40, 43, 44, 45, 48, 49, 50, 53], "summary": {"covered_lines": 15, "num_statements": 18, "percent_covered": 80.76923076923077, "percent_covered_display": "80.77", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 83.33333333333333, "percent_statements_covered_display": "83.33", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 6, "missing_branches": 2, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [54, 55, 56], "excluded_lines": [], "start_line": 23, "executed_branches": [[31, 33], [31, 48], [35, 37], [35, 48], [38, 39], [43, 44]], "missing_branches": [[38, 43], [43, 48]]}, "_run_schema_migrations": {"executed_lines": [64, 66, 69, 70, 71, 72, 73, 74, 75, 78, 79, 80, 86, 93, 99, 106, 107, 108, 111], "summary": {"covered_lines": 19, "num_statements": 42, "percent_covered": 48.333333333333336, "percent_covered_display": "48.33", "missing_lines": 23, "excluded_lines": 0, "percent_statements_covered": 45.23809523809524, "percent_statements_covered_display": "45.24", "num_branches": 18, "num_partial_branches": 6, "covered_branches": 10, "missing_branches": 8, "percent_branches_covered": 55.55555555555556, "percent_branches_covered_display": "55.56"}, "missing_lines": [81, 82, 83, 84, 87, 88, 89, 90, 94, 95, 96, 97, 100, 101, 102, 103, 112, 113, 114, 115, 116, 117, 118], "excluded_lines": [], "start_line": 59, "executed_branches": [[69, 70], [71, 72], [71, 78], [78, -59], [78, 79], [80, 86], [86, 93], [93, 99], [99, 106], [111, -59]], "missing_branches": [[69, 78], [80, 81], [86, 87], [93, 94], [99, 100], [111, 112], [114, 115], [114, 116]]}, "get_db": {"executed_lines": [126, 127, 128, 130], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 121, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [3, 4, 6, 7, 8, 9, 11, 13, 15, 18, 19, 20, 23, 59, 121], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 6, 7, 8, 9, 11, 13, 15, 18, 19, 20, 23, 30, 31, 33, 35, 37, 38, 39, 40, 43, 44, 45, 48, 49, 50, 53, 59, 64, 66, 69, 70, 71, 72, 73, 74, 75, 78, 79, 80, 86, 93, 99, 106, 107, 108, 111, 121, 126, 127, 128, 130], "summary": {"covered_lines": 53, "num_statements": 79, "percent_covered": 65.71428571428571, "percent_covered_display": "65.71", "missing_lines": 26, "excluded_lines": 0, "percent_statements_covered": 67.0886075949367, "percent_statements_covered_display": "67.09", "num_branches": 26, "num_partial_branches": 8, "covered_branches": 16, "missing_branches": 10, "percent_branches_covered": 61.53846153846154, "percent_branches_covered_display": "61.54"}, "missing_lines": [54, 55, 56, 81, 82, 83, 84, 87, 88, 89, 90, 94, 95, 96, 97, 100, 101, 102, 103, 112, 113, 114, 115, 116, 117, 118], "excluded_lines": [], "start_line": 1, "executed_branches": [[31, 33], [31, 48], [35, 37], [35, 48], [38, 39], [43, 44], [69, 70], [71, 72], [71, 78], [78, -59], [78, 79], [80, 86], [86, 93], [93, 99], [99, 106], [111, -59]], "missing_branches": [[38, 43], [43, 48], [69, 78], [80, 81], [86, 87], [93, 94], [99, 100], [111, 112], [114, 115], [114, 116]]}}}, "app/frontend.py": {"executed_lines": [7], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [7], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [7], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/main.py": {"executed_lines": [2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 27, 30, 33, 36, 41, 46, 47, 53, 56, 57, 59, 60, 61, 62, 66, 69, 71, 74, 77, 80, 81, 85, 88, 91, 94, 97, 100, 103, 106, 107, 108, 116, 119, 122, 125, 128, 129, 130, 136, 137, 143, 144, 147, 150, 151, 162, 163, 169, 170, 181, 182, 187, 188, 189, 190], "summary": {"covered_lines": 76, "num_statements": 85, "percent_covered": 85.56701030927834, "percent_covered_display": "85.57", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 89.41176470588235, "percent_statements_covered_display": "89.41", "num_branches": 12, "num_partial_branches": 5, "covered_branches": 7, "missing_branches": 5, "percent_branches_covered": 58.333333333333336, "percent_branches_covered_display": "58.33"}, "missing_lines": [37, 63, 64, 83, 132, 155, 175, 176, 183], "excluded_lines": [], "executed_branches": [[36, 41], [80, 81], [129, 130], [143, 144], [143, 147], [150, 151], [169, 170]], "missing_branches": [[36, 37], [80, 83], [129, 132], [150, 155], [169, 175]], "functions": {"lifespan": {"executed_lines": [53, 56, 57, 59, 60, 61, 62, 66, 69, 71, 74, 77, 80, 81, 85, 88, 91, 94, 97, 100], "summary": {"covered_lines": 20, "num_statements": 23, "percent_covered": 84.0, "percent_covered_display": "84.00", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 86.95652173913044, "percent_statements_covered_display": "86.96", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [63, 64, 83], "excluded_lines": [], "start_line": 47, "executed_branches": [[80, 81]], "missing_branches": [[80, 83]]}, "http_exception_handler": {"executed_lines": [143, 144, 147, 150, 151], "summary": {"covered_lines": 5, "num_statements": 6, "percent_covered": 80.0, "percent_covered_display": "80.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 83.33333333333333, "percent_statements_covered_display": "83.33", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [155], "excluded_lines": [], "start_line": 137, "executed_branches": [[143, 144], [143, 147], [150, 151]], "missing_branches": [[150, 155]]}, "custom_500_handler": {"executed_lines": [169, 170], "summary": {"covered_lines": 2, "num_statements": 4, "percent_covered": 50.0, "percent_covered_display": "50.00", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 50.0, "percent_statements_covered_display": "50.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [175, 176], "excluded_lines": [], "start_line": 163, "executed_branches": [[169, 170]], "missing_branches": [[169, 175]]}, "test_500": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [183], "excluded_lines": [], "start_line": 182, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 27, 30, 33, 36, 41, 46, 47, 103, 106, 107, 108, 116, 119, 122, 125, 128, 129, 130, 136, 137, 162, 163, 181, 182, 187, 188, 189, 190], "summary": {"covered_lines": 49, "num_statements": 51, "percent_covered": 92.72727272727273, "percent_covered_display": "92.73", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 96.07843137254902, "percent_statements_covered_display": "96.08", "num_branches": 4, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 2, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [37, 132], "excluded_lines": [], "start_line": 1, "executed_branches": [[36, 41], [129, 130]], "missing_branches": [[36, 37], [129, 132]]}}, "classes": {"": {"executed_lines": [2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 27, 30, 33, 36, 41, 46, 47, 53, 56, 57, 59, 60, 61, 62, 66, 69, 71, 74, 77, 80, 81, 85, 88, 91, 94, 97, 100, 103, 106, 107, 108, 116, 119, 122, 125, 128, 129, 130, 136, 137, 143, 144, 147, 150, 151, 162, 163, 169, 170, 181, 182, 187, 188, 189, 190], "summary": {"covered_lines": 76, "num_statements": 85, "percent_covered": 85.56701030927834, "percent_covered_display": "85.57", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 89.41176470588235, "percent_statements_covered_display": "89.41", "num_branches": 12, "num_partial_branches": 5, "covered_branches": 7, "missing_branches": 5, "percent_branches_covered": 58.333333333333336, "percent_branches_covered_display": "58.33"}, "missing_lines": [37, 63, 64, 83, 132, 155, 175, 176, 183], "excluded_lines": [], "start_line": 1, "executed_branches": [[36, 41], [80, 81], [129, 130], [143, 144], [143, 147], [150, 151], [169, 170]], "missing_branches": [[36, 37], [80, 83], [129, 132], [150, 155], [169, 175]]}}}, "app/middleware/__init__.py": {"executed_lines": [3, 5], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [3, 5], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 5], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/middleware/rate_limit.py": {"executed_lines": [19, 20, 22, 23, 24, 26, 29, 44, 45, 47, 48, 49, 50, 51, 54, 55, 56, 59, 70, 71, 73, 80, 82, 83, 85, 92, 100, 101, 104, 114], "summary": {"covered_lines": 30, "num_statements": 30, "percent_covered": 95.0, "percent_covered_display": "95.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 10, "num_partial_branches": 2, "covered_branches": 8, "missing_branches": 2, "percent_branches_covered": 80.0, "percent_branches_covered_display": "80.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[44, 45], [44, 54], [47, 48], [49, 50], [70, 71], [70, 80], [82, 83], [82, 85]], "missing_branches": [[47, 54], [49, 54]], "functions": {"get_identifier": {"executed_lines": [44, 45, 47, 48, 49, 50, 51, 54, 55, 56], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 87.5, "percent_covered_display": "87.50", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 6, "num_partial_branches": 2, "covered_branches": 4, "missing_branches": 2, "percent_branches_covered": 66.66666666666667, "percent_branches_covered_display": "66.67"}, "missing_lines": [], "excluded_lines": [], "start_line": 29, "executed_branches": [[44, 45], [44, 54], [47, 48], [49, 50]], "missing_branches": [[47, 54], [49, 54]]}, "create_limiter": {"executed_lines": [70, 71, 73, 80, 82, 83, 85, 92, 100, 101], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 59, "executed_branches": [[70, 71], [70, 80], [82, 83], [82, 85]], "missing_branches": []}, "get_rate_limit_exceeded_handler": {"executed_lines": [114], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 104, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [19, 20, 22, 23, 24, 26, 29, 59, 104], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [19, 20, 22, 23, 24, 26, 29, 44, 45, 47, 48, 49, 50, 51, 54, 55, 56, 59, 70, 71, 73, 80, 82, 83, 85, 92, 100, 101, 104, 114], "summary": {"covered_lines": 30, "num_statements": 30, "percent_covered": 95.0, "percent_covered_display": "95.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 10, "num_partial_branches": 2, "covered_branches": 8, "missing_branches": 2, "percent_branches_covered": 80.0, "percent_branches_covered_display": "80.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[44, 45], [44, 54], [47, 48], [49, 50], [70, 71], [70, 80], [82, 83], [82, 85]], "missing_branches": [[47, 54], [49, 54]]}}}, "app/middleware/rate_limit_decorators.py": {"executed_lines": [11, 14, 17, 18, 20, 21, 24, 41, 42, 44, 46, 49, 63, 64, 66, 68], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[17, 18], [17, 21]], "missing_branches": [], "functions": {"get_limiter": {"executed_lines": [17, 18, 20, 21], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 14, "executed_branches": [[17, 18], [17, 21]], "missing_branches": []}, "limit": {"executed_lines": [41, 46], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 24, "executed_branches": [], "missing_branches": []}, "limit.decorator": {"executed_lines": [42, 44], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 41, "executed_branches": [], "missing_branches": []}, "exempt": {"executed_lines": [63, 68], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 49, "executed_branches": [], "missing_branches": []}, "exempt.decorator": {"executed_lines": [64, 66], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 63, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [11, 14, 24, 49], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [11, 14, 17, 18, 20, 21, 24, 41, 42, 44, 46, 49, 63, 64, 66, 68], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[17, 18], [17, 21]], "missing_branches": []}}}, "app/middleware/security_headers.py": {"executed_lines": [14, 15, 17, 18, 20, 23, 36, 44, 45, 46, 48, 57, 59, 71, 74, 77, 79], "summary": {"covered_lines": 17, "num_statements": 35, "percent_covered": 40.42553191489362, "percent_covered_display": "40.43", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 48.57142857142857, "percent_statements_covered_display": "48.57", "num_branches": 12, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 10, "percent_branches_covered": 16.666666666666668, "percent_branches_covered_display": "16.67"}, "missing_lines": [49, 50, 75, 91, 92, 93, 94, 99, 100, 101, 102, 107, 108, 109, 110, 115, 116, 117], "excluded_lines": [], "executed_branches": [[48, 57], [74, 77]], "missing_branches": [[48, 49], [74, 75], [91, 92], [91, 99], [99, 100], [99, 107], [107, 108], [107, 115], [115, -79], [115, 116]], "functions": {"SecurityHeadersMiddleware.__init__": {"executed_lines": [44, 45, 46, 48, 57], "summary": {"covered_lines": 5, "num_statements": 7, "percent_covered": 66.66666666666667, "percent_covered_display": "66.67", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 71.42857142857143, "percent_statements_covered_display": "71.43", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [49, 50], "excluded_lines": [], "start_line": 36, "executed_branches": [[48, 57]], "missing_branches": [[48, 49]]}, "SecurityHeadersMiddleware.dispatch": {"executed_lines": [71, 74, 77], "summary": {"covered_lines": 3, "num_statements": 4, "percent_covered": 66.66666666666667, "percent_covered_display": "66.67", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [75], "excluded_lines": [], "start_line": 59, "executed_branches": [[74, 77]], "missing_branches": [[74, 75]]}, "SecurityHeadersMiddleware._add_security_headers": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 15, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 15, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [91, 92, 93, 94, 99, 100, 101, 102, 107, 108, 109, 110, 115, 116, 117], "excluded_lines": [], "start_line": 79, "executed_branches": [], "missing_branches": [[91, 92], [91, 99], [99, 100], [99, 107], [107, 108], [107, 115], [115, -79], [115, 116]]}, "": {"executed_lines": [14, 15, 17, 18, 20, 23, 36, 59, 79], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"SecurityHeadersMiddleware": {"executed_lines": [44, 45, 46, 48, 57, 71, 74, 77], "summary": {"covered_lines": 8, "num_statements": 26, "percent_covered": 26.31578947368421, "percent_covered_display": "26.32", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 30.76923076923077, "percent_statements_covered_display": "30.77", "num_branches": 12, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 10, "percent_branches_covered": 16.666666666666668, "percent_branches_covered_display": "16.67"}, "missing_lines": [49, 50, 75, 91, 92, 93, 94, 99, 100, 101, 102, 107, 108, 109, 110, 115, 116, 117], "excluded_lines": [], "start_line": 23, "executed_branches": [[48, 57], [74, 77]], "missing_branches": [[48, 49], [74, 75], [91, 92], [91, 99], [99, 100], [99, 107], [107, 108], [107, 115], [115, -79], [115, 116]]}, "": {"executed_lines": [14, 15, 17, 18, 20, 23, 36, 59, 79], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/models.py": {"executed_lines": [3, 5, 8, 9, 11, 12, 13, 14, 15, 16, 19, 20, 22, 26, 29, 32, 36, 40, 43, 46, 50, 53, 56, 59, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 92, 95, 97, 98, 99, 100, 101], "summary": {"covered_lines": 52, "num_statements": 52, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [3, 5, 8, 9, 11, 12, 13, 14, 15, 16, 19, 20, 22, 26, 29, 32, 36, 40, 43, 46, 50, 53, 56, 59, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 92, 95, 97, 98, 99, 100, 101], "summary": {"covered_lines": 52, "num_statements": 52, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"DocumentMetadata": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 8, "executed_branches": [], "missing_branches": []}, "FileRecord": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 19, "executed_branches": [], "missing_branches": []}, "FileProcessingStep": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 59, "executed_branches": [], "missing_branches": []}, "ProcessingLog": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 80, "executed_branches": [], "missing_branches": []}, "ApplicationSettings": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 92, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [3, 5, 8, 9, 11, 12, 13, 14, 15, 16, 19, 20, 22, 26, 29, 32, 36, 40, 43, 46, 50, 53, 56, 59, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 92, 95, 97, 98, 99, 100, 101], "summary": {"covered_lines": 52, "num_statements": 52, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/tasks/__init__.py": {"executed_lines": [2, 3], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [2, 3], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [2, 3], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/tasks/check_credentials.py": {"executed_lines": [1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 14, 15, 16, 19, 20, 24, 27, 28, 29, 30, 31, 32, 34, 35, 37, 38, 41, 44, 47, 49, 50, 51, 52, 57, 60, 62, 63, 64, 70, 72, 73, 74, 78, 81, 82, 83, 84, 85, 88, 90, 91, 92, 93, 94, 97, 99, 100, 101, 102, 103, 106, 108, 109, 110, 111, 112, 115, 117, 118, 119, 120, 121, 124, 125], "summary": {"covered_lines": 74, "num_statements": 134, "percent_covered": 54.32098765432099, "percent_covered_display": "54.32", "missing_lines": 60, "excluded_lines": 0, "percent_statements_covered": 55.223880597014926, "percent_statements_covered_display": "55.22", "num_branches": 28, "num_partial_branches": 0, "covered_branches": 14, "missing_branches": 14, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [53, 54, 65, 66, 127, 130, 133, 136, 137, 140, 174, 175, 177, 178, 179, 182, 183, 184, 185, 187, 188, 190, 192, 195, 196, 199, 201, 202, 205, 206, 210, 211, 212, 213, 214, 219, 225, 227, 230, 231, 234, 235, 237, 239, 240, 241, 242, 245, 246, 249, 250, 251, 252, 255, 258, 261, 264, 265, 268, 273], "excluded_lines": [], "executed_branches": [[50, 51], [50, 57], [72, 73], [72, 74], [83, 84], [83, 85], [92, 93], [92, 94], [101, 102], [101, 103], [110, 111], [110, 112], [119, 120], [119, 121]], "missing_branches": [[177, 178], [177, 261], [182, 183], [182, 190], [201, 202], [201, 227], [210, 211], [210, 219], [230, 231], [230, 235], [235, 177], [235, 237], [249, 250], [249, 255]], "functions": {"MockRequest.__init__": {"executed_lines": [28, 29, 30, 31, 32], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 27, "executed_branches": [], "missing_branches": []}, "MockRequest.json": {"executed_lines": [35], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 34, "executed_branches": [], "missing_branches": []}, "MockRequest.form": {"executed_lines": [38], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 37, "executed_branches": [], "missing_branches": []}, "get_failure_state": {"executed_lines": [49, 50, 51, 52, 57], "summary": {"covered_lines": 5, "num_statements": 7, "percent_covered": 77.77777777777777, "percent_covered_display": "77.78", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 71.42857142857143, "percent_statements_covered_display": "71.43", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [53, 54], "excluded_lines": [], "start_line": 47, "executed_branches": [[50, 51], [50, 57]], "missing_branches": []}, "save_failure_state": {"executed_lines": [62, 63, 64], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 60.0, "percent_covered_display": "60.00", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [65, 66], "excluded_lines": [], "start_line": 60, "executed_branches": [], "missing_branches": []}, "unwrap_decorated_function": {"executed_lines": [72, 73, 74], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 70, "executed_branches": [[72, 73], [72, 74]], "missing_branches": []}, "sync_test_openai_connection": {"executed_lines": [81, 82, 83, 84, 85], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 78, "executed_branches": [[83, 84], [83, 85]], "missing_branches": []}, "sync_test_azure_connection": {"executed_lines": [90, 91, 92, 93, 94], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 88, "executed_branches": [[92, 93], [92, 94]], "missing_branches": []}, "sync_test_dropbox_token": {"executed_lines": [99, 100, 101, 102, 103], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 97, "executed_branches": [[101, 102], [101, 103]], "missing_branches": []}, "sync_test_google_drive_token": {"executed_lines": [108, 109, 110, 111, 112], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 106, "executed_branches": [[110, 111], [110, 112]], "missing_branches": []}, "sync_test_onedrive_token": {"executed_lines": [117, 118, 119, 120, 121], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 115, "executed_branches": [[119, 120], [119, 121]], "missing_branches": []}, "check_credentials": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 56, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 56, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 14, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 14, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [127, 130, 133, 136, 137, 140, 174, 175, 177, 178, 179, 182, 183, 184, 185, 187, 188, 190, 192, 195, 196, 199, 201, 202, 205, 206, 210, 211, 212, 213, 214, 219, 225, 227, 230, 231, 234, 235, 237, 239, 240, 241, 242, 245, 246, 249, 250, 251, 252, 255, 258, 261, 264, 265, 268, 273], "excluded_lines": [], "start_line": 125, "executed_branches": [], "missing_branches": [[177, 178], [177, 261], [182, 183], [182, 190], [201, 202], [201, 227], [210, 211], [210, 219], [230, 231], [230, 235], [235, 177], [235, 237], [249, 250], [249, 255]]}, "": {"executed_lines": [1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 14, 15, 16, 19, 20, 24, 27, 34, 37, 41, 44, 47, 60, 70, 78, 88, 97, 106, 115, 124, 125], "summary": {"covered_lines": 31, "num_statements": 31, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"MockRequest": {"executed_lines": [28, 29, 30, 31, 32, 35, 38], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 24, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 14, 15, 16, 19, 20, 24, 27, 34, 37, 41, 44, 47, 49, 50, 51, 52, 57, 60, 62, 63, 64, 70, 72, 73, 74, 78, 81, 82, 83, 84, 85, 88, 90, 91, 92, 93, 94, 97, 99, 100, 101, 102, 103, 106, 108, 109, 110, 111, 112, 115, 117, 118, 119, 120, 121, 124, 125], "summary": {"covered_lines": 67, "num_statements": 127, "percent_covered": 52.25806451612903, "percent_covered_display": "52.26", "missing_lines": 60, "excluded_lines": 0, "percent_statements_covered": 52.75590551181102, "percent_statements_covered_display": "52.76", "num_branches": 28, "num_partial_branches": 0, "covered_branches": 14, "missing_branches": 14, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [53, 54, 65, 66, 127, 130, 133, 136, 137, 140, 174, 175, 177, 178, 179, 182, 183, 184, 185, 187, 188, 190, 192, 195, 196, 199, 201, 202, 205, 206, 210, 211, 212, 213, 214, 219, 225, 227, 230, 231, 234, 235, 237, 239, 240, 241, 242, 245, 246, 249, 250, 251, 252, 255, 258, 261, 264, 265, 268, 273], "excluded_lines": [], "start_line": 1, "executed_branches": [[50, 51], [50, 57], [72, 73], [72, 74], [83, 84], [83, 85], [92, 93], [92, 94], [101, 102], [101, 103], [110, 111], [110, 112], [119, 120], [119, 121]], "missing_branches": [[177, 178], [177, 261], [182, 183], [182, 190], [201, 202], [201, 227], [210, 211], [210, 219], [230, 231], [230, 235], [235, 177], [235, 237], [249, 250], [249, 255]]}}}, "app/tasks/convert_to_pdf.py": {"executed_lines": [2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 14, 16, 19, 29, 30, 31, 32, 33, 34, 36, 37, 38, 40, 43, 54, 55, 56, 58, 59, 60, 61, 63, 66, 78, 79, 80, 82, 83, 84, 85, 87, 88, 90, 91, 92, 93, 94, 95, 97, 98, 101, 104, 116, 117, 119, 120, 121, 123, 126, 127, 137, 138, 139, 141, 142, 143, 144, 145, 148, 149, 150, 151, 152, 163, 164, 165, 168, 169, 170, 173, 205, 207, 210, 217, 218, 221, 230, 231, 234, 237, 250, 252, 256, 257, 277, 278, 279, 281, 282, 287, 297, 298, 306, 311, 312, 313, 316, 318, 320, 321, 322, 324, 325, 326, 331, 333, 334, 335, 339, 341, 342, 347, 348, 349, 350, 351, 352, 353], "summary": {"covered_lines": 128, "num_statements": 136, "percent_covered": 90.55555555555556, "percent_covered_display": "90.56", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 94.11764705882354, "percent_statements_covered_display": "94.12", "num_branches": 44, "num_partial_branches": 9, "covered_branches": 35, "missing_branches": 9, "percent_branches_covered": 79.54545454545455, "percent_branches_covered_display": "79.55"}, "missing_lines": [99, 302, 303, 304, 307, 308, 309, 337], "excluded_lines": [], "executed_branches": [[31, 32], [37, 38], [37, 40], [55, 56], [55, 58], [58, 59], [58, 63], [60, 61], [79, 80], [79, 82], [82, 83], [82, 87], [84, 85], [87, 88], [87, 90], [92, 93], [98, 101], [116, 117], [116, 119], [120, 121], [120, 123], [142, 143], [142, 148], [151, 152], [151, 165], [210, 217], [210, 230], [230, 231], [230, 250], [250, 252], [297, 298], [306, 311], [318, 320], [318, 341], [331, 333]], "missing_branches": [[31, 36], [60, 63], [84, 87], [92, 97], [98, 99], [250, 302], [297, 306], [306, 307], [331, 337]], "functions": {"_detect_mime_type_from_magic": {"executed_lines": [29, 30, 31, 32, 33, 34, 36, 37, 38, 40], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 92.85714285714286, "percent_covered_display": "92.86", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 19, "executed_branches": [[31, 32], [37, 38], [37, 40]], "missing_branches": [[31, 36]]}, "_detect_mime_type": {"executed_lines": [54, 55, 56, 58, 59, 60, 61, 63], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 92.85714285714286, "percent_covered_display": "92.86", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [], "excluded_lines": [], "start_line": 43, "executed_branches": [[55, 56], [55, 58], [58, 59], [58, 63], [60, 61]], "missing_branches": [[60, 63]]}, "_detect_extension": {"executed_lines": [78, 79, 80, 82, 83, 84, 85, 87, 88, 90, 91, 92, 93, 94, 95, 97, 98, 101], "summary": {"covered_lines": 18, "num_statements": 19, "percent_covered": 87.09677419354838, "percent_covered_display": "87.10", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 94.73684210526316, "percent_statements_covered_display": "94.74", "num_branches": 12, "num_partial_branches": 3, "covered_branches": 9, "missing_branches": 3, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [99], "excluded_lines": [], "start_line": 66, "executed_branches": [[79, 80], [79, 82], [82, 83], [82, 87], [84, 85], [87, 88], [87, 90], [92, 93], [98, 101]], "missing_branches": [[84, 87], [92, 97], [98, 99]]}, "_build_filename": {"executed_lines": [116, 117, 119, 120, 121, 123], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 104, "executed_branches": [[116, 117], [116, 119], [120, 121], [120, 123]], "missing_branches": []}, "convert_to_pdf": {"executed_lines": [137, 138, 139, 141, 142, 143, 144, 145, 148, 149, 150, 151, 152, 163, 164, 165, 168, 169, 170, 173, 205, 207, 210, 217, 218, 221, 230, 231, 234, 237, 250, 252, 256, 257, 277, 278, 279, 281, 282, 287, 297, 298, 306, 311, 312, 313, 316, 318, 320, 321, 322, 324, 325, 326, 331, 333, 334, 335, 339, 341, 342, 347, 348, 349, 350, 351, 352, 353], "summary": {"covered_lines": 68, "num_statements": 75, "percent_covered": 88.17204301075269, "percent_covered_display": "88.17", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 90.66666666666667, "percent_statements_covered_display": "90.67", "num_branches": 18, "num_partial_branches": 4, "covered_branches": 14, "missing_branches": 4, "percent_branches_covered": 77.77777777777777, "percent_branches_covered_display": "77.78"}, "missing_lines": [302, 303, 304, 307, 308, 309, 337], "excluded_lines": [], "start_line": 127, "executed_branches": [[142, 143], [142, 148], [151, 152], [151, 165], [210, 217], [210, 230], [230, 231], [230, 250], [250, 252], [297, 298], [306, 311], [318, 320], [318, 341], [331, 333]], "missing_branches": [[250, 302], [297, 306], [306, 307], [331, 337]]}, "": {"executed_lines": [2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 14, 16, 19, 43, 66, 104, 126, 127], "summary": {"covered_lines": 18, "num_statements": 18, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 14, 16, 19, 29, 30, 31, 32, 33, 34, 36, 37, 38, 40, 43, 54, 55, 56, 58, 59, 60, 61, 63, 66, 78, 79, 80, 82, 83, 84, 85, 87, 88, 90, 91, 92, 93, 94, 95, 97, 98, 101, 104, 116, 117, 119, 120, 121, 123, 126, 127, 137, 138, 139, 141, 142, 143, 144, 145, 148, 149, 150, 151, 152, 163, 164, 165, 168, 169, 170, 173, 205, 207, 210, 217, 218, 221, 230, 231, 234, 237, 250, 252, 256, 257, 277, 278, 279, 281, 282, 287, 297, 298, 306, 311, 312, 313, 316, 318, 320, 321, 322, 324, 325, 326, 331, 333, 334, 335, 339, 341, 342, 347, 348, 349, 350, 351, 352, 353], "summary": {"covered_lines": 128, "num_statements": 136, "percent_covered": 90.55555555555556, "percent_covered_display": "90.56", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 94.11764705882354, "percent_statements_covered_display": "94.12", "num_branches": 44, "num_partial_branches": 9, "covered_branches": 35, "missing_branches": 9, "percent_branches_covered": 79.54545454545455, "percent_branches_covered_display": "79.55"}, "missing_lines": [99, 302, 303, 304, 307, 308, 309, 337], "excluded_lines": [], "start_line": 1, "executed_branches": [[31, 32], [37, 38], [37, 40], [55, 56], [55, 58], [58, 59], [58, 63], [60, 61], [79, 80], [79, 82], [82, 83], [82, 87], [84, 85], [87, 88], [87, 90], [92, 93], [98, 101], [116, 117], [116, 119], [120, 121], [120, 123], [142, 143], [142, 148], [151, 152], [151, 165], [210, 217], [210, 230], [230, 231], [230, 250], [250, 252], [297, 298], [306, 311], [318, 320], [318, 341], [331, 333]], "missing_branches": [[31, 36], [60, 63], [84, 87], [92, 97], [98, 99], [250, 302], [297, 306], [306, 307], [331, 337]]}}}, "app/tasks/embed_metadata_into_pdf.py": {"executed_lines": [3, 4, 5, 6, 7, 8, 10, 13, 14, 15, 16, 17, 18, 19, 20, 22, 29, 30, 33, 50, 51, 54, 55, 56, 57, 58, 60, 61, 62, 65, 66, 80, 81, 82, 91, 98, 119, 121, 122, 123, 124, 127, 129, 130, 131, 134, 135, 136, 139, 143, 153, 154, 156, 157, 161, 163, 165, 167, 168, 170, 172, 173, 181, 183, 185, 190, 191, 192, 193, 194, 195, 197, 198, 199, 203, 204, 205, 250, 251, 252, 264, 265, 266, 267, 270], "summary": {"covered_lines": 85, "num_statements": 117, "percent_covered": 68.79432624113475, "percent_covered_display": "68.79", "missing_lines": 32, "excluded_lines": 0, "percent_statements_covered": 72.64957264957265, "percent_statements_covered_display": "72.65", "num_branches": 24, "num_partial_branches": 6, "covered_branches": 12, "missing_branches": 12, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [92, 93, 94, 95, 99, 100, 101, 103, 104, 116, 140, 184, 208, 209, 214, 215, 229, 233, 234, 235, 236, 239, 240, 241, 242, 243, 244, 245, 246, 248, 268, 269], "excluded_lines": [], "executed_branches": [[55, 56], [55, 57], [57, 58], [57, 60], [91, 98], [98, 119], [139, 143], [183, 185], [192, 193], [194, 195], [264, 265], [264, 270]], "missing_branches": [[91, 92], [94, 95], [94, 98], [98, 99], [100, 101], [100, 103], [139, 140], [183, 184], [192, 203], [194, 203], [239, 240], [239, 248]], "functions": {"persist_metadata": {"executed_lines": [50, 51, 54, 55, 56, 57, 58, 60, 61, 62], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 33, "executed_branches": [[55, 56], [55, 57], [57, 58], [57, 60]], "missing_branches": []}, "embed_metadata_into_pdf": {"executed_lines": [80, 81, 82, 91, 98, 119, 121, 122, 123, 124, 127, 129, 130, 131, 134, 135, 136, 139, 143, 153, 154, 156, 157, 161, 163, 165, 167, 168, 170, 172, 173, 181, 183, 185, 190, 191, 192, 193, 194, 195, 197, 198, 199, 203, 204, 205, 250, 251, 252, 264, 265, 266, 267, 270], "summary": {"covered_lines": 54, "num_statements": 86, "percent_covered": 58.490566037735846, "percent_covered_display": "58.49", "missing_lines": 32, "excluded_lines": 0, "percent_statements_covered": 62.7906976744186, "percent_statements_covered_display": "62.79", "num_branches": 20, "num_partial_branches": 6, "covered_branches": 8, "missing_branches": 12, "percent_branches_covered": 40.0, "percent_branches_covered_display": "40.00"}, "missing_lines": [92, 93, 94, 95, 99, 100, 101, 103, 104, 116, 140, 184, 208, 209, 214, 215, 229, 233, 234, 235, 236, 239, 240, 241, 242, 243, 244, 245, 246, 248, 268, 269], "excluded_lines": [], "start_line": 66, "executed_branches": [[91, 98], [98, 119], [139, 143], [183, 185], [192, 193], [194, 195], [264, 265], [264, 270]], "missing_branches": [[91, 92], [94, 95], [94, 98], [98, 99], [100, 101], [100, 103], [139, 140], [183, 184], [192, 203], [194, 203], [239, 240], [239, 248]]}, "": {"executed_lines": [3, 4, 5, 6, 7, 8, 10, 13, 14, 15, 16, 17, 18, 19, 20, 22, 29, 30, 33, 65, 66], "summary": {"covered_lines": 21, "num_statements": 21, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 5, 6, 7, 8, 10, 13, 14, 15, 16, 17, 18, 19, 20, 22, 29, 30, 33, 50, 51, 54, 55, 56, 57, 58, 60, 61, 62, 65, 66, 80, 81, 82, 91, 98, 119, 121, 122, 123, 124, 127, 129, 130, 131, 134, 135, 136, 139, 143, 153, 154, 156, 157, 161, 163, 165, 167, 168, 170, 172, 173, 181, 183, 185, 190, 191, 192, 193, 194, 195, 197, 198, 199, 203, 204, 205, 250, 251, 252, 264, 265, 266, 267, 270], "summary": {"covered_lines": 85, "num_statements": 117, "percent_covered": 68.79432624113475, "percent_covered_display": "68.79", "missing_lines": 32, "excluded_lines": 0, "percent_statements_covered": 72.64957264957265, "percent_statements_covered_display": "72.65", "num_branches": 24, "num_partial_branches": 6, "covered_branches": 12, "missing_branches": 12, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [92, 93, 94, 95, 99, 100, 101, 103, 104, 116, 140, 184, 208, 209, 214, 215, 229, 233, 234, 235, 236, 239, 240, 241, 242, 243, 244, 245, 246, 248, 268, 269], "excluded_lines": [], "start_line": 1, "executed_branches": [[55, 56], [55, 57], [57, 58], [57, 60], [91, 98], [98, 119], [139, 143], [183, 185], [192, 193], [194, 195], [264, 265], [264, 270]], "missing_branches": [[91, 92], [94, 95], [94, 98], [98, 99], [100, 101], [100, 103], [139, 140], [183, 184], [192, 203], [194, 203], [239, 240], [239, 248]]}}}, "app/tasks/extract_metadata_with_gpt.py": {"executed_lines": [3, 4, 5, 6, 8, 11, 12, 13, 14, 15, 16, 17, 19, 22, 23, 24, 30, 36, 37, 38, 39, 41, 42, 43, 44, 45, 48, 49], "summary": {"covered_lines": 28, "num_statements": 71, "percent_covered": 36.7816091954023, "percent_covered_display": "36.78", "missing_lines": 43, "excluded_lines": 0, "percent_statements_covered": 39.436619718309856, "percent_statements_covered_display": "39.44", "num_branches": 16, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 12, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [25, 26, 27, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64, 65, 67, 100, 101, 102, 103, 112, 113, 114, 123, 124, 125, 126, 134, 136, 141, 142, 149, 150, 152, 154, 155, 166, 167, 170, 172, 174, 175, 176, 184], "excluded_lines": [], "executed_branches": [[38, 39], [38, 41], [43, 44], [43, 45]], "missing_branches": [[58, 59], [58, 67], [61, 62], [61, 67], [64, 65], [64, 67], [124, 125], [124, 136], [142, 149], [142, 154], [149, 150], [149, 154]], "functions": {"extract_json_from_text": {"executed_lines": [36, 37, 38, 39, 41, 42, 43, 44, 45], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 30, "executed_branches": [[38, 39], [38, 41], [43, 44], [43, 45]], "missing_branches": []}, "extract_metadata_with_gpt": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 40, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 40, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 12, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [51, 52, 53, 58, 59, 60, 61, 62, 63, 64, 65, 67, 100, 101, 102, 103, 112, 113, 114, 123, 124, 125, 126, 134, 136, 141, 142, 149, 150, 152, 154, 155, 166, 167, 170, 172, 174, 175, 176, 184], "excluded_lines": [], "start_line": 49, "executed_branches": [], "missing_branches": [[58, 59], [58, 67], [61, 62], [61, 67], [64, 65], [64, 67], [124, 125], [124, 136], [142, 149], [142, 154], [149, 150], [149, 154]]}, "": {"executed_lines": [3, 4, 5, 6, 8, 11, 12, 13, 14, 15, 16, 17, 19, 22, 23, 24, 30, 48, 49], "summary": {"covered_lines": 19, "num_statements": 22, "percent_covered": 86.36363636363636, "percent_covered_display": "86.36", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 86.36363636363636, "percent_statements_covered_display": "86.36", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [25, 26, 27], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 5, 6, 8, 11, 12, 13, 14, 15, 16, 17, 19, 22, 23, 24, 30, 36, 37, 38, 39, 41, 42, 43, 44, 45, 48, 49], "summary": {"covered_lines": 28, "num_statements": 71, "percent_covered": 36.7816091954023, "percent_covered_display": "36.78", "missing_lines": 43, "excluded_lines": 0, "percent_statements_covered": 39.436619718309856, "percent_statements_covered_display": "39.44", "num_branches": 16, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 12, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [25, 26, 27, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64, 65, 67, 100, 101, 102, 103, 112, 113, 114, 123, 124, 125, 126, 134, 136, 141, 142, 149, 150, 152, 154, 155, 166, 167, 170, 172, 174, 175, 176, 184], "excluded_lines": [], "start_line": 1, "executed_branches": [[38, 39], [38, 41], [43, 44], [43, 45]], "missing_branches": [[58, 59], [58, 67], [61, 62], [61, 67], [64, 65], [64, 67], [124, 125], [124, 136], [142, 149], [142, 154], [149, 150], [149, 154]]}}}, "app/tasks/finalize_document_storage.py": {"executed_lines": [3, 4, 7, 8, 9, 10, 11, 14, 17, 20, 22, 25, 26], "summary": {"covered_lines": 13, "num_statements": 42, "percent_covered": 26.0, "percent_covered_display": "26.00", "missing_lines": 29, "excluded_lines": 0, "percent_statements_covered": 30.952380952380953, "percent_statements_covered_display": "30.95", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [32, 33, 36, 45, 46, 48, 49, 50, 51, 55, 56, 57, 59, 60, 62, 63, 64, 65, 66, 70, 71, 77, 82, 84, 85, 87, 90, 91, 93], "excluded_lines": [], "executed_branches": [], "missing_branches": [[45, 46], [45, 55], [50, 51], [50, 55], [59, 60], [59, 70], [60, 59], [60, 62]], "functions": {"finalize_document_storage": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 29, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 29, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [32, 33, 36, 45, 46, 48, 49, 50, 51, 55, 56, 57, 59, 60, 62, 63, 64, 65, 66, 70, 71, 77, 82, 84, 85, 87, 90, 91, 93], "excluded_lines": [], "start_line": 26, "executed_branches": [], "missing_branches": [[45, 46], [45, 55], [50, 51], [50, 55], [59, 60], [59, 70], [60, 59], [60, 62]]}, "": {"executed_lines": [3, 4, 7, 8, 9, 10, 11, 14, 17, 20, 22, 25, 26], "summary": {"covered_lines": 13, "num_statements": 13, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 7, 8, 9, 10, 11, 14, 17, 20, 22, 25, 26], "summary": {"covered_lines": 13, "num_statements": 42, "percent_covered": 26.0, "percent_covered_display": "26.00", "missing_lines": 29, "excluded_lines": 0, "percent_statements_covered": 30.952380952380953, "percent_statements_covered_display": "30.95", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [32, 33, 36, 45, 46, 48, 49, 50, 51, 55, 56, 57, 59, 60, 62, 63, 64, 65, 66, 70, 71, 77, 82, 84, 85, 87, 90, 91, 93], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": [[45, 46], [45, 55], [50, 51], [50, 55], [59, 60], [59, 70], [60, 59], [60, 62]]}}}, "app/tasks/imap_tasks.py": {"executed_lines": [2, 3, 4, 5, 6, 7, 8, 10, 11, 13, 14, 15, 17, 20, 22, 23, 26, 29, 40, 46, 48, 49, 50, 51, 52, 53, 57, 60, 62, 63, 66, 68, 69, 70, 71, 72, 73, 74, 75, 78, 79, 120, 130, 131, 132, 134, 135, 146, 244, 271, 285, 286, 287, 288, 290, 291, 292, 295, 297, 299, 300, 301, 303, 304, 305, 308, 309, 310, 311, 313, 314, 316, 317, 320, 325, 327, 330, 331, 332, 333, 334, 335, 336, 337, 340, 342, 343, 344, 345, 346, 349, 351, 352, 353, 354, 355, 358, 364, 371, 372, 373, 374, 376, 377, 381, 384, 386, 387, 388, 389, 390, 393, 398, 399, 400, 402, 403, 404, 405, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416], "summary": {"covered_lines": 129, "num_statements": 215, "percent_covered": 57.491289198606275, "percent_covered_display": "57.49", "missing_lines": 86, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 72, "num_partial_branches": 6, "covered_branches": 36, "missing_branches": 36, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [31, 32, 33, 34, 35, 36, 37, 42, 43, 54, 55, 56, 85, 86, 87, 89, 90, 93, 104, 114, 117, 157, 158, 160, 161, 162, 164, 165, 167, 168, 169, 170, 172, 173, 175, 176, 179, 180, 181, 183, 184, 185, 186, 187, 189, 190, 192, 193, 194, 195, 196, 198, 199, 200, 202, 203, 204, 206, 207, 208, 211, 212, 213, 214, 218, 220, 221, 222, 224, 225, 227, 228, 229, 231, 233, 234, 236, 237, 238, 240, 241, 328, 378, 379, 380, 406], "excluded_lines": [], "executed_branches": [[48, 49], [48, 57], [70, 71], [70, 75], [73, 70], [73, 74], [130, 131], [130, 134], [286, 287], [286, 317], [287, 288], [287, 290], [291, 292], [291, 295], [299, 300], [299, 303], [308, 309], [308, 311], [311, 313], [327, 330], [331, 332], [333, 334], [333, 337], [371, 372], [371, 376], [373, 371], [373, 374], [377, 381], [387, 388], [387, 390], [405, 407], [408, 409], [408, 414], [410, 411], [414, 403], [414, 415]], "missing_branches": [[32, 33], [32, 36], [85, 86], [85, 89], [165, 167], [165, 179], [168, 169], [168, 172], [183, 184], [183, 189], [192, 193], [192, 233], [194, 195], [194, 198], [202, 203], [202, 206], [206, 207], [206, 211], [211, 212], [211, 218], [212, 213], [212, 218], [220, 221], [220, 224], [227, 228], [227, 231], [233, 234], [233, 236], [311, 316], [327, 328], [331, 337], [377, 378], [379, 380], [379, 381], [405, 406], [410, 414]], "functions": {"acquire_lock": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [31, 32, 33, 34, 35, 36, 37], "excluded_lines": [], "start_line": 29, "executed_branches": [], "missing_branches": [[32, 33], [32, 36]]}, "release_lock": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [42, 43], "excluded_lines": [], "start_line": 40, "executed_branches": [], "missing_branches": []}, "load_processed_emails": {"executed_lines": [48, 49, 50, 51, 52, 53, 57], "summary": {"covered_lines": 7, "num_statements": 10, "percent_covered": 75.0, "percent_covered_display": "75.00", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 70.0, "percent_statements_covered_display": "70.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [54, 55, 56], "excluded_lines": [], "start_line": 46, "executed_branches": [[48, 49], [48, 57]], "missing_branches": []}, "save_processed_emails": {"executed_lines": [62, 63], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 60, "executed_branches": [], "missing_branches": []}, "cleanup_old_entries": {"executed_lines": [68, 69, 70, 71, 72, 73, 74, 75], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 66, "executed_branches": [[70, 71], [70, 75], [73, 70], [73, 74]], "missing_branches": []}, "pull_all_inboxes": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 9, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [85, 86, 87, 89, 90, 93, 104, 114, 117], "excluded_lines": [], "start_line": 79, "executed_branches": [], "missing_branches": [[85, 86], [85, 89]]}, "check_and_pull_mailbox": {"executed_lines": [130, 131, 132, 134, 135], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 120, "executed_branches": [[130, 131], [130, 134]], "missing_branches": []}, "pull_inbox": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 60, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 60, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 24, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 24, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [157, 158, 160, 161, 162, 164, 165, 167, 168, 169, 170, 172, 173, 175, 176, 179, 180, 181, 183, 184, 185, 186, 187, 189, 190, 192, 193, 194, 195, 196, 198, 199, 200, 202, 203, 204, 206, 207, 208, 211, 212, 213, 214, 218, 220, 221, 222, 224, 225, 227, 228, 229, 231, 233, 234, 236, 237, 238, 240, 241], "excluded_lines": [], "start_line": 146, "executed_branches": [], "missing_branches": [[165, 167], [165, 179], [168, 169], [168, 172], [183, 184], [183, 189], [192, 193], [192, 233], [194, 195], [194, 198], [202, 203], [202, 206], [206, 207], [206, 211], [211, 212], [211, 218], [212, 213], [212, 218], [220, 221], [220, 224], [227, 228], [227, 231], [233, 234], [233, 236]]}, "fetch_attachments_and_enqueue": {"executed_lines": [271, 285, 286, 287, 288, 290, 291, 292, 295, 297, 299, 300, 301, 303, 304, 305, 308, 309, 310, 311, 313, 314, 316, 317], "summary": {"covered_lines": 24, "num_statements": 24, "percent_covered": 97.22222222222223, "percent_covered_display": "97.22", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 12, "num_partial_branches": 1, "covered_branches": 11, "missing_branches": 1, "percent_branches_covered": 91.66666666666667, "percent_branches_covered_display": "91.67"}, "missing_lines": [], "excluded_lines": [], "start_line": 244, "executed_branches": [[286, 287], [286, 317], [287, 288], [287, 290], [291, 292], [291, 295], [299, 300], [299, 303], [308, 309], [308, 311], [311, 313]], "missing_branches": [[311, 316]]}, "email_already_has_label": {"executed_lines": [325, 327, 330, 331, 332, 333, 334, 335, 336, 337], "summary": {"covered_lines": 10, "num_statements": 11, "percent_covered": 82.3529411764706, "percent_covered_display": "82.35", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.9090909090909, "percent_statements_covered_display": "90.91", "num_branches": 6, "num_partial_branches": 2, "covered_branches": 4, "missing_branches": 2, "percent_branches_covered": 66.66666666666667, "percent_branches_covered_display": "66.67"}, "missing_lines": [328], "excluded_lines": [], "start_line": 320, "executed_branches": [[327, 330], [331, 332], [333, 334], [333, 337]], "missing_branches": [[327, 328], [331, 337]]}, "mark_as_processed_with_star": {"executed_lines": [342, 343, 344, 345, 346], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 340, "executed_branches": [], "missing_branches": []}, "mark_as_processed_with_label": {"executed_lines": [351, 352, 353, 354, 355], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 349, "executed_branches": [], "missing_branches": []}, "find_all_mail_folder": {"executed_lines": [364, 371, 372, 373, 374, 376, 377, 381], "summary": {"covered_lines": 8, "num_statements": 11, "percent_covered": 68.42105263157895, "percent_covered_display": "68.42", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 72.72727272727273, "percent_statements_covered_display": "72.73", "num_branches": 8, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 3, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62.50"}, "missing_lines": [378, 379, 380], "excluded_lines": [], "start_line": 358, "executed_branches": [[371, 372], [371, 376], [373, 371], [373, 374], [377, 381]], "missing_branches": [[377, 378], [379, 380], [379, 381]]}, "get_capabilities": {"executed_lines": [386, 387, 388, 389, 390], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 384, "executed_branches": [[387, 388], [387, 390]], "missing_branches": []}, "find_all_mail_xlist": {"executed_lines": [398, 399, 400, 402, 403, 404, 405, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416], "summary": {"covered_lines": 17, "num_statements": 18, "percent_covered": 88.46153846153847, "percent_covered_display": "88.46", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 94.44444444444444, "percent_statements_covered_display": "94.44", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 6, "missing_branches": 2, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [406], "excluded_lines": [], "start_line": 393, "executed_branches": [[405, 407], [408, 409], [408, 414], [410, 411], [414, 403], [414, 415]], "missing_branches": [[405, 406], [410, 414]]}, "": {"executed_lines": [2, 3, 4, 5, 6, 7, 8, 10, 11, 13, 14, 15, 17, 20, 22, 23, 26, 29, 40, 46, 60, 66, 78, 79, 120, 146, 244, 320, 340, 349, 358, 384, 393], "summary": {"covered_lines": 33, "num_statements": 33, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [2, 3, 4, 5, 6, 7, 8, 10, 11, 13, 14, 15, 17, 20, 22, 23, 26, 29, 40, 46, 48, 49, 50, 51, 52, 53, 57, 60, 62, 63, 66, 68, 69, 70, 71, 72, 73, 74, 75, 78, 79, 120, 130, 131, 132, 134, 135, 146, 244, 271, 285, 286, 287, 288, 290, 291, 292, 295, 297, 299, 300, 301, 303, 304, 305, 308, 309, 310, 311, 313, 314, 316, 317, 320, 325, 327, 330, 331, 332, 333, 334, 335, 336, 337, 340, 342, 343, 344, 345, 346, 349, 351, 352, 353, 354, 355, 358, 364, 371, 372, 373, 374, 376, 377, 381, 384, 386, 387, 388, 389, 390, 393, 398, 399, 400, 402, 403, 404, 405, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416], "summary": {"covered_lines": 129, "num_statements": 215, "percent_covered": 57.491289198606275, "percent_covered_display": "57.49", "missing_lines": 86, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 72, "num_partial_branches": 6, "covered_branches": 36, "missing_branches": 36, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [31, 32, 33, 34, 35, 36, 37, 42, 43, 54, 55, 56, 85, 86, 87, 89, 90, 93, 104, 114, 117, 157, 158, 160, 161, 162, 164, 165, 167, 168, 169, 170, 172, 173, 175, 176, 179, 180, 181, 183, 184, 185, 186, 187, 189, 190, 192, 193, 194, 195, 196, 198, 199, 200, 202, 203, 204, 206, 207, 208, 211, 212, 213, 214, 218, 220, 221, 222, 224, 225, 227, 228, 229, 231, 233, 234, 236, 237, 238, 240, 241, 328, 378, 379, 380, 406], "excluded_lines": [], "start_line": 1, "executed_branches": [[48, 49], [48, 57], [70, 71], [70, 75], [73, 70], [73, 74], [130, 131], [130, 134], [286, 287], [286, 317], [287, 288], [287, 290], [291, 292], [291, 295], [299, 300], [299, 303], [308, 309], [308, 311], [311, 313], [327, 330], [331, 332], [333, 334], [333, 337], [371, 372], [371, 376], [373, 371], [373, 374], [377, 381], [387, 388], [387, 390], [405, 407], [408, 409], [408, 414], [410, 411], [414, 403], [414, 415]], "missing_branches": [[32, 33], [32, 36], [85, 86], [85, 89], [165, 167], [165, 179], [168, 169], [168, 172], [183, 184], [183, 189], [192, 193], [192, 233], [194, 195], [194, 198], [202, 203], [202, 206], [206, 207], [206, 211], [211, 212], [211, 218], [212, 213], [212, 218], [220, 221], [220, 224], [227, 228], [227, 231], [233, 234], [233, 236], [311, 316], [327, 328], [331, 337], [377, 378], [379, 380], [379, 381], [405, 406], [410, 414]]}}}, "app/tasks/monitor_stalled_steps.py": {"executed_lines": [8, 9, 11, 12, 13, 15, 18, 19, 34, 35, 36, 38, 39, 45, 47, 49, 50, 51], "summary": {"covered_lines": 18, "num_statements": 18, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[38, 39], [38, 45]], "missing_branches": [], "functions": {"monitor_stalled_steps": {"executed_lines": [34, 35, 36, 38, 39, 45, 47, 49, 50, 51], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 19, "executed_branches": [[38, 39], [38, 45]], "missing_branches": []}, "": {"executed_lines": [8, 9, 11, 12, 13, 15, 18, 19], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [8, 9, 11, 12, 13, 15, 18, 19, 34, 35, 36, 38, 39, 45, 47, 49, 50, 51], "summary": {"covered_lines": 18, "num_statements": 18, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[38, 39], [38, 45]], "missing_branches": []}}}, "app/tasks/process_document.py": {"executed_lines": [3, 4, 5, 6, 7, 9, 10, 12, 13, 14, 15, 16, 17, 20, 21, 23, 26, 27, 51, 52, 53, 60, 72, 73, 74, 75, 81, 82, 83, 84, 85, 88, 91, 92, 100, 103, 104, 105, 106, 107, 108, 109, 110, 117, 121, 127, 128, 134, 135, 136, 145, 146, 147, 149, 150, 164, 177, 185, 186, 187, 193, 194, 202, 203, 204, 205, 206, 215, 216, 217, 221, 223, 224, 227, 228, 230, 231, 238, 239, 248, 251, 252, 261, 262, 263, 265, 266, 274, 275, 284, 285, 288, 292, 293, 294, 302, 309, 316, 317, 320, 321, 343, 344, 351, 352, 353, 354, 355, 356, 357, 358, 380, 381, 382, 391, 392, 399, 400, 401, 402, 403, 405, 406, 415, 424, 425, 432, 433, 440, 441, 450, 458, 465, 466], "summary": {"covered_lines": 134, "num_statements": 149, "percent_covered": 88.10810810810811, "percent_covered_display": "88.11", "missing_lines": 15, "excluded_lines": 0, "percent_statements_covered": 89.93288590604027, "percent_statements_covered_display": "89.93", "num_branches": 36, "num_partial_branches": 7, "covered_branches": 29, "missing_branches": 7, "percent_branches_covered": 80.55555555555556, "percent_branches_covered_display": "80.56"}, "missing_lines": [61, 62, 69, 77, 78, 86, 322, 323, 330, 337, 341, 359, 360, 361, 369], "excluded_lines": [], "executed_branches": [[60, 72], [72, 73], [81, 82], [81, 83], [85, 88], [91, 92], [103, 104], [103, 121], [105, 106], [105, 109], [127, 128], [127, 134], [134, 135], [134, 185], [149, 150], [186, 187], [221, 223], [221, 251], [292, 293], [292, 320], [321, 343], [355, 356], [355, 380], [356, 355], [356, 357], [380, 381], [380, 440], [402, 403], [402, 405]], "missing_branches": [[60, 61], [72, 77], [85, 86], [91, 100], [149, 164], [186, 193], [321, 322]], "functions": {"process_document": {"executed_lines": [51, 52, 53, 60, 72, 73, 74, 75, 81, 82, 83, 84, 85, 88, 91, 92, 100, 103, 104, 105, 106, 107, 108, 109, 110, 117, 121, 127, 128, 134, 135, 136, 145, 146, 147, 149, 150, 164, 177, 185, 186, 187, 193, 194, 202, 203, 204, 205, 206, 215, 216, 217, 221, 223, 224, 227, 228, 230, 231, 238, 239, 248, 251, 252, 261, 262, 263, 265, 266, 274, 275, 284, 285, 288, 292, 293, 294, 302, 309, 316, 317, 320, 321, 343, 344, 351, 352, 353, 354, 355, 356, 357, 358, 380, 381, 382, 391, 392, 399, 400, 401, 402, 403, 405, 406, 415, 424, 425, 432, 433, 440, 441, 450, 458, 465, 466], "summary": {"covered_lines": 116, "num_statements": 131, "percent_covered": 86.82634730538922, "percent_covered_display": "86.83", "missing_lines": 15, "excluded_lines": 0, "percent_statements_covered": 88.54961832061069, "percent_statements_covered_display": "88.55", "num_branches": 36, "num_partial_branches": 7, "covered_branches": 29, "missing_branches": 7, "percent_branches_covered": 80.55555555555556, "percent_branches_covered_display": "80.56"}, "missing_lines": [61, 62, 69, 77, 78, 86, 322, 323, 330, 337, 341, 359, 360, 361, 369], "excluded_lines": [], "start_line": 27, "executed_branches": [[60, 72], [72, 73], [81, 82], [81, 83], [85, 88], [91, 92], [103, 104], [103, 121], [105, 106], [105, 109], [127, 128], [127, 134], [134, 135], [134, 185], [149, 150], [186, 187], [221, 223], [221, 251], [292, 293], [292, 320], [321, 343], [355, 356], [355, 380], [356, 355], [356, 357], [380, 381], [380, 440], [402, 403], [402, 405]], "missing_branches": [[60, 61], [72, 77], [85, 86], [91, 100], [149, 164], [186, 193], [321, 322]]}, "": {"executed_lines": [3, 4, 5, 6, 7, 9, 10, 12, 13, 14, 15, 16, 17, 20, 21, 23, 26, 27], "summary": {"covered_lines": 18, "num_statements": 18, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 5, 6, 7, 9, 10, 12, 13, 14, 15, 16, 17, 20, 21, 23, 26, 27, 51, 52, 53, 60, 72, 73, 74, 75, 81, 82, 83, 84, 85, 88, 91, 92, 100, 103, 104, 105, 106, 107, 108, 109, 110, 117, 121, 127, 128, 134, 135, 136, 145, 146, 147, 149, 150, 164, 177, 185, 186, 187, 193, 194, 202, 203, 204, 205, 206, 215, 216, 217, 221, 223, 224, 227, 228, 230, 231, 238, 239, 248, 251, 252, 261, 262, 263, 265, 266, 274, 275, 284, 285, 288, 292, 293, 294, 302, 309, 316, 317, 320, 321, 343, 344, 351, 352, 353, 354, 355, 356, 357, 358, 380, 381, 382, 391, 392, 399, 400, 401, 402, 403, 405, 406, 415, 424, 425, 432, 433, 440, 441, 450, 458, 465, 466], "summary": {"covered_lines": 134, "num_statements": 149, "percent_covered": 88.10810810810811, "percent_covered_display": "88.11", "missing_lines": 15, "excluded_lines": 0, "percent_statements_covered": 89.93288590604027, "percent_statements_covered_display": "89.93", "num_branches": 36, "num_partial_branches": 7, "covered_branches": 29, "missing_branches": 7, "percent_branches_covered": 80.55555555555556, "percent_branches_covered_display": "80.56"}, "missing_lines": [61, 62, 69, 77, 78, 86, 322, 323, 330, 337, 341, 359, 360, 361, 369], "excluded_lines": [], "start_line": 1, "executed_branches": [[60, 72], [72, 73], [81, 82], [81, 83], [85, 88], [91, 92], [103, 104], [103, 121], [105, 106], [105, 109], [127, 128], [127, 134], [134, 135], [134, 185], [149, 150], [186, 187], [221, 223], [221, 251], [292, 293], [292, 320], [321, 343], [355, 356], [355, 380], [356, 355], [356, 357], [380, 381], [380, 440], [402, 403], [402, 405]], "missing_branches": [[60, 61], [72, 77], [85, 86], [91, 100], [149, 164], [186, 193], [321, 322]]}}}, "app/tasks/process_with_azure_document_intelligence.py": {"executed_lines": [1, 2, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 16, 19, 20, 23, 32, 38, 40, 41, 42, 43, 44, 45, 46, 49, 61, 62, 63, 65, 66, 67, 69, 70, 71, 72, 73, 75, 77, 79, 81, 84, 85, 102, 103, 110, 111, 112, 113, 116, 117, 118, 121, 122, 130, 134, 135, 136, 137, 138, 139, 147, 148, 149, 153, 161, 162, 171, 172, 175, 176, 179, 182, 183, 184, 185, 186, 189, 190, 192, 202, 204, 213, 214, 215, 216, 224], "summary": {"covered_lines": 87, "num_statements": 93, "percent_covered": 93.69369369369369, "percent_covered_display": "93.69", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 93.54838709677419, "percent_statements_covered_display": "93.55", "num_branches": 18, "num_partial_branches": 1, "covered_branches": 17, "missing_branches": 1, "percent_branches_covered": 94.44444444444444, "percent_branches_covered_display": "94.44"}, "missing_lines": [24, 25, 26, 27, 28, 29], "excluded_lines": [], "executed_branches": [[65, 66], [65, 69], [69, 70], [69, 81], [70, 71], [70, 79], [72, 73], [72, 77], [112, 113], [112, 116], [117, 118], [117, 134], [134, 135], [136, 137], [136, 148], [148, 149], [148, 153]], "missing_branches": [[134, 153]], "functions": {"get_pdf_page_count": {"executed_lines": [40, 41, 42, 43, 44, 45, 46], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 38, "executed_branches": [], "missing_branches": []}, "check_page_rotation": {"executed_lines": [61, 62, 63, 65, 66, 67, 69, 70, 71, 72, 73, 75, 77, 79, 81], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 49, "executed_branches": [[65, 66], [65, 69], [69, 70], [69, 81], [70, 71], [70, 79], [72, 73], [72, 77]], "missing_branches": []}, "process_with_azure_document_intelligence": {"executed_lines": [102, 103, 110, 111, 112, 113, 116, 117, 118, 121, 122, 130, 134, 135, 136, 137, 138, 139, 147, 148, 149, 153, 161, 162, 171, 172, 175, 176, 179, 182, 183, 184, 185, 186, 189, 190, 192, 202, 204, 213, 214, 215, 216, 224], "summary": {"covered_lines": 44, "num_statements": 44, "percent_covered": 98.14814814814815, "percent_covered_display": "98.15", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 10, "num_partial_branches": 1, "covered_branches": 9, "missing_branches": 1, "percent_branches_covered": 90.0, "percent_branches_covered_display": "90.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 85, "executed_branches": [[112, 113], [112, 116], [117, 118], [117, 134], [134, 135], [136, 137], [136, 148], [148, 149], [148, 153]], "missing_branches": [[134, 153]]}, "": {"executed_lines": [1, 2, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 16, 19, 20, 23, 32, 38, 49, 84, 85], "summary": {"covered_lines": 21, "num_statements": 27, "percent_covered": 77.77777777777777, "percent_covered_display": "77.78", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 77.77777777777777, "percent_statements_covered_display": "77.78", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [24, 25, 26, 27, 28, 29], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [1, 2, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 16, 19, 20, 23, 32, 38, 40, 41, 42, 43, 44, 45, 46, 49, 61, 62, 63, 65, 66, 67, 69, 70, 71, 72, 73, 75, 77, 79, 81, 84, 85, 102, 103, 110, 111, 112, 113, 116, 117, 118, 121, 122, 130, 134, 135, 136, 137, 138, 139, 147, 148, 149, 153, 161, 162, 171, 172, 175, 176, 179, 182, 183, 184, 185, 186, 189, 190, 192, 202, 204, 213, 214, 215, 216, 224], "summary": {"covered_lines": 87, "num_statements": 93, "percent_covered": 93.69369369369369, "percent_covered_display": "93.69", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 93.54838709677419, "percent_statements_covered_display": "93.55", "num_branches": 18, "num_partial_branches": 1, "covered_branches": 17, "missing_branches": 1, "percent_branches_covered": 94.44444444444444, "percent_branches_covered_display": "94.44"}, "missing_lines": [24, 25, 26, 27, 28, 29], "excluded_lines": [], "start_line": 1, "executed_branches": [[65, 66], [65, 69], [69, 70], [69, 81], [70, 71], [70, 79], [72, 73], [72, 77], [112, 113], [112, 116], [117, 118], [117, 134], [134, 135], [136, 137], [136, 148], [148, 149], [148, 153]], "missing_branches": [[134, 153]]}}}, "app/tasks/refine_text_with_gpt.py": {"executed_lines": [3, 5, 8, 9, 10, 11, 13, 16, 19, 20, 22, 23, 24, 26, 27, 29, 43, 45, 46, 55, 57, 59, 60, 62, 63, 64, 65, 72], "summary": {"covered_lines": 28, "num_statements": 28, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"refine_text_with_gpt": {"executed_lines": [22, 23, 24, 26, 27, 29, 43, 45, 46, 55, 57, 59, 60, 62, 63, 64, 65, 72], "summary": {"covered_lines": 18, "num_statements": 18, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 20, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [3, 5, 8, 9, 10, 11, 13, 16, 19, 20], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 5, 8, 9, 10, 11, 13, 16, 19, 20, 22, 23, 24, 26, 27, 29, 43, 45, 46, 55, 57, 59, 60, 62, 63, 64, 65, 72], "summary": {"covered_lines": 28, "num_statements": 28, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/tasks/retry_config.py": {"executed_lines": [3, 6, 7, 8, 9], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [3, 6, 7, 8, 9], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"BaseTaskWithRetry": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 6, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [3, 6, 7, 8, 9], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/tasks/rotate_pdf_pages.py": {"executed_lines": [1, 2, 3, 5, 7, 8, 9, 10, 11, 13, 16, 27, 28, 32, 33, 36, 37, 39, 40, 41, 45, 47, 48, 49, 52, 53, 63, 64, 65, 72, 73, 74, 77, 78, 79, 86, 87, 90, 91, 92, 93, 97, 98, 101, 108, 109, 111, 112, 119, 122, 123, 124, 127, 128, 131, 132, 133, 135, 137, 138, 142, 149, 152, 153, 155, 156, 166, 168, 177, 184, 185, 186, 195, 196], "summary": {"covered_lines": 74, "num_statements": 79, "percent_covered": 91.2621359223301, "percent_covered_display": "91.26", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 93.67088607594937, "percent_statements_covered_display": "93.67", "num_branches": 24, "num_partial_branches": 4, "covered_branches": 20, "missing_branches": 4, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [29, 94, 95, 144, 160], "excluded_lines": [], "executed_branches": [[28, 32], [32, 33], [32, 36], [36, 37], [36, 45], [37, 36], [37, 39], [73, 74], [73, 77], [77, 78], [77, 90], [91, 92], [91, 97], [97, 98], [97, 111], [127, 128], [127, 152], [131, 132], [135, 137], [155, 156]], "missing_branches": [[28, 29], [131, 149], [135, 144], [155, 160]], "functions": {"determine_rotation_angle": {"executed_lines": [27, 28, 32, 33, 36, 37, 39, 40, 41, 45, 47, 48, 49], "summary": {"covered_lines": 13, "num_statements": 14, "percent_covered": 90.9090909090909, "percent_covered_display": "90.91", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 92.85714285714286, "percent_statements_covered_display": "92.86", "num_branches": 8, "num_partial_branches": 1, "covered_branches": 7, "missing_branches": 1, "percent_branches_covered": 87.5, "percent_branches_covered_display": "87.50"}, "missing_lines": [29], "excluded_lines": [], "start_line": 16, "executed_branches": [[28, 32], [32, 33], [32, 36], [36, 37], [36, 45], [37, 36], [37, 39]], "missing_branches": [[28, 29]]}, "rotate_pdf_pages": {"executed_lines": [63, 64, 65, 72, 73, 74, 77, 78, 79, 86, 87, 90, 91, 92, 93, 97, 98, 101, 108, 109, 111, 112, 119, 122, 123, 124, 127, 128, 131, 132, 133, 135, 137, 138, 142, 149, 152, 153, 155, 156, 166, 168, 177, 184, 185, 186, 195, 196], "summary": {"covered_lines": 48, "num_statements": 52, "percent_covered": 89.70588235294117, "percent_covered_display": "89.71", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 92.3076923076923, "percent_statements_covered_display": "92.31", "num_branches": 16, "num_partial_branches": 3, "covered_branches": 13, "missing_branches": 3, "percent_branches_covered": 81.25, "percent_branches_covered_display": "81.25"}, "missing_lines": [94, 95, 144, 160], "excluded_lines": [], "start_line": 53, "executed_branches": [[73, 74], [73, 77], [77, 78], [77, 90], [91, 92], [91, 97], [97, 98], [97, 111], [127, 128], [127, 152], [131, 132], [135, 137], [155, 156]], "missing_branches": [[131, 149], [135, 144], [155, 160]]}, "": {"executed_lines": [1, 2, 3, 5, 7, 8, 9, 10, 11, 13, 16, 52, 53], "summary": {"covered_lines": 13, "num_statements": 13, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [1, 2, 3, 5, 7, 8, 9, 10, 11, 13, 16, 27, 28, 32, 33, 36, 37, 39, 40, 41, 45, 47, 48, 49, 52, 53, 63, 64, 65, 72, 73, 74, 77, 78, 79, 86, 87, 90, 91, 92, 93, 97, 98, 101, 108, 109, 111, 112, 119, 122, 123, 124, 127, 128, 131, 132, 133, 135, 137, 138, 142, 149, 152, 153, 155, 156, 166, 168, 177, 184, 185, 186, 195, 196], "summary": {"covered_lines": 74, "num_statements": 79, "percent_covered": 91.2621359223301, "percent_covered_display": "91.26", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 93.67088607594937, "percent_statements_covered_display": "93.67", "num_branches": 24, "num_partial_branches": 4, "covered_branches": 20, "missing_branches": 4, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [29, 94, 95, 144, 160], "excluded_lines": [], "start_line": 1, "executed_branches": [[28, 32], [32, 33], [32, 36], [36, 37], [36, 45], [37, 36], [37, 39], [73, 74], [73, 77], [77, 78], [77, 90], [91, 92], [91, 97], [97, 98], [97, 111], [127, 128], [127, 152], [131, 132], [135, 137], [155, 156]], "missing_branches": [[28, 29], [131, 149], [135, 144], [155, 160]]}}}, "app/tasks/send_to_all.py": {"executed_lines": [3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 27, 28, 31, 32, 35, 36, 39, 41, 42, 53, 54, 57, 58, 61, 62, 65, 66, 71, 72, 75, 79, 108, 109, 119, 121, 126, 127, 136, 148, 151, 205, 206, 207, 208, 209, 215, 216, 217, 220, 221, 222, 223, 225, 226, 227, 233, 234, 235, 238, 239, 240, 241, 242, 245, 246, 247, 248, 250, 251, 253], "summary": {"covered_lines": 80, "num_statements": 102, "percent_covered": 73.77049180327869, "percent_covered_display": "73.77", "missing_lines": 22, "excluded_lines": 0, "percent_statements_covered": 78.43137254901961, "percent_statements_covered_display": "78.43", "num_branches": 20, "num_partial_branches": 4, "covered_branches": 10, "missing_branches": 10, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [50, 76, 85, 87, 100, 101, 102, 103, 105, 122, 123, 124, 137, 140, 145, 146, 210, 211, 212, 228, 229, 230], "excluded_lines": [], "executed_branches": [[41, 42], [121, 126], [136, 148], [206, 207], [216, 217], [216, 250], [221, 222], [221, 225], [233, 216], [233, 234]], "missing_branches": [[41, 50], [101, 102], [101, 105], [102, 101], [102, 103], [121, 122], [136, 137], [145, 146], [145, 148], [206, 215]], "functions": {"_should_upload_to_dropbox": {"executed_lines": [28], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 27, "executed_branches": [], "missing_branches": []}, "_should_upload_to_nextcloud": {"executed_lines": [32], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 31, "executed_branches": [], "missing_branches": []}, "_should_upload_to_paperless": {"executed_lines": [36], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 35, "executed_branches": [], "missing_branches": []}, "_should_upload_to_google_drive": {"executed_lines": [41, 42], "summary": {"covered_lines": 2, "num_statements": 3, "percent_covered": 60.0, "percent_covered_display": "60.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 66.66666666666667, "percent_statements_covered_display": "66.67", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [50], "excluded_lines": [], "start_line": 39, "executed_branches": [[41, 42]], "missing_branches": [[41, 50]]}, "_should_upload_to_webdav": {"executed_lines": [54], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 53, "executed_branches": [], "missing_branches": []}, "_should_upload_to_ftp": {"executed_lines": [58], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 57, "executed_branches": [], "missing_branches": []}, "_should_upload_to_sftp": {"executed_lines": [62], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 61, "executed_branches": [], "missing_branches": []}, "_should_upload_to_email": {"executed_lines": [66], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 65, "executed_branches": [], "missing_branches": []}, "_should_upload_to_onedrive": {"executed_lines": [72], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 71, "executed_branches": [], "missing_branches": []}, "_should_upload_to_s3": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [76], "excluded_lines": [], "start_line": 75, "executed_branches": [], "missing_branches": []}, "get_configured_services_from_validator": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 4, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [85, 87, 100, 101, 102, 103, 105], "excluded_lines": [], "start_line": 79, "executed_branches": [], "missing_branches": [[101, 102], [101, 105], [102, 101], [102, 103]]}, "send_to_all_destinations": {"executed_lines": [119, 121, 126, 127, 136, 148, 151, 205, 206, 207, 208, 209, 215, 216, 217, 220, 221, 222, 223, 225, 226, 227, 233, 234, 235, 238, 239, 240, 241, 242, 245, 246, 247, 248, 250, 251, 253], "summary": {"covered_lines": 37, "num_statements": 50, "percent_covered": 71.875, "percent_covered_display": "71.88", "missing_lines": 13, "excluded_lines": 0, "percent_statements_covered": 74.0, "percent_statements_covered_display": "74.00", "num_branches": 14, "num_partial_branches": 3, "covered_branches": 9, "missing_branches": 5, "percent_branches_covered": 64.28571428571429, "percent_branches_covered_display": "64.29"}, "missing_lines": [122, 123, 124, 137, 140, 145, 146, 210, 211, 212, 228, 229, 230], "excluded_lines": [], "start_line": 109, "executed_branches": [[121, 126], [136, 148], [206, 207], [216, 217], [216, 250], [221, 222], [221, 225], [233, 216], [233, 234]], "missing_branches": [[121, 122], [136, 137], [145, 146], [145, 148], [206, 215]]}, "": {"executed_lines": [3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 27, 31, 35, 39, 53, 57, 61, 65, 71, 75, 79, 108, 109], "summary": {"covered_lines": 33, "num_statements": 33, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 27, 28, 31, 32, 35, 36, 39, 41, 42, 53, 54, 57, 58, 61, 62, 65, 66, 71, 72, 75, 79, 108, 109, 119, 121, 126, 127, 136, 148, 151, 205, 206, 207, 208, 209, 215, 216, 217, 220, 221, 222, 223, 225, 226, 227, 233, 234, 235, 238, 239, 240, 241, 242, 245, 246, 247, 248, 250, 251, 253], "summary": {"covered_lines": 80, "num_statements": 102, "percent_covered": 73.77049180327869, "percent_covered_display": "73.77", "missing_lines": 22, "excluded_lines": 0, "percent_statements_covered": 78.43137254901961, "percent_statements_covered_display": "78.43", "num_branches": 20, "num_partial_branches": 4, "covered_branches": 10, "missing_branches": 10, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [50, 76, 85, 87, 100, 101, 102, 103, 105, 122, 123, 124, 137, 140, 145, 146, 210, 211, 212, 228, 229, 230], "excluded_lines": [], "start_line": 1, "executed_branches": [[41, 42], [121, 126], [136, 148], [206, 207], [216, 217], [216, 250], [221, 222], [221, 225], [233, 216], [233, 234]], "missing_branches": [[41, 50], [101, 102], [101, 105], [102, 101], [102, 103], [121, 122], [136, 137], [145, 146], [145, 148], [206, 215]]}}}, "app/tasks/upload_to_dropbox.py": {"executed_lines": [3, 4, 6, 7, 8, 10, 11, 12, 13, 14, 16, 19, 21, 23, 24, 26, 27, 29, 30, 32, 33, 34, 39, 43, 44, 65, 105, 106], "summary": {"covered_lines": 28, "num_statements": 119, "percent_covered": 22.448979591836736, "percent_covered_display": "22.45", "missing_lines": 91, "excluded_lines": 0, "percent_statements_covered": 23.529411764705884, "percent_statements_covered_display": "23.53", "num_branches": 28, "num_partial_branches": 5, "covered_branches": 5, "missing_branches": 23, "percent_branches_covered": 17.857142857142858, "percent_branches_covered_display": "17.86"}, "missing_lines": [36, 46, 47, 48, 55, 57, 58, 60, 61, 62, 76, 77, 78, 81, 82, 84, 85, 88, 89, 92, 93, 94, 96, 97, 98, 100, 101, 102, 114, 115, 116, 124, 125, 126, 127, 128, 131, 139, 140, 141, 143, 145, 147, 150, 151, 154, 155, 156, 157, 158, 159, 160, 161, 164, 165, 168, 171, 172, 173, 175, 176, 177, 178, 179, 182, 183, 186, 187, 189, 196, 197, 200, 201, 203, 204, 207, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223], "excluded_lines": [], "executed_branches": [[23, 24], [26, 27], [29, 30], [32, 33], [43, 44]], "missing_branches": [[23, 26], [26, 29], [29, 32], [32, 36], [43, 46], [57, 58], [57, 60], [81, 82], [81, 84], [84, 85], [84, 88], [124, 125], [124, 131], [131, 139], [131, 143], [159, 160], [159, 161], [176, 177], [176, 200], [186, 187], [186, 203], [187, 189], [187, 196]], "functions": {"_validate_dropbox_settings": {"executed_lines": [21, 23, 24, 26, 27, 29, 30, 32, 33, 34], "summary": {"covered_lines": 10, "num_statements": 11, "percent_covered": 73.6842105263158, "percent_covered_display": "73.68", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.9090909090909, "percent_statements_covered_display": "90.91", "num_branches": 8, "num_partial_branches": 4, "covered_branches": 4, "missing_branches": 4, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [36], "excluded_lines": [], "start_line": 19, "executed_branches": [[23, 24], [26, 27], [29, 30], [32, 33]], "missing_branches": [[23, 26], [26, 29], [29, 32], [32, 36]]}, "get_dropbox_access_token": {"executed_lines": [43, 44], "summary": {"covered_lines": 2, "num_statements": 11, "percent_covered": 20.0, "percent_covered_display": "20.00", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 18.181818181818183, "percent_statements_covered_display": "18.18", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [46, 47, 48, 55, 57, 58, 60, 61, 62], "excluded_lines": [], "start_line": 39, "executed_branches": [[43, 44]], "missing_branches": [[43, 46], [57, 58], [57, 60]]}, "get_dropbox_client": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 18, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 4, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [76, 77, 78, 81, 82, 84, 85, 88, 89, 92, 93, 94, 96, 97, 98, 100, 101, 102], "excluded_lines": [], "start_line": 65, "executed_branches": [], "missing_branches": [[81, 82], [81, 84], [84, 85], [84, 88]]}, "upload_to_dropbox": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 56, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 56, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 10, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [114, 115, 116, 124, 125, 126, 127, 128, 131, 139, 140, 141, 143, 145, 147, 150, 151, 154, 164, 165, 168, 171, 172, 173, 175, 176, 177, 178, 179, 182, 183, 186, 187, 189, 196, 197, 200, 201, 203, 204, 207, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223], "excluded_lines": [], "start_line": 106, "executed_branches": [], "missing_branches": [[124, 125], [124, 131], [131, 139], [131, 143], [176, 177], [176, 200], [186, 187], [186, 203], [187, 189], [187, 196]]}, "upload_to_dropbox.check_exists_in_dropbox": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [155, 156, 157, 158, 159, 160, 161], "excluded_lines": [], "start_line": 154, "executed_branches": [], "missing_branches": [[159, 160], [159, 161]]}, "": {"executed_lines": [3, 4, 6, 7, 8, 10, 11, 12, 13, 14, 16, 19, 39, 65, 105, 106], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 6, 7, 8, 10, 11, 12, 13, 14, 16, 19, 21, 23, 24, 26, 27, 29, 30, 32, 33, 34, 39, 43, 44, 65, 105, 106], "summary": {"covered_lines": 28, "num_statements": 119, "percent_covered": 22.448979591836736, "percent_covered_display": "22.45", "missing_lines": 91, "excluded_lines": 0, "percent_statements_covered": 23.529411764705884, "percent_statements_covered_display": "23.53", "num_branches": 28, "num_partial_branches": 5, "covered_branches": 5, "missing_branches": 23, "percent_branches_covered": 17.857142857142858, "percent_branches_covered_display": "17.86"}, "missing_lines": [36, 46, 47, 48, 55, 57, 58, 60, 61, 62, 76, 77, 78, 81, 82, 84, 85, 88, 89, 92, 93, 94, 96, 97, 98, 100, 101, 102, 114, 115, 116, 124, 125, 126, 127, 128, 131, 139, 140, 141, 143, 145, 147, 150, 151, 154, 155, 156, 157, 158, 159, 160, 161, 164, 165, 168, 171, 172, 173, 175, 176, 177, 178, 179, 182, 183, 186, 187, 189, 196, 197, 200, 201, 203, 204, 207, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223], "excluded_lines": [], "start_line": 1, "executed_branches": [[23, 24], [26, 27], [29, 30], [32, 33], [43, 44]], "missing_branches": [[23, 26], [26, 29], [29, 32], [32, 36], [43, 46], [57, 58], [57, 60], [81, 82], [81, 84], [84, 85], [84, 88], [124, 125], [124, 131], [131, 139], [131, 143], [159, 160], [159, 161], [176, 177], [176, 200], [186, 187], [186, 203], [187, 189], [187, 196]]}}}, "app/tasks/upload_to_email.py": {"executed_lines": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 17, 18, 19, 21, 24, 59, 86, 122, 135, 166, 167, 190, 191, 192, 196, 203, 206, 213, 219, 220, 226, 229, 230, 231, 233, 235, 236, 237, 238, 241, 242, 245, 248, 251, 264, 265, 268, 269, 270, 271, 274, 275, 280, 281, 283], "summary": {"covered_lines": 57, "num_statements": 158, "percent_covered": 32.97872340425532, "percent_covered_display": "32.98", "missing_lines": 101, "excluded_lines": 0, "percent_statements_covered": 36.075949367088604, "percent_statements_covered_display": "36.08", "num_branches": 30, "num_partial_branches": 5, "covered_branches": 5, "missing_branches": 25, "percent_branches_covered": 16.666666666666668, "percent_branches_covered_display": "16.67"}, "missing_lines": [31, 32, 33, 34, 37, 38, 39, 40, 41, 42, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 67, 70, 71, 72, 73, 74, 75, 76, 77, 78, 83, 88, 90, 91, 92, 95, 96, 98, 99, 101, 102, 103, 106, 107, 108, 109, 110, 111, 112, 114, 115, 117, 118, 119, 124, 125, 126, 127, 128, 129, 130, 131, 132, 137, 139, 142, 144, 145, 148, 149, 152, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 197, 198, 199, 200, 207, 208, 209, 210, 221, 222, 223, 276, 277, 278, 292, 293, 294, 295, 296], "excluded_lines": [], "executed_branches": [[196, 203], [206, 213], [220, 226], [230, 231], [275, 280]], "missing_branches": [[33, 34], [33, 45], [71, 72], [71, 83], [91, 92], [91, 95], [98, 99], [98, 101], [101, 102], [101, 114], [124, 125], [124, 130], [125, 126], [125, 129], [130, 131], [130, 132], [144, 145], [144, 148], [148, 149], [148, 152], [196, 197], [206, 207], [220, 221], [230, 233], [275, 276]], "functions": {"get_email_template": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 21, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 21, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [31, 32, 33, 34, 37, 38, 39, 40, 41, 42, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56], "excluded_lines": [], "start_line": 24, "executed_branches": [], "missing_branches": [[33, 34], [33, 45]]}, "extract_metadata_from_file": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 11, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 11, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [67, 70, 71, 72, 73, 74, 75, 76, 77, 78, 83], "excluded_lines": [], "start_line": 59, "executed_branches": [], "missing_branches": [[71, 72], [71, 83]]}, "attach_logo": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 23, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 23, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [88, 90, 91, 92, 95, 96, 98, 99, 101, 102, 103, 106, 107, 108, 109, 110, 111, 112, 114, 115, 117, 118, 119], "excluded_lines": [], "start_line": 86, "executed_branches": [], "missing_branches": [[91, 92], [91, 95], [98, 99], [98, 101], [101, 102], [101, 114]]}, "_prepare_recipients": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 9, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [124, 125, 126, 127, 128, 129, 130, 131, 132], "excluded_lines": [], "start_line": 122, "executed_branches": [], "missing_branches": [[124, 125], [124, 130], [125, 126], [125, 129], [130, 131], [130, 132]]}, "_send_email_with_smtp": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 18, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 4, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [137, 139, 142, 144, 145, 148, 149, 152, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163], "excluded_lines": [], "start_line": 135, "executed_branches": [], "missing_branches": [[144, 145], [144, 148], [148, 149], [148, 152]]}, "upload_to_email": {"executed_lines": [190, 191, 192, 196, 203, 206, 213, 219, 220, 226, 229, 230, 231, 233, 235, 236, 237, 238, 241, 242, 245, 248, 251, 264, 265, 268, 269, 270, 271, 274, 275, 280, 281, 283], "summary": {"covered_lines": 34, "num_statements": 53, "percent_covered": 61.904761904761905, "percent_covered_display": "61.90", "missing_lines": 19, "excluded_lines": 0, "percent_statements_covered": 64.15094339622641, "percent_statements_covered_display": "64.15", "num_branches": 10, "num_partial_branches": 5, "covered_branches": 5, "missing_branches": 5, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [197, 198, 199, 200, 207, 208, 209, 210, 221, 222, 223, 276, 277, 278, 292, 293, 294, 295, 296], "excluded_lines": [], "start_line": 167, "executed_branches": [[196, 203], [206, 213], [220, 226], [230, 231], [275, 280]], "missing_branches": [[196, 197], [206, 207], [220, 221], [230, 233], [275, 276]]}, "": {"executed_lines": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 17, 18, 19, 21, 24, 59, 86, 122, 135, 166, 167], "summary": {"covered_lines": 23, "num_statements": 23, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 17, 18, 19, 21, 24, 59, 86, 122, 135, 166, 167, 190, 191, 192, 196, 203, 206, 213, 219, 220, 226, 229, 230, 231, 233, 235, 236, 237, 238, 241, 242, 245, 248, 251, 264, 265, 268, 269, 270, 271, 274, 275, 280, 281, 283], "summary": {"covered_lines": 57, "num_statements": 158, "percent_covered": 32.97872340425532, "percent_covered_display": "32.98", "missing_lines": 101, "excluded_lines": 0, "percent_statements_covered": 36.075949367088604, "percent_statements_covered_display": "36.08", "num_branches": 30, "num_partial_branches": 5, "covered_branches": 5, "missing_branches": 25, "percent_branches_covered": 16.666666666666668, "percent_branches_covered_display": "16.67"}, "missing_lines": [31, 32, 33, 34, 37, 38, 39, 40, 41, 42, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 67, 70, 71, 72, 73, 74, 75, 76, 77, 78, 83, 88, 90, 91, 92, 95, 96, 98, 99, 101, 102, 103, 106, 107, 108, 109, 110, 111, 112, 114, 115, 117, 118, 119, 124, 125, 126, 127, 128, 129, 130, 131, 132, 137, 139, 142, 144, 145, 148, 149, 152, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 197, 198, 199, 200, 207, 208, 209, 210, 221, 222, 223, 276, 277, 278, 292, 293, 294, 295, 296], "excluded_lines": [], "start_line": 1, "executed_branches": [[196, 203], [206, 213], [220, 226], [230, 231], [275, 280]], "missing_branches": [[33, 34], [33, 45], [71, 72], [71, 83], [91, 92], [91, 95], [98, 99], [98, 101], [101, 102], [101, 114], [124, 125], [124, 130], [125, 126], [125, 129], [130, 131], [130, 132], [144, 145], [144, 148], [148, 149], [148, 152], [196, 197], [206, 207], [220, 221], [230, 233], [275, 276]]}}}, "app/tasks/upload_to_ftp.py": {"executed_lines": [5, 6, 7, 9, 10, 11, 12, 14, 17, 18, 30, 31, 32, 36, 37, 38, 39, 40, 43, 46, 52, 54, 55, 57, 84, 90, 91, 92, 95, 98, 99, 101, 103, 107, 108, 127, 128, 131, 133, 134, 135], "summary": {"covered_lines": 41, "num_statements": 85, "percent_covered": 47.57281553398058, "percent_covered_display": "47.57", "missing_lines": 44, "excluded_lines": 0, "percent_statements_covered": 48.23529411764706, "percent_statements_covered_display": "48.24", "num_branches": 18, "num_partial_branches": 4, "covered_branches": 8, "missing_branches": 10, "percent_branches_covered": 44.44444444444444, "percent_branches_covered_display": "44.44"}, "missing_lines": [47, 48, 49, 50, 58, 59, 60, 61, 64, 67, 68, 69, 70, 71, 72, 73, 75, 77, 78, 81, 85, 86, 87, 104, 109, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 143, 144, 145, 146, 147], "excluded_lines": [], "executed_branches": [[36, 37], [36, 43], [46, 52], [57, 84], [84, 90], [98, 99], [98, 127], [103, 107]], "missing_branches": [[46, 47], [57, 58], [70, 71], [70, 75], [84, 85], [103, 104], [113, 114], [113, 127], [114, 113], [114, 115]], "functions": {"upload_to_ftp": {"executed_lines": [30, 31, 32, 36, 37, 38, 39, 40, 43, 46, 52, 54, 55, 57, 84, 90, 91, 92, 95, 98, 99, 101, 103, 107, 108, 127, 128, 131, 133, 134, 135], "summary": {"covered_lines": 31, "num_statements": 75, "percent_covered": 41.935483870967744, "percent_covered_display": "41.94", "missing_lines": 44, "excluded_lines": 0, "percent_statements_covered": 41.333333333333336, "percent_statements_covered_display": "41.33", "num_branches": 18, "num_partial_branches": 4, "covered_branches": 8, "missing_branches": 10, "percent_branches_covered": 44.44444444444444, "percent_branches_covered_display": "44.44"}, "missing_lines": [47, 48, 49, 50, 58, 59, 60, 61, 64, 67, 68, 69, 70, 71, 72, 73, 75, 77, 78, 81, 85, 86, 87, 104, 109, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 143, 144, 145, 146, 147], "excluded_lines": [], "start_line": 18, "executed_branches": [[36, 37], [36, 43], [46, 52], [57, 84], [84, 90], [98, 99], [98, 127], [103, 107]], "missing_branches": [[46, 47], [57, 58], [70, 71], [70, 75], [84, 85], [103, 104], [113, 114], [113, 127], [114, 113], [114, 115]]}, "": {"executed_lines": [5, 6, 7, 9, 10, 11, 12, 14, 17, 18], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 9, 10, 11, 12, 14, 17, 18, 30, 31, 32, 36, 37, 38, 39, 40, 43, 46, 52, 54, 55, 57, 84, 90, 91, 92, 95, 98, 99, 101, 103, 107, 108, 127, 128, 131, 133, 134, 135], "summary": {"covered_lines": 41, "num_statements": 85, "percent_covered": 47.57281553398058, "percent_covered_display": "47.57", "missing_lines": 44, "excluded_lines": 0, "percent_statements_covered": 48.23529411764706, "percent_statements_covered_display": "48.24", "num_branches": 18, "num_partial_branches": 4, "covered_branches": 8, "missing_branches": 10, "percent_branches_covered": 44.44444444444444, "percent_branches_covered_display": "44.44"}, "missing_lines": [47, 48, 49, 50, 58, 59, 60, 61, 64, 67, 68, 69, 70, 71, 72, 73, 75, 77, 78, 81, 85, 86, 87, 104, 109, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 143, 144, 145, 146, 147], "excluded_lines": [], "start_line": 1, "executed_branches": [[36, 37], [36, 43], [46, 52], [57, 84], [84, 90], [98, 99], [98, 127], [103, 107]], "missing_branches": [[46, 47], [57, 58], [70, 71], [70, 75], [84, 85], [103, 104], [113, 114], [113, 127], [114, 113], [114, 115]]}}}, "app/tasks/upload_to_google_drive.py": {"executed_lines": [5, 6, 7, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 21, 24, 65, 98, 119, 152, 153, 162, 163, 164, 172, 179, 182, 183, 184, 186, 188, 189, 196, 201, 202, 205, 238, 240, 249, 250, 252, 253, 254, 258, 266, 269], "summary": {"covered_lines": 45, "num_statements": 125, "percent_covered": 32.48407643312102, "percent_covered_display": "32.48", "missing_lines": 80, "excluded_lines": 0, "percent_statements_covered": 36.0, "percent_statements_covered_display": "36.00", "num_branches": 32, "num_partial_branches": 6, "covered_branches": 6, "missing_branches": 26, "percent_branches_covered": 18.75, "percent_branches_covered_display": "18.75"}, "missing_lines": [29, 31, 36, 37, 40, 51, 54, 55, 57, 58, 59, 60, 61, 62, 70, 72, 73, 76, 77, 78, 80, 81, 86, 87, 90, 91, 93, 94, 95, 106, 107, 108, 109, 110, 111, 112, 113, 114, 116, 126, 129, 130, 131, 134, 135, 139, 142, 143, 146, 147, 149, 173, 174, 175, 176, 190, 191, 192, 193, 207, 211, 212, 214, 215, 218, 219, 220, 221, 222, 225, 228, 232, 233, 235, 267, 271, 272, 273, 274, 275], "excluded_lines": [], "executed_branches": [[172, 179], [183, 184], [189, 196], [201, 202], [205, 238], [266, 269]], "missing_branches": [[31, 36], [31, 40], [72, 73], [72, 76], [76, 77], [76, 80], [86, 87], [86, 90], [107, 108], [107, 116], [134, 135], [134, 139], [142, 143], [142, 146], [146, 147], [146, 149], [172, 173], [183, 186], [189, 190], [201, 205], [205, 207], [212, 214], [212, 225], [214, 215], [214, 218], [266, 267]], "functions": {"get_drive_service_oauth": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 14, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 14, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [29, 31, 36, 37, 40, 51, 54, 55, 57, 58, 59, 60, 61, 62], "excluded_lines": [], "start_line": 24, "executed_branches": [], "missing_branches": [[31, 36], [31, 40]]}, "get_google_drive_service": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 15, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 15, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [70, 72, 73, 76, 77, 78, 80, 81, 86, 87, 90, 91, 93, 94, 95], "excluded_lines": [], "start_line": 65, "executed_branches": [], "missing_branches": [[72, 73], [72, 76], [76, 77], [76, 80], [86, 87], [86, 90]]}, "extract_metadata_from_file": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 10, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [106, 107, 108, 109, 110, 111, 112, 113, 114, 116], "excluded_lines": [], "start_line": 98, "executed_branches": [], "missing_branches": [[107, 108], [107, 116]]}, "truncate_property_value": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 12, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 12, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [126, 129, 130, 131, 134, 135, 139, 142, 143, 146, 147, 149], "excluded_lines": [], "start_line": 119, "executed_branches": [], "missing_branches": [[134, 135], [134, 139], [142, 143], [142, 146], [146, 147], [146, 149]]}, "upload_to_google_drive": {"executed_lines": [162, 163, 164, 172, 179, 182, 183, 184, 186, 188, 189, 196, 201, 202, 205, 238, 240, 249, 250, 252, 253, 254, 258, 266, 269], "summary": {"covered_lines": 25, "num_statements": 54, "percent_covered": 44.285714285714285, "percent_covered_display": "44.29", "missing_lines": 29, "excluded_lines": 0, "percent_statements_covered": 46.2962962962963, "percent_statements_covered_display": "46.30", "num_branches": 16, "num_partial_branches": 6, "covered_branches": 6, "missing_branches": 10, "percent_branches_covered": 37.5, "percent_branches_covered_display": "37.50"}, "missing_lines": [173, 174, 175, 176, 190, 191, 192, 193, 207, 211, 212, 214, 215, 218, 219, 220, 221, 222, 225, 228, 232, 233, 235, 267, 271, 272, 273, 274, 275], "excluded_lines": [], "start_line": 153, "executed_branches": [[172, 179], [183, 184], [189, 196], [201, 202], [205, 238], [266, 269]], "missing_branches": [[172, 173], [183, 186], [189, 190], [201, 205], [205, 207], [212, 214], [212, 225], [214, 215], [214, 218], [266, 267]]}, "": {"executed_lines": [5, 6, 7, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 21, 24, 65, 98, 119, 152, 153], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 21, 24, 65, 98, 119, 152, 153, 162, 163, 164, 172, 179, 182, 183, 184, 186, 188, 189, 196, 201, 202, 205, 238, 240, 249, 250, 252, 253, 254, 258, 266, 269], "summary": {"covered_lines": 45, "num_statements": 125, "percent_covered": 32.48407643312102, "percent_covered_display": "32.48", "missing_lines": 80, "excluded_lines": 0, "percent_statements_covered": 36.0, "percent_statements_covered_display": "36.00", "num_branches": 32, "num_partial_branches": 6, "covered_branches": 6, "missing_branches": 26, "percent_branches_covered": 18.75, "percent_branches_covered_display": "18.75"}, "missing_lines": [29, 31, 36, 37, 40, 51, 54, 55, 57, 58, 59, 60, 61, 62, 70, 72, 73, 76, 77, 78, 80, 81, 86, 87, 90, 91, 93, 94, 95, 106, 107, 108, 109, 110, 111, 112, 113, 114, 116, 126, 129, 130, 131, 134, 135, 139, 142, 143, 146, 147, 149, 173, 174, 175, 176, 190, 191, 192, 193, 207, 211, 212, 214, 215, 218, 219, 220, 221, 222, 225, 228, 232, 233, 235, 267, 271, 272, 273, 274, 275], "excluded_lines": [], "start_line": 1, "executed_branches": [[172, 179], [183, 184], [189, 196], [201, 202], [205, 238], [266, 269]], "missing_branches": [[31, 36], [31, 40], [72, 73], [72, 76], [76, 77], [76, 80], [86, 87], [86, 90], [107, 108], [107, 116], [134, 135], [134, 139], [142, 143], [142, 146], [146, 147], [146, 149], [172, 173], [183, 186], [189, 190], [201, 205], [205, 207], [212, 214], [212, 225], [214, 215], [214, 218], [266, 267]]}}}, "app/tasks/upload_to_nextcloud.py": {"executed_lines": [3, 4, 6, 7, 9, 10, 11, 12, 13, 15, 18, 19, 27, 28, 29, 37, 45, 50, 51, 52], "summary": {"covered_lines": 20, "num_statements": 79, "percent_covered": 22.22222222222222, "percent_covered_display": "22.22", "missing_lines": 59, "excluded_lines": 0, "percent_statements_covered": 25.31645569620253, "percent_statements_covered_display": "25.32", "num_branches": 20, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 18, "percent_branches_covered": 10.0, "percent_branches_covered_display": "10.00"}, "missing_lines": [38, 39, 40, 41, 54, 56, 58, 59, 60, 63, 64, 65, 68, 69, 70, 71, 74, 75, 76, 77, 85, 86, 88, 91, 92, 95, 96, 97, 98, 101, 102, 103, 104, 105, 106, 107, 108, 110, 111, 112, 113, 115, 123, 124, 125, 126, 134, 135, 136, 139, 146, 147, 148, 149, 151, 152, 153, 154, 155], "excluded_lines": [], "executed_branches": [[37, 45], [45, 50]], "missing_branches": [[37, 38], [45, 54], [59, 60], [59, 63], [69, 70], [69, 71], [96, 97], [96, 98], [102, 103], [102, 123], [104, 105], [104, 123], [105, 106], [105, 107], [111, 112], [111, 113], [134, 135], [134, 146]], "functions": {"upload_to_nextcloud": {"executed_lines": [27, 28, 29, 37, 45, 50, 51, 52], "summary": {"covered_lines": 8, "num_statements": 61, "percent_covered": 12.345679012345679, "percent_covered_display": "12.35", "missing_lines": 53, "excluded_lines": 0, "percent_statements_covered": 13.114754098360656, "percent_statements_covered_display": "13.11", "num_branches": 20, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 18, "percent_branches_covered": 10.0, "percent_branches_covered_display": "10.00"}, "missing_lines": [38, 39, 40, 41, 54, 56, 58, 59, 60, 63, 64, 65, 68, 69, 70, 71, 74, 91, 92, 95, 96, 97, 98, 101, 102, 103, 104, 105, 106, 107, 108, 110, 111, 112, 113, 115, 123, 124, 125, 126, 134, 135, 136, 139, 146, 147, 148, 149, 151, 152, 153, 154, 155], "excluded_lines": [], "start_line": 19, "executed_branches": [[37, 45], [45, 50]], "missing_branches": [[37, 38], [45, 54], [59, 60], [59, 63], [69, 70], [69, 71], [96, 97], [96, 98], [102, 103], [102, 123], [104, 105], [104, 123], [105, 106], [105, 107], [111, 112], [111, 113], [134, 135], [134, 146]]}, "upload_to_nextcloud.check_exists_in_nextcloud": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 6, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [75, 76, 77, 85, 86, 88], "excluded_lines": [], "start_line": 74, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [3, 4, 6, 7, 9, 10, 11, 12, 13, 15, 18, 19], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 6, 7, 9, 10, 11, 12, 13, 15, 18, 19, 27, 28, 29, 37, 45, 50, 51, 52], "summary": {"covered_lines": 20, "num_statements": 79, "percent_covered": 22.22222222222222, "percent_covered_display": "22.22", "missing_lines": 59, "excluded_lines": 0, "percent_statements_covered": 25.31645569620253, "percent_statements_covered_display": "25.32", "num_branches": 20, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 18, "percent_branches_covered": 10.0, "percent_branches_covered_display": "10.00"}, "missing_lines": [38, 39, 40, 41, 54, 56, 58, 59, 60, 63, 64, 65, 68, 69, 70, 71, 74, 75, 76, 77, 85, 86, 88, 91, 92, 95, 96, 97, 98, 101, 102, 103, 104, 105, 106, 107, 108, 110, 111, 112, 113, 115, 123, 124, 125, 126, 134, 135, 136, 139, 146, 147, 148, 149, 151, 152, 153, 154, 155], "excluded_lines": [], "start_line": 1, "executed_branches": [[37, 45], [45, 50]], "missing_branches": [[37, 38], [45, 54], [59, 60], [59, 63], [69, 70], [69, 71], [96, 97], [96, 98], [102, 103], [102, 123], [104, 105], [104, 123], [105, 106], [105, 107], [111, 112], [111, 113], [134, 135], [134, 146]]}}}, "app/tasks/upload_to_onedrive.py": {"executed_lines": [3, 4, 5, 6, 8, 9, 11, 12, 13, 14, 16, 19, 100, 146, 212, 213, 221, 222, 223, 231, 232, 233, 234, 235, 238, 241, 247, 249, 252, 255, 258, 259, 260, 261, 265], "summary": {"covered_lines": 35, "num_statements": 133, "percent_covered": 22.75449101796407, "percent_covered_display": "22.75", "missing_lines": 98, "excluded_lines": 0, "percent_statements_covered": 26.31578947368421, "percent_statements_covered_display": "26.32", "num_branches": 34, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 31, "percent_branches_covered": 8.823529411764707, "percent_branches_covered_display": "8.82"}, "missing_lines": [26, 27, 30, 31, 34, 37, 39, 46, 47, 51, 52, 53, 56, 57, 58, 60, 61, 62, 64, 67, 68, 69, 72, 73, 75, 78, 79, 80, 87, 89, 90, 91, 92, 94, 97, 103, 106, 108, 111, 112, 115, 116, 119, 120, 122, 125, 127, 129, 131, 133, 134, 135, 136, 138, 139, 140, 141, 142, 143, 152, 155, 158, 160, 161, 162, 163, 164, 167, 168, 171, 174, 177, 178, 180, 181, 182, 187, 189, 191, 192, 193, 194, 195, 196, 197, 199, 200, 205, 209, 242, 243, 244, 245, 272, 273, 274, 275, 276], "excluded_lines": [], "executed_branches": [[231, 232], [231, 238], [241, 247]], "missing_branches": [[26, 27], [26, 30], [37, 39], [37, 78], [51, 52], [51, 67], [60, 61], [60, 64], [67, 68], [67, 75], [78, 79], [78, 97], [89, 90], [89, 94], [106, 108], [106, 119], [133, 134], [133, 138], [163, 164], [163, 167], [180, 181], [180, 199], [187, 189], [187, 191], [192, 180], [192, 193], [196, 180], [196, 197], [199, 200], [199, 205], [241, 242]], "functions": {"get_onedrive_token": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 35, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 35, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 14, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 14, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [26, 27, 30, 31, 34, 37, 39, 46, 47, 51, 52, 53, 56, 57, 58, 60, 61, 62, 64, 67, 68, 69, 72, 73, 75, 78, 79, 80, 87, 89, 90, 91, 92, 94, 97], "excluded_lines": [], "start_line": 19, "executed_branches": [], "missing_branches": [[26, 27], [26, 30], [37, 39], [37, 78], [51, 52], [51, 67], [60, 61], [60, 64], [67, 68], [67, 75], [78, 79], [78, 97], [89, 90], [89, 94]]}, "create_upload_session": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 24, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 24, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 4, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [103, 106, 108, 111, 112, 115, 116, 119, 120, 122, 125, 127, 129, 131, 133, 134, 135, 136, 138, 139, 140, 141, 142, 143], "excluded_lines": [], "start_line": 100, "executed_branches": [], "missing_branches": [[106, 108], [106, 119], [133, 134], [133, 138]]}, "upload_large_file": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 30, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 30, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 12, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [152, 155, 158, 160, 161, 162, 163, 164, 167, 168, 171, 174, 177, 178, 180, 181, 182, 187, 189, 191, 192, 193, 194, 195, 196, 197, 199, 200, 205, 209], "excluded_lines": [], "start_line": 146, "executed_branches": [], "missing_branches": [[163, 164], [163, 167], [180, 181], [180, 199], [187, 189], [187, 191], [192, 180], [192, 193], [196, 180], [196, 197], [199, 200], [199, 205]]}, "upload_to_onedrive": {"executed_lines": [221, 222, 223, 231, 232, 233, 234, 235, 238, 241, 247, 249, 252, 255, 258, 259, 260, 261, 265], "summary": {"covered_lines": 19, "num_statements": 28, "percent_covered": 68.75, "percent_covered_display": "68.75", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 67.85714285714286, "percent_statements_covered_display": "67.86", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [242, 243, 244, 245, 272, 273, 274, 275, 276], "excluded_lines": [], "start_line": 213, "executed_branches": [[231, 232], [231, 238], [241, 247]], "missing_branches": [[241, 242]]}, "": {"executed_lines": [3, 4, 5, 6, 8, 9, 11, 12, 13, 14, 16, 19, 100, 146, 212, 213], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 5, 6, 8, 9, 11, 12, 13, 14, 16, 19, 100, 146, 212, 213, 221, 222, 223, 231, 232, 233, 234, 235, 238, 241, 247, 249, 252, 255, 258, 259, 260, 261, 265], "summary": {"covered_lines": 35, "num_statements": 133, "percent_covered": 22.75449101796407, "percent_covered_display": "22.75", "missing_lines": 98, "excluded_lines": 0, "percent_statements_covered": 26.31578947368421, "percent_statements_covered_display": "26.32", "num_branches": 34, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 31, "percent_branches_covered": 8.823529411764707, "percent_branches_covered_display": "8.82"}, "missing_lines": [26, 27, 30, 31, 34, 37, 39, 46, 47, 51, 52, 53, 56, 57, 58, 60, 61, 62, 64, 67, 68, 69, 72, 73, 75, 78, 79, 80, 87, 89, 90, 91, 92, 94, 97, 103, 106, 108, 111, 112, 115, 116, 119, 120, 122, 125, 127, 129, 131, 133, 134, 135, 136, 138, 139, 140, 141, 142, 143, 152, 155, 158, 160, 161, 162, 163, 164, 167, 168, 171, 174, 177, 178, 180, 181, 182, 187, 189, 191, 192, 193, 194, 195, 196, 197, 199, 200, 205, 209, 242, 243, 244, 245, 272, 273, 274, 275, 276], "excluded_lines": [], "start_line": 1, "executed_branches": [[231, 232], [231, 238], [241, 247]], "missing_branches": [[26, 27], [26, 30], [37, 39], [37, 78], [51, 52], [51, 67], [60, 61], [60, 64], [67, 68], [67, 75], [78, 79], [78, 97], [89, 90], [89, 94], [106, 108], [106, 119], [133, 134], [133, 138], [163, 164], [163, 167], [180, 181], [180, 199], [187, 189], [187, 191], [192, 180], [192, 193], [196, 180], [196, 197], [199, 200], [199, 205], [241, 242]]}}}, "app/tasks/upload_to_paperless.py": {"executed_lines": [3, 4, 5, 6, 7, 9, 11, 12, 13, 14, 16, 18, 19, 21, 24, 29, 40, 59, 75, 124, 156, 202, 203], "summary": {"covered_lines": 23, "num_statements": 191, "percent_covered": 9.31174089068826, "percent_covered_display": "9.31", "missing_lines": 168, "excluded_lines": 0, "percent_statements_covered": 12.041884816753926, "percent_statements_covered_display": "12.04", "num_branches": 56, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 56, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [26, 34, 35, 36, 37, 50, 51, 52, 54, 55, 56, 69, 70, 71, 72, 84, 85, 87, 88, 89, 92, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 118, 119, 121, 137, 138, 139, 140, 141, 144, 146, 147, 148, 150, 151, 152, 153, 165, 166, 169, 170, 171, 172, 173, 174, 175, 176, 179, 180, 181, 183, 184, 185, 188, 189, 191, 192, 193, 194, 195, 196, 197, 199, 211, 212, 213, 221, 222, 223, 224, 225, 228, 231, 232, 233, 234, 235, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 249, 252, 253, 254, 255, 256, 259, 261, 262, 263, 266, 267, 268, 269, 270, 276, 287, 289, 290, 291, 294, 295, 296, 297, 298, 299, 307, 314, 315, 320, 323, 324, 326, 327, 330, 331, 333, 334, 335, 336, 337, 338, 339, 340, 343, 345, 346, 347, 350, 351, 352, 354, 355, 356, 363, 364, 365, 368, 370], "excluded_lines": [], "executed_branches": [], "missing_branches": [[35, 36], [35, 37], [50, 51], [50, 52], [54, 55], [54, 56], [69, 70], [69, 71], [87, 88], [87, 121], [100, 101], [100, 103], [103, 104], [103, 118], [106, 107], [106, 111], [108, 109], [108, 110], [111, 112], [111, 118], [113, 114], [113, 116], [146, 147], [146, 150], [147, 146], [147, 148], [165, 166], [165, 169], [170, 171], [170, 183], [172, 170], [172, 173], [183, 184], [183, 188], [221, 222], [221, 228], [231, 232], [231, 238], [240, 241], [240, 249], [297, 298], [297, 314], [323, 324], [323, 343], [330, 331], [330, 343], [331, 330], [331, 333], [334, 330], [334, 335], [343, 345], [343, 350], [345, 346], [345, 350], [350, 351], [350, 368]], "functions": {"_get_headers": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [26], "excluded_lines": [], "start_line": 24, "executed_branches": [], "missing_branches": []}, "_paperless_api_url": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [34, 35, 36, 37], "excluded_lines": [], "start_line": 29, "executed_branches": [], "missing_branches": [[35, 36], [35, 37]]}, "normalize_metadata_value": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 6, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 4, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [50, 51, 52, 54, 55, 56], "excluded_lines": [], "start_line": 40, "executed_branches": [], "missing_branches": [[50, 51], [50, 52], [54, 55], [54, 56]]}, "_is_duplicate_error": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [69, 70, 71, 72], "excluded_lines": [], "start_line": 59, "executed_branches": [], "missing_branches": [[69, 70], [69, 71]]}, "poll_task_for_document_id": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 31, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 31, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 14, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 14, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [84, 85, 87, 88, 89, 92, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 118, 119, 121], "excluded_lines": [], "start_line": 75, "executed_branches": [], "missing_branches": [[87, 88], [87, 121], [100, 101], [100, 103], [103, 104], [103, 118], [106, 107], [106, 111], [108, 109], [108, 110], [111, 112], [111, 118], [113, 114], [113, 116]]}, "get_custom_field_id": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 13, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 13, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 4, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [137, 138, 139, 140, 141, 144, 146, 147, 148, 150, 151, 152, 153], "excluded_lines": [], "start_line": 124, "executed_branches": [], "missing_branches": [[146, 147], [146, 150], [147, 146], [147, 148]]}, "set_document_custom_fields": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 26, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 26, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [165, 166, 169, 170, 171, 172, 173, 174, 175, 176, 179, 180, 181, 183, 184, 185, 188, 189, 191, 192, 193, 194, 195, 196, 197, 199], "excluded_lines": [], "start_line": 156, "executed_branches": [], "missing_branches": [[165, 166], [165, 169], [170, 171], [170, 183], [172, 170], [172, 173], [183, 184], [183, 188]]}, "upload_to_paperless": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 83, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 83, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 22, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 22, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [211, 212, 213, 221, 222, 223, 224, 225, 228, 231, 232, 233, 234, 235, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 249, 252, 253, 254, 255, 256, 259, 261, 262, 263, 266, 267, 268, 269, 270, 276, 287, 289, 290, 291, 294, 295, 296, 297, 298, 299, 307, 314, 315, 320, 323, 324, 326, 327, 330, 331, 333, 334, 335, 336, 337, 338, 339, 340, 343, 345, 346, 347, 350, 351, 352, 354, 355, 356, 363, 364, 365, 368, 370], "excluded_lines": [], "start_line": 203, "executed_branches": [], "missing_branches": [[221, 222], [221, 228], [231, 232], [231, 238], [240, 241], [240, 249], [297, 298], [297, 314], [323, 324], [323, 343], [330, 331], [330, 343], [331, 330], [331, 333], [334, 330], [334, 335], [343, 345], [343, 350], [345, 346], [345, 350], [350, 351], [350, 368]]}, "": {"executed_lines": [3, 4, 5, 6, 7, 9, 11, 12, 13, 14, 16, 18, 19, 21, 24, 29, 40, 59, 75, 124, 156, 202, 203], "summary": {"covered_lines": 23, "num_statements": 23, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 5, 6, 7, 9, 11, 12, 13, 14, 16, 18, 19, 21, 24, 29, 40, 59, 75, 124, 156, 202, 203], "summary": {"covered_lines": 23, "num_statements": 191, "percent_covered": 9.31174089068826, "percent_covered_display": "9.31", "missing_lines": 168, "excluded_lines": 0, "percent_statements_covered": 12.041884816753926, "percent_statements_covered_display": "12.04", "num_branches": 56, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 56, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [26, 34, 35, 36, 37, 50, 51, 52, 54, 55, 56, 69, 70, 71, 72, 84, 85, 87, 88, 89, 92, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 118, 119, 121, 137, 138, 139, 140, 141, 144, 146, 147, 148, 150, 151, 152, 153, 165, 166, 169, 170, 171, 172, 173, 174, 175, 176, 179, 180, 181, 183, 184, 185, 188, 189, 191, 192, 193, 194, 195, 196, 197, 199, 211, 212, 213, 221, 222, 223, 224, 225, 228, 231, 232, 233, 234, 235, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 249, 252, 253, 254, 255, 256, 259, 261, 262, 263, 266, 267, 268, 269, 270, 276, 287, 289, 290, 291, 294, 295, 296, 297, 298, 299, 307, 314, 315, 320, 323, 324, 326, 327, 330, 331, 333, 334, 335, 336, 337, 338, 339, 340, 343, 345, 346, 347, 350, 351, 352, 354, 355, 356, 363, 364, 365, 368, 370], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": [[35, 36], [35, 37], [50, 51], [50, 52], [54, 55], [54, 56], [69, 70], [69, 71], [87, 88], [87, 121], [100, 101], [100, 103], [103, 104], [103, 118], [106, 107], [106, 111], [108, 109], [108, 110], [111, 112], [111, 118], [113, 114], [113, 116], [146, 147], [146, 150], [147, 146], [147, 148], [165, 166], [165, 169], [170, 171], [170, 183], [172, 170], [172, 173], [183, 184], [183, 188], [221, 222], [221, 228], [231, 232], [231, 238], [240, 241], [240, 249], [297, 298], [297, 314], [323, 324], [323, 343], [330, 331], [330, 343], [331, 330], [331, 333], [334, 330], [334, 335], [343, 345], [343, 350], [345, 346], [345, 350], [350, 351], [350, 368]]}}}, "app/tasks/upload_to_s3.py": {"executed_lines": [3, 4, 6, 7, 9, 10, 11, 12, 14, 17, 18, 26, 27, 28, 32, 33, 34, 35, 36, 39, 42, 48, 54, 56, 64, 66, 67, 68, 69, 74, 77, 81, 85, 87, 90, 91], "summary": {"covered_lines": 36, "num_statements": 56, "percent_covered": 63.23529411764706, "percent_covered_display": "63.24", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 64.28571428571429, "percent_statements_covered_display": "64.29", "num_branches": 12, "num_partial_branches": 5, "covered_branches": 7, "missing_branches": 5, "percent_branches_covered": 58.333333333333336, "percent_branches_covered_display": "58.33"}, "missing_lines": [43, 44, 45, 46, 49, 50, 51, 52, 71, 78, 99, 100, 101, 102, 103, 105, 106, 107, 108, 109], "excluded_lines": [], "executed_branches": [[32, 33], [32, 39], [42, 48], [48, 54], [64, 66], [67, 68], [77, 81]], "missing_branches": [[42, 43], [48, 49], [64, 71], [67, 69], [77, 78]], "functions": {"upload_to_s3": {"executed_lines": [26, 27, 28, 32, 33, 34, 35, 36, 39, 42, 48, 54, 56, 64, 66, 67, 68, 69, 74, 77, 81, 85, 87, 90, 91], "summary": {"covered_lines": 25, "num_statements": 45, "percent_covered": 56.14035087719298, "percent_covered_display": "56.14", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 55.55555555555556, "percent_statements_covered_display": "55.56", "num_branches": 12, "num_partial_branches": 5, "covered_branches": 7, "missing_branches": 5, "percent_branches_covered": 58.333333333333336, "percent_branches_covered_display": "58.33"}, "missing_lines": [43, 44, 45, 46, 49, 50, 51, 52, 71, 78, 99, 100, 101, 102, 103, 105, 106, 107, 108, 109], "excluded_lines": [], "start_line": 18, "executed_branches": [[32, 33], [32, 39], [42, 48], [48, 54], [64, 66], [67, 68], [77, 81]], "missing_branches": [[42, 43], [48, 49], [64, 71], [67, 69], [77, 78]]}, "": {"executed_lines": [3, 4, 6, 7, 9, 10, 11, 12, 14, 17, 18], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 6, 7, 9, 10, 11, 12, 14, 17, 18, 26, 27, 28, 32, 33, 34, 35, 36, 39, 42, 48, 54, 56, 64, 66, 67, 68, 69, 74, 77, 81, 85, 87, 90, 91], "summary": {"covered_lines": 36, "num_statements": 56, "percent_covered": 63.23529411764706, "percent_covered_display": "63.24", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 64.28571428571429, "percent_statements_covered_display": "64.29", "num_branches": 12, "num_partial_branches": 5, "covered_branches": 7, "missing_branches": 5, "percent_branches_covered": 58.333333333333336, "percent_branches_covered_display": "58.33"}, "missing_lines": [43, 44, 45, 46, 49, 50, 51, 52, 71, 78, 99, 100, 101, 102, 103, 105, 106, 107, 108, 109], "excluded_lines": [], "start_line": 1, "executed_branches": [[32, 33], [32, 39], [42, 48], [48, 54], [64, 66], [67, 68], [77, 81]], "missing_branches": [[42, 43], [48, 49], [64, 71], [67, 69], [77, 78]]}}}, "app/tasks/upload_to_sftp.py": {"executed_lines": [3, 4, 6, 8, 9, 10, 11, 12, 14, 17, 18, 26, 27, 28, 32, 33, 34, 35, 36, 38, 44, 45, 48, 53, 54, 59, 65, 67, 74, 75, 77, 78, 79, 80, 81, 91, 92, 95, 98, 99, 102, 106, 114, 117, 118, 119, 121, 122, 123, 124, 125, 126, 127, 135, 136, 137, 138, 141, 142, 144], "summary": {"covered_lines": 60, "num_statements": 94, "percent_covered": 62.06896551724138, "percent_covered_display": "62.07", "missing_lines": 34, "excluded_lines": 0, "percent_statements_covered": 63.829787234042556, "percent_statements_covered_display": "63.83", "num_branches": 22, "num_partial_branches": 6, "covered_branches": 12, "missing_branches": 10, "percent_branches_covered": 54.54545454545455, "percent_branches_covered_display": "54.55"}, "missing_lines": [39, 40, 41, 42, 62, 63, 82, 83, 84, 86, 87, 88, 103, 107, 108, 109, 110, 111, 128, 129, 130, 131, 132, 146, 148, 149, 150, 151, 152, 153, 155, 156, 157, 158], "excluded_lines": [], "executed_branches": [[32, 33], [32, 38], [38, 44], [53, 54], [77, 78], [80, 81], [102, 106], [118, 119], [122, 123], [122, 135], [123, 124], [123, 125]], "missing_branches": [[38, 39], [53, 62], [77, 82], [80, 91], [82, 83], [82, 86], [102, 103], [118, 135], [149, 150], [149, 151]], "functions": {"upload_to_sftp": {"executed_lines": [26, 27, 28, 32, 33, 34, 35, 36, 38, 44, 45, 48, 53, 54, 59, 65, 67, 74, 75, 77, 78, 79, 80, 81, 91, 92, 95, 98, 99, 102, 106, 114, 117, 118, 119, 121, 122, 123, 124, 125, 126, 127, 135, 136, 137, 138, 141, 142, 144], "summary": {"covered_lines": 49, "num_statements": 78, "percent_covered": 61.0, "percent_covered_display": "61.00", "missing_lines": 29, "excluded_lines": 0, "percent_statements_covered": 62.82051282051282, "percent_statements_covered_display": "62.82", "num_branches": 22, "num_partial_branches": 6, "covered_branches": 12, "missing_branches": 10, "percent_branches_covered": 54.54545454545455, "percent_branches_covered_display": "54.55"}, "missing_lines": [39, 40, 41, 42, 62, 63, 82, 83, 84, 86, 87, 88, 103, 128, 129, 130, 131, 132, 146, 148, 149, 150, 151, 152, 153, 155, 156, 157, 158], "excluded_lines": [], "start_line": 18, "executed_branches": [[32, 33], [32, 38], [38, 44], [53, 54], [77, 78], [80, 81], [102, 106], [118, 119], [122, 123], [122, 135], [123, 124], [123, 125]], "missing_branches": [[38, 39], [53, 62], [77, 82], [80, 91], [82, 83], [82, 86], [102, 103], [118, 135], [149, 150], [149, 151]]}, "upload_to_sftp.check_exists_in_sftp": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [107, 108, 109, 110, 111], "excluded_lines": [], "start_line": 106, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [3, 4, 6, 8, 9, 10, 11, 12, 14, 17, 18], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 6, 8, 9, 10, 11, 12, 14, 17, 18, 26, 27, 28, 32, 33, 34, 35, 36, 38, 44, 45, 48, 53, 54, 59, 65, 67, 74, 75, 77, 78, 79, 80, 81, 91, 92, 95, 98, 99, 102, 106, 114, 117, 118, 119, 121, 122, 123, 124, 125, 126, 127, 135, 136, 137, 138, 141, 142, 144], "summary": {"covered_lines": 60, "num_statements": 94, "percent_covered": 62.06896551724138, "percent_covered_display": "62.07", "missing_lines": 34, "excluded_lines": 0, "percent_statements_covered": 63.829787234042556, "percent_statements_covered_display": "63.83", "num_branches": 22, "num_partial_branches": 6, "covered_branches": 12, "missing_branches": 10, "percent_branches_covered": 54.54545454545455, "percent_branches_covered_display": "54.55"}, "missing_lines": [39, 40, 41, 42, 62, 63, 82, 83, 84, 86, 87, 88, 103, 107, 108, 109, 110, 111, 128, 129, 130, 131, 132, 146, 148, 149, 150, 151, 152, 153, 155, 156, 157, 158], "excluded_lines": [], "start_line": 1, "executed_branches": [[32, 33], [32, 38], [38, 44], [53, 54], [77, 78], [80, 81], [102, 106], [118, 119], [122, 123], [122, 135], [123, 124], [123, 125]], "missing_branches": [[38, 39], [53, 62], [77, 82], [80, 91], [82, 83], [82, 86], [102, 103], [118, 135], [149, 150], [149, 151]]}}}, "app/tasks/upload_to_webdav.py": {"executed_lines": [3, 4, 5, 7, 9, 10, 11, 12, 14, 17, 18, 26, 27, 28, 36, 37, 38, 39, 40, 43, 46, 47, 48, 49, 50, 53, 55, 56, 59, 61, 62, 65, 68, 69, 70, 79, 80, 81, 84, 86, 87, 88, 89, 91, 92, 93, 94, 95], "summary": {"covered_lines": 48, "num_statements": 48, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 10, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[36, 37], [36, 43], [46, 47], [46, 53], [55, 56], [55, 59], [61, 62], [61, 65], [79, 80], [79, 86]], "missing_branches": [], "functions": {"upload_to_webdav": {"executed_lines": [26, 27, 28, 36, 37, 38, 39, 40, 43, 46, 47, 48, 49, 50, 53, 55, 56, 59, 61, 62, 65, 68, 69, 70, 79, 80, 81, 84, 86, 87, 88, 89, 91, 92, 93, 94, 95], "summary": {"covered_lines": 37, "num_statements": 37, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 10, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 18, "executed_branches": [[36, 37], [36, 43], [46, 47], [46, 53], [55, 56], [55, 59], [61, 62], [61, 65], [79, 80], [79, 86]], "missing_branches": []}, "": {"executed_lines": [3, 4, 5, 7, 9, 10, 11, 12, 14, 17, 18], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 5, 7, 9, 10, 11, 12, 14, 17, 18, 26, 27, 28, 36, 37, 38, 39, 40, 43, 46, 47, 48, 49, 50, 53, 55, 56, 59, 61, 62, 65, 68, 69, 70, 79, 80, 81, 84, 86, 87, 88, 89, 91, 92, 93, 94, 95], "summary": {"covered_lines": 48, "num_statements": 48, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 10, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[36, 37], [36, 43], [46, 47], [46, 53], [55, 56], [55, 59], [61, 62], [61, 65], [79, 80], [79, 86]], "missing_branches": []}}}, "app/tasks/upload_with_rclone.py": {"executed_lines": [3, 4, 5, 7, 8, 9, 10, 12, 15, 16, 25, 27, 28, 31, 33, 36, 37, 40, 44, 45, 48, 49, 50, 51, 52, 110, 111], "summary": {"covered_lines": 27, "num_statements": 98, "percent_covered": 27.868852459016395, "percent_covered_display": "27.87", "missing_lines": 71, "excluded_lines": 0, "percent_statements_covered": 27.551020408163264, "percent_statements_covered_display": "27.55", "num_branches": 24, "num_partial_branches": 1, "covered_branches": 7, "missing_branches": 17, "percent_branches_covered": 29.166666666666668, "percent_branches_covered_display": "29.17"}, "missing_lines": [54, 56, 58, 60, 63, 65, 68, 71, 73, 74, 75, 76, 77, 78, 79, 81, 82, 89, 91, 92, 93, 95, 96, 97, 98, 101, 103, 104, 105, 106, 107, 116, 118, 119, 122, 124, 129, 130, 131, 132, 133, 136, 137, 138, 140, 142, 145, 146, 147, 148, 149, 150, 153, 156, 157, 158, 159, 160, 162, 163, 164, 166, 172, 174, 175, 176, 178, 179, 180, 181, 188], "excluded_lines": [], "executed_branches": [[27, 28], [27, 31], [36, 37], [36, 40], [44, 45], [44, 48], [49, 50]], "missing_branches": [[49, 54], [71, 73], [71, 91], [118, 119], [118, 122], [130, 131], [130, 136], [140, 142], [140, 174], [146, 147], [146, 156], [149, 150], [149, 153], [157, 158], [157, 166], [159, 160], [159, 162]], "functions": {"upload_with_rclone": {"executed_lines": [25, 27, 28, 31, 33, 36, 37, 40, 44, 45, 48, 49, 50, 51, 52], "summary": {"covered_lines": 15, "num_statements": 46, "percent_covered": 39.285714285714285, "percent_covered_display": "39.29", "missing_lines": 31, "excluded_lines": 0, "percent_statements_covered": 32.608695652173914, "percent_statements_covered_display": "32.61", "num_branches": 10, "num_partial_branches": 1, "covered_branches": 7, "missing_branches": 3, "percent_branches_covered": 70.0, "percent_branches_covered_display": "70.00"}, "missing_lines": [54, 56, 58, 60, 63, 65, 68, 71, 73, 74, 75, 76, 77, 78, 79, 81, 82, 89, 91, 92, 93, 95, 96, 97, 98, 101, 103, 104, 105, 106, 107], "excluded_lines": [], "start_line": 16, "executed_branches": [[27, 28], [27, 31], [36, 37], [36, 40], [44, 45], [44, 48], [49, 50]], "missing_branches": [[49, 54], [71, 73], [71, 91]]}, "send_to_all_rclone_destinations": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 40, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 40, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 14, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 14, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [116, 118, 119, 122, 124, 129, 130, 131, 132, 133, 136, 137, 138, 140, 142, 145, 146, 147, 148, 149, 150, 153, 156, 157, 158, 159, 160, 162, 163, 164, 166, 172, 174, 175, 176, 178, 179, 180, 181, 188], "excluded_lines": [], "start_line": 111, "executed_branches": [], "missing_branches": [[118, 119], [118, 122], [130, 131], [130, 136], [140, 142], [140, 174], [146, 147], [146, 156], [149, 150], [149, 153], [157, 158], [157, 166], [159, 160], [159, 162]]}, "": {"executed_lines": [3, 4, 5, 7, 8, 9, 10, 12, 15, 16, 110, 111], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 5, 7, 8, 9, 10, 12, 15, 16, 25, 27, 28, 31, 33, 36, 37, 40, 44, 45, 48, 49, 50, 51, 52, 110, 111], "summary": {"covered_lines": 27, "num_statements": 98, "percent_covered": 27.868852459016395, "percent_covered_display": "27.87", "missing_lines": 71, "excluded_lines": 0, "percent_statements_covered": 27.551020408163264, "percent_statements_covered_display": "27.55", "num_branches": 24, "num_partial_branches": 1, "covered_branches": 7, "missing_branches": 17, "percent_branches_covered": 29.166666666666668, "percent_branches_covered_display": "29.17"}, "missing_lines": [54, 56, 58, 60, 63, 65, 68, 71, 73, 74, 75, 76, 77, 78, 79, 81, 82, 89, 91, 92, 93, 95, 96, 97, 98, 101, 103, 104, 105, 106, 107, 116, 118, 119, 122, 124, 129, 130, 131, 132, 133, 136, 137, 138, 140, 142, 145, 146, 147, 148, 149, 150, 153, 156, 157, 158, 159, 160, 162, 163, 164, 166, 172, 174, 175, 176, 178, 179, 180, 181, 188], "excluded_lines": [], "start_line": 1, "executed_branches": [[27, 28], [27, 31], [36, 37], [36, 40], [44, 45], [44, 48], [49, 50]], "missing_branches": [[49, 54], [71, 73], [71, 91], [118, 119], [118, 122], [130, 131], [130, 136], [140, 142], [140, 174], [146, 147], [146, 156], [149, 150], [149, 153], [157, 158], [157, 166], [159, 160], [159, 162]]}}}, "app/tasks/uptime_kuma_tasks.py": {"executed_lines": [3, 5, 6, 8, 10, 13, 14, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32], "summary": {"covered_lines": 19, "num_statements": 19, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[20, 21], [20, 24]], "missing_branches": [], "functions": {"ping_uptime_kuma": {"executed_lines": [20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 14, "executed_branches": [[20, 21], [20, 24]], "missing_branches": []}, "": {"executed_lines": [3, 5, 6, 8, 10, 13, 14], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 5, 6, 8, 10, 13, 14, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32], "summary": {"covered_lines": 19, "num_statements": 19, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[20, 21], [20, 24]], "missing_branches": []}}}, "app/utils/__init__.py": {"executed_lines": [6, 7, 8, 11], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [6, 7, 8, 11], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [6, 7, 8, 11], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/utils/config_loader.py": {"executed_lines": [10, 11, 13, 15, 17, 20, 31, 32, 34, 35, 36, 39, 40, 41, 42, 45, 47, 48, 50, 53, 54, 55, 57, 58, 68, 79, 80, 83, 84, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 106, 107, 111, 114], "summary": {"covered_lines": 48, "num_statements": 66, "percent_covered": 74.44444444444444, "percent_covered_display": "74.44", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 72.72727272727273, "percent_statements_covered_display": "72.73", "num_branches": 24, "num_partial_branches": 5, "covered_branches": 19, "missing_branches": 5, "percent_branches_covered": 79.16666666666667, "percent_branches_covered_display": "79.17"}, "missing_lines": [60, 62, 63, 65, 86, 87, 108, 127, 128, 130, 131, 132, 133, 134, 136, 137, 138, 139], "excluded_lines": [], "executed_branches": [[34, 35], [34, 39], [40, 41], [40, 57], [45, 47], [48, 50], [57, 58], [79, 80], [79, 83], [84, 90], [90, 91], [90, 92], [92, 93], [92, 98], [98, 99], [98, 104], [104, 106], [104, 111], [106, 107]], "missing_branches": [[45, 40], [48, 40], [57, 60], [84, 86], [106, 108]], "functions": {"load_settings_from_db": {"executed_lines": [31, 32, 34, 35, 36, 39, 40, 41, 42, 45, 47, 48, 50, 53, 54, 55, 57, 58], "summary": {"covered_lines": 18, "num_statements": 22, "percent_covered": 78.125, "percent_covered_display": "78.12", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 81.81818181818181, "percent_statements_covered_display": "81.82", "num_branches": 10, "num_partial_branches": 3, "covered_branches": 7, "missing_branches": 3, "percent_branches_covered": 70.0, "percent_branches_covered_display": "70.00"}, "missing_lines": [60, 62, 63, 65], "excluded_lines": [], "start_line": 20, "executed_branches": [[34, 35], [34, 39], [40, 41], [40, 57], [45, 47], [48, 50], [57, 58]], "missing_branches": [[45, 40], [48, 40], [57, 60]]}, "convert_setting_value": {"executed_lines": [79, 80, 83, 84, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 106, 107, 111], "summary": {"covered_lines": 22, "num_statements": 25, "percent_covered": 87.17948717948718, "percent_covered_display": "87.18", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 88.0, "percent_statements_covered_display": "88.00", "num_branches": 14, "num_partial_branches": 2, "covered_branches": 12, "missing_branches": 2, "percent_branches_covered": 85.71428571428571, "percent_branches_covered_display": "85.71"}, "missing_lines": [86, 87, 108], "excluded_lines": [], "start_line": 68, "executed_branches": [[79, 80], [79, 83], [84, 90], [90, 91], [90, 92], [92, 93], [92, 98], [98, 99], [98, 104], [104, 106], [104, 111], [106, 107]], "missing_branches": [[84, 86], [106, 108]]}, "reload_settings_from_db": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 11, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 11, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [127, 128, 130, 131, 132, 133, 134, 136, 137, 138, 139], "excluded_lines": [], "start_line": 114, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [10, 11, 13, 15, 17, 20, 68, 114], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [10, 11, 13, 15, 17, 20, 31, 32, 34, 35, 36, 39, 40, 41, 42, 45, 47, 48, 50, 53, 54, 55, 57, 58, 68, 79, 80, 83, 84, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 106, 107, 111, 114], "summary": {"covered_lines": 48, "num_statements": 66, "percent_covered": 74.44444444444444, "percent_covered_display": "74.44", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 72.72727272727273, "percent_statements_covered_display": "72.73", "num_branches": 24, "num_partial_branches": 5, "covered_branches": 19, "missing_branches": 5, "percent_branches_covered": 79.16666666666667, "percent_branches_covered_display": "79.17"}, "missing_lines": [60, 62, 63, 65, 86, 87, 108, 127, 128, 130, 131, 132, 133, 134, 136, 137, 138, 139], "excluded_lines": [], "start_line": 1, "executed_branches": [[34, 35], [34, 39], [40, 41], [40, 57], [45, 47], [48, 50], [57, 58], [79, 80], [79, 83], [84, 90], [90, 91], [90, 92], [92, 93], [92, 98], [98, 99], [98, 104], [104, 106], [104, 111], [106, 107]], "missing_branches": [[45, 40], [48, 40], [57, 60], [84, 86], [106, 108]]}}}, "app/utils/config_validator.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [7, 8, 9, 12, 19], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [7, 8, 9, 12, 19], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [7, 8, 9, 12, 19], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/utils/config_validator/__init__.py": {"executed_lines": [5, 6, 7, 8, 16], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [5, 6, 7, 8, 16], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 8, 16], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/utils/config_validator/masking.py": {"executed_lines": [6, 11, 12, 13], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[11, 12], [11, 13]], "missing_branches": [], "functions": {"mask_sensitive_value": {"executed_lines": [11, 12, 13], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 6, "executed_branches": [[11, 12], [11, 13]], "missing_branches": []}, "": {"executed_lines": [6], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [6, 11, 12, 13], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[11, 12], [11, 13]], "missing_branches": []}}}, "app/utils/config_validator/providers.py": {"executed_lines": [5, 6, 9, 13, 16, 17, 23, 25, 39, 61, 76, 90, 109, 129, 151, 157, 160, 162, 164, 190, 192, 193, 196, 216, 236, 251, 273, 295, 308, 327], "summary": {"covered_lines": 30, "num_statements": 31, "percent_covered": 93.93939393939394, "percent_covered_display": "93.94", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 96.7741935483871, "percent_statements_covered_display": "96.77", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [194], "excluded_lines": [], "executed_branches": [[193, 196]], "missing_branches": [[193, 194]], "functions": {"get_provider_status": {"executed_lines": [13, 16, 17, 23, 25, 39, 61, 76, 90, 109, 129, 151, 157, 160, 162, 164, 190, 192, 193, 196, 216, 236, 251, 273, 295, 308, 327], "summary": {"covered_lines": 27, "num_statements": 28, "percent_covered": 93.33333333333333, "percent_covered_display": "93.33", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 96.42857142857143, "percent_statements_covered_display": "96.43", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [194], "excluded_lines": [], "start_line": 9, "executed_branches": [[193, 196]], "missing_branches": [[193, 194]]}, "": {"executed_lines": [5, 6, 9], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 9, 13, 16, 17, 23, 25, 39, 61, 76, 90, 109, 129, 151, 157, 160, 162, 164, 190, 192, 193, 196, 216, 236, 251, 273, 295, 308, 327], "summary": {"covered_lines": 30, "num_statements": 31, "percent_covered": 93.93939393939394, "percent_covered_display": "93.94", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 96.7741935483871, "percent_statements_covered_display": "96.77", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [194], "excluded_lines": [], "start_line": 1, "executed_branches": [[193, 196]], "missing_branches": [[193, 194]]}}}, "app/utils/config_validator/settings_display.py": {"executed_lines": [5, 7, 8, 10, 13, 15, 16, 17, 18, 20, 26, 27, 28, 29, 30, 36, 43, 56, 57, 60, 69, 77, 188, 199, 201, 202, 203, 205, 206, 207, 210, 211, 212, 213, 214, 217, 229, 232, 235, 236, 240, 241, 242, 246, 247, 248, 250, 252, 253, 255], "summary": {"covered_lines": 50, "num_statements": 59, "percent_covered": 83.87096774193549, "percent_covered_display": "83.87", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 84.7457627118644, "percent_statements_covered_display": "84.75", "num_branches": 34, "num_partial_branches": 4, "covered_branches": 28, "missing_branches": 6, "percent_branches_covered": 82.3529411764706, "percent_branches_covered_display": "82.35"}, "missing_lines": [44, 45, 47, 48, 49, 51, 52, 53, 54], "excluded_lines": [], "executed_branches": [[16, 17], [16, 57], [17, 16], [17, 18], [20, 26], [20, 43], [26, 27], [26, 43], [27, 28], [27, 36], [43, 56], [202, 203], [202, 205], [206, 207], [210, 211], [210, 255], [212, 213], [212, 252], [213, 214], [232, 235], [232, 240], [240, 241], [240, 246], [241, 242], [241, 246], [247, 248], [247, 250], [252, 253]], "missing_branches": [[43, 44], [47, 48], [47, 51], [206, 210], [213, 212], [252, 210]], "functions": {"dump_all_settings": {"executed_lines": [15, 16, 17, 18, 20, 26, 27, 28, 29, 30, 36, 43, 56, 57], "summary": {"covered_lines": 14, "num_statements": 23, "percent_covered": 67.56756756756756, "percent_covered_display": "67.57", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 60.869565217391305, "percent_statements_covered_display": "60.87", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 11, "missing_branches": 3, "percent_branches_covered": 78.57142857142857, "percent_branches_covered_display": "78.57"}, "missing_lines": [44, 45, 47, 48, 49, 51, 52, 53, 54], "excluded_lines": [], "start_line": 13, "executed_branches": [[16, 17], [16, 57], [17, 16], [17, 18], [20, 26], [20, 43], [26, 27], [26, 43], [27, 28], [27, 36], [43, 56]], "missing_branches": [[43, 44], [47, 48], [47, 51]]}, "get_settings_for_display": {"executed_lines": [69, 77, 188, 199, 201, 202, 203, 205, 206, 207, 210, 211, 212, 213, 214, 217, 229, 232, 235, 236, 240, 241, 242, 246, 247, 248, 250, 252, 253, 255], "summary": {"covered_lines": 30, "num_statements": 30, "percent_covered": 94.0, "percent_covered_display": "94.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 20, "num_partial_branches": 3, "covered_branches": 17, "missing_branches": 3, "percent_branches_covered": 85.0, "percent_branches_covered_display": "85.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 60, "executed_branches": [[202, 203], [202, 205], [206, 207], [210, 211], [210, 255], [212, 213], [212, 252], [213, 214], [232, 235], [232, 240], [240, 241], [240, 246], [241, 242], [241, 246], [247, 248], [247, 250], [252, 253]], "missing_branches": [[206, 210], [213, 212], [252, 210]]}, "": {"executed_lines": [5, 7, 8, 10, 13, 60], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 8, 10, 13, 15, 16, 17, 18, 20, 26, 27, 28, 29, 30, 36, 43, 56, 57, 60, 69, 77, 188, 199, 201, 202, 203, 205, 206, 207, 210, 211, 212, 213, 214, 217, 229, 232, 235, 236, 240, 241, 242, 246, 247, 248, 250, 252, 253, 255], "summary": {"covered_lines": 50, "num_statements": 59, "percent_covered": 83.87096774193549, "percent_covered_display": "83.87", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 84.7457627118644, "percent_statements_covered_display": "84.75", "num_branches": 34, "num_partial_branches": 4, "covered_branches": 28, "missing_branches": 6, "percent_branches_covered": 82.3529411764706, "percent_branches_covered_display": "82.35"}, "missing_lines": [44, 45, 47, 48, 49, 51, 52, 53, 54], "excluded_lines": [], "start_line": 1, "executed_branches": [[16, 17], [16, 57], [17, 16], [17, 18], [20, 26], [20, 43], [26, 27], [26, 43], [27, 28], [27, 36], [43, 56], [202, 203], [202, 205], [206, 207], [210, 211], [210, 255], [212, 213], [212, 252], [213, 214], [232, 235], [232, 240], [240, 241], [240, 246], [241, 242], [241, 246], [247, 248], [247, 250], [252, 253]], "missing_branches": [[43, 44], [47, 48], [47, 51], [206, 210], [213, 212], [252, 210]]}}}, "app/utils/config_validator/validators.py": {"executed_lines": [3, 4, 5, 7, 9, 12, 14, 17, 18, 19, 23, 31, 32, 33, 34, 36, 39, 41, 44, 69, 72, 74, 77, 78, 83, 84, 87, 88, 93, 94, 97, 98, 99, 101, 102, 105, 106, 108, 111, 112, 113, 114, 115, 116, 119, 120, 121, 122, 123, 124, 127, 128, 129, 130, 131, 132, 133, 134, 137, 138, 139, 140, 141, 142, 143, 144, 147, 148, 149, 150, 151, 152, 155, 156, 157, 158, 159, 160, 163, 164, 169, 170, 173, 174, 175, 176, 178, 181, 183, 186, 187, 205, 208, 210, 213, 215, 217, 220, 224, 225, 228, 231, 232, 233, 238, 239, 240, 241, 246, 247, 248, 253], "summary": {"covered_lines": 112, "num_statements": 145, "percent_covered": 65.19823788546256, "percent_covered_display": "65.20", "missing_lines": 33, "excluded_lines": 0, "percent_statements_covered": 77.24137931034483, "percent_statements_covered_display": "77.24", "num_branches": 82, "num_partial_branches": 34, "covered_branches": 36, "missing_branches": 46, "percent_branches_covered": 43.90243902439025, "percent_branches_covered_display": "43.90"}, "missing_lines": [20, 24, 26, 27, 28, 46, 47, 48, 49, 52, 56, 62, 63, 66, 67, 103, 189, 191, 193, 195, 196, 197, 198, 199, 200, 202, 203, 206, 221, 226, 235, 243, 250], "excluded_lines": [], "executed_branches": [[17, 18], [19, 23], [23, 31], [31, 32], [33, 34], [44, 69], [78, 83], [88, 93], [98, 99], [102, 105], [105, 106], [112, 113], [114, 115], [120, 121], [122, 123], [128, 129], [130, 131], [132, 133], [138, 139], [140, 141], [142, 143], [148, 149], [150, 151], [156, 157], [158, 159], [164, 169], [174, 175], [186, 187], [205, 208], [220, 224], [225, 228], [232, 233], [239, 240], [239, 246], [240, 241], [247, 248]], "missing_branches": [[17, 19], [19, 20], [23, 24], [31, 33], [33, 36], [44, 46], [46, 47], [46, 48], [48, 49], [48, 52], [62, 63], [62, 66], [66, 67], [66, 69], [78, 84], [88, 94], [98, 101], [102, 103], [105, 108], [112, 114], [114, 116], [120, 122], [122, 124], [128, 130], [130, 132], [132, 134], [138, 140], [140, 142], [142, 144], [148, 150], [150, 152], [156, 158], [158, 160], [164, 170], [174, 176], [186, 189], [195, 196], [195, 205], [197, 195], [197, 198], [205, 206], [220, 221], [225, 226], [232, 235], [240, 243], [247, 250]], "functions": {"validate_email_config": {"executed_lines": [14, 17, 18, 19, 23, 31, 32, 33, 34, 36], "summary": {"covered_lines": 10, "num_statements": 15, "percent_covered": 60.0, "percent_covered_display": "60.00", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 66.66666666666667, "percent_statements_covered_display": "66.67", "num_branches": 10, "num_partial_branches": 5, "covered_branches": 5, "missing_branches": 5, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [20, 24, 26, 27, 28], "excluded_lines": [], "start_line": 12, "executed_branches": [[17, 18], [19, 23], [23, 31], [31, 32], [33, 34]], "missing_branches": [[17, 19], [19, 20], [23, 24], [31, 33], [33, 36]]}, "validate_auth_config": {"executed_lines": [41, 44, 69], "summary": {"covered_lines": 3, "num_statements": 13, "percent_covered": 17.391304347826086, "percent_covered_display": "17.39", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 23.076923076923077, "percent_statements_covered_display": "23.08", "num_branches": 10, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 9, "percent_branches_covered": 10.0, "percent_branches_covered_display": "10.00"}, "missing_lines": [46, 47, 48, 49, 52, 56, 62, 63, 66, 67], "excluded_lines": [], "start_line": 39, "executed_branches": [[44, 69]], "missing_branches": [[44, 46], [46, 47], [46, 48], [48, 49], [48, 52], [62, 63], [62, 66], [66, 67], [66, 69]]}, "validate_storage_configs": {"executed_lines": [74, 77, 78, 83, 84, 87, 88, 93, 94, 97, 98, 99, 101, 102, 105, 106, 108, 111, 112, 113, 114, 115, 116, 119, 120, 121, 122, 123, 124, 127, 128, 129, 130, 131, 132, 133, 134, 137, 138, 139, 140, 141, 142, 143, 144, 147, 148, 149, 150, 151, 152, 155, 156, 157, 158, 159, 160, 163, 164, 169, 170, 173, 174, 175, 176, 178], "summary": {"covered_lines": 66, "num_statements": 67, "percent_covered": 79.81651376146789, "percent_covered_display": "79.82", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 98.50746268656717, "percent_statements_covered_display": "98.51", "num_branches": 42, "num_partial_branches": 21, "covered_branches": 21, "missing_branches": 21, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [103], "excluded_lines": [], "start_line": 72, "executed_branches": [[78, 83], [88, 93], [98, 99], [102, 105], [105, 106], [112, 113], [114, 115], [120, 121], [122, 123], [128, 129], [130, 131], [132, 133], [138, 139], [140, 141], [142, 143], [148, 149], [150, 151], [156, 157], [158, 159], [164, 169], [174, 175]], "missing_branches": [[78, 84], [88, 94], [98, 101], [102, 103], [105, 108], [112, 114], [114, 116], [120, 122], [122, 124], [128, 130], [130, 132], [132, 134], [138, 140], [140, 142], [142, 144], [148, 150], [150, 152], [156, 158], [158, 160], [164, 170], [174, 176]]}, "validate_notification_config": {"executed_lines": [183, 186, 187, 205, 208, 210], "summary": {"covered_lines": 6, "num_statements": 18, "percent_covered": 30.76923076923077, "percent_covered_display": "30.77", "missing_lines": 12, "excluded_lines": 0, "percent_statements_covered": 33.333333333333336, "percent_statements_covered_display": "33.33", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 6, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [189, 191, 193, 195, 196, 197, 198, 199, 200, 202, 203, 206], "excluded_lines": [], "start_line": 181, "executed_branches": [[186, 187], [205, 208]], "missing_branches": [[186, 189], [195, 196], [195, 205], [197, 195], [197, 198], [205, 206]]}, "check_all_configs": {"executed_lines": [215, 217, 220, 224, 225, 228, 231, 232, 233, 238, 239, 240, 241, 246, 247, 248, 253], "summary": {"covered_lines": 17, "num_statements": 22, "percent_covered": 70.58823529411765, "percent_covered_display": "70.59", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 77.27272727272727, "percent_statements_covered_display": "77.27", "num_branches": 12, "num_partial_branches": 5, "covered_branches": 7, "missing_branches": 5, "percent_branches_covered": 58.333333333333336, "percent_branches_covered_display": "58.33"}, "missing_lines": [221, 226, 235, 243, 250], "excluded_lines": [], "start_line": 213, "executed_branches": [[220, 224], [225, 228], [232, 233], [239, 240], [239, 246], [240, 241], [247, 248]], "missing_branches": [[220, 221], [225, 226], [232, 235], [240, 243], [247, 250]]}, "": {"executed_lines": [3, 4, 5, 7, 9, 12, 39, 72, 181, 213], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 5, 7, 9, 12, 14, 17, 18, 19, 23, 31, 32, 33, 34, 36, 39, 41, 44, 69, 72, 74, 77, 78, 83, 84, 87, 88, 93, 94, 97, 98, 99, 101, 102, 105, 106, 108, 111, 112, 113, 114, 115, 116, 119, 120, 121, 122, 123, 124, 127, 128, 129, 130, 131, 132, 133, 134, 137, 138, 139, 140, 141, 142, 143, 144, 147, 148, 149, 150, 151, 152, 155, 156, 157, 158, 159, 160, 163, 164, 169, 170, 173, 174, 175, 176, 178, 181, 183, 186, 187, 205, 208, 210, 213, 215, 217, 220, 224, 225, 228, 231, 232, 233, 238, 239, 240, 241, 246, 247, 248, 253], "summary": {"covered_lines": 112, "num_statements": 145, "percent_covered": 65.19823788546256, "percent_covered_display": "65.20", "missing_lines": 33, "excluded_lines": 0, "percent_statements_covered": 77.24137931034483, "percent_statements_covered_display": "77.24", "num_branches": 82, "num_partial_branches": 34, "covered_branches": 36, "missing_branches": 46, "percent_branches_covered": 43.90243902439025, "percent_branches_covered_display": "43.90"}, "missing_lines": [20, 24, 26, 27, 28, 46, 47, 48, 49, 52, 56, 62, 63, 66, 67, 103, 189, 191, 193, 195, 196, 197, 198, 199, 200, 202, 203, 206, 221, 226, 235, 243, 250], "excluded_lines": [], "start_line": 1, "executed_branches": [[17, 18], [19, 23], [23, 31], [31, 32], [33, 34], [44, 69], [78, 83], [88, 93], [98, 99], [102, 105], [105, 106], [112, 113], [114, 115], [120, 121], [122, 123], [128, 129], [130, 131], [132, 133], [138, 139], [140, 141], [142, 143], [148, 149], [150, 151], [156, 157], [158, 159], [164, 169], [174, 175], [186, 187], [205, 208], [220, 224], [225, 228], [232, 233], [239, 240], [239, 246], [240, 241], [247, 248]], "missing_branches": [[17, 19], [19, 20], [23, 24], [31, 33], [33, 36], [44, 46], [46, 47], [46, 48], [48, 49], [48, 52], [62, 63], [62, 66], [66, 67], [66, 69], [78, 84], [88, 94], [98, 101], [102, 103], [105, 108], [112, 114], [114, 116], [120, 122], [122, 124], [128, 130], [130, 132], [132, 134], [138, 140], [140, 142], [142, 144], [148, 150], [150, 152], [156, 158], [158, 160], [164, 170], [174, 176], [186, 189], [195, 196], [195, 205], [197, 195], [197, 198], [205, 206], [220, 221], [225, 226], [232, 235], [240, 243], [247, 250]]}}}, "app/utils/encryption.py": {"executed_lines": [8, 9, 10, 11, 13, 16, 19, 33, 34, 35, 37, 41, 44, 45, 47, 48, 61, 64, 74, 75, 77, 79, 81, 82, 84, 85, 87, 88, 89, 91, 94, 104, 105, 108, 110, 112, 114, 115, 116, 118, 120, 121, 122, 123, 124, 125, 128, 138, 141, 148], "summary": {"covered_lines": 50, "num_statements": 56, "percent_covered": 91.17647058823529, "percent_covered_display": "91.18", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 89.28571428571429, "percent_statements_covered_display": "89.29", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 12, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [50, 51, 56, 57, 58, 59], "excluded_lines": [], "executed_branches": [[33, 34], [33, 61], [74, 75], [74, 77], [79, 81], [79, 84], [104, 105], [104, 108], [108, 110], [108, 112], [114, 115], [114, 118]], "missing_branches": [], "functions": {"_get_cipher_suite": {"executed_lines": [33, 34, 35, 37, 41, 44, 45, 47, 48, 61], "summary": {"covered_lines": 10, "num_statements": 16, "percent_covered": 66.66666666666667, "percent_covered_display": "66.67", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 62.5, "percent_statements_covered_display": "62.50", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [50, 51, 56, 57, 58, 59], "excluded_lines": [], "start_line": 19, "executed_branches": [[33, 34], [33, 61]], "missing_branches": []}, "encrypt_value": {"executed_lines": [74, 75, 77, 79, 81, 82, 84, 85, 87, 88, 89, 91], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 64, "executed_branches": [[74, 75], [74, 77], [79, 81], [79, 84]], "missing_branches": []}, "decrypt_value": {"executed_lines": [104, 105, 108, 110, 112, 114, 115, 116, 118, 120, 121, 122, 123, 124, 125], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 94, "executed_branches": [[104, 105], [104, 108], [108, 110], [108, 112], [114, 115], [114, 118]], "missing_branches": []}, "is_encrypted": {"executed_lines": [138], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 128, "executed_branches": [], "missing_branches": []}, "is_encryption_available": {"executed_lines": [148], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 141, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [8, 9, 10, 11, 13, 16, 19, 64, 94, 128, 141], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [8, 9, 10, 11, 13, 16, 19, 33, 34, 35, 37, 41, 44, 45, 47, 48, 61, 64, 74, 75, 77, 79, 81, 82, 84, 85, 87, 88, 89, 91, 94, 104, 105, 108, 110, 112, 114, 115, 116, 118, 120, 121, 122, 123, 124, 125, 128, 138, 141, 148], "summary": {"covered_lines": 50, "num_statements": 56, "percent_covered": 91.17647058823529, "percent_covered_display": "91.18", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 89.28571428571429, "percent_statements_covered_display": "89.29", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 12, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [50, 51, 56, 57, 58, 59], "excluded_lines": [], "start_line": 1, "executed_branches": [[33, 34], [33, 61], [74, 75], [74, 77], [79, 81], [79, 84], [104, 105], [104, 108], [108, 110], [108, 112], [114, 115], [114, 118]], "missing_branches": []}}}, "app/utils/file_operations.py": {"executed_lines": [1, 4, 9, 10, 11, 12, 13, 14, 15, 16], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[13, 14], [13, 15]], "missing_branches": [], "functions": {"hash_file": {"executed_lines": [9, 10, 11, 12, 13, 14, 15, 16], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 4, "executed_branches": [[13, 14], [13, 15]], "missing_branches": []}, "": {"executed_lines": [1, 4], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [1, 4, 9, 10, 11, 12, 13, 14, 15, 16], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[13, 14], [13, 15]], "missing_branches": []}}}, "app/utils/file_queries.py": {"executed_lines": [8, 10, 11, 13, 16, 50, 51, 55, 57, 80, 81, 84, 86, 88, 89, 90, 92, 93, 94, 96, 97, 98, 101, 104, 107, 116, 119, 123], "summary": {"covered_lines": 28, "num_statements": 29, "percent_covered": 93.02325581395348, "percent_covered_display": "93.02", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 96.55172413793103, "percent_statements_covered_display": "96.55", "num_branches": 14, "num_partial_branches": 2, "covered_branches": 12, "missing_branches": 2, "percent_branches_covered": 85.71428571428571, "percent_branches_covered_display": "85.71"}, "missing_lines": [121], "excluded_lines": [], "executed_branches": [[50, 51], [50, 55], [80, 81], [86, 88], [86, 90], [90, 92], [90, 94], [94, 96], [94, 98], [98, 101], [98, 119], [119, 123]], "missing_branches": [[80, 84], [119, 121]], "functions": {"apply_status_filter": {"executed_lines": [50, 51, 55, 57, 80, 81, 84, 86, 88, 89, 90, 92, 93, 94, 96, 97, 98, 101, 104, 107, 116, 119, 123], "summary": {"covered_lines": 23, "num_statements": 24, "percent_covered": 92.10526315789474, "percent_covered_display": "92.11", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 95.83333333333333, "percent_statements_covered_display": "95.83", "num_branches": 14, "num_partial_branches": 2, "covered_branches": 12, "missing_branches": 2, "percent_branches_covered": 85.71428571428571, "percent_branches_covered_display": "85.71"}, "missing_lines": [121], "excluded_lines": [], "start_line": 16, "executed_branches": [[50, 51], [50, 55], [80, 81], [86, 88], [86, 90], [90, 92], [90, 94], [94, 96], [94, 98], [98, 101], [98, 119], [119, 123]], "missing_branches": [[80, 84], [119, 121]]}, "": {"executed_lines": [8, 10, 11, 13, 16], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [8, 10, 11, 13, 16, 50, 51, 55, 57, 80, 81, 84, 86, 88, 89, 90, 92, 93, 94, 96, 97, 98, 101, 104, 107, 116, 119, 123], "summary": {"covered_lines": 28, "num_statements": 29, "percent_covered": 93.02325581395348, "percent_covered_display": "93.02", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 96.55172413793103, "percent_statements_covered_display": "96.55", "num_branches": 14, "num_partial_branches": 2, "covered_branches": 12, "missing_branches": 2, "percent_branches_covered": 85.71428571428571, "percent_branches_covered_display": "85.71"}, "missing_lines": [121], "excluded_lines": [], "start_line": 1, "executed_branches": [[50, 51], [50, 55], [80, 81], [86, 88], [86, 90], [90, 92], [90, 94], [94, 96], [94, 98], [98, 101], [98, 119], [119, 123]], "missing_branches": [[80, 84], [119, 121]]}}}, "app/utils/file_splitting.py": {"executed_lines": [8, 9, 10, 11, 13, 15, 18, 53, 54, 57, 58, 59, 62, 63, 64, 65, 66, 67, 69, 74, 76, 77, 78, 79, 81, 83, 85, 86, 87, 90, 91, 92, 93, 95, 99, 119, 139, 140, 141, 142, 143, 144, 146, 147, 150, 161, 162, 164, 165, 167, 168], "summary": {"covered_lines": 51, "num_statements": 73, "percent_covered": 69.89247311827957, "percent_covered_display": "69.89", "missing_lines": 22, "excluded_lines": 0, "percent_statements_covered": 69.86301369863014, "percent_statements_covered_display": "69.86", "num_branches": 20, "num_partial_branches": 4, "covered_branches": 14, "missing_branches": 6, "percent_branches_covered": 70.0, "percent_branches_covered_display": "70.00"}, "missing_lines": [70, 71, 102, 103, 104, 107, 108, 109, 111, 112, 115, 116, 117, 118, 122, 127, 128, 129, 130, 133, 134, 135], "excluded_lines": [], "executed_branches": [[53, 54], [53, 57], [57, 58], [57, 59], [69, 74], [83, 85], [83, 139], [99, 119], [119, 83], [139, 140], [161, 162], [161, 164], [164, 165], [164, 167]], "missing_branches": [[69, 70], [99, 102], [103, 104], [103, 107], [119, 122], [139, 146]], "functions": {"split_pdf_by_size": {"executed_lines": [53, 54, 57, 58, 59, 62, 63, 64, 65, 66, 67, 69, 74, 76, 77, 78, 79, 81, 83, 85, 86, 87, 90, 91, 92, 93, 95, 99, 119, 139, 140, 141, 142, 143, 144, 146, 147], "summary": {"covered_lines": 37, "num_statements": 59, "percent_covered": 62.666666666666664, "percent_covered_display": "62.67", "missing_lines": 22, "excluded_lines": 0, "percent_statements_covered": 62.71186440677966, "percent_statements_covered_display": "62.71", "num_branches": 16, "num_partial_branches": 4, "covered_branches": 10, "missing_branches": 6, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62.50"}, "missing_lines": [70, 71, 102, 103, 104, 107, 108, 109, 111, 112, 115, 116, 117, 118, 122, 127, 128, 129, 130, 133, 134, 135], "excluded_lines": [], "start_line": 18, "executed_branches": [[53, 54], [53, 57], [57, 58], [57, 59], [69, 74], [83, 85], [83, 139], [99, 119], [119, 83], [139, 140]], "missing_branches": [[69, 70], [99, 102], [103, 104], [103, 107], [119, 122], [139, 146]]}, "should_split_file": {"executed_lines": [161, 162, 164, 165, 167, 168], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 150, "executed_branches": [[161, 162], [161, 164], [164, 165], [164, 167]], "missing_branches": []}, "": {"executed_lines": [8, 9, 10, 11, 13, 15, 18, 150], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [8, 9, 10, 11, 13, 15, 18, 53, 54, 57, 58, 59, 62, 63, 64, 65, 66, 67, 69, 74, 76, 77, 78, 79, 81, 83, 85, 86, 87, 90, 91, 92, 93, 95, 99, 119, 139, 140, 141, 142, 143, 144, 146, 147, 150, 161, 162, 164, 165, 167, 168], "summary": {"covered_lines": 51, "num_statements": 73, "percent_covered": 69.89247311827957, "percent_covered_display": "69.89", "missing_lines": 22, "excluded_lines": 0, "percent_statements_covered": 69.86301369863014, "percent_statements_covered_display": "69.86", "num_branches": 20, "num_partial_branches": 4, "covered_branches": 14, "missing_branches": 6, "percent_branches_covered": 70.0, "percent_branches_covered_display": "70.00"}, "missing_lines": [70, 71, 102, 103, 104, 107, 108, 109, 111, 112, 115, 116, 117, 118, 122, 127, 128, 129, 130, 133, 134, 135], "excluded_lines": [], "start_line": 1, "executed_branches": [[53, 54], [53, 57], [57, 58], [57, 59], [69, 74], [83, 85], [83, 139], [99, 119], [119, 83], [139, 140], [161, 162], [161, 164], [164, 165], [164, 167]], "missing_branches": [[69, 70], [99, 102], [103, 104], [103, 107], [119, 122], [139, 146]]}}}, "app/utils/file_status.py": {"executed_lines": [5, 7, 9, 10, 13, 26, 27, 36, 39, 46, 54, 74, 80, 82, 105, 106, 109, 116, 117, 118, 119, 120, 123, 124, 125, 133, 134, 135, 138, 139, 140, 141, 142, 144, 147, 148, 149, 150, 151, 152, 157, 159, 166, 169], "summary": {"covered_lines": 44, "num_statements": 65, "percent_covered": 60.824742268041234, "percent_covered_display": "60.82", "missing_lines": 21, "excluded_lines": 0, "percent_statements_covered": 67.6923076923077, "percent_statements_covered_display": "67.69", "num_branches": 32, "num_partial_branches": 5, "covered_branches": 15, "missing_branches": 17, "percent_branches_covered": 46.875, "percent_branches_covered_display": "46.88"}, "missing_lines": [28, 126, 132, 154, 182, 183, 187, 188, 189, 190, 193, 196, 199, 202, 203, 204, 205, 206, 207, 209, 211], "excluded_lines": [], "executed_branches": [[27, 36], [105, 106], [117, 118], [117, 123], [118, 119], [124, 125], [124, 166], [125, 133], [134, 135], [134, 138], [147, 148], [147, 149], [149, 150], [149, 151], [151, 152]], "missing_branches": [[27, 28], [105, 109], [118, 120], [125, 126], [151, 154], [182, 183], [182, 187], [188, 189], [188, 193], [189, 188], [189, 190], [202, 203], [202, 204], [204, 205], [204, 206], [206, 207], [206, 209]], "functions": {"get_file_processing_status": {"executed_lines": [26, 27, 36, 39, 46], "summary": {"covered_lines": 5, "num_statements": 6, "percent_covered": 75.0, "percent_covered_display": "75.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 83.33333333333333, "percent_statements_covered_display": "83.33", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [28], "excluded_lines": [], "start_line": 13, "executed_branches": [[27, 36]], "missing_branches": [[27, 28]]}, "get_files_processing_status": {"executed_lines": [74, 80, 82, 105, 106, 109, 116, 117, 118, 119, 120, 123, 124, 125, 133, 134, 135, 138, 139, 140, 141, 142, 144, 147, 148, 149, 150, 151, 152, 157, 159, 166], "summary": {"covered_lines": 32, "num_statements": 35, "percent_covered": 86.79245283018868, "percent_covered_display": "86.79", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 91.42857142857143, "percent_statements_covered_display": "91.43", "num_branches": 18, "num_partial_branches": 4, "covered_branches": 14, "missing_branches": 4, "percent_branches_covered": 77.77777777777777, "percent_branches_covered_display": "77.78"}, "missing_lines": [126, 132, 154], "excluded_lines": [], "start_line": 54, "executed_branches": [[105, 106], [117, 118], [117, 123], [118, 119], [124, 125], [124, 166], [125, 133], [134, 135], [134, 138], [147, 148], [147, 149], [149, 150], [149, 151], [151, 152]], "missing_branches": [[105, 109], [118, 120], [125, 126], [151, 154]]}, "_compute_status_from_logs": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 17, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 17, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 12, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [182, 183, 187, 188, 189, 190, 193, 196, 199, 202, 203, 204, 205, 206, 207, 209, 211], "excluded_lines": [], "start_line": 169, "executed_branches": [], "missing_branches": [[182, 183], [182, 187], [188, 189], [188, 193], [189, 188], [189, 190], [202, 203], [202, 204], [204, 205], [204, 206], [206, 207], [206, 209]]}, "": {"executed_lines": [5, 7, 9, 10, 13, 54, 169], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 9, 10, 13, 26, 27, 36, 39, 46, 54, 74, 80, 82, 105, 106, 109, 116, 117, 118, 119, 120, 123, 124, 125, 133, 134, 135, 138, 139, 140, 141, 142, 144, 147, 148, 149, 150, 151, 152, 157, 159, 166, 169], "summary": {"covered_lines": 44, "num_statements": 65, "percent_covered": 60.824742268041234, "percent_covered_display": "60.82", "missing_lines": 21, "excluded_lines": 0, "percent_statements_covered": 67.6923076923077, "percent_statements_covered_display": "67.69", "num_branches": 32, "num_partial_branches": 5, "covered_branches": 15, "missing_branches": 17, "percent_branches_covered": 46.875, "percent_branches_covered_display": "46.88"}, "missing_lines": [28, 126, 132, 154, 182, 183, 187, 188, 189, 190, 193, 196, 199, 202, 203, 204, 205, 206, 207, 209, 211], "excluded_lines": [], "start_line": 1, "executed_branches": [[27, 36], [105, 106], [117, 118], [117, 123], [118, 119], [124, 125], [124, 166], [125, 133], [134, 135], [134, 138], [147, 148], [147, 149], [149, 150], [149, 151], [151, 152]], "missing_branches": [[27, 28], [105, 109], [118, 120], [125, 126], [151, 154], [182, 183], [182, 187], [188, 189], [188, 193], [189, 188], [189, 190], [202, 203], [202, 204], [204, 205], [204, 206], [206, 207], [206, 209]]}}}, "app/utils/filename_utils.py": {"executed_lines": [1, 2, 3, 4, 5, 6, 8, 11, 24, 25, 27, 28, 29, 30, 33, 34, 37, 38, 39, 41, 42, 43, 46, 47, 48, 50, 51, 52, 72, 96, 97, 98, 101, 102, 104, 105, 106, 107, 108, 111, 123, 141, 145, 149, 152, 153, 156, 159, 160, 162, 165, 173, 174, 177, 178, 181, 184, 185, 187, 188, 191, 192, 194, 196, 198, 201, 203], "summary": {"covered_lines": 67, "num_statements": 84, "percent_covered": 79.46428571428571, "percent_covered_display": "79.46", "missing_lines": 17, "excluded_lines": 0, "percent_statements_covered": 79.76190476190476, "percent_statements_covered_display": "79.76", "num_branches": 28, "num_partial_branches": 2, "covered_branches": 22, "missing_branches": 6, "percent_branches_covered": 78.57142857142857, "percent_branches_covered_display": "78.57"}, "missing_lines": [55, 56, 57, 58, 59, 60, 61, 62, 65, 66, 67, 69, 113, 114, 115, 116, 120], "excluded_lines": [], "executed_branches": [[24, 25], [24, 27], [33, 34], [33, 37], [41, 42], [41, 46], [50, 51], [97, 98], [97, 101], [106, 107], [106, 108], [111, 102], [159, 160], [159, 162], [177, 178], [177, 181], [185, 187], [185, 191], [191, 192], [191, 198], [192, 194], [192, 196]], "missing_branches": [[50, 55], [56, 57], [56, 65], [59, 60], [59, 62], [111, 113]], "functions": {"get_unique_filename": {"executed_lines": [24, 25, 27, 28, 29, 30, 33, 34, 37, 38, 39, 41, 42, 43, 46, 47, 48, 50, 51, 52], "summary": {"covered_lines": 20, "num_statements": 32, "percent_covered": 61.36363636363637, "percent_covered_display": "61.36", "missing_lines": 12, "excluded_lines": 0, "percent_statements_covered": 62.5, "percent_statements_covered_display": "62.50", "num_branches": 12, "num_partial_branches": 1, "covered_branches": 7, "missing_branches": 5, "percent_branches_covered": 58.333333333333336, "percent_branches_covered_display": "58.33"}, "missing_lines": [55, 56, 57, 58, 59, 60, 61, 62, 65, 66, 67, 69], "excluded_lines": [], "start_line": 11, "executed_branches": [[24, 25], [24, 27], [33, 34], [33, 37], [41, 42], [41, 46], [50, 51]], "missing_branches": [[50, 55], [56, 57], [56, 65], [59, 60], [59, 62]]}, "get_unique_filepath_with_counter": {"executed_lines": [96, 97, 98, 101, 102, 104, 105, 106, 107, 108, 111], "summary": {"covered_lines": 11, "num_statements": 16, "percent_covered": 72.72727272727273, "percent_covered_display": "72.73", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 68.75, "percent_statements_covered_display": "68.75", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [113, 114, 115, 116, 120], "excluded_lines": [], "start_line": 72, "executed_branches": [[97, 98], [97, 101], [106, 107], [106, 108], [111, 102]], "missing_branches": [[111, 113]]}, "sanitize_filename": {"executed_lines": [141, 145, 149, 152, 153, 156, 159, 160, 162], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 123, "executed_branches": [[159, 160], [159, 162]], "missing_branches": []}, "extract_remote_path": {"executed_lines": [173, 174, 177, 178, 181, 184, 185, 187, 188, 191, 192, 194, 196, 198, 201, 203], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 165, "executed_branches": [[177, 178], [177, 181], [185, 187], [185, 191], [191, 192], [191, 198], [192, 194], [192, 196]], "missing_branches": []}, "": {"executed_lines": [1, 2, 3, 4, 5, 6, 8, 11, 72, 123, 165], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [1, 2, 3, 4, 5, 6, 8, 11, 24, 25, 27, 28, 29, 30, 33, 34, 37, 38, 39, 41, 42, 43, 46, 47, 48, 50, 51, 52, 72, 96, 97, 98, 101, 102, 104, 105, 106, 107, 108, 111, 123, 141, 145, 149, 152, 153, 156, 159, 160, 162, 165, 173, 174, 177, 178, 181, 184, 185, 187, 188, 191, 192, 194, 196, 198, 201, 203], "summary": {"covered_lines": 67, "num_statements": 84, "percent_covered": 79.46428571428571, "percent_covered_display": "79.46", "missing_lines": 17, "excluded_lines": 0, "percent_statements_covered": 79.76190476190476, "percent_statements_covered_display": "79.76", "num_branches": 28, "num_partial_branches": 2, "covered_branches": 22, "missing_branches": 6, "percent_branches_covered": 78.57142857142857, "percent_branches_covered_display": "78.57"}, "missing_lines": [55, 56, 57, 58, 59, 60, 61, 62, 65, 66, 67, 69, 113, 114, 115, 116, 120], "excluded_lines": [], "start_line": 1, "executed_branches": [[24, 25], [24, 27], [33, 34], [33, 37], [41, 42], [41, 46], [50, 51], [97, 98], [97, 101], [106, 107], [106, 108], [111, 102], [159, 160], [159, 162], [177, 178], [177, 181], [185, 187], [185, 191], [191, 192], [191, 198], [192, 194], [192, 196]], "missing_branches": [[50, 55], [56, 57], [56, 65], [59, 60], [59, 62], [111, 113]]}}}, "app/utils/logging.py": {"executed_lines": [1, 2, 3, 4, 6, 7, 10, 19, 20, 21, 22, 24, 26, 27, 29, 30, 31, 32, 33, 34, 35, 39, 41, 42, 43, 47, 48, 49, 52, 55, 56, 58, 59, 60, 63, 82, 83, 84, 85, 88, 90, 98, 101, 103, 109, 111, 124, 125, 127, 128, 129, 132], "summary": {"covered_lines": 52, "num_statements": 59, "percent_covered": 85.18518518518519, "percent_covered_display": "85.19", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 88.13559322033899, "percent_statements_covered_display": "88.14", "num_branches": 22, "num_partial_branches": 5, "covered_branches": 17, "missing_branches": 5, "percent_branches_covered": 77.27272727272727, "percent_branches_covered_display": "77.27"}, "missing_lines": [36, 37, 86, 113, 121, 126, 130], "excluded_lines": [], "executed_branches": [[29, -24], [29, 30], [33, -24], [33, 34], [55, -52], [55, 56], [58, 59], [82, 83], [82, 88], [85, 88], [101, 103], [101, 132], [111, 124], [125, 127], [127, 128], [127, 129], [129, 132]], "missing_branches": [[58, 60], [85, 86], [111, 113], [125, 126], [129, 130]], "functions": {"TaskLogCollector.__init__": {"executed_lines": [20, 21, 22], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 19, "executed_branches": [], "missing_branches": []}, "TaskLogCollector.emit": {"executed_lines": [26, 27, 29, 30, 31, 32, 33, 34, 35], "summary": {"covered_lines": 9, "num_statements": 11, "percent_covered": 86.66666666666667, "percent_covered_display": "86.67", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 81.81818181818181, "percent_statements_covered_display": "81.82", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [36, 37], "excluded_lines": [], "start_line": 24, "executed_branches": [[29, -24], [29, 30], [33, -24], [33, 34]], "missing_branches": []}, "TaskLogCollector.drain": {"executed_lines": [41, 42, 43], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 39, "executed_branches": [], "missing_branches": []}, "_ensure_collector_installed": {"executed_lines": [55, 56, 58, 59, 60], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 88.88888888888889, "percent_covered_display": "88.89", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 52, "executed_branches": [[55, -52], [55, 56], [58, 59]], "missing_branches": [[58, 60]]}, "log_task_progress": {"executed_lines": [82, 83, 84, 85, 88, 90, 98, 101, 103, 109, 111, 124, 125, 127, 128, 129, 132], "summary": {"covered_lines": 17, "num_statements": 22, "percent_covered": 75.0, "percent_covered_display": "75.00", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 77.27272727272727, "percent_statements_covered_display": "77.27", "num_branches": 14, "num_partial_branches": 4, "covered_branches": 10, "missing_branches": 4, "percent_branches_covered": 71.42857142857143, "percent_branches_covered_display": "71.43"}, "missing_lines": [86, 113, 121, 126, 130], "excluded_lines": [], "start_line": 63, "executed_branches": [[82, 83], [82, 88], [85, 88], [101, 103], [101, 132], [111, 124], [125, 127], [127, 128], [127, 129], [129, 132]], "missing_branches": [[85, 86], [111, 113], [125, 126], [129, 130]]}, "": {"executed_lines": [1, 2, 3, 4, 6, 7, 10, 19, 24, 39, 47, 48, 49, 52, 63], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"TaskLogCollector": {"executed_lines": [20, 21, 22, 26, 27, 29, 30, 31, 32, 33, 34, 35, 41, 42, 43], "summary": {"covered_lines": 15, "num_statements": 17, "percent_covered": 90.47619047619048, "percent_covered_display": "90.48", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 88.23529411764706, "percent_statements_covered_display": "88.24", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [36, 37], "excluded_lines": [], "start_line": 10, "executed_branches": [[29, -24], [29, 30], [33, -24], [33, 34]], "missing_branches": []}, "": {"executed_lines": [1, 2, 3, 4, 6, 7, 10, 19, 24, 39, 47, 48, 49, 52, 55, 56, 58, 59, 60, 63, 82, 83, 84, 85, 88, 90, 98, 101, 103, 109, 111, 124, 125, 127, 128, 129, 132], "summary": {"covered_lines": 37, "num_statements": 42, "percent_covered": 83.33333333333333, "percent_covered_display": "83.33", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 88.0952380952381, "percent_statements_covered_display": "88.10", "num_branches": 18, "num_partial_branches": 5, "covered_branches": 13, "missing_branches": 5, "percent_branches_covered": 72.22222222222223, "percent_branches_covered_display": "72.22"}, "missing_lines": [86, 113, 121, 126, 130], "excluded_lines": [], "start_line": 1, "executed_branches": [[55, -52], [55, 56], [58, 59], [82, 83], [82, 88], [85, 88], [101, 103], [101, 132], [111, 124], [125, 127], [127, 128], [127, 129], [129, 132]], "missing_branches": [[58, 60], [85, 86], [111, 113], [125, 126], [129, 130]]}}}, "app/utils/migrate_logs_to_steps.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 115, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 115, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 48, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 48, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [8, 9, 11, 13, 15, 18, 40, 42, 44, 51, 52, 53, 56, 59, 60, 66, 68, 73, 76, 77, 78, 79, 80, 82, 83, 86, 87, 95, 96, 98, 99, 100, 107, 108, 110, 111, 112, 113, 115, 118, 139, 141, 142, 143, 146, 147, 155, 157, 158, 159, 161, 163, 165, 166, 167, 168, 170, 172, 173, 174, 175, 176, 178, 180, 181, 186, 189, 209, 220, 221, 223, 224, 226, 228, 229, 232, 233, 234, 238, 239, 241, 242, 243, 245, 246, 247, 248, 250, 257, 260, 278, 281, 285, 286, 287, 288, 290, 291, 294, 295, 298, 301, 302, 303, 304, 305, 308, 309, 311, 312, 315, 318, 319, 320, 323], "excluded_lines": [], "executed_branches": [], "missing_branches": [[51, 52], [51, 56], [59, 60], [59, 98], [66, 68], [66, 86], [68, 73], [68, 82], [98, 99], [98, 107], [141, 142], [141, 186], [146, 147], [146, 155], [155, 157], [155, 161], [157, 158], [157, 159], [161, 163], [161, 170], [163, 165], [163, 166], [170, 172], [170, 178], [172, 173], [172, 174], [178, 141], [178, 180], [180, 141], [180, 181], [232, 233], [232, 250], [238, 232], [238, 239], [241, 242], [241, 245], [285, 286], [285, 290], [301, 302], [301, 318], [302, 303], [302, 308], [311, 301], [311, 312], [318, 319], [318, 323], [319, 318], [319, 320]], "functions": {"migrate_logs_to_steps": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 33, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 33, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 10, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [40, 42, 44, 51, 52, 53, 56, 59, 60, 66, 68, 73, 76, 77, 78, 79, 80, 82, 83, 86, 87, 95, 96, 98, 99, 100, 107, 108, 110, 111, 112, 113, 115], "excluded_lines": [], "start_line": 18, "executed_branches": [], "missing_branches": [[51, 52], [51, 56], [59, 60], [59, 98], [66, 68], [66, 86], [68, 73], [68, 82], [98, 99], [98, 107]]}, "_parse_logs_to_step_states": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 26, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 26, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 20, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 20, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [139, 141, 142, 143, 146, 147, 155, 157, 158, 159, 161, 163, 165, 166, 167, 168, 170, 172, 173, 174, 175, 176, 178, 180, 181, 186], "excluded_lines": [], "start_line": 118, "executed_branches": [], "missing_branches": [[141, 142], [141, 186], [146, 147], [146, 155], [155, 157], [155, 161], [157, 158], [157, 159], [161, 163], [161, 170], [163, 165], [163, 166], [170, 172], [170, 178], [172, 173], [172, 174], [178, 141], [178, 180], [180, 141], [180, 181]]}, "migrate_all_files": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 22, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 22, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [209, 220, 221, 223, 224, 226, 228, 229, 232, 233, 234, 238, 239, 241, 242, 243, 245, 246, 247, 248, 250, 257], "excluded_lines": [], "start_line": 189, "executed_branches": [], "missing_branches": [[232, 233], [232, 250], [238, 232], [238, 239], [241, 242], [241, 245]]}, "verify_migration": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 25, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 25, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 12, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [278, 281, 285, 286, 287, 288, 290, 291, 294, 295, 298, 301, 302, 303, 304, 305, 308, 309, 311, 312, 315, 318, 319, 320, 323], "excluded_lines": [], "start_line": 260, "executed_branches": [], "missing_branches": [[285, 286], [285, 290], [301, 302], [301, 318], [302, 303], [302, 308], [311, 301], [311, 312], [318, 319], [318, 323], [319, 318], [319, 320]]}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 9, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [8, 9, 11, 13, 15, 18, 118, 189, 260], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 115, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 115, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 48, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 48, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [8, 9, 11, 13, 15, 18, 40, 42, 44, 51, 52, 53, 56, 59, 60, 66, 68, 73, 76, 77, 78, 79, 80, 82, 83, 86, 87, 95, 96, 98, 99, 100, 107, 108, 110, 111, 112, 113, 115, 118, 139, 141, 142, 143, 146, 147, 155, 157, 158, 159, 161, 163, 165, 166, 167, 168, 170, 172, 173, 174, 175, 176, 178, 180, 181, 186, 189, 209, 220, 221, 223, 224, 226, 228, 229, 232, 233, 234, 238, 239, 241, 242, 243, 245, 246, 247, 248, 250, 257, 260, 278, 281, 285, 286, 287, 288, 290, 291, 294, 295, 298, 301, 302, 303, 304, 305, 308, 309, 311, 312, 315, 318, 319, 320, 323], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": [[51, 52], [51, 56], [59, 60], [59, 98], [66, 68], [66, 86], [68, 73], [68, 82], [98, 99], [98, 107], [141, 142], [141, 186], [146, 147], [146, 155], [155, 157], [155, 161], [157, 158], [157, 159], [161, 163], [161, 170], [163, 165], [163, 166], [170, 172], [170, 178], [172, 173], [172, 174], [178, 141], [178, 180], [180, 141], [180, 181], [232, 233], [232, 250], [238, 232], [238, 239], [241, 242], [241, 245], [285, 286], [285, 290], [301, 302], [301, 318], [302, 303], [302, 308], [311, 301], [311, 312], [318, 319], [318, 323], [319, 318], [319, 320]]}}}, "app/utils/notification.py": {"executed_lines": [1, 2, 4, 6, 8, 11, 14, 18, 19, 22, 23, 24, 25, 26, 27, 28, 30, 32, 35, 38, 41, 42, 43, 44, 45, 48, 70, 71, 72, 121, 123, 124, 126, 127, 134, 139, 141, 142, 144, 145, 151, 156, 158, 159, 161, 162, 163, 166, 168, 169, 171, 172, 173, 176, 178, 179, 182, 183, 186, 187, 188, 191, 193, 194, 204], "summary": {"covered_lines": 65, "num_statements": 97, "percent_covered": 63.565891472868216, "percent_covered_display": "63.57", "missing_lines": 32, "excluded_lines": 0, "percent_statements_covered": 67.01030927835052, "percent_statements_covered_display": "67.01", "num_branches": 32, "num_partial_branches": 1, "covered_branches": 17, "missing_branches": 15, "percent_branches_covered": 53.125, "percent_branches_covered_display": "53.12"}, "missing_lines": [74, 75, 78, 79, 80, 81, 82, 83, 84, 87, 88, 89, 91, 92, 94, 95, 96, 97, 99, 100, 101, 103, 104, 105, 107, 109, 110, 112, 114, 116, 117, 118], "excluded_lines": [], "executed_branches": [[18, 19], [18, 32], [22, 23], [22, 30], [23, 24], [23, 32], [70, 71], [123, 124], [123, 126], [141, 142], [141, 144], [158, 159], [158, 161], [168, 169], [168, 171], [178, 179], [178, 182]], "missing_branches": [[70, 74], [79, 80], [79, 81], [81, 82], [81, 83], [83, 84], [83, 87], [87, 88], [87, 91], [94, 95], [94, 107], [99, 100], [99, 103], [109, 110], [109, 112]], "functions": {"init_apprise": {"executed_lines": [18, 19, 22, 23, 24, 25, 26, 27, 28, 30, 32], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 14, "executed_branches": [[18, 19], [18, 32], [22, 23], [22, 30], [23, 24], [23, 32]], "missing_branches": []}, "_mask_sensitive_url": {"executed_lines": [38, 41, 42, 43, 44, 45], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 35, "executed_branches": [], "missing_branches": []}, "send_notification": {"executed_lines": [70, 71, 72], "summary": {"covered_lines": 3, "num_statements": 35, "percent_covered": 7.8431372549019605, "percent_covered_display": "7.84", "missing_lines": 32, "excluded_lines": 0, "percent_statements_covered": 8.571428571428571, "percent_statements_covered_display": "8.57", "num_branches": 16, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 15, "percent_branches_covered": 6.25, "percent_branches_covered_display": "6.25"}, "missing_lines": [74, 75, 78, 79, 80, 81, 82, 83, 84, 87, 88, 89, 91, 92, 94, 95, 96, 97, 99, 100, 101, 103, 104, 105, 107, 109, 110, 112, 114, 116, 117, 118], "excluded_lines": [], "start_line": 48, "executed_branches": [[70, 71]], "missing_branches": [[70, 74], [79, 80], [79, 81], [81, 82], [81, 83], [83, 84], [83, 87], [87, 88], [87, 91], [94, 95], [94, 107], [99, 100], [99, 103], [109, 110], [109, 112]]}, "notify_celery_failure": {"executed_lines": [123, 124, 126, 127, 134], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 121, "executed_branches": [[123, 124], [123, 126]], "missing_branches": []}, "notify_credential_failure": {"executed_lines": [141, 142, 144, 145, 151], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 139, "executed_branches": [[141, 142], [141, 144]], "missing_branches": []}, "notify_startup": {"executed_lines": [158, 159, 161, 162, 163], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 156, "executed_branches": [[158, 159], [158, 161]], "missing_branches": []}, "notify_shutdown": {"executed_lines": [168, 169, 171, 172, 173], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 166, "executed_branches": [[168, 169], [168, 171]], "missing_branches": []}, "notify_file_processed": {"executed_lines": [178, 179, 182, 183, 186, 187, 188, 191, 193, 194, 204], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 176, "executed_branches": [[178, 179], [178, 182]], "missing_branches": []}, "": {"executed_lines": [1, 2, 4, 6, 8, 11, 14, 35, 48, 121, 139, 156, 166, 176], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [1, 2, 4, 6, 8, 11, 14, 18, 19, 22, 23, 24, 25, 26, 27, 28, 30, 32, 35, 38, 41, 42, 43, 44, 45, 48, 70, 71, 72, 121, 123, 124, 126, 127, 134, 139, 141, 142, 144, 145, 151, 156, 158, 159, 161, 162, 163, 166, 168, 169, 171, 172, 173, 176, 178, 179, 182, 183, 186, 187, 188, 191, 193, 194, 204], "summary": {"covered_lines": 65, "num_statements": 97, "percent_covered": 63.565891472868216, "percent_covered_display": "63.57", "missing_lines": 32, "excluded_lines": 0, "percent_statements_covered": 67.01030927835052, "percent_statements_covered_display": "67.01", "num_branches": 32, "num_partial_branches": 1, "covered_branches": 17, "missing_branches": 15, "percent_branches_covered": 53.125, "percent_branches_covered_display": "53.12"}, "missing_lines": [74, 75, 78, 79, 80, 81, 82, 83, 84, 87, 88, 89, 91, 92, 94, 95, 96, 97, 99, 100, 101, 103, 104, 105, 107, 109, 110, 112, 114, 116, 117, 118], "excluded_lines": [], "start_line": 1, "executed_branches": [[18, 19], [18, 32], [22, 23], [22, 30], [23, 24], [23, 32], [70, 71], [123, 124], [123, 126], [141, 142], [141, 144], [158, 159], [158, 161], [168, 169], [168, 171], [178, 179], [178, 182]], "missing_branches": [[70, 74], [79, 80], [79, 81], [81, 82], [81, 83], [83, 84], [83, 87], [87, 88], [87, 91], [94, 95], [94, 107], [99, 100], [99, 103], [109, 110], [109, 112]]}}}, "app/utils/oauth_helper.py": {"executed_lines": [6, 7, 9, 10, 12, 14, 17, 38, 39, 41, 42, 45, 50, 53, 54, 57, 59, 61, 62, 64, 65, 66, 67, 68, 69, 71, 76, 79, 80, 81, 87, 89, 91, 93, 94, 95, 96, 100, 101, 102], "summary": {"covered_lines": 40, "num_statements": 40, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[38, 39], [38, 41], [59, 61], [59, 76], [79, 80], [79, 87]], "missing_branches": [], "functions": {"exchange_oauth_token": {"executed_lines": [38, 39, 41, 42, 45, 50, 53, 54, 57, 59, 61, 62, 64, 65, 66, 67, 68, 69, 71, 76, 79, 80, 81, 87, 89, 91, 93, 94, 95, 96, 100, 101, 102], "summary": {"covered_lines": 33, "num_statements": 33, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 17, "executed_branches": [[38, 39], [38, 41], [59, 61], [59, 76], [79, 80], [79, 87]], "missing_branches": []}, "": {"executed_lines": [6, 7, 9, 10, 12, 14, 17], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [6, 7, 9, 10, 12, 14, 17, 38, 39, 41, 42, 45, 50, 53, 54, 57, 59, 61, 62, 64, 65, 66, 67, 68, 69, 71, 76, 79, 80, 81, 87, 89, 91, 93, 94, 95, 96, 100, 101, 102], "summary": {"covered_lines": 40, "num_statements": 40, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[38, 39], [38, 41], [59, 61], [59, 76], [79, 80], [79, 87]], "missing_branches": []}}}, "app/utils/settings_service.py": {"executed_lines": [10, 11, 13, 14, 16, 18, 21, 860, 873, 874, 875, 876, 879, 880, 885, 891, 905, 907, 908, 910, 911, 913, 914, 915, 919, 920, 921, 923, 924, 925, 926, 927, 934, 946, 947, 948, 950, 952, 953, 958, 960, 966, 977, 978, 979, 980, 981, 982, 983, 984, 991, 1001, 1014, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1030, 1041, 1042, 1045, 1049, 1050, 1051, 1053, 1060, 1061, 1063], "summary": {"covered_lines": 71, "num_statements": 95, "percent_covered": 76.8, "percent_covered_display": "76.80", "missing_lines": 24, "excluded_lines": 0, "percent_statements_covered": 74.73684210526316, "percent_statements_covered_display": "74.74", "num_branches": 30, "num_partial_branches": 5, "covered_branches": 25, "missing_branches": 5, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [881, 883, 886, 887, 888, 917, 928, 929, 930, 931, 954, 956, 961, 962, 963, 985, 986, 987, 988, 1046, 1054, 1055, 1056, 1057], "excluded_lines": [], "executed_branches": [[875, 876], [875, 879], [880, 885], [910, 911], [910, 919], [913, 914], [920, 921], [920, 923], [950, 952], [950, 960], [953, 958], [979, 980], [979, 984], [1022, 1023], [1022, 1027], [1024, 1025], [1024, 1026], [1045, 1049], [1049, 1050], [1049, 1053], [1050, 1051], [1050, 1060], [1053, 1060], [1060, 1061], [1060, 1063]], "missing_branches": [[880, 881], [913, 917], [953, 954], [1045, 1046], [1053, 1054]], "functions": {"get_setting_from_db": {"executed_lines": [873, 874, 875, 876, 879, 880, 885], "summary": {"covered_lines": 7, "num_statements": 12, "percent_covered": 62.5, "percent_covered_display": "62.50", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 58.333333333333336, "percent_statements_covered_display": "58.33", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [881, 883, 886, 887, 888], "excluded_lines": [], "start_line": 860, "executed_branches": [[875, 876], [875, 879], [880, 885]], "missing_branches": [[880, 881]]}, "save_setting_to_db": {"executed_lines": [905, 907, 908, 910, 911, 913, 914, 915, 919, 920, 921, 923, 924, 925, 926, 927], "summary": {"covered_lines": 16, "num_statements": 21, "percent_covered": 77.77777777777777, "percent_covered_display": "77.78", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 76.19047619047619, "percent_statements_covered_display": "76.19", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [917, 928, 929, 930, 931], "excluded_lines": [], "start_line": 891, "executed_branches": [[910, 911], [910, 919], [913, 914], [920, 921], [920, 923]], "missing_branches": [[913, 917]]}, "get_all_settings_from_db": {"executed_lines": [946, 947, 948, 950, 952, 953, 958, 960], "summary": {"covered_lines": 8, "num_statements": 13, "percent_covered": 64.70588235294117, "percent_covered_display": "64.71", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 61.53846153846154, "percent_statements_covered_display": "61.54", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [954, 956, 961, 962, 963], "excluded_lines": [], "start_line": 934, "executed_branches": [[950, 952], [950, 960], [953, 958]], "missing_branches": [[953, 954]]}, "delete_setting_from_db": {"executed_lines": [977, 978, 979, 980, 981, 982, 983, 984], "summary": {"covered_lines": 8, "num_statements": 12, "percent_covered": 71.42857142857143, "percent_covered_display": "71.43", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 66.66666666666667, "percent_statements_covered_display": "66.67", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [985, 986, 987, 988], "excluded_lines": [], "start_line": 966, "executed_branches": [[979, 980], [979, 984]], "missing_branches": []}, "get_setting_metadata": {"executed_lines": [1001], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 991, "executed_branches": [], "missing_branches": []}, "get_settings_by_category": {"executed_lines": [1021, 1022, 1023, 1024, 1025, 1026, 1027], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1014, "executed_branches": [[1022, 1023], [1022, 1027], [1024, 1025], [1024, 1026]], "missing_branches": []}, "validate_setting_value": {"executed_lines": [1041, 1042, 1045, 1049, 1050, 1051, 1053, 1060, 1061, 1063], "summary": {"covered_lines": 10, "num_statements": 15, "percent_covered": 72.0, "percent_covered_display": "72.00", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 66.66666666666667, "percent_statements_covered_display": "66.67", "num_branches": 10, "num_partial_branches": 2, "covered_branches": 8, "missing_branches": 2, "percent_branches_covered": 80.0, "percent_branches_covered_display": "80.00"}, "missing_lines": [1046, 1054, 1055, 1056, 1057], "excluded_lines": [], "start_line": 1030, "executed_branches": [[1045, 1049], [1049, 1050], [1049, 1053], [1050, 1051], [1050, 1060], [1053, 1060], [1060, 1061], [1060, 1063]], "missing_branches": [[1045, 1046], [1053, 1054]]}, "": {"executed_lines": [10, 11, 13, 14, 16, 18, 21, 860, 891, 934, 966, 991, 1014, 1030], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [10, 11, 13, 14, 16, 18, 21, 860, 873, 874, 875, 876, 879, 880, 885, 891, 905, 907, 908, 910, 911, 913, 914, 915, 919, 920, 921, 923, 924, 925, 926, 927, 934, 946, 947, 948, 950, 952, 953, 958, 960, 966, 977, 978, 979, 980, 981, 982, 983, 984, 991, 1001, 1014, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1030, 1041, 1042, 1045, 1049, 1050, 1051, 1053, 1060, 1061, 1063], "summary": {"covered_lines": 71, "num_statements": 95, "percent_covered": 76.8, "percent_covered_display": "76.80", "missing_lines": 24, "excluded_lines": 0, "percent_statements_covered": 74.73684210526316, "percent_statements_covered_display": "74.74", "num_branches": 30, "num_partial_branches": 5, "covered_branches": 25, "missing_branches": 5, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [881, 883, 886, 887, 888, 917, 928, 929, 930, 931, 954, 956, 961, 962, 963, 985, 986, 987, 988, 1046, 1054, 1055, 1056, 1057], "excluded_lines": [], "start_line": 1, "executed_branches": [[875, 876], [875, 879], [880, 885], [910, 911], [910, 919], [913, 914], [920, 921], [920, 923], [950, 952], [950, 960], [953, 958], [979, 980], [979, 984], [1022, 1023], [1022, 1027], [1024, 1025], [1024, 1026], [1045, 1049], [1049, 1050], [1049, 1053], [1050, 1051], [1050, 1060], [1053, 1060], [1060, 1061], [1060, 1063]], "missing_branches": [[880, 881], [913, 917], [953, 954], [1045, 1046], [1053, 1054]]}}}, "app/utils/setup_wizard.py": {"executed_lines": [7, 8, 10, 12, 15, 22, 136, 145, 147, 154, 155, 156, 157, 158, 161, 163, 164, 166, 169, 176, 178, 179, 180, 183, 193, 194, 196, 199, 206, 208, 209, 210, 211, 212, 214], "summary": {"covered_lines": 35, "num_statements": 35, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 12, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[154, 155], [154, 161], [156, 154], [156, 157], [178, 179], [178, 196], [193, 178], [193, 194], [208, 209], [208, 214], [210, 211], [210, 212]], "missing_branches": [], "functions": {"get_required_settings": {"executed_lines": [22], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 15, "executed_branches": [], "missing_branches": []}, "is_setup_required": {"executed_lines": [145, 147, 154, 155, 156, 157, 158, 161, 163, 164, 166], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 136, "executed_branches": [[154, 155], [154, 161], [156, 154], [156, 157]], "missing_branches": []}, "get_missing_required_settings": {"executed_lines": [176, 178, 179, 180, 183, 193, 194, 196], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 169, "executed_branches": [[178, 179], [178, 196], [193, 178], [193, 194]], "missing_branches": []}, "get_wizard_steps": {"executed_lines": [206, 208, 209, 210, 211, 212, 214], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 199, "executed_branches": [[208, 209], [208, 214], [210, 211], [210, 212]], "missing_branches": []}, "": {"executed_lines": [7, 8, 10, 12, 15, 136, 169, 199], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [7, 8, 10, 12, 15, 22, 136, 145, 147, 154, 155, 156, 157, 158, 161, 163, 164, 166, 169, 176, 178, 179, 180, 183, 193, 194, 196, 199, 206, 208, 209, 210, 211, 212, 214], "summary": {"covered_lines": 35, "num_statements": 35, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 12, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[154, 155], [154, 161], [156, 154], [156, 157], [178, 179], [178, 196], [193, 178], [193, 194], [208, 209], [208, 214], [210, 211], [210, 212]], "missing_branches": []}}}, "app/utils/step_manager.py": {"executed_lines": [8, 9, 11, 13, 14, 18, 28, 33, 34, 35, 36, 39, 49, 50, 51, 53, 56, 65, 67, 68, 70, 75, 76, 77, 79, 82, 103, 109, 111, 119, 122, 123, 124, 125, 126, 127, 128, 130, 133, 153, 155, 156, 157, 164, 167, 190, 191, 204, 216, 217, 219, 222, 228, 229, 238, 239, 240, 241, 242, 244, 247, 248, 249, 250, 251, 252, 254, 256, 267, 289, 301, 302, 304, 306, 307, 309, 310, 312, 314, 315, 316, 319, 322, 324, 328, 329, 330, 331, 332, 333, 334, 335, 337], "summary": {"covered_lines": 93, "num_statements": 95, "percent_covered": 93.00699300699301, "percent_covered_display": "93.01", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 97.89473684210526, "percent_statements_covered_display": "97.89", "num_branches": 48, "num_partial_branches": 8, "covered_branches": 40, "missing_branches": 8, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [192, 326], "excluded_lines": [], "executed_branches": [[34, 35], [49, 50], [49, 53], [65, 67], [65, 79], [67, 65], [67, 68], [75, 76], [109, 111], [109, 122], [123, 124], [123, 125], [125, 126], [125, 127], [127, 128], [127, 130], [156, 157], [156, 164], [191, 204], [216, 217], [228, 229], [228, 238], [247, 248], [247, 249], [249, 250], [249, 251], [251, 252], [251, 254], [301, 302], [312, 314], [312, 337], [315, 316], [315, 319], [324, 328], [328, 329], [328, 332], [329, 330], [332, 312], [332, 333], [333, 334]], "missing_branches": [[34, 36], [75, 67], [191, 192], [216, 219], [301, 304], [324, 326], [329, 331], [333, 335]], "functions": {"initialize_file_steps": {"executed_lines": [49, 50, 51, 53], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 39, "executed_branches": [[49, 50], [49, 53]], "missing_branches": []}, "add_upload_steps": {"executed_lines": [65, 67, 68, 70, 75, 76, 77, 79], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 92.85714285714286, "percent_covered_display": "92.86", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [], "excluded_lines": [], "start_line": 56, "executed_branches": [[65, 67], [65, 79], [67, 65], [67, 68], [75, 76]], "missing_branches": [[75, 67]]}, "update_step_status": {"executed_lines": [103, 109, 111, 119, 122, 123, 124, 125, 126, 127, 128, 130], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 82, "executed_branches": [[109, 111], [109, 122], [123, 124], [123, 125], [125, 126], [125, 127], [127, 128], [127, 130]], "missing_branches": []}, "get_file_step_status": {"executed_lines": [153, 155, 156, 157, 164], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 133, "executed_branches": [[156, 157], [156, 164]], "missing_branches": []}, "get_file_overall_status": {"executed_lines": [190, 191, 204, 216, 217, 219, 222, 228, 229, 238, 239, 240, 241, 242, 244, 247, 248, 249, 250, 251, 252, 254, 256], "summary": {"covered_lines": 23, "num_statements": 24, "percent_covered": 91.66666666666667, "percent_covered_display": "91.67", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 95.83333333333333, "percent_statements_covered_display": "95.83", "num_branches": 12, "num_partial_branches": 2, "covered_branches": 10, "missing_branches": 2, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [192], "excluded_lines": [], "start_line": 167, "executed_branches": [[191, 204], [216, 217], [228, 229], [228, 238], [247, 248], [247, 249], [249, 250], [249, 251], [251, 252], [251, 254]], "missing_branches": [[191, 192], [216, 219]]}, "get_step_summary": {"executed_lines": [289, 301, 302, 304, 306, 307, 309, 310, 312, 314, 315, 316, 319, 322, 324, 328, 329, 330, 331, 332, 333, 334, 335, 337], "summary": {"covered_lines": 24, "num_statements": 25, "percent_covered": 87.8048780487805, "percent_covered_display": "87.80", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 96.0, "percent_statements_covered_display": "96.00", "num_branches": 16, "num_partial_branches": 4, "covered_branches": 12, "missing_branches": 4, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [326], "excluded_lines": [], "start_line": 267, "executed_branches": [[301, 302], [312, 314], [312, 337], [315, 316], [315, 319], [324, 328], [328, 329], [328, 332], [329, 330], [332, 312], [332, 333], [333, 334]], "missing_branches": [[301, 304], [324, 326], [329, 331], [333, 335]]}, "": {"executed_lines": [8, 9, 11, 13, 14, 18, 28, 33, 34, 35, 36, 39, 56, 82, 133, 167, 267], "summary": {"covered_lines": 17, "num_statements": 17, "percent_covered": 94.73684210526316, "percent_covered_display": "94.74", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[34, 35]], "missing_branches": [[34, 36]]}}, "classes": {"": {"executed_lines": [8, 9, 11, 13, 14, 18, 28, 33, 34, 35, 36, 39, 49, 50, 51, 53, 56, 65, 67, 68, 70, 75, 76, 77, 79, 82, 103, 109, 111, 119, 122, 123, 124, 125, 126, 127, 128, 130, 133, 153, 155, 156, 157, 164, 167, 190, 191, 204, 216, 217, 219, 222, 228, 229, 238, 239, 240, 241, 242, 244, 247, 248, 249, 250, 251, 252, 254, 256, 267, 289, 301, 302, 304, 306, 307, 309, 310, 312, 314, 315, 316, 319, 322, 324, 328, 329, 330, 331, 332, 333, 334, 335, 337], "summary": {"covered_lines": 93, "num_statements": 95, "percent_covered": 93.00699300699301, "percent_covered_display": "93.01", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 97.89473684210526, "percent_statements_covered_display": "97.89", "num_branches": 48, "num_partial_branches": 8, "covered_branches": 40, "missing_branches": 8, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [192, 326], "excluded_lines": [], "start_line": 1, "executed_branches": [[34, 35], [49, 50], [49, 53], [65, 67], [65, 79], [67, 65], [67, 68], [75, 76], [109, 111], [109, 122], [123, 124], [123, 125], [125, 126], [125, 127], [127, 128], [127, 130], [156, 157], [156, 164], [191, 204], [216, 217], [228, 229], [228, 238], [247, 248], [247, 249], [249, 250], [249, 251], [251, 252], [251, 254], [301, 302], [312, 314], [312, 337], [315, 316], [315, 319], [324, 328], [328, 329], [328, 332], [329, 330], [332, 312], [332, 333], [333, 334]], "missing_branches": [[34, 36], [75, 67], [191, 192], [216, 219], [301, 304], [324, 326], [329, 331], [333, 335]]}}}, "app/utils/step_timeout.py": {"executed_lines": [8, 9, 10, 12, 14, 15, 17, 20, 23, 31, 34, 54, 55, 57, 58, 61, 67, 68, 70, 72, 75, 79, 80, 95, 96, 99, 110, 111], "summary": {"covered_lines": 28, "num_statements": 34, "percent_covered": 80.95238095238095, "percent_covered_display": "80.95", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 82.3529411764706, "percent_statements_covered_display": "82.35", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 6, "missing_branches": 2, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [73, 81, 82, 83, 88, 90], "excluded_lines": [], "executed_branches": [[54, 55], [54, 57], [67, 68], [67, 70], [72, 75], [80, 95]], "missing_branches": [[72, 73], [80, 81]], "functions": {"get_step_timeout": {"executed_lines": [31], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 23, "executed_branches": [], "missing_branches": []}, "mark_stalled_steps_as_failed": {"executed_lines": [54, 55, 57, 58, 61, 67, 68, 70, 72, 75, 79, 80, 95, 96], "summary": {"covered_lines": 14, "num_statements": 20, "percent_covered": 71.42857142857143, "percent_covered_display": "71.43", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 70.0, "percent_statements_covered_display": "70.00", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 6, "missing_branches": 2, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [73, 81, 82, 83, 88, 90], "excluded_lines": [], "start_line": 34, "executed_branches": [[54, 55], [54, 57], [67, 68], [67, 70], [72, 75], [80, 95]], "missing_branches": [[72, 73], [80, 81]]}, "check_and_recover_stalled_file": {"executed_lines": [110, 111], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 99, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [8, 9, 10, 12, 14, 15, 17, 20, 23, 34, 99], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [8, 9, 10, 12, 14, 15, 17, 20, 23, 31, 34, 54, 55, 57, 58, 61, 67, 68, 70, 72, 75, 79, 80, 95, 96, 99, 110, 111], "summary": {"covered_lines": 28, "num_statements": 34, "percent_covered": 80.95238095238095, "percent_covered_display": "80.95", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 82.3529411764706, "percent_statements_covered_display": "82.35", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 6, "missing_branches": 2, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [73, 81, 82, 83, 88, 90], "excluded_lines": [], "start_line": 1, "executed_branches": [[54, 55], [54, 57], [67, 68], [67, 70], [72, 75], [80, 95]], "missing_branches": [[72, 73], [80, 81]]}}}, "app/views/__init__.py": {"executed_lines": [5, 7, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 26, 27], "summary": {"covered_lines": 18, "num_statements": 18, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [5, 7, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 26, 27], "summary": {"covered_lines": 18, "num_statements": 18, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 26, 27], "summary": {"covered_lines": 18, "num_statements": 18, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/views/base.py": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 17, 18, 21, 22, 25, 28, 31, 32, 35, 38, 41], "summary": {"covered_lines": 19, "num_statements": 21, "percent_covered": 80.0, "percent_covered_display": "80.00", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 90.47619047619048, "percent_statements_covered_display": "90.48", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [33, 34], "excluded_lines": [], "executed_branches": [[31, 32]], "missing_branches": [[31, 33], [33, 34], [33, 35]], "functions": {"template_response_with_version": {"executed_lines": [31, 32, 35], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 44.44444444444444, "percent_covered_display": "44.44", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [33, 34], "excluded_lines": [], "start_line": 28, "executed_branches": [[31, 32]], "missing_branches": [[31, 33], [33, 34], [33, 35]]}, "": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 17, 18, 21, 22, 25, 28, 38, 41], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 17, 18, 21, 22, 25, 28, 31, 32, 35, 38, 41], "summary": {"covered_lines": 19, "num_statements": 21, "percent_covered": 80.0, "percent_covered_display": "80.00", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 90.47619047619048, "percent_statements_covered_display": "90.48", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [33, 34], "excluded_lines": [], "start_line": 1, "executed_branches": [[31, 32]], "missing_branches": [[31, 33], [33, 34], [33, 35]]}}}, "app/views/dropbox.py": {"executed_lines": [5, 7, 9, 12, 13, 14, 20, 22, 35, 36, 37, 42, 43, 45, 46, 53], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[42, 43], [42, 45], [45, 46], [45, 53]], "missing_branches": [], "functions": {"dropbox_setup_page": {"executed_lines": [20, 22], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 14, "executed_branches": [], "missing_branches": []}, "dropbox_callback": {"executed_lines": [42, 43, 45, 46, 53], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 37, "executed_branches": [[42, 43], [42, 45], [45, 46], [45, 53]], "missing_branches": []}, "": {"executed_lines": [5, 7, 9, 12, 13, 14, 35, 36, 37], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 9, 12, 13, 14, 20, 22, 35, 36, 37, 42, 43, 45, 46, 53], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[42, 43], [42, 45], [45, 46], [45, 53]], "missing_branches": []}}}, "app/views/files.py": {"executed_lines": [5, 7, 8, 10, 11, 12, 14, 17, 18, 19, 33, 35, 37, 40, 43, 47, 51, 54, 57, 65, 68, 71, 72, 75, 76, 79, 80, 81, 82, 85, 88, 89, 92, 94, 128, 129, 130, 134, 135, 136, 138, 141, 143, 144, 149, 157, 158, 159, 162, 163, 164, 167, 168, 170, 171, 172, 173, 174, 175, 180, 183, 184, 186, 191, 209, 217, 236, 238, 245, 269, 270, 272, 273, 276, 278, 279, 280, 281, 286, 287, 288, 293, 294, 295, 298, 299, 300, 301, 302, 303, 305, 306, 307, 308, 310, 322, 323, 324, 325, 326, 328, 339, 341, 343, 346, 355, 358, 359, 360, 361, 374, 376, 377, 380, 381, 383, 384, 385, 388, 392, 394, 396, 397, 398, 400, 401, 404, 405, 406, 409, 410, 411, 413, 421, 422, 423, 427, 429, 430, 432, 434, 435, 438, 439, 441, 448, 449, 450, 454, 456, 457, 459, 461, 462, 465, 466, 468, 475, 476, 477, 515, 516, 517], "summary": {"covered_lines": 163, "num_statements": 224, "percent_covered": 69.48051948051948, "percent_covered_display": "69.48", "missing_lines": 61, "excluded_lines": 0, "percent_statements_covered": 72.76785714285714, "percent_statements_covered_display": "72.77", "num_branches": 84, "num_partial_branches": 15, "covered_branches": 51, "missing_branches": 33, "percent_branches_covered": 60.714285714285715, "percent_branches_covered_display": "60.71"}, "missing_lines": [44, 48, 66, 113, 115, 117, 176, 177, 187, 189, 204, 205, 206, 239, 241, 242, 389, 436, 463, 481, 483, 484, 486, 488, 489, 490, 492, 493, 495, 497, 499, 500, 501, 502, 504, 505, 507, 508, 509, 510, 521, 523, 524, 526, 528, 529, 530, 532, 533, 535, 537, 539, 540, 541, 542, 544, 545, 547, 548, 549, 550], "excluded_lines": [], "executed_branches": [[43, 47], [47, 51], [65, 68], [80, 81], [80, 85], [143, 144], [143, 149], [158, 159], [158, 162], [163, 164], [163, 167], [168, 170], [168, 180], [171, 172], [171, 180], [238, 245], [272, 273], [272, 293], [276, 278], [276, 286], [279, 280], [286, 287], [294, 295], [294, 343], [298, 299], [298, 305], [322, 323], [322, 341], [324, 325], [324, 339], [359, 360], [383, 384], [383, 404], [388, 392], [394, 396], [394, 398], [396, 397], [398, 400], [400, 401], [404, 405], [404, 409], [405, 406], [409, 410], [409, 413], [410, 411], [435, 438], [438, 439], [438, 441], [462, 465], [465, 466], [465, 468]], "missing_branches": [[43, 44], [47, 48], [65, 66], [238, 239], [241, 242], [241, 245], [279, 281], [286, 288], [359, 361], [388, 389], [396, 383], [398, 383], [400, 383], [405, 404], [410, 409], [435, 436], [462, 463], [489, 490], [489, 492], [492, 493], [492, 495], [501, 502], [501, 504], [504, 505], [504, 507], [529, 530], [529, 532], [532, 533], [532, 535], [541, 542], [541, 544], [544, 545], [544, 547]], "functions": {"files_page": {"executed_lines": [33, 35, 37, 40, 43, 47, 51, 54, 57, 65, 68, 71, 72, 75, 76, 79, 80, 81, 82, 85, 88, 89, 92, 94], "summary": {"covered_lines": 24, "num_statements": 30, "percent_covered": 76.3157894736842, "percent_covered_display": "76.32", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80.00", "num_branches": 8, "num_partial_branches": 3, "covered_branches": 5, "missing_branches": 3, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62.50"}, "missing_lines": [44, 48, 66, 113, 115, 117], "excluded_lines": [], "start_line": 19, "executed_branches": [[43, 47], [47, 51], [65, 68], [80, 81], [80, 85]], "missing_branches": [[43, 44], [47, 48], [65, 66]]}, "file_detail_page": {"executed_lines": [134, 135, 136, 138, 141, 143, 144, 149, 157, 158, 159, 162, 163, 164, 167, 168, 170, 171, 172, 173, 174, 175, 180, 183, 184, 186, 191], "summary": {"covered_lines": 27, "num_statements": 34, "percent_covered": 84.0909090909091, "percent_covered_display": "84.09", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 79.41176470588235, "percent_statements_covered_display": "79.41", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 10, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [176, 177, 187, 189, 204, 205, 206], "excluded_lines": [], "start_line": 130, "executed_branches": [[143, 144], [143, 149], [158, 159], [158, 162], [163, 164], [163, 167], [168, 170], [168, 180], [171, 172], [171, 180]], "missing_branches": []}, "_compute_processing_flow": {"executed_lines": [217, 236, 238, 245, 269, 270, 272, 273, 276, 278, 279, 280, 281, 286, 287, 288, 293, 294, 295, 298, 299, 300, 301, 302, 303, 305, 306, 307, 308, 310, 322, 323, 324, 325, 326, 328, 339, 341, 343], "summary": {"covered_lines": 39, "num_statements": 42, "percent_covered": 87.09677419354838, "percent_covered_display": "87.10", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 92.85714285714286, "percent_statements_covered_display": "92.86", "num_branches": 20, "num_partial_branches": 3, "covered_branches": 15, "missing_branches": 5, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [239, 241, 242], "excluded_lines": [], "start_line": 209, "executed_branches": [[238, 245], [272, 273], [272, 293], [276, 278], [276, 286], [279, 280], [286, 287], [294, 295], [294, 343], [298, 299], [298, 305], [322, 323], [322, 341], [324, 325], [324, 339]], "missing_branches": [[238, 239], [241, 242], [241, 245], [279, 281], [286, 288]]}, "_compute_step_summary": {"executed_lines": [355, 358, 359, 360, 361, 374, 376, 377, 380, 381, 383, 384, 385, 388, 392, 394, 396, 397, 398, 400, 401, 404, 405, 406, 409, 410, 411, 413], "summary": {"covered_lines": 28, "num_statements": 29, "percent_covered": 84.31372549019608, "percent_covered_display": "84.31", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 96.55172413793103, "percent_statements_covered_display": "96.55", "num_branches": 22, "num_partial_branches": 7, "covered_branches": 15, "missing_branches": 7, "percent_branches_covered": 68.18181818181819, "percent_branches_covered_display": "68.18"}, "missing_lines": [389], "excluded_lines": [], "start_line": 346, "executed_branches": [[359, 360], [383, 384], [383, 404], [388, 392], [394, 396], [394, 398], [396, 397], [398, 400], [400, 401], [404, 405], [404, 409], [405, 406], [409, 410], [409, 413], [410, 411]], "missing_branches": [[359, 361], [388, 389], [396, 383], [398, 383], [400, 383], [405, 404], [410, 409]]}, "preview_original_file": {"executed_lines": [427, 429, 430, 432, 434, 435, 438, 439, 441], "summary": {"covered_lines": 9, "num_statements": 10, "percent_covered": 85.71428571428571, "percent_covered_display": "85.71", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.0, "percent_statements_covered_display": "90.00", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [436], "excluded_lines": [], "start_line": 423, "executed_branches": [[435, 438], [438, 439], [438, 441]], "missing_branches": [[435, 436]]}, "preview_processed_file": {"executed_lines": [454, 456, 457, 459, 461, 462, 465, 466, 468], "summary": {"covered_lines": 9, "num_statements": 10, "percent_covered": 85.71428571428571, "percent_covered_display": "85.71", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.0, "percent_statements_covered_display": "90.00", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [463], "excluded_lines": [], "start_line": 450, "executed_branches": [[462, 465], [465, 466], [465, 468]], "missing_branches": [[462, 463]]}, "get_original_text": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 21, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 21, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [481, 483, 484, 486, 488, 489, 490, 492, 493, 495, 497, 499, 500, 501, 502, 504, 505, 507, 508, 509, 510], "excluded_lines": [], "start_line": 477, "executed_branches": [], "missing_branches": [[489, 490], [489, 492], [492, 493], [492, 495], [501, 502], [501, 504], [504, 505], [504, 507]]}, "get_processed_text": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 21, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 21, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [521, 523, 524, 526, 528, 529, 530, 532, 533, 535, 537, 539, 540, 541, 542, 544, 545, 547, 548, 549, 550], "excluded_lines": [], "start_line": 517, "executed_branches": [], "missing_branches": [[529, 530], [529, 532], [532, 533], [532, 535], [541, 542], [541, 544], [544, 545], [544, 547]]}, "": {"executed_lines": [5, 7, 8, 10, 11, 12, 14, 17, 18, 19, 128, 129, 130, 209, 346, 421, 422, 423, 448, 449, 450, 475, 476, 477, 515, 516, 517], "summary": {"covered_lines": 27, "num_statements": 27, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 8, 10, 11, 12, 14, 17, 18, 19, 33, 35, 37, 40, 43, 47, 51, 54, 57, 65, 68, 71, 72, 75, 76, 79, 80, 81, 82, 85, 88, 89, 92, 94, 128, 129, 130, 134, 135, 136, 138, 141, 143, 144, 149, 157, 158, 159, 162, 163, 164, 167, 168, 170, 171, 172, 173, 174, 175, 180, 183, 184, 186, 191, 209, 217, 236, 238, 245, 269, 270, 272, 273, 276, 278, 279, 280, 281, 286, 287, 288, 293, 294, 295, 298, 299, 300, 301, 302, 303, 305, 306, 307, 308, 310, 322, 323, 324, 325, 326, 328, 339, 341, 343, 346, 355, 358, 359, 360, 361, 374, 376, 377, 380, 381, 383, 384, 385, 388, 392, 394, 396, 397, 398, 400, 401, 404, 405, 406, 409, 410, 411, 413, 421, 422, 423, 427, 429, 430, 432, 434, 435, 438, 439, 441, 448, 449, 450, 454, 456, 457, 459, 461, 462, 465, 466, 468, 475, 476, 477, 515, 516, 517], "summary": {"covered_lines": 163, "num_statements": 224, "percent_covered": 69.48051948051948, "percent_covered_display": "69.48", "missing_lines": 61, "excluded_lines": 0, "percent_statements_covered": 72.76785714285714, "percent_statements_covered_display": "72.77", "num_branches": 84, "num_partial_branches": 15, "covered_branches": 51, "missing_branches": 33, "percent_branches_covered": 60.714285714285715, "percent_branches_covered_display": "60.71"}, "missing_lines": [44, 48, 66, 113, 115, 117, 176, 177, 187, 189, 204, 205, 206, 239, 241, 242, 389, 436, 463, 481, 483, 484, 486, 488, 489, 490, 492, 493, 495, 497, 499, 500, 501, 502, 504, 505, 507, 508, 509, 510, 521, 523, 524, 526, 528, 529, 530, 532, 533, 535, 537, 539, 540, 541, 542, 544, 545, 547, 548, 549, 550], "excluded_lines": [], "start_line": 1, "executed_branches": [[43, 47], [47, 51], [65, 68], [80, 81], [80, 85], [143, 144], [143, 149], [158, 159], [158, 162], [163, 164], [163, 167], [168, 170], [168, 180], [171, 172], [171, 180], [238, 245], [272, 273], [272, 293], [276, 278], [276, 286], [279, 280], [286, 287], [294, 295], [294, 343], [298, 299], [298, 305], [322, 323], [322, 341], [324, 325], [324, 339], [359, 360], [383, 384], [383, 404], [388, 392], [394, 396], [394, 398], [396, 397], [398, 400], [400, 401], [404, 405], [404, 409], [405, 406], [409, 410], [409, 413], [410, 411], [435, 438], [438, 439], [438, 441], [462, 465], [465, 466], [465, 468]], "missing_branches": [[43, 44], [47, 48], [65, 66], [238, 239], [241, 242], [241, 245], [279, 281], [286, 288], [359, 361], [388, 389], [396, 383], [398, 383], [400, 383], [405, 404], [410, 409], [435, 436], [462, 463], [489, 490], [489, 492], [492, 493], [492, 495], [501, 502], [501, 504], [504, 505], [504, 507], [529, 530], [529, 532], [532, 533], [532, 535], [541, 542], [541, 544], [544, 545], [544, 547]]}}}, "app/views/general.py": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 15, 18, 19, 26, 27, 30, 33, 35, 36, 37, 40, 43, 46, 47, 55, 56, 58, 60, 66, 72, 75, 76, 78, 81, 82, 85, 86, 89, 90, 92, 95, 96, 97, 99, 102, 103, 105, 106, 109, 112, 113, 116, 122, 125, 126, 127, 128, 129, 134, 145, 148, 149, 151, 152, 155, 156, 158, 159], "summary": {"covered_lines": 65, "num_statements": 71, "percent_covered": 88.60759493670886, "percent_covered_display": "88.61", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 91.54929577464789, "percent_statements_covered_display": "91.55", "num_branches": 8, "num_partial_branches": 3, "covered_branches": 5, "missing_branches": 3, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62.50"}, "missing_lines": [61, 63, 108, 130, 131, 135], "excluded_lines": [], "executed_branches": [[35, 36], [35, 40], [106, 109], [125, 126], [134, 145]], "missing_branches": [[106, 108], [125, 134], [134, 135]], "functions": {"serve_index": {"executed_lines": [26, 27, 30, 33, 35, 36, 37, 40, 43, 46, 47, 55, 56, 58, 60, 66, 72], "summary": {"covered_lines": 17, "num_statements": 19, "percent_covered": 90.47619047619048, "percent_covered_display": "90.48", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 89.47368421052632, "percent_statements_covered_display": "89.47", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [61, 63], "excluded_lines": [], "start_line": 19, "executed_branches": [[35, 36], [35, 40]], "missing_branches": []}, "serve_about": {"executed_lines": [78], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 76, "executed_branches": [], "missing_branches": []}, "serve_privacy": {"executed_lines": [85, 86], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 82, "executed_branches": [], "missing_branches": []}, "serve_imprint": {"executed_lines": [92], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 90, "executed_branches": [], "missing_branches": []}, "serve_upload": {"executed_lines": [99], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 97, "executed_branches": [], "missing_branches": []}, "favicon": {"executed_lines": [105, 106, 109], "summary": {"covered_lines": 3, "num_statements": 4, "percent_covered": 66.66666666666667, "percent_covered_display": "66.67", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [108], "excluded_lines": [], "start_line": 103, "executed_branches": [[106, 109]], "missing_branches": [[106, 108]]}, "serve_license": {"executed_lines": [116, 122, 125, 126, 127, 128, 129, 134, 145], "summary": {"covered_lines": 9, "num_statements": 12, "percent_covered": 68.75, "percent_covered_display": "68.75", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75.00", "num_branches": 4, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 2, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [130, 131, 135], "excluded_lines": [], "start_line": 113, "executed_branches": [[125, 126], [134, 145]], "missing_branches": [[125, 134], [134, 135]]}, "serve_cookies": {"executed_lines": [151, 152], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 149, "executed_branches": [], "missing_branches": []}, "serve_terms": {"executed_lines": [158, 159], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 156, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 15, 18, 19, 75, 76, 81, 82, 89, 90, 95, 96, 97, 102, 103, 112, 113, 148, 149, 155, 156], "summary": {"covered_lines": 27, "num_statements": 27, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 15, 18, 19, 26, 27, 30, 33, 35, 36, 37, 40, 43, 46, 47, 55, 56, 58, 60, 66, 72, 75, 76, 78, 81, 82, 85, 86, 89, 90, 92, 95, 96, 97, 99, 102, 103, 105, 106, 109, 112, 113, 116, 122, 125, 126, 127, 128, 129, 134, 145, 148, 149, 151, 152, 155, 156, 158, 159], "summary": {"covered_lines": 65, "num_statements": 71, "percent_covered": 88.60759493670886, "percent_covered_display": "88.61", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 91.54929577464789, "percent_statements_covered_display": "91.55", "num_branches": 8, "num_partial_branches": 3, "covered_branches": 5, "missing_branches": 3, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62.50"}, "missing_lines": [61, 63, 108, 130, 131, 135], "excluded_lines": [], "start_line": 1, "executed_branches": [[35, 36], [35, 40], [106, 109], [125, 126], [134, 145]], "missing_branches": [[106, 108], [125, 134], [134, 135]]}}}, "app/views/google_drive.py": {"executed_lines": [5, 7, 8, 10, 12, 15, 16, 17, 23, 26, 31, 34, 36, 39, 42, 62, 63, 64, 69, 70, 72, 73, 79, 82, 83, 84], "summary": {"covered_lines": 26, "num_statements": 33, "percent_covered": 75.60975609756098, "percent_covered_display": "75.61", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 78.78787878787878, "percent_statements_covered_display": "78.79", "num_branches": 8, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 3, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62.50"}, "missing_lines": [37, 88, 89, 93, 95, 97, 107], "excluded_lines": [], "executed_branches": [[36, 39], [69, 70], [69, 72], [72, 73], [72, 79]], "missing_branches": [[36, 37], [88, 89], [88, 93]], "functions": {"google_drive_setup_page": {"executed_lines": [23, 26, 31, 34, 36, 39, 42], "summary": {"covered_lines": 7, "num_statements": 8, "percent_covered": 80.0, "percent_covered_display": "80.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 87.5, "percent_statements_covered_display": "87.50", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [37], "excluded_lines": [], "start_line": 17, "executed_branches": [[36, 39]], "missing_branches": [[36, 37]]}, "google_drive_callback": {"executed_lines": [69, 70, 72, 73, 79], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 64, "executed_branches": [[69, 70], [69, 72], [72, 73], [72, 79]], "missing_branches": []}, "google_drive_auth_start": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 6, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [88, 89, 93, 95, 97, 107], "excluded_lines": [], "start_line": 84, "executed_branches": [], "missing_branches": [[88, 89], [88, 93]]}, "": {"executed_lines": [5, 7, 8, 10, 12, 15, 16, 17, 62, 63, 64, 82, 83, 84], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 8, 10, 12, 15, 16, 17, 23, 26, 31, 34, 36, 39, 42, 62, 63, 64, 69, 70, 72, 73, 79, 82, 83, 84], "summary": {"covered_lines": 26, "num_statements": 33, "percent_covered": 75.60975609756098, "percent_covered_display": "75.61", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 78.78787878787878, "percent_statements_covered_display": "78.79", "num_branches": 8, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 3, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62.50"}, "missing_lines": [37, 88, 89, 93, 95, 97, 107], "excluded_lines": [], "start_line": 1, "executed_branches": [[36, 39], [69, 70], [69, 72], [72, 73], [72, 79]], "missing_branches": [[36, 37], [88, 89], [88, 93]]}}}, "app/views/license_routes.py": {"executed_lines": [1, 3, 4, 6, 8, 11, 12, 24, 25], "summary": {"covered_lines": 9, "num_statements": 15, "percent_covered": 52.94117647058823, "percent_covered_display": "52.94", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [16, 17, 18, 20, 21, 29], "excluded_lines": [], "executed_branches": [], "missing_branches": [[17, 18], [17, 20]], "functions": {"get_lgpl_license": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [16, 17, 18, 20, 21], "excluded_lines": [], "start_line": 12, "executed_branches": [], "missing_branches": [[17, 18], [17, 20]]}, "serve_attribution": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [29], "excluded_lines": [], "start_line": 25, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [1, 3, 4, 6, 8, 11, 12, 24, 25], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [1, 3, 4, 6, 8, 11, 12, 24, 25], "summary": {"covered_lines": 9, "num_statements": 15, "percent_covered": 52.94117647058823, "percent_covered_display": "52.94", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [16, 17, 18, 20, 21, 29], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": [[17, 18], [17, 20]]}}}, "app/views/onedrive.py": {"executed_lines": [5, 7, 9, 12, 13, 14, 20, 25, 42, 43, 44, 49, 50, 52, 53, 59], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[49, 50], [49, 52], [52, 53], [52, 59]], "missing_branches": [], "functions": {"onedrive_setup_page": {"executed_lines": [20, 25], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 14, "executed_branches": [], "missing_branches": []}, "onedrive_callback": {"executed_lines": [49, 50, 52, 53, 59], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 44, "executed_branches": [[49, 50], [49, 52], [52, 53], [52, 59]], "missing_branches": []}, "": {"executed_lines": [5, 7, 9, 12, 13, 14, 42, 43, 44], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 9, 12, 13, 14, 20, 25, 42, 43, 44, 49, 50, 52, 53, 59], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[49, 50], [49, 52], [52, 53], [52, 59]], "missing_branches": []}}}, "app/views/settings.py": {"executed_lines": [5, 6, 7, 8, 10, 11, 12, 14, 15, 16, 18, 19, 22, 31, 32, 33, 34, 35, 36, 39, 40, 44, 47, 48, 49, 50], "summary": {"covered_lines": 26, "num_statements": 56, "percent_covered": 41.42857142857143, "percent_covered_display": "41.43", "missing_lines": 30, "excluded_lines": 0, "percent_statements_covered": 46.42857142857143, "percent_statements_covered_display": "46.43", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 11, "percent_branches_covered": 21.428571428571427, "percent_branches_covered_display": "21.43"}, "missing_lines": [42, 58, 60, 62, 65, 68, 69, 70, 71, 73, 77, 78, 79, 80, 82, 83, 84, 85, 88, 89, 90, 93, 96, 97, 98, 100, 111, 114, 115, 116], "excluded_lines": [], "executed_branches": [[34, 35], [34, 39], [39, 40]], "missing_branches": [[39, 42], [69, 70], [69, 111], [71, 69], [71, 73], [77, 78], [77, 82], [82, 83], [82, 88], [97, 98], [97, 100]], "functions": {"require_admin_access": {"executed_lines": [31, 32, 44], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 22, "executed_branches": [], "missing_branches": []}, "require_admin_access.wrapper": {"executed_lines": [33, 34, 35, 36, 39, 40], "summary": {"covered_lines": 6, "num_statements": 7, "percent_covered": 81.81818181818181, "percent_covered_display": "81.82", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 85.71428571428571, "percent_statements_covered_display": "85.71", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [42], "excluded_lines": [], "start_line": 32, "executed_branches": [[34, 35], [34, 39], [39, 40]], "missing_branches": [[39, 42]]}, "settings_page": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 29, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 29, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 10, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [58, 60, 62, 65, 68, 69, 70, 71, 73, 77, 78, 79, 80, 82, 83, 84, 85, 88, 89, 90, 93, 96, 97, 98, 100, 111, 114, 115, 116], "excluded_lines": [], "start_line": 50, "executed_branches": [], "missing_branches": [[69, 70], [69, 111], [71, 69], [71, 73], [77, 78], [77, 82], [82, 83], [82, 88], [97, 98], [97, 100]]}, "": {"executed_lines": [5, 6, 7, 8, 10, 11, 12, 14, 15, 16, 18, 19, 22, 47, 48, 49, 50], "summary": {"covered_lines": 17, "num_statements": 17, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 8, 10, 11, 12, 14, 15, 16, 18, 19, 22, 31, 32, 33, 34, 35, 36, 39, 40, 44, 47, 48, 49, 50], "summary": {"covered_lines": 26, "num_statements": 56, "percent_covered": 41.42857142857143, "percent_covered_display": "41.43", "missing_lines": 30, "excluded_lines": 0, "percent_statements_covered": 46.42857142857143, "percent_statements_covered_display": "46.43", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 11, "percent_branches_covered": 21.428571428571427, "percent_branches_covered_display": "21.43"}, "missing_lines": [42, 58, 60, 62, 65, 68, 69, 70, 71, 73, 77, 78, 79, 80, 82, 83, 84, 85, 88, 89, 90, 93, 96, 97, 98, 100, 111, 114, 115, 116], "excluded_lines": [], "start_line": 1, "executed_branches": [[34, 35], [34, 39], [39, 40]], "missing_branches": [[39, 42], [69, 70], [69, 111], [71, 69], [71, 73], [77, 78], [77, 82], [82, 83], [82, 88], [97, 98], [97, 100]]}}}, "app/views/status.py": {"executed_lines": [5, 6, 7, 9, 11, 13, 14, 17, 18, 19, 23, 26, 29, 32, 33, 35, 63, 66, 67, 68, 75, 77, 92, 93, 94, 100, 103, 105, 107], "summary": {"covered_lines": 29, "num_statements": 52, "percent_covered": 51.724137931034484, "percent_covered_display": "51.72", "missing_lines": 23, "excluded_lines": 0, "percent_statements_covered": 55.76923076923077, "percent_statements_covered_display": "55.77", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 5, "percent_branches_covered": 16.666666666666668, "percent_branches_covered_display": "16.67"}, "missing_lines": [37, 40, 41, 42, 43, 44, 45, 46, 47, 48, 51, 52, 53, 54, 55, 58, 59, 60, 61, 69, 70, 71, 72], "excluded_lines": [], "executed_branches": [[35, 63]], "missing_branches": [[35, 37], [42, 43], [42, 51], [43, 42], [43, 44]], "functions": {"status_dashboard": {"executed_lines": [23, 26, 29, 32, 33, 35, 63, 66, 67, 68, 75, 77], "summary": {"covered_lines": 12, "num_statements": 35, "percent_covered": 31.70731707317073, "percent_covered_display": "31.71", "missing_lines": 23, "excluded_lines": 0, "percent_statements_covered": 34.285714285714285, "percent_statements_covered_display": "34.29", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 5, "percent_branches_covered": 16.666666666666668, "percent_branches_covered_display": "16.67"}, "missing_lines": [37, 40, 41, 42, 43, 44, 45, 46, 47, 48, 51, 52, 53, 54, 55, 58, 59, 60, 61, 69, 70, 71, 72], "excluded_lines": [], "start_line": 19, "executed_branches": [[35, 63]], "missing_branches": [[35, 37], [42, 43], [42, 51], [43, 42], [43, 44]]}, "env_debug": {"executed_lines": [100, 103, 105, 107], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 94, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [5, 6, 7, 9, 11, 13, 14, 17, 18, 19, 92, 93, 94], "summary": {"covered_lines": 13, "num_statements": 13, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 9, 11, 13, 14, 17, 18, 19, 23, 26, 29, 32, 33, 35, 63, 66, 67, 68, 75, 77, 92, 93, 94, 100, 103, 105, 107], "summary": {"covered_lines": 29, "num_statements": 52, "percent_covered": 51.724137931034484, "percent_covered_display": "51.72", "missing_lines": 23, "excluded_lines": 0, "percent_statements_covered": 55.76923076923077, "percent_statements_covered_display": "55.77", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 5, "percent_branches_covered": 16.666666666666668, "percent_branches_covered_display": "16.67"}, "missing_lines": [37, 40, 41, 42, 43, 44, 45, 46, 47, 48, 51, 52, 53, 54, 55, 58, 59, 60, 61, 69, 70, 71, 72], "excluded_lines": [], "start_line": 1, "executed_branches": [[35, 63]], "missing_branches": [[35, 37], [42, 43], [42, 51], [43, 42], [43, 44]]}}}, "app/views/wizard.py": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 20, 21, 29, 30, 33, 34, 35, 36, 39, 42, 44, 57, 58, 62, 64, 67, 68, 71, 72, 73, 74, 77, 79, 80, 81, 84, 85, 86, 88, 91, 92, 94, 96, 99, 106, 107, 113, 114, 115, 117, 118, 119, 121], "summary": {"covered_lines": 53, "num_statements": 59, "percent_covered": 90.41095890410959, "percent_covered_display": "90.41", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 89.83050847457628, "percent_statements_covered_display": "89.83", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 13, "missing_branches": 1, "percent_branches_covered": 92.85714285714286, "percent_branches_covered_display": "92.86"}, "missing_lines": [101, 102, 103, 122, 123, 124], "excluded_lines": [], "executed_branches": [[33, 34], [33, 35], [35, 36], [35, 39], [72, 73], [72, 88], [77, 72], [77, 79], [79, 80], [79, 84], [84, 85], [94, 96], [94, 99]], "missing_branches": [[84, 72]], "functions": {"setup_wizard": {"executed_lines": [29, 30, 33, 34, 35, 36, 39, 42, 44], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 21, "executed_branches": [[33, 34], [33, 35], [35, 36], [35, 39]], "missing_branches": []}, "setup_wizard_save": {"executed_lines": [62, 64, 67, 68, 71, 72, 73, 74, 77, 79, 80, 81, 84, 85, 86, 88, 91, 92, 94, 96, 99], "summary": {"covered_lines": 21, "num_statements": 24, "percent_covered": 88.23529411764706, "percent_covered_display": "88.24", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 87.5, "percent_statements_covered_display": "87.50", "num_branches": 10, "num_partial_branches": 1, "covered_branches": 9, "missing_branches": 1, "percent_branches_covered": 90.0, "percent_branches_covered_display": "90.00"}, "missing_lines": [101, 102, 103], "excluded_lines": [], "start_line": 58, "executed_branches": [[72, 73], [72, 88], [77, 72], [77, 79], [79, 80], [79, 84], [84, 85], [94, 96], [94, 99]], "missing_branches": [[84, 72]]}, "setup_wizard_skip": {"executed_lines": [113, 114, 115, 117, 118, 119, 121], "summary": {"covered_lines": 7, "num_statements": 10, "percent_covered": 70.0, "percent_covered_display": "70.00", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 70.0, "percent_statements_covered_display": "70.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [122, 123, 124], "excluded_lines": [], "start_line": 107, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 20, 21, 57, 58, 106, 107], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 20, 21, 29, 30, 33, 34, 35, 36, 39, 42, 44, 57, 58, 62, 64, 67, 68, 71, 72, 73, 74, 77, 79, 80, 81, 84, 85, 86, 88, 91, 92, 94, 96, 99, 106, 107, 113, 114, 115, 117, 118, 119, 121], "summary": {"covered_lines": 53, "num_statements": 59, "percent_covered": 90.41095890410959, "percent_covered_display": "90.41", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 89.83050847457628, "percent_statements_covered_display": "89.83", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 13, "missing_branches": 1, "percent_branches_covered": 92.85714285714286, "percent_branches_covered_display": "92.86"}, "missing_lines": [101, 102, 103, 122, 123, 124], "excluded_lines": [], "start_line": 1, "executed_branches": [[33, 34], [33, 35], [35, 36], [35, 39], [72, 73], [72, 88], [77, 72], [77, 79], [79, 80], [79, 84], [84, 85], [94, 96], [94, 99]], "missing_branches": [[84, 72]]}}}}, "totals": {"covered_lines": 4002, "num_statements": 6286, "percent_covered": 60.58339566192969, "percent_covered_display": "60.58", "missing_lines": 2284, "excluded_lines": 0, "percent_statements_covered": 63.66528794145721, "percent_statements_covered_display": "63.67", "num_branches": 1736, "num_partial_branches": 234, "covered_branches": 858, "missing_branches": 878, "percent_branches_covered": 49.423963133640555, "percent_branches_covered_display": "49.42"}} \ No newline at end of file +{"meta": {"format": 3, "version": "7.13.4", "timestamp": "2026-02-12T09:26:29.397216", "branch_coverage": true, "show_contexts": false}, "files": {"app/__init__.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/api/__init__.py": {"executed_lines": [5, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 25, 28, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42], "summary": {"covered_lines": 28, "num_statements": 28, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [5, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 25, 28, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42], "summary": {"covered_lines": 28, "num_statements": 28, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 25, 28, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42], "summary": {"covered_lines": 28, "num_statements": 28, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/api/azure.py": {"executed_lines": [5, 7, 8, 11, 12, 14, 15, 18, 20, 23, 24, 25, 30, 31, 34, 48, 50, 55, 91, 98, 99, 100], "summary": {"covered_lines": 22, "num_statements": 52, "percent_covered": 37.096774193548384, "percent_covered_display": "37.10", "missing_lines": 30, "excluded_lines": 0, "percent_statements_covered": 42.30769230769231, "percent_statements_covered_display": "42.31", "num_branches": 10, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 9, "percent_branches_covered": 10.0, "percent_branches_covered_display": "10.00"}, "missing_lines": [35, 36, 37, 38, 39, 40, 42, 58, 61, 62, 63, 64, 65, 71, 73, 74, 81, 83, 84, 92, 93, 105, 106, 107, 108, 109, 110, 112, 113, 114], "excluded_lines": [], "executed_branches": [[34, 48]], "missing_branches": [[34, 35], [37, 38], [37, 39], [39, 40], [39, 42], [63, 64], [63, 73], [64, 63], [64, 65]], "functions": {"test_azure_connection": {"executed_lines": [30, 31, 34, 48, 50, 55, 91, 98, 99, 100], "summary": {"covered_lines": 10, "num_statements": 40, "percent_covered": 22.0, "percent_covered_display": "22.00", "missing_lines": 30, "excluded_lines": 0, "percent_statements_covered": 25.0, "percent_statements_covered_display": "25.00", "num_branches": 10, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 9, "percent_branches_covered": 10.0, "percent_branches_covered_display": "10.00"}, "missing_lines": [35, 36, 37, 38, 39, 40, 42, 58, 61, 62, 63, 64, 65, 71, 73, 74, 81, 83, 84, 92, 93, 105, 106, 107, 108, 109, 110, 112, 113, 114], "excluded_lines": [], "start_line": 25, "executed_branches": [[34, 48]], "missing_branches": [[34, 35], [37, 38], [37, 39], [39, 40], [39, 42], [63, 64], [63, 73], [64, 63], [64, 65]]}, "": {"executed_lines": [5, 7, 8, 11, 12, 14, 15, 18, 20, 23, 24, 25], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 8, 11, 12, 14, 15, 18, 20, 23, 24, 25, 30, 31, 34, 48, 50, 55, 91, 98, 99, 100], "summary": {"covered_lines": 22, "num_statements": 52, "percent_covered": 37.096774193548384, "percent_covered_display": "37.10", "missing_lines": 30, "excluded_lines": 0, "percent_statements_covered": 42.30769230769231, "percent_statements_covered_display": "42.31", "num_branches": 10, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 9, "percent_branches_covered": 10.0, "percent_branches_covered_display": "10.00"}, "missing_lines": [35, 36, 37, 38, 39, 40, 42, 58, 61, 62, 63, 64, 65, 71, 73, 74, 81, 83, 84, 92, 93, 105, 106, 107, 108, 109, 110, 112, 113, 114], "excluded_lines": [], "start_line": 1, "executed_branches": [[34, 48]], "missing_branches": [[34, 35], [37, 38], [37, 39], [39, 40], [39, 42], [63, 64], [63, 73], [64, 63], [64, 65]]}}}, "app/api/common.py": {"executed_lines": [5, 6, 7, 9, 11, 14, 17, 37, 40, 41, 43, 46, 48, 51, 55, 56, 57, 59, 60, 64], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[40, 41], [40, 43], [46, 48], [46, 51]], "missing_branches": [], "functions": {"resolve_file_path": {"executed_lines": [37, 40, 41, 43, 46, 48, 51, 55, 56, 57, 59, 60, 64], "summary": {"covered_lines": 13, "num_statements": 13, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 17, "executed_branches": [[40, 41], [40, 43], [46, 48], [46, 51]], "missing_branches": []}, "": {"executed_lines": [5, 6, 7, 9, 11, 14, 17], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 9, 11, 14, 17, 37, 40, 41, 43, 46, 48, 51, 55, 56, 57, 59, 60, 64], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[40, 41], [40, 43], [46, 48], [46, 51]], "missing_branches": []}}}, "app/api/diagnostic.py": {"executed_lines": [5, 6, 8, 10, 11, 14, 16, 18, 21, 22, 23, 28, 31, 34, 54, 61, 62, 63, 65, 67, 68, 71, 73, 74, 75, 76], "summary": {"covered_lines": 26, "num_statements": 36, "percent_covered": 67.5, "percent_covered_display": "67.50", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 72.22222222222223, "percent_statements_covered_display": "72.22", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [82, 83, 93, 94, 95, 101, 102, 107, 108, 109], "excluded_lines": [], "executed_branches": [[75, 76]], "missing_branches": [[75, 82], [93, 94], [93, 101]], "functions": {"diagnostic_settings": {"executed_lines": [28, 31, 34, 54], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 23, "executed_branches": [], "missing_branches": []}, "test_notification": {"executed_lines": [65, 67, 68, 71, 73, 74, 75, 76], "summary": {"covered_lines": 8, "num_statements": 18, "percent_covered": 40.90909090909091, "percent_covered_display": "40.91", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 44.44444444444444, "percent_statements_covered_display": "44.44", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [82, 83, 93, 94, 95, 101, 102, 107, 108, 109], "excluded_lines": [], "start_line": 63, "executed_branches": [[75, 76]], "missing_branches": [[75, 82], [93, 94], [93, 101]]}, "": {"executed_lines": [5, 6, 8, 10, 11, 14, 16, 18, 21, 22, 23, 61, 62, 63], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 8, 10, 11, 14, 16, 18, 21, 22, 23, 28, 31, 34, 54, 61, 62, 63, 65, 67, 68, 71, 73, 74, 75, 76], "summary": {"covered_lines": 26, "num_statements": 36, "percent_covered": 67.5, "percent_covered_display": "67.50", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 72.22222222222223, "percent_statements_covered_display": "72.22", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [82, 83, 93, 94, 95, 101, 102, 107, 108, 109], "excluded_lines": [], "start_line": 1, "executed_branches": [[75, 76]], "missing_branches": [[75, 82], [93, 94], [93, 101]]}}}, "app/api/dropbox.py": {"executed_lines": [5, 6, 7, 9, 10, 12, 13, 14, 17, 19, 22, 23, 24, 58, 59, 60, 101, 102, 103, 107, 108, 110, 111, 112, 182, 183, 184], "summary": {"covered_lines": 27, "num_statements": 125, "percent_covered": 16.374269005847953, "percent_covered_display": "16.37", "missing_lines": 98, "excluded_lines": 0, "percent_statements_covered": 21.6, "percent_statements_covered_display": "21.60", "num_branches": 46, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 45, "percent_branches_covered": 2.1739130434782608, "percent_branches_covered_display": "2.17"}, "missing_lines": [37, 39, 48, 51, 70, 71, 74, 75, 76, 78, 79, 80, 82, 83, 84, 86, 87, 88, 92, 94, 95, 96, 115, 116, 123, 124, 127, 128, 135, 137, 138, 139, 141, 142, 145, 146, 152, 153, 154, 160, 161, 162, 165, 167, 169, 177, 178, 179, 194, 196, 198, 199, 200, 204, 207, 208, 211, 216, 217, 218, 219, 220, 221, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 241, 242, 243, 246, 247, 250, 251, 252, 253, 254, 255, 256, 257, 259, 261, 263, 264, 265, 266, 267], "excluded_lines": [], "executed_branches": [[110, 111]], "missing_branches": [[74, 75], [74, 78], [78, 79], [78, 82], [82, 83], [82, 86], [86, 87], [86, 92], [110, 115], [123, 124], [123, 152], [137, 138], [137, 141], [152, 153], [152, 160], [198, 199], [198, 204], [216, 217], [216, 218], [218, 219], [218, 220], [220, 221], [220, 224], [226, 227], [226, 241], [229, 230], [229, 237], [230, 229], [230, 231], [231, 232], [231, 233], [237, 226], [237, 238], [241, 242], [241, 246], [242, 241], [242, 243], [250, 251], [250, 252], [252, 253], [252, 254], [254, 255], [254, 256], [256, 257], [256, 259]], "functions": {"exchange_dropbox_token": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [37, 39, 48, 51], "excluded_lines": [], "start_line": 24, "executed_branches": [], "missing_branches": []}, "update_dropbox_settings": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 18, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [70, 71, 74, 75, 76, 78, 79, 80, 82, 83, 84, 86, 87, 88, 92, 94, 95, 96], "excluded_lines": [], "start_line": 60, "executed_branches": [], "missing_branches": [[74, 75], [74, 78], [78, 79], [78, 82], [82, 83], [82, 86], [86, 87], [86, 92]]}, "test_dropbox_token": {"executed_lines": [107, 108, 110, 111, 112], "summary": {"covered_lines": 5, "num_statements": 31, "percent_covered": 15.384615384615385, "percent_covered_display": "15.38", "missing_lines": 26, "excluded_lines": 0, "percent_statements_covered": 16.129032258064516, "percent_statements_covered_display": "16.13", "num_branches": 8, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 7, "percent_branches_covered": 12.5, "percent_branches_covered_display": "12.50"}, "missing_lines": [115, 116, 123, 124, 127, 128, 135, 137, 138, 139, 141, 142, 145, 146, 152, 153, 154, 160, 161, 162, 165, 167, 169, 177, 178, 179], "excluded_lines": [], "start_line": 103, "executed_branches": [[110, 111]], "missing_branches": [[110, 115], [123, 124], [123, 152], [137, 138], [137, 141], [152, 153], [152, 160]]}, "save_dropbox_settings": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 50, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 50, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 30, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 30, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [194, 196, 198, 199, 200, 204, 207, 208, 211, 216, 217, 218, 219, 220, 221, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 241, 242, 243, 246, 247, 250, 251, 252, 253, 254, 255, 256, 257, 259, 261, 263, 264, 265, 266, 267], "excluded_lines": [], "start_line": 184, "executed_branches": [], "missing_branches": [[198, 199], [198, 204], [216, 217], [216, 218], [218, 219], [218, 220], [220, 221], [220, 224], [226, 227], [226, 241], [229, 230], [229, 237], [230, 229], [230, 231], [231, 232], [231, 233], [237, 226], [237, 238], [241, 242], [241, 246], [242, 241], [242, 243], [250, 251], [250, 252], [252, 253], [252, 254], [254, 255], [254, 256], [256, 257], [256, 259]]}, "": {"executed_lines": [5, 6, 7, 9, 10, 12, 13, 14, 17, 19, 22, 23, 24, 58, 59, 60, 101, 102, 103, 182, 183, 184], "summary": {"covered_lines": 22, "num_statements": 22, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 9, 10, 12, 13, 14, 17, 19, 22, 23, 24, 58, 59, 60, 101, 102, 103, 107, 108, 110, 111, 112, 182, 183, 184], "summary": {"covered_lines": 27, "num_statements": 125, "percent_covered": 16.374269005847953, "percent_covered_display": "16.37", "missing_lines": 98, "excluded_lines": 0, "percent_statements_covered": 21.6, "percent_statements_covered_display": "21.60", "num_branches": 46, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 45, "percent_branches_covered": 2.1739130434782608, "percent_branches_covered_display": "2.17"}, "missing_lines": [37, 39, 48, 51, 70, 71, 74, 75, 76, 78, 79, 80, 82, 83, 84, 86, 87, 88, 92, 94, 95, 96, 115, 116, 123, 124, 127, 128, 135, 137, 138, 139, 141, 142, 145, 146, 152, 153, 154, 160, 161, 162, 165, 167, 169, 177, 178, 179, 194, 196, 198, 199, 200, 204, 207, 208, 211, 216, 217, 218, 219, 220, 221, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 241, 242, 243, 246, 247, 250, 251, 252, 253, 254, 255, 256, 257, 259, 261, 263, 264, 265, 266, 267], "excluded_lines": [], "start_line": 1, "executed_branches": [[110, 111]], "missing_branches": [[74, 75], [74, 78], [78, 79], [78, 82], [82, 83], [82, 86], [86, 87], [86, 92], [110, 115], [123, 124], [123, 152], [137, 138], [137, 141], [152, 153], [152, 160], [198, 199], [198, 204], [216, 217], [216, 218], [218, 219], [218, 220], [220, 221], [220, 224], [226, 227], [226, 241], [229, 230], [229, 237], [230, 229], [230, 231], [231, 232], [231, 233], [237, 226], [237, 238], [241, 242], [241, 246], [242, 241], [242, 243], [250, 251], [250, 252], [252, 253], [252, 254], [254, 255], [254, 256], [256, 257], [256, 259]]}}}, "app/api/files.py": {"executed_lines": [5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 26, 28, 30, 33, 40, 41, 42, 80, 83, 84, 87, 88, 91, 94, 97, 105, 106, 108, 111, 112, 115, 116, 119, 120, 121, 137, 139, 145, 150, 152, 155, 156, 157, 162, 164, 165, 168, 173, 174, 175, 187, 190, 192, 208, 209, 210, 216, 217, 219, 221, 223, 224, 227, 230, 231, 233, 235, 236, 237, 238, 239, 240, 243, 244, 245, 251, 254, 256, 258, 259, 261, 262, 265, 268, 269, 271, 273, 279, 280, 287, 288, 289, 293, 295, 297, 298, 300, 301, 302, 304, 305, 307, 308, 315, 318, 319, 320, 324, 333, 341, 342, 348, 349, 350, 360, 362, 364, 365, 368, 369, 372, 376, 380, 388, 389, 395, 396, 397, 457, 467, 469, 470, 471, 472, 473, 474, 477, 495, 497, 499, 501, 504, 505, 508, 509, 510, 511, 512, 513, 515, 519, 520, 521, 522, 523, 528, 532, 533, 534, 538, 540, 549, 550, 551, 573, 575, 577, 578, 581, 588, 589, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 603, 616, 617, 618, 624, 625, 628, 629, 635, 636, 637, 641, 642, 658, 659, 665, 666, 667, 683, 685, 687, 689, 690, 692, 694, 697, 699, 701, 702, 705, 706, 712, 713, 714, 718, 719, 721, 724, 730, 731, 737, 738, 739, 809, 810, 811, 813, 817, 819, 822, 824, 825, 826, 828, 831, 833, 834, 835, 836, 837, 838, 841, 844, 845, 846, 848, 849, 856, 871, 883, 884, 887, 890, 892, 894, 896, 898, 899, 903, 904, 907, 908, 909, 910, 911, 912, 915, 917, 925, 926, 928, 929, 931, 933, 934, 935, 939, 940, 941, 946, 947, 950, 951, 953], "summary": {"covered_lines": 292, "num_statements": 375, "percent_covered": 76.70103092783505, "percent_covered_display": "76.70", "missing_lines": 83, "excluded_lines": 0, "percent_statements_covered": 77.86666666666666, "percent_statements_covered_display": "77.87", "num_branches": 110, "num_partial_branches": 10, "covered_branches": 80, "missing_branches": 30, "percent_branches_covered": 72.72727272727273, "percent_branches_covered_display": "72.73"}, "missing_lines": [35, 37, 252, 281, 282, 283, 284, 329, 330, 331, 343, 344, 345, 390, 391, 392, 411, 413, 415, 416, 419, 420, 421, 422, 423, 424, 425, 427, 432, 436, 441, 450, 451, 452, 453, 454, 500, 516, 529, 536, 638, 639, 645, 646, 648, 650, 660, 661, 662, 695, 715, 716, 732, 733, 734, 755, 757, 759, 761, 762, 764, 766, 767, 769, 771, 773, 774, 777, 778, 784, 785, 786, 787, 788, 790, 791, 793, 796, 802, 803, 804, 805, 806], "excluded_lines": [], "executed_branches": [[83, 84], [83, 87], [87, 88], [87, 91], [105, 106], [105, 108], [120, 121], [120, 137], [164, 165], [164, 168], [174, 175], [174, 187], [216, 217], [216, 219], [223, 224], [223, 227], [251, 254], [258, 259], [258, 261], [268, 269], [268, 271], [297, 298], [297, 300], [304, 305], [304, 333], [307, 308], [307, 318], [364, 365], [364, 368], [368, 369], [368, 372], [472, 473], [472, 474], [497, 499], [497, 504], [499, 501], [504, 505], [504, 512], [508, 509], [508, 510], [512, 513], [512, 522], [515, 519], [522, 523], [528, 532], [577, 578], [577, 581], [588, 589], [588, 592], [616, 617], [616, 624], [636, 637], [636, 641], [637, 636], [641, 642], [689, 690], [689, 692], [692, 694], [692, 699], [694, 697], [699, 701], [699, 721], [713, 714], [713, 718], [714, 713], [718, 719], [824, 825], [824, 828], [846, 848], [846, 856], [894, 896], [894, 931], [908, 909], [908, 915], [931, 933], [931, 935], [935, 939], [935, 941], [941, 946], [941, 950]], "missing_branches": [[251, 252], [415, 416], [415, 419], [420, 421], [420, 423], [423, 424], [423, 427], [499, 500], [515, 516], [522, 536], [528, 529], [637, 638], [641, 645], [694, 695], [714, 715], [718, 724], [761, 762], [761, 764], [764, 766], [764, 771], [766, 767], [766, 769], [771, 773], [771, 793], [785, 786], [785, 790], [786, 785], [786, 787], [790, 791], [790, 796]], "functions": {"get_limiter": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [35, 37], "excluded_lines": [], "start_line": 33, "executed_branches": [], "missing_branches": []}, "list_files_api": {"executed_lines": [80, 83, 84, 87, 88, 91, 94, 97, 105, 106, 108, 111, 112, 115, 116, 119, 120, 121, 137, 139], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 42, "executed_branches": [[83, 84], [83, 87], [87, 88], [87, 91], [105, 106], [105, 108], [120, 121], [120, 137]], "missing_branches": []}, "_get_file_processing_status": {"executed_lines": [150, 152], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 145, "executed_branches": [], "missing_branches": []}, "get_file_details": {"executed_lines": [162, 164, 165, 168, 173, 174, 175, 187, 190, 192], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 157, "executed_branches": [[164, 165], [164, 168], [174, 175], [174, 187]], "missing_branches": []}, "delete_file_record": {"executed_lines": [216, 217, 219, 221, 223, 224, 227, 230, 231, 233, 235, 236, 237, 238, 239, 240], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 210, "executed_branches": [[216, 217], [216, 219], [223, 224], [223, 227]], "missing_branches": []}, "bulk_delete_files": {"executed_lines": [251, 254, 256, 258, 259, 261, 262, 265, 268, 269, 271, 273, 279, 280], "summary": {"covered_lines": 14, "num_statements": 19, "percent_covered": 76.0, "percent_covered_display": "76.00", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 73.6842105263158, "percent_statements_covered_display": "73.68", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [252, 281, 282, 283, 284], "excluded_lines": [], "start_line": 245, "executed_branches": [[251, 254], [258, 259], [258, 261], [268, 269], [268, 271]], "missing_branches": [[251, 252]]}, "bulk_reprocess_files": {"executed_lines": [293, 295, 297, 298, 300, 301, 302, 304, 305, 307, 308, 315, 318, 319, 320, 324, 333, 341, 342], "summary": {"covered_lines": 19, "num_statements": 25, "percent_covered": 80.64516129032258, "percent_covered_display": "80.65", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 76.0, "percent_statements_covered_display": "76.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [329, 330, 331, 343, 344, 345], "excluded_lines": [], "start_line": 289, "executed_branches": [[297, 298], [297, 300], [304, 305], [304, 333], [307, 308], [307, 318]], "missing_branches": []}, "reprocess_single_file": {"executed_lines": [360, 362, 364, 365, 368, 369, 372, 376, 380, 388, 389], "summary": {"covered_lines": 11, "num_statements": 14, "percent_covered": 83.33333333333333, "percent_covered_display": "83.33", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 78.57142857142857, "percent_statements_covered_display": "78.57", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [390, 391, 392], "excluded_lines": [], "start_line": 350, "executed_branches": [[364, 365], [364, 368], [368, 369], [368, 372]], "missing_branches": []}, "reprocess_with_cloud_ocr": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 20, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [411, 413, 415, 416, 419, 420, 421, 422, 423, 424, 425, 427, 432, 436, 441, 450, 451, 452, 453, 454], "excluded_lines": [], "start_line": 397, "executed_branches": [], "missing_branches": [[415, 416], [415, 419], [420, 421], [420, 423], [423, 424], [423, 427]]}, "_extract_text_from_pdf": {"executed_lines": [467, 469, 470, 471, 472, 473, 474], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 457, "executed_branches": [[472, 473], [472, 474]], "missing_branches": []}, "_retry_pipeline_step": {"executed_lines": [495, 497, 499, 501, 504, 505, 508, 509, 510, 511, 512, 513, 515, 519, 520, 521, 522, 523, 528, 532, 533, 534, 538, 540], "summary": {"covered_lines": 24, "num_statements": 28, "percent_covered": 81.81818181818181, "percent_covered_display": "81.82", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 85.71428571428571, "percent_statements_covered_display": "85.71", "num_branches": 16, "num_partial_branches": 4, "covered_branches": 12, "missing_branches": 4, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [500, 516, 529, 536], "excluded_lines": [], "start_line": 477, "executed_branches": [[497, 499], [497, 504], [499, 501], [504, 505], [504, 512], [508, 509], [508, 510], [512, 513], [512, 522], [515, 519], [522, 523], [528, 532]], "missing_branches": [[499, 500], [515, 516], [522, 536], [528, 529]]}, "retry_subtask": {"executed_lines": [573, 575, 577, 578, 581, 588, 589, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 603, 616, 617, 618, 624, 625, 628, 629, 635, 636, 637, 641, 642, 658, 659], "summary": {"covered_lines": 32, "num_statements": 41, "percent_covered": 79.24528301886792, "percent_covered_display": "79.25", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 78.04878048780488, "percent_statements_covered_display": "78.05", "num_branches": 12, "num_partial_branches": 2, "covered_branches": 10, "missing_branches": 2, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [638, 639, 645, 646, 648, 650, 660, 661, 662], "excluded_lines": [], "start_line": 551, "executed_branches": [[577, 578], [577, 581], [588, 589], [588, 592], [616, 617], [616, 624], [636, 637], [636, 641], [637, 636], [641, 642]], "missing_branches": [[637, 638], [641, 645]]}, "get_file_preview": {"executed_lines": [683, 685, 687, 689, 690, 692, 694, 697, 699, 701, 702, 705, 706, 712, 713, 714, 718, 719, 721, 724, 730, 731], "summary": {"covered_lines": 22, "num_statements": 28, "percent_covered": 78.57142857142857, "percent_covered_display": "78.57", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 78.57142857142857, "percent_statements_covered_display": "78.57", "num_branches": 14, "num_partial_branches": 3, "covered_branches": 11, "missing_branches": 3, "percent_branches_covered": 78.57142857142857, "percent_branches_covered_display": "78.57"}, "missing_lines": [695, 715, 716, 732, 733, 734], "excluded_lines": [], "start_line": 667, "executed_branches": [[689, 690], [689, 692], [692, 694], [692, 699], [694, 697], [699, 701], [699, 721], [713, 714], [713, 718], [714, 713], [718, 719]], "missing_branches": [[694, 695], [714, 715], [718, 724]]}, "download_file": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 28, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 28, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 14, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 14, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [755, 757, 759, 761, 762, 764, 766, 767, 769, 771, 773, 774, 777, 778, 784, 785, 786, 787, 788, 790, 791, 793, 796, 802, 803, 804, 805, 806], "excluded_lines": [], "start_line": 739, "executed_branches": [], "missing_branches": [[761, 762], [761, 764], [764, 766], [764, 771], [766, 767], [766, 769], [771, 773], [771, 793], [785, 786], [785, 790], [786, 785], [786, 787], [790, 791], [790, 796]]}, "ui_upload": {"executed_lines": [813, 817, 819, 822, 824, 825, 826, 828, 831, 833, 834, 835, 836, 837, 838, 841, 844, 845, 846, 848, 849, 856, 871, 883, 884, 887, 890, 892, 894, 896, 898, 899, 903, 904, 907, 908, 909, 910, 911, 912, 915, 917, 925, 926, 928, 929, 931, 933, 934, 935, 939, 940, 941, 946, 947, 950, 951, 953], "summary": {"covered_lines": 58, "num_statements": 58, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 14, "num_partial_branches": 0, "covered_branches": 14, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 811, "executed_branches": [[824, 825], [824, 828], [846, 848], [846, 856], [894, 896], [894, 931], [908, 909], [908, 915], [931, 933], [931, 935], [935, 939], [935, 941], [941, 946], [941, 950]], "missing_branches": []}, "": {"executed_lines": [5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 26, 28, 30, 33, 40, 41, 42, 145, 155, 156, 157, 208, 209, 210, 243, 244, 245, 287, 288, 289, 348, 349, 350, 395, 396, 397, 457, 477, 549, 550, 551, 665, 666, 667, 737, 738, 739, 809, 810, 811], "summary": {"covered_lines": 57, "num_statements": 57, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 26, 28, 30, 33, 40, 41, 42, 80, 83, 84, 87, 88, 91, 94, 97, 105, 106, 108, 111, 112, 115, 116, 119, 120, 121, 137, 139, 145, 150, 152, 155, 156, 157, 162, 164, 165, 168, 173, 174, 175, 187, 190, 192, 208, 209, 210, 216, 217, 219, 221, 223, 224, 227, 230, 231, 233, 235, 236, 237, 238, 239, 240, 243, 244, 245, 251, 254, 256, 258, 259, 261, 262, 265, 268, 269, 271, 273, 279, 280, 287, 288, 289, 293, 295, 297, 298, 300, 301, 302, 304, 305, 307, 308, 315, 318, 319, 320, 324, 333, 341, 342, 348, 349, 350, 360, 362, 364, 365, 368, 369, 372, 376, 380, 388, 389, 395, 396, 397, 457, 467, 469, 470, 471, 472, 473, 474, 477, 495, 497, 499, 501, 504, 505, 508, 509, 510, 511, 512, 513, 515, 519, 520, 521, 522, 523, 528, 532, 533, 534, 538, 540, 549, 550, 551, 573, 575, 577, 578, 581, 588, 589, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 603, 616, 617, 618, 624, 625, 628, 629, 635, 636, 637, 641, 642, 658, 659, 665, 666, 667, 683, 685, 687, 689, 690, 692, 694, 697, 699, 701, 702, 705, 706, 712, 713, 714, 718, 719, 721, 724, 730, 731, 737, 738, 739, 809, 810, 811, 813, 817, 819, 822, 824, 825, 826, 828, 831, 833, 834, 835, 836, 837, 838, 841, 844, 845, 846, 848, 849, 856, 871, 883, 884, 887, 890, 892, 894, 896, 898, 899, 903, 904, 907, 908, 909, 910, 911, 912, 915, 917, 925, 926, 928, 929, 931, 933, 934, 935, 939, 940, 941, 946, 947, 950, 951, 953], "summary": {"covered_lines": 292, "num_statements": 375, "percent_covered": 76.70103092783505, "percent_covered_display": "76.70", "missing_lines": 83, "excluded_lines": 0, "percent_statements_covered": 77.86666666666666, "percent_statements_covered_display": "77.87", "num_branches": 110, "num_partial_branches": 10, "covered_branches": 80, "missing_branches": 30, "percent_branches_covered": 72.72727272727273, "percent_branches_covered_display": "72.73"}, "missing_lines": [35, 37, 252, 281, 282, 283, 284, 329, 330, 331, 343, 344, 345, 390, 391, 392, 411, 413, 415, 416, 419, 420, 421, 422, 423, 424, 425, 427, 432, 436, 441, 450, 451, 452, 453, 454, 500, 516, 529, 536, 638, 639, 645, 646, 648, 650, 660, 661, 662, 695, 715, 716, 732, 733, 734, 755, 757, 759, 761, 762, 764, 766, 767, 769, 771, 773, 774, 777, 778, 784, 785, 786, 787, 788, 790, 791, 793, 796, 802, 803, 804, 805, 806], "excluded_lines": [], "start_line": 1, "executed_branches": [[83, 84], [83, 87], [87, 88], [87, 91], [105, 106], [105, 108], [120, 121], [120, 137], [164, 165], [164, 168], [174, 175], [174, 187], [216, 217], [216, 219], [223, 224], [223, 227], [251, 254], [258, 259], [258, 261], [268, 269], [268, 271], [297, 298], [297, 300], [304, 305], [304, 333], [307, 308], [307, 318], [364, 365], [364, 368], [368, 369], [368, 372], [472, 473], [472, 474], [497, 499], [497, 504], [499, 501], [504, 505], [504, 512], [508, 509], [508, 510], [512, 513], [512, 522], [515, 519], [522, 523], [528, 532], [577, 578], [577, 581], [588, 589], [588, 592], [616, 617], [616, 624], [636, 637], [636, 641], [637, 636], [641, 642], [689, 690], [689, 692], [692, 694], [692, 699], [694, 697], [699, 701], [699, 721], [713, 714], [713, 718], [714, 713], [718, 719], [824, 825], [824, 828], [846, 848], [846, 856], [894, 896], [894, 931], [908, 909], [908, 915], [931, 933], [931, 935], [935, 939], [935, 941], [941, 946], [941, 950]], "missing_branches": [[251, 252], [415, 416], [415, 419], [420, 421], [420, 423], [423, 424], [423, 427], [499, 500], [515, 516], [522, 536], [528, 529], [637, 638], [641, 645], [694, 695], [714, 715], [718, 724], [761, 762], [761, 764], [764, 766], [764, 771], [766, 767], [766, 769], [771, 773], [771, 793], [785, 786], [785, 790], [786, 785], [786, 787], [790, 791], [790, 796]]}}}, "app/api/google_drive.py": {"executed_lines": [5, 6, 7, 8, 10, 12, 13, 14, 17, 19, 22, 23, 24, 58, 59, 60, 108, 109, 110, 115, 116, 118, 121, 189, 190, 191, 224, 225, 226, 307, 309, 310, 312, 313, 314, 316, 317, 318, 319, 320, 321, 322, 324, 327, 328, 329], "summary": {"covered_lines": 46, "num_statements": 201, "percent_covered": 20.363636363636363, "percent_covered_display": "20.36", "missing_lines": 155, "excluded_lines": 0, "percent_statements_covered": 22.885572139303484, "percent_statements_covered_display": "22.89", "num_branches": 74, "num_partial_branches": 2, "covered_branches": 10, "missing_branches": 64, "percent_branches_covered": 13.513513513513514, "percent_branches_covered_display": "13.51"}, "missing_lines": [37, 39, 48, 51, 71, 72, 75, 78, 79, 80, 82, 83, 84, 86, 87, 88, 90, 91, 92, 95, 96, 98, 100, 101, 102, 122, 127, 128, 130, 132, 135, 136, 138, 147, 148, 151, 152, 153, 154, 155, 156, 163, 164, 166, 168, 175, 176, 177, 180, 181, 186, 193, 194, 195, 198, 199, 201, 202, 204, 206, 208, 214, 215, 216, 217, 219, 220, 221, 232, 233, 236, 237, 238, 243, 248, 249, 251, 253, 254, 256, 265, 266, 269, 270, 271, 272, 273, 274, 281, 283, 289, 290, 291, 294, 295, 300, 302, 303, 304, 340, 342, 345, 348, 351, 352, 353, 354, 355, 356, 357, 360, 361, 364, 365, 366, 369, 370, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 390, 391, 392, 395, 396, 398, 399, 400, 402, 407, 408, 409, 410, 411, 412, 413, 414, 417, 419, 421, 427, 428, 429], "excluded_lines": [], "executed_branches": [[121, 189], [189, 190], [309, 310], [309, 312], [317, 318], [317, 319], [319, 320], [319, 321], [321, 322], [321, 324]], "missing_branches": [[78, 79], [78, 82], [82, 83], [82, 86], [86, 87], [86, 90], [90, 91], [90, 95], [121, 122], [122, 127], [122, 130], [147, 148], [147, 151], [152, 153], [152, 163], [180, 181], [180, 186], [189, 193], [201, 202], [201, 204], [236, 237], [236, 243], [243, 248], [243, 251], [265, 266], [265, 269], [270, 271], [270, 281], [294, 295], [294, 300], [351, 352], [351, 360], [352, 353], [352, 354], [354, 355], [354, 356], [356, 357], [356, 360], [360, 361], [360, 364], [364, 365], [364, 402], [375, 376], [375, 390], [378, 379], [378, 386], [379, 378], [379, 380], [380, 381], [380, 382], [386, 375], [386, 387], [390, 391], [390, 395], [391, 390], [391, 392], [407, 408], [407, 409], [409, 410], [409, 411], [411, 412], [411, 413], [413, 414], [413, 417]], "functions": {"exchange_google_drive_token": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [37, 39, 48, 51], "excluded_lines": [], "start_line": 24, "executed_branches": [], "missing_branches": []}, "update_google_drive_settings": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 21, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 21, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [71, 72, 75, 78, 79, 80, 82, 83, 84, 86, 87, 88, 90, 91, 92, 95, 96, 98, 100, 101, 102], "excluded_lines": [], "start_line": 60, "executed_branches": [], "missing_branches": [[78, 79], [78, 82], [82, 83], [82, 86], [86, 87], [86, 90], [90, 91], [90, 95]]}, "test_google_drive_token": {"executed_lines": [115, 116, 118, 121, 189, 190, 191], "summary": {"covered_lines": 7, "num_statements": 50, "percent_covered": 14.0625, "percent_covered_display": "14.06", "missing_lines": 43, "excluded_lines": 0, "percent_statements_covered": 14.0, "percent_statements_covered_display": "14.00", "num_branches": 14, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 12, "percent_branches_covered": 14.285714285714286, "percent_branches_covered_display": "14.29"}, "missing_lines": [122, 127, 128, 130, 132, 135, 136, 138, 147, 148, 151, 152, 153, 154, 155, 156, 163, 164, 166, 168, 175, 176, 177, 180, 181, 186, 193, 194, 195, 198, 199, 201, 202, 204, 206, 208, 214, 215, 216, 217, 219, 220, 221], "excluded_lines": [], "start_line": 110, "executed_branches": [[121, 189], [189, 190]], "missing_branches": [[121, 122], [122, 127], [122, 130], [147, 148], [147, 151], [152, 153], [152, 163], [180, 181], [180, 186], [189, 193], [201, 202], [201, 204]]}, "get_google_drive_token_info": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 31, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 31, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 10, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [232, 233, 236, 237, 238, 243, 248, 249, 251, 253, 254, 256, 265, 266, 269, 270, 271, 272, 273, 274, 281, 283, 289, 290, 291, 294, 295, 300, 302, 303, 304], "excluded_lines": [], "start_line": 226, "executed_branches": [], "missing_branches": [[236, 237], [236, 243], [243, 248], [243, 251], [265, 266], [265, 269], [270, 271], [270, 281], [294, 295], [294, 300]]}, "format_time_remaining": {"executed_lines": [309, 310, 312, 313, 314, 316, 317, 318, 319, 320, 321, 322, 324], "summary": {"covered_lines": 13, "num_statements": 13, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 307, "executed_branches": [[309, 310], [309, 312], [317, 318], [317, 319], [319, 320], [319, 321], [321, 322], [321, 324]], "missing_branches": []}, "save_dropbox_settings": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 56, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 56, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 34, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 34, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [340, 342, 345, 348, 351, 352, 353, 354, 355, 356, 357, 360, 361, 364, 365, 366, 369, 370, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 390, 391, 392, 395, 396, 398, 399, 400, 402, 407, 408, 409, 410, 411, 412, 413, 414, 417, 419, 421, 427, 428, 429], "excluded_lines": [], "start_line": 329, "executed_branches": [], "missing_branches": [[351, 352], [351, 360], [352, 353], [352, 354], [354, 355], [354, 356], [356, 357], [356, 360], [360, 361], [360, 364], [364, 365], [364, 402], [375, 376], [375, 390], [378, 379], [378, 386], [379, 378], [379, 380], [380, 381], [380, 382], [386, 375], [386, 387], [390, 391], [390, 395], [391, 390], [391, 392], [407, 408], [407, 409], [409, 410], [409, 411], [411, 412], [411, 413], [413, 414], [413, 417]]}, "": {"executed_lines": [5, 6, 7, 8, 10, 12, 13, 14, 17, 19, 22, 23, 24, 58, 59, 60, 108, 109, 110, 224, 225, 226, 307, 327, 328, 329], "summary": {"covered_lines": 26, "num_statements": 26, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 8, 10, 12, 13, 14, 17, 19, 22, 23, 24, 58, 59, 60, 108, 109, 110, 115, 116, 118, 121, 189, 190, 191, 224, 225, 226, 307, 309, 310, 312, 313, 314, 316, 317, 318, 319, 320, 321, 322, 324, 327, 328, 329], "summary": {"covered_lines": 46, "num_statements": 201, "percent_covered": 20.363636363636363, "percent_covered_display": "20.36", "missing_lines": 155, "excluded_lines": 0, "percent_statements_covered": 22.885572139303484, "percent_statements_covered_display": "22.89", "num_branches": 74, "num_partial_branches": 2, "covered_branches": 10, "missing_branches": 64, "percent_branches_covered": 13.513513513513514, "percent_branches_covered_display": "13.51"}, "missing_lines": [37, 39, 48, 51, 71, 72, 75, 78, 79, 80, 82, 83, 84, 86, 87, 88, 90, 91, 92, 95, 96, 98, 100, 101, 102, 122, 127, 128, 130, 132, 135, 136, 138, 147, 148, 151, 152, 153, 154, 155, 156, 163, 164, 166, 168, 175, 176, 177, 180, 181, 186, 193, 194, 195, 198, 199, 201, 202, 204, 206, 208, 214, 215, 216, 217, 219, 220, 221, 232, 233, 236, 237, 238, 243, 248, 249, 251, 253, 254, 256, 265, 266, 269, 270, 271, 272, 273, 274, 281, 283, 289, 290, 291, 294, 295, 300, 302, 303, 304, 340, 342, 345, 348, 351, 352, 353, 354, 355, 356, 357, 360, 361, 364, 365, 366, 369, 370, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 390, 391, 392, 395, 396, 398, 399, 400, 402, 407, 408, 409, 410, 411, 412, 413, 414, 417, 419, 421, 427, 428, 429], "excluded_lines": [], "start_line": 1, "executed_branches": [[121, 189], [189, 190], [309, 310], [309, 312], [317, 318], [317, 319], [319, 320], [319, 321], [321, 322], [321, 324]], "missing_branches": [[78, 79], [78, 82], [82, 83], [82, 86], [86, 87], [86, 90], [90, 91], [90, 95], [121, 122], [122, 127], [122, 130], [147, 148], [147, 151], [152, 153], [152, 163], [180, 181], [180, 186], [189, 193], [201, 202], [201, 204], [236, 237], [236, 243], [243, 248], [243, 251], [265, 266], [265, 269], [270, 271], [270, 281], [294, 295], [294, 300], [351, 352], [351, 360], [352, 353], [352, 354], [354, 355], [354, 356], [356, 357], [356, 360], [360, 361], [360, 364], [364, 365], [364, 402], [375, 376], [375, 390], [378, 379], [378, 386], [379, 378], [379, 380], [380, 381], [380, 382], [386, 375], [386, 387], [390, 391], [390, 395], [391, 390], [391, 392], [407, 408], [407, 409], [409, 410], [409, 411], [411, 412], [411, 413], [413, 414], [413, 417]]}}}, "app/api/logs.py": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 17, 19, 21, 24, 25, 26, 56, 59, 61, 62, 65, 68, 69, 70, 81, 84, 85, 86, 94, 95, 96, 99, 102, 103, 104, 115, 128, 129, 130, 136, 138, 139, 142, 143, 144, 155], "summary": {"covered_lines": 44, "num_statements": 45, "percent_covered": 96.61016949152543, "percent_covered_display": "96.61", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 97.77777777777777, "percent_statements_covered_display": "97.78", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 13, "missing_branches": 1, "percent_branches_covered": 92.85714285714286, "percent_branches_covered_display": "92.86"}, "missing_lines": [60], "excluded_lines": [], "executed_branches": [[59, 61], [61, 62], [61, 65], [69, 70], [69, 81], [95, 96], [95, 99], [103, 104], [103, 115], [138, 139], [138, 142], [143, 144], [143, 155]], "missing_branches": [[59, 60]], "functions": {"list_processing_logs": {"executed_lines": [56, 59, 61, 62, 65, 68, 69, 70, 81], "summary": {"covered_lines": 9, "num_statements": 10, "percent_covered": 87.5, "percent_covered_display": "87.50", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.0, "percent_statements_covered_display": "90.00", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [60], "excluded_lines": [], "start_line": 26, "executed_branches": [[59, 61], [61, 62], [61, 65], [69, 70], [69, 81]], "missing_branches": [[59, 60]]}, "get_file_processing_logs": {"executed_lines": [94, 95, 96, 99, 102, 103, 104, 115], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 86, "executed_branches": [[95, 96], [95, 99], [103, 104], [103, 115]], "missing_branches": []}, "get_task_processing_logs": {"executed_lines": [136, 138, 139, 142, 143, 144, 155], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 130, "executed_branches": [[138, 139], [138, 142], [143, 144], [143, 155]], "missing_branches": []}, "": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 17, 19, 21, 24, 25, 26, 84, 85, 86, 128, 129, 130], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 17, 19, 21, 24, 25, 26, 56, 59, 61, 62, 65, 68, 69, 70, 81, 84, 85, 86, 94, 95, 96, 99, 102, 103, 104, 115, 128, 129, 130, 136, 138, 139, 142, 143, 144, 155], "summary": {"covered_lines": 44, "num_statements": 45, "percent_covered": 96.61016949152543, "percent_covered_display": "96.61", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 97.77777777777777, "percent_statements_covered_display": "97.78", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 13, "missing_branches": 1, "percent_branches_covered": 92.85714285714286, "percent_branches_covered_display": "92.86"}, "missing_lines": [60], "excluded_lines": [], "start_line": 1, "executed_branches": [[59, 61], [61, 62], [61, 65], [69, 70], [69, 81], [95, 96], [95, 99], [103, 104], [103, 115], [138, 139], [138, 142], [143, 144], [143, 155]], "missing_branches": [[59, 60]]}}}, "app/api/onedrive.py": {"executed_lines": [5, 6, 7, 8, 10, 11, 13, 14, 15, 18, 20, 23, 24, 25, 56, 57, 58, 62, 63, 65, 70, 71, 177, 179, 180, 182, 183, 184, 186, 187, 188, 189, 190, 191, 192, 194, 197, 198, 199, 292, 293, 294, 348, 349, 350], "summary": {"covered_lines": 45, "num_statements": 189, "percent_covered": 21.011673151750973, "percent_covered_display": "21.01", "missing_lines": 144, "excluded_lines": 0, "percent_statements_covered": 23.80952380952381, "percent_statements_covered_display": "23.81", "num_branches": 68, "num_partial_branches": 1, "covered_branches": 9, "missing_branches": 59, "percent_branches_covered": 13.235294117647058, "percent_branches_covered_display": "13.24"}, "missing_lines": [38, 40, 50, 53, 74, 75, 77, 85, 87, 88, 89, 91, 92, 93, 96, 97, 98, 101, 104, 105, 106, 107, 108, 110, 111, 113, 114, 115, 116, 118, 120, 121, 123, 124, 126, 128, 129, 132, 133, 135, 137, 138, 139, 145, 146, 147, 150, 151, 154, 155, 162, 164, 172, 173, 174, 210, 212, 214, 215, 216, 220, 223, 224, 227, 232, 233, 234, 235, 236, 237, 238, 239, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 259, 260, 261, 264, 265, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 279, 281, 283, 284, 285, 286, 287, 305, 306, 309, 310, 311, 313, 314, 315, 317, 318, 319, 321, 322, 323, 325, 326, 327, 330, 331, 333, 334, 335, 336, 337, 339, 341, 342, 343, 354, 356, 365, 375, 376, 377, 378], "excluded_lines": [], "executed_branches": [[65, 70], [179, 180], [179, 182], [187, 188], [187, 189], [189, 190], [189, 191], [191, 192], [191, 194]], "missing_branches": [[65, 74], [87, 88], [87, 91], [97, 98], [97, 132], [106, 107], [106, 132], [113, 114], [113, 120], [114, 115], [114, 118], [120, 121], [120, 123], [137, 138], [137, 145], [214, 215], [214, 220], [232, 233], [232, 234], [234, 235], [234, 236], [236, 237], [236, 238], [238, 239], [238, 242], [244, 245], [244, 259], [247, 248], [247, 255], [248, 247], [248, 249], [249, 250], [249, 251], [255, 244], [255, 256], [259, 260], [259, 264], [260, 259], [260, 261], [268, 269], [268, 270], [270, 271], [270, 272], [272, 273], [272, 274], [274, 275], [274, 276], [276, 277], [276, 279], [309, 310], [309, 313], [313, 314], [313, 317], [317, 318], [317, 321], [321, 322], [321, 325], [325, 326], [325, 330]], "functions": {"exchange_onedrive_token": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [38, 40, 50, 53], "excluded_lines": [], "start_line": 25, "executed_branches": [], "missing_branches": []}, "test_onedrive_token": {"executed_lines": [62, 63, 65, 70, 71], "summary": {"covered_lines": 5, "num_statements": 56, "percent_covered": 8.333333333333334, "percent_covered_display": "8.33", "missing_lines": 51, "excluded_lines": 0, "percent_statements_covered": 8.928571428571429, "percent_statements_covered_display": "8.93", "num_branches": 16, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 15, "percent_branches_covered": 6.25, "percent_branches_covered_display": "6.25"}, "missing_lines": [74, 75, 77, 85, 87, 88, 89, 91, 92, 93, 96, 97, 98, 101, 104, 105, 106, 107, 108, 110, 111, 113, 114, 115, 116, 118, 120, 121, 123, 124, 126, 128, 129, 132, 133, 135, 137, 138, 139, 145, 146, 147, 150, 151, 154, 155, 162, 164, 172, 173, 174], "excluded_lines": [], "start_line": 58, "executed_branches": [[65, 70]], "missing_branches": [[65, 74], [87, 88], [87, 91], [97, 98], [97, 132], [106, 107], [106, 132], [113, 114], [113, 120], [114, 115], [114, 118], [120, 121], [120, 123], [137, 138], [137, 145]]}, "format_time_remaining": {"executed_lines": [179, 180, 182, 183, 184, 186, 187, 188, 189, 190, 191, 192, 194], "summary": {"covered_lines": 13, "num_statements": 13, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 177, "executed_branches": [[179, 180], [179, 182], [187, 188], [187, 189], [189, 190], [189, 191], [191, 192], [191, 194]], "missing_branches": []}, "save_onedrive_settings": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 54, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 54, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 34, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 34, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [210, 212, 214, 215, 216, 220, 223, 224, 227, 232, 233, 234, 235, 236, 237, 238, 239, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 259, 260, 261, 264, 265, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 279, 281, 283, 284, 285, 286, 287], "excluded_lines": [], "start_line": 199, "executed_branches": [], "missing_branches": [[214, 215], [214, 220], [232, 233], [232, 234], [234, 235], [234, 236], [236, 237], [236, 238], [238, 239], [238, 242], [244, 245], [244, 259], [247, 248], [247, 255], [248, 247], [248, 249], [249, 250], [249, 251], [255, 244], [255, 256], [259, 260], [259, 264], [260, 259], [260, 261], [268, 269], [268, 270], [270, 271], [270, 272], [272, 273], [272, 274], [274, 275], [274, 276], [276, 277], [276, 279]]}, "update_onedrive_settings": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 28, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 28, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 10, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [305, 306, 309, 310, 311, 313, 314, 315, 317, 318, 319, 321, 322, 323, 325, 326, 327, 330, 331, 333, 334, 335, 336, 337, 339, 341, 342, 343], "excluded_lines": [], "start_line": 294, "executed_branches": [], "missing_branches": [[309, 310], [309, 313], [313, 314], [313, 317], [317, 318], [317, 321], [321, 322], [321, 325], [325, 326], [325, 330]]}, "get_onedrive_full_config": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [354, 356, 365, 375, 376, 377, 378], "excluded_lines": [], "start_line": 350, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [5, 6, 7, 8, 10, 11, 13, 14, 15, 18, 20, 23, 24, 25, 56, 57, 58, 177, 197, 198, 199, 292, 293, 294, 348, 349, 350], "summary": {"covered_lines": 27, "num_statements": 27, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 8, 10, 11, 13, 14, 15, 18, 20, 23, 24, 25, 56, 57, 58, 62, 63, 65, 70, 71, 177, 179, 180, 182, 183, 184, 186, 187, 188, 189, 190, 191, 192, 194, 197, 198, 199, 292, 293, 294, 348, 349, 350], "summary": {"covered_lines": 45, "num_statements": 189, "percent_covered": 21.011673151750973, "percent_covered_display": "21.01", "missing_lines": 144, "excluded_lines": 0, "percent_statements_covered": 23.80952380952381, "percent_statements_covered_display": "23.81", "num_branches": 68, "num_partial_branches": 1, "covered_branches": 9, "missing_branches": 59, "percent_branches_covered": 13.235294117647058, "percent_branches_covered_display": "13.24"}, "missing_lines": [38, 40, 50, 53, 74, 75, 77, 85, 87, 88, 89, 91, 92, 93, 96, 97, 98, 101, 104, 105, 106, 107, 108, 110, 111, 113, 114, 115, 116, 118, 120, 121, 123, 124, 126, 128, 129, 132, 133, 135, 137, 138, 139, 145, 146, 147, 150, 151, 154, 155, 162, 164, 172, 173, 174, 210, 212, 214, 215, 216, 220, 223, 224, 227, 232, 233, 234, 235, 236, 237, 238, 239, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 259, 260, 261, 264, 265, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 279, 281, 283, 284, 285, 286, 287, 305, 306, 309, 310, 311, 313, 314, 315, 317, 318, 319, 321, 322, 323, 325, 326, 327, 330, 331, 333, 334, 335, 336, 337, 339, 341, 342, 343, 354, 356, 365, 375, 376, 377, 378], "excluded_lines": [], "start_line": 1, "executed_branches": [[65, 70], [179, 180], [179, 182], [187, 188], [187, 189], [189, 190], [189, 191], [191, 192], [191, 194]], "missing_branches": [[65, 74], [87, 88], [87, 91], [97, 98], [97, 132], [106, 107], [106, 132], [113, 114], [113, 120], [114, 115], [114, 118], [120, 121], [120, 123], [137, 138], [137, 145], [214, 215], [214, 220], [232, 233], [232, 234], [234, 235], [234, 236], [236, 237], [236, 238], [238, 239], [238, 242], [244, 245], [244, 259], [247, 248], [247, 255], [248, 247], [248, 249], [249, 250], [249, 251], [255, 244], [255, 256], [259, 260], [259, 264], [260, 259], [260, 261], [268, 269], [268, 270], [270, 271], [270, 272], [272, 273], [272, 274], [274, 275], [274, 276], [276, 277], [276, 279], [309, 310], [309, 313], [313, 314], [313, 317], [317, 318], [317, 321], [321, 322], [321, 325], [325, 326], [325, 330]]}}}, "app/api/openai.py": {"executed_lines": [5, 7, 9, 10, 13, 15, 18, 19, 20, 24, 25, 27, 30, 35, 38, 40, 49, 50, 51, 54, 56], "summary": {"covered_lines": 21, "num_statements": 31, "percent_covered": 66.66666666666667, "percent_covered_display": "66.67", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 67.74193548387096, "percent_statements_covered_display": "67.74", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [31, 32, 43, 44, 62, 63, 64, 65, 66, 67], "excluded_lines": [], "executed_branches": [[30, 35]], "missing_branches": [[30, 31]], "functions": {"test_openai_connection": {"executed_lines": [24, 25, 27, 30, 35, 38, 40, 49, 50, 51, 54, 56], "summary": {"covered_lines": 12, "num_statements": 22, "percent_covered": 54.166666666666664, "percent_covered_display": "54.17", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 54.54545454545455, "percent_statements_covered_display": "54.55", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [31, 32, 43, 44, 62, 63, 64, 65, 66, 67], "excluded_lines": [], "start_line": 20, "executed_branches": [[30, 35]], "missing_branches": [[30, 31]]}, "": {"executed_lines": [5, 7, 9, 10, 13, 15, 18, 19, 20], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 9, 10, 13, 15, 18, 19, 20, 24, 25, 27, 30, 35, 38, 40, 49, 50, 51, 54, 56], "summary": {"covered_lines": 21, "num_statements": 31, "percent_covered": 66.66666666666667, "percent_covered_display": "66.67", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 67.74193548387096, "percent_statements_covered_display": "67.74", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [31, 32, 43, 44, 62, 63, 64, 65, 66, 67], "excluded_lines": [], "start_line": 1, "executed_branches": [[30, 35]], "missing_branches": [[30, 31]]}}}, "app/api/process.py": {"executed_lines": [5, 6, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 24, 27, 28, 29, 31, 33, 34, 40, 41, 42, 44, 45, 46, 51, 52, 53, 55, 56, 57, 62, 63, 64, 66, 67, 68, 73, 74, 75, 77, 78, 79, 84, 85, 86, 88, 89, 90, 95, 96, 97, 99, 101, 102, 108, 109, 110, 117, 118, 119, 121, 122, 123, 124, 126, 127, 129, 130, 133, 135, 136, 142, 143, 145, 149, 150, 151, 154, 156, 158, 159, 160, 161, 163], "summary": {"covered_lines": 87, "num_statements": 101, "percent_covered": 83.20610687022901, "percent_covered_display": "83.21", "missing_lines": 14, "excluded_lines": 0, "percent_statements_covered": 86.13861386138613, "percent_statements_covered_display": "86.14", "num_branches": 30, "num_partial_branches": 8, "covered_branches": 22, "missing_branches": 8, "percent_branches_covered": 73.33333333333333, "percent_branches_covered_display": "73.33"}, "missing_lines": [36, 37, 47, 48, 58, 59, 69, 70, 80, 81, 91, 92, 104, 105], "excluded_lines": [], "executed_branches": [[33, 34], [45, 46], [56, 57], [67, 68], [78, 79], [89, 90], [101, 102], [118, 119], [118, 121], [122, 123], [122, 126], [123, 124], [126, 127], [126, 129], [135, 136], [135, 142], [142, 143], [142, 158], [145, 149], [145, 154], [159, 160], [159, 163]], "missing_branches": [[33, 36], [45, 47], [56, 58], [67, 69], [78, 80], [89, 91], [101, 104], [123, 122]], "functions": {"process": {"executed_lines": [31, 33, 34], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 57.142857142857146, "percent_covered_display": "57.14", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [36, 37], "excluded_lines": [], "start_line": 29, "executed_branches": [[33, 34]], "missing_branches": [[33, 36]]}, "send_to_dropbox_endpoint": {"executed_lines": [44, 45, 46], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 57.142857142857146, "percent_covered_display": "57.14", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [47, 48], "excluded_lines": [], "start_line": 42, "executed_branches": [[45, 46]], "missing_branches": [[45, 47]]}, "send_to_paperless_endpoint": {"executed_lines": [55, 56, 57], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 57.142857142857146, "percent_covered_display": "57.14", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [58, 59], "excluded_lines": [], "start_line": 53, "executed_branches": [[56, 57]], "missing_branches": [[56, 58]]}, "send_to_nextcloud_endpoint": {"executed_lines": [66, 67, 68], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 57.142857142857146, "percent_covered_display": "57.14", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [69, 70], "excluded_lines": [], "start_line": 64, "executed_branches": [[67, 68]], "missing_branches": [[67, 69]]}, "send_to_google_drive_endpoint": {"executed_lines": [77, 78, 79], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 57.142857142857146, "percent_covered_display": "57.14", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [80, 81], "excluded_lines": [], "start_line": 75, "executed_branches": [[78, 79]], "missing_branches": [[78, 80]]}, "send_to_onedrive_endpoint": {"executed_lines": [88, 89, 90], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 57.142857142857146, "percent_covered_display": "57.14", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [91, 92], "excluded_lines": [], "start_line": 86, "executed_branches": [[89, 90]], "missing_branches": [[89, 91]]}, "send_to_all_destinations_endpoint": {"executed_lines": [99, 101, 102], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 57.142857142857146, "percent_covered_display": "57.14", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [104, 105], "excluded_lines": [], "start_line": 97, "executed_branches": [[101, 102]], "missing_branches": [[101, 104]]}, "process_all_pdfs_in_workdir": {"executed_lines": [117, 118, 119, 121, 122, 123, 124, 126, 127, 129, 130, 133, 135, 136, 142, 143, 145, 149, 150, 151, 154, 156, 158, 159, 160, 161, 163], "summary": {"covered_lines": 27, "num_statements": 27, "percent_covered": 97.67441860465117, "percent_covered_display": "97.67", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 16, "num_partial_branches": 1, "covered_branches": 15, "missing_branches": 1, "percent_branches_covered": 93.75, "percent_branches_covered_display": "93.75"}, "missing_lines": [], "excluded_lines": [], "start_line": 110, "executed_branches": [[118, 119], [118, 121], [122, 123], [122, 126], [123, 124], [126, 127], [126, 129], [135, 136], [135, 142], [142, 143], [142, 158], [145, 149], [145, 154], [159, 160], [159, 163]], "missing_branches": [[123, 122]]}, "": {"executed_lines": [5, 6, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 24, 27, 28, 29, 40, 41, 42, 51, 52, 53, 62, 63, 64, 73, 74, 75, 84, 85, 86, 95, 96, 97, 108, 109, 110], "summary": {"covered_lines": 39, "num_statements": 39, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 24, 27, 28, 29, 31, 33, 34, 40, 41, 42, 44, 45, 46, 51, 52, 53, 55, 56, 57, 62, 63, 64, 66, 67, 68, 73, 74, 75, 77, 78, 79, 84, 85, 86, 88, 89, 90, 95, 96, 97, 99, 101, 102, 108, 109, 110, 117, 118, 119, 121, 122, 123, 124, 126, 127, 129, 130, 133, 135, 136, 142, 143, 145, 149, 150, 151, 154, 156, 158, 159, 160, 161, 163], "summary": {"covered_lines": 87, "num_statements": 101, "percent_covered": 83.20610687022901, "percent_covered_display": "83.21", "missing_lines": 14, "excluded_lines": 0, "percent_statements_covered": 86.13861386138613, "percent_statements_covered_display": "86.14", "num_branches": 30, "num_partial_branches": 8, "covered_branches": 22, "missing_branches": 8, "percent_branches_covered": 73.33333333333333, "percent_branches_covered_display": "73.33"}, "missing_lines": [36, 37, 47, 48, 58, 59, 69, 70, 80, 81, 91, 92, 104, 105], "excluded_lines": [], "start_line": 1, "executed_branches": [[33, 34], [45, 46], [56, 57], [67, 68], [78, 79], [89, 90], [101, 102], [118, 119], [118, 121], [122, 123], [122, 126], [123, 124], [126, 127], [126, 129], [135, 136], [135, 142], [142, 143], [142, 158], [145, 149], [145, 154], [159, 160], [159, 163]], "missing_branches": [[33, 36], [45, 47], [56, 58], [67, 69], [78, 80], [89, 91], [101, 104], [123, 122]]}}}, "app/api/settings.py": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 24, 25, 28, 36, 37, 38, 39, 42, 43, 46, 49, 50, 53, 56, 57, 58, 61, 64, 65, 66, 69, 70, 95, 96, 116, 117, 162, 163, 186, 187], "summary": {"covered_lines": 38, "num_statements": 101, "percent_covered": 32.520325203252035, "percent_covered_display": "32.52", "missing_lines": 63, "excluded_lines": 0, "percent_statements_covered": 37.62376237623762, "percent_statements_covered_display": "37.62", "num_branches": 22, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 20, "percent_branches_covered": 9.090909090909092, "percent_branches_covered_display": "9.09"}, "missing_lines": [75, 77, 78, 79, 80, 81, 84, 87, 89, 90, 91, 92, 101, 103, 106, 108, 109, 110, 111, 128, 130, 131, 132, 133, 136, 137, 138, 143, 144, 146, 153, 154, 155, 156, 157, 168, 169, 170, 171, 173, 177, 178, 179, 180, 181, 192, 193, 195, 196, 198, 199, 200, 201, 202, 205, 206, 207, 209, 210, 211, 212, 214, 216], "excluded_lines": [], "executed_branches": [[37, 38], [37, 39]], "missing_branches": [[78, 79], [78, 84], [79, 78], [79, 80], [130, 131], [130, 136], [132, 133], [132, 136], [137, 138], [137, 143], [170, 171], [170, 173], [195, 196], [195, 214], [198, 199], [198, 205], [200, 201], [200, 205], [206, 207], [206, 209]], "functions": {"require_admin": {"executed_lines": [36, 37, 38, 39], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 28, "executed_branches": [[37, 38], [37, 39]], "missing_branches": []}, "get_settings": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 12, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 12, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 4, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [75, 77, 78, 79, 80, 81, 84, 87, 89, 90, 91, 92], "excluded_lines": [], "start_line": 70, "executed_branches": [], "missing_branches": [[78, 79], [78, 84], [79, 78], [79, 80]]}, "get_setting": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [101, 103, 106, 108, 109, 110, 111], "excluded_lines": [], "start_line": 96, "executed_branches": [], "missing_branches": []}, "update_setting": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 16, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 16, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [128, 130, 131, 132, 133, 136, 137, 138, 143, 144, 146, 153, 154, 155, 156, 157], "excluded_lines": [], "start_line": 117, "executed_branches": [], "missing_branches": [[130, 131], [130, 136], [132, 133], [132, 136], [137, 138], [137, 143]]}, "delete_setting": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 10, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [168, 169, 170, 171, 173, 177, 178, 179, 180, 181], "excluded_lines": [], "start_line": 163, "executed_branches": [], "missing_branches": [[170, 171], [170, 173]]}, "bulk_update_settings": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 18, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [192, 193, 195, 196, 198, 199, 200, 201, 202, 205, 206, 207, 209, 210, 211, 212, 214, 216], "excluded_lines": [], "start_line": 187, "executed_branches": [], "missing_branches": [[195, 196], [195, 214], [198, 199], [198, 205], [200, 201], [200, 205], [206, 207], [206, 209]]}, "": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 24, 25, 28, 42, 43, 46, 49, 50, 53, 56, 57, 58, 61, 64, 65, 66, 69, 70, 95, 96, 116, 117, 162, 163, 186, 187], "summary": {"covered_lines": 34, "num_statements": 34, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"SettingUpdate": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 46, "executed_branches": [], "missing_branches": []}, "SettingResponse": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 53, "executed_branches": [], "missing_branches": []}, "SettingsListResponse": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 61, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 24, 25, 28, 36, 37, 38, 39, 42, 43, 46, 49, 50, 53, 56, 57, 58, 61, 64, 65, 66, 69, 70, 95, 96, 116, 117, 162, 163, 186, 187], "summary": {"covered_lines": 38, "num_statements": 101, "percent_covered": 32.520325203252035, "percent_covered_display": "32.52", "missing_lines": 63, "excluded_lines": 0, "percent_statements_covered": 37.62376237623762, "percent_statements_covered_display": "37.62", "num_branches": 22, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 20, "percent_branches_covered": 9.090909090909092, "percent_branches_covered_display": "9.09"}, "missing_lines": [75, 77, 78, 79, 80, 81, 84, 87, 89, 90, 91, 92, 101, 103, 106, 108, 109, 110, 111, 128, 130, 131, 132, 133, 136, 137, 138, 143, 144, 146, 153, 154, 155, 156, 157, 168, 169, 170, 171, 173, 177, 178, 179, 180, 181, 192, 193, 195, 196, 198, 199, 200, 201, 202, 205, 206, 207, 209, 210, 211, 212, 214, 216], "excluded_lines": [], "start_line": 1, "executed_branches": [[37, 38], [37, 39]], "missing_branches": [[78, 79], [78, 84], [79, 78], [79, 80], [130, 131], [130, 136], [132, 133], [132, 136], [137, 138], [137, 143], [170, 171], [170, 173], [195, 196], [195, 214], [198, 199], [198, 205], [200, 201], [200, 205], [206, 207], [206, 209]]}}}, "app/api/url_upload.py": {"executed_lines": [5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 17, 18, 19, 20, 23, 25, 28, 31, 32, 34, 35, 37, 38, 40, 43, 48, 50, 51, 52, 54, 55, 58, 59, 60, 61, 63, 64, 66, 70, 71, 74, 81, 84, 88, 92, 93, 99, 104, 108, 120, 134, 146, 148, 149, 150, 153, 154, 155, 156, 159, 162, 163, 164, 184, 187, 190, 191, 194, 195, 196, 199, 200, 206, 207, 208, 211, 220, 223, 224, 225, 232, 233, 234, 235, 236, 237, 243, 244, 245, 246, 250, 253, 254, 256, 257, 258, 259, 260, 263, 265, 266, 267, 272, 275, 277, 285, 286, 287, 289, 290, 291, 293, 294, 295, 297, 301, 303], "summary": {"covered_lines": 117, "num_statements": 137, "percent_covered": 80.11049723756906, "percent_covered_display": "80.11", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 85.4014598540146, "percent_statements_covered_display": "85.40", "num_branches": 44, "num_partial_branches": 12, "covered_branches": 28, "missing_branches": 16, "percent_branches_covered": 63.63636363636363, "percent_branches_covered_display": "63.64"}, "missing_lines": [39, 65, 85, 89, 105, 157, 201, 248, 298, 299, 305, 306, 308, 309, 310, 312, 313, 315, 316, 317], "excluded_lines": [], "executed_branches": [[38, 40], [59, 60], [63, 64], [84, 88], [88, 92], [92, 93], [92, 99], [104, -74], [146, 148], [149, 150], [149, 153], [154, 155], [156, 159], [190, 191], [190, 194], [200, 206], [224, 225], [224, 232], [233, 234], [233, 243], [236, 237], [236, 243], [244, 245], [257, 258], [257, 272], [258, 259], [263, 257], [263, 265]], "missing_branches": [[38, 39], [59, 65], [63, 59], [84, 85], [88, 89], [104, 105], [146, 153], [154, 159], [156, 157], [200, 201], [244, 248], [258, 257], [308, 309], [308, 310], [315, 316], [315, 317]], "functions": {"URLUploadRequest.validate_url_scheme": {"executed_lines": [37, 38, 40], "summary": {"covered_lines": 3, "num_statements": 4, "percent_covered": 66.66666666666667, "percent_covered_display": "66.67", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [39], "excluded_lines": [], "start_line": 35, "executed_branches": [[38, 40]], "missing_branches": [[38, 39]]}, "is_private_ip": {"executed_lines": [48, 50, 51, 52, 54, 55, 58, 59, 60, 61, 63, 64, 66, 70, 71], "summary": {"covered_lines": 15, "num_statements": 16, "percent_covered": 85.0, "percent_covered_display": "85.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 93.75, "percent_statements_covered_display": "93.75", "num_branches": 4, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 2, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [65], "excluded_lines": [], "start_line": 43, "executed_branches": [[59, 60], [63, 64]], "missing_branches": [[59, 65], [63, 59]]}, "validate_url_safety": {"executed_lines": [81, 84, 88, 92, 93, 99, 104], "summary": {"covered_lines": 7, "num_statements": 10, "percent_covered": 66.66666666666667, "percent_covered_display": "66.67", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 70.0, "percent_statements_covered_display": "70.00", "num_branches": 8, "num_partial_branches": 3, "covered_branches": 5, "missing_branches": 3, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62.50"}, "missing_lines": [85, 89, 105], "excluded_lines": [], "start_line": 74, "executed_branches": [[84, 88], [88, 92], [92, 93], [92, 99], [104, -74]], "missing_branches": [[84, 85], [88, 89], [104, 105]]}, "validate_file_type": {"executed_lines": [120, 134, 146, 148, 149, 150, 153, 154, 155, 156, 159], "summary": {"covered_lines": 11, "num_statements": 12, "percent_covered": 80.0, "percent_covered_display": "80.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 91.66666666666667, "percent_statements_covered_display": "91.67", "num_branches": 8, "num_partial_branches": 3, "covered_branches": 5, "missing_branches": 3, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62.50"}, "missing_lines": [157], "excluded_lines": [], "start_line": 108, "executed_branches": [[146, 148], [149, 150], [149, 153], [154, 155], [156, 159]], "missing_branches": [[146, 153], [154, 159], [156, 157]]}, "process_url": {"executed_lines": [184, 187, 190, 191, 194, 195, 196, 199, 200, 206, 207, 208, 211, 220, 223, 224, 225, 232, 233, 234, 235, 236, 237, 243, 244, 245, 246, 250, 253, 254, 256, 257, 258, 259, 260, 263, 265, 266, 267, 272, 275, 277, 285, 286, 287, 289, 290, 291, 293, 294, 295, 297, 301, 303], "summary": {"covered_lines": 54, "num_statements": 68, "percent_covered": 76.66666666666667, "percent_covered_display": "76.67", "missing_lines": 14, "excluded_lines": 0, "percent_statements_covered": 79.41176470588235, "percent_statements_covered_display": "79.41", "num_branches": 22, "num_partial_branches": 3, "covered_branches": 15, "missing_branches": 7, "percent_branches_covered": 68.18181818181819, "percent_branches_covered_display": "68.18"}, "missing_lines": [201, 248, 298, 299, 305, 306, 308, 309, 310, 312, 313, 315, 316, 317], "excluded_lines": [], "start_line": 164, "executed_branches": [[190, 191], [190, 194], [200, 206], [224, 225], [224, 232], [233, 234], [233, 243], [236, 237], [236, 243], [244, 245], [257, 258], [257, 272], [258, 259], [263, 257], [263, 265]], "missing_branches": [[200, 201], [244, 248], [258, 257], [308, 309], [308, 310], [315, 316], [315, 317]]}, "": {"executed_lines": [5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 17, 18, 19, 20, 23, 25, 28, 31, 32, 34, 35, 43, 74, 108, 162, 163, 164], "summary": {"covered_lines": 27, "num_statements": 27, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"URLUploadRequest": {"executed_lines": [37, 38, 40], "summary": {"covered_lines": 3, "num_statements": 4, "percent_covered": 66.66666666666667, "percent_covered_display": "66.67", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [39], "excluded_lines": [], "start_line": 28, "executed_branches": [[38, 40]], "missing_branches": [[38, 39]]}, "": {"executed_lines": [5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 17, 18, 19, 20, 23, 25, 28, 31, 32, 34, 35, 43, 48, 50, 51, 52, 54, 55, 58, 59, 60, 61, 63, 64, 66, 70, 71, 74, 81, 84, 88, 92, 93, 99, 104, 108, 120, 134, 146, 148, 149, 150, 153, 154, 155, 156, 159, 162, 163, 164, 184, 187, 190, 191, 194, 195, 196, 199, 200, 206, 207, 208, 211, 220, 223, 224, 225, 232, 233, 234, 235, 236, 237, 243, 244, 245, 246, 250, 253, 254, 256, 257, 258, 259, 260, 263, 265, 266, 267, 272, 275, 277, 285, 286, 287, 289, 290, 291, 293, 294, 295, 297, 301, 303], "summary": {"covered_lines": 114, "num_statements": 133, "percent_covered": 80.57142857142857, "percent_covered_display": "80.57", "missing_lines": 19, "excluded_lines": 0, "percent_statements_covered": 85.71428571428571, "percent_statements_covered_display": "85.71", "num_branches": 42, "num_partial_branches": 11, "covered_branches": 27, "missing_branches": 15, "percent_branches_covered": 64.28571428571429, "percent_branches_covered_display": "64.29"}, "missing_lines": [65, 85, 89, 105, 157, 201, 248, 298, 299, 305, 306, 308, 309, 310, 312, 313, 315, 316, 317], "excluded_lines": [], "start_line": 1, "executed_branches": [[59, 60], [63, 64], [84, 88], [88, 92], [92, 93], [92, 99], [104, -74], [146, 148], [149, 150], [149, 153], [154, 155], [156, 159], [190, 191], [190, 194], [200, 206], [224, 225], [224, 232], [233, 234], [233, 243], [236, 237], [236, 243], [244, 245], [257, 258], [257, 272], [258, 259], [263, 257], [263, 265]], "missing_branches": [[59, 65], [63, 59], [84, 85], [88, 89], [104, 105], [146, 153], [154, 159], [156, 157], [200, 201], [244, 248], [258, 257], [308, 309], [308, 310], [315, 316], [315, 317]]}}}, "app/api/user.py": {"executed_lines": [5, 6, 8, 11, 13, 16, 20, 21, 22, 24, 25, 26, 30, 31, 34, 35, 37, 41, 42, 43, 46, 47], "summary": {"covered_lines": 22, "num_statements": 23, "percent_covered": 96.29629629629629, "percent_covered_display": "96.30", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 95.65217391304348, "percent_statements_covered_display": "95.65", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [48], "excluded_lines": [], "executed_branches": [[21, 22], [21, 24], [25, 26], [25, 30]], "missing_branches": [], "functions": {"whoami_handler": {"executed_lines": [20, 21, 22, 24, 25, 26, 30, 31, 34, 35, 37], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 16, "executed_branches": [[21, 22], [21, 24], [25, 26], [25, 30]], "missing_branches": []}, "whoami": {"executed_lines": [43], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 42, "executed_branches": [], "missing_branches": []}, "auth_whoami": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [48], "excluded_lines": [], "start_line": 47, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [5, 6, 8, 11, 13, 16, 41, 42, 46, 47], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 8, 11, 13, 16, 20, 21, 22, 24, 25, 26, 30, 31, 34, 35, 37, 41, 42, 43, 46, 47], "summary": {"covered_lines": 22, "num_statements": 23, "percent_covered": 96.29629629629629, "percent_covered_display": "96.30", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 95.65217391304348, "percent_statements_covered_display": "95.65", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [48], "excluded_lines": [], "start_line": 1, "executed_branches": [[21, 22], [21, 24], [25, 26], [25, 30]], "missing_branches": []}}}, "app/auth.py": {"executed_lines": [1, 2, 3, 4, 6, 7, 8, 9, 11, 13, 15, 18, 19, 22, 23, 25, 36, 39, 40, 43, 44, 45, 47, 48, 49, 50, 51, 53, 54, 56, 58, 61, 63, 65, 66, 69, 170, 171, 172, 174, 175, 178, 179, 180, 182, 183], "summary": {"covered_lines": 46, "num_statements": 95, "percent_covered": 46.95652173913044, "percent_covered_display": "46.96", "missing_lines": 49, "excluded_lines": 0, "percent_statements_covered": 48.421052631578945, "percent_statements_covered_display": "48.42", "num_branches": 20, "num_partial_branches": 2, "covered_branches": 8, "missing_branches": 12, "percent_branches_covered": 40.0, "percent_branches_covered_display": "40.00"}, "missing_lines": [26, 33, 34, 71, 72, 74, 86, 87, 89, 90, 92, 93, 95, 96, 98, 99, 100, 101, 102, 107, 110, 111, 116, 117, 119, 120, 121, 124, 126, 129, 132, 133, 134, 135, 136, 140, 141, 143, 144, 145, 147, 149, 158, 159, 161, 163, 164, 166, 167], "excluded_lines": [], "executed_branches": [[25, 36], [44, 45], [44, 47], [49, 50], [49, 53], [53, 54], [53, 56], [69, 170]], "missing_branches": [[25, 26], [69, 71], [89, 90], [89, 92], [101, 102], [101, 107], [110, 111], [110, 116], [117, 119], [117, 124], [147, 149], [147, 161]], "functions": {"get_current_user": {"executed_lines": [40], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 39, "executed_branches": [], "missing_branches": []}, "require_login": {"executed_lines": [44, 45, 47, 48, 58], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 43, "executed_branches": [[44, 45], [44, 47]], "missing_branches": []}, "require_login.wrapper": {"executed_lines": [49, 50, 51, 53, 54, 56], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 48, "executed_branches": [[49, 50], [49, 53], [53, 54], [53, 56]], "missing_branches": []}, "get_gravatar_url": {"executed_lines": [63, 65, 66], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 61, "executed_branches": [], "missing_branches": []}, "login": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [74], "excluded_lines": [], "start_line": 72, "executed_branches": [], "missing_branches": []}, "oauth_login": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [89, 90, 92, 93], "excluded_lines": [], "start_line": 87, "executed_branches": [], "missing_branches": [[89, 90], [89, 92]]}, "oauth_callback": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 21, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 21, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [98, 99, 100, 101, 102, 107, 110, 111, 116, 117, 119, 120, 121, 124, 126, 129, 132, 133, 134, 135, 136], "excluded_lines": [], "start_line": 96, "executed_branches": [], "missing_branches": [[101, 102], [101, 107], [110, 111], [110, 116], [117, 119], [117, 124]]}, "auth": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 8, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [143, 144, 145, 147, 149, 158, 159, 161], "excluded_lines": [], "start_line": 141, "executed_branches": [], "missing_branches": [[147, 149], [147, 161]]}, "logout": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [166, 167], "excluded_lines": [], "start_line": 164, "executed_branches": [], "missing_branches": []}, "whoami": {"executed_lines": [174, 175], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 172, "executed_branches": [], "missing_branches": []}, "private_page": {"executed_lines": [182, 183], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 180, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [1, 2, 3, 4, 6, 7, 8, 9, 11, 13, 15, 18, 19, 22, 23, 25, 36, 39, 43, 61, 69, 170, 171, 172, 178, 179, 180], "summary": {"covered_lines": 27, "num_statements": 40, "percent_covered": 65.9090909090909, "percent_covered_display": "65.91", "missing_lines": 13, "excluded_lines": 0, "percent_statements_covered": 67.5, "percent_statements_covered_display": "67.50", "num_branches": 4, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 2, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [26, 33, 34, 71, 72, 86, 87, 95, 96, 140, 141, 163, 164], "excluded_lines": [], "start_line": 1, "executed_branches": [[25, 36], [69, 170]], "missing_branches": [[25, 26], [69, 71]]}}, "classes": {"": {"executed_lines": [1, 2, 3, 4, 6, 7, 8, 9, 11, 13, 15, 18, 19, 22, 23, 25, 36, 39, 40, 43, 44, 45, 47, 48, 49, 50, 51, 53, 54, 56, 58, 61, 63, 65, 66, 69, 170, 171, 172, 174, 175, 178, 179, 180, 182, 183], "summary": {"covered_lines": 46, "num_statements": 95, "percent_covered": 46.95652173913044, "percent_covered_display": "46.96", "missing_lines": 49, "excluded_lines": 0, "percent_statements_covered": 48.421052631578945, "percent_statements_covered_display": "48.42", "num_branches": 20, "num_partial_branches": 2, "covered_branches": 8, "missing_branches": 12, "percent_branches_covered": 40.0, "percent_branches_covered_display": "40.00"}, "missing_lines": [26, 33, 34, 71, 72, 74, 86, 87, 89, 90, 92, 93, 95, 96, 98, 99, 100, 101, 102, 107, 110, 111, 116, 117, 119, 120, 121, 124, 126, 129, 132, 133, 134, 135, 136, 140, 141, 143, 144, 145, 147, 149, 158, 159, 161, 163, 164, 166, 167], "excluded_lines": [], "start_line": 1, "executed_branches": [[25, 36], [44, 45], [44, 47], [49, 50], [49, 53], [53, 54], [53, 56], [69, 170]], "missing_branches": [[25, 26], [69, 71], [89, 90], [89, 92], [101, 102], [101, 107], [110, 111], [110, 116], [117, 119], [117, 124], [147, 149], [147, 161]]}}}, "app/celery_app.py": {"executed_lines": [3, 4, 6, 8, 16, 19, 20, 25, 26, 30, 31, 33, 35], "summary": {"covered_lines": 13, "num_statements": 16, "percent_covered": 77.77777777777777, "percent_covered_display": "77.78", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 81.25, "percent_statements_covered_display": "81.25", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [42, 43, 45], "excluded_lines": [], "executed_branches": [[30, 31]], "missing_branches": [[30, -25]], "functions": {"task_failure_handler": {"executed_lines": [30, 31, 33, 35], "summary": {"covered_lines": 4, "num_statements": 7, "percent_covered": 55.55555555555556, "percent_covered_display": "55.56", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 57.142857142857146, "percent_statements_covered_display": "57.14", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [42, 43, 45], "excluded_lines": [], "start_line": 26, "executed_branches": [[30, 31]], "missing_branches": [[30, -25]]}, "": {"executed_lines": [3, 4, 6, 8, 16, 19, 20, 25, 26], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 6, 8, 16, 19, 20, 25, 26, 30, 31, 33, 35], "summary": {"covered_lines": 13, "num_statements": 16, "percent_covered": 77.77777777777777, "percent_covered_display": "77.78", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 81.25, "percent_statements_covered_display": "81.25", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [42, 43, 45], "excluded_lines": [], "start_line": 1, "executed_branches": [[30, 31]], "missing_branches": [[30, -25]]}}}, "app/celery_worker.py": {"executed_lines": [3, 6, 9, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 38, 43, 44, 49], "summary": {"covered_lines": 30, "num_statements": 33, "percent_covered": 90.9090909090909, "percent_covered_display": "90.91", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 90.9090909090909, "percent_statements_covered_display": "90.91", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [45, 51, 92], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"test_task": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [45], "excluded_lines": [], "start_line": 44, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [3, 6, 9, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 38, 43, 44, 49], "summary": {"covered_lines": 30, "num_statements": 32, "percent_covered": 93.75, "percent_covered_display": "93.75", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 93.75, "percent_statements_covered_display": "93.75", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [51, 92], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 6, 9, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 38, 43, 44, 49], "summary": {"covered_lines": 30, "num_statements": 33, "percent_covered": 90.9090909090909, "percent_covered_display": "90.91", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 90.9090909090909, "percent_statements_covered_display": "90.91", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [45, 51, 92], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/config.py": {"executed_lines": [3, 4, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 22, 23, 26, 27, 28, 29, 32, 33, 34, 38, 40, 41, 42, 43, 44, 47, 48, 49, 50, 51, 54, 55, 56, 57, 60, 61, 62, 63, 64, 65, 66, 69, 70, 71, 72, 73, 74, 75, 78, 79, 80, 83, 84, 85, 86, 89, 90, 91, 92, 93, 96, 97, 98, 99, 100, 101, 102, 105, 106, 107, 108, 109, 110, 111, 114, 117, 118, 119, 120, 121, 122, 123, 126, 127, 128, 129, 130, 133, 134, 135, 136, 137, 138, 139, 142, 143, 146, 149, 152, 155, 160, 163, 164, 167, 168, 169, 174, 178, 187, 194, 203, 214, 220, 223, 229, 230, 239, 240, 245, 251, 255, 259, 263, 268, 269, 271, 272, 273, 277, 279, 280, 282, 283, 284, 285, 286, 289, 290, 292, 293, 294, 297, 298, 299, 300, 306, 307, 309, 310, 311, 314, 315, 316, 317, 320, 322, 323, 326, 327, 328, 331, 332, 333, 334, 337, 339, 340, 342, 343, 344, 345, 350, 351, 355, 356, 374], "summary": {"covered_lines": 180, "num_statements": 195, "percent_covered": 86.8995633187773, "percent_covered_display": "86.90", "missing_lines": 15, "excluded_lines": 0, "percent_statements_covered": 92.3076923076923, "percent_statements_covered_display": "92.31", "num_branches": 34, "num_partial_branches": 3, "covered_branches": 19, "missing_branches": 15, "percent_branches_covered": 55.88235294117647, "percent_branches_covered_display": "55.88"}, "missing_lines": [274, 275, 276, 303, 348, 358, 359, 362, 363, 366, 367, 368, 369, 370, 371], "excluded_lines": [], "executed_branches": [[271, 272], [271, 277], [272, 273], [282, 283], [282, 284], [284, 285], [284, 286], [293, 294], [293, 297], [298, 299], [310, 311], [310, 314], [315, 316], [315, 320], [327, 328], [327, 331], [332, 333], [332, 337], [343, 344]], "missing_branches": [[272, 274], [274, 275], [274, 276], [298, 303], [343, 348], [358, 359], [358, 366], [359, 362], [359, 363], [366, 367], [366, 371], [367, 368], [367, 369], [369, 370], [369, 371]], "functions": {"Settings.parse_notification_urls": {"executed_lines": [271, 272, 273, 277], "summary": {"covered_lines": 4, "num_statements": 7, "percent_covered": 53.84615384615385, "percent_covered_display": "53.85", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 57.142857142857146, "percent_statements_covered_display": "57.14", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 3, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [274, 275, 276], "excluded_lines": [], "start_line": 269, "executed_branches": [[271, 272], [271, 277], [272, 273]], "missing_branches": [[272, 274], [274, 275], [274, 276]]}, "Settings.validate_session_secret": {"executed_lines": [282, 283, 284, 285, 286], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 280, "executed_branches": [[282, 283], [282, 284], [284, 285], [284, 286]], "missing_branches": []}, "Settings.build_date": {"executed_lines": [292, 293, 294, 297, 298, 299, 300], "summary": {"covered_lines": 7, "num_statements": 8, "percent_covered": 83.33333333333333, "percent_covered_display": "83.33", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 87.5, "percent_statements_covered_display": "87.50", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [303], "excluded_lines": [], "start_line": 290, "executed_branches": [[293, 294], [293, 297], [298, 299]], "missing_branches": [[298, 303]]}, "Settings.version": {"executed_lines": [309, 310, 311, 314, 315, 316, 317, 320], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 307, "executed_branches": [[310, 311], [310, 314], [315, 316], [315, 320]], "missing_branches": []}, "Settings.git_sha": {"executed_lines": [326, 327, 328, 331, 332, 333, 334, 337], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 323, "executed_branches": [[327, 328], [327, 331], [332, 333], [332, 337]], "missing_branches": []}, "Settings.runtime_info": {"executed_lines": [342, 343, 344, 345], "summary": {"covered_lines": 4, "num_statements": 5, "percent_covered": 71.42857142857143, "percent_covered_display": "71.43", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [348], "excluded_lines": [], "start_line": 340, "executed_branches": [[343, 344]], "missing_branches": [[343, 348]]}, "Settings.Config.parse_env_var": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 10, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 10, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [358, 359, 362, 363, 366, 367, 368, 369, 370, 371], "excluded_lines": [], "start_line": 356, "executed_branches": [], "missing_branches": [[358, 359], [358, 366], [359, 362], [359, 363], [366, 367], [366, 371], [367, 368], [367, 369], [369, 370], [369, 371]]}, "": {"executed_lines": [3, 4, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 22, 23, 26, 27, 28, 29, 32, 33, 34, 38, 40, 41, 42, 43, 44, 47, 48, 49, 50, 51, 54, 55, 56, 57, 60, 61, 62, 63, 64, 65, 66, 69, 70, 71, 72, 73, 74, 75, 78, 79, 80, 83, 84, 85, 86, 89, 90, 91, 92, 93, 96, 97, 98, 99, 100, 101, 102, 105, 106, 107, 108, 109, 110, 111, 114, 117, 118, 119, 120, 121, 122, 123, 126, 127, 128, 129, 130, 133, 134, 135, 136, 137, 138, 139, 142, 143, 146, 149, 152, 155, 160, 163, 164, 167, 168, 169, 174, 178, 187, 194, 203, 214, 220, 223, 229, 230, 239, 240, 245, 251, 255, 259, 263, 268, 269, 279, 280, 289, 290, 306, 307, 322, 323, 339, 340, 350, 351, 355, 356, 374], "summary": {"covered_lines": 144, "num_statements": 144, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"Settings": {"executed_lines": [271, 272, 273, 277, 282, 283, 284, 285, 286, 292, 293, 294, 297, 298, 299, 300, 309, 310, 311, 314, 315, 316, 317, 320, 326, 327, 328, 331, 332, 333, 334, 337, 342, 343, 344, 345], "summary": {"covered_lines": 36, "num_statements": 41, "percent_covered": 84.61538461538461, "percent_covered_display": "84.62", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 87.8048780487805, "percent_statements_covered_display": "87.80", "num_branches": 24, "num_partial_branches": 3, "covered_branches": 19, "missing_branches": 5, "percent_branches_covered": 79.16666666666667, "percent_branches_covered_display": "79.17"}, "missing_lines": [274, 275, 276, 303, 348], "excluded_lines": [], "start_line": 10, "executed_branches": [[271, 272], [271, 277], [272, 273], [282, 283], [282, 284], [284, 285], [284, 286], [293, 294], [293, 297], [298, 299], [310, 311], [310, 314], [315, 316], [315, 320], [327, 328], [327, 331], [332, 333], [332, 337], [343, 344]], "missing_branches": [[272, 274], [274, 275], [274, 276], [298, 303], [343, 348]]}, "Settings.Config": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 10, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 10, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [358, 359, 362, 363, 366, 367, 368, 369, 370, 371], "excluded_lines": [], "start_line": 350, "executed_branches": [], "missing_branches": [[358, 359], [358, 366], [359, 362], [359, 363], [366, 367], [366, 371], [367, 368], [367, 369], [369, 370], [369, 371]]}, "": {"executed_lines": [3, 4, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 22, 23, 26, 27, 28, 29, 32, 33, 34, 38, 40, 41, 42, 43, 44, 47, 48, 49, 50, 51, 54, 55, 56, 57, 60, 61, 62, 63, 64, 65, 66, 69, 70, 71, 72, 73, 74, 75, 78, 79, 80, 83, 84, 85, 86, 89, 90, 91, 92, 93, 96, 97, 98, 99, 100, 101, 102, 105, 106, 107, 108, 109, 110, 111, 114, 117, 118, 119, 120, 121, 122, 123, 126, 127, 128, 129, 130, 133, 134, 135, 136, 137, 138, 139, 142, 143, 146, 149, 152, 155, 160, 163, 164, 167, 168, 169, 174, 178, 187, 194, 203, 214, 220, 223, 229, 230, 239, 240, 245, 251, 255, 259, 263, 268, 269, 279, 280, 289, 290, 306, 307, 322, 323, 339, 340, 350, 351, 355, 356, 374], "summary": {"covered_lines": 144, "num_statements": 144, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/database.py": {"executed_lines": [3, 4, 6, 7, 8, 9, 11, 13, 15, 18, 19, 20, 23, 30, 31, 33, 35, 37, 38, 39, 40, 43, 44, 45, 48, 49, 50, 53, 59, 64, 66, 69, 70, 71, 72, 73, 74, 75, 78, 79, 80, 86, 93, 99, 106, 107, 108, 111, 121, 126, 127, 128, 130], "summary": {"covered_lines": 53, "num_statements": 79, "percent_covered": 65.71428571428571, "percent_covered_display": "65.71", "missing_lines": 26, "excluded_lines": 0, "percent_statements_covered": 67.0886075949367, "percent_statements_covered_display": "67.09", "num_branches": 26, "num_partial_branches": 8, "covered_branches": 16, "missing_branches": 10, "percent_branches_covered": 61.53846153846154, "percent_branches_covered_display": "61.54"}, "missing_lines": [54, 55, 56, 81, 82, 83, 84, 87, 88, 89, 90, 94, 95, 96, 97, 100, 101, 102, 103, 112, 113, 114, 115, 116, 117, 118], "excluded_lines": [], "executed_branches": [[31, 33], [31, 48], [35, 37], [35, 48], [38, 39], [43, 44], [69, 70], [71, 72], [71, 78], [78, -59], [78, 79], [80, 86], [86, 93], [93, 99], [99, 106], [111, -59]], "missing_branches": [[38, 43], [43, 48], [69, 78], [80, 81], [86, 87], [93, 94], [99, 100], [111, 112], [114, 115], [114, 116]], "functions": {"init_db": {"executed_lines": [30, 31, 33, 35, 37, 38, 39, 40, 43, 44, 45, 48, 49, 50, 53], "summary": {"covered_lines": 15, "num_statements": 18, "percent_covered": 80.76923076923077, "percent_covered_display": "80.77", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 83.33333333333333, "percent_statements_covered_display": "83.33", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 6, "missing_branches": 2, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [54, 55, 56], "excluded_lines": [], "start_line": 23, "executed_branches": [[31, 33], [31, 48], [35, 37], [35, 48], [38, 39], [43, 44]], "missing_branches": [[38, 43], [43, 48]]}, "_run_schema_migrations": {"executed_lines": [64, 66, 69, 70, 71, 72, 73, 74, 75, 78, 79, 80, 86, 93, 99, 106, 107, 108, 111], "summary": {"covered_lines": 19, "num_statements": 42, "percent_covered": 48.333333333333336, "percent_covered_display": "48.33", "missing_lines": 23, "excluded_lines": 0, "percent_statements_covered": 45.23809523809524, "percent_statements_covered_display": "45.24", "num_branches": 18, "num_partial_branches": 6, "covered_branches": 10, "missing_branches": 8, "percent_branches_covered": 55.55555555555556, "percent_branches_covered_display": "55.56"}, "missing_lines": [81, 82, 83, 84, 87, 88, 89, 90, 94, 95, 96, 97, 100, 101, 102, 103, 112, 113, 114, 115, 116, 117, 118], "excluded_lines": [], "start_line": 59, "executed_branches": [[69, 70], [71, 72], [71, 78], [78, -59], [78, 79], [80, 86], [86, 93], [93, 99], [99, 106], [111, -59]], "missing_branches": [[69, 78], [80, 81], [86, 87], [93, 94], [99, 100], [111, 112], [114, 115], [114, 116]]}, "get_db": {"executed_lines": [126, 127, 128, 130], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 121, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [3, 4, 6, 7, 8, 9, 11, 13, 15, 18, 19, 20, 23, 59, 121], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 6, 7, 8, 9, 11, 13, 15, 18, 19, 20, 23, 30, 31, 33, 35, 37, 38, 39, 40, 43, 44, 45, 48, 49, 50, 53, 59, 64, 66, 69, 70, 71, 72, 73, 74, 75, 78, 79, 80, 86, 93, 99, 106, 107, 108, 111, 121, 126, 127, 128, 130], "summary": {"covered_lines": 53, "num_statements": 79, "percent_covered": 65.71428571428571, "percent_covered_display": "65.71", "missing_lines": 26, "excluded_lines": 0, "percent_statements_covered": 67.0886075949367, "percent_statements_covered_display": "67.09", "num_branches": 26, "num_partial_branches": 8, "covered_branches": 16, "missing_branches": 10, "percent_branches_covered": 61.53846153846154, "percent_branches_covered_display": "61.54"}, "missing_lines": [54, 55, 56, 81, 82, 83, 84, 87, 88, 89, 90, 94, 95, 96, 97, 100, 101, 102, 103, 112, 113, 114, 115, 116, 117, 118], "excluded_lines": [], "start_line": 1, "executed_branches": [[31, 33], [31, 48], [35, 37], [35, 48], [38, 39], [43, 44], [69, 70], [71, 72], [71, 78], [78, -59], [78, 79], [80, 86], [86, 93], [93, 99], [99, 106], [111, -59]], "missing_branches": [[38, 43], [43, 48], [69, 78], [80, 81], [86, 87], [93, 94], [99, 100], [111, 112], [114, 115], [114, 116]]}}}, "app/frontend.py": {"executed_lines": [7], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [7], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [7], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/main.py": {"executed_lines": [2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 27, 30, 33, 36, 41, 46, 47, 53, 56, 57, 59, 60, 61, 62, 66, 69, 71, 74, 77, 80, 81, 85, 88, 91, 94, 97, 100, 103, 106, 107, 108, 116, 119, 122, 125, 128, 129, 130, 136, 137, 143, 144, 147, 150, 151, 162, 163, 169, 170, 181, 182, 187, 188, 189, 190], "summary": {"covered_lines": 76, "num_statements": 85, "percent_covered": 85.56701030927834, "percent_covered_display": "85.57", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 89.41176470588235, "percent_statements_covered_display": "89.41", "num_branches": 12, "num_partial_branches": 5, "covered_branches": 7, "missing_branches": 5, "percent_branches_covered": 58.333333333333336, "percent_branches_covered_display": "58.33"}, "missing_lines": [37, 63, 64, 83, 132, 155, 175, 176, 183], "excluded_lines": [], "executed_branches": [[36, 41], [80, 81], [129, 130], [143, 144], [143, 147], [150, 151], [169, 170]], "missing_branches": [[36, 37], [80, 83], [129, 132], [150, 155], [169, 175]], "functions": {"lifespan": {"executed_lines": [53, 56, 57, 59, 60, 61, 62, 66, 69, 71, 74, 77, 80, 81, 85, 88, 91, 94, 97, 100], "summary": {"covered_lines": 20, "num_statements": 23, "percent_covered": 84.0, "percent_covered_display": "84.00", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 86.95652173913044, "percent_statements_covered_display": "86.96", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [63, 64, 83], "excluded_lines": [], "start_line": 47, "executed_branches": [[80, 81]], "missing_branches": [[80, 83]]}, "http_exception_handler": {"executed_lines": [143, 144, 147, 150, 151], "summary": {"covered_lines": 5, "num_statements": 6, "percent_covered": 80.0, "percent_covered_display": "80.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 83.33333333333333, "percent_statements_covered_display": "83.33", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [155], "excluded_lines": [], "start_line": 137, "executed_branches": [[143, 144], [143, 147], [150, 151]], "missing_branches": [[150, 155]]}, "custom_500_handler": {"executed_lines": [169, 170], "summary": {"covered_lines": 2, "num_statements": 4, "percent_covered": 50.0, "percent_covered_display": "50.00", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 50.0, "percent_statements_covered_display": "50.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [175, 176], "excluded_lines": [], "start_line": 163, "executed_branches": [[169, 170]], "missing_branches": [[169, 175]]}, "test_500": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [183], "excluded_lines": [], "start_line": 182, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 27, 30, 33, 36, 41, 46, 47, 103, 106, 107, 108, 116, 119, 122, 125, 128, 129, 130, 136, 137, 162, 163, 181, 182, 187, 188, 189, 190], "summary": {"covered_lines": 49, "num_statements": 51, "percent_covered": 92.72727272727273, "percent_covered_display": "92.73", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 96.07843137254902, "percent_statements_covered_display": "96.08", "num_branches": 4, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 2, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [37, 132], "excluded_lines": [], "start_line": 1, "executed_branches": [[36, 41], [129, 130]], "missing_branches": [[36, 37], [129, 132]]}}, "classes": {"": {"executed_lines": [2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 27, 30, 33, 36, 41, 46, 47, 53, 56, 57, 59, 60, 61, 62, 66, 69, 71, 74, 77, 80, 81, 85, 88, 91, 94, 97, 100, 103, 106, 107, 108, 116, 119, 122, 125, 128, 129, 130, 136, 137, 143, 144, 147, 150, 151, 162, 163, 169, 170, 181, 182, 187, 188, 189, 190], "summary": {"covered_lines": 76, "num_statements": 85, "percent_covered": 85.56701030927834, "percent_covered_display": "85.57", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 89.41176470588235, "percent_statements_covered_display": "89.41", "num_branches": 12, "num_partial_branches": 5, "covered_branches": 7, "missing_branches": 5, "percent_branches_covered": 58.333333333333336, "percent_branches_covered_display": "58.33"}, "missing_lines": [37, 63, 64, 83, 132, 155, 175, 176, 183], "excluded_lines": [], "start_line": 1, "executed_branches": [[36, 41], [80, 81], [129, 130], [143, 144], [143, 147], [150, 151], [169, 170]], "missing_branches": [[36, 37], [80, 83], [129, 132], [150, 155], [169, 175]]}}}, "app/middleware/__init__.py": {"executed_lines": [3, 5], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [3, 5], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 5], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/middleware/rate_limit.py": {"executed_lines": [19, 20, 22, 23, 24, 26, 29, 44, 45, 47, 48, 49, 50, 51, 54, 55, 56, 59, 70, 71, 73, 80, 82, 83, 85, 92, 100, 101, 104, 114], "summary": {"covered_lines": 30, "num_statements": 30, "percent_covered": 95.0, "percent_covered_display": "95.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 10, "num_partial_branches": 2, "covered_branches": 8, "missing_branches": 2, "percent_branches_covered": 80.0, "percent_branches_covered_display": "80.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[44, 45], [44, 54], [47, 48], [49, 50], [70, 71], [70, 80], [82, 83], [82, 85]], "missing_branches": [[47, 54], [49, 54]], "functions": {"get_identifier": {"executed_lines": [44, 45, 47, 48, 49, 50, 51, 54, 55, 56], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 87.5, "percent_covered_display": "87.50", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 6, "num_partial_branches": 2, "covered_branches": 4, "missing_branches": 2, "percent_branches_covered": 66.66666666666667, "percent_branches_covered_display": "66.67"}, "missing_lines": [], "excluded_lines": [], "start_line": 29, "executed_branches": [[44, 45], [44, 54], [47, 48], [49, 50]], "missing_branches": [[47, 54], [49, 54]]}, "create_limiter": {"executed_lines": [70, 71, 73, 80, 82, 83, 85, 92, 100, 101], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 59, "executed_branches": [[70, 71], [70, 80], [82, 83], [82, 85]], "missing_branches": []}, "get_rate_limit_exceeded_handler": {"executed_lines": [114], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 104, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [19, 20, 22, 23, 24, 26, 29, 59, 104], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [19, 20, 22, 23, 24, 26, 29, 44, 45, 47, 48, 49, 50, 51, 54, 55, 56, 59, 70, 71, 73, 80, 82, 83, 85, 92, 100, 101, 104, 114], "summary": {"covered_lines": 30, "num_statements": 30, "percent_covered": 95.0, "percent_covered_display": "95.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 10, "num_partial_branches": 2, "covered_branches": 8, "missing_branches": 2, "percent_branches_covered": 80.0, "percent_branches_covered_display": "80.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[44, 45], [44, 54], [47, 48], [49, 50], [70, 71], [70, 80], [82, 83], [82, 85]], "missing_branches": [[47, 54], [49, 54]]}}}, "app/middleware/rate_limit_decorators.py": {"executed_lines": [11, 14, 17, 18, 20, 21, 24, 41, 42, 44, 46, 49, 63, 64, 66, 68], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[17, 18], [17, 21]], "missing_branches": [], "functions": {"get_limiter": {"executed_lines": [17, 18, 20, 21], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 14, "executed_branches": [[17, 18], [17, 21]], "missing_branches": []}, "limit": {"executed_lines": [41, 46], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 24, "executed_branches": [], "missing_branches": []}, "limit.decorator": {"executed_lines": [42, 44], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 41, "executed_branches": [], "missing_branches": []}, "exempt": {"executed_lines": [63, 68], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 49, "executed_branches": [], "missing_branches": []}, "exempt.decorator": {"executed_lines": [64, 66], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 63, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [11, 14, 24, 49], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [11, 14, 17, 18, 20, 21, 24, 41, 42, 44, 46, 49, 63, 64, 66, 68], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[17, 18], [17, 21]], "missing_branches": []}}}, "app/middleware/security_headers.py": {"executed_lines": [14, 15, 17, 18, 20, 23, 36, 44, 45, 46, 48, 57, 59, 71, 74, 77, 79], "summary": {"covered_lines": 17, "num_statements": 35, "percent_covered": 40.42553191489362, "percent_covered_display": "40.43", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 48.57142857142857, "percent_statements_covered_display": "48.57", "num_branches": 12, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 10, "percent_branches_covered": 16.666666666666668, "percent_branches_covered_display": "16.67"}, "missing_lines": [49, 50, 75, 91, 92, 93, 94, 99, 100, 101, 102, 107, 108, 109, 110, 115, 116, 117], "excluded_lines": [], "executed_branches": [[48, 57], [74, 77]], "missing_branches": [[48, 49], [74, 75], [91, 92], [91, 99], [99, 100], [99, 107], [107, 108], [107, 115], [115, -79], [115, 116]], "functions": {"SecurityHeadersMiddleware.__init__": {"executed_lines": [44, 45, 46, 48, 57], "summary": {"covered_lines": 5, "num_statements": 7, "percent_covered": 66.66666666666667, "percent_covered_display": "66.67", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 71.42857142857143, "percent_statements_covered_display": "71.43", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [49, 50], "excluded_lines": [], "start_line": 36, "executed_branches": [[48, 57]], "missing_branches": [[48, 49]]}, "SecurityHeadersMiddleware.dispatch": {"executed_lines": [71, 74, 77], "summary": {"covered_lines": 3, "num_statements": 4, "percent_covered": 66.66666666666667, "percent_covered_display": "66.67", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [75], "excluded_lines": [], "start_line": 59, "executed_branches": [[74, 77]], "missing_branches": [[74, 75]]}, "SecurityHeadersMiddleware._add_security_headers": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 15, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 15, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [91, 92, 93, 94, 99, 100, 101, 102, 107, 108, 109, 110, 115, 116, 117], "excluded_lines": [], "start_line": 79, "executed_branches": [], "missing_branches": [[91, 92], [91, 99], [99, 100], [99, 107], [107, 108], [107, 115], [115, -79], [115, 116]]}, "": {"executed_lines": [14, 15, 17, 18, 20, 23, 36, 59, 79], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"SecurityHeadersMiddleware": {"executed_lines": [44, 45, 46, 48, 57, 71, 74, 77], "summary": {"covered_lines": 8, "num_statements": 26, "percent_covered": 26.31578947368421, "percent_covered_display": "26.32", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 30.76923076923077, "percent_statements_covered_display": "30.77", "num_branches": 12, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 10, "percent_branches_covered": 16.666666666666668, "percent_branches_covered_display": "16.67"}, "missing_lines": [49, 50, 75, 91, 92, 93, 94, 99, 100, 101, 102, 107, 108, 109, 110, 115, 116, 117], "excluded_lines": [], "start_line": 23, "executed_branches": [[48, 57], [74, 77]], "missing_branches": [[48, 49], [74, 75], [91, 92], [91, 99], [99, 100], [99, 107], [107, 108], [107, 115], [115, -79], [115, 116]]}, "": {"executed_lines": [14, 15, 17, 18, 20, 23, 36, 59, 79], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/models.py": {"executed_lines": [3, 5, 8, 9, 11, 12, 13, 14, 15, 16, 19, 20, 22, 26, 29, 32, 36, 40, 43, 46, 50, 53, 56, 59, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 92, 95, 97, 98, 99, 100, 101], "summary": {"covered_lines": 52, "num_statements": 52, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [3, 5, 8, 9, 11, 12, 13, 14, 15, 16, 19, 20, 22, 26, 29, 32, 36, 40, 43, 46, 50, 53, 56, 59, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 92, 95, 97, 98, 99, 100, 101], "summary": {"covered_lines": 52, "num_statements": 52, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"DocumentMetadata": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 8, "executed_branches": [], "missing_branches": []}, "FileRecord": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 19, "executed_branches": [], "missing_branches": []}, "FileProcessingStep": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 59, "executed_branches": [], "missing_branches": []}, "ProcessingLog": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 80, "executed_branches": [], "missing_branches": []}, "ApplicationSettings": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 92, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [3, 5, 8, 9, 11, 12, 13, 14, 15, 16, 19, 20, 22, 26, 29, 32, 36, 40, 43, 46, 50, 53, 56, 59, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 92, 95, 97, 98, 99, 100, 101], "summary": {"covered_lines": 52, "num_statements": 52, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/tasks/__init__.py": {"executed_lines": [2, 3], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [2, 3], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [2, 3], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/tasks/check_credentials.py": {"executed_lines": [1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 14, 15, 16, 19, 20, 24, 27, 28, 29, 30, 31, 32, 34, 35, 37, 38, 41, 44, 47, 49, 50, 51, 52, 57, 60, 62, 63, 64, 70, 72, 73, 74, 78, 81, 82, 83, 84, 85, 88, 90, 91, 92, 93, 94, 97, 99, 100, 101, 102, 103, 106, 108, 109, 110, 111, 112, 115, 117, 118, 119, 120, 121, 124, 125], "summary": {"covered_lines": 74, "num_statements": 134, "percent_covered": 54.32098765432099, "percent_covered_display": "54.32", "missing_lines": 60, "excluded_lines": 0, "percent_statements_covered": 55.223880597014926, "percent_statements_covered_display": "55.22", "num_branches": 28, "num_partial_branches": 0, "covered_branches": 14, "missing_branches": 14, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [53, 54, 65, 66, 127, 130, 133, 136, 137, 140, 174, 175, 177, 178, 179, 182, 183, 184, 185, 187, 188, 190, 192, 195, 196, 199, 201, 202, 205, 206, 210, 211, 212, 213, 214, 219, 225, 227, 230, 231, 234, 235, 237, 239, 240, 241, 242, 245, 246, 249, 250, 251, 252, 255, 258, 261, 264, 265, 268, 273], "excluded_lines": [], "executed_branches": [[50, 51], [50, 57], [72, 73], [72, 74], [83, 84], [83, 85], [92, 93], [92, 94], [101, 102], [101, 103], [110, 111], [110, 112], [119, 120], [119, 121]], "missing_branches": [[177, 178], [177, 261], [182, 183], [182, 190], [201, 202], [201, 227], [210, 211], [210, 219], [230, 231], [230, 235], [235, 177], [235, 237], [249, 250], [249, 255]], "functions": {"MockRequest.__init__": {"executed_lines": [28, 29, 30, 31, 32], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 27, "executed_branches": [], "missing_branches": []}, "MockRequest.json": {"executed_lines": [35], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 34, "executed_branches": [], "missing_branches": []}, "MockRequest.form": {"executed_lines": [38], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 37, "executed_branches": [], "missing_branches": []}, "get_failure_state": {"executed_lines": [49, 50, 51, 52, 57], "summary": {"covered_lines": 5, "num_statements": 7, "percent_covered": 77.77777777777777, "percent_covered_display": "77.78", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 71.42857142857143, "percent_statements_covered_display": "71.43", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [53, 54], "excluded_lines": [], "start_line": 47, "executed_branches": [[50, 51], [50, 57]], "missing_branches": []}, "save_failure_state": {"executed_lines": [62, 63, 64], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 60.0, "percent_covered_display": "60.00", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [65, 66], "excluded_lines": [], "start_line": 60, "executed_branches": [], "missing_branches": []}, "unwrap_decorated_function": {"executed_lines": [72, 73, 74], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 70, "executed_branches": [[72, 73], [72, 74]], "missing_branches": []}, "sync_test_openai_connection": {"executed_lines": [81, 82, 83, 84, 85], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 78, "executed_branches": [[83, 84], [83, 85]], "missing_branches": []}, "sync_test_azure_connection": {"executed_lines": [90, 91, 92, 93, 94], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 88, "executed_branches": [[92, 93], [92, 94]], "missing_branches": []}, "sync_test_dropbox_token": {"executed_lines": [99, 100, 101, 102, 103], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 97, "executed_branches": [[101, 102], [101, 103]], "missing_branches": []}, "sync_test_google_drive_token": {"executed_lines": [108, 109, 110, 111, 112], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 106, "executed_branches": [[110, 111], [110, 112]], "missing_branches": []}, "sync_test_onedrive_token": {"executed_lines": [117, 118, 119, 120, 121], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 115, "executed_branches": [[119, 120], [119, 121]], "missing_branches": []}, "check_credentials": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 56, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 56, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 14, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 14, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [127, 130, 133, 136, 137, 140, 174, 175, 177, 178, 179, 182, 183, 184, 185, 187, 188, 190, 192, 195, 196, 199, 201, 202, 205, 206, 210, 211, 212, 213, 214, 219, 225, 227, 230, 231, 234, 235, 237, 239, 240, 241, 242, 245, 246, 249, 250, 251, 252, 255, 258, 261, 264, 265, 268, 273], "excluded_lines": [], "start_line": 125, "executed_branches": [], "missing_branches": [[177, 178], [177, 261], [182, 183], [182, 190], [201, 202], [201, 227], [210, 211], [210, 219], [230, 231], [230, 235], [235, 177], [235, 237], [249, 250], [249, 255]]}, "": {"executed_lines": [1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 14, 15, 16, 19, 20, 24, 27, 34, 37, 41, 44, 47, 60, 70, 78, 88, 97, 106, 115, 124, 125], "summary": {"covered_lines": 31, "num_statements": 31, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"MockRequest": {"executed_lines": [28, 29, 30, 31, 32, 35, 38], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 24, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 14, 15, 16, 19, 20, 24, 27, 34, 37, 41, 44, 47, 49, 50, 51, 52, 57, 60, 62, 63, 64, 70, 72, 73, 74, 78, 81, 82, 83, 84, 85, 88, 90, 91, 92, 93, 94, 97, 99, 100, 101, 102, 103, 106, 108, 109, 110, 111, 112, 115, 117, 118, 119, 120, 121, 124, 125], "summary": {"covered_lines": 67, "num_statements": 127, "percent_covered": 52.25806451612903, "percent_covered_display": "52.26", "missing_lines": 60, "excluded_lines": 0, "percent_statements_covered": 52.75590551181102, "percent_statements_covered_display": "52.76", "num_branches": 28, "num_partial_branches": 0, "covered_branches": 14, "missing_branches": 14, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [53, 54, 65, 66, 127, 130, 133, 136, 137, 140, 174, 175, 177, 178, 179, 182, 183, 184, 185, 187, 188, 190, 192, 195, 196, 199, 201, 202, 205, 206, 210, 211, 212, 213, 214, 219, 225, 227, 230, 231, 234, 235, 237, 239, 240, 241, 242, 245, 246, 249, 250, 251, 252, 255, 258, 261, 264, 265, 268, 273], "excluded_lines": [], "start_line": 1, "executed_branches": [[50, 51], [50, 57], [72, 73], [72, 74], [83, 84], [83, 85], [92, 93], [92, 94], [101, 102], [101, 103], [110, 111], [110, 112], [119, 120], [119, 121]], "missing_branches": [[177, 178], [177, 261], [182, 183], [182, 190], [201, 202], [201, 227], [210, 211], [210, 219], [230, 231], [230, 235], [235, 177], [235, 237], [249, 250], [249, 255]]}}}, "app/tasks/convert_to_pdf.py": {"executed_lines": [2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 14, 16, 19, 29, 30, 31, 32, 33, 34, 36, 37, 38, 40, 43, 54, 55, 56, 58, 59, 60, 61, 63, 66, 78, 79, 80, 82, 83, 84, 85, 87, 88, 90, 91, 92, 93, 94, 95, 97, 98, 101, 104, 116, 117, 119, 120, 121, 123, 126, 127, 137, 138, 139, 141, 142, 143, 144, 145, 148, 149, 150, 151, 152, 163, 164, 165, 168, 169, 170, 173, 205, 207, 210, 217, 218, 221, 230, 231, 234, 237, 250, 252, 256, 257, 277, 278, 279, 281, 282, 287, 297, 298, 306, 311, 312, 313, 316, 318, 320, 321, 322, 324, 325, 326, 331, 333, 334, 335, 339, 341, 342, 347, 348, 349, 350, 351, 352, 353], "summary": {"covered_lines": 128, "num_statements": 136, "percent_covered": 90.55555555555556, "percent_covered_display": "90.56", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 94.11764705882354, "percent_statements_covered_display": "94.12", "num_branches": 44, "num_partial_branches": 9, "covered_branches": 35, "missing_branches": 9, "percent_branches_covered": 79.54545454545455, "percent_branches_covered_display": "79.55"}, "missing_lines": [99, 302, 303, 304, 307, 308, 309, 337], "excluded_lines": [], "executed_branches": [[31, 32], [37, 38], [37, 40], [55, 56], [55, 58], [58, 59], [58, 63], [60, 61], [79, 80], [79, 82], [82, 83], [82, 87], [84, 85], [87, 88], [87, 90], [92, 93], [98, 101], [116, 117], [116, 119], [120, 121], [120, 123], [142, 143], [142, 148], [151, 152], [151, 165], [210, 217], [210, 230], [230, 231], [230, 250], [250, 252], [297, 298], [306, 311], [318, 320], [318, 341], [331, 333]], "missing_branches": [[31, 36], [60, 63], [84, 87], [92, 97], [98, 99], [250, 302], [297, 306], [306, 307], [331, 337]], "functions": {"_detect_mime_type_from_magic": {"executed_lines": [29, 30, 31, 32, 33, 34, 36, 37, 38, 40], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 92.85714285714286, "percent_covered_display": "92.86", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 19, "executed_branches": [[31, 32], [37, 38], [37, 40]], "missing_branches": [[31, 36]]}, "_detect_mime_type": {"executed_lines": [54, 55, 56, 58, 59, 60, 61, 63], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 92.85714285714286, "percent_covered_display": "92.86", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [], "excluded_lines": [], "start_line": 43, "executed_branches": [[55, 56], [55, 58], [58, 59], [58, 63], [60, 61]], "missing_branches": [[60, 63]]}, "_detect_extension": {"executed_lines": [78, 79, 80, 82, 83, 84, 85, 87, 88, 90, 91, 92, 93, 94, 95, 97, 98, 101], "summary": {"covered_lines": 18, "num_statements": 19, "percent_covered": 87.09677419354838, "percent_covered_display": "87.10", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 94.73684210526316, "percent_statements_covered_display": "94.74", "num_branches": 12, "num_partial_branches": 3, "covered_branches": 9, "missing_branches": 3, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [99], "excluded_lines": [], "start_line": 66, "executed_branches": [[79, 80], [79, 82], [82, 83], [82, 87], [84, 85], [87, 88], [87, 90], [92, 93], [98, 101]], "missing_branches": [[84, 87], [92, 97], [98, 99]]}, "_build_filename": {"executed_lines": [116, 117, 119, 120, 121, 123], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 104, "executed_branches": [[116, 117], [116, 119], [120, 121], [120, 123]], "missing_branches": []}, "convert_to_pdf": {"executed_lines": [137, 138, 139, 141, 142, 143, 144, 145, 148, 149, 150, 151, 152, 163, 164, 165, 168, 169, 170, 173, 205, 207, 210, 217, 218, 221, 230, 231, 234, 237, 250, 252, 256, 257, 277, 278, 279, 281, 282, 287, 297, 298, 306, 311, 312, 313, 316, 318, 320, 321, 322, 324, 325, 326, 331, 333, 334, 335, 339, 341, 342, 347, 348, 349, 350, 351, 352, 353], "summary": {"covered_lines": 68, "num_statements": 75, "percent_covered": 88.17204301075269, "percent_covered_display": "88.17", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 90.66666666666667, "percent_statements_covered_display": "90.67", "num_branches": 18, "num_partial_branches": 4, "covered_branches": 14, "missing_branches": 4, "percent_branches_covered": 77.77777777777777, "percent_branches_covered_display": "77.78"}, "missing_lines": [302, 303, 304, 307, 308, 309, 337], "excluded_lines": [], "start_line": 127, "executed_branches": [[142, 143], [142, 148], [151, 152], [151, 165], [210, 217], [210, 230], [230, 231], [230, 250], [250, 252], [297, 298], [306, 311], [318, 320], [318, 341], [331, 333]], "missing_branches": [[250, 302], [297, 306], [306, 307], [331, 337]]}, "": {"executed_lines": [2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 14, 16, 19, 43, 66, 104, 126, 127], "summary": {"covered_lines": 18, "num_statements": 18, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 14, 16, 19, 29, 30, 31, 32, 33, 34, 36, 37, 38, 40, 43, 54, 55, 56, 58, 59, 60, 61, 63, 66, 78, 79, 80, 82, 83, 84, 85, 87, 88, 90, 91, 92, 93, 94, 95, 97, 98, 101, 104, 116, 117, 119, 120, 121, 123, 126, 127, 137, 138, 139, 141, 142, 143, 144, 145, 148, 149, 150, 151, 152, 163, 164, 165, 168, 169, 170, 173, 205, 207, 210, 217, 218, 221, 230, 231, 234, 237, 250, 252, 256, 257, 277, 278, 279, 281, 282, 287, 297, 298, 306, 311, 312, 313, 316, 318, 320, 321, 322, 324, 325, 326, 331, 333, 334, 335, 339, 341, 342, 347, 348, 349, 350, 351, 352, 353], "summary": {"covered_lines": 128, "num_statements": 136, "percent_covered": 90.55555555555556, "percent_covered_display": "90.56", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 94.11764705882354, "percent_statements_covered_display": "94.12", "num_branches": 44, "num_partial_branches": 9, "covered_branches": 35, "missing_branches": 9, "percent_branches_covered": 79.54545454545455, "percent_branches_covered_display": "79.55"}, "missing_lines": [99, 302, 303, 304, 307, 308, 309, 337], "excluded_lines": [], "start_line": 1, "executed_branches": [[31, 32], [37, 38], [37, 40], [55, 56], [55, 58], [58, 59], [58, 63], [60, 61], [79, 80], [79, 82], [82, 83], [82, 87], [84, 85], [87, 88], [87, 90], [92, 93], [98, 101], [116, 117], [116, 119], [120, 121], [120, 123], [142, 143], [142, 148], [151, 152], [151, 165], [210, 217], [210, 230], [230, 231], [230, 250], [250, 252], [297, 298], [306, 311], [318, 320], [318, 341], [331, 333]], "missing_branches": [[31, 36], [60, 63], [84, 87], [92, 97], [98, 99], [250, 302], [297, 306], [306, 307], [331, 337]]}}}, "app/tasks/embed_metadata_into_pdf.py": {"executed_lines": [3, 4, 5, 6, 7, 8, 10, 13, 14, 15, 16, 17, 18, 19, 20, 22, 29, 30, 33, 50, 51, 54, 55, 56, 57, 58, 60, 61, 62, 65, 66, 80, 81, 82, 91, 98, 119, 121, 122, 123, 124, 127, 129, 130, 131, 134, 135, 136, 139, 143, 153, 154, 156, 157, 161, 163, 165, 167, 168, 170, 172, 173, 181, 183, 185, 190, 191, 192, 193, 194, 195, 197, 198, 199, 203, 204, 205, 250, 251, 252, 264, 265, 266, 267, 270], "summary": {"covered_lines": 85, "num_statements": 117, "percent_covered": 68.79432624113475, "percent_covered_display": "68.79", "missing_lines": 32, "excluded_lines": 0, "percent_statements_covered": 72.64957264957265, "percent_statements_covered_display": "72.65", "num_branches": 24, "num_partial_branches": 6, "covered_branches": 12, "missing_branches": 12, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [92, 93, 94, 95, 99, 100, 101, 103, 104, 116, 140, 184, 208, 209, 214, 215, 229, 233, 234, 235, 236, 239, 240, 241, 242, 243, 244, 245, 246, 248, 268, 269], "excluded_lines": [], "executed_branches": [[55, 56], [55, 57], [57, 58], [57, 60], [91, 98], [98, 119], [139, 143], [183, 185], [192, 193], [194, 195], [264, 265], [264, 270]], "missing_branches": [[91, 92], [94, 95], [94, 98], [98, 99], [100, 101], [100, 103], [139, 140], [183, 184], [192, 203], [194, 203], [239, 240], [239, 248]], "functions": {"persist_metadata": {"executed_lines": [50, 51, 54, 55, 56, 57, 58, 60, 61, 62], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 33, "executed_branches": [[55, 56], [55, 57], [57, 58], [57, 60]], "missing_branches": []}, "embed_metadata_into_pdf": {"executed_lines": [80, 81, 82, 91, 98, 119, 121, 122, 123, 124, 127, 129, 130, 131, 134, 135, 136, 139, 143, 153, 154, 156, 157, 161, 163, 165, 167, 168, 170, 172, 173, 181, 183, 185, 190, 191, 192, 193, 194, 195, 197, 198, 199, 203, 204, 205, 250, 251, 252, 264, 265, 266, 267, 270], "summary": {"covered_lines": 54, "num_statements": 86, "percent_covered": 58.490566037735846, "percent_covered_display": "58.49", "missing_lines": 32, "excluded_lines": 0, "percent_statements_covered": 62.7906976744186, "percent_statements_covered_display": "62.79", "num_branches": 20, "num_partial_branches": 6, "covered_branches": 8, "missing_branches": 12, "percent_branches_covered": 40.0, "percent_branches_covered_display": "40.00"}, "missing_lines": [92, 93, 94, 95, 99, 100, 101, 103, 104, 116, 140, 184, 208, 209, 214, 215, 229, 233, 234, 235, 236, 239, 240, 241, 242, 243, 244, 245, 246, 248, 268, 269], "excluded_lines": [], "start_line": 66, "executed_branches": [[91, 98], [98, 119], [139, 143], [183, 185], [192, 193], [194, 195], [264, 265], [264, 270]], "missing_branches": [[91, 92], [94, 95], [94, 98], [98, 99], [100, 101], [100, 103], [139, 140], [183, 184], [192, 203], [194, 203], [239, 240], [239, 248]]}, "": {"executed_lines": [3, 4, 5, 6, 7, 8, 10, 13, 14, 15, 16, 17, 18, 19, 20, 22, 29, 30, 33, 65, 66], "summary": {"covered_lines": 21, "num_statements": 21, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 5, 6, 7, 8, 10, 13, 14, 15, 16, 17, 18, 19, 20, 22, 29, 30, 33, 50, 51, 54, 55, 56, 57, 58, 60, 61, 62, 65, 66, 80, 81, 82, 91, 98, 119, 121, 122, 123, 124, 127, 129, 130, 131, 134, 135, 136, 139, 143, 153, 154, 156, 157, 161, 163, 165, 167, 168, 170, 172, 173, 181, 183, 185, 190, 191, 192, 193, 194, 195, 197, 198, 199, 203, 204, 205, 250, 251, 252, 264, 265, 266, 267, 270], "summary": {"covered_lines": 85, "num_statements": 117, "percent_covered": 68.79432624113475, "percent_covered_display": "68.79", "missing_lines": 32, "excluded_lines": 0, "percent_statements_covered": 72.64957264957265, "percent_statements_covered_display": "72.65", "num_branches": 24, "num_partial_branches": 6, "covered_branches": 12, "missing_branches": 12, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [92, 93, 94, 95, 99, 100, 101, 103, 104, 116, 140, 184, 208, 209, 214, 215, 229, 233, 234, 235, 236, 239, 240, 241, 242, 243, 244, 245, 246, 248, 268, 269], "excluded_lines": [], "start_line": 1, "executed_branches": [[55, 56], [55, 57], [57, 58], [57, 60], [91, 98], [98, 119], [139, 143], [183, 185], [192, 193], [194, 195], [264, 265], [264, 270]], "missing_branches": [[91, 92], [94, 95], [94, 98], [98, 99], [100, 101], [100, 103], [139, 140], [183, 184], [192, 203], [194, 203], [239, 240], [239, 248]]}}}, "app/tasks/extract_metadata_with_gpt.py": {"executed_lines": [3, 4, 5, 6, 8, 11, 12, 13, 14, 15, 16, 17, 19, 22, 23, 24, 30, 36, 37, 38, 39, 41, 42, 43, 44, 45, 48, 49], "summary": {"covered_lines": 28, "num_statements": 71, "percent_covered": 36.7816091954023, "percent_covered_display": "36.78", "missing_lines": 43, "excluded_lines": 0, "percent_statements_covered": 39.436619718309856, "percent_statements_covered_display": "39.44", "num_branches": 16, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 12, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [25, 26, 27, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64, 65, 67, 100, 101, 102, 103, 112, 113, 114, 123, 124, 125, 126, 134, 136, 141, 142, 149, 150, 152, 154, 155, 166, 167, 170, 172, 174, 175, 176, 184], "excluded_lines": [], "executed_branches": [[38, 39], [38, 41], [43, 44], [43, 45]], "missing_branches": [[58, 59], [58, 67], [61, 62], [61, 67], [64, 65], [64, 67], [124, 125], [124, 136], [142, 149], [142, 154], [149, 150], [149, 154]], "functions": {"extract_json_from_text": {"executed_lines": [36, 37, 38, 39, 41, 42, 43, 44, 45], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 30, "executed_branches": [[38, 39], [38, 41], [43, 44], [43, 45]], "missing_branches": []}, "extract_metadata_with_gpt": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 40, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 40, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 12, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [51, 52, 53, 58, 59, 60, 61, 62, 63, 64, 65, 67, 100, 101, 102, 103, 112, 113, 114, 123, 124, 125, 126, 134, 136, 141, 142, 149, 150, 152, 154, 155, 166, 167, 170, 172, 174, 175, 176, 184], "excluded_lines": [], "start_line": 49, "executed_branches": [], "missing_branches": [[58, 59], [58, 67], [61, 62], [61, 67], [64, 65], [64, 67], [124, 125], [124, 136], [142, 149], [142, 154], [149, 150], [149, 154]]}, "": {"executed_lines": [3, 4, 5, 6, 8, 11, 12, 13, 14, 15, 16, 17, 19, 22, 23, 24, 30, 48, 49], "summary": {"covered_lines": 19, "num_statements": 22, "percent_covered": 86.36363636363636, "percent_covered_display": "86.36", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 86.36363636363636, "percent_statements_covered_display": "86.36", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [25, 26, 27], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 5, 6, 8, 11, 12, 13, 14, 15, 16, 17, 19, 22, 23, 24, 30, 36, 37, 38, 39, 41, 42, 43, 44, 45, 48, 49], "summary": {"covered_lines": 28, "num_statements": 71, "percent_covered": 36.7816091954023, "percent_covered_display": "36.78", "missing_lines": 43, "excluded_lines": 0, "percent_statements_covered": 39.436619718309856, "percent_statements_covered_display": "39.44", "num_branches": 16, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 12, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [25, 26, 27, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64, 65, 67, 100, 101, 102, 103, 112, 113, 114, 123, 124, 125, 126, 134, 136, 141, 142, 149, 150, 152, 154, 155, 166, 167, 170, 172, 174, 175, 176, 184], "excluded_lines": [], "start_line": 1, "executed_branches": [[38, 39], [38, 41], [43, 44], [43, 45]], "missing_branches": [[58, 59], [58, 67], [61, 62], [61, 67], [64, 65], [64, 67], [124, 125], [124, 136], [142, 149], [142, 154], [149, 150], [149, 154]]}}}, "app/tasks/finalize_document_storage.py": {"executed_lines": [3, 4, 7, 8, 9, 10, 11, 14, 17, 20, 22, 25, 26], "summary": {"covered_lines": 13, "num_statements": 42, "percent_covered": 26.0, "percent_covered_display": "26.00", "missing_lines": 29, "excluded_lines": 0, "percent_statements_covered": 30.952380952380953, "percent_statements_covered_display": "30.95", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [32, 33, 36, 45, 46, 48, 49, 50, 51, 55, 56, 57, 59, 60, 62, 63, 64, 65, 66, 70, 71, 77, 82, 84, 85, 87, 90, 91, 93], "excluded_lines": [], "executed_branches": [], "missing_branches": [[45, 46], [45, 55], [50, 51], [50, 55], [59, 60], [59, 70], [60, 59], [60, 62]], "functions": {"finalize_document_storage": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 29, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 29, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [32, 33, 36, 45, 46, 48, 49, 50, 51, 55, 56, 57, 59, 60, 62, 63, 64, 65, 66, 70, 71, 77, 82, 84, 85, 87, 90, 91, 93], "excluded_lines": [], "start_line": 26, "executed_branches": [], "missing_branches": [[45, 46], [45, 55], [50, 51], [50, 55], [59, 60], [59, 70], [60, 59], [60, 62]]}, "": {"executed_lines": [3, 4, 7, 8, 9, 10, 11, 14, 17, 20, 22, 25, 26], "summary": {"covered_lines": 13, "num_statements": 13, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 7, 8, 9, 10, 11, 14, 17, 20, 22, 25, 26], "summary": {"covered_lines": 13, "num_statements": 42, "percent_covered": 26.0, "percent_covered_display": "26.00", "missing_lines": 29, "excluded_lines": 0, "percent_statements_covered": 30.952380952380953, "percent_statements_covered_display": "30.95", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [32, 33, 36, 45, 46, 48, 49, 50, 51, 55, 56, 57, 59, 60, 62, 63, 64, 65, 66, 70, 71, 77, 82, 84, 85, 87, 90, 91, 93], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": [[45, 46], [45, 55], [50, 51], [50, 55], [59, 60], [59, 70], [60, 59], [60, 62]]}}}, "app/tasks/imap_tasks.py": {"executed_lines": [2, 3, 4, 5, 6, 7, 8, 10, 11, 13, 14, 15, 17, 20, 22, 23, 26, 29, 40, 46, 48, 49, 50, 51, 52, 53, 57, 60, 62, 63, 66, 68, 69, 70, 71, 72, 73, 74, 75, 78, 79, 120, 130, 131, 132, 134, 135, 146, 244, 271, 285, 286, 287, 288, 290, 291, 292, 295, 297, 299, 300, 301, 303, 304, 305, 308, 309, 310, 311, 313, 314, 316, 317, 320, 325, 327, 330, 331, 332, 333, 334, 335, 336, 337, 340, 342, 343, 344, 345, 346, 349, 351, 352, 353, 354, 355, 358, 364, 371, 372, 373, 374, 376, 377, 381, 384, 386, 387, 388, 389, 390, 393, 398, 399, 400, 402, 403, 404, 405, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416], "summary": {"covered_lines": 129, "num_statements": 215, "percent_covered": 57.491289198606275, "percent_covered_display": "57.49", "missing_lines": 86, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 72, "num_partial_branches": 6, "covered_branches": 36, "missing_branches": 36, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [31, 32, 33, 34, 35, 36, 37, 42, 43, 54, 55, 56, 85, 86, 87, 89, 90, 93, 104, 114, 117, 157, 158, 160, 161, 162, 164, 165, 167, 168, 169, 170, 172, 173, 175, 176, 179, 180, 181, 183, 184, 185, 186, 187, 189, 190, 192, 193, 194, 195, 196, 198, 199, 200, 202, 203, 204, 206, 207, 208, 211, 212, 213, 214, 218, 220, 221, 222, 224, 225, 227, 228, 229, 231, 233, 234, 236, 237, 238, 240, 241, 328, 378, 379, 380, 406], "excluded_lines": [], "executed_branches": [[48, 49], [48, 57], [70, 71], [70, 75], [73, 70], [73, 74], [130, 131], [130, 134], [286, 287], [286, 317], [287, 288], [287, 290], [291, 292], [291, 295], [299, 300], [299, 303], [308, 309], [308, 311], [311, 313], [327, 330], [331, 332], [333, 334], [333, 337], [371, 372], [371, 376], [373, 371], [373, 374], [377, 381], [387, 388], [387, 390], [405, 407], [408, 409], [408, 414], [410, 411], [414, 403], [414, 415]], "missing_branches": [[32, 33], [32, 36], [85, 86], [85, 89], [165, 167], [165, 179], [168, 169], [168, 172], [183, 184], [183, 189], [192, 193], [192, 233], [194, 195], [194, 198], [202, 203], [202, 206], [206, 207], [206, 211], [211, 212], [211, 218], [212, 213], [212, 218], [220, 221], [220, 224], [227, 228], [227, 231], [233, 234], [233, 236], [311, 316], [327, 328], [331, 337], [377, 378], [379, 380], [379, 381], [405, 406], [410, 414]], "functions": {"acquire_lock": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [31, 32, 33, 34, 35, 36, 37], "excluded_lines": [], "start_line": 29, "executed_branches": [], "missing_branches": [[32, 33], [32, 36]]}, "release_lock": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [42, 43], "excluded_lines": [], "start_line": 40, "executed_branches": [], "missing_branches": []}, "load_processed_emails": {"executed_lines": [48, 49, 50, 51, 52, 53, 57], "summary": {"covered_lines": 7, "num_statements": 10, "percent_covered": 75.0, "percent_covered_display": "75.00", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 70.0, "percent_statements_covered_display": "70.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [54, 55, 56], "excluded_lines": [], "start_line": 46, "executed_branches": [[48, 49], [48, 57]], "missing_branches": []}, "save_processed_emails": {"executed_lines": [62, 63], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 60, "executed_branches": [], "missing_branches": []}, "cleanup_old_entries": {"executed_lines": [68, 69, 70, 71, 72, 73, 74, 75], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 66, "executed_branches": [[70, 71], [70, 75], [73, 70], [73, 74]], "missing_branches": []}, "pull_all_inboxes": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 9, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [85, 86, 87, 89, 90, 93, 104, 114, 117], "excluded_lines": [], "start_line": 79, "executed_branches": [], "missing_branches": [[85, 86], [85, 89]]}, "check_and_pull_mailbox": {"executed_lines": [130, 131, 132, 134, 135], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 120, "executed_branches": [[130, 131], [130, 134]], "missing_branches": []}, "pull_inbox": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 60, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 60, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 24, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 24, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [157, 158, 160, 161, 162, 164, 165, 167, 168, 169, 170, 172, 173, 175, 176, 179, 180, 181, 183, 184, 185, 186, 187, 189, 190, 192, 193, 194, 195, 196, 198, 199, 200, 202, 203, 204, 206, 207, 208, 211, 212, 213, 214, 218, 220, 221, 222, 224, 225, 227, 228, 229, 231, 233, 234, 236, 237, 238, 240, 241], "excluded_lines": [], "start_line": 146, "executed_branches": [], "missing_branches": [[165, 167], [165, 179], [168, 169], [168, 172], [183, 184], [183, 189], [192, 193], [192, 233], [194, 195], [194, 198], [202, 203], [202, 206], [206, 207], [206, 211], [211, 212], [211, 218], [212, 213], [212, 218], [220, 221], [220, 224], [227, 228], [227, 231], [233, 234], [233, 236]]}, "fetch_attachments_and_enqueue": {"executed_lines": [271, 285, 286, 287, 288, 290, 291, 292, 295, 297, 299, 300, 301, 303, 304, 305, 308, 309, 310, 311, 313, 314, 316, 317], "summary": {"covered_lines": 24, "num_statements": 24, "percent_covered": 97.22222222222223, "percent_covered_display": "97.22", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 12, "num_partial_branches": 1, "covered_branches": 11, "missing_branches": 1, "percent_branches_covered": 91.66666666666667, "percent_branches_covered_display": "91.67"}, "missing_lines": [], "excluded_lines": [], "start_line": 244, "executed_branches": [[286, 287], [286, 317], [287, 288], [287, 290], [291, 292], [291, 295], [299, 300], [299, 303], [308, 309], [308, 311], [311, 313]], "missing_branches": [[311, 316]]}, "email_already_has_label": {"executed_lines": [325, 327, 330, 331, 332, 333, 334, 335, 336, 337], "summary": {"covered_lines": 10, "num_statements": 11, "percent_covered": 82.3529411764706, "percent_covered_display": "82.35", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.9090909090909, "percent_statements_covered_display": "90.91", "num_branches": 6, "num_partial_branches": 2, "covered_branches": 4, "missing_branches": 2, "percent_branches_covered": 66.66666666666667, "percent_branches_covered_display": "66.67"}, "missing_lines": [328], "excluded_lines": [], "start_line": 320, "executed_branches": [[327, 330], [331, 332], [333, 334], [333, 337]], "missing_branches": [[327, 328], [331, 337]]}, "mark_as_processed_with_star": {"executed_lines": [342, 343, 344, 345, 346], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 340, "executed_branches": [], "missing_branches": []}, "mark_as_processed_with_label": {"executed_lines": [351, 352, 353, 354, 355], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 349, "executed_branches": [], "missing_branches": []}, "find_all_mail_folder": {"executed_lines": [364, 371, 372, 373, 374, 376, 377, 381], "summary": {"covered_lines": 8, "num_statements": 11, "percent_covered": 68.42105263157895, "percent_covered_display": "68.42", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 72.72727272727273, "percent_statements_covered_display": "72.73", "num_branches": 8, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 3, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62.50"}, "missing_lines": [378, 379, 380], "excluded_lines": [], "start_line": 358, "executed_branches": [[371, 372], [371, 376], [373, 371], [373, 374], [377, 381]], "missing_branches": [[377, 378], [379, 380], [379, 381]]}, "get_capabilities": {"executed_lines": [386, 387, 388, 389, 390], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 384, "executed_branches": [[387, 388], [387, 390]], "missing_branches": []}, "find_all_mail_xlist": {"executed_lines": [398, 399, 400, 402, 403, 404, 405, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416], "summary": {"covered_lines": 17, "num_statements": 18, "percent_covered": 88.46153846153847, "percent_covered_display": "88.46", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 94.44444444444444, "percent_statements_covered_display": "94.44", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 6, "missing_branches": 2, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [406], "excluded_lines": [], "start_line": 393, "executed_branches": [[405, 407], [408, 409], [408, 414], [410, 411], [414, 403], [414, 415]], "missing_branches": [[405, 406], [410, 414]]}, "": {"executed_lines": [2, 3, 4, 5, 6, 7, 8, 10, 11, 13, 14, 15, 17, 20, 22, 23, 26, 29, 40, 46, 60, 66, 78, 79, 120, 146, 244, 320, 340, 349, 358, 384, 393], "summary": {"covered_lines": 33, "num_statements": 33, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [2, 3, 4, 5, 6, 7, 8, 10, 11, 13, 14, 15, 17, 20, 22, 23, 26, 29, 40, 46, 48, 49, 50, 51, 52, 53, 57, 60, 62, 63, 66, 68, 69, 70, 71, 72, 73, 74, 75, 78, 79, 120, 130, 131, 132, 134, 135, 146, 244, 271, 285, 286, 287, 288, 290, 291, 292, 295, 297, 299, 300, 301, 303, 304, 305, 308, 309, 310, 311, 313, 314, 316, 317, 320, 325, 327, 330, 331, 332, 333, 334, 335, 336, 337, 340, 342, 343, 344, 345, 346, 349, 351, 352, 353, 354, 355, 358, 364, 371, 372, 373, 374, 376, 377, 381, 384, 386, 387, 388, 389, 390, 393, 398, 399, 400, 402, 403, 404, 405, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416], "summary": {"covered_lines": 129, "num_statements": 215, "percent_covered": 57.491289198606275, "percent_covered_display": "57.49", "missing_lines": 86, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 72, "num_partial_branches": 6, "covered_branches": 36, "missing_branches": 36, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [31, 32, 33, 34, 35, 36, 37, 42, 43, 54, 55, 56, 85, 86, 87, 89, 90, 93, 104, 114, 117, 157, 158, 160, 161, 162, 164, 165, 167, 168, 169, 170, 172, 173, 175, 176, 179, 180, 181, 183, 184, 185, 186, 187, 189, 190, 192, 193, 194, 195, 196, 198, 199, 200, 202, 203, 204, 206, 207, 208, 211, 212, 213, 214, 218, 220, 221, 222, 224, 225, 227, 228, 229, 231, 233, 234, 236, 237, 238, 240, 241, 328, 378, 379, 380, 406], "excluded_lines": [], "start_line": 1, "executed_branches": [[48, 49], [48, 57], [70, 71], [70, 75], [73, 70], [73, 74], [130, 131], [130, 134], [286, 287], [286, 317], [287, 288], [287, 290], [291, 292], [291, 295], [299, 300], [299, 303], [308, 309], [308, 311], [311, 313], [327, 330], [331, 332], [333, 334], [333, 337], [371, 372], [371, 376], [373, 371], [373, 374], [377, 381], [387, 388], [387, 390], [405, 407], [408, 409], [408, 414], [410, 411], [414, 403], [414, 415]], "missing_branches": [[32, 33], [32, 36], [85, 86], [85, 89], [165, 167], [165, 179], [168, 169], [168, 172], [183, 184], [183, 189], [192, 193], [192, 233], [194, 195], [194, 198], [202, 203], [202, 206], [206, 207], [206, 211], [211, 212], [211, 218], [212, 213], [212, 218], [220, 221], [220, 224], [227, 228], [227, 231], [233, 234], [233, 236], [311, 316], [327, 328], [331, 337], [377, 378], [379, 380], [379, 381], [405, 406], [410, 414]]}}}, "app/tasks/monitor_stalled_steps.py": {"executed_lines": [8, 9, 11, 12, 13, 15, 18, 19, 34, 35, 36, 38, 39, 45, 47, 49, 50, 51], "summary": {"covered_lines": 18, "num_statements": 18, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[38, 39], [38, 45]], "missing_branches": [], "functions": {"monitor_stalled_steps": {"executed_lines": [34, 35, 36, 38, 39, 45, 47, 49, 50, 51], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 19, "executed_branches": [[38, 39], [38, 45]], "missing_branches": []}, "": {"executed_lines": [8, 9, 11, 12, 13, 15, 18, 19], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [8, 9, 11, 12, 13, 15, 18, 19, 34, 35, 36, 38, 39, 45, 47, 49, 50, 51], "summary": {"covered_lines": 18, "num_statements": 18, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[38, 39], [38, 45]], "missing_branches": []}}}, "app/tasks/process_document.py": {"executed_lines": [3, 4, 5, 6, 7, 9, 10, 12, 13, 14, 15, 16, 17, 20, 21, 23, 26, 27, 51, 52, 53, 60, 72, 73, 74, 75, 81, 82, 83, 84, 85, 88, 91, 92, 100, 103, 104, 105, 106, 107, 108, 109, 110, 117, 121, 127, 128, 134, 135, 136, 145, 146, 147, 149, 150, 164, 177, 185, 186, 187, 193, 194, 202, 203, 204, 205, 206, 215, 216, 217, 221, 223, 224, 227, 228, 230, 231, 238, 239, 248, 251, 252, 261, 262, 263, 265, 266, 274, 275, 284, 285, 288, 292, 293, 294, 302, 309, 316, 317, 320, 321, 343, 344, 351, 352, 353, 354, 355, 356, 357, 358, 380, 381, 382, 391, 392, 399, 400, 401, 402, 403, 405, 406, 415, 424, 425, 432, 433, 440, 441, 450, 458, 465, 466], "summary": {"covered_lines": 134, "num_statements": 149, "percent_covered": 88.10810810810811, "percent_covered_display": "88.11", "missing_lines": 15, "excluded_lines": 0, "percent_statements_covered": 89.93288590604027, "percent_statements_covered_display": "89.93", "num_branches": 36, "num_partial_branches": 7, "covered_branches": 29, "missing_branches": 7, "percent_branches_covered": 80.55555555555556, "percent_branches_covered_display": "80.56"}, "missing_lines": [61, 62, 69, 77, 78, 86, 322, 323, 330, 337, 341, 359, 360, 361, 369], "excluded_lines": [], "executed_branches": [[60, 72], [72, 73], [81, 82], [81, 83], [85, 88], [91, 92], [103, 104], [103, 121], [105, 106], [105, 109], [127, 128], [127, 134], [134, 135], [134, 185], [149, 150], [186, 187], [221, 223], [221, 251], [292, 293], [292, 320], [321, 343], [355, 356], [355, 380], [356, 355], [356, 357], [380, 381], [380, 440], [402, 403], [402, 405]], "missing_branches": [[60, 61], [72, 77], [85, 86], [91, 100], [149, 164], [186, 193], [321, 322]], "functions": {"process_document": {"executed_lines": [51, 52, 53, 60, 72, 73, 74, 75, 81, 82, 83, 84, 85, 88, 91, 92, 100, 103, 104, 105, 106, 107, 108, 109, 110, 117, 121, 127, 128, 134, 135, 136, 145, 146, 147, 149, 150, 164, 177, 185, 186, 187, 193, 194, 202, 203, 204, 205, 206, 215, 216, 217, 221, 223, 224, 227, 228, 230, 231, 238, 239, 248, 251, 252, 261, 262, 263, 265, 266, 274, 275, 284, 285, 288, 292, 293, 294, 302, 309, 316, 317, 320, 321, 343, 344, 351, 352, 353, 354, 355, 356, 357, 358, 380, 381, 382, 391, 392, 399, 400, 401, 402, 403, 405, 406, 415, 424, 425, 432, 433, 440, 441, 450, 458, 465, 466], "summary": {"covered_lines": 116, "num_statements": 131, "percent_covered": 86.82634730538922, "percent_covered_display": "86.83", "missing_lines": 15, "excluded_lines": 0, "percent_statements_covered": 88.54961832061069, "percent_statements_covered_display": "88.55", "num_branches": 36, "num_partial_branches": 7, "covered_branches": 29, "missing_branches": 7, "percent_branches_covered": 80.55555555555556, "percent_branches_covered_display": "80.56"}, "missing_lines": [61, 62, 69, 77, 78, 86, 322, 323, 330, 337, 341, 359, 360, 361, 369], "excluded_lines": [], "start_line": 27, "executed_branches": [[60, 72], [72, 73], [81, 82], [81, 83], [85, 88], [91, 92], [103, 104], [103, 121], [105, 106], [105, 109], [127, 128], [127, 134], [134, 135], [134, 185], [149, 150], [186, 187], [221, 223], [221, 251], [292, 293], [292, 320], [321, 343], [355, 356], [355, 380], [356, 355], [356, 357], [380, 381], [380, 440], [402, 403], [402, 405]], "missing_branches": [[60, 61], [72, 77], [85, 86], [91, 100], [149, 164], [186, 193], [321, 322]]}, "": {"executed_lines": [3, 4, 5, 6, 7, 9, 10, 12, 13, 14, 15, 16, 17, 20, 21, 23, 26, 27], "summary": {"covered_lines": 18, "num_statements": 18, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 5, 6, 7, 9, 10, 12, 13, 14, 15, 16, 17, 20, 21, 23, 26, 27, 51, 52, 53, 60, 72, 73, 74, 75, 81, 82, 83, 84, 85, 88, 91, 92, 100, 103, 104, 105, 106, 107, 108, 109, 110, 117, 121, 127, 128, 134, 135, 136, 145, 146, 147, 149, 150, 164, 177, 185, 186, 187, 193, 194, 202, 203, 204, 205, 206, 215, 216, 217, 221, 223, 224, 227, 228, 230, 231, 238, 239, 248, 251, 252, 261, 262, 263, 265, 266, 274, 275, 284, 285, 288, 292, 293, 294, 302, 309, 316, 317, 320, 321, 343, 344, 351, 352, 353, 354, 355, 356, 357, 358, 380, 381, 382, 391, 392, 399, 400, 401, 402, 403, 405, 406, 415, 424, 425, 432, 433, 440, 441, 450, 458, 465, 466], "summary": {"covered_lines": 134, "num_statements": 149, "percent_covered": 88.10810810810811, "percent_covered_display": "88.11", "missing_lines": 15, "excluded_lines": 0, "percent_statements_covered": 89.93288590604027, "percent_statements_covered_display": "89.93", "num_branches": 36, "num_partial_branches": 7, "covered_branches": 29, "missing_branches": 7, "percent_branches_covered": 80.55555555555556, "percent_branches_covered_display": "80.56"}, "missing_lines": [61, 62, 69, 77, 78, 86, 322, 323, 330, 337, 341, 359, 360, 361, 369], "excluded_lines": [], "start_line": 1, "executed_branches": [[60, 72], [72, 73], [81, 82], [81, 83], [85, 88], [91, 92], [103, 104], [103, 121], [105, 106], [105, 109], [127, 128], [127, 134], [134, 135], [134, 185], [149, 150], [186, 187], [221, 223], [221, 251], [292, 293], [292, 320], [321, 343], [355, 356], [355, 380], [356, 355], [356, 357], [380, 381], [380, 440], [402, 403], [402, 405]], "missing_branches": [[60, 61], [72, 77], [85, 86], [91, 100], [149, 164], [186, 193], [321, 322]]}}}, "app/tasks/process_with_azure_document_intelligence.py": {"executed_lines": [1, 2, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 16, 19, 20, 23, 32, 38, 40, 41, 42, 43, 44, 45, 46, 49, 61, 62, 63, 65, 66, 67, 69, 70, 71, 72, 73, 75, 77, 79, 81, 84, 85, 102, 103, 110, 111, 112, 113, 116, 117, 118, 121, 122, 130, 134, 135, 136, 137, 138, 139, 147, 148, 149, 153, 161, 162, 171, 172, 175, 176, 179, 182, 183, 184, 185, 186, 189, 190, 192, 202, 204, 213, 214, 215, 216, 224], "summary": {"covered_lines": 87, "num_statements": 93, "percent_covered": 93.69369369369369, "percent_covered_display": "93.69", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 93.54838709677419, "percent_statements_covered_display": "93.55", "num_branches": 18, "num_partial_branches": 1, "covered_branches": 17, "missing_branches": 1, "percent_branches_covered": 94.44444444444444, "percent_branches_covered_display": "94.44"}, "missing_lines": [24, 25, 26, 27, 28, 29], "excluded_lines": [], "executed_branches": [[65, 66], [65, 69], [69, 70], [69, 81], [70, 71], [70, 79], [72, 73], [72, 77], [112, 113], [112, 116], [117, 118], [117, 134], [134, 135], [136, 137], [136, 148], [148, 149], [148, 153]], "missing_branches": [[134, 153]], "functions": {"get_pdf_page_count": {"executed_lines": [40, 41, 42, 43, 44, 45, 46], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 38, "executed_branches": [], "missing_branches": []}, "check_page_rotation": {"executed_lines": [61, 62, 63, 65, 66, 67, 69, 70, 71, 72, 73, 75, 77, 79, 81], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 49, "executed_branches": [[65, 66], [65, 69], [69, 70], [69, 81], [70, 71], [70, 79], [72, 73], [72, 77]], "missing_branches": []}, "process_with_azure_document_intelligence": {"executed_lines": [102, 103, 110, 111, 112, 113, 116, 117, 118, 121, 122, 130, 134, 135, 136, 137, 138, 139, 147, 148, 149, 153, 161, 162, 171, 172, 175, 176, 179, 182, 183, 184, 185, 186, 189, 190, 192, 202, 204, 213, 214, 215, 216, 224], "summary": {"covered_lines": 44, "num_statements": 44, "percent_covered": 98.14814814814815, "percent_covered_display": "98.15", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 10, "num_partial_branches": 1, "covered_branches": 9, "missing_branches": 1, "percent_branches_covered": 90.0, "percent_branches_covered_display": "90.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 85, "executed_branches": [[112, 113], [112, 116], [117, 118], [117, 134], [134, 135], [136, 137], [136, 148], [148, 149], [148, 153]], "missing_branches": [[134, 153]]}, "": {"executed_lines": [1, 2, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 16, 19, 20, 23, 32, 38, 49, 84, 85], "summary": {"covered_lines": 21, "num_statements": 27, "percent_covered": 77.77777777777777, "percent_covered_display": "77.78", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 77.77777777777777, "percent_statements_covered_display": "77.78", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [24, 25, 26, 27, 28, 29], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [1, 2, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 16, 19, 20, 23, 32, 38, 40, 41, 42, 43, 44, 45, 46, 49, 61, 62, 63, 65, 66, 67, 69, 70, 71, 72, 73, 75, 77, 79, 81, 84, 85, 102, 103, 110, 111, 112, 113, 116, 117, 118, 121, 122, 130, 134, 135, 136, 137, 138, 139, 147, 148, 149, 153, 161, 162, 171, 172, 175, 176, 179, 182, 183, 184, 185, 186, 189, 190, 192, 202, 204, 213, 214, 215, 216, 224], "summary": {"covered_lines": 87, "num_statements": 93, "percent_covered": 93.69369369369369, "percent_covered_display": "93.69", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 93.54838709677419, "percent_statements_covered_display": "93.55", "num_branches": 18, "num_partial_branches": 1, "covered_branches": 17, "missing_branches": 1, "percent_branches_covered": 94.44444444444444, "percent_branches_covered_display": "94.44"}, "missing_lines": [24, 25, 26, 27, 28, 29], "excluded_lines": [], "start_line": 1, "executed_branches": [[65, 66], [65, 69], [69, 70], [69, 81], [70, 71], [70, 79], [72, 73], [72, 77], [112, 113], [112, 116], [117, 118], [117, 134], [134, 135], [136, 137], [136, 148], [148, 149], [148, 153]], "missing_branches": [[134, 153]]}}}, "app/tasks/refine_text_with_gpt.py": {"executed_lines": [3, 5, 8, 9, 10, 11, 13, 16, 19, 20, 22, 23, 24, 26, 27, 29, 43, 45, 46, 55, 57, 59, 60, 62, 63, 64, 65, 72], "summary": {"covered_lines": 28, "num_statements": 28, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"refine_text_with_gpt": {"executed_lines": [22, 23, 24, 26, 27, 29, 43, 45, 46, 55, 57, 59, 60, 62, 63, 64, 65, 72], "summary": {"covered_lines": 18, "num_statements": 18, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 20, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [3, 5, 8, 9, 10, 11, 13, 16, 19, 20], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 5, 8, 9, 10, 11, 13, 16, 19, 20, 22, 23, 24, 26, 27, 29, 43, 45, 46, 55, 57, 59, 60, 62, 63, 64, 65, 72], "summary": {"covered_lines": 28, "num_statements": 28, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/tasks/retry_config.py": {"executed_lines": [3, 6, 7, 8, 9], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [3, 6, 7, 8, 9], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"BaseTaskWithRetry": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 6, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [3, 6, 7, 8, 9], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/tasks/rotate_pdf_pages.py": {"executed_lines": [1, 2, 3, 5, 7, 8, 9, 10, 11, 13, 16, 27, 28, 32, 33, 36, 37, 39, 40, 41, 45, 47, 48, 49, 52, 53, 63, 64, 65, 72, 73, 74, 77, 78, 79, 86, 87, 90, 91, 92, 93, 97, 98, 101, 108, 109, 111, 112, 119, 122, 123, 124, 127, 128, 131, 132, 133, 135, 137, 138, 142, 149, 152, 153, 155, 156, 166, 168, 177, 184, 185, 186, 195, 196], "summary": {"covered_lines": 74, "num_statements": 79, "percent_covered": 91.2621359223301, "percent_covered_display": "91.26", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 93.67088607594937, "percent_statements_covered_display": "93.67", "num_branches": 24, "num_partial_branches": 4, "covered_branches": 20, "missing_branches": 4, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [29, 94, 95, 144, 160], "excluded_lines": [], "executed_branches": [[28, 32], [32, 33], [32, 36], [36, 37], [36, 45], [37, 36], [37, 39], [73, 74], [73, 77], [77, 78], [77, 90], [91, 92], [91, 97], [97, 98], [97, 111], [127, 128], [127, 152], [131, 132], [135, 137], [155, 156]], "missing_branches": [[28, 29], [131, 149], [135, 144], [155, 160]], "functions": {"determine_rotation_angle": {"executed_lines": [27, 28, 32, 33, 36, 37, 39, 40, 41, 45, 47, 48, 49], "summary": {"covered_lines": 13, "num_statements": 14, "percent_covered": 90.9090909090909, "percent_covered_display": "90.91", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 92.85714285714286, "percent_statements_covered_display": "92.86", "num_branches": 8, "num_partial_branches": 1, "covered_branches": 7, "missing_branches": 1, "percent_branches_covered": 87.5, "percent_branches_covered_display": "87.50"}, "missing_lines": [29], "excluded_lines": [], "start_line": 16, "executed_branches": [[28, 32], [32, 33], [32, 36], [36, 37], [36, 45], [37, 36], [37, 39]], "missing_branches": [[28, 29]]}, "rotate_pdf_pages": {"executed_lines": [63, 64, 65, 72, 73, 74, 77, 78, 79, 86, 87, 90, 91, 92, 93, 97, 98, 101, 108, 109, 111, 112, 119, 122, 123, 124, 127, 128, 131, 132, 133, 135, 137, 138, 142, 149, 152, 153, 155, 156, 166, 168, 177, 184, 185, 186, 195, 196], "summary": {"covered_lines": 48, "num_statements": 52, "percent_covered": 89.70588235294117, "percent_covered_display": "89.71", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 92.3076923076923, "percent_statements_covered_display": "92.31", "num_branches": 16, "num_partial_branches": 3, "covered_branches": 13, "missing_branches": 3, "percent_branches_covered": 81.25, "percent_branches_covered_display": "81.25"}, "missing_lines": [94, 95, 144, 160], "excluded_lines": [], "start_line": 53, "executed_branches": [[73, 74], [73, 77], [77, 78], [77, 90], [91, 92], [91, 97], [97, 98], [97, 111], [127, 128], [127, 152], [131, 132], [135, 137], [155, 156]], "missing_branches": [[131, 149], [135, 144], [155, 160]]}, "": {"executed_lines": [1, 2, 3, 5, 7, 8, 9, 10, 11, 13, 16, 52, 53], "summary": {"covered_lines": 13, "num_statements": 13, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [1, 2, 3, 5, 7, 8, 9, 10, 11, 13, 16, 27, 28, 32, 33, 36, 37, 39, 40, 41, 45, 47, 48, 49, 52, 53, 63, 64, 65, 72, 73, 74, 77, 78, 79, 86, 87, 90, 91, 92, 93, 97, 98, 101, 108, 109, 111, 112, 119, 122, 123, 124, 127, 128, 131, 132, 133, 135, 137, 138, 142, 149, 152, 153, 155, 156, 166, 168, 177, 184, 185, 186, 195, 196], "summary": {"covered_lines": 74, "num_statements": 79, "percent_covered": 91.2621359223301, "percent_covered_display": "91.26", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 93.67088607594937, "percent_statements_covered_display": "93.67", "num_branches": 24, "num_partial_branches": 4, "covered_branches": 20, "missing_branches": 4, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [29, 94, 95, 144, 160], "excluded_lines": [], "start_line": 1, "executed_branches": [[28, 32], [32, 33], [32, 36], [36, 37], [36, 45], [37, 36], [37, 39], [73, 74], [73, 77], [77, 78], [77, 90], [91, 92], [91, 97], [97, 98], [97, 111], [127, 128], [127, 152], [131, 132], [135, 137], [155, 156]], "missing_branches": [[28, 29], [131, 149], [135, 144], [155, 160]]}}}, "app/tasks/send_to_all.py": {"executed_lines": [3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 27, 28, 31, 32, 35, 36, 39, 41, 42, 53, 54, 57, 58, 61, 62, 65, 66, 71, 72, 75, 79, 108, 109, 119, 121, 126, 127, 136, 148, 151, 205, 206, 207, 208, 209, 215, 216, 217, 220, 221, 222, 223, 225, 226, 227, 233, 234, 235, 238, 239, 240, 241, 242, 245, 246, 247, 248, 250, 251, 253], "summary": {"covered_lines": 80, "num_statements": 102, "percent_covered": 73.77049180327869, "percent_covered_display": "73.77", "missing_lines": 22, "excluded_lines": 0, "percent_statements_covered": 78.43137254901961, "percent_statements_covered_display": "78.43", "num_branches": 20, "num_partial_branches": 4, "covered_branches": 10, "missing_branches": 10, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [50, 76, 85, 87, 100, 101, 102, 103, 105, 122, 123, 124, 137, 140, 145, 146, 210, 211, 212, 228, 229, 230], "excluded_lines": [], "executed_branches": [[41, 42], [121, 126], [136, 148], [206, 207], [216, 217], [216, 250], [221, 222], [221, 225], [233, 216], [233, 234]], "missing_branches": [[41, 50], [101, 102], [101, 105], [102, 101], [102, 103], [121, 122], [136, 137], [145, 146], [145, 148], [206, 215]], "functions": {"_should_upload_to_dropbox": {"executed_lines": [28], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 27, "executed_branches": [], "missing_branches": []}, "_should_upload_to_nextcloud": {"executed_lines": [32], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 31, "executed_branches": [], "missing_branches": []}, "_should_upload_to_paperless": {"executed_lines": [36], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 35, "executed_branches": [], "missing_branches": []}, "_should_upload_to_google_drive": {"executed_lines": [41, 42], "summary": {"covered_lines": 2, "num_statements": 3, "percent_covered": 60.0, "percent_covered_display": "60.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 66.66666666666667, "percent_statements_covered_display": "66.67", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [50], "excluded_lines": [], "start_line": 39, "executed_branches": [[41, 42]], "missing_branches": [[41, 50]]}, "_should_upload_to_webdav": {"executed_lines": [54], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 53, "executed_branches": [], "missing_branches": []}, "_should_upload_to_ftp": {"executed_lines": [58], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 57, "executed_branches": [], "missing_branches": []}, "_should_upload_to_sftp": {"executed_lines": [62], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 61, "executed_branches": [], "missing_branches": []}, "_should_upload_to_email": {"executed_lines": [66], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 65, "executed_branches": [], "missing_branches": []}, "_should_upload_to_onedrive": {"executed_lines": [72], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 71, "executed_branches": [], "missing_branches": []}, "_should_upload_to_s3": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [76], "excluded_lines": [], "start_line": 75, "executed_branches": [], "missing_branches": []}, "get_configured_services_from_validator": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 4, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [85, 87, 100, 101, 102, 103, 105], "excluded_lines": [], "start_line": 79, "executed_branches": [], "missing_branches": [[101, 102], [101, 105], [102, 101], [102, 103]]}, "send_to_all_destinations": {"executed_lines": [119, 121, 126, 127, 136, 148, 151, 205, 206, 207, 208, 209, 215, 216, 217, 220, 221, 222, 223, 225, 226, 227, 233, 234, 235, 238, 239, 240, 241, 242, 245, 246, 247, 248, 250, 251, 253], "summary": {"covered_lines": 37, "num_statements": 50, "percent_covered": 71.875, "percent_covered_display": "71.88", "missing_lines": 13, "excluded_lines": 0, "percent_statements_covered": 74.0, "percent_statements_covered_display": "74.00", "num_branches": 14, "num_partial_branches": 3, "covered_branches": 9, "missing_branches": 5, "percent_branches_covered": 64.28571428571429, "percent_branches_covered_display": "64.29"}, "missing_lines": [122, 123, 124, 137, 140, 145, 146, 210, 211, 212, 228, 229, 230], "excluded_lines": [], "start_line": 109, "executed_branches": [[121, 126], [136, 148], [206, 207], [216, 217], [216, 250], [221, 222], [221, 225], [233, 216], [233, 234]], "missing_branches": [[121, 122], [136, 137], [145, 146], [145, 148], [206, 215]]}, "": {"executed_lines": [3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 27, 31, 35, 39, 53, 57, 61, 65, 71, 75, 79, 108, 109], "summary": {"covered_lines": 33, "num_statements": 33, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 27, 28, 31, 32, 35, 36, 39, 41, 42, 53, 54, 57, 58, 61, 62, 65, 66, 71, 72, 75, 79, 108, 109, 119, 121, 126, 127, 136, 148, 151, 205, 206, 207, 208, 209, 215, 216, 217, 220, 221, 222, 223, 225, 226, 227, 233, 234, 235, 238, 239, 240, 241, 242, 245, 246, 247, 248, 250, 251, 253], "summary": {"covered_lines": 80, "num_statements": 102, "percent_covered": 73.77049180327869, "percent_covered_display": "73.77", "missing_lines": 22, "excluded_lines": 0, "percent_statements_covered": 78.43137254901961, "percent_statements_covered_display": "78.43", "num_branches": 20, "num_partial_branches": 4, "covered_branches": 10, "missing_branches": 10, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [50, 76, 85, 87, 100, 101, 102, 103, 105, 122, 123, 124, 137, 140, 145, 146, 210, 211, 212, 228, 229, 230], "excluded_lines": [], "start_line": 1, "executed_branches": [[41, 42], [121, 126], [136, 148], [206, 207], [216, 217], [216, 250], [221, 222], [221, 225], [233, 216], [233, 234]], "missing_branches": [[41, 50], [101, 102], [101, 105], [102, 101], [102, 103], [121, 122], [136, 137], [145, 146], [145, 148], [206, 215]]}}}, "app/tasks/upload_to_dropbox.py": {"executed_lines": [3, 4, 6, 7, 8, 10, 11, 12, 13, 14, 16, 19, 21, 23, 24, 26, 27, 29, 30, 32, 33, 34, 39, 43, 44, 65, 105, 106], "summary": {"covered_lines": 28, "num_statements": 119, "percent_covered": 22.448979591836736, "percent_covered_display": "22.45", "missing_lines": 91, "excluded_lines": 0, "percent_statements_covered": 23.529411764705884, "percent_statements_covered_display": "23.53", "num_branches": 28, "num_partial_branches": 5, "covered_branches": 5, "missing_branches": 23, "percent_branches_covered": 17.857142857142858, "percent_branches_covered_display": "17.86"}, "missing_lines": [36, 46, 47, 48, 55, 57, 58, 60, 61, 62, 76, 77, 78, 81, 82, 84, 85, 88, 89, 92, 93, 94, 96, 97, 98, 100, 101, 102, 114, 115, 116, 124, 125, 126, 127, 128, 131, 139, 140, 141, 143, 145, 147, 150, 151, 154, 155, 156, 157, 158, 159, 160, 161, 164, 165, 168, 171, 172, 173, 175, 176, 177, 178, 179, 182, 183, 186, 187, 189, 196, 197, 200, 201, 203, 204, 207, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223], "excluded_lines": [], "executed_branches": [[23, 24], [26, 27], [29, 30], [32, 33], [43, 44]], "missing_branches": [[23, 26], [26, 29], [29, 32], [32, 36], [43, 46], [57, 58], [57, 60], [81, 82], [81, 84], [84, 85], [84, 88], [124, 125], [124, 131], [131, 139], [131, 143], [159, 160], [159, 161], [176, 177], [176, 200], [186, 187], [186, 203], [187, 189], [187, 196]], "functions": {"_validate_dropbox_settings": {"executed_lines": [21, 23, 24, 26, 27, 29, 30, 32, 33, 34], "summary": {"covered_lines": 10, "num_statements": 11, "percent_covered": 73.6842105263158, "percent_covered_display": "73.68", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.9090909090909, "percent_statements_covered_display": "90.91", "num_branches": 8, "num_partial_branches": 4, "covered_branches": 4, "missing_branches": 4, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [36], "excluded_lines": [], "start_line": 19, "executed_branches": [[23, 24], [26, 27], [29, 30], [32, 33]], "missing_branches": [[23, 26], [26, 29], [29, 32], [32, 36]]}, "get_dropbox_access_token": {"executed_lines": [43, 44], "summary": {"covered_lines": 2, "num_statements": 11, "percent_covered": 20.0, "percent_covered_display": "20.00", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 18.181818181818183, "percent_statements_covered_display": "18.18", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [46, 47, 48, 55, 57, 58, 60, 61, 62], "excluded_lines": [], "start_line": 39, "executed_branches": [[43, 44]], "missing_branches": [[43, 46], [57, 58], [57, 60]]}, "get_dropbox_client": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 18, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 4, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [76, 77, 78, 81, 82, 84, 85, 88, 89, 92, 93, 94, 96, 97, 98, 100, 101, 102], "excluded_lines": [], "start_line": 65, "executed_branches": [], "missing_branches": [[81, 82], [81, 84], [84, 85], [84, 88]]}, "upload_to_dropbox": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 56, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 56, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 10, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [114, 115, 116, 124, 125, 126, 127, 128, 131, 139, 140, 141, 143, 145, 147, 150, 151, 154, 164, 165, 168, 171, 172, 173, 175, 176, 177, 178, 179, 182, 183, 186, 187, 189, 196, 197, 200, 201, 203, 204, 207, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223], "excluded_lines": [], "start_line": 106, "executed_branches": [], "missing_branches": [[124, 125], [124, 131], [131, 139], [131, 143], [176, 177], [176, 200], [186, 187], [186, 203], [187, 189], [187, 196]]}, "upload_to_dropbox.check_exists_in_dropbox": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [155, 156, 157, 158, 159, 160, 161], "excluded_lines": [], "start_line": 154, "executed_branches": [], "missing_branches": [[159, 160], [159, 161]]}, "": {"executed_lines": [3, 4, 6, 7, 8, 10, 11, 12, 13, 14, 16, 19, 39, 65, 105, 106], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 6, 7, 8, 10, 11, 12, 13, 14, 16, 19, 21, 23, 24, 26, 27, 29, 30, 32, 33, 34, 39, 43, 44, 65, 105, 106], "summary": {"covered_lines": 28, "num_statements": 119, "percent_covered": 22.448979591836736, "percent_covered_display": "22.45", "missing_lines": 91, "excluded_lines": 0, "percent_statements_covered": 23.529411764705884, "percent_statements_covered_display": "23.53", "num_branches": 28, "num_partial_branches": 5, "covered_branches": 5, "missing_branches": 23, "percent_branches_covered": 17.857142857142858, "percent_branches_covered_display": "17.86"}, "missing_lines": [36, 46, 47, 48, 55, 57, 58, 60, 61, 62, 76, 77, 78, 81, 82, 84, 85, 88, 89, 92, 93, 94, 96, 97, 98, 100, 101, 102, 114, 115, 116, 124, 125, 126, 127, 128, 131, 139, 140, 141, 143, 145, 147, 150, 151, 154, 155, 156, 157, 158, 159, 160, 161, 164, 165, 168, 171, 172, 173, 175, 176, 177, 178, 179, 182, 183, 186, 187, 189, 196, 197, 200, 201, 203, 204, 207, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223], "excluded_lines": [], "start_line": 1, "executed_branches": [[23, 24], [26, 27], [29, 30], [32, 33], [43, 44]], "missing_branches": [[23, 26], [26, 29], [29, 32], [32, 36], [43, 46], [57, 58], [57, 60], [81, 82], [81, 84], [84, 85], [84, 88], [124, 125], [124, 131], [131, 139], [131, 143], [159, 160], [159, 161], [176, 177], [176, 200], [186, 187], [186, 203], [187, 189], [187, 196]]}}}, "app/tasks/upload_to_email.py": {"executed_lines": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 17, 18, 19, 21, 24, 59, 86, 122, 135, 166, 167, 190, 191, 192, 196, 203, 206, 213, 219, 220, 226, 229, 230, 231, 233, 235, 236, 237, 238, 241, 242, 245, 248, 251, 264, 265, 268, 269, 270, 271, 274, 275, 280, 281, 283], "summary": {"covered_lines": 57, "num_statements": 158, "percent_covered": 32.97872340425532, "percent_covered_display": "32.98", "missing_lines": 101, "excluded_lines": 0, "percent_statements_covered": 36.075949367088604, "percent_statements_covered_display": "36.08", "num_branches": 30, "num_partial_branches": 5, "covered_branches": 5, "missing_branches": 25, "percent_branches_covered": 16.666666666666668, "percent_branches_covered_display": "16.67"}, "missing_lines": [31, 32, 33, 34, 37, 38, 39, 40, 41, 42, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 67, 70, 71, 72, 73, 74, 75, 76, 77, 78, 83, 88, 90, 91, 92, 95, 96, 98, 99, 101, 102, 103, 106, 107, 108, 109, 110, 111, 112, 114, 115, 117, 118, 119, 124, 125, 126, 127, 128, 129, 130, 131, 132, 137, 139, 142, 144, 145, 148, 149, 152, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 197, 198, 199, 200, 207, 208, 209, 210, 221, 222, 223, 276, 277, 278, 292, 293, 294, 295, 296], "excluded_lines": [], "executed_branches": [[196, 203], [206, 213], [220, 226], [230, 231], [275, 280]], "missing_branches": [[33, 34], [33, 45], [71, 72], [71, 83], [91, 92], [91, 95], [98, 99], [98, 101], [101, 102], [101, 114], [124, 125], [124, 130], [125, 126], [125, 129], [130, 131], [130, 132], [144, 145], [144, 148], [148, 149], [148, 152], [196, 197], [206, 207], [220, 221], [230, 233], [275, 276]], "functions": {"get_email_template": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 21, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 21, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [31, 32, 33, 34, 37, 38, 39, 40, 41, 42, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56], "excluded_lines": [], "start_line": 24, "executed_branches": [], "missing_branches": [[33, 34], [33, 45]]}, "extract_metadata_from_file": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 11, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 11, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [67, 70, 71, 72, 73, 74, 75, 76, 77, 78, 83], "excluded_lines": [], "start_line": 59, "executed_branches": [], "missing_branches": [[71, 72], [71, 83]]}, "attach_logo": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 23, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 23, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [88, 90, 91, 92, 95, 96, 98, 99, 101, 102, 103, 106, 107, 108, 109, 110, 111, 112, 114, 115, 117, 118, 119], "excluded_lines": [], "start_line": 86, "executed_branches": [], "missing_branches": [[91, 92], [91, 95], [98, 99], [98, 101], [101, 102], [101, 114]]}, "_prepare_recipients": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 9, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [124, 125, 126, 127, 128, 129, 130, 131, 132], "excluded_lines": [], "start_line": 122, "executed_branches": [], "missing_branches": [[124, 125], [124, 130], [125, 126], [125, 129], [130, 131], [130, 132]]}, "_send_email_with_smtp": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 18, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 4, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [137, 139, 142, 144, 145, 148, 149, 152, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163], "excluded_lines": [], "start_line": 135, "executed_branches": [], "missing_branches": [[144, 145], [144, 148], [148, 149], [148, 152]]}, "upload_to_email": {"executed_lines": [190, 191, 192, 196, 203, 206, 213, 219, 220, 226, 229, 230, 231, 233, 235, 236, 237, 238, 241, 242, 245, 248, 251, 264, 265, 268, 269, 270, 271, 274, 275, 280, 281, 283], "summary": {"covered_lines": 34, "num_statements": 53, "percent_covered": 61.904761904761905, "percent_covered_display": "61.90", "missing_lines": 19, "excluded_lines": 0, "percent_statements_covered": 64.15094339622641, "percent_statements_covered_display": "64.15", "num_branches": 10, "num_partial_branches": 5, "covered_branches": 5, "missing_branches": 5, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [197, 198, 199, 200, 207, 208, 209, 210, 221, 222, 223, 276, 277, 278, 292, 293, 294, 295, 296], "excluded_lines": [], "start_line": 167, "executed_branches": [[196, 203], [206, 213], [220, 226], [230, 231], [275, 280]], "missing_branches": [[196, 197], [206, 207], [220, 221], [230, 233], [275, 276]]}, "": {"executed_lines": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 17, 18, 19, 21, 24, 59, 86, 122, 135, 166, 167], "summary": {"covered_lines": 23, "num_statements": 23, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 17, 18, 19, 21, 24, 59, 86, 122, 135, 166, 167, 190, 191, 192, 196, 203, 206, 213, 219, 220, 226, 229, 230, 231, 233, 235, 236, 237, 238, 241, 242, 245, 248, 251, 264, 265, 268, 269, 270, 271, 274, 275, 280, 281, 283], "summary": {"covered_lines": 57, "num_statements": 158, "percent_covered": 32.97872340425532, "percent_covered_display": "32.98", "missing_lines": 101, "excluded_lines": 0, "percent_statements_covered": 36.075949367088604, "percent_statements_covered_display": "36.08", "num_branches": 30, "num_partial_branches": 5, "covered_branches": 5, "missing_branches": 25, "percent_branches_covered": 16.666666666666668, "percent_branches_covered_display": "16.67"}, "missing_lines": [31, 32, 33, 34, 37, 38, 39, 40, 41, 42, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 67, 70, 71, 72, 73, 74, 75, 76, 77, 78, 83, 88, 90, 91, 92, 95, 96, 98, 99, 101, 102, 103, 106, 107, 108, 109, 110, 111, 112, 114, 115, 117, 118, 119, 124, 125, 126, 127, 128, 129, 130, 131, 132, 137, 139, 142, 144, 145, 148, 149, 152, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 197, 198, 199, 200, 207, 208, 209, 210, 221, 222, 223, 276, 277, 278, 292, 293, 294, 295, 296], "excluded_lines": [], "start_line": 1, "executed_branches": [[196, 203], [206, 213], [220, 226], [230, 231], [275, 280]], "missing_branches": [[33, 34], [33, 45], [71, 72], [71, 83], [91, 92], [91, 95], [98, 99], [98, 101], [101, 102], [101, 114], [124, 125], [124, 130], [125, 126], [125, 129], [130, 131], [130, 132], [144, 145], [144, 148], [148, 149], [148, 152], [196, 197], [206, 207], [220, 221], [230, 233], [275, 276]]}}}, "app/tasks/upload_to_ftp.py": {"executed_lines": [5, 6, 7, 9, 10, 11, 12, 14, 17, 18, 30, 31, 32, 36, 37, 38, 39, 40, 43, 46, 52, 54, 55, 57, 84, 90, 91, 92, 95, 98, 99, 101, 103, 107, 108, 127, 128, 131, 133, 134, 135], "summary": {"covered_lines": 41, "num_statements": 85, "percent_covered": 47.57281553398058, "percent_covered_display": "47.57", "missing_lines": 44, "excluded_lines": 0, "percent_statements_covered": 48.23529411764706, "percent_statements_covered_display": "48.24", "num_branches": 18, "num_partial_branches": 4, "covered_branches": 8, "missing_branches": 10, "percent_branches_covered": 44.44444444444444, "percent_branches_covered_display": "44.44"}, "missing_lines": [47, 48, 49, 50, 58, 59, 60, 61, 64, 67, 68, 69, 70, 71, 72, 73, 75, 77, 78, 81, 85, 86, 87, 104, 109, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 143, 144, 145, 146, 147], "excluded_lines": [], "executed_branches": [[36, 37], [36, 43], [46, 52], [57, 84], [84, 90], [98, 99], [98, 127], [103, 107]], "missing_branches": [[46, 47], [57, 58], [70, 71], [70, 75], [84, 85], [103, 104], [113, 114], [113, 127], [114, 113], [114, 115]], "functions": {"upload_to_ftp": {"executed_lines": [30, 31, 32, 36, 37, 38, 39, 40, 43, 46, 52, 54, 55, 57, 84, 90, 91, 92, 95, 98, 99, 101, 103, 107, 108, 127, 128, 131, 133, 134, 135], "summary": {"covered_lines": 31, "num_statements": 75, "percent_covered": 41.935483870967744, "percent_covered_display": "41.94", "missing_lines": 44, "excluded_lines": 0, "percent_statements_covered": 41.333333333333336, "percent_statements_covered_display": "41.33", "num_branches": 18, "num_partial_branches": 4, "covered_branches": 8, "missing_branches": 10, "percent_branches_covered": 44.44444444444444, "percent_branches_covered_display": "44.44"}, "missing_lines": [47, 48, 49, 50, 58, 59, 60, 61, 64, 67, 68, 69, 70, 71, 72, 73, 75, 77, 78, 81, 85, 86, 87, 104, 109, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 143, 144, 145, 146, 147], "excluded_lines": [], "start_line": 18, "executed_branches": [[36, 37], [36, 43], [46, 52], [57, 84], [84, 90], [98, 99], [98, 127], [103, 107]], "missing_branches": [[46, 47], [57, 58], [70, 71], [70, 75], [84, 85], [103, 104], [113, 114], [113, 127], [114, 113], [114, 115]]}, "": {"executed_lines": [5, 6, 7, 9, 10, 11, 12, 14, 17, 18], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 9, 10, 11, 12, 14, 17, 18, 30, 31, 32, 36, 37, 38, 39, 40, 43, 46, 52, 54, 55, 57, 84, 90, 91, 92, 95, 98, 99, 101, 103, 107, 108, 127, 128, 131, 133, 134, 135], "summary": {"covered_lines": 41, "num_statements": 85, "percent_covered": 47.57281553398058, "percent_covered_display": "47.57", "missing_lines": 44, "excluded_lines": 0, "percent_statements_covered": 48.23529411764706, "percent_statements_covered_display": "48.24", "num_branches": 18, "num_partial_branches": 4, "covered_branches": 8, "missing_branches": 10, "percent_branches_covered": 44.44444444444444, "percent_branches_covered_display": "44.44"}, "missing_lines": [47, 48, 49, 50, 58, 59, 60, 61, 64, 67, 68, 69, 70, 71, 72, 73, 75, 77, 78, 81, 85, 86, 87, 104, 109, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 143, 144, 145, 146, 147], "excluded_lines": [], "start_line": 1, "executed_branches": [[36, 37], [36, 43], [46, 52], [57, 84], [84, 90], [98, 99], [98, 127], [103, 107]], "missing_branches": [[46, 47], [57, 58], [70, 71], [70, 75], [84, 85], [103, 104], [113, 114], [113, 127], [114, 113], [114, 115]]}}}, "app/tasks/upload_to_google_drive.py": {"executed_lines": [5, 6, 7, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 21, 24, 65, 98, 119, 152, 153, 162, 163, 164, 172, 179, 182, 183, 184, 186, 188, 189, 196, 201, 202, 205, 238, 240, 249, 250, 252, 253, 254, 258, 266, 269], "summary": {"covered_lines": 45, "num_statements": 125, "percent_covered": 32.48407643312102, "percent_covered_display": "32.48", "missing_lines": 80, "excluded_lines": 0, "percent_statements_covered": 36.0, "percent_statements_covered_display": "36.00", "num_branches": 32, "num_partial_branches": 6, "covered_branches": 6, "missing_branches": 26, "percent_branches_covered": 18.75, "percent_branches_covered_display": "18.75"}, "missing_lines": [29, 31, 36, 37, 40, 51, 54, 55, 57, 58, 59, 60, 61, 62, 70, 72, 73, 76, 77, 78, 80, 81, 86, 87, 90, 91, 93, 94, 95, 106, 107, 108, 109, 110, 111, 112, 113, 114, 116, 126, 129, 130, 131, 134, 135, 139, 142, 143, 146, 147, 149, 173, 174, 175, 176, 190, 191, 192, 193, 207, 211, 212, 214, 215, 218, 219, 220, 221, 222, 225, 228, 232, 233, 235, 267, 271, 272, 273, 274, 275], "excluded_lines": [], "executed_branches": [[172, 179], [183, 184], [189, 196], [201, 202], [205, 238], [266, 269]], "missing_branches": [[31, 36], [31, 40], [72, 73], [72, 76], [76, 77], [76, 80], [86, 87], [86, 90], [107, 108], [107, 116], [134, 135], [134, 139], [142, 143], [142, 146], [146, 147], [146, 149], [172, 173], [183, 186], [189, 190], [201, 205], [205, 207], [212, 214], [212, 225], [214, 215], [214, 218], [266, 267]], "functions": {"get_drive_service_oauth": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 14, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 14, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [29, 31, 36, 37, 40, 51, 54, 55, 57, 58, 59, 60, 61, 62], "excluded_lines": [], "start_line": 24, "executed_branches": [], "missing_branches": [[31, 36], [31, 40]]}, "get_google_drive_service": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 15, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 15, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [70, 72, 73, 76, 77, 78, 80, 81, 86, 87, 90, 91, 93, 94, 95], "excluded_lines": [], "start_line": 65, "executed_branches": [], "missing_branches": [[72, 73], [72, 76], [76, 77], [76, 80], [86, 87], [86, 90]]}, "extract_metadata_from_file": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 10, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [106, 107, 108, 109, 110, 111, 112, 113, 114, 116], "excluded_lines": [], "start_line": 98, "executed_branches": [], "missing_branches": [[107, 108], [107, 116]]}, "truncate_property_value": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 12, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 12, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [126, 129, 130, 131, 134, 135, 139, 142, 143, 146, 147, 149], "excluded_lines": [], "start_line": 119, "executed_branches": [], "missing_branches": [[134, 135], [134, 139], [142, 143], [142, 146], [146, 147], [146, 149]]}, "upload_to_google_drive": {"executed_lines": [162, 163, 164, 172, 179, 182, 183, 184, 186, 188, 189, 196, 201, 202, 205, 238, 240, 249, 250, 252, 253, 254, 258, 266, 269], "summary": {"covered_lines": 25, "num_statements": 54, "percent_covered": 44.285714285714285, "percent_covered_display": "44.29", "missing_lines": 29, "excluded_lines": 0, "percent_statements_covered": 46.2962962962963, "percent_statements_covered_display": "46.30", "num_branches": 16, "num_partial_branches": 6, "covered_branches": 6, "missing_branches": 10, "percent_branches_covered": 37.5, "percent_branches_covered_display": "37.50"}, "missing_lines": [173, 174, 175, 176, 190, 191, 192, 193, 207, 211, 212, 214, 215, 218, 219, 220, 221, 222, 225, 228, 232, 233, 235, 267, 271, 272, 273, 274, 275], "excluded_lines": [], "start_line": 153, "executed_branches": [[172, 179], [183, 184], [189, 196], [201, 202], [205, 238], [266, 269]], "missing_branches": [[172, 173], [183, 186], [189, 190], [201, 205], [205, 207], [212, 214], [212, 225], [214, 215], [214, 218], [266, 267]]}, "": {"executed_lines": [5, 6, 7, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 21, 24, 65, 98, 119, 152, 153], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 21, 24, 65, 98, 119, 152, 153, 162, 163, 164, 172, 179, 182, 183, 184, 186, 188, 189, 196, 201, 202, 205, 238, 240, 249, 250, 252, 253, 254, 258, 266, 269], "summary": {"covered_lines": 45, "num_statements": 125, "percent_covered": 32.48407643312102, "percent_covered_display": "32.48", "missing_lines": 80, "excluded_lines": 0, "percent_statements_covered": 36.0, "percent_statements_covered_display": "36.00", "num_branches": 32, "num_partial_branches": 6, "covered_branches": 6, "missing_branches": 26, "percent_branches_covered": 18.75, "percent_branches_covered_display": "18.75"}, "missing_lines": [29, 31, 36, 37, 40, 51, 54, 55, 57, 58, 59, 60, 61, 62, 70, 72, 73, 76, 77, 78, 80, 81, 86, 87, 90, 91, 93, 94, 95, 106, 107, 108, 109, 110, 111, 112, 113, 114, 116, 126, 129, 130, 131, 134, 135, 139, 142, 143, 146, 147, 149, 173, 174, 175, 176, 190, 191, 192, 193, 207, 211, 212, 214, 215, 218, 219, 220, 221, 222, 225, 228, 232, 233, 235, 267, 271, 272, 273, 274, 275], "excluded_lines": [], "start_line": 1, "executed_branches": [[172, 179], [183, 184], [189, 196], [201, 202], [205, 238], [266, 269]], "missing_branches": [[31, 36], [31, 40], [72, 73], [72, 76], [76, 77], [76, 80], [86, 87], [86, 90], [107, 108], [107, 116], [134, 135], [134, 139], [142, 143], [142, 146], [146, 147], [146, 149], [172, 173], [183, 186], [189, 190], [201, 205], [205, 207], [212, 214], [212, 225], [214, 215], [214, 218], [266, 267]]}}}, "app/tasks/upload_to_nextcloud.py": {"executed_lines": [3, 4, 6, 7, 9, 10, 11, 12, 13, 15, 18, 19, 27, 28, 29, 37, 45, 50, 51, 52], "summary": {"covered_lines": 20, "num_statements": 79, "percent_covered": 22.22222222222222, "percent_covered_display": "22.22", "missing_lines": 59, "excluded_lines": 0, "percent_statements_covered": 25.31645569620253, "percent_statements_covered_display": "25.32", "num_branches": 20, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 18, "percent_branches_covered": 10.0, "percent_branches_covered_display": "10.00"}, "missing_lines": [38, 39, 40, 41, 54, 56, 58, 59, 60, 63, 64, 65, 68, 69, 70, 71, 74, 75, 76, 77, 85, 86, 88, 91, 92, 95, 96, 97, 98, 101, 102, 103, 104, 105, 106, 107, 108, 110, 111, 112, 113, 115, 123, 124, 125, 126, 134, 135, 136, 139, 146, 147, 148, 149, 151, 152, 153, 154, 155], "excluded_lines": [], "executed_branches": [[37, 45], [45, 50]], "missing_branches": [[37, 38], [45, 54], [59, 60], [59, 63], [69, 70], [69, 71], [96, 97], [96, 98], [102, 103], [102, 123], [104, 105], [104, 123], [105, 106], [105, 107], [111, 112], [111, 113], [134, 135], [134, 146]], "functions": {"upload_to_nextcloud": {"executed_lines": [27, 28, 29, 37, 45, 50, 51, 52], "summary": {"covered_lines": 8, "num_statements": 61, "percent_covered": 12.345679012345679, "percent_covered_display": "12.35", "missing_lines": 53, "excluded_lines": 0, "percent_statements_covered": 13.114754098360656, "percent_statements_covered_display": "13.11", "num_branches": 20, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 18, "percent_branches_covered": 10.0, "percent_branches_covered_display": "10.00"}, "missing_lines": [38, 39, 40, 41, 54, 56, 58, 59, 60, 63, 64, 65, 68, 69, 70, 71, 74, 91, 92, 95, 96, 97, 98, 101, 102, 103, 104, 105, 106, 107, 108, 110, 111, 112, 113, 115, 123, 124, 125, 126, 134, 135, 136, 139, 146, 147, 148, 149, 151, 152, 153, 154, 155], "excluded_lines": [], "start_line": 19, "executed_branches": [[37, 45], [45, 50]], "missing_branches": [[37, 38], [45, 54], [59, 60], [59, 63], [69, 70], [69, 71], [96, 97], [96, 98], [102, 103], [102, 123], [104, 105], [104, 123], [105, 106], [105, 107], [111, 112], [111, 113], [134, 135], [134, 146]]}, "upload_to_nextcloud.check_exists_in_nextcloud": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 6, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [75, 76, 77, 85, 86, 88], "excluded_lines": [], "start_line": 74, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [3, 4, 6, 7, 9, 10, 11, 12, 13, 15, 18, 19], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 6, 7, 9, 10, 11, 12, 13, 15, 18, 19, 27, 28, 29, 37, 45, 50, 51, 52], "summary": {"covered_lines": 20, "num_statements": 79, "percent_covered": 22.22222222222222, "percent_covered_display": "22.22", "missing_lines": 59, "excluded_lines": 0, "percent_statements_covered": 25.31645569620253, "percent_statements_covered_display": "25.32", "num_branches": 20, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 18, "percent_branches_covered": 10.0, "percent_branches_covered_display": "10.00"}, "missing_lines": [38, 39, 40, 41, 54, 56, 58, 59, 60, 63, 64, 65, 68, 69, 70, 71, 74, 75, 76, 77, 85, 86, 88, 91, 92, 95, 96, 97, 98, 101, 102, 103, 104, 105, 106, 107, 108, 110, 111, 112, 113, 115, 123, 124, 125, 126, 134, 135, 136, 139, 146, 147, 148, 149, 151, 152, 153, 154, 155], "excluded_lines": [], "start_line": 1, "executed_branches": [[37, 45], [45, 50]], "missing_branches": [[37, 38], [45, 54], [59, 60], [59, 63], [69, 70], [69, 71], [96, 97], [96, 98], [102, 103], [102, 123], [104, 105], [104, 123], [105, 106], [105, 107], [111, 112], [111, 113], [134, 135], [134, 146]]}}}, "app/tasks/upload_to_onedrive.py": {"executed_lines": [3, 4, 5, 6, 8, 9, 11, 12, 13, 14, 16, 19, 100, 146, 212, 213, 221, 222, 223, 231, 232, 233, 234, 235, 238, 241, 247, 249, 252, 255, 258, 259, 260, 261, 265], "summary": {"covered_lines": 35, "num_statements": 133, "percent_covered": 22.75449101796407, "percent_covered_display": "22.75", "missing_lines": 98, "excluded_lines": 0, "percent_statements_covered": 26.31578947368421, "percent_statements_covered_display": "26.32", "num_branches": 34, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 31, "percent_branches_covered": 8.823529411764707, "percent_branches_covered_display": "8.82"}, "missing_lines": [26, 27, 30, 31, 34, 37, 39, 46, 47, 51, 52, 53, 56, 57, 58, 60, 61, 62, 64, 67, 68, 69, 72, 73, 75, 78, 79, 80, 87, 89, 90, 91, 92, 94, 97, 103, 106, 108, 111, 112, 115, 116, 119, 120, 122, 125, 127, 129, 131, 133, 134, 135, 136, 138, 139, 140, 141, 142, 143, 152, 155, 158, 160, 161, 162, 163, 164, 167, 168, 171, 174, 177, 178, 180, 181, 182, 187, 189, 191, 192, 193, 194, 195, 196, 197, 199, 200, 205, 209, 242, 243, 244, 245, 272, 273, 274, 275, 276], "excluded_lines": [], "executed_branches": [[231, 232], [231, 238], [241, 247]], "missing_branches": [[26, 27], [26, 30], [37, 39], [37, 78], [51, 52], [51, 67], [60, 61], [60, 64], [67, 68], [67, 75], [78, 79], [78, 97], [89, 90], [89, 94], [106, 108], [106, 119], [133, 134], [133, 138], [163, 164], [163, 167], [180, 181], [180, 199], [187, 189], [187, 191], [192, 180], [192, 193], [196, 180], [196, 197], [199, 200], [199, 205], [241, 242]], "functions": {"get_onedrive_token": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 35, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 35, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 14, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 14, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [26, 27, 30, 31, 34, 37, 39, 46, 47, 51, 52, 53, 56, 57, 58, 60, 61, 62, 64, 67, 68, 69, 72, 73, 75, 78, 79, 80, 87, 89, 90, 91, 92, 94, 97], "excluded_lines": [], "start_line": 19, "executed_branches": [], "missing_branches": [[26, 27], [26, 30], [37, 39], [37, 78], [51, 52], [51, 67], [60, 61], [60, 64], [67, 68], [67, 75], [78, 79], [78, 97], [89, 90], [89, 94]]}, "create_upload_session": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 24, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 24, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 4, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [103, 106, 108, 111, 112, 115, 116, 119, 120, 122, 125, 127, 129, 131, 133, 134, 135, 136, 138, 139, 140, 141, 142, 143], "excluded_lines": [], "start_line": 100, "executed_branches": [], "missing_branches": [[106, 108], [106, 119], [133, 134], [133, 138]]}, "upload_large_file": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 30, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 30, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 12, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [152, 155, 158, 160, 161, 162, 163, 164, 167, 168, 171, 174, 177, 178, 180, 181, 182, 187, 189, 191, 192, 193, 194, 195, 196, 197, 199, 200, 205, 209], "excluded_lines": [], "start_line": 146, "executed_branches": [], "missing_branches": [[163, 164], [163, 167], [180, 181], [180, 199], [187, 189], [187, 191], [192, 180], [192, 193], [196, 180], [196, 197], [199, 200], [199, 205]]}, "upload_to_onedrive": {"executed_lines": [221, 222, 223, 231, 232, 233, 234, 235, 238, 241, 247, 249, 252, 255, 258, 259, 260, 261, 265], "summary": {"covered_lines": 19, "num_statements": 28, "percent_covered": 68.75, "percent_covered_display": "68.75", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 67.85714285714286, "percent_statements_covered_display": "67.86", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [242, 243, 244, 245, 272, 273, 274, 275, 276], "excluded_lines": [], "start_line": 213, "executed_branches": [[231, 232], [231, 238], [241, 247]], "missing_branches": [[241, 242]]}, "": {"executed_lines": [3, 4, 5, 6, 8, 9, 11, 12, 13, 14, 16, 19, 100, 146, 212, 213], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 5, 6, 8, 9, 11, 12, 13, 14, 16, 19, 100, 146, 212, 213, 221, 222, 223, 231, 232, 233, 234, 235, 238, 241, 247, 249, 252, 255, 258, 259, 260, 261, 265], "summary": {"covered_lines": 35, "num_statements": 133, "percent_covered": 22.75449101796407, "percent_covered_display": "22.75", "missing_lines": 98, "excluded_lines": 0, "percent_statements_covered": 26.31578947368421, "percent_statements_covered_display": "26.32", "num_branches": 34, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 31, "percent_branches_covered": 8.823529411764707, "percent_branches_covered_display": "8.82"}, "missing_lines": [26, 27, 30, 31, 34, 37, 39, 46, 47, 51, 52, 53, 56, 57, 58, 60, 61, 62, 64, 67, 68, 69, 72, 73, 75, 78, 79, 80, 87, 89, 90, 91, 92, 94, 97, 103, 106, 108, 111, 112, 115, 116, 119, 120, 122, 125, 127, 129, 131, 133, 134, 135, 136, 138, 139, 140, 141, 142, 143, 152, 155, 158, 160, 161, 162, 163, 164, 167, 168, 171, 174, 177, 178, 180, 181, 182, 187, 189, 191, 192, 193, 194, 195, 196, 197, 199, 200, 205, 209, 242, 243, 244, 245, 272, 273, 274, 275, 276], "excluded_lines": [], "start_line": 1, "executed_branches": [[231, 232], [231, 238], [241, 247]], "missing_branches": [[26, 27], [26, 30], [37, 39], [37, 78], [51, 52], [51, 67], [60, 61], [60, 64], [67, 68], [67, 75], [78, 79], [78, 97], [89, 90], [89, 94], [106, 108], [106, 119], [133, 134], [133, 138], [163, 164], [163, 167], [180, 181], [180, 199], [187, 189], [187, 191], [192, 180], [192, 193], [196, 180], [196, 197], [199, 200], [199, 205], [241, 242]]}}}, "app/tasks/upload_to_paperless.py": {"executed_lines": [3, 4, 5, 6, 7, 9, 11, 12, 13, 14, 16, 18, 19, 21, 24, 29, 40, 59, 75, 124, 156, 202, 203], "summary": {"covered_lines": 23, "num_statements": 191, "percent_covered": 9.31174089068826, "percent_covered_display": "9.31", "missing_lines": 168, "excluded_lines": 0, "percent_statements_covered": 12.041884816753926, "percent_statements_covered_display": "12.04", "num_branches": 56, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 56, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [26, 34, 35, 36, 37, 50, 51, 52, 54, 55, 56, 69, 70, 71, 72, 84, 85, 87, 88, 89, 92, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 118, 119, 121, 137, 138, 139, 140, 141, 144, 146, 147, 148, 150, 151, 152, 153, 165, 166, 169, 170, 171, 172, 173, 174, 175, 176, 179, 180, 181, 183, 184, 185, 188, 189, 191, 192, 193, 194, 195, 196, 197, 199, 211, 212, 213, 221, 222, 223, 224, 225, 228, 231, 232, 233, 234, 235, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 249, 252, 253, 254, 255, 256, 259, 261, 262, 263, 266, 267, 268, 269, 270, 276, 287, 289, 290, 291, 294, 295, 296, 297, 298, 299, 307, 314, 315, 320, 323, 324, 326, 327, 330, 331, 333, 334, 335, 336, 337, 338, 339, 340, 343, 345, 346, 347, 350, 351, 352, 354, 355, 356, 363, 364, 365, 368, 370], "excluded_lines": [], "executed_branches": [], "missing_branches": [[35, 36], [35, 37], [50, 51], [50, 52], [54, 55], [54, 56], [69, 70], [69, 71], [87, 88], [87, 121], [100, 101], [100, 103], [103, 104], [103, 118], [106, 107], [106, 111], [108, 109], [108, 110], [111, 112], [111, 118], [113, 114], [113, 116], [146, 147], [146, 150], [147, 146], [147, 148], [165, 166], [165, 169], [170, 171], [170, 183], [172, 170], [172, 173], [183, 184], [183, 188], [221, 222], [221, 228], [231, 232], [231, 238], [240, 241], [240, 249], [297, 298], [297, 314], [323, 324], [323, 343], [330, 331], [330, 343], [331, 330], [331, 333], [334, 330], [334, 335], [343, 345], [343, 350], [345, 346], [345, 350], [350, 351], [350, 368]], "functions": {"_get_headers": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [26], "excluded_lines": [], "start_line": 24, "executed_branches": [], "missing_branches": []}, "_paperless_api_url": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [34, 35, 36, 37], "excluded_lines": [], "start_line": 29, "executed_branches": [], "missing_branches": [[35, 36], [35, 37]]}, "normalize_metadata_value": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 6, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 4, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [50, 51, 52, 54, 55, 56], "excluded_lines": [], "start_line": 40, "executed_branches": [], "missing_branches": [[50, 51], [50, 52], [54, 55], [54, 56]]}, "_is_duplicate_error": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [69, 70, 71, 72], "excluded_lines": [], "start_line": 59, "executed_branches": [], "missing_branches": [[69, 70], [69, 71]]}, "poll_task_for_document_id": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 31, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 31, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 14, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 14, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [84, 85, 87, 88, 89, 92, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 118, 119, 121], "excluded_lines": [], "start_line": 75, "executed_branches": [], "missing_branches": [[87, 88], [87, 121], [100, 101], [100, 103], [103, 104], [103, 118], [106, 107], [106, 111], [108, 109], [108, 110], [111, 112], [111, 118], [113, 114], [113, 116]]}, "get_custom_field_id": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 13, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 13, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 4, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [137, 138, 139, 140, 141, 144, 146, 147, 148, 150, 151, 152, 153], "excluded_lines": [], "start_line": 124, "executed_branches": [], "missing_branches": [[146, 147], [146, 150], [147, 146], [147, 148]]}, "set_document_custom_fields": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 26, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 26, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [165, 166, 169, 170, 171, 172, 173, 174, 175, 176, 179, 180, 181, 183, 184, 185, 188, 189, 191, 192, 193, 194, 195, 196, 197, 199], "excluded_lines": [], "start_line": 156, "executed_branches": [], "missing_branches": [[165, 166], [165, 169], [170, 171], [170, 183], [172, 170], [172, 173], [183, 184], [183, 188]]}, "upload_to_paperless": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 83, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 83, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 22, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 22, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [211, 212, 213, 221, 222, 223, 224, 225, 228, 231, 232, 233, 234, 235, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 249, 252, 253, 254, 255, 256, 259, 261, 262, 263, 266, 267, 268, 269, 270, 276, 287, 289, 290, 291, 294, 295, 296, 297, 298, 299, 307, 314, 315, 320, 323, 324, 326, 327, 330, 331, 333, 334, 335, 336, 337, 338, 339, 340, 343, 345, 346, 347, 350, 351, 352, 354, 355, 356, 363, 364, 365, 368, 370], "excluded_lines": [], "start_line": 203, "executed_branches": [], "missing_branches": [[221, 222], [221, 228], [231, 232], [231, 238], [240, 241], [240, 249], [297, 298], [297, 314], [323, 324], [323, 343], [330, 331], [330, 343], [331, 330], [331, 333], [334, 330], [334, 335], [343, 345], [343, 350], [345, 346], [345, 350], [350, 351], [350, 368]]}, "": {"executed_lines": [3, 4, 5, 6, 7, 9, 11, 12, 13, 14, 16, 18, 19, 21, 24, 29, 40, 59, 75, 124, 156, 202, 203], "summary": {"covered_lines": 23, "num_statements": 23, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 5, 6, 7, 9, 11, 12, 13, 14, 16, 18, 19, 21, 24, 29, 40, 59, 75, 124, 156, 202, 203], "summary": {"covered_lines": 23, "num_statements": 191, "percent_covered": 9.31174089068826, "percent_covered_display": "9.31", "missing_lines": 168, "excluded_lines": 0, "percent_statements_covered": 12.041884816753926, "percent_statements_covered_display": "12.04", "num_branches": 56, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 56, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [26, 34, 35, 36, 37, 50, 51, 52, 54, 55, 56, 69, 70, 71, 72, 84, 85, 87, 88, 89, 92, 93, 94, 95, 96, 97, 98, 100, 101, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 118, 119, 121, 137, 138, 139, 140, 141, 144, 146, 147, 148, 150, 151, 152, 153, 165, 166, 169, 170, 171, 172, 173, 174, 175, 176, 179, 180, 181, 183, 184, 185, 188, 189, 191, 192, 193, 194, 195, 196, 197, 199, 211, 212, 213, 221, 222, 223, 224, 225, 228, 231, 232, 233, 234, 235, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 249, 252, 253, 254, 255, 256, 259, 261, 262, 263, 266, 267, 268, 269, 270, 276, 287, 289, 290, 291, 294, 295, 296, 297, 298, 299, 307, 314, 315, 320, 323, 324, 326, 327, 330, 331, 333, 334, 335, 336, 337, 338, 339, 340, 343, 345, 346, 347, 350, 351, 352, 354, 355, 356, 363, 364, 365, 368, 370], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": [[35, 36], [35, 37], [50, 51], [50, 52], [54, 55], [54, 56], [69, 70], [69, 71], [87, 88], [87, 121], [100, 101], [100, 103], [103, 104], [103, 118], [106, 107], [106, 111], [108, 109], [108, 110], [111, 112], [111, 118], [113, 114], [113, 116], [146, 147], [146, 150], [147, 146], [147, 148], [165, 166], [165, 169], [170, 171], [170, 183], [172, 170], [172, 173], [183, 184], [183, 188], [221, 222], [221, 228], [231, 232], [231, 238], [240, 241], [240, 249], [297, 298], [297, 314], [323, 324], [323, 343], [330, 331], [330, 343], [331, 330], [331, 333], [334, 330], [334, 335], [343, 345], [343, 350], [345, 346], [345, 350], [350, 351], [350, 368]]}}}, "app/tasks/upload_to_s3.py": {"executed_lines": [3, 4, 6, 7, 9, 10, 11, 12, 14, 17, 18, 26, 27, 28, 32, 33, 34, 35, 36, 39, 42, 48, 54, 56, 64, 66, 67, 68, 69, 74, 77, 81, 85, 87, 90, 91], "summary": {"covered_lines": 36, "num_statements": 56, "percent_covered": 63.23529411764706, "percent_covered_display": "63.24", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 64.28571428571429, "percent_statements_covered_display": "64.29", "num_branches": 12, "num_partial_branches": 5, "covered_branches": 7, "missing_branches": 5, "percent_branches_covered": 58.333333333333336, "percent_branches_covered_display": "58.33"}, "missing_lines": [43, 44, 45, 46, 49, 50, 51, 52, 71, 78, 99, 100, 101, 102, 103, 105, 106, 107, 108, 109], "excluded_lines": [], "executed_branches": [[32, 33], [32, 39], [42, 48], [48, 54], [64, 66], [67, 68], [77, 81]], "missing_branches": [[42, 43], [48, 49], [64, 71], [67, 69], [77, 78]], "functions": {"upload_to_s3": {"executed_lines": [26, 27, 28, 32, 33, 34, 35, 36, 39, 42, 48, 54, 56, 64, 66, 67, 68, 69, 74, 77, 81, 85, 87, 90, 91], "summary": {"covered_lines": 25, "num_statements": 45, "percent_covered": 56.14035087719298, "percent_covered_display": "56.14", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 55.55555555555556, "percent_statements_covered_display": "55.56", "num_branches": 12, "num_partial_branches": 5, "covered_branches": 7, "missing_branches": 5, "percent_branches_covered": 58.333333333333336, "percent_branches_covered_display": "58.33"}, "missing_lines": [43, 44, 45, 46, 49, 50, 51, 52, 71, 78, 99, 100, 101, 102, 103, 105, 106, 107, 108, 109], "excluded_lines": [], "start_line": 18, "executed_branches": [[32, 33], [32, 39], [42, 48], [48, 54], [64, 66], [67, 68], [77, 81]], "missing_branches": [[42, 43], [48, 49], [64, 71], [67, 69], [77, 78]]}, "": {"executed_lines": [3, 4, 6, 7, 9, 10, 11, 12, 14, 17, 18], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 6, 7, 9, 10, 11, 12, 14, 17, 18, 26, 27, 28, 32, 33, 34, 35, 36, 39, 42, 48, 54, 56, 64, 66, 67, 68, 69, 74, 77, 81, 85, 87, 90, 91], "summary": {"covered_lines": 36, "num_statements": 56, "percent_covered": 63.23529411764706, "percent_covered_display": "63.24", "missing_lines": 20, "excluded_lines": 0, "percent_statements_covered": 64.28571428571429, "percent_statements_covered_display": "64.29", "num_branches": 12, "num_partial_branches": 5, "covered_branches": 7, "missing_branches": 5, "percent_branches_covered": 58.333333333333336, "percent_branches_covered_display": "58.33"}, "missing_lines": [43, 44, 45, 46, 49, 50, 51, 52, 71, 78, 99, 100, 101, 102, 103, 105, 106, 107, 108, 109], "excluded_lines": [], "start_line": 1, "executed_branches": [[32, 33], [32, 39], [42, 48], [48, 54], [64, 66], [67, 68], [77, 81]], "missing_branches": [[42, 43], [48, 49], [64, 71], [67, 69], [77, 78]]}}}, "app/tasks/upload_to_sftp.py": {"executed_lines": [3, 4, 6, 8, 9, 10, 11, 12, 14, 17, 18, 26, 27, 28, 32, 33, 34, 35, 36, 38, 44, 45, 48, 53, 54, 59, 65, 67, 74, 75, 77, 78, 79, 80, 81, 91, 92, 95, 98, 99, 102, 106, 114, 117, 118, 119, 121, 122, 123, 124, 125, 126, 127, 135, 136, 137, 138, 141, 142, 144], "summary": {"covered_lines": 60, "num_statements": 94, "percent_covered": 62.06896551724138, "percent_covered_display": "62.07", "missing_lines": 34, "excluded_lines": 0, "percent_statements_covered": 63.829787234042556, "percent_statements_covered_display": "63.83", "num_branches": 22, "num_partial_branches": 6, "covered_branches": 12, "missing_branches": 10, "percent_branches_covered": 54.54545454545455, "percent_branches_covered_display": "54.55"}, "missing_lines": [39, 40, 41, 42, 62, 63, 82, 83, 84, 86, 87, 88, 103, 107, 108, 109, 110, 111, 128, 129, 130, 131, 132, 146, 148, 149, 150, 151, 152, 153, 155, 156, 157, 158], "excluded_lines": [], "executed_branches": [[32, 33], [32, 38], [38, 44], [53, 54], [77, 78], [80, 81], [102, 106], [118, 119], [122, 123], [122, 135], [123, 124], [123, 125]], "missing_branches": [[38, 39], [53, 62], [77, 82], [80, 91], [82, 83], [82, 86], [102, 103], [118, 135], [149, 150], [149, 151]], "functions": {"upload_to_sftp": {"executed_lines": [26, 27, 28, 32, 33, 34, 35, 36, 38, 44, 45, 48, 53, 54, 59, 65, 67, 74, 75, 77, 78, 79, 80, 81, 91, 92, 95, 98, 99, 102, 106, 114, 117, 118, 119, 121, 122, 123, 124, 125, 126, 127, 135, 136, 137, 138, 141, 142, 144], "summary": {"covered_lines": 49, "num_statements": 78, "percent_covered": 61.0, "percent_covered_display": "61.00", "missing_lines": 29, "excluded_lines": 0, "percent_statements_covered": 62.82051282051282, "percent_statements_covered_display": "62.82", "num_branches": 22, "num_partial_branches": 6, "covered_branches": 12, "missing_branches": 10, "percent_branches_covered": 54.54545454545455, "percent_branches_covered_display": "54.55"}, "missing_lines": [39, 40, 41, 42, 62, 63, 82, 83, 84, 86, 87, 88, 103, 128, 129, 130, 131, 132, 146, 148, 149, 150, 151, 152, 153, 155, 156, 157, 158], "excluded_lines": [], "start_line": 18, "executed_branches": [[32, 33], [32, 38], [38, 44], [53, 54], [77, 78], [80, 81], [102, 106], [118, 119], [122, 123], [122, 135], [123, 124], [123, 125]], "missing_branches": [[38, 39], [53, 62], [77, 82], [80, 91], [82, 83], [82, 86], [102, 103], [118, 135], [149, 150], [149, 151]]}, "upload_to_sftp.check_exists_in_sftp": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [107, 108, 109, 110, 111], "excluded_lines": [], "start_line": 106, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [3, 4, 6, 8, 9, 10, 11, 12, 14, 17, 18], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 6, 8, 9, 10, 11, 12, 14, 17, 18, 26, 27, 28, 32, 33, 34, 35, 36, 38, 44, 45, 48, 53, 54, 59, 65, 67, 74, 75, 77, 78, 79, 80, 81, 91, 92, 95, 98, 99, 102, 106, 114, 117, 118, 119, 121, 122, 123, 124, 125, 126, 127, 135, 136, 137, 138, 141, 142, 144], "summary": {"covered_lines": 60, "num_statements": 94, "percent_covered": 62.06896551724138, "percent_covered_display": "62.07", "missing_lines": 34, "excluded_lines": 0, "percent_statements_covered": 63.829787234042556, "percent_statements_covered_display": "63.83", "num_branches": 22, "num_partial_branches": 6, "covered_branches": 12, "missing_branches": 10, "percent_branches_covered": 54.54545454545455, "percent_branches_covered_display": "54.55"}, "missing_lines": [39, 40, 41, 42, 62, 63, 82, 83, 84, 86, 87, 88, 103, 107, 108, 109, 110, 111, 128, 129, 130, 131, 132, 146, 148, 149, 150, 151, 152, 153, 155, 156, 157, 158], "excluded_lines": [], "start_line": 1, "executed_branches": [[32, 33], [32, 38], [38, 44], [53, 54], [77, 78], [80, 81], [102, 106], [118, 119], [122, 123], [122, 135], [123, 124], [123, 125]], "missing_branches": [[38, 39], [53, 62], [77, 82], [80, 91], [82, 83], [82, 86], [102, 103], [118, 135], [149, 150], [149, 151]]}}}, "app/tasks/upload_to_webdav.py": {"executed_lines": [3, 4, 5, 7, 9, 10, 11, 12, 14, 17, 18, 26, 27, 28, 36, 37, 38, 39, 40, 43, 46, 47, 48, 49, 50, 53, 55, 56, 59, 61, 62, 65, 68, 69, 70, 79, 80, 81, 84, 86, 87, 88, 89, 91, 92, 93, 94, 95], "summary": {"covered_lines": 48, "num_statements": 48, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 10, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[36, 37], [36, 43], [46, 47], [46, 53], [55, 56], [55, 59], [61, 62], [61, 65], [79, 80], [79, 86]], "missing_branches": [], "functions": {"upload_to_webdav": {"executed_lines": [26, 27, 28, 36, 37, 38, 39, 40, 43, 46, 47, 48, 49, 50, 53, 55, 56, 59, 61, 62, 65, 68, 69, 70, 79, 80, 81, 84, 86, 87, 88, 89, 91, 92, 93, 94, 95], "summary": {"covered_lines": 37, "num_statements": 37, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 10, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 18, "executed_branches": [[36, 37], [36, 43], [46, 47], [46, 53], [55, 56], [55, 59], [61, 62], [61, 65], [79, 80], [79, 86]], "missing_branches": []}, "": {"executed_lines": [3, 4, 5, 7, 9, 10, 11, 12, 14, 17, 18], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 5, 7, 9, 10, 11, 12, 14, 17, 18, 26, 27, 28, 36, 37, 38, 39, 40, 43, 46, 47, 48, 49, 50, 53, 55, 56, 59, 61, 62, 65, 68, 69, 70, 79, 80, 81, 84, 86, 87, 88, 89, 91, 92, 93, 94, 95], "summary": {"covered_lines": 48, "num_statements": 48, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 10, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[36, 37], [36, 43], [46, 47], [46, 53], [55, 56], [55, 59], [61, 62], [61, 65], [79, 80], [79, 86]], "missing_branches": []}}}, "app/tasks/upload_with_rclone.py": {"executed_lines": [3, 4, 5, 7, 8, 9, 10, 12, 15, 16, 25, 27, 28, 31, 33, 36, 37, 40, 44, 45, 48, 49, 50, 51, 52, 110, 111], "summary": {"covered_lines": 27, "num_statements": 98, "percent_covered": 27.868852459016395, "percent_covered_display": "27.87", "missing_lines": 71, "excluded_lines": 0, "percent_statements_covered": 27.551020408163264, "percent_statements_covered_display": "27.55", "num_branches": 24, "num_partial_branches": 1, "covered_branches": 7, "missing_branches": 17, "percent_branches_covered": 29.166666666666668, "percent_branches_covered_display": "29.17"}, "missing_lines": [54, 56, 58, 60, 63, 65, 68, 71, 73, 74, 75, 76, 77, 78, 79, 81, 82, 89, 91, 92, 93, 95, 96, 97, 98, 101, 103, 104, 105, 106, 107, 116, 118, 119, 122, 124, 129, 130, 131, 132, 133, 136, 137, 138, 140, 142, 145, 146, 147, 148, 149, 150, 153, 156, 157, 158, 159, 160, 162, 163, 164, 166, 172, 174, 175, 176, 178, 179, 180, 181, 188], "excluded_lines": [], "executed_branches": [[27, 28], [27, 31], [36, 37], [36, 40], [44, 45], [44, 48], [49, 50]], "missing_branches": [[49, 54], [71, 73], [71, 91], [118, 119], [118, 122], [130, 131], [130, 136], [140, 142], [140, 174], [146, 147], [146, 156], [149, 150], [149, 153], [157, 158], [157, 166], [159, 160], [159, 162]], "functions": {"upload_with_rclone": {"executed_lines": [25, 27, 28, 31, 33, 36, 37, 40, 44, 45, 48, 49, 50, 51, 52], "summary": {"covered_lines": 15, "num_statements": 46, "percent_covered": 39.285714285714285, "percent_covered_display": "39.29", "missing_lines": 31, "excluded_lines": 0, "percent_statements_covered": 32.608695652173914, "percent_statements_covered_display": "32.61", "num_branches": 10, "num_partial_branches": 1, "covered_branches": 7, "missing_branches": 3, "percent_branches_covered": 70.0, "percent_branches_covered_display": "70.00"}, "missing_lines": [54, 56, 58, 60, 63, 65, 68, 71, 73, 74, 75, 76, 77, 78, 79, 81, 82, 89, 91, 92, 93, 95, 96, 97, 98, 101, 103, 104, 105, 106, 107], "excluded_lines": [], "start_line": 16, "executed_branches": [[27, 28], [27, 31], [36, 37], [36, 40], [44, 45], [44, 48], [49, 50]], "missing_branches": [[49, 54], [71, 73], [71, 91]]}, "send_to_all_rclone_destinations": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 40, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 40, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 14, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 14, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [116, 118, 119, 122, 124, 129, 130, 131, 132, 133, 136, 137, 138, 140, 142, 145, 146, 147, 148, 149, 150, 153, 156, 157, 158, 159, 160, 162, 163, 164, 166, 172, 174, 175, 176, 178, 179, 180, 181, 188], "excluded_lines": [], "start_line": 111, "executed_branches": [], "missing_branches": [[118, 119], [118, 122], [130, 131], [130, 136], [140, 142], [140, 174], [146, 147], [146, 156], [149, 150], [149, 153], [157, 158], [157, 166], [159, 160], [159, 162]]}, "": {"executed_lines": [3, 4, 5, 7, 8, 9, 10, 12, 15, 16, 110, 111], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 5, 7, 8, 9, 10, 12, 15, 16, 25, 27, 28, 31, 33, 36, 37, 40, 44, 45, 48, 49, 50, 51, 52, 110, 111], "summary": {"covered_lines": 27, "num_statements": 98, "percent_covered": 27.868852459016395, "percent_covered_display": "27.87", "missing_lines": 71, "excluded_lines": 0, "percent_statements_covered": 27.551020408163264, "percent_statements_covered_display": "27.55", "num_branches": 24, "num_partial_branches": 1, "covered_branches": 7, "missing_branches": 17, "percent_branches_covered": 29.166666666666668, "percent_branches_covered_display": "29.17"}, "missing_lines": [54, 56, 58, 60, 63, 65, 68, 71, 73, 74, 75, 76, 77, 78, 79, 81, 82, 89, 91, 92, 93, 95, 96, 97, 98, 101, 103, 104, 105, 106, 107, 116, 118, 119, 122, 124, 129, 130, 131, 132, 133, 136, 137, 138, 140, 142, 145, 146, 147, 148, 149, 150, 153, 156, 157, 158, 159, 160, 162, 163, 164, 166, 172, 174, 175, 176, 178, 179, 180, 181, 188], "excluded_lines": [], "start_line": 1, "executed_branches": [[27, 28], [27, 31], [36, 37], [36, 40], [44, 45], [44, 48], [49, 50]], "missing_branches": [[49, 54], [71, 73], [71, 91], [118, 119], [118, 122], [130, 131], [130, 136], [140, 142], [140, 174], [146, 147], [146, 156], [149, 150], [149, 153], [157, 158], [157, 166], [159, 160], [159, 162]]}}}, "app/tasks/uptime_kuma_tasks.py": {"executed_lines": [3, 5, 6, 8, 10, 13, 14, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32], "summary": {"covered_lines": 19, "num_statements": 19, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[20, 21], [20, 24]], "missing_branches": [], "functions": {"ping_uptime_kuma": {"executed_lines": [20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 14, "executed_branches": [[20, 21], [20, 24]], "missing_branches": []}, "": {"executed_lines": [3, 5, 6, 8, 10, 13, 14], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 5, 6, 8, 10, 13, 14, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32], "summary": {"covered_lines": 19, "num_statements": 19, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[20, 21], [20, 24]], "missing_branches": []}}}, "app/utils/__init__.py": {"executed_lines": [6, 7, 8, 11], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [6, 7, 8, 11], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [6, 7, 8, 11], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/utils/config_loader.py": {"executed_lines": [10, 11, 13, 15, 17, 20, 31, 32, 34, 35, 36, 39, 40, 41, 42, 45, 47, 48, 50, 53, 54, 55, 57, 58, 68, 79, 80, 83, 84, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 106, 107, 111, 114], "summary": {"covered_lines": 48, "num_statements": 66, "percent_covered": 74.44444444444444, "percent_covered_display": "74.44", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 72.72727272727273, "percent_statements_covered_display": "72.73", "num_branches": 24, "num_partial_branches": 5, "covered_branches": 19, "missing_branches": 5, "percent_branches_covered": 79.16666666666667, "percent_branches_covered_display": "79.17"}, "missing_lines": [60, 62, 63, 65, 86, 87, 108, 127, 128, 130, 131, 132, 133, 134, 136, 137, 138, 139], "excluded_lines": [], "executed_branches": [[34, 35], [34, 39], [40, 41], [40, 57], [45, 47], [48, 50], [57, 58], [79, 80], [79, 83], [84, 90], [90, 91], [90, 92], [92, 93], [92, 98], [98, 99], [98, 104], [104, 106], [104, 111], [106, 107]], "missing_branches": [[45, 40], [48, 40], [57, 60], [84, 86], [106, 108]], "functions": {"load_settings_from_db": {"executed_lines": [31, 32, 34, 35, 36, 39, 40, 41, 42, 45, 47, 48, 50, 53, 54, 55, 57, 58], "summary": {"covered_lines": 18, "num_statements": 22, "percent_covered": 78.125, "percent_covered_display": "78.12", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 81.81818181818181, "percent_statements_covered_display": "81.82", "num_branches": 10, "num_partial_branches": 3, "covered_branches": 7, "missing_branches": 3, "percent_branches_covered": 70.0, "percent_branches_covered_display": "70.00"}, "missing_lines": [60, 62, 63, 65], "excluded_lines": [], "start_line": 20, "executed_branches": [[34, 35], [34, 39], [40, 41], [40, 57], [45, 47], [48, 50], [57, 58]], "missing_branches": [[45, 40], [48, 40], [57, 60]]}, "convert_setting_value": {"executed_lines": [79, 80, 83, 84, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 106, 107, 111], "summary": {"covered_lines": 22, "num_statements": 25, "percent_covered": 87.17948717948718, "percent_covered_display": "87.18", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 88.0, "percent_statements_covered_display": "88.00", "num_branches": 14, "num_partial_branches": 2, "covered_branches": 12, "missing_branches": 2, "percent_branches_covered": 85.71428571428571, "percent_branches_covered_display": "85.71"}, "missing_lines": [86, 87, 108], "excluded_lines": [], "start_line": 68, "executed_branches": [[79, 80], [79, 83], [84, 90], [90, 91], [90, 92], [92, 93], [92, 98], [98, 99], [98, 104], [104, 106], [104, 111], [106, 107]], "missing_branches": [[84, 86], [106, 108]]}, "reload_settings_from_db": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 11, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 11, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [127, 128, 130, 131, 132, 133, 134, 136, 137, 138, 139], "excluded_lines": [], "start_line": 114, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [10, 11, 13, 15, 17, 20, 68, 114], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [10, 11, 13, 15, 17, 20, 31, 32, 34, 35, 36, 39, 40, 41, 42, 45, 47, 48, 50, 53, 54, 55, 57, 58, 68, 79, 80, 83, 84, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 106, 107, 111, 114], "summary": {"covered_lines": 48, "num_statements": 66, "percent_covered": 74.44444444444444, "percent_covered_display": "74.44", "missing_lines": 18, "excluded_lines": 0, "percent_statements_covered": 72.72727272727273, "percent_statements_covered_display": "72.73", "num_branches": 24, "num_partial_branches": 5, "covered_branches": 19, "missing_branches": 5, "percent_branches_covered": 79.16666666666667, "percent_branches_covered_display": "79.17"}, "missing_lines": [60, 62, 63, 65, 86, 87, 108, 127, 128, 130, 131, 132, 133, 134, 136, 137, 138, 139], "excluded_lines": [], "start_line": 1, "executed_branches": [[34, 35], [34, 39], [40, 41], [40, 57], [45, 47], [48, 50], [57, 58], [79, 80], [79, 83], [84, 90], [90, 91], [90, 92], [92, 93], [92, 98], [98, 99], [98, 104], [104, 106], [104, 111], [106, 107]], "missing_branches": [[45, 40], [48, 40], [57, 60], [84, 86], [106, 108]]}}}, "app/utils/config_validator.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [7, 8, 9, 12, 19], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [7, 8, 9, 12, 19], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [7, 8, 9, 12, 19], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/utils/config_validator/__init__.py": {"executed_lines": [5, 6, 7, 8, 16], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [5, 6, 7, 8, 16], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 8, 16], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/utils/config_validator/masking.py": {"executed_lines": [6, 11, 12, 13], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[11, 12], [11, 13]], "missing_branches": [], "functions": {"mask_sensitive_value": {"executed_lines": [11, 12, 13], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 6, "executed_branches": [[11, 12], [11, 13]], "missing_branches": []}, "": {"executed_lines": [6], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [6, 11, 12, 13], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[11, 12], [11, 13]], "missing_branches": []}}}, "app/utils/config_validator/providers.py": {"executed_lines": [5, 6, 9, 13, 16, 17, 23, 25, 39, 61, 76, 90, 109, 129, 151, 157, 160, 162, 164, 190, 192, 193, 196, 216, 236, 251, 273, 295, 308, 327], "summary": {"covered_lines": 30, "num_statements": 31, "percent_covered": 93.93939393939394, "percent_covered_display": "93.94", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 96.7741935483871, "percent_statements_covered_display": "96.77", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [194], "excluded_lines": [], "executed_branches": [[193, 196]], "missing_branches": [[193, 194]], "functions": {"get_provider_status": {"executed_lines": [13, 16, 17, 23, 25, 39, 61, 76, 90, 109, 129, 151, 157, 160, 162, 164, 190, 192, 193, 196, 216, 236, 251, 273, 295, 308, 327], "summary": {"covered_lines": 27, "num_statements": 28, "percent_covered": 93.33333333333333, "percent_covered_display": "93.33", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 96.42857142857143, "percent_statements_covered_display": "96.43", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [194], "excluded_lines": [], "start_line": 9, "executed_branches": [[193, 196]], "missing_branches": [[193, 194]]}, "": {"executed_lines": [5, 6, 9], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 9, 13, 16, 17, 23, 25, 39, 61, 76, 90, 109, 129, 151, 157, 160, 162, 164, 190, 192, 193, 196, 216, 236, 251, 273, 295, 308, 327], "summary": {"covered_lines": 30, "num_statements": 31, "percent_covered": 93.93939393939394, "percent_covered_display": "93.94", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 96.7741935483871, "percent_statements_covered_display": "96.77", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [194], "excluded_lines": [], "start_line": 1, "executed_branches": [[193, 196]], "missing_branches": [[193, 194]]}}}, "app/utils/config_validator/settings_display.py": {"executed_lines": [5, 7, 8, 10, 13, 15, 16, 17, 18, 20, 26, 27, 28, 29, 30, 36, 43, 56, 57, 60, 69, 77, 188, 199, 201, 202, 203, 205, 206, 207, 210, 211, 212, 213, 214, 217, 229, 232, 235, 236, 240, 241, 242, 246, 247, 248, 250, 252, 253, 255], "summary": {"covered_lines": 50, "num_statements": 59, "percent_covered": 83.87096774193549, "percent_covered_display": "83.87", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 84.7457627118644, "percent_statements_covered_display": "84.75", "num_branches": 34, "num_partial_branches": 4, "covered_branches": 28, "missing_branches": 6, "percent_branches_covered": 82.3529411764706, "percent_branches_covered_display": "82.35"}, "missing_lines": [44, 45, 47, 48, 49, 51, 52, 53, 54], "excluded_lines": [], "executed_branches": [[16, 17], [16, 57], [17, 16], [17, 18], [20, 26], [20, 43], [26, 27], [26, 43], [27, 28], [27, 36], [43, 56], [202, 203], [202, 205], [206, 207], [210, 211], [210, 255], [212, 213], [212, 252], [213, 214], [232, 235], [232, 240], [240, 241], [240, 246], [241, 242], [241, 246], [247, 248], [247, 250], [252, 253]], "missing_branches": [[43, 44], [47, 48], [47, 51], [206, 210], [213, 212], [252, 210]], "functions": {"dump_all_settings": {"executed_lines": [15, 16, 17, 18, 20, 26, 27, 28, 29, 30, 36, 43, 56, 57], "summary": {"covered_lines": 14, "num_statements": 23, "percent_covered": 67.56756756756756, "percent_covered_display": "67.57", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 60.869565217391305, "percent_statements_covered_display": "60.87", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 11, "missing_branches": 3, "percent_branches_covered": 78.57142857142857, "percent_branches_covered_display": "78.57"}, "missing_lines": [44, 45, 47, 48, 49, 51, 52, 53, 54], "excluded_lines": [], "start_line": 13, "executed_branches": [[16, 17], [16, 57], [17, 16], [17, 18], [20, 26], [20, 43], [26, 27], [26, 43], [27, 28], [27, 36], [43, 56]], "missing_branches": [[43, 44], [47, 48], [47, 51]]}, "get_settings_for_display": {"executed_lines": [69, 77, 188, 199, 201, 202, 203, 205, 206, 207, 210, 211, 212, 213, 214, 217, 229, 232, 235, 236, 240, 241, 242, 246, 247, 248, 250, 252, 253, 255], "summary": {"covered_lines": 30, "num_statements": 30, "percent_covered": 94.0, "percent_covered_display": "94.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 20, "num_partial_branches": 3, "covered_branches": 17, "missing_branches": 3, "percent_branches_covered": 85.0, "percent_branches_covered_display": "85.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 60, "executed_branches": [[202, 203], [202, 205], [206, 207], [210, 211], [210, 255], [212, 213], [212, 252], [213, 214], [232, 235], [232, 240], [240, 241], [240, 246], [241, 242], [241, 246], [247, 248], [247, 250], [252, 253]], "missing_branches": [[206, 210], [213, 212], [252, 210]]}, "": {"executed_lines": [5, 7, 8, 10, 13, 60], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 8, 10, 13, 15, 16, 17, 18, 20, 26, 27, 28, 29, 30, 36, 43, 56, 57, 60, 69, 77, 188, 199, 201, 202, 203, 205, 206, 207, 210, 211, 212, 213, 214, 217, 229, 232, 235, 236, 240, 241, 242, 246, 247, 248, 250, 252, 253, 255], "summary": {"covered_lines": 50, "num_statements": 59, "percent_covered": 83.87096774193549, "percent_covered_display": "83.87", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 84.7457627118644, "percent_statements_covered_display": "84.75", "num_branches": 34, "num_partial_branches": 4, "covered_branches": 28, "missing_branches": 6, "percent_branches_covered": 82.3529411764706, "percent_branches_covered_display": "82.35"}, "missing_lines": [44, 45, 47, 48, 49, 51, 52, 53, 54], "excluded_lines": [], "start_line": 1, "executed_branches": [[16, 17], [16, 57], [17, 16], [17, 18], [20, 26], [20, 43], [26, 27], [26, 43], [27, 28], [27, 36], [43, 56], [202, 203], [202, 205], [206, 207], [210, 211], [210, 255], [212, 213], [212, 252], [213, 214], [232, 235], [232, 240], [240, 241], [240, 246], [241, 242], [241, 246], [247, 248], [247, 250], [252, 253]], "missing_branches": [[43, 44], [47, 48], [47, 51], [206, 210], [213, 212], [252, 210]]}}}, "app/utils/config_validator/validators.py": {"executed_lines": [3, 4, 5, 7, 9, 12, 14, 17, 18, 19, 23, 31, 32, 33, 34, 36, 39, 41, 44, 69, 72, 74, 77, 78, 83, 84, 87, 88, 93, 94, 97, 98, 99, 101, 102, 105, 106, 108, 111, 112, 113, 114, 115, 116, 119, 120, 121, 122, 123, 124, 127, 128, 129, 130, 131, 132, 133, 134, 137, 138, 139, 140, 141, 142, 143, 144, 147, 148, 149, 150, 151, 152, 155, 156, 157, 158, 159, 160, 163, 164, 169, 170, 173, 174, 175, 176, 178, 181, 183, 186, 187, 205, 208, 210, 213, 215, 217, 220, 224, 225, 228, 231, 232, 233, 238, 239, 240, 241, 246, 247, 248, 253], "summary": {"covered_lines": 112, "num_statements": 145, "percent_covered": 65.19823788546256, "percent_covered_display": "65.20", "missing_lines": 33, "excluded_lines": 0, "percent_statements_covered": 77.24137931034483, "percent_statements_covered_display": "77.24", "num_branches": 82, "num_partial_branches": 34, "covered_branches": 36, "missing_branches": 46, "percent_branches_covered": 43.90243902439025, "percent_branches_covered_display": "43.90"}, "missing_lines": [20, 24, 26, 27, 28, 46, 47, 48, 49, 52, 56, 62, 63, 66, 67, 103, 189, 191, 193, 195, 196, 197, 198, 199, 200, 202, 203, 206, 221, 226, 235, 243, 250], "excluded_lines": [], "executed_branches": [[17, 18], [19, 23], [23, 31], [31, 32], [33, 34], [44, 69], [78, 83], [88, 93], [98, 99], [102, 105], [105, 106], [112, 113], [114, 115], [120, 121], [122, 123], [128, 129], [130, 131], [132, 133], [138, 139], [140, 141], [142, 143], [148, 149], [150, 151], [156, 157], [158, 159], [164, 169], [174, 175], [186, 187], [205, 208], [220, 224], [225, 228], [232, 233], [239, 240], [239, 246], [240, 241], [247, 248]], "missing_branches": [[17, 19], [19, 20], [23, 24], [31, 33], [33, 36], [44, 46], [46, 47], [46, 48], [48, 49], [48, 52], [62, 63], [62, 66], [66, 67], [66, 69], [78, 84], [88, 94], [98, 101], [102, 103], [105, 108], [112, 114], [114, 116], [120, 122], [122, 124], [128, 130], [130, 132], [132, 134], [138, 140], [140, 142], [142, 144], [148, 150], [150, 152], [156, 158], [158, 160], [164, 170], [174, 176], [186, 189], [195, 196], [195, 205], [197, 195], [197, 198], [205, 206], [220, 221], [225, 226], [232, 235], [240, 243], [247, 250]], "functions": {"validate_email_config": {"executed_lines": [14, 17, 18, 19, 23, 31, 32, 33, 34, 36], "summary": {"covered_lines": 10, "num_statements": 15, "percent_covered": 60.0, "percent_covered_display": "60.00", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 66.66666666666667, "percent_statements_covered_display": "66.67", "num_branches": 10, "num_partial_branches": 5, "covered_branches": 5, "missing_branches": 5, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [20, 24, 26, 27, 28], "excluded_lines": [], "start_line": 12, "executed_branches": [[17, 18], [19, 23], [23, 31], [31, 32], [33, 34]], "missing_branches": [[17, 19], [19, 20], [23, 24], [31, 33], [33, 36]]}, "validate_auth_config": {"executed_lines": [41, 44, 69], "summary": {"covered_lines": 3, "num_statements": 13, "percent_covered": 17.391304347826086, "percent_covered_display": "17.39", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 23.076923076923077, "percent_statements_covered_display": "23.08", "num_branches": 10, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 9, "percent_branches_covered": 10.0, "percent_branches_covered_display": "10.00"}, "missing_lines": [46, 47, 48, 49, 52, 56, 62, 63, 66, 67], "excluded_lines": [], "start_line": 39, "executed_branches": [[44, 69]], "missing_branches": [[44, 46], [46, 47], [46, 48], [48, 49], [48, 52], [62, 63], [62, 66], [66, 67], [66, 69]]}, "validate_storage_configs": {"executed_lines": [74, 77, 78, 83, 84, 87, 88, 93, 94, 97, 98, 99, 101, 102, 105, 106, 108, 111, 112, 113, 114, 115, 116, 119, 120, 121, 122, 123, 124, 127, 128, 129, 130, 131, 132, 133, 134, 137, 138, 139, 140, 141, 142, 143, 144, 147, 148, 149, 150, 151, 152, 155, 156, 157, 158, 159, 160, 163, 164, 169, 170, 173, 174, 175, 176, 178], "summary": {"covered_lines": 66, "num_statements": 67, "percent_covered": 79.81651376146789, "percent_covered_display": "79.82", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 98.50746268656717, "percent_statements_covered_display": "98.51", "num_branches": 42, "num_partial_branches": 21, "covered_branches": 21, "missing_branches": 21, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [103], "excluded_lines": [], "start_line": 72, "executed_branches": [[78, 83], [88, 93], [98, 99], [102, 105], [105, 106], [112, 113], [114, 115], [120, 121], [122, 123], [128, 129], [130, 131], [132, 133], [138, 139], [140, 141], [142, 143], [148, 149], [150, 151], [156, 157], [158, 159], [164, 169], [174, 175]], "missing_branches": [[78, 84], [88, 94], [98, 101], [102, 103], [105, 108], [112, 114], [114, 116], [120, 122], [122, 124], [128, 130], [130, 132], [132, 134], [138, 140], [140, 142], [142, 144], [148, 150], [150, 152], [156, 158], [158, 160], [164, 170], [174, 176]]}, "validate_notification_config": {"executed_lines": [183, 186, 187, 205, 208, 210], "summary": {"covered_lines": 6, "num_statements": 18, "percent_covered": 30.76923076923077, "percent_covered_display": "30.77", "missing_lines": 12, "excluded_lines": 0, "percent_statements_covered": 33.333333333333336, "percent_statements_covered_display": "33.33", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 6, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [189, 191, 193, 195, 196, 197, 198, 199, 200, 202, 203, 206], "excluded_lines": [], "start_line": 181, "executed_branches": [[186, 187], [205, 208]], "missing_branches": [[186, 189], [195, 196], [195, 205], [197, 195], [197, 198], [205, 206]]}, "check_all_configs": {"executed_lines": [215, 217, 220, 224, 225, 228, 231, 232, 233, 238, 239, 240, 241, 246, 247, 248, 253], "summary": {"covered_lines": 17, "num_statements": 22, "percent_covered": 70.58823529411765, "percent_covered_display": "70.59", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 77.27272727272727, "percent_statements_covered_display": "77.27", "num_branches": 12, "num_partial_branches": 5, "covered_branches": 7, "missing_branches": 5, "percent_branches_covered": 58.333333333333336, "percent_branches_covered_display": "58.33"}, "missing_lines": [221, 226, 235, 243, 250], "excluded_lines": [], "start_line": 213, "executed_branches": [[220, 224], [225, 228], [232, 233], [239, 240], [239, 246], [240, 241], [247, 248]], "missing_branches": [[220, 221], [225, 226], [232, 235], [240, 243], [247, 250]]}, "": {"executed_lines": [3, 4, 5, 7, 9, 12, 39, 72, 181, 213], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [3, 4, 5, 7, 9, 12, 14, 17, 18, 19, 23, 31, 32, 33, 34, 36, 39, 41, 44, 69, 72, 74, 77, 78, 83, 84, 87, 88, 93, 94, 97, 98, 99, 101, 102, 105, 106, 108, 111, 112, 113, 114, 115, 116, 119, 120, 121, 122, 123, 124, 127, 128, 129, 130, 131, 132, 133, 134, 137, 138, 139, 140, 141, 142, 143, 144, 147, 148, 149, 150, 151, 152, 155, 156, 157, 158, 159, 160, 163, 164, 169, 170, 173, 174, 175, 176, 178, 181, 183, 186, 187, 205, 208, 210, 213, 215, 217, 220, 224, 225, 228, 231, 232, 233, 238, 239, 240, 241, 246, 247, 248, 253], "summary": {"covered_lines": 112, "num_statements": 145, "percent_covered": 65.19823788546256, "percent_covered_display": "65.20", "missing_lines": 33, "excluded_lines": 0, "percent_statements_covered": 77.24137931034483, "percent_statements_covered_display": "77.24", "num_branches": 82, "num_partial_branches": 34, "covered_branches": 36, "missing_branches": 46, "percent_branches_covered": 43.90243902439025, "percent_branches_covered_display": "43.90"}, "missing_lines": [20, 24, 26, 27, 28, 46, 47, 48, 49, 52, 56, 62, 63, 66, 67, 103, 189, 191, 193, 195, 196, 197, 198, 199, 200, 202, 203, 206, 221, 226, 235, 243, 250], "excluded_lines": [], "start_line": 1, "executed_branches": [[17, 18], [19, 23], [23, 31], [31, 32], [33, 34], [44, 69], [78, 83], [88, 93], [98, 99], [102, 105], [105, 106], [112, 113], [114, 115], [120, 121], [122, 123], [128, 129], [130, 131], [132, 133], [138, 139], [140, 141], [142, 143], [148, 149], [150, 151], [156, 157], [158, 159], [164, 169], [174, 175], [186, 187], [205, 208], [220, 224], [225, 228], [232, 233], [239, 240], [239, 246], [240, 241], [247, 248]], "missing_branches": [[17, 19], [19, 20], [23, 24], [31, 33], [33, 36], [44, 46], [46, 47], [46, 48], [48, 49], [48, 52], [62, 63], [62, 66], [66, 67], [66, 69], [78, 84], [88, 94], [98, 101], [102, 103], [105, 108], [112, 114], [114, 116], [120, 122], [122, 124], [128, 130], [130, 132], [132, 134], [138, 140], [140, 142], [142, 144], [148, 150], [150, 152], [156, 158], [158, 160], [164, 170], [174, 176], [186, 189], [195, 196], [195, 205], [197, 195], [197, 198], [205, 206], [220, 221], [225, 226], [232, 235], [240, 243], [247, 250]]}}}, "app/utils/encryption.py": {"executed_lines": [8, 9, 10, 11, 13, 16, 19, 33, 34, 35, 37, 41, 44, 45, 47, 48, 61, 64, 74, 75, 77, 79, 81, 82, 84, 85, 87, 88, 89, 91, 94, 104, 105, 108, 110, 112, 114, 115, 116, 118, 120, 121, 122, 123, 124, 125, 128, 138, 141, 148], "summary": {"covered_lines": 50, "num_statements": 56, "percent_covered": 91.17647058823529, "percent_covered_display": "91.18", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 89.28571428571429, "percent_statements_covered_display": "89.29", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 12, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [50, 51, 56, 57, 58, 59], "excluded_lines": [], "executed_branches": [[33, 34], [33, 61], [74, 75], [74, 77], [79, 81], [79, 84], [104, 105], [104, 108], [108, 110], [108, 112], [114, 115], [114, 118]], "missing_branches": [], "functions": {"_get_cipher_suite": {"executed_lines": [33, 34, 35, 37, 41, 44, 45, 47, 48, 61], "summary": {"covered_lines": 10, "num_statements": 16, "percent_covered": 66.66666666666667, "percent_covered_display": "66.67", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 62.5, "percent_statements_covered_display": "62.50", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [50, 51, 56, 57, 58, 59], "excluded_lines": [], "start_line": 19, "executed_branches": [[33, 34], [33, 61]], "missing_branches": []}, "encrypt_value": {"executed_lines": [74, 75, 77, 79, 81, 82, 84, 85, 87, 88, 89, 91], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 64, "executed_branches": [[74, 75], [74, 77], [79, 81], [79, 84]], "missing_branches": []}, "decrypt_value": {"executed_lines": [104, 105, 108, 110, 112, 114, 115, 116, 118, 120, 121, 122, 123, 124, 125], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 94, "executed_branches": [[104, 105], [104, 108], [108, 110], [108, 112], [114, 115], [114, 118]], "missing_branches": []}, "is_encrypted": {"executed_lines": [138], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 128, "executed_branches": [], "missing_branches": []}, "is_encryption_available": {"executed_lines": [148], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 141, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [8, 9, 10, 11, 13, 16, 19, 64, 94, 128, 141], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [8, 9, 10, 11, 13, 16, 19, 33, 34, 35, 37, 41, 44, 45, 47, 48, 61, 64, 74, 75, 77, 79, 81, 82, 84, 85, 87, 88, 89, 91, 94, 104, 105, 108, 110, 112, 114, 115, 116, 118, 120, 121, 122, 123, 124, 125, 128, 138, 141, 148], "summary": {"covered_lines": 50, "num_statements": 56, "percent_covered": 91.17647058823529, "percent_covered_display": "91.18", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 89.28571428571429, "percent_statements_covered_display": "89.29", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 12, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [50, 51, 56, 57, 58, 59], "excluded_lines": [], "start_line": 1, "executed_branches": [[33, 34], [33, 61], [74, 75], [74, 77], [79, 81], [79, 84], [104, 105], [104, 108], [108, 110], [108, 112], [114, 115], [114, 118]], "missing_branches": []}}}, "app/utils/file_operations.py": {"executed_lines": [1, 4, 9, 10, 11, 12, 13, 14, 15, 16], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[13, 14], [13, 15]], "missing_branches": [], "functions": {"hash_file": {"executed_lines": [9, 10, 11, 12, 13, 14, 15, 16], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 4, "executed_branches": [[13, 14], [13, 15]], "missing_branches": []}, "": {"executed_lines": [1, 4], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [1, 4, 9, 10, 11, 12, 13, 14, 15, 16], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[13, 14], [13, 15]], "missing_branches": []}}}, "app/utils/file_queries.py": {"executed_lines": [8, 10, 11, 13, 16, 50, 51, 55, 57, 80, 81, 84, 86, 88, 89, 90, 92, 93, 94, 96, 97, 98, 101, 104, 107, 116, 119, 123], "summary": {"covered_lines": 28, "num_statements": 29, "percent_covered": 93.02325581395348, "percent_covered_display": "93.02", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 96.55172413793103, "percent_statements_covered_display": "96.55", "num_branches": 14, "num_partial_branches": 2, "covered_branches": 12, "missing_branches": 2, "percent_branches_covered": 85.71428571428571, "percent_branches_covered_display": "85.71"}, "missing_lines": [121], "excluded_lines": [], "executed_branches": [[50, 51], [50, 55], [80, 81], [86, 88], [86, 90], [90, 92], [90, 94], [94, 96], [94, 98], [98, 101], [98, 119], [119, 123]], "missing_branches": [[80, 84], [119, 121]], "functions": {"apply_status_filter": {"executed_lines": [50, 51, 55, 57, 80, 81, 84, 86, 88, 89, 90, 92, 93, 94, 96, 97, 98, 101, 104, 107, 116, 119, 123], "summary": {"covered_lines": 23, "num_statements": 24, "percent_covered": 92.10526315789474, "percent_covered_display": "92.11", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 95.83333333333333, "percent_statements_covered_display": "95.83", "num_branches": 14, "num_partial_branches": 2, "covered_branches": 12, "missing_branches": 2, "percent_branches_covered": 85.71428571428571, "percent_branches_covered_display": "85.71"}, "missing_lines": [121], "excluded_lines": [], "start_line": 16, "executed_branches": [[50, 51], [50, 55], [80, 81], [86, 88], [86, 90], [90, 92], [90, 94], [94, 96], [94, 98], [98, 101], [98, 119], [119, 123]], "missing_branches": [[80, 84], [119, 121]]}, "": {"executed_lines": [8, 10, 11, 13, 16], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [8, 10, 11, 13, 16, 50, 51, 55, 57, 80, 81, 84, 86, 88, 89, 90, 92, 93, 94, 96, 97, 98, 101, 104, 107, 116, 119, 123], "summary": {"covered_lines": 28, "num_statements": 29, "percent_covered": 93.02325581395348, "percent_covered_display": "93.02", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 96.55172413793103, "percent_statements_covered_display": "96.55", "num_branches": 14, "num_partial_branches": 2, "covered_branches": 12, "missing_branches": 2, "percent_branches_covered": 85.71428571428571, "percent_branches_covered_display": "85.71"}, "missing_lines": [121], "excluded_lines": [], "start_line": 1, "executed_branches": [[50, 51], [50, 55], [80, 81], [86, 88], [86, 90], [90, 92], [90, 94], [94, 96], [94, 98], [98, 101], [98, 119], [119, 123]], "missing_branches": [[80, 84], [119, 121]]}}}, "app/utils/file_splitting.py": {"executed_lines": [8, 9, 10, 11, 13, 15, 18, 53, 54, 57, 58, 59, 62, 63, 64, 65, 66, 67, 69, 74, 76, 77, 78, 79, 81, 83, 85, 86, 87, 90, 91, 92, 93, 95, 99, 119, 139, 140, 141, 142, 143, 144, 146, 147, 150, 161, 162, 164, 165, 167, 168], "summary": {"covered_lines": 51, "num_statements": 73, "percent_covered": 69.89247311827957, "percent_covered_display": "69.89", "missing_lines": 22, "excluded_lines": 0, "percent_statements_covered": 69.86301369863014, "percent_statements_covered_display": "69.86", "num_branches": 20, "num_partial_branches": 4, "covered_branches": 14, "missing_branches": 6, "percent_branches_covered": 70.0, "percent_branches_covered_display": "70.00"}, "missing_lines": [70, 71, 102, 103, 104, 107, 108, 109, 111, 112, 115, 116, 117, 118, 122, 127, 128, 129, 130, 133, 134, 135], "excluded_lines": [], "executed_branches": [[53, 54], [53, 57], [57, 58], [57, 59], [69, 74], [83, 85], [83, 139], [99, 119], [119, 83], [139, 140], [161, 162], [161, 164], [164, 165], [164, 167]], "missing_branches": [[69, 70], [99, 102], [103, 104], [103, 107], [119, 122], [139, 146]], "functions": {"split_pdf_by_size": {"executed_lines": [53, 54, 57, 58, 59, 62, 63, 64, 65, 66, 67, 69, 74, 76, 77, 78, 79, 81, 83, 85, 86, 87, 90, 91, 92, 93, 95, 99, 119, 139, 140, 141, 142, 143, 144, 146, 147], "summary": {"covered_lines": 37, "num_statements": 59, "percent_covered": 62.666666666666664, "percent_covered_display": "62.67", "missing_lines": 22, "excluded_lines": 0, "percent_statements_covered": 62.71186440677966, "percent_statements_covered_display": "62.71", "num_branches": 16, "num_partial_branches": 4, "covered_branches": 10, "missing_branches": 6, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62.50"}, "missing_lines": [70, 71, 102, 103, 104, 107, 108, 109, 111, 112, 115, 116, 117, 118, 122, 127, 128, 129, 130, 133, 134, 135], "excluded_lines": [], "start_line": 18, "executed_branches": [[53, 54], [53, 57], [57, 58], [57, 59], [69, 74], [83, 85], [83, 139], [99, 119], [119, 83], [139, 140]], "missing_branches": [[69, 70], [99, 102], [103, 104], [103, 107], [119, 122], [139, 146]]}, "should_split_file": {"executed_lines": [161, 162, 164, 165, 167, 168], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 150, "executed_branches": [[161, 162], [161, 164], [164, 165], [164, 167]], "missing_branches": []}, "": {"executed_lines": [8, 9, 10, 11, 13, 15, 18, 150], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [8, 9, 10, 11, 13, 15, 18, 53, 54, 57, 58, 59, 62, 63, 64, 65, 66, 67, 69, 74, 76, 77, 78, 79, 81, 83, 85, 86, 87, 90, 91, 92, 93, 95, 99, 119, 139, 140, 141, 142, 143, 144, 146, 147, 150, 161, 162, 164, 165, 167, 168], "summary": {"covered_lines": 51, "num_statements": 73, "percent_covered": 69.89247311827957, "percent_covered_display": "69.89", "missing_lines": 22, "excluded_lines": 0, "percent_statements_covered": 69.86301369863014, "percent_statements_covered_display": "69.86", "num_branches": 20, "num_partial_branches": 4, "covered_branches": 14, "missing_branches": 6, "percent_branches_covered": 70.0, "percent_branches_covered_display": "70.00"}, "missing_lines": [70, 71, 102, 103, 104, 107, 108, 109, 111, 112, 115, 116, 117, 118, 122, 127, 128, 129, 130, 133, 134, 135], "excluded_lines": [], "start_line": 1, "executed_branches": [[53, 54], [53, 57], [57, 58], [57, 59], [69, 74], [83, 85], [83, 139], [99, 119], [119, 83], [139, 140], [161, 162], [161, 164], [164, 165], [164, 167]], "missing_branches": [[69, 70], [99, 102], [103, 104], [103, 107], [119, 122], [139, 146]]}}}, "app/utils/file_status.py": {"executed_lines": [5, 7, 9, 10, 13, 26, 27, 36, 39, 46, 54, 74, 80, 82, 105, 106, 109, 116, 117, 118, 119, 120, 123, 124, 125, 133, 134, 135, 138, 139, 140, 141, 142, 144, 147, 148, 149, 150, 151, 152, 157, 159, 166, 169], "summary": {"covered_lines": 44, "num_statements": 65, "percent_covered": 60.824742268041234, "percent_covered_display": "60.82", "missing_lines": 21, "excluded_lines": 0, "percent_statements_covered": 67.6923076923077, "percent_statements_covered_display": "67.69", "num_branches": 32, "num_partial_branches": 5, "covered_branches": 15, "missing_branches": 17, "percent_branches_covered": 46.875, "percent_branches_covered_display": "46.88"}, "missing_lines": [28, 126, 132, 154, 182, 183, 187, 188, 189, 190, 193, 196, 199, 202, 203, 204, 205, 206, 207, 209, 211], "excluded_lines": [], "executed_branches": [[27, 36], [105, 106], [117, 118], [117, 123], [118, 119], [124, 125], [124, 166], [125, 133], [134, 135], [134, 138], [147, 148], [147, 149], [149, 150], [149, 151], [151, 152]], "missing_branches": [[27, 28], [105, 109], [118, 120], [125, 126], [151, 154], [182, 183], [182, 187], [188, 189], [188, 193], [189, 188], [189, 190], [202, 203], [202, 204], [204, 205], [204, 206], [206, 207], [206, 209]], "functions": {"get_file_processing_status": {"executed_lines": [26, 27, 36, 39, 46], "summary": {"covered_lines": 5, "num_statements": 6, "percent_covered": 75.0, "percent_covered_display": "75.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 83.33333333333333, "percent_statements_covered_display": "83.33", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [28], "excluded_lines": [], "start_line": 13, "executed_branches": [[27, 36]], "missing_branches": [[27, 28]]}, "get_files_processing_status": {"executed_lines": [74, 80, 82, 105, 106, 109, 116, 117, 118, 119, 120, 123, 124, 125, 133, 134, 135, 138, 139, 140, 141, 142, 144, 147, 148, 149, 150, 151, 152, 157, 159, 166], "summary": {"covered_lines": 32, "num_statements": 35, "percent_covered": 86.79245283018868, "percent_covered_display": "86.79", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 91.42857142857143, "percent_statements_covered_display": "91.43", "num_branches": 18, "num_partial_branches": 4, "covered_branches": 14, "missing_branches": 4, "percent_branches_covered": 77.77777777777777, "percent_branches_covered_display": "77.78"}, "missing_lines": [126, 132, 154], "excluded_lines": [], "start_line": 54, "executed_branches": [[105, 106], [117, 118], [117, 123], [118, 119], [124, 125], [124, 166], [125, 133], [134, 135], [134, 138], [147, 148], [147, 149], [149, 150], [149, 151], [151, 152]], "missing_branches": [[105, 109], [118, 120], [125, 126], [151, 154]]}, "_compute_status_from_logs": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 17, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 17, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 12, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [182, 183, 187, 188, 189, 190, 193, 196, 199, 202, 203, 204, 205, 206, 207, 209, 211], "excluded_lines": [], "start_line": 169, "executed_branches": [], "missing_branches": [[182, 183], [182, 187], [188, 189], [188, 193], [189, 188], [189, 190], [202, 203], [202, 204], [204, 205], [204, 206], [206, 207], [206, 209]]}, "": {"executed_lines": [5, 7, 9, 10, 13, 54, 169], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 9, 10, 13, 26, 27, 36, 39, 46, 54, 74, 80, 82, 105, 106, 109, 116, 117, 118, 119, 120, 123, 124, 125, 133, 134, 135, 138, 139, 140, 141, 142, 144, 147, 148, 149, 150, 151, 152, 157, 159, 166, 169], "summary": {"covered_lines": 44, "num_statements": 65, "percent_covered": 60.824742268041234, "percent_covered_display": "60.82", "missing_lines": 21, "excluded_lines": 0, "percent_statements_covered": 67.6923076923077, "percent_statements_covered_display": "67.69", "num_branches": 32, "num_partial_branches": 5, "covered_branches": 15, "missing_branches": 17, "percent_branches_covered": 46.875, "percent_branches_covered_display": "46.88"}, "missing_lines": [28, 126, 132, 154, 182, 183, 187, 188, 189, 190, 193, 196, 199, 202, 203, 204, 205, 206, 207, 209, 211], "excluded_lines": [], "start_line": 1, "executed_branches": [[27, 36], [105, 106], [117, 118], [117, 123], [118, 119], [124, 125], [124, 166], [125, 133], [134, 135], [134, 138], [147, 148], [147, 149], [149, 150], [149, 151], [151, 152]], "missing_branches": [[27, 28], [105, 109], [118, 120], [125, 126], [151, 154], [182, 183], [182, 187], [188, 189], [188, 193], [189, 188], [189, 190], [202, 203], [202, 204], [204, 205], [204, 206], [206, 207], [206, 209]]}}}, "app/utils/filename_utils.py": {"executed_lines": [1, 2, 3, 4, 5, 6, 8, 11, 24, 25, 27, 28, 29, 30, 33, 34, 37, 38, 39, 41, 42, 43, 46, 47, 48, 50, 51, 52, 72, 96, 97, 98, 101, 102, 104, 105, 106, 107, 108, 111, 123, 141, 145, 149, 152, 153, 156, 159, 160, 162, 165, 173, 174, 177, 178, 181, 184, 185, 187, 188, 191, 192, 194, 196, 198, 201, 203], "summary": {"covered_lines": 67, "num_statements": 84, "percent_covered": 79.46428571428571, "percent_covered_display": "79.46", "missing_lines": 17, "excluded_lines": 0, "percent_statements_covered": 79.76190476190476, "percent_statements_covered_display": "79.76", "num_branches": 28, "num_partial_branches": 2, "covered_branches": 22, "missing_branches": 6, "percent_branches_covered": 78.57142857142857, "percent_branches_covered_display": "78.57"}, "missing_lines": [55, 56, 57, 58, 59, 60, 61, 62, 65, 66, 67, 69, 113, 114, 115, 116, 120], "excluded_lines": [], "executed_branches": [[24, 25], [24, 27], [33, 34], [33, 37], [41, 42], [41, 46], [50, 51], [97, 98], [97, 101], [106, 107], [106, 108], [111, 102], [159, 160], [159, 162], [177, 178], [177, 181], [185, 187], [185, 191], [191, 192], [191, 198], [192, 194], [192, 196]], "missing_branches": [[50, 55], [56, 57], [56, 65], [59, 60], [59, 62], [111, 113]], "functions": {"get_unique_filename": {"executed_lines": [24, 25, 27, 28, 29, 30, 33, 34, 37, 38, 39, 41, 42, 43, 46, 47, 48, 50, 51, 52], "summary": {"covered_lines": 20, "num_statements": 32, "percent_covered": 61.36363636363637, "percent_covered_display": "61.36", "missing_lines": 12, "excluded_lines": 0, "percent_statements_covered": 62.5, "percent_statements_covered_display": "62.50", "num_branches": 12, "num_partial_branches": 1, "covered_branches": 7, "missing_branches": 5, "percent_branches_covered": 58.333333333333336, "percent_branches_covered_display": "58.33"}, "missing_lines": [55, 56, 57, 58, 59, 60, 61, 62, 65, 66, 67, 69], "excluded_lines": [], "start_line": 11, "executed_branches": [[24, 25], [24, 27], [33, 34], [33, 37], [41, 42], [41, 46], [50, 51]], "missing_branches": [[50, 55], [56, 57], [56, 65], [59, 60], [59, 62]]}, "get_unique_filepath_with_counter": {"executed_lines": [96, 97, 98, 101, 102, 104, 105, 106, 107, 108, 111], "summary": {"covered_lines": 11, "num_statements": 16, "percent_covered": 72.72727272727273, "percent_covered_display": "72.73", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 68.75, "percent_statements_covered_display": "68.75", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [113, 114, 115, 116, 120], "excluded_lines": [], "start_line": 72, "executed_branches": [[97, 98], [97, 101], [106, 107], [106, 108], [111, 102]], "missing_branches": [[111, 113]]}, "sanitize_filename": {"executed_lines": [141, 145, 149, 152, 153, 156, 159, 160, 162], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 123, "executed_branches": [[159, 160], [159, 162]], "missing_branches": []}, "extract_remote_path": {"executed_lines": [173, 174, 177, 178, 181, 184, 185, 187, 188, 191, 192, 194, 196, 198, 201, 203], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 165, "executed_branches": [[177, 178], [177, 181], [185, 187], [185, 191], [191, 192], [191, 198], [192, 194], [192, 196]], "missing_branches": []}, "": {"executed_lines": [1, 2, 3, 4, 5, 6, 8, 11, 72, 123, 165], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [1, 2, 3, 4, 5, 6, 8, 11, 24, 25, 27, 28, 29, 30, 33, 34, 37, 38, 39, 41, 42, 43, 46, 47, 48, 50, 51, 52, 72, 96, 97, 98, 101, 102, 104, 105, 106, 107, 108, 111, 123, 141, 145, 149, 152, 153, 156, 159, 160, 162, 165, 173, 174, 177, 178, 181, 184, 185, 187, 188, 191, 192, 194, 196, 198, 201, 203], "summary": {"covered_lines": 67, "num_statements": 84, "percent_covered": 79.46428571428571, "percent_covered_display": "79.46", "missing_lines": 17, "excluded_lines": 0, "percent_statements_covered": 79.76190476190476, "percent_statements_covered_display": "79.76", "num_branches": 28, "num_partial_branches": 2, "covered_branches": 22, "missing_branches": 6, "percent_branches_covered": 78.57142857142857, "percent_branches_covered_display": "78.57"}, "missing_lines": [55, 56, 57, 58, 59, 60, 61, 62, 65, 66, 67, 69, 113, 114, 115, 116, 120], "excluded_lines": [], "start_line": 1, "executed_branches": [[24, 25], [24, 27], [33, 34], [33, 37], [41, 42], [41, 46], [50, 51], [97, 98], [97, 101], [106, 107], [106, 108], [111, 102], [159, 160], [159, 162], [177, 178], [177, 181], [185, 187], [185, 191], [191, 192], [191, 198], [192, 194], [192, 196]], "missing_branches": [[50, 55], [56, 57], [56, 65], [59, 60], [59, 62], [111, 113]]}}}, "app/utils/logging.py": {"executed_lines": [1, 2, 3, 4, 6, 7, 10, 19, 20, 21, 22, 24, 26, 27, 29, 30, 31, 32, 33, 34, 35, 39, 41, 42, 43, 47, 48, 49, 52, 55, 56, 58, 59, 60, 63, 82, 83, 84, 85, 88, 90, 98, 101, 103, 109, 111, 124, 125, 127, 128, 129, 132], "summary": {"covered_lines": 52, "num_statements": 59, "percent_covered": 85.18518518518519, "percent_covered_display": "85.19", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 88.13559322033899, "percent_statements_covered_display": "88.14", "num_branches": 22, "num_partial_branches": 5, "covered_branches": 17, "missing_branches": 5, "percent_branches_covered": 77.27272727272727, "percent_branches_covered_display": "77.27"}, "missing_lines": [36, 37, 86, 113, 121, 126, 130], "excluded_lines": [], "executed_branches": [[29, -24], [29, 30], [33, -24], [33, 34], [55, -52], [55, 56], [58, 59], [82, 83], [82, 88], [85, 88], [101, 103], [101, 132], [111, 124], [125, 127], [127, 128], [127, 129], [129, 132]], "missing_branches": [[58, 60], [85, 86], [111, 113], [125, 126], [129, 130]], "functions": {"TaskLogCollector.__init__": {"executed_lines": [20, 21, 22], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 19, "executed_branches": [], "missing_branches": []}, "TaskLogCollector.emit": {"executed_lines": [26, 27, 29, 30, 31, 32, 33, 34, 35], "summary": {"covered_lines": 9, "num_statements": 11, "percent_covered": 86.66666666666667, "percent_covered_display": "86.67", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 81.81818181818181, "percent_statements_covered_display": "81.82", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [36, 37], "excluded_lines": [], "start_line": 24, "executed_branches": [[29, -24], [29, 30], [33, -24], [33, 34]], "missing_branches": []}, "TaskLogCollector.drain": {"executed_lines": [41, 42, 43], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 39, "executed_branches": [], "missing_branches": []}, "_ensure_collector_installed": {"executed_lines": [55, 56, 58, 59, 60], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 88.88888888888889, "percent_covered_display": "88.89", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 52, "executed_branches": [[55, -52], [55, 56], [58, 59]], "missing_branches": [[58, 60]]}, "log_task_progress": {"executed_lines": [82, 83, 84, 85, 88, 90, 98, 101, 103, 109, 111, 124, 125, 127, 128, 129, 132], "summary": {"covered_lines": 17, "num_statements": 22, "percent_covered": 75.0, "percent_covered_display": "75.00", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 77.27272727272727, "percent_statements_covered_display": "77.27", "num_branches": 14, "num_partial_branches": 4, "covered_branches": 10, "missing_branches": 4, "percent_branches_covered": 71.42857142857143, "percent_branches_covered_display": "71.43"}, "missing_lines": [86, 113, 121, 126, 130], "excluded_lines": [], "start_line": 63, "executed_branches": [[82, 83], [82, 88], [85, 88], [101, 103], [101, 132], [111, 124], [125, 127], [127, 128], [127, 129], [129, 132]], "missing_branches": [[85, 86], [111, 113], [125, 126], [129, 130]]}, "": {"executed_lines": [1, 2, 3, 4, 6, 7, 10, 19, 24, 39, 47, 48, 49, 52, 63], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"TaskLogCollector": {"executed_lines": [20, 21, 22, 26, 27, 29, 30, 31, 32, 33, 34, 35, 41, 42, 43], "summary": {"covered_lines": 15, "num_statements": 17, "percent_covered": 90.47619047619048, "percent_covered_display": "90.48", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 88.23529411764706, "percent_statements_covered_display": "88.24", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [36, 37], "excluded_lines": [], "start_line": 10, "executed_branches": [[29, -24], [29, 30], [33, -24], [33, 34]], "missing_branches": []}, "": {"executed_lines": [1, 2, 3, 4, 6, 7, 10, 19, 24, 39, 47, 48, 49, 52, 55, 56, 58, 59, 60, 63, 82, 83, 84, 85, 88, 90, 98, 101, 103, 109, 111, 124, 125, 127, 128, 129, 132], "summary": {"covered_lines": 37, "num_statements": 42, "percent_covered": 83.33333333333333, "percent_covered_display": "83.33", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 88.0952380952381, "percent_statements_covered_display": "88.10", "num_branches": 18, "num_partial_branches": 5, "covered_branches": 13, "missing_branches": 5, "percent_branches_covered": 72.22222222222223, "percent_branches_covered_display": "72.22"}, "missing_lines": [86, 113, 121, 126, 130], "excluded_lines": [], "start_line": 1, "executed_branches": [[55, -52], [55, 56], [58, 59], [82, 83], [82, 88], [85, 88], [101, 103], [101, 132], [111, 124], [125, 127], [127, 128], [127, 129], [129, 132]], "missing_branches": [[58, 60], [85, 86], [111, 113], [125, 126], [129, 130]]}}}, "app/utils/migrate_logs_to_steps.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 115, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 115, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 48, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 48, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [8, 9, 11, 13, 15, 18, 40, 42, 44, 51, 52, 53, 56, 59, 60, 66, 68, 73, 76, 77, 78, 79, 80, 82, 83, 86, 87, 95, 96, 98, 99, 100, 107, 108, 110, 111, 112, 113, 115, 118, 139, 141, 142, 143, 146, 147, 155, 157, 158, 159, 161, 163, 165, 166, 167, 168, 170, 172, 173, 174, 175, 176, 178, 180, 181, 186, 189, 209, 220, 221, 223, 224, 226, 228, 229, 232, 233, 234, 238, 239, 241, 242, 243, 245, 246, 247, 248, 250, 257, 260, 278, 281, 285, 286, 287, 288, 290, 291, 294, 295, 298, 301, 302, 303, 304, 305, 308, 309, 311, 312, 315, 318, 319, 320, 323], "excluded_lines": [], "executed_branches": [], "missing_branches": [[51, 52], [51, 56], [59, 60], [59, 98], [66, 68], [66, 86], [68, 73], [68, 82], [98, 99], [98, 107], [141, 142], [141, 186], [146, 147], [146, 155], [155, 157], [155, 161], [157, 158], [157, 159], [161, 163], [161, 170], [163, 165], [163, 166], [170, 172], [170, 178], [172, 173], [172, 174], [178, 141], [178, 180], [180, 141], [180, 181], [232, 233], [232, 250], [238, 232], [238, 239], [241, 242], [241, 245], [285, 286], [285, 290], [301, 302], [301, 318], [302, 303], [302, 308], [311, 301], [311, 312], [318, 319], [318, 323], [319, 318], [319, 320]], "functions": {"migrate_logs_to_steps": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 33, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 33, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 10, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [40, 42, 44, 51, 52, 53, 56, 59, 60, 66, 68, 73, 76, 77, 78, 79, 80, 82, 83, 86, 87, 95, 96, 98, 99, 100, 107, 108, 110, 111, 112, 113, 115], "excluded_lines": [], "start_line": 18, "executed_branches": [], "missing_branches": [[51, 52], [51, 56], [59, 60], [59, 98], [66, 68], [66, 86], [68, 73], [68, 82], [98, 99], [98, 107]]}, "_parse_logs_to_step_states": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 26, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 26, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 20, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 20, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [139, 141, 142, 143, 146, 147, 155, 157, 158, 159, 161, 163, 165, 166, 167, 168, 170, 172, 173, 174, 175, 176, 178, 180, 181, 186], "excluded_lines": [], "start_line": 118, "executed_branches": [], "missing_branches": [[141, 142], [141, 186], [146, 147], [146, 155], [155, 157], [155, 161], [157, 158], [157, 159], [161, 163], [161, 170], [163, 165], [163, 166], [170, 172], [170, 178], [172, 173], [172, 174], [178, 141], [178, 180], [180, 141], [180, 181]]}, "migrate_all_files": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 22, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 22, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [209, 220, 221, 223, 224, 226, 228, 229, 232, 233, 234, 238, 239, 241, 242, 243, 245, 246, 247, 248, 250, 257], "excluded_lines": [], "start_line": 189, "executed_branches": [], "missing_branches": [[232, 233], [232, 250], [238, 232], [238, 239], [241, 242], [241, 245]]}, "verify_migration": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 25, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 25, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 12, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [278, 281, 285, 286, 287, 288, 290, 291, 294, 295, 298, 301, 302, 303, 304, 305, 308, 309, 311, 312, 315, 318, 319, 320, 323], "excluded_lines": [], "start_line": 260, "executed_branches": [], "missing_branches": [[285, 286], [285, 290], [301, 302], [301, 318], [302, 303], [302, 308], [311, 301], [311, 312], [318, 319], [318, 323], [319, 318], [319, 320]]}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 9, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [8, 9, 11, 13, 15, 18, 118, 189, 260], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 115, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 115, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 48, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 48, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [8, 9, 11, 13, 15, 18, 40, 42, 44, 51, 52, 53, 56, 59, 60, 66, 68, 73, 76, 77, 78, 79, 80, 82, 83, 86, 87, 95, 96, 98, 99, 100, 107, 108, 110, 111, 112, 113, 115, 118, 139, 141, 142, 143, 146, 147, 155, 157, 158, 159, 161, 163, 165, 166, 167, 168, 170, 172, 173, 174, 175, 176, 178, 180, 181, 186, 189, 209, 220, 221, 223, 224, 226, 228, 229, 232, 233, 234, 238, 239, 241, 242, 243, 245, 246, 247, 248, 250, 257, 260, 278, 281, 285, 286, 287, 288, 290, 291, 294, 295, 298, 301, 302, 303, 304, 305, 308, 309, 311, 312, 315, 318, 319, 320, 323], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": [[51, 52], [51, 56], [59, 60], [59, 98], [66, 68], [66, 86], [68, 73], [68, 82], [98, 99], [98, 107], [141, 142], [141, 186], [146, 147], [146, 155], [155, 157], [155, 161], [157, 158], [157, 159], [161, 163], [161, 170], [163, 165], [163, 166], [170, 172], [170, 178], [172, 173], [172, 174], [178, 141], [178, 180], [180, 141], [180, 181], [232, 233], [232, 250], [238, 232], [238, 239], [241, 242], [241, 245], [285, 286], [285, 290], [301, 302], [301, 318], [302, 303], [302, 308], [311, 301], [311, 312], [318, 319], [318, 323], [319, 318], [319, 320]]}}}, "app/utils/notification.py": {"executed_lines": [1, 2, 4, 6, 8, 11, 14, 18, 19, 22, 23, 24, 25, 26, 27, 28, 30, 32, 35, 38, 41, 42, 43, 44, 45, 48, 70, 71, 72, 121, 123, 124, 126, 127, 134, 139, 141, 142, 144, 145, 151, 156, 158, 159, 161, 162, 163, 166, 168, 169, 171, 172, 173, 176, 178, 179, 182, 183, 186, 187, 188, 191, 193, 194, 204], "summary": {"covered_lines": 65, "num_statements": 97, "percent_covered": 63.565891472868216, "percent_covered_display": "63.57", "missing_lines": 32, "excluded_lines": 0, "percent_statements_covered": 67.01030927835052, "percent_statements_covered_display": "67.01", "num_branches": 32, "num_partial_branches": 1, "covered_branches": 17, "missing_branches": 15, "percent_branches_covered": 53.125, "percent_branches_covered_display": "53.12"}, "missing_lines": [74, 75, 78, 79, 80, 81, 82, 83, 84, 87, 88, 89, 91, 92, 94, 95, 96, 97, 99, 100, 101, 103, 104, 105, 107, 109, 110, 112, 114, 116, 117, 118], "excluded_lines": [], "executed_branches": [[18, 19], [18, 32], [22, 23], [22, 30], [23, 24], [23, 32], [70, 71], [123, 124], [123, 126], [141, 142], [141, 144], [158, 159], [158, 161], [168, 169], [168, 171], [178, 179], [178, 182]], "missing_branches": [[70, 74], [79, 80], [79, 81], [81, 82], [81, 83], [83, 84], [83, 87], [87, 88], [87, 91], [94, 95], [94, 107], [99, 100], [99, 103], [109, 110], [109, 112]], "functions": {"init_apprise": {"executed_lines": [18, 19, 22, 23, 24, 25, 26, 27, 28, 30, 32], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 14, "executed_branches": [[18, 19], [18, 32], [22, 23], [22, 30], [23, 24], [23, 32]], "missing_branches": []}, "_mask_sensitive_url": {"executed_lines": [38, 41, 42, 43, 44, 45], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 35, "executed_branches": [], "missing_branches": []}, "send_notification": {"executed_lines": [70, 71, 72], "summary": {"covered_lines": 3, "num_statements": 35, "percent_covered": 7.8431372549019605, "percent_covered_display": "7.84", "missing_lines": 32, "excluded_lines": 0, "percent_statements_covered": 8.571428571428571, "percent_statements_covered_display": "8.57", "num_branches": 16, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 15, "percent_branches_covered": 6.25, "percent_branches_covered_display": "6.25"}, "missing_lines": [74, 75, 78, 79, 80, 81, 82, 83, 84, 87, 88, 89, 91, 92, 94, 95, 96, 97, 99, 100, 101, 103, 104, 105, 107, 109, 110, 112, 114, 116, 117, 118], "excluded_lines": [], "start_line": 48, "executed_branches": [[70, 71]], "missing_branches": [[70, 74], [79, 80], [79, 81], [81, 82], [81, 83], [83, 84], [83, 87], [87, 88], [87, 91], [94, 95], [94, 107], [99, 100], [99, 103], [109, 110], [109, 112]]}, "notify_celery_failure": {"executed_lines": [123, 124, 126, 127, 134], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 121, "executed_branches": [[123, 124], [123, 126]], "missing_branches": []}, "notify_credential_failure": {"executed_lines": [141, 142, 144, 145, 151], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 139, "executed_branches": [[141, 142], [141, 144]], "missing_branches": []}, "notify_startup": {"executed_lines": [158, 159, 161, 162, 163], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 156, "executed_branches": [[158, 159], [158, 161]], "missing_branches": []}, "notify_shutdown": {"executed_lines": [168, 169, 171, 172, 173], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 166, "executed_branches": [[168, 169], [168, 171]], "missing_branches": []}, "notify_file_processed": {"executed_lines": [178, 179, 182, 183, 186, 187, 188, 191, 193, 194, 204], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 176, "executed_branches": [[178, 179], [178, 182]], "missing_branches": []}, "": {"executed_lines": [1, 2, 4, 6, 8, 11, 14, 35, 48, 121, 139, 156, 166, 176], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [1, 2, 4, 6, 8, 11, 14, 18, 19, 22, 23, 24, 25, 26, 27, 28, 30, 32, 35, 38, 41, 42, 43, 44, 45, 48, 70, 71, 72, 121, 123, 124, 126, 127, 134, 139, 141, 142, 144, 145, 151, 156, 158, 159, 161, 162, 163, 166, 168, 169, 171, 172, 173, 176, 178, 179, 182, 183, 186, 187, 188, 191, 193, 194, 204], "summary": {"covered_lines": 65, "num_statements": 97, "percent_covered": 63.565891472868216, "percent_covered_display": "63.57", "missing_lines": 32, "excluded_lines": 0, "percent_statements_covered": 67.01030927835052, "percent_statements_covered_display": "67.01", "num_branches": 32, "num_partial_branches": 1, "covered_branches": 17, "missing_branches": 15, "percent_branches_covered": 53.125, "percent_branches_covered_display": "53.12"}, "missing_lines": [74, 75, 78, 79, 80, 81, 82, 83, 84, 87, 88, 89, 91, 92, 94, 95, 96, 97, 99, 100, 101, 103, 104, 105, 107, 109, 110, 112, 114, 116, 117, 118], "excluded_lines": [], "start_line": 1, "executed_branches": [[18, 19], [18, 32], [22, 23], [22, 30], [23, 24], [23, 32], [70, 71], [123, 124], [123, 126], [141, 142], [141, 144], [158, 159], [158, 161], [168, 169], [168, 171], [178, 179], [178, 182]], "missing_branches": [[70, 74], [79, 80], [79, 81], [81, 82], [81, 83], [83, 84], [83, 87], [87, 88], [87, 91], [94, 95], [94, 107], [99, 100], [99, 103], [109, 110], [109, 112]]}}}, "app/utils/oauth_helper.py": {"executed_lines": [6, 7, 9, 10, 12, 14, 17, 38, 39, 41, 42, 45, 50, 53, 54, 57, 59, 61, 62, 64, 65, 66, 67, 68, 69, 71, 76, 79, 80, 81, 87, 89, 91, 93, 94, 95, 96, 100, 101, 102], "summary": {"covered_lines": 40, "num_statements": 40, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[38, 39], [38, 41], [59, 61], [59, 76], [79, 80], [79, 87]], "missing_branches": [], "functions": {"exchange_oauth_token": {"executed_lines": [38, 39, 41, 42, 45, 50, 53, 54, 57, 59, 61, 62, 64, 65, 66, 67, 68, 69, 71, 76, 79, 80, 81, 87, 89, 91, 93, 94, 95, 96, 100, 101, 102], "summary": {"covered_lines": 33, "num_statements": 33, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 17, "executed_branches": [[38, 39], [38, 41], [59, 61], [59, 76], [79, 80], [79, 87]], "missing_branches": []}, "": {"executed_lines": [6, 7, 9, 10, 12, 14, 17], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [6, 7, 9, 10, 12, 14, 17, 38, 39, 41, 42, 45, 50, 53, 54, 57, 59, 61, 62, 64, 65, 66, 67, 68, 69, 71, 76, 79, 80, 81, 87, 89, 91, 93, 94, 95, 96, 100, 101, 102], "summary": {"covered_lines": 40, "num_statements": 40, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[38, 39], [38, 41], [59, 61], [59, 76], [79, 80], [79, 87]], "missing_branches": []}}}, "app/utils/settings_service.py": {"executed_lines": [10, 11, 13, 14, 16, 18, 21, 860, 873, 874, 875, 876, 879, 880, 885, 891, 905, 907, 908, 910, 911, 913, 914, 915, 919, 920, 921, 923, 924, 925, 926, 927, 934, 946, 947, 948, 950, 952, 953, 958, 960, 966, 977, 978, 979, 980, 981, 982, 983, 984, 991, 1001, 1014, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1030, 1041, 1042, 1045, 1049, 1050, 1051, 1053, 1060, 1061, 1063], "summary": {"covered_lines": 71, "num_statements": 95, "percent_covered": 76.8, "percent_covered_display": "76.80", "missing_lines": 24, "excluded_lines": 0, "percent_statements_covered": 74.73684210526316, "percent_statements_covered_display": "74.74", "num_branches": 30, "num_partial_branches": 5, "covered_branches": 25, "missing_branches": 5, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [881, 883, 886, 887, 888, 917, 928, 929, 930, 931, 954, 956, 961, 962, 963, 985, 986, 987, 988, 1046, 1054, 1055, 1056, 1057], "excluded_lines": [], "executed_branches": [[875, 876], [875, 879], [880, 885], [910, 911], [910, 919], [913, 914], [920, 921], [920, 923], [950, 952], [950, 960], [953, 958], [979, 980], [979, 984], [1022, 1023], [1022, 1027], [1024, 1025], [1024, 1026], [1045, 1049], [1049, 1050], [1049, 1053], [1050, 1051], [1050, 1060], [1053, 1060], [1060, 1061], [1060, 1063]], "missing_branches": [[880, 881], [913, 917], [953, 954], [1045, 1046], [1053, 1054]], "functions": {"get_setting_from_db": {"executed_lines": [873, 874, 875, 876, 879, 880, 885], "summary": {"covered_lines": 7, "num_statements": 12, "percent_covered": 62.5, "percent_covered_display": "62.50", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 58.333333333333336, "percent_statements_covered_display": "58.33", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [881, 883, 886, 887, 888], "excluded_lines": [], "start_line": 860, "executed_branches": [[875, 876], [875, 879], [880, 885]], "missing_branches": [[880, 881]]}, "save_setting_to_db": {"executed_lines": [905, 907, 908, 910, 911, 913, 914, 915, 919, 920, 921, 923, 924, 925, 926, 927], "summary": {"covered_lines": 16, "num_statements": 21, "percent_covered": 77.77777777777777, "percent_covered_display": "77.78", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 76.19047619047619, "percent_statements_covered_display": "76.19", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [917, 928, 929, 930, 931], "excluded_lines": [], "start_line": 891, "executed_branches": [[910, 911], [910, 919], [913, 914], [920, 921], [920, 923]], "missing_branches": [[913, 917]]}, "get_all_settings_from_db": {"executed_lines": [946, 947, 948, 950, 952, 953, 958, 960], "summary": {"covered_lines": 8, "num_statements": 13, "percent_covered": 64.70588235294117, "percent_covered_display": "64.71", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 61.53846153846154, "percent_statements_covered_display": "61.54", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [954, 956, 961, 962, 963], "excluded_lines": [], "start_line": 934, "executed_branches": [[950, 952], [950, 960], [953, 958]], "missing_branches": [[953, 954]]}, "delete_setting_from_db": {"executed_lines": [977, 978, 979, 980, 981, 982, 983, 984], "summary": {"covered_lines": 8, "num_statements": 12, "percent_covered": 71.42857142857143, "percent_covered_display": "71.43", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 66.66666666666667, "percent_statements_covered_display": "66.67", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [985, 986, 987, 988], "excluded_lines": [], "start_line": 966, "executed_branches": [[979, 980], [979, 984]], "missing_branches": []}, "get_setting_metadata": {"executed_lines": [1001], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 991, "executed_branches": [], "missing_branches": []}, "get_settings_by_category": {"executed_lines": [1021, 1022, 1023, 1024, 1025, 1026, 1027], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1014, "executed_branches": [[1022, 1023], [1022, 1027], [1024, 1025], [1024, 1026]], "missing_branches": []}, "validate_setting_value": {"executed_lines": [1041, 1042, 1045, 1049, 1050, 1051, 1053, 1060, 1061, 1063], "summary": {"covered_lines": 10, "num_statements": 15, "percent_covered": 72.0, "percent_covered_display": "72.00", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 66.66666666666667, "percent_statements_covered_display": "66.67", "num_branches": 10, "num_partial_branches": 2, "covered_branches": 8, "missing_branches": 2, "percent_branches_covered": 80.0, "percent_branches_covered_display": "80.00"}, "missing_lines": [1046, 1054, 1055, 1056, 1057], "excluded_lines": [], "start_line": 1030, "executed_branches": [[1045, 1049], [1049, 1050], [1049, 1053], [1050, 1051], [1050, 1060], [1053, 1060], [1060, 1061], [1060, 1063]], "missing_branches": [[1045, 1046], [1053, 1054]]}, "": {"executed_lines": [10, 11, 13, 14, 16, 18, 21, 860, 891, 934, 966, 991, 1014, 1030], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [10, 11, 13, 14, 16, 18, 21, 860, 873, 874, 875, 876, 879, 880, 885, 891, 905, 907, 908, 910, 911, 913, 914, 915, 919, 920, 921, 923, 924, 925, 926, 927, 934, 946, 947, 948, 950, 952, 953, 958, 960, 966, 977, 978, 979, 980, 981, 982, 983, 984, 991, 1001, 1014, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1030, 1041, 1042, 1045, 1049, 1050, 1051, 1053, 1060, 1061, 1063], "summary": {"covered_lines": 71, "num_statements": 95, "percent_covered": 76.8, "percent_covered_display": "76.80", "missing_lines": 24, "excluded_lines": 0, "percent_statements_covered": 74.73684210526316, "percent_statements_covered_display": "74.74", "num_branches": 30, "num_partial_branches": 5, "covered_branches": 25, "missing_branches": 5, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [881, 883, 886, 887, 888, 917, 928, 929, 930, 931, 954, 956, 961, 962, 963, 985, 986, 987, 988, 1046, 1054, 1055, 1056, 1057], "excluded_lines": [], "start_line": 1, "executed_branches": [[875, 876], [875, 879], [880, 885], [910, 911], [910, 919], [913, 914], [920, 921], [920, 923], [950, 952], [950, 960], [953, 958], [979, 980], [979, 984], [1022, 1023], [1022, 1027], [1024, 1025], [1024, 1026], [1045, 1049], [1049, 1050], [1049, 1053], [1050, 1051], [1050, 1060], [1053, 1060], [1060, 1061], [1060, 1063]], "missing_branches": [[880, 881], [913, 917], [953, 954], [1045, 1046], [1053, 1054]]}}}, "app/utils/setup_wizard.py": {"executed_lines": [7, 8, 10, 12, 15, 22, 136, 145, 147, 154, 155, 156, 157, 158, 161, 163, 164, 166, 169, 176, 178, 179, 180, 183, 193, 194, 196, 199, 206, 208, 209, 210, 211, 212, 214], "summary": {"covered_lines": 35, "num_statements": 35, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 12, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[154, 155], [154, 161], [156, 154], [156, 157], [178, 179], [178, 196], [193, 178], [193, 194], [208, 209], [208, 214], [210, 211], [210, 212]], "missing_branches": [], "functions": {"get_required_settings": {"executed_lines": [22], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 15, "executed_branches": [], "missing_branches": []}, "is_setup_required": {"executed_lines": [145, 147, 154, 155, 156, 157, 158, 161, 163, 164, 166], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 136, "executed_branches": [[154, 155], [154, 161], [156, 154], [156, 157]], "missing_branches": []}, "get_missing_required_settings": {"executed_lines": [176, 178, 179, 180, 183, 193, 194, 196], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 169, "executed_branches": [[178, 179], [178, 196], [193, 178], [193, 194]], "missing_branches": []}, "get_wizard_steps": {"executed_lines": [206, 208, 209, 210, 211, 212, 214], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 199, "executed_branches": [[208, 209], [208, 214], [210, 211], [210, 212]], "missing_branches": []}, "": {"executed_lines": [7, 8, 10, 12, 15, 136, 169, 199], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [7, 8, 10, 12, 15, 22, 136, 145, 147, 154, 155, 156, 157, 158, 161, 163, 164, 166, 169, 176, 178, 179, 180, 183, 193, 194, 196, 199, 206, 208, 209, 210, 211, 212, 214], "summary": {"covered_lines": 35, "num_statements": 35, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 12, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[154, 155], [154, 161], [156, 154], [156, 157], [178, 179], [178, 196], [193, 178], [193, 194], [208, 209], [208, 214], [210, 211], [210, 212]], "missing_branches": []}}}, "app/utils/step_manager.py": {"executed_lines": [8, 9, 11, 13, 14, 18, 28, 33, 34, 35, 36, 39, 49, 50, 51, 53, 56, 65, 67, 68, 70, 75, 76, 77, 79, 82, 103, 109, 111, 119, 122, 123, 124, 125, 126, 127, 128, 130, 133, 153, 155, 156, 157, 164, 167, 190, 191, 204, 216, 217, 219, 222, 228, 229, 238, 239, 240, 241, 242, 244, 247, 248, 249, 250, 251, 252, 254, 256, 267, 289, 301, 302, 304, 306, 307, 309, 310, 312, 314, 315, 316, 319, 322, 324, 328, 329, 330, 331, 332, 333, 334, 335, 337], "summary": {"covered_lines": 93, "num_statements": 95, "percent_covered": 93.00699300699301, "percent_covered_display": "93.01", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 97.89473684210526, "percent_statements_covered_display": "97.89", "num_branches": 48, "num_partial_branches": 8, "covered_branches": 40, "missing_branches": 8, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [192, 326], "excluded_lines": [], "executed_branches": [[34, 35], [49, 50], [49, 53], [65, 67], [65, 79], [67, 65], [67, 68], [75, 76], [109, 111], [109, 122], [123, 124], [123, 125], [125, 126], [125, 127], [127, 128], [127, 130], [156, 157], [156, 164], [191, 204], [216, 217], [228, 229], [228, 238], [247, 248], [247, 249], [249, 250], [249, 251], [251, 252], [251, 254], [301, 302], [312, 314], [312, 337], [315, 316], [315, 319], [324, 328], [328, 329], [328, 332], [329, 330], [332, 312], [332, 333], [333, 334]], "missing_branches": [[34, 36], [75, 67], [191, 192], [216, 219], [301, 304], [324, 326], [329, 331], [333, 335]], "functions": {"initialize_file_steps": {"executed_lines": [49, 50, 51, 53], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 39, "executed_branches": [[49, 50], [49, 53]], "missing_branches": []}, "add_upload_steps": {"executed_lines": [65, 67, 68, 70, 75, 76, 77, 79], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 92.85714285714286, "percent_covered_display": "92.86", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [], "excluded_lines": [], "start_line": 56, "executed_branches": [[65, 67], [65, 79], [67, 65], [67, 68], [75, 76]], "missing_branches": [[75, 67]]}, "update_step_status": {"executed_lines": [103, 109, 111, 119, 122, 123, 124, 125, 126, 127, 128, 130], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 82, "executed_branches": [[109, 111], [109, 122], [123, 124], [123, 125], [125, 126], [125, 127], [127, 128], [127, 130]], "missing_branches": []}, "get_file_step_status": {"executed_lines": [153, 155, 156, 157, 164], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 133, "executed_branches": [[156, 157], [156, 164]], "missing_branches": []}, "get_file_overall_status": {"executed_lines": [190, 191, 204, 216, 217, 219, 222, 228, 229, 238, 239, 240, 241, 242, 244, 247, 248, 249, 250, 251, 252, 254, 256], "summary": {"covered_lines": 23, "num_statements": 24, "percent_covered": 91.66666666666667, "percent_covered_display": "91.67", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 95.83333333333333, "percent_statements_covered_display": "95.83", "num_branches": 12, "num_partial_branches": 2, "covered_branches": 10, "missing_branches": 2, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [192], "excluded_lines": [], "start_line": 167, "executed_branches": [[191, 204], [216, 217], [228, 229], [228, 238], [247, 248], [247, 249], [249, 250], [249, 251], [251, 252], [251, 254]], "missing_branches": [[191, 192], [216, 219]]}, "get_step_summary": {"executed_lines": [289, 301, 302, 304, 306, 307, 309, 310, 312, 314, 315, 316, 319, 322, 324, 328, 329, 330, 331, 332, 333, 334, 335, 337], "summary": {"covered_lines": 24, "num_statements": 25, "percent_covered": 87.8048780487805, "percent_covered_display": "87.80", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 96.0, "percent_statements_covered_display": "96.00", "num_branches": 16, "num_partial_branches": 4, "covered_branches": 12, "missing_branches": 4, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [326], "excluded_lines": [], "start_line": 267, "executed_branches": [[301, 302], [312, 314], [312, 337], [315, 316], [315, 319], [324, 328], [328, 329], [328, 332], [329, 330], [332, 312], [332, 333], [333, 334]], "missing_branches": [[301, 304], [324, 326], [329, 331], [333, 335]]}, "": {"executed_lines": [8, 9, 11, 13, 14, 18, 28, 33, 34, 35, 36, 39, 56, 82, 133, 167, 267], "summary": {"covered_lines": 17, "num_statements": 17, "percent_covered": 94.73684210526316, "percent_covered_display": "94.74", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[34, 35]], "missing_branches": [[34, 36]]}}, "classes": {"": {"executed_lines": [8, 9, 11, 13, 14, 18, 28, 33, 34, 35, 36, 39, 49, 50, 51, 53, 56, 65, 67, 68, 70, 75, 76, 77, 79, 82, 103, 109, 111, 119, 122, 123, 124, 125, 126, 127, 128, 130, 133, 153, 155, 156, 157, 164, 167, 190, 191, 204, 216, 217, 219, 222, 228, 229, 238, 239, 240, 241, 242, 244, 247, 248, 249, 250, 251, 252, 254, 256, 267, 289, 301, 302, 304, 306, 307, 309, 310, 312, 314, 315, 316, 319, 322, 324, 328, 329, 330, 331, 332, 333, 334, 335, 337], "summary": {"covered_lines": 93, "num_statements": 95, "percent_covered": 93.00699300699301, "percent_covered_display": "93.01", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 97.89473684210526, "percent_statements_covered_display": "97.89", "num_branches": 48, "num_partial_branches": 8, "covered_branches": 40, "missing_branches": 8, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83.33"}, "missing_lines": [192, 326], "excluded_lines": [], "start_line": 1, "executed_branches": [[34, 35], [49, 50], [49, 53], [65, 67], [65, 79], [67, 65], [67, 68], [75, 76], [109, 111], [109, 122], [123, 124], [123, 125], [125, 126], [125, 127], [127, 128], [127, 130], [156, 157], [156, 164], [191, 204], [216, 217], [228, 229], [228, 238], [247, 248], [247, 249], [249, 250], [249, 251], [251, 252], [251, 254], [301, 302], [312, 314], [312, 337], [315, 316], [315, 319], [324, 328], [328, 329], [328, 332], [329, 330], [332, 312], [332, 333], [333, 334]], "missing_branches": [[34, 36], [75, 67], [191, 192], [216, 219], [301, 304], [324, 326], [329, 331], [333, 335]]}}}, "app/utils/step_timeout.py": {"executed_lines": [8, 9, 10, 12, 14, 15, 17, 20, 23, 31, 34, 54, 55, 57, 58, 61, 67, 68, 70, 72, 75, 79, 80, 95, 96, 99, 110, 111], "summary": {"covered_lines": 28, "num_statements": 34, "percent_covered": 80.95238095238095, "percent_covered_display": "80.95", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 82.3529411764706, "percent_statements_covered_display": "82.35", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 6, "missing_branches": 2, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [73, 81, 82, 83, 88, 90], "excluded_lines": [], "executed_branches": [[54, 55], [54, 57], [67, 68], [67, 70], [72, 75], [80, 95]], "missing_branches": [[72, 73], [80, 81]], "functions": {"get_step_timeout": {"executed_lines": [31], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 23, "executed_branches": [], "missing_branches": []}, "mark_stalled_steps_as_failed": {"executed_lines": [54, 55, 57, 58, 61, 67, 68, 70, 72, 75, 79, 80, 95, 96], "summary": {"covered_lines": 14, "num_statements": 20, "percent_covered": 71.42857142857143, "percent_covered_display": "71.43", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 70.0, "percent_statements_covered_display": "70.00", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 6, "missing_branches": 2, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [73, 81, 82, 83, 88, 90], "excluded_lines": [], "start_line": 34, "executed_branches": [[54, 55], [54, 57], [67, 68], [67, 70], [72, 75], [80, 95]], "missing_branches": [[72, 73], [80, 81]]}, "check_and_recover_stalled_file": {"executed_lines": [110, 111], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 99, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [8, 9, 10, 12, 14, 15, 17, 20, 23, 34, 99], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [8, 9, 10, 12, 14, 15, 17, 20, 23, 31, 34, 54, 55, 57, 58, 61, 67, 68, 70, 72, 75, 79, 80, 95, 96, 99, 110, 111], "summary": {"covered_lines": 28, "num_statements": 34, "percent_covered": 80.95238095238095, "percent_covered_display": "80.95", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 82.3529411764706, "percent_statements_covered_display": "82.35", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 6, "missing_branches": 2, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [73, 81, 82, 83, 88, 90], "excluded_lines": [], "start_line": 1, "executed_branches": [[54, 55], [54, 57], [67, 68], [67, 70], [72, 75], [80, 95]], "missing_branches": [[72, 73], [80, 81]]}}}, "app/views/__init__.py": {"executed_lines": [5, 7, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 26, 27], "summary": {"covered_lines": 18, "num_statements": 18, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [5, 7, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 26, 27], "summary": {"covered_lines": 18, "num_statements": 18, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 26, 27], "summary": {"covered_lines": 18, "num_statements": 18, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "app/views/base.py": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 17, 18, 21, 22, 25, 28, 31, 32, 35, 38, 41], "summary": {"covered_lines": 19, "num_statements": 21, "percent_covered": 80.0, "percent_covered_display": "80.00", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 90.47619047619048, "percent_statements_covered_display": "90.48", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [33, 34], "excluded_lines": [], "executed_branches": [[31, 32]], "missing_branches": [[31, 33], [33, 34], [33, 35]], "functions": {"template_response_with_version": {"executed_lines": [31, 32, 35], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 44.44444444444444, "percent_covered_display": "44.44", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [33, 34], "excluded_lines": [], "start_line": 28, "executed_branches": [[31, 32]], "missing_branches": [[31, 33], [33, 34], [33, 35]]}, "": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 17, 18, 21, 22, 25, 28, 38, 41], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 17, 18, 21, 22, 25, 28, 31, 32, 35, 38, 41], "summary": {"covered_lines": 19, "num_statements": 21, "percent_covered": 80.0, "percent_covered_display": "80.00", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 90.47619047619048, "percent_statements_covered_display": "90.48", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25.00"}, "missing_lines": [33, 34], "excluded_lines": [], "start_line": 1, "executed_branches": [[31, 32]], "missing_branches": [[31, 33], [33, 34], [33, 35]]}}}, "app/views/dropbox.py": {"executed_lines": [5, 7, 9, 12, 13, 14, 20, 22, 35, 36, 37, 42, 43, 45, 46, 53], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[42, 43], [42, 45], [45, 46], [45, 53]], "missing_branches": [], "functions": {"dropbox_setup_page": {"executed_lines": [20, 22], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 14, "executed_branches": [], "missing_branches": []}, "dropbox_callback": {"executed_lines": [42, 43, 45, 46, 53], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 37, "executed_branches": [[42, 43], [42, 45], [45, 46], [45, 53]], "missing_branches": []}, "": {"executed_lines": [5, 7, 9, 12, 13, 14, 35, 36, 37], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 9, 12, 13, 14, 20, 22, 35, 36, 37, 42, 43, 45, 46, 53], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[42, 43], [42, 45], [45, 46], [45, 53]], "missing_branches": []}}}, "app/views/files.py": {"executed_lines": [5, 7, 8, 10, 11, 12, 14, 17, 18, 19, 33, 35, 37, 40, 43, 47, 51, 54, 57, 65, 68, 71, 72, 75, 76, 79, 80, 81, 82, 85, 88, 89, 92, 94, 128, 129, 130, 134, 135, 136, 138, 141, 143, 144, 149, 157, 158, 159, 162, 163, 164, 167, 168, 170, 171, 172, 173, 174, 175, 180, 183, 184, 186, 191, 209, 217, 236, 238, 245, 269, 270, 272, 273, 276, 278, 279, 280, 281, 286, 287, 288, 293, 294, 295, 298, 299, 300, 301, 302, 303, 305, 306, 307, 308, 310, 322, 323, 324, 325, 326, 328, 339, 341, 343, 346, 355, 358, 359, 360, 361, 374, 376, 377, 380, 381, 383, 384, 385, 388, 392, 394, 396, 397, 398, 400, 401, 404, 405, 406, 409, 410, 411, 413, 421, 422, 423, 427, 429, 430, 432, 434, 435, 438, 439, 441, 448, 449, 450, 454, 456, 457, 459, 461, 462, 465, 466, 468, 475, 476, 477, 515, 516, 517], "summary": {"covered_lines": 163, "num_statements": 224, "percent_covered": 69.48051948051948, "percent_covered_display": "69.48", "missing_lines": 61, "excluded_lines": 0, "percent_statements_covered": 72.76785714285714, "percent_statements_covered_display": "72.77", "num_branches": 84, "num_partial_branches": 15, "covered_branches": 51, "missing_branches": 33, "percent_branches_covered": 60.714285714285715, "percent_branches_covered_display": "60.71"}, "missing_lines": [44, 48, 66, 113, 115, 117, 176, 177, 187, 189, 204, 205, 206, 239, 241, 242, 389, 436, 463, 481, 483, 484, 486, 488, 489, 490, 492, 493, 495, 497, 499, 500, 501, 502, 504, 505, 507, 508, 509, 510, 521, 523, 524, 526, 528, 529, 530, 532, 533, 535, 537, 539, 540, 541, 542, 544, 545, 547, 548, 549, 550], "excluded_lines": [], "executed_branches": [[43, 47], [47, 51], [65, 68], [80, 81], [80, 85], [143, 144], [143, 149], [158, 159], [158, 162], [163, 164], [163, 167], [168, 170], [168, 180], [171, 172], [171, 180], [238, 245], [272, 273], [272, 293], [276, 278], [276, 286], [279, 280], [286, 287], [294, 295], [294, 343], [298, 299], [298, 305], [322, 323], [322, 341], [324, 325], [324, 339], [359, 360], [383, 384], [383, 404], [388, 392], [394, 396], [394, 398], [396, 397], [398, 400], [400, 401], [404, 405], [404, 409], [405, 406], [409, 410], [409, 413], [410, 411], [435, 438], [438, 439], [438, 441], [462, 465], [465, 466], [465, 468]], "missing_branches": [[43, 44], [47, 48], [65, 66], [238, 239], [241, 242], [241, 245], [279, 281], [286, 288], [359, 361], [388, 389], [396, 383], [398, 383], [400, 383], [405, 404], [410, 409], [435, 436], [462, 463], [489, 490], [489, 492], [492, 493], [492, 495], [501, 502], [501, 504], [504, 505], [504, 507], [529, 530], [529, 532], [532, 533], [532, 535], [541, 542], [541, 544], [544, 545], [544, 547]], "functions": {"files_page": {"executed_lines": [33, 35, 37, 40, 43, 47, 51, 54, 57, 65, 68, 71, 72, 75, 76, 79, 80, 81, 82, 85, 88, 89, 92, 94], "summary": {"covered_lines": 24, "num_statements": 30, "percent_covered": 76.3157894736842, "percent_covered_display": "76.32", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80.00", "num_branches": 8, "num_partial_branches": 3, "covered_branches": 5, "missing_branches": 3, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62.50"}, "missing_lines": [44, 48, 66, 113, 115, 117], "excluded_lines": [], "start_line": 19, "executed_branches": [[43, 47], [47, 51], [65, 68], [80, 81], [80, 85]], "missing_branches": [[43, 44], [47, 48], [65, 66]]}, "file_detail_page": {"executed_lines": [134, 135, 136, 138, 141, 143, 144, 149, 157, 158, 159, 162, 163, 164, 167, 168, 170, 171, 172, 173, 174, 175, 180, 183, 184, 186, 191], "summary": {"covered_lines": 27, "num_statements": 34, "percent_covered": 84.0909090909091, "percent_covered_display": "84.09", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 79.41176470588235, "percent_statements_covered_display": "79.41", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 10, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [176, 177, 187, 189, 204, 205, 206], "excluded_lines": [], "start_line": 130, "executed_branches": [[143, 144], [143, 149], [158, 159], [158, 162], [163, 164], [163, 167], [168, 170], [168, 180], [171, 172], [171, 180]], "missing_branches": []}, "_compute_processing_flow": {"executed_lines": [217, 236, 238, 245, 269, 270, 272, 273, 276, 278, 279, 280, 281, 286, 287, 288, 293, 294, 295, 298, 299, 300, 301, 302, 303, 305, 306, 307, 308, 310, 322, 323, 324, 325, 326, 328, 339, 341, 343], "summary": {"covered_lines": 39, "num_statements": 42, "percent_covered": 87.09677419354838, "percent_covered_display": "87.10", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 92.85714285714286, "percent_statements_covered_display": "92.86", "num_branches": 20, "num_partial_branches": 3, "covered_branches": 15, "missing_branches": 5, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [239, 241, 242], "excluded_lines": [], "start_line": 209, "executed_branches": [[238, 245], [272, 273], [272, 293], [276, 278], [276, 286], [279, 280], [286, 287], [294, 295], [294, 343], [298, 299], [298, 305], [322, 323], [322, 341], [324, 325], [324, 339]], "missing_branches": [[238, 239], [241, 242], [241, 245], [279, 281], [286, 288]]}, "_compute_step_summary": {"executed_lines": [355, 358, 359, 360, 361, 374, 376, 377, 380, 381, 383, 384, 385, 388, 392, 394, 396, 397, 398, 400, 401, 404, 405, 406, 409, 410, 411, 413], "summary": {"covered_lines": 28, "num_statements": 29, "percent_covered": 84.31372549019608, "percent_covered_display": "84.31", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 96.55172413793103, "percent_statements_covered_display": "96.55", "num_branches": 22, "num_partial_branches": 7, "covered_branches": 15, "missing_branches": 7, "percent_branches_covered": 68.18181818181819, "percent_branches_covered_display": "68.18"}, "missing_lines": [389], "excluded_lines": [], "start_line": 346, "executed_branches": [[359, 360], [383, 384], [383, 404], [388, 392], [394, 396], [394, 398], [396, 397], [398, 400], [400, 401], [404, 405], [404, 409], [405, 406], [409, 410], [409, 413], [410, 411]], "missing_branches": [[359, 361], [388, 389], [396, 383], [398, 383], [400, 383], [405, 404], [410, 409]]}, "preview_original_file": {"executed_lines": [427, 429, 430, 432, 434, 435, 438, 439, 441], "summary": {"covered_lines": 9, "num_statements": 10, "percent_covered": 85.71428571428571, "percent_covered_display": "85.71", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.0, "percent_statements_covered_display": "90.00", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [436], "excluded_lines": [], "start_line": 423, "executed_branches": [[435, 438], [438, 439], [438, 441]], "missing_branches": [[435, 436]]}, "preview_processed_file": {"executed_lines": [454, 456, 457, 459, 461, 462, 465, 466, 468], "summary": {"covered_lines": 9, "num_statements": 10, "percent_covered": 85.71428571428571, "percent_covered_display": "85.71", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.0, "percent_statements_covered_display": "90.00", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [463], "excluded_lines": [], "start_line": 450, "executed_branches": [[462, 465], [465, 466], [465, 468]], "missing_branches": [[462, 463]]}, "get_original_text": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 21, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 21, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [481, 483, 484, 486, 488, 489, 490, 492, 493, 495, 497, 499, 500, 501, 502, 504, 505, 507, 508, 509, 510], "excluded_lines": [], "start_line": 477, "executed_branches": [], "missing_branches": [[489, 490], [489, 492], [492, 493], [492, 495], [501, 502], [501, 504], [504, 505], [504, 507]]}, "get_processed_text": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 21, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 21, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [521, 523, 524, 526, 528, 529, 530, 532, 533, 535, 537, 539, 540, 541, 542, 544, 545, 547, 548, 549, 550], "excluded_lines": [], "start_line": 517, "executed_branches": [], "missing_branches": [[529, 530], [529, 532], [532, 533], [532, 535], [541, 542], [541, 544], [544, 545], [544, 547]]}, "": {"executed_lines": [5, 7, 8, 10, 11, 12, 14, 17, 18, 19, 128, 129, 130, 209, 346, 421, 422, 423, 448, 449, 450, 475, 476, 477, 515, 516, 517], "summary": {"covered_lines": 27, "num_statements": 27, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 8, 10, 11, 12, 14, 17, 18, 19, 33, 35, 37, 40, 43, 47, 51, 54, 57, 65, 68, 71, 72, 75, 76, 79, 80, 81, 82, 85, 88, 89, 92, 94, 128, 129, 130, 134, 135, 136, 138, 141, 143, 144, 149, 157, 158, 159, 162, 163, 164, 167, 168, 170, 171, 172, 173, 174, 175, 180, 183, 184, 186, 191, 209, 217, 236, 238, 245, 269, 270, 272, 273, 276, 278, 279, 280, 281, 286, 287, 288, 293, 294, 295, 298, 299, 300, 301, 302, 303, 305, 306, 307, 308, 310, 322, 323, 324, 325, 326, 328, 339, 341, 343, 346, 355, 358, 359, 360, 361, 374, 376, 377, 380, 381, 383, 384, 385, 388, 392, 394, 396, 397, 398, 400, 401, 404, 405, 406, 409, 410, 411, 413, 421, 422, 423, 427, 429, 430, 432, 434, 435, 438, 439, 441, 448, 449, 450, 454, 456, 457, 459, 461, 462, 465, 466, 468, 475, 476, 477, 515, 516, 517], "summary": {"covered_lines": 163, "num_statements": 224, "percent_covered": 69.48051948051948, "percent_covered_display": "69.48", "missing_lines": 61, "excluded_lines": 0, "percent_statements_covered": 72.76785714285714, "percent_statements_covered_display": "72.77", "num_branches": 84, "num_partial_branches": 15, "covered_branches": 51, "missing_branches": 33, "percent_branches_covered": 60.714285714285715, "percent_branches_covered_display": "60.71"}, "missing_lines": [44, 48, 66, 113, 115, 117, 176, 177, 187, 189, 204, 205, 206, 239, 241, 242, 389, 436, 463, 481, 483, 484, 486, 488, 489, 490, 492, 493, 495, 497, 499, 500, 501, 502, 504, 505, 507, 508, 509, 510, 521, 523, 524, 526, 528, 529, 530, 532, 533, 535, 537, 539, 540, 541, 542, 544, 545, 547, 548, 549, 550], "excluded_lines": [], "start_line": 1, "executed_branches": [[43, 47], [47, 51], [65, 68], [80, 81], [80, 85], [143, 144], [143, 149], [158, 159], [158, 162], [163, 164], [163, 167], [168, 170], [168, 180], [171, 172], [171, 180], [238, 245], [272, 273], [272, 293], [276, 278], [276, 286], [279, 280], [286, 287], [294, 295], [294, 343], [298, 299], [298, 305], [322, 323], [322, 341], [324, 325], [324, 339], [359, 360], [383, 384], [383, 404], [388, 392], [394, 396], [394, 398], [396, 397], [398, 400], [400, 401], [404, 405], [404, 409], [405, 406], [409, 410], [409, 413], [410, 411], [435, 438], [438, 439], [438, 441], [462, 465], [465, 466], [465, 468]], "missing_branches": [[43, 44], [47, 48], [65, 66], [238, 239], [241, 242], [241, 245], [279, 281], [286, 288], [359, 361], [388, 389], [396, 383], [398, 383], [400, 383], [405, 404], [410, 409], [435, 436], [462, 463], [489, 490], [489, 492], [492, 493], [492, 495], [501, 502], [501, 504], [504, 505], [504, 507], [529, 530], [529, 532], [532, 533], [532, 535], [541, 542], [541, 544], [544, 545], [544, 547]]}}}, "app/views/general.py": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 15, 18, 19, 26, 27, 30, 33, 35, 36, 37, 40, 43, 46, 47, 55, 56, 58, 60, 66, 72, 75, 76, 78, 81, 82, 85, 86, 89, 90, 92, 95, 96, 97, 99, 102, 103, 105, 106, 109, 112, 113, 116, 122, 125, 126, 127, 128, 129, 134, 145, 148, 149, 151, 152, 155, 156, 158, 159], "summary": {"covered_lines": 65, "num_statements": 71, "percent_covered": 88.60759493670886, "percent_covered_display": "88.61", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 91.54929577464789, "percent_statements_covered_display": "91.55", "num_branches": 8, "num_partial_branches": 3, "covered_branches": 5, "missing_branches": 3, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62.50"}, "missing_lines": [61, 63, 108, 130, 131, 135], "excluded_lines": [], "executed_branches": [[35, 36], [35, 40], [106, 109], [125, 126], [134, 145]], "missing_branches": [[106, 108], [125, 134], [134, 135]], "functions": {"serve_index": {"executed_lines": [26, 27, 30, 33, 35, 36, 37, 40, 43, 46, 47, 55, 56, 58, 60, 66, 72], "summary": {"covered_lines": 17, "num_statements": 19, "percent_covered": 90.47619047619048, "percent_covered_display": "90.48", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 89.47368421052632, "percent_statements_covered_display": "89.47", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [61, 63], "excluded_lines": [], "start_line": 19, "executed_branches": [[35, 36], [35, 40]], "missing_branches": []}, "serve_about": {"executed_lines": [78], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 76, "executed_branches": [], "missing_branches": []}, "serve_privacy": {"executed_lines": [85, 86], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 82, "executed_branches": [], "missing_branches": []}, "serve_imprint": {"executed_lines": [92], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 90, "executed_branches": [], "missing_branches": []}, "serve_upload": {"executed_lines": [99], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 97, "executed_branches": [], "missing_branches": []}, "favicon": {"executed_lines": [105, 106, 109], "summary": {"covered_lines": 3, "num_statements": 4, "percent_covered": 66.66666666666667, "percent_covered_display": "66.67", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75.00", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [108], "excluded_lines": [], "start_line": 103, "executed_branches": [[106, 109]], "missing_branches": [[106, 108]]}, "serve_license": {"executed_lines": [116, 122, 125, 126, 127, 128, 129, 134, 145], "summary": {"covered_lines": 9, "num_statements": 12, "percent_covered": 68.75, "percent_covered_display": "68.75", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75.00", "num_branches": 4, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 2, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [130, 131, 135], "excluded_lines": [], "start_line": 113, "executed_branches": [[125, 126], [134, 145]], "missing_branches": [[125, 134], [134, 135]]}, "serve_cookies": {"executed_lines": [151, 152], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 149, "executed_branches": [], "missing_branches": []}, "serve_terms": {"executed_lines": [158, 159], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 156, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 15, 18, 19, 75, 76, 81, 82, 89, 90, 95, 96, 97, 102, 103, 112, 113, 148, 149, 155, 156], "summary": {"covered_lines": 27, "num_statements": 27, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 15, 18, 19, 26, 27, 30, 33, 35, 36, 37, 40, 43, 46, 47, 55, 56, 58, 60, 66, 72, 75, 76, 78, 81, 82, 85, 86, 89, 90, 92, 95, 96, 97, 99, 102, 103, 105, 106, 109, 112, 113, 116, 122, 125, 126, 127, 128, 129, 134, 145, 148, 149, 151, 152, 155, 156, 158, 159], "summary": {"covered_lines": 65, "num_statements": 71, "percent_covered": 88.60759493670886, "percent_covered_display": "88.61", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 91.54929577464789, "percent_statements_covered_display": "91.55", "num_branches": 8, "num_partial_branches": 3, "covered_branches": 5, "missing_branches": 3, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62.50"}, "missing_lines": [61, 63, 108, 130, 131, 135], "excluded_lines": [], "start_line": 1, "executed_branches": [[35, 36], [35, 40], [106, 109], [125, 126], [134, 145]], "missing_branches": [[106, 108], [125, 134], [134, 135]]}}}, "app/views/google_drive.py": {"executed_lines": [5, 7, 8, 10, 12, 15, 16, 17, 23, 26, 31, 34, 36, 39, 42, 62, 63, 64, 69, 70, 72, 73, 79, 82, 83, 84], "summary": {"covered_lines": 26, "num_statements": 33, "percent_covered": 75.60975609756098, "percent_covered_display": "75.61", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 78.78787878787878, "percent_statements_covered_display": "78.79", "num_branches": 8, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 3, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62.50"}, "missing_lines": [37, 88, 89, 93, 95, 97, 107], "excluded_lines": [], "executed_branches": [[36, 39], [69, 70], [69, 72], [72, 73], [72, 79]], "missing_branches": [[36, 37], [88, 89], [88, 93]], "functions": {"google_drive_setup_page": {"executed_lines": [23, 26, 31, 34, 36, 39, 42], "summary": {"covered_lines": 7, "num_statements": 8, "percent_covered": 80.0, "percent_covered_display": "80.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 87.5, "percent_statements_covered_display": "87.50", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50.00"}, "missing_lines": [37], "excluded_lines": [], "start_line": 17, "executed_branches": [[36, 39]], "missing_branches": [[36, 37]]}, "google_drive_callback": {"executed_lines": [69, 70, 72, 73, 79], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 64, "executed_branches": [[69, 70], [69, 72], [72, 73], [72, 79]], "missing_branches": []}, "google_drive_auth_start": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 6, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [88, 89, 93, 95, 97, 107], "excluded_lines": [], "start_line": 84, "executed_branches": [], "missing_branches": [[88, 89], [88, 93]]}, "": {"executed_lines": [5, 7, 8, 10, 12, 15, 16, 17, 62, 63, 64, 82, 83, 84], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 8, 10, 12, 15, 16, 17, 23, 26, 31, 34, 36, 39, 42, 62, 63, 64, 69, 70, 72, 73, 79, 82, 83, 84], "summary": {"covered_lines": 26, "num_statements": 33, "percent_covered": 75.60975609756098, "percent_covered_display": "75.61", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 78.78787878787878, "percent_statements_covered_display": "78.79", "num_branches": 8, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 3, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62.50"}, "missing_lines": [37, 88, 89, 93, 95, 97, 107], "excluded_lines": [], "start_line": 1, "executed_branches": [[36, 39], [69, 70], [69, 72], [72, 73], [72, 79]], "missing_branches": [[36, 37], [88, 89], [88, 93]]}}}, "app/views/license_routes.py": {"executed_lines": [1, 3, 4, 6, 8, 11, 12, 24, 25], "summary": {"covered_lines": 9, "num_statements": 15, "percent_covered": 52.94117647058823, "percent_covered_display": "52.94", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [16, 17, 18, 20, 21, 29], "excluded_lines": [], "executed_branches": [], "missing_branches": [[17, 18], [17, 20]], "functions": {"get_lgpl_license": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 5, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [16, 17, 18, 20, 21], "excluded_lines": [], "start_line": 12, "executed_branches": [], "missing_branches": [[17, 18], [17, 20]]}, "serve_attribution": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [29], "excluded_lines": [], "start_line": 25, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [1, 3, 4, 6, 8, 11, 12, 24, 25], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [1, 3, 4, 6, 8, 11, 12, 24, 25], "summary": {"covered_lines": 9, "num_statements": 15, "percent_covered": 52.94117647058823, "percent_covered_display": "52.94", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60.00", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [16, 17, 18, 20, 21, 29], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": [[17, 18], [17, 20]]}}}, "app/views/onedrive.py": {"executed_lines": [5, 7, 9, 12, 13, 14, 20, 25, 42, 43, 44, 49, 50, 52, 53, 59], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[49, 50], [49, 52], [52, 53], [52, 59]], "missing_branches": [], "functions": {"onedrive_setup_page": {"executed_lines": [20, 25], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 14, "executed_branches": [], "missing_branches": []}, "onedrive_callback": {"executed_lines": [49, 50, 52, 53, 59], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 44, "executed_branches": [[49, 50], [49, 52], [52, 53], [52, 59]], "missing_branches": []}, "": {"executed_lines": [5, 7, 9, 12, 13, 14, 42, 43, 44], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 9, 12, 13, 14, 20, 25, 42, 43, 44, 49, 50, 52, 53, 59], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[49, 50], [49, 52], [52, 53], [52, 59]], "missing_branches": []}}}, "app/views/settings.py": {"executed_lines": [5, 6, 7, 8, 10, 11, 12, 14, 15, 16, 18, 19, 22, 31, 32, 33, 34, 35, 36, 39, 40, 44, 47, 48, 49, 50], "summary": {"covered_lines": 26, "num_statements": 56, "percent_covered": 41.42857142857143, "percent_covered_display": "41.43", "missing_lines": 30, "excluded_lines": 0, "percent_statements_covered": 46.42857142857143, "percent_statements_covered_display": "46.43", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 11, "percent_branches_covered": 21.428571428571427, "percent_branches_covered_display": "21.43"}, "missing_lines": [42, 58, 60, 62, 65, 68, 69, 70, 71, 73, 77, 78, 79, 80, 82, 83, 84, 85, 88, 89, 90, 93, 96, 97, 98, 100, 111, 114, 115, 116], "excluded_lines": [], "executed_branches": [[34, 35], [34, 39], [39, 40]], "missing_branches": [[39, 42], [69, 70], [69, 111], [71, 69], [71, 73], [77, 78], [77, 82], [82, 83], [82, 88], [97, 98], [97, 100]], "functions": {"require_admin_access": {"executed_lines": [31, 32, 44], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 22, "executed_branches": [], "missing_branches": []}, "require_admin_access.wrapper": {"executed_lines": [33, 34, 35, 36, 39, 40], "summary": {"covered_lines": 6, "num_statements": 7, "percent_covered": 81.81818181818181, "percent_covered_display": "81.82", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 85.71428571428571, "percent_statements_covered_display": "85.71", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75.00"}, "missing_lines": [42], "excluded_lines": [], "start_line": 32, "executed_branches": [[34, 35], [34, 39], [39, 40]], "missing_branches": [[39, 42]]}, "settings_page": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 29, "percent_covered": 0.0, "percent_covered_display": "0.00", "missing_lines": 29, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0.00", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 10, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0.00"}, "missing_lines": [58, 60, 62, 65, 68, 69, 70, 71, 73, 77, 78, 79, 80, 82, 83, 84, 85, 88, 89, 90, 93, 96, 97, 98, 100, 111, 114, 115, 116], "excluded_lines": [], "start_line": 50, "executed_branches": [], "missing_branches": [[69, 70], [69, 111], [71, 69], [71, 73], [77, 78], [77, 82], [82, 83], [82, 88], [97, 98], [97, 100]]}, "": {"executed_lines": [5, 6, 7, 8, 10, 11, 12, 14, 15, 16, 18, 19, 22, 47, 48, 49, 50], "summary": {"covered_lines": 17, "num_statements": 17, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 8, 10, 11, 12, 14, 15, 16, 18, 19, 22, 31, 32, 33, 34, 35, 36, 39, 40, 44, 47, 48, 49, 50], "summary": {"covered_lines": 26, "num_statements": 56, "percent_covered": 41.42857142857143, "percent_covered_display": "41.43", "missing_lines": 30, "excluded_lines": 0, "percent_statements_covered": 46.42857142857143, "percent_statements_covered_display": "46.43", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 11, "percent_branches_covered": 21.428571428571427, "percent_branches_covered_display": "21.43"}, "missing_lines": [42, 58, 60, 62, 65, 68, 69, 70, 71, 73, 77, 78, 79, 80, 82, 83, 84, 85, 88, 89, 90, 93, 96, 97, 98, 100, 111, 114, 115, 116], "excluded_lines": [], "start_line": 1, "executed_branches": [[34, 35], [34, 39], [39, 40]], "missing_branches": [[39, 42], [69, 70], [69, 111], [71, 69], [71, 73], [77, 78], [77, 82], [82, 83], [82, 88], [97, 98], [97, 100]]}}}, "app/views/status.py": {"executed_lines": [5, 6, 7, 9, 11, 13, 14, 17, 18, 19, 23, 26, 29, 32, 33, 35, 63, 66, 67, 68, 75, 77, 92, 93, 94, 100, 103, 105, 107], "summary": {"covered_lines": 29, "num_statements": 52, "percent_covered": 51.724137931034484, "percent_covered_display": "51.72", "missing_lines": 23, "excluded_lines": 0, "percent_statements_covered": 55.76923076923077, "percent_statements_covered_display": "55.77", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 5, "percent_branches_covered": 16.666666666666668, "percent_branches_covered_display": "16.67"}, "missing_lines": [37, 40, 41, 42, 43, 44, 45, 46, 47, 48, 51, 52, 53, 54, 55, 58, 59, 60, 61, 69, 70, 71, 72], "excluded_lines": [], "executed_branches": [[35, 63]], "missing_branches": [[35, 37], [42, 43], [42, 51], [43, 42], [43, 44]], "functions": {"status_dashboard": {"executed_lines": [23, 26, 29, 32, 33, 35, 63, 66, 67, 68, 75, 77], "summary": {"covered_lines": 12, "num_statements": 35, "percent_covered": 31.70731707317073, "percent_covered_display": "31.71", "missing_lines": 23, "excluded_lines": 0, "percent_statements_covered": 34.285714285714285, "percent_statements_covered_display": "34.29", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 5, "percent_branches_covered": 16.666666666666668, "percent_branches_covered_display": "16.67"}, "missing_lines": [37, 40, 41, 42, 43, 44, 45, 46, 47, 48, 51, 52, 53, 54, 55, 58, 59, 60, 61, 69, 70, 71, 72], "excluded_lines": [], "start_line": 19, "executed_branches": [[35, 63]], "missing_branches": [[35, 37], [42, 43], [42, 51], [43, 42], [43, 44]]}, "env_debug": {"executed_lines": [100, 103, 105, 107], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 94, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [5, 6, 7, 9, 11, 13, 14, 17, 18, 19, 92, 93, 94], "summary": {"covered_lines": 13, "num_statements": 13, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 7, 9, 11, 13, 14, 17, 18, 19, 23, 26, 29, 32, 33, 35, 63, 66, 67, 68, 75, 77, 92, 93, 94, 100, 103, 105, 107], "summary": {"covered_lines": 29, "num_statements": 52, "percent_covered": 51.724137931034484, "percent_covered_display": "51.72", "missing_lines": 23, "excluded_lines": 0, "percent_statements_covered": 55.76923076923077, "percent_statements_covered_display": "55.77", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 5, "percent_branches_covered": 16.666666666666668, "percent_branches_covered_display": "16.67"}, "missing_lines": [37, 40, 41, 42, 43, 44, 45, 46, 47, 48, 51, 52, 53, 54, 55, 58, 59, 60, 61, 69, 70, 71, 72], "excluded_lines": [], "start_line": 1, "executed_branches": [[35, 63]], "missing_branches": [[35, 37], [42, 43], [42, 51], [43, 42], [43, 44]]}}}, "app/views/wizard.py": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 20, 21, 29, 30, 33, 34, 35, 36, 39, 42, 44, 57, 58, 62, 64, 67, 68, 71, 72, 73, 74, 77, 79, 80, 81, 84, 85, 86, 88, 91, 92, 94, 96, 99, 106, 107, 113, 114, 115, 117, 118, 119, 121], "summary": {"covered_lines": 53, "num_statements": 59, "percent_covered": 90.41095890410959, "percent_covered_display": "90.41", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 89.83050847457628, "percent_statements_covered_display": "89.83", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 13, "missing_branches": 1, "percent_branches_covered": 92.85714285714286, "percent_branches_covered_display": "92.86"}, "missing_lines": [101, 102, 103, 122, 123, 124], "excluded_lines": [], "executed_branches": [[33, 34], [33, 35], [35, 36], [35, 39], [72, 73], [72, 88], [77, 72], [77, 79], [79, 80], [79, 84], [84, 85], [94, 96], [94, 99]], "missing_branches": [[84, 72]], "functions": {"setup_wizard": {"executed_lines": [29, 30, 33, 34, 35, 36, 39, 42, 44], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 21, "executed_branches": [[33, 34], [33, 35], [35, 36], [35, 39]], "missing_branches": []}, "setup_wizard_save": {"executed_lines": [62, 64, 67, 68, 71, 72, 73, 74, 77, 79, 80, 81, 84, 85, 86, 88, 91, 92, 94, 96, 99], "summary": {"covered_lines": 21, "num_statements": 24, "percent_covered": 88.23529411764706, "percent_covered_display": "88.24", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 87.5, "percent_statements_covered_display": "87.50", "num_branches": 10, "num_partial_branches": 1, "covered_branches": 9, "missing_branches": 1, "percent_branches_covered": 90.0, "percent_branches_covered_display": "90.00"}, "missing_lines": [101, 102, 103], "excluded_lines": [], "start_line": 58, "executed_branches": [[72, 73], [72, 88], [77, 72], [77, 79], [79, 80], [79, 84], [84, 85], [94, 96], [94, 99]], "missing_branches": [[84, 72]]}, "setup_wizard_skip": {"executed_lines": [113, 114, 115, 117, 118, 119, 121], "summary": {"covered_lines": 7, "num_statements": 10, "percent_covered": 70.0, "percent_covered_display": "70.00", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 70.0, "percent_statements_covered_display": "70.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [122, 123, 124], "excluded_lines": [], "start_line": 107, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 20, 21, 57, 58, 106, 107], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100.00", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100.00", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100.00"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 20, 21, 29, 30, 33, 34, 35, 36, 39, 42, 44, 57, 58, 62, 64, 67, 68, 71, 72, 73, 74, 77, 79, 80, 81, 84, 85, 86, 88, 91, 92, 94, 96, 99, 106, 107, 113, 114, 115, 117, 118, 119, 121], "summary": {"covered_lines": 53, "num_statements": 59, "percent_covered": 90.41095890410959, "percent_covered_display": "90.41", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 89.83050847457628, "percent_statements_covered_display": "89.83", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 13, "missing_branches": 1, "percent_branches_covered": 92.85714285714286, "percent_branches_covered_display": "92.86"}, "missing_lines": [101, 102, 103, 122, 123, 124], "excluded_lines": [], "start_line": 1, "executed_branches": [[33, 34], [33, 35], [35, 36], [35, 39], [72, 73], [72, 88], [77, 72], [77, 79], [79, 80], [79, 84], [84, 85], [94, 96], [94, 99]], "missing_branches": [[84, 72]]}}}}, "totals": {"covered_lines": 4002, "num_statements": 6286, "percent_covered": 60.58339566192969, "percent_covered_display": "60.58", "missing_lines": 2284, "excluded_lines": 0, "percent_statements_covered": 63.66528794145721, "percent_statements_covered_display": "63.67", "num_branches": 1736, "num_partial_branches": 234, "covered_branches": 858, "missing_branches": 878, "percent_branches_covered": 49.423963133640555, "percent_branches_covered_display": "49.42"}} diff --git a/docs/API.md b/docs/API.md index 44042c56..4255f02b 100644 --- a/docs/API.md +++ b/docs/API.md @@ -71,16 +71,16 @@ def make_api_request(url, max_retries=3): """Make API request with rate limit handling.""" for attempt in range(max_retries): response = requests.get(url) - + if response.status_code == 429: # Rate limit exceeded retry_after = int(response.headers.get('Retry-After', 60)) print(f"Rate limit exceeded. Retrying after {retry_after} seconds...") time.sleep(retry_after) continue - + return response - + raise Exception("Max retries exceeded") ``` @@ -203,7 +203,7 @@ The DocuElevate browser extension uses this endpoint to send files directly from Upload one or more files from your computer for processing. -**Request**: +**Request**: - Multipart form data with file(s) **Response**: diff --git a/docs/AuthenticationSetup.md b/docs/AuthenticationSetup.md index de1d3cb4..5cc9a7b4 100644 --- a/docs/AuthenticationSetup.md +++ b/docs/AuthenticationSetup.md @@ -79,7 +79,7 @@ For larger deployments or when you need more advanced authentication features, O ### 1. Create an Application in Authentik 1. Log in to your Authentik admin interface -2. Navigate to "Applications" > "Applications" +2. Navigate to "Applications" > "Applications" 3. Click "Create" 4. Fill in the following details: - **Name**: DocuElevate diff --git a/docs/BuildMetadata.md b/docs/BuildMetadata.md index c95b6377..7feff2a9 100644 --- a/docs/BuildMetadata.md +++ b/docs/BuildMetadata.md @@ -243,7 +243,7 @@ docker build -t docuelevate . **Cause:** Building outside of a Git repository -**Solution:** +**Solution:** - Clone the repository properly with `.git` directory - Or set `GIT_COMMIT_SHA` environment variable @@ -261,7 +261,7 @@ docker build --no-cache -t docuelevate . **Cause:** Files listed in `.dockerignore` -**Solution:** +**Solution:** - Check `.dockerignore` doesn't block `BUILD_DATE`, `GIT_SHA`, or `RUNTIME_INFO` - The `VERSION` file should always be committed to git diff --git a/docs/ConfigurationGuide.md b/docs/ConfigurationGuide.md index cdec2742..1d0d7e1f 100644 --- a/docs/ConfigurationGuide.md +++ b/docs/ConfigurationGuide.md @@ -352,7 +352,7 @@ PAPERLESS_CUSTOM_FIELDS_MAPPING='{"absender": "Sender", "empfaenger": "Recipient ### Dropbox -| **Variable** | **Description** | +| **Variable** | **Description** | |-------------------------|--------------------------------------------------| | `DROPBOX_APP_KEY` | Dropbox API app key. | | `DROPBOX_APP_SECRET` | Dropbox API app secret. | diff --git a/docs/ConfigurationMaster.md b/docs/ConfigurationMaster.md index aec61d2b..9358900d 100644 --- a/docs/ConfigurationMaster.md +++ b/docs/ConfigurationMaster.md @@ -1,4 +1,4 @@ -# DocuElevate Configuration +# DocuElevate Configuration This section contains detailed documentation about configuring DocuElevate for your environment. diff --git a/docs/DeploymentGuide.md b/docs/DeploymentGuide.md index 5f5a42c5..6f7a88db 100644 --- a/docs/DeploymentGuide.md +++ b/docs/DeploymentGuide.md @@ -106,17 +106,17 @@ Add security headers to your Nginx configuration: server { listen 443 ssl http2; server_name docuelevate.example.com; - + # SSL configuration ssl_certificate /etc/nginx/ssl/cert.pem; ssl_certificate_key /etc/nginx/ssl/key.pem; - + # Security headers add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:;" always; add_header X-Frame-Options "DENY" always; add_header X-Content-Type-Options "nosniff" always; - + location / { proxy_pass http://localhost:8000; proxy_set_header Host $host; @@ -185,7 +185,7 @@ For production use, we recommend setting up a reverse proxy (like Nginx or Traef server { listen 80; server_name docuelevate.example.com; - + location / { proxy_pass http://localhost:8000; proxy_set_header Host $host; diff --git a/docs/DropboxSetup.md b/docs/DropboxSetup.md index 95b4409b..37de4701 100644 --- a/docs/DropboxSetup.md +++ b/docs/DropboxSetup.md @@ -4,7 +4,7 @@ This guide explains how to set up the Dropbox integration for DocuElevate. ## Required Configuration Parameters -| **Variable** | **Description** | +| **Variable** | **Description** | |-------------------------|--------------------------------------------------| | `DROPBOX_APP_KEY` | Dropbox API app key | | `DROPBOX_APP_SECRET` | Dropbox API app secret | @@ -64,11 +64,11 @@ The wizard handles all the token exchange steps and provides you with the exact 1. Go to the "OAuth 2" tab in your app settings 2. Add a redirect URI: `http://localhost` (this is for the authorization flow) 3. Generate an authorization URL with these instructions: - + ``` https://www.dropbox.com/oauth2/authorize?client_id=YOUR_APP_KEY&response_type=code&token_access_type=offline ``` - + 4. Replace `YOUR_APP_KEY` with your app key 5. Open this URL in your browser 6. Authorize the app when prompted @@ -78,7 +78,7 @@ The wizard handles all the token exchange steps and provides you with the exact ### 5. Exchange the Code for a Refresh Token 1. Use this curl command to exchange the code for tokens: - + ```bash curl -X POST https://api.dropboxapi.com/oauth2/token \ -d code=YOUR_AUTH_CODE \ @@ -87,7 +87,7 @@ The wizard handles all the token exchange steps and provides you with the exact -d client_secret=YOUR_APP_SECRET \ -d redirect_uri=http://localhost ``` - + 2. From the response, copy the `refresh_token` value ### 6. Configure DocuElevate diff --git a/docs/FileDetailPageLayout.md b/docs/FileDetailPageLayout.md index 6ebefb89..de6fb0a3 100644 --- a/docs/FileDetailPageLayout.md +++ b/docs/FileDetailPageLayout.md @@ -108,4 +108,3 @@ Text extraction logs to check for `extracted_text`: - `process_with_azure_document_intelligence` - Azure OCR processing Both may contain extracted text in the `detail` field when `status = 'success'`. - diff --git a/docs/FileProcessingStatusArchitecture.md b/docs/FileProcessingStatusArchitecture.md index 109e98b8..ca78467e 100644 --- a/docs/FileProcessingStatusArchitecture.md +++ b/docs/FileProcessingStatusArchitecture.md @@ -215,9 +215,9 @@ for step in ["hash_file", "create_file_record", "check_text", ...]: # Start update_step_status(db, file.id, step, "in_progress", started_at=now()) log_event(db, file.id, step, "in_progress", "Starting...") - + # Do work... - + # Complete update_step_status(db, file.id, step, "success", completed_at=now()) log_event(db, file.id, step, "success", "Completed successfully") @@ -349,6 +349,6 @@ For deploying to existing system: - [ ] Run migration utility: `migrate_all_files(db, dry_run=True)` to test - [ ] Run actual migration: `migrate_all_files(db, dry_run=False)` - [ ] Verify: Check a few files with `verify_migration()` -- [ ] Update workers to call `update_step_status()` +- [ ] Update workers to call `update_step_status()` - [ ] Update file creation to call `initialize_file_steps()` - [ ] Monitor dashboard for correct status display diff --git a/docs/OAuth_Testing_CI_CD.md b/docs/OAuth_Testing_CI_CD.md index 3888c800..1611ccd8 100644 --- a/docs/OAuth_Testing_CI_CD.md +++ b/docs/OAuth_Testing_CI_CD.md @@ -16,19 +16,19 @@ on: [push, pull_request] jobs: test: runs-on: ubuntu-latest - + steps: - uses: actions/checkout@v4 - + - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.12' - + - name: Install dependencies run: | pip install -r requirements-dev.txt - + - name: Run OAuth tests (mock) run: | pytest tests/test_oauth_integration_flows.py -v @@ -48,19 +48,19 @@ jobs: runs-on: ubuntu-latest # Only run if secrets are available (not on external PRs) if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository - + steps: - uses: actions/checkout@v4 - + - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.12' - + - name: Install dependencies run: | pip install -r requirements-dev.txt - + - name: Run OAuth tests (real) env: AUTHENTIK_CLIENT_ID: ${{ secrets.AUTHENTIK_CLIENT_ID }} @@ -84,43 +84,43 @@ jobs: test-mock-oauth: name: OAuth Tests (Mock) runs-on: ubuntu-latest - + steps: - uses: actions/checkout@v4 - + - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.12' - + - name: Install dependencies run: | pip install -r requirements-dev.txt - + - name: Run mock OAuth tests run: | pytest tests/test_oauth_integration_flows.py \ -v \ -m "not requires_external" - + test-real-oauth: name: OAuth Tests (Real - Internal Only) runs-on: ubuntu-latest # Only run on internal commits where secrets are available if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository - + steps: - uses: actions/checkout@v4 - + - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.12' - + - name: Install dependencies run: | pip install -r requirements-dev.txt - + - name: Run real OAuth tests env: AUTHENTIK_CLIENT_ID: ${{ secrets.AUTHENTIK_CLIENT_ID }} @@ -157,7 +157,7 @@ on: [push, pull_request] jobs: test: runs-on: ubuntu-latest - + services: mock-oauth: image: ghcr.io/navikt/mock-oauth2-server:2.1.1 @@ -168,24 +168,24 @@ jobs: --health-interval 10s --health-timeout 5s --health-retries 5 - + steps: - uses: actions/checkout@v4 - + - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.12' - + - name: Install dependencies run: | pip install -r requirements-dev.txt - + - name: Configure OAuth to use service run: | export OAUTH_MOCK_URL=http://localhost:8080 export USE_MOCK_OAUTH=true - + - name: Run tests run: | pytest tests/test_oauth_integration_flows.py -v @@ -255,7 +255,7 @@ Add this step to debug mock OAuth server issues: **Cause**: Real OAuth credentials not configured or not accessible. -**Solution**: +**Solution**: - For local dev: Use mock mode (default) - For CI: Add secrets to GitHub repository settings - Check secret availability: `if github.event_name == 'push'` @@ -291,20 +291,20 @@ on: [push, pull_request] jobs: # Fast mock OAuth tests (always run) mock-oauth-tests: - name: OAuth Tests (Mock) + name: OAuth Tests (Mock) runs-on: ubuntu-latest - + steps: - uses: actions/checkout@v4 - + - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.12' - + - name: Install dependencies run: pip install -r requirements-dev.txt - + - name: Run mock OAuth tests run: | pytest tests/test_oauth_integration_flows.py \ @@ -312,7 +312,7 @@ jobs: -m "not requires_external" \ --cov=app.auth \ --cov-report=term-missing - + - name: Upload coverage uses: codecov/codecov-action@v3 with: @@ -324,18 +324,18 @@ jobs: name: OAuth Tests (Real - Internal) runs-on: ubuntu-latest if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository - + steps: - uses: actions/checkout@v4 - + - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.12' - + - name: Install dependencies run: pip install -r requirements-dev.txt - + - name: Run real OAuth tests env: AUTHENTIK_CLIENT_ID: ${{ secrets.AUTHENTIK_CLIENT_ID }} @@ -345,7 +345,7 @@ jobs: pytest tests/test_oauth_integration_flows.py \ -v \ -m requires_external - + - name: Upload coverage uses: codecov/codecov-action@v3 with: diff --git a/docs/OneDriveSetup.md b/docs/OneDriveSetup.md index 67ad870e..035fb61e 100644 --- a/docs/OneDriveSetup.md +++ b/docs/OneDriveSetup.md @@ -138,7 +138,7 @@ If you're using a work/school account provided by your organization: ### 2. Configuration based on use case **Option A: Access your own OneDrive (Interactive Login)** - + This option requires a refresh token: 1. Use the auth wizard with your tenant ID, or 2. Follow the same manual steps as for personal accounts, but use your work email to sign in @@ -146,7 +146,7 @@ This option requires a refresh token: 4. Set the refresh token you receive as `ONEDRIVE_REFRESH_TOKEN` **Option B: Access OneDrive as a system service (App-only access)** - + This option is for service accounts or automated systems with no user interaction: 1. In API permissions, add "Application permissions" instead of "Delegated permissions" 2. Add `Files.ReadWrite.All` permission under "Application permissions" @@ -158,15 +158,15 @@ This option is for service accounts or automated systems with no user interactio If you encounter errors during authentication: -1. **Check account permissions**: +1. **Check account permissions**: - Ensure your Microsoft account has the necessary permissions to grant access - For corporate accounts, check if your admin has restricted third-party app access -2. **Permission errors**: +2. **Permission errors**: - Verify the app registration has the correct API permissions - For corporate accounts, ensure an admin has consented to the permissions -3. **Refresh token expired**: +3. **Refresh token expired**: - If uploads stop working, you can generate a new refresh token using the auth wizard - Click on "Refresh Token" in the OneDrive setup page diff --git a/docs/RateLimitingStrategy.md b/docs/RateLimitingStrategy.md index 80def7e4..b2a3d540 100644 --- a/docs/RateLimitingStrategy.md +++ b/docs/RateLimitingStrategy.md @@ -271,7 +271,7 @@ from locust import HttpUser, task, between class APIUser(HttpUser): wait_time = between(0.1, 0.5) - + @task def get_files(self): self.client.get("/api/files") diff --git a/docs/SettingsManagement.md b/docs/SettingsManagement.md index a27f7fae..d710c8d8 100644 --- a/docs/SettingsManagement.md +++ b/docs/SettingsManagement.md @@ -93,7 +93,7 @@ The current value displayed is **always** the effective value after applying pre 6. Successfully saved settings will show a 🟢 DB badge 7. If any changed setting requires a restart, you'll be notified -**Important**: +**Important**: - You don't need to fill all fields - only change what you want to override - Saving a setting to the database makes it override environment variables - Empty fields are ignored (won't clear existing values) @@ -196,7 +196,7 @@ Settings are stored in the `application_settings` table with: ### Can't Access Settings Page - **Check authentication**: Make sure you're logged in -- **Check admin status**: +- **Check admin status**: - Local auth: Verify `ADMIN_USERNAME` and `ADMIN_PASSWORD` are correct - OAuth: Verify your user is in the admin group (configurable via `ADMIN_GROUP_NAME`) - **Check logs**: Look for "Non-admin user attempted to access settings page" messages @@ -243,5 +243,5 @@ python3 test_integration.py ## Related Documentation - [Configuration Guide](./ConfigurationGuide.md) - Environment variable reference -- [Deployment Guide](./DeploymentGuide.md) - Production deployment +- [Deployment Guide](./DeploymentGuide.md) - Production deployment - [API Documentation](./API.md) - Full API reference diff --git a/docs/StorageArchitecture.md b/docs/StorageArchitecture.md index f37f76d2..9237c690 100644 --- a/docs/StorageArchitecture.md +++ b/docs/StorageArchitecture.md @@ -223,7 +223,7 @@ curl -X POST "http://localhost:8000/api/files/123/reprocess-with-cloud-ocr" \ ```python class FileRecord(Base): __tablename__ = "files" - + id = Column(Integer, primary_key=True) filehash = Column(String, unique=True, nullable=False) original_filename = Column(String) # User's original name diff --git a/docs/archive/ANALYSIS_SUMMARY.md b/docs/archive/ANALYSIS_SUMMARY.md index 89b55baa..15c7b528 100644 --- a/docs/archive/ANALYSIS_SUMMARY.md +++ b/docs/archive/ANALYSIS_SUMMARY.md @@ -1,7 +1,7 @@ # Repository Analysis & Improvement Summary -**Date:** 2026-02-06 -**Repository:** christianlouis/DocuElevate +**Date:** 2026-02-06 +**Repository:** christianlouis/DocuElevate **Current Version:** v0.5.0 ## Executive Summary @@ -343,6 +343,6 @@ httpx>=0.26.0 --- -**Prepared by:** GitHub Copilot Agent -**Review Status:** Ready for maintainer review +**Prepared by:** GitHub Copilot Agent +**Review Status:** Ready for maintainer review **Recommended Action:** Merge and continue with TODO.md priorities diff --git a/docs/archive/FILENAME_FIX_SUMMARY.md b/docs/archive/FILENAME_FIX_SUMMARY.md index 7ff71e37..8eb6e62d 100644 --- a/docs/archive/FILENAME_FIX_SUMMARY.md +++ b/docs/archive/FILENAME_FIX_SUMMARY.md @@ -61,7 +61,7 @@ Created comprehensive unit tests to verify: 1. **Test 1**: Original filename is preserved when parameter is provided - Uploads a file with UUID-based path but provides original filename "Apostille Sverige.pdf" - Verifies the database stores the original filename, not the UUID-based path - + 2. **Test 2**: Backward compatibility is maintained - Calls `process_document` without the optional parameter - Verifies it falls back to extracting filename from path diff --git a/docs/archive/FRAMEWORK_ANALYSIS.md b/docs/archive/FRAMEWORK_ANALYSIS.md index 0e5afe35..f99e3d95 100644 --- a/docs/archive/FRAMEWORK_ANALYSIS.md +++ b/docs/archive/FRAMEWORK_ANALYSIS.md @@ -170,7 +170,7 @@ Phase 1 (Current - MVP): Settings: DB + ENV + DEFAULT Encryption: Fernet (app-level) UI: Custom settings page - + Phase 2 (Production - Optional): Settings: DB + ENV + DEFAULT (keep) Secrets: HashiCorp Vault (add) diff --git a/docs/archive/IMPLEMENTATION_CHECKLIST.md b/docs/archive/IMPLEMENTATION_CHECKLIST.md index 3502a3c8..f75e0ac8 100644 --- a/docs/archive/IMPLEMENTATION_CHECKLIST.md +++ b/docs/archive/IMPLEMENTATION_CHECKLIST.md @@ -155,7 +155,7 @@ **Status: 100% COMPLETE (Code Implementation)** ✅ ✅ Core settings functionality: 100% complete -✅ Encryption implementation: 100% complete +✅ Encryption implementation: 100% complete ✅ Setup wizard: 100% complete ⚠️ Testing: Manual testing recommended ⚠️ Documentation: Enhancement recommended diff --git a/docs/archive/SETTINGS_IMPLEMENTATION.md b/docs/archive/SETTINGS_IMPLEMENTATION.md index d48ad1fc..ba2de132 100644 --- a/docs/archive/SETTINGS_IMPLEMENTATION.md +++ b/docs/archive/SETTINGS_IMPLEMENTATION.md @@ -121,7 +121,7 @@ Created comprehensive `docs/SettingsManagement.md` covering: # Non-admin users /settings → @require_login → @require_admin_access → Redirect to / -# Admin users +# Admin users /settings → @require_login → @require_admin_access → Settings page renders ``` diff --git a/docs/security/PATH_TRAVERSAL_AUDIT_2026-02-10.md b/docs/security/PATH_TRAVERSAL_AUDIT_2026-02-10.md index cbddecc6..29fc16b7 100644 --- a/docs/security/PATH_TRAVERSAL_AUDIT_2026-02-10.md +++ b/docs/security/PATH_TRAVERSAL_AUDIT_2026-02-10.md @@ -10,11 +10,11 @@ A comprehensive security audit was conducted on all file path operations in Docu ### 1. Critical: Path Traversal via GPT Metadata Filename -**Severity:** CRITICAL -**Location:** `app/tasks/embed_metadata_into_pdf.py` (line 144) +**Severity:** CRITICAL +**Location:** `app/tasks/embed_metadata_into_pdf.py` (line 144) **Status:** ✅ FIXED -**Description:** +**Description:** The `metadata["filename"]` field extracted by GPT was used directly in file path construction without sanitization. A malicious document could be crafted to make GPT return metadata containing path traversal sequences (e.g., `../../etc/passwd`), allowing file writes outside the intended directory. **Attack Scenario:** @@ -39,11 +39,11 @@ final_path = os.path.join(processed_dir, suggested_filename) # Safe ### 2. Medium: Insecure String-Based Path Validation -**Severity:** MEDIUM -**Location:** `app/tasks/embed_metadata_into_pdf.py` (line 188) +**Severity:** MEDIUM +**Location:** `app/tasks/embed_metadata_into_pdf.py` (line 188) **Status:** ✅ FIXED -**Description:** +**Description:** Used insecure string-based `startswith()` check to validate file paths before deletion. This approach is vulnerable to: - Partial directory name matches - Symlink attacks (symlinks not resolved) @@ -78,11 +78,11 @@ if original_file_path.is_relative_to(workdir_tmp_resolved): ### 3. Medium: Insufficient GPT Filename Validation -**Severity:** MEDIUM -**Location:** `app/tasks/extract_metadata_with_gpt.py` +**Severity:** MEDIUM +**Location:** `app/tasks/extract_metadata_with_gpt.py` **Status:** ✅ FIXED -**Description:** +**Description:** While the GPT prompt requested specific filename format, there was no enforcement. GPT could return filenames with path separators or traversal patterns. **Fix Applied:** @@ -221,7 +221,7 @@ All identified path traversal vulnerabilities have been successfully remediated --- -**Audit Date:** February 10, 2026 -**Auditor:** GitHub Copilot Agent -**Scope:** All Python file path operations +**Audit Date:** February 10, 2026 +**Auditor:** GitHub Copilot Agent +**Scope:** All Python file path operations **Next Review:** Recommended within 6 months or after significant file handling changes diff --git a/frontend/static/images/default-avatar.svg b/frontend/static/images/default-avatar.svg index 4ec0cbed..bb67aa4e 100644 --- a/frontend/static/images/default-avatar.svg +++ b/frontend/static/images/default-avatar.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/frontend/static/js/common.js b/frontend/static/js/common.js index 15a09a38..42524d30 100644 --- a/frontend/static/js/common.js +++ b/frontend/static/js/common.js @@ -7,15 +7,15 @@ const response = await fetch('/api/auth/whoami'); const data = await response.json(); - + const authSection = document.getElementById("authSection"); const mobileAuthSection = document.getElementById("mobileAuthSection"); - + // If we have an email, user is authenticated (the whoami endpoint would have thrown 401 otherwise) if (data.email) { // Get the display name (prefer name, fall back to preferred_username, then email) const displayName = data.name || data.preferred_username || data.email; - + // User is logged in let authHTML = `
    @@ -26,11 +26,11 @@
    `; - + if (authSection) { authSection.innerHTML = authHTML; } - + if (mobileAuthSection) { mobileAuthSection.innerHTML = `
    @@ -49,7 +49,7 @@ if (authSection) { authSection.innerHTML = `Login`; } - + if (mobileAuthSection) { mobileAuthSection.innerHTML = `Login`; } @@ -59,11 +59,11 @@ // Fallback if whoami endpoint fails const authSection = document.getElementById("authSection"); const mobileAuthSection = document.getElementById("mobileAuthSection"); - + if (authSection) { authSection.innerHTML = `Login`; } - + if (mobileAuthSection) { mobileAuthSection.innerHTML = `Login`; } diff --git a/frontend/static/js/fontawesome-loader.js b/frontend/static/js/fontawesome-loader.js index 04f39fb6..9cbbd85e 100644 --- a/frontend/static/js/fontawesome-loader.js +++ b/frontend/static/js/fontawesome-loader.js @@ -7,6 +7,6 @@ link.rel = 'stylesheet'; link.href = '/static/fontawesome/css/all.min.css'; document.head.appendChild(link); - + console.log('Font Awesome loaded locally'); })(); diff --git a/frontend/static/js/upload.js b/frontend/static/js/upload.js index 13786cf7..91a29f6d 100644 --- a/frontend/static/js/upload.js +++ b/frontend/static/js/upload.js @@ -8,30 +8,30 @@ const MAX_FILE_SIZE = 500 * 1024 * 1024; // 500MB const ACCEPTED_TYPES = { // PDF files 'application/pdf': true, - + // Image formats 'image/jpeg': true, 'image/jpg': true, 'image/png': true, 'image/gif': true, 'image/bmp': true, 'image/tiff': true, 'image/webp': true, 'image/svg+xml': true, - + // Office document formats - Word 'application/msword': true, 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': true, 'application/vnd.openxmlformats-officedocument.wordprocessingml.template': true, 'application/vnd.ms-word.document.macroEnabled.12': true, - + // Excel 'application/vnd.ms-excel': true, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': true, 'application/vnd.openxmlformats-officedocument.spreadsheetml.template': true, 'application/vnd.ms-excel.sheet.macroEnabled.12': true, - + // PowerPoint 'application/vnd.ms-powerpoint': true, 'application/vnd.openxmlformats-officedocument.presentationml.presentation': true, 'application/vnd.openxmlformats-officedocument.presentationml.template': true, 'application/vnd.openxmlformats-officedocument.presentationml.slideshow': true, - + // Other common formats 'text/plain': true, 'text/csv': true, @@ -57,16 +57,16 @@ const ACCEPTED_EXTENSIONS = [ */ function processFiles(files, progressContainer, statusMessage) { if (files.length === 0) return; - + if (statusMessage) { statusMessage.textContent = `Processing ${files.length} file(s)...`; } - + // Clear previous upload progress if (progressContainer) { progressContainer.innerHTML = ""; } - + // Process each file for (let i = 0; i < files.length; i++) { const file = files[i]; @@ -94,32 +94,32 @@ function validateAndUpload(file, progressContainer, statusMessage) {
    Validating...
    `; - + if (progressContainer) { progressContainer.appendChild(fileProgress); } - + const progressBar = fileProgress.querySelector(".file-progress-bar"); const statusEl = fileProgress.querySelector(".file-status"); - + // Validate file type by checking both MIME type and extension const isValidMimeType = ACCEPTED_TYPES[file.type] || false; const fileExtension = '.' + file.name.split('.').pop().toLowerCase(); const isValidExtension = ACCEPTED_EXTENSIONS.includes(fileExtension); - + if (!isValidMimeType && !isValidExtension) { statusEl.textContent = `Error: ${file.name} - Unsupported file type`; statusEl.className = "text-xs text-red-500 mt-1"; return; } - + // Validate file size if (file.size > MAX_FILE_SIZE) { statusEl.textContent = `Error: ${file.name} - File size exceeds 500MB limit`; statusEl.className = "text-xs text-red-500 mt-1"; return; } - + // Upload the file uploadFile(file, progressBar, statusEl, statusMessage); } @@ -136,10 +136,10 @@ async function uploadFile(file, progressBar, statusEl, statusMessage) { try { let formData = new FormData(); formData.append("file", file); - + const xhr = new XMLHttpRequest(); xhr.open("POST", "/api/ui-upload", true); - + xhr.upload.onprogress = (e) => { if (e.lengthComputable) { const percentComplete = (e.loaded / e.total) * 100; @@ -147,7 +147,7 @@ async function uploadFile(file, progressBar, statusEl, statusMessage) { statusEl.textContent = `Uploading: ${Math.round(percentComplete)}%`; } }; - + xhr.onload = function() { if (xhr.status === 200) { const result = JSON.parse(xhr.responseText); @@ -160,13 +160,13 @@ async function uploadFile(file, progressBar, statusEl, statusMessage) { throw new Error(`Upload failed with status ${xhr.status}`); } }; - + xhr.onerror = function() { throw new Error("Network error occurred"); }; - + xhr.send(formData); - + } catch (err) { statusEl.textContent = `Error: ${err.message}`; statusEl.className = "text-xs text-red-500 mt-1"; @@ -181,21 +181,21 @@ async function uploadFile(file, progressBar, statusEl, statusMessage) { */ function updateOverallStatus(statusMessage) { if (!statusMessage) return; - + // Count success/failure const fileStatuses = document.querySelectorAll('.file-status'); let completed = 0; let total = fileStatuses.length; - + fileStatuses.forEach(status => { if (status.textContent.includes('Success') || status.textContent.includes('Error')) { completed++; } }); - + if (completed === total) { statusMessage.textContent = `All uploads completed (${completed}/${total})`; - + // Trigger a custom event when all uploads are complete const allUploadsComplete = new CustomEvent('allUploadsComplete', { detail: { total: total, completed: completed } @@ -231,38 +231,38 @@ function initDragAndDrop(element, progressContainer, statusMessage, options = {} console.error("Element not found for drag-and-drop initialization"); return; } - + // Add event listeners for drag-and-drop element.addEventListener("dragover", (e) => { e.preventDefault(); e.stopPropagation(); e.dataTransfer.dropEffect = "copy"; - + // Add visual feedback if (options.dragOverClass) { element.classList.add(options.dragOverClass); } }); - + element.addEventListener("dragleave", (e) => { e.preventDefault(); e.stopPropagation(); - + // Remove visual feedback if (options.dragOverClass) { element.classList.remove(options.dragOverClass); } }); - + element.addEventListener("drop", (e) => { e.preventDefault(); e.stopPropagation(); - + // Remove visual feedback if (options.dragOverClass) { element.classList.remove(options.dragOverClass); } - + if (e.dataTransfer.files.length) { processFiles(e.dataTransfer.files, progressContainer, statusMessage); } diff --git a/frontend/static/licenses/lgpl.txt b/frontend/static/licenses/lgpl.txt index 3ea3109d..d35234e4 100644 --- a/frontend/static/licenses/lgpl.txt +++ b/frontend/static/licenses/lgpl.txt @@ -55,7 +55,7 @@ modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. - + Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a @@ -111,7 +111,7 @@ modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. - + GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION @@ -158,7 +158,7 @@ Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. - + 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 @@ -216,7 +216,7 @@ instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. - + Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. @@ -267,7 +267,7 @@ Library will still fall under Section 6.) distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. - + 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work @@ -329,7 +329,7 @@ restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. - + 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined @@ -370,7 +370,7 @@ subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. - + 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or @@ -422,7 +422,7 @@ conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. - + 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is @@ -456,7 +456,7 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS - + How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest @@ -498,4 +498,4 @@ necessary. Here is a sample; alter the names: , 1 April 1990 Moe Ghoul, President of Vice -That's all there is to it! \ No newline at end of file +That's all there is to it! diff --git a/frontend/static/logo.svg b/frontend/static/logo.svg index 40fbb63d..ee756bb0 100644 --- a/frontend/static/logo.svg +++ b/frontend/static/logo.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/frontend/static/styles.css b/frontend/static/styles.css index c11d17f9..bb255d11 100644 --- a/frontend/static/styles.css +++ b/frontend/static/styles.css @@ -15,4 +15,4 @@ body { mask-repeat: no-repeat; -webkit-mask-size: 100% 100%; mask-size: 100% 100%; - } \ No newline at end of file + } diff --git a/frontend/templates/about.html b/frontend/templates/about.html index d9e00b69..2a1c043b 100644 --- a/frontend/templates/about.html +++ b/frontend/templates/about.html @@ -7,19 +7,19 @@

    Welcome to DocuElevate – your modern, intelligent solution for document processing! We've built DocuElevate to completely transform the way you handle your documents – from upload - to extraction, from processing to storage. + to extraction, from processing to storage.

    Our Story

    - DocuElevate was created with one goal in mind: to simplify and streamline document management + DocuElevate was created with one goal in mind: to simplify and streamline document management for everyone, whether you're a small startup or a large enterprise.

    - We harness the power of OpenAI for metadata extraction and text refinement, integrate seamlessly - with Dropbox, Nextcloud, and Paperless NGX for storage and indexing, leverage Azure Document + We harness the power of OpenAI for metadata extraction and text refinement, integrate seamlessly + with Dropbox, Nextcloud, and Paperless NGX for storage and indexing, leverage Azure Document Intelligence for OCR, and even use Gotenberg for file-to-PDF conversions.

    diff --git a/frontend/templates/attribution.html b/frontend/templates/attribution.html index 47016dcb..95ffd433 100644 --- a/frontend/templates/attribution.html +++ b/frontend/templates/attribution.html @@ -5,7 +5,7 @@ {% block content %}

    Third-Party Software Attributions

    - +

    DocuElevate uses several open source libraries and tools. We are grateful to the @@ -21,11 +21,11 @@

    - Special Attribution: This software includes Paramiko, which is licensed under LGPL. The source code for Paramiko is available at + Special Attribution: This software includes Paramiko, which is licensed under LGPL. The source code for Paramiko is available at https://github.com/paramiko/paramiko . - A copy of the LGPL license can be found + A copy of the LGPL license can be found here . @@ -33,7 +33,7 @@

    - +

    Python Dependencies

    - +

    Docker Images

    - +

    Frontend Dependencies