mirror of
https://github.com/Benexl/FastAnime.git
synced 2025-12-12 15:50:01 -08:00
refactor: improve media actions tests with enhanced mocking and assertions
This commit is contained in:
@@ -7,7 +7,7 @@ from unittest.mock import Mock, patch
|
||||
|
||||
from fastanime.cli.interactive.menus.media_actions import media_actions
|
||||
from fastanime.cli.interactive.state import ControlFlow, State, MediaApiState, ProviderState
|
||||
from fastanime.libs.api.types import MediaItem
|
||||
from fastanime.libs.api.types import MediaItem, MediaTitle, MediaTrailer
|
||||
from fastanime.libs.players.types import PlayerResult
|
||||
|
||||
|
||||
@@ -45,80 +45,92 @@ class TestMediaActionsMenu:
|
||||
mock_context.selector.choose.return_value = "▶️ Stream"
|
||||
|
||||
with patch('fastanime.cli.interactive.menus.media_actions._stream') as mock_stream:
|
||||
mock_stream.return_value = lambda: State(menu_name="PROVIDER_SEARCH")
|
||||
mock_action = Mock()
|
||||
mock_action.return_value = State(menu_name="PROVIDER_SEARCH")
|
||||
mock_stream.return_value = mock_action
|
||||
|
||||
result = media_actions(mock_context, state_with_media_api)
|
||||
|
||||
# Should call stream function
|
||||
mock_stream.assert_called_once_with(mock_context, state_with_media_api)
|
||||
# Should return state transition
|
||||
assert isinstance(result(), State)
|
||||
assert result().menu_name == "PROVIDER_SEARCH"
|
||||
assert isinstance(result, State)
|
||||
assert result.menu_name == "PROVIDER_SEARCH"
|
||||
|
||||
def test_media_actions_trailer_selection(self, mock_context, state_with_media_api):
|
||||
"""Test selecting watch trailer from media actions."""
|
||||
mock_context.selector.choose.return_value = "📼 Watch Trailer"
|
||||
|
||||
with patch('fastanime.cli.interactive.menus.media_actions._watch_trailer') as mock_trailer:
|
||||
mock_trailer.return_value = lambda: ControlFlow.CONTINUE
|
||||
mock_action = Mock()
|
||||
mock_action.return_value = ControlFlow.CONTINUE
|
||||
mock_trailer.return_value = mock_action
|
||||
|
||||
result = media_actions(mock_context, state_with_media_api)
|
||||
|
||||
# Should call trailer function
|
||||
mock_trailer.assert_called_once_with(mock_context, state_with_media_api)
|
||||
assert result() == ControlFlow.CONTINUE
|
||||
assert result == ControlFlow.CONTINUE
|
||||
|
||||
def test_media_actions_add_to_list_selection(self, mock_context, state_with_media_api):
|
||||
"""Test selecting add/update list from media actions."""
|
||||
mock_context.selector.choose.return_value = "➕ Add/Update List"
|
||||
|
||||
with patch('fastanime.cli.interactive.menus.media_actions._add_to_list') as mock_add:
|
||||
mock_add.return_value = lambda: ControlFlow.CONTINUE
|
||||
mock_action = Mock()
|
||||
mock_action.return_value = ControlFlow.CONTINUE
|
||||
mock_add.return_value = mock_action
|
||||
|
||||
result = media_actions(mock_context, state_with_media_api)
|
||||
|
||||
# Should call add to list function
|
||||
mock_add.assert_called_once_with(mock_context, state_with_media_api)
|
||||
assert result() == ControlFlow.CONTINUE
|
||||
assert result == ControlFlow.CONTINUE
|
||||
|
||||
def test_media_actions_score_selection(self, mock_context, state_with_media_api):
|
||||
"""Test selecting score anime from media actions."""
|
||||
mock_context.selector.choose.return_value = "⭐ Score Anime"
|
||||
|
||||
with patch('fastanime.cli.interactive.menus.media_actions._score_anime') as mock_score:
|
||||
mock_score.return_value = lambda: ControlFlow.CONTINUE
|
||||
mock_action = Mock()
|
||||
mock_action.return_value = ControlFlow.CONTINUE
|
||||
mock_score.return_value = mock_action
|
||||
|
||||
result = media_actions(mock_context, state_with_media_api)
|
||||
|
||||
# Should call score function
|
||||
mock_score.assert_called_once_with(mock_context, state_with_media_api)
|
||||
assert result() == ControlFlow.CONTINUE
|
||||
assert result == ControlFlow.CONTINUE
|
||||
|
||||
def test_media_actions_local_history_selection(self, mock_context, state_with_media_api):
|
||||
"""Test selecting add to local history from media actions."""
|
||||
mock_context.selector.choose.return_value = "📚 Add to Local History"
|
||||
|
||||
with patch('fastanime.cli.interactive.menus.media_actions._add_to_local_history') as mock_history:
|
||||
mock_history.return_value = lambda: ControlFlow.CONTINUE
|
||||
mock_action = Mock()
|
||||
mock_action.return_value = ControlFlow.CONTINUE
|
||||
mock_history.return_value = mock_action
|
||||
|
||||
result = media_actions(mock_context, state_with_media_api)
|
||||
|
||||
# Should call local history function
|
||||
mock_history.assert_called_once_with(mock_context, state_with_media_api)
|
||||
assert result() == ControlFlow.CONTINUE
|
||||
assert result == ControlFlow.CONTINUE
|
||||
|
||||
def test_media_actions_view_info_selection(self, mock_context, state_with_media_api):
|
||||
"""Test selecting view info from media actions."""
|
||||
mock_context.selector.choose.return_value = "ℹ️ View Info"
|
||||
|
||||
with patch('fastanime.cli.interactive.menus.media_actions._view_info') as mock_info:
|
||||
mock_info.return_value = lambda: ControlFlow.CONTINUE
|
||||
mock_action = Mock()
|
||||
mock_action.return_value = ControlFlow.CONTINUE
|
||||
mock_info.return_value = mock_action
|
||||
|
||||
result = media_actions(mock_context, state_with_media_api)
|
||||
|
||||
# Should call view info function
|
||||
mock_info.assert_called_once_with(mock_context, state_with_media_api)
|
||||
assert result() == ControlFlow.CONTINUE
|
||||
assert result == ControlFlow.CONTINUE
|
||||
|
||||
def test_media_actions_back_selection(self, mock_context, state_with_media_api):
|
||||
"""Test selecting back from media actions."""
|
||||
@@ -140,8 +152,8 @@ class TestMediaActionsMenu:
|
||||
|
||||
result = media_actions(mock_context, state_with_media_api)
|
||||
|
||||
# Should return None when no choice is made
|
||||
assert result is None
|
||||
# Should return BACK when no choice is made
|
||||
assert result == ControlFlow.BACK
|
||||
|
||||
def test_media_actions_unknown_choice(self, mock_context, state_with_media_api):
|
||||
"""Test media actions menu with unknown choice."""
|
||||
@@ -152,8 +164,8 @@ class TestMediaActionsMenu:
|
||||
|
||||
result = media_actions(mock_context, state_with_media_api)
|
||||
|
||||
# Should return None for unknown choices
|
||||
assert result is None
|
||||
# Should return BACK for unknown choices
|
||||
assert result == ControlFlow.BACK
|
||||
|
||||
def test_media_actions_header_content(self, mock_context, state_with_media_api):
|
||||
"""Test that media actions header contains anime title and auth status."""
|
||||
@@ -176,12 +188,15 @@ class TestMediaActionsMenu:
|
||||
mock_context.selector.choose.return_value = "▶️ Stream"
|
||||
|
||||
with patch('fastanime.cli.interactive.menus.media_actions._stream') as mock_stream:
|
||||
mock_stream.return_value = lambda: ControlFlow.CONTINUE
|
||||
mock_action = Mock()
|
||||
mock_action.return_value = State(menu_name="PROVIDER_SEARCH")
|
||||
mock_stream.return_value = mock_action
|
||||
|
||||
result = media_actions(mock_context, state_with_media_api)
|
||||
|
||||
# Should work with icons enabled
|
||||
assert result() == ControlFlow.CONTINUE
|
||||
assert isinstance(result, State)
|
||||
assert result.menu_name == "PROVIDER_SEARCH"
|
||||
|
||||
def test_media_actions_icons_disabled(self, mock_context, state_with_media_api):
|
||||
"""Test media actions menu with icons disabled."""
|
||||
@@ -189,12 +204,15 @@ class TestMediaActionsMenu:
|
||||
mock_context.selector.choose.return_value = "Stream"
|
||||
|
||||
with patch('fastanime.cli.interactive.menus.media_actions._stream') as mock_stream:
|
||||
mock_stream.return_value = lambda: ControlFlow.CONTINUE
|
||||
mock_action = Mock()
|
||||
mock_action.return_value = State(menu_name="PROVIDER_SEARCH")
|
||||
mock_stream.return_value = mock_action
|
||||
|
||||
result = media_actions(mock_context, state_with_media_api)
|
||||
|
||||
# Should work with icons disabled
|
||||
assert result() == ControlFlow.CONTINUE
|
||||
assert isinstance(result, State)
|
||||
assert result.menu_name == "PROVIDER_SEARCH"
|
||||
|
||||
|
||||
class TestMediaActionsHelperFunctions:
|
||||
@@ -220,10 +238,10 @@ class TestMediaActionsHelperFunctions:
|
||||
# Mock anime with trailer URL
|
||||
anime_with_trailer = MediaItem(
|
||||
id=1,
|
||||
title={"english": "Test Anime", "romaji": "Test Anime"},
|
||||
title=MediaTitle(english="Test Anime", romaji="Test Anime"),
|
||||
status="FINISHED",
|
||||
episodes=12,
|
||||
trailer="https://youtube.com/watch?v=test"
|
||||
trailer=MediaTrailer(id="test", site="youtube")
|
||||
)
|
||||
|
||||
state_with_trailer = State(
|
||||
@@ -234,7 +252,7 @@ class TestMediaActionsHelperFunctions:
|
||||
trailer_func = _watch_trailer(mock_context, state_with_trailer)
|
||||
|
||||
# Mock successful player result
|
||||
mock_context.player.play.return_value = PlayerResult(success=True, exit_code=0)
|
||||
mock_context.player.play.return_value = PlayerResult()
|
||||
|
||||
with patch('fastanime.cli.interactive.menus.media_actions.create_feedback_manager') as mock_feedback:
|
||||
feedback_obj = Mock()
|
||||
@@ -258,8 +276,8 @@ class TestMediaActionsHelperFunctions:
|
||||
|
||||
result = trailer_func()
|
||||
|
||||
# Should show error and continue
|
||||
feedback_obj.error.assert_called_once()
|
||||
# Should show warning and continue
|
||||
feedback_obj.warning.assert_called_once()
|
||||
assert result == ControlFlow.CONTINUE
|
||||
|
||||
def test_add_to_list_authenticated(self, mock_context, state_with_media_api):
|
||||
@@ -352,17 +370,26 @@ class TestMediaActionsHelperFunctions:
|
||||
|
||||
history_func = _add_to_local_history(mock_context, state_with_media_api)
|
||||
|
||||
with patch('fastanime.cli.interactive.menus.media_actions.track_anime_in_history') as mock_track:
|
||||
with patch('fastanime.cli.interactive.menus.media_actions.create_feedback_manager') as mock_feedback:
|
||||
feedback_obj = Mock()
|
||||
mock_feedback.return_value = feedback_obj
|
||||
with patch('fastanime.cli.utils.watch_history_tracker.watch_tracker') as mock_tracker:
|
||||
mock_tracker.add_anime_to_history.return_value = True
|
||||
mock_context.selector.choose.return_value = "Watching"
|
||||
mock_context.selector.ask.return_value = "5"
|
||||
|
||||
with patch('fastanime.cli.utils.watch_history_manager.WatchHistoryManager') as mock_history_manager:
|
||||
mock_manager_instance = Mock()
|
||||
mock_history_manager.return_value = mock_manager_instance
|
||||
mock_manager_instance.get_entry.return_value = None
|
||||
|
||||
result = history_func()
|
||||
|
||||
# Should track in history and continue
|
||||
mock_track.assert_called_once()
|
||||
feedback_obj.success.assert_called_once()
|
||||
assert result == ControlFlow.CONTINUE
|
||||
with patch('fastanime.cli.interactive.menus.media_actions.create_feedback_manager') as mock_feedback:
|
||||
feedback_obj = Mock()
|
||||
mock_feedback.return_value = feedback_obj
|
||||
|
||||
result = history_func()
|
||||
|
||||
# Should add to history successfully
|
||||
mock_tracker.add_anime_to_history.assert_called_once()
|
||||
feedback_obj.success.assert_called_once()
|
||||
assert result == ControlFlow.CONTINUE
|
||||
|
||||
def test_view_info(self, mock_context, state_with_media_api):
|
||||
"""Test viewing anime information."""
|
||||
@@ -370,14 +397,13 @@ class TestMediaActionsHelperFunctions:
|
||||
|
||||
info_func = _view_info(mock_context, state_with_media_api)
|
||||
|
||||
with patch('fastanime.cli.interactive.menus.media_actions.display_anime_info') as mock_display:
|
||||
with patch('fastanime.cli.interactive.menus.media_actions.create_feedback_manager') as mock_feedback:
|
||||
feedback_obj = Mock()
|
||||
mock_feedback.return_value = feedback_obj
|
||||
|
||||
result = info_func()
|
||||
|
||||
# Should display info and pause for user
|
||||
mock_display.assert_called_once()
|
||||
feedback_obj.pause_for_user.assert_called_once()
|
||||
assert result == ControlFlow.CONTINUE
|
||||
with patch('fastanime.cli.interactive.menus.media_actions.Console') as mock_console:
|
||||
mock_context.selector.ask.return_value = ""
|
||||
|
||||
result = info_func()
|
||||
|
||||
# Should create console and display info
|
||||
mock_console.assert_called_once()
|
||||
# Should ask user to continue
|
||||
mock_context.selector.ask.assert_called_once_with("Press Enter to continue...")
|
||||
assert result == ControlFlow.CONTINUE
|
||||
|
||||
Reference in New Issue
Block a user