예제 #1
0
    def test_share_solution_function(
        exercise: Exercise,
        student_user: User,
    ):
        student_user2 = conftest.create_student_user(index=1)
        solution = conftest.create_solution(exercise, student_user2)

        client2 = conftest.get_logged_user(student_user2.username)
        # Sharing his own solution
        shared_response = client2.post('/share', data=json.dumps(dict(
            solutionId=solution.id, act='get',
        )), content_type='application/json')
        assert shared_response.status_code == 200

        # Entering another student solution
        shared_url = SharedSolution.get_or_none(
            SharedSolution.solution == solution,
        )
        conftest.logout_user(client2)
        client = conftest.get_logged_user(student_user.username)
        shared_response = client.get(f'{routes.SHARED}/{shared_url}')
        assert shared_response.status_code == 200

        # Downloading another student solution by solution.id
        solution_id_download_response = client.get(
            f'{routes.DOWNLOADS}/{solution.id}',
        )
        assert solution_id_download_response.status_code == 403

        # Downloading another student solution
        download_response = client.get(
            f'{routes.DOWNLOADS}/{shared_url}',
        )
        assert download_response.status_code == 200

        # Deleting another user's solution
        delete_not_user_solution_response = client.post(
            '/share', data=json.dumps(dict(
                solutionId=solution.id, act='delete',
            )), content_type='application/json',
        )
        assert delete_not_user_solution_response.status_code == 403

        # Deleting his own solution
        conftest.logout_user(client)
        client2 = conftest.get_logged_user(student_user2.username)
        delete_share_response = client2.post('/share', data=json.dumps(dict(
            solutionId=solution.id, act='delete',
        )), content_type='application/json')
        assert delete_share_response.status_code == 200

        # Entering not shared solution after deletion
        conftest.logout_user(client2)
        client = conftest.get_logged_user(student_user.username)
        not_shared_solution_response = client.get(
            f'{routes.SHARED}/{shared_url}',
        )
        assert not_shared_solution_response.status_code == 404
예제 #2
0
 def test_download_solution(
     self,
     exercise: Exercise,
     student_user: User,
 ):
     storage = self.create_zipfile_storage()
     hash_ = hashing.by_file(storage)
     solution = conftest.create_solution(
         exercise=exercise,
         student_user=student_user,
         files=list(TestDownloadSolution.get_zip_files()),
         hash_=hash_,
     )
     client = conftest.get_logged_user(student_user.username)
     download_response = client.get(f'{routes.DOWNLOADS}/{solution.id}')
     downloaded_bytes_file = BytesIO(download_response.data)
     downloaded_zipfile = ZipFile(downloaded_bytes_file, 'r')
     exist_zipfile = ZipFile(self.zipfile_file, 'r')
     for exist_filename, downloaded_filename in zip(
             exist_zipfile.namelist(),
             downloaded_zipfile.namelist(),
     ):
         assert exist_filename == downloaded_filename
         with exist_zipfile.open(exist_filename, 'r') as exist_file:
             with downloaded_zipfile.open(
                     downloaded_filename,
                     'r',
             ) as downloaded_file:
                 assert exist_file.read() == downloaded_file.read()
예제 #3
0
    def test_staff_and_user_comments(
        exercise: Exercise,
        student_user: User,
        staff_user: User,
    ):
        solution = conftest.create_solution(exercise, student_user)

        client = conftest.get_logged_user(staff_user.username)
        # Enabling user comments option
        conftest.enable_users_comments()
        # Creating a comment
        comment_response = client.post('/comments', data=json.dumps(dict(
            fileId=solution.files[0].id, act='create', kind='text',
            comment='try again', line=1,
        )), content_type='application/json')
        assert comment_response.status_code == 200

        # Creating another comment
        another_comment_response = client.post(
            '/comments', data=json.dumps(dict(
                fileId=solution.files[0].id, act='create', kind='text',
                comment='hey', line=1,
            )), content_type='application/json',
        )
        assert another_comment_response.status_code == 200

        # Removing the second comment
        json_response_another_comment = json.loads(
            another_comment_response.get_data(as_text=True),
        )
        delete_response = client.get('/comments', query_string=dict(
            fileId=solution.files[0].id, act='delete',
            commentId=json_response_another_comment['id'],
        ), content_type='application/json')
        assert delete_response.status_code == 200

        conftest.logout_user(client)
        client2 = conftest.get_logged_user(student_user.username)
        # Trying to remove a comment
        json_response_comment = json.loads(
            comment_response.get_data(as_text=True),
        )
        delete_response = client2.get('/comments', query_string=dict(
            fileId=solution.files[0].id, act='delete',
            commentId=json_response_comment['id'],
        ), content_type='application/json')
        assert delete_response.status_code == 403
예제 #4
0
    def test_zip_bomb(self, student_user: User):
        conftest.create_exercise()

        client = conftest.get_logged_user(username=student_user.username)

        # Trying to upload a zipbomb file
        upload_response = client.post('/upload', data={
            'file': self.zipbomb_bytes_io,
        })
        assert upload_response.status_code == 413
예제 #5
0
    def test_limiter_login_success(student_user: User):
        client = webapp.test_client()
        client.post('/login', data={
            'username': student_user.username,
            'password': '******',
        }, follow_redirects=True)
        fail_login_response = client.get('/exercises')
        assert fail_login_response.status_code == 302

        client = conftest.get_logged_user(student_user.username)
        success_login_response = client.get('/exercises')
        assert success_login_response.status_code == 200
예제 #6
0
    def test_share_with_disabled_shareable_solutions(
        exercise: Exercise,
        student_user: User,
    ):
        solution = conftest.create_solution(exercise, student_user)

        client = conftest.get_logged_user(student_user.username)
        conftest.disable_shareable_solutions()
        shared_response = client.post('/share', data=json.dumps(dict(
            solutionId=solution.id, act='get',
        )), content_type='application/json')
        assert shared_response.status_code == 403
예제 #7
0
    def test_comment_text_escaping(student_user: User, solution: Solution):
        client = conftest.get_logged_user(student_user.username)

        # Creating a comment
        comment_response = client.post(
            '/comments',
            data=json.dumps(
                dict(
                    fileId=solution.files[0].id,
                    act='create',
                    kind='text',
                    comment=USER_COMMENT_BEFORE_ESCAPING,
                    line=1,
                )),
            content_type='application/json')
        assert comment_response.status_code == 200
        assert solution.comments[0].comment.text == USER_COMMENT_AFTER_ESCAPING
예제 #8
0
    def test_comment_text_escaping(student_user: User, solution: Solution):
        client = conftest.get_logged_user(student_user.username)

        comment_response = client.post('/comments',
                                       data=json.dumps({
                                           'fileId':
                                           solution.files[0].id,
                                           'act':
                                           'create',
                                           'kind':
                                           'text',
                                           'comment':
                                           USER_COMMENT_BEFORE_ESCAPING,
                                           'line':
                                           1,
                                       }),
                                       content_type='application/json')
        assert comment_response.status_code == 200
        assert solution.comments[0].comment.text == USER_COMMENT_AFTER_ESCAPING
예제 #9
0
    def test_share_solution_by_another_user(
        exercise: Exercise,
        student_user: User,
    ):
        student_user2 = conftest.create_student_user(index=1)
        solution = conftest.create_solution(exercise, student_user2)

        client = conftest.get_logged_user(student_user.username)

        not_exist_share_response = client.post('/share', data=json.dumps(dict(
            solutionId=solution.id + 1, act='get',
        )), content_type='application/json')
        assert not_exist_share_response.status_code == 404

        not_user_solution_share_response = client.post(
            '/share', data=json.dumps(dict(
                solutionId=solution.id, act='get',
            )), content_type='application/json',
        )
        assert not_user_solution_share_response.status_code == 403
예제 #10
0
    def test_zip(self, student_user: User):
        conftest.create_exercise()
        conftest.create_exercise()
        conftest.create_exercise()
        conftest.create_exercise(is_archived=True)

        client = conftest.get_logged_user(username=student_user.username)

        # Uploading a multiple zip solutions file
        upload_response = client.post(
            '/upload', data=dict(file=self.zipfiles_extractors_bytes_io[1], ))
        json_response_upload = json.loads(
            upload_response.get_data(as_text=True), )
        assert len(json_response_upload['exercise_misses']) == 1
        assert len(json_response_upload['exercise_matches']) == 2
        assert upload_response.status_code == 200

        # Uploading a zip file with a same solution exists in the previous zip
        second_upload_response = client.post(
            '/upload', data=dict(file=self.zipfiles_extractors_bytes_io[0], ))
        assert second_upload_response.status_code == 400
예제 #11
0
    def test_user_commented_after_check(
        solution: Solution,
        student_user: User,
        staff_user: User,
    ):
        client = conftest.get_logged_user(student_user.username)

        # Marking the solution as checked
        solutions.mark_as_checked(solution.id, staff_user.id)
        solution = Solution.get_by_id(solution.id)

        # Sending comments after solution checked
        comment_response = client.post('/comments',
                                       data=json.dumps({
                                           'fileId':
                                           solution.files[0].id,
                                           'act':
                                           'create',
                                           'kind':
                                           'text',
                                           'comment':
                                           'new one',
                                           'line':
                                           1,
                                       }),
                                       content_type='application/json')
        new_comment_response = client.post('/comments',
                                           data=json.dumps({
                                               'fileId':
                                               solution.files[0].id,
                                               'act':
                                               'create',
                                               'kind':
                                               'text',
                                               'comment':
                                               'another one',
                                               'line':
                                               2,
                                           }),
                                           content_type='application/json')
        assert comment_response.status_code == 200
        assert new_comment_response.status_code == 200
        assert len(list(notifications.get(staff_user))) == 1

        conftest.logout_user(client)
        client2 = conftest.get_logged_user(staff_user.username)

        # Sending a comment after student user commented
        staff_comment_response = client2.post(
            '/comments',
            data=json.dumps({
                'fileId': solution.files[0].id,
                'act': 'create',
                'kind': 'text',
                'comment': 'FINE',
                'line': 1,
            }),
            content_type='application/json',
        )
        assert staff_comment_response.status_code == 200
        assert len(list(notifications.get(student_user))) == 2

        conftest.logout_user(client2)
        client = conftest.get_logged_user(student_user.username)

        # User student comments again
        another_comment_response = client.post(
            '/comments',
            data=json.dumps({
                'fileId': solution.files[0].id,
                'act': 'create',
                'kind': 'text',
                'comment': 'OK',
                'line': 3,
            }),
            content_type='application/json',
        )
        assert another_comment_response.status_code == 200
        assert len(list(notifications.get(staff_user))) == 2