test_sync.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import os
  2. import re
  3. import shutil
  4. import unittest.mock
  5. import pytest
  6. from symuid import PlayCount, Track
  7. from symuid._datetime import unix_epoch_time_to_datetime_utc
  8. from symuid._uuid import generate_uuid4_bytes
  9. from symuid.sync import _main, sync
  10. DUMMY_PATH_IGNORE_REGEX = re.compile(r'\.jpg$')
  11. def test_add_uuid(empty_ogg_opus_path):
  12. assert Track(empty_ogg_opus_path).get_uuid() is None
  13. sync(os.path.dirname(empty_ogg_opus_path),
  14. path_ignore_regex=DUMMY_PATH_IGNORE_REGEX)
  15. assert Track(empty_ogg_opus_path).get_uuid() is not None
  16. def test_add_uuid_idempotent(empty_ogg_opus_path):
  17. sync(os.path.dirname(empty_ogg_opus_path),
  18. path_ignore_regex=DUMMY_PATH_IGNORE_REGEX)
  19. uuid = Track(empty_ogg_opus_path).get_uuid()
  20. sync(os.path.dirname(empty_ogg_opus_path),
  21. path_ignore_regex=DUMMY_PATH_IGNORE_REGEX)
  22. assert Track(empty_ogg_opus_path).get_uuid() == uuid
  23. def test_add_uuid_main(empty_ogg_opus_path):
  24. assert Track(empty_ogg_opus_path).get_uuid() is None
  25. with unittest.mock.patch('sys.argv', ['', os.path.dirname(empty_ogg_opus_path)]):
  26. _main()
  27. assert Track(empty_ogg_opus_path).get_uuid() is not None
  28. def test_sync_play_count(tmpdir, tracks_dir_path):
  29. shutil.copyfile(
  30. src=os.path.join(tracks_dir_path, 'id3v2.4-empty.mp3'),
  31. dst=tmpdir.join('a1.mp3'),
  32. )
  33. shutil.copyfile(
  34. src=os.path.join(tracks_dir_path, 'ogg-vorbis-empty.ogg'),
  35. dst=tmpdir.join('a2.ogg'),
  36. )
  37. shutil.copyfile(
  38. src=os.path.join(tracks_dir_path, 'ogg-opus-empty.opus'),
  39. dst=tmpdir.join('a3.opus'),
  40. )
  41. shutil.copyfile(
  42. src=os.path.join(tracks_dir_path, 'id3v2.4-empty.mp3'),
  43. dst=tmpdir.join('b.mp3'),
  44. )
  45. uuid_a = generate_uuid4_bytes()
  46. uuid_b = generate_uuid4_bytes()
  47. track_a1 = Track(tmpdir.join('a1.mp3'))
  48. track_a1.assign_uuid(uuid_a)
  49. track_a2 = Track(tmpdir.join('a2.ogg'))
  50. track_a2.assign_uuid(uuid_a)
  51. track_a3 = Track(tmpdir.join('a3.opus'))
  52. track_a3.assign_uuid(uuid_a)
  53. track_b = Track(tmpdir.join('b.mp3'))
  54. track_b.assign_uuid(uuid_b)
  55. track_a1.register_play_count(PlayCount(
  56. player='cmus',
  57. library_id='lib1',
  58. register_dt=unix_epoch_time_to_datetime_utc(0),
  59. count=21,
  60. ))
  61. track_a1.register_play_count(PlayCount(
  62. player='cmus',
  63. library_id='lib1',
  64. register_dt=unix_epoch_time_to_datetime_utc(1),
  65. count=22,
  66. ))
  67. track_a2.register_play_count(PlayCount(
  68. player='cmus',
  69. library_id='lib1',
  70. register_dt=unix_epoch_time_to_datetime_utc(0),
  71. count=21,
  72. ))
  73. track_a2.register_play_count(PlayCount(
  74. player='cmus',
  75. library_id='lib2',
  76. register_dt=unix_epoch_time_to_datetime_utc(2),
  77. count=7,
  78. ))
  79. track_b.register_play_count(PlayCount(
  80. player='cmus',
  81. library_id='lib2',
  82. register_dt=unix_epoch_time_to_datetime_utc(3),
  83. count=4,
  84. ))
  85. sync(tmpdir, path_ignore_regex=DUMMY_PATH_IGNORE_REGEX)
  86. play_counts_a1 = set(Track(tmpdir.join('a1.mp3')).get_play_counts())
  87. play_counts_a2 = set(Track(tmpdir.join('a2.ogg')).get_play_counts())
  88. play_counts_a3 = set(Track(tmpdir.join('a3.opus')).get_play_counts())
  89. play_counts_b = set(Track(tmpdir.join('b.mp3')).get_play_counts())
  90. assert len(play_counts_a1) == 3
  91. assert len(play_counts_a1) == len(play_counts_a2)
  92. assert len(play_counts_a1) == len(play_counts_a3)
  93. assert play_counts_a1 == play_counts_a2
  94. assert {pc.register_dt.timestamp() for pc in play_counts_a1} \
  95. == pytest.approx({0, 1, 2})
  96. assert len(play_counts_b) == 1
  97. assert {pc.register_dt.timestamp() for pc in play_counts_b} \
  98. == pytest.approx({3})
  99. def test_sync_play_count_callback(tmpdir, tracks_dir_path):
  100. shutil.copyfile(
  101. src=os.path.join(tracks_dir_path, 'id3v2.4-empty.mp3'),
  102. dst=tmpdir.join('a1.mp3'),
  103. )
  104. shutil.copyfile(
  105. src=os.path.join(tracks_dir_path, 'ogg-vorbis-empty.ogg'),
  106. dst=tmpdir.join('a2.ogg'),
  107. )
  108. uuid_a = generate_uuid4_bytes()
  109. track_a1 = Track(tmpdir.join('a1.mp3'))
  110. track_a1.assign_uuid(uuid_a)
  111. track_a2 = Track(tmpdir.join('a2.ogg'))
  112. track_a2.assign_uuid(uuid_a)
  113. track_a1.register_play_count(PlayCount(
  114. player='cmus',
  115. library_id='lib1',
  116. register_dt=unix_epoch_time_to_datetime_utc(0),
  117. count=21,
  118. ))
  119. play_count_added_cb = unittest.mock.MagicMock()
  120. sync(tmpdir, path_ignore_regex=DUMMY_PATH_IGNORE_REGEX,
  121. play_count_added_cb=play_count_added_cb)
  122. play_count_added_cb.assert_called_once_with(
  123. track_a2, ('symuid:pcnt:cmus:lib1:0', ['21']))
  124. def test_sync_play_count_callback_main(capsys, tmpdir, tracks_dir_path):
  125. shutil.copyfile(
  126. src=os.path.join(tracks_dir_path, 'id3v2.4-empty.mp3'),
  127. dst=tmpdir.join('a1.mp3'),
  128. )
  129. shutil.copyfile(
  130. src=os.path.join(tracks_dir_path, 'ogg-vorbis-empty.ogg'),
  131. dst=tmpdir.join('a2.ogg'),
  132. )
  133. uuid_a = generate_uuid4_bytes()
  134. track_a1 = Track(tmpdir.join('a1.mp3'))
  135. track_a1.assign_uuid(uuid_a)
  136. track_a2 = Track(tmpdir.join('a2.ogg'))
  137. track_a2.assign_uuid(uuid_a)
  138. track_a1.register_play_count(PlayCount(
  139. player='cmus',
  140. library_id='lib1',
  141. register_dt=unix_epoch_time_to_datetime_utc(0),
  142. count=21,
  143. ))
  144. with unittest.mock.patch('sys.argv', ['', tmpdir.strpath]):
  145. _main()
  146. out, _ = capsys.readouterr()
  147. assert out == "{!r}: added play count tag ('symuid:pcnt:cmus:lib1:0', ['21'])\n" \
  148. .format(track_a2.path)