Skip to content

Commit

Permalink
Fixing linting issue on timeline widget
Browse files Browse the repository at this point in the history
  • Loading branch information
VineetBala-AOT committed Jan 15, 2024
1 parent e5efd89 commit 94589fb
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 43 deletions.
2 changes: 2 additions & 0 deletions met-api/sample.env
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ DATABASE_TEST_NAME=
DATABASE_TEST_HOST=
DATABASE_TEST_PORT=

KEYCLOAK_TEST_BASE_URL="http://localhost:8081"

# Docker database settings
# If unset, uses the same settings as the main database
DATABASE_DOCKER_USERNAME=
Expand Down
2 changes: 1 addition & 1 deletion met-api/src/met_api/constants/timeline_event_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ class TimelineEventStatus(IntEnum):

Pending = 1
InProgress = 2
Completed = 3
Completed = 3
16 changes: 1 addition & 15 deletions met-api/src/met_api/models/widget_timeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
Manages the timeline widget
"""
from __future__ import annotations
from typing import Optional
from sqlalchemy.sql.schema import ForeignKey
from met_api.models.timeline_event import TimelineEvent
from met_api.services.timeline_event_service import TimelineEventService
from .base_model import BaseModel
from .db import db


class WidgetTimeline(BaseModel): # pylint: disable=too-few-public-methods, too-many-instance-attributes
"""Definition of the Timeline entity."""

Expand All @@ -30,16 +29,3 @@ def get_timeline(cls, timeline_id) -> list[WidgetTimeline]:
.filter(WidgetTimeline.widget_id == timeline_id) \
.all()
return widget_timeline

@classmethod
def update_timeline(cls, timeline_id, timeline_data: dict) -> Optional[WidgetTimeline or None]:
"""Update timeline."""
TimelineEvent.delete_event(timeline_id)
widget_timeline: WidgetTimeline = WidgetTimeline.query.get(timeline_id)
if widget_timeline:
widget_timeline.title = timeline_data.get('title')
widget_timeline.description = timeline_data.get('description')
for event in timeline_data.get('events', []):
TimelineEventService.create_timeline_event(timeline_id, event)
widget_timeline.save()
return widget_timeline
5 changes: 4 additions & 1 deletion met-api/src/met_api/schemas/widget_timeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
from marshmallow import Schema
from marshmallow_sqlalchemy.fields import Nested


class TimelineEventSchema(Schema): # pylint: disable=too-many-ancestors, too-few-public-methods
"""This is the schema for the timeline event model."""

class Meta: # pylint: disable=too-few-public-methods
"""All of the fields in the Timeline Event schema."""
Expand All @@ -29,11 +31,12 @@ class Meta: # pylint: disable=too-few-public-methods


class WidgetTimelineSchema(Schema): # pylint: disable=too-many-ancestors, too-few-public-methods
"""This is the schema for the widget timeline model."""

class Meta: # pylint: disable=too-few-public-methods
"""All of the fields in the Widget Timeline schema."""

model = WidgetTimelineModel
fields = ('id', 'engagement_id', 'widget_id', 'title', 'description', 'events')

events = Nested(TimelineEventSchema, many=True)
60 changes: 45 additions & 15 deletions met-api/src/met_api/services/widget_timeline_service.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
"""Service for Widget Timeline management."""
from http import HTTPStatus
from typing import Optional

from met_api.constants.membership_type import MembershipType
from met_api.exceptions.business_exception import BusinessException
from met_api.models.widget_timeline import WidgetTimeline as WidgetTimelineModel
from met_api.models.timeline_event import TimelineEvent as TimelineEventModel
from met_api.services import authorization
from met_api.services.timeline_event_service import TimelineEventService
from met_api.utils.roles import Role


Expand All @@ -28,23 +33,48 @@ def create_timeline(widget_id: int, timeline_details: dict):
return widget_timeline

@staticmethod
def update_timeline(widget_id: int, timeline_id: int, timeline_data: dict):
def update_timeline(widget_id: int, timeline_id: int, timeline_data: dict) -> Optional[WidgetTimelineModel]:
"""Update timeline widget."""
events = timeline_data.get("events")
events = timeline_data.get('events')
first_event = events[0]

WidgetTimelineService._check_update_timeline_auth(first_event)

widget_timeline: WidgetTimelineModel = WidgetTimelineModel.find_by_id(timeline_id)
authorization.check_auth(one_of_roles=(MembershipType.TEAM_MEMBER.name,
Role.EDIT_ENGAGEMENT.value), engagement_id=first_event.get('engagement_id'))

if not widget_timeline:
raise KeyError('Timeline widget not found')
raise BusinessException(
error='Timeline widget not found',
status_code=HTTPStatus.BAD_REQUEST)

if widget_timeline.widget_id != widget_id:
raise ValueError('Invalid widget ID')
raise BusinessException(
error='Invalid widget ID',
status_code=HTTPStatus.BAD_REQUEST)

if widget_timeline.id != timeline_id:
raise ValueError('Invalid timeline ID')
raise BusinessException(
error='Invalid timeline ID',
status_code=HTTPStatus.BAD_REQUEST)

WidgetTimelineService._update_widget_timeline(widget_timeline, timeline_data)

return widget_timeline

return WidgetTimelineModel.update_timeline(timeline_id, timeline_data)
@staticmethod
def _check_update_timeline_auth(first_event):
eng_id = first_event.get('engagement_id')
authorization.check_auth(one_of_roles=(MembershipType.TEAM_MEMBER.name,
Role.EDIT_ENGAGEMENT.value), engagement_id=eng_id)

@staticmethod
def _update_widget_timeline(widget_timeline: WidgetTimelineModel, timeline_data: dict):
widget_timeline.title = timeline_data.get('title')
widget_timeline.description = timeline_data.get('description')
TimelineEventModel.delete_event(widget_timeline.id)
for event in timeline_data.get('events', []):
TimelineEventService.create_timeline_event(widget_timeline.id, event)
widget_timeline.save()

@staticmethod
def _create_timeline_model(widget_id: int, timeline_data: dict):
Expand All @@ -56,13 +86,13 @@ def _create_timeline_model(widget_id: int, timeline_data: dict):
for event in timeline_data.get('events', []):
timeline_model.events.append(
TimelineEventModel(
widget_id = widget_id,
engagement_id = event.get('engagement_id'),
timeline_id = event.get('timeline_id'),
description = event.get('description'),
time = event.get('time'),
position = event.get('position'),
status = event.get('status'),
widget_id=widget_id,
engagement_id=event.get('engagement_id'),
timeline_id=event.get('timeline_id'),
description=event.get('description'),
time=event.get('time'),
position=event.get('position'),
status=event.get('status'),
)
)
timeline_model.flush()
Expand Down
14 changes: 9 additions & 5 deletions met-api/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from met_api import create_app, setup_jwt_manager
from met_api.auth import jwt as _jwt
from met_api.models import db as _db
from tests.utilities.factory_utils import factory_staff_user_model, set_global_tenant
from tests.utilities.factory_utils import factory_staff_user_model
from tests.utilities.factory_scenarios import TestJwtClaims, TestUserInfo


Expand Down Expand Up @@ -177,42 +177,46 @@ def auth_mock(monkeypatch):
# Fixture for setting up user and claims for an admin user
@pytest.fixture
def setup_admin_user_and_claims(jwt):
"""Set up a user with the staff admin role."""
staff_info = dict(TestUserInfo.user_staff_1)
user = factory_staff_user_model(user_info=staff_info)
claims = copy.deepcopy(TestJwtClaims.staff_admin_role.value)
claims['sub'] = str(user.external_id)

return user, claims


# Fixture for setting up user and claims for a reviewer
@pytest.fixture
def setup_reviewer_and_claims(jwt):
"""Set up a user with the reviewer role."""
staff_info = dict(TestUserInfo.user_staff_1)
user = factory_staff_user_model(user_info=staff_info)
claims = copy.deepcopy(TestJwtClaims.reviewer_role.value)
claims['sub'] = str(user.external_id)

return user, claims


# Fixture for setting up user and claims for an team member
@pytest.fixture
def setup_team_member_and_claims(jwt):
"""Set up a user with the team member role."""
staff_info = dict(TestUserInfo.user_staff_1)
user = factory_staff_user_model(user_info=staff_info)
claims = copy.deepcopy(TestJwtClaims.team_member_role.value)
claims['sub'] = str(user.external_id)

return user, claims


# Fixture for setting up user and claims for a user with no role
@pytest.fixture
def setup_unprivileged_user_and_claims(jwt):
"""Set up a user with the no role."""
staff_info = dict(TestUserInfo.user_staff_1)
user = factory_staff_user_model(user_info=staff_info)
claims = copy.deepcopy(TestJwtClaims.no_role.value)
claims['sub'] = str(user.external_id)

return user, claims
1 change: 0 additions & 1 deletion met-api/tests/unit/api/test_engagement_membership.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

from met_api.constants.membership_type import MembershipType
from met_api.utils.enums import ContentType, KeycloakGroupName, MembershipStatus
from tests.utilities.factory_scenarios import TestJwtClaims
from tests.utilities.factory_utils import (
factory_auth_header, factory_engagement_model, factory_membership_model, factory_staff_user_model)

Expand Down
3 changes: 1 addition & 2 deletions met-api/tests/unit/api/test_survey.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from tests.utilities.factory_scenarios import TestJwtClaims, TestSurveyInfo, TestTenantInfo, TestUserInfo
from tests.utilities.factory_utils import (
factory_auth_header, factory_engagement_model, factory_membership_model, factory_staff_user_model,
factory_survey_model, factory_tenant_model, set_global_tenant)
factory_survey_model, set_global_tenant)


surveys_url = '/api/surveys/'
Expand Down Expand Up @@ -74,7 +74,6 @@ def test_create_survey_with_tenant(client, jwt, session,

# Create a tenant
tenant_data = TestTenantInfo.tenant2
tenant_model = factory_tenant_model(tenant_data)
tenant2_short_name = tenant_data['short_name']
tenant_2 = TenantModel.find_by_short_name(tenant2_short_name)
# Verify that the tenant was created successfully
Expand Down
2 changes: 1 addition & 1 deletion met-api/tests/unit/api/test_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

from met_api.constants.widget import WidgetType
from met_api.utils.enums import ContentType
from tests.utilities.factory_scenarios import TestJwtClaims, TestWidgetInfo, TestWidgetItemInfo
from tests.utilities.factory_scenarios import TestWidgetInfo, TestWidgetItemInfo
from tests.utilities.factory_utils import factory_auth_header, factory_engagement_model, factory_widget_model


Expand Down
4 changes: 2 additions & 2 deletions met-api/tests/unit/services/test_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
from met_api.services.widget_service import WidgetService
from tests.utilities.factory_scenarios import TestJwtClaims, TestUserInfo, TestWidgetInfo, TestWidgetItemInfo
from tests.utilities.factory_utils import (
factory_engagement_model, factory_widget_item_model, factory_widget_model, patch_token_info,
factory_staff_user_model)
factory_engagement_model, factory_staff_user_model, factory_widget_item_model, factory_widget_model,
patch_token_info)


fake = Faker()
Expand Down

0 comments on commit 94589fb

Please sign in to comment.