Esempio n. 1
0
class Test_EpisodeActionChanges(unittest.TestCase):
    ACTIONS = [
        api.EpisodeAction(FEED_URL_1, EPISODE_URL_1, 'download'),
        api.EpisodeAction(FEED_URL_2, EPISODE_URL_3, 'play'),
        api.EpisodeAction(FEED_URL_2, EPISODE_URL_4, 'delete'),
    ]
    SINCE = 1262102013

    def test_initSetsCorrectAttributes(self):
        changes = api.EpisodeActionChanges(self.ACTIONS, self.SINCE)
        self.assertEquals(changes.actions, self.ACTIONS)
        self.assertEquals(changes.since, self.SINCE)
Esempio n. 2
0
 def convert_to_api(action):
     dt = datetime.datetime.utcfromtimestamp(action.timestamp)
     action_ts = mygpoutil.datetime_to_iso8601(dt)
     return api.EpisodeAction(action.podcast_url, action.episode_url,
                              action.action, action.device_id,
                              action_ts, action.started,
                              action.position, action.total)
Esempio n. 3
0
 def test_toDictionary_containsMandatoryAttributes(self):
     action = api.EpisodeAction(FEED_URL_1, EPISODE_URL_1, 'play')
     dictionary = action.to_dictionary()
     self.assertEquals(len(dictionary.keys()), 3)
     self.assert_('podcast' in dictionary)
     self.assert_('episode' in dictionary)
     self.assert_('action' in dictionary)
     self.assertEquals(dictionary['podcast'], FEED_URL_1)
     self.assertEquals(dictionary['episode'], EPISODE_URL_1)
     self.assertEquals(dictionary['action'], 'play')
Esempio n. 4
0
 def test_initSetsCorrectAttributes(self):
     action = api.EpisodeAction(FEED_URL_1, EPISODE_URL_1, 'play',
             DEVICE_ID_1, self.XML_TIMESTAMP, self.VALID_STARTED,
             self.VALID_POSITION, self.VALID_TOTAL)
     self.assertEquals(action.podcast, FEED_URL_1)
     self.assertEquals(action.episode, EPISODE_URL_1)
     self.assertEquals(action.action, 'play')
     self.assertEquals(action.device, DEVICE_ID_1)
     self.assertEquals(action.timestamp, self.XML_TIMESTAMP)
     self.assertEquals(action.started, self.VALID_STARTED)
     self.assertEquals(action.position, self.VALID_POSITION)
     self.assertEquals(action.total, self.VALID_TOTAL)
Esempio n. 5
0
 def test_toDictionary_containsAllAttributes(self):
     action = api.EpisodeAction(FEED_URL_3, EPISODE_URL_4, 'play',
             DEVICE_ID_1, self.XML_TIMESTAMP, self.VALID_STARTED,
             self.VALID_POSITION, self.VALID_TOTAL)
     dictionary = action.to_dictionary()
     self.assertEquals(len(dictionary.keys()), 8)
     self.assert_('podcast' in dictionary)
     self.assert_('episode' in dictionary)
     self.assert_('action' in dictionary)
     self.assert_('device' in dictionary)
     self.assert_('timestamp' in dictionary)
     self.assert_('started' in dictionary)
     self.assert_('position' in dictionary)
     self.assert_('total' in dictionary)
     self.assertEquals(dictionary['podcast'], FEED_URL_3)
     self.assertEquals(dictionary['episode'], EPISODE_URL_4)
     self.assertEquals(dictionary['action'], 'play')
     self.assertEquals(dictionary['device'], DEVICE_ID_1)
     self.assertEquals(dictionary['timestamp'], self.XML_TIMESTAMP)
     self.assertEquals(dictionary['started'], self.VALID_STARTED)
     self.assertEquals(dictionary['position'], self.VALID_POSITION)
     self.assertEquals(dictionary['total'], self.VALID_TOTAL)
Esempio n. 6
0
class Test_MygPodderClient(unittest.TestCase):
    ADD = [
        FEED_URL_1,
        FEED_URL_3,
    ]
    REMOVE = [
        FEED_URL_2,
        FEED_URL_4,
    ]
    ADD_REMOVE_AS_JSON_UPLOAD = {
        'add': [FEED_URL_1, FEED_URL_3],
        'remove': [FEED_URL_2, FEED_URL_4],
    }
    ACTIONS = [
        api.EpisodeAction(FEED_URL_1, EPISODE_URL_1, 'download'),
        api.EpisodeAction(FEED_URL_2, EPISODE_URL_3, 'play'),
        api.EpisodeAction(FEED_URL_2, EPISODE_URL_4, 'delete'),
    ]
    ACTIONS_AS_JSON_UPLOAD = [
        {
            'podcast': FEED_URL_1,
            'episode': EPISODE_URL_1,
            'action': 'download'
        },
        {
            'podcast': FEED_URL_2,
            'episode': EPISODE_URL_3,
            'action': 'play'
        },
        {
            'podcast': FEED_URL_2,
            'episode': EPISODE_URL_4,
            'action': 'delete'
        },
    ]
    USERNAME = '******'
    PASSWORD = '******'
    SINCE = 1262103016

    def setUp(self):
        self.fake_client = testing.FakeJsonClient()
        self.client = api.MygPodderClient(self.USERNAME,
                                          self.PASSWORD,
                                          client_class=self.fake_client)

    def set_http_response_value(self, value):
        self.fake_client.response_value = value

    def assert_http_request_count(self, count):
        self.assertEquals(len(self.fake_client.requests), count)

    def has_put_json_data(self, data, required_method='PUT'):
        """Returns True if the FakeJsonClient has received the given data"""
        for method, uri, sent in self.fake_client.requests:
            if method == required_method:
                self.assertEquals(sent, data)
                return True

        return False

    def has_posted_json_data(self, data):
        """Same as has_put_json_data, but require a POST request"""
        return self.has_put_json_data(data, required_method='POST')

    def test_getSubscriptions_withPodcastDevice(self):
        self.set_http_response_value('[]')
        device = api.PodcastDevice('manatee', 'My Device', 'mobile', 20)
        self.assertEquals(self.client.get_subscriptions(device), [])
        self.assert_http_request_count(1)

    def test_putSubscriptions_withPodcastDevice(self):
        self.set_http_response_value('')
        device = api.PodcastDevice('manatee', 'My Device', 'mobile', 20)
        self.assertEquals(self.client.put_subscriptions(device, self.ADD),
                          True)
        self.assert_http_request_count(1)
        self.assert_(self.has_put_json_data(self.ADD))

    def test_updateSubscriptions_raisesValueError_onInvalidAddList(self):
        self.assertRaises(ValueError, self.client.update_subscriptions,
                          DEVICE_ID_2, [FEED_URL_1, 123, FEED_URL_3],
                          self.REMOVE)

    def test_updateSubscriptions_raisesValueError_onInvalidRemoveList(self):
        self.assertRaises(ValueError, self.client.update_subscriptions,
                          DEVICE_ID_2, self.ADD,
                          [FEED_URL_2, FEED_URL_4, [1, 2, 3]])

    def test_updateSubscriptions_raisesInvalidResponse_onEmptyResponse(self):
        self.set_http_response_value('')
        self.assertRaises(api.InvalidResponse,
                          self.client.update_subscriptions, DEVICE_ID_1,
                          self.ADD, self.REMOVE)

    def test_updateSubscriptions_raisesInvalidResponse_onMissingTimestamp(
            self):
        self.set_http_response_value('{}')
        self.assertRaises(api.InvalidResponse,
                          self.client.update_subscriptions, DEVICE_ID_1,
                          self.ADD, self.REMOVE)

    def test_updateSubscriptions_raisesInvalidResponse_onInvalidTimestamp(
            self):
        self.set_http_response_value("""
        {"timestamp": "not gonna happen"}
        """)
        self.assertRaises(api.InvalidResponse,
                          self.client.update_subscriptions, DEVICE_ID_1,
                          self.ADD, self.REMOVE)

    def test_updateSubscriptions_raisesInvalidResponse_withoutUpdateUrls(self):
        self.set_http_response_value("""
        {"timestamp": 1262103016}
        """)
        self.assertRaises(api.InvalidResponse,
                          self.client.update_subscriptions, DEVICE_ID_1,
                          self.ADD, self.REMOVE)

    def test_updateSubscriptions_raisesInvalidResponse_withNonStringList(self):
        self.set_http_response_value("""
        {"timestamp": 1262103016, "update_urls": [
            ["http://example.com/", 2],
            [56, "http://example.org/"]
        ]}
        """)
        self.assertRaises(api.InvalidResponse,
                          self.client.update_subscriptions, DEVICE_ID_2,
                          self.ADD, self.REMOVE)

    def test_updateSubscriptions_raisesInvalidResponse_withInvalidList(self):
        self.set_http_response_value("""
        {"timestamp": 1262103016, "update_urls": [
            ["test", "test2", "test3"],
            ["test", "test2"]
        ]}
        """)
        self.assertRaises(api.InvalidResponse,
                          self.client.update_subscriptions, DEVICE_ID_2,
                          self.ADD, self.REMOVE)

    def test_updateSubscriptions_returnsUpdateResult(self):
        self.set_http_response_value("""
        {"timestamp": 1262103016, "update_urls": [
            ["http://test2.invalid/feed.rss",
             "http://test2.invalid/feed.rss"],
            ["http://x.invalid/episodes.xml?format=2",
             "http://x.invalid/episodes.xml"]
        ]}
        """)
        update_urls_expected = [
            ('http://test2.invalid/feed.rss', 'http://test2.invalid/feed.rss'),
            ('http://x.invalid/episodes.xml?format=2',
             'http://x.invalid/episodes.xml'),
        ]

        result = self.client.update_subscriptions(DEVICE_ID_1, self.ADD,
                                                  self.REMOVE)
        # result is a UpdateResult object
        self.assert_(hasattr(result, 'since'))
        self.assert_(hasattr(result, 'update_urls'))
        self.assertEquals(result.since, self.SINCE)
        self.assertEquals(result.update_urls, update_urls_expected)
        self.assert_http_request_count(1)
        self.assert_(self.has_posted_json_data(self.ADD_REMOVE_AS_JSON_UPLOAD))

    def test_pullSubscriptions_raisesInvalidResponse_onEmptyResponse(self):
        self.set_http_response_value('')
        self.assertRaises(api.InvalidResponse, self.client.pull_subscriptions,
                          DEVICE_ID_2)

    def test_pullSubscriptions_raisesInvalidResponse_onMissingTimestamp(self):
        self.set_http_response_value("""
        {"add": [
            "http://example.com/test.rss",
            "http://feeds.example.org/1/feed.atom"
        ],
        "remove": [
            "http://example.co.uk/episodes.xml",
            "http://pod.cast/test.xml"
        ]}
        """)
        self.assertRaises(api.InvalidResponse, self.client.pull_subscriptions,
                          DEVICE_ID_2)

    def test_pullSubscriptions_raisesInvalidResponse_onMissingAddList(self):
        self.set_http_response_value("""
        {"remove": [
            "http://example.co.uk/episodes.xml",
            "http://pod.cast/test.xml"
        ],
        "timestamp": 1262103016}
        """)
        self.assertRaises(api.InvalidResponse, self.client.pull_subscriptions,
                          DEVICE_ID_2)

    def test_pullSubscriptions_raisesInvalidResponse_onMissingRemoveList(self):
        self.set_http_response_value("""
        {"add": [
            "http://example.com/test.rss",
            "http://feeds.example.org/1/feed.atom"
        ],
        "timestamp": 1262103016}
        """)
        self.assertRaises(api.InvalidResponse, self.client.pull_subscriptions,
                          DEVICE_ID_2)

    def test_pullSubscriptions_raisesInvalidResponse_onInvalidTimestamp(self):
        self.set_http_response_value("""
        {"add": [
            "http://example.com/test.rss",
            "http://feeds.example.org/1/feed.atom"
        ],
        "remove": [
            "http://example.co.uk/episodes.xml",
            "http://pod.cast/test.xml"
        ],
        "timestamp": "should not work"}
        """)
        self.assertRaises(api.InvalidResponse, self.client.pull_subscriptions,
                          DEVICE_ID_2)

    def test_pullSubscriptions_raisesInvalidResponse_onInvalidAddList(self):
        self.set_http_response_value("""
        {"add": [
            "http://example.com/test.rss",
            1234,
            "http://feeds.example.org/1/feed.atom"
        ],
        "remove": [
            "http://example.co.uk/episodes.xml",
            "http://pod.cast/test.xml"
        ],
        "timestamp": 1262103016}
        """)
        self.assertRaises(api.InvalidResponse, self.client.pull_subscriptions,
                          DEVICE_ID_2)

    def test_pullSubscriptions_raisesInvalidResponse_onInvalidRemoveList(self):
        self.set_http_response_value("""
        {"add": [
            "http://example.com/test.rss",
            "http://feeds.example.org/1/feed.atom"
        ],
        "remove": [
            "http://example.co.uk/episodes.xml",
            ["should", "not", "work", "either"],
            "http://pod.cast/test.xml"
        ],
        "timestamp": 1262103016}
        """)
        self.assertRaises(api.InvalidResponse, self.client.pull_subscriptions,
                          DEVICE_ID_2)

    def test_pullSubscriptions_returnsChangesListAndTimestamp(self):
        self.set_http_response_value("""
        {"add": [
            "http://example.com/test.rss",
            "http://feeds.example.org/1/feed.atom"
        ],
        "remove": [
            "http://example.co.uk/episodes.xml",
            "http://pod.cast/test.xml"
        ],
        "timestamp": 1262103016}
        """)
        changes = self.client.pull_subscriptions(DEVICE_ID_2)
        self.assertEquals(changes.add, [FEED_URL_1, FEED_URL_2])
        self.assertEquals(changes.remove, [FEED_URL_3, FEED_URL_4])
        self.assertEquals(changes.since, self.SINCE)
        self.assert_http_request_count(1)

    def test_uploadEpisodeActions_raisesInvalidResponse_onEmptyResponse(self):
        self.set_http_response_value('')
        self.assertRaises(api.InvalidResponse,
                          self.client.upload_episode_actions, self.ACTIONS)

    def test_uploadEpisodeActions_raisesInvalidResponse_onMissingTimestamp(
            self):
        self.set_http_response_value('{}')
        self.assertRaises(api.InvalidResponse,
                          self.client.upload_episode_actions, self.ACTIONS)

    def test_uploadEpisodeActions_raisesInvalidResponse_onInvalidTimestamp(
            self):
        self.set_http_response_value("""
        {"timestamp": "just nothin'.."}
        """)
        self.assertRaises(api.InvalidResponse,
                          self.client.upload_episode_actions, self.ACTIONS)

    def test_uploadEpisodeActions_returnsTimestamp(self):
        self.set_http_response_value("""
        {"timestamp": 1262103016}
        """)
        result = self.client.upload_episode_actions(self.ACTIONS)
        self.assertEquals(result, self.SINCE)
        self.assert_http_request_count(1)
        self.assert_(self.has_posted_json_data(self.ACTIONS_AS_JSON_UPLOAD))

    def test_downloadEpisodeActions_raisesInvalidResponse_onEmptyResponse(
            self):
        self.set_http_response_value('')
        self.assertRaises(api.InvalidResponse,
                          self.client.download_episode_actions)

    def test_downloadEpisodeActions_raisesInvalidResponse_onMissingActions(
            self):
        self.set_http_response_value("""
        {"timestamp": 1262103016}
        """)
        self.assertRaises(api.InvalidResponse,
                          self.client.download_episode_actions)

    def test_downloadEpisodeActions_raisesInvalidResponse_onMissingTimestamp(
            self):
        self.set_http_response_value("""
        {"actions": [
            {"podcast": "a", "episode": "b", "action": "download"},
            {"podcast": "x", "episode": "y", "action": "play"}
        ]}
        """)
        self.assertRaises(api.InvalidResponse,
                          self.client.download_episode_actions)

    def test_downloadEpisodeActions_raisesInvalidResponse_onInvalidTimestamp(
            self):
        self.set_http_response_value("""
        {"actions": [
            {"podcast": "a", "episode": "b", "action": "download"},
            {"podcast": "x", "episode": "y", "action": "play"}
        ], "timestamp": "right now"}
        """)
        self.assertRaises(api.InvalidResponse,
                          self.client.download_episode_actions)

    def test_downloadEpisodeActions_raisesInvalidResponse_onIncompleteActions(
            self):
        self.set_http_response_value("""
        {"actions": [
            {"podcast": "a", "episode": "b", "action": "download"},
            {"podcast": "x", "episode": "y"}
        ], "timestamp": 1262103016}
        """)
        self.assertRaises(api.InvalidResponse,
                          self.client.download_episode_actions)

    def test_downloadEpisodeActions_returnsActionList(self):
        self.set_http_response_value("""
        {"actions": [
            {"podcast": "a", "episode": "b", "action": "download"},
            {"podcast": "x", "episode": "y", "action": "play"}
        ], "timestamp": 1262103016}
        """)
        changes = self.client.download_episode_actions()
        self.assertEquals(len(changes.actions), 2)
        action1, action2 = changes.actions
        self.assertEquals(action1.podcast, 'a')
        self.assertEquals(action1.episode, 'b')
        self.assertEquals(action1.action, 'download')
        self.assertEquals(action2.podcast, 'x')
        self.assertEquals(action2.episode, 'y')
        self.assertEquals(action2.action, 'play')
        self.assertEquals(changes.since, self.SINCE)
        self.assert_http_request_count(1)

    def test_updateDeviceSettings_withNothing(self):
        self.set_http_response_value('')
        result = self.client.update_device_settings(DEVICE_ID_1)
        self.assertEquals(result, True)
        self.assert_http_request_count(1)
        self.assert_(self.has_posted_json_data({}))

    def test_updateDeviceSettings_withCaption(self):
        self.set_http_response_value('')
        result = self.client.update_device_settings(DEVICE_ID_1,
                                                    caption='Poodonkis')
        self.assertEquals(result, True)
        self.assert_http_request_count(1)
        self.assert_(self.has_posted_json_data({'caption': 'Poodonkis'}))

    def test_updateDeviceSettings_withType(self):
        self.set_http_response_value('')
        result = self.client.update_device_settings(DEVICE_ID_1,
                                                    type='desktop')
        self.assertEquals(result, True)
        self.assert_http_request_count(1)
        self.assert_(self.has_posted_json_data({'type': 'desktop'}))

    def test_updateDeviceSettings_withCaptionAndType(self):
        self.set_http_response_value('')
        result = self.client.update_device_settings(DEVICE_ID_1,
                                                    'My Unit Testing Device',
                                                    'desktop')
        self.assertEquals(result, True)
        self.assert_http_request_count(1)
        self.assert_(
            self.has_posted_json_data({
                'caption': 'My Unit Testing Device',
                'type': 'desktop'
            }))

    def test_getDevices_raisesInvalidResponse_onEmptyResponse(self):
        self.set_http_response_value('')
        self.assertRaises(api.InvalidResponse, self.client.get_devices)

    def test_getDevices_raisesInvalidResponse_onMissingKeys(self):
        self.set_http_response_value("""
        [
            {"id": "gpodder.on.my.phone",
             "type": "mobile",
             "subscriptions": 42},
            {"id": "95dce59cf340123fa",
             "caption": "The Lappy",
             "subscriptions": 4711}
        ]
        """)
        self.assertRaises(api.InvalidResponse, self.client.get_devices)

    def test_getDevices_returnsDeviceList(self):
        self.set_http_response_value("""
        [
            {"id": "gpodder.on.my.phone",
             "caption": "Phone",
             "type": "mobile",
             "subscriptions": 42},
            {"id": "95dce59cf340123fa",
             "caption": "The Lappy",
             "type": "laptop",
             "subscriptions": 4711}
        ]
        """)
        devices = self.client.get_devices()
        self.assertEquals(len(devices), 2)
        device1, device2 = devices
        self.assertEquals(device1.device_id, DEVICE_ID_1)
        self.assertEquals(device1.caption, 'Phone')
        self.assertEquals(device1.type, 'mobile')
        self.assertEquals(device1.subscriptions, 42)
        self.assertEquals(device2.device_id, DEVICE_ID_2)
        self.assertEquals(device2.caption, 'The Lappy')
        self.assertEquals(device2.type, 'laptop')
        self.assertEquals(device2.subscriptions, 4711)
        self.assert_http_request_count(1)

    def test_getFavoriteEpisodes_returnsEpisodeList(self):
        self.set_http_response_value("""
        [
            {"title": "TWiT 245: No Hitler For You",
             "url": "http://www.podtrac.com/pts/redirect.mp3/aolradio.podcast.aol.com/twit/twit0245.mp3",
             "podcast_title": "this WEEK in TECH - MP3 Edition",
             "podcast_url": "http://leo.am/podcasts/twit", 
             "description": "[...]",
             "website": "http://www.podtrac.com/pts/redirect.mp3/aolradio.podcast.aol.com/twit/twit0245.mp3", 
             "released": "2010-12-25T00:30:00",
             "mygpo_link": "http://gpodder.net/episode/1046492"},
            {"website": "http://feedproxy.google.com/~r/coverville/~3/5UK8-PZmmMQ/", 
             "podcast_title": "Coverville", 
             "description": "Bob Dylan turned 70 this week. Bob Dylan has done a lot of songs. A lot of people have covered Bob’s songs. Did I mention Bob Dylan turned 70 this week? All this adds up to a Cover Story. Let me play you it. 59 minutes | Featuring: Title Artist Album Original Artist 1 Blowin’ [...]", 
             "title": "Coverville 774: The Bob Dylan Cover Story VI", 
             "url": "http://feedproxy.google.com/~r/coverville/~5/iV_RxVU1Jek/Coverville-110527.mp3", 
             "podcast_url": "http://feeds.feedburner.com/coverville", 
             "released": "2011-05-28T01:08:59", 
             "mygpo_link": "http://gpodder.net/episode/5329203"}
        ]
        """)
        favorites = self.client.get_favorite_episodes()
        self.assertEquals(len(favorites), 2)
        episode1, episode2 = favorites
        self.assertEquals(episode1.title, 'TWiT 245: No Hitler For You')
        self.assertEquals(
            episode1.url,
            'http://www.podtrac.com/pts/redirect.mp3/aolradio.podcast.aol.com/twit/twit0245.mp3'
        )
        self.assertEquals(episode1.podcast_title,
                          'this WEEK in TECH - MP3 Edition')
        self.assertEquals(episode1.podcast_url, 'http://leo.am/podcasts/twit')
        self.assertEquals(episode1.description, '[...]')
        self.assertEquals(
            episode1.website,
            'http://www.podtrac.com/pts/redirect.mp3/aolradio.podcast.aol.com/twit/twit0245.mp3'
        )
        self.assertEquals(episode1.released, '2010-12-25T00:30:00')
        self.assertEquals(episode1.mygpo_link,
                          'http://gpodder.net/episode/1046492')
        self.assertEquals(
            episode2.website,
            'http://feedproxy.google.com/~r/coverville/~3/5UK8-PZmmMQ/')