diff --git a/test/rsrc/itunes_library.xml b/test/rsrc/itunes_library.xml new file mode 100644 index 000000000..a0750251b --- /dev/null +++ b/test/rsrc/itunes_library.xml @@ -0,0 +1,173 @@ + + + + + Major Version1 + Minor Version1 + Date2015-05-08T14:36:28Z + Application Version12.1.2.27 + Features5 + Show Content Ratings + Music Folderfile:///beetstests/Music/iTunes/iTunes%20Media/ + Library Persistent ID1ABA8417E4946A32 + Tracks + + 634 + + Track ID634 + NameTessellate + Artistalt-J + Album Artistalt-J + AlbumAn Awesome Wave + GenreAlternative + KindMPEG audio file + Size5525212 + Total Time182674 + Disc Number1 + Disc Count1 + Track Number3 + Track Count13 + Year2012 + Date Modified2015-02-02T15:23:08Z + Date Added2014-04-24T09:28:38Z + Bit Rate238 + Sample Rate44100 + Play Count0 + Play Date3513593824 + Skip Count3 + Skip Date2015-02-05T15:41:04Z + Rating80 + Album Rating80 + Album Rating Computed + Artwork Count1 + Sort AlbumAwesome Wave + Sort Artistalt-J + Persistent ID20E89D1580C31363 + Track TypeFile + Locationfile:///beetstests/Music/Music/Alt-J/An%20Awesome%20Wave/03%20Tessellate.mp3 + File Folder Count4 + Library Folder Count2 + + 636 + + Track ID636 + NameBreezeblocks + Artistalt-J + Album Artistalt-J + AlbumAn Awesome Wave + GenreAlternative + KindMPEG audio file + Size6827195 + Total Time227082 + Disc Number1 + Disc Count1 + Track Number4 + Track Count13 + Year2012 + Date Modified2015-02-02T15:23:08Z + Date Added2014-04-24T09:28:38Z + Bit Rate237 + Sample Rate44100 + Play Count31 + Play Date3513594051 + Play Date UTC2015-05-04T12:20:51Z + Skip Count0 + Rating100 + Album Rating80 + Album Rating Computed + Artwork Count1 + Sort AlbumAwesome Wave + Sort Artistalt-J + Persistent IDD7017B127B983D38 + Track TypeFile + Locationfile:///beetstests/Music/Music/Alt-J/An%20Awesome%20Wave/04%20Breezeblocks.mp3 + File Folder Count4 + Library Folder Count2 + + + Playlists + + + NameLibrary + Master + Playlist ID11480 + Playlist Persistent IDCD6FF684E7A6A166 + Visible + All Items + Playlist Items + + + Track ID634 + + + Track ID636 + + + + + NameMusic + Playlist ID16906 + Playlist Persistent ID4FB2E64E0971DD45 + Distinguished Kind4 + Music + All Items + Playlist Items + + + Track ID634 + + + Track ID636 + + + + + NameMovies + Playlist ID22338 + Playlist Persistent IDED848683ABD912C5 + Distinguished Kind2 + Movies + All Items + + + NameTV Shows + Playlist ID22344 + Playlist Persistent ID030882163A22E881 + Distinguished Kind3 + TV Shows + All Items + + + NamePodcasts + Playlist ID22347 + Playlist Persistent ID8A8C2A6F094235CF + Distinguished Kind10 + Podcasts + All Items + + + NameiTunesĀ U + Playlist ID22354 + Playlist Persistent ID571BAA51CE17C191 + Distinguished Kind31 + iTunesU + All Items + + + NameAudiobooks + Playlist ID22357 + Playlist Persistent ID2D2BE73BF9612562 + Distinguished Kind5 + Audiobooks + All Items + + + NameGenius + Playlist ID22372 + Playlist Persistent IDF35301460DED0A7A + Distinguished Kind26 + All Items + + + + diff --git a/test/test_metasync.py b/test/test_metasync.py new file mode 100644 index 000000000..82f8bf17a --- /dev/null +++ b/test/test_metasync.py @@ -0,0 +1,91 @@ +# This file is part of beets. +# Copyright 2015, Tom Jaspers. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +import os +from beets.library import Item + +from test import _common +from test._common import unittest +from test.helper import TestHelper + + +class MetaSyncTest(_common.TestCase, TestHelper): + itunes_library = os.path.join(_common.RSRC, 'itunes_library.xml') + + def setUp(self): + self.setup_beets() + self.load_plugins('metasync') + + self.config['metasync']['source'] = 'itunes' + self.config['metasync']['itunes']['library'] = self.itunes_library + + self._set_up_data() + + def _set_up_data(self): + items = [_common.item() for _ in range(2)] + items[0].title = 'Tessellate' + items[0].artist = 'alt-J' + items[0].albumartist = 'alt-J' + items[0].album = 'An Awesome Wave' + items[0].itunes_rating = 60 + + items[1].title = 'Breezeblocks' + items[1].artist = 'alt-J' + items[1].albumartist = 'alt-J' + items[1].album = 'An Awesome Wave' + + for item in items: + self.lib.add(item) + + def tearDown(self): + self.unload_plugins() + self.teardown_beets() + + def test_load_item_types(self): + # This test also verifies that the MetaSources have loaded correctly + self.assertIn('amarok_score', Item._types) + self.assertIn('itunes_rating', Item._types) + + def test_pretend_sync_from_itunes(self): + out = self.run_with_output('metasync', '-p') + + self.assertIn('itunes_rating: 60 -> 80', out) + self.assertIn('itunes_rating: 100', out) + self.assertIn('itunes_playcount: 31', out) + self.assertIn('itunes_skipcount: 3', out) + self.assertIn('itunes_lastplayed: 2015-05-04 12:20:51', out) + self.assertIn('itunes_lastskipped: 2015-02-05 15:41:04', out) + + self.assertEqual(self.lib.items()[0].itunes_rating, 60) + + def test_sync_from_itunes(self): + self.run_command('metasync') + + self.assertEqual(self.lib.items()[0].itunes_rating, 80) + self.assertEqual(self.lib.items()[0].itunes_playcount, 0) + self.assertEqual(self.lib.items()[0].itunes_skipcount, 3) + self.assertFalse(hasattr(self.lib.items()[0], 'itunes_lastplayed')) + self.assertEqual(self.lib.items()[0].itunes_lastskipped, 1423147264.0) + + self.assertEqual(self.lib.items()[1].itunes_rating, 100) + self.assertEqual(self.lib.items()[1].itunes_playcount, 31) + self.assertEqual(self.lib.items()[1].itunes_skipcount, 0) + self.assertEqual(self.lib.items()[1].itunes_lastplayed, 1430734851.0) + self.assertFalse(hasattr(self.lib.items()[1], 'itunes_lastskipped')) + + +def suite(): + return unittest.TestLoader().loadTestsFromName(__name__) + +if __name__ == b'__main__': + unittest.main(defaultTest='suite')