Skip to content

Commit

Permalink
Feat: POST and GET /user/personal_background
Browse files Browse the repository at this point in the history
  • Loading branch information
mtreacy002 committed Jul 21, 2020
1 parent cfcfa93 commit 3099657
Show file tree
Hide file tree
Showing 7 changed files with 322 additions and 14 deletions.
106 changes: 106 additions & 0 deletions app/api/dao/personal_background.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
from http import HTTPStatus
from flask import json
from app.database.models.bit_schema.personal_background import PersonalBackgroundModel
from app import messages
from app.api.request_api_utils import AUTH_COOKIE


class PersonalBackgroundDAO:

"""Data Access Object for Personal_Background functionalities"""

@staticmethod
def create_user_personal_background(data):
"""Creates a personal_background instance for a new registered user.
Arguments:
data: A list containing user's id, and user's background details (gender,
age, ethnicity, sexual_orientation, religion, physical_ability, mental_ability,
socio_economic, highest_education, years_of_experience, others) as well as
whether or not user agrees to make their personal background information
public to other members of BridgeInTech.
Returns:
A dictionary containing "message" which indicates whether or not the user_exension
was created successfully and "code" for the HTTP response code.
"""

user_id = AUTH_COOKIE["user_id"].value,

existing_personal_background = PersonalBackgroundModel.find_by_user_id(user_id)
if existing_personal_background:
return messages.PERSONAL_BACKGROUND_OF_USER_ALREADY_EXIST, HTTPStatus.CONFLICT

try:
personal_background = PersonalBackgroundModel(
user_id=user_id,
gender=data["gender"],
age=data["age"],
ethnicity=data["ethnicity"],
sexual_orientation=data["sexual_orientation"],
religion=data["religion"],
physical_ability=data["physical_ability"],
mental_ability=data["mental_ability"],
socio_economic=data["socio_economic"],
highest_education=data["highest_education"],
years_of_experience=data["years_of_experience"],
)
personal_background.others = {
"gender_other": data["gender_other"],
"age_other": data["age_other"],
"ethnicity_other": data["ethnicity_other"],
"sexual_orientation_other": data["sexual_orientation_other"],
"religion_other": data["religion_other"],
"physical_ability_other": data["physical_ability_other"],
"mental_ability_other": data["mental_ability_other"],
"socio_economic_other": data["socio_economic_other"],
"highest_education_other": data["highest_education_other"],
"years_of_experience_other": data["years_of_experience_other"]
}
personal_background.is_public = data["is_public"]
except KeyError as e:
return e, HTTPStatus.BAD_REQUEST

personal_background.save_to_db()

return messages.PERSONAL_BACKGROUND_SUCCESSFULLY_CREATED, HTTPStatus.CREATED


@staticmethod
def get_user_personal_background_info(user_id):
"""Retrieves a user's perrsonal background information using a specified ID.
Arguments:
user_id: The ID of the user to be searched.
Returns:
The PersonalBackgroundModel class of the user whose ID was searched, containing their additional information.
"""

result = PersonalBackgroundModel.find_by_user_id(user_id)
if result:
return {
"user_id": result.user_id,
"gender": result.gender.name,
"age": result.age.name,
"ethnicity": result.ethnicity.name,
"sexual_orientation": result.sexual_orientation.name,
"religion": result.religion.name,
"physical_ability": result.physical_ability.name,
"mental_ability": result.mental_ability.name,
"socio_economic": result.socio_economic.name,
"highest_education": result.highest_education.name,
"years_of_experience": result.years_of_experience.name,
"gender_other": result.others["gender_other"],
"age_other": result.others["age_other"],
"ethnicity_other": result.others["ethnicity_other"],
"sexual_orientation_other": result.others["sexual_orientation_other"],
"religion_other": result.others["religion_other"],
"physical_ability_other": result.others["physical_ability_other"],
"mental_ability_other": result.others["mental_ability_other"],
"socio_economic_other": result.others["socio_economic_other"],
"highest_education_other": result.others["highest_education_other"],
"years_of_experience_other": result.others["years_of_experience_other"],
"is_public": result.is_public
}

8 changes: 5 additions & 3 deletions app/api/dao/user_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ def create_user_additional_info(data):
the user is representing an organization, as well as their timezone
Returns:
A dictionary containing "message" which indicates whether or not the user_exension was created successfully and "code" for the HTTP response code.
A dictionary containing "message" which indicates whether or not
the user_exension was created successfully and "code" for the HTTP response code.
"""

try:
Expand Down Expand Up @@ -60,7 +61,7 @@ def get_user_additional_data_info(user_id):
user_id: The ID of the user to be searched.
Returns:
The UserModel class of the user whose ID was searched, containing their additional information.
The UserExtensionModel class of the user whose ID was searched, containing their additional information.
"""

result = UserExtensionModel.find_by_user_id(user_id)
Expand All @@ -84,7 +85,8 @@ def update_user_additional_info(data):
the user is representing an organization, as well as their timezone
Returns:
A dictionary containing "message" which indicates whether or not the user_exension was created successfully and "code" for the HTTP response code.
A dictionary containing "message" which indicates whether or not
the user_exension was updated successfully and "code" for the HTTP response code.
"""

try:
Expand Down
60 changes: 59 additions & 1 deletion app/api/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ def add_models_to_namespace(api_namespace):
api_namespace.models[update_user_details_request_body_model.name] = update_user_details_request_body_model
api_namespace.models[get_user_extension_response_model.name] = get_user_extension_response_model
api_namespace.models[user_extension_request_body_model.name] = user_extension_request_body_model

api_namespace.models[get_user_personal_background_response_model.name] = get_user_personal_background_response_model
api_namespace.models[user_personal_background_api_model.name] = user_personal_background_api_model

register_user_api_model = Model(
"User registration model",
{
Expand Down Expand Up @@ -151,3 +153,59 @@ def add_models_to_namespace(api_namespace):
"personal_website": fields.String(required=False, description="personal_website"),
}
)

get_user_personal_background_response_model = Model(
"Retrieve personal background infomation response data model",
{
"user_id": fields.Integer(required=True, description="user_id"),
"gender": fields.String(required=True, description="gender"),
"age": fields.String(required=True, description="age"),
"ethnicity": fields.String(required=True, description="ethnicity"),
"sexual_orientation": fields.String(required=True, description="sexual_orientation"),
"religion": fields.String(required=True, description="religion"),
"physical_ability": fields.String(required=True, description="physical_ability"),
"mental_ability": fields.String(required=True, description="mental_ability"),
"socio_economic": fields.String(required=True, description="socio_economic"),
"highest_education": fields.String(required=True, description="highest_education"),
"years_of_experience": fields.String(required=True, description="years_of_experience"),
"others": fields.String(required=True, description="others"),
"gender_other": fields.String(required=False, description="gender_other"),
"age_other": fields.String(required=False, description="age_other"),
"ethnicity_other": fields.String(required=False, description="ethnicity_other"),
"sexual_orientation_other": fields.String(required=False, description="sexual_orientation_other"),
"religion_other": fields.String(required=False, description="religion_other"),
"physical_ability_other": fields.String(required=False, description="physical_ability_other"),
"mental_ability_other": fields.String(required=False, description="mental_ability_other"),
"socio_economic_other": fields.String(required=False, description="socio_economic_other"),
"highest_education_other": fields.String(required=False, description="highest_education_other"),
"years_of_experience_other": fields.String(required=False, description="years_of_experience_other"),
"is_public": fields.Boolean(required=True, description="is_public"),
}
)

user_personal_background_api_model = Model(
"Create or update personal background information request model",
{
"gender": fields.String(required=True, description="gender"),
"age": fields.String(required=True, description="age"),
"ethnicity": fields.String(required=True, description="ethnicity"),
"sexual_orientation": fields.String(required=True, description="sexual_orientation"),
"religion": fields.String(required=True, description="religion"),
"physical_ability": fields.String(required=True, description="physical_ability"),
"mental_ability": fields.String(required=True, description="mental_ability"),
"socio_economic": fields.String(required=True, description="socio_economic"),
"highest_education": fields.String(required=True, description="highest_education"),
"years_of_experience": fields.String(required=True, description="years_of_experience"),
"gender_other": fields.String(required=False, description="gender_other"),
"age_other": fields.String(required=False, description="age_other"),
"ethnicity_other": fields.String(required=False, description="ethnicity_other"),
"sexual_orientation_other": fields.String(required=False, description="sexual_orientation_other"),
"religion_other": fields.String(required=False, description="religion_other"),
"physical_ability_other": fields.String(required=False, description="physical_ability_other"),
"mental_ability_other": fields.String(required=False, description="mental_ability_other"),
"socio_economic_other": fields.String(required=False, description="socio_economic_other"),
"highest_education_other": fields.String(required=False, description="highest_education_other"),
"years_of_experience_other": fields.String(required=False, description="years_of_experience_other"),
"is_public": fields.Boolean(required=True, description="is_public"),
}
)
101 changes: 95 additions & 6 deletions app/api/resources/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from app.api.resources.common import auth_header_parser
from app.api.models.user import *
from app.api.dao.user_extension import UserExtensionDAO
from app.api.dao.personal_background import PersonalBackgroundDAO
from app.utils.validation_utils import expected_fields_validator
from app.database.models.bit_schema.user_extension import UserExtensionModel

Expand Down Expand Up @@ -169,7 +170,7 @@ def put(cls):
data = request.json

if not data:
return messages.NO_DATA_FOR_UPDATING_PROFILE_WAS_SENT
return messages.NO_DATA_FOR_UPDATING_PROFILE_WAS_SENT, HTTPStatus.BAD_REQUEST

is_field_valid = expected_fields_validator(data, update_user_details_request_body_model)
if not is_field_valid.get("is_field_valid"):
Expand Down Expand Up @@ -269,7 +270,7 @@ def post(cls):
if not is_wrong_token:
data = request.json
if not data:
return messages.NO_DATA_FOR_UPDATING_PROFILE_WAS_SENT
return messages.NO_DATA_FOR_UPDATING_PROFILE_WAS_SENT, HTTPStatus.BAD_REQUEST

is_field_valid = expected_fields_validator(data, user_extension_request_body_model)
if not is_field_valid.get("is_field_valid"):
Expand All @@ -287,7 +288,7 @@ def post(cls):
@classmethod
@users_ns.doc("update_user_additional_info")
@users_ns.response(
HTTPStatus.CREATED, f"{messages.ADDITIONAL_INFO_SUCCESSFULLY_CREATED}"
HTTPStatus.OK, f"{messages.ADDITIONAL_INFO_SUCCESSFULLY_UPDATED}"
)
@users_ns.response(
HTTPStatus.BAD_REQUEST,
Expand Down Expand Up @@ -320,7 +321,7 @@ def put(cls):
if not is_wrong_token:
data = request.json
if not data:
return messages.NO_DATA_FOR_UPDATING_PROFILE_WAS_SENT
return messages.NO_DATA_FOR_UPDATING_PROFILE_WAS_SENT, HTTPStatus.BAD_REQUEST

is_field_valid = expected_fields_validator(data, user_extension_request_body_model)
if not is_field_valid.get("is_field_valid"):
Expand All @@ -330,8 +331,96 @@ def put(cls):
if is_not_valid:
return is_not_valid, HTTPStatus.BAD_REQUEST

return UserExtensionDAO.update_user_additional_info(data);
return UserExtensionDAO.update_user_additional_info(data)

return is_wrong_token



@users_ns.doc(
responses={
HTTPStatus.INTERNAL_SERVER_ERROR: f"{messages.INTERNAL_SERVER_ERROR['message']}"
}
)
@users_ns.response(
HTTPStatus.UNAUTHORIZED,
f"{messages.TOKEN_HAS_EXPIRED}\n"
f"{messages.TOKEN_IS_INVALID}\n"
f"{messages.AUTHORISATION_TOKEN_IS_MISSING}"
)
@users_ns.response(HTTPStatus.INTERNAL_SERVER_ERROR, f"{messages.INTERNAL_SERVER_ERROR}")
@users_ns.route("user/personal_background")
class MyProfilePersonalBackground(Resource):
@classmethod
@users_ns.doc("get_user_personal_background")
@users_ns.response(HTTPStatus.OK, "Successful request", get_user_personal_background_response_model)
@users_ns.response(HTTPStatus.BAD_REQUEST, "Invalid input.")
@users_ns.response(HTTPStatus.NOT_FOUND, f"{messages.PERSONAL_BACKGROUND_DOES_NOT_EXIST}")
@users_ns.expect(auth_header_parser, validate=True)
def get(cls):
"""
Returns personal background information of current user
A user with valid access token can use this endpoint to view their personal background information details.
The endpoint doesn't take any other input. This request only accessible once user retrieve their user_id
by sending GET /user/personal_details.
"""

token = request.headers.environ["HTTP_AUTHORIZATION"]

is_wrong_token = validate_token(token)

if not is_wrong_token:
result = PersonalBackgroundDAO.get_user_personal_background_info(AUTH_COOKIE["user_id"].value)
if not result:
return messages.PERSONAL_BACKGROUND_DOES_NOT_EXIST, HTTPStatus.NOT_FOUND
return result
return is_wrong_token


@classmethod
@users_ns.doc("create_user_personal_background")
@users_ns.response(
HTTPStatus.CREATED, f"{messages.PERSONAL_BACKGROUND_SUCCESSFULLY_CREATED}"
)
@users_ns.response(
HTTPStatus.BAD_REQUEST,
f"{messages.USER_ID_IS_NOT_VALID}\n"
f"{messages.PERSONAL_BACKGROUND_DATA_HAS_MISSING_FIELD}\n"
f"{messages.UNEXPECTED_INPUT}"
)
@users_ns.response(
HTTPStatus.INTERNAL_SERVER_ERROR, f"{messages.INTERNAL_SERVER_ERROR}"
)
@users_ns.expect(auth_header_parser, user_personal_background_api_model, validate=True)
def post(cls):
"""
Creates user personal background.
A user with valid access token can use this endpoint to add personal background information to their own data.
The endpoint takes any of the given parameters (gender, age, ethnicity, sexusl_orientation, religion, physical_ability,
mental_ability, socio_economic, highest_education, years_of_experience enums), others (dictionary of any additional
information the user added from any of the background fields) and is_public (boolean value true or false which
indicates whether or not the user agrees to make their personal background information public to other BridgeInTech members).
The response contains a success or error message. This request only accessible once user retrieve their user_id
by sending GET /user/personal_details.
"""

token = request.headers.environ["HTTP_AUTHORIZATION"]
is_wrong_token = validate_token(token)

if not is_wrong_token:
data = request.json
if not data:
return messages.NO_DATA_FOR_UPDATING_PROFILE_WAS_SENT, HTTPStatus.BAD_REQUEST

is_field_valid = expected_fields_validator(data, user_personal_background_api_model)
if not is_field_valid.get("is_field_valid"):
return is_field_valid.get("message"), HTTPStatus.BAD_REQUEST

is_not_valid = validate_update_personal_background_info_request(data)
if is_not_valid:
return is_not_valid, HTTPStatus.BAD_REQUEST

return PersonalBackgroundDAO.create_user_personal_background(data)

return is_wrong_token
Loading

0 comments on commit 3099657

Please sign in to comment.