def test_views_bootstrap_elasticsearch_with_permission(self, mock_command):
        """Confirm triggering the search index bootstrapping works as expected."""
        user = UserFactory(is_staff=True)
        self.client.login(username=user.username, password="******")

        # Add the necessary permission
        self.add_permission(user, "can_manage_elasticsearch")

        url = "/api/v1.0/bootstrap-elasticsearch/"
        response = self.client.post(url, follow=True)
        self.assertEqual(response.status_code, 200)
        content = json.loads(response.content)
        self.assertEqual(content, {})

        # Check the presence of a confirmation message
        messages = list(get_messages(response.wsgi_request))
        self.assertEqual(len(messages), 1)
        self.assertEqual(str(messages[0]),
                         "The search index was successfully bootstrapped")

        mock_command.assert_called_once_with("bootstrap_elasticsearch")
    def test_cms_wizards_person_create_wizards_list(self):
        """
        The wizard to create a new person page should be present on the wizards list page
        """
        user = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=user.username, password="******")

        # Let the authorized user get the page with all wizards listed
        url = reverse("cms_wizard_create")
        response = self.client.get(url)

        # Check that our wizard to create persons is on this page
        self.assertContains(
            response,
            '<span class="info">Create a new person page</span>',
            status_code=200,
            html=True,
        )
        self.assertContains(response,
                            "<strong>New person page</strong>",
                            html=True)
Esempio n. 3
0
    def test_cms_wizards_course_run_create_wizards_list_superuser_snapshot(
            self, *_):
        """
        The wizard to create a new course run page should not be present on the wizards list
        page for a superuser visiting a course snapshot page.
        """
        snapshot = CourseFactory()
        CourseFactory(page_parent=snapshot.extended_object)
        user = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=user.username, password="******")

        # Let the authorized user get the page with all wizards listed
        url = "{:s}?page={:d}".format(reverse("cms_wizard_create"),
                                      snapshot.extended_object.id)
        response = self.client.get(url)

        # Check that our wizard to create course runs is not on this page
        self.assertNotContains(response,
                               "new course run",
                               status_code=200,
                               html=True)
    def test_templates_course_detail_organization_main_logo(self):
        """The main organization logo should be present on the page with a link."""
        user = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=user.username, password="******")

        organizations = OrganizationFactory.create_batch(2,
                                                         fill_logo=True,
                                                         should_publish=True)
        course = CourseFactory(fill_organizations=organizations)

        response = self.client.get(course.extended_object.get_absolute_url())

        self.assertEqual(response.status_code, 200)
        pattern = (
            r'<a href="{url:s}" title="{title:s}" class="course-detail__aside__main-org-logo">'
            r'<img src="/media/filer_public_thumbnails/filer_public/.*logo\.jpg__200x113'
        ).format(
            url=organizations[0].extended_object.get_absolute_url(),
            title=organizations[0].extended_object.get_title(),
        )
        self.assertIsNotNone(re.search(pattern, str(response.content)))
Esempio n. 5
0
    def test_templates_person_detail_maincontent_empty(self):
        """
        The "maincontent" placeholder block should not be displayed on the public
        page when empty but only on the draft version for staff.
        """
        person = PersonFactory(should_publish=True)

        # The "organizations" section should not be present on the public page
        url = person.public_extension.extended_object.get_absolute_url()
        response = self.client.get(url)
        self.assertContains(response, person.extended_object.get_title())
        self.assertNotContains(response, "person-detail__maincontent")

        # But it should be present on the draft page
        user = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=user.username, password="******")

        url = person.extended_object.get_absolute_url()
        response = self.client.get(url)
        self.assertContains(response, person.extended_object.get_title())
        self.assertContains(response, "person-detail__maincontent")
Esempio n. 6
0
    def test_cms_wizards_course_run_language_active(self, *_):
        """
        The language should be set to the active language.
        """
        course = CourseFactory()

        # Submit a valid form
        user = UserFactory(is_staff=True, is_superuser=True)
        form = CourseRunWizardForm(
            data={"title": "My title"},
            wizard_language="en",
            wizard_user=user,
            wizard_page=course.extended_object,
        )

        self.assertTrue(form.is_valid())
        with translation.override("fr"):
            page = form.save()

        # The language field should have been set to the active language
        self.assertEqual(page.courserun.languages, ["fr"])
    def test_cms_wizards_category_create_wizards_list_superuser(self):
        """
        The wizard to create a new category page should be present on the wizards list page
        for a superuser.
        """
        page = create_page("page", "richie/single_column.html", "en")
        user = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=user.username, password="******")

        # Let the authorized user get the page with all wizards listed
        url = "{:s}?page={:d}".format(reverse("cms_wizard_create"), page.id)
        response = self.client.get(url)

        # Check that our wizard to create categories is on this page
        self.assertContains(
            response,
            '<span class="info">Create a new category page</span>',
            status_code=200,
            html=True,
        )
        self.assertContains(response, "<strong>New category page</strong>", html=True)
    def test_cms_wizards_category_submit_form_invalid_slug(self):
        """Trying to submit a slug that is not valid should raise a 400 exception."""
        # A parent page should pre-exist
        parent_page = create_page(
            "Categories",
            "richie/single_column.html",
            "en",
            reverse_id=Category.PAGE["reverse_id"],
        )

        # Submit an invalid slug
        data = {"title": "my title", "slug": "invalid slug"}

        user = UserFactory(is_superuser=True, is_staff=True)
        form = CategoryWizardForm(data=data, wizard_language="en", wizard_user=user)
        form.page = parent_page
        self.assertFalse(form.is_valid())
        self.assertEqual(
            form.errors["slug"][0],
            "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens.",
        )
    def test_cms_wizards_category_submit_form_max_lengths(self):
        """
        Check that the form correctly raises an error when the slug is too long. The path built
        by combining the slug of the page with the slug of its parent page, should not exceed
        255 characters in length.
        """
        # A parent page with a very long slug
        page = create_page(
            "y" * 200,
            "richie/single_column.html",
            "en",
            reverse_id=Category.PAGE["reverse_id"],
        )

        # A category with a slug at the limit length should work
        user = UserFactory(is_staff=True, is_superuser=True)
        form = CategoryWizardForm(
            data={"title": "t" * 255, "slug": "s" * 54},
            wizard_language="en",
            wizard_user=user,
            wizard_page=page,
        )
        self.assertTrue(form.is_valid())
        form.save()

        # A category with a slug too long with regards to the parent's one should raise an error
        form = CategoryWizardForm(
            data={"title": "t" * 255, "slug": "s" * 55},
            wizard_language="en",
            wizard_user=user,
            wizard_page=page,
        )
        self.assertFalse(form.is_valid())
        self.assertEqual(
            form.errors["slug"][0],
            (
                "This slug is too long. The length of the path built by prepending the slug of "
                "the parent page would be 256 characters long and it should be less than 255"
            ),
        )
    def test_cms_plugins_organization_render_instance_variant(self):
        """
        The organization plugin should render according to the variant plugin
        option.
        """
        staff = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=staff.username, password="******")

        # Create an Organization
        organization = OrganizationFactory(page_title="public title")
        organization_page = organization.extended_object

        # Create a page to add the plugin to
        page = create_i18n_page("A page")
        placeholder = page.placeholders.get(slot="maincontent")

        # Add organization plugin with default variant
        add_plugin(placeholder,
                   OrganizationPlugin,
                   "en",
                   page=organization_page)

        url = "{:s}?edit".format(page.get_absolute_url(language="en"))

        # The organization-glimpse default variant should not have the small attribute
        response = self.client.get(url)
        self.assertNotContains(response, "--small")

        # Add organization plugin with small variant
        add_plugin(
            placeholder,
            OrganizationPlugin,
            "en",
            page=organization_page,
            variant="small",
        )

        # The new organization-glimpse should have the small attribute
        response = self.client.get(url)
        self.assertContains(response, "organization-small")
Esempio n. 11
0
    def test_admin_form_course_run_choices_staff_permissions(self):
        """
        Staff users should only see course pages on which they have change permission.
        Unless CMS permissions are not activated.
        """
        course1 = CourseFactory(page_title="Title 1", should_publish=True)
        course2 = CourseFactory(page_title="Title 2", should_publish=True)
        course3 = CourseFactory(page_title="Title 3", should_publish=True)
        user = UserFactory(is_staff=True)

        # Add permission only for courses 2 and 3
        self.add_permission(user, "change_page")
        for course in [course2, course3]:
            PagePermission.objects.create(
                page=course.extended_object,
                user=user,
                can_add=False,
                can_change=True,
                can_delete=False,
                can_publish=False,
                can_move_page=False,
            )

        # The user should only see the 2 courses on which he has permissions
        form = self._get_admin_form(course2, user)
        self.assertEqual(len(form.fields["direct_course"].choices), 3)
        html = form.as_ul()
        self.assertIn('<option value="">---------</option>', html)
        self.assertNotIn("Title 1", html)
        self.assertIn(
            f'<option value="{course2.id:d}" selected>Title 2</option>', html)
        self.assertIn(f'<option value="{course3.id:d}">Title 3</option>', html)

        # Unless CMS permissions are not activated
        with override_settings(CMS_PERMISSION=False):
            form = self._get_admin_form(course2, user)

        self.assertEqual(len(form.fields["direct_course"].choices), 4)
        self.assertIn(f'<option value="{course1.id:d}">Title 1</option>',
                      form.as_ul())
    def test_templates_course_detail_placeholder(self):
        """
        Draft editing course page should contain all key placeholders when empty.
        """
        user = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=user.username, password="******")

        course = CourseFactory(page_title="Very interesting course")
        page = course.extended_object
        url = "{:s}?edit".format(page.get_absolute_url(language="en"))
        response = self.client.get(url)

        pattern = (
            r'<div class="course-detail__row course-detail__introduction">'
            r'<div class="cms-placeholder')
        self.assertIsNotNone(re.search(pattern, str(response.content)))
        pattern = (r'<div class="category-badge-list__container">'
                   r'<div class="cms-placeholder')
        self.assertIsNotNone(re.search(pattern, str(response.content)))
        pattern = r'<div class="subheader__teaser"><div class="cms-placeholder'
        self.assertIsNotNone(re.search(pattern, str(response.content)))
        pattern = (
            r'<div class="subheader__content subheader__content--aside">'
            r'<div class="cms-placeholder')
        self.assertIsNotNone(re.search(pattern, str(response.content)))
        pattern = (
            r'<div class="section__items section__items--organizations">'
            r'<div class="cms-placeholder')
        self.assertIsNotNone(re.search(pattern, str(response.content)))
        pattern = (r'<div class="section__items section__items--team">'
                   r'<div class="cms-placeholder')
        self.assertIsNotNone(re.search(pattern, str(response.content)))
        pattern = (
            r'<div class="course-detail__row course-detail__information">'
            r'<div class="cms-placeholder')
        self.assertIsNotNone(re.search(pattern, str(response.content)))
        pattern = (
            r'<h3 class="course-detail__label">'
            r'License for the course content</h3><div class="cms-placeholder')
        self.assertIsNotNone(re.search(pattern, str(response.content)))
Esempio n. 13
0
    def test_cms_wizards_blogpost_submit_form(self):
        """
        A user with the required permissions submitting a valid BlogPostWizardForm should be able
        to create a BlogPost page extension and its related page.
        """
        any_page = create_page("Any page", "richie/single_column.html", "en")

        # A parent page should pre-exist
        create_page(
            "News",
            "richie/single_column.html",
            "en",
            reverse_id=BlogPost.PAGE["reverse_id"],
        )

        # Create a user with just the required permissions
        user = UserFactory(
            is_staff=True,
            permissions=["courses.add_blogpost", "cms.add_page", "cms.change_page"],
        )

        # We can submit a form with just the title set
        form = BlogPostWizardForm(
            data={"title": "My title"},
            wizard_language="en",
            wizard_user=user,
            wizard_page=any_page,
        )
        self.assertTrue(form.is_valid())
        blog_page = form.save()

        # Related page should have been created as draft
        Page.objects.drafts().get(id=blog_page.id)
        BlogPost.objects.get(id=blog_page.blogpost.id, extended_object=blog_page)

        self.assertEqual(blog_page.get_title(), "My title")
        # The slug should have been automatically set
        self.assertEqual(blog_page.get_slug(), "my-title")
        # The page should be in navigation to appear in the breadcrumb
        self.assertTrue(blog_page.in_navigation)
Esempio n. 14
0
    def test_templates_category_list_cms_content(self):
        """
        Validate that the public website only displays categories that are currently published,
        while staff users can see draft and unpublished categories.
        """
        page = PageFactory(
            template="courses/cms/category_list.html",
            title__language="en",
            should_publish=True,
        )

        CategoryFactory(page_parent=page, page_title="First category")
        CategoryFactory(page_parent=page,
                        page_title="Second category",
                        should_publish=True)

        # Publish with a publication date in the future
        future = timezone.now() + timedelta(hours=1)
        with mock.patch("cms.models.pagemodel.now", return_value=future):
            CategoryFactory(page_parent=page,
                            page_title="Third category",
                            should_publish=True)

        # Anonymous users should only see published categories
        response = self.client.get(page.get_absolute_url())

        self.assertEqual(response.status_code, 200)
        self.assertNotContains(response, "First")
        self.assertContains(response, "Second")
        self.assertNotContains(response, "Third")

        # Staff users can see draft and unpublished categories
        user = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=user.username, password="******")

        response = self.client.get(page.get_absolute_url())
        self.assertEqual(response.status_code, 200)

        for title in ["First", "Second", "Third"]:
            self.assertContains(response, title)
Esempio n. 15
0
    def test_cms_wizards_blogpost_submit_form_insufficient_permission(self):
        """
        A user with insufficient permissions trying to submit a BlogPostWizardForm should trigger
        a PermissionDenied exception.
        We make loop to remove each time only one permission from the set of required permissions
        and check that they are all required.
        """
        any_page = create_page("Any page", "richie/single_column.html", "en")

        # A parent page should pre-exist
        create_page(
            "News",
            "richie/single_column.html",
            "en",
            reverse_id=BlogPost.PAGE["reverse_id"],
        )

        required_permissions = ["courses.add_blogpost"]

        for is_staff in [True, False]:
            for permission_to_be_removed in required_permissions + [None]:
                if is_staff is True and permission_to_be_removed is None:
                    # This is the case of sufficient permissions treated in the next test
                    continue

                altered_permissions = required_permissions.copy()
                if permission_to_be_removed:
                    altered_permissions.remove(permission_to_be_removed)

                user = UserFactory(is_staff=is_staff, permissions=altered_permissions)

                form = BlogPostWizardForm(
                    data={"title": "My title"},
                    wizard_language="en",
                    wizard_user=user,
                    wizard_page=any_page,
                )

                with self.assertRaises(PermissionDenied):
                    form.is_valid()
Esempio n. 16
0
    def test_admin_person_list_view(self):
        """
        The admin list view of persons should display page title, person's title
        first_name and last_name
        """
        user = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=user.username, password="******")

        # Create a person linked to a page
        person = PersonFactory()

        # Get the admin list view
        url = reverse("admin:persons_person_changelist")
        response = self.client.get(url)

        # Check that the page includes all our fields
        self.assertContains(response,
                            person.extended_object.get_title(),
                            status_code=200)
        self.assertContains(response, person.first_name)
        self.assertContains(response, person.last_name)
        self.assertContains(response, person.person_title)
Esempio n. 17
0
    def test_cms_wizards_blogpost_submit_form_slug_duplicate(self):
        """
        Trying to create a blog post with a slug that would lead to a duplicate path should
        raise a validation error.
        """
        # A parent page should pre-exist
        parent_page = create_page(
            "News",
            "richie/single_column.html",
            "en",
            reverse_id=BlogPost.PAGE["reverse_id"],
        )
        # Create an existing page with a known slug
        BlogPostFactory(page_parent=parent_page, page_title="My title")

        # Submit a title that will lead to the same slug
        data = {"title": "my title"}
        user = UserFactory(is_staff=True, is_superuser=True)
        form = BlogPostWizardForm(data=data, wizard_language="en", wizard_user=user)

        self.assertFalse(form.is_valid())
        self.assertEqual(form.errors, {"slug": ["This slug is already in use"]})
 def test_cms_wizards_blogpost_parent_page_should_exist(self):
     """
     We should not be able to create a blogpost page if the parent page does not exist
     """
     user = UserFactory(is_staff=True, is_superuser=True)
     form = BlogPostWizardForm(
         data={
             "title": "My title",
             "slug": "my-title"
         },
         wizard_language="en",
         wizard_user=user,
     )
     self.assertFalse(form.is_valid())
     self.assertEqual(
         form.errors,
         {
             "slug": [
                 "You must first create a parent page and set its `reverse_id` to `blogposts`."
             ]
         },
     )
Esempio n. 19
0
    def test_enrollment_create_closed(self, lms_mock):
        """
        Attempting to enroll in a course that is not open for enrollment anymore results
        in an error.
        """
        user = UserFactory()
        course_run = CourseRunFactory(
            start=arrow.utcnow().shift(days=-35).datetime,
            end=arrow.utcnow().shift(days=+60).datetime,
            enrollment_start=arrow.utcnow().shift(days=-65).datetime,
            enrollment_end=arrow.utcnow().shift(days=-20).datetime,
        )

        self.client.force_login(user)
        response = self.client.post("/api/v1.0/enrollments/",
                                    data={"course_run": course_run.id})

        self.assertEqual(response.status_code, 400)
        self.assertEqual(
            response.json(),
            {"errors": ["Course run is not open for enrollments."]})
        lms_mock.set_enrollment.assert_not_called()
Esempio n. 20
0
    def test_cms_wizards_course_run_submit_form_invalid_slug(
            self, mock_snapshot):
        """Trying to submit a slug that is not valid should raise a 400 exception."""
        # A course should pre-exist
        course = CourseFactory()

        # Submit an invalid slug
        data = {"title": "my title", "slug": "invalid slug"}

        user = UserFactory(is_superuser=True, is_staff=True)
        form = CourseRunWizardForm(data=data,
                                   wizard_language="en",
                                   wizard_user=user)
        form.page = course.extended_object
        self.assertFalse(form.is_valid())
        self.assertEqual(
            form.errors["slug"][0],
            "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens.",
        )

        # Snapshot was not request and should not have been triggered
        self.assertFalse(mock_snapshot.called)
Esempio n. 21
0
    def test_admin_course_run_change_view_get_superuser_public(self):
        """Public course runs should not render a change view."""
        user = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=user.username, password="******")

        # Create a public course run
        course = CourseFactory()
        CourseRunFactory(direct_course=course)
        course.extended_object.publish("en")

        self.assertEqual(CourseRun.objects.count(), 2)
        public_course_run = CourseRun.objects.get(
            draft_course_run__isnull=False)

        # Get the admin change view
        url = reverse("admin:courses_courserun_change",
                      args=[public_course_run.id])
        response = self.client.get(url, follow=True)

        self.assertEqual(response.status_code, 200)
        self.assertNotContains(response, "id_title")
        self.assertContains(response, "Perhaps it was deleted?")
Esempio n. 22
0
    def test_admin_course_change_view_post(self):
        """
        Validate that the course can be updated via the admin.
        In particular, make sure that when a course is updated from the admin, the main
        organization is automatically added to the many-to-many field "organizations".
        See http://stackoverflow.com/a/1925784/469575 for details on the issue.
        """
        user = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=user.username, password="******")

        # Create a course, some organizations and some subjects
        organization1, organization2, organization3 = OrganizationFactory.create_batch(
            3)
        subject1, subject2 = SubjectFactory.create_batch(2)
        course = CourseFactory(with_organizations=[organization1],
                               with_subjects=[subject1])
        self.assertEqual(set(course.organizations.all()),
                         {organization1, course.organization_main})
        self.assertEqual(set(course.subjects.all()), {subject1})

        # Get the admin change view
        url = reverse("admin:courses_course_change", args=[course.id])
        data = {
            "organization_main": organization2.id,
            "organizations": [organization3.id],
            "subjects": [subject2.id],
            "courserun_set-TOTAL_FORMS": 0,
            "courserun_set-INITIAL_FORMS": 0,
        }
        response = self.client.post(url, data)
        self.assertEqual(response.status_code, 302)

        # Check that the course was updated as expected
        course.refresh_from_db()
        self.assertEqual(course.organization_main, organization2)
        self.assertEqual(set(course.subjects.all()), {subject2})
        # Check that the main organization was added and the old organization cleared
        self.assertEqual(set(course.organizations.all()),
                         {organization2, organization3})
    def test_templatetags_placeholder_as_plugins_edit(self):
        """
        The "placeholder_as_plugins" template tag should inject in the page the edit markup
        """
        page = create_page("Test",
                           "richie/single_column.html",
                           "en",
                           published=True)
        placeholder = page.placeholders.all()[0]
        add_plugin(placeholder, CKEditorPlugin, "en", body="<b>Test 1</b>")
        add_plugin(placeholder, CKEditorPlugin, "en", body="<b>Test 2</b>")

        request = RequestFactory().get("/")
        request.current_page = page
        user = UserFactory(is_staff=True, is_superuser=True)
        request.user = user
        request.session = {"cms_edit": True}
        request.toolbar = CMSToolbar(request)
        request.toolbar.is_staff = True

        # Silent keyword argument in edition mode omit markup related to placeholder
        # edition
        template = (
            "{% load cms_tags extra_tags %}"
            '{% placeholder_as_plugins "maincontent" as plugins %}'
            "{% for plugin in plugins %}{% render_plugin plugin %}{% endfor %}"
        )
        output = self.render_template_obj(template, {}, request)

        # Tag adds HTML placeholder which set stuff for DjangoCMS edition (we don't
        # assert on Javascript content since it holds too many references to write here)
        self.assertInHTML(
            f'<div class="cms-placeholder cms-placeholder-{placeholder.id:d}"></div>',
            output,
        )
        self.assertIn(
            "CMS._plugins.push",
            output,
        )
Esempio n. 24
0
    def test_cms_wizards_person_submit_form_slugify_long_title(self):
        """
        When generating the slug from the title, we should respect the slug's "max_length"
        """
        # A parent page should pre-exist
        create_page(
            "Persons",
            "richie/single_column.html",
            "en",
            reverse_id=Person.PAGE["reverse_id"],
        )

        # Submit a title at max length
        data = {"title": "t" * 255}
        user = UserFactory(is_superuser=True, is_staff=True)
        form = PersonWizardForm(data=data,
                                wizard_language="en",
                                wizard_user=user)
        self.assertTrue(form.is_valid())
        page = form.save()
        # Check that the slug has been truncated
        self.assertEqual(page.get_slug(), "t" * 200)
Esempio n. 25
0
    def test_cms_wizards_category_root_page_should_exist(self):
        """
        We should not be able to create a category page if the root page does not exist
        """
        page = create_page("page", "richie/single_column.html", "en")
        user = UserFactory(is_staff=True, is_superuser=True)
        form = CategoryWizardForm(
            data={"title": "My title", "slug": "my-title"},
            wizard_language="en",
            wizard_user=user,
            wizard_page=page,
        )

        self.assertFalse(form.is_valid())
        self.assertEqual(
            form.errors,
            {
                "slug": [
                    "You must first create a parent page and set its `reverse_id` to `categories`."
                ]
            },
        )
Esempio n. 26
0
    def test_admin_form_course_run_choices_superuser_several_courses_initial(self):
        """
        If there are several courses but an initial value is passed for the "direct_course" field,
        the choice is made and the "direct_course" field is hidden.
        """
        course = CourseFactory(page_title="Title 1", should_publish=True)
        CourseFactory(page_title="Title 2", should_publish=True)
        user = UserFactory(is_staff=True, is_superuser=True)

        request = RequestFactory().get("/")
        request.user = user
        CourseRunAdminForm.request = request
        form = CourseRunAdminForm(initial={"direct_course": course.id})

        self.assertEqual(len(form.fields["direct_course"].choices), 3)
        self.assertIn(
            (
                f'<input type="hidden" name="direct_course" value="{course.id:d}" '
                'id="id_direct_course">'
            ),
            form.as_ul(),
        )
Esempio n. 27
0
    def test_admin_page_snapshot_blocked_for_public_page(self):
        """
        It should not be possible to snapshot the public page of a course.
        """
        user = UserFactory(is_staff=True)
        self.client.login(username=user.username, password="******")

        public_course = CourseFactory(should_publish=True).public_extension

        # Add the necessary permissions (global and per page)
        self.add_permission(user, "add_page")
        self.add_permission(user, "change_page")
        self.add_page_permission(
            user, public_course.extended_object, can_change=True, can_add=True
        )

        # Try triggering the creation of a snapshot for the course
        url = f"/en/admin/courses/course/{public_course.id:d}/snapshot/"
        response = self.client.post(url, follow=True)

        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.content, b"Course could not be found.")
Esempio n. 28
0
    def test_admin_course_run_delete_staff_user_missing_permission(self):
        """
        Staff users with missing page permissions can not delete a course run via the admin
        unless CMS permissions are not activated.
        """
        course_run = CourseRunFactory()

        user = UserFactory(is_staff=True)
        self.client.login(username=user.username, password="******")

        # Add only model permissions, not page permission on the course page
        self.add_permission(user, "delete_courserun")
        self.add_permission(user, "change_page")

        self._prepare_delete(course_run, 200, self.assertTrue)

        # But it should work if CMS permissions are not activated
        with override_settings(CMS_PERMISSION=False):
            self._prepare_delete(course_run, 200, self.assertFalse)

        # The course object should not be deleted
        self.assertEqual(Course.objects.count(), 1)
Esempio n. 29
0
    def test_cms_wizards_person_submit_form(self):
        """
        A user with the required permissions submitting a valid PersonWizardForm should be able
        to create a Person page extension and its related page.
        """
        any_page = create_page("page", "richie/single_column.html", "en")

        # A parent page should pre-exist
        create_page(
            "Persons",
            "richie/single_column.html",
            "en",
            reverse_id=Person.PAGE["reverse_id"],
        )

        # Create a user with just the required permissions
        user = UserFactory(
            is_staff=True,
            permissions=[
                "courses.add_person", "cms.add_page", "cms.change_page"
            ],
        )

        form = PersonWizardForm(
            data={"title": "A person"},
            wizard_language="en",
            wizard_user=user,
            wizard_page=any_page,
        )
        self.assertTrue(form.is_valid())
        page = form.save()

        # Related page should have been created as draft
        Page.objects.drafts().get(id=page.id)
        Person.objects.get(id=page.person.id, extended_object=page)

        self.assertEqual(page.get_title(), "A person")
        # The slug should have been automatically set
        self.assertEqual(page.get_slug(), "a-person")
Esempio n. 30
0
    def test_admin_person_title_change_view_post(self):
        """
        Validate that the person title can be updated via the admin.
        """
        user = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=user.username, password="******")

        # Create a person, title will automaticaly be created
        person_title = PersonTitleFactory(translation__title="Mister",
                                          translation__abbreviation="Mr.")
        self.assertEqual(PersonTitleTranslation.objects.count(), 1)

        # Get the admin change view
        url = reverse("admin:persons_persontitle_change",
                      args=[person_title.id])
        data = {"title": "Madam", "abbreviation": "Mm."}
        response = self.client.post(url, data)
        self.assertEqual(response.status_code, 302)
        # Check that the person title was updated as expected
        person_title = PersonTitle.objects.get(id=person_title.id)
        self.assertEqual(person_title.title, "Madam")
        self.assertEqual(person_title.abbreviation, "Mm.")