Skip to content

Commit

Permalink
19334 - relocate simple orgs route (#2703)
Browse files Browse the repository at this point in the history
- move /simple-orgs to /orgs/simple
- update order by for search orgs for full matching id to the top
- update order by for simple org search for full matching id to the top
  • Loading branch information
ochiu authored Feb 2, 2024
1 parent 4d99b5e commit 4424eaf
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 78 deletions.
15 changes: 12 additions & 3 deletions auth-api/src/auth_api/models/org.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"""
from typing import List
from flask import current_app
from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Integer, String, and_, cast, event, func, text
from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Integer, String, and_, cast, desc, event, func, text
from sqlalchemy.orm import contains_eager, relationship
from sqlalchemy.dialects.postgresql import UUID

Expand Down Expand Up @@ -153,11 +153,20 @@ def search_org(cls, search: OrgSearch, environment: str):
query = cls._search_by_business_identifier(query, search.business_identifier, environment)
query = cls._search_for_statuses(query, search.statuses)

pagination = query.order_by(Org.created.desc()) \
.paginate(per_page=search.limit, page=search.page)
query = cls.get_order_by(search, query)
pagination = query.paginate(per_page=search.limit, page=search.page)

return pagination.items, pagination.total

@classmethod
def get_order_by(cls, search, query):
"""Handle search query order by."""
# If searching by id, surface the perfect matches to the top
if search.id:
return query.order_by(desc(Org.id == search.id), Org.created.desc())

return query.order_by(Org.created.desc())

@classmethod
def search_orgs_by_business_identifier(cls,
business_identifier,
Expand Down
2 changes: 0 additions & 2 deletions auth-api/src/auth_api/resources/v1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
from .org_products import bp as org_products_bp
from .permissions import bp as permissions_bp
from .products import bp as products_bp
from .simple_org import bp as simple_org_bp
from .task import bp as task_bp
from .user import bp as user_bp
from .user_settings import bp as user_settings_bp
Expand Down Expand Up @@ -73,7 +72,6 @@ def init_app(self, app):
self.app.register_blueprint(org_products_bp)
self.app.register_blueprint(permissions_bp)
self.app.register_blueprint(products_bp)
self.app.register_blueprint(simple_org_bp)
self.app.register_blueprint(task_bp)
self.app.register_blueprint(user_bp)
self.app.register_blueprint(user_settings_bp)
Expand Down
34 changes: 33 additions & 1 deletion auth-api/src/auth_api/resources/v1/org.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from auth_api.models import Org as OrgModel
from auth_api.models.dataclass import Affiliation as AffiliationData
from auth_api.models.dataclass import DeleteAffiliationRequest
from auth_api.models.dataclass import SimpleOrgSearch
from auth_api.models.org import OrgSearch # noqa: I005; Not sure why isort doesn't like this
from auth_api.schemas import InvitationSchema, MembershipSchema
from auth_api.schemas import utils as schema_utils
Expand All @@ -33,11 +34,12 @@
from auth_api.services import Invitation as InvitationService
from auth_api.services import Membership as MembershipService
from auth_api.services import Org as OrgService
from auth_api.services import SimpleOrg as SimpleOrgService
from auth_api.services import User as UserService
from auth_api.services.authorization import Authorization as AuthorizationService
from auth_api.tracer import Tracer
from auth_api.utils.endpoints_enums import EndpointEnum
from auth_api.utils.enums import AccessType, NotificationType, OrgType, PatchActions, Status
from auth_api.utils.enums import AccessType, NotificationType, OrgStatus, OrgType, PatchActions, Status
from auth_api.utils.role_validator import validate_roles
from auth_api.utils.roles import ALL_ALLOWED_ROLES, CLIENT_ADMIN_ROLES, STAFF, USER, Role # noqa: I005
from auth_api.utils.util import get_request_environment
Expand Down Expand Up @@ -93,6 +95,36 @@ def search_organizations():
return response, status


@bp.route('/simple', methods=['GET', 'OPTIONS'])
@cross_origin(origins='*', methods=['GET'])
@TRACER.trace()
@_jwt.has_one_of_roles(
[Role.SYSTEM.value, Role.STAFF_VIEW_ACCOUNTS.value])
def search_simple_orgs():
"""Return simplified organization information."""
current_app.logger.info('<search_simple_orgs')

org_id = request.args.get('id', None)
page: int = int(request.args.get('page', '1'))
limit: int = int(request.args.get('limit', '10'))
name = request.args.get('name', None)
branch_name = request.args.get('branchName', None)
search_text = request.args.get('searchText', None)
status = request.args.get('status', OrgStatus.ACTIVE.value)

response, status = SimpleOrgService.search(SimpleOrgSearch(
id=org_id,
name=name,
branch_name=branch_name,
search_text=search_text,
status=status,
page=page,
limit=limit)), http_status.HTTP_200_OK

current_app.logger.info('>search_simple_orgs')
return jsonify(response), status


@bp.route('', methods=['POST'])
@cross_origin(origins='*')
@TRACER.trace()
Expand Down
58 changes: 0 additions & 58 deletions auth-api/src/auth_api/resources/v1/simple_org.py

This file was deleted.

12 changes: 11 additions & 1 deletion auth-api/src/auth_api/services/simple_org.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

from jinja2 import Environment, FileSystemLoader
from flask import current_app
from sqlalchemy import String, and_, func, or_
from sqlalchemy import String, and_, desc, func, or_

from auth_api.config import get_named_config
from auth_api.models import db
Expand Down Expand Up @@ -64,6 +64,7 @@ def search(cls, search_criteria: SimpleOrgSearch):
OrgModel.branch_name != ''))
))

query = cls.get_order_by(search_criteria, query)
pagination = query.paginate(per_page=search_criteria.limit,
page=search_criteria.page)

Expand All @@ -78,3 +79,12 @@ def search(cls, search_criteria: SimpleOrgSearch):
'items': org_list,
'total': pagination.total
}

@classmethod
def get_order_by(cls, search, query):
"""Handle search query order by."""
# If searching by id, surface the perfect matches to the top
if search.id:
return query.order_by(desc(OrgModel.id == search.id), OrgModel.created.desc())

return query.order_by(OrgModel.name)
2 changes: 1 addition & 1 deletion auth-api/tests/unit/api/test_cors_preflight.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ def test_preflight_user(app, client, jwt, session):

def test_preflight_simple_org(app, client, jwt, session):
"""Assert preflight responses for simple org are correct."""
rv = client.options('/api/v1/simple-orgs', headers={'Access-Control-Request-Method': 'GET'})
rv = client.options('/api/v1/orgs/simple', headers={'Access-Control-Request-Method': 'GET'})
assert rv.status_code == http_status.HTTP_200_OK
assert_access_control_headers(rv, '*', 'GET')

Expand Down
24 changes: 12 additions & 12 deletions auth-api/tests/unit/api/test_simple_org.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def test_simple_org_search(client, jwt, session, keycloak_mock): # pylint:disab
headers = factory_auth_header(jwt=jwt, claims=TestJwtClaims.staff_view_accounts_role)

# Assert status filter by inactive orgs
rv = client.get(f'/api/v1/simple-orgs?status={OrgStatus.INACTIVE.value}',
rv = client.get(f'/api/v1/orgs/simple?status={OrgStatus.INACTIVE.value}',
headers=headers, content_type='application/json')

result = rv.json
Expand All @@ -78,7 +78,7 @@ def test_simple_org_search(client, jwt, session, keycloak_mock): # pylint:disab
assert_simple_org(result['items'][0], org_inactive)

# Assert default search - returns active orgs
rv = client.get('/api/v1/simple-orgs', headers=headers, content_type='application/json')
rv = client.get('/api/v1/orgs/simple', headers=headers, content_type='application/json')

result = rv.json
assert rv.status_code == http_status.HTTP_200_OK
Expand All @@ -93,7 +93,7 @@ def test_simple_org_search(client, jwt, session, keycloak_mock): # pylint:disab
assert_simple_org(result['items'][3], org_no_branch_2)

# Assert search id
rv = client.get(f'/api/v1/simple-orgs?id={org_no_branch_1.id}', headers=headers, content_type='application/json')
rv = client.get(f'/api/v1/orgs/simple?id={org_no_branch_1.id}', headers=headers, content_type='application/json')

result = rv.json
assert rv.status_code == http_status.HTTP_200_OK
Expand All @@ -105,7 +105,7 @@ def test_simple_org_search(client, jwt, session, keycloak_mock): # pylint:disab
assert_simple_org(result['items'][0], org_no_branch_1)

# Assert search id
rv = client.get(f'/api/v1/simple-orgs?id={org_no_branch_1.id}', headers=headers, content_type='application/json')
rv = client.get(f'/api/v1/orgs/simple?id={org_no_branch_1.id}', headers=headers, content_type='application/json')

result = rv.json
assert rv.status_code == http_status.HTTP_200_OK
Expand All @@ -117,7 +117,7 @@ def test_simple_org_search(client, jwt, session, keycloak_mock): # pylint:disab
assert_simple_org(result['items'][0], org_no_branch_1)

# Assert search name
rv = client.get('/api/v1/simple-orgs?name=Name 2', headers=headers, content_type='application/json')
rv = client.get('/api/v1/orgs/simple?name=Name 2', headers=headers, content_type='application/json')

result = rv.json
assert rv.status_code == http_status.HTTP_200_OK
Expand All @@ -130,7 +130,7 @@ def test_simple_org_search(client, jwt, session, keycloak_mock): # pylint:disab
assert_simple_org(result['items'][1], org_no_branch_2)

# Assert search branch name
rv = client.get('/api/v1/simple-orgs?branchName=branch', headers=headers, content_type='application/json')
rv = client.get('/api/v1/orgs/simple?branchName=branch', headers=headers, content_type='application/json')

result = rv.json
assert rv.status_code == http_status.HTTP_200_OK
Expand All @@ -143,7 +143,7 @@ def test_simple_org_search(client, jwt, session, keycloak_mock): # pylint:disab
assert_simple_org(result['items'][1], org_branch_2)

# Assert search branch name
rv = client.get('/api/v1/simple-orgs?branchName=ch 1', headers=headers, content_type='application/json')
rv = client.get('/api/v1/orgs/simple?branchName=ch 1', headers=headers, content_type='application/json')

result = rv.json
assert rv.status_code == http_status.HTTP_200_OK
Expand All @@ -155,7 +155,7 @@ def test_simple_org_search(client, jwt, session, keycloak_mock): # pylint:disab
assert_simple_org(result['items'][0], org_branch_1)

# Assert search text with id
rv = client.get(f'/api/v1/simple-orgs?searchText={org_no_branch_2.id}', headers=headers,
rv = client.get(f'/api/v1/orgs/simple?searchText={org_no_branch_2.id}', headers=headers,
content_type='application/json')

result = rv.json
Expand All @@ -168,7 +168,7 @@ def test_simple_org_search(client, jwt, session, keycloak_mock): # pylint:disab
assert_simple_org(result['items'][0], org_no_branch_2)

# Assert search text with name
rv = client.get('/api/v1/simple-orgs?searchText=name 1', headers=headers, content_type='application/json')
rv = client.get('/api/v1/orgs/simple?searchText=name 1', headers=headers, content_type='application/json')

result = rv.json
assert rv.status_code == http_status.HTTP_200_OK
Expand All @@ -181,7 +181,7 @@ def test_simple_org_search(client, jwt, session, keycloak_mock): # pylint:disab
assert_simple_org(result['items'][1], org_no_branch_1)

# Assert search text with branch name
rv = client.get('/api/v1/simple-orgs?searchText=ch 1', headers=headers, content_type='application/json')
rv = client.get('/api/v1/orgs/simple?searchText=ch 1', headers=headers, content_type='application/json')

result = rv.json
assert rv.status_code == http_status.HTTP_200_OK
Expand All @@ -193,7 +193,7 @@ def test_simple_org_search(client, jwt, session, keycloak_mock): # pylint:disab
assert_simple_org(result['items'][0], org_branch_1)

# Assert page 1
rv = client.get('/api/v1/simple-orgs?page=1&limit=1', headers=headers, content_type='application/json')
rv = client.get('/api/v1/orgs/simple?page=1&limit=1', headers=headers, content_type='application/json')

result = rv.json
assert rv.status_code == http_status.HTTP_200_OK
Expand All @@ -205,7 +205,7 @@ def test_simple_org_search(client, jwt, session, keycloak_mock): # pylint:disab
assert_simple_org(result['items'][0], org_branch_1)

# Assert page 2
rv = client.get('/api/v1/simple-orgs?page=2&limit=1', headers=headers, content_type='application/json')
rv = client.get('/api/v1/orgs/simple?page=2&limit=1', headers=headers, content_type='application/json')

result = rv.json
assert rv.status_code == http_status.HTTP_200_OK
Expand Down

0 comments on commit 4424eaf

Please sign in to comment.