Skip to content

Commit 5d43571

Browse files
martin056RadoRado
authored andcommitted
Add exmaple tests for selector
1 parent 91493fb commit 5d43571

File tree

5 files changed

+198
-9
lines changed

5 files changed

+198
-9
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# flake8: noqa
2+
3+
from .schools import *
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from datetime import date
2+
from typing import Optional, Iterable
3+
4+
from django.db.models.query import Q
5+
from django.core.exceptions import ValidationError
6+
7+
from styleguide_example.test_examples.models import School, SchoolCourse
8+
9+
10+
SCHOOL_LIST_SCHOOL_COURSES_PROVIDE_START_DATE_MSG =\
11+
'Provide `start_date` in order to list all School Courses for a period.'
12+
13+
14+
def school_list_school_courses(
15+
*,
16+
school: School,
17+
start_date: Optional[date] = None,
18+
end_date: Optional[date] = None
19+
) -> Iterable[SchoolCourse]:
20+
if start_date is None and end_date:
21+
raise ValidationError(SCHOOL_LIST_SCHOOL_COURSES_PROVIDE_START_DATE_MSG)
22+
23+
school_courses = school.school_courses.order_by('start_date')
24+
25+
if start_date and end_date:
26+
started_courses_Q = Q(start_date__lte=start_date, end_date__gte=start_date, end_date__lte=end_date)
27+
courses_in_period_q = Q(start_date__gte=start_date, end_date__lte=end_date)
28+
courses_wrapping_period_q = Q(start_date__lte=start_date, end_date__gte=end_date)
29+
future_course_q = Q(start_date__gte=start_date, start_date__lte=end_date, end_date__gte=end_date)
30+
31+
return school_courses.filter(
32+
started_courses_Q
33+
| courses_in_period_q
34+
| courses_wrapping_period_q
35+
| future_course_q
36+
)
37+
38+
if start_date and end_date is None:
39+
return school_courses.filter(
40+
Q(start_date__gte=start_date)
41+
| Q(start_date__lte=start_date, end_date__gte=start_date)
42+
)
43+
44+
return school_courses

styleguide_example/test_examples/tests/factories.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,10 @@ class Meta:
3232

3333
class SchoolWithStudentsFactory(SchoolFactory):
3434
@factory.post_generation
35-
def students(obj, created, extracted, **kwargs):
36-
if created and extracted is None:
37-
students = StudentFactory.create_batch(kwargs.get('count', 5))
35+
def students(obj, create, extracted, **kwargs):
36+
if create:
37+
students = extracted or StudentFactory.create_batch(kwargs.get('count', 5))
3838
obj.students.set(students)
39-
4039
return students
4140

4241

@@ -67,10 +66,10 @@ class Meta:
6766
# end_date = factory.LazyAttribute(lambda _: faker.future_date())
6867
start_date = factory.LazyAttribute(lambda self: faker.date_between_dates(
6968
date_start=self.school_course.start_date,
70-
date_end=self.school_course.end_date - timedelta(days=1)
69+
date_end=self.school_course.end_date - timedelta(days=2)
7170
))
7271
end_date = factory.LazyAttribute(lambda self: faker.date_between_dates(
73-
date_start=self.start_date,
72+
date_start=self.start_date + timedelta(days=1),
7473
date_end=self.school_course.end_date
7574
))
7675

@@ -87,12 +86,13 @@ class Meta:
8786

8887
class SchoolCourseWithRostersFactory(SchoolCourseFactory):
8988
@factory.post_generation
90-
def rosters(obj, created, extracted, **kwargs):
91-
if created and extracted is None:
92-
rosters = RosterFactory.create_batch(
89+
def rosters(obj, create, extracted, **kwargs):
90+
if create:
91+
rosters = extracted or RosterFactory.create_batch(
9392
kwargs.get('count', 5),
9493
student__school=obj.school # NOTE!
9594
)
95+
9696
obj.rosters.set(rosters)
9797

9898
return rosters

styleguide_example/test_examples/tests/selectors/__init__.py

Whitespace-only changes.
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
from datetime import timedelta
2+
3+
import factory
4+
5+
from django.test import TestCase
6+
from django.core.exceptions import ValidationError
7+
from django.utils import timezone
8+
9+
from styleguide_example.utils.tests import faker
10+
from styleguide_example.test_examples.selectors import (
11+
school_list_school_courses,
12+
SCHOOL_LIST_SCHOOL_COURSES_PROVIDE_START_DATE_MSG
13+
)
14+
from styleguide_example.test_examples.tests.factories import (
15+
SchoolFactory,
16+
SchoolCourseFactory
17+
)
18+
19+
20+
class SchoolListSchoolCoursesTests(TestCase):
21+
def _order_school_courses(self, school_courses):
22+
# Helper method - the result from the selector is ordered
23+
return sorted(school_courses, key=lambda x: x.start_date)
24+
25+
def test_selector_raises_validation_error_if_unexpected_period_is_given(self):
26+
with self.assertRaisesMessage(
27+
ValidationError,
28+
SCHOOL_LIST_SCHOOL_COURSES_PROVIDE_START_DATE_MSG
29+
):
30+
school_list_school_courses(
31+
school=SchoolFactory.build(),
32+
start_date=None,
33+
end_date=faker.future_date()
34+
)
35+
36+
def test_selector_returns_all_school_courses_if_no_dates_passed(self):
37+
school = SchoolFactory()
38+
school_courses = SchoolCourseFactory.create_batch(3, school=school)
39+
40+
result = school_list_school_courses(school=school)
41+
42+
self.assertEqual(
43+
self._order_school_courses(school_courses),
44+
list(result)
45+
)
46+
47+
def test_selector_does_not_return_school_courses_for_other_schools(self):
48+
expected_school_course = SchoolCourseFactory()
49+
other_school_course = SchoolCourseFactory()
50+
51+
result = school_list_school_courses(school=expected_school_course.school)
52+
53+
self.assertNotIn(other_school_course, result)
54+
self.assertEqual([expected_school_course], list(result))
55+
56+
def test_selector_returns_all_school_courses_for_a_given_start_date(self):
57+
school = SchoolFactory()
58+
now = timezone.now()
59+
60+
future_school_course = SchoolCourseFactory(
61+
school=school,
62+
start_date=faker.future_date()
63+
)
64+
started_school_course = SchoolCourseFactory(
65+
school=school,
66+
start_date=faker.past_date(),
67+
end_date=faker.future_date()
68+
)
69+
70+
finished_school_course = SchoolCourseFactory(
71+
school=school,
72+
start_date=faker.past_date(),
73+
# Uses timedelta in order to make sure the generated date is not equal to the period
74+
end_date=factory.LazyAttribute(lambda _self: faker.date_between_dates(
75+
date_start=_self.start_date + timedelta(days=1),
76+
date_end=now - timedelta(days=1)
77+
))
78+
)
79+
80+
result = school_list_school_courses(school=school, start_date=now)
81+
82+
self.assertNotIn(finished_school_course, result)
83+
self.assertEqual(
84+
[started_school_course, future_school_course],
85+
list(result)
86+
)
87+
88+
def test_selector_returns_all_school_courses_for_a_given_period(self):
89+
school = SchoolFactory()
90+
91+
period_start = timezone.now()
92+
period_end = period_start + timedelta(days=100)
93+
94+
started_school_course = SchoolCourseFactory(
95+
school=school,
96+
start_date=period_start - timedelta(days=10),
97+
end_date=period_end - timedelta(days=10)
98+
)
99+
school_course_inside_period = SchoolCourseFactory(
100+
school=school,
101+
start_date=period_start + timedelta(days=10),
102+
end_date=period_end - timedelta(days=10)
103+
)
104+
school_course_wrapping_period = SchoolCourseFactory(
105+
school=school,
106+
start_date=period_start - timedelta(days=5),
107+
end_date=period_end + timedelta(days=5)
108+
)
109+
starting_school_course = SchoolCourseFactory(
110+
school=school,
111+
start_date=period_end - timedelta(days=10),
112+
end_date=period_end + timedelta(days=10)
113+
)
114+
115+
past_school_course = SchoolCourseFactory(
116+
school=school,
117+
start_date=period_start - timedelta(days=20),
118+
end_date=period_start - timedelta(days=10)
119+
)
120+
future_school_course = SchoolCourseFactory(
121+
school=school,
122+
start_date=period_end + timedelta(days=10),
123+
end_date=period_end + timedelta(days=20)
124+
)
125+
126+
result = school_list_school_courses(
127+
school=school,
128+
start_date=period_start,
129+
end_date=period_end
130+
)
131+
132+
self.assertNotIn(past_school_course, result)
133+
self.assertNotIn(future_school_course, result)
134+
self.assertEqual(
135+
self._order_school_courses([
136+
started_school_course,
137+
school_course_inside_period,
138+
school_course_wrapping_period,
139+
starting_school_course
140+
]),
141+
list(result)
142+
)

0 commit comments

Comments
 (0)