Skip to content

Commit

Permalink
Merge branch 'master' of github.com:ubclaunchpad/bounce into updated-…
Browse files Browse the repository at this point in the history
…club-search-capabilities
  • Loading branch information
bfbachmann committed Mar 23, 2019
2 parents 0bd4f2e + f52df3b commit 0c07f75
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 25 deletions.
36 changes: 28 additions & 8 deletions bounce/db/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import math

from sqlalchemy import Column, Integer, String, desc, func
from sqlalchemy import Column, Integer, String, desc, func, or_
from sqlalchemy.orm import relationship
from sqlalchemy.types import TIMESTAMP

Expand Down Expand Up @@ -62,23 +62,43 @@ def select_by_id(session, user_id):
return session.query(User).filter(User.identifier == user_id).first()


def search(session, query=None, page=0, size=MAX_SIZE):
"""Returns a list of clubs that contain content from the user's query"""
def search(session,
full_name=None,
username=None,
identifier=None,
email=None,
created_at=None,
page=0,
size=MAX_SIZE):
"""Returns a list of users that contain content from the user's query"""
# number used for offset is the
# page number multiplied by the size of each page

offset_num = page * size
users = session.query(User)

if query:
# show clubs that have a name that matches the query
users = users.filter(User.full_name.ilike(f'%{query}%'))
not_null_filters = []

if full_name:
not_null_filters.append(User.full_name.ilike(f'%{full_name}%'))
if username:
not_null_filters.append(User.username.ilike(f'%{username}%'))
if email:
not_null_filters.append(User.email.ilike(f'%{email}%'))
if identifier:
not_null_filters.append(User.id.ilike(f'%{identifier}%'))
if created_at:
not_null_filters.append(User.id.ilike(f'%{created_at}%'))

# TODO: implement search_vector functionality:
# users = users.filter(User.search_vector.match(query))
# Currently search_vector column isn't working properly

else:
# show clubs ordered by most recently created
if not not_null_filters:
# show users ordered by most recently created
users = users.order_by(desc(User.created_at))
else:
users = users.filter(or_(*not_null_filters))

result_count = users.count()
total_pages = math.ceil(result_count / size)
Expand Down
26 changes: 22 additions & 4 deletions bounce/server/api/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,18 +225,36 @@ async def get(self, session, request):
"""Handles a GET /club/search request by returning
users that contain content from the query."""

query = None
if 'query' in request.args:
query = request.args['query']
# pylint: disable=too-many-locals
full_name = None
username = None
email = None
identifier = None
created_at = None

if 'full_name' in request.args:
full_name = request.args['full_name']
if 'username' in request.args:
username = request.args['username']
if 'email' in request.args:
email = request.args['email']
if 'id' in request.args:
identifier = request.args['id']
if 'created_at' in request.args:
created_at = request.args['created at']
# pylint: enable=too-many-locals

page = int(request.args['page'])

size = int(request.args['size'])
if size > MAX_SIZE:
raise APIError('size too high', status=400)
if size < MIN_SIZE:
raise APIError('size too low', status=400)

queried_users, result_count, total_pages = user.search(
session, query, page, size)
session, full_name, email, identifier, username, created_at, page,
size)
if not queried_users:
# Failed to find users that match the query
raise APIError('No users match your query', status=404)
Expand Down
37 changes: 25 additions & 12 deletions bounce/server/resource/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,31 @@ class GetUserResponse(metaclass=ResourceMeta):
class SearchUsersRequest(metaclass=ResourceMeta):
"""Defines the schema for a GET /users/search request."""
__params__ = {
'query': {
'type': 'string',
},
'page': {
'type': 'string',
'default': '0',
'minimum': '0',
},
'size': {
'type': 'string',
'default': '20',
'minimum': '1',
'type': 'object',
'properties': {
'full_name': {
'type': 'string',
},
'id': {
'type': 'string',
},
'email': {
'type': 'string',
},
'username': {
'type': 'string',
},
'created_at': {
'type': 'string',
},
'page': {
'type': 'string',
'default': '0',
},
'size': {
'type': 'string',
'default': '20',
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion tests/api/endpoints/test_1_users_and_login.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ def test_paginate_users__failure(server):


def test_search_users__success(server):
_, response = server.app.test_client.get('/users/search?query=gin')
_, response = server.app.test_client.get(
'/users/search?username=gin&full_name=gin')
assert response.status == 200
body = response.json
assert len(body.get('results')) == 2
Expand Down

0 comments on commit 0c07f75

Please sign in to comment.