bgneal@868: """Unit tests for the ssl_images management command."""
bgneal@870: import re
bgneal@868: import unittest
bgneal@889: from urlparse import urlparse
bgneal@868: 
bgneal@872: import mock
bgneal@872: 
bgneal@894: from core.management.commands.ssl_images import html_check
bgneal@868: from core.management.commands.ssl_images import process_post
bgneal@889: import core.management.commands.ssl_images
bgneal@868: 
bgneal@868: 
bgneal@868: class ProcessPostTestCase(unittest.TestCase):
bgneal@868: 
bgneal@870:     SG101_RE = re.compile(r'http://(?:www\.)?surfguitar101.com/', re.I)
bgneal@870: 
bgneal@889:     def tearDown(self):
bgneal@889:         core.management.commands.ssl_images.url_cache = {}
bgneal@889: 
bgneal@868:     def test_empty_string(self):
bgneal@868:         s = process_post('')
bgneal@868:         self.assertEqual(s, '')
bgneal@870: 
bgneal@870:     def test_no_matches(self):
bgneal@870:         test_str = """Here is a post that doesn't contain any image links at
bgneal@870:         all. It also spans lines.
bgneal@870:         """
bgneal@870:         result = process_post(test_str)
bgneal@870:         self.assertEqual(test_str, result)
bgneal@870: 
bgneal@870:     def test_sg101_images(self):
bgneal@870:         test_str = """An image: ![image](http://www.surfguitar101.com/img.jpg)
bgneal@870:         And another: ![pic](HTTP://SURFGUITAR101.COM/foo/bar/img.png).
bgneal@870:         More stuff here."""
bgneal@870:         expected = self.SG101_RE.sub('/', test_str)
bgneal@870:         result = process_post(test_str)
bgneal@870:         self.assertNotEqual(test_str, expected)
bgneal@870:         self.assertEqual(expected, result)
bgneal@870: 
bgneal@871:     def test_sg101_with_newlines(self):
bgneal@871:         test_str = """An image: ![image](
bgneal@871: http://surfguitar101.com/media/zzz.jpg
bgneal@871: )
bgneal@871:     with trailing text."""
bgneal@871:         expected = """An image: ![image](/media/zzz.jpg)
bgneal@871:     with trailing text."""
bgneal@871:         result = process_post(test_str)
bgneal@871:         self.assertNotEqual(test_str, expected)
bgneal@871:         self.assertEqual(expected, result)
bgneal@871: 
bgneal@870:     def test_https_already(self):
bgneal@871:         test_str = """An image that is already using https:
bgneal@871:             ![flyer](https://example.com/zzz.png)
bgneal@871:             It's cool.
bgneal@871:             """
bgneal@871:         result = process_post(test_str)
bgneal@871:         self.assertEqual(test_str, result)
bgneal@871: 
bgneal@871:     def test_https_sg101(self):
bgneal@871:         test_str = """An image that is already using https:
bgneal@871:             ![flyer](https://www.SURFGUITAR101.com/zzz.png)
bgneal@871:             It's cool.
bgneal@871:             """
bgneal@871:         expected = """An image that is already using https:
bgneal@871:             ![flyer](/zzz.png)
bgneal@871:             It's cool.
bgneal@871:             """
bgneal@871:         result = process_post(test_str)
bgneal@871:         self.assertEqual(expected, result)
bgneal@871: 
bgneal@871:     def test_multiple_non_http(self):
bgneal@871:         test_str = """An image: ![image](http://www.surfguitar101.com/img.jpg)
bgneal@871:         And another: ![pic](HTTPS://example.com/foo/bar/img.png).
bgneal@871:         More stuff here."""
bgneal@871:         expected = """An image: ![image](/img.jpg)
bgneal@871:         And another: ![pic](HTTPS://example.com/foo/bar/img.png).
bgneal@871:         More stuff here."""
bgneal@871:         result = process_post(test_str)
bgneal@871:         self.assertEqual(expected, result)
bgneal@871: 
bgneal@871:     def test_https_already_with_title(self):
bgneal@871:         test_str = """An image that is already using https:
bgneal@871:             ![flyer](https://example.com/zzz.png "the title")
bgneal@871:             It's cool.
bgneal@871:             """
bgneal@871:         result = process_post(test_str)
bgneal@871:         self.assertEqual(test_str, result)
bgneal@871: 
bgneal@871:     def test_sg101_with_title(self):
bgneal@871:         test_str = """An image on SG101:
bgneal@871:             ![flyer](http://surfguitar101.com/zzz.png "the title")
bgneal@871:             It's cool.
bgneal@871:             """
bgneal@871:         expected = """An image on SG101:
bgneal@871:             ![flyer](/zzz.png "the title")
bgneal@871:             It's cool.
bgneal@871:             """
bgneal@871:         result = process_post(test_str)
bgneal@871:         self.assertEqual(expected, result)
bgneal@871: 
bgneal@871:     def test_https_sg101_brackets(self):
bgneal@871:         test_str = """An image that is already using https:
bgneal@871:             ![flyer](<https://www.SURFGUITAR101.com/zzz.png>)
bgneal@871:             It's cool.
bgneal@871:             """
bgneal@871:         expected = """An image that is already using https:
bgneal@871:             ![flyer](/zzz.png)
bgneal@871:             It's cool.
bgneal@871:             """
bgneal@871:         result = process_post(test_str)
bgneal@871:         self.assertEqual(expected, result)
bgneal@871: 
bgneal@871:     def test_https_already_brackets(self):
bgneal@871:         test_str = """An image that is already using https:
bgneal@871:             ![flyer](<https://example.com/zzz.png>)
bgneal@871:             It's cool.
bgneal@871:             """
bgneal@871:         expected = """An image that is already using https:
bgneal@871:             ![flyer](https://example.com/zzz.png)
bgneal@871:             It's cool.
bgneal@871:             """
bgneal@871:         result = process_post(test_str)
bgneal@871:         self.assertEqual(expected, result)
bgneal@872: 
bgneal@872:     @mock.patch('core.management.commands.ssl_images.save_image_to_cloud')
bgneal@872:     def test_simple_replacement(self, upload_mock):
bgneal@872:         old_src = 'http://example.com/images/my_image.jpg'
bgneal@873:         new_src = 'https://cloud.com/ABCDEF.jpg'
bgneal@872:         test_str = """Here is a really cool http: based image:
bgneal@872:             ![flyer]({})
bgneal@872:             Cool, right?""".format(old_src)
bgneal@872:         expected = """Here is a really cool http: based image:
bgneal@872:             ![flyer]({})
bgneal@872:             Cool, right?""".format(new_src)
bgneal@872: 
bgneal@872:         upload_mock.return_value = new_src
bgneal@872:         result = process_post(test_str)
bgneal@872:         self.assertEqual(expected, result)
bgneal@927:         upload_mock.assert_called_once_with(urlparse(old_src))
bgneal@873: 
bgneal@873:     @mock.patch('core.management.commands.ssl_images.save_image_to_cloud')
bgneal@873:     def test_multiple_replacement(self, upload_mock):
bgneal@873:         old_src = [
bgneal@873:             'http://example.com/images/my_image.jpg',
bgneal@873:             'http://example.com/static/wow.gif',
bgneal@873:             'http://example.com/media/a/b/c/pic.png',
bgneal@873:         ]
bgneal@873:         new_src = [
bgneal@873:             'https://cloud.com/some/path/012345.jpg',
bgneal@873:             'https://cloud.com/some/path/6789AB.gif',
bgneal@873:             'https://cloud.com/some/path/CDEF01.png',
bgneal@873:         ]
bgneal@873: 
bgneal@873:         template = """Here is a really cool http: based image:
bgneal@873:             ![flyer]({})
bgneal@873:             Cool, right?
bgneal@873:             Another one: ![pic]({})
bgneal@873:             And finally
bgneal@873:             ![an image]({})
bgneal@873:             """
bgneal@873: 
bgneal@873:         test_str = template.format(*old_src)
bgneal@873:         expected = template.format(*new_src)
bgneal@873: 
bgneal@873:         upload_mock.side_effect = new_src
bgneal@873:         result = process_post(test_str)
bgneal@873:         self.assertEqual(expected, result)
bgneal@927:         expected_args = [mock.call(urlparse(c)) for c in old_src]
bgneal@873:         self.assertEqual(upload_mock.call_args_list, expected_args)
bgneal@873: 
bgneal@873:     @mock.patch('core.management.commands.ssl_images.save_image_to_cloud')
bgneal@873:     def test_multiple_replacement_2(self, upload_mock):
bgneal@873:         old_src = [
bgneal@873:             'http://example.com/images/my_image.jpg',
bgneal@873:             'https://example.com/static/wow.gif',
bgneal@873:             'http://www.surfguitar101.com/media/a/b/c/pic.png',
bgneal@873:             'http://surfguitar101.com/media/a/b/c/pic2.png',
bgneal@873:         ]
bgneal@873:         new_src = [
bgneal@873:             'https://cloud.com/some/path/012345.jpg',
bgneal@873:             'https://example.com/static/wow.gif',
bgneal@873:             '/media/a/b/c/pic.png',
bgneal@873:             '/media/a/b/c/pic2.png',
bgneal@873:         ]
bgneal@873: 
bgneal@873:         template = """Here is a really cool http: based image:
bgneal@873:             ![flyer]({})
bgneal@873:             Cool, right?
bgneal@873:             Another two: ![pic]({})  ![photo]({})
bgneal@873:             And finally
bgneal@873:             ![an image]({}).
bgneal@873:             """
bgneal@873: 
bgneal@873:         test_str = template.format(*old_src)
bgneal@873:         expected = template.format(*new_src)
bgneal@873: 
bgneal@873:         upload_mock.side_effect = new_src
bgneal@873:         result = process_post(test_str)
bgneal@873:         self.assertEqual(expected, result)
bgneal@927:         upload_mock.assert_called_once_with(urlparse(old_src[0]))
bgneal@889: 
bgneal@889:     @mock.patch('core.management.commands.ssl_images.save_image_to_cloud')
bgneal@889:     def test_caching(self, upload_mock):
bgneal@889:         old_src = [
bgneal@889:             'http://example.com/images/my_image.jpg',
bgneal@889:             'http://example.com/static/wow.gif',
bgneal@889:             'http://example.com/images/my_image.jpg',
bgneal@889:         ]
bgneal@889:         new_src = [
bgneal@889:             'https://cloud.com/some/path/012345.jpg',
bgneal@889:             'https://cloud.com/some/path/6789AB.gif',
bgneal@889:             'https://cloud.com/some/path/012345.jpg',
bgneal@889:         ]
bgneal@889: 
bgneal@889:         template = """Here is a really cool http: based image:
bgneal@889:             ![flyer]({})
bgneal@889:             Cool, right?
bgneal@889:             Another one: ![pic]({})
bgneal@889:             And finally
bgneal@889:             ![an image]({})
bgneal@889:             """
bgneal@889: 
bgneal@889:         test_str = template.format(*old_src)
bgneal@889:         expected = template.format(*new_src)
bgneal@889: 
bgneal@889:         upload_mock.side_effect = new_src
bgneal@889:         result = process_post(test_str)
bgneal@889:         self.assertEqual(expected, result)
bgneal@927:         expected_args = [mock.call(urlparse(c)) for c in old_src[:2]]
bgneal@889:         self.assertEqual(upload_mock.call_args_list, expected_args)
bgneal@889: 
bgneal@894: 
bgneal@894: class HtmlCheckTestCase(unittest.TestCase):
bgneal@894: 
bgneal@894:     def test_empty(self):
bgneal@894:         self.assertFalse(html_check(''))
bgneal@894: 
bgneal@894:     def test_no_images(self):
bgneal@894:         self.assertFalse(html_check('<p>Hi there!</p>'))
bgneal@894:         self.assertFalse(html_check('<p>Hi <b>there</b>!</p>'))
bgneal@894: 
bgneal@894:     def test_safe_image(self):
bgneal@894:         self.assertFalse(html_check('<img src="https://a.jpg" />'))
bgneal@894:         self.assertFalse(html_check('<img src="" alt="stuff" />'))
bgneal@894:         self.assertFalse(html_check('<img src="HTTPS://a.jpg" />'))
bgneal@894:         self.assertFalse(html_check("""
bgneal@894:             <div>
bgneal@894:             <p>Look: <img src="https://a.jpg" alt="a" /></p>
bgneal@894:             <p>Look again: <img src="https://b.jpg" alt="b" /></p>
bgneal@894:             </div>
bgneal@894:             """))
bgneal@894: 
bgneal@894:     def test_one_image(self):
bgneal@894:         self.assertTrue(html_check('<img src="http://a.jpg" alt="a" />'))
bgneal@894:         self.assertTrue(html_check(
bgneal@894:             '<p>Look: <img src="http://a.jpg" alt="a" /></p>'))
bgneal@894: 
bgneal@894:     def test_two_images(self):
bgneal@894:         self.assertTrue(html_check("""
bgneal@894:             <p>Look: <img src="https://a.jpg" alt="a" /></p>
bgneal@894:             <p>Look again: <img src="http://b.jpg" alt="b" /></p>
bgneal@894:             """))
bgneal@894:         self.assertTrue(html_check("""
bgneal@894:             <p>Look: <img src="http://a.jpg" alt="a" /></p>
bgneal@894:             <p>Look again: <img src="http://b.jpg" alt="b" /></p>
bgneal@894:             """))
bgneal@894:         self.assertTrue(html_check("""
bgneal@894:             <div>
bgneal@894:             <p>Look: <img src="http://a.jpg" alt="a" /></p>
bgneal@894:             <p>Look again: <img src="http://b.jpg" alt="b" /></p>
bgneal@894:             </div>
bgneal@894:             """))
bgneal@894:         self.assertTrue(html_check("""
bgneal@894:             <div>
bgneal@894:             <p>Look: <img src="http://a.jpg" alt="a" /></p>
bgneal@894:             <p>Look again: <img src="https://b.jpg" alt="b" /></p>
bgneal@894:             </div>
bgneal@894:             """))