Пример #1
0
def test_file_descriptors_after_sharing_with_old_team(
        mock_get_download_url, mock_remove_file, shared_file_upload_fixture, mock_block
):
    # Include a deleted file entry, and later assert that we have empty file descriptors
    # returned by ``file_descriptors()``
    block = mock_block(
        descriptions=['The first file', 'The deleted file', 'The second file'],
        names=['File A', 'File that is deleted', 'File B'],
        sizes=[22, 666, 44],
    )
    block.team.team_id = DEFAULT_TEAM_ID
    block.is_team_assignment.return_value = True

    student_item_dict = {
        'student_id': DEFAULT_OWNER_ID,
        'course_id': DEFAULT_COURSE_ID,
        'item_id': DEFAULT_ITEM_ID,
    }
    key_a = api.get_student_file_key(student_item_dict, index=0)
    key_deleted = api.get_student_file_key(student_item_dict, index=1)
    key_b = api.get_student_file_key(student_item_dict, index=2)

    # create a shared upload that was shared with an old team
    _ = shared_file_upload_fixture(team_id='an-old-team', file_key=key_a)

    # create one for the file we're going to delete
    _ = shared_file_upload_fixture(team_id=block.team.team_id, file_key=key_deleted)

    # create a shared upload that's shared with the learner's current team
    _ = shared_file_upload_fixture(team_id=block.team.team_id, file_key=key_b)

    file_manager = api.FileUploadManager(block)

    # go and delete the file we want to delete
    file_manager.delete_upload(1)

    # file_descriptors() should only give back a record for the upload shared with the current team
    actual_descriptors = file_manager.file_descriptors(team_id=block.team.team_id, include_deleted=True)
    expected_descriptors = [
        {
            'download_url': None,
            'name': None,
            'description': None,
            'size': 0,
            'show_delete_button': False,
        },
        {
            'download_url': mock_get_download_url.return_value,
            'name': 'File B',
            'description': 'The second file',
            'size': 44,
            'show_delete_button': True,
        }
    ]

    assert expected_descriptors == actual_descriptors
    mock_get_download_url.assert_called_once_with(key_b)
    mock_remove_file.assert_called_once_with(key_deleted)
Пример #2
0
    def get_files_info_from_user_state(self, username):
        """
        Returns the files information from the user state for a given username.

        If the files information is present in the user state, return a list of following tuple:
        (file_download_url, file_description, file_name)

        Arguments:
            username(str): user's name whose state is being check for files information.
        Returns:
            List of files information tuple, if present, else empty list.
        """

        files_info = []
        user_state = self.get_user_state(username)
        item_dict = self.get_student_item_dict_from_username(username)
        if u'saved_files_descriptions' in user_state:
            # pylint: disable=protected-access
            files_descriptions = file_upload_api._safe_load_json_list(
                user_state.get('saved_files_descriptions'))

            files_names = file_upload_api._safe_load_json_list(
                user_state.get('saved_files_names', '[]'))
            for index, description in enumerate(files_descriptions):
                file_key = file_upload_api.get_student_file_key(
                    item_dict, index)
                download_url = self._get_url_by_file_key(file_key)
                if download_url:
                    file_name = files_names[index] if index < len(
                        files_names) else ''
                    files_info.append((download_url, description, file_name))
                else:
                    # If file has been removed, the URL doesn't exist
                    continue
        return files_info
Пример #3
0
    def _get_student_item_key(self, num=0):
        """
        Simple utility method to generate a common file upload key based on
        the student item.

        Returns:
            A string representation of the key.

        """
        return file_upload_api.get_student_file_key(self.get_student_item_dict(), index=num)
Пример #4
0
    def test_descriptionless_files(self, xblock):
        """
        Tests the old corner-case of a user being able to save files
        without descriptions.
        """
        with patch('openassessment.fileupload.api.get_download_url') as mock_download_url:
            # Pretend there are two uploaded files for this XBlock.
            mock_download_url.side_effect = [
                Mock(),
                Mock(),
                None,
            ]

            student_item_dict = xblock.get_student_item_dict()
            key_1 = api.get_student_file_key(student_item_dict, index=0)
            key_2 = api.get_student_file_key(student_item_dict, index=1)

            actual_keys = [upload.key for upload in xblock.file_manager.get_uploads()]
            self.assertEqual([key_1, key_2], actual_keys)
Пример #5
0
    def get_files_info_from_user_state(self, username):
        """
        Returns the files information from the user state for a given username.

        If the files information is present in the user state, return a list of following tuple:
        (file_download_url, file_description, file_name)

        Arguments:
            username(str): user's name whose state is being check for files information.
        Returns:
            List of files information tuple, if present, else empty list.
        """

        files_info = []
        user_state = self.get_user_state(username)
        item_dict = self.get_student_item_dict_from_username_or_email(username)
        if 'saved_files_descriptions' in user_state:
            # pylint: disable=protected-access
            files_descriptions = file_upload_api._safe_load_json_list(
                user_state.get('saved_files_descriptions'),
                log_error=True
            )
            files_names = file_upload_api._safe_load_json_list(
                user_state.get('saved_files_names', '[]'),
                log_error=True
            )
            for index, description in enumerate(files_descriptions):
                file_key = file_upload_api.get_student_file_key(item_dict, index)
                download_url = self._get_url_by_file_key(file_key)
                if download_url:
                    file_name = files_names[index] if index < len(files_names) else ''
                    files_info.append(
                        file_upload_api.FileDescriptor(
                            download_url=download_url,
                            description=description,
                            name=file_name,
                            show_delete_button=False
                        )._asdict()
                    )
                else:
                    # If file has been removed, the URL doesn't exist
                    logger.info(
                        "URLWorkaround: no URL for description %s & key %s for user:%s",
                        description,
                        username,
                        file_key
                    )
                    continue
        return files_info
Пример #6
0
    def get_all_upload_urls_for_user(self, username_or_email):
        """
        For a particular ORA block, get the download URLs for all the files uploaded and still present.

        Used for an extreme edge case, where the stored files indices are out of sync with
        the uploaded files, this is a last resort to get the download URLs of all the files
        that have been uploaded by a learner in an ORA block(and haven't been deleted from the storage).
        Starting from 0 index to maximum file upload count possible, this checks if a file exists against
        every index. If present, add the info, else repeat it for the next indices.

        Arguments:
            username_or_email(str): username or email of the learner whose files' information is to be obtained.
        Returns:
            List of 3-valued tuples, with first value being file URL and other two values as empty string.
            The other 2 values have to be appended to work properly in the template.
        """
        file_uploads = []
        student_item_dict = self.get_student_item_dict_from_username_or_email(username_or_email)
        for index in range(self.MAX_FILES_COUNT):
            file_key = file_upload_api.get_student_file_key(student_item_dict, index)
            download_url = ''
            try:
                download_url = file_upload_api.get_download_url(file_key)
            except FileUploadError:
                pass

            if download_url:
                logger.info(
                    "Download URL exists for key %s in block %s for user %s",
                    file_key,
                    username_or_email,
                    str(self.location)
                )
                file_uploads.append(
                    file_upload_api.FileDescriptor(
                        download_url=download_url,
                        description='',
                        name='',
                        show_delete_button=False
                    )._asdict()
                )
            else:
                continue

        return file_uploads
Пример #7
0
def test_team_files_metadata(mock_get_download_url, shared_file_upload_fixture, mock_block):
    mock_get_download_url.return_value = "some-download-url"
    block = mock_block(
        descriptions=['The first file'],
        names=['File A'],
        sizes=[22],
    )
    block.team.team_id = DEFAULT_TEAM_ID
    block.is_team_assignment.return_value = True

    student_item_dict = {
        'student_id': DEFAULT_OWNER_ID,
        'course_id': DEFAULT_COURSE_ID,
        'item_id': DEFAULT_ITEM_ID,
    }
    key_a = api.get_student_file_key(student_item_dict, index=0)

    # create a shared upload that's shared with the learner's current team
    _ = shared_file_upload_fixture(team_id=block.team.team_id, file_key=key_a)

    # create a couple of files uploaded by teammates
    key_beta = api.get_student_file_key(
        {'student_id': 'another-student', 'course_id': DEFAULT_COURSE_ID, 'item_id': DEFAULT_ITEM_ID}
    )
    _ = shared_file_upload_fixture(
        description='Another file',
        name='File Beta',
        team_id=block.team.team_id,
        owner_id='another-student',
        file_key=key_beta,
    )

    key_delta = api.get_student_file_key(
        {'student_id': 'yet-another-student', 'course_id': DEFAULT_COURSE_ID, 'item_id': DEFAULT_ITEM_ID}
    )
    _ = shared_file_upload_fixture(
        description='Yet another file',
        name='File Delta',
        team_id=block.team.team_id,
        owner_id='yet-another-student',
        file_key=key_delta,
    )

    file_manager = api.FileUploadManager(block)

    # team_file_descriptors() should only give back records for files owned by teammates
    actual_descriptors = file_manager.team_file_descriptors(team_id=block.team.team_id)

    expected_descriptors = [
        {
            'download_url': mock_get_download_url.return_value,
            'name': 'File Beta',
            'description': 'Another file',
            'size': 0,
            'uploaded_by': 'some_username',
        },
        {
            'download_url': mock_get_download_url.return_value,
            'name': 'File Delta',
            'description': 'Yet another file',
            'size': 0,
            'uploaded_by': 'some_username',
        }
    ]
    assert expected_descriptors == actual_descriptors
    mock_get_download_url.assert_has_calls([
        mock.call(key_beta),
        mock.call(key_delta),
    ])