bgneal@973: """
bgneal@973: Tests for the forms in the user_photos application.
bgneal@973: """
bgneal@976: from contextlib import contextmanager
bgneal@973: 
bgneal@973: import mock
bgneal@973: from django import forms
bgneal@973: from django.conf import settings
bgneal@973: from django.contrib.auth.models import User
bgneal@973: from django.test import TestCase
bgneal@973: 
bgneal@973: from user_photos.forms import HotLinkImageForm
bgneal@973: 
bgneal@973: 
bgneal@976: @contextmanager
bgneal@976: def fake_remove_file(path):
bgneal@976:     yield path
bgneal@976: 
bgneal@976: 
bgneal@973: class HotLinkImageFormTestCase(TestCase):
bgneal@973: 
bgneal@973:     def setUp(self):
bgneal@973:         self.username = 'test_user'
bgneal@973:         self.pw = 'password'
bgneal@973:         self.user = User.objects.create_user(self.username, '', self.pw)
bgneal@973:         self.user.save()
bgneal@973:         self.client.login(username=self.username, password=self.pw)
bgneal@973: 
bgneal@973:     @mock.patch('user_photos.forms.rate_limit_user')
bgneal@973:     def test_no_url(self, rate_limit_mock):
bgneal@973:         args = {}
bgneal@973:         form = HotLinkImageForm(args, user=self.user)
bgneal@973:         self.assertFalse(form.is_valid())
bgneal@973: 
bgneal@973:     @mock.patch('user_photos.forms.rate_limit_user')
bgneal@973:     def test_bad_url(self, rate_limit_mock):
bgneal@973:         args = {'url': 'jkdal;jkkls;$JSx49'}
bgneal@973:         form = HotLinkImageForm(args, user=self.user)
bgneal@973:         self.assertFalse(form.is_valid())
bgneal@973: 
bgneal@973:     @mock.patch('user_photos.forms.rate_limit_user')
bgneal@973:     def test_rate_limit(self, rate_limit_mock):
bgneal@973:         rate_limit_mock.side_effect = forms.ValidationError("Rate limit exceeded")
bgneal@973:         args = {'url': 'http://example.com/a.jpg'}
bgneal@973:         form = HotLinkImageForm(args, user=self.user)
bgneal@973:         self.assertFalse(form.is_valid())
bgneal@973: 
bgneal@973:     @mock.patch('user_photos.forms.rate_limit_user')
bgneal@973:     @mock.patch('user_photos.forms.download_file')
bgneal@976:     @mock.patch('user_photos.forms.remove_file', new=fake_remove_file)
bgneal@973:     @mock.patch('user_photos.forms.S3Bucket')
bgneal@973:     @mock.patch('user_photos.forms.upload')
bgneal@973:     def test_white_listed_url(self, upload_mock, bucket_mock, dl_mock, rate_limit_mock):
bgneal@973:         url = 'https://{}/a.jpg'.format(settings.USER_IMAGES_SOURCES[0])
bgneal@973:         args = {'url': url}
bgneal@973:         form = HotLinkImageForm(args, user=self.user)
bgneal@973:         self.assertTrue(form.is_valid())
bgneal@973:         result = form.save()
bgneal@973:         self.assertEqual(result, url)
bgneal@973:         self.assertFalse(dl_mock.called)
bgneal@973:         self.assertFalse(bucket_mock.called)
bgneal@973:         self.assertFalse(upload_mock.called)
bgneal@973: 
bgneal@973:     @mock.patch('user_photos.forms.rate_limit_user')
bgneal@973:     @mock.patch('user_photos.forms.download_file')
bgneal@976:     @mock.patch('user_photos.forms.remove_file', new=fake_remove_file)
bgneal@973:     @mock.patch('user_photos.forms.S3Bucket')
bgneal@973:     @mock.patch('user_photos.forms.upload')
bgneal@973:     def test_happy_path(self, upload_mock, bucket_mock, dl_mock, rate_limit_mock):
bgneal@973:         url = 'http://example.com/a.jpg'
bgneal@973:         args = {'url': url}
bgneal@973:         form = HotLinkImageForm(args, user=self.user)
bgneal@973:         self.assertTrue(form.is_valid())
bgneal@973:         new_url = 'https://img.example.com/a.jpg'
bgneal@973:         upload_mock.return_value = (new_url, None)
bgneal@973:         result = form.save()
bgneal@973:         dl_mock.assert_called_once_with(url)
bgneal@973:         self.assertEqual(result, new_url)
bgneal@973: