Skip to content

Commit

Permalink
Course API test updates (#1962)
Browse files Browse the repository at this point in the history
* Added tests, fixture and utility functions

* oops, put nplus 1 back & reparameterize the fixture

* reformat

* updated per Nathan's feedback

* Example of catalog data fixture

* reformat

---------

Co-authored-by: Nathan Levesque <rhysyngsun@gmail.com>
  • Loading branch information
JenniWhitman and rhysyngsun authored Oct 27, 2023
1 parent 6ebc24c commit e46ce7f
Show file tree
Hide file tree
Showing 7 changed files with 335 additions and 66 deletions.
113 changes: 113 additions & 0 deletions courses/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
"""Shared pytest configuration for courses application"""
import random

import pytest

from courses.factories import (
CourseFactory,
CourseRunFactory,
ProgramFactory,
ProgramRequirementFactory,
)
from courses.models import (
ProgramRequirementNodeType,
ProgramRequirement,
)


@pytest.fixture()
def programs():
"""Fixture for a set of Programs in the database"""
return ProgramFactory.create_batch(3)


@pytest.fixture()
def courses():
"""Fixture for a set of Courses in the database"""
return CourseFactory.create_batch(3)


@pytest.fixture()
def course_runs():
"""Fixture for a set of CourseRuns in the database"""
return CourseRunFactory.create_batch(3)


@pytest.fixture()
def course_catalog_program_count(request):
return getattr(request, "param", 5)


@pytest.fixture()
def course_catalog_course_count(request):
return getattr(request, "param", 10)


@pytest.fixture()
def course_catalog_data(course_catalog_program_count, course_catalog_course_count):
"""
Current production data is around 85 courses and 150 course runs. I opted to create 3 of each to allow
the best course run logic to play out as well as to push the endpoint a little harder in testing.
There are currently 3 programs in production, so I went with 15, again, to get ready for more data. To allow
things to be somewhat random, I grab courses for them at random (one required and one elective) which also allows
for courses to be in more than one program. If we need/want more specific test cases, we can add them, but this
is a more robust data set than production is presently.
Returns 3 separate lists to simulate what the tests received prior.
Args:
num_courses(int): number of courses to generate.
num_programs(int): number of programs to generate.
"""
programs = []
courses = []
course_runs = []
for n in range(course_catalog_course_count):
course, course_runs_for_course = _create_course(n)
courses.append(course)
course_runs.append(course_runs_for_course)
for n in range(course_catalog_program_count):
program = _create_program(courses)
programs.append(program)
return courses, programs, course_runs


def _create_course(n):
test_course = CourseFactory.create(title=f"Test Course {n}")
cr1 = CourseRunFactory.create(course=test_course, past_start=True)
cr2 = CourseRunFactory.create(course=test_course, in_progress=True)
cr3 = CourseRunFactory.create(course=test_course, in_future=True)
return test_course, [cr1, cr2, cr3]


def _create_program(courses):
program = ProgramFactory.create()
ProgramRequirementFactory.add_root(program)
root_node = program.requirements_root
required_courses_node = root_node.add_child(
node_type=ProgramRequirementNodeType.OPERATOR,
operator=ProgramRequirement.Operator.ALL_OF,
title="Required Courses",
)
elective_courses_node = root_node.add_child(
node_type=ProgramRequirementNodeType.OPERATOR,
operator=ProgramRequirement.Operator.MIN_NUMBER_OF,
operator_value=2,
title="Elective Courses",
elective_flag=True,
)
if len(courses) > 3:
for c in random.sample(courses, 3):
required_courses_node.add_child(
node_type=ProgramRequirementNodeType.COURSE, course=c
)
for c in random.sample(courses, 3):
elective_courses_node.add_child(
node_type=ProgramRequirementNodeType.COURSE, course=c
)
else:
required_courses_node.add_child(
node_type=ProgramRequirementNodeType.COURSE, course=courses[0]
)
return program
2 changes: 1 addition & 1 deletion courses/views/v1/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Course views verson 1"""
"""Course views version 1"""
import logging
from typing import Optional, Tuple, Union

Expand Down
Loading

0 comments on commit e46ce7f

Please sign in to comment.