test_media_commands.py 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. # -*- coding: utf-8 -*-
  2. """
  3. Tests für Media-Commands.
  4. Testet:
  5. - MusicPlayPause, MusicNext, MusicStop, etc.
  6. - MediaStopAll Command
  7. """
  8. import pytest
  9. from dataclasses import is_dataclass
  10. from trixy_core.network.cmd import (
  11. MusicPlayPause,
  12. MusicNext,
  13. MusicPrevious,
  14. MusicStop,
  15. MusicVolumeChange,
  16. MediaStopAll,
  17. MusicStatus,
  18. MusicStatusResponse,
  19. CommandMessage,
  20. )
  21. # =============================================================================
  22. # Tests für MusicPlayPause
  23. # =============================================================================
  24. class TestMusicPlayPause:
  25. """Tests für MusicPlayPause Command."""
  26. def test_is_dataclass(self):
  27. """Testet, dass MusicPlayPause ein Dataclass ist."""
  28. assert is_dataclass(MusicPlayPause)
  29. def test_inherits_from_command_message(self):
  30. """Testet die Vererbung."""
  31. assert issubclass(MusicPlayPause, CommandMessage)
  32. def test_default_values(self):
  33. """Testet die Standardwerte."""
  34. cmd = MusicPlayPause()
  35. assert cmd.satellite_id == ""
  36. def test_custom_satellite_id(self):
  37. """Testet benutzerdefinierte satellite_id."""
  38. cmd = MusicPlayPause(satellite_id="living-room")
  39. assert cmd.satellite_id == "living-room"
  40. # =============================================================================
  41. # Tests für MusicNext
  42. # =============================================================================
  43. class TestMusicNext:
  44. """Tests für MusicNext Command."""
  45. def test_is_dataclass(self):
  46. """Testet, dass MusicNext ein Dataclass ist."""
  47. assert is_dataclass(MusicNext)
  48. def test_inherits_from_command_message(self):
  49. """Testet die Vererbung."""
  50. assert issubclass(MusicNext, CommandMessage)
  51. def test_default_values(self):
  52. """Testet die Standardwerte."""
  53. cmd = MusicNext()
  54. assert cmd.satellite_id == ""
  55. assert cmd.use_crossfade is True
  56. def test_crossfade_disabled(self):
  57. """Testet Crossfade deaktiviert."""
  58. cmd = MusicNext(use_crossfade=False)
  59. assert cmd.use_crossfade is False
  60. def test_with_satellite_id(self):
  61. """Testet mit satellite_id."""
  62. cmd = MusicNext(satellite_id="bedroom", use_crossfade=True)
  63. assert cmd.satellite_id == "bedroom"
  64. assert cmd.use_crossfade is True
  65. # =============================================================================
  66. # Tests für MusicPrevious
  67. # =============================================================================
  68. class TestMusicPrevious:
  69. """Tests für MusicPrevious Command."""
  70. def test_is_dataclass(self):
  71. """Testet, dass MusicPrevious ein Dataclass ist."""
  72. assert is_dataclass(MusicPrevious)
  73. def test_default_values(self):
  74. """Testet die Standardwerte."""
  75. cmd = MusicPrevious()
  76. assert cmd.satellite_id == ""
  77. assert cmd.use_crossfade is True
  78. # =============================================================================
  79. # Tests für MusicStop
  80. # =============================================================================
  81. class TestMusicStop:
  82. """Tests für MusicStop Command."""
  83. def test_is_dataclass(self):
  84. """Testet, dass MusicStop ein Dataclass ist."""
  85. assert is_dataclass(MusicStop)
  86. def test_inherits_from_command_message(self):
  87. """Testet die Vererbung."""
  88. assert issubclass(MusicStop, CommandMessage)
  89. def test_default_values(self):
  90. """Testet die Standardwerte."""
  91. cmd = MusicStop()
  92. assert cmd.satellite_id == ""
  93. # =============================================================================
  94. # Tests für MusicVolumeChange
  95. # =============================================================================
  96. class TestMusicVolumeChange:
  97. """Tests für MusicVolumeChange Command."""
  98. def test_is_dataclass(self):
  99. """Testet, dass MusicVolumeChange ein Dataclass ist."""
  100. assert is_dataclass(MusicVolumeChange)
  101. def test_default_values(self):
  102. """Testet die Standardwerte."""
  103. cmd = MusicVolumeChange()
  104. assert cmd.satellite_id == ""
  105. assert cmd.volume == 1.0
  106. assert cmd.relative is False
  107. def test_absolute_volume(self):
  108. """Testet absolute Lautstärke."""
  109. cmd = MusicVolumeChange(volume=0.5, relative=False)
  110. assert cmd.volume == 0.5
  111. assert cmd.relative is False
  112. def test_relative_volume(self):
  113. """Testet relative Lautstärkeänderung."""
  114. cmd = MusicVolumeChange(volume=-0.1, relative=True)
  115. assert cmd.volume == -0.1
  116. assert cmd.relative is True
  117. # =============================================================================
  118. # Tests für MediaStopAll
  119. # =============================================================================
  120. class TestMediaStopAll:
  121. """Tests für MediaStopAll Command."""
  122. def test_is_dataclass(self):
  123. """Testet, dass MediaStopAll ein Dataclass ist."""
  124. assert is_dataclass(MediaStopAll)
  125. def test_inherits_from_command_message(self):
  126. """Testet die Vererbung."""
  127. assert issubclass(MediaStopAll, CommandMessage)
  128. def test_default_values(self):
  129. """Testet die Standardwerte."""
  130. cmd = MediaStopAll()
  131. assert cmd.satellite_id == ""
  132. def test_with_satellite_id(self):
  133. """Testet mit satellite_id."""
  134. cmd = MediaStopAll(satellite_id="kitchen")
  135. assert cmd.satellite_id == "kitchen"
  136. # =============================================================================
  137. # Tests für MusicStatus
  138. # =============================================================================
  139. class TestMusicStatus:
  140. """Tests für MusicStatus Command."""
  141. def test_is_dataclass(self):
  142. """Testet, dass MusicStatus ein Dataclass ist."""
  143. assert is_dataclass(MusicStatus)
  144. def test_default_values(self):
  145. """Testet die Standardwerte."""
  146. cmd = MusicStatus()
  147. assert cmd.satellite_id == ""
  148. # =============================================================================
  149. # Tests für MusicStatusResponse
  150. # =============================================================================
  151. class TestMusicStatusResponse:
  152. """Tests für MusicStatusResponse Command."""
  153. def test_is_dataclass(self):
  154. """Testet, dass MusicStatusResponse ein Dataclass ist."""
  155. assert is_dataclass(MusicStatusResponse)
  156. def test_default_values(self):
  157. """Testet die Standardwerte."""
  158. cmd = MusicStatusResponse()
  159. assert cmd.satellite_id == ""
  160. assert cmd.is_playing is False
  161. assert cmd.is_paused is False
  162. assert cmd.current_track == ""
  163. assert cmd.track_position_ms == 0
  164. assert cmd.track_duration_ms == 0
  165. assert cmd.playlist_index == 0
  166. assert cmd.playlist_length == 0
  167. assert cmd.volume == 1.0
  168. def test_playing_state(self):
  169. """Testet Status bei laufender Wiedergabe."""
  170. cmd = MusicStatusResponse(
  171. satellite_id="living-room",
  172. is_playing=True,
  173. is_paused=False,
  174. current_track="Artist - Song",
  175. track_position_ms=60000,
  176. track_duration_ms=180000,
  177. playlist_index=2,
  178. playlist_length=10,
  179. volume=0.8,
  180. )
  181. assert cmd.is_playing is True
  182. assert cmd.is_paused is False
  183. assert cmd.current_track == "Artist - Song"
  184. assert cmd.track_position_ms == 60000
  185. assert cmd.volume == 0.8
  186. def test_paused_state(self):
  187. """Testet Status bei pausierter Wiedergabe."""
  188. cmd = MusicStatusResponse(
  189. is_playing=False,
  190. is_paused=True,
  191. )
  192. assert cmd.is_playing is False
  193. assert cmd.is_paused is True
  194. # =============================================================================
  195. # Tests für Command-Serialisierung (Pickle-Kompatibilität)
  196. # =============================================================================
  197. class TestMediaCommandSerialization:
  198. """Tests für Serialisierung der Media-Commands."""
  199. def test_pickle_music_play_pause(self):
  200. """Testet Pickle-Serialisierung von MusicPlayPause."""
  201. import pickle
  202. cmd = MusicPlayPause(satellite_id="test")
  203. data = pickle.dumps(cmd)
  204. restored = pickle.loads(data)
  205. assert restored.satellite_id == "test"
  206. def test_pickle_music_next(self):
  207. """Testet Pickle-Serialisierung von MusicNext."""
  208. import pickle
  209. cmd = MusicNext(satellite_id="test", use_crossfade=False)
  210. data = pickle.dumps(cmd)
  211. restored = pickle.loads(data)
  212. assert restored.satellite_id == "test"
  213. assert restored.use_crossfade is False
  214. def test_pickle_media_stop_all(self):
  215. """Testet Pickle-Serialisierung von MediaStopAll."""
  216. import pickle
  217. cmd = MediaStopAll(satellite_id="test")
  218. data = pickle.dumps(cmd)
  219. restored = pickle.loads(data)
  220. assert restored.satellite_id == "test"
  221. def test_pickle_music_status_response(self):
  222. """Testet Pickle-Serialisierung von MusicStatusResponse."""
  223. import pickle
  224. cmd = MusicStatusResponse(
  225. satellite_id="test",
  226. is_playing=True,
  227. current_track="Test Track",
  228. volume=0.5,
  229. )
  230. data = pickle.dumps(cmd)
  231. restored = pickle.loads(data)
  232. assert restored.satellite_id == "test"
  233. assert restored.is_playing is True
  234. assert restored.current_track == "Test Track"
  235. assert restored.volume == 0.5