Skip to content

Commit

Permalink
feat: add Global Alumni in external course sync (#3330)
Browse files Browse the repository at this point in the history
* feat: add Global Alumni in external course sync

* refactor: made code generic and adjusted tests

* refactor: added sync_daily in platform and refactored courses/task.py to be more generic

* fix: test

* fix: some issues

* fix: some issues

* fix: some issues

* fix: issues after rebase

* fix: some issues

* fix: some issues

* fix: pre-commit issues

* fix: issues

* fix: tests

* test: add GA tests

* fix: issues

* fix: tests

* fix: tests

---------

Co-authored-by: Asad Ali <[email protected]>
  • Loading branch information
Anas12091101 and asadali145 authored Dec 12, 2024
1 parent a19d3e8 commit d09c364
Show file tree
Hide file tree
Showing 18 changed files with 721 additions and 454 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ HUBSPOT_ID_PREFIX=
MITOL_DIGITAL_CREDENTIALS_VERIFY_SERVICE_BASE_URL=http://host.docker.internal:5000/
MITOL_DIGITAL_CREDENTIALS_HMAC_SECRET=test-hmac-secret # pragma: allowlist secret

EMERITUS_API_KEY=fake_api_key
EXTERNAL_COURSE_SYNC_API_KEY=fake_api_key

POSTHOG_PROJECT_API_KEY=
POSTHOG_API_HOST=https://app.posthog.com/
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ jobs:
DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres # pragma: allowlist secret
WEBPACK_DISABLE_LOADER_STATS: "True"
ELASTICSEARCH_URL: localhost:9200
EMERITUS_API_KEY: fake_emeritus_api_key # pragma: allowlist secret
EXTERNAL_COURSE_SYNC_API_KEY: fake_external_course_sync_api_key # pragma: allowlist secret
MAILGUN_KEY: fake_mailgun_key
MAILGUN_SENDER_DOMAIN: other.fake.site
MITOL_DIGITAL_CREDENTIALS_VERIFY_SERVICE_BASE_URL: http://localhost:5000
Expand Down
28 changes: 14 additions & 14 deletions app.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,12 @@
"description": "'hours' value for the 'generate-course-certificate' scheduled task (defaults to midnight)",
"required": false
},
"CRON_EMERITUS_COURSERUN_SYNC_DAYS": {
"description": "'day_of_week' value for 'sync-emeritus-course-runs' scheduled task (default will run once a day).",
"CRON_EXTERNAL_COURSERUN_SYNC_DAYS": {
"description": "'day_of_week' value for 'sync-external-course-runs' scheduled task (default will run once a day).",
"required": false
},
"CRON_EMERITUS_COURSERUN_SYNC_HOURS": {
"description": "'hours' value for the 'sync-emeritus-course-runs' scheduled task (defaults to midnight)",
"CRON_EXTERNAL_COURSERUN_SYNC_HOURS": {
"description": "'hours' value for the 'sync-external-course-runs' scheduled task (defaults to midnight)",
"required": false
},
"CSRF_TRUSTED_ORIGINS": {
Expand Down Expand Up @@ -234,20 +234,20 @@
"description": "Timeout (in seconds) for requests made via the edX API client",
"required": false
},
"EMERITUS_API_BASE_URL": {
"description": "Base API URL for Emeritus API",
"ENROLLMENT_CHANGE_SHEET_ID": {
"description": "ID of the Google Sheet that contains the enrollment change request worksheets (refunds, transfers, etc)",
"required": false
},
"EMERITUS_API_KEY": {
"description": "The API Key for Emeritus API",
"required": true
},
"EMERITUS_API_TIMEOUT": {
"description": "API request timeout for Emeritus APIs in seconds",
"EXTERNAL_COURSE_SYNC_API_BASE_URL": {
"description": "Base API URL for external course sync API",
"required": false
},
"ENROLLMENT_CHANGE_SHEET_ID": {
"description": "ID of the Google Sheet that contains the enrollment change request worksheets (refunds, transfers, etc)",
"EXTERNAL_COURSE_SYNC_API_KEY": {
"description": "The API Key for external course sync API",
"required": true
},
"EXTERNAL_COURSE_SYNC_API_REQUEST_TIMEOUT": {
"description": "API request timeout for external course sync APIs in seconds",
"required": false
},
"GA_TRACKING_ID": {
Expand Down
31 changes: 16 additions & 15 deletions courses/management/commands/sync_external_course_runs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

from django.core.management.base import BaseCommand

from courses.sync_external_courses.emeritus_api import (
EmeritusKeyMap,
fetch_emeritus_courses,
update_emeritus_course_runs,
from courses.sync_external_courses.external_course_sync_api import (
EXTERNAL_COURSE_VENDOR_KEYMAPS,
fetch_external_courses,
update_external_course_runs,
)
from mitxpro import settings

Expand Down Expand Up @@ -36,18 +36,19 @@ def handle(self, *args, **options): # noqa: ARG002
return

vendor_name = options["vendor_name"]
if vendor_name.lower() == EmeritusKeyMap.PLATFORM_NAME.value.lower():
self.stdout.write(f"Starting course sync for {vendor_name}.")
emeritus_course_runs = fetch_emeritus_courses()
stats = update_emeritus_course_runs(emeritus_course_runs)
self.log_stats(stats)
self.stdout.write(
self.style.SUCCESS(
f"External course sync successful for {vendor_name}."
)
)
else:
keymap = EXTERNAL_COURSE_VENDOR_KEYMAPS.get(vendor_name.lower())
if not keymap:
self.stdout.write(self.style.ERROR(f"Unknown vendor name {vendor_name}."))
return

self.stdout.write(f"Starting course sync for {vendor_name}.")
keymap = keymap()
external_course_runs = fetch_external_courses(keymap)
stats = update_external_course_runs(external_course_runs, keymap)
self.log_stats(stats)
self.stdout.write(
self.style.SUCCESS(f"External course sync successful for {vendor_name}.")
)

def log_stats(self, stats):
"""
Expand Down
20 changes: 20 additions & 0 deletions courses/migrations/0041_platform_sync_daily.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 4.2.16 on 2024-12-06 13:47

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("courses", "0040_alter_courserun_courseware_id"),
]

operations = [
migrations.AddField(
model_name="platform",
name="sync_daily",
field=models.BooleanField(
default=False,
help_text="Select this option to enable daily syncing for external course platforms.",
),
),
]
4 changes: 4 additions & 0 deletions courses/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@ class Platform(TimestampedModel, ValidateOnSaveMixin):
"""

name = models.CharField(max_length=255, unique=True)
sync_daily = models.BooleanField(
default=False,
help_text="Select this option to enable daily syncing for external course platforms.",
)

def __str__(self):
return self.name
Expand Down
7 changes: 5 additions & 2 deletions courses/models_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
ProgramRunFactory,
)
from courses.models import CourseRunEnrollment, limit_to_certificate_pages
from courses.sync_external_courses.external_course_sync_api import (
EMERITUS_PLATFORM_NAME,
)
from ecommerce.factories import ProductFactory, ProductVersionFactory
from mitxpro.test_utils import format_as_iso8601
from mitxpro.utils import now_in_utc
Expand Down Expand Up @@ -812,7 +815,7 @@ def test_platform_name_is_unique():
"""
Tests that case-insensitive platform name is unique.
"""
PlatformFactory.create(name="Emeritus")
PlatformFactory.create(name=EMERITUS_PLATFORM_NAME)

with pytest.raises(ValidationError):
PlatformFactory.create(name="emeritus")
PlatformFactory.create(name=EMERITUS_PLATFORM_NAME.lower())
Loading

0 comments on commit d09c364

Please sign in to comment.