mirror of
https://github.com/pinry/pinry.git
synced 2026-01-27 01:29:21 +01:00
Rewrite tests to use a Model mocker library
There has been issues when running a full test suite (for pinry and the entire Django stack), and test fixtures are hard to maintain anyway, so rewrite tests to use a Model mocker library (Factory Boy) to populate database.
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -6,6 +6,7 @@ from django_images.models import Thumbnail
|
||||
from taggit.models import Tag
|
||||
from tastypie.test import ResourceTestCase
|
||||
|
||||
from .helpers import ImageFactory, PinFactory, UserFactory
|
||||
from ..models import Pin, Image
|
||||
from ...users.models import User
|
||||
|
||||
@@ -31,15 +32,13 @@ def mock_storage_path(self, name):
|
||||
|
||||
@mock.patch('django.core.files.storage.FileSystemStorage.path', mock_storage_path)
|
||||
class ImageResourceTest(ResourceTestCase):
|
||||
fixtures = ['test_resources.json']
|
||||
|
||||
def test_post_create_unsupported(self):
|
||||
"""Make sure that new images can't be created using API"""
|
||||
response = self.api_client.post('/api/v1/image/', format='json', data={})
|
||||
self.assertHttpUnauthorized(response)
|
||||
|
||||
def test_list_detail(self):
|
||||
image = Image.objects.get(pk=1)
|
||||
image = ImageFactory()
|
||||
thumbnail = filter_generator_for('thumbnail')(image)
|
||||
standard = filter_generator_for('standard')(image)
|
||||
square = filter_generator_for('square')(image)
|
||||
@@ -68,15 +67,9 @@ class ImageResourceTest(ResourceTestCase):
|
||||
|
||||
@mock.patch('django.core.files.storage.FileSystemStorage.path', mock_storage_path)
|
||||
class PinResourceTest(ResourceTestCase):
|
||||
fixtures = ['test_resources.json']
|
||||
|
||||
def setUp(self):
|
||||
super(PinResourceTest, self).setUp()
|
||||
|
||||
self.pin_1 = Pin.objects.get(pk=1)
|
||||
self.image_url = ''
|
||||
|
||||
self.user = User.objects.get(pk=1)
|
||||
self.user = UserFactory(password='password')
|
||||
self.api_client.client.login(username=self.user.username, password='password')
|
||||
|
||||
@mock.patch('urllib2.urlopen', mock_urlopen)
|
||||
@@ -88,11 +81,11 @@ class PinResourceTest(ResourceTestCase):
|
||||
}
|
||||
response = self.api_client.post('/api/v1/pin/', data=post_data)
|
||||
self.assertHttpCreated(response)
|
||||
self.assertEqual(Pin.objects.count(), 3)
|
||||
self.assertEqual(Image.objects.count(), 3)
|
||||
self.assertEqual(Pin.objects.count(), 1)
|
||||
self.assertEqual(Image.objects.count(), 1)
|
||||
|
||||
@mock.patch('urllib2.urlopen', mock_urlopen)
|
||||
def test_post_create_url_empty_tags(self):
|
||||
def test_post_create_url_with_empty_tags(self):
|
||||
url = 'http://testserver/mocked/screenshot.png'
|
||||
post_data = {
|
||||
'submitter': '/api/v1/user/1/',
|
||||
@@ -102,8 +95,8 @@ class PinResourceTest(ResourceTestCase):
|
||||
}
|
||||
response = self.api_client.post('/api/v1/pin/', data=post_data)
|
||||
self.assertHttpCreated(response)
|
||||
self.assertEqual(Pin.objects.count(), 3)
|
||||
self.assertEqual(Image.objects.count(), 3)
|
||||
self.assertEqual(Pin.objects.count(), 1)
|
||||
self.assertEqual(Image.objects.count(), 1)
|
||||
pin = Pin.objects.get(url=url)
|
||||
self.assertEqual(pin.tags.count(), 0)
|
||||
|
||||
@@ -118,8 +111,8 @@ class PinResourceTest(ResourceTestCase):
|
||||
}
|
||||
response = self.api_client.post('/api/v1/pin/', data=post_data)
|
||||
self.assertHttpCreated(response)
|
||||
self.assertEqual(Pin.objects.count(), 3)
|
||||
self.assertEqual(Image.objects.count(), 3)
|
||||
self.assertEqual(Pin.objects.count(), 1)
|
||||
self.assertEqual(Image.objects.count(), 1)
|
||||
self.assertEqual(Pin.objects.get(url=url).origin, None)
|
||||
|
||||
@mock.patch('urllib2.urlopen', mock_urlopen)
|
||||
@@ -134,96 +127,102 @@ class PinResourceTest(ResourceTestCase):
|
||||
}
|
||||
response = self.api_client.post('/api/v1/pin/', data=post_data)
|
||||
self.assertHttpCreated(response)
|
||||
self.assertEqual(Pin.objects.count(), 3)
|
||||
self.assertEqual(Image.objects.count(), 3)
|
||||
self.assertEqual(Pin.objects.count(), 1)
|
||||
self.assertEqual(Image.objects.count(), 1)
|
||||
self.assertEqual(Pin.objects.get(url=url).origin, origin)
|
||||
|
||||
def test_post_create_obj(self):
|
||||
user = User.objects.get(pk=1)
|
||||
image = Image.objects.get(pk=1)
|
||||
image = ImageFactory()
|
||||
post_data = {
|
||||
'submitter': '/api/v1/user/{}/'.format(user.pk),
|
||||
'submitter': '/api/v1/user/{}/'.format(self.user.pk),
|
||||
'image': '/api/v1/image/{}/'.format(image.pk),
|
||||
'description': 'That\'s something else (probably a CC logo)!',
|
||||
'tags': ['random', 'tags'],
|
||||
}
|
||||
response = self.api_client.post('/api/v1/pin/', data=post_data)
|
||||
self.assertEqual(self.deserialize(response)['id'], 3)
|
||||
self.assertEqual(self.deserialize(response)['id'], 1)
|
||||
self.assertHttpCreated(response)
|
||||
# A number of Image objects should stay the same as we are using an existing image
|
||||
self.assertEqual(Image.objects.count(), 2)
|
||||
self.assertEqual(Pin.objects.count(), 3)
|
||||
self.assertEquals(Tag.objects.count(), 4)
|
||||
self.assertEqual(Image.objects.count(), 1)
|
||||
self.assertEqual(Pin.objects.count(), 1)
|
||||
self.assertEquals(Tag.objects.count(), 2)
|
||||
|
||||
def test_put_detail_unauthenticated(self):
|
||||
self.api_client.client.logout()
|
||||
uri = '/api/v1/pin/{}/'.format(self.pin_1.pk)
|
||||
uri = '/api/v1/pin/{}/'.format(PinFactory().pk)
|
||||
response = self.api_client.put(uri, format='json', data={})
|
||||
self.assertHttpUnauthorized(response)
|
||||
|
||||
def test_put_detail_unauthorized(self):
|
||||
uri = '/api/v1/pin/{}/'.format(self.pin_1.pk)
|
||||
User.objects.create_user('test', 'test@example.com', 'test')
|
||||
self.api_client.client.login(username='test', password='test')
|
||||
uri = '/api/v1/pin/{}/'.format(PinFactory(submitter=self.user).pk)
|
||||
user = UserFactory(password='password')
|
||||
self.api_client.client.login(username=user.username, password='password')
|
||||
response = self.api_client.put(uri, format='json', data={})
|
||||
self.assertHttpUnauthorized(response)
|
||||
|
||||
def test_put_detail(self):
|
||||
uri = '/api/v1/pin/{}/'.format(self.pin_1.pk)
|
||||
original = self.deserialize(self.api_client.get(uri, format='json'))
|
||||
pin = PinFactory(submitter=self.user)
|
||||
uri = '/api/v1/pin/{}/'.format(pin.pk)
|
||||
new = {'description': 'Updated description'}
|
||||
|
||||
response = self.api_client.put(uri, format='json', data=new)
|
||||
self.assertHttpAccepted(response)
|
||||
self.assertEqual(Pin.objects.count(), 2)
|
||||
self.assertEqual(Pin.objects.get(pk=self.pin_1.pk).description, new['description'])
|
||||
self.assertEqual(Pin.objects.count(), 1)
|
||||
self.assertEqual(Pin.objects.get(pk=pin.pk).description, new['description'])
|
||||
|
||||
def test_delete_detail_unauthenticated(self):
|
||||
uri = '/api/v1/pin/{}/'.format(self.pin_1.pk)
|
||||
uri = '/api/v1/pin/{}/'.format(PinFactory(submitter=self.user).pk)
|
||||
self.api_client.client.logout()
|
||||
self.assertHttpUnauthorized(self.api_client.delete(uri))
|
||||
|
||||
def test_delete_detail_unauthorized(self):
|
||||
uri = '/api/v1/pin/{}/'.format(self.pin_1.pk)
|
||||
uri = '/api/v1/pin/{}/'.format(PinFactory(submitter=self.user).pk)
|
||||
User.objects.create_user('test', 'test@example.com', 'test')
|
||||
self.api_client.client.login(username='test', password='test')
|
||||
self.assertHttpUnauthorized(self.api_client.delete(uri))
|
||||
|
||||
def test_delete_detail(self):
|
||||
uri = '/api/v1/pin/{}/'.format(self.pin_1.pk)
|
||||
uri = '/api/v1/pin/{}/'.format(PinFactory(submitter=self.user).pk)
|
||||
self.assertHttpAccepted(self.api_client.delete(uri))
|
||||
self.assertEqual(Pin.objects.count(), 1)
|
||||
self.assertEqual(Pin.objects.count(), 0)
|
||||
|
||||
def test_get_list_json_ordered(self):
|
||||
pin = Pin.objects.latest('id')
|
||||
_, pin = PinFactory(), PinFactory()
|
||||
response = self.api_client.get('/api/v1/pin/', format='json', data={'order_by': '-id'})
|
||||
self.assertValidJSONResponse(response)
|
||||
self.assertEqual(self.deserialize(response)['objects'][0]['id'], pin.id)
|
||||
|
||||
def test_get_list_json_filtered_by_tags(self):
|
||||
tag = self.pin_1.tags.all()[0]
|
||||
response = self.api_client.get('/api/v1/pin/', format='json', data={'tag': tag})
|
||||
pin = PinFactory()
|
||||
response = self.api_client.get('/api/v1/pin/', format='json', data={'tag': pin.tags.get(pk=1)})
|
||||
self.assertValidJSONResponse(response)
|
||||
self.assertEqual(self.deserialize(response)['objects'][0]['id'], self.pin_1.id)
|
||||
self.assertEqual(self.deserialize(response)['objects'][0]['id'], pin.pk)
|
||||
|
||||
def test_get_list_json_filtered_by_submitter(self):
|
||||
pin = PinFactory(submitter=self.user)
|
||||
response = self.api_client.get('/api/v1/pin/', format='json', data={'submitter__username': self.user.username})
|
||||
self.assertValidJSONResponse(response)
|
||||
self.assertEqual(self.deserialize(response)['objects'][0]['id'], self.pin_1.id)
|
||||
self.assertEqual(self.deserialize(response)['objects'][0]['id'], pin.pk)
|
||||
|
||||
def test_get_list_json(self):
|
||||
user = User.objects.get(pk=1)
|
||||
image = Image.objects.get(pk=1)
|
||||
image = ImageFactory()
|
||||
pin = PinFactory(**{
|
||||
'submitter': self.user,
|
||||
'image': image,
|
||||
'url': 'http://testserver/mocked/screenshot.png',
|
||||
'description': u'Mocked Description',
|
||||
'origin': None
|
||||
})
|
||||
standard = filter_generator_for('standard')(image)
|
||||
thumbnail = filter_generator_for('thumbnail')(image)
|
||||
square = filter_generator_for('square')(image)
|
||||
response = self.api_client.get('/api/v1/pin/', format='json')
|
||||
self.assertValidJSONResponse(response)
|
||||
self.assertDictEqual(self.deserialize(response)['objects'][0], {
|
||||
u'id': self.pin_1.id,
|
||||
u'id': pin.id,
|
||||
u'submitter': {
|
||||
u'username': user.username,
|
||||
u'gravatar': user.gravatar
|
||||
u'username': unicode(self.user.username),
|
||||
u'gravatar': unicode(self.user.gravatar)
|
||||
},
|
||||
u'image': {
|
||||
u'image': unicode(image.image.url),
|
||||
@@ -245,8 +244,8 @@ class PinResourceTest(ResourceTestCase):
|
||||
u'height': square.height,
|
||||
},
|
||||
},
|
||||
u'url': self.pin_1.url,
|
||||
u'origin': self.pin_1.origin,
|
||||
u'description': self.pin_1.description,
|
||||
u'tags': [u'creative-commons'],
|
||||
u'url': pin.url,
|
||||
u'origin': pin.origin,
|
||||
u'description': pin.description,
|
||||
u'tags': [tag.name for tag in pin.tags.all()]
|
||||
})
|
||||
|
||||
55
pinry/core/tests/helpers.py
Normal file
55
pinry/core/tests/helpers.py
Normal file
@@ -0,0 +1,55 @@
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.core.files import File
|
||||
|
||||
import factory
|
||||
from taggit.models import Tag
|
||||
|
||||
from ..models import Image, Pin
|
||||
from ...users.models import User
|
||||
|
||||
|
||||
TEST_IMAGE_PATH = settings.SITE_ROOT + 'screenshot.png'
|
||||
|
||||
|
||||
class UserFactory(factory.Factory):
|
||||
FACTORY_FOR = User
|
||||
|
||||
username = factory.Sequence(lambda n: 'user_{}'.format(n))
|
||||
email = factory.Sequence(lambda n: 'user_{}@example.com'.format(n))
|
||||
|
||||
@classmethod
|
||||
def _prepare(cls, create, **kwargs):
|
||||
password = kwargs.pop('password', None)
|
||||
user = super(UserFactory, cls)._prepare(create, **kwargs)
|
||||
user.user_permissions = Permission.objects.filter(codename__in=['add_pin', 'add_image'])
|
||||
if password:
|
||||
user.set_password(password)
|
||||
if create:
|
||||
user.save()
|
||||
return user
|
||||
|
||||
|
||||
class TagFactory(factory.Factory):
|
||||
FACTORY_FOR = Tag
|
||||
|
||||
name = factory.Sequence(lambda n: 'tag_{}'.format(n))
|
||||
|
||||
|
||||
class ImageFactory(factory.Factory):
|
||||
FACTORY_FOR = Image
|
||||
|
||||
image = factory.LazyAttribute(lambda a: File(open(TEST_IMAGE_PATH)))
|
||||
|
||||
|
||||
class PinFactory(factory.Factory):
|
||||
FACTORY_FOR = Pin
|
||||
|
||||
submitter = factory.SubFactory(UserFactory)
|
||||
image = factory.SubFactory(ImageFactory)
|
||||
|
||||
@classmethod
|
||||
def _prepare(cls, create, **kwargs):
|
||||
pin = super(PinFactory, cls)._prepare(create, **kwargs)
|
||||
pin.tags.add(TagFactory())
|
||||
return pin
|
||||
@@ -3,6 +3,7 @@ from django.core.urlresolvers import reverse
|
||||
from django.template import TemplateDoesNotExist
|
||||
from django.test import TestCase
|
||||
|
||||
from .api import UserFactory
|
||||
from ...core.models import Image
|
||||
|
||||
|
||||
@@ -10,11 +11,9 @@ __all__ = ['CreateImageTest']
|
||||
|
||||
|
||||
class CreateImageTest(TestCase):
|
||||
fixtures = ['test_resources.json']
|
||||
|
||||
def setUp(self):
|
||||
self.client.login(username='jdoe', password='password')
|
||||
|
||||
self.user = UserFactory(password='password')
|
||||
self.client.login(username=self.user.username, password='password')
|
||||
|
||||
def test_get_browser(self):
|
||||
response = self.client.get(reverse('core:create-image'))
|
||||
|
||||
@@ -4,5 +4,6 @@ South
|
||||
django-tastypie
|
||||
django-braces
|
||||
mock
|
||||
factory-boy
|
||||
http://github.com/mirumee/django-images/tarball/master#egg=django-images
|
||||
http://github.com/hcarvalhoalves/django-taggit/tarball/master#egg=django-taggit
|
||||
|
||||
Reference in New Issue
Block a user