Skip to content

Commit

Permalink
Merge branch 'master' into ENT-9748/introduce-new-marketable-field
Browse files Browse the repository at this point in the history
  • Loading branch information
hamzawaleed01 committed Dec 10, 2024
2 parents f31b688 + d92ed15 commit 7d6ef26
Show file tree
Hide file tree
Showing 12 changed files with 89 additions and 36 deletions.
3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ RUN apt-get update && \
libcairo2-dev \
python3-pip \
python${PYTHON_VERSION} \
python${PYTHON_VERSION}-dev \
python${PYTHON_VERSION}-distutils && \
python${PYTHON_VERSION}-dev &&\
rm -rf /var/lib/apt/lists/*

# Use UTF-8.
Expand Down
30 changes: 30 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,39 @@
from django_elasticsearch_dsl.registries import registry
from elasticsearch_dsl.connections import get_connection
from pytest_django.lazy_django import skip_if_no_django
from xdist.scheduler import LoadScopeScheduling

from course_discovery.apps.core.tests.factories import PartnerFactory, SiteFactory

logger = logging.getLogger(__name__)

TEST_DOMAIN = 'testserver.fake'

# List of test classes that are backed by TransactionTestCase
TTC = ['course_discovery/apps/course_metadata/management/commands/tests/test_refresh_course_metadata.py::'
'RefreshCourseMetadataCommandTests',
'course_discovery/apps/course_metadata/tests/test_admin.py::ProgramAdminFunctionalTests']


class LoadScopeSchedulingDjangoOrdered(LoadScopeScheduling):
# pylint: disable=abstract-method

# Recent versions of pytest-xdist change the order of test execution such that TransactionTestCases may
# be run before TestCases. Since TransactionTestCase based tests do not restore the data created
# in data migrations during cleanup, this can cause TestCases which rely on that data to fail.
# pytest-xdist has an open issue for this regression at `https://github.com/pytest-dev/pytest-xdist/issues/1083`

# We extend the LoadScopeScheduling class used by pytest-xdist to push the TransactionTestCases (in our test suites)
# to the end of the workqueue. This ensures the proper ordering of TransactionTestCases
def _assign_work_unit(self, node) -> None:
if not hasattr(self, 'django_ordered'):
self.django_ordered = True # pylint: disable=attribute-defined-outside-init
for test_class in TTC:
if test_class in self.workqueue:
self.workqueue.move_to_end(test_class)

return super()._assign_work_unit(node)


@pytest.fixture(scope='session', autouse=True)
def django_cache_add_xdist_key_prefix(request):
Expand Down Expand Up @@ -108,3 +134,7 @@ def clear_es_indexes():
conn = get_connection()
for index_name in settings.ELASTICSEARCH_INDEX_NAMES.values():
conn.indices.delete(index=index_name + '_*')


def pytest_xdist_make_scheduler(config, log):
return LoadScopeSchedulingDjangoOrdered(config, log)
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ def test_list(self):
""" Verify the endpoint returns a list of all programs. """
expected = [self.create_program() for __ in range(3)]

self.assert_list_results(self.list_path, expected, 27)
self.assert_list_results(self.list_path, expected, 26)

@pytest.mark.parametrize("include_restriction_param", [True, False])
def test_list_restricted_runs(self, include_restriction_param):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ def _process_course_run_summary(self, course_run_summary):
course_run.enrollment_count = course_run_count
course_run.recent_enrollment_count = course_run_recent_count
course_run.save(update_fields=['enrollment_count', 'recent_enrollment_count'], suppress_publication=True)
draft_run = course_run.draft_version
if draft_run:
draft_run.enrollment_count = course_run_count
draft_run.recent_enrollment_count = course_run_recent_count
draft_run.save(update_fields=['enrollment_count', 'recent_enrollment_count'], suppress_publication=True)

# Add course run total to course total in dictionary
if course.uuid in self.course_dictionary:
Expand All @@ -92,7 +97,11 @@ def _process_course_enrollment_count(self, course, count, recent_count):
course.enrollment_count = count
course.recent_enrollment_count = recent_count
course.save(update_fields=['enrollment_count', 'recent_enrollment_count'])

draft_course = course.draft_version
if draft_course:
draft_course.enrollment_count = count
draft_course.recent_enrollment_count = recent_count
draft_course.save(update_fields=['enrollment_count', 'recent_enrollment_count'])
# Add course count to program dictionary for all programs
for program in course.programs.all():
# add course total to program total in dictionary
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,8 @@ def ingest(self): # pylint: disable=too-many-statements

course_run.refresh_from_db()

if course_run.status in [CourseRunStatus.Unpublished, CourseRunStatus.LegalReview]:
if course_run.status in [CourseRunStatus.Unpublished, CourseRunStatus.LegalReview,
CourseRunStatus.InternalReview]:
if course_run.status == CourseRunStatus.Unpublished:
# Pushing the run into LegalReview is necessary to ensure that the
# url slug is correctly generated in subdirectory format
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from course_discovery.apps.course_metadata.data_loaders.tests.mixins import DataLoaderTestMixin
from course_discovery.apps.course_metadata.models import Course, CourseRun, Program
from course_discovery.apps.course_metadata.tests.factories import CourseFactory, CourseRunFactory, ProgramFactory
from course_discovery.apps.course_metadata.utils import ensure_draft_world


class AnalyticsAPIDataLoaderTests(DataLoaderTestMixin, TestCase):
Expand Down Expand Up @@ -48,18 +49,20 @@ def _define_course_metadata(self):
program = ProgramFactory()
program.courses.set(courses.values())

@responses.activate
def test_ingest(self):
self._define_course_metadata()

def _mock_course_summaries(self, data):
url = f'{self.api_url}course_summaries/'
responses.add(
method=responses.GET,
url=url,
body=json.dumps(self.mocked_data),
body=json.dumps(data),
match_querystring=False,
content_type=JSON
)

@responses.activate
def test_ingest(self):
self._define_course_metadata()
self._mock_course_summaries(self.mocked_data)
self.loader.ingest()

# For runs, let's just confirm that enrollment counts were recorded and add up counts for courses
Expand Down Expand Up @@ -92,3 +95,21 @@ def test_ingest(self):
programs = Program.objects.all()
assert programs[0].enrollment_count == expected_program_enrollment_count
assert programs[0].recent_enrollment_count == expected_program_recent_enrollment_count

@responses.activate
def test_draft_versions_updated(self):
course = CourseFactory(key='OrgX+CS100')
course_run = CourseRunFactory(key='course-v1:OrgX+CS100+Y', course=course)
ensure_draft_world(course_run)

analytics_api_response = [{
'course_id': 'course-v1:OrgX+CS100+Y',
'count': '528',
'recent_count_change': '87'
}]
self._mock_course_summaries(analytics_api_response)
self.loader.ingest()

for obj in [Course.objects.first(), CourseRun.objects.first()]:
assert obj.draft_version.enrollment_count == 528
assert obj.draft_version.recent_enrollment_count == 87
Original file line number Diff line number Diff line change
Expand Up @@ -724,8 +724,9 @@ def test_ingest_flow_for_preexisting_unpublished_course(self, jwt_decode_patch):
)

@responses.activate
def test_ingest_flow_for_preexisting_course_having_run_in_legal_review_status(
self, jwt_decode_patch
@data(CourseRunStatus.LegalReview, CourseRunStatus.InternalReview)
def test_ingest_flow_for_preexisting_course_having_run_in_review_statuses(
self, status, jwt_decode_patch
): # pylint: disable=unused-argument
"""
Verify that the course run will be reviewed if csv loader updates data for a course having a run in legal
Expand All @@ -744,7 +745,7 @@ def test_ingest_flow_for_preexisting_course_having_run_in_legal_review_status(
course=course,
key=self.COURSE_RUN_KEY,
type=self.course_run_type,
status=CourseRunStatus.LegalReview,
status=status,
go_live_date=datetime.datetime.now(UTC) - datetime.timedelta(days=5),
draft=True,
fixed_price_usd=111.11
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@

import responses
from django.core.management import call_command
from django.test import TransactionTestCase
from django.test import TestCase

from course_discovery.apps.api.v1.tests.test_views.mixins import OAuth2Mixin
from course_discovery.apps.course_metadata.models import (
Course, CourseEntitlement, CourseRun, Degree, LevelType, Person, Program, Seat, Subject
)


class AddProvisioningDataCommandTests(TransactionTestCase, OAuth2Mixin):
class AddProvisioningDataCommandTests(TestCase, OAuth2Mixin):
"""
Test suite for add_provisioning_data management command.
"""
Expand Down
8 changes: 5 additions & 3 deletions course_discovery/apps/course_metadata/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2978,14 +2978,16 @@ def is_marketable_external(self):
Else, a course run is deemed suitable for external marketing if it is an
executive education (EE) course, the discovery service status is
'Reviewed', and the course start date is in the future.
'Reviewed', and the course go_live_date & start_date is in future.
"""
if self.is_marketable:
return self.is_marketable
is_exec_ed_course = self.course.type.slug == CourseType.EXECUTIVE_EDUCATION_2U
if is_exec_ed_course:
return self.status == CourseRunStatus.Reviewed and self.is_upcoming()
now = datetime.datetime.now(pytz.UTC)
is_reviewed = self.status == CourseRunStatus.Reviewed
has_future_go_live_date = self.go_live_date and self.go_live_date > now
return is_reviewed and self.is_upcoming() and has_future_go_live_date
return False

@property
Expand Down
8 changes: 0 additions & 8 deletions requirements/constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,6 @@ selenium==4.12.0
# Open AI version 1.0.0 dropped support for openai.ChatCompletion which is currently in use in enterprise.
openai<=0.28.1

# Version 3.5.0 is causing some tests (learner_pathway models, test_add_provisioning_data, etc.) to fail
# all of a sudden. The v3.5.0 introduces some ordering changes in `loadscope` dist and that is causing an existing test(s)
# that do not clean up properly to cause failures. Pinning the version to unblock requirements upgrade.
# This is happening on some other open source repositories as well.
# https://github.com/PrefectHQ/prefect/pull/11229/files
# https://github.com/hyperspy/hyperspy/pull/3274
pytest-xdist < 3.5.0

# 5.4.0 is breaking for Python 3.8 and 3.11 CI checks with error
# importlib.resources' has no attribute 'files'
# To be unpinned once course-discovery moves to Python 3.12
Expand Down
12 changes: 5 additions & 7 deletions requirements/local.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ boltons==21.0.0
# face
# glom
# semgrep
boto3==1.35.71
boto3==1.35.72
# via django-ses
botocore==1.35.71
botocore==1.35.72
# via
# boto3
# s3transfer
Expand Down Expand Up @@ -352,7 +352,7 @@ edx-api-doc-tools==2.0.0
# via -r requirements/base.in
edx-auth-backends==4.4.0
# via -r requirements/base.in
edx-ccx-keys==1.3.0
edx-ccx-keys==2.0.2
# via
# -r requirements/base.in
# openedx-events
Expand Down Expand Up @@ -675,10 +675,8 @@ pytest-responses==0.5.1
# via -r requirements/test.in
pytest-split==0.10.0
# via -r requirements/local.in
pytest-xdist==3.4.0
# via
# -c requirements/constraints.txt
# -r requirements/test.in
pytest-xdist==3.6.1
# via -r requirements/test.in
python-dateutil==2.9.0.post0
# via
# -r requirements/base.in
Expand Down
6 changes: 3 additions & 3 deletions requirements/production.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ beautifulsoup4==4.12.3
# taxonomy-connector
billiard==4.2.1
# via celery
boto3==1.35.71
boto3==1.35.72
# via django-ses
botocore==1.35.71
botocore==1.35.72
# via
# boto3
# s3transfer
Expand Down Expand Up @@ -288,7 +288,7 @@ edx-api-doc-tools==2.0.0
# via -r requirements/base.in
edx-auth-backends==4.4.0
# via -r requirements/base.in
edx-ccx-keys==1.3.0
edx-ccx-keys==2.0.2
# via
# -r requirements/base.in
# openedx-events
Expand Down

0 comments on commit 7d6ef26

Please sign in to comment.