def test_templates_course_detail_cms_published_content(self): """ Validate that the important elements are displayed on a published course page """ categories = CategoryFactory.create_batch(4) icons = CategoryFactory.create_batch(4, fill_icon=True) organizations = OrganizationFactory.create_batch(4) course = CourseFactory( page_title="Very interesting course", fill_organizations=organizations, fill_categories=categories, fill_icons=icons, ) page = course.extended_object # Create an ongoing open course run that will be published (created before # publishing the page) now = timezone.now() CourseRunFactory( direct_course=course, start=now - timedelta(hours=1), end=now + timedelta(hours=2), enrollment_end=now + timedelta(hours=1), languages=["en", "fr"], ) program_published, program_unpublished = ProgramFactory.create_batch( 2, fill_courses=[course], should_publish=True) program_unpublished.extended_object.unpublish("en") # Publish only 2 out of 4 categories, icons and organizations self.assertTrue(categories[0].extended_object.publish("en")) self.assertTrue(categories[1].extended_object.publish("en")) self.assertTrue(icons[0].extended_object.publish("en")) self.assertTrue(icons[1].extended_object.publish("en")) self.assertTrue(organizations[0].extended_object.publish("en")) self.assertTrue(organizations[1].extended_object.publish("en")) # The unpublished objects may have been published and unpublished which puts them in a # status different from objects that have never been published. # We want to test both cases. self.assertTrue(categories[2].extended_object.publish("en")) self.assertTrue(categories[2].extended_object.unpublish("en")) self.assertTrue(icons[2].extended_object.publish("en")) self.assertTrue(icons[2].extended_object.unpublish("en")) self.assertTrue(organizations[2].extended_object.publish("en")) self.assertTrue(organizations[2].extended_object.unpublish("en")) # The page should not be visible before it is published url = page.get_absolute_url() response = self.client.get(url) self.assertEqual(response.status_code, 404) # Publish and ensure content is correct self.assertTrue(page.publish("en")) # Create an unpublished ongoing open course run (created after # publishing the page) CourseRunFactory( direct_course=course, start=now - timedelta(hours=1), end=now + timedelta(hours=2), enrollment_end=now + timedelta(hours=1), languages=["en", "fr"], ) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertContains(response, "<title>Very interesting course</title>", html=True) self.assertContains( response, f'<div class="subheader__code">Ref. {course.code:s}</div>', html=True, ) self.assertContains( response, '<h1 class="subheader__title">Very interesting course</h1>', html=True, ) # Only published categories should be present on the page for category in categories[:2]: self.assertContains( response, ('<a class="category-badge" href="{:s}">' '<span class="category-badge__title">{:s}</span></a>').format( category.extended_object.get_absolute_url(), category.extended_object.get_title(), ), html=True, ) for category in categories[-2:]: self.assertNotContains(response, category.extended_object.get_title()) # Only published icons should be present on the page pattern = ( r'<a.*class="category-badge".*href="{link:s}".*>' r'<img src="/media/filer_public_thumbnails/filer_public/.*icon\.jpg.*alt="{title:s}">' r'<span class="category-badge__title">' r".*{title:s}.*</span>") for icon in icons[:2]: self.assertIsNotNone( re.search( pattern.format( link=icon.extended_object.get_absolute_url(), title=icon.extended_object.get_title(), ), str(response.content), )) for icon in icons[-2:]: self.assertNotContains(response, icon.extended_object.get_title()) # Public organizations should be in response content for organization in organizations[:2]: self.assertContains( response, '<div class="organization-glimpse__title">{title:s}</div>'. format(title=organization.extended_object.get_title()), html=True, ) # Draft organizations should not be in response content for organization in organizations[-2:]: self.assertNotContains(response, organization.extended_object.get_title(), html=True) # Only the published course run should be in response content self.assertEqual(CourseRun.objects.count(), 3) self.assertContains(response, "<dd>English and french</dd>", html=True, count=1) # Only the published program should be in response content self.assertContains(response, "course-detail__programs") self.assertContains(response, "This course is part of a program") self.assertContains(response, program_published.extended_object.get_title(), html=True, count=1) self.assertNotContains(response, program_unpublished.extended_object.get_title())
def test_templates_course_detail_cms_draft_content(self): """ A staff user should see a draft course including only the related objects that are published. """ user = UserFactory(is_staff=True, is_superuser=True) self.client.login(username=user.username, password="******") categories = CategoryFactory.create_batch(4) organizations = OrganizationFactory.create_batch(2) published_organizations = OrganizationFactory.create_batch(2) course = CourseFactory( page_title="Very interesting course", fill_organizations=organizations + published_organizations, fill_categories=categories, ) page = course.extended_object now = timezone.now() CourseRunFactory( direct_course=course, start=now - timedelta(hours=1), end=now + timedelta(hours=2), enrollment_end=now + timedelta(hours=1), languages=["en", "fr"], ) program_published, program_unpublished = ProgramFactory.create_batch( 2, fill_courses=[course], should_publish=True) program_unpublished.extended_object.unpublish("en") # Publish only 2 out of 4 categories and 2 out of 4 organizations self.assertTrue(categories[0].extended_object.publish("en")) self.assertTrue(categories[1].extended_object.publish("en")) self.assertTrue( published_organizations[0].extended_object.publish("en")) self.assertTrue( published_organizations[1].extended_object.publish("en")) # The unpublished objects may have been published and unpublished which puts them in a # status different from objects that have never been published. # We want to test both cases. self.assertTrue(categories[2].extended_object.publish("en")) self.assertTrue(categories[2].extended_object.unpublish("en")) self.assertTrue(organizations[0].extended_object.publish("en")) self.assertTrue(organizations[0].extended_object.unpublish("en")) # The page should be visible as draft to the staff user url = page.get_absolute_url() response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertContains(response, "<title>Very interesting course</title>", html=True) self.assertContains( response, '<h1 class="subheader__title">Very interesting course</h1>', html=True, ) self.assertContains( response, f'<div class="subheader__code">Ref. {course.code:s}</div>', html=True, ) # only public organizations should be present on the page for organization in organizations: self.assertNotContains(response, organization.extended_object.get_title()) for organization in published_organizations: self.assertContains( response, '<div class="organization-glimpse__title">{title:s}</div>'. format(title=organization.extended_object.get_title()), html=True, ) # The published categories should be present on the page for category in categories[:2]: self.assertContains( response, ('<a class="category-badge" href="{:s}">' '<span class="category-badge__title">{:s}</span></a>').format( category.extended_object.get_absolute_url(), category.extended_object.get_title(), ), html=True, ) # Draft categories should not be present on the page for category in categories[-2:]: self.assertNotContains( response, category.extended_object.get_title(), html=True, ) # The course run should be in the page self.assertContains(response, "<dd>English and french</dd>", html=True, count=1) # Both programs should be in response content self.assertContains(response, "course-detail__programs") self.assertContains(response, "This course is part of programs") self.assertContains(response, program_published.extended_object.get_title(), html=True, count=1) self.assertContains( response, program_unpublished.extended_object.get_title(), html=True, count=1, )