diff --git a/pinry/core/fixtures/test_resources.json b/pinry/core/fixtures/test_resources.json deleted file mode 100644 index cce74b4..0000000 --- a/pinry/core/fixtures/test_resources.json +++ /dev/null @@ -1 +0,0 @@ -[{"pk": 1, "model": "auth.permission", "fields": {"codename": "add_permission", "name": "Can add permission", "content_type": 1}}, {"pk": 2, "model": "auth.permission", "fields": {"codename": "change_permission", "name": "Can change permission", "content_type": 1}}, {"pk": 3, "model": "auth.permission", "fields": {"codename": "delete_permission", "name": "Can delete permission", "content_type": 1}}, {"pk": 4, "model": "auth.permission", "fields": {"codename": "add_group", "name": "Can add group", "content_type": 2}}, {"pk": 5, "model": "auth.permission", "fields": {"codename": "change_group", "name": "Can change group", "content_type": 2}}, {"pk": 6, "model": "auth.permission", "fields": {"codename": "delete_group", "name": "Can delete group", "content_type": 2}}, {"pk": 7, "model": "auth.permission", "fields": {"codename": "add_user", "name": "Can add user", "content_type": 3}}, {"pk": 8, "model": "auth.permission", "fields": {"codename": "change_user", "name": "Can change user", "content_type": 3}}, {"pk": 9, "model": "auth.permission", "fields": {"codename": "delete_user", "name": "Can delete user", "content_type": 3}}, {"pk": 10, "model": "auth.permission", "fields": {"codename": "add_contenttype", "name": "Can add content type", "content_type": 4}}, {"pk": 11, "model": "auth.permission", "fields": {"codename": "change_contenttype", "name": "Can change content type", "content_type": 4}}, {"pk": 12, "model": "auth.permission", "fields": {"codename": "delete_contenttype", "name": "Can delete content type", "content_type": 4}}, {"pk": 13, "model": "auth.permission", "fields": {"codename": "add_session", "name": "Can add session", "content_type": 5}}, {"pk": 14, "model": "auth.permission", "fields": {"codename": "change_session", "name": "Can change session", "content_type": 5}}, {"pk": 15, "model": "auth.permission", "fields": {"codename": "delete_session", "name": "Can delete session", "content_type": 5}}, {"pk": 16, "model": "auth.permission", "fields": {"codename": "add_migrationhistory", "name": "Can add migration history", "content_type": 6}}, {"pk": 17, "model": "auth.permission", "fields": {"codename": "change_migrationhistory", "name": "Can change migration history", "content_type": 6}}, {"pk": 18, "model": "auth.permission", "fields": {"codename": "delete_migrationhistory", "name": "Can delete migration history", "content_type": 6}}, {"pk": 19, "model": "auth.permission", "fields": {"codename": "add_tag", "name": "Can add Tag", "content_type": 7}}, {"pk": 20, "model": "auth.permission", "fields": {"codename": "change_tag", "name": "Can change Tag", "content_type": 7}}, {"pk": 21, "model": "auth.permission", "fields": {"codename": "delete_tag", "name": "Can delete Tag", "content_type": 7}}, {"pk": 22, "model": "auth.permission", "fields": {"codename": "add_taggeditem", "name": "Can add Tagged Item", "content_type": 8}}, {"pk": 23, "model": "auth.permission", "fields": {"codename": "change_taggeditem", "name": "Can change Tagged Item", "content_type": 8}}, {"pk": 24, "model": "auth.permission", "fields": {"codename": "delete_taggeditem", "name": "Can delete Tagged Item", "content_type": 8}}, {"pk": 25, "model": "auth.permission", "fields": {"codename": "add_image", "name": "Can add image", "content_type": 9}}, {"pk": 26, "model": "auth.permission", "fields": {"codename": "change_image", "name": "Can change image", "content_type": 9}}, {"pk": 27, "model": "auth.permission", "fields": {"codename": "delete_image", "name": "Can delete image", "content_type": 9}}, {"pk": 28, "model": "auth.permission", "fields": {"codename": "add_thumbnail", "name": "Can add thumbnail", "content_type": 10}}, {"pk": 29, "model": "auth.permission", "fields": {"codename": "change_thumbnail", "name": "Can change thumbnail", "content_type": 10}}, {"pk": 30, "model": "auth.permission", "fields": {"codename": "delete_thumbnail", "name": "Can delete thumbnail", "content_type": 10}}, {"pk": 31, "model": "auth.permission", "fields": {"codename": "add_pin", "name": "Can add pin", "content_type": 12}}, {"pk": 32, "model": "auth.permission", "fields": {"codename": "change_pin", "name": "Can change pin", "content_type": 12}}, {"pk": 33, "model": "auth.permission", "fields": {"codename": "delete_pin", "name": "Can delete pin", "content_type": 12}}, {"pk": 1, "model": "auth.user", "fields": {"username": "jdoe", "first_name": "", "last_name": "", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2013-02-25T18:07:05.308Z", "groups": [], "user_permissions": [31], "password": "pbkdf2_sha256$10000$fWo1asHpXTeD$zDtszDL5fU2JZQd2goXayWCWl/EZbL8CZ+COg4Xqi04=", "email": "jdoe@example.com", "date_joined": "2013-02-25T18:07:05.308Z"}}, {"pk": 1, "model": "core.pin", "fields": {"submitter": 1, "url": "https://si0.twimg.com/profile_images/70370524/cc_white.png", "image": 1, "description": "Creative Commons Logo", "published": "2013-02-25T18:08:31.308Z"}}, {"pk": 2, "model": "core.pin", "fields": {"submitter": 1, "url": "https://si0.twimg.com/profile_images/70370524/cc_white.png", "image": 2, "description": "Creative Commons logo downloaded from DeviantArt", "published": "2013-02-25T18:08:54.612Z"}}, {"pk": 1, "model": "taggit.tag", "fields": {"name": "creative-commons", "slug": "creative-commons"}}, {"pk": 2, "model": "taggit.tag", "fields": {"name": "deviantart", "slug": "deviantart"}}, {"pk": 1, "model": "taggit.taggeditem", "fields": {"tag": 1, "content_type": 11, "object_id": 1}}, {"pk": 2, "model": "taggit.taggeditem", "fields": {"tag": 2, "content_type": 11, "object_id": 2}}, {"pk": 3, "model": "taggit.taggeditem", "fields": {"tag": 1, "content_type": 11, "object_id": 2}}, {"pk": 1, "model": "django_images.image", "fields": {"width": 300, "image": "screenshot.png", "height": 300}}, {"pk": 2, "model": "django_images.image", "fields": {"width": 500, "image": "screenshot.png", "height": 500}}] \ No newline at end of file diff --git a/pinry/core/tests/api.py b/pinry/core/tests/api.py index 0900314..e1f49f2 100644 --- a/pinry/core/tests/api.py +++ b/pinry/core/tests/api.py @@ -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()] }) diff --git a/pinry/core/tests/helpers.py b/pinry/core/tests/helpers.py new file mode 100644 index 0000000..2ffe2cc --- /dev/null +++ b/pinry/core/tests/helpers.py @@ -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 \ No newline at end of file diff --git a/pinry/core/tests/views.py b/pinry/core/tests/views.py index d5d110c..7305dbf 100644 --- a/pinry/core/tests/views.py +++ b/pinry/core/tests/views.py @@ -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')) diff --git a/requirements.txt b/requirements.txt index 8ae83a6..945a7b5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -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