Skip to content

Commit

Permalink
Merge pull request #34 from nelc/omar/mobile-v4-api-take2
Browse files Browse the repository at this point in the history
feat: Mobile API v4 from Redwood and `master` into `palm.nelp`
  • Loading branch information
shadinaif authored Aug 6, 2024
2 parents b657b30 + daf827a commit e9609fb
Show file tree
Hide file tree
Showing 118 changed files with 1,603 additions and 403 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def setUp(self):
self.factory = RequestFactory()
self.global_admin = AdminFactory()
self.client = AjaxEnabledTestClient()
self.client.login(username=self.user.username, password='test')
self.client.login(username=self.user.username, password=self.TEST_PASSWORD)
self.course_create_rerun_url = reverse('course_handler')
self.course_start = datetime.datetime.utcnow()
self.course_end = self.course_start + datetime.timedelta(days=30)
Expand Down
4 changes: 2 additions & 2 deletions cms/djangoapps/contentstore/tests/test_course_listing.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ def setUp(self):
super().setUp()
# create and log in a staff user.
# create and log in a non-staff user
self.user = UserFactory()
self.user = UserFactory(password=self.TEST_PASSWORD)
self.factory = RequestFactory()
self.request = self.factory.get('/course')
self.request.user = self.user
self.client = AjaxEnabledTestClient()
self.client.login(username=self.user.username, password='test')
self.client.login(username=self.user.username, password=self.TEST_PASSWORD)

def _create_course_with_access_groups(self, course_location, user=None):
"""
Expand Down
4 changes: 2 additions & 2 deletions cms/djangoapps/contentstore/tests/test_course_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -1866,10 +1866,10 @@ def _get_course_details_response(self, global_staff):
"""
Return the course details page as either global or non-global staff
"""
user = UserFactory(is_staff=global_staff)
user = UserFactory(is_staff=global_staff, password=self.TEST_PASSWORD)
CourseInstructorRole(self.course.id).add_users(user)

self.client.login(username=user.username, password='test')
self.client.login(username=user.username, password=self.TEST_PASSWORD)

return self.client.get_html(self.course_details_url)

Expand Down
2 changes: 1 addition & 1 deletion cms/djangoapps/contentstore/tests/test_i18n.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def setUp(self):

self.uname = 'testuser'
self.email = '[email protected]'
self.password = 'foo'
self.password = self.TEST_PASSWORD

# Create the use so we can log them in.
self.user = UserFactory.create(username=self.uname, email=self.email, password=self.password)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def setUp(self):
# create and log in a staff user.
self.user = UserFactory(is_staff=True)
self.client = AjaxEnabledTestClient()
self.client.login(username=self.user.username, password='test')
self.client.login(username=self.user.username, password=self.TEST_PASSWORD)

# create a course via the view handler to create course
self.course_key = self.store.make_course_key('Org_1', 'Course_1', 'Run_1')
Expand Down
2 changes: 1 addition & 1 deletion cms/djangoapps/contentstore/tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def setUp(self):
super().setUp()

self.email = '[email protected]'
self.pw = 'xyz'
self.pw = 'password1234'
self.username = 'testuser'
self.client = AjaxEnabledTestClient()
# clear the cache so ratelimiting won't affect these tests
Expand Down
10 changes: 5 additions & 5 deletions cms/djangoapps/contentstore/views/tests/test_certificates.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def test_cannot_create_certificate_if_user_has_no_write_permissions(self):
Tests user without write permissions on course should not able to create certificate
"""
user = UserFactory()
self.client.login(username=user.username, password='test')
self.client.login(username=user.username, password=self.TEST_PASSWORD)
response = self.client.ajax_post(
self._url(),
data=CERTIFICATE_JSON
Expand Down Expand Up @@ -635,7 +635,7 @@ def test_delete_certificate_without_write_permissions(self, signatory_path):
"""
self._add_course_certificates(count=2, signatory_count=1, asset_path_format=signatory_path)
user = UserFactory()
self.client.login(username=user.username, password='test')
self.client.login(username=user.username, password=self.TEST_PASSWORD)
response = self.client.delete(
self._url(cid=1),
content_type="application/json",
Expand All @@ -653,7 +653,7 @@ def test_delete_certificate_without_global_staff_permissions(self, signatory_pat
user = UserFactory()
for role in [CourseInstructorRole, CourseStaffRole]:
role(self.course.id).add_users(user)
self.client.login(username=user.username, password='test')
self.client.login(username=user.username, password=self.TEST_PASSWORD)
response = self.client.delete(
self._url(cid=1),
content_type="application/json",
Expand Down Expand Up @@ -681,7 +681,7 @@ def test_update_active_certificate_without_global_staff_permissions(self, signat
user = UserFactory()
for role in [CourseInstructorRole, CourseStaffRole]:
role(self.course.id).add_users(user)
self.client.login(username=user.username, password='test')
self.client.login(username=user.username, password=self.TEST_PASSWORD)
response = self.client.put(
self._url(cid=1),
data=json.dumps(cert_data),
Expand Down Expand Up @@ -799,7 +799,7 @@ def test_certificate_activation_without_write_permissions(self, activate, signat
test_url = reverse_course_url('certificate_activation_handler', self.course.id)
self._add_course_certificates(count=1, signatory_count=2, asset_path_format=signatory_path)
user = UserFactory()
self.client.login(username=user.username, password='test')
self.client.login(username=user.username, password=self.TEST_PASSWORD)
response = self.client.post(
test_url,
data=json.dumps({"is_active": activate}),
Expand Down
5 changes: 3 additions & 2 deletions cms/djangoapps/contentstore/views/tests/test_organizations.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ class TestOrganizationListing(TestCase):
"""Verify Organization listing behavior."""
def setUp(self):
super().setUp()
self.staff = UserFactory(is_staff=True)
self.client.login(username=self.staff.username, password='test')
self.password = "password1234"
self.staff = UserFactory(is_staff=True, password=self.password)
self.client.login(username=self.staff.username, password=self.password)
self.org_names_listing_url = reverse('organizations')
self.org_short_names = ["alphaX", "betaX", "orgX"]
for index, short_name in enumerate(self.org_short_names):
Expand Down
16 changes: 8 additions & 8 deletions cms/djangoapps/maintenance/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class TestMaintenanceIndex(ModuleStoreTestCase):
def setUp(self):
super().setUp()
self.user = AdminFactory()
login_success = self.client.login(username=self.user.username, password='test')
login_success = self.client.login(username=self.user.username, password=self.TEST_PASSWORD)
self.assertTrue(login_success)
self.view_url = reverse('maintenance:maintenance_index')

Expand All @@ -56,7 +56,7 @@ class MaintenanceViewTestCase(ModuleStoreTestCase):
def setUp(self):
super().setUp()
self.user = AdminFactory()
login_success = self.client.login(username=self.user.username, password='test')
login_success = self.client.login(username=self.user.username, password=self.TEST_PASSWORD)
self.assertTrue(login_success)

def verify_error_message(self, data, error_message):
Expand Down Expand Up @@ -110,8 +110,8 @@ def test_non_global_staff_access(self, url):
"""
Test that all maintenance app views are not accessible to non-global-staff user.
"""
user = UserFactory(username='test', email='[email protected]', password='test')
login_success = self.client.login(username=user.username, password='test')
user = UserFactory(username='test', email='[email protected]', password=self.TEST_PASSWORD)
login_success = self.client.login(username=user.username, password=self.TEST_PASSWORD)
self.assertTrue(login_success)

response = self.client.get(url)
Expand Down Expand Up @@ -245,13 +245,13 @@ def setUp(self):
self.admin = AdminFactory.create(
email='[email protected]',
username='admin',
password='pass'
password=self.TEST_PASSWORD
)
self.client.login(username=self.admin.username, password='pass')
self.client.login(username=self.admin.username, password=self.TEST_PASSWORD)
self.non_staff_user = UserFactory.create(
email='[email protected]',
username='test',
password='pass'
password=self.TEST_PASSWORD
)

def test_index(self):
Expand Down Expand Up @@ -301,7 +301,7 @@ def _test_403(self, viewname, kwargs=None):
self.assertEqual(response.status_code, 403)

def test_authorization(self):
self.client.login(username=self.non_staff_user, password='pass')
self.client.login(username=self.non_staff_user, password=self.TEST_PASSWORD)
announcement = Announcement.objects.create(content="Test Delete")
announcement.save()

Expand Down
2 changes: 1 addition & 1 deletion common/djangoapps/course_modes/tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def test_expiration_timezone(self):
'_expiration_datetime_1': expiration.time(),
}

self.client.login(username=user.username, password='test')
self.client.login(username=user.username, password=self.TEST_PASSWORD)

# Create a new course mode from django admin page
response = self.client.post(reverse('admin:course_modes_coursemode_add'), data=data)
Expand Down
62 changes: 62 additions & 0 deletions common/djangoapps/student/models/course_enrollment.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,73 @@ class UnenrollmentNotAllowed(CourseEnrollmentException):
pass


class CourseEnrollmentQuerySet(models.QuerySet):
"""
Custom queryset for CourseEnrollment with Table-level filter methods.
"""

def active(self):
"""
Returns a queryset of CourseEnrollment objects for courses that are currently active.
"""
return self.filter(is_active=True)

def without_certificates(self, username):
"""
Returns a queryset of CourseEnrollment objects for courses that do not have a certificate.
"""
return self.exclude(course_id__in=self.get_user_course_ids_with_certificates(username))

def with_certificates(self, username):
"""
Returns a queryset of CourseEnrollment objects for courses that have a certificate.
"""
return self.filter(course_id__in=self.get_user_course_ids_with_certificates(username))

def in_progress(self, username, time_zone=UTC):
"""
Returns a queryset of CourseEnrollment objects for courses that are currently in progress.
"""
now = datetime.now(time_zone)
return self.active().without_certificates(username).filter(
Q(course__start__lte=now, course__end__gte=now)
| Q(course__start__isnull=True, course__end__isnull=True)
| Q(course__start__isnull=True, course__end__gte=now)
| Q(course__start__lte=now, course__end__isnull=True),
)

def completed(self, username):
"""
Returns a queryset of CourseEnrollment objects for courses that have been completed.
"""
return self.active().with_certificates(username)

def expired(self, username, time_zone=UTC):
"""
Returns a queryset of CourseEnrollment objects for courses that have expired.
"""
now = datetime.now(time_zone)
return self.active().without_certificates(username).filter(course__end__lt=now)

def get_user_course_ids_with_certificates(self, username):
"""
Gets user's course ids with certificates.
"""
from lms.djangoapps.certificates.models import GeneratedCertificate # pylint: disable=import-outside-toplevel
course_ids_with_certificates = GeneratedCertificate.objects.filter(
user__username=username
).values_list('course_id', flat=True)
return course_ids_with_certificates


class CourseEnrollmentManager(models.Manager):
"""
Custom manager for CourseEnrollment with Table-level filter methods.
"""

def get_queryset(self):
return CourseEnrollmentQuerySet(self.model, using=self._db)

def is_small_course(self, course_id):
"""
Returns false if the number of enrollments are one greater than 'max_enrollments' else true
Expand Down
4 changes: 2 additions & 2 deletions common/djangoapps/student/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory

TEST_PASSWORD = 'test'
TEST_PASSWORD = 'Password1234'


class GroupFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
Expand Down Expand Up @@ -81,7 +81,7 @@ class Meta:
model = User
django_get_or_create = ('email', 'username')

_DEFAULT_PASSWORD = 'test'
_DEFAULT_PASSWORD = 'Password1234'

username = factory.Sequence('robot{}'.format)
email = factory.Sequence('robot+test+{}@edx.org'.format)
Expand Down
19 changes: 10 additions & 9 deletions common/djangoapps/student/tests/test_admin_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def test_save_valid_data(self):
'email': self.user.email
}

self.client.login(username=self.user.username, password='test')
self.client.login(username=self.user.username, password=self.TEST_PASSWORD)

# # adding new role from django admin page
response = self.client.post(reverse('admin:student_courseaccessrole_add'), data=data)
Expand All @@ -78,7 +78,7 @@ def test_save_without_org_and_course_data(self):
'course_id': str(self.course.id)
}

self.client.login(username=self.user.username, password='test')
self.client.login(username=self.user.username, password=self.TEST_PASSWORD)

# # adding new role from django admin page
response = self.client.post(reverse('admin:student_courseaccessrole_add'), data=data)
Expand All @@ -96,7 +96,7 @@ def test_save_with_course_only(self):

}

self.client.login(username=self.user.username, password='test')
self.client.login(username=self.user.username, password=self.TEST_PASSWORD)

# # adding new role from django admin page
response = self.client.post(reverse('admin:student_courseaccessrole_add'), data=data)
Expand All @@ -115,7 +115,7 @@ def test_save_with_org_only(self):

}

self.client.login(username=self.user.username, password='test')
self.client.login(username=self.user.username, password=self.TEST_PASSWORD)

# # adding new role from django admin page
response = self.client.post(reverse('admin:student_courseaccessrole_add'), data=data)
Expand All @@ -136,7 +136,7 @@ def test_save_with_invalid_course(self):
'email': email
}

self.client.login(username=self.user.username, password='test')
self.client.login(username=self.user.username, password=self.TEST_PASSWORD)

# Adding new role with invalid data
response = self.client.post(reverse('admin:student_courseaccessrole_add'), data=data)
Expand All @@ -163,7 +163,7 @@ def test_save_valid_course_invalid_org(self):
'email': self.user.email
}

self.client.login(username=self.user.username, password='test')
self.client.login(username=self.user.username, password=self.TEST_PASSWORD)

# # adding new role from django admin page
response = self.client.post(reverse('admin:student_courseaccessrole_add'), data=data)
Expand Down Expand Up @@ -230,7 +230,7 @@ def setUp(self):
user=self.user,
course_id=self.course.id, # pylint: disable=no-member
)
self.client.login(username=self.user.username, password='test')
self.client.login(username=self.user.username, password=self.TEST_PASSWORD)

@ddt.data(*ADMIN_URLS)
@ddt.unpack
Expand Down Expand Up @@ -324,13 +324,14 @@ class LoginFailuresAdminTest(TestCase):
def setUpClass(cls):
"""Setup class"""
super().setUpClass()
cls.user = UserFactory.create(username='§', is_staff=True, is_superuser=True)
cls.TEST_PASSWORD = 'Password1234'
cls.user = UserFactory.create(username='§', password=cls.TEST_PASSWORD, is_staff=True, is_superuser=True)
cls.user.save()

def setUp(self):
"""Setup."""
super().setUp()
self.client.login(username=self.user.username, password='test')
self.client.login(username=self.user.username, password=self.TEST_PASSWORD)
self.user2 = UserFactory.create(username='Zażółć gęślą jaźń')
self.user_lockout_until = datetime.datetime.now(UTC)
LoginFailures.objects.create(user=self.user, failure_count=10, lockout_until=self.user_lockout_until)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def setUp(self):
# Create student account
student = UserFactory.create()
CourseEnrollmentFactory.create(user=student, course_id=self.course.id)
self.client.login(username=student.username, password="test")
self.client.login(username=student.username, password=self.TEST_PASSWORD)

self.url = reverse('dashboard')
# URL for email settings modal
Expand Down
6 changes: 3 additions & 3 deletions common/djangoapps/student/tests/test_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def _create_account(self):
params = {
'username': 'test_user',
'email': '[email protected]',
'password': 'edx',
'password': 'Password1234',
'name': 'Test User',
'honor_code': True,
'terms_of_service': True
Expand Down Expand Up @@ -319,7 +319,7 @@ def setUp(self, tracker='common.djangoapps.student.views.management.tracker'):
self.new_email = '[email protected]'
self.req_factory = RequestFactory()
self.request = self.req_factory.post('unused_url', data={
'password': 'test',
'password': 'Password1234',
'new_email': self.new_email
})
self.request.user = self.user
Expand Down Expand Up @@ -628,7 +628,7 @@ def setUp(self, tracker='common.djangoapps.student.views.management.tracker'):
self.new_secondary_email = '[email protected]'
self.req_factory = RequestFactory()
self.request = self.req_factory.post('unused_url', data={
'password': 'test',
'password': 'Password1234',
'new_email': self.new_secondary_email
})
self.request.user = self.user
Expand Down
Loading

0 comments on commit e9609fb

Please sign in to comment.