def test_featured_product(): """Verify that there will be only one product marked as feature.""" program_page = ProgramPageFactory.create(featured=True) another_program_page = ProgramPageFactory.create(featured=True) program_page.refresh_from_db() assert not program_page.featured assert another_program_page.featured # add and mark course as featured course_page = CoursePageFactory.create(featured=True) another_program_page.refresh_from_db() assert not another_program_page.featured assert course_page.featured another_course_page = CoursePageFactory.create(featured=True) course_page.refresh_from_db() assert not course_page.featured assert another_course_page.featured external_course_page = ExternalCoursePageFactory.create(featured=True) another_course_page.refresh_from_db() assert not another_course_page.featured assert external_course_page.featured external_program_page = ExternalProgramPageFactory.create(featured=True) external_course_page.refresh_from_db() assert not external_course_page.featured assert external_program_page.featured
def test_certificate_for_program_page(): """ The Certificate property should return expected values if associated with a CertificatePage """ program_page = ProgramPageFactory.create(certificate_page=None) assert CertificatePage.can_create_at(program_page) assert not SignatoryPage.can_create_at(program_page) certificate_page = CertificatePageFactory.create( parent=program_page, product_name="product_name", CEUs="2.8", signatories__0__signatory__name="Name", signatories__0__signatory__title_1="Title_1", signatories__0__signatory__title_2="Title_2", signatories__0__signatory__organization="Organization", signatories__0__signatory__signature_image__title="Image", ) assert certificate_page.get_parent() == program_page assert certificate_page.CEUs == "2.8" assert certificate_page.product_name == "product_name" for signatory in certificate_page.signatories: # pylint: disable=not-an-iterable assert signatory.value.name == "Name" assert signatory.value.title_1 == "Title_1" assert signatory.value.title_2 == "Title_2" assert signatory.value.organization == "Organization" assert signatory.value.signature_image.title == "Image"
def test_program_page(browser, base_test_data, logged_in_student): """ Test viewing the program page """ courses = list(base_test_data.program.course_set.all()) + \ CourseFactory.create_batch(2, program=base_test_data.program) page = ProgramPageFactory.create(program=base_test_data.program, title="A Program Title") faculty = FacultyFactory.create_batch(3, program_page=page) info_links = InfoLinksFactory.create_batch(3, program_page=page) semester_dates = SemesterDateFactory.create_batch(3, program_page=page) program_courses = ProgramCourseFactory.create_batch( len(courses), program_page=page, course=Iterator(courses) ) browser.get("/a-program-title/") faculty_elements = browser.driver.find_elements_by_css_selector(".faculty-tile") assert len(faculty) == len(faculty_elements) info_elements = browser.driver.find_elements_by_css_selector(".program-contact-link") assert len(info_links) == len(info_elements) semester_elements = browser.driver.find_elements_by_css_selector(".semester-date") assert len(semester_dates) == len(semester_elements) program_course_elements = browser.driver.find_elements_by_css_selector(".program-course .title") assert len(program_courses) == len(program_course_elements)
def test_custom_detail_page_urls(): """Verify that course/external-course/program detail pages return our custom URL path""" readable_id = "some:readable-id" external_readable_id = "some:external-readable-id" program_pages = ProgramPageFactory.create_batch( 2, program__readable_id=factory.Iterator([readable_id, "non-matching-id"])) external_program_pages = ExternalProgramPageFactory.create_batch( 2, readable_id=factory.Iterator([readable_id, "non-matching-external-id"])) course_pages = CoursePageFactory.create_batch( 2, course__readable_id=factory.Iterator([readable_id, "non-matching-id"])) external_course_pages = ExternalCoursePageFactory.create_batch( 2, readable_id=factory.Iterator( [external_readable_id, "non-matching-external-id"]), ) assert program_pages[0].get_url() == "/programs/{}/".format(readable_id) assert external_program_pages[0].get_url() == "/programs/{}/".format( readable_id) assert course_pages[0].get_url() == "/courses/{}/".format(readable_id) assert external_course_pages[0].get_url() == "/courses/{}/".format( external_readable_id)
def test_program_page_serializer(self): """ Test program page serializer """ page = ProgramPageFactory.create() courses = CourseFactory.create_batch(6, program=page.program) faculty = FacultyFactory.create_batch(3, program_page=page) elective_set = ElectivesSet.objects.create(program=page.program, required_number=2, title="Elective") # Add 3 courses to elective set - For required 2 of 3 scenario for elective_course in courses[:3]: ElectiveCourse.objects.create(electives_set=elective_set, course=elective_course) data = ProgramPageSerializer(page).data data['faculty'] = sorted(data['faculty'], key=lambda member: member['name']) assert data == { "id": page.program.id, "title": page.title, "slug": ProgramPageSerializer().get_slug(page), "faculty": FacultySerializer(sorted(faculty, key=lambda member: member.name), many=True).data, # Only core courses (Not associated with electives) "courses": CourseSerializer(courses[3:], many=True).data, "electives_sets": ElectivesSetSerializer([elective_set], many=True).data, }
def test_program_page(browser, base_test_data, logged_in_student): """ Test viewing the program page """ courses = list(base_test_data.program.course_set.all()) + \ CourseFactory.create_batch(2, program=base_test_data.program) page = ProgramPageFactory.create(program=base_test_data.program, title="A Program Title") faculty = FacultyFactory.create_batch(3, program_page=page) info_links = InfoLinksFactory.create_batch(3, program_page=page) semester_dates = SemesterDateFactory.create_batch(3, program_page=page) program_courses = ProgramCourseFactory.create_batch( len(courses), program_page=page, course=Iterator(courses)) browser.get("/a-program-title/") faculty_elements = browser.driver.find_elements_by_css_selector( ".faculty-tile") assert len(faculty) == len(faculty_elements) info_elements = browser.driver.find_elements_by_css_selector( ".program-contact-link") assert len(info_links) == len(info_elements) semester_elements = browser.driver.find_elements_by_css_selector( ".semester-date") assert len(semester_dates) == len(semester_elements) program_course_elements = browser.driver.find_elements_by_css_selector( ".program-course .title") assert len(program_courses) == len(program_course_elements)
def test_is_course_page(): """Returns True if object is type of CoursePage""" program_page = ProgramPageFactory.create() course_page = CoursePageFactory.create() assert not program_page.is_course_page assert course_page.is_course_page
def test_catalog_program_serializer(has_page, has_thumbnail): """Tests that the catalog serializer returns a correct data structure""" page = ProgramPageFactory.create( has_thumbnail=has_thumbnail) if has_page else None program = page.program if page else ProgramFactory.create() courses = CourseFactory.create_batch(3, program=program) for course in courses: CourseRunFactory.create_batch(2, course=course) faculty_name = "faculty" if has_page: ProgramFaculty.objects.create( program_page=page, name=faculty_name, ) serialized = CatalogProgramSerializer(program).data # coerce OrderedDict objects to dict serialized = { **serialized, "courses": [{ **course, "course_runs": [dict(run) for run in course["course_runs"]] } for course in serialized["courses"]] } assert serialized == { "id": program.id, "title": program.title, "programpage_url": page.get_full_url() if has_page else None, "thumbnail_url": (page.thumbnail_image.get_rendition('fill-300x186').url if has_page and has_thumbnail else None), "courses": [{ "id": course.id, "edx_key": course.edx_key, "position_in_program": course.position_in_program, "course_runs": [{ "id": course_run.id, "edx_course_key": course_run.edx_course_key, } for course_run in course.courserun_set.all()] } for course in courses], 'topics': [{ 'name': topic.name } for topic in program.topics.iterator()], "instructors": [{ "name": faculty_name }] if has_page else [], "start_date": courses[0].first_unexpired_run().start_date, "enrollment_start": courses[0].first_unexpired_run().enrollment_start, "end_date": courses[-1].courserun_set.last().end_date, "total_price": str(program.price * program.num_required_courses), }
def test_program_page(): """ page property should return an associated Wagtail page if one exists """ program = ProgramFactory.create(page=None) assert program.page is None page = ProgramPageFactory.create(program=program) assert program.page == page
def test_course_page_program_page(): """ Verify `program_page` property from the course page returns expected value """ program_page = ProgramPageFactory.create() course_page = CoursePageFactory.create( course__program=program_page.program) assert course_page.program_page == program_page
def test_program_page_course_pages(): """ Verify `course_pages` property from the program page returns expected value """ program_page = ProgramPageFactory.create() assert list(program_page.course_pages) == [] course_page = CoursePageFactory.create( course__program=program_page.program) assert list(program_page.course_pages) == [course_page]
def test_program_page_faq_property(): """ Faqs property should return list of faqs related to given ProgramPage""" program_page = ProgramPageFactory.create() assert FrequentlyAskedQuestionPage.can_create_at(program_page) faqs_page = FrequentlyAskedQuestionPageFactory.create(parent=program_page) faq = FrequentlyAskedQuestionFactory.create(faqs_page=faqs_page) assert faqs_page.get_parent() is program_page assert list(program_page.faqs) == [faq]
def test_program_page_faculty_subpage(): """ FacultyMembersPage should return expected values if associated with ProgramPage """ program_page = ProgramPageFactory.create() assert not program_page.faculty FacultyMembersPageFactory.create(parent=program_page, members=json.dumps( _get_faculty_members())) _assert_faculty_members(program_page)
def test_program_page_course_lineup(): """ course_lineup property should return expected values if associated with a ProgramPage """ program_page = ProgramPageFactory.create() assert CoursesInProgramPage.can_create_at(program_page) courses_page = CoursesInProgramPageFactory.create(parent=program_page, heading="heading", body="<p>body</p>") assert program_page.course_lineup == courses_page assert courses_page.heading == "heading" assert courses_page.body == "<p>body</p>"
def test_program_page_checkout_url_product(client, wagtail_basics): """ The checkout URL in the program page context should include the product ID if a product exists for the given program """ program_page = ProgramPageFactory.create() program_page.save_revision().publish() product_version = ProductVersionFactory.create( product__content_object=program_page.program ) resp = client.get(program_page.get_url()) checkout_url = resp.context["checkout_url"] assert f"product={product_version.product.id}" in checkout_url
def test_program_page_propel_career(): """ The propel_career property should return expected values if associated with a ProgramPage """ program_page = ProgramPageFactory.create() propel_career_page = TextSectionFactory.create( parent=program_page, content="<p>content</p>", dark_theme=True, action_title="Action Title", ) assert program_page.propel_career == propel_career_page assert propel_career_page.action_title == "Action Title" assert propel_career_page.content == "<p>content</p>" assert propel_career_page.dark_theme
def test_program_certificate_invalid_view(user_client, user, wagtail_basics): """ Test that program certificate page returns a 404 if CertificatePage does not exist for that program """ home = HomePageFactory.create(parent=wagtail_basics.root, slug="home") home.save_revision().publish() program_page = ProgramPageFactory.create(parent=home, certificate_page=None) program_page.save_revision().publish() program_certificate = ProgramCertificateFactory.create( user=user, program=program_page.program ) resp = user_client.get(program_certificate.link) assert resp.status_code == status.HTTP_404_NOT_FOUND
def test_program_with_programpage(self): """ Test ProgramSerializer with a program page attached """ programpage = ProgramPageFactory.build(program=self.program) homepage = HomePage.objects.first() homepage.add_child(instance=programpage) data = ProgramSerializer(self.program, context=self.context).data assert data == { 'id': self.program.id, 'title': self.program.title, 'programpage_url': programpage.url, 'enrolled': False, 'total_courses': 0, } assert len(programpage.url) > 0
def test_basket_thumbnail_program(basket_and_coupons, mock_context): """Basket thumbnail should be serialized for a program""" thumbnail_filename = "abcde.jpg" program_page = ProgramPageFactory.create( thumbnail_image__file__filename=thumbnail_filename ) program = program_page.program product_version = ProductVersionFactory.create(product__content_object=program) data = FullProductVersionSerializer( instance=product_version, context=mock_context ).data assert ( data["thumbnail_url"] == program_page.thumbnail_image.get_rendition( CATALOG_COURSE_IMG_WAGTAIL_FILL ).url )
def test_program_page_serializer(self): """ Test program page serializer """ page = ProgramPageFactory.create() courses = CourseFactory.create_batch(3, program=page.program) faculty = FacultyFactory.create_batch(3, program_page=page) data = ProgramPageSerializer(page).data data['faculty'] = sorted(data['faculty'], key=lambda member: member['name']) assert data == { "id": page.program.id, "title": page.title, "slug": ProgramPageSerializer().get_slug(page), "faculty": FacultySerializer(sorted(faculty, key=lambda member: member.name), many=True).data, "courses": CourseSerializer(courses, many=True).data, }
def test_program_certificate_view(user_client, user, wagtail_basics): """ Test that certificate page show correctly """ home = HomePageFactory.create(parent=wagtail_basics.root, slug="home") home.save_revision().publish() program_page = ProgramPageFactory.create(parent=home) program_page.save_revision().publish() program_certificate = ProgramCertificateFactory.create( user=user, program=program_page.program ) resp = user_client.get(program_certificate.link) assert resp.status_code == status.HTTP_200_OK assert resp.context_data["page"] == program_page.certificate_page assert resp.context_data["page"].certificate == program_certificate
def test_program_page_child_page_url(): """ The live URL of child pages should be of the correct format: <site_root>/programs/<program__readable_id>/<child_page__slug> """ program_page = ProgramPageFactory.create( program__readable_id="program:test") child_page = TextSectionFactory.create(parent=program_page) program_page_url = program_page.get_full_url() child_page_url = child_page.get_full_url() if WAGTAIL_APPEND_SLASH: assert child_page_url == "{}{}/".format(program_page_url, child_page.slug) else: assert child_page_url == "{}/{}".format(program_page_url, child_page.slug)
def test_program_page_for_teams(): """ The ForTeams property should return expected values if associated with a ProgramPage """ program_page = ProgramPageFactory.create() assert ForTeamsPage.can_create_at(program_page) teams_page = ForTeamsPageFactory.create( parent=program_page, content="<p>content</p>", switch_layout=True, dark_theme=True, action_title="Action Title", ) assert program_page.for_teams == teams_page assert teams_page.action_title == "Action Title" assert teams_page.content == "<p>content</p>" assert teams_page.switch_layout assert teams_page.dark_theme assert not ForTeamsPage.can_create_at(program_page)
def test_program_page_for_program_run(client): """ Test that prgram page URL works with program run id """ program_page = ProgramPageFactory.create() program_page.save_revision().publish() program_run = ProgramRunFactory.create( program=program_page.program, run_tag="R1", start_date=(now_in_utc() + timedelta(days=10)), ) page_base_url = program_page.get_url().rstrip("/") good_url = "{}+{}/".format(page_base_url, program_run.run_tag) resp = client.get(good_url) assert resp.status_code == 200 bad_url = "{}+R2/".format(page_base_url) resp = client.get(bad_url) assert resp.status_code == 404
def test_program_course_order(): """ The course pages in program page should be ordered on the basis of position_in_program """ program_page = ProgramPageFactory.create() course_pages = CoursePageFactory.create_batch( 3, course__position_in_program=factory.Iterator([2, 3, 1]), course__program=program_page.program, ) single_course_page = course_pages[0] assert [ course_page.course.position_in_program for course_page in single_course_page.course_pages ] == [1, 2, 3] assert [ course_page.course.position_in_program for course_page in program_page.course_pages ] == [1, 2, 3]
def test_program_page_learning_techniques(): """ ProgramPage related subpages should return expected values if they exist ProgramPage related LearningTechniquesPage should return expected values if it exists """ program_page = ProgramPageFactory.create(description="<p>desc</p>", duration="1 week") assert LearningTechniquesPage.can_create_at(program_page) learning_techniques_page = LearningTechniquesPageFactory( parent=program_page, technique_items__0__techniques__heading="heading", technique_items__0__techniques__sub_heading="sub_heading", technique_items__0__techniques__image__title="image-title", ) assert learning_techniques_page.get_parent() == program_page for (technique) in learning_techniques_page.technique_items: # pylint: disable=not-an-iterable assert technique.value.get("heading") == "heading" assert technique.value.get("sub_heading") == "sub_heading" assert technique.value.get("image").title == "image-title"
def test_program_page_properties(): """ Wagtail-page-related properties should return expected values if the Wagtail page exists """ program_page = ProgramPageFactory.create( title="<p>page title</p>", subhead="subhead", description="<p>desc</p>", catalog_details="<p>catalog desc</p>", duration="1 week", video_title="<p>title</p>", video_url="http://test.com/mock.mp4", background_image__title="background-image", ) assert program_page.title == "<p>page title</p>" assert program_page.subhead == "subhead" assert program_page.description == "<p>desc</p>" assert program_page.catalog_details == "<p>catalog desc</p>" assert program_page.duration == "1 week" assert program_page.video_title == "<p>title</p>" assert program_page.video_url == "http://test.com/mock.mp4" assert program_page.background_image.title == "background-image"
def test_program_page_checkout_url_program_run(client, wagtail_basics): """ The checkout URL in the program page context should include the program run text ID if a program run exists """ program_page = ProgramPageFactory.create() program_page.save_revision().publish() program_run = ProgramRunFactory.create( program=program_page.program, start_date=(now_in_utc() - timedelta(days=1)) ) resp = client.get(program_page.get_url()) checkout_url = resp.context["checkout_url"] assert checkout_url is None program_run.start_date = now_in_utc() + timedelta(days=1) program_run.save() # If multiple future program runs exist, the one with the earliest start date should be used ProgramRunFactory.create( program=program_page.program, start_date=(program_run.start_date + timedelta(days=1)), ) resp = client.get(program_page.get_url()) checkout_url = resp.context["checkout_url"] assert f"product={program_run.full_readable_id}" in checkout_url
def test_program_page_testimonials(): """ testimonials property should return expected value if associated with a ProgramPage """ program_page = ProgramPageFactory.create() assert UserTestimonialsPage.can_create_at(program_page) testimonials_page = UserTestimonialsPageFactory.create( parent=program_page, heading="heading", subhead="subhead", items__0__testimonial__name="name", items__0__testimonial__title="title", items__0__testimonial__image__title="image", items__0__testimonial__quote="quote", ) assert program_page.testimonials == testimonials_page assert testimonials_page.heading == "heading" assert testimonials_page.subhead == "subhead" for testimonial in testimonials_page.items: # pylint: disable=not-an-iterable assert testimonial.value.get("name") == "name" assert testimonial.value.get("title") == "title" assert testimonial.value.get("image").title == "image" assert testimonial.value.get("quote") == "quote"
def test_program_page_who_should_enroll(): """ ProgramPage related WhoShouldEnrollPage should return expected values if it exists """ program_page = ProgramPageFactory.create() assert WhoShouldEnrollPage.can_create_at(program_page) who_should_enroll_page = WhoShouldEnrollPageFactory.create( parent=program_page, content=json.dumps([ { "type": "item", "value": "<p>item</p>" }, { "type": "item", "value": "<p>item</p>" }, ]), ) assert who_should_enroll_page.get_parent() == program_page assert len(who_should_enroll_page.content) == 2 for block in who_should_enroll_page.content: # pylint: disable=not-an-iterable assert block.block_type == "item" assert block.value.source == "<p>item</p>" assert program_page.who_should_enroll == who_should_enroll_page assert not WhoShouldEnrollPage.can_create_at(program_page) # default page hedding assert who_should_enroll_page.heading == "Who Should Enroll" # test that it can be modified new_heading = "New heading of the page" who_should_enroll_page.heading = new_heading who_should_enroll_page.save() assert who_should_enroll_page.heading == new_heading
def test_program_learning_outcomes(): """ ProgramPage related LearningOutcomesPage should return expected values if it exists """ program_page = ProgramPageFactory.create() assert LearningOutcomesPage.can_create_at(program_page) learning_outcomes_page = LearningOutcomesPageFactory( parent=program_page, heading="heading", sub_heading="subheading", outcome_items=json.dumps([{ "type": "outcome", "value": "benefit" }]), ) assert learning_outcomes_page.get_parent() == program_page assert learning_outcomes_page.heading == "heading" for (block) in learning_outcomes_page.outcome_items: # pylint: disable=not-an-iterable assert block.block_type == "outcome" assert block.value == "benefit" assert program_page.outcomes == learning_outcomes_page assert not LearningOutcomesPage.can_create_at(program_page)