diff --git a/cms/models.py b/cms/models.py index bcb2ea9041..67d2fca5d1 100644 --- a/cms/models.py +++ b/cms/models.py @@ -1109,18 +1109,6 @@ def get_url_parts(self, request=None): ), ) - @property - def get_current_finaid(self): - """ - Returns information about financial aid for the current learner. - - If the learner has a flexible pricing(financial aid) request that's - approved, this should return the learner's adjusted price. If they - don't, this should return the Page for the applicable request form. - If they're not logged in, this should return None. - """ - raise NotImplementedError - def get_context(self, request, *args, **kwargs): # noqa: ARG002 instructors = [ member.linked_instructor_page @@ -1165,7 +1153,7 @@ def product(self): """Gets the product associated with this page""" return self.course - def get_current_finaid(self, request): + def _get_current_finaid(self, request): """ Returns information about financial aid for the current learner. @@ -1216,7 +1204,7 @@ def get_context(self, request, *args, **kwargs): and relevant_run is not None and (relevant_run.is_in_progress or request.user.is_editor) ) - finaid_price = self.get_current_finaid(request) + finaid_price = self._get_current_finaid(request) product = ( relevant_run.products.filter(is_active=True).first() if relevant_run diff --git a/cms/models_test.py b/cms/models_test.py index 8b1c565aea..11abe9a5d6 100644 --- a/cms/models_test.py +++ b/cms/models_test.py @@ -618,28 +618,6 @@ def test_courseware_title_synced_with_product_page_title(test_course): assert courseware.title == updated_title -def test_get_current_finaid_with_flex_price_for_expired_course_run(mocker): - """ - Tests that get_current_finaid returns None for a user approved for - financial aid on a course with only expired course runs. - """ - now = now_in_utc() - course_run = CourseRunFactory.create(enrollment_end=now - timedelta(days=10)) - ProductFactory.create(purchasable_object=course_run) - rf = RequestFactory() - request = rf.get("/") - request.user = UserFactory.create() - patched_flexible_price_approved = mocker.patch( - "flexiblepricing.api.is_courseware_flexible_price_approved" - ) - patched_flexible_price_discount = mocker.patch( - "flexiblepricing.api.determine_courseware_flexible_price_discount" - ) - assert course_run.course.page.get_current_finaid(request) is None - patched_flexible_price_discount.assert_not_called() - patched_flexible_price_approved.assert_not_called() - - @pytest.mark.parametrize("flex_form_for_course", [True, False]) def test_flexible_pricing_request_form_context(flex_form_for_course): """ diff --git a/cms/templates/product_page.html b/cms/templates/product_page.html index 81d9a9bac5..b23e3de7ee 100644 --- a/cms/templates/product_page.html +++ b/cms/templates/product_page.html @@ -9,8 +9,8 @@ {% block seohead %} {% meta_tags page %} - {% if page.thumbnail_image %} - + {% if page.feature_image %} + {% endif %} {% endblock %} @@ -129,7 +129,7 @@

Prerequisites

{{ page.prerequisites |richtext }} {% endif %} - {% if instructors or page.faculty_members %} + {% if instructors %}

{{ page.faculty_section_title }}

diff --git a/courses/api.py b/courses/api.py index dcbda04687..94ec2e8f8e 100644 --- a/courses/api.py +++ b/courses/api.py @@ -1,6 +1,5 @@ """API for the Courses app""" -import itertools import logging from collections import namedtuple from datetime import timedelta @@ -16,7 +15,6 @@ from mitol.common.utils.collections import ( first_or_none, has_equal_properties, - partition, ) from requests.exceptions import ConnectionError as RequestsConnectionError from requests.exceptions import HTTPError @@ -96,98 +94,6 @@ def get_user_relevant_program_course_run_qset( return enrollable_run_qset.order_by("enrollment_start") -def get_relevant_course_run( - course: Course, -) -> CourseRun: - """ - For a given Course, finds the course run that is the most relevant to the user. - For anonymous users, this means the soonest enrollable course run. - For logged-in users, this means an active course run that they're enrolled in, or the soonest enrollable course run. - """ - runs = get_relevant_course_run_qset(course) - run = first_or_none(runs) - return run # noqa: RET504 - - -def get_user_enrollments(user): - """ - Fetches a user's enrollments - - If the user is enrolled in a course that belongs to a program, we count that - as an enrollment in the program (and we create an ephemeral - ProgramEnrollment for that) unless the user is already enrolled in the - program directly. - - Args: - user (User): A user - Returns: - UserEnrollments: An object representing a user's program and course run enrollments - """ - course_run_enrollments = ( - CourseRunEnrollment.objects.filter(user=user).order_by("run__start_date").all() - ) - - all_course_run_programs = [] # all the programs that the course runs belong to - filtered_course_run_programs = [] # just the programs we don't have distinct ProgramEnrollments for - - for cre in course_run_enrollments: - if cre.run.course.programs: - all_course_run_programs += cre.run.course.programs - all_course_run_programs = set(all_course_run_programs) - - program_enrollments = ProgramEnrollment.objects.filter(user=user).all() - - for program in all_course_run_programs: - found = False - - for enrollment in program_enrollments: - if enrollment.program == program: - found = True - break - - if not found: - filtered_course_run_programs.append(program) - - program_enrollments = list( - itertools.chain( - program_enrollments, - [ - ProgramEnrollment(user=user, program=program) - for program in filtered_course_run_programs - ], - ) - ) - - program_courses = itertools.chain( - *( - program_enrollment.program.courses - for program_enrollment in program_enrollments - ) - ) - program_course_ids = set(course[0].id for course in program_courses) # noqa: C401 - non_program_run_enrollments, program_run_enrollments = partition( - course_run_enrollments, - lambda course_run_enrollment: ( - course_run_enrollment.run.course_id in program_course_ids - ), - ) - program_enrollments, past_program_enrollments = partition( - program_enrollments, lambda program_enrollment: program_enrollment.is_ended - ) - non_program_run_enrollments, past_non_program_run_enrollments = partition( - non_program_run_enrollments, - lambda non_program_run_enrollment: non_program_run_enrollment.is_ended, - ) - - return UserEnrollments( - programs=program_enrollments, - past_programs=past_program_enrollments, - program_runs=program_run_enrollments, - non_program_runs=non_program_run_enrollments, - past_non_program_runs=past_non_program_run_enrollments, - ) - - def create_run_enrollments( # noqa: C901 user, runs, diff --git a/courses/api_test.py b/courses/api_test.py index b68c9d3ea1..a8a25982c4 100644 --- a/courses/api_test.py +++ b/courses/api_test.py @@ -22,8 +22,6 @@ defer_enrollment, generate_course_run_certificates, generate_program_certificate, - get_relevant_course_run, - get_user_enrollments, manage_course_run_certificate_access, manage_program_certificate_access, override_user_grade, @@ -118,178 +116,6 @@ def courses_api_logs(mocker): return mocker.patch("courses.api.log") -@pytest.mark.parametrize("is_enrolled", [True, False]) -@pytest.mark.parametrize("is_live", [True, False]) -def test_get_relevant_course_run(user, dates, course, is_live, is_enrolled): - """ - get_relevant_course_run should return the soonest course - run that is enrollable, even if the user is already enrolled. - """ - # One run in the near future, one run in progress with an expired enrollment period, and one run in the far future. - course_runs = CourseRunFactory.create_batch( - 3, - course=course, - start_date=factory.Iterator( - [dates.future_10_days, dates.past_10_days, dates.future_30_days] - ), - end_date=factory.Iterator([None, dates.future_10_days, dates.future_60_days]), - enrollment_start=factory.Iterator( - [dates.past_60_days, dates.past_10_days, dates.past_30_days] - ), - enrollment_end=factory.Iterator( - [None, dates.future_30_days, dates.future_60_days] - ), - ) - if is_enrolled: - # Enroll in the in-progress course run - CourseRunEnrollmentFactory.create( - run=course_runs[1], user=user, edx_enrolled=True, active=True - ) - returned_run = get_relevant_course_run(course=course) - assert returned_run == course_runs[0] - course_runs[0].live = is_live - course_runs[0].save() - returned_run = get_relevant_course_run(course=course) - assert returned_run == (course_runs[0] if is_live else course_runs[2]) - - -def test_get_relevant_course_run_invalid_dates(user, dates, course): - """ - get_relevant_course_run should ignore course runs with any of the following properties when the user is not enrolled: - 1) No start date or enrollment start date - 2) An enrollment end date in the past - 3) The course run is not live - - """ - CourseRunFactory.create_batch( - 3, - course=course, - start_date=factory.Iterator([None, dates.future_10_days, dates.past_30_days]), - end_date=factory.Iterator([None, dates.future_60_days, dates.past_10_days]), - enrollment_start=factory.Iterator( - [dates.future_10_days, None, dates.past_30_days] - ), - enrollment_end=factory.Iterator( - [dates.future_60_days, None, dates.past_10_days] - ), - ) - CourseRunFactory.create(course=course, live=False) - returned_run = get_relevant_course_run(course=course) - assert returned_run is None - - -def test_get_user_enrollments(user, program_with_empty_requirements): # noqa: F811 - """Test that get_user_enrollments returns an object with a user's program and course enrollments""" - past_date = now_in_utc() - timedelta(days=1) - past_start_dates = [ - now_in_utc() - timedelta(days=2), - now_in_utc() - timedelta(days=3), - now_in_utc() - timedelta(days=4), - ] - program_course_runs = CourseRunFactory.create_batch(3) - for course_run in program_course_runs: - program_with_empty_requirements.add_requirement(course_run.course) - - past_program = ProgramFactory.create() - ProgramRequirementFactory.add_root(past_program) - root_node = past_program.requirements_root - required_courses_node = root_node.add_child( - node_type=ProgramRequirementNodeType.OPERATOR, - operator=ProgramRequirement.Operator.ALL_OF, - title="Required Courses", - ) - past_program_course_runs = CourseRunFactory.create_batch( - 3, - start_date=factory.Iterator(past_start_dates), - end_date=past_date, - ) - for course_run in past_program_course_runs: - past_program.add_requirement(course_run.course) - - non_program_course_runs = CourseRunFactory.create_batch(2) - past_non_program_course_runs = CourseRunFactory.create_batch( - 2, - start_date=factory.Iterator(past_start_dates), - end_date=past_date, - ) - all_course_runs = ( - program_course_runs - + past_program_course_runs - + non_program_course_runs - + past_non_program_course_runs - ) - course_run_enrollments = CourseRunEnrollmentFactory.create_batch( - len(all_course_runs), run=factory.Iterator(all_course_runs), user=user - ) - program_enrollment = ProgramEnrollmentFactory.create( - program=program_with_empty_requirements, user=user - ) - past_program_enrollment = ProgramEnrollmentFactory.create( - program=past_program, user=user - ) - # Add a non-active enrollment so we can confirm that it isn't returned - CourseRunEnrollmentFactory.create(user=user, active=False) - - def key_func(enrollment): - """Function for sorting runs by start_date""" - return enrollment.run.start_date - - user_enrollments = get_user_enrollments(user) - assert list(user_enrollments.programs) == [program_enrollment] - assert list(user_enrollments.past_programs) == [past_program_enrollment] - assert list(user_enrollments.program_runs) == sorted( - [ - run_enrollment - for run_enrollment in course_run_enrollments - if run_enrollment.run in program_course_runs + past_program_course_runs - ], - key=key_func, - ) - assert list(user_enrollments.non_program_runs) == sorted( - [ - run_enrollment - for run_enrollment in course_run_enrollments - if run_enrollment.run in non_program_course_runs - ], - key=key_func, - ) - - assert list(user_enrollments.past_non_program_runs) == sorted( - [ - run_enrollment - for run_enrollment in course_run_enrollments - if run_enrollment.run in past_non_program_course_runs - ], - key=key_func, - ) - - # Create a separate Course and Program and then just enroll in the course - # The program ought to still show up as an enrollment - separate_program = ProgramFactory.create() - ProgramRequirementFactory.add_root(separate_program) - root_node = separate_program.requirements_root - required_courses_node = root_node.add_child( # noqa: F841 - node_type=ProgramRequirementNodeType.OPERATOR, - operator=ProgramRequirement.Operator.ALL_OF, - title="Required Courses", - ) - separate_courserun = CourseRunFactory.create() - separate_program.add_requirement(separate_courserun.course) - separate_courserun_enrollment = CourseRunEnrollmentFactory.create( # noqa: F841 - run=separate_courserun, user=user - ) - - user_enrollments = get_user_enrollments(user) - assert len(list(user_enrollments.programs)) == 2 - - user_enrollments = get_user_enrollments(user) - enrollment_programs = [ - enrollment.program for enrollment in user_enrollments.programs - ] - assert program_enrollment.program in enrollment_programs - assert separate_program in enrollment_programs - - @pytest.mark.parametrize( "enrollment_mode", [EDX_DEFAULT_ENROLLMENT_MODE, EDX_ENROLLMENT_VERIFIED_MODE] ) diff --git a/courses/serializers/base.py b/courses/serializers/base.py index baeab0e82f..92211be92e 100644 --- a/courses/serializers/base.py +++ b/courses/serializers/base.py @@ -19,11 +19,11 @@ def get_thumbnail_url(page): A page URL """ relative_url = ( - page.thumbnail_image.file.url + page.feature_image.file.url if page - and page.thumbnail_image - and page.thumbnail_image.file - and page.thumbnail_image.file.url + and page.feature_image + and page.feature_image.file + and page.feature_image.file.url else static("images/mit-dome.png") ) return urljoin(settings.SITE_BASE_URL, relative_url) diff --git a/frontend/public/src/components/CourseInfoBox.js b/frontend/public/src/components/CourseInfoBox.js index d6d77ae0a5..a8dc1a7d80 100644 --- a/frontend/public/src/components/CourseInfoBox.js +++ b/frontend/public/src/components/CourseInfoBox.js @@ -10,14 +10,12 @@ import { getFirstRelevantRun, isRunArchived } from "../lib/courseApi" import moment from "moment-timezone" import type { BaseCourseRun } from "../flow/courseTypes" -import { EnrollmentFlaggedCourseRun, RunEnrollment } from "../flow/courseTypes" +import { EnrollmentFlaggedCourseRun } from "../flow/courseTypes" import type { CurrentUser } from "../flow/authTypes" import { Modal, ModalBody, ModalHeader } from "reactstrap" type CourseInfoBoxProps = { courses: Array, - courseRuns: ?Array, - enrollments: ?Array, currentUser: CurrentUser, setCurrentCourseRun: (run: EnrollmentFlaggedCourseRun) => Promise } @@ -156,21 +154,22 @@ export default class CourseInfoBox extends React.PureComponent 0 && run.products[0] const isArchived = isRunArchived(run) const startDates = [] - const moreEnrollableCourseRuns = courseRuns && courseRuns.length > 1 + const moreEnrollableCourseRuns = + course.courseruns && course.courseruns.length > 1 if (moreEnrollableCourseRuns) { - courseRuns.forEach((courseRun, index) => { + course.courseruns.forEach((courseRun, index) => { if (courseRun.id !== run.id) { startDates.push(
  • {getCourseDates(courseRun, isArchived, true)}
  • diff --git a/frontend/public/src/components/CourseProductDetailEnroll.js b/frontend/public/src/components/CourseProductDetailEnroll.js index f719d0b656..389e0ef78b 100644 --- a/frontend/public/src/components/CourseProductDetailEnroll.js +++ b/frontend/public/src/components/CourseProductDetailEnroll.js @@ -12,28 +12,16 @@ import { Modal, ModalBody, ModalHeader } from "reactstrap" import Loader from "./Loader" import { routes } from "../lib/urls" import { getFlexiblePriceForProduct, formatLocalePrice } from "../lib/util" -import { EnrollmentFlaggedCourseRun, RunEnrollment } from "../flow/courseTypes" +import { EnrollmentFlaggedCourseRun } from "../flow/courseTypes" import { - courseRunsSelector, - courseRunsQuery, - courseRunsQueryKey, coursesSelector, coursesQuery, coursesQueryKey } from "../lib/queries/courseRuns" -import { - enrollmentsQuery, - enrollmentsQueryKey, - enrollmentsSelector -} from "../lib/queries/enrollment" import { formatPrettyDate, emptyOrNil } from "../lib/util" import moment from "moment-timezone" -import { - getFirstRelevantRun, - isRunArchived, - isFinancialAssistanceAvailable -} from "../lib/courseApi" +import { getFirstRelevantRun, isRunArchived } from "../lib/courseApi" import { getCookie } from "../lib/api" import users, { currentUserSelector } from "../lib/queries/users" import { @@ -49,14 +37,10 @@ import type { Product } from "../flow/cartTypes" type Props = { courseId: ?string, isLoading: ?boolean, - courseRuns: ?Array, courses: ?Array, - enrollments: ?Array, status: ?number, courseIsLoading: ?boolean, courseStatus: ?number, - enrollmentsIsLoading: ?boolean, - enrollmentsStatus: ?number, upgradeEnrollmentDialogVisibility: boolean, addProductToBasket: (user: number, productId: number) => Promise, currentUser: User, @@ -147,7 +131,8 @@ export class CourseProductDetailEnroll extends React.Component< } hndSetCourseRun = (event: any) => { - const { courseRuns } = this.props + const { courses } = this.props + const courseRuns = courses && courses[0] ? courses[0].courseruns : null if (event.target.value === "default") { this.setCurrentCourseRun(null) return @@ -176,7 +161,8 @@ export class CourseProductDetailEnroll extends React.Component< } renderRunSelectorButtons() { - const { courseRuns } = this.props + const { courses } = this.props + const courseRuns = courses && courses[0] ? courses[0].courseruns : null const enrollableCourseRuns = courseRuns ? courseRuns.filter( (run: EnrollmentFlaggedCourseRun) => run.is_enrollable @@ -242,16 +228,19 @@ export class CourseProductDetailEnroll extends React.Component< } renderUpgradeEnrollmentDialog(firstRelevantRun: EnrollmentFlaggedCourseRun) { - const { courseRuns } = this.props + const { courses } = this.props + const courseRuns = courses && courses[0] ? courses[0].courseruns : null + const course = courses && courses[0] ? courses[0] : null let run = this.getCurrentCourseRun() - const course = courseRuns && courseRuns[0].course const hasMultipleEnrollableRuns = courseRuns && courseRuns.length > 1 if (!run && !hasMultipleEnrollableRuns) { run = firstRelevantRun } const needFinancialAssistanceLink = run && - isFinancialAssistanceAvailable(run) && + course && + course.page && + course.page.financial_assistance_form_url && !run.approved_flexible_price_exists ? (

    run.is_upgradable @@ -461,7 +450,8 @@ export class CourseProductDetailEnroll extends React.Component< run: EnrollmentFlaggedCourseRun, product: Product | null ) { - const { courseRuns } = this.props + const { courses } = this.props + const courseRuns = courses && courses[0] ? courses[0].courseruns : null const csrfToken = getCookie("csrftoken") return run ? (

    @@ -493,23 +483,18 @@ export class CourseProductDetailEnroll extends React.Component< } render() { - const { - courseRuns, - courses, - courseIsLoading, - currentUser, - enrollments, - enrollmentsIsLoading - } = this.props + const { courses, courseIsLoading, currentUser } = this.props let run, product = null - - if (courses && courseRuns) { - run = getFirstRelevantRun(courses[0], courseRuns) - - if (run) { - product = run && run.products ? run.products[0] : null - this.updateDate(run) + if (courses) { + const courseRuns = courses[0] ? courses[0].courseruns : null + if (courseRuns) { + run = getFirstRelevantRun(courses[0], courseRuns) + + if (run) { + product = run && run.products ? run.products[0] : null + this.updateDate(run) + } } } @@ -519,7 +504,7 @@ export class CourseProductDetailEnroll extends React.Component< // $FlowFixMe: isLoading null or undefined <> {run ? @@ -536,16 +521,11 @@ export class CourseProductDetailEnroll extends React.Component< <> { // $FlowFixMe: isLoading null or undefined - + } @@ -576,26 +556,14 @@ const updateAddlFields = (currentUser: User) => { } const mapStateToProps = createStructuredSelector({ - courseRuns: courseRunsSelector, - courses: coursesSelector, - currentUser: currentUserSelector, - enrollments: enrollmentsSelector, - isLoading: pathOr(true, ["queries", courseRunsQueryKey, "isPending"]), - courseIsLoading: pathOr(true, ["queries", coursesQueryKey, "isPending"]), - enrollmentsIsLoading: pathOr(true, [ - "queries", - enrollmentsQueryKey, - "isPending" - ]), - status: pathOr(null, ["queries", courseRunsQueryKey, "status"]), - courseStatus: pathOr(true, ["queries", coursesQueryKey, "status"]), - enrollmentsStatus: pathOr(true, ["queries", enrollmentsQueryKey, "status"]) + courses: coursesSelector, + currentUser: currentUserSelector, + courseIsLoading: pathOr(true, ["queries", coursesQueryKey, "isPending"]), + courseStatus: pathOr(true, ["queries", coursesQueryKey, "status"]) }) const mapPropsToConfig = props => [ - courseRunsQuery(props.courseId), coursesQuery(props.courseId), - enrollmentsQuery(), users.currentUserQuery() ] diff --git a/frontend/public/src/components/CourseProductDetailEnroll_test.js b/frontend/public/src/components/CourseProductDetailEnroll_test.js index 831d4c4f7a..a89e5e1e28 100644 --- a/frontend/public/src/components/CourseProductDetailEnroll_test.js +++ b/frontend/public/src/components/CourseProductDetailEnroll_test.js @@ -109,13 +109,15 @@ describe("CourseProductDetailEnrollShallowRender", () => { it("checks for enroll now button should appear disabled if enrollment start in future", async () => { const courseRun = makeCourseRunDetail() courseRun["is_enrollable"] = false + const course = makeCourseDetailNoRuns() + course.courseruns = [courseRun] const { inner } = await renderPage( { entities: { - courseRuns: [courseRun] + courses: [course] }, queries: { - courseRuns: { + courses: { isPending: false, status: 200 } @@ -129,13 +131,15 @@ describe("CourseProductDetailEnrollShallowRender", () => { it("checks for enroll now button should appear if enrollment start not in future", async () => { const courseRun = makeCourseRunDetail() + const course = makeCourseDetailNoRuns() + course.courseruns = [courseRun] const { inner } = await renderPage( { entities: { - courseRuns: [courseRun] + courses: [course] }, queries: { - courseRuns: { + courses: { isPending: false, status: 200 } @@ -156,13 +160,15 @@ describe("CourseProductDetailEnrollShallowRender", () => { end_date: moment().subtract(7, "months").toISOString(), upgrade_deadline: null } + const course = makeCourseDetailNoRuns() + course.courseruns = [courseRun] const { inner } = await renderPage( { entities: { - courseRuns: [courseRun] + courses: [course] }, queries: { - courseRuns: { + courses: { isPending: false, status: 200 } @@ -210,8 +216,7 @@ describe("CourseProductDetailEnrollShallowRender", () => { userExists ? "is logged in" : "is anonymous" }`, async () => { const entities = { - currentUser: userExists ? currentUser : makeAnonymousUser(), - enrollments: [] + currentUser: userExists ? currentUser : makeAnonymousUser() } const { inner } = await renderPage({ @@ -236,10 +241,12 @@ describe("CourseProductDetailEnrollShallowRender", () => { courseRuns.push(makeCourseRunDetail()) } + const course = makeCourseDetailNoRuns() + course.courseruns = courseRuns + const entities = { currentUser: userExists ? currentUser : makeAnonymousUser(), - enrollments: [], - courseRuns: courseRuns + courses: [course] } const { inner } = await renderPage({ @@ -271,8 +278,23 @@ describe("CourseProductDetailEnrollShallowRender", () => { financial_assistance_form_url: "google.com" } } + const course = makeCourseDetailNoRuns() + course.courseruns = [courseRun] isFinancialAssistanceAvailableStub.returns(true) - const { inner } = await renderPage() + const { inner } = await renderPage( + { + entities: { + courses: [course] + }, + queries: { + courses: { + isPending: false, + status: 200 + } + } + }, + {} + ) inner.setState({ currentCourseRun: courseRun }) const enrollBtn = inner.find(".enroll-now").at(0) @@ -302,11 +324,11 @@ describe("CourseProductDetailEnrollShallowRender", () => { } else { courseRun["is_self_paced"] = false } - const courseRuns = [courseRun] + const course = makeCourseDetailNoRuns() + course.courseruns = [courseRun] const entities = { currentUser: currentUser, - enrollments: [], - courseRuns: courseRuns + courses: [course] } const { inner } = await renderPage({ entities: entities @@ -378,18 +400,14 @@ describe("CourseProductDetailEnrollShallowRender", () => { it(`shows form based enrollment button when upgrade deadline has passed but course is within enrollment period`, async () => { courseRun.is_upgradable = false course.next_run_id = courseRun.id + course.courseruns = [courseRun] const { inner } = await renderPage( { entities: { - courseRuns: [courseRun], - courses: [course] + courses: [course] }, queries: { - courseRuns: { - isPending: false, - status: 200 - }, courses: { isPending: false, status: 200 @@ -417,7 +435,21 @@ describe("CourseProductDetailEnrollShallowRender", () => { } } ] - const { inner } = await renderPage() + course.courseruns = [courseRun] + const { inner } = await renderPage( + { + entities: { + courses: [course] + }, + queries: { + courses: { + isPending: false, + status: 200 + } + } + }, + { courseId: course.id } + ) const enrollBtn = inner.find(".enroll-now").at(0) assert.isTrue(enrollBtn.exists()) @@ -442,7 +474,21 @@ describe("CourseProductDetailEnrollShallowRender", () => { } } ] - const { inner } = await renderPage() + course.courseruns = [courseRun] + const { inner } = await renderPage( + { + entities: { + courses: [course] + }, + queries: { + courses: { + isPending: false, + status: 200 + } + } + }, + { courseId: course.id } + ) const enrollBtn = inner.find(".enroll-now").at(0) assert.isTrue(enrollBtn.exists()) await enrollBtn.prop("onClick")() @@ -470,7 +516,21 @@ describe("CourseProductDetailEnrollShallowRender", () => { } ] isFinancialAssistanceAvailableStub.returns(false) - const { inner } = await renderPage() + course.courseruns = [courseRun] + const { inner } = await renderPage( + { + entities: { + courses: [course] + }, + queries: { + courses: { + isPending: false, + status: 200 + } + } + }, + { courseId: course.id } + ) const enrollBtn = inner.find(".enroll-now").at(0) assert.isTrue(enrollBtn.exists()) await enrollBtn.prop("onClick")() @@ -523,8 +583,21 @@ describe("CourseProductDetailEnrollShallowRender", () => { product_flexible_price: {} } ] - - const { inner } = await renderPage() + course.courseruns = [courseRun] + const { inner } = await renderPage( + { + entities: { + courses: [course] + }, + queries: { + courses: { + isPending: false, + status: 200 + } + } + }, + { courseId: course.id } + ) const enrollBtn = inner.find(".enroll-now").at(0) assert.isTrue(enrollBtn.exists()) @@ -541,12 +614,11 @@ describe("CourseProductDetailEnrollShallowRender", () => { if (multiples) { courseRuns.push(courseRun) } + course.courseruns = courseRuns const { inner } = await renderPage({ entities: { - courseRuns: courseRuns, courses: [course], - enrollments: [enrollment], currentUser: currentUser } }) @@ -598,12 +670,11 @@ describe("CourseProductDetailEnrollShallowRender", () => { courseRun["is_upgradable"] = false const courseRuns = [courseRun] courseRuns.push(courseRun) + course.courseruns = courseRuns const { inner } = await renderPage({ entities: { - courseRuns: courseRuns, courses: [course], - enrollments: [enrollment], currentUser: currentUser } }) @@ -638,12 +709,11 @@ describe("CourseProductDetailEnrollShallowRender", () => { } const courseRuns = [courseRun] courseRuns.push(runWithMixedInfo) + course.courseruns = courseRuns const { inner } = await renderPage({ entities: { - courseRuns: courseRuns, courses: [course], - enrollments: [enrollment], currentUser: currentUser } }) @@ -711,33 +781,35 @@ describe("CourseProductDetailEnrollShallowRender", () => { } } ] - const course = { ...makeCourseDetailWithRuns(), courseruns: [pastCourseRun, currentCourseRun] } - const entities = { - courseRuns: [currentCourseRun], - courses: [course], - enrollments: [pastCourseRunEnrollment], - currentUser: currentUser - } - const { inner } = await renderPage({ - entities: entities + entities: { + courses: [course], + currentUser: currentUser + }, + queries: { + courses: { + isPending: false, + status: 200 + } + } }) const enrollBtn = inner.find(".enroll-now").at(0) assert.isTrue(enrollBtn.exists()) - + inner.setState({ currentCourseRun: currentCourseRun }) await enrollBtn.prop("onClick")() - + inner.setState({ currentCourseRun: currentCourseRun }) const modal = inner.find(".upgrade-enrollment-modal") const upgradeForm = modal.find("form").at(0) assert.isTrue(upgradeForm.exists()) const certPricing = modal.find(".certificate-pricing").at(0) assert.isTrue(certPricing.exists()) + inner.setState({ currentCourseRun: currentCourseRun }) assert.isTrue( certPricing .text() @@ -767,12 +839,11 @@ describe("CourseProductDetailEnrollShallowRender", () => { } else { courseRun["start_date"] = moment().subtract(10, "months").toISOString() } - const courseRuns = [courseRun] + course.courseruns = [courseRun] const entities = { currentUser: currentUser, - enrollments: [], - courseRuns: courseRuns + courses: [course] } const { inner } = await renderPage({ @@ -836,10 +907,11 @@ describe("CourseProductDetailEnrollShallowRender", () => { courseRuns.push(makeCourseRunDetail()) } + course.courseruns = courseRuns + const entities = { currentUser: userExists ? currentUser : makeAnonymousUser(), - enrollments: [], - courseRuns: courseRuns + courses: [course] } const { inner } = await renderPage({ diff --git a/frontend/public/src/components/ProgramProductDetailEnroll.js b/frontend/public/src/components/ProgramProductDetailEnroll.js index 9ea9d8ede8..dbe2b95021 100644 --- a/frontend/public/src/components/ProgramProductDetailEnroll.js +++ b/frontend/public/src/components/ProgramProductDetailEnroll.js @@ -139,10 +139,6 @@ export class ProgramProductDetailEnroll extends React.Component< }) } - getCurrentCourseRun = (): EnrollmentFlaggedCourseRun => { - return this.state.currentCourseRun - } - renderCertificateInfoPanel() { const { currentCourseRun: run } = this.state