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 32470cd commit 414ba2a
Show file tree
Hide file tree
Showing 14 changed files with 119 additions and 97 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
4 changes: 2 additions & 2 deletions cms/serializers_test.py
Expand Up @@ -52,8 +52,8 @@ def test_program_page_serializer(self):
"""
Test program page serializer
"""
program = ProgramFactory.create(title="Supply Chain Management")
course = CourseFactory.create(program=program, title="Learning How to Supply")
program = ProgramFactory.create(title="Supply Chain Management", course=None)
course = CourseFactory.create(program=program, title="Learning How to Supply", course_run=None)
page = ProgramPageFactory.create(program=program, title=program.title)
faculty = FacultyFactory.create(
program_page=page, name="Charles Fluffles", image=None,
Expand Down
63 changes: 31 additions & 32 deletions courses/factories.py
Expand Up @@ -7,56 +7,50 @@
from factory import fuzzy
from factory.django import DjangoModelFactory

from .models import Program, Course, CourseRun
from courses.models import Program, Course, CourseRun
from ecommerce.models import CoursePrice

FAKE = faker.Factory.create()


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
@factory.post_generation
def tiers(self, create, extracted, **kwargs): # pylint: disable=unused-argument
if self.financial_aid_availability:
from financialaid.factories import TierProgramFactory
for discount, threshold in [(0, 1000), (50, 0)]:
TierProgramFactory.create(
program=program,
program=self,
current=True,
discount_amount=0,
income_threshold=1000
discount_amount=discount,
income_threshold=threshold,
)
TierProgramFactory.create(
program=program,
current=True,
discount_amount=int(course_price.price / 10),
income_threshold=0
)
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 +67,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 +96,11 @@ class CourseRunFactory(DjangoModelFactory):
lambda x: FAKE.paragraph()
)

course = factory.SubFactory(CourseFactory)
course_price = factory.RelatedFactory(
'ecommerce.factories.CoursePriceFactory',
"course_run",
)

class Meta: # pylint: disable=missing-docstring
model = CourseRun
4 changes: 2 additions & 2 deletions courses/models_test.py
Expand Up @@ -45,7 +45,7 @@ class CourseModelTests(ESTestCase):
@classmethod
def setUpTestData(cls):
super(CourseModelTests, cls).setUpTestData()
cls.course = CourseFactory.create(title="Title")
cls.course = CourseFactory.create(title="Title", course_run=None)

def setUp(self):
super(CourseModelTests, self).setUp()
Expand Down Expand Up @@ -236,7 +236,7 @@ def test_course_fuzzy_start_date(self):

def test_url_with_no_run(self):
"""Test course url with no course runs"""
course = CourseFactory.create()
course = CourseFactory.create(course_run=None)
assert course.url == ""

def test_url_with_empty_course_key(self):
Expand Down
4 changes: 2 additions & 2 deletions courses/serializers_test.py
Expand Up @@ -26,11 +26,11 @@ class CourseSerializerTests(ESTestCase):
Tests for CourseSerializer
"""

def test_course(self):
def test_course_without_run(self):
"""
Make sure course serializes correctly
"""
course = CourseFactory.create()
course = CourseFactory.create(course_run=None)
data = CourseSerializer(course).data
expected = {
"id": course.id,
Expand Down
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
2 changes: 1 addition & 1 deletion dashboard/api_edx_cache_test.py
Expand Up @@ -43,7 +43,7 @@ def setUpTestData(cls):
cls.p1_course_run_keys = ['p1_course_run']
cls.p2_course_run_keys = ['p2_course_run_1', 'p2_course_run_2']
cls.p1_course_run = CourseRunFactory.create(edx_course_key=cls.p1_course_run_keys[0])
p2 = ProgramFactory.create(full=True)
p2 = ProgramFactory.create()
first_course = p2.course_set.first()
extra_course = CourseFactory.create(program=p2)
cls.p2_course_run_1 = CourseRunFactory.create(course=first_course, edx_course_key=cls.p2_course_run_keys[0])
Expand Down
23 changes: 15 additions & 8 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 @@ -122,6 +124,7 @@ def create_run(self, course=None, start=None, end=None,
enrollment_start=enr_start,
enrollment_end=enr_end,
upgrade_deadline=upgrade_deadline,
course_price=None,
)
if edx_key is not None:
run.edx_course_key = edx_key
Expand Down Expand Up @@ -370,7 +373,7 @@ class InfoCourseTest(CourseTests):
def setUpTestData(cls):
super(InfoCourseTest, cls).setUpTestData()
cls.user = UserFactory()
cls.course_noruns = CourseFactory.create(title="Title no runs")
cls.course_noruns = CourseFactory.create(title="Title no runs", course_run=None)

now = datetime.now(pytz.utc)
# create a run that is current
Expand All @@ -394,7 +397,7 @@ def setUpTestData(cls):
title="Demo"
)

cls.course_no_next_run = CourseFactory.create(title="Title no next run")
cls.course_no_next_run = CourseFactory.create(title="Title no next run", course_run=None)
cls.course_run_past = cls.create_run(
cls,
course=cls.course_no_next_run,
Expand Down Expand Up @@ -710,14 +713,16 @@ def mocked_get_status_for_courserun(run, enrollments): # pylint: disable=unused
start_date=datetime.now(pytz.utc),
end_date=None,
enrollment_start=None,
enrollment_end=None
enrollment_end=None,
course_price=None,
)
CourseRunFactory.create(
start_date=datetime.now(pytz.utc),
end_date=datetime.now(pytz.utc),
enrollment_start=None,
enrollment_end=None,
course=run1.course
course=run1.course,
course_price=None,
)
with patch(
'dashboard.api.get_status_for_courserun',
Expand All @@ -738,11 +743,13 @@ 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]:

# 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 414ba2a

Please sign in to comment.