def setUp(self): TestCase.setUp(self) self.owner = self.make_user('owner') self.owner.get_profile().approved = True self.owner.get_profile().save() self.channels = [] for i in range(2): channel = self.make_channel(self.owner, state='A') channel.name = 'My Channel %i' % i channel.save() self.channels.append(channel) self.categories = categories = [] self.languages = languages = [] self.items = [] for n in range(2): cat = Category(name='category%i' % n) cat.save() lang = Language(name='language%i' % n) lang.save() item = Item() item.channel_id = self.channels[0].id item.url = self.channels[0].url + '?item=%i' % n item.name = 'item%i' % n item.description = 'Item' item.size = i item.date = datetime.now() item.save() item.save_thumbnail( file(test_data_path('thumbnail.jpg'))) categories.append(cat) languages.append(lang) self.items.append(item) self.channels[0].categories.add(*categories) self.channels[0].language = languages[0] self.channels[0].add_tags(self.owner, ['tag0', 'tag1']) self.channels[0].save_thumbnail( file(test_data_path('thumbnail.jpg'))) self.channels[1].description = 'This is a different description.' self.channels[1].save() # the order is important because of throttling so we do them in reverse # order Subscription.objects.add(self.channels[0], '123.123.123.123', timestamp=datetime.now() - timedelta(days=1)) Subscription.objects.add(self.channels[0], '123.123.123.123') for i in range(5): user = self.make_user('foo%i' % i) user.get_profile().approved = True user.get_profile().save() for channel in self.channels: rating, _ = Rating.objects.get_or_create(channel=channel, user=user) rating.rating = i + 1 rating.save()
def test_future_corner_cases(self): """Test some corner cases when we update a feed, duplicate URLS, duplicate GUIDs, items missing GUIDs and URLS. """ self.channel.update_items( feedparser_input=open(test_data_path('feed-future.xml'))) self.channel.update_items(feedparser_input=open( test_data_path('feed-future-corner-cases.xml')))
def setUp(self): TestCase.setUp(self) self.owner = self.make_user('owner') self.owner.get_profile().approved = True self.owner.get_profile().save() self.channels = [] for i in range(2): channel = self.make_channel(self.owner, state='A') channel.name = 'My Channel %i' % i channel.save() self.channels.append(channel) self.categories = categories = [] self.languages = languages = [] self.items = [] for n in range(2): cat = Category(name='category%i' % n) cat.save() lang = Language(name='language%i' % n) lang.save() item = Item() item.channel_id = self.channels[0].id item.url = self.channels[0].url + '?item=%i' % n item.name = 'item%i' % n item.description = 'Item' item.size = i item.date = datetime.now() item.save() item.save_thumbnail(file(test_data_path('thumbnail.jpg'))) categories.append(cat) languages.append(lang) self.items.append(item) self.channels[0].categories.add(*categories) self.channels[0].language = languages[0] self.channels[0].add_tags(self.owner, ['tag0', 'tag1']) self.channels[0].save_thumbnail(file(test_data_path('thumbnail.jpg'))) self.channels[1].description = 'This is a different description.' self.channels[1].save() # the order is important because of throttling so we do them in reverse # order Subscription.objects.add(self.channels[0], '123.123.123.123', timestamp=datetime.now() - timedelta(days=1)) Subscription.objects.add(self.channels[0], '123.123.123.123') for i in range(5): user = self.make_user('foo%i' % i) user.get_profile().approved = True user.get_profile().save() for channel in self.channels: rating, _ = Rating.objects.get_or_create(channel=channel, user=user) rating.rating = i + 1 rating.save()
def test_future_corner_cases(self): """Test some corner cases when we update a feed, duplicate URLS, duplicate GUIDs, items missing GUIDs and URLS. """ self.channel.update_items( feedparser_input=open(test_data_path('feed-future.xml'))) self.channel.update_items( feedparser_input=open(test_data_path( 'feed-future-corner-cases.xml')))
def test_date_is_updated(self): """ If the date is updated in a feed item, the date should be updated in our database as well. """ self.channel.update_items( feedparser_input=open(test_data_path('feed-future.xml'))) old_item = Item.objects.get(name='rb_06_dec_12') self.channel.update_items(feedparser_input=open( test_data_path('feed-future-corner-cases.xml'))) new_item = Item.objects.get(pk=old_item.pk) self.assertNotEquals(old_item.date, new_item.date)
def test_unsuspending_feed(self): """ If a formerly suspended feed is updated and works, it should return to its old state. """ self.assertEquals(self.channel.state, Channel.NEW) self.channel.update_items( feedparser_input=open(test_data_path('badfeed.html'))) self.update_channel() self.assertEquals(self.channel.state, Channel.SUSPENDED) self.channel.update_items( feedparser_input=open(test_data_path('feed.xml'))) self.assertEquals(self.channel.state, Channel.NEW)
def test_item_url_in_database(self): self.channel.url = test_data_path('feed.xml') self.channel.save() self.channel.update_items( feedparser_input=open(self.channel.url)) response = self.get_item(test_data_path('feed.xml'), 'http://www.rocketboom.net/video/' 'rb_06_dec_13.mov') self.assertEquals(response.status_code, 302) self.assertEquals(response['Location'], util.make_absolute_url( self.channel.items.all()[0].get_url(), {'share': 'true'}))
def test_date_is_updated(self): """ If the date is updated in a feed item, the date should be updated in our database as well. """ self.channel.update_items( feedparser_input=open(test_data_path('feed-future.xml'))) old_item = Item.objects.get(name='rb_06_dec_12') self.channel.update_items( feedparser_input=open(test_data_path( 'feed-future-corner-cases.xml'))) new_item = Item.objects.get(pk=old_item.pk) self.assertNotEquals(old_item.date, new_item.date)
def test_item_url_in_database(self): self.channel.url = test_data_path('feed.xml') self.channel.save() self.channel.update_items(feedparser_input=open(self.channel.url)) response = self.get_item( test_data_path('feed.xml'), 'http://www.rocketboom.net/video/' 'rb_06_dec_13.mov') self.assertEquals(response.status_code, 302) self.assertEquals( response['Location'], util.make_absolute_url(self.channel.items.all()[0].get_url(), {'share': 'true'}))
def test_suspend_only_once(self): """ A second update_items() call (say, the next evening) should not result in a second moderator action. """ self.channel.update_items( feedparser_input=open(test_data_path('badfeed.html'))) self.channel.update_items( feedparser_input=open(test_data_path('badfeed.html'))) self.update_channel() self.assertEquals(self.channel.moderator_actions.count(), 1) self.assertEquals(self.channel.moderator_actions.all()[0].action, Channel.SUSPENDED)
def test_replace_thumbnail(self): self.login_and_submit_url() response = self.submit(dont_send='name') self.check_submit_failed(response) response = self.submit(response, thumbnail_file=open(test_data_path('thumbnail_square.png'))) self.check_submit_worked(response, thumb_name='thumbnail_square.png')
def test_archived(self): """ If after a channel is updated, it hasn't had a new item in 90 days, it should have its 'archived' flag set. """ self.assertEquals(self.channel.archived, False) self.channel.update_items( feedparser_input=open(test_data_path('feed.xml'))) self.assertEquals(self.channel.archived, True) newer = """<?xml version="1.0" encoding="utf-8"?> <rss version="2.0"> <channel> <title>Rocketboom RSS 2.0 Main Index</title> <link>http://www.rocketboom.com/vlog/</link> <item> <title>Test</title> <description>Test</description> <link>Test</link> <guid>Test</guid> <pubDate>%s</pubDate> <enclosure url="http://test.com/movie.mov" length="10000" type="video/quicktime"/> </item> </channel> </rss>""" % datetime.now().strftime('%a,%e %h %Y %H:%M:%S %z') self.channel.update_items(newer) self.assertEquals(self.channel.archived, False)
def test_edit_thumbnail(self): self.login(self.ralph) data = self.get_default_values() data['thumbnail_file'] = open(test_data_path('thumbnail.jpg')) self.post_to_edit_page(data) updated = Channel.objects.get(pk=self.channel.pk) self.assertTrue(updated.thumbnail_exists())
def test_item_info(self): def check_count(correct): channel = Channel.objects.get(pk=self.channel.id) self.assertEquals(channel.items.count(), correct) check_count(0) self.channel.update_items( feedparser_input=open(test_data_path('feed.xml'))) check_count(5)
def _feed_data(self): return { 'feed_url': test_data_path('feed.xml'), 'share_url': util.make_absolute_url('/share/feed/?feed_url=foo'), 'share_type': 'feed', 'from_email': '*****@*****.**', 'comment': 'this is my comment', 'recipients': '[email protected], [email protected]'}
def check_last_channel_thumbnail(self, thumb_name): last = self.get_last_channel() path = os.path.join(settings.MEDIA_ROOT, Channel.THUMBNAIL_DIR, 'original', '%d.%s' % (last.id, last.thumbnail_extension)) self.assert_(os.path.exists(path)) right_data = file(test_data_path(thumb_name)).read() actual_data = file(path).read() self.assertEquals(right_data, actual_data, 'thumbnail does not match')
def test_suspending_invalid_feed(self): """ Invalid feeds should be marked as suspended when updated. """ self.channel.update_items( feedparser_input=open(test_data_path('badfeed.html'))) self.update_channel() self.assertEquals(self.channel.state, Channel.SUSPENDED)
def test_thumbnail_before_save(self): c = Channel() c.url = "http://myblog.com/videos/rss" c.website_url = "http://myblog.com/" c.publisher = "TestVision" c.description = "lots of stuff" self.assertRaises(ValueError, c.save_thumbnail, file(test_data_path('thumbnail.jpg')))
def test_suspending_empty_feed(self): """ Empty feeds (no items) should be marked as suspended when updated. """ self.channel.update_items( feedparser_input=open(test_data_path('emptyfeed.xml'))) self.update_channel() self.assertEquals(self.channel.state, Channel.SUSPENDED)
def test_feed_url_in_database(self): self.channel.url = test_data_path('feed.xml') self.channel.save() response = self.get_feed(self.channel.url) self.assertEquals(response.status_code, 302) self.assertEquals(response['Location'], self.channel.get_absolute_url() + '?share=true')
def _feed_data(self): return { 'feed_url': test_data_path('feed.xml'), 'share_url': util.make_absolute_url('/share/feed/?feed_url=foo'), 'share_type': 'feed', 'from_email': '*****@*****.**', 'comment': 'this is my comment', 'recipients': '[email protected], [email protected]' }
def test_suspend_is_logged_empty(self): """ Suspending an empty feed should be logged as a moderator action. """ self.channel.update_items( feedparser_input=open(test_data_path('emptyfeed.xml'))) self.update_channel() self.assertEquals(self.channel.moderator_actions.all()[0].action, Channel.SUSPENDED)
def test_thumbnail(self): image_file = file(test_data_path('thumbnail.jpg')) self.channel.save_thumbnail(image_file) self.check_thumb_exists('original') for width, height in Channel.THUMBNAIL_SIZES: self.check_thumb_exists('%ix%i' % (width, height)) self.assertEquals(image_file.read(), file(self.get_thumb_path('original')).read(), 'thumbnails are not equal')
def test_clean_out_old_suspensions_new(self): """ If, due to a bug, there's a long line of suspensions on a good feed, they shouldn't be counted when going back to the previous state. """ miroguide = User.objects.get(username='******') for i in range(5): ModeratorAction(user=miroguide, channel=self.channel, action='S').save() self.update_channel() self.channel.update_items( feedparser_input=open(test_data_path('badfeed.html'))) self.channel.update_items( feedparser_input=open(test_data_path('feed.xml'))) self.update_channel() self.assertEquals(self.channel.state, 'N') self.assertEquals(self.channel.last_moderated_by_id, None) self.assertEquals(self.channel.moderator_actions.count(), 0)
def test_feed_url_not_in_database(self): response = self.get_feed(test_data_path('feed.xml')) channel = response.context[0]['channel'] self.assertEquals(channel.fake, True) self.assertEquals(channel.name, 'Rocketboom RSS 2.0 Main Index') self.assertFalse(channel.thumbnail_url is None) item_page = response.context[0]['item_page'] self.assertEquals(len(item_page.object_list), 5)
def test_description_capped_at_170_characters(self): self.channel.url = test_data_path('feed.xml') self.channel.description = 'a' * 200 self.channel.save() data = self._feed_data() self.post_data('/share/email/', data) message = self._basic_mail_tests(data) self.assertFalse(self.channel.description in message.body) self.assertTrue(('a' * 167 + '...') in message.body)
def _item_data(self): return { 'feed_url': test_data_path('feed.xml'), 'file_url': 'http://www.rocketboom.net/video/rb_06_dec_13.mov', 'share_url': util.make_absolute_url( '/share/item/?feed_url=foo&item_url=bar'), 'share_type': 'item', 'from_email': '*****@*****.**', 'comment': 'this is my comment', 'recipients': '[email protected], [email protected]'}
def test_unmodified_suspended_with_items_are_unsuspended(self): """ """ self.channel.change_state(self.ralph, Channel.APPROVED) self.channel.update_items( feedparser_input=open(test_data_path('feed.xml'))) self.update_channel() self.channel.change_state(self.ralph, Channel.SUSPENDED) self.channel.download_feed = lambda: None self.channel.update_items() self.assertEquals(self.channel.state, Channel.APPROVED)
def test_send_feed_email_in_database(self): self.channel.url = test_data_path('feed.xml') self.channel.save() data = self._feed_data() self.post_data('/share/email/', data) message = self._basic_mail_tests(data) self.assertEquals(message.subject, '[email protected] wants to share a video feed with you') self.assertTrue(self.channel.name in message.body) self.assertTrue(self.channel.description in message.body)
def test_send_item_email_in_database(self): self.channel.url = test_data_path('feed.xml') self.channel.save() self.channel.update_items(feedparser_input=open(self.channel.url)) data = self._item_data() self.post_data('/share/email/', data) message = self._basic_mail_tests(data) self.assertEquals(message.subject, '[email protected] wants to share a video with you') self.assertTrue('rb_06_dec_13' in message.body) self.assertTrue('wii have a problem' in message.body)
def test_send_feed_email_in_database(self): self.channel.url = test_data_path('feed.xml') self.channel.save() data = self._feed_data() self.post_data('/share/email/', data) message = self._basic_mail_tests(data) self.assertEquals( message.subject, '[email protected] wants to share a video feed with you') self.assertTrue(self.channel.name in message.body) self.assertTrue(self.channel.description in message.body)
def test_item_url_not_in_feed_or_database(self): response = self.get_item(test_data_path('feed.xml'), 'http://google.com/') channel = response.context[0]['channel'] self.assertEquals(channel.fake, True) self.assertEquals(channel.name, 'Rocketboom RSS 2.0 Main Index') item = response.context[0]['item'] self.assertEquals(item.fake, True) self.assertEquals(item.name, 'http://google.com/') self.assertTrue(item.thumbnail_url is None)
def test_thumbnails_converted_to_jpeg(self): self.login_and_submit_url() self.submit(thumbnail_file= open(test_data_path('thumbnail_square.png'))) channel = self.get_last_channel() self.assertTrue(channel.thumbnail_exists()) for size in channel.THUMBNAIL_SIZES: path = channel.thumb_path('%dx%d' % size) self.assertTrue(os.path.exists(path)) self.assertEquals(os.path.splitext(path)[1], '.jpeg') self.assertEquals(util.get_image_extension( file(path)), 'jpeg')
def test_duplicates_not_replaced(self): """Test that when we update a feed, we only replace thumbnails if the enclosure URL is different and the GUID is different. """ def get_item_ids(): return list(self.channel.items.values_list('id', flat=True)) self.channel.update_items( feedparser_input=open(test_data_path('feed.xml'))) old_ids = get_item_ids() self.channel.update_items( feedparser_input=open(test_data_path('feed-future.xml'))) # 2 new entries, 2 entries are gone, the rest are the same. The new # feed has some entries where the GUID stays the same and some where # the enclosure URL stays the same It also has 2 entries with the same # enclosure URL to try to mess with the CG logic new_ids = get_item_ids() self.assert_(new_ids[0] not in old_ids) self.assert_(new_ids[1] not in old_ids) self.assert_(old_ids[-1] not in new_ids) self.assert_(old_ids[-2] not in new_ids) self.assertEquals(new_ids[2:], old_ids[0:-2])
def test_unsuspending_approved_feed(self): """ If a suspended feed was previously approved, it should be approved again after suspension. """ self.channel.change_state(self.ralph, Channel.APPROVED) old_approved_at = self.channel.approved_at.replace(microsecond=0) self.channel.update_items( feedparser_input=open(test_data_path('badfeed.html'))) self.update_channel() self.assertEquals(self.channel.state, Channel.SUSPENDED) self.channel.update_items( feedparser_input=open(test_data_path('feed.xml'))) self.update_channel() self.assertEquals(self.channel.state, Channel.APPROVED) self.assertEquals(self.channel.approved_at, old_approved_at) self.assertEquals(self.channel.last_moderated_by_id, self.ralph.id) self.assertEquals(self.channel.moderator_actions.all()[0].user_id, self.ralph.id) self.assertEquals(self.channel.moderator_actions.all()[0].action, Channel.APPROVED) self.assertEquals(len(mail.outbox), 1) # one for the first approval
def test_bad_feeds_are_suspended(self): """ Test that some known-bad feeds are marked as suspended. """ names = ['24x7_podcasts.xml'] for name in names: self.channel.change_state(self.ralph, Channel.APPROVED) self.update_channel() feed_file = open(test_data_path(os.path.join('bad', name))) self.channel.update_items(feedparser_input=feed_file) self.update_channel() self.assertEquals(self.channel.state, Channel.SUSPENDED, 'did not suspend %r by mistake' % name)
def test_send_item_email_in_database(self): self.channel.url = test_data_path('feed.xml') self.channel.save() self.channel.update_items( feedparser_input=open(self.channel.url)) data = self._item_data() self.post_data('/share/email/', data) message = self._basic_mail_tests(data) self.assertEquals(message.subject, '[email protected] wants to share a video with you') self.assertTrue('rb_06_dec_13' in message.body) self.assertTrue('wii have a problem' in message.body)
def test_item_url_in_feed_not_in_database(self): response = self.get_item(test_data_path('feed.xml'), 'http://www.rocketboom.net/video/' 'rb_06_dec_13.mov') channel = response.context[0]['channel'] self.assertEquals(channel.fake, True) self.assertEquals(channel.name, 'Rocketboom RSS 2.0 Main Index') self.assertFalse(channel.thumbnail_url is None) item = response.context[0]['item'] self.assertEquals(item.fake, True) self.assertEquals(item.name, 'rb_06_dec_13') self.assertFalse(item.thumbnail_url is None)
def test_item_url_in_feed_not_in_database(self): response = self.get_item( test_data_path('feed.xml'), 'http://www.rocketboom.net/video/' 'rb_06_dec_13.mov') channel = response.context[0]['channel'] self.assertEquals(channel.fake, True) self.assertEquals(channel.name, 'Rocketboom RSS 2.0 Main Index') self.assertFalse(channel.thumbnail_url is None) item = response.context[0]['item'] self.assertEquals(item.fake, True) self.assertEquals(item.name, 'rb_06_dec_13') self.assertFalse(item.thumbnail_url is None)