Files
edx-platform/common/djangoapps/student/tests/factories.py
2023-10-12 10:31:13 -04:00

343 lines
10 KiB
Python

"""Provides factories for student models."""
from datetime import datetime
from uuid import uuid4
import factory
from django.contrib.auth.models import AnonymousUser, Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.test.client import RequestFactory
from factory.django import DjangoModelFactory
from opaque_keys.edx.keys import CourseKey
from pytz import UTC
from common.djangoapps.student.models import (
AccountRecovery,
CourseAccessRole,
CourseEnrollment,
CourseEnrollmentAllowed,
CourseEnrollmentAttribute,
CourseEnrollmentCelebration,
PendingEmailChange,
Registration,
User,
UserAttribute,
UserProfile,
UserStanding
)
from common.djangoapps.student.roles import GlobalStaff
from common.djangoapps.student.roles import CourseBetaTesterRole
from common.djangoapps.student.roles import CourseInstructorRole
from common.djangoapps.student.roles import CourseStaffRole
from common.djangoapps.student.roles import OrgInstructorRole
from common.djangoapps.student.roles import OrgStaffRole
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory
TEST_PASSWORD = 'Password1234'
class GroupFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta:
model = Group
django_get_or_create = ('name', )
name = factory.Sequence('group{}'.format)
class UserStandingFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta:
model = UserStanding
user = None
account_status = None
changed_by = None
class UserProfileFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta:
model = UserProfile
django_get_or_create = ('user', )
user = None
name = factory.LazyAttribute('{0.user.first_name} {0.user.last_name}'.format)
level_of_education = None
gender = 'm'
mailing_address = None
goals = 'Learn a lot'
class RegistrationFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta:
model = Registration
user = None
activation_key = str(uuid4().hex)
class UserFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta:
model = User
django_get_or_create = ('email', 'username')
_DEFAULT_PASSWORD = 'Password1234'
username = factory.Sequence('robot{}'.format)
email = factory.Sequence('robot+test+{}@edx.org'.format)
password = factory.PostGenerationMethodCall('set_password', _DEFAULT_PASSWORD)
first_name = factory.Sequence('Robot{}'.format)
last_name = 'Test'
is_staff = False
is_active = True
is_superuser = False
last_login = datetime(2012, 1, 1, tzinfo=UTC)
date_joined = datetime(2011, 1, 1, tzinfo=UTC)
@factory.post_generation
def profile(obj, create, extracted, **kwargs): # pylint: disable=unused-argument, missing-function-docstring
if create:
obj.save()
return UserProfileFactory.create(user=obj, **kwargs)
elif kwargs:
raise Exception("Cannot build a user profile without saving the user")
else:
return None
@factory.post_generation
def groups(self, create, extracted, **kwargs): # lint-amnesty, pylint: disable=missing-function-docstring, unused-argument
if extracted is None:
return
if isinstance(extracted, str):
extracted = [extracted]
for group_name in extracted:
self.groups.add(GroupFactory.simple_generate(create, name=group_name)) # lint-amnesty, pylint: disable=no-member
class UserAttributeFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta:
model = UserAttribute
user = factory.SubFactory(UserFactory)
name = factory.Sequence('{}'.format)
value = factory.Sequence('{}'.format)
class RequestFactoryNoCsrf(RequestFactory):
"""
RequestFactory, which disables csrf checks.
"""
def request(self, **kwargs):
request = super().request(**kwargs)
setattr(request, '_dont_enforce_csrf_checks', True) # pylint: disable=literal-used-as-attribute
return request
class AnonymousUserFactory(factory.Factory):
class Meta:
model = AnonymousUser
class AdminFactory(UserFactory):
is_staff = True
class SuperuserFactory(UserFactory):
is_superuser = True
class CourseEnrollmentFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta:
model = CourseEnrollment
user = factory.SubFactory(UserFactory)
@classmethod
def _create(cls, model_class, *args, **kwargs):
manager = cls._get_manager(model_class)
course_kwargs = {}
for key in list(kwargs):
if key.startswith('course__'):
course_kwargs[key.split('__')[1]] = kwargs.pop(key)
if 'course' not in kwargs:
course_id = kwargs.get('course_id')
course_overview = None
if course_id is not None:
# 'course_id' is not needed by the model when course is passed.
# This arg used to be called course_id before we added the CourseOverview
# foreign key constraint to CourseEnrollment.
del kwargs['course_id']
if isinstance(course_id, str):
course_id = CourseKey.from_string(course_id)
course_kwargs.setdefault('id', course_id)
try:
course_overview = CourseOverview.get_from_id(course_id)
except CourseOverview.DoesNotExist:
pass
if course_overview is None:
if 'id' not in course_kwargs and course_id:
course_kwargs['id'] = course_id
course_overview = CourseOverviewFactory(**course_kwargs)
kwargs['course'] = course_overview
return manager.create(*args, **kwargs)
class CourseEnrollmentCelebrationFactory(DjangoModelFactory):
class Meta:
model = CourseEnrollmentCelebration
enrollment = factory.SubFactory(CourseEnrollmentFactory)
class CourseEnrollmentAttributeFactory(DjangoModelFactory):
class Meta:
model = CourseEnrollmentAttribute
enrollment = factory.SubFactory(CourseEnrollmentFactory)
class CourseAccessRoleFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta:
model = CourseAccessRole
user = factory.SubFactory(UserFactory)
course_id = CourseKey.from_string('edX/toy/2012_Fall')
role = 'TestRole'
class CourseEnrollmentAllowedFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta:
model = CourseEnrollmentAllowed
email = 'test@edx.org'
course_id = CourseKey.from_string('edX/toy/2012_Fall')
class PendingEmailChangeFactory(DjangoModelFactory):
"""Factory for PendingEmailChange objects
user: generated by UserFactory
new_email: sequence of new+email+{}@edx.org
activation_key: sequence of integers, padded to 30 characters
"""
class Meta:
model = PendingEmailChange
user = factory.SubFactory(UserFactory)
new_email = factory.Sequence('new+email+{}@edx.org'.format)
activation_key = factory.Sequence('{:0<30d}'.format)
class ContentTypeFactory(DjangoModelFactory):
class Meta:
model = ContentType
app_label = factory.Faker('app_name')
class PermissionFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta:
model = Permission
codename = factory.Faker('codename')
content_type = factory.SubFactory(ContentTypeFactory)
class AccountRecoveryFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta:
model = AccountRecovery
django_get_or_create = ('user',)
user = None
secondary_email = factory.Sequence('robot+test+recovery+{}@edx.org'.format)
is_active = True
class BetaTesterFactory(UserFactory):
"""
Given a course Location, returns a User object with beta-tester
permissions for `course`.
"""
last_name = 'Beta-Tester'
@factory.post_generation
def course_key(self, _create, extracted, **kwargs):
if extracted is None:
raise ValueError('Must specify a CourseKey for a beta-tester user')
CourseBetaTesterRole(extracted).add_users(self)
class GlobalStaffFactory(UserFactory):
"""
Returns a User object with global staff access
"""
last_name = 'GlobalStaff'
@factory.post_generation
def set_staff(self, _create, _extracted, **kwargs):
GlobalStaff().add_users(self)
class InstructorFactory(UserFactory):
"""
Given a course Location, returns a User object with instructor
permissions for `course`.
"""
last_name = 'Instructor'
@factory.post_generation
def course_key(self, _create, extracted, **kwargs):
if extracted is None:
raise ValueError('Must specify a CourseKey for a course instructor user')
CourseInstructorRole(extracted).add_users(self)
class OrgInstructorFactory(UserFactory):
"""
Given a course Location, returns a User object with org-instructor
permissions for `course`.
"""
last_name = 'Org-Instructor'
@factory.post_generation
def course_key(self, _create, extracted, **kwargs):
if extracted is None:
raise ValueError('Must specify a CourseKey for an org-instructor user')
OrgInstructorRole(extracted.org).add_users(self)
class OrgStaffFactory(UserFactory):
"""
Given a course Location, returns a User object with org-staff
permissions for `course`.
"""
last_name = 'Org-Staff'
@factory.post_generation
def course_key(self, _create, extracted, **kwargs):
if extracted is None:
raise ValueError('Must specify a CourseKey for an org-staff user')
OrgStaffRole(extracted.org).add_users(self)
class StaffFactory(UserFactory):
"""
Given a course Location, returns a User object with staff
permissions for `course`.
"""
last_name = 'Staff'
@factory.post_generation
def course_key(self, _create, extracted, **kwargs):
if extracted is None:
raise ValueError('Must specify a CourseKey for a course staff user')
CourseStaffRole(extracted).add_users(self)