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)
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)
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."}, )
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"
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)
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)
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)
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." ) ], )
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)
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)
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)
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)
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": "******"})
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."}, )
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)
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)
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")
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)
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
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
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)
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.'})
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.", )
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, )
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)
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())
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)
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, [], )
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)
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.'})