Files
MusicPlayer/tests/integration/test_full_flow.gd
T
Sansan 4a275e6a88 Add GdUnit4 testing framework with comprehensive test coverage
- Add GdUnit4 v6.2.1 framework in addons/gdUnit4/
- Create test directory structure (tests/unit/, tests/integration/, tests/mocks/)
- Add unit tests for MusicPlayer.gd (8 tests)
- Add unit tests for MainWindow.gd (15+ tests)
- Add unit tests for Settings.gd (5 tests)
- Add unit tests for Playlist.gd (11 tests)
- Add integration tests for full flow (10+ tests)
- Add MockHTTPRequest for HTTP request mocking
- Add TestHelpers with utility functions
- Add Gitea Actions CI workflow (.gitea/workflows/test.yml)
- Add .runsettings for GdUnit4 CLI configuration
- Add run_tests.sh for convenient test execution
- Add TESTING.md with comprehensive documentation
- Add TESTING_PLAN.md with implementation details
- Update .gitignore for test artifacts
- Enable GdUnit4 plugin in project.godot

Features:
- Test button functionality (play, pause, search, sync, etc.)
- Mock REST API requests to server
- Test complete application flows
- Run tests in CI (headless mode)
- Run tests in GUI for visual feedback
- JUnit XML and HTML test reports

Generated by OpenCode AI assistant.
2026-10-01 20:55:09 +02:00

262 lines
6.9 KiB
GDScript

class_name FullFlowTest
extends GdUnitTestSuite
func test_fetch_song_list_at_start_populates_playlist():
# Mock Settings.make_request2
var original_make_request = Settings.make_request2
Settings.make_request2 = func(address: String, func_name: Callable, expect_data: bool) -> void:
if address == "/music/list":
func_name.call([
{"SongNo": 1, "Soundtrack": "Test Soundtrack 1", "Song": "Test Song 1"},
{"SongNo": 2, "Soundtrack": "Test Soundtrack 2", "Song": "Test Song 2"}
])
Playlist.clear_song_list()
var main_window = MainWindow.new()
main_window.fetch_song_list_at_start()
# Wait for async
await main_window.get_tree().create_timer(0.1).timeout
assert_eq(Playlist.song_object_array.size(), 2)
Settings.make_request2 = original_make_request
func test_fetch_song_adds_to_playlist():
# Mock Settings.make_request2
var original_make_request = Settings.make_request2
var rand_called = false
var info_called = false
var add_que_called = false
Settings.make_request2 = func(address: String, func_name: Callable, expect_data: bool) -> void:
if address == "/music/rand":
rand_called = true
var test_stream = TestHelpers.create_mock_audio_stream()
func_name.call(test_stream.get_data())
elif address == "/music/info":
info_called = true
func_name.call({"SongNo": 3, "Soundtrack": "New Soundtrack", "Song": "New Song"})
elif address == "/music/addQue":
add_que_called = true
func_name.call()
Playlist.clear_song_list()
Playlist.is_song_downloading = false
var main_window = MainWindow.new()
main_window.fetch_song()
# Wait for async
await main_window.get_tree().create_timer(0.2).timeout
assert_true(rand_called)
assert_true(info_called)
assert_true(add_que_called)
assert_eq(Playlist.song_object_array.size(), 1)
Settings.make_request2 = original_make_request
func test_search_function_filters_soundtracks():
var main_window = MainWindow.new()
# Setup test data
main_window.soundtracks = ["Soundtrack 1", "Soundtrack 2", "Test Soundtrack"]
# This is a simplified test - in reality, search would be more complex
# We're testing that the search_view gets the list
var mock_search_view = mock(Control)
mock_search_view.get_list_of_soundtracks = func():
pass # Mock implementation
main_window.search_view = mock_search_view
# Call the method that populates the list
main_window.get_suggestion_list()
# Wait for async
await main_window.get_tree().create_timer(0.1).timeout
# Verify search_view was called
assert_true(mock_search_view.get_list_of_soundtracks.was_called())
func test_player_list_updates_on_add():
var main_window = MainWindow.new()
Settings.player_array.clear()
Settings.edit_players = false
# Setup mock container
var mock_container = mock(VBoxContainer)
main_window.players_list_container = mock_container
# Add a player
var player_obj = PlayerObject.new("Test Player", 0)
Settings.player_array.append(player_obj)
main_window.load_players()
# Verify player was added to container
assert_eq(mock_container.get_child_count(), 1)
func test_player_list_updates_on_remove():
var main_window = MainWindow.new()
Settings.player_array.clear()
# Setup mock container
var mock_container = mock(VBoxContainer)
main_window.players_list_container = mock_container
# Add players
for i in range(3):
var player_obj = PlayerObject.new("Player %d" % i, i)
Settings.player_array.append(player_obj)
main_window.load_players()
assert_eq(mock_container.get_child_count(), 3)
# Remove a player
main_window._on_player_removed(1)
assert_eq(Settings.player_array.size(), 2)
assert_eq(mock_container.get_child_count(), 2)
func test_point_given_updates_log_and_playlist():
var main_window = MainWindow.new()
# Setup
Settings.player_array.clear()
var player = PlayerObject.new("Test Player", 0)
Settings.player_array.append(player)
Playlist.clear_song_list()
var song = TestHelpers.create_test_song_object(1)
Playlist.add_to_playlist(song)
Playlist.currently_playing_song = 0
# Mock log window
var mock_log = mock(Control)
mock_log.add_log_row = func(text: String):
pass
main_window.log_window = mock_log
# Emit point given
player.player_point_given.emit()
# Wait for async
await main_window.get_tree().create_timer(0.1).timeout
# Verify log was updated
assert_true(mock_log.add_log_row.was_called())
# Verify playlist was updated
assert_true(song.players_given_point.has(0))
func test_point_taken_updates_log_and_playlist():
var main_window = MainWindow.new()
# Setup
Settings.player_array.clear()
var player = PlayerObject.new("Test Player", 0)
player.player_score = 5
Settings.player_array.append(player)
Playlist.clear_song_list()
var song = TestHelpers.create_test_song_object(1)
song.players_given_point.append(0)
Playlist.add_to_playlist(song)
Playlist.currently_playing_song = 0
# Mock log window
var mock_log = mock(Control)
mock_log.add_log_row = func(text: String):
pass
main_window.log_window = mock_log
# Emit point taken
player.player_point_taken.emit()
# Wait for async
await main_window.get_tree().create_timer(0.1).timeout
# Verify log was updated
assert_true(mock_log.add_log_row.was_called())
# Verify playlist was updated
assert_false(song.players_given_point.has(0))
func test_player_won_shows_winner_window():
var main_window = MainWindow.new()
# Setup
Settings.player_array.clear()
var player = PlayerObject.new("Test Player", 0)
Settings.player_array.append(player)
# Mock winner window
var mock_winner_window = mock(Control)
mock_winner_window.show_winner = func(winning_player_id: int):
pass
main_window.winner_window = mock_winner_window
# Emit winner
player.winner_triggerd.emit()
# Wait for async
await main_window.get_tree().create_timer(0.1).timeout
# Verify winner window was shown
assert_true(mock_winner_window.show_winner.was_called_with([0]))
func test_show_answer_pressed_marks_song_as_answered():
var main_window = MainWindow.new()
Playlist.clear_song_list()
var song = TestHelpers.create_test_song_object(1)
song.is_answered = false
Playlist.add_to_playlist(song)
Playlist.currently_playing_song = 0
main_window.show_answer_pressed()
assert_true(song.is_answered)
func test_update_song_list_refreshes_ui():
var main_window = MainWindow.new()
# Setup mock UI elements
var mock_soundtrack_label = mock(Label)
var mock_song_label = mock(Label)
var mock_music_list = mock(VBoxContainer)
main_window.soundtrack_label = mock_soundtrack_label
main_window.song_label = mock_song_label
main_window.music_list = mock_music_list
Playlist.clear_song_list()
var song = TestHelpers.create_test_song_object(1, "Test Soundtrack", "Test Song")
song.is_answered = true
song.has_played = true
Playlist.add_to_playlist(song)
Playlist.currently_playing_song = 0
main_window.update_song_list()
# Verify labels were updated
assert_eq(mock_soundtrack_label.text, "Test Soundtrack")
assert_eq(mock_song_label.text, "Test Song")