Ability to generate unique fields in factories

This commit is contained in:
2020-05-21 19:34:02 +02:00
parent c6f2bacf0f
commit c17b558d14
4 changed files with 49 additions and 7 deletions

View File

@@ -1,4 +1,5 @@
""" Module generating useful models in 1 place """
from inspect import signature
from typing import Type, TypeVar
from django.core.files.uploadedfile import SimpleUploadedFile
@@ -11,7 +12,11 @@ T = TypeVar('T', bound=django.db.models.Model)
def create(model: Type[T], **kwargs) -> T:
if model is models.Video:
return _create_with_defaults(models.Video, kwargs, title='Title', slug='slug', description='Description')
return _create_with_defaults(models.Video, kwargs,
title=lambda x: 'Title {}'.format(x),
slug=lambda x: 'slug-{}'.format(x),
description=lambda x: 'Description {}'.format(x),
)
if model is models.Transcoding:
def url():
@@ -38,6 +43,9 @@ def _create_with_defaults(model: Type[T], kwargs: dict, **defaults) -> T:
When providing lambda as default item, the result of the lambda will be taken.
The lambda will ONLY be executed when not provided in kwargs.
When a lambda requires an argument, the primary key of the to be created object
will be provided to that argument. This is useful for generating unique fields.
:param model: django model to create
:param kwargs: keyword arguments to fill the model
:param defaults: default keyword arguments to use when not mentioned in kwargs
@@ -45,6 +53,17 @@ def _create_with_defaults(model: Type[T], kwargs: dict, **defaults) -> T:
for k, v in defaults.items():
if callable(v) and not k in kwargs:
defaults[k] = v()
if len(signature(v).parameters) == 1:
result = v(_next_pk(model))
else:
result = v()
defaults[k] = result
return model.objects.create(**{**defaults, **kwargs})
def _next_pk(model: Type[T]) -> int:
try:
return model.objects.order_by('-pk').first().pk + 1
except AttributeError:
return 1

View File

@@ -8,7 +8,7 @@ from tests.videodinges import factories, UploadMixin
class TranscodingTestCase(TestCase):
def test_factory_returns_model(self):
transcoding = factories.create(Transcoding)
self.assertEqual(transcoding.video.slug, 'slug')
self.assertEqual(transcoding.video.slug, 'slug-1')
self.assertEqual(transcoding.quality, '360p')
self.assertEqual(transcoding.type, 'video/webm')
self.assertEqual(transcoding.url, 'https://some_url')

View File

@@ -6,8 +6,31 @@ from datetime import datetime
class VideoTestCase(TestCase):
def test_factory_returns_model(self):
video = factories.create(Video)
self.assertEqual(video.slug, 'slug')
self.assertEqual(video.title, 'Title')
self.assertEqual(video.description, 'Description')
self.assertEqual(video.slug, 'slug-1')
self.assertEqual(video.title, 'Title 1')
self.assertEqual(video.description, 'Description 1')
self.assertIsInstance(video.created_at, datetime)
self.assertIsInstance(video.updated_at, datetime)
def test_factory_can_create_multiple_models(self):
video1 = factories.create(Video)
video2 = factories.create(Video)
video3 = factories.create(Video)
self.assertEqual(video1.slug, 'slug-1')
self.assertEqual(video1.title, 'Title 1')
self.assertEqual(video1.description, 'Description 1')
self.assertIsInstance(video1.created_at, datetime)
self.assertIsInstance(video1.updated_at, datetime)
self.assertEqual(video2.slug, 'slug-2')
self.assertEqual(video2.title, 'Title 2')
self.assertEqual(video2.description, 'Description 2')
self.assertIsInstance(video2.created_at, datetime)
self.assertIsInstance(video2.updated_at, datetime)
self.assertEqual(video3.slug, 'slug-3')
self.assertEqual(video3.title, 'Title 3')
self.assertEqual(video3.description, 'Description 3')
self.assertIsInstance(video3.created_at, datetime)
self.assertIsInstance(video3.updated_at, datetime)

View File

@@ -70,7 +70,7 @@ class VideoTestCase(UploadMixin, TestCase):
self.assertInHTML('<h1>Vid 1</h1>', content)
self.assertInHTML('<p>Description</p>', content)
self.assertInHTML('<p>Description 1</p>', content)
self.assertInHTML('<strong>480p versie</strong>', content)