Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions tests/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Contains base test case with needed setup and helpers."""

import os
import warnings
from collections import namedtuple
from contextlib import contextmanager
from unittest import mock
Expand All @@ -22,6 +23,15 @@
TestResult, TestResultFile, TestStatus, TestType)
from mod_upload.models import Platform, Upload

# Filter RuntimeWarning about coroutines from AsyncMock in Python 3.13+
# This occurs when MagicMock auto-detects async-like method names (commit, debug, etc.)
# Must be set before test execution begins.
warnings.filterwarnings(
"ignore",
message="coroutine .* was never awaited",
category=RuntimeWarning
)


@contextmanager
def provide_file_at_root(file_name, to_write=None, to_delete=True):
Expand All @@ -47,6 +57,26 @@ def empty_github_token():
g.github['bot_token'] = original


def setup_mock_g(mock_g):
"""
Set up mock_g with explicit MagicMock objects to avoid AsyncMock warnings.

In Python 3.13+, MagicMock returns AsyncMock for method calls that look
async-like (commit, debug, warning, etc.). This causes RuntimeWarnings
when the code calls these methods synchronously.

This helper sets up explicit MagicMock objects for g.db and g.log to
prevent these warnings.

:param mock_g: The mocked g object from @mock.patch
:return: mock_g for chaining
"""
from unittest.mock import MagicMock
mock_g.db = MagicMock()
mock_g.log = MagicMock()
return mock_g


def create_mock_db_query(mock_g, extra_setup=None):
"""
Create a MagicMock for mock_g.db with common query chain setup.
Expand All @@ -60,6 +90,7 @@ def create_mock_db_query(mock_g, extra_setup=None):
"""
from unittest.mock import MagicMock
mock_g.db = MagicMock()
mock_g.log = MagicMock() # Also set up log to prevent AsyncMock warnings
mock_query = MagicMock()
mock_g.db.query.return_value = mock_query
mock_query.filter.return_value = mock_query
Expand Down
11 changes: 10 additions & 1 deletion tests/test_ci/test_controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ def __init__(self, platform):
self.value = 'linux'


class MockStatus:
"""Mock GitHub commit status object."""

def __init__(self, context):
self.context = context


class MockFork:
"""Mock fork object."""

Expand Down Expand Up @@ -781,8 +788,10 @@ def __init__(self):
self.commit = "test"

mock_test.query.filter.return_value.all.return_value = [MockTest()]
# Use MockStatus object instead of dict - code expects .context attribute
# Use 'linux' to match MockPlatform.value
mock_repo.return_value.get_commit.return_value.get_statuses.return_value = [
{"context": f"CI - {platform_name}"}]
MockStatus("CI - linux")]

data = {'action': 'closed',
'pull_request': {'number': 1234, 'draft': False}}
Expand Down