예제 #1
0
    def test_updates_status_pending(self):
        existing_asset_row = AssetRow(
            id=None,
            uploaded_status=UploadedStatus.COMPLETE.value,
            bucket=DEFAULT_BUCKET,
            object_key='abc',
            create_date=datetime.now())
        with self.connection.cursor() as cur:
            existing_asset_row = AssetDao.insert_one(existing_asset_row, cur)

        with run_server():
            response = self.request('put',
                                    '/status',
                                    data=json.dumps({
                                        'asset_id':
                                        existing_asset_row.id,
                                        'uploaded_status':
                                        UploadedStatus.PENDING.value
                                    }))

            self.assertEqual(response.status_code, 200)
            response_body = json.loads(response.content)

            with self.connection.cursor() as cur:
                updated_asset_row = AssetDao.get_by_id(existing_asset_row.id,
                                                       cur)

            self.assertEqual(updated_asset_row.uploaded_status,
                             UploadedStatus.PENDING.value)

            self.assertEqual(response_body, {
                'success': True,
                'uploaded_status': UploadedStatus.PENDING.value,
            })
예제 #2
0
    def test_upload_using_existing_pending_asset(self):
        pending_asset_row = AssetRow(
            id=None,
            uploaded_status=UploadedStatus.PENDING.value,
            bucket=DEFAULT_BUCKET,
            object_key='abc',
            create_date=datetime.now(),
        )
        with self.connection.cursor() as cur:
            pending_asset_row = AssetDao.insert_one(pending_asset_row, cur)
        
        with run_server():
            response = self.request(
                'post',
                '/upload',
                data=json.dumps({ 'object_key': 'abc', 'expires_in': 50 }),
            )

            dict_data = json.loads(response.content)

            self.assertEqual(dict_data, {
                'signed_info': self.post_object_url_response,
                'asset_id': pending_asset_row.id,
            })

            self.assertEqual(pending_asset_row.uploaded_status, UploadedStatus.PENDING.value)
예제 #3
0
    def test_upload_existing_completed_asset_fails(self):
        completed_asset_row = AssetRow(
            id=None,
            uploaded_status=UploadedStatus.COMPLETE.value,
            bucket=DEFAULT_BUCKET,
            object_key='abc',
            create_date=datetime.now(),
        )
        with self.connection.cursor() as cur:
            AssetDao.insert_one(completed_asset_row, cur)

        with run_server():
            response = self.request(
                'post',
                '/upload',
                data=json.dumps({ 'object_key': 'abc' }),
            )

            self.assertEqual(response.status_code, 400)
            self.assertTrue('Upload already complete, try another object_key.' in response.content.decode())
def initiate_upload(upload_request, cursor):
    """
    Creates a signed URL for a put_object operation.
    Should the URL signing succeed, a row is also written to the `assets`
    table. Should it not, the exception is exposed to the user and no
    information is persisted.

    If the combination of bucket and key already exist in the database, an error
    is raised and no action is taken.

    :param upload_request: a dict with keys `object_key` and `expires_in`, denoting
    the asset's name and the amount of time, in seconds, that the signed URL should last.
    """

    _check_valid_upload_request(upload_request)
    object_key = upload_request['object_key']
    expiration = upload_request.get('expires_in')

    asset = AssetDao.get_by_bucket_and_key(
        DEFAULT_BUCKET,
        object_key,
        cursor,
    )

    if not asset:
        new_asset = AssetRow(
            id=None,
            uploaded_status=UploadedStatus.PENDING.value,
            bucket=DEFAULT_BUCKET,
            object_key=object_key,
            create_date=datetime.utcnow(),
        )
        asset = AssetDao.insert_one(new_asset, cursor)
    elif asset.uploaded_status == UploadedStatus.COMPLETE.value:
        raise UploadInvalidArgsException('Upload already complete, try another object_key.')

    if expiration:
        return {
            'signed_info': S3Service.create_signed_url(
                       S3ClientMethod.POST_OBJECT,
                       upload_request['object_key'],
                       expiration=expiration,
                   ),
            'asset_id': asset.id,
        }

    return {
        'signed_info': S3Service.create_signed_url(
                   S3ClientMethod.POST_OBJECT,
                   upload_request['object_key'],
               ),
        'asset_id': asset.id,
    }
    def test_happy_path(self):
        """
        Given:
            An AssetRow dataclass is supplied to insert
        Then:
            The data is inserted, and a dataclass with its row's data is returned
        """
        self.mock_cursor.fetchone.return_value = self.sample_asset_row_tuple
        result = AssetDao.insert_one(self.pre_insert_dataclass, self.mock_cursor)

        self.mock_cursor.execute.assert_called_once_with(
            'insert into asset(uploaded_status,bucket,object_key,create_date) values('
            '%s,%s,%s,%s) returning id,uploaded_status,bucket,object_key,create_date',
            (
                self.pre_insert_dataclass.uploaded_status,
                self.pre_insert_dataclass.bucket,
                self.pre_insert_dataclass.object_key,
                self.pre_insert_dataclass.create_date,
            )
        )

        self.assertEqual(result, self.sample_asset_row_dataclass)