Skip to content

Commit

Permalink
LITE-29342 Add disable action for feeds
Browse files Browse the repository at this point in the history
  • Loading branch information
jonatrios committed Feb 8, 2024
1 parent 23dd613 commit 797602d
Show file tree
Hide file tree
Showing 4 changed files with 311 additions and 7 deletions.
26 changes: 24 additions & 2 deletions connect_bi_reporter/feeds/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
FeedUpdateSchema,
map_to_feed_schema,
)
from connect_bi_reporter.feeds.enums import FeedStatusChoices
from connect_bi_reporter.feeds.services import (
change_feed_status,
create_feed,
delete_feed,
enable_feed,
get_feed_or_404,
get_feeds,
update_feed,
Expand Down Expand Up @@ -115,6 +116,7 @@ def delete_feed(
summary='Enable a Feed',
response_model=FeedSchema,
status_code=status.HTTP_200_OK,
name=FeedStatusChoices.enabled,
)
def enable_feed(
self,
Expand All @@ -123,6 +125,26 @@ def enable_feed(
installation: dict = Depends(get_installation),
request: Request = None,
):
return self.handle_feed_status_change(feed_id, db, installation, request)

@router.post(
'/feeds/{feed_id}/disable',
summary='Enable a Feed',
response_model=FeedSchema,
status_code=status.HTTP_200_OK,
name=FeedStatusChoices.disabled,
)
def disable_feed(
self,
feed_id: str,
db: VerboseBaseSession = Depends(get_db),
installation: dict = Depends(get_installation),
request: Request = None,
):
return self.handle_feed_status_change(feed_id, db, installation, request)

def handle_feed_status_change(self, feed_id, db, installation, request):
logged_user_data = get_user_data_from_auth_token(request.headers['connect-auth'])
feed = enable_feed(db, installation, feed_id, logged_user_data)
status_for_change = request.scope['route'].name
feed = change_feed_status(db, installation, feed_id, logged_user_data, status_for_change)
return map_to_feed_schema(feed)
8 changes: 4 additions & 4 deletions connect_bi_reporter/feeds/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from connect_extension_utils.api.views import get_object_or_404

from connect_bi_reporter.feeds.api.schemas import FeedCreateSchema, FeedUpdateSchema
from connect_bi_reporter.feeds.enums import FeedStatusChoices
from connect_bi_reporter.feeds.errors import FeedError
from connect_bi_reporter.feeds.models import Feed
from connect_bi_reporter.feeds.validator import FeedValidator
Expand Down Expand Up @@ -79,21 +78,22 @@ def delete_feed(
db.commit()


def enable_feed(
def change_feed_status(
db,
installation: Dict[str, Any],
feed_id: str,
user: Dict[str, str],
status: str,
):
feed = get_feed_or_404(db, installation, feed_id)
if feed.status == FeedStatusChoices.enabled:
if feed.status == status:
raise FeedError.RF_003(
format_kwargs={
'feed_id': feed.id,
'status': feed.status,
},
)
feed.status = FeedStatusChoices.enabled
feed.status = status
feed.updated_by = user['id']
db.commit()
return feed
70 changes: 69 additions & 1 deletion tests/feeds/api/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ def test_enable_feed_404(installation, api_client, connect_auth_header):
assert response_data['errors'][0] == 'Object `NOT-FOUND` not found.'


def test_already_enable_feed(
def test_already_enabled_feed(
installation,
feed_factory,
api_client,
Expand All @@ -456,3 +456,71 @@ def test_already_enable_feed(
assert response_data['errors'][0] == (
f'Feed `{feed.id}` is already in status `{feed.status}`.'
)


def test_disable_feed(
installation,
feed_factory,
api_client,
connect_auth_header,
):
feed = feed_factory(account_id=installation['owner']['id'])
updated_at = feed.updated_at
previous_status = feed.status

response = api_client.post(
f'/api/feeds/{feed.id}/disable',
installation=installation,
headers={'connect-auth': connect_auth_header},
)
user = get_user_data_from_auth_token(connect_auth_header)

assert response.status_code == 200

response_data = response.json()
assert response_data['id'] == feed.id
assert response_data['id'].startswith(feed_factory._meta.model.PREFIX)
assert response_data['file_name'] == feed.file_name
assert response_data['description'] == feed.description
assert response_data['owner']['id'] == installation['owner']['id']
events = response_data['events']
assert events['created']['at'] is not None
assert events['created']['by'] is not None
assert feed.updated_at > updated_at
assert events['updated']['by']['id'] == user['id']
assert response_data['status'] == 'disabled'
assert feed.status != previous_status and feed.status == 'disabled'


def test_disable_feed_404(installation, api_client, connect_auth_header):
response = api_client.post(
'/api/feeds/NOT-FOUND/disable',
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_already_disabled_feed(
installation,
feed_factory,
api_client,
connect_auth_header,
):
feed = feed_factory(account_id=installation['owner']['id'], status='disabled')
response = api_client.post(
f'/api/feeds/{feed.id}/disable',
installation=installation,
headers={'connect-auth': connect_auth_header},
)

assert response.status_code == 400
response_data = response.json()
assert response_data['error_code'] == 'RF_003'
assert response_data['errors'][0] == (
f'Feed `{feed.id}` is already in status `{feed.status}`.'
)
214 changes: 214 additions & 0 deletions tests/feeds/test_services.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
import pytest
from connect.client import ClientError
from connect_extension_utils.api.views import get_user_data_from_auth_token

from connect_bi_reporter.feeds.services import (
change_feed_status,
create_feed,
delete_feed,
get_feed_or_404,
get_feeds,
update_feed,
)
from connect_bi_reporter.feeds.api.schemas import FeedCreateSchema, FeedUpdateSchema


def test_create_feed(dbsession, installation, credential_factory, feed_factory):
account_id = installation['owner']['id']
cred = credential_factory(account_id=account_id)
data = FeedCreateSchema(
schedule={'id': 'RS-123'},
credential={'id': cred.id},
file_name='My file',
)
assert not dbsession.query(feed_factory._meta.model).all()
feed = create_feed(dbsession, data, account_id, {'id': 'SU-123'})
assert dbsession.query(feed_factory._meta.model).count() == 1
assert feed.file_name == data.file_name
assert feed.schedule_id == data.schedule.id
assert feed.credential_id == data.credential.id


def test_get_feed_or_404_error(dbsession, installation):
with pytest.raises(ClientError) as ex:
get_feed_or_404(dbsession, installation, 'NOT_FOUND')
assert ex.value.message == 'Object `NOT_FOUND` not found.'


def test_get_feed_or_404_ok(dbsession, installation, feed_factory):
feed = feed_factory(account_id=installation['owner']['id'])
get_feed = get_feed_or_404(dbsession, installation, feed.id)
assert feed == get_feed


@pytest.mark.parametrize(
'account_id,expected_count',
(
('PA-000-000', 3),
('OTHER', 0),
),
)
def test_get_feeds(dbsession, installation, feed_factory, account_id, expected_count):
feed_factory(account_id=account_id)
feed_factory(account_id=account_id)
feed_factory(account_id=account_id)

assert len(get_feeds(dbsession, installation)) == expected_count


def test_update_feed_ok(
dbsession,
installation,
logger,
credential_factory,
connect_auth_header,
feed_factory,
):
feed = feed_factory(account_id=installation['owner']['id'], file_name='test')
new_cred = credential_factory(account_id=installation['owner']['id'])
previous_updated_at = feed.updated_at
data = FeedUpdateSchema(
credential={'id': new_cred.id},
file_name='New file name',
)
user = get_user_data_from_auth_token(connect_auth_header)

assert feed.file_name == 'test'
assert feed.credential_id != new_cred.id

updated_feed = update_feed(dbsession, data, installation, feed.id, user, logger)
assert updated_feed.updated_by == user['id']
assert updated_feed.file_name == data.file_name
assert updated_feed.credential_id == new_cred.id
assert updated_feed.updated_at > previous_updated_at


def test_update_feed_fail(
dbsession,
installation,
logger,
credential_factory,
connect_auth_header,
feed_factory,
):
feed = feed_factory(account_id=installation['owner']['id'], file_name='test')
new_cred = credential_factory()
data = FeedUpdateSchema(
credential={'id': new_cred.id},
file_name='New file name',
)
user = get_user_data_from_auth_token(connect_auth_header)

with pytest.raises(ClientError) as ex:
update_feed(dbsession, data, installation, feed.id, user, logger)
assert ex.value.message == (
f'Can not update Feed, the Credential `{new_cred.id}` is not valid.'
)


def test_update_nothing_to_update(
dbsession,
installation,
logger,
credential_factory,
connect_auth_header,
feed_factory,
):
feed = feed_factory(account_id=installation['owner']['id'], file_name='test')
new_cred = credential_factory(account_id=installation['owner']['id'])
previous_updated_at = feed.updated_at
data = FeedUpdateSchema()
user = get_user_data_from_auth_token(connect_auth_header)

assert feed.file_name == 'test'
assert feed.credential_id != new_cred.id
assert feed.updated_by != user['id']

updated_feed = update_feed(dbsession, data, installation, feed.id, user, logger)
assert updated_feed.updated_by == feed.updated_by
assert updated_feed.file_name == feed.file_name
assert updated_feed.credential_id == feed.credential_id
assert updated_feed.updated_at == previous_updated_at


def test_delete_feed(
dbsession,
installation,
feed_factory,
):
feed = feed_factory(account_id=installation['owner']['id'])

assert dbsession.query(feed_factory._meta.model).all()

delete_feed(dbsession, installation, feed.id)
assert not dbsession.query(feed_factory._meta.model).all()


def test_delete_feed_in_use_fail(
dbsession,
installation,
feed_factory,
upload_factory,
):
feed = feed_factory(account_id=installation['owner']['id'])
upload = upload_factory(feed_id=feed.id)

existing_feeds = dbsession.query(feed_factory._meta.model).all()
assert existing_feeds

with pytest.raises(ClientError) as ex:
delete_feed(dbsession, installation, feed.id)
assert ex.value.message == (
f'Can not delete Feed `{feed.id}`, '
f'is already related to Uploads `{upload.id}`.'
)
assert existing_feeds


@pytest.mark.parametrize(
'current_status,target_status',
(
('enabled', 'disabled'),
('disabled', 'enabled'),
),
)
def test_change_feed_status_ok(
dbsession,
installation,
feed_factory,
connect_auth_header,
current_status,
target_status,
):
feed = feed_factory(account_id=installation['owner']['id'], status=current_status)
user = get_user_data_from_auth_token(connect_auth_header)
assert feed.status == current_status

change_feed_status(dbsession, installation, feed.id, user, target_status)
assert feed.status == target_status


@pytest.mark.parametrize(
'current_status,target_status',
(
('disabled', 'disabled'),
('enabled', 'enabled'),
),
)
def test_change_feed_status_fail(
dbsession,
installation,
feed_factory,
connect_auth_header,
current_status,
target_status,
):
feed = feed_factory(account_id=installation['owner']['id'], status=current_status)
user = get_user_data_from_auth_token(connect_auth_header)
assert feed.status == current_status

with pytest.raises(ClientError) as ex:
change_feed_status(dbsession, installation, feed.id, user, target_status)

assert ex.value.message == f'Feed `{feed.id}` is already in status `{current_status}`.'
assert feed.status == current_status

0 comments on commit 797602d

Please sign in to comment.