Compare commits

...

6 Commits

Author SHA1 Message Date
e655e1598a Trying to test deletion, wip 2020-09-11 12:09:51 +02:00
64ed38332f Refactoring and testing __str__ 2020-09-11 12:09:34 +02:00
d438303aec file for model tests 2020-09-11 12:08:43 +02:00
38b3736951 New Model tests 2020-09-11 12:08:27 +02:00
6be060ea40 Refactoring and more keywords to test 2020-09-11 12:08:15 +02:00
5c5756150f More dev dep 2020-09-11 12:07:57 +02:00
7 changed files with 245 additions and 70 deletions

View File

@ -11,6 +11,7 @@ pipenv = "*"
wheel = "*" wheel = "*"
twine = "*" twine = "*"
pandoc ="*" pandoc ="*"
pylint-django ="*"
[packages] [packages]
django = "*" django = "*"

View File

@ -1,50 +1,91 @@
from django.db import models from django.db import models
from django.core.exceptions import FieldDoesNotExist
from django.test import TestCase
class TestModel:
class ModelTestCase:
''' '''
Base class for Lostplaces models Base class for Lostplaces models
''' '''
model_name = None model_name = None
def _test_field(self, field_name, field_class): def _test_field(self, field_name, field_class, must_have={}, must_not_have={}):
''' '''
Tests if a field exists under the given name and Tests if a field exists under the given name and
if the field is of the right type if the field is of the right type.
Also checks if the field has the given must_have attributes
and does not have any of the must_not_have attributes. If you
dont care about the value of the attribute you can just set it to
something that fullfills value == False (i.e. '' or 0)
''' '''
try:
field = self.object._meta.get_field(field_name) field = self.object._meta.get_field(field_name)
self.assertTrue( except FieldDoesNotExist:
field, self.fail(
msg="%s has no field named '%s'" % ( 'Expecting %s to have a field named \'%s\'' % (
self.model_name, self.model_name,
field_name field_name
) )
) )
self.assertEqual( self.assertEqual(
type(field), field_class, type(field), field_class,
msg='%s.%s name field is no CharField' % ( msg='Expecting type of %s.%s to be %s' % (
self.model_name, self.model_name,
field_name field_name,
field_class.__name__
) )
) )
for key, value in must_have.items():
if value:
self.assertEqual(getattr(field, key), value,
msg='Expeting %s.%s.%s to be \'%s\'' % (
self.model_name,
field_name,
key,
value
)
)
else:
self.assertTrue(hasattr(field, key),
msg='Expeting %s.%s to have \'%s\'' % (
self.model_name,
field_name,
key
)
)
for key, value in must_not_have.items():
if value:
self.assertTrue(getattr(field, key) != value,
msg='Expeting %s.%s.%s to not be \'%s\'' % (
self.model_name,
field_name,
key,
value
)
)
else:
self.assertFalse(hasattr(field, value),
msg='Expeting %s.%s to not have \'%s\'' % (
self.model_name,
field_name,
key
)
)
return field return field
def _test_char_field(self, field_name, min_length, max_length, must_have={}, must_hot_have={}):
def _test_char_field(self, field_name, min_length, max_length):
''' '''
Tests if the given field is a char field and if its max_length Tests if the given field is a char field and if its max_length
is in min_length and max_legth is in min_length and max_legth
''' '''
field = self._test_field(field_name, models.CharField) field = self._test_field(
self.assertEqual( field_name, models.CharField, must_have, must_hot_have)
type(field), models.CharField,
msg='%s.%s name field is no CharField' % (
self.model_name,
field_name
)
)
self.assertTrue( self.assertTrue(
field.max_length in range(min_length, max_length), field.max_length in range(min_length, max_length),
msg='%s.%s field max_length not in range of %d and %d' % ( msg='Expeting %s.%s field max_length to be in the range of %d and %d' % (
self.model_name, self.model_name,
field_name, field_name,
min_length, min_length,
@ -52,7 +93,7 @@ class TestModel:
) )
) )
def _test_float_field(self, field_name, min_value=None, max_value=None): def _test_float_field(self, field_name, min_value=None, max_value=None, must_have={}, must_hot_have={}):
''' '''
Tests if the field is a floatfield. If min_value and/or max_value are passed, Tests if the field is a floatfield. If min_value and/or max_value are passed,
the validators of the field are also checked. The validator list of the field should the validators of the field are also checked. The validator list of the field should
@ -61,11 +102,12 @@ class TestModel:
[MinValueValidator] if only min_value is passed, [MinValueValidator] if only min_value is passed,
[MaxValueValidator] if only max_value is passed [MaxValueValidator] if only max_value is passed
''' '''
field = self._test_field(field_name, models.FloatField) field = self._test_field(
field_name, models.FloatField, must_have, must_hot_have)
if min_value: if min_value:
self.assertTrue( self.assertTrue(
len(field.validators) >= 1, len(field.validators) >= 1,
msg='%s.%s first validator should check minimum' % ( msg='Expecting the first valiator of %s.%s to check the minimum' % (
self.model_name, self.model_name,
field_name field_name
) )
@ -73,9 +115,10 @@ class TestModel:
self.assertEqual( self.assertEqual(
field.validators[0].limit_value, field.validators[0].limit_value,
min_value, min_value,
msg='%s.%s min value missmatch' % ( msg='Expecting the min value of %s.%s min to be at least %d' % (
self.model_name, self.model_name,
field_name field_name,
min_value
) )
) )
if max_value: if max_value:
@ -84,7 +127,7 @@ class TestModel:
index += 1 index += 1
self.assertTrue( self.assertTrue(
len(field.validators) >= index+1, len(field.validators) >= index+1,
msg='%s.%s second validator should check maximum' % ( msg='Expecting the second valiator of %s.%s to check the maximum' % (
self.model_name, self.model_name,
field_name field_name
) )
@ -92,30 +135,33 @@ class TestModel:
self.assertEqual( self.assertEqual(
field.validators[1].limit_value, field.validators[1].limit_value,
max_value, max_value,
msg='%s.%s max value missmatch' % ( msg='Expecting the max value of %s.%s min to be at most %d' % (
self.model_name, self.model_name,
field_name field_name,
max_value
) )
) )
class TestSubmittable(TestModel):
class SubmittableTestCase(ModelTestCase):
model_name = '<Class>' model_name = '<Class>'
related_name = None related_name = None
nullable = False nullable = False
def test_submitted_when(self): def test_submitted_when(self):
submitted_when = self._test_field('submitted_when', models.DateTimeField) submitted_when = self._test_field(
self.assertTrue(submitted_when.auto_now_add, 'submitted_when',
msg='%s.submitted_when should be auto_now_add' % ( models.DateTimeField,
self.model_name must_have={'auto_now_add': True}
)
) )
def test_submitted_by(self): def test_submitted_by(self):
submitted_by = self._test_field('submitted_by', models.ForeignKey) submitted_by = self._test_field('submitted_by', models.ForeignKey)
if self.related_name: if self.related_name:
self.assertEqual(submitted_by.remote_field.related_name, self.related_name) self.assertEqual(
submitted_by.remote_field.related_name, self.related_name)
if self.nullable: if self.nullable:
self.assertTrue(submitted_by.null,) self.assertTrue(submitted_by.null,)
self.assertTrue(submitted_by.blank) self.assertTrue(submitted_by.blank)
self.assertEqual(submitted_by.remote_field.on_delete, models.SET_NULL) self.assertEqual(
submitted_by.remote_field.on_delete, models.SET_NULL)

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View File

@ -0,0 +1,55 @@
from django.test import TestCase
from django.db import models
from django.contrib.auth.models import User
from lostplaces_app.models import Explorer
from lostplaces_app.tests import mock_user
class ExplorerTestCase(TestCase):
def setUp(self):
mock_user()
def test_epxlorer_creation(self):
'''
Tests if the explorer profile will be automticly
created when a user is created
'''
user = User.objects.get(id=1)
explorer_list = Explorer.objects.all()
self.assertTrue(len(explorer_list) > 0,
msg='Expecting at least one Exlorer object, none found'
)
self.assertTrue(hasattr(user, 'explorer'),
msg='''Expecting the User instance to have an \'explorer\' attribute.
Check the Explorer model and the related name.'''
)
explorer = Explorer.objects.get(id=1)
self.assertEqual(explorer, user.explorer,
msg='''The Explorer object of the User did not match.
Expecting User with id 1 to have Explorer with id 1'''
)
explorer = Explorer.objects.get(id=1)
self.assertEqual(explorer.user, user,
msg='''The User object of the Explorer did not match.
Expecting Explorer with id 1 to have User with id 1'''
)
def test_explorer_deletion(self):
'''
Tests if the Explorer objects get's deleted when the User instance is deleted
'''
user = User.objects.get(id=1)
explorer_id = user.explorer.id
user.delete()
with self.assertRaises(models.ObjectDoesNotExist,
msg='Expecting explorer objec to be deleted when the corresponding User object is deleted'
):
Explorer.objects.get(id=explorer_id)

View File

@ -1,28 +1,39 @@
import datetime import datetime
import os
import shutil
from unittest import mock from unittest import mock
from django.test import TestCase from django.test import TestCase
from django.db import models from django.db import models
from django.core.files import File from django.core.files import File
from django.conf import settings
from lostplaces_app.models import PlaceImage from lostplaces_app.models import PlaceImage
from lostplaces_app.tests.models import TestSubmittable from lostplaces_app.tests.models import SubmittableTestCase
from lostplaces_app.tests import mock_user from lostplaces_app.tests import mock_user
from lostplaces_app.tests.models import TestModel
from lostplaces_app.tests.models.test_place_model import mock_place from lostplaces_app.tests.models.test_place_model import mock_place
from easy_thumbnails.fields import ThumbnailerImageField from easy_thumbnails.fields import ThumbnailerImageField
def mock_place_image(): def mock_place_image():
return PlaceImage( all_place_images = PlaceImage.objects.all()
if len(all_place_images) <= 0:
current_dir = os.path.dirname(os.path.abspath(__file__))
if not os.path.isfile(os.path.join(settings.MEDIA_ROOT, 'im_a_image_copy.jpeg')):
shutil.copyfile(
os.path.join(current_dir, 'im_a_image.jpeg'),
os.path.join(settings.MEDIA_ROOT, 'im_a_image_copy.jpeg')
)
return PlaceImage.objects.create(
description='Im a description', description='Im a description',
filename=mock.MagicMock(spec=File, name='FileMock'), filename=os.path.join(settings.MEDIA_ROOT, 'im_a_image_copy.jpeg'),
place=mock_place(), place=mock_place(),
submitted_when=datetime.datetime.now(), submitted_when=datetime.datetime.now(),
submitted_by=mock_user().explorer submitted_by=mock_user().explorer
) )
return all_place_images[0]
class TestPlaceImage(TestSubmittable, TestCase): class TestPlaceImage(SubmittableTestCase, TestCase):
model_name = 'PlaceImage' model_name = 'PlaceImage'
def setUp(self): def setUp(self):
@ -51,5 +62,18 @@ class TestPlaceImage(TestSubmittable, TestCase):
) )
def test_str(self): def test_str(self):
place_image = mock_place_image() place_image = self.object
self.assertEqual(str(place_image), ' '.join([place_image.place.name, str(place_image.pk)])) self.assertTrue(place_image.place.name.lower() in str(place_image).lower(),
msg='Expecting %s.__str__ to contain the name of the place' % (
self.model_name
)
)
def test_deletion(self):
# TODO
path = self.object.filename.path
self.object.delete()
self.assertFalse(
os.path.isfile(path),
msg='Expecting the file of an place_image to be deleteed when an place_image is deleted'
)

View File

@ -4,9 +4,8 @@ from django.test import TestCase
from django.db import models from django.db import models
from lostplaces_app.models import Place from lostplaces_app.models import Place
from lostplaces_app.tests.models import TestSubmittable from lostplaces_app.tests.models import SubmittableTestCase
from lostplaces_app.tests import mock_user from lostplaces_app.tests import mock_user
from lostplaces_app.tests.models import TestModel
from taggit.managers import TaggableManager from taggit.managers import TaggableManager
@ -24,7 +23,7 @@ def mock_place():
return place return place
class PlaceTestCase(TestSubmittable, TestCase): class PlaceTestCase(SubmittableTestCase, TestCase):
model_name = 'Place' model_name = 'Place'
related_name = 'places' related_name = 'places'
nullable = True nullable = True
@ -127,10 +126,9 @@ class PlaceTestCase(TestSubmittable, TestCase):
) )
def test_str(self): def test_str(self):
place = mock_place() place = self.object
self.assertEqual(str(place), place.name, self.assertTrue(place.name.lower() in str(place).lower(),
msg='%s __str__ should return the name' % ( msg='Expecting %s.__str__ to contain the name' % (
self.model_name self.model_name
) )
) )

View File

@ -0,0 +1,51 @@
import datetime
from django.test import TestCase
from django.db import models
from lostplaces_app.models import Voucher
from lostplaces_app.tests.models import ModelTestCase
def mock_voucher():
return Voucher.objects.create(
code='ayDraJCCwfhcFiYmSR5GrcjcchDfcahv',
expires=datetime.datetime.now() + datetime.timedelta(days=1)
)
class VoucheTestCase(ModelTestCase, TestCase):
model_name = 'Voucher'
def setUp(self):
self.object = mock_voucher()
def test_voucher_code(self):
self._test_char_field(
'code',
10,
100,
must_have={'unique': True}
)
def test_voucher_created(self):
self._test_field(
'created_when',
models.DateTimeField,
must_have={'auto_now_add': True}
)
def test_voucher_expires(self):
self._test_field(
'expires_when',
models.DateTimeField,
must_not_have={'auto_now_add': True}
)
def test_str(self):
voucher = self.object
self.assertTrue(voucher.code.lower() in str(voucher).lower(),
msg='Expecting %s.__str__ to contain the voucher code' % (
self.model_name
)
)