Skip to content

Commit

Permalink
Improve test factory usage
Browse files Browse the repository at this point in the history
  • Loading branch information
singingwolfboy committed Dec 6, 2016
1 parent 49a69a0 commit 352563b
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 83 deletions.
30 changes: 27 additions & 3 deletions cms/factories.py
Expand Up @@ -4,13 +4,15 @@
import shutil
import tempfile

from django.utils.text import slugify
import factory
from factory.django import DjangoModelFactory
import faker
from wagtail.wagtailimages.models import Image
from wagtail.wagtailimages.tests.utils import get_test_image_file_jpeg
from willow.image import Image as WillowImage

from cms.models import ProgramPage, ProgramFaculty
from cms.models import HomePage, ProgramPage, ProgramFaculty
from courses.factories import ProgramFactory


Expand All @@ -22,11 +24,16 @@ class ImageFactory(DjangoModelFactory):
class Meta: # pylint: disable=missing-docstring
model = Image

file = factory.LazyAttribute(lambda x: FAKE.uri_path())
title = factory.LazyAttribute(lambda x: FAKE.file_name(extension="jpg"))
width = factory.LazyAttribute(lambda x: FAKE.pyint())
height = factory.LazyAttribute(lambda x: FAKE.pyint())

@factory.lazy_attribute
def file(self):
"""Get a fake file for testing directly from wagtail"""
size = (self.width, self.height)
return get_test_image_file_jpeg(filename=self.title, size=size)

@factory.post_generation
def fake_willow_image(self, create, extracted, **kwargs): # pylint: disable=unused-argument
"""
Expand Down Expand Up @@ -55,10 +62,27 @@ class Meta: # pylint: disable=missing-docstring

path = '/'
depth = 1
title = factory.LazyAttribute(lambda x: FAKE.sentence(nb_words=4))

@factory.lazy_attribute
def title(self):
return self.program.title

@factory.lazy_attribute
def slug(self):
return slugify(self.title)

program = factory.SubFactory(ProgramFactory)

@factory.post_generation
def set_homepage_as_parent(self, create, extracted, **kwargs): # pylint: disable=unused-argument
"""
Set this page as a child of the homepage, so that Wagtail marks
this page as routable and it can generate a URL.
"""
homepage = HomePage.objects.first()
self.set_url_path(homepage)
return self


class FacultyFactory(DjangoModelFactory):
"""Factory for program faculty"""
Expand Down
66 changes: 37 additions & 29 deletions courses/factories.py
Expand Up @@ -14,49 +14,56 @@

class ProgramFactory(DjangoModelFactory):
"""Factory for Programs"""
title = fuzzy.FuzzyText(prefix="Program ")
live = fuzzy.FuzzyAttribute(FAKE.boolean)
description = fuzzy.FuzzyText()
title = factory.LazyAttribute(lambda x: FAKE.company())
description = factory.LazyAttribute(lambda x: FAKE.bs())
live = True
financial_aid_availability = False

class Meta: # pylint: disable=missing-docstring
model = Program
course = factory.RelatedFactory('courses.factories.CourseFactory', "program")

@classmethod
def _create(cls, model_class, *args, **kwargs):
full_create = kwargs.pop('full', False)
program = model_class(*args, **kwargs)
program.save()
if full_create:
course = CourseFactory.create(program=program)
course_run = CourseRunFactory.create(course=course)
from ecommerce.factories import CoursePriceFactory
course_price = CoursePriceFactory.create(course_run=course_run, is_valid=True)
if program.financial_aid_availability:
from financialaid.factories import TierProgramFactory
TierProgramFactory.create(
program=program,
current=True,
discount_amount=0,
income_threshold=1000
@factory.post_generation
def ecommerce(self, create, extracted, **kwargs): # pylint: disable=unused-argument
if not extracted:
return self
price = 0
course_runs = CourseRun.objects.filter(course__program=self)
for course_run in course_runs:
course_price = CoursePrice.objects.filter(course_run=course_run).first()
if not course_price:
course_price = CoursePriceFactory.create(
course_run=course_run, is_valid=True,
)
price = course_price.price
if self.financial_aid_availability:
finaid_values = [
(0, 1000),
int(price / 10),
]
for discount, threshold in finaid_values:
TierProgramFactory.create(
program=program,
current=True,
discount_amount=int(course_price.price / 10),
income_threshold=0
discount_amount=discount,
income_threshold=threshold,
)
return program

class Meta: # pylint: disable=missing-docstring
model = Program


class CourseFactory(DjangoModelFactory):
"""Factory for Courses"""
title = fuzzy.FuzzyText(prefix="Course ")
program = factory.SubFactory(ProgramFactory)
position_in_program = factory.Sequence(lambda n: n)

description = fuzzy.FuzzyText()
description = factory.LazyAttribute(lambda x: FAKE.bs())
prerequisites = fuzzy.FuzzyText(prefix="Course requires ")

program = factory.SubFactory(ProgramFactory)
course_run = factory.RelatedFactory(
'courses.factories.CourseRunFactory',
"course"
)

class Meta: # pylint: disable=missing-docstring
model = Course

Expand All @@ -73,7 +80,6 @@ class CourseRunFactory(DjangoModelFactory):
title = factory.LazyAttribute(
lambda x: "CourseRun " + FAKE.sentence()
)
course = factory.SubFactory(CourseFactory)
# Try to make sure we escape this correctly
edx_course_key = factory.LazyAttribute(
lambda x: "course:/v{}/{}".format(randint(1, 100), FAKE.slug())
Expand Down Expand Up @@ -103,5 +109,7 @@ class CourseRunFactory(DjangoModelFactory):
lambda x: FAKE.paragraph()
)

course = factory.SubFactory(CourseFactory)

class Meta: # pylint: disable=missing-docstring
model = CourseRun
6 changes: 3 additions & 3 deletions courses/views_test.py
Expand Up @@ -55,9 +55,9 @@ def setUpTestData(cls):

cls.user1 = UserFactory.create()
cls.user2 = UserFactory.create()
cls.program1 = ProgramFactory.create(live=True)
cls.program2 = ProgramFactory.create(live=True)
cls.program3 = ProgramFactory.create(live=True)
cls.program1 = ProgramFactory.create()
cls.program2 = ProgramFactory.create()
cls.program3 = ProgramFactory.create()

cls.url = reverse('user_program_enrollments')

Expand Down
31 changes: 27 additions & 4 deletions dashboard/api_test.py
Expand Up @@ -22,6 +22,8 @@
from micromasters.factories import UserFactory
from micromasters.utils import is_subset_dict
from search.base import ESTestCase
from ecommerce.factories import CoursePriceFactory
from financialaid.factories import TierProgramFactory


# pylint: disable=too-many-lines
Expand Down Expand Up @@ -738,11 +740,32 @@ def setUpTestData(cls):
super(UserProgramInfoIntegrationTest, cls).setUpTestData()
cls.user = UserFactory()
# create the programs
cls.program_non_fin_aid = ProgramFactory.create(full=True, live=True)
cls.program_fin_aid = ProgramFactory.create(full=True, live=True, financial_aid_availability=True)
cls.program_unenrolled = ProgramFactory.create(full=True, live=True)
cls.program_non_fin_aid = ProgramFactory.create(financial_aid_availability=False)
cls.program_fin_aid = ProgramFactory.create(financial_aid_availability=True)
cls.program_unenrolled = ProgramFactory.create()
cls.program_not_live = ProgramFactory.create(live=False)
for program in [cls.program_non_fin_aid, cls.program_fin_aid, cls.program_not_live]:

# create associated course models (except non-live course)
for program in (cls.program_non_fin_aid, cls.program_fin_aid, cls.program_unenrolled):
course = CourseFactory.create(program=program)
course_run = CourseRunFactory.create(course=course)
course_price = CoursePriceFactory.create(course_run=course_run, is_valid=True)
if program.financial_aid_availability:
TierProgramFactory.create(
program=program,
current=True,
discount_amount=0,
income_threshold=1000
)
TierProgramFactory.create(
program=program,
current=True,
discount_amount=int(course_price.price / 10),
income_threshold=0
)

# enroll user in programs (except unenrolled)
for program in (cls.program_non_fin_aid, cls.program_fin_aid, cls.program_not_live):
models.ProgramEnrollment.objects.create(user=cls.user, program=program)

def setUp(self):
Expand Down
8 changes: 4 additions & 4 deletions dashboard/utils_test.py
Expand Up @@ -43,8 +43,8 @@ def setUpTestData(cls):
)

# create the programs
cls.program = ProgramFactory.create(live=True, financial_aid_availability=False)
cls.program_financial_aid = ProgramFactory.create(live=True, financial_aid_availability=True)
cls.program = ProgramFactory.create()
cls.program_financial_aid = ProgramFactory.create(financial_aid_availability=True)

# create course runs for the normal program
course = CourseFactory.create(program=cls.program)
Expand Down Expand Up @@ -249,7 +249,7 @@ def test_course_price_mandatory(self):
"""
Test that if financial aid is available for the program, at least one course price should be available.
"""
program = ProgramFactory.create(live=True, financial_aid_availability=True)
program = ProgramFactory.create(financial_aid_availability=True)
TierProgramFactory.create(
program=program,
discount_amount=750,
Expand All @@ -266,7 +266,7 @@ def test_course_tier_mandatory(self):
"""
Test that if financial aid is available for the program, at least one tier should be available.
"""
program = ProgramFactory.create(live=True, financial_aid_availability=True)
program = ProgramFactory.create(financial_aid_availability=True)
course = CourseFactory.create(program=program)
crun_fa = CourseRunFactory.create(course=course)
CoursePriceFactory.create(
Expand Down
2 changes: 1 addition & 1 deletion mail/views_test.py
Expand Up @@ -39,7 +39,7 @@ class MailViewsTests(APITestCase):
@classmethod
def setUpTestData(cls):
cls.search_result_mail_url = reverse('search_result_mail_api')
cls.program = ProgramFactory.create(live=True)
cls.program = ProgramFactory.create()
# create a user with a role for one program
with mute_signals(post_save):
staff_profile = ProfileFactory.create()
Expand Down
4 changes: 2 additions & 2 deletions roles/api_test.py
Expand Up @@ -19,8 +19,8 @@ def setUpTestData(cls):
# create an user
cls.user = UserFactory.create()
# create the programs
cls.program1 = ProgramFactory.create(live=True)
cls.program2 = ProgramFactory.create(live=True)
cls.program1 = ProgramFactory.create()
cls.program2 = ProgramFactory.create()

def test_get_advance_searchable_programs(self):
"""
Expand Down
2 changes: 1 addition & 1 deletion search/permissions_test.py
Expand Up @@ -21,7 +21,7 @@ def setUpTestData(cls):
# create an user
cls.user = UserFactory.create()
# create the program
cls.program = ProgramFactory.create(live=True)
cls.program = ProgramFactory.create()

def setUp(self):
super(PermissionsTests, self).setUp()
Expand Down
6 changes: 3 additions & 3 deletions search/views_test.py
Expand Up @@ -34,9 +34,9 @@ def setUpTestData(cls):
with mute_signals(post_save):
cls.students = [(ProfileFactory.create()).user for _ in range(30)]
# create the programs
cls.program1 = ProgramFactory.create(live=True)
cls.program2 = ProgramFactory.create(live=True)
cls.program3 = ProgramFactory.create(live=True)
cls.program1 = ProgramFactory.create()
cls.program2 = ProgramFactory.create()
cls.program3 = ProgramFactory.create()

# enroll the users in the programs
for num, student in enumerate(cls.students):
Expand Down

0 comments on commit 352563b

Please sign in to comment.