diff --git a/lms/tasks/course_roster.py b/lms/tasks/course_roster.py new file mode 100644 index 0000000000..16a3eb502f --- /dev/null +++ b/lms/tasks/course_roster.py @@ -0,0 +1,22 @@ +"""Celery tasks for fetching course rosters.""" + +from lms.models import LMSCourse +from lms.services.course_roster import CourseRosterService +from lms.tasks.celery import app + + +@app.task( + acks_late=True, + autoretry_for=(Exception,), + max_retries=2, + retry_backoff=3600, + retry_backoff_max=7200, +) +def fetch_roster(*, lms_course_id) -> None: + """Fetch the roster for one course.""" + + with app.request_context() as request: + roster_service = request.find_service(CourseRosterService) + with request.tm: + lms_course = request.db.get(LMSCourse, lms_course_id) + roster_service.fetch_roster(lms_course) diff --git a/tests/unit/lms/tasks/course_roster_test.py b/tests/unit/lms/tasks/course_roster_test.py new file mode 100644 index 0000000000..a989a3a304 --- /dev/null +++ b/tests/unit/lms/tasks/course_roster_test.py @@ -0,0 +1,29 @@ +from contextlib import contextmanager + +import pytest + +from lms.tasks.course_roster import fetch_roster +from tests import factories + + +class TestFetchRoster: + def test_it(self, course_roster_service, db_session): + lms_course = factories.LMSCourse() + db_session.flush() + + fetch_roster(lms_course_id=lms_course.id) + + course_roster_service.fetch_roster.assert_called_once_with(lms_course) + + +@pytest.fixture(autouse=True) +def app(patch, pyramid_request): + app = patch("lms.tasks.course_roster.app") + + @contextmanager + def request_context(): + yield pyramid_request + + app.request_context = request_context + + return app diff --git a/tests/unit/services.py b/tests/unit/services.py index f6b1272581..9fe45ff0f9 100644 --- a/tests/unit/services.py +++ b/tests/unit/services.py @@ -18,6 +18,7 @@ from lms.services.canvas_api import CanvasAPIClient from lms.services.canvas_studio import CanvasStudioService from lms.services.course import CourseService +from lms.services.course_roster import CourseRosterService from lms.services.d2l_api import D2LAPIClient from lms.services.dashboard import DashboardService from lms.services.digest import DigestService @@ -67,6 +68,7 @@ "canvas_service", "canvas_studio_service", "course_service", + "course_roster_service", "d2l_api_client", "dashboard_service", "digest_service", @@ -187,6 +189,11 @@ def course_service(mock_service): return mock_service(CourseService, service_name="course") +@pytest.fixture +def course_roster_service(mock_service): + return mock_service(CourseRosterService) + + @pytest.fixture def d2l_api_client(mock_service): return mock_service(D2LAPIClient)