def test_happy_path_existing_asset(self, bucket_key_mock, insert_one_mock, create_signed_url_mock): """ Given: The object key and bucket already correspond to a row in the database that is in the `pending` state Then: An S3 signed URL is generated, and no row is inserted """ bucket_key_mock.return_value = self.asset_row_from_db create_signed_url_mock.return_value = self.sample_presigned_post upload_request = {'object_key': 'important_secrets.txt'} result = initiate_upload(upload_request, self.mock_cursor) insert_one_mock.assert_not_called() create_signed_url_mock.assert_called_once_with( S3ClientMethod.POST_OBJECT, 'important_secrets.txt', ) self.assertEqual( result, { 'signed_info': self.sample_presigned_post, 'asset_id': self.asset_row_from_db.id, })
def test_happy_path_with_expiration(self, bucket_key_mock, insert_one_mock, create_signed_url_mock): """ Given: A request is made with an expiry time Then: An S3 signed URL is generated with the expiry time """ bucket_key_mock.return_value = self.asset_row_from_db create_signed_url_mock.return_value = self.sample_presigned_post upload_request = { 'object_key': 'important_secrets.txt', 'expires_in': 30 # seconds } result = initiate_upload(upload_request, self.mock_cursor) create_signed_url_mock.assert_called_once_with( S3ClientMethod.POST_OBJECT, 'important_secrets.txt', expiration=30, ) self.assertEqual( result, { 'signed_info': self.sample_presigned_post, 'asset_id': self.asset_row_from_db.id, })
def test_invalid_request(self): """ Given: The request is missing keys, or the values have invalid types Then: An applicable error is thrown """ data = {} with self.assertRaises(UploadInvalidArgsException) as ctx: initiate_upload(data, self.mock_cursor) self.assertEqual(str(ctx.exception), 'Missing key: object_key') data = {'object_key': 1} with self.assertRaises(UploadInvalidArgsException) as ctx: initiate_upload(data, self.mock_cursor) self.assertEqual(str(ctx.exception), 'Invalid key: object_key, Value: 1 is not a string') data = {'object_key': 'sick_name.txt', 'expires_in': 'mamajama'} with self.assertRaises(UploadInvalidArgsException) as ctx: initiate_upload(data, self.mock_cursor) self.assertEqual( str(ctx.exception), 'Invalid key: expires_in, Value: mamajama is not an int')
def test_completed_asset_invalid(self, bucket_and_key_mock): """ Given: The request uses a bucket and object_key for an asset that already exists in the database, and the asset has an uploaded_status of `complete` Then: An applicable error is thrown """ bucket_and_key_mock.return_value = AssetRow( id=1, uploaded_status=UploadedStatus.COMPLETE.value, bucket=DEFAULT_BUCKET, object_key='something', create_date=datetime.utcnow()) data = { 'object_key': 'sick_name.txt', } with self.assertRaises(UploadInvalidArgsException) as ctx: initiate_upload(data, self.mock_cursor) self.assertEqual(str(ctx.exception), 'Upload already complete, try another object_key.')
def POST(self): json = cherrypy.request.json with DatabaseAccessor.get_connection() as c: try: with c.cursor() as cursor: return initiate_upload(json, cursor) except UploadInvalidArgsException as ue: logger.error(traceback.format_exc()) raise cherrypy.HTTPError(400, message=str(ue)) except S3ServiceInvalidArgsException as s3e: logger.error(traceback.format_exc()) raise cherrypy.HTTPError(400, message=str(s3e)) except S3ServiceException as s3e: logger.error(traceback.format_exc()) raise cherrypy.HTTPError(500, message=str(s3e))
def test_happy_path(self, bucket_key_mock, insert_one_mock, create_signed_url_mock): """ Given: The object key and bucket don't already correspond to a row in the database Then: A new Asset row is inserted and an S3 signed URL is generated """ bucket_key_mock.return_value = None create_signed_url_mock.return_value = self.sample_presigned_post upload_request = {'object_key': 'important_secrets.txt'} with freeze_time(datetime.utcnow()): row_to_be_inserted = AssetRow( id=None, uploaded_status=UploadedStatus.PENDING.value, bucket=DEFAULT_BUCKET, object_key='important_secrets.txt', create_date=datetime.utcnow()) insert_one_mock.return_value = self.asset_row_from_db result = initiate_upload(upload_request, self.mock_cursor) insert_one_mock.assert_called_once_with(row_to_be_inserted, self.mock_cursor) create_signed_url_mock.assert_called_once_with( S3ClientMethod.POST_OBJECT, 'important_secrets.txt', ) self.assertEqual( result, { 'signed_info': self.sample_presigned_post, 'asset_id': self.asset_row_from_db.id, })