Пример #1
0
    def test_access_api_can_manage_moderators_update_student_no_group_moderator(
            self):
        """If moderator group doesn't exist user can be updated and group created
        Case for forum created before this feature"""
        update_user = UserFactory()
        api_user = UserFactory(lti_consumer=update_user.lti_consumer)

        lti_context = LTIContextFactory(lti_consumer=update_user.lti_consumer)
        forum = ForumFactory()
        forum.lti_contexts.add(lti_context)
        # Add group student
        lti_context.sync_user_groups(update_user, ["student"])
        # Assign the permission
        assign_perm("can_manage_moderator", api_user, forum, True)
        # Creates the session
        self.client.force_login(api_user, "ashley.auth.backend.LTIBackend")
        session = self.client.session
        session[SESSION_LTI_CONTEXT_ID] = lti_context.id
        session.save()

        # Data to promote user to moderator
        response = self.client.patch(
            f"/api/v1.0/users/{update_user.id}/add_group_moderator/",
            content_type="application/json",
        )
        self.assertEqual(response.status_code, 200)
Пример #2
0
    def test_access_api_can_manage_moderators_update_student_no_session(self):
        """Users with no session can't update user"""
        update_user = UserFactory()
        api_user = UserFactory(lti_consumer=update_user.lti_consumer)

        lti_context = LTIContextFactory(lti_consumer=update_user.lti_consumer)
        forum = ForumFactory()
        forum.lti_contexts.add(lti_context)

        # Assign student group to user
        lti_context.sync_user_groups(update_user, ["student"])
        # Assign the permission
        assign_perm("can_manage_moderator", api_user, forum, True)
        #
        response = self.client.patch(
            f"/api/v1.0/users/{update_user.id}/add_group_moderator/",
            content_type="application/json",
        )
        self.assertEqual(response.status_code, 403)
        content = json.loads(response.content)
        self.assertEqual(
            content,
            {"detail": "Authentication credentials were not provided."})
        # Create the session and it should work
        self.client.force_login(api_user, "ashley.auth.backend.LTIBackend")
        session = self.client.session
        session[SESSION_LTI_CONTEXT_ID] = lti_context.id
        session.save()
        response = self.client.patch(
            f"/api/v1.0/users/{update_user.id}/add_group_moderator/",
            content_type="application/json",
        )
        self.assertEqual(response.status_code, 200)
Пример #3
0
    def test_access_api_can_manage_moderators_instructor_other_forum(self):
        """
        If a user can manage another forum, he can't update moderators from a forum
        where is doesn't have this permission.
        """
        update_user = UserFactory()
        api_user = UserFactory(lti_consumer=update_user.lti_consumer)

        lti_context = LTIContextFactory(lti_consumer=update_user.lti_consumer)
        forum = ForumFactory()
        forum.lti_contexts.add(lti_context)
        update_user.refresh_from_db()
        # Assign the permission
        assign_perm("can_manage_moderator", api_user, ForumFactory(), True)
        # Creates the session
        self.client.force_login(api_user, "ashley.auth.backend.LTIBackend")
        session = self.client.session
        session[SESSION_LTI_CONTEXT_ID] = lti_context.id
        session.save()

        action = random.choice(
            ["add_group_moderator", "remove_group_moderator"])
        # Revoke user to moderator
        response = self.client.patch(
            f"/api/v1.0/users/{update_user.id}/{action}/",
            content_type="application/json",
        )
        self.assertEqual(response.status_code, 403)
        self.assertEqual(
            response.json(),
            {"detail": "You do not have permission to perform this action."},
        )
Пример #4
0
    def test_can_tell_if_the_user_is_instructor_of_this_forum():
        """
        Given two users. User1 is student of the forum, User2 is instructor.
        We control that is_user_instructor can detect if a user is an instructor.
        Then a forum can be part of multiple contexts. If a user is instructor in one context,
        he is considered intructor of this forum in all contexts. We add a new context to the forum
        where user is instructor and test that user is now considered as instructor
        """

        # load template
        def get_rendered(topic, user):
            template = Template(
                "{% load custom_tags %}" +
                "{% if topic|is_user_instructor:user %}YES{% else %}NO{% endif %}"
            )
            context = Context({"topic": topic, "user": user})
            rendered = template.render(context)

            return rendered

        lti_consumer = LTIConsumerFactory()
        # Create two LTI Context
        context1 = LTIContextFactory(lti_consumer=lti_consumer)
        context2 = LTIContextFactory(lti_consumer=lti_consumer)
        # Create two users
        user1 = UserFactory(lti_consumer=lti_consumer)
        user2 = UserFactory(lti_consumer=lti_consumer)

        # Sync user1 groups in context1 with role "student"
        context1.sync_user_groups(user1, ["student"])
        # Sync user1 groups in context2 with role "instructor"
        context2.sync_user_groups(user1, ["instructor"])
        # Sync user2 groups in context1 with role "instructor"
        context1.sync_user_groups(user2, ["instructor"])

        # Create forum and add context1
        forum = ForumFactory(name="Initial forum name")
        forum.lti_contexts.add(context1)

        # Set up topic
        topic = TopicFactory(forum=forum,
                             poster=user1,
                             subject="topic création")

        # Chek that user1 is not instructor
        assert get_rendered(topic, user1) == "NO"
        # Chek that user2 is instructor
        assert get_rendered(topic, user2) == "YES"

        # Add forum to context2 where user1 has role "instructor"
        forum.lti_contexts.add(context2)
        # Check that user1 is now instructor as well
        assert get_rendered(topic, user1) == "YES"
Пример #5
0
    def test_forum_search_post_poster_restrict_forums(self):
        """
        Forum searches can be restricted to only one forum
        when searching for a specific poster.
        """
        post1 = PostFactory()
        post2 = PostFactory(poster=post1.poster,
                            topic__forum=post1.topic.forum)
        post3 = PostFactory(poster=post1.poster)

        user = UserFactory()
        assign_perm("can_read_forum", user, post1.topic.forum)
        assign_perm("can_read_forum", user, post3.topic.forum)

        # Index the post in Elasticsearch
        call_command("rebuild_index", interactive=False)

        self.client.force_login(user)
        response = self.client.get(
            f"/forum/search/?q=&search_poster_name={post1.poster.public_username}\
            &search_forums={post1.topic.forum.pk}")

        self.assertContains(response,
                            "Your search has returned <b>2</b> results",
                            html=True)
        self.assertContains(response, post1.subject)
        self.assertContains(response, post2.subject)

        response = self.client.get(
            f"/forum/search/?q=&search_poster_name={post1.poster.public_username}\
                &search_forums={post3.topic.forum.pk}")
        self.assertContains(response,
                            "Your search has returned <b>1</b> result",
                            html=True)
        self.assertContains(response, post3.subject)
Пример #6
0
    def test_forum_search_several_forums_restrict_to_one(self):
        """Forum searches can be restricted to only one forum."""
        post1 = PostFactory(text="Hello world", subject="a5g3g6k75")
        post2 = PostFactory(text="Good morning world", subject="497jk1sav")

        user = UserFactory()
        assign_perm("can_read_forum", user, post1.topic.forum)
        assign_perm("can_read_forum", user, post2.topic.forum)

        # Index the post in Elasticsearch
        call_command("rebuild_index", interactive=False)

        self.client.force_login(user)
        response = self.client.get(
            f"/forum/search/?q=world&search_forums={post1.topic.forum.pk}")

        self.assertContains(response,
                            "Your search has returned <b>1</b> result",
                            html=True)
        self.assertContains(response, post1.subject)

        response = self.client.get(
            f"/forum/search/?q=world&search_forums={post2.topic.forum.pk}")
        self.assertContains(response,
                            "Your search has returned <b>1</b> result",
                            html=True)
        self.assertContains(response, post2.subject)
Пример #7
0
    def test_forum_search_only_topics(self):
        """
        If the "search only topics" checkbox is ticked, matching content elsewhere should not
        return any result.
        """
        post1 = PostFactory(subject="497jk1sav", text="497jk1sav")
        forum = post1.topic.forum
        post2 = PostFactory(topic__subject="497jk1sav", topic__forum=forum)

        user = UserFactory()
        assign_perm("can_read_forum", user, forum)

        # Index the post in Elasticsearch
        call_command("rebuild_index", interactive=False)

        self.client.force_login(user)

        # Searching without the "search_topics" flag returns post1 because it contains
        # the search string in its text body.
        response = self.client.get("/forum/search/?q=497jk")

        self.assertContains(response,
                            "Your search has returned <b>1</b> result",
                            html=True)
        self.assertContains(response, post1.topic.slug)

        # Searching with the "search_topics" flag returns post2 because it contains
        # the search string in the related topic subject.
        response = self.client.get("/forum/search/?q=497jk&search_topics=on")

        self.assertContains(response,
                            "Your search has returned <b>1</b> result",
                            html=True)
        self.assertContains(response, post2.topic.slug)
Пример #8
0
    def test_api_create_upload_bad_extension(self):
        """Make sure we can't upload a file with an unauthorized extension"""
        user = UserFactory()
        forum = ForumFactory()
        self.client.force_login(user, "ashley.auth.backend.LTIBackend")
        video = SimpleUploadedFile(
            "file.mp4", b"file_content", content_type="video/mp4"
        )

        data = {
            "file": video,
            "forum": forum.id,
            "poster": user.id,
        }
        # Upload image
        response = self.client.post("/api/v1.0/images/", data, format="multipart")
        self.assertEqual(response.status_code, 400)
        self.assertEqual(
            json.loads(response.content)["file"],
            [
                (
                    "Upload a valid image. The file you uploaded was either "
                    + "not an image or a corrupted image."
                )
            ],
        )
Пример #9
0
    def test_testing_topic_announce(self):
        """Controls topics that are of type announcement don't have sorted options"""
        # Creates posts for announcement topics
        forum = ForumFactory()
        PostFactory(topic=TopicFactory(forum=forum, type=Topic.TOPIC_ANNOUNCE))
        PostFactory(topic=TopicFactory(forum=forum, type=Topic.TOPIC_ANNOUNCE))

        user = UserFactory()
        assign_perm("can_read_forum", user, forum)
        self.client.force_login(user)

        response = self.client.get(f"/forum/forum/{forum.slug}-{forum.pk}/")

        html = lxml.html.fromstring(response.content)
        # Select the header block of the announcement block, the first block
        announce_block = str(
            etree.tostring(html.cssselect(".topiclist .card-header")[0]))

        # Controls that announce_block is about announcements and not topics
        self.assertIn("Announcements", announce_block)
        self.assertNotIn("Topics", announce_block)
        self.assertIn("Replies", announce_block)
        self.assertIn("Views", announce_block)
        self.assertIn("Last post", announce_block)

        # There's no sortable informations
        self.assertNotIn("sortable sorted", announce_block)
        # There's no column that has a sorting link on
        self.assertNotIn("<a href=", announce_block)
        # There's no toggle sorting
        self.assertNotIn("Toggle sorting", announce_block)
Пример #10
0
    def test_basic_user(self):
        """
        A user without the `can_archive_forum` permission
        should not be able to archive it.
        """
        user = UserFactory()
        lti_context = LTIContextFactory(lti_consumer=user.lti_consumer)
        forum = ForumFactory()
        forum.lti_contexts.add(lti_context)
        assign_perm("can_read_forum", user, forum)

        self.assertFalse(forum.archived)

        self.client.force_login(user, "ashley.auth.backend.LTIBackend")

        # The user can read the forum
        response = self.client.get(f"/forum/forum/{forum.slug}-{forum.pk}/")
        self.assertEqual(200, response.status_code)
        self.assertContains(response, forum.name)

        # but he's not allowed to archive it
        response = self.client.get(f"/forum/admin/archive/{forum.pk}/")
        self.assertEqual(403, response.status_code)

        update_response = self.client.post(f"/forum/admin/archive/{forum.pk}/")
        self.assertEqual(403, update_response.status_code)

        self.assertFalse(Forum.objects.get(pk=forum.pk).archived)
Пример #11
0
    def test_forum_search_archived_forum(self):
        """Content of an archived forum should not be indexed"""
        post = PostFactory(text="yah7Eo0A")
        forum = post.topic.forum

        user = UserFactory()
        assign_perm("can_read_forum", user, forum)

        # Index the post in Elasticsearch
        call_command("rebuild_index", interactive=False)

        self.client.force_login(user)
        response = self.client.get("/forum/search/?q=yah7")
        self.assertContains(response,
                            "Your search has returned <b>1</b> result",
                            html=True)
        self.assertContains(response, post, html=True)

        # Archive the forum
        forum.archived = True
        forum.save()

        # Re-build the index
        call_command("rebuild_index", interactive=False)

        # The same search should return nothing
        response = self.client.get("/forum/search/?q=yah7")
        self.assertContains(response,
                            "Your search has returned <b>0</b> results",
                            html=True)
Пример #12
0
    def test_access_can_manage_moderators_moderator_list_students(self):
        """Users that can manage moderators should be able to use the API to request
        list of students"""
        user = UserFactory()
        lti_context = LTIContextFactory(lti_consumer=user.lti_consumer)
        forum = ForumFactory()
        forum.lti_contexts.add(lti_context)

        self.client.force_login(user, "ashley.auth.backend.LTIBackend")
        response = self.client.get("/api/v1.0/users/?role=student")
        # First it's forbidden
        self.assertEqual(403, response.status_code)
        # Add session
        session = self.client.session
        session[SESSION_LTI_CONTEXT_ID] = lti_context.id
        session.save()
        self.assertEqual(self.client.session.get(SESSION_LTI_CONTEXT_ID),
                         lti_context.id)

        response = self.client.get("/api/v1.0/users/?role=student")
        # Still forbidden session ok but missing permission
        self.assertEqual(response.status_code, 403)

        assign_perm("can_manage_moderator", user, forum, True)
        # Should now be authorized
        response = self.client.get("/api/v1.0/users/?role=student")
        self.assertEqual(response.status_code, 200)
Пример #13
0
    def test_access_api_update_instructor_patch(self):
        """
        Standard instructor call to patch user is allowed but doesn't change anything,
        as serializer's attributes are read-only.
        """
        # Creates a forum
        user = UserFactory(id=1, public_username="******")
        lti_context = LTIContextFactory(lti_consumer=user.lti_consumer)
        forum = ForumFactory()
        forum.lti_contexts.add(lti_context)
        lti_context.sync_user_groups(user, ["instructor"])
        assign_perm("can_manage_moderator", user, forum, True)
        # Creates the session
        self.client.force_login(user, "ashley.auth.backend.LTIBackend")
        session = self.client.session
        session[SESSION_LTI_CONTEXT_ID] = lti_context.id
        session.save()
        data = {"id": 10, "public_username": "******"}
        response = self.client.patch(
            f"/api/v1.0/users/{user.id}/",
            json.dumps(data),
            content_type="application/json",
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json(), {"id": 1, "public_username": "******"})
Пример #14
0
    def test_access_api_update_student_patch(self):
        """Standard call should not be allowed to update a student."""
        # Creates a forum
        user = UserFactory()
        lti_context = LTIContextFactory(lti_consumer=user.lti_consumer)
        forum = ForumFactory()
        forum.lti_contexts.add(lti_context)
        assign_perm("can_read_forum", user, forum, True)

        # Creates the session
        self.client.force_login(user, "ashley.auth.backend.LTIBackend")
        session = self.client.session
        session[SESSION_LTI_CONTEXT_ID] = lti_context.id
        session.save()
        data = {
            "public_username": "******",
        }
        response = self.client.patch(
            f"/api/v1.0/users/{user.id}/",
            json.dumps(data),
            content_type="application/json",
        )
        self.assertEqual(response.status_code, 403)
        self.assertEqual(
            response.json(),
            {"detail": "You do not have permission to perform this action."},
        )
Пример #15
0
    def test_access_can_manage_moderators_list_non_moderators(self):
        """Users that can manage moderators should be able to use the API to request
        list of users that are not moderators"""
        user = UserFactory()
        lti_context = LTIContextFactory(lti_consumer=user.lti_consumer)
        forum = ForumFactory()
        forum.lti_contexts.add(lti_context)
        self.client.force_login(user, "ashley.auth.backend.LTIBackend")
        response = self.client.get("/api/v1.0/users/?role=!moderator")

        # First it's forbidden
        self.assertEqual(403, response.status_code)

        # Add permission
        assign_perm("can_manage_moderator", user, forum, True)

        # Still forbidden, missing the session
        response = self.client.get("/api/v1.0/users/?!role=moderator")
        self.assertEqual(403, response.status_code)

        # Add session
        session = self.client.session
        session[SESSION_LTI_CONTEXT_ID] = lti_context.id
        session.save()
        self.assertEqual(self.client.session.get(SESSION_LTI_CONTEXT_ID),
                         lti_context.id)

        response = self.client.get("/api/v1.0/users/?role=!moderator")
        # Permission + session added, it should be allowed
        self.assertEqual(response.status_code, 200)
Пример #16
0
    def test_forum_search_with_unautorized_forum_from_other_lti_context(self):
        """
        Try to search in a forum that is not part of our LTIContext by submitting
        in the search form a forum from another LTIContext.
        """
        user = UserFactory()

        lti_context = LTIContextFactory(lti_consumer=user.lti_consumer)
        lti_context2 = LTIContextFactory(lti_consumer=user.lti_consumer)
        forum = ForumFactory()
        forum2 = ForumFactory()
        forum.lti_contexts.add(lti_context)
        forum2.lti_contexts.add(lti_context2)

        PostFactory(
            topic=TopicFactory(forum=forum),
            text="Good morning world",
        )

        PostFactory(
            topic=TopicFactory(forum=forum2),
            text="Hello world",
        )
        # Index posts in Elasticsearch
        call_command("rebuild_index", interactive=False)

        # Connects and gets acces to the forum
        self.client.force_login(user, "ashley.auth.backend.LTIBackend")
        assign_perm("can_read_forum", user, forum)
        assign_perm("can_read_forum", user, forum2)
        session = self.client.session
        session[SESSION_LTI_CONTEXT_ID] = lti_context.id
        session.save()

        form = SearchForm(user=user, lti_context=lti_context)

        # Checks that only the forum that is allowed is proposed as choice
        self.assertEqual(
            form.fields["search_forums"].choices,
            [(forum.id, "{} {}".format("-" * forum.margin_level, forum.name))],
        )
        # Despite that, we force the request on the forum that is not allowed
        response = self.client.get(
            f"/forum/search/?q=world&search_forums={forum2.id}")
        self.assertEqual(response.status_code, 200)
        # Controls that we get an error and the search is not executed
        self.assertContains(
            response,
            f"Select a valid choice. {forum2.id} is not one of the available choices.",
            html=True,
        )

        # Valid request, we search on the forum that is allowed, we get only one result
        # as forum2 is ignored
        response = self.client.get(
            f"/forum/search/?q=world&search_forums={forum.id}")
        self.assertEqual(response.status_code, 200)
        self.assertContains(response,
                            "Your search has returned <b>1</b> result",
                            html=True)
Пример #17
0
    def test_browsing_with_can_manage_moderator_forum_permission(self):
        """
        A user with the `can_manage_moderator_forum` permission and
        `SESSION_LTI_CONTEXT_ID` should be able to access it.
        """
        user = UserFactory()
        lti_context = LTIContextFactory(lti_consumer=user.lti_consumer)
        forum = ForumFactory()
        forum.lti_contexts.add(lti_context)

        assign_perm("can_manage_moderator", user, forum, True)

        self.client.force_login(user, "ashley.auth.backend.LTIBackend")
        response = self.client.get("/moderators/")
        # Controls the page is forbidden as session is not set
        self.assertEqual(403, response.status_code)

        session = self.client.session
        session[SESSION_LTI_CONTEXT_ID] = lti_context.id
        session.save()
        self.assertEqual(
            self.client.session.get(SESSION_LTI_CONTEXT_ID), lti_context.id
        )

        # Now session and permission are set, we should be able to access it
        response = self.client.get("/moderators/")
        self.assertEqual(200, response.status_code)
        self.assertContains(response, "Manage forum's moderators")
Пример #18
0
    def test_lti_context_id(self):
        """
        When the `SESSION_LTI_CONTEXT_ID` is set in the user session, it should
        be injected into the PermissionHandler instance that is stored in the
        request object.
        """

        user = UserFactory()
        lti_context = LTIContextFactory(lti_consumer=user.lti_consumer)

        # Generate a request
        request = RequestFactory().get("/")

        # Attach a user to the request
        request.user = user

        # Attach a session to the request
        session_middleware = SessionMiddleware(lambda r: None)
        session_middleware.process_request(request)

        # Store the LTIContext id in the session
        request.session[SESSION_LTI_CONTEXT_ID] = lti_context.id
        self.assertEqual(request.session.get(SESSION_LTI_CONTEXT_ID),
                         lti_context.id)

        # Execute the ForumPermissionMiddleware on the request
        permission_middleware = ForumPermissionMiddleware(lambda r: None)
        permission_middleware.process_request(request)

        # The permission handler instance should have been injected, with the
        # right current_lti_context_id
        self.assertEqual(
            request.forum_permission_handler.current_lti_context_id,
            lti_context.id)
Пример #19
0
    def test_access_topic_reply_form(self):
        """
        The post form in a created topic is overridden from django_machina,
        we control it still loads as expected
        """
        user = UserFactory(lti_consumer=self.lti_consumer)
        assign_perm("can_read_forum", user, self.forum)
        assign_perm("can_reply_to_topics", user, self.forum)

        # Set up topic and initial post
        topic = TopicFactory(forum=self.forum, poster=user)
        PostFactory(topic=topic)

        # authenticate the user related to consumer
        self.client.force_login(user)

        url_topic_reply = (
            f"/forum/forum/{self.forum.slug}-{self.forum.pk}"
            f"/topic/{topic.slug}-{topic.pk}/post/create/"
        )

        # Run
        response = self.client.get(url_topic_reply, follow=True)
        # Check
        assert response.status_code == 200
Пример #20
0
    def _get_url_list_topic_with_three_topics(self):
        """Creates a forum with three topics and a user to access the forum that has
        the permission to access it. It's a shortcut used in all the tests below."""
        forum = ForumFactory()
        # create 3 topics with distinct subject, views_count and date
        PostFactory(
            topic=TopicFactory(forum=forum, views_count=9),
            subject="TOPIC B the eldest with 9 views_count",
        )
        PostFactory(
            topic=TopicFactory(forum=forum, views_count=6),
            subject="TOPIC A created second with 6 views_count",
        )

        PostFactory(
            topic=TopicFactory(forum=forum, views_count=12),
            subject="TOPIC C the newest one with 12 views_count",
        )

        user = UserFactory()
        assign_perm("can_read_forum", user, forum)
        self.client.force_login(user)

        # Setup
        url_list_topic = f"/forum/forum/{forum.slug}-{forum.pk}/"

        return forum, url_list_topic
Пример #21
0
    def test_with_can_rename_forum_permission(self):
        """
        A user with the `can_rename_forum` permission should be able
        to rename it.
        """

        user = UserFactory()
        lti_context = LTIContextFactory(lti_consumer=user.lti_consumer)
        forum = ForumFactory(name="Initial forum name")
        forum.lti_contexts.add(lti_context)

        assign_perm("can_rename_forum", user, forum, True)

        self.client.force_login(user, "ashley.auth.backend.LTIBackend")
        response = self.client.get(f"/forum/admin/rename/{forum.pk}/")
        self.assertEqual(200, response.status_code)
        self.assertContains(response, "Rename the forum")

        update_response = self.client.post(
            f"/forum/admin/rename/{forum.pk}/",
            data={"name": "Modified forum name"})
        self.assertEqual(302, update_response.status_code)

        self.assertEqual("Modified forum name",
                         Forum.objects.get(pk=forum.pk).name)
Пример #22
0
    def test_api_cant_delete_image(self):
        """Controls user doesn't have the right to delete a record"""
        user = UserFactory()
        forum = ForumFactory()
        self.client.force_login(user, "ashley.auth.backend.LTIBackend")
        filename = "image.png"
        data = {
            "file": self._generate_image(filename),
            "forum": forum.id,
            "poster": user.id,
        }
        # At first, no image exists
        self.assertEqual(UploadImage.objects.count(), 0)
        # Upload image
        response = self.client.post("/api/v1.0/images/", data, format="multipart")
        self.assertEqual(response.status_code, 201)

        # Gets last id generated
        self.assertEqual(UploadImage.objects.count(), 1)
        image_db = UploadImage.objects.last()
        # Controls image's path is respected on server
        self.assertIn(f"image_uploads/{forum.id}/{user.id}/", image_db.file.name)

        # Specify the id of the image for the update
        data = {
            "id": image_db.id,
            "file": self._generate_image(filename),
            "forum": forum.id,
            "poster": user.id,
        }
        response = self.client.delete("/api/v1.0/images/", data, format="multipart")
        self.assertEqual(response.status_code, 405)
        content = json.loads(response.content)
        self.assertEqual(content, {"detail": 'Method "DELETE" not allowed.'})
Пример #23
0
    def test_forum_search_authorized(self):
        """A user with the rights to read a forum should be able to search."""
        created_on = datetime(2020, 10, 5, 8, 13, tzinfo=timezone.utc)
        with mock.patch.object(timezone, "now", return_value=created_on):
            post = PostFactory()

        poster = post.poster
        user = UserFactory()
        assign_perm("can_read_forum", user, post.topic.forum)

        # Index the post in Elasticsearch
        call_command("rebuild_index", interactive=False)

        self.client.force_login(user)
        response = self.client.get("/forum/search/?q=*")

        # Check the format of the results
        self.assertContains(response,
                            "Your search has returned <b>1</b> result",
                            html=True)
        self.assertContains(response, post.subject)
        self.assertContains(response, post.topic.subject)
        self.assertContains(
            response,
            f'By: <a href="/forum/member/profile/{poster.id:d}/">{poster.public_username:s}</a>',
        )
        self.assertContains(
            response,
            "on Oct. 5, 2020, 8:13 a.m.",
        )
Пример #24
0
    def test_forum_display_button_manage_moderator(self):
        """
        Connects a user with standard forum permission and controls that CTA to manage
        moderator is not present, then add the permission can_manage_moderator and
        control that we now see the CTA as expected
        """
        user = UserFactory()
        lti_context = LTIContextFactory(lti_consumer=user.lti_consumer)
        forum = ForumFactory(name="Initial forum name")
        forum.lti_contexts.add(lti_context)
        assign_perm("can_read_forum", user, forum)

        # Connects user and go on the forum page
        self.client.force_login(user)
        response = self.client.get(f"/forum/forum/{forum.name}-{forum.id}/")

        # Check the CTA to manage moderators is not present
        self.assertNotContains(
            response,
            ('<a href="/moderators/" title="Manage moderators" class="dropdown-item">'
             "Manage moderators</a>"),
            html=True,
        )
        # Assign permission can_manage_moderator
        assign_perm("can_manage_moderator", user, forum)
        response = self.client.get(f"/forum/forum/{forum.name}-{forum.id}/")

        # Check the CTA to manage moderators is now present
        self.assertContains(
            response,
            ('<a href="/moderators/" title="Manage moderators" class="dropdown-item">'
             "Manage moderators</a>"),
            html=True,
        )
Пример #25
0
    def test_post_with_an_inactive_user(self):
        """An inactive user should not be allowed to authenticate via a valid LTI request"""

        user = UserFactory(is_active=False)
        passport = LTIPassportFactory(title="consumer1_passport1",
                                      consumer=user.lti_consumer)

        forum_uuid = "8bb319aa-f3cf-4509-952c-c4bd0fb42fd7"
        context_id = "course-v1:testschool+login+0001"

        # Build the LTI launch request
        lti_parameters = {
            "user_id": "643f1625-f240-4a5a-b6eb-89b317807963",
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": "aaa",
            "context_id": context_id,
            "lis_person_contact_email_primary":
            "*****@*****.**",
            "lis_person_sourcedid": user.public_username,
            "launch_presentation_locale": "en",
            "roles": "Instructor",
        }
        url = f"http://testserver/lti/forum/{forum_uuid}"
        signed_parameters = sign_parameters(passport, lti_parameters, url)

        response = self.client.post(
            f"/lti/forum/{forum_uuid}",
            data=urlencode(signed_parameters),
            content_type=CONTENT_TYPE,
        )

        self.assertEqual(403, response.status_code)
Пример #26
0
    def test_api_create_upload_image(self):
        """Verify that image gets created and uploaded"""
        user = UserFactory()
        forum = ForumFactory()
        self.client.force_login(user, "ashley.auth.backend.LTIBackend")
        filename = f"test-{datetime.datetime.now().strftime('%f')}.png"
        data = {
            "file": self._generate_image(filename),
            "forum": forum.id,
            "poster": user.id,
        }
        # At first, no image exists
        self.assertEqual(UploadImage.objects.count(), 0)
        # Upload image
        response = self.client.post("/api/v1.0/images/", data, format="multipart")
        self.assertEqual(response.status_code, 201)

        # Gets last id generated
        image_db = UploadImage.objects.last()

        # Image should have be added with right values
        self.assertEqual(UploadImage.objects.count(), 1)
        self.assertEqual(image_db.forum.id, forum.id)
        self.assertEqual(image_db.poster.id, user.id)

        # Controls image's path is respected on server
        self.assertIn(f"image_uploads/{forum.id}/{user.id}/", image_db.file.name)

        # Controls file has been uploaded
        uploaded_file = image_db.file.open()
        self.assertGreater(uploaded_file.size, 0)
        self.assertIsNotNone(uploaded_file.read())
Пример #27
0
 def test_access_authenticated_api_upload_images_item(self):
     """Authenticated users should not be allowed to retrieve image detail"""
     user = UserFactory()
     self.client.force_login(user, "ashley.auth.backend.LTIBackend")
     image = UploadImageFactory()
     response = self.client.get(f"/api/v1.0/images/{image.id}/")
     self.assertEqual(response.status_code, 404)
Пример #28
0
    def test_list_users_no_moderator_if_no_group_in_context(self):
        """Controls that list of moderators only concerns users that are part of
        users that have group in this context
        """
        api_user, lti_context = self._login_authorized_user_to_manage_moderators(
        )

        user1 = UserFactory(public_username="******",
                            lti_consumer=api_user.lti_consumer)
        # add group moderator
        group_moderator = lti_context.get_role_group(_FORUM_ROLE_MODERATOR)
        user1.groups.add(group_moderator)
        user1.save()
        # check user has group moderator
        self.assertCountEqual(
            [f"{lti_context.base_group_name}:role:moderator"],
            list(user1.groups.values_list("name", flat=True)),
        )
        # request users that are moderator
        response = self.client.get("/api/v1.0/users/?role=moderator",
                                   content_type="application/json")
        self.assertEqual(response.status_code, 200)
        content = json.loads(response.content)
        # should be empty because user has no other groups from this context
        self.assertEqual(content, [])

        # request all users
        response = self.client.get("/api/v1.0/users/",
                                   content_type="application/json")
        self.assertEqual(response.status_code, 200)
        content = json.loads(response.content)
        # should be empty because user has no other groups from this context
        self.assertEqual(
            content,
            [],
        )

        # request all users that are not moderators
        response = self.client.get("/api/v1.0/users/?role=!moderator",
                                   content_type="application/json")
        self.assertEqual(response.status_code, 200)
        content = json.loads(response.content)
        # should be empty because user has no other groups from this context
        self.assertEqual(
            content,
            [],
        )
Пример #29
0
 def test_access_authenticated_api_create_upload_image(self):
     """Authenticated users should be able to create an image but request
     needs to be completed."""
     user = UserFactory()
     self.client.force_login(user, "ashley.auth.backend.LTIBackend")
     response = self.client.post("/api/v1.0/images/")
     # Request uncomplete so it returns a 400 but not a 403 anymore
     self.assertEqual(response.status_code, 400)
Пример #30
0
 def test_access_authenticated_api_upload_images_list(self):
     """Authenticated users should not be allowed to retrieve list of images"""
     user = UserFactory()
     self.client.force_login(user, "ashley.auth.backend.LTIBackend")
     response = self.client.get("/api/v1.0/images/")
     self.assertEqual(response.status_code, 405)
     content = json.loads(response.content)
     self.assertEqual(content, {"detail": 'Method "GET" not allowed.'})