Skip to content

Commit

Permalink
LITE-29286 Create upload list and retrieve endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
jonatrios committed Feb 8, 2024
1 parent 3159ffd commit 909c74f
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 0 deletions.
19 changes: 19 additions & 0 deletions connect_bi_reporter/uploads/api/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,22 @@ class UploadSchema(NonNullSchema):
size: Optional[int]
status: str
events: Events


def map_to_upload_schema(upload):
return UploadSchema(
id=upload.id,
name=upload.name,
feed={'id': upload.feed_id},
report={'id': upload.report_id},
size=upload.size,
status=upload.status,
events={
'created': {
'at': upload.created_at,
},
'updated': {
'at': upload.updated_at,
},
},
)
43 changes: 43 additions & 0 deletions connect_bi_reporter/uploads/api/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from typing import List

from fastapi import Depends, status
from connect.eaas.core.decorators import router
from connect.eaas.core.inject.synchronous import get_installation
from connect_extension_utils.db.models import get_db, VerboseBaseSession

from connect_bi_reporter.uploads.api.schemas import map_to_upload_schema, UploadSchema
from connect_bi_reporter.uploads.services import get_upload_or_404, get_uploads_or_404


class UploadsWebAppMixin:

@router.get(
'/feeds/{feed_id}/uploads/{upload_id}',
summary='Returns the require Upload related to a Feed',
response_model=UploadSchema,
status_code=status.HTTP_200_OK,
)
def get_upload(
self,
feed_id: str,
upload_id: str,
db: VerboseBaseSession = Depends(get_db),
installation: dict = Depends(get_installation),
):
return map_to_upload_schema(get_upload_or_404(db, installation, feed_id, upload_id))

@router.get(
'/feeds/{feed_id}/uploads',
summary='Returns all Uploads related to a Feed',
response_model=List[UploadSchema],
status_code=status.HTTP_200_OK,
)
def get_uploads(
self,
feed_id: str,
db: VerboseBaseSession = Depends(get_db),
installation: dict = Depends(get_installation),
):
return [
map_to_upload_schema(upload) for upload in get_uploads_or_404(db, installation, feed_id)
]
27 changes: 27 additions & 0 deletions connect_bi_reporter/uploads/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from sqlalchemy import util
from connect.client import ClientError
from connect.client.rql import R
from connect_extension_utils.api.errors import Http404

from connect_bi_reporter.feeds.enums import FeedStatusChoices
from connect_bi_reporter.scheduler import TriggerTypeEnum
Expand Down Expand Up @@ -187,3 +188,29 @@ def create_process_upload_tasks(uploads, scheduler, **kwargs):
report_id=upload.report_id,
),
)


def get_uploads(db, installation, feed_id):
filters = (
Upload.feed.has(
account_id=installation['owner']['id'],
id=feed_id,
),
)
upload_qs = db.query(Upload).filter(*filters)
return upload_qs


def get_uploads_or_404(db, installation, feed_id):
upload_qs = get_uploads(db, installation, feed_id)
if not db.query(upload_qs.exists()).scalar():
raise Http404(obj_id=feed_id)
return upload_qs


def get_upload_or_404(db, installation, feed_id, upload_id):
upload_qs = get_uploads_or_404(db, installation, feed_id)
upload = upload_qs.filter(Upload.id == upload_id).one_or_none()
if not upload:
raise Http404(obj_id=upload_id)
return upload
2 changes: 2 additions & 0 deletions connect_bi_reporter/webapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@

from connect_bi_reporter.credentials.api.views import CredentialsWebAppMixin
from connect_bi_reporter.feeds.api.views import FeedsWebAppMixin
from connect_bi_reporter.uploads.api.views import UploadsWebAppMixin
from connect_bi_reporter.scheduler import genererate_default_recurring_schedule_task


@web_app(router)
class ConnectBiReporterWebApplication(
CredentialsWebAppMixin,
FeedsWebAppMixin,
UploadsWebAppMixin,
WebApplicationBase,
):

Expand Down
124 changes: 124 additions & 0 deletions tests/uploads/api/test_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
def test_list_uploads(installation, feed_factory, api_client, connect_auth_header, upload_factory):
uploads = []
invalid_feed = feed_factory(account_id='other-account')
valid_feed = feed_factory(account_id=installation['owner']['id'])
upload_factory(feed_id=invalid_feed.id)

for _ in range(5):
uploads.append(upload_factory(feed_id=valid_feed.id, name='Name', size=600))

response = api_client.get(
f'/api/feeds/{valid_feed.id}/uploads',
installation=installation,
headers={'connect-auth': connect_auth_header},
)

assert response.status_code == 200

response_data = response.json()

assert len(response_data) == len(uploads)

for upload, response_upload in zip(uploads, response_data):
assert response_upload['id'] == upload.id
assert response_upload['name'] == upload.name
assert response_upload['report'] == {'id': upload.report_id}
assert response_upload['feed'] == {'id': valid_feed.id}
assert response_upload['size'] == upload.size
assert response_upload['status'] == upload.status
events = response_upload['events']
assert events['created']['at'] is not None
assert events['updated']['at'] is not None


def test_list_uploads_feed_not_found(
installation,
feed_factory,
api_client,
connect_auth_header,
upload_factory,
):
uploads = []
valid_feed = feed_factory(account_id=installation['owner']['id'])
for _ in range(5):
uploads.append(upload_factory(feed_id=valid_feed.id, name='Name', size=600))

response = api_client.get(
'/api/feeds/NOT-FOUND/uploads',
installation=installation,
headers={'connect-auth': connect_auth_header},
)

assert response.status_code == 404
response_data = response.json()
assert response_data['error_code'] == 'NFND_000'
assert response_data['errors'][0] == 'Object `NOT-FOUND` not found.'


def test_get_upload(installation, feed_factory, api_client, connect_auth_header, upload_factory):
feed = feed_factory(account_id=installation['owner']['id'])
upload = upload_factory(feed_id=feed.id, name='Test', size=600)

response = api_client.get(
f'/api/feeds/{feed.id}/uploads/{upload.id}',
installation=installation,
headers={'connect-auth': connect_auth_header},
)

assert response.status_code == 200

response_data = response.json()

assert response_data['id'] == upload.id
assert response_data['name'] == upload.name
assert response_data['report'] == {'id': upload.report_id}
assert response_data['feed'] == {'id': feed.id}
assert response_data['size'] == upload.size
assert response_data['status'] == upload.status
events = response_data['events']
assert events['created']['at'] is not None
assert events['updated']['at'] is not None


def test_get_upload_feed_not_found(
installation,
feed_factory,
api_client,
connect_auth_header,
upload_factory,
):
feed = feed_factory(account_id=installation['owner']['id'])
upload = upload_factory(feed_id=feed.id, name='Test', size=600)

response = api_client.get(
f'/api/feeds/FEED-NOT-FOUND/uploads/{upload.id}',
installation=installation,
headers={'connect-auth': connect_auth_header},
)

assert response.status_code == 404
response_data = response.json()
assert response_data['error_code'] == 'NFND_000'
assert response_data['errors'][0] == 'Object `FEED-NOT-FOUND` not found.'


def test_get_upload_upload_not_found(
installation,
feed_factory,
api_client,
connect_auth_header,
upload_factory,
):
feed = feed_factory(account_id=installation['owner']['id'])
upload_factory(feed_id=feed.id, name='Test', size=600)

response = api_client.get(
f'/api/feeds/{feed.id}/uploads/UPLOAD-NOT-FOUND',
installation=installation,
headers={'connect-auth': connect_auth_header},
)

assert response.status_code == 404
response_data = response.json()
assert response_data['error_code'] == 'NFND_000'
assert response_data['errors'][0] == 'Object `UPLOAD-NOT-FOUND` not found.'

0 comments on commit 909c74f

Please sign in to comment.