diff --git a/.gitattributes b/.gitattributes index 3687a743119c44f3160b010e343b17c4dbc575ba..a8453356a5818eb58e1c32a64e7024210c355e82 100644 --- a/.gitattributes +++ b/.gitattributes @@ -36,3 +36,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text tests/test_controller/user_file/quangphuc@gmail.com/demo1.pdf filter=lfs diff=lfs merge=lfs -text tests/test_service/user_file/quangphuc@gmail.com/demo1.pdf filter=lfs diff=lfs merge=lfs -text tests/user_file/quangphuc@gmail.com/demo1.pdf filter=lfs diff=lfs merge=lfs -text +vector_database/vonhuy5112002@gmail.com/chroma.sqlite3 filter=lfs diff=lfs merge=lfs -text +vector_database/vonhuy777@gmail.com/chroma.sqlite3 filter=lfs diff=lfs merge=lfs -text diff --git a/auth/__pycache__/authentication.cpython-310.pyc b/auth/__pycache__/authentication.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9af4d22bf32d7b02719ff3170e47a2349eff7e89 Binary files /dev/null and b/auth/__pycache__/authentication.cpython-310.pyc differ diff --git a/auth/__pycache__/authentication.cpython-311.pyc b/auth/__pycache__/authentication.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5055416c354805c3a0eb61db4242eff66aa2ac4e Binary files /dev/null and b/auth/__pycache__/authentication.cpython-311.pyc differ diff --git a/auth/authentication.py b/auth/authentication.py new file mode 100644 index 0000000000000000000000000000000000000000..16be3a6b580142ac85b68e62227400945db66aa0 --- /dev/null +++ b/auth/authentication.py @@ -0,0 +1,133 @@ +import time +from typing import Dict +import jwt +import secrets +import logging +from fastapi import Depends, HTTPException +import base64 +from datetime import datetime, timedelta +from repository import UserRepository, UserLoginRepository +import string, random + +def check_token_is_valid(token): + check = UserRepository.getEmailUserByAccessToken(token) + if check is None: + return False + return True + +def unique_string(byte: int = 8) -> str: + return secrets.token_urlsafe(byte) +JWT_SECRET = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7" +JWT_ALGORITHM = "HS512" +SECRET_KEY="8deadce9449770680910741063cd0a3fe0acb62a8978661f421bbcbb66dc41f1" + +def token_response(token: str): + return { + "access_token": token + } +def str_encode(string: str) -> str: + return base64.b85encode(string.encode('ascii')).decode('ascii') + +def get_token_payload(token: str, secret: str, algo: str): + try: + payload = jwt.decode(token, secret, algorithms=algo) + except Exception as jwt_exec: + logging.debug(f"JWT Error: {str(jwt_exec)}") + payload = None + return payload + +from datetime import datetime +def generate_token(payload: dict, secret: str, algo: str, expiry: timedelta): + expire = datetime.now() + expiry + payload.update({"exp": expire}) + return jwt.encode(payload, secret, algorithm=algo) + +def str_decode(string: str) -> str: + return base64.b85decode(string.encode('ascii')).decode('ascii') + +def generate_random_string(length=12): + characters = string.ascii_letters + string.digits + random_string = ''.join(random.choice(characters) for i in range(length)) + return random_string + +import pytz +from datetime import datetime +def signJWT(user_email: str) -> Dict[str, str]: + rt_expires = timedelta(minutes=3) + refresh_key = unique_string(100) + access_key = unique_string(50) + at_expires = timedelta(minutes=2) + at_payload = { + "sub": str_encode(str(user_email)), + 'a': access_key, + } + access_token = generate_token(at_payload, JWT_SECRET, JWT_ALGORITHM, at_expires) + rt_payload = {"sub": str_encode(str(user_email)), "t": refresh_key, 'a': access_key} + refresh_token = generate_token(rt_payload, SECRET_KEY,JWT_ALGORITHM, rt_expires) + expires_in = at_expires.seconds + vn_timezone = pytz.timezone('Asia/Ho_Chi_Minh') + current_time = datetime.now().replace(tzinfo=pytz.utc).astimezone(vn_timezone) + timedelta(seconds=expires_in) + formatted_time = current_time.strftime('%Y-%m-%d %H:%M:%S ') + existing_user = UserRepository.getUserByEmail(user_email) + if existing_user is None: + UserRepository.addUser(user_email, access_token, refresh_token, formatted_time) + else: + UserRepository.updateUserLogin(user_email, access_token, refresh_token, formatted_time) + user_record = UserRepository.getUserByEmail(user_email) + session_id = "" + if user_record: + session_id = generate_random_string() + existing_userlogin = UserLoginRepository.getUserLogin(user_email) + if existing_userlogin is None: + UserLoginRepository.addUserLogin(user_email,session_id=session_id) + else: + UserLoginRepository.updateUserLogin(user_email, session_id) + return { + "access_token": access_token, + "refresh_token": refresh_token, + "expires_in": at_expires.seconds, + "session_id": session_id + } + +def returnAccessToken(user_email: str, refresh_token: str) -> Dict[str, str]: + access_key = unique_string(50) + at_expires = timedelta(minutes=2) + at_payload = { + "sub": str_encode(str(user_email)), + 'a': access_key, + } + access_token = generate_token(at_payload, JWT_SECRET, JWT_ALGORITHM, at_expires) + user_record = UserRepository.getUserByEmail(user_email) + session_id = "" + if user_record: + email1 = user_record.email + if email1: + session_id = generate_random_string() + existing_userlogin = UserLoginRepository.getUserLogin(user_email) + if existing_userlogin is None: + UserLoginRepository.addUserLogin(user_email,session_id=session_id) + else: + UserLoginRepository.updateUserLogin(user_email,session_id) + return { + "access_token": access_token, + "refresh_token": refresh_token, + "expires_in": at_expires.seconds, + "session_id": session_id + } + +def decodeJWT(token: str) -> dict: + try: + decoded_token = jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM]) + return decoded_token if decoded_token["exp"] >= time.time() else None + except: + return {} + +def get_refresh_token(refresh_token,token_now, email): + token_payload = get_token_payload(refresh_token, SECRET_KEY, JWT_ALGORITHM) + if not token_payload: + raise HTTPException(status_code=400, detail="Invalid Request.") + exp = token_payload.get('exp') + if exp >= time.time() and token_payload: + return returnAccessToken(email,refresh_token) + elif not token_payload: + return signJWT(email) \ No newline at end of file diff --git a/controller/ChatController.py b/controller/ChatController.py new file mode 100644 index 0000000000000000000000000000000000000000..ec093e874c887524e12bc6a50f9dad77ed53b7db --- /dev/null +++ b/controller/ChatController.py @@ -0,0 +1,36 @@ +from fastapi import APIRouter, Form, Request +from service import ChatService +from request import RequestChat +from typing import Optional +from fastapi.requests import Request +from function import support_function +from response import ResponseChat as res +router = APIRouter() + +@router.post("/chatbot/query/", tags=["Chat"]) +async def handle_query2_upgrade_old(request: Request, + user_id: str = Form(None), + text_all: str = Form(...), + question: Optional[str] = Form(None), + chat_name: Optional[str] = Form(None)): + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + request = RequestChat.RequestQuery2UpgradeOld(user_id=user_id, text_all=text_all, question=question, chat_name=chat_name) + return ChatService.query2_upgrade_old(request) + +@router.get("/chatbot/extract_file/", tags=["Chat"]) +async def extract_file(user_id: str): + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + request = RequestChat.RequestExtractFile(user_id=user_id) + return ChatService.extract_file(request) + +@router.get("/chatbot/generate_question/",tags=["Chat"]) +async def generate_question(user_id: str): + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + request = RequestChat.RequestGenerateQuestion(user_id=user_id) + return ChatService.generate_question(request) \ No newline at end of file diff --git a/controller/DefaultController.py b/controller/DefaultController.py new file mode 100644 index 0000000000000000000000000000000000000000..10b6523533a65495558dcbbae24adb1595d711fe --- /dev/null +++ b/controller/DefaultController.py @@ -0,0 +1,62 @@ +from fastapi import HTTPException, Depends, Query,APIRouter +from service import DefaultService +from request import RequestDefault +from request import RequestDefault as req +from function import support_function +from auth.authentication import decodeJWT +from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials +from fastapi.responses import JSONResponse +from auth import authentication +from fastapi.requests import Request +from response import ResponseDefault as res +from fastapi import File, UploadFile, Form +router = APIRouter() + +@router.get("/is_me/", tags=["Default"]) +async def is_me(token: str = Query(...)): + if token.strip() == "" or token is None: + return res.ReponseError(status=400, + data=res.Message(message="Token field is required.")) + if token.lower() == "none": + return res.ReponseError(status=400, + data=res.Message(message="Token cannot be None.")) + if not isinstance(token, str): + return res.ReponseError(status=400, + data=res.Message(message="Token must be a non-empty string.")) + try: + float(token) + return res.ReponseError(status=400, + data=res.Message(message="Token must be a string, not a number.")) + except ValueError: + pass + request = RequestDefault.RequestIsMe(token=token) + return DefaultService.is_me(request) + +@router.post('/create_firebase_user_google', tags=["Default"]) +async def get_or_create_firebase_user(request: RequestDefault.RequestCreateFireBaseUserGoogle): + email = request.email + check = support_function.check_value_email_controller(request.email) + if check is not True: + return check + return DefaultService.create_firebase_user(request) + +@router.get("/info_user", tags=["Default"]) +async def get_user(user_id: str = Query(None)): + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + request = RequestDefault.RequestInfoUser(user_id=user_id) + return DefaultService.info_user(request) + +ALLOWED_IMAGE_EXTENSIONS = {"jpeg", "jpg", "png"} + +def allowed_file(filename: str) -> bool: + return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_IMAGE_EXTENSIONS + +@router.post("/upload_image/", tags=["Default"]) +async def upload_image(user_id: str = Form(None), file: UploadFile = File(...)): + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + request = req.RequestUpLoadImage(user_id=user_id, files= file) + return DefaultService.upload_image_service(request) \ No newline at end of file diff --git a/controller/FileController.py b/controller/FileController.py new file mode 100644 index 0000000000000000000000000000000000000000..d82972cfaf3d35536687b16944ad079a2dd8921a --- /dev/null +++ b/controller/FileController.py @@ -0,0 +1,64 @@ +from fastapi import APIRouter, Form, File, UploadFile,Query +from typing import List,Optional +from service import FileService +from function import support_function +from fastapi import HTTPException +from response import ResponseFile as res +from request import RequestFile +router = APIRouter() + +ALLOWED_EXTENSIONS = {'csv', 'txt', 'doc', 'docx', 'pdf', 'xlsx', 'pptx', 'json', 'html'} +def allowed_file(filename): + return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS + +@router.delete("/delete_all_file/", tags=["File"]) +async def delete_folder(request: RequestFile.RequestDeleteAllFile): + check = support_function.check_value_user_id_controller(request.user_id) + if check is not True: + return check + # request = RequestFile.RequestDeleteAllFile(user_id=user_id) + return FileService.deleteAllFile(request) + +@router.get("/list_name_files/", tags=["File"]) +async def get_name(user_id: str): + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + request = RequestFile.RequestGetNameFile(user_id=user_id) + return FileService.listNameFiles(request) + +@router.delete("/delete_one_file/", tags=["File"]) +async def delete_one_file(request: RequestFile.RequestDeleteFile): + user_id = request.user_id + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + name_file = request.name_file + if name_file is None or name_file.strip() == "": + return res.ReponseError(status=400, + data=res.Message(message="Name file is required.")) + return FileService.deleteFile(request) + +@router.post("/chatbot/download_folder/", tags=["File"]) +async def download_folder_from_dropbox(request: RequestFile.RequestDownLoadFolder): + user_id = request.user_id + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + return FileService.download_folder(request) + +@router.post("/chatbot/download_files/", tags=["File"]) +async def download_file_by_id(request: RequestFile.RequestDownLoadFile): + user_id = request.user_id + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + return FileService.download_file(request) + +@router.post("/upload_files/", tags=["File"]) +async def upload_files_dropbox(user_id: str = Form(None), files: Optional[List[UploadFile]] = File(None)): + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + request = RequestFile.RequestUploadFile(files=files, user_id=user_id) + return FileService.upload_files(request) \ No newline at end of file diff --git a/controller/LoginController.py b/controller/LoginController.py new file mode 100644 index 0000000000000000000000000000000000000000..d70cfa94aec47cf1342f555ea81935f6370ba477 --- /dev/null +++ b/controller/LoginController.py @@ -0,0 +1,144 @@ +from fastapi import APIRouter, Query +from request import RequestLogin +from response import ResponseLogin as res +from service import LoginService +from function import support_function +from fastapi import HTTPException +from response import ResponseLogin as res +router = APIRouter() + +@router.post('/login', tags=["Login"]) +async def login(request: RequestLogin.RequestLoginEmail): + email = request.email + check = support_function.check_value_email_controller(email) + if check is not True: + return check + password = request.password + if password is None or password.strip() == "": + return res.ReponseError(status=400, + data=res.Message(message="Password is required.")) + return LoginService.login(request) + +@router.post('/login_google', tags=["Login"]) +async def login_google(request: RequestLogin.RequestLoginGoogle): + email = request.email + token_google = request.token_google + check = support_function.check_value_email_controller(email) + if check is not True: + return check + if token_google is None or token_google.strip() == "": + return res.ReponseError(status=400, + data=res.Message(message="token_google oauth2 is required.")) + if token_google.isdigit(): + return res.ReponseError(status=400, + data=res.Message(message="token_google must be a string, not a number.")) + return LoginService.login_google(request) + +@router.post("/update_user_info", tags=["Login"]) +async def update_user_info(request: RequestLogin.RequestUpdateUserInfo): + user_id = request.user_id + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + uid = request.uid + email = request.email + display_name = request.display_name + photo_url = request.photo_url + if uid is None or uid.strip() == "": + return res.ReponseError(status=400, + data=res.Message(message="uid field is required.")) + if email is None or email.strip() == "": + return res.ReponseError(status=400, + data=res.Message(message="email field is required.")) + if display_name is None or display_name.strip() == "": + return res.ReponseError(status=400, + data=res.Message(message="display_name field is required.")) + if photo_url is None or photo_url.strip() == "": + return res.ReponseError(status=400, + data=res.Message(message="photo_url field is required.")) + return LoginService.update_user_info(request) + +@router.get('/check_info_google', tags=["Login"]) +async def check_info_google(user_id: str = Query(None)): + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + request = RequestLogin.RequestCheckInfoGoogle(user_id=user_id) + return LoginService.check_info_google(request) + +@router.get('/check_info_google_signup', tags=["Login"]) +async def check_info_google_signup(email: str = None): + check = support_function.check_value_email_controller(email) + if check is not True: + return check + request = RequestLogin.RequestCheckInfoGoogleEmail(email=email) + return LoginService.check_info_google_email(request) + +@router.get('/check_state_login', tags=["Login"]) +async def check_state_login(user_id: str = Query(None), session_id_now: str = Query(None)): + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + if session_id_now is None or session_id_now.strip() == "": + return res.ReponseError(status=400, + data=res.Message(message="Session Id is required.")) + try: + int(session_id_now) + return res.ReponseError(status=400, + data=res.Message(message="Session Id must be a string, not a number.")) + except ValueError: + pass + request = RequestLogin.RequestCheckStateLogin(user_id=user_id, session_id_now=session_id_now) + return LoginService.check_state_login(request) + +@router.post('/sign_up', tags=["Login"]) +async def signup(request: RequestLogin.RequestSignUp): + email = request.email + check = support_function.check_value_email_controller(email) + if check is not True: + return check + password = request.password + if password is None or password.strip( )== "": + return res.ReponseError(status=400, + data=res.Message(message="Password is required.")) + return LoginService.sign_up(request) + +@router.post('/reset_password', tags=["Login"]) +async def reset_password(request: RequestLogin.RequestResetPassword): + email = request.email + check = support_function.check_value_email_controller(email) + if check is not True: + return check + return LoginService.reset_password(request) + +@router.put('/change_password', tags=["Login"]) +async def reset_password_firebase(request: RequestLogin.RequestChangePassword): + user_id = request.user_id + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + new_password = request.new_password + current_password = request.current_password + if new_password is None or new_password.strip() == "": + return res.ReponseError(status=400, + data=res.Message(message="New password field is required.")) + if current_password is None or current_password.strip() == "": + return res.ReponseError(status=400, + data=res.Message(message="Current password field is required.")) + return LoginService.change_password(request) + +@router.post('/refresh_token/', tags=["Login"]) +async def refresh_token_account(request: RequestLogin.RequestRefreshTokenLogin): + user_id = request.user_id + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + token = request.token + if token is None or token.strip() == "": + return res.ReponseError(status=400, + data=res.Message(message="token is required.")) + elif token.isdigit(): + return res.ReponseError(status=400, + data=res.Message(message="token must be string")) + + return LoginService.refresh_token(request) \ No newline at end of file diff --git a/controller/MySQLController.py b/controller/MySQLController.py new file mode 100644 index 0000000000000000000000000000000000000000..059b127a1b34a642b81dc275b337b2f68e174e33 --- /dev/null +++ b/controller/MySQLController.py @@ -0,0 +1,70 @@ +from fastapi import Query, APIRouter +from service import MySQLService +from request import RequestMySQL +from response import ResponseMySQL as res +from typing import Optional +from request import RequestMySQL as req +from function import support_function +from fastapi import HTTPException +router = APIRouter() + +@router.get("/render_chat_history", tags=["MySQL"]) +async def render_chat(user_id: Optional[str] = Query(None)): + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + request = RequestMySQL.RequestRenderChatHistory(user_id=user_id) + return MySQLService.render_chat_history(request) + +@router.get("/data_relevant", tags=["MySQL"]) +async def render_chat_1(chat_detail_id: str): + if chat_detail_id is None or chat_detail_id.strip() == "": + return res.ReponseError(status=400, + data=res.Message(message="Id field is required.")) + chat_detail_id = chat_detail_id.strip("'").strip('"') + try: + chat_detail_id_int = int(chat_detail_id) + except ValueError: + return res.ReponseError(status=400, + data=res.Message(message="Value must be an integer")) + if not support_function.is_positive_integer(chat_detail_id_int): + return res.ReponseError(status=400, + data=res.Message(message="Value must be greater than 0")) + request = req.RequestGetChatDetails(id=chat_detail_id) + return MySQLService.get_detail_chat_by_chat_id(request) + +@router.get("/load_chat_history", tags=["MySQL"]) +async def load_chat(chat_id: Optional[str] = Query(None), user_id: Optional[str] = Query(None)): + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + if chat_id is None or chat_id.strip() == "": + return res.ReponseError(status=400, + data=res.Message(message="Chat id field is required.")) + chat_id = chat_id.strip("'").strip('"') + try: + chat_id_int = int(chat_id) + except ValueError: + return res.ReponseError(status=400, + data=res.Message(message="Value must be an integer")) + if not support_function.is_positive_integer(chat_id_int): + return res.ReponseError(status=400, + data=res.Message(message="Value must be greater than 0")) + request = req.RequestLoadChatHistory(chat_id=chat_id,user_id = user_id) + return MySQLService.load_chat_history(request) + +@router.put("/edit_chat/", tags=["MySQL"]) +async def edit_chat(request: RequestMySQL.RequestEditNameChat): + user_id = request.user_id + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + return MySQLService.edit_chat(request) + +@router.delete("/delete_chat/", tags=["MySQL"]) +async def delete_chat(request: RequestMySQL.RequestDeleteChat): + user_id = request.user_id + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + return MySQLService.delete_chat(request) \ No newline at end of file diff --git a/controller/OTPController.py b/controller/OTPController.py new file mode 100644 index 0000000000000000000000000000000000000000..e16ae0d8bf2c4ecc83181c6278b01bf0fa6eac59 --- /dev/null +++ b/controller/OTPController.py @@ -0,0 +1,37 @@ +from fastapi import APIRouter +from function import support_function +from request import RequestOTP +from service import OTPService +from fastapi import HTTPException +from pydantic.error_wrappers import ErrorWrapper +from pydantic import BaseModel +from response import ResponseOTP as res +router = APIRouter() + +@router.post('/create_otp', tags=["OTP"]) +async def create_otp(request: RequestOTP.RequestCreateOTP): + email = request.email + check = support_function.check_value_email_controller(email) + if check is not True: + return check + return OTPService.createOTP(request) + +@router.post('/verify_otp', tags=["OTP"]) +async def verify_otp(request: RequestOTP.RequestVerifyOTP): + check = support_function.check_value_email_controller(request.email) + if check is not True: + return check + check_otp = support_function.check_value_otp(request.otp) + if check_otp is not True: + return check_otp + return OTPService.verifyOTP(request) + +@router.post('/verify_otp_reset_password', tags=["OTP"]) +async def verify_otp_reset(request: RequestOTP.RequestVerifyOTP): + check = support_function.check_value_email_controller(request.email) + if check is not True: + return check + check_otp = support_function.check_value_otp(request.otp) + if check_otp is not True: + return check_otp + return OTPService.verifyOTPReset(request) \ No newline at end of file diff --git a/controller/__pycache__/ChatController.cpython-310.pyc b/controller/__pycache__/ChatController.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2581e598adbda8c57e017237f6aa8c4da4b28426 Binary files /dev/null and b/controller/__pycache__/ChatController.cpython-310.pyc differ diff --git a/controller/__pycache__/ChatController.cpython-311.pyc b/controller/__pycache__/ChatController.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b561fe72289eadeed68793fb8ba7c363a2fae072 Binary files /dev/null and b/controller/__pycache__/ChatController.cpython-311.pyc differ diff --git a/controller/__pycache__/ChatController.py b/controller/__pycache__/ChatController.py new file mode 100644 index 0000000000000000000000000000000000000000..db2919f2097e9cac56ba1c749e09762e382e61f0 --- /dev/null +++ b/controller/__pycache__/ChatController.py @@ -0,0 +1,35 @@ +from fastapi import APIRouter, Form, Request +from service import ChatService +from request import RequestChat +from typing import Optional +from fastapi.requests import Request +from function import support_function +from response import ResponseChat as res +router = APIRouter() + +@router.post("/chatbot/query/", tags=["Chat"]) +async def handle_query2_upgrade_old(request: Request, + user_id: str = Form(None), + text_all: str = Form(...), question: Optional[str] = Form(None), + chat_name: Optional[str] = Form(None)): + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + request = RequestChat.RequestQuery2UpgradeOld(user_id=user_id, text_all=text_all, question=question, chat_name=chat_name) + return ChatService.query2_upgrade_old(request) + +@router.get("/chatbot/extract_file/", tags=["Chat"]) +async def extract_file(user_id: str): + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + request = RequestChat.RequestExtractFile(user_id=user_id) + return ChatService.extract_file(request) + +@router.get("/chatbot/generate_question/",tags=["Chat"]) +async def generate_question(user_id: str): + check = support_function.check_value_user_id_controller(user_id) + if check is not True: + return check + request = RequestChat.RequestGenerateQuestion(user_id=user_id) + return ChatService.generate_question(request) \ No newline at end of file diff --git a/controller/__pycache__/DefaultController.cpython-310.pyc b/controller/__pycache__/DefaultController.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a0512fd215f49aa6a0674cd02b9757db47ba24e9 Binary files /dev/null and b/controller/__pycache__/DefaultController.cpython-310.pyc differ diff --git a/controller/__pycache__/DefaultController.cpython-311.pyc b/controller/__pycache__/DefaultController.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aefcf79154c52c2ed6faf4e8631ac9eb9c13c26b Binary files /dev/null and b/controller/__pycache__/DefaultController.cpython-311.pyc differ diff --git a/controller/__pycache__/FileController.cpython-310.pyc b/controller/__pycache__/FileController.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..524e19948e45c5f2c078b912af8ca73e14e9eee6 Binary files /dev/null and b/controller/__pycache__/FileController.cpython-310.pyc differ diff --git a/controller/__pycache__/FileController.cpython-311.pyc b/controller/__pycache__/FileController.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c870ba061c3fe02da6ecc4032b53ebf23db9117f Binary files /dev/null and b/controller/__pycache__/FileController.cpython-311.pyc differ diff --git a/controller/__pycache__/LoginController.cpython-310.pyc b/controller/__pycache__/LoginController.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..29f7ddf9ecd9d9df56c480a0f9e36c1adf315efc Binary files /dev/null and b/controller/__pycache__/LoginController.cpython-310.pyc differ diff --git a/controller/__pycache__/LoginController.cpython-311.pyc b/controller/__pycache__/LoginController.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37fdb017f44fb36fe73dd76e71d30d530508c00c Binary files /dev/null and b/controller/__pycache__/LoginController.cpython-311.pyc differ diff --git a/controller/__pycache__/MySQLController.cpython-310.pyc b/controller/__pycache__/MySQLController.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..79ce95755d8ea1518e2a4c2dfc9806bb1f3a4f21 Binary files /dev/null and b/controller/__pycache__/MySQLController.cpython-310.pyc differ diff --git a/controller/__pycache__/MySQLController.cpython-311.pyc b/controller/__pycache__/MySQLController.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e8f872781f6f6221c3f8cdd7648e795f70d25a92 Binary files /dev/null and b/controller/__pycache__/MySQLController.cpython-311.pyc differ diff --git a/controller/__pycache__/OTPController.cpython-310.pyc b/controller/__pycache__/OTPController.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ee8d94c310f1465591b7287587175d3768617b3e Binary files /dev/null and b/controller/__pycache__/OTPController.cpython-310.pyc differ diff --git a/controller/__pycache__/OTPController.cpython-311.pyc b/controller/__pycache__/OTPController.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..97b0b284e88a1afd99c661fd019d59d8bfc10638 Binary files /dev/null and b/controller/__pycache__/OTPController.cpython-311.pyc differ diff --git a/entity/Database_Entity.py b/entity/Database_Entity.py new file mode 100644 index 0000000000000000000000000000000000000000..728e94f64b8d770fc2405c8d342f79e12c7be6d4 --- /dev/null +++ b/entity/Database_Entity.py @@ -0,0 +1,68 @@ +from sqlalchemy import Column, String, Text, DateTime, Integer, ForeignKey, TIMESTAMP +from sqlalchemy.orm import relationship +from sqlalchemy.orm import DeclarativeBase +from sqlalchemy.sql import func +class Base(DeclarativeBase): + pass + +class User(Base): + __tablename__ = 'users' + id = Column(Integer, primary_key=True, autoincrement=True) + email = Column(String(255)) + access_token = Column(Text) + refresh_token = Column(Text) + expires_at = Column(DateTime) + + chat_histories = relationship("ChatHistory", back_populates="user") + user_logins = relationship("UserLogin", back_populates="user") + user_infos = relationship("UserInfo", back_populates="user") + +class ChatHistory(Base): + __tablename__ = 'chat_history' + + id = Column(Integer, primary_key=True,autoincrement=True) + email = Column(String(255), ForeignKey('users.email')) + name_chat = Column(String(255), unique=True) + + user = relationship("User", back_populates="chat_histories") + detail_chats = relationship("DetailChat", back_populates="chat_history") + +class UserLogin(Base): + __tablename__ = 'user_login' + + id = Column(Integer, primary_key=True,autoincrement=True) + user_email = Column(String(100), ForeignKey('users.email'), primary_key=True) + user_session_id = Column(String(100), primary_key=True) + + user = relationship("User", back_populates="user_logins") + +class UserInfo(Base): + __tablename__ = 'user_info' + + id = Column(Integer, primary_key=True, autoincrement=True) + uid = Column(Text) + email = Column(String(255), ForeignKey('users.email'), unique=True) + display_name = Column(Text) + photo_url = Column(Text) + + user = relationship("User", back_populates="user_infos") + +class DetailChat(Base): + __tablename__ = 'detail_chat' + + id = Column(Integer, primary_key=True, autoincrement=True) + chat_id = Column(Integer, ForeignKey('chat_history.id')) + YouMessage = Column(Text) + AiMessage = Column(Text) + data_relevant = Column(Text) + source_file = Column(Text) + + chat_history = relationship("ChatHistory", back_populates="detail_chats") + +class OTP(Base): + __tablename__ = 'otp' + + id = Column(Integer, primary_key=True, autoincrement=True) + email = Column(String(255), nullable=False) + otp = Column(String(6), nullable=False) + created_at = Column(TIMESTAMP, server_default=func.now()) \ No newline at end of file diff --git a/entity/__pycache__/Database_Entity.cpython-310.pyc b/entity/__pycache__/Database_Entity.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fba1ad294e651fa268e99f270291fc760ebe94f1 Binary files /dev/null and b/entity/__pycache__/Database_Entity.cpython-310.pyc differ diff --git a/entity/__pycache__/Database_Entity.cpython-311.pyc b/entity/__pycache__/Database_Entity.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c73d242252da8fc34c16e3bc4897aa98cdaaa892 Binary files /dev/null and b/entity/__pycache__/Database_Entity.cpython-311.pyc differ diff --git a/entity/__pycache__/__init__.cpython-310.pyc b/entity/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..61a5d9ae82eec8d7bb7386483099cf3ff8fd71e7 Binary files /dev/null and b/entity/__pycache__/__init__.cpython-310.pyc differ diff --git a/function/__pycache__/chatbot.cpython-310.pyc b/function/__pycache__/chatbot.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5e4bcb79c97754a79643089d59503ad85f12d95c Binary files /dev/null and b/function/__pycache__/chatbot.cpython-310.pyc differ diff --git a/function/__pycache__/chatbot.cpython-311.pyc b/function/__pycache__/chatbot.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6b4e3daf9444117f02731efe02b251f49a99b6e9 Binary files /dev/null and b/function/__pycache__/chatbot.cpython-311.pyc differ diff --git a/function/__pycache__/dropbox.cpython-310.pyc b/function/__pycache__/dropbox.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..04a62e246d5499fab47c7ee80f16efd094bc02ae Binary files /dev/null and b/function/__pycache__/dropbox.cpython-310.pyc differ diff --git a/function/__pycache__/dropbox.cpython-311.pyc b/function/__pycache__/dropbox.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b06da5f0808ccb370a606cc2991bdd209d2532c9 Binary files /dev/null and b/function/__pycache__/dropbox.cpython-311.pyc differ diff --git a/function/__pycache__/support_function.cpython-310.pyc b/function/__pycache__/support_function.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b6c85020615b0f6f9c7ed68e19a1d34e85849ade Binary files /dev/null and b/function/__pycache__/support_function.cpython-310.pyc differ diff --git a/function/__pycache__/support_function.cpython-311.pyc b/function/__pycache__/support_function.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6899d2572ebbaec8c62552f6f561f8713b90666b Binary files /dev/null and b/function/__pycache__/support_function.cpython-311.pyc differ diff --git a/function/chatbot.py b/function/chatbot.py new file mode 100644 index 0000000000000000000000000000000000000000..bae349b2b9249d9564888ab19e5d12b32ab2e736 --- /dev/null +++ b/function/chatbot.py @@ -0,0 +1,685 @@ +from langchain.text_splitter import CharacterTextSplitter +import json +import os +import random +import re +from concurrent.futures import ThreadPoolExecutor, as_completed +import google.generativeai as genai +import nltk +import pandas as pd +from groq import Groq +from langchain.chains.summarize import load_summarize_chain +from langchain.docstore.document import Document +from langchain.prompts import PromptTemplate +from langchain.retrievers import BM25Retriever, EnsembleRetriever +from langchain.retrievers.contextual_compression import ContextualCompressionRetriever +from langchain.text_splitter import CharacterTextSplitter +from langchain.text_splitter import RecursiveCharacterTextSplitter +from langchain_cohere import CohereRerank +from langchain_community.document_loaders import Docx2txtLoader +from langchain_community.document_loaders import TextLoader +from langchain_community.document_loaders import UnstructuredCSVLoader +from langchain_community.document_loaders import UnstructuredExcelLoader +from langchain_community.document_loaders import UnstructuredHTMLLoader +from langchain_community.document_loaders import UnstructuredMarkdownLoader +from langchain_community.document_loaders import UnstructuredPDFLoader +from langchain_community.document_loaders import UnstructuredPowerPointLoader +from langchain_community.document_loaders import UnstructuredXMLLoader +from langchain_community.document_loaders.csv_loader import CSVLoader +from langchain_community.llms import Cohere +from langchain_community.vectorstores import Chroma +from langchain_core.output_parsers.openai_tools import PydanticToolsParser +from langchain_core.prompts import ChatPromptTemplate +from langchain_core.pydantic_v1 import BaseModel, Field +from langchain_core.runnables import RunnablePassthrough +from langchain_openai import ChatOpenAI +from typing import List +nltk.download('punkt') + +def process_json_file(file_path): + json_data = [] + with open(file_path, 'r') as file: + for line in file: + try: + data = json.loads(line) + json_data.append(data) + except json.JSONDecodeError: + try: + data = json.loads(line[:-1]) + json_data.append(data) + except json.JSONDecodeError as e: + print(f"Error decoding JSON: {e}") + return json_data + + +from dotenv import load_dotenv +import os +load_dotenv() +GROQ_API_KEY = os.getenv("GROQ_API_KEY") +COHERE_API_KEY = os.getenv("COHERE_API_KEY") +OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") +GOOGLE_API_KEY1= os.getenv("GOOGLE_API_KEY_1") +GOOGLE_API_KEY= os.getenv("GOOGLE_API_KEY") +os.environ["COHERE_API_KEY"] = COHERE_API_KEY +os.environ["OPENAI_API_KEY"] = OPENAI_API_KEY +client = Groq( + api_key= GROQ_API_KEY, +) +genai.configure(api_key=GOOGLE_API_KEY1) +os.environ["GOOGLE_API_KEY"] = GOOGLE_API_KEY +from langchain_google_genai import GoogleGenerativeAIEmbeddings, ChatGoogleGenerativeAI +embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001") +llm = ChatGoogleGenerativeAI(model='gemini-pro', + max_output_tokens=2048, + temperature=0.3, + convert_system_message_to_human=True) +def extract_multi_metadata_content(texts, tests): + extracted_content = [] + precomputed_metadata = [x.metadata['source'].lower() for x in texts] + for idx, test in enumerate(tests): + temp_content = [] + test_terms = set(test.lower().split()) # Use set for faster lookup + for metadata_lower, x in zip(precomputed_metadata, texts): + if any(term in metadata_lower for term in test_terms): + temp_content.append(x.page_content) + if idx == 0: + extracted_content.append(f"Dữ liệu của {test}:\n{''.join(temp_content)}") + else: + extracted_content.append(''.join(temp_content)) + return '\n'.join(extracted_content) + +def find_matching_files_in_docs_12_id(text, id): + folder_path = f"./user_file/{id}" + search_terms = [] + search_terms_old = [] + matching_index = [] + search_origin = re.findall(r'\b\w+\.\w+\b|\b\w+\b', text) + search_terms_origin = [] + for word in search_origin: + if '.' in word: + search_terms_origin.append(word) + else: + search_terms_origin.extend(re.findall(r'\b\w+\b', word)) + + file_names_with_extension = re.findall(r'\b\w+\.\w+\b|\b\w+\b', text.lower()) + file_names_with_extension_old = re.findall(r'\b(\w+\.\w+)\b', text) + for file_name in search_terms_origin: + if "." in file_name: + term_position = search_terms_origin.index(file_name) + search_terms_old.append(file_name) + for file_name in file_names_with_extension_old: + if "." in file_name: + search_terms_old.append(file_name) + for file_name in file_names_with_extension: + search_terms.append(file_name) + clean_text_old = text + clean_text = text.lower() + search_terms_old1 = list(set(search_terms_old)) + for term in search_terms_old: + clean_text_old = clean_text_old.replace(term, '') + for term in search_terms: + clean_text = clean_text.replace(term, '') + words_old = re.findall(r'\b\w+\b', clean_text_old) + search_terms_old.extend(words_old) + matching_files = set() + matching_files_old = set() + for root, dirs, files in os.walk(folder_path): + for file in files: + for term in search_terms: + if term.lower() in file.lower(): + term_position = search_terms.index(term) + term_value = search_terms_origin[term_position] + matching_files.add(file) + matching_index.append(term_position) + break + matching_files_old1 = [] + matching_index.sort() + for x in matching_index: + matching_files_old1.append(search_terms_origin[x]) + return matching_files, matching_files_old1 + +def convert_xlsx_to_csv(xlsx_file_path, csv_file_path): + df = pd.read_excel(xlsx_file_path) + df.to_csv(csv_file_path, index=False) + +def save_list_CSV_id(file_list, id): + text = "" + for x in file_list: + if x.endswith('.xlsx'): + old = f"./user_file/{id}/{x}" + new = old.replace(".xlsx", ".csv") + convert_xlsx_to_csv(old, new) + x = x.replace(".xlsx", ".csv") + loader1 = CSVLoader(f"./user_file/{id}/{x}") + docs1 = loader1.load() + text += f"Dữ liệu file {x}:\n" + for z in docs1: + text += z.page_content + "\n" + return text + +def merge_files(file_set, file_list): + """Hàm này ghép lại các tên file dựa trên điều kiện đã cho.""" + merged_files = {} + for file_name in file_list: + name = file_name.split('.')[0] + for f in file_set: + if name in f: + merged_files[name] = f + break + return merged_files + +def replace_keys_with_values(original_dict, replacement_dict): + new_dict = {} + for key, value in original_dict.items(): + if key in replacement_dict: + new_key = replacement_dict[key] + new_dict[new_key] = value + else: + new_dict[key] = value + return new_dict + +def aws1_csv_id(new_dict_csv, id): + text = "" + query_all = "" + keyword = [] + for key, value in new_dict_csv.items(): + print(key, value) + query_all += value + keyword.append(key) + test = save_list_CSV_id(keyword, id) + text += test + sources = ",".join(keyword) + return text, query_all, sources + +def chat_llama3(prompt_query): + try: + chat_completion = client.chat.completions.create( + messages=[ + { + "role": "system", + "content": "Bạn là một trợ lý trung thưc, trả lời dựa trên nội dung tài liệu được cung cấp. Chỉ trả lời liên quan đến câu hỏi một cách đầy đủ chính xác, không bỏ sót thông tin." + }, + { + "role": "user", + "content": f"{prompt_query}", + } + ], + model="llama3-70b-8192", + temperature=0.0, + max_tokens=9000, + stop=None, + stream=False, + ) + return chat_completion.choices[0].message.content + except Exception as error: + return False + +def chat_gemini(prompt): + generation_config = { + "temperature": 0.0, + "top_p": 0.0, + "top_k": 0, + "max_output_tokens": 8192, + } + safety_settings = [ + { + "category": "HARM_CATEGORY_HARASSMENT", + "threshold": "BLOCK_MEDIUM_AND_ABOVE" + }, + { + "category": "HARM_CATEGORY_HATE_SPEECH", + "threshold": "BLOCK_MEDIUM_AND_ABOVE" + }, + { + "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", + "threshold": "BLOCK_MEDIUM_AND_ABOVE" + }, + { + "category": "HARM_CATEGORY_DANGEROUS_CONTENT", + "threshold": "BLOCK_MEDIUM_AND_ABOVE" + }, + ] + model = genai.GenerativeModel(model_name="gemini-1.5-pro-latest", + generation_config=generation_config, + safety_settings=safety_settings) + convo = model.start_chat(history=[]) + convo.send_message(prompt) + return convo.last.text + +def question_answer(question): + completion = chat_llama3(question) + if completion: + return completion + else: + answer = chat_gemini(question) + return answer + +def check_persist_directory(id, file_name): + directory_path = f"./vector_database/{id}/{file_name}" + return os.path.exists(directory_path) + +from langchain_community.vectorstores import FAISS + +def check_path_exists(path): + return os.path.exists(path) +def aws1_all_id(new_dict, text_alls, id, thread_id): + answer = "" + COHERE_API_KEY1 = os.getenv("COHERE_API_KEY_1") + os.environ["COHERE_API_KEY"] = COHERE_API_KEY1 + answer_relevant = "" + directory = "" + + for key, value in new_dict.items(): + query = value + keyword, keyword2 = find_matching_files_in_docs_12_id(query, id) + data = extract_multi_metadata_content(text_alls, keyword) + if keyword: + file_name = next(iter(keyword)) + text_splitter = CharacterTextSplitter(chunk_size=3200, chunk_overlap=1500) + texts_data = text_splitter.split_text(data) + + if check_persist_directory(id, file_name): + vectordb_query = Chroma(persist_directory=f"./vector_database/{id}/{file_name}", embedding_function=embeddings) + else: + vectordb_query = Chroma.from_texts(texts_data, + embedding=embeddings, + persist_directory=f"./vector_database/{id}/{file_name}") + + k_1 = len(texts_data) + retriever = vectordb_query.as_retriever(search_kwargs={f"k": k_1}) + bm25_retriever = BM25Retriever.from_texts(texts_data) + bm25_retriever.k = k_1 + ensemble_retriever = EnsembleRetriever(retrievers=[bm25_retriever, retriever], + weights=[0.6, 0.4]) + docs = ensemble_retriever.get_relevant_documents(f"{query}") + + path = f"./vector_database/FAISS/{id}/{file_name}" + if check_path_exists(path): + docsearch = FAISS.load_local(path, embeddings, allow_dangerous_deserialization=True) + else: + docsearch = FAISS.from_documents(docs, embeddings) + docsearch.save_local(f"./vector_database/FAISS/{id}/{file_name}") + docsearch = FAISS.load_local(path, embeddings, allow_dangerous_deserialization=True) + + k_2 = len(docs) + compressor = CohereRerank(top_n=5) + retrieve3 = docsearch.as_retriever(search_kwargs={f"k": k_2}) + compression_retriever = ContextualCompressionRetriever( + base_compressor=compressor, base_retriever=retrieve3 + ) + compressed_docs = compression_retriever.get_relevant_documents(f"{query}") + + if compressed_docs: + data = compressed_docs[0].page_content + text = ''.join(map(lambda x: x.page_content, compressed_docs)) + prompt_document = f"Dựa vào nội dung sau:{text}. Hãy trả lời câu hỏi sau đây: {query}. Mà không thay đổi nội dung mà mình đã cung cấp" + answer_for = question_answer(prompt_document) + answer += answer_for + "\n" + answer_relevant = data + directory = file_name + + return answer, answer_relevant, directory + +def extract_content_between_keywords(query, keywords): + contents = {} + num_keywords = len(keywords) + keyword_positions = [] + for i in range(num_keywords): + keyword = keywords[i] + keyword_position = query.find(keyword) + keyword_positions.append(keyword_position) + if keyword_position == -1: + continue + next_keyword_position = len(query) + for j in range(i + 1, num_keywords): + next_keyword = keywords[j] + next_keyword_position = query.find(next_keyword) + if next_keyword_position != -1: + break + if i == 0: + content_before = query[:keyword_position].strip() + else: + content_before = query[keyword_positions[i - 1] + len(keywords[i - 1]):keyword_position].strip() + if i == num_keywords - 1: + content_after = query[keyword_position + len(keyword):].strip() + else: + content_after = query[keyword_position + len(keyword):next_keyword_position].strip() + content = f"{content_before} {keyword} {content_after}" + contents[keyword] = content + return contents + +def generate_random_questions(filtered_ques_list): + if len(filtered_ques_list) >= 2: + random_questions = random.sample(filtered_ques_list, 2) + else: + random_questions = filtered_ques_list + return random_questions + +def generate_question_main(loader, name_file): + text_splitter = RecursiveCharacterTextSplitter(chunk_size=4500, chunk_overlap=2500) + texts = text_splitter.split_documents(loader) + question_gen = f"nội dung {name_file} : \n" + question_gen += texts[0].page_content + splitter_ques_gen = RecursiveCharacterTextSplitter( + chunk_size=4500, + chunk_overlap=2200 + ) + chunks_ques_gen = splitter_ques_gen.split_text(question_gen) + document_ques_gen = [Document(page_content=t) for t in chunks_ques_gen] + llm_ques_gen_pipeline = llm + prompt_template_vn = """ + Bạn là một chuyên gia tạo câu hỏi dựa trên tài liệu và tài liệu hướng dẫn. + Bạn làm điều này bằng cách đặt các câu hỏi về đoạn văn bản dưới đây: + + ------------ + {text} + ------------ + + Hãy tạo ra các câu hỏi từ đoạn văn bản này.Nếu đoạn văn là tiếng Việt hãy tạo câu hỏi tiếng Việt. Nếu đoạn văn là tiếng Anh hãy tạo câu hỏi tiếng Anh. + Hãy chắc chắn không bỏ sót bất kỳ thông tin quan trọng nào. Và chỉ tạo với đoạn tài liệu đó tối đa 5 câu hỏi liên quan tới tài liệu cung cấp nhất.Nếu trong đoạn tài liệu có các tên liên quan đến file như demo1.pdf( nhiều file khác) thì phải kèm nó vào nội dung câu hỏi bạn tạo ra. + + CÁC CÂU HỎI: + """ + + PROMPT_QUESTIONS_VN = PromptTemplate(template=prompt_template_vn, input_variables=["text"]) + refine_template_vn = (""" + Bạn là một chuyên gia tạo câu hỏi thực hành dựa trên tài liệu và tài liệu hướng dẫn. + Mục tiêu của bạn là giúp người học chuẩn bị cho một kỳ thi. + Chúng tôi đã nhận được một số câu hỏi thực hành ở mức độ nào đó: {existing_answer}. + Chúng tôi có thể tinh chỉnh các câu hỏi hiện có hoặc thêm câu hỏi mới + (chỉ khi cần thiết) với một số ngữ cảnh bổ sung dưới đây. + ------------ + {text} + ------------ + + Dựa trên ngữ cảnh mới, hãy tinh chỉnh các câu hỏi bằng tiếng Việt nếu đoạn văn đó cung cấp tiếng Việt. Nếu không hãy tinh chỉnh câu hỏi bằng tiếng Anh nếu đoạn đó cung cấp tiếng Anh. + Nếu ngữ cảnh không hữu ích, vui lòng cung cấp các câu hỏi gốc. Và chỉ tạo với đoạn tài liệu đó tối đa 5 câu hỏi liên quan tới tài liệu cung cấp nhất. Nếu trong đoạn tài liệu có các tên file thì phải kèm nó vào câu hỏi. + CÁC CÂU HỎI: + """ + ) + + REFINE_PROMPT_QUESTIONS = PromptTemplate( + input_variables=["existing_answer", "text"], + template=refine_template_vn, + ) + ques_gen_chain = load_summarize_chain(llm=llm_ques_gen_pipeline, + chain_type="refine", + verbose=True, + question_prompt=PROMPT_QUESTIONS_VN, + refine_prompt=REFINE_PROMPT_QUESTIONS) + ques = ques_gen_chain.run(document_ques_gen) + ques_list = ques.split("\n") + filtered_ques_list = ["{}: {}".format(name_file, re.sub(r'^\d+\.\s*', '', element)) for element in ques_list if + element.endswith('?') or element.endswith('.')] + return generate_random_questions(filtered_ques_list) + +def load_file(loader): + return loader.load() + +def extract_data2(id): + documents = [] + directory_path = f"./user_file/{id}" + if not os.path.exists(directory_path) or not any( + os.path.isfile(os.path.join(directory_path, f)) for f in os.listdir(directory_path)): + return False + tasks = [] + with ThreadPoolExecutor() as executor: + for file in os.listdir(directory_path): + if file.endswith(".pdf"): + pdf_path = os.path.join(directory_path, file) + loader = UnstructuredPDFLoader(pdf_path) + tasks.append(executor.submit(load_file, loader)) + elif file.endswith('.docx') or file.endswith('.doc'): + doc_path = os.path.join(directory_path, file) + loader = Docx2txtLoader(doc_path) + tasks.append(executor.submit(load_file, loader)) + elif file.endswith('.txt'): + txt_path = os.path.join(directory_path, file) + loader = TextLoader(txt_path, encoding="utf8") + tasks.append(executor.submit(load_file, loader)) + elif file.endswith('.pptx'): + ppt_path = os.path.join(directory_path, file) + loader = UnstructuredPowerPointLoader(ppt_path) + tasks.append(executor.submit(load_file, loader)) + elif file.endswith('.csv'): + csv_path = os.path.join(directory_path, file) + loader = UnstructuredCSVLoader(csv_path) + tasks.append(executor.submit(load_file, loader)) + elif file.endswith('.xlsx'): + excel_path = os.path.join(directory_path, file) + loader = UnstructuredExcelLoader(excel_path) + tasks.append(executor.submit(load_file, loader)) + elif file.endswith('.json'): + json_path = os.path.join(directory_path, file) + loader = TextLoader(json_path) + tasks.append(executor.submit(load_file, loader)) + elif file.endswith('.md'): + md_path = os.path.join(directory_path, file) + loader = UnstructuredMarkdownLoader(md_path) + tasks.append(executor.submit(load_file, loader)) + for future in as_completed(tasks): + result = future.result() + documents.extend(result) + text_splitter = CharacterTextSplitter(chunk_size=4500, chunk_overlap=2500) + texts = text_splitter.split_documents(documents) + Chroma.from_documents(documents=texts, + embedding=embeddings, + persist_directory=f"./vector_database/{id}") + return texts + +def generate_question(id): + directory_path = f"./user_file/{id}" + if not os.path.exists(directory_path) or not any( + os.path.isfile(os.path.join(directory_path, f)) for f in os.listdir(directory_path)): + return False + all_questions = [] + tasks = [] + with ThreadPoolExecutor() as executor: + for file in os.listdir(directory_path): + if file.endswith(".pdf"): + pdf_path = os.path.join(directory_path, file) + loader = UnstructuredPDFLoader(pdf_path).load() + tasks.append(executor.submit(generate_question_main, loader, file)) + elif file.endswith('.docx') or file.endswith('.doc'): + doc_path = os.path.join(directory_path, file) + loader = Docx2txtLoader(doc_path).load() + tasks.append(executor.submit(generate_question_main, loader, file)) + elif file.endswith('.txt'): + txt_path = os.path.join(directory_path, file) + loader = TextLoader(txt_path, encoding="utf8").load() + tasks.append(executor.submit(generate_question_main, loader, file)) + elif file.endswith('.pptx'): + ppt_path = os.path.join(directory_path, file) + loader = UnstructuredPowerPointLoader(ppt_path).load() + tasks.append(executor.submit(generate_question_main, loader, file)) + elif file.endswith('.json'): + json_path = os.path.join(directory_path, file) + loader = TextLoader(json_path, encoding="utf8").load() + tasks.append(executor.submit(generate_question_main, loader, file)) + elif file.endswith('.md'): + md_path = os.path.join(directory_path, file) + loader = UnstructuredMarkdownLoader(md_path).load() + tasks.append(executor.submit(generate_question_main, loader, file)) + for future in as_completed(tasks): + result = future.result() + all_questions.extend(result) + return all_questions + +class Search(BaseModel): + queries: List[str] = Field( + ..., + description="Truy vấn riêng biệt để tìm kiếm, giữ nguyên ý chính câu hỏi riêng biệt", + ) + +def query_analyzer(query): + output_parser = PydanticToolsParser(tools=[Search]) + system = """Bạn có khả năng đưa ra các truy vấn tìm kiếm chính xác để lấy thông tin giúp trả lời các yêu cầu của người dùng. Các truy vấn của bạn phải chính xác, không được bỏ ngắn rút gọn. + Nếu bạn cần tra cứu hai hoặc nhiều thông tin riêng biệt, bạn có thể làm điều đó!. Trả lời câu hỏi bằng tiếng Việt(Vietnamese), không được dùng ngôn ngữ khác""" + prompt = ChatPromptTemplate.from_messages( + [ + ("system", system), + ("human", "{question}"), + ] + ) + llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0.0) + structured_llm = llm.with_structured_output(Search) + query_analyzer = {"question": RunnablePassthrough()} | prompt | structured_llm + text = query_analyzer.invoke(query) + return text + +def handle_query(question, text_all, compression_retriever, id, thread_id): + COHERE_API_KEY_3 = os.environ["COHERE_API_KEY_3"] + os.environ["COHERE_API_KEY"] = COHERE_API_KEY_3 + query = question + x = query + keyword, key_words_old = find_matching_files_in_docs_12_id(query, id) + # if keyword == set() or key_words_old == list(): + # return "Not found file" + file_list = keyword + + if file_list: + list_keywords2 = list(key_words_old) + contents1 = extract_content_between_keywords(query, list_keywords2) + merged_result = merge_files(keyword, list_keywords2) + original_dict = contents1 + replacement_dict = merged_result + new_dict = replace_keys_with_values(original_dict, replacement_dict) + files_to_remove = [filename for filename in new_dict.keys() if + filename.endswith('.xlsx') or filename.endswith('.csv')] + removed_files = {} + for filename in files_to_remove: + removed_files[filename] = new_dict[filename] + for filename in files_to_remove: + new_dict.pop(filename) + test_csv = "" + text_csv, query_csv, source = aws1_csv_id(removed_files, id) + prompt_csv = "" + answer_csv = "" + if test_csv: + prompt_csv = f"Dựa vào nội dung sau: {text_csv}. Hãy trả lời câu hỏi sau đây: {query_csv}.Bằng tiếng Việt" + answer_csv = question_answer(prompt_csv) + answer_document, data_relevant, source = aws1_all_id(new_dict, text_all, id, thread_id) + answer_all1 = answer_document + answer_csv + return answer_all1, data_relevant, source + else: + compressed_docs = compression_retriever.get_relevant_documents(f"{query}") + relevance_score_float = float(compressed_docs[0].metadata['relevance_score']) + print(relevance_score_float) + if relevance_score_float <= 0.15: + documents1 = [] + for file in os.listdir(f"./user_file/{id}"): + if file.endswith('.csv'): + csv_path = f"./user_file/{id}/" + file + loader = UnstructuredCSVLoader(csv_path) + documents1.extend(loader.load()) + elif file.endswith('.xlsx'): + excel_path = f"./user_file/{id}/" + file + loader = UnstructuredExcelLoader(excel_path) + documents1.extend(loader.load()) + text_splitter_csv = CharacterTextSplitter.from_tiktoken_encoder(chunk_size=2200, chunk_overlap=1500) + texts_csv = text_splitter_csv.split_documents(documents1) + vectordb_csv = Chroma.from_documents(documents=texts_csv, + embedding=embeddings, persist_directory=f'./vector_database/csv/{thread_id}') + k = len(texts_csv) + retriever_csv = vectordb_csv.as_retriever(search_kwargs={"k": k}) + llm = Cohere(temperature=0) + compressor_csv = CohereRerank(top_n=3, model="rerank-english-v2.0") + compression_retriever_csv = ContextualCompressionRetriever( + base_compressor=compressor_csv, base_retriever=retriever_csv + ) + compressed_docs_csv = compression_retriever_csv.get_relevant_documents(f"{query}") + file_path = compressed_docs_csv[0].metadata['source'] + print(file_path) + if file_path.endswith('.xlsx'): + new = file_path.replace(".xlsx", ".csv") + convert_xlsx_to_csv(file_path, new) + loader1 = CSVLoader(new) + else: + loader1 = CSVLoader(file_path) + docs1 = loader1.load() + text = " " + for z in docs1: + text += z.page_content + "\n" + prompt_csv = f"Dựa vào nội dung sau: {text}. Hãy trả lời câu hỏi sau đây: {query}. Bằng tiếng Việt" + answer_csv = question_answer(prompt_csv) + return answer_csv + else: + file_path = compressed_docs[0].metadata['source'] + file_path = file_path.replace('\\', '/') + print(file_path) + if file_path.endswith(".pdf"): + loader = UnstructuredPDFLoader(file_path) + elif file_path.endswith('.docx') or file_path.endswith('doc'): + loader = Docx2txtLoader(file_path) + elif file_path.endswith('.txt'): + loader = TextLoader(file_path, encoding="utf8") + elif file_path.endswith('.pptx'): + loader = UnstructuredPowerPointLoader(file_path) + elif file_path.endswith('.xml'): + loader = UnstructuredXMLLoader(file_path) + elif file_path.endswith('.html'): + loader = UnstructuredHTMLLoader(file_path) + elif file_path.endswith('.json'): + loader = TextLoader(file_path) + elif file_path.endswith('.md'): + loader = UnstructuredMarkdownLoader(file_path) + elif file_path.endswith('.xlsx'): + file_path_new = file_path.replace(".xlsx", ".csv") + convert_xlsx_to_csv(file_path, file_path_new) + loader = CSVLoader(file_path_new) + elif file_path.endswith('.csv'): + loader = CSVLoader(file_path) + text_splitter = CharacterTextSplitter(chunk_size=3200, chunk_overlap=1500) + texts = text_splitter.split_documents(loader.load()) + k_1 = len(texts) + file_name = os.path.basename(file_path) + if check_persist_directory(id, file_name): + vectordb_file = Chroma(persist_directory=f"./vector_database/{id}/{file_name}", + embedding_function=embeddings) + else: + vectordb_file = Chroma.from_documents(texts, + embedding=embeddings, + persist_directory=f"./vector_database/{id}/{file_name}") + retriever_file = vectordb_file.as_retriever(search_kwargs={f"k": k_1}) + compressor_file = CohereRerank(top_n=5, model="rerank-english-v2.0") + compression_retriever_file = ContextualCompressionRetriever( + base_compressor=compressor_file, base_retriever=retriever_file + ) + compressed_docs_file = compression_retriever_file.get_relevant_documents(f"{x}") + query = question + text = ''.join(map(lambda x: x.page_content, compressed_docs_file)) + prompt = f"Dựa vào nội dung sau:{text}. Hãy trả lời câu hỏi sau đây: {query}. Mà không thay đổi, chỉnh sửa nội dung mà mình đã cung cấp" + answer = question_answer(prompt) + list_relevant = compressed_docs_file[0].page_content + source = file_name + return answer, list_relevant, source + +def handle_query_upgrade_keyword_old(query_all, text_all, id): + COHERE_API_KEY_2 = os.environ["COHERE_API_KEY_2"] + os.environ["COHERE_API_KEY"] = COHERE_API_KEY_2 + test = query_analyzer(query_all) + test_string = str(test) + matches = re.findall(r"'([^']*)'", test_string) + vectordb = Chroma(persist_directory=f"./vector_database/{id}", embedding_function=embeddings) + k = len(text_all) + retriever = vectordb.as_retriever(search_kwargs={"k": k}) + compressor = CohereRerank(top_n=5, model="rerank-english-v2.0") + compression_retriever = ContextualCompressionRetriever(base_compressor=compressor, base_retriever= retriever) + with ThreadPoolExecutor() as executor: + futures = {executor.submit(handle_query, query, text_all, compression_retriever, id, i): query for i, query in + enumerate(matches)} + results = [] + data_relevant = [] + sources = [] + for future in as_completed(futures): + try: + result, list_data, list_source = future.result() + results.append(result) + data_relevant.append(list_data) + sources.append(list_source) + except Exception as e: + print(f'An error occurred: {e}') + answer_all = ''.join(results) + prompt1 = f"Dựa vào nội dung sau:{answer_all}. Hãy trả lời câu hỏi sau đây: {query_all}. Mà không thay đổi, chỉnh sửa nội dung mà mình đã cung cấp" + answer1 = question_answer(prompt1) + return answer1, data_relevant, sources \ No newline at end of file diff --git a/function/dropbox.py b/function/dropbox.py new file mode 100644 index 0000000000000000000000000000000000000000..71a944b433ed0031e9ca1952b0411093aa15f778 --- /dev/null +++ b/function/dropbox.py @@ -0,0 +1,155 @@ +import dropbox.files +import os +import shutil +import requests, base64 +from fastapi import HTTPException +from dotenv import load_dotenv +import os +load_dotenv() +DROPBOX_APP_KEY=os.getenv('DROPBOX_APP_KEY') +DROPBOX_APP_SECRET=os.getenv('DROPBOX_APP_SECRET') +DROPBOX_REFRESH_TOKEN=os.getenv('DROPBOX_REFRESH_TOKEN') + +def refresh_token_dropbox(): + app_key = DROPBOX_APP_KEY + app_secret = DROPBOX_APP_SECRET + refresh_token = DROPBOX_REFRESH_TOKEN + url = 'https://api.dropbox.com/oauth2/token' + auth_string = f"{app_key}:{app_secret}" + base64authorization = base64.b64encode(auth_string.encode()).decode('utf-8') + headers = { + 'Authorization': f'Basic {base64authorization}', + 'Content-Type': 'application/x-www-form-urlencoded' + } + data = { + 'refresh_token': refresh_token, + 'grant_type': 'refresh_token' + } + response = requests.post(url, headers=headers, data=data) + response_json = response.json() + access_token = response_json.get('access_token', None) + return access_token + +def delete_file(id,name_file): + try: + TOKEN = refresh_token_dropbox() + dbx=dropbox.Dropbox(TOKEN) + file_path = f"/{id}/{name_file}" + dbx.files_delete_v2(file_path) + print(f"Xóa file '{file_path}' thành công.") + except dropbox.exceptions.ApiError as e: + print(f"Lỗi khi xóa file '{file_path}': {e}") + +def list_files(id): + file_names = [] + try: + TOKEN = refresh_token_dropbox() + dbx=dropbox.Dropbox(TOKEN) + result = dbx.files_list_folder(f"/{id}") + for entry in result.entries: + if isinstance(entry, dropbox.files.FileMetadata): + file_names.append(os.path.basename(entry.path_display)) + except dropbox.exceptions.ApiError as e: + print(f"Error listing files: {e}") + return file_names + +def upload_file_fix(local_path,cloud_path,token): + try: + TOKEN = refresh_token_dropbox() + dbx=dropbox.Dropbox(TOKEN) + with open(local_path, "rb") as f: + data = f.read() + dbx.files_upload(data, cloud_path) + print(f"Uploaded file '{local_path}' to '{cloud_path}'") + except dropbox.exceptions.ApiError as e: + print(f"Error uploading file '{local_path}': {e}") + +def upload_file(local_path, cloud_path): + try: + TOKEN = refresh_token_dropbox() + dbx=dropbox.Dropbox(TOKEN) + with open(local_path, "rb") as f: + data = f.read() + dbx.files_upload(data, cloud_path) + print(f"Uploaded file '{local_path}' to '{cloud_path}'") + except dropbox.exceptions.ApiError as e: + upload_file_fix() + +def clear_local_folder(path): + try: + for filename in os.listdir(path): + file_path = os.path.join(path, filename) + if os.path.isfile(file_path) or os.path.islink(file_path): + os.unlink(file_path) + elif os.path.isdir(file_path): + shutil.rmtree(file_path) + except Exception as e: + print(f"Failed to delete contents of {path}. Reason: {e}") + +def download_folder(id): + try: + TOKEN = refresh_token_dropbox() + dbx = dropbox.Dropbox(TOKEN) + local_path = f"./user_file/{id}" + os.makedirs(local_path, exist_ok=True) + clear_local_folder(local_path) + result = dbx.files_list_folder(f"/{id}") + for entry in result.entries: + if isinstance(entry, dropbox.files.FileMetadata): + cloud_file_path = entry.path_display + file_name = os.path.basename(cloud_file_path) + local_file_path = os.path.join(local_path, file_name) + dbx.files_download_to_file(local_file_path, cloud_file_path) + print(f"Downloaded file '{file_name}' to '{local_file_path}'") + except dropbox.exceptions.ApiError as e: + print(f"Error downloading file '{id}': {e}") + +def download_file_id(file_name, id): + try: + TOKEN = refresh_token_dropbox() + dbx = dropbox.Dropbox(TOKEN) + local_folder_path = f"./user_file/{id}" + os.makedirs(local_folder_path, exist_ok=True) + local_file_path = os.path.join(local_folder_path, file_name) + with open(local_file_path, "wb") as f: + metadata, response = dbx.files_download(f"/{id}/{file_name}") + f.write(response.content) + print(f"Downloaded file '{file_name}' to '{local_file_path}'") + except dropbox.exceptions.ApiError as e: + print(f"Error downloading file '{file_name}': {e}") + raise HTTPException(status_code=500, detail="Internal Server Error") + +def search_and_download_file(start_char, id): + try: + TOKEN = refresh_token_dropbox() + dbx = dropbox.Dropbox(TOKEN) + result = dbx.files_list_folder(f"/{id}") + files_starting_with_char = [entry.name for entry in result.entries if entry.name.startswith(start_char)] + if len(files_starting_with_char) == 0: + print(f"No file found starting with '{start_char}' in folder '{id}'") + return + file_name = files_starting_with_char[0] + local_folder_path = f"./user_file/{id}" + os.makedirs(local_folder_path, exist_ok=True) + local_file_path = os.path.join(local_folder_path, file_name) + with open(local_file_path, "wb") as f: + metadata, response = dbx.files_download(f"/{id}/{file_name}") + f.write(response.content) + print(f"Downloaded file '{file_name}' to '{local_file_path}'") + except dropbox.exceptions.ApiError as e: + print(f"Error searching or downloading file: {e}") + raise HTTPException(status_code=500, detail="Internal Server Error") + +def delete_all_files_in_folder(folder_id): + try: + TOKEN = refresh_token_dropbox() + dbx = dropbox.Dropbox(TOKEN) + result = dbx.files_list_folder(f"/{folder_id}") + for entry in result.entries: + if isinstance(entry, dropbox.files.FileMetadata): + file_path = entry.path_display + dbx.files_delete_v2(file_path) + print(f"Deleted file '{file_path}'") + print(f"All files in folder '{folder_id}' have been deleted.") + except dropbox.exceptions.ApiError as e: + print(f"Error deleting files: {e}") \ No newline at end of file diff --git a/function/support_function.py b/function/support_function.py new file mode 100644 index 0000000000000000000000000000000000000000..cf7743dd80b92479c0e97515c1c5c72c449695dc --- /dev/null +++ b/function/support_function.py @@ -0,0 +1,129 @@ +from pydantic.error_wrappers import ErrorWrapper +from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials +from service import MySQLService,LoginService,ChatService +from request import RequestMySQL,RequestLogin,RequestDefault +from auth.authentication import decodeJWT +from repository import UserRepository +from auth import authentication +from datetime import datetime, timedelta +from fastapi import Depends, HTTPException, Form, File, UploadFile +from typing import List +from service import FileService,DefaultService,LoginService +from request import RequestFile,RequestChat,RequestDefault +from fastapi import FastAPI, Request, HTTPException +from fastapi.responses import JSONResponse +from pydantic.error_wrappers import ErrorWrapper +import json +from function import support_function +from repository import UserRepository +from response import ResponseDefault as res +import re + +def is_positive_integer(value): + if isinstance(value, int) and value > 0: + return True + else: + return False + +def check_value_user_id_controller(user_id: str): + if user_id is None or user_id.strip() == "": + return res.ReponseError(status=400, + data=res.Message(message="user_id field is required.")) + user_id = user_id.strip("'").strip('"') + try: + user_id_int = int(user_id) + except ValueError: + return res.ReponseError(status=400, + data=res.Message(message="user_id must be an integer")) + + if not support_function.is_positive_integer(user_id_int): + return res.ReponseError(status=400, + data=res.Message(message="user_id must be greater than 0")) + return True + +def check_value_user_id(user_id: str, current_user_email: str): + if user_id is None or user_id.strip() == "": + return res.ReponseError(status=400, + data=res.Message(message="user_id field is required.")) + user_id = user_id.strip("'").strip('"') + try: + user_id_int = int(user_id) + except ValueError: + return res.ReponseError(status=400, + data=res.Message(message="user_id must be an integer")) + + if not support_function.is_positive_integer(user_id_int): + return res.ReponseError(status=400, + data=res.Message(message="user_id must be greater than 0")) + email = UserRepository.getEmailUserByIdFix(user_id) + if email is None: + return res.ReponseError(status=400, + data=res.Message(message="user_id not exist")) + email = email[0] + if email != current_user_email: + return res.ReponseError(status=400, + data=res.Message(message="Sorry, you can't perform actions with this user id.")) + return True + +def check_value_email_controller(email: str): + if email is None or email.strip() == "": + return res.ReponseError(status = 400, + data = res.Message(message="Email is required.")) + try: + int(email) + return res.ReponseError(status=400, + data=res.Message(message="Email must be a string, not a number.")) + except ValueError: + pass + return True + +def check_value_otp(otp: str): + if otp is None: + return res.ReponseError(status=400, + data=res.Message(message="OTP is required")) + if otp.isdigit(): + return res.ReponseError(status=400, + data=res.Message(message="OTP must be a string, not a number.")) + if len(otp) != 6: + return res.ReponseError(status=400, + data=res.Message(message="OTP max length is 6")) + return True + +regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b' +def check_email(email): + if(re.fullmatch(regex, email)): + return True + else: + return False +def check_email_service(user_id: str): + email1 = UserRepository.getEmailUserByIdFix(user_id) + if email1 is None: + return res.ReponseError( + status=400, + data=res.Message(message="Id not exist") + ) + email = email1[0] + if email is None: + return res.ReponseError( + status=400, + data=res.Message(message="Email is empty") + ) + if check_email(email) == False: + return res.ReponseError( + status=400, + data=res.Message(message="Email invalid") + ) + return email + +def check_email_empty_invalid(email: str): + if email is None or email == "": + return res.ReponseError( + status=400, + data=res.Message(message="Email is empty") + ) + if check_email(email) == False: + return res.ReponseError( + status=400, + data =res.Message(message="Email invalid") + ) + return True \ No newline at end of file diff --git a/repository/ChatHistoryRepository.py b/repository/ChatHistoryRepository.py new file mode 100644 index 0000000000000000000000000000000000000000..383bedeeb8b116572c1b816cb947b1ecad758f44 --- /dev/null +++ b/repository/ChatHistoryRepository.py @@ -0,0 +1,237 @@ +from sqlalchemy.orm import sessionmaker +import sys +import os +app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) +sys.path.insert(0, app_path) +from entity import Database_Entity +from repository import ConfigDatabase as cf +chat_history = Database_Entity.ChatHistory +users = Database_Entity.User +detail_chat = Database_Entity.DetailChat +from sqlalchemy.orm import sessionmaker +from functools import lru_cache +import sys +import os + +def getIdChatHistoryByUserIdAndNameChat(user_id:int,name_old :str) -> chat_history.id: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == user_id).one_or_none()[0] + chat_id = session.query(chat_history.id).filter(chat_history.email == email, chat_history.name_chat == name_old).scalar() + session.commit() + if chat_id: + session.close() + return chat_id + else: + session.close() + return None + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == user_id).one_or_none()[0] + chat_id = session.query(chat_history.id).filter(chat_history.email == email, chat_history.name_chat == name_old).scalar() + session.commit() + if chat_id: + session.close() + return chat_id + else: + session.close() + return None + +def getIdChatHistoryByUserIdAndNameChatNew(user_id:int,name_old :str) -> chat_history.id: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == user_id).one_or_none()[0] + chat_id = session.query(chat_history.id).filter(chat_history.email == email, chat_history.name_chat == name_old).scalar() + session.commit() + if chat_id: + session.close() + return chat_id + else: + session.close() + return None + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == user_id).one_or_none()[0] + chat_id = session.query(chat_history.id).filter(chat_history.email == email, + chat_history.name_chat == name_old).scalar() + session.commit() + if chat_id: + session.close() + return chat_id + else: + session.close() + return None + +def updateNameChatHistory(user_id: int,name_old :str,name_new:str) -> bool: + try: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + try: + email = session.query(users.email).filter(users.id == user_id).one_or_none()[0] + session.query(chat_history).filter(chat_history.email == email,chat_history.name_chat == name_old).update({chat_history.name_chat: name_new}) + session.commit() + session.close() + return True + except: + session.rollback() + session.close() + return False + except: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + try: + email = session.query(users.email).filter(users.id == user_id).one_or_none()[0] + session.query(chat_history).filter(chat_history.email == email,chat_history.name_chat == name_old).update({chat_history.name_chat: name_new}) + session.commit() + session.close() + return True + except: + session.rollback() + session.close() + return False + +def deleteChatHistory(user_id,chat_name: str) -> bool: + try: + try: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == user_id).one_or_none()[0] + session.query(chat_history).filter(chat_history.email == email, chat_history.name_chat == chat_name).delete() + session.commit() + session.close() + return True + except Exception as e: + session.rollback() + session.close() + return False + except: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == user_id).one_or_none()[0] + session.query(chat_history).filter(chat_history.email == email, chat_history.name_chat == chat_name).delete() + session.commit() + session.close() + return True + except Exception as e: + session.rollback() + session.close() + return False + + +def getChatHistoryByEmail(email: str) -> chat_history: + try: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + chat_history1 = session.query(chat_history).filter(chat_history.email == email) + if chat_history1: + session.commit() + session.close() + return chat_history1 + session.close() + return None + except: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + chat_history1 = session.query(chat_history).filter(chat_history.email == email) + if chat_history1: + session.commit() + session.close() + return chat_history1 + session.close() + return None + +from sqlalchemy.orm import aliased + +def getChatHistoryByChatIdAndUserId(chat_id: int, user_id: int) -> chat_history: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == user_id).one_or_none()[0] + chat_history1 = session.query(chat_history).filter(chat_history.id == chat_id,chat_history.email == email).one_or_none() + if chat_history1: + session.commit() + session.close() + return True + session.close() + return None + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == id).one_or_none()[0] + chat_history1 = session.query(chat_history).filter(chat_history.email == email) + if chat_history1: + session.commit() + session.close() + return True + session.close() + return None + + +def getChatHistoryById(id: int) -> chat_history: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == id).one_or_none()[0] + chat_history1 = session.query(chat_history).filter(chat_history.email == email) + if chat_history1: + session.commit() + session.close() + return chat_history1 + session.close() + return None + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == id).one_or_none()[0] + chat_history1 = session.query(chat_history).filter(chat_history.email == email) + if chat_history1: + session.commit() + session.close() + return chat_history1 + session.close() + return None + +def addChatHistory(user_id: str, name_chat:str)->None: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == user_id).one_or_none()[0] + new_user = chat_history( + email = email, + name_chat = name_chat + ) + session.add(new_user) + session.commit() + session.close() + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == user_id).one_or_none()[0] + new_user = chat_history( + email = email, + name_chat = name_chat + ) + session.add(new_user) + session.commit() + session.close() diff --git a/repository/ConfigDatabase.py b/repository/ConfigDatabase.py new file mode 100644 index 0000000000000000000000000000000000000000..a547e0ba83d4795fb168e89329c039252b3c3238 --- /dev/null +++ b/repository/ConfigDatabase.py @@ -0,0 +1,42 @@ +from sqlalchemy import create_engine, URL +from sqlalchemy.orm import DeclarativeBase +Base = DeclarativeBase() +from sqlalchemy.engine import create_engine, URL +from dotenv import load_dotenv +import os +load_dotenv() +MYSQL_USER_NAME=os.getenv('MYSQL_USER_NAME') +MYSQL_PASSWORD=os.getenv('MYSQL_PASSWOR') +MYSQL_PORT=os.getenv('MYSQL_PORT') +MYSQL_DATABASE=os.getenv('MYSQL_DATABASE') +MYSQL_HOST=os.getenv('MYSQL_HOST') +#IF USE DOCKER HOST = host.docker.internal +def get_db_engine(): + dsn = URL.create( + drivername="mysql+pymysql", + username=MYSQL_USER_NAME, + password=MYSQL_PASSWORD, + host=MYSQL_HOST, + port=MYSQL_PORT, + database=MYSQL_DATABASE + ) + connect_args = {} + return create_engine( + dsn, + connect_args=connect_args, + ) + +def get_db_engine1(): + dsn = URL.create( + drivername="mysql+pymysql", + username=MYSQL_USER_NAME, + password=MYSQL_PASSWORD, + host=MYSQL_HOST, + port=MYSQL_PORT, + database=MYSQL_DATABASE + ) + connect_args = {} + return create_engine( + dsn, + connect_args=connect_args, + ) \ No newline at end of file diff --git a/repository/DetailChatRepository.py b/repository/DetailChatRepository.py new file mode 100644 index 0000000000000000000000000000000000000000..8960e98c40b946e17290c13bd8e2efcbe2840d24 --- /dev/null +++ b/repository/DetailChatRepository.py @@ -0,0 +1,115 @@ +from sqlalchemy.orm import sessionmaker +from entity import Database_Entity +from repository import ConfigDatabase as cf +detail_chat = Database_Entity.DetailChat +chat_history = Database_Entity.ChatHistory + +def getListDetailChatByChatId(chat_id: int) -> detail_chat: + try: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + chat_record= session.query(detail_chat).filter(detail_chat.chat_id == chat_id) + session.commit() + if chat_record: + session.close() + return chat_record + else: + session.close() + return None + except: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + chat_record= session.query(detail_chat).filter(detail_chat.chat_id == chat_id) + session.commit() + if chat_record: + session.close() + return chat_record + else: + session.close() + return None + +def addDetailChat(chat_id: int, YouMessage: str, AiMessage: str, data_relevant: str, source_file: str) -> None: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + new_user = detail_chat( + chat_id = chat_id, + YouMessage = YouMessage, + AiMessage = AiMessage, + data_relevant = data_relevant, + source_file = source_file + ) + session.add(new_user) + session.commit() + return new_user.id + session.close() + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + new_user = detail_chat( + chat_id=chat_id, + YouMessage=YouMessage, + AiMessage=AiMessage, + data_relevant=data_relevant, + source_file=source_file + ) + session.add(new_user) + session.commit() + return new_user.id + session.close() + +def getDetailChatByChatId(id: int) -> detail_chat: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + try: + chat = session.query(detail_chat).filter(detail_chat.id == id).one_or_none() + return chat + except: + session.close() + return False + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + try: + chat = session.query(detail_chat.id,detail_chat.data_relevant,detail_chat.source_file).filter(detail_chat.id == id).one_or_none() + session.commit() + session.close() + return chat + except: + session.close() + return False + + +def delete_chat_detail(chat_name: str) -> bool: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + try: + detail_chat2 = session.query(detail_chat).filter(detail_chat.chat_id == chat_history.id).filter(chat_history.name_chat == chat_name) + session.query(detail_chat).filter(detail_chat.chat_id == chat_history.id).filter(chat_history.name_chat == chat_name).delete(synchronize_session=False) + session.commit() + session.close() + return True + except: + session.close() + return False + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + try: + session.query(detail_chat).filter(detail_chat.chat_id == chat_history.id).filter(chat_history.name_chat == chat_name).delete(synchronize_session=False) + session.commit() + session.close() + return True + except: + session.close() + return False diff --git a/repository/OTPRepository.py b/repository/OTPRepository.py new file mode 100644 index 0000000000000000000000000000000000000000..15f90f5df6f94745a95afaf90af45b94353afaa0 --- /dev/null +++ b/repository/OTPRepository.py @@ -0,0 +1,82 @@ +from sqlalchemy.orm import sessionmaker +from entity import Database_Entity +from repository import ConfigDatabase as cf +otp_user = Database_Entity.OTP +from sqlalchemy.orm import sessionmaker +from functools import lru_cache +import sys +import os + +def getOtpByEmail(email: str) -> otp_user: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record= session.query(otp_user).filter(otp_user.email == email).one_or_none() + if user_record: + session.close() + return user_record + else: + session.close() + return None + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record= session.query(otp_user).filter(otp_user.email == email).one_or_none() + if user_record: + session.close() + return user_record + else: + session.close() + return None + +def addOTP(email: str, otp: str) -> None: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + otp_record = session.query(otp_user).filter_by(email=email).first() + if otp_record: + session.delete(otp_record) + session.commit() + new_user = otp_user( + email = email, + otp= otp + ) + session.add(new_user) + session.commit() + session.close() + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + otp_record = session.query(otp_user).filter_by(email=email).first() + if otp_record: + session.delete(otp_record) + session.commit() + new_user = otp_user( + email = email, + otp= otp + ) + session.add(new_user) + session.commit() + session.close() + +def deleteOTP(email: str, otp:str) -> None: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + otp_record = session.query(otp_user).filter_by(email=email, otp=otp).first() + if otp_record: + session.delete(otp_record) + session.commit() + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + otp_record = session.query(otp_user).filter_by(email=email, otp=otp).first() + if otp_record: + session.delete(otp_record) + session.commit() \ No newline at end of file diff --git a/repository/UserInfoRepository.py b/repository/UserInfoRepository.py new file mode 100644 index 0000000000000000000000000000000000000000..c6efb2c7ed0feb0f147fe56ef5f3723868193826 --- /dev/null +++ b/repository/UserInfoRepository.py @@ -0,0 +1,139 @@ +from sqlalchemy.orm import sessionmaker +from entity import Database_Entity +from repository import ConfigDatabase as cf +user_info = Database_Entity.UserInfo +users = Database_Entity.User +from sqlalchemy.orm import sessionmaker +import sys +import os + +def getUserInfo(user_id: int) -> user_info: + try: + email = session.query(users.email).filter(users.id == user_id).one_or_none() + if email: + email = email[0] + user_record= session.query(user_info).filter(user_info.email == email).one_or_none() + if user_record: + session.close() + return user_record + else: + session.close() + return None + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == user_id).one_or_none() + if email: + email = email[0] + user_record= session.query(user_info).filter(user_info.email == email).one_or_none() + if user_record: + session.close() + return user_record + else: + session.close() + return None + +def getUserInfoByEmail(email:str) -> user_info: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record= session.query(user_info).filter(user_info.email == email).one_or_none() + if user_record: + session.close() + return user_record + else: + session.close() + return None + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record= session.query(user_info).filter(user_info.email == email).one_or_none() + if user_record: + session.close() + return user_record + else: + session.close() + return None + + + +def addUserInfo(uid: str, email: str, display_name: str, photo_url: str) -> None: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + new_user = user_info( + uid = uid, + email = email, + display_name = display_name, + photo_url = photo_url + ) + session.add(new_user) + session.commit() + session.close() + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + new_user = user_info( + uid = uid, + email = email, + display_name = display_name, + photo_url = photo_url + ) + session.add(new_user) + session.commit() + session.close() + +def updateUserInfo(user_id, uid: str, email: str, display_name: str, photo_url: str) -> None: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == user_id).one_or_none() + user_update= session.query(user_info).filter(user_info.email == email).one_or_none() + if user_update is not None: + user_update.uid = uid, + user_update.display_name = display_name, + user_update.photo_url = photo_url + session.commit() + session.close() + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == user_id).one_or_none() + user_update= session.query(user_info).filter(user_info.email == email).one_or_none() + if user_update is not None: + user_update.uid = uid, + user_update.display_name = display_name, + user_update.photo_url = photo_url + session.commit() + session.close() + + +def updateImage(user_id, photo_url: str) -> None: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == user_id).one_or_none() + user_update= session.query(user_info).filter(user_info.email == email).one_or_none() + if user_update is not None: + user_update.photo_url = photo_url + session.commit() + session.close() + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == user_id).one_or_none() + user_update = session.query(user_info).filter(user_info.email == email).one_or_none() + if user_update is not None: + user_update.photo_url = photo_url + session.commit() + session.close() + diff --git a/repository/UserLoginRepository.py b/repository/UserLoginRepository.py new file mode 100644 index 0000000000000000000000000000000000000000..8b1981c8d2b34e5a40b1950ab1ab3291219c2400 --- /dev/null +++ b/repository/UserLoginRepository.py @@ -0,0 +1,135 @@ +from sqlalchemy.orm import sessionmaker +from entity import Database_Entity +from repository import ConfigDatabase as cf +user_login = Database_Entity.UserLogin +users = Database_Entity.User + +def getUserLogin(email: str) -> user_login: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record = session.query(user_login).filter(user_login.user_email == email).one_or_none() + if user_record: + session.close() + return user_record + else: + session.close() + return None + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record = session.query(user_login).filter(user_login.user_email == email).one_or_none() + if user_record: + session.close() + return user_record + else: + session.close() + return None + + +def getUserLoginById(id: int) -> user_login: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == id).one_or_none()[0] + user_record = session.query(user_login).filter(user_login.user_email == email).one_or_none() + if user_record: + session.close() + return user_record + else: + session.close() + return None + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == id).one_or_none()[0] + user_record = session.query(user_login).filter(user_login.user_email == email).one_or_none() + if user_record: + session.close() + return user_record + else: + session.close() + return None + +def addUserLogin(user_email: str, session_id : str) -> None: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + new_user = user_login( + user_email = user_email, + user_session_id = session_id + ) + session.add(new_user) + session.commit() + session.close() + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + new_user = user_login( + user_email = user_email, + user_session_id = session_id + ) + session.add(new_user) + session.commit() + session.close() + + +def updateUserLogin(email: str, session_id : str ) -> None: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_update= session.query(user_login).filter(user_login.user_email == email).one_or_none() + if user_update is not None: + user_update.user_session_id = session_id + session.commit() + session.close() + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_update= session.query(user_login).filter(user_login.user_email == email).one_or_none() + if user_update is not None: + user_update.user_session_id = session_id + session.commit() + session.close() + + + +def getUserSessionIdByUserEmail(id: int) -> user_login: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == id).one_or_none()[0] + session.commit() + user_record= session.query(user_login.user_session_id).filter(user_login.user_email == email).one_or_none()[0] + session.commit() + print(user_record) + if user_record: + session.close() + return user_record + else: + session.close() + return None + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + email = session.query(users.email).filter(users.id == id).one_or_none()[0] + session.commit() + user_record= session.query(user_login.user_session_id).filter(user_login.user_email == email).one_or_none()[0] + session.commit() + print(user_record) + if user_record: + session.close() + return user_record + else: + session.close() + return None \ No newline at end of file diff --git a/repository/UserRepository.py b/repository/UserRepository.py new file mode 100644 index 0000000000000000000000000000000000000000..07199013e079040dc085eda7b30f81e7dfa40c47 --- /dev/null +++ b/repository/UserRepository.py @@ -0,0 +1,356 @@ +from sqlalchemy.orm import sessionmaker +from entity import Database_Entity +from repository import ConfigDatabase as cf +import pytz , datetime +from datetime import timedelta +user = Database_Entity.User + +def getUserIdByAccessToken(token:str) -> int: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record = session.query(user.id).filter(user.access_token == token).one_or_none() + session.close() + return user_record + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record = session.query(user.id).filter(user.access_token == token).one_or_none() + session.close() + return user_record + +def getUserIdByAccessTokenAndUserId(token:str,user_id: int) -> int: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record = session.query(user.id).filter(user.access_token == token,user.id == user_id).one_or_none() + session.close() + return user_record + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record = session.query(user.id).filter(user.access_token == token,user.id == user_id).one_or_none() + session.close() + return user_record + +def getUserByEmail(email: str) -> user: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record = session.query(user).filter(user.email == email).one_or_none() + session.close() + return user_record + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record = session.query(user).filter(user.email == email).one_or_none() + session.close() + return user_record + +def getUserIdByEmail(email: str) -> user.id: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record = session.query(user.id).filter(user.email == email).one_or_none()[0] + session.close() + return user_record + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record = session.query(user.id).filter(user.email == email).one_or_none()[0] + session.close() + return user_record + +def getUserById(user_id: str) -> user: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record = session.query(user).filter(user.id == user_id).one_or_none() + session.close() + return user_record + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record = session.query(user).filter(user.id == user_id).one_or_none() + session.close() + return user_record + +def getRefreshTokenUserByAccessToken(token: str) -> user.refresh_token: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record = session.query(user.refresh_token).filter(user.access_token == token).one_or_none() + session.close() + return user_record + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record = session.query(user.refresh_token).filter(user.access_token == token).one_or_none() + session.close() + return user_record + +def getRefreshTokenUserByIdAndAccessToken(user_id: str,accessToken: str) -> user.refresh_token: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record = session.query(user.refresh_token).filter(user.id == user_id,user.access_token == accessToken).one_or_none()[0] + session.close() + return user_record + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record = session.query(user.refresh_token).filter(user.id == user_id).one_or_none()[0] + session.close() + return user_record + +def getRefreshTokenUserById(user_id: str) -> user.refresh_token: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record = session.query(user.refresh_token).filter(user.id == user_id).one_or_none()[0] + session.close() + return user_record + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_record = session.query(user.refresh_token).filter(user.id == user_id).one_or_none()[0] + session.close() + return user_record + +def getEmailUser(email:str) -> user.email: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_email = session.query(user.email).filter(user.email == email).one_or_none() + session.close() + return user_email + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_email = session.query(user.email).filter(user.email == email).one_or_none() + session.close() + return user_email + +def getEmailUserById(user_id:int) -> user.email: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_email = session.query(user.email).filter(user.id == user_id).one_or_none()[0] + session.close() + return user_email + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_email = session.query(user.email).filter(user.id == user_id).one_or_none()[0] + session.close() + return user_email + +def getEmailUserByIdFix(user_id:int) -> user.email: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_email = session.query(user.email).filter(user.id == user_id).one_or_none() + session.close() + return user_email + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_email = session.query(user.email).filter(user.id == user_id).one_or_none() + session.close() + return user_email + + + +def getEmailUserByAccessToken(token: str) -> user.email: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_email = session.query(user.email).filter(user.access_token == token).one_or_none() + session.close() + return user_email + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_email = session.query(user.email).filter(user.access_token == token).one_or_none() + session.close() + return user_email + + +def addUser(email: str, access_token: str, refresh_token: str, expires_at: datetime.datetime) -> None: + try: + engine = cf.get_db_engine() + Session = sessionmaker(bind=engine) + with Session() as session: + new_user = Database_Entity.User( + email=email, + access_token=access_token, + refresh_token=refresh_token, + expires_at=expires_at + ) + session.add(new_user) + session.commit() + session.close() + except: + engine = cf.get_db_engine1() + Session = sessionmaker(bind=engine) + with Session() as session: + new_user = Database_Entity.User( + email=email, + access_token=access_token, + refresh_token=refresh_token, + expires_at=expires_at + ) + session.add(new_user) + session.commit() + session.close() + + +def updateUserLogin(email: str, access_token: str, refresh_token: str, expires_at: datetime.datetime) -> bool: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_update = session.query(user).filter(user.email == email).one_or_none() + if user_update: + user_update.email = email + user_update.access_token = access_token + user_update.refresh_token = refresh_token + user_update.expires_at = expires_at + session.commit() + session.close() + return True + else: + session.close() + return False + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_update = session.query(user).filter(user.email == email).one_or_none() + if user_update: + user_update.email = email + user_update.access_token = access_token + user_update.refresh_token = refresh_token + user_update.expires_at = expires_at + session.commit() + session.close() + return True + else: + session.close() + return False + + +def updateAccessToken(user_id: int,access_token: str, expires_at: datetime.datetime) -> None: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_update = session.query(user).filter(user.id == user_id).one_or_none() + if user_update: + user_update.access_token = access_token + user_update.expires_at = expires_at + session.commit() + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_update = session.query(user).filter(user.id == user_id).one_or_none() + if user_update: + user_update.access_token = access_token + user_update.expires_at = expires_at + session.commit() + +def updateAccessTokenById(id: int,access_token: str, expires_at: datetime.datetime) -> None: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_update = session.query(user).filter(user.id == id).one_or_none() + if user_update: + user_update.access_token = access_token + user_update.expires_at = expires_at + session.commit() + session.close() + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_update = session.query(user).filter(user.id == id).one_or_none() + if user_update: + user_update.access_token = access_token + user_update.expires_at = expires_at + session.commit() + session.close() + + +def UpdateAccessTokenRefreshToken(email: str, access_token: str, refresh_token: str, expires_at: datetime.datetime) -> None: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_update = session.query(user).filter(user.email == email).one_or_none() + if user_update: + user_update.access_token = access_token + user_update.refresh_token = refresh_token + user_update.expires_at = expires_at + session.commit() + session.close() + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_update = session.query(user).filter(user.email == email).one_or_none() + if user_update: + user_update.access_token = access_token + user_update.refresh_token = refresh_token + user_update.expires_at = expires_at + session.commit() + session.close() + +def UpdateAccessTokenRefreshTokenById(user_id: int,access_token: str, refresh_token: str, expires_at: datetime.datetime) -> None: + try: + engine = cf.get_db_engine() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_update = session.query(user).filter(user.id == user_id).one_or_none() + if user_update: + user_update.access_token = access_token + user_update.refresh_token = refresh_token + user_update.expires_at = expires_at + session.commit() + session.close() + except: + engine = cf.get_db_engine1() + Session = sessionmaker(autocommit=False, autoflush=False, bind=engine) + with Session() as session: + user_update = session.query(user).filter(user.id == user_id).one_or_none() + if user_update: + user_update.access_token = access_token + user_update.refresh_token = refresh_token + user_update.expires_at = expires_at + session.commit() + session.close() diff --git a/repository/__pycache__/ChatHistoryRepository.cpython-310.pyc b/repository/__pycache__/ChatHistoryRepository.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..88b6e58e8e6d38f4dca4812ab1de7e2540519ee8 Binary files /dev/null and b/repository/__pycache__/ChatHistoryRepository.cpython-310.pyc differ diff --git a/repository/__pycache__/ChatHistoryRepository.cpython-311.pyc b/repository/__pycache__/ChatHistoryRepository.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a9d24b87f95fa36968e4fbdce481fc4a0a91ff25 Binary files /dev/null and b/repository/__pycache__/ChatHistoryRepository.cpython-311.pyc differ diff --git a/repository/__pycache__/ConfigDatabase.cpython-310.pyc b/repository/__pycache__/ConfigDatabase.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e4ab9d5ea504152b102d0fe1416fe790cd4c1606 Binary files /dev/null and b/repository/__pycache__/ConfigDatabase.cpython-310.pyc differ diff --git a/repository/__pycache__/ConfigDatabase.cpython-311.pyc b/repository/__pycache__/ConfigDatabase.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ee365c3025f246c18f00fc9a618b73b38f263a1c Binary files /dev/null and b/repository/__pycache__/ConfigDatabase.cpython-311.pyc differ diff --git a/repository/__pycache__/DetailChatRepository.cpython-310.pyc b/repository/__pycache__/DetailChatRepository.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..162aed6f42a83cbec0667142f658c7111f347576 Binary files /dev/null and b/repository/__pycache__/DetailChatRepository.cpython-310.pyc differ diff --git a/repository/__pycache__/DetailChatRepository.cpython-311.pyc b/repository/__pycache__/DetailChatRepository.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c0a547eae70e9c80dee6b54f336d2f6793c5a327 Binary files /dev/null and b/repository/__pycache__/DetailChatRepository.cpython-311.pyc differ diff --git a/repository/__pycache__/OTPRepository.cpython-310.pyc b/repository/__pycache__/OTPRepository.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4664fb0094dbeb3464e6231ebf68ceacac12eaaf Binary files /dev/null and b/repository/__pycache__/OTPRepository.cpython-310.pyc differ diff --git a/repository/__pycache__/OTPRepository.cpython-311.pyc b/repository/__pycache__/OTPRepository.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..087856e3235ceaf12d5fa0c2d9c17aec53bfea04 Binary files /dev/null and b/repository/__pycache__/OTPRepository.cpython-311.pyc differ diff --git a/repository/__pycache__/UserInfoRepository.cpython-310.pyc b/repository/__pycache__/UserInfoRepository.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fd5e487f1bb3a0ecd61141348c23465d05461577 Binary files /dev/null and b/repository/__pycache__/UserInfoRepository.cpython-310.pyc differ diff --git a/repository/__pycache__/UserInfoRepository.cpython-311.pyc b/repository/__pycache__/UserInfoRepository.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5a1aa35a8ddffaa1cf56dba05ab6bb9c72662af6 Binary files /dev/null and b/repository/__pycache__/UserInfoRepository.cpython-311.pyc differ diff --git a/repository/__pycache__/UserLoginRepository.cpython-310.pyc b/repository/__pycache__/UserLoginRepository.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e00032da81c19dfeaebf622c8998e341a1934bac Binary files /dev/null and b/repository/__pycache__/UserLoginRepository.cpython-310.pyc differ diff --git a/repository/__pycache__/UserLoginRepository.cpython-311.pyc b/repository/__pycache__/UserLoginRepository.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b696c690382071788cbe6473c625b3fd42d14c4b Binary files /dev/null and b/repository/__pycache__/UserLoginRepository.cpython-311.pyc differ diff --git a/repository/__pycache__/UserRepository.cpython-310.pyc b/repository/__pycache__/UserRepository.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..17a3ee6dde64913c59da869eeaf7ff67ebe38f73 Binary files /dev/null and b/repository/__pycache__/UserRepository.cpython-310.pyc differ diff --git a/repository/__pycache__/UserRepository.cpython-311.pyc b/repository/__pycache__/UserRepository.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b52d4f9e617c21824f3063171a558c9c109c1ce Binary files /dev/null and b/repository/__pycache__/UserRepository.cpython-311.pyc differ diff --git a/request/RequestChat.py b/request/RequestChat.py new file mode 100644 index 0000000000000000000000000000000000000000..b15f21f1e5538f29ad0be359edff0a00de11f2dc --- /dev/null +++ b/request/RequestChat.py @@ -0,0 +1,17 @@ +from pydantic import BaseModel +from typing import Optional + +class RequestQuery2UpgradeOld(BaseModel): + user_id: int + text_all: str + question: Optional[str] + chat_name: Optional[str] + +class RequestExtractFile(BaseModel): + user_id: int + +class RequestDeleteChat(BaseModel): + user_id: int + chat_name: Optional[str] +class RequestGenerateQuestion(BaseModel): + user_id: int \ No newline at end of file diff --git a/request/RequestDefault.py b/request/RequestDefault.py new file mode 100644 index 0000000000000000000000000000000000000000..43cd65cb988edefcee6bc620ee9320c82d386590 --- /dev/null +++ b/request/RequestDefault.py @@ -0,0 +1,13 @@ +from pydantic import BaseModel, EmailStr +from typing import Optional, List +from fastapi import UploadFile +class RequestCreateFireBaseUserGoogle(BaseModel): + email: Optional[str] = None +class RequestInfoUser(BaseModel): + user_id: str +class RequestIsMe(BaseModel): + token: Optional[str] + +class RequestUpLoadImage(BaseModel): + user_id: Optional[str] + files: UploadFile = None diff --git a/request/RequestFile.py b/request/RequestFile.py new file mode 100644 index 0000000000000000000000000000000000000000..ae9ba15ccd5152f3a7b77a51fc62a0fbbe2a2858 --- /dev/null +++ b/request/RequestFile.py @@ -0,0 +1,19 @@ +from pydantic import BaseModel +from typing import List, Optional +from fastapi import UploadFile +class RequestGetNameFile(BaseModel): + user_id: Optional[str] +class RequestDeleteFile(BaseModel): + user_id: Optional[str] + name_file: Optional[str] +class RequestDeleteAllFile(BaseModel): + user_id: Optional[str] +class RequestDownLoadFolder(BaseModel): + user_id: Optional[str] + +class RequestDownLoadFile(BaseModel): + user_id: Optional[str] + name_file: Optional[str] +class RequestUploadFile(BaseModel): + files: Optional[List[UploadFile]] = None + user_id: Optional[str] \ No newline at end of file diff --git a/request/RequestLogin.py b/request/RequestLogin.py new file mode 100644 index 0000000000000000000000000000000000000000..3798558d1355c3ba85647c93a7eea95d6f391032 --- /dev/null +++ b/request/RequestLogin.py @@ -0,0 +1,47 @@ +from pydantic import BaseModel +from typing import Optional +class RequestLoginEmail(BaseModel): + email: Optional[str] + password: Optional[str] + +class RequestLoginGoogle(BaseModel): + email: Optional[str] + token_google: Optional[str] +class RequestUpdateUserInfo(BaseModel): + user_id: Optional[str] + uid: Optional[str] + email: Optional[str] + display_name: Optional[str] + photo_url: Optional[str] + +class RequestCheckInfoGoogle(BaseModel): + user_id: int +class RequestCheckInfoGoogleEmail(BaseModel): + email:Optional[str] +class RequestCreateOTP(BaseModel): + email: Optional[str] + +class RequestVerifyOTP(BaseModel): + email: Optional[str] + otp: Optional[str] + +class RequestCheckStateLogin(BaseModel): + user_id: Optional[int] + session_id_now: Optional[str] + +class RequestSignUp(BaseModel): + email: Optional[str] + password: Optional[str] + username: Optional[str] + +class RequestResetPassword(BaseModel): + email: Optional[str] + +class RequestChangePassword(BaseModel): + user_id: Optional[str] + new_password: Optional[str] + current_password: Optional[str] + +class RequestRefreshTokenLogin(BaseModel): + user_id: Optional[str] + token: Optional[str] \ No newline at end of file diff --git a/request/RequestMySQL.py b/request/RequestMySQL.py new file mode 100644 index 0000000000000000000000000000000000000000..ff9a0ac0e2a2dfbc60260eece05644cc286b2a24 --- /dev/null +++ b/request/RequestMySQL.py @@ -0,0 +1,21 @@ +from pydantic import BaseModel +from typing import Optional + +class RequestRenderChatHistory(BaseModel): + user_id: Optional[int] + +class RequestLoadChatHistory(BaseModel): + user_id: Optional[int] + chat_id: Optional[int] + +class RequestGetChatDetails(BaseModel): + id: Optional[str] + +class RequestEditNameChat(BaseModel): + user_id: Optional[str] + name_old: Optional[str] + name_new: Optional[str] + +class RequestDeleteChat(BaseModel): + user_id: Optional[str] + chat_name: Optional[str] \ No newline at end of file diff --git a/request/RequestOTP.py b/request/RequestOTP.py new file mode 100644 index 0000000000000000000000000000000000000000..76341a3644007547101b7753c4ff9d82ca45240d --- /dev/null +++ b/request/RequestOTP.py @@ -0,0 +1,9 @@ +from pydantic import BaseModel +from typing import Optional + +class RequestCreateOTP(BaseModel): + email: Optional[str] + +class RequestVerifyOTP(BaseModel): + email: Optional[str] + otp: Optional[str] \ No newline at end of file diff --git a/request/__pycache__/RequestChat.cpython-310.pyc b/request/__pycache__/RequestChat.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e21a05a3920ca501da5788a7be5b9ab10c0c60c Binary files /dev/null and b/request/__pycache__/RequestChat.cpython-310.pyc differ diff --git a/request/__pycache__/RequestChat.cpython-311.pyc b/request/__pycache__/RequestChat.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4658d020f25a7665808013e93598fc4adb393ae0 Binary files /dev/null and b/request/__pycache__/RequestChat.cpython-311.pyc differ diff --git a/request/__pycache__/RequestDefault.cpython-310.pyc b/request/__pycache__/RequestDefault.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d268593760c9ce6d05f02d94a7d7dbfa262892e8 Binary files /dev/null and b/request/__pycache__/RequestDefault.cpython-310.pyc differ diff --git a/request/__pycache__/RequestDefault.cpython-311.pyc b/request/__pycache__/RequestDefault.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b5a5e8207edebdcf08e65a99e1110874a74be194 Binary files /dev/null and b/request/__pycache__/RequestDefault.cpython-311.pyc differ diff --git a/request/__pycache__/RequestFile.cpython-310.pyc b/request/__pycache__/RequestFile.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..973374f9b1172f74689d87bebe98ed539c487b57 Binary files /dev/null and b/request/__pycache__/RequestFile.cpython-310.pyc differ diff --git a/request/__pycache__/RequestFile.cpython-311.pyc b/request/__pycache__/RequestFile.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5967aa6e7c1df37dc22303cb87f2a64064fe2688 Binary files /dev/null and b/request/__pycache__/RequestFile.cpython-311.pyc differ diff --git a/request/__pycache__/RequestLogin.cpython-310.pyc b/request/__pycache__/RequestLogin.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..379c044abb22fcca57f3389322d6c58127533477 Binary files /dev/null and b/request/__pycache__/RequestLogin.cpython-310.pyc differ diff --git a/request/__pycache__/RequestLogin.cpython-311.pyc b/request/__pycache__/RequestLogin.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9cc8e1e645e99a7c818f4c023fe05f241537bb7e Binary files /dev/null and b/request/__pycache__/RequestLogin.cpython-311.pyc differ diff --git a/request/__pycache__/RequestMySQL.cpython-310.pyc b/request/__pycache__/RequestMySQL.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f8e8d618fae73051919908b940bf29d7b52602f Binary files /dev/null and b/request/__pycache__/RequestMySQL.cpython-310.pyc differ diff --git a/request/__pycache__/RequestMySQL.cpython-311.pyc b/request/__pycache__/RequestMySQL.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ac6dcc1d3a909dc454070b945d55a3140a57f756 Binary files /dev/null and b/request/__pycache__/RequestMySQL.cpython-311.pyc differ diff --git a/request/__pycache__/RequestOTP.cpython-310.pyc b/request/__pycache__/RequestOTP.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d50102a3c3ff602039be809f53245240a4d4ef78 Binary files /dev/null and b/request/__pycache__/RequestOTP.cpython-310.pyc differ diff --git a/request/__pycache__/RequestOTP.cpython-311.pyc b/request/__pycache__/RequestOTP.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e6d943511a401a478afa432f290a9a8aa7806379 Binary files /dev/null and b/request/__pycache__/RequestOTP.cpython-311.pyc differ diff --git a/response/ResponseChat.py b/response/ResponseChat.py new file mode 100644 index 0000000000000000000000000000000000000000..8fe21d49a969955dba54f15a201f4d0d96d5ee0e --- /dev/null +++ b/response/ResponseChat.py @@ -0,0 +1,55 @@ +from pydantic import BaseModel +from typing import List, Union, Optional + +class DataAnswer(BaseModel): + answer: str + +class DataAnswer1(BaseModel): + id: int + answer: str + data_relevant: List[str] + sources: List[str] + +class FileMetadata(BaseModel): + source: str + +class FileResponse(BaseModel): + page_content: str + metadata: FileMetadata + type: str + +class DataExtractFile(BaseModel): + text_all: Union[List[FileResponse], None, str] + +class Message(BaseModel): + message: str + +class CheckModel(BaseModel): + check: bool + +class ResponseQuery2Upgrade(BaseModel): + status: int + data: DataAnswer + +class GenerateQuestion(BaseModel): + question: Union[List[str], bool] + +class ResponseGenerateQuestion(BaseModel): + status: int + data: GenerateQuestion + +class ResponseQuery2UpgradeOld(BaseModel): + status: int + data: DataAnswer1 + +class ResponseExtractFile(BaseModel): + status: int + data: DataExtractFile + +class ResponseDeleteChat(BaseModel): + status: int + data: Message + +class ReponseError(BaseModel): + status: int + data: Message \ No newline at end of file diff --git a/response/ResponseDefault.py b/response/ResponseDefault.py new file mode 100644 index 0000000000000000000000000000000000000000..75750c932209b9b3ac83d0bd4809d80637c35e55 --- /dev/null +++ b/response/ResponseDefault.py @@ -0,0 +1,44 @@ +from pydantic import BaseModel + +class DataInfoUser(BaseModel): + uid: str + email: str + display_name: str + photo_url: str + +class DataIsMe(BaseModel): + user_id: int + +class DataUploadImage(BaseModel): + url: str +class Message(BaseModel): + message: str + +class CheckModel(BaseModel): + check: bool + +class DataCreateFireBaseUser(BaseModel): + localId: str + email: str + displayName: str + photoUrl: str + +class ResponseCreateFireBaseUser(BaseModel): + status: int + data: DataCreateFireBaseUser + +class ResponseInfoUser(BaseModel): + status: int + data: DataInfoUser + +class ResponseIsMe(BaseModel): + status: int + data: DataIsMe + +class ResponseUploadImage(BaseModel): + status: int + data: DataUploadImage + +class ReponseError(BaseModel): + status: int + data: Message \ No newline at end of file diff --git a/response/ResponseFile.py b/response/ResponseFile.py new file mode 100644 index 0000000000000000000000000000000000000000..8a92828bfef812b57793e2e55093c28d9bb0b31b --- /dev/null +++ b/response/ResponseFile.py @@ -0,0 +1,39 @@ +from pydantic import BaseModel +from typing import List + +class Message(BaseModel): + message: str + +class CheckModel(BaseModel): + check: bool + +class DataGetNameFile(BaseModel): + files: List[str] + +class ResponseGetNameFile(BaseModel): + status: int + data: DataGetNameFile + +class ResponseDeleteFile(BaseModel): + status: int + data: Message + +class ResponseDownloadFolder(BaseModel): + status: int + data: Message + +class ResponseDeleteAllFile(BaseModel): + status: int + data: Message + +class ResponseDownloadFile(BaseModel): + status: int + data: Message + +class ResponseUploadedFile(BaseModel): + status: int + data: Message + +class ReponseError(BaseModel): + status: int + data: Message \ No newline at end of file diff --git a/response/ResponseLogin.py b/response/ResponseLogin.py new file mode 100644 index 0000000000000000000000000000000000000000..e0d9a7bcb90591701fba6aee54f4b3ad2d5dc2ba --- /dev/null +++ b/response/ResponseLogin.py @@ -0,0 +1,74 @@ +from pydantic import BaseModel + +class DataLogin(BaseModel): + access_token: str + refresh_token: str + expires_in: int + session_id: str + +class DataRefreshToken(BaseModel): + token_new: str + session_id: str + +class DataSignUp(BaseModel): + email: str + +class Message(BaseModel): + message: str + +class CheckModel(BaseModel): + check: bool + +class ResponseLoginEmail(BaseModel): + status: int + data: DataLogin + +class ResponseLoginGoogle(BaseModel): + status: int + data: DataLogin + +class ResponseUpdateUserInfo(BaseModel): + status : int + data: Message + +class ResponseCreateOTP(BaseModel): + status: int + data: CheckModel + otp: str + +class ResponseVerifyOTP(BaseModel): + status: int + data: Message + newpassword: str + +class ResponseVerifyOTPSignUp(BaseModel): + status: int + data: Message + +class ResponseCheckInfoGoogle(BaseModel): + status: int + data: CheckModel + +class ResponseCheckStateLogin(BaseModel): + status: int + data: CheckModel + +class ResponseSignUp(BaseModel): + status: int + data: DataSignUp + +class ResponseResetPassword(BaseModel): + status: int + data: Message + +class ResponseChangePassword(BaseModel): + status: int + data: Message + +class ResponseRefreshTokenLogin(BaseModel): + status: int + data: DataRefreshToken + +class ReponseError(BaseModel): + status: int + data: Message \ No newline at end of file diff --git a/response/ResponseMySQL.py b/response/ResponseMySQL.py new file mode 100644 index 0000000000000000000000000000000000000000..99ab9785d7ae07580b4a188ae0a61480da39ad32 --- /dev/null +++ b/response/ResponseMySQL.py @@ -0,0 +1,55 @@ +from pydantic import BaseModel +from typing import List + +class ListUserChat(BaseModel): + id: int + email: str + chat_name: str + +class ChatDetail(BaseModel): + id: int + chat_id: int + question: str + answer: str + data_relevant: str + source_file: str + +class ChatDetailById(BaseModel): + id: int + data_relevant: str + source_file: str + +class ListChatDeTail(BaseModel): + detail_chat: List[ChatDetail] + +class UserInfoListResponse(BaseModel): + chat: List[ListUserChat] + +class Message(BaseModel): + message: str + +class CheckModel(BaseModel): + check: bool + +class ResponseRenderChatHistory(BaseModel): + status: int + data: UserInfoListResponse + +class ResponseChatDetailById(BaseModel): + status: int + data: ChatDetailById +class ResponseLoadChatHistory(BaseModel): + status: int + data: ListChatDeTail + +class ResponseEditChat(BaseModel): + status: int + data: Message + +class ResponseDeleteChat(BaseModel): + status: int + data: Message + +class ReponseError(BaseModel): + status: int + data: Message \ No newline at end of file diff --git a/response/ResponseOTP.py b/response/ResponseOTP.py new file mode 100644 index 0000000000000000000000000000000000000000..1918bc376bfa0a00d204c9c1052f8d61711ded42 --- /dev/null +++ b/response/ResponseOTP.py @@ -0,0 +1,25 @@ +from pydantic import BaseModel + +class Message(BaseModel): + message: str + +class CheckModel(BaseModel): + check: bool + +class ResponseCreateOTP(BaseModel): + status: int + data: CheckModel + otp: str + +class ResponseVerifyOTP(BaseModel): + status: int + data: Message + newpassword: str + +class ResponseVerifyOTPSignUp(BaseModel): + status: int + data: Message + +class ReponseError(BaseModel): + status: int + data: Message \ No newline at end of file diff --git a/response/__pycache__/ResponseChat.cpython-310.pyc b/response/__pycache__/ResponseChat.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b9636d14712a58d16f711fca747d72a7ddf5abbe Binary files /dev/null and b/response/__pycache__/ResponseChat.cpython-310.pyc differ diff --git a/response/__pycache__/ResponseChat.cpython-311.pyc b/response/__pycache__/ResponseChat.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..238f5f31a8d3338298c085cdfe209190dea336df Binary files /dev/null and b/response/__pycache__/ResponseChat.cpython-311.pyc differ diff --git a/response/__pycache__/ResponseDefault.cpython-310.pyc b/response/__pycache__/ResponseDefault.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..837702d5cf014f8171b367ca5d7ce6c5f2215443 Binary files /dev/null and b/response/__pycache__/ResponseDefault.cpython-310.pyc differ diff --git a/response/__pycache__/ResponseDefault.cpython-311.pyc b/response/__pycache__/ResponseDefault.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5513f4d6004c2bfb678fdf1de9f12fd38416f152 Binary files /dev/null and b/response/__pycache__/ResponseDefault.cpython-311.pyc differ diff --git a/response/__pycache__/ResponseFile.cpython-310.pyc b/response/__pycache__/ResponseFile.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6641b4f3071be21616c971d09ee84a700856bed7 Binary files /dev/null and b/response/__pycache__/ResponseFile.cpython-310.pyc differ diff --git a/response/__pycache__/ResponseFile.cpython-311.pyc b/response/__pycache__/ResponseFile.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2a35244661dd857cf584ce7d95f38f9739ae044 Binary files /dev/null and b/response/__pycache__/ResponseFile.cpython-311.pyc differ diff --git a/response/__pycache__/ResponseLogin.cpython-310.pyc b/response/__pycache__/ResponseLogin.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f017530f8050b5435bd116a2e0efb9dd84afb6b8 Binary files /dev/null and b/response/__pycache__/ResponseLogin.cpython-310.pyc differ diff --git a/response/__pycache__/ResponseLogin.cpython-311.pyc b/response/__pycache__/ResponseLogin.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f4befad384cf55b6b212a575b831ac788821e4a9 Binary files /dev/null and b/response/__pycache__/ResponseLogin.cpython-311.pyc differ diff --git a/response/__pycache__/ResponseMySQL.cpython-310.pyc b/response/__pycache__/ResponseMySQL.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e1e0d838e5b078c93025ac073eeefb3283faebeb Binary files /dev/null and b/response/__pycache__/ResponseMySQL.cpython-310.pyc differ diff --git a/response/__pycache__/ResponseMySQL.cpython-311.pyc b/response/__pycache__/ResponseMySQL.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..42a4f731cca5106b937647ed4957284e0fb68053 Binary files /dev/null and b/response/__pycache__/ResponseMySQL.cpython-311.pyc differ diff --git a/response/__pycache__/ResponseOTP.cpython-310.pyc b/response/__pycache__/ResponseOTP.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..21a77772024e80f45f7348dcfbbe864ad02208c8 Binary files /dev/null and b/response/__pycache__/ResponseOTP.cpython-310.pyc differ diff --git a/response/__pycache__/ResponseOTP.cpython-311.pyc b/response/__pycache__/ResponseOTP.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da4dfb797b3c6c760660ab4df3202f6e9a57ca93 Binary files /dev/null and b/response/__pycache__/ResponseOTP.cpython-311.pyc differ diff --git a/service/ChatService.py b/service/ChatService.py new file mode 100644 index 0000000000000000000000000000000000000000..615b17c5d108ce19169e84801a31a5175cd80a76 --- /dev/null +++ b/service/ChatService.py @@ -0,0 +1,142 @@ +from typing import Union +from datetime import timedelta +from request import RequestChat as req +from response import ResponseChat as res +from repository import ChatHistoryRepository, DetailChatRepository, UserRepository +import function.chatbot as sf +from typing import Dict +import json, re +from pydantic import BaseModel +from function import support_function +regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b' + +def check_email(email): + if(re.fullmatch(regex, email)): + return True + else: + return False + +class Document(BaseModel): + page_content: str + metadata: Dict[str, str] + type: str + +def query2_upgrade_old(request: req.RequestQuery2UpgradeOld): + try: + user_id = request.user_id + question = request.question + text_all = request.text_all + chat_name = request.chat_name + email = support_function.check_email_service(str(user_id)) + if isinstance(email, res.ReponseError): + return email + if question is None: + return res.ReponseError( + status=400, + data =res.Message(message="question is empty") + ) + if chat_name is None: + return res.ReponseError( + status=400, + data =res.Message(message="chat_name is empty") + ) + text_all_dicts = json.loads(text_all) + # text_all1 = [Document(**doc) for doc in text_all_dicts] + text_all1 = list(map(lambda doc: Document(**doc), text_all_dicts)) + test, list1, list2 = sf.handle_query_upgrade_keyword_old(question, text_all1, email) + text1 = "".join(list1) + text2 = "".join(list2) + id = 0 + if test: + chat_id = ChatHistoryRepository.getIdChatHistoryByUserIdAndNameChat(user_id,chat_name) + if chat_id: + id = DetailChatRepository.addDetailChat(chat_id,question, test, text1, text2) + if chat_id is None: + ChatHistoryRepository.addChatHistory(user_id,chat_name) + chat_id_new = ChatHistoryRepository.getIdChatHistoryByUserIdAndNameChat(user_id,chat_name) + id = DetailChatRepository.addDetailChat(chat_id_new, question, test, text1, text2) + return res.ResponseQuery2UpgradeOld( + status= 200, + data = res.DataAnswer1(id = id, + answer=test, + data_relevant=list1, + sources=list2)) + if test is None or test == "": + return res.ReponseError( + status=500, + data =res.Message(message="No answer") + ) + except: + return res.ReponseError( + status=500, + data =res.Message(message="Server Error") + ) + +def extract_file(request: req.RequestExtractFile): + try: + user_id = request.user_id + email = support_function.check_email_service(str(user_id)) + if isinstance(email, res.ReponseError): + return email + text_all1 = sf.extract_data2(email) + if text_all1 is False: + return res.ResponseExtractFile( + status= 200, + data = res.DataExtractFile(text_all="No data response")) + return res.ResponseExtractFile( + status= 200, + data = res.DataExtractFile(text_all=text_all1)) + except: + return res.ReponseError( + status=500, + data =res.Message(message="Server Error") + ) + +def generate_question(request: req.RequestGenerateQuestion): + try: + user_id = request.user_id + email = support_function.check_email_service(str(user_id)) + if isinstance(email, res.ReponseError): + return email + text_all1 = sf.generate_question(email) + if text_all1 is False: + return res.ResponseGenerateQuestion( + status= 200, + data = res.GenerateQuestion(question=False)) + + return res.ResponseGenerateQuestion( + status= 200, + data = res.GenerateQuestion(question=text_all1)) + except: + return res.ReponseError( + status=500, + data=res.Message(message="Server Error") + ) + +def delete_chat(request: req.RequestDeleteChat): + try: + user_id = request.user_id + email = support_function.check_email_service(str(user_id)) + if isinstance(email, res.ReponseError): + return email + chat_name = request.chat_name + if chat_name is None: + return res.ReponseError( + status=400, + data =res.Message(message="chat_name is empty") + ) + DetailChatRepository.delete_chat_detail(chat_name) + check = ChatHistoryRepository.deleteChatHistory(user_id,chat_name) + if check is False: + return res.ResponseDeleteChat( + status = 500, + data = res.Message(message="Delete conversation chat failed")) + else: + return res.ResponseDeleteChat( + status = 200, + data = res.Message(message="Delete conversation chat success")) + except: + return res.ReponseError( + status= 500, + data = res.Message(message="Server Error") + ) \ No newline at end of file diff --git a/service/DefaultService.py b/service/DefaultService.py new file mode 100644 index 0000000000000000000000000000000000000000..3607b4b4df1c43a50d98d1bc7295bee434d4130a --- /dev/null +++ b/service/DefaultService.py @@ -0,0 +1,204 @@ +from typing import Union +from datetime import timedelta +from request import RequestDefault as req +from response import ResponseDefault as res +from firebase_admin import credentials,auth,exceptions +import firebase_admin +import base64 +import auth.authentication as auth123 +import re +from repository import UserRepository, UserInfoRepository +from pathlib import Path +import cloudinary +import cloudinary.uploader +from fastapi import FastAPI, File, UploadFile +from function import support_function as sf +from dotenv import load_dotenv +import os +load_dotenv() +CLOUDINARY_CLOUD_NAME=os.getenv("CLOUDINARY_CLOUD_NAME") +CLOUDINARY_API_KEY=os.getenv("CLOUDINARY_API_KEY") +CLOUDINARY_API_SECRET=os.getenv("CLOUDINARY_API_SECRET") + + +cloudinary.config( + cloud_name=CLOUDINARY_CLOUD_NAME, + api_key=CLOUDINARY_API_KEY, + api_secret=CLOUDINARY_API_SECRET +) +import os + +try: + if not firebase_admin._apps: + cred = credentials.Certificate("../certificate/firebase_certificate.json") + fred = firebase_admin.initialize_app(cred) +except: + try: + if not firebase_admin._apps: + cred = credentials.Certificate("firebase_certificate.json") + fred = firebase_admin.initialize_app(cred) + except: + if not firebase_admin._apps: + json_path = Path(__file__).resolve().parent / 'app' / 'firebase_certificate.json' + cred = credentials.Certificate(str(json_path)) + fred = firebase_admin.initialize_app(cred) + +regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b' + +def check_email(email): + if(re.fullmatch(regex, email)): + return True + else: + return False + +def get_user(email): + try: + user = auth.get_user_by_email(email) + return user + except exceptions.FirebaseError as e: + return None + +def create_user(email): + user = auth.create_user(email=email) + return user + +def get_user1(email): + try: + user = auth.get_user_by_email(email) + return user + except exceptions.FirebaseError as e: + return None + +def create_firebase_user(request: req.RequestCreateFireBaseUserGoogle): + try: + email = request.email + check_email_fc = sf.check_email_empty_invalid(email) + if check_email_fc is not True: + return check_email_fc + user = get_user(email) + if user: + email1 = user.email + display_name = user.display_name + uid = user.uid + photo_url = user.photo_url + return res.ResponseCreateFireBaseUser( + status=200, + data = res.DataCreateFireBaseUser(localId=uid, + email=email1, + displayName=display_name, + photoUrl=photo_url) + ) + else: + return res.ReponseError( + status=500, + data =res.Message(message="Error") + ) + except: + return res.ReponseError( + status=500, + data =res.Message(message="Server Error") + ) + +def info_user(request: req.RequestInfoUser): + try: + user_id = request.user_id + email = sf.check_email_service(user_id) + if isinstance(email, res.ReponseError): + return email + user = get_user(email) + if user is None: + return res.ReponseError( + status=404, + data=res.Message(message="User not found") + ) + uid = user.uid if user.uid else "" + email = user.email if user.email else "" + display_name = user.display_name if user.display_name else "N/A" + photo_url = user.photo_url if user.photo_url else "N/A" + return res.ResponseInfoUser( + status=200, + data=res.DataInfoUser( + uid=uid, + email=email, + display_name=display_name, + photo_url=photo_url + ) + ) + except Exception as e: + return res.ReponseError( + status=500, + data=res.Message(message="Server Error: " + str(e)) + ) + +def check_email_token(token): + try: + decoded_token = auth123.decodeJWT(token) + sub_value = decoded_token.get("sub") + name_user = base64.b85decode(sub_value.encode('ascii')).decode('ascii') + return name_user + except: + return False + +def is_me(request: req.RequestIsMe): +# try: + token = request.token + if token is None or token == "": + return res.ReponseError( + status=400, + data =res.Message(message="token is empty") + ) + test = check_email_token(token) + if test is False: + user_id=UserRepository.getUserIdByAccessToken(token) + if user_id is None: + return res.ReponseError( + status=400, + data =res.Message(message="Token not exist") + ) + user_id = user_id[0] + return res.ResponseIsMe( + status=200, + data = res.DataIsMe(user_id = user_id)) + + else: + user_id = UserRepository.getUserByEmail(test).id + return res.ResponseIsMe( + status=200, + data = res.DataIsMe(user_id = user_id)) +# except: +# return res.ReponseError( +# status=500, +# data =res.Message(message="Server Error") +# ) + +ALLOWED_EXTENSIONS = {'png', 'jpg','jpeg'} +def allowed_file(filename): + return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS + +def upload_image_service(request: req.RequestUpLoadImage): + try: + user_id = request.user_id + file = request.files + email = sf.check_email_service(user_id) + if isinstance(email, res.ReponseError): + return email + if not allowed_file(file.filename): + return res.ReponseError( + status=415, + data=res.Message(message=f"File type not allow") + ) + temp_file_path = f"temp_image_{email}.png" + contents = file.file.read() + with open(temp_file_path, "wb") as temp_file: + temp_file.write(contents) + upload_result = cloudinary.uploader.upload(temp_file_path, public_id=email) + os.remove(temp_file_path) + return res.ResponseUploadImage( + status=200, + data=res.DataUploadImage(url=upload_result["secure_url"]) + ) + except: + return res.ReponseError( + status=500, + data=res.Message(message="Server Error") + ) \ No newline at end of file diff --git a/service/FileService.py b/service/FileService.py new file mode 100644 index 0000000000000000000000000000000000000000..b48d93b8f5fcfaa11934ac29ef82995000ec0f2e --- /dev/null +++ b/service/FileService.py @@ -0,0 +1,152 @@ +from request import RequestFile as req +from response import ResponseFile as res +from response import ResponseDefault as res1 +import function.dropbox as sf_dropbox +import os +import shutil +import re +from repository import UserRepository +from function import support_function as sf +ALLOWED_EXTENSIONS = {'csv', 'txt', 'doc', 'docx', 'pdf', 'xlsx', 'pptx', 'json','md'} +regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b' + +def check_email(email): + if(re.fullmatch(regex, email)): + return True + else: + return False + +def allowed_file(filename): + return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS + +def listNameFiles(request: req.RequestGetNameFile ): + try: + user_id = request.user_id + email = sf.check_email_service(user_id) + if isinstance(email,res1.ReponseError): + return email + list_files = sf_dropbox.list_files(email) + return res.ResponseGetNameFile( + status= 200, + data = res.DataGetNameFile(files=list_files) + ) + except: + return res.ReponseError( + status=500, + data =res.Message(message="Server Error") + ) + +def deleteFile(request: req.RequestDeleteFile): + try: + user_id = request.user_id + name_file = request.name_file + email = sf.check_email_service(user_id) + if isinstance(email, res1.ReponseError): + return email + if name_file is None or name_file == "": + return res.ReponseError( + status=400, + data =res.Message(message="Name file is empty") + ) + sf_dropbox.delete_file(email,name_file) + return res.ResponseDeleteFile( + status=200, + data =res.Message(message=f"delete {name_file} success") + ) + except: + return res.ReponseError( + status=500, + data =res.Message(message=f"delete {name_file} error") + ) + +def download_folder(request:req.RequestDownLoadFolder): + try: + user_id = request.user_id + email = sf.check_email_service(user_id) + if isinstance(email, res1.ReponseError): + return email + sf_dropbox.download_folder(email) + return res.ResponseDownloadFolder( + status=200, + data =res.Message(message=f"Downloaded folder {email} success") + ) + except: + return res.ReponseError( + status=500, + data =res.Message(message=f"Server error") + ) + +def download_file(request:req.RequestDownLoadFile): + try: + user_id = request.user_id + name_file = request.name_file + email = sf.check_email_service(user_id) + if isinstance(email, res1.ReponseError): + return email + if name_file is None or name_file =="": + return res.ReponseError( + status=400, + data =res.Message(message="name_file is empty") + ) + sf_dropbox.search_and_download_file(name_file,email) + return res.ResponseDownloadFile( + status=200, + data =res.Message(message=f"Downloaded file '{name_file}' by email: '{email}' success") + ) + except: + return res.ReponseError( + status=500, + data =res.Message(message=f"Server error") + ) + +ALLOWED_EXTENSIONS = {'csv', 'txt', 'doc', 'docx', 'pdf', 'xlsx', 'pptx', 'json','md'} + +def allowed_file1(filename): + return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS +def upload_files(request: req.RequestUploadFile): + try: + user_id = request.user_id + files = request.files + email = sf.check_email_service(user_id) + if isinstance(email, res1.ReponseError): + return email + for file in files: + if not allowed_file(file.filename): + return res.ReponseError( + status=415, + data =res.Message(message=f"File type not allow") + ) + temp_dir = f"/code/temp/{email}" + os.makedirs(temp_dir, exist_ok=True) + file_path = os.path.join(temp_dir, file.filename) + with open(file_path, "wb") as buffer: + shutil.copyfileobj(file.file, buffer) + cloud_path = f"/{email}/{file.filename}" + sf_dropbox.upload_file(file_path, cloud_path) + return res.ResponseUploadedFile( + status=200, + data =res.Message(message=f"Load file success") + ) + except: + return res.ReponseError( + status=500, + data =res.Message(message=f"Load file error") + ) + +def deleteAllFile(request: req.RequestDeleteAllFile): + try: + user_id = request.user_id + email = sf.check_email_service(user_id) + if isinstance(email, res.ReponseError): + return email + + sf_dropbox.delete_all_files_in_folder(email) + return res.ResponseDeleteAllFile( + status=200, + data=res.Message(message=f"Delete all file success") + ) + except: + return res.ReponseError( + status=500, + data=res.Message(message=f"Delete all file error") + ) \ No newline at end of file diff --git a/service/LoginService.py b/service/LoginService.py new file mode 100644 index 0000000000000000000000000000000000000000..c9696308923cf8238517b24f92e56ba807773c31 --- /dev/null +++ b/service/LoginService.py @@ -0,0 +1,512 @@ +from datetime import timedelta, datetime +from request import RequestLogin as req_login +from response import ResponseLogin as res_login +import requests +import json, re +from auth.authentication import signJWT +from firebase_admin import credentials, auth, exceptions +import firebase_admin +from repository import UserLoginRepository, UserRepository, UserInfoRepository, OTPRepository +import service.OTPService +from function import support_function as sf +from dotenv import load_dotenv +import os +from response import ResponseLogin as res +load_dotenv() +CLIENT_ID_GOOGLE = os.getenv('CLIENT_ID') +API_SIGN_UP_FIREBASE_PATH = os.getenv('API_SIGN_UP_FIREBASE') +regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b' + +def get_user1(email): + try: + user = auth.get_user_by_email(email) + return user + except exceptions.FirebaseError as e: + return None + +def check_email(email): + if isinstance(email, str) and re.fullmatch(regex, email): + return True + else: + return False +from pathlib import Path +try: + if not firebase_admin._apps: + json_path = Path(__file__).resolve().parent / 'app' / 'firebase_certificate.json' + cred = credentials.Certificate(str(json_path)) + fred = firebase_admin.initialize_app(cred) +except: + if not firebase_admin._apps: + cred = credentials.Certificate("firebase_certificate.json") + fred = firebase_admin.initialize_app(cred) + +def sign_up_with_email_and_password(email, password, username=None, return_secure_token=True): + try: + rest_api_url = "https://identitytoolkit.googleapis.com/v1/accounts:signUp" + payload = { + "email": email, + "password": password, + "returnSecureToken": return_secure_token + } + if username: + payload["displayName"] = username + payload = json.dumps(payload) + r = requests.post(rest_api_url, params={"key": API_SIGN_UP_FIREBASE_PATH}, data=payload) + try: + return r.json()['email'] + except Exception as e: + pass + except Exception as e: + pass + +def sign_in_with_email_and_password(email=None, password=None, return_secure_token=True): + rest_api_url = "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword" + try: + payload = { + "returnSecureToken": return_secure_token + } + if email: + payload["email"] = email + if password: + payload["password"] = password + payload = json.dumps(payload) + r = requests.post(rest_api_url, params={"key": API_SIGN_UP_FIREBASE_PATH}, data=payload) + r.raise_for_status() + data = r.json() + if 'idToken' in data: + return data['email'] + else: + return False + except requests.exceptions.RequestException as e: + print(f"Error signing in: {e}") + return False + +def update_info_user(uid, email=None, user_name=None, photo_url=None): + user_data = {} + if email is not None: + user_data['email'] = email + if user_name is not None: + user_data['display_name'] = user_name + if photo_url is not None and photo_url != 'N/A': + user_data['photo_url'] = photo_url + if user_data: + auth.update_user(uid, **user_data) + +def login(request: req_login.RequestLoginEmail): + try: + email = request.email + password = request.password + check_email_fc = sf.check_email_empty_invalid(email) + if check_email_fc is not True: + return check_email_fc + if password is None: + return res_login.ReponseError( + status=400, + data =res_login.Message(message="Password is empty") + ) + user_check = get_user1(email) + if user_check is None: + return res_login.ReponseError( + status=425, + data =res_login.Message(message="Email not exits") + ) + user = sign_in_with_email_and_password(email,password) + + if user: + check = signJWT(user) + if check is False: + return res_login.ReponseError( + status=500, + data =res_login.Message(message="Invalid authorization code.") + ) + else: + access_token = check["access_token"] + refresh_token = check["refresh_token"] + expires_in = check["expires_in"] + session_id = check["session_id"] + return res_login.ResponseLoginEmail( + status= 200, + data = res_login.DataLogin(access_token=access_token,refresh_token=refresh_token,expires_in=expires_in,session_id=session_id) + ) + else: + return res_login.ReponseError( + status=425, + data =res_login.Message(message="Passwords do not match") + ) + except: + return res_login.ReponseError( + status=500, + data=res_login.Message(message="Server Error") + ) + +def verify_token_google(token): + from google.oauth2 import id_token + from google.auth.transport import requests + try: + CLIENT_ID = CLIENT_ID_GOOGLE + id_info = id_token.verify_oauth2_token(token, requests.Request(), CLIENT_ID) + check = id_info['email_verified'] + if check is True: + return True + except ValueError as e: + return False + +def login_google(request: req_login.RequestLoginGoogle): + try: + email = request.email + token_google = request.token_google + check_google = verify_token_google(token_google) + if check_google is False: + return res_login.ReponseError( + status=400, + data =res_login.Message(message="Login google failed") + ) + check_email_fc = sf.check_email_empty_invalid(email) + if check_email_fc is not True: + return check_email_fc + user = get_user1(email) + if user: + check = signJWT(email) + if check == False: + return res_login.ReponseError( + status=500, + data =res_login.Message(message="Invalid authorization code.") + ) + else: + access_token = check["access_token"] + refresh_token = check["refresh_token"] + expires_in = check["expires_in"] + session_id = check["session_id"] + return res_login.ResponseLoginGoogle( + status= 200, + data = res_login.DataLogin(access_token=access_token,refresh_token=refresh_token,expires_in=expires_in,session_id=session_id) + ) + else: + return res_login.ReponseError( + status= 425, + data = res_login.Message(message="Email not exist") + ) + except: + return res_login.ReponseError( + status=500, + data=res_login.Message(message="Server Error") + ) + +def update_user_info(request: req_login.RequestUpdateUserInfo): + try: + email = request.email + user_id = request.user_id + email_check = sf.check_email_service(user_id) + if isinstance(email_check, res1.ReponseError): + return email_check + check_email_fc = sf.check_email_empty_invalid(email) + if check_email_fc is not True: + return check_email_fc + user = get_user1(email) + if user: + user_info = UserInfoRepository.getUserInfo(user_id) + if user_info: + UserInfoRepository.updateUserInfo( + request.user_id, + request.uid, + request.email, + request.display_name, + request.photo_url) + else: + UserInfoRepository.addUserInfo( + request.uid, + request.email, + request.display_name, + request.photo_url + ) + update_info_user(request.uid, + request.email, + request.display_name, + request.photo_url + ) + return res_login.ResponseUpdateUserInfo(status=200, + data = res_login.Message(message=f"User info updated successfully")) + else: + return res_login.ReponseError( + status = 400, + data = res_login.Message(message="Not found user") + ) + except: + return res_login.ReponseError( + status=500, + data=res_login.Message(message="Server Error") + ) + +def check_info_google(request: req_login.RequestCheckInfoGoogle): + try: + user_id = request.user_id + check = UserRepository.getEmailUserByIdFix(user_id) + if check is None: + return res_login.ReponseError( + status = 400, + data = res_login.Message(message="user_id not exist") + ) + email = sf.check_email_service(str(user_id)) + if isinstance(email, res.ReponseError): + return email + user_info = UserInfoRepository.getUserInfo(user_id) + if user_info is not None: + email_check = True + else: + email_check = False + if email_check is not None: + return res_login.ResponseCheckInfoGoogle(status= 200,data = res_login.CheckModel(check=email_check)) + except: + return res_login.ReponseError( + status=500, + data=res_login.Message(message="Server Error") + ) + +def check_info_google_email(request: req_login.RequestCheckInfoGoogleEmail): + try: + email = request.email + check_email_fc = sf.check_email_empty_invalid(email) + if check_email_fc is not True: + return check_email_fc + user_info = UserInfoRepository.getUserInfoByEmail(email) + if user_info is not None: + email_check = True + else: + email_check = False + if email_check is not None: + return res_login.ResponseCheckInfoGoogle(status= 200,data = res_login.CheckModel(check=email_check)) + except: + return res_login.ReponseError( + status=500, + data=res_login.Message(message="Server Error") + ) + +def check_state_login(request: req_login.RequestCheckStateLogin): +# try: + user_id = request.user_id + session_id_now = request.session_id_now + email = sf.check_email_service(user_id) + if isinstance(email, res1.ReponseError): + return email + elif session_id_now is None or session_id_now=="": + return res_login.ReponseError( + status= 400, + data =res_login.Message(message="session_id is empty") + ) + user = get_user1(email) + if user: + check1 = False + session_id = UserLoginRepository.getUserSessionIdByUserEmail(user_id) + print(f"session_id: {session_id}") + if session_id != session_id_now: + check1 = False + else: + check1 = True + return res_login.ResponseCheckInfoGoogle(status= 200,data = res_login.CheckModel(check = check1)) + else: + return res_login.ReponseError( + status=500, + data =res_login.Message(message="Not found user") + ) +# except: +# return res_login.ReponseError( +# status=500, +# data=res_login.Message(message="Server Error") +# ) + +def sign_up(request: req_login.RequestSignUp): + try: + email = request.email + password = request.password + username = request.username + check_email_fc = sf.check_email_empty_invalid(email) + if check_email_fc is not True: + return check_email_fc + if password is None: + return res_login.ReponseError( + status=400, + data =res_login.Message(message="password is empty") + ) + user_signup = get_user1(email) + if user_signup is not None: + return res_login.ReponseError( + status=500, + data =res_login.Message(message="Email exist") + ) + + user_info = sign_up_with_email_and_password(email, password, username) + if user_info: + return res_login.ResponseSignUp( + status=200, + data =res_login.DataSignUp(email=user_info) + ) + else: + return res_login.ReponseError( + status=500, + data =res_login.Message(message="Internal Server Error") + ) + except: + return res_login.ReponseError( + status=500, + data=res_login.Message(message="Server Error") + ) +import string, random +def generate_otp(length=6): + characters = string.ascii_uppercase + string.digits + otp = ''.join(random.choice(characters) for _ in range(length)) + return otp + +def createOTPReset(email): + otp = generate_otp() + check_email_fc = sf.check_email_empty_invalid(email) + if check_email_fc is not True: + return check_email_fc + OTPRepository.addOTP(email,otp) + return otp + +def reset_password(request: req_login.RequestResetPassword): + try: + email = request.email + check_email_fc = sf.check_email_empty_invalid(email) + if check_email_fc is not True: + return check_email_fc + try: + user = get_user1(email) + if user is not None: + otp = createOTPReset(email) + return res_login.ResponseCreateOTP( + status= 200, + data= res_login.CheckModel(check = True), + otp = otp + ) + else: + return res_login.ReponseError( + status= 500, + data =res_login.Message(message="Email not exist") + ) + except auth.UserNotFoundError as e: + return res_login.ReponseError( + status=500, + data =res_login.Message(message=str(e)) + ) + except: + return res_login.ReponseError( + status=500, + data=res_login.Message(message="Server Error") + ) + +def change_password(request: req_login.RequestChangePassword): + try: + user_id = request.user_id + email = sf.check_email_service(user_id) + new_password = request.new_password + current_password= request.current_password + if isinstance(email, res1.ReponseError): + return email + if new_password is None: + return res_login.ReponseError( + status=400, + data =res_login.Message(message="new_password is empty") + ) + if current_password is None: + return res_login.ReponseError( + status=400, + data =res_login.Message(message="current_password is empty") + ) + if current_password == new_password: + return res_login.ReponseError( + status=400, + data=res_login.Message(message="The new_password and the current_password must be different") + ) + user = sign_in_with_email_and_password(email, current_password) + try: + if user: + user_email = auth.get_user_by_email(email) + auth.update_user( + user_email.uid, + password=new_password + ) + return res_login.ResponseChangePassword( + status= 200, + data = res_login.Message(message=f"Update password success")) + else: + return res_login.ReponseError( + status=500, + data =res_login.Message(message="Current password not valid") + ) + except : + return res_login.ReponseError( + status=500, + data =res_login.Message(message="Server Error") + ) + except: + return res_login.ReponseError( + status=500, + data=res_login.Message(message="Server Error!!") + ) + +import pytz,datetime +import auth.authentication as auth123 +from response import ResponseDefault as res1 +def refresh_token(request: req_login.RequestRefreshTokenLogin): + try: + user_id = request.user_id + token = request.token + email = sf.check_email_service(user_id) + print(email) + if isinstance(email, res1.ReponseError): + return email + user_id_check=UserRepository.getUserIdByAccessTokenAndUserId(token,user_id) + if user_id_check is None: + return res.ReponseError( + status=400, + data =res.Message(message="Token not exist") + ) + user_record = UserRepository.getRefreshTokenUserById(user_id) + + if token is None: + return res_login.ReponseError( + status = 400, + data = res_login.Message(message="token is empty") + ) + user_token = UserRepository.getRefreshTokenUserByIdAndAccessToken(user_id,token) + if user_token is None: + return res_login.ReponseError( + status=400, + data=res_login.Message(message="Not found refresh token") + ) + if user_record: + rf_token = user_record + result = auth123.get_refresh_token(rf_token,token, email) + token_new = result["access_token"] + rf_token_new = result["refresh_token"] + seconds1 = result["expires_in"] + session_id = result["session_id"] + vn_timezone = pytz.timezone('Asia/Ho_Chi_Minh') + current_time = datetime.datetime.utcnow().replace(tzinfo=pytz.utc).astimezone(vn_timezone) +timedelta(seconds=seconds1) + formatted_time = current_time.strftime('%Y-%m-%d %H:%M:%S ') + if rf_token == rf_token_new: + UserRepository.updateAccessToken(user_id,token_new,formatted_time) + else: + UserRepository.UpdateAccessTokenRefreshTokenById(user_id,token_new,rf_token_new,formatted_time) + user = token_new + if user == False: + return res_login.ReponseError( + status=406, + data =res_login.Message(message="Refresh token error") + ) + return res_login.ResponseRefreshTokenLogin( + status= 200, + data = res_login.DataRefreshToken(token_new=user,session_id=session_id) + ) + except: + return res_login.ReponseError( + status = 500, + data = res_login.Message(message="Server Error") + ) + +def check_token_is_valid(token): + check = UserRepository.getEmailUserByAccessToken(token) + if check is None: + return False + return True \ No newline at end of file diff --git a/service/MySQLService.py b/service/MySQLService.py new file mode 100644 index 0000000000000000000000000000000000000000..77891894f7f7dc6ee518eb7235d88d8b75a0f92f --- /dev/null +++ b/service/MySQLService.py @@ -0,0 +1,180 @@ +import json + +from request import RequestMySQL as req +from response import ResponseMySQL as res +from response import ResponseDefault as res1 +from repository import ChatHistoryRepository +from repository import DetailChatRepository,UserRepository +from fastapi.responses import JSONResponse +from function import support_function as sf +import re +regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b' + +def check_email(email): + if(re.fullmatch(regex, email)): + return True + else: + return False + +def edit_chat(request: req.RequestEditNameChat): + try: + user_id = request.user_id + name_old = request.name_old + name_new = request.name_new + email = sf.check_email_service(user_id) + if isinstance(email, res1.ReponseError): + return email + if name_old is None or name_old =="": + return res.ReponseError( + status=400, + data =res.Message(message="name_old is empty") + ) + if name_new is None or name_new == "": + return res.ReponseError( + status=400, + data =res.Message(message="name_new is empty") + ) + chat_exist = ChatHistoryRepository.getIdChatHistoryByUserIdAndNameChatNew(user_id, name_new) + if chat_exist: + return res.ReponseError( + status=400, + data=res.Message(message="name_new duplicate") + ) + id_chat = ChatHistoryRepository.getIdChatHistoryByUserIdAndNameChat(user_id, name_old) + if id_chat: + ChatHistoryRepository.updateNameChatHistory(user_id,name_old,name_new) + check = True + else: + check = False + if check is True: + return res.ResponseEditChat( + status= 200, + data= res.Message(message=check) + ) + else: + return res.ReponseError( + status=500, + data =res.Message(message="Update chat error") + ) + except: + return res.ReponseError( + status=500, + data =res.Message(message="Server Error") + ) + +def delete_chat(request: req.RequestDeleteChat): + try: + user_id = request.user_id + chat_name = request.chat_name + email = sf.check_email_service(user_id) + if isinstance(email, res1.ReponseError): + return email + if chat_name is None or chat_name =="": + return res.ReponseError( + status=400, + data =res.Message(message="chat_name is empty") + ) + DetailChatRepository.delete_chat_detail(chat_name) + chat_exist = ChatHistoryRepository.getIdChatHistoryByUserIdAndNameChat(user_id, chat_name) + if chat_exist is None: + return res.ReponseError( + status=400, + data=res.Message(message="chat_name not exist") + ) + check = ChatHistoryRepository.deleteChatHistory(user_id,chat_name) + if check is True: + return res.ResponseDeleteChat( + status= 200, + data= res.Message(message="Delete conversation chat success") + ) + else: + return res.ReponseError( + status=500, + data =res.Message(message="Delete conversation chat error") + ) + except Exception as e: + return res.ResponseDeleteChat( + status=500, + data=res.Message(message=str(e)) + ) + +def render_chat_history(request: req.RequestRenderChatHistory): + try: + user_id = request.user_id + email = sf.check_email_service(user_id) + if isinstance(email, res1.ReponseError): + return email + chat_detail = ChatHistoryRepository.getChatHistoryById(user_id) + for item in chat_detail: + print(item) + chat1 = [res.ListUserChat(id=item.id, email=item.email, chat_name=item.name_chat) for item in chat_detail] + return res.ResponseRenderChatHistory( + status=200, + data=res.UserInfoListResponse(chat=chat1) + ) + except Exception as e: + return res.ReponseError( + status=500, + data=res.Message(message="Server Error") + ) + +def get_detail_chat_by_chat_id(request: req.RequestGetChatDetails): + id = request.id + if id is None or id == "": + return res.ReponseError( + status=400, + data=res.Message(message="Id is empty") + ) + chat_detail1 = DetailChatRepository.getDetailChatByChatId(id) + if chat_detail1: + return res.ResponseChatDetailById( + status=200, + data=res.ChatDetailById( + id = chat_detail1.id, + data_relevant = chat_detail1.data_relevant, + source_file = chat_detail1.source_file + ) + ) + else: + return res.ReponseError( + status=500, + data=res.Message(message="Chat not exist") + ) + +def load_chat_history(request: req.RequestLoadChatHistory): + try: + chat_id = request.chat_id + user_id = request.user_id + email = sf.check_email_service(user_id) + if isinstance(email, res1.ReponseError): + return email + if chat_id is None or chat_id == "": + return res.ReponseError( + status = 400, + data = res.Message(message="chat_id is empty") + ) + check_exist_chatid_width_user_id = ChatHistoryRepository.getChatHistoryByChatIdAndUserId(chat_id,user_id) + if check_exist_chatid_width_user_id is None: + return res.ReponseError( + status=400, + data=res.Message(message="Not found chat width chat_id and user_id") + ) + result = DetailChatRepository.getListDetailChatByChatId(chat_id) + chat1 = list(map(lambda item: res.ChatDetail( + id=item.id, + chat_id=item.chat_id, + question=item.YouMessage, + answer=item.AiMessage, + data_relevant=item.data_relevant, + source_file=item.source_file + ), result)) + # chat1 = [res.ChatDetail(id=item.id, chat_id = item.chat_id, question=item.YouMessage,answer=item.AiMessage,data_relevant = item.data_relevant,source_file=item.source_file) for item in result] + return res.ResponseLoadChatHistory( + status = 200, + data = res.ListChatDeTail(detail_chat=chat1) + ) + except: + return res.ReponseError( + status=500, + data=res.Message(message="Server Error") + ) \ No newline at end of file diff --git a/service/OTPService.py b/service/OTPService.py new file mode 100644 index 0000000000000000000000000000000000000000..fa059d111a8f2408e02b4e85d40795be3682a7cf --- /dev/null +++ b/service/OTPService.py @@ -0,0 +1,168 @@ +from datetime import timedelta,datetime +from request import RequestOTP as req +from response import ResponseOTP as res +import re +from firebase_admin import auth, exceptions +from repository import OTPRepository +from datetime import datetime, timedelta +import datetime, string,random +from function import support_function as sf +regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b' + +def get_user1(email): + try: + user = auth.get_user_by_email(email) + return user + except exceptions.FirebaseError as e: + return None + +def check_email(email): + if isinstance(email, str) and re.fullmatch(regex, email): + return True + else: + return False + +def generate_otp(length=6): + characters = string.ascii_uppercase + string.digits + otp = ''.join(random.choice(characters) for _ in range(length)) + return otp + +def createOTP(request: req.RequestCreateOTP): + try: + email = request.email + otp = generate_otp() + check_email_fc = sf.check_email_empty_invalid(email) + if check_email_fc is not True: + return check_email_fc + OTPRepository.addOTP(email,otp) + return res.ResponseCreateOTP( + status=200, + data = res.CheckModel(check=True), + otp = otp + ) + except: + return res.ReponseError( + status=500, + data=res.Message(message="Server Error") + ) + +def verifyOTP(request: req.RequestVerifyOTP): + try: + email = request.email + otp = request.otp + check_email_fc = sf.check_email_empty_invalid(email) + if check_email_fc is not True: + return check_email_fc + if otp is None: + return res.ReponseError( + status=400, + data=res.Message(message="otp is empty") + ) + user_otp = OTPRepository.getOtpByEmail(email) + if user_otp: + otp_db = user_otp.otp + otp_created_at = user_otp.created_at + if otp == otp_db: + current_time = datetime.datetime.now() + otp_expiry_time = otp_created_at + timedelta(minutes=15) + if current_time <= otp_expiry_time: + OTPRepository.deleteOTP(email, otp) + return res.ResponseVerifyOTPSignUp( + status=200, + data=res.Message(message="OTP is valid") + ) + else: + return res.ReponseError( + status=400, + data=res.Message(message="OTP has expired") + ) + else: + return res.ReponseError( + status=400, + data=res.Message(message="Invalid OTP") + ) + else: + return res.ReponseError( + status=400, + data=res.Message(message="No OTP found for this email") + ) + except: + return res.ReponseError( + status=500, + data=res.Message(message="Server Error") + ) + +def createOTPReset(email): + try: + otp = generate_otp() + check_email_fc = sf.check_email_empty_invalid(email) + if check_email_fc is not True: + return check_email_fc + OTPRepository.addOTP(email,otp) + return res.ResponseCreateOTP( + status=200, + data = res.CheckModel(check=True), + otp = otp + ) + except: + return res.ReponseError( + status=500, + data=res.Message(message="Server Error") + ) + +def generate_random_password(length=8): + characters = string.ascii_letters + string.digits + password = ''.join(random.choice(characters) for i in range(length)) + return password + +def verifyOTPReset(request: req.RequestVerifyOTP): + try: + email = request.email + otp = request.otp + check_email_fc = sf.check_email_empty_invalid(email) + if check_email_fc is not True: + return check_email_fc + if otp is None: + return res.ReponseError( + status=400, + data=res.Message(message="OTP is empty") + ) + user_otp = OTPRepository.getOtpByEmail(email) + if user_otp: + otp_db = user_otp.otp + otp_created_at = user_otp.created_at + if otp == otp_db: + current_time = datetime.datetime.now() # Lấy thời gian hiện tại với múi giờ hệ thống (múi giờ +7) + otp_expiry_time = otp_created_at + timedelta(minutes=15) + new_password = generate_random_password() + if current_time <= otp_expiry_time: + OTPRepository.deleteOTP(email, otp) + user_email = auth.get_user_by_email(email) + auth.update_user( + user_email.uid, + password=new_password) + return res.ResponseVerifyOTP( + status=200, + data=res.Message(message="New Password send to Email"), + newpassword=new_password + ) + else: + return res.ReponseError( + status=400, + data=res.Message(message="OTP has expired") + ) + else: + return res.ReponseError( + status=400, + data=res.Message(message="Invalid OTP") + ) + else: + return res.ReponseError( + status=400, + data=res.Message(message="No OTP found for this email") + ) + except: + return res.ReponseError( + status=500, + data=res.Message(message="Server Error") + ) \ No newline at end of file diff --git a/service/__pycache__/ChatService.cpython-310.pyc b/service/__pycache__/ChatService.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c0dc27eafdeaf062d8f083eef49aebb843acd7c9 Binary files /dev/null and b/service/__pycache__/ChatService.cpython-310.pyc differ diff --git a/service/__pycache__/ChatService.cpython-311.pyc b/service/__pycache__/ChatService.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3ac3d8c3860d41e1d3573e65922a14bff89b4752 Binary files /dev/null and b/service/__pycache__/ChatService.cpython-311.pyc differ diff --git a/service/__pycache__/DefaultService.cpython-310.pyc b/service/__pycache__/DefaultService.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b0c931634ef6f9d12e95b15dd50984452037f555 Binary files /dev/null and b/service/__pycache__/DefaultService.cpython-310.pyc differ diff --git a/service/__pycache__/DefaultService.cpython-311.pyc b/service/__pycache__/DefaultService.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..61554439dc3649a7ac4447b56d913ed54ca3bad7 Binary files /dev/null and b/service/__pycache__/DefaultService.cpython-311.pyc differ diff --git a/service/__pycache__/FileService.cpython-310.pyc b/service/__pycache__/FileService.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5566e4f3d5a79b458d3b7f14790e9b8f38d4aa98 Binary files /dev/null and b/service/__pycache__/FileService.cpython-310.pyc differ diff --git a/service/__pycache__/FileService.cpython-311.pyc b/service/__pycache__/FileService.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4b58afff7665c425d88f73edee79d981630ac50a Binary files /dev/null and b/service/__pycache__/FileService.cpython-311.pyc differ diff --git a/service/__pycache__/LoginService.cpython-310.pyc b/service/__pycache__/LoginService.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..29b997dc7b71d0d2709716dd701ad71e2aba331f Binary files /dev/null and b/service/__pycache__/LoginService.cpython-310.pyc differ diff --git a/service/__pycache__/LoginService.cpython-311.pyc b/service/__pycache__/LoginService.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..79b0b2f45fe81cfd08101254da8fb4eb3bcc9534 Binary files /dev/null and b/service/__pycache__/LoginService.cpython-311.pyc differ diff --git a/service/__pycache__/MySQLService.cpython-310.pyc b/service/__pycache__/MySQLService.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da76e555a853a1e7e51bbd69317a13a175647f2d Binary files /dev/null and b/service/__pycache__/MySQLService.cpython-310.pyc differ diff --git a/service/__pycache__/MySQLService.cpython-311.pyc b/service/__pycache__/MySQLService.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cafb061255eff9a34850d8e128b45b1bb43319d1 Binary files /dev/null and b/service/__pycache__/MySQLService.cpython-311.pyc differ diff --git a/service/__pycache__/OTPService.cpython-310.pyc b/service/__pycache__/OTPService.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..04384c225df190e7990aef6913e542b39a799578 Binary files /dev/null and b/service/__pycache__/OTPService.cpython-310.pyc differ diff --git a/service/__pycache__/OTPService.cpython-311.pyc b/service/__pycache__/OTPService.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb8791e7164320f1358b235a848e55a5f875e371 Binary files /dev/null and b/service/__pycache__/OTPService.cpython-311.pyc differ diff --git a/service/app/firebase_certificate.json b/service/app/firebase_certificate.json new file mode 100644 index 0000000000000000000000000000000000000000..98b77ef706ec8c88babbdeb945950f0993cdeb0a --- /dev/null +++ b/service/app/firebase_certificate.json @@ -0,0 +1,13 @@ +{ + "type": "service_account", + "project_id": "cogent-octane-384105", + "private_key_id": "94d2eb71fcc53c8504e822a2367157b49b65b16d", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC+awYE99nwJwid\neFuujKYL1cxdknb5lze6ON2wwn6F/lZCjf0wyYTyYAzk2yVDy8p+xy+jsbT22iaX\n8K6fwCqMVUMby9e813cQuS7ycF7WSS1Fw9JwljktnMLplJZuTv3zmlolNiePz/rS\nPcPaSvjQWO4s/G1A8knbY2gXaY4e7ie37GGKDOsgfEF8sQJ2TRll79qzoAWqIz1I\np87s+vR+Z3nPlVqiCM7cYP9ddvFEQxF381STDIExQzKSYbQyUsnU1lOZ7zWKb4F+\nHGjLzYBhf6CzU+l3M/kiaTJck+T7H/tSWo+bzFYFRpeh6Q7/UBwbBYN+7VOXTJ1Q\nEBQdwolBAgMBAAECggEAGG8v+405GG751Qhvw1XlrMPHkK5NuWNlJu6gdqEj49p/\ng9TSi43LEzWuEePpGT+vrABapZ0VGqQNqxZFt4F3iZXF9xgmMTj43LAr97eMWTT/\nVozKlotAVRELleDs7hoRePlH3gSKo71Ncz2ybHLjELaIrER2rzcoBmXwIn5MsBJ+\nDOqdZAo3UadvzcRpTUY6ju1Kd8w72FYgW/3RfK6eikZEw8sX8vKQ7QEH8bKeZVt7\nWOrkBK2kHEyR8dTga2igQRI7Cezqv48yiYjYbi+D/DBocjpHtJnPLbgOOWyjbmDU\n5fB+bxf+7qXZn/AIp96Iq1s2ZHxldlKk38yne40N7QKBgQDf/+A2lQswySNdLR1+\nNJME3OGgBG9Jq0mnBoe9rWOBBBAQNYv4uZO4MVvmLwzIN1y32MV6zkbnD9fMWKIf\nciIzje8xip/9ei6weB5n0Yp13f9JxBW0r1HaUVk7jpHyH7rk3GvNcebZNKM+yndh\n1rdyE1V6xGNqAXzX9vP4t6IiYwKBgQDZnwEwggMToQrl1jsxz7VlujPNSUhOgwGL\nj0nHCbUf2/jZ1hyMRU659RWmWGA70rsALwQ4IQoM5UHZkKc12MjswmXllrkk1Jmu\nc04OE5SWde7SWAzSj5oqCIoQt0B/3r7cRjgr0TK3SwxxIUOcazyFzvLrxJxsGFHc\nOfE3jP5lCwKBgCf0kl/qEgbvudki9QHQCvFxHOXYJKm1XfvnFEtnJDqdKOhbRM5m\n+8x9MXFLrzH/fhBlIESZitgoYUvX+4M0bplXlfT2Tzd9ldpwcqv+Gn6PzLuxuFV0\neFtC63HOKoZP1pyAHNKWoKDZ3MyUfNr829gDTtoJMdp0zXoQWNBioQ8VAoGBAKvd\n5aSXqTJhZyfpL0rBjbNPgQXJsG9BC4Faopus0PzeTwRLErS9L9Ww924uMaJNZR5a\nA20IutVAYecfVM8z7Er/pFXT2Vh7Bvw9WBHJ6PmDHh/FJitM+iXkJJXbA/d4xSdV\n1ZrVVsZnYOYfrTPlhSDwNe15k0fTVSMmJ5kFowvNAoGAc101K46kuKl+K/V6gdnW\nN2reMwlJf4Wgaz7yX0Gkha95dNGmy1ZC+NdD3qlSbOv353OITzNCBo7pSAAphQr2\noVkpyToTQOcSBjjAzTkXHabn3N1Rmj1P7GPwz5WyDPjp4t+GmT8Se3aJ1gtCnKeb\noxwTPi7EHyoIiYnEXYRuzSw=\n-----END PRIVATE KEY-----\n", + "client_email": "firebase-adminsdk-z0bu3@cogent-octane-384105.iam.gserviceaccount.com", + "client_id": "105944722897200826755", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-z0bu3%40cogent-octane-384105.iam.gserviceaccount.com", + "universe_domain": "googleapis.com" + } diff --git a/tests/.pytest_cache/.gitignore b/tests/.pytest_cache/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..08a7f458f1f002823bc794c47ca1996a57e72c86 --- /dev/null +++ b/tests/.pytest_cache/.gitignore @@ -0,0 +1,2 @@ +# Created by pytest automatically. +* diff --git a/tests/.pytest_cache/CACHEDIR.TAG b/tests/.pytest_cache/CACHEDIR.TAG new file mode 100644 index 0000000000000000000000000000000000000000..fce15ad7eaa74e5682b644c84efb75334c112f95 --- /dev/null +++ b/tests/.pytest_cache/CACHEDIR.TAG @@ -0,0 +1,4 @@ +Signature: 8a477f597d28d172789f06886806bc55 +# This file is a cache directory tag created by pytest. +# For information about cache directory tags, see: +# https://bford.info/cachedir/spec.html diff --git a/tests/.pytest_cache/README.md b/tests/.pytest_cache/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c7526af2448672de4537dfed042ed74daadb17bf --- /dev/null +++ b/tests/.pytest_cache/README.md @@ -0,0 +1,8 @@ +# pytest cache directory # + +This directory contains data from the pytest's cache plugin, +which provides the `--lf` and `--ff` options, as well as the `cache` fixture. + +**Do not** commit this to version control. + +See [the docs](https://docs.pytest.org/en/stable/how-to/cache.html) for more information. diff --git a/tests/.pytest_cache/v/cache/lastfailed b/tests/.pytest_cache/v/cache/lastfailed new file mode 100644 index 0000000000000000000000000000000000000000..9e26dfeeb6e641a33dae4961196235bdb965b21b --- /dev/null +++ b/tests/.pytest_cache/v/cache/lastfailed @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/.pytest_cache/v/cache/nodeids b/tests/.pytest_cache/v/cache/nodeids new file mode 100644 index 0000000000000000000000000000000000000000..9e5b408367af944e06a0dd10f1dd65a3dc221366 --- /dev/null +++ b/tests/.pytest_cache/v/cache/nodeids @@ -0,0 +1,442 @@ +[ + "test_controller/test_ChatController.py::test_extract_file_email_empty", + "test_controller/test_ChatController.py::test_extract_file_email_in_valid", + "test_controller/test_ChatController.py::test_extract_file_id_not_exist", + "test_controller/test_ChatController.py::test_extract_file_no_data", + "test_controller/test_ChatController.py::test_extract_file_success", + "test_controller/test_ChatController.py::test_extract_file_user_id_greater_0", + "test_controller/test_ChatController.py::test_extract_file_user_id_interger", + "test_controller/test_ChatController.py::test_extract_file_user_id_required", + "test_controller/test_ChatController.py::test_generate_question_email_empty", + "test_controller/test_ChatController.py::test_generate_question_email_in_valid", + "test_controller/test_ChatController.py::test_generate_question_id_not_exist", + "test_controller/test_ChatController.py::test_generate_question_no_data", + "test_controller/test_ChatController.py::test_generate_question_success", + "test_controller/test_ChatController.py::test_generate_question_user_id_greater_0", + "test_controller/test_ChatController.py::test_generate_question_user_id_interger", + "test_controller/test_ChatController.py::test_generate_question_user_id_required", + "test_controller/test_ChatController.py::test_query2_upgrade_old_chat_history_empty", + "test_controller/test_ChatController.py::test_query2_upgrade_old_email_empty", + "test_controller/test_ChatController.py::test_query2_upgrade_old_email_in_valid", + "test_controller/test_ChatController.py::test_query2_upgrade_old_id_not_exist", + "test_controller/test_ChatController.py::test_query2_upgrade_old_no_answer", + "test_controller/test_ChatController.py::test_query2_upgrade_old_question_empty", + "test_controller/test_ChatController.py::test_query2_upgrade_old_success", + "test_controller/test_ChatController.py::test_query_chatbot_user_id_greater_0", + "test_controller/test_ChatController.py::test_query_chatbot_user_id_interger", + "test_controller/test_ChatController.py::test_query_chatbot_user_id_required", + "test_controller/test_DefaultController.py::test_create_firebase_server_error", + "test_controller/test_DefaultController.py::test_create_firebase_user_error", + "test_controller/test_DefaultController.py::test_create_firebase_user_google_email_must_be_string", + "test_controller/test_DefaultController.py::test_create_firebase_user_google_is_None", + "test_controller/test_DefaultController.py::test_create_firebase_user_null_email", + "test_controller/test_DefaultController.py::test_create_firebase_user_success", + "test_controller/test_DefaultController.py::test_id_not_exist", + "test_controller/test_DefaultController.py::test_info_success", + "test_controller/test_DefaultController.py::test_info_user_email_empty", + "test_controller/test_DefaultController.py::test_info_user_email_invalid", + "test_controller/test_DefaultController.py::test_info_user_user_id_must_be_string", + "test_controller/test_DefaultController.py::test_info_user_user_id_required", + "test_controller/test_DefaultController.py::test_info_user_user_not_found", + "test_controller/test_DefaultController.py::test_invalid_email", + "test_controller/test_DefaultController.py::test_is_me_invalid_token", + "test_controller/test_DefaultController.py::test_is_me_none_token", + "test_controller/test_DefaultController.py::test_is_me_server_error", + "test_controller/test_DefaultController.py::test_is_me_success", + "test_controller/test_DefaultController.py::test_is_me_token_is_required", + "test_controller/test_DefaultController.py::test_is_me_token_must_be_string", + "test_controller/test_DefaultController.py::test_upload_image_email_empty", + "test_controller/test_DefaultController.py::test_upload_image_email_invalid", + "test_controller/test_DefaultController.py::test_upload_image_id_not_exist", + "test_controller/test_DefaultController.py::test_upload_image_server_err", + "test_controller/test_DefaultController.py::test_upload_image_success", + "test_controller/test_DefaultController.py::test_upload_image_user_id_greater_than_0", + "test_controller/test_DefaultController.py::test_upload_image_user_id_integer", + "test_controller/test_DefaultController.py::test_upload_image_user_id_required", + "test_controller/test_DefaultController.py::test_user_info_server_error", + "test_controller/test_FileController.py::test_delete__all_file_user_id_required", + "test_controller/test_FileController.py::test_delete_all_file_email_empty", + "test_controller/test_FileController.py::test_delete_all_file_email_invalid", + "test_controller/test_FileController.py::test_delete_all_file_success", + "test_controller/test_FileController.py::test_delete_all_file_user_id_is_greater_0", + "test_controller/test_FileController.py::test_delete_all_file_user_id_is_integer", + "test_controller/test_FileController.py::test_delete_file_email_empty", + "test_controller/test_FileController.py::test_delete_file_email_invalid", + "test_controller/test_FileController.py::test_delete_file_id_not_exist", + "test_controller/test_FileController.py::test_delete_file_namefile_empty", + "test_controller/test_FileController.py::test_delete_file_success", + "test_controller/test_FileController.py::test_delete_one_file_name_file_required", + "test_controller/test_FileController.py::test_delete_one_file_user_id_is_greater_0", + "test_controller/test_FileController.py::test_delete_one_file_user_id_is_integer", + "test_controller/test_FileController.py::test_delete_one_file_user_id_required", + "test_controller/test_FileController.py::test_download_file_email_empty", + "test_controller/test_FileController.py::test_download_file_email_invalid", + "test_controller/test_FileController.py::test_download_file_id_not_exist", + "test_controller/test_FileController.py::test_download_file_name_file_empty", + "test_controller/test_FileController.py::test_download_file_success", + "test_controller/test_FileController.py::test_download_file_user_id_required", + "test_controller/test_FileController.py::test_download_files_user_id_is_greater_0", + "test_controller/test_FileController.py::test_download_files_user_id_is_integer", + "test_controller/test_FileController.py::test_download_folder_email_empty", + "test_controller/test_FileController.py::test_download_folder_email_invalid", + "test_controller/test_FileController.py::test_download_folder_id_not_exist", + "test_controller/test_FileController.py::test_download_folder_success", + "test_controller/test_FileController.py::test_download_folder_user_id_is_greater_0", + "test_controller/test_FileController.py::test_download_folder_user_id_is_integer", + "test_controller/test_FileController.py::test_download_folder_user_id_required", + "test_controller/test_FileController.py::test_list_name_file_email_empty", + "test_controller/test_FileController.py::test_list_name_file_email_invalid", + "test_controller/test_FileController.py::test_list_name_file_id_not_exist", + "test_controller/test_FileController.py::test_list_name_file_success", + "test_controller/test_FileController.py::test_list_name_files_user_id_is_greater_0", + "test_controller/test_FileController.py::test_list_name_files_user_id_is_integer", + "test_controller/test_FileController.py::test_list_name_files_user_id_required", + "test_controller/test_FileController.py::test_upload_file_user_id_required", + "test_controller/test_FileController.py::test_upload_files_empty_email", + "test_controller/test_FileController.py::test_upload_files_id_not_exist", + "test_controller/test_FileController.py::test_upload_files_invalid_email", + "test_controller/test_FileController.py::test_upload_files_invalid_file_type", + "test_controller/test_FileController.py::test_upload_files_success", + "test_controller/test_FileController.py::test_upload_files_user_id_is_greater_0", + "test_controller/test_FileController.py::test_upload_files_user_id_is_integer", + "test_controller/test_LoginController.py::test_change_password_current_password_empty", + "test_controller/test_LoginController.py::test_change_password_current_password_not_valid", + "test_controller/test_LoginController.py::test_change_password_current_password_required", + "test_controller/test_LoginController.py::test_change_password_email_invalid", + "test_controller/test_LoginController.py::test_change_password_email_is_empty", + "test_controller/test_LoginController.py::test_change_password_id_not_exist", + "test_controller/test_LoginController.py::test_change_password_new_password_empty", + "test_controller/test_LoginController.py::test_change_password_new_password_required", + "test_controller/test_LoginController.py::test_change_password_success", + "test_controller/test_LoginController.py::test_change_password_user_id_integer", + "test_controller/test_LoginController.py::test_change_password_user_id_integer_greater_than_0", + "test_controller/test_LoginController.py::test_change_password_user_id_required", + "test_controller/test_LoginController.py::test_check_info_google_by_email_success", + "test_controller/test_LoginController.py::test_check_info_google_email_empty", + "test_controller/test_LoginController.py::test_check_info_google_email_invalid", + "test_controller/test_LoginController.py::test_check_info_google_id_not_exist", + "test_controller/test_LoginController.py::test_check_info_google_sign_up_email_is_required", + "test_controller/test_LoginController.py::test_check_info_google_sign_up_email_must_str", + "test_controller/test_LoginController.py::test_check_info_google_signup_email_empty", + "test_controller/test_LoginController.py::test_check_info_google_signup_email_invalid", + "test_controller/test_LoginController.py::test_check_info_google_success", + "test_controller/test_LoginController.py::test_check_info_google_user_id_must_integer", + "test_controller/test_LoginController.py::test_check_info_google_user_id_must_integer_greater_than_0", + "test_controller/test_LoginController.py::test_check_info_google_user_id_required", + "test_controller/test_LoginController.py::test_check_state_login_email_empty", + "test_controller/test_LoginController.py::test_check_state_login_email_invalid", + "test_controller/test_LoginController.py::test_check_state_login_id_not_exits", + "test_controller/test_LoginController.py::test_check_state_login_not_found", + "test_controller/test_LoginController.py::test_check_state_login_session_id_must_str", + "test_controller/test_LoginController.py::test_check_state_login_session_id_required", + "test_controller/test_LoginController.py::test_check_state_login_success", + "test_controller/test_LoginController.py::test_check_state_login_user_id_must_integer", + "test_controller/test_LoginController.py::test_check_state_login_user_id_must_integer_greater_than_0", + "test_controller/test_LoginController.py::test_check_state_login_user_id_required", + "test_controller/test_LoginController.py::test_check_state_session_empty", + "test_controller/test_LoginController.py::test_login_email_can_not_empty", + "test_controller/test_LoginController.py::test_login_email_empty", + "test_controller/test_LoginController.py::test_login_email_invalid", + "test_controller/test_LoginController.py::test_login_email_not_exist", + "test_controller/test_LoginController.py::test_login_email_password_error", + "test_controller/test_LoginController.py::test_login_email_required", + "test_controller/test_LoginController.py::test_login_email_required_str", + "test_controller/test_LoginController.py::test_login_google_email_can_not_empty", + "test_controller/test_LoginController.py::test_login_google_email_empty", + "test_controller/test_LoginController.py::test_login_google_email_invalid", + "test_controller/test_LoginController.py::test_login_google_email_required", + "test_controller/test_LoginController.py::test_login_google_email_required_str_1", + "test_controller/test_LoginController.py::test_login_google_email_token_required_str", + "test_controller/test_LoginController.py::test_login_google_success", + "test_controller/test_LoginController.py::test_login_google_token_google_required", + "test_controller/test_LoginController.py::test_login_invalid_authorization_code", + "test_controller/test_LoginController.py::test_login_password_empty", + "test_controller/test_LoginController.py::test_login_password_required", + "test_controller/test_LoginController.py::test_login_success", + "test_controller/test_LoginController.py::test_refresh_token_email_empty", + "test_controller/test_LoginController.py::test_refresh_token_email_invalid", + "test_controller/test_LoginController.py::test_refresh_token_success", + "test_controller/test_LoginController.py::test_refresh_token_token_empty", + "test_controller/test_LoginController.py::test_refresh_token_token_errror", + "test_controller/test_LoginController.py::test_refresh_token_token_is_required", + "test_controller/test_LoginController.py::test_refresh_token_token_must_be_str", + "test_controller/test_LoginController.py::test_refresh_token_user_id_integer", + "test_controller/test_LoginController.py::test_refresh_token_user_id_integer_greater_than_0", + "test_controller/test_LoginController.py::test_refresh_token_user_id_not_exist", + "test_controller/test_LoginController.py::test_refresh_token_user_id_required", + "test_controller/test_LoginController.py::test_reset_email_must_str", + "test_controller/test_LoginController.py::test_reset_email_required", + "test_controller/test_LoginController.py::test_reset_password_email_is_None", + "test_controller/test_LoginController.py::test_reset_password_invalid_email", + "test_controller/test_LoginController.py::test_reset_password_success", + "test_controller/test_LoginController.py::test_reset_password_user_not_found", + "test_controller/test_LoginController.py::test_sign_up_email_exist", + "test_controller/test_LoginController.py::test_sign_up_email_invadlid", + "test_controller/test_LoginController.py::test_sign_up_email_is_empty", + "test_controller/test_LoginController.py::test_sign_up_error", + "test_controller/test_LoginController.py::test_sign_up_password_empty", + "test_controller/test_LoginController.py::test_sign_up_success", + "test_controller/test_LoginController.py::test_signup_email_is_required", + "test_controller/test_LoginController.py::test_signup_email_must_str", + "test_controller/test_LoginController.py::test_signup_password_required", + "test_controller/test_LoginController.py::test_update_user_info_dis_play_name_field_required", + "test_controller/test_LoginController.py::test_update_user_info_email_empty", + "test_controller/test_LoginController.py::test_update_user_info_email_field_required", + "test_controller/test_LoginController.py::test_update_user_info_email_invalid", + "test_controller/test_LoginController.py::test_update_user_info_email_or_password_error", + "test_controller/test_LoginController.py::test_update_user_info_id_not_exist", + "test_controller/test_LoginController.py::test_update_user_info_photo_url_field_required", + "test_controller/test_LoginController.py::test_update_user_info_success", + "test_controller/test_LoginController.py::test_update_user_info_uid_field_required", + "test_controller/test_LoginController.py::test_update_user_info_user_id_greater_than_0", + "test_controller/test_LoginController.py::test_update_user_info_user_id_integer_required", + "test_controller/test_LoginController.py::test_update_user_info_user_id_required", + "test_controller/test_MySQLController.py::test_delete_chat_email_empty", + "test_controller/test_MySQLController.py::test_delete_chat_email_invalid", + "test_controller/test_MySQLController.py::test_delete_chat_id_not_exits", + "test_controller/test_MySQLController.py::test_delete_chat_name_empty", + "test_controller/test_MySQLController.py::test_delete_chat_name_error_500", + "test_controller/test_MySQLController.py::test_delete_chat_success", + "test_controller/test_MySQLController.py::test_edit_chat1_error", + "test_controller/test_MySQLController.py::test_edit_chat_email_empty", + "test_controller/test_MySQLController.py::test_edit_chat_email_invalid", + "test_controller/test_MySQLController.py::test_edit_chat_invalid_id", + "test_controller/test_MySQLController.py::test_edit_chat_name_new", + "test_controller/test_MySQLController.py::test_edit_chat_name_old", + "test_controller/test_MySQLController.py::test_edit_chat_success", + "test_controller/test_MySQLController.py::test_load_chat_history", + "test_controller/test_MySQLController.py::test_load_chat_history_chat_id_greater_than_inter", + "test_controller/test_MySQLController.py::test_load_chat_history_chat_id_is_required", + "test_controller/test_MySQLController.py::test_load_chat_history_empty", + "test_controller/test_MySQLController.py::test_load_chat_history_empty1", + "test_controller/test_MySQLController.py::test_load_chat_history_user_id_greater_than0", + "test_controller/test_MySQLController.py::test_load_chat_history_user_id_greater_than_inter", + "test_controller/test_MySQLController.py::test_load_chat_history_user_id_is_required", + "test_controller/test_MySQLController.py::test_load_chat_history_user_id_must_be_integer", + "test_controller/test_MySQLController.py::test_load_chat_history_user_id_mustbe_inter", + "test_controller/test_MySQLController.py::test_load_chat_history_value_mustbe_inter", + "test_controller/test_MySQLController.py::test_render_chat_empty", + "test_controller/test_MySQLController.py::test_render_chat_history", + "test_controller/test_MySQLController.py::test_render_chat_user_id_greater_than_inter", + "test_controller/test_MySQLController.py::test_render_chat_user_id_required", + "test_controller/test_MySQLController.py::test_render_chat_value_mustbe_interger", + "test_controller/test_OTPController.py::test_createOTPReset_email_empty", + "test_controller/test_OTPController.py::test_createOTPReset_email_invalid", + "test_controller/test_OTPController.py::test_createOTPReset_success", + "test_controller/test_OTPController.py::test_createOTP_email_must_be_string", + "test_controller/test_OTPController.py::test_createOTP_email_required", + "test_controller/test_OTPController.py::test_createOTP_failed_empty_email", + "test_controller/test_OTPController.py::test_createOTP_failed_empty_invalid", + "test_controller/test_OTPController.py::test_createOTP_success", + "test_controller/test_OTPController.py::test_verifyOTPReset1_success", + "test_controller/test_OTPController.py::test_verifyOTPReset_email_is_required", + "test_controller/test_OTPController.py::test_verifyOTPReset_failed_empty_email", + "test_controller/test_OTPController.py::test_verifyOTPReset_failed_empty_otp", + "test_controller/test_OTPController.py::test_verifyOTPReset_failed_invalid_email", + "test_controller/test_OTPController.py::test_verifyOTPReset_failed_invalid_otp", + "test_controller/test_OTPController.py::test_verifyOTPReset_failed_no_otp_found", + "test_controller/test_OTPController.py::test_verifyOTPReset_has_expired", + "test_controller/test_OTPController.py::test_verifyOTPReset_otp_email_must_be_string", + "test_controller/test_OTPController.py::test_verifyOTPReset_otp_is_required", + "test_controller/test_OTPController.py::test_verifyOTPReset_otp_max_length", + "test_controller/test_OTPController.py::test_verifyOTPReset_otp_must_be_string", + "test_controller/test_OTPController.py::test_verifyOTP_email_is_required", + "test_controller/test_OTPController.py::test_verifyOTP_failed_empty_email", + "test_controller/test_OTPController.py::test_verifyOTP_failed_empty_otp", + "test_controller/test_OTPController.py::test_verifyOTP_failed_invalid_email", + "test_controller/test_OTPController.py::test_verifyOTP_failed_invalid_otp", + "test_controller/test_OTPController.py::test_verifyOTP_failed_no_otp_found", + "test_controller/test_OTPController.py::test_verifyOTP_has_expired", + "test_controller/test_OTPController.py::test_verifyOTP_otp_email_must_be_string", + "test_controller/test_OTPController.py::test_verifyOTP_otp_is_required", + "test_controller/test_OTPController.py::test_verifyOTP_otp_max_length", + "test_controller/test_OTPController.py::test_verifyOTP_otp_must_be_string", + "test_controller/test_OTPController.py::test_verifyOTP_success", + "test_service/test_ChatService.py::TestDeleteChat::test_delete_chat_chat_name_empty", + "test_service/test_ChatService.py::TestDeleteChat::test_delete_chat_failed", + "test_service/test_ChatService.py::TestDeleteChat::test_delete_chat_id_not_exist", + "test_service/test_ChatService.py::TestDeleteChat::test_delete_chat_server_err", + "test_service/test_ChatService.py::TestDeleteChat::test_delete_chat_success", + "test_service/test_ChatService.py::TestExtractFile::test_extract_file_email_empty", + "test_service/test_ChatService.py::TestExtractFile::test_extract_file_email_in_valid", + "test_service/test_ChatService.py::TestExtractFile::test_extract_file_id_not_exist", + "test_service/test_ChatService.py::TestExtractFile::test_extract_file_no_data", + "test_service/test_ChatService.py::TestExtractFile::test_extract_file_server_error_sf", + "test_service/test_ChatService.py::TestExtractFile::test_extract_file_success", + "test_service/test_ChatService.py::TestGenerateQuestion::test_generate_question_email_empty", + "test_service/test_ChatService.py::TestGenerateQuestion::test_generate_question_email_in_valid", + "test_service/test_ChatService.py::TestGenerateQuestion::test_generate_question_id_not_exist", + "test_service/test_ChatService.py::TestGenerateQuestion::test_generate_question_no_data", + "test_service/test_ChatService.py::TestGenerateQuestion::test_generate_question_server_err_user_repo", + "test_service/test_ChatService.py::TestGenerateQuestion::test_generate_question_success", + "test_service/test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_chat_empty", + "test_service/test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_email_empty", + "test_service/test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_email_in_valid", + "test_service/test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_id_not_exist", + "test_service/test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_no_answer", + "test_service/test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_question_empty", + "test_service/test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_server_error_chathistory_repo", + "test_service/test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_server_error_detailchat_repo", + "test_service/test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_server_error_function_repo", + "test_service/test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_server_error_user_repo", + "test_service/test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_success", + "test_service/test_DefaultService.py::TestCreateFireBaseUser::test_email_none", + "test_service/test_DefaultService.py::TestCreateFireBaseUser::test_existing_user", + "test_service/test_DefaultService.py::TestCreateFireBaseUser::test_invalid_email", + "test_service/test_DefaultService.py::TestCreateFireBaseUser::test_non_existing_user", + "test_service/test_DefaultService.py::TestCreateFireBaseUser::test_server_error", + "test_service/test_DefaultService.py::TestInfoUser::test_email_is_none", + "test_service/test_DefaultService.py::TestInfoUser::test_id_not_exist", + "test_service/test_DefaultService.py::TestInfoUser::test_invalid_email", + "test_service/test_DefaultService.py::TestInfoUser::test_server_error", + "test_service/test_DefaultService.py::TestInfoUser::test_successful_user_retrieval", + "test_service/test_DefaultService.py::TestInfoUser::test_user_not_found", + "test_service/test_DefaultService.py::TestIsMe::test_invalid_token", + "test_service/test_DefaultService.py::TestIsMe::test_none_token", + "test_service/test_DefaultService.py::TestIsMe::test_server_error", + "test_service/test_DefaultService.py::TestIsMe::test_valid_token", + "test_service/test_DefaultService.py::TestUpLoadFile::test_upload_image_email_empty", + "test_service/test_DefaultService.py::TestUpLoadFile::test_upload_image_email_invalid", + "test_service/test_DefaultService.py::TestUpLoadFile::test_upload_image_id_not_exist", + "test_service/test_DefaultService.py::TestUpLoadFile::test_upload_image_invalid_filetype", + "test_service/test_DefaultService.py::TestUpLoadFile::test_upload_image_server_err", + "test_service/test_DefaultService.py::TestUpLoadFile::test_upload_image_success", + "test_service/test_FileService.py::TestDeleteAllFile::test_delete_all_file_email_empty", + "test_service/test_FileService.py::TestDeleteAllFile::test_delete_all_file_email_invalid", + "test_service/test_FileService.py::TestDeleteAllFile::test_delete_all_file_id_not_exist", + "test_service/test_FileService.py::TestDeleteAllFile::test_delete_all_file_server_err", + "test_service/test_FileService.py::TestDeleteAllFile::test_delete_all_file_success", + "test_service/test_FileService.py::TestDeleteFile::test_delete_file_email_empty", + "test_service/test_FileService.py::TestDeleteFile::test_delete_file_email_invalid", + "test_service/test_FileService.py::TestDeleteFile::test_delete_file_id_not_exist", + "test_service/test_FileService.py::TestDeleteFile::test_delete_file_namefile_empty", + "test_service/test_FileService.py::TestDeleteFile::test_delete_file_server_error", + "test_service/test_FileService.py::TestDeleteFile::test_delete_file_success", + "test_service/test_FileService.py::TestDownLoadFile::test_download_file_email_empty", + "test_service/test_FileService.py::TestDownLoadFile::test_download_file_email_invalid", + "test_service/test_FileService.py::TestDownLoadFile::test_download_file_id_not_exist", + "test_service/test_FileService.py::TestDownLoadFile::test_download_file_name_file_empty", + "test_service/test_FileService.py::TestDownLoadFile::test_download_file_server_error", + "test_service/test_FileService.py::TestDownLoadFile::test_download_file_success", + "test_service/test_FileService.py::TestDownLoadFolder::test_download_folder_email_empty", + "test_service/test_FileService.py::TestDownLoadFolder::test_download_folder_email_invalid", + "test_service/test_FileService.py::TestDownLoadFolder::test_download_folder_id_not_exist", + "test_service/test_FileService.py::TestDownLoadFolder::test_download_folder_server_error", + "test_service/test_FileService.py::TestDownLoadFolder::test_download_folder_success", + "test_service/test_FileService.py::TestListNameFiles::test_listNameFiles_server_error", + "test_service/test_FileService.py::TestListNameFiles::test_list_name_file_success", + "test_service/test_FileService.py::TestListNameFiles::test_list_name_files_email_empty", + "test_service/test_FileService.py::TestListNameFiles::test_list_name_files_email_invalid", + "test_service/test_FileService.py::TestListNameFiles::test_list_name_files_id_not_exist", + "test_service/test_FileService.py::TestUploadFileService::test_upload_files_empty_email", + "test_service/test_FileService.py::TestUploadFileService::test_upload_files_error_handling", + "test_service/test_FileService.py::TestUploadFileService::test_upload_files_id_not_exist", + "test_service/test_FileService.py::TestUploadFileService::test_upload_files_invalid_email", + "test_service/test_FileService.py::TestUploadFileService::test_upload_files_invalid_file_type", + "test_service/test_FileService.py::TestUploadFileService::test_upload_files_success", + "test_service/test_LoginService.py::TestChangePassword::test_change_password_current_password_empty", + "test_service/test_LoginService.py::TestChangePassword::test_change_password_current_password_not_valid", + "test_service/test_LoginService.py::TestChangePassword::test_change_password_email_invalid", + "test_service/test_LoginService.py::TestChangePassword::test_change_password_email_is_empty", + "test_service/test_LoginService.py::TestChangePassword::test_change_password_id_not_exist", + "test_service/test_LoginService.py::TestChangePassword::test_change_password_new_password_empty", + "test_service/test_LoginService.py::TestChangePassword::test_change_password_server_error", + "test_service/test_LoginService.py::TestChangePassword::test_change_password_success", + "test_service/test_LoginService.py::TestCheckInfoGoogle::test_check_info_google_email_empty", + "test_service/test_LoginService.py::TestCheckInfoGoogle::test_check_info_google_email_invalid", + "test_service/test_LoginService.py::TestCheckInfoGoogle::test_check_info_google_id_not_exist", + "test_service/test_LoginService.py::TestCheckInfoGoogle::test_check_info_google_server_error", + "test_service/test_LoginService.py::TestCheckInfoGoogle::test_check_info_google_success", + "test_service/test_LoginService.py::TestCheckInfoGoogleEmail::test_check_info_google_by_email_email_empty", + "test_service/test_LoginService.py::TestCheckInfoGoogleEmail::test_check_info_google_email_invalid", + "test_service/test_LoginService.py::TestCheckInfoGoogleEmail::test_check_info_google_email_server_error", + "test_service/test_LoginService.py::TestCheckInfoGoogleEmail::test_check_info_google_email_success", + "test_service/test_LoginService.py::TestCheckStateLogin::test_check_state_login_email_empty", + "test_service/test_LoginService.py::TestCheckStateLogin::test_check_state_login_email_invalid", + "test_service/test_LoginService.py::TestCheckStateLogin::test_check_state_login_id_not_exits", + "test_service/test_LoginService.py::TestCheckStateLogin::test_check_state_login_not_found", + "test_service/test_LoginService.py::TestCheckStateLogin::test_check_state_login_server_error", + "test_service/test_LoginService.py::TestCheckStateLogin::test_check_state_login_success", + "test_service/test_LoginService.py::TestCheckStateLogin::test_check_state_session_empty", + "test_service/test_LoginService.py::TestLoginFunction::test_login_email_empty", + "test_service/test_LoginService.py::TestLoginFunction::test_login_email_invalid", + "test_service/test_LoginService.py::TestLoginFunction::test_login_email_not_exists", + "test_service/test_LoginService.py::TestLoginFunction::test_login_email_or_password_error", + "test_service/test_LoginService.py::TestLoginFunction::test_login_invalid_authorization_code", + "test_service/test_LoginService.py::TestLoginFunction::test_login_password_empty", + "test_service/test_LoginService.py::TestLoginFunction::test_login_server_error", + "test_service/test_LoginService.py::TestLoginFunction::test_login_success", + "test_service/test_LoginService.py::TestLoginGoogle::test_login_email_invalid", + "test_service/test_LoginService.py::TestLoginGoogle::test_login_google_email_empty", + "test_service/test_LoginService.py::TestLoginGoogle::test_login_google_email_not_exists", + "test_service/test_LoginService.py::TestLoginGoogle::test_login_google_server_error", + "test_service/test_LoginService.py::TestLoginGoogle::test_login_google_success", + "test_service/test_LoginService.py::TestRefreshToken::test_refresh_token_email_empty", + "test_service/test_LoginService.py::TestRefreshToken::test_refresh_token_email_invalid", + "test_service/test_LoginService.py::TestRefreshToken::test_refresh_token_refresh_token_error", + "test_service/test_LoginService.py::TestRefreshToken::test_refresh_token_server_error", + "test_service/test_LoginService.py::TestRefreshToken::test_refresh_token_success", + "test_service/test_LoginService.py::TestRefreshToken::test_refresh_token_token_empty", + "test_service/test_LoginService.py::TestRefreshToken::test_refresh_token_user_id_not_exist", + "test_service/test_LoginService.py::TestResetPassword::test_reset_password_invalid_email", + "test_service/test_LoginService.py::TestResetPassword::test_reset_password_server_error", + "test_service/test_LoginService.py::TestResetPassword::test_reset_password_success", + "test_service/test_LoginService.py::TestResetPassword::test_reset_password_user_not_found", + "test_service/test_LoginService.py::TestSignUpFunction::test_sign_up_email_exist", + "test_service/test_LoginService.py::TestSignUpFunction::test_sign_up_email_invalid", + "test_service/test_LoginService.py::TestSignUpFunction::test_sign_up_email_is_empty", + "test_service/test_LoginService.py::TestSignUpFunction::test_sign_up_error", + "test_service/test_LoginService.py::TestSignUpFunction::test_sign_up_password_empty", + "test_service/test_LoginService.py::TestSignUpFunction::test_sign_up_server_error", + "test_service/test_LoginService.py::TestSignUpFunction::test_sign_up_success", + "test_service/test_LoginService.py::TestUpdateUserInfoFunction::test_update_user_info_email_empty", + "test_service/test_LoginService.py::TestUpdateUserInfoFunction::test_update_user_info_email_invalid", + "test_service/test_LoginService.py::TestUpdateUserInfoFunction::test_update_user_info_email_or_password_error", + "test_service/test_LoginService.py::TestUpdateUserInfoFunction::test_update_user_info_id_not_exist", + "test_service/test_LoginService.py::TestUpdateUserInfoFunction::test_update_user_info_server_error", + "test_service/test_LoginService.py::TestUpdateUserInfoFunction::test_update_user_info_success_existing_user", + "test_service/test_LoginService.py::TestUpdateUserInfoFunction::test_update_user_info_success_new_user_info", + "test_service/test_MySQLService.py::TestDeleteChat::test_delete_chat_chatname_empty", + "test_service/test_MySQLService.py::TestDeleteChat::test_delete_chat_email_empty", + "test_service/test_MySQLService.py::TestDeleteChat::test_delete_chat_email_invalid", + "test_service/test_MySQLService.py::TestDeleteChat::test_delete_chat_error_1", + "test_service/test_MySQLService.py::TestDeleteChat::test_delete_chat_id_not_exist", + "test_service/test_MySQLService.py::TestDeleteChat::test_delete_chat_server_error", + "test_service/test_MySQLService.py::TestDeleteChat::test_delete_chat_success", + "test_service/test_MySQLService.py::TestLoadChatHistory::test_load_chat_history_error", + "test_service/test_MySQLService.py::TestLoadChatHistory::test_load_chat_history_not_found_chat", + "test_service/test_MySQLService.py::TestLoadChatHistory::test_load_chat_history_server_err", + "test_service/test_MySQLService.py::TestLoadChatHistory::test_load_chat_history_success", + "test_service/test_MySQLService.py::TestLoadChatHistory::test_load_chat_history_user_id_str", + "test_service/test_MySQLService.py::TestMySQLService::test_edit_chat_email_empty", + "test_service/test_MySQLService.py::TestMySQLService::test_edit_chat_email_in_valid", + "test_service/test_MySQLService.py::TestMySQLService::test_edit_chat_id_not_exist", + "test_service/test_MySQLService.py::TestMySQLService::test_edit_chat_name_new_empty", + "test_service/test_MySQLService.py::TestMySQLService::test_edit_chat_name_old_empty", + "test_service/test_MySQLService.py::TestMySQLService::test_edit_chat_server_error", + "test_service/test_MySQLService.py::TestMySQLService::test_edit_chat_success", + "test_service/test_MySQLService.py::TestMySQLService::test_edit_chat_update_error", + "test_service/test_MySQLService.py::TestRenderChatHistory::test_render_chat_history_id_not_exist", + "test_service/test_MySQLService.py::TestRenderChatHistory::test_render_chat_history_server_err", + "test_service/test_MySQLService.py::TestRenderChatHistory::test_render_chat_history_success", + "test_service/test_OTPService.py::TestCreateOTPFunctions::test_createOTP_failed_empty_email", + "test_service/test_OTPService.py::TestCreateOTPFunctions::test_createOTP_failed_empty_invalid", + "test_service/test_OTPService.py::TestCreateOTPFunctions::test_createOTP_success", + "test_service/test_OTPService.py::TestCreateOTPReset::test_createOTPReset_email_empty", + "test_service/test_OTPService.py::TestCreateOTPReset::test_createOTPReset_email_invalid", + "test_service/test_OTPService.py::TestCreateOTPReset::test_createOTPReset_success", + "test_service/test_OTPService.py::TestVerifyOTPFunctions::test_verifyOTP_failed_empty_email", + "test_service/test_OTPService.py::TestVerifyOTPFunctions::test_verifyOTP_failed_empty_otp", + "test_service/test_OTPService.py::TestVerifyOTPFunctions::test_verifyOTP_failed_invalid_email", + "test_service/test_OTPService.py::TestVerifyOTPFunctions::test_verifyOTP_failed_invalid_otp", + "test_service/test_OTPService.py::TestVerifyOTPFunctions::test_verifyOTP_failed_no_otp_found", + "test_service/test_OTPService.py::TestVerifyOTPFunctions::test_verifyOTP_has_expired", + "test_service/test_OTPService.py::TestVerifyOTPFunctions::test_verifyOTP_success", + "test_service/test_OTPService.py::TestVerifyOTPReset::test_verifyOTPReset_failed_empty_email", + "test_service/test_OTPService.py::TestVerifyOTPReset::test_verifyOTPReset_failed_empty_otp", + "test_service/test_OTPService.py::TestVerifyOTPReset::test_verifyOTPReset_failed_invalid_email", + "test_service/test_OTPService.py::TestVerifyOTPReset::test_verifyOTPReset_failed_invalid_otp", + "test_service/test_OTPService.py::TestVerifyOTPReset::test_verifyOTPReset_failed_no_otp_found", + "test_service/test_OTPService.py::TestVerifyOTPReset::test_verifyOTPReset_has_expired", + "test_service/test_OTPService.py::TestVerifyOTPReset::test_verifyOTPReset_success" +] \ No newline at end of file diff --git a/tests/.pytest_cache/v/cache/stepwise b/tests/.pytest_cache/v/cache/stepwise new file mode 100644 index 0000000000000000000000000000000000000000..0637a088a01e8ddab3bf3fa98dbe804cbde1a0dc --- /dev/null +++ b/tests/.pytest_cache/v/cache/stepwise @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/tests/test_controller/.pytest_cache/.gitignore b/tests/test_controller/.pytest_cache/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..08a7f458f1f002823bc794c47ca1996a57e72c86 --- /dev/null +++ b/tests/test_controller/.pytest_cache/.gitignore @@ -0,0 +1,2 @@ +# Created by pytest automatically. +* diff --git a/tests/test_controller/.pytest_cache/CACHEDIR.TAG b/tests/test_controller/.pytest_cache/CACHEDIR.TAG new file mode 100644 index 0000000000000000000000000000000000000000..fce15ad7eaa74e5682b644c84efb75334c112f95 --- /dev/null +++ b/tests/test_controller/.pytest_cache/CACHEDIR.TAG @@ -0,0 +1,4 @@ +Signature: 8a477f597d28d172789f06886806bc55 +# This file is a cache directory tag created by pytest. +# For information about cache directory tags, see: +# https://bford.info/cachedir/spec.html diff --git a/tests/test_controller/.pytest_cache/README.md b/tests/test_controller/.pytest_cache/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c7526af2448672de4537dfed042ed74daadb17bf --- /dev/null +++ b/tests/test_controller/.pytest_cache/README.md @@ -0,0 +1,8 @@ +# pytest cache directory # + +This directory contains data from the pytest's cache plugin, +which provides the `--lf` and `--ff` options, as well as the `cache` fixture. + +**Do not** commit this to version control. + +See [the docs](https://docs.pytest.org/en/stable/how-to/cache.html) for more information. diff --git a/tests/test_controller/.pytest_cache/v/cache/lastfailed b/tests/test_controller/.pytest_cache/v/cache/lastfailed new file mode 100644 index 0000000000000000000000000000000000000000..e9f15783d9d3da0d87ce6763ae60bc0edf6a9578 --- /dev/null +++ b/tests/test_controller/.pytest_cache/v/cache/lastfailed @@ -0,0 +1,20 @@ +{ + "test_OTPController.py::test_create_otp_with_missing_email": true, + "test_OTPController.py::test_create_otp_with_missing_body": true, + "test_DefaultController.py::test_email_none": true, + "test_DefaultController.py::test_create_firebase_user_google": true, + "test_ChatController.py::test_query2_upgrade_success": true, + "test_ChatController.py::test_query2_upgrade_id_not_exist": true, + "test_ChatController.py::test_query2_upgrade_email_empty": true, + "test_ChatController.py::test_query2_upgrade_question_empty": true, + "test_ChatController.py::test_query2_upgrade_chat_history_empty": true, + "test_ChatController.py::test_query2_upgrade_no_answer": true, + "test_FileController.py::test_delete_file_all_file_user_id_interger": true, + "test_LoginController.py::test_login_gooogle_email_can_not_empty": true, + "test_LoginController.py::test_login_gooogle_email_required": true, + "test_LoginController.py::test_check_signup_session_id_required": true, + "test_LoginController.py::test_check_info_google_email_empty": true, + "test_LoginController.py::test_check_info_google_email_invalid": true, + "test_LoginController.py::test_refresh_token_success": true, + "test_LoginController.py::test_refresh_token_token_errror": true +} \ No newline at end of file diff --git a/tests/test_controller/.pytest_cache/v/cache/nodeids b/tests/test_controller/.pytest_cache/v/cache/nodeids new file mode 100644 index 0000000000000000000000000000000000000000..e856c6aa175ff71985506e8fbf23a35e820922e9 --- /dev/null +++ b/tests/test_controller/.pytest_cache/v/cache/nodeids @@ -0,0 +1,284 @@ +[ + "test_ChatController.py::test_extract_file_email_empty", + "test_ChatController.py::test_extract_file_email_in_valid", + "test_ChatController.py::test_extract_file_id_not_exist", + "test_ChatController.py::test_extract_file_no_data", + "test_ChatController.py::test_extract_file_success", + "test_ChatController.py::test_extract_file_user_id_greater_0", + "test_ChatController.py::test_extract_file_user_id_interger", + "test_ChatController.py::test_extract_file_user_id_required", + "test_ChatController.py::test_generate_question_email_empty", + "test_ChatController.py::test_generate_question_email_in_valid", + "test_ChatController.py::test_generate_question_id_not_exist", + "test_ChatController.py::test_generate_question_no_data", + "test_ChatController.py::test_generate_question_success", + "test_ChatController.py::test_generate_question_user_id_greater_0", + "test_ChatController.py::test_generate_question_user_id_interger", + "test_ChatController.py::test_generate_question_user_id_required", + "test_ChatController.py::test_query2_upgrade_chat_history_empty", + "test_ChatController.py::test_query2_upgrade_email_empty", + "test_ChatController.py::test_query2_upgrade_id_not_exist", + "test_ChatController.py::test_query2_upgrade_no_answer", + "test_ChatController.py::test_query2_upgrade_old_chat_history_empty", + "test_ChatController.py::test_query2_upgrade_old_email_empty", + "test_ChatController.py::test_query2_upgrade_old_email_in_valid", + "test_ChatController.py::test_query2_upgrade_old_id_not_exist", + "test_ChatController.py::test_query2_upgrade_old_no_answer", + "test_ChatController.py::test_query2_upgrade_old_question_empty", + "test_ChatController.py::test_query2_upgrade_old_success", + "test_ChatController.py::test_query2_upgrade_question_empty", + "test_ChatController.py::test_query2_upgrade_success", + "test_ChatController.py::test_query_chatbot_user_id_greater_0", + "test_ChatController.py::test_query_chatbot_user_id_interger", + "test_ChatController.py::test_query_chatbot_user_id_required", + "test_DefaultController.py::test_create_firebase_server_error", + "test_DefaultController.py::test_create_firebase_user_error", + "test_DefaultController.py::test_create_firebase_user_google", + "test_DefaultController.py::test_create_firebase_user_google_email_must_be_string", + "test_DefaultController.py::test_create_firebase_user_google_is_None", + "test_DefaultController.py::test_create_firebase_user_null_email", + "test_DefaultController.py::test_create_firebase_user_success", + "test_DefaultController.py::test_email_none", + "test_DefaultController.py::test_id_not_exist", + "test_DefaultController.py::test_info_success", + "test_DefaultController.py::test_info_user_email_empty", + "test_DefaultController.py::test_info_user_email_invalid", + "test_DefaultController.py::test_info_user_user_id_must_be_string", + "test_DefaultController.py::test_info_user_user_id_required", + "test_DefaultController.py::test_info_user_user_not_found", + "test_DefaultController.py::test_invalid_email", + "test_DefaultController.py::test_is_me_invalid_token", + "test_DefaultController.py::test_is_me_none_token", + "test_DefaultController.py::test_is_me_server_error", + "test_DefaultController.py::test_is_me_success", + "test_DefaultController.py::test_is_me_token_is_required", + "test_DefaultController.py::test_is_me_token_must_be_string", + "test_DefaultController.py::test_upload_image_email_empty", + "test_DefaultController.py::test_upload_image_email_invalid", + "test_DefaultController.py::test_upload_image_id_not_exist", + "test_DefaultController.py::test_upload_image_server_err", + "test_DefaultController.py::test_upload_image_success", + "test_DefaultController.py::test_upload_image_user_id_greater_than_0", + "test_DefaultController.py::test_upload_image_user_id_integer", + "test_DefaultController.py::test_upload_image_user_id_interger", + "test_DefaultController.py::test_upload_image_user_id_required", + "test_DefaultController.py::test_user_info_server_error", + "test_FileController.py::test_delete__all_file_user_id_required", + "test_FileController.py::test_delete_all_file_email_empty", + "test_FileController.py::test_delete_all_file_email_invalid", + "test_FileController.py::test_delete_all_file_success", + "test_FileController.py::test_delete_all_file_user_id_is_greater_0", + "test_FileController.py::test_delete_all_file_user_id_is_integer", + "test_FileController.py::test_delete_all_file_user_id_is_interger", + "test_FileController.py::test_delete_file_all_file_user_id_interger", + "test_FileController.py::test_delete_file_all_file_user_id_required", + "test_FileController.py::test_delete_file_email_empty", + "test_FileController.py::test_delete_file_email_invalid", + "test_FileController.py::test_delete_file_id_not_exist", + "test_FileController.py::test_delete_file_namefile_empty", + "test_FileController.py::test_delete_file_success", + "test_FileController.py::test_delete_one_file_name_file_required", + "test_FileController.py::test_delete_one_file_user_id_is_greater_0", + "test_FileController.py::test_delete_one_file_user_id_is_integer", + "test_FileController.py::test_delete_one_file_user_id_is_interger", + "test_FileController.py::test_delete_one_file_user_id_required", + "test_FileController.py::test_download_file_email_empty", + "test_FileController.py::test_download_file_email_invalid", + "test_FileController.py::test_download_file_id_not_exist", + "test_FileController.py::test_download_file_name_file_empty", + "test_FileController.py::test_download_file_success", + "test_FileController.py::test_download_file_user_id_required", + "test_FileController.py::test_download_files_user_id_is_greater_0", + "test_FileController.py::test_download_files_user_id_is_integer", + "test_FileController.py::test_download_files_user_id_is_interger", + "test_FileController.py::test_download_folder_email_empty", + "test_FileController.py::test_download_folder_email_invalid", + "test_FileController.py::test_download_folder_id_not_exist", + "test_FileController.py::test_download_folder_success", + "test_FileController.py::test_download_folder_user_id_is_greater_0", + "test_FileController.py::test_download_folder_user_id_is_integer", + "test_FileController.py::test_download_folder_user_id_is_interger", + "test_FileController.py::test_download_folder_user_id_required", + "test_FileController.py::test_list_name_file_email_empty", + "test_FileController.py::test_list_name_file_email_invalid", + "test_FileController.py::test_list_name_file_id_not_exist", + "test_FileController.py::test_list_name_file_success", + "test_FileController.py::test_list_name_files_user_id_is_greater_0", + "test_FileController.py::test_list_name_files_user_id_is_integer", + "test_FileController.py::test_list_name_files_user_id_is_interger", + "test_FileController.py::test_list_name_files_user_id_required", + "test_FileController.py::test_upload_file_user_id_required", + "test_FileController.py::test_upload_files_empty_email", + "test_FileController.py::test_upload_files_id_not_exist", + "test_FileController.py::test_upload_files_invalid_email", + "test_FileController.py::test_upload_files_invalid_file_type", + "test_FileController.py::test_upload_files_success", + "test_FileController.py::test_upload_files_user_id_is_greater_0", + "test_FileController.py::test_upload_files_user_id_is_integer", + "test_FileController.py::test_upload_files_user_id_is_interger", + "test_LoginController.py::test_change_password_current_password_empty", + "test_LoginController.py::test_change_password_current_password_not_valid", + "test_LoginController.py::test_change_password_current_password_required", + "test_LoginController.py::test_change_password_email_invalid", + "test_LoginController.py::test_change_password_email_is_empty", + "test_LoginController.py::test_change_password_id_not_exist", + "test_LoginController.py::test_change_password_new_password_empty", + "test_LoginController.py::test_change_password_new_password_required", + "test_LoginController.py::test_change_password_success", + "test_LoginController.py::test_change_password_user_id_integer", + "test_LoginController.py::test_change_password_user_id_integer_greater_than_0", + "test_LoginController.py::test_change_password_user_id_required", + "test_LoginController.py::test_check_info_google_by_email_success", + "test_LoginController.py::test_check_info_google_email_empty", + "test_LoginController.py::test_check_info_google_email_invalid", + "test_LoginController.py::test_check_info_google_id_not_exist", + "test_LoginController.py::test_check_info_google_sign_up_email_is_required", + "test_LoginController.py::test_check_info_google_sign_up_email_must_str", + "test_LoginController.py::test_check_info_google_signup_email_empty", + "test_LoginController.py::test_check_info_google_signup_email_invalid", + "test_LoginController.py::test_check_info_google_success", + "test_LoginController.py::test_check_info_google_user_id_must_integer", + "test_LoginController.py::test_check_info_google_user_id_must_integer_greater_than_0", + "test_LoginController.py::test_check_info_google_user_id_required", + "test_LoginController.py::test_check_signup_session_id_must_str", + "test_LoginController.py::test_check_signup_session_id_required", + "test_LoginController.py::test_check_state_login_email_empty", + "test_LoginController.py::test_check_state_login_email_invalid", + "test_LoginController.py::test_check_state_login_id_not_exits", + "test_LoginController.py::test_check_state_login_not_found", + "test_LoginController.py::test_check_state_login_session_id_must_str", + "test_LoginController.py::test_check_state_login_session_id_required", + "test_LoginController.py::test_check_state_login_success", + "test_LoginController.py::test_check_state_login_user_id_must_integer", + "test_LoginController.py::test_check_state_login_user_id_must_integer_greater_than_0", + "test_LoginController.py::test_check_state_login_user_id_required", + "test_LoginController.py::test_check_state_session_empty", + "test_LoginController.py::test_login_email_can_not_empty", + "test_LoginController.py::test_login_email_empty", + "test_LoginController.py::test_login_email_invalid", + "test_LoginController.py::test_login_email_not_exist", + "test_LoginController.py::test_login_email_password_error", + "test_LoginController.py::test_login_email_required", + "test_LoginController.py::test_login_email_required_str", + "test_LoginController.py::test_login_google_email_can_not_empty", + "test_LoginController.py::test_login_google_email_empty", + "test_LoginController.py::test_login_google_email_invalid", + "test_LoginController.py::test_login_google_email_password_error", + "test_LoginController.py::test_login_google_email_required", + "test_LoginController.py::test_login_google_email_required_str", + "test_LoginController.py::test_login_google_email_required_str_1", + "test_LoginController.py::test_login_google_email_token_required_str", + "test_LoginController.py::test_login_google_invalid_authorization_code", + "test_LoginController.py::test_login_google_success", + "test_LoginController.py::test_login_google_token_google_required", + "test_LoginController.py::test_login_gooogle_email_can_not_empty", + "test_LoginController.py::test_login_gooogle_email_required", + "test_LoginController.py::test_login_invalid_authorization_code", + "test_LoginController.py::test_login_password_empty", + "test_LoginController.py::test_login_password_required", + "test_LoginController.py::test_login_success", + "test_LoginController.py::test_refresh_token_email_empty", + "test_LoginController.py::test_refresh_token_email_invalid", + "test_LoginController.py::test_refresh_token_success", + "test_LoginController.py::test_refresh_token_token_empty", + "test_LoginController.py::test_refresh_token_token_errror", + "test_LoginController.py::test_refresh_token_token_is_required", + "test_LoginController.py::test_refresh_token_token_must_be_str", + "test_LoginController.py::test_refresh_token_user_id_integer", + "test_LoginController.py::test_refresh_token_user_id_integer_greater_than_0", + "test_LoginController.py::test_refresh_token_user_id_not_exist", + "test_LoginController.py::test_refresh_token_user_id_required", + "test_LoginController.py::test_reset_email_must_str", + "test_LoginController.py::test_reset_email_required", + "test_LoginController.py::test_reset_password_email_is_None", + "test_LoginController.py::test_reset_password_invalid_email", + "test_LoginController.py::test_reset_password_success", + "test_LoginController.py::test_reset_password_user_not_found", + "test_LoginController.py::test_sign_up_email_exist", + "test_LoginController.py::test_sign_up_email_invadlid", + "test_LoginController.py::test_sign_up_email_is_empty", + "test_LoginController.py::test_sign_up_error", + "test_LoginController.py::test_sign_up_password_empty", + "test_LoginController.py::test_sign_up_success", + "test_LoginController.py::test_signup_email_is_required", + "test_LoginController.py::test_signup_email_must_str", + "test_LoginController.py::test_signup_password_required", + "test_LoginController.py::test_signup_session_id_must_str", + "test_LoginController.py::test_signup_session_id_required", + "test_LoginController.py::test_update_user_info_dis_play_name_field_required", + "test_LoginController.py::test_update_user_info_email_empty", + "test_LoginController.py::test_update_user_info_email_field_required", + "test_LoginController.py::test_update_user_info_email_invalid", + "test_LoginController.py::test_update_user_info_email_or_password_error", + "test_LoginController.py::test_update_user_info_id_not_exist", + "test_LoginController.py::test_update_user_info_photo_url_field_required", + "test_LoginController.py::test_update_user_info_success", + "test_LoginController.py::test_update_user_info_uid_field_required", + "test_LoginController.py::test_update_user_info_user_id_greater_than_0", + "test_LoginController.py::test_update_user_info_user_id_integer_required", + "test_LoginController.py::test_update_user_info_user_id_interger_required", + "test_LoginController.py::test_update_user_info_user_id_required", + "test_MySQLController.py::test_delete_chat_email_empty", + "test_MySQLController.py::test_delete_chat_email_invalid", + "test_MySQLController.py::test_delete_chat_id_not_exits", + "test_MySQLController.py::test_delete_chat_name_empty", + "test_MySQLController.py::test_delete_chat_name_error_500", + "test_MySQLController.py::test_delete_chat_success", + "test_MySQLController.py::test_edit_chat1_error", + "test_MySQLController.py::test_edit_chat_email_empty", + "test_MySQLController.py::test_edit_chat_email_invalid", + "test_MySQLController.py::test_edit_chat_invalid_id", + "test_MySQLController.py::test_edit_chat_name_new", + "test_MySQLController.py::test_edit_chat_name_old", + "test_MySQLController.py::test_edit_chat_success", + "test_MySQLController.py::test_load_chat_history", + "test_MySQLController.py::test_load_chat_history_chat_id_greater_than_inter", + "test_MySQLController.py::test_load_chat_history_chat_id_is_required", + "test_MySQLController.py::test_load_chat_history_empty", + "test_MySQLController.py::test_load_chat_history_empty1", + "test_MySQLController.py::test_load_chat_history_user_id_greater_than0", + "test_MySQLController.py::test_load_chat_history_user_id_greater_than_inter", + "test_MySQLController.py::test_load_chat_history_user_id_is_required", + "test_MySQLController.py::test_load_chat_history_user_id_must_be_integer", + "test_MySQLController.py::test_load_chat_history_user_id_mustbe_inter", + "test_MySQLController.py::test_load_chat_history_value_mustbe_inter", + "test_MySQLController.py::test_render_chat_empty", + "test_MySQLController.py::test_render_chat_history", + "test_MySQLController.py::test_render_chat_user_id_greater_than_inter", + "test_MySQLController.py::test_render_chat_user_id_required", + "test_MySQLController.py::test_render_chat_value_mustbe_interger", + "test_OTPController.py::test_createOTPReset_email_empty", + "test_OTPController.py::test_createOTPReset_email_invalid", + "test_OTPController.py::test_createOTPReset_success", + "test_OTPController.py::test_createOTP_email_must_be_string", + "test_OTPController.py::test_createOTP_email_required", + "test_OTPController.py::test_createOTP_failed_empty_email", + "test_OTPController.py::test_createOTP_failed_empty_invalid", + "test_OTPController.py::test_createOTP_success", + "test_OTPController.py::test_create_otp_with_missing_body", + "test_OTPController.py::test_create_otp_with_missing_email", + "test_OTPController.py::test_verifyOTPReset1_success", + "test_OTPController.py::test_verifyOTPReset_email_is_required", + "test_OTPController.py::test_verifyOTPReset_failed_empty_email", + "test_OTPController.py::test_verifyOTPReset_failed_empty_otp", + "test_OTPController.py::test_verifyOTPReset_failed_invalid_email", + "test_OTPController.py::test_verifyOTPReset_failed_invalid_otp", + "test_OTPController.py::test_verifyOTPReset_failed_no_otp_found", + "test_OTPController.py::test_verifyOTPReset_has_expired", + "test_OTPController.py::test_verifyOTPReset_otp_email_must_be_string", + "test_OTPController.py::test_verifyOTPReset_otp_is_required", + "test_OTPController.py::test_verifyOTPReset_otp_max_length", + "test_OTPController.py::test_verifyOTPReset_otp_must_be_string", + "test_OTPController.py::test_verifyOTP_email_is_required", + "test_OTPController.py::test_verifyOTP_failed_empty_email", + "test_OTPController.py::test_verifyOTP_failed_empty_otp", + "test_OTPController.py::test_verifyOTP_failed_invalid_email", + "test_OTPController.py::test_verifyOTP_failed_invalid_otp", + "test_OTPController.py::test_verifyOTP_failed_no_otp_found", + "test_OTPController.py::test_verifyOTP_has_expired", + "test_OTPController.py::test_verifyOTP_otp_email_must_be_string", + "test_OTPController.py::test_verifyOTP_otp_is_required", + "test_OTPController.py::test_verifyOTP_otp_max_length", + "test_OTPController.py::test_verifyOTP_otp_must_be_string", + "test_OTPController.py::test_verifyOTP_success" +] \ No newline at end of file diff --git a/tests/test_controller/.pytest_cache/v/cache/stepwise b/tests/test_controller/.pytest_cache/v/cache/stepwise new file mode 100644 index 0000000000000000000000000000000000000000..0637a088a01e8ddab3bf3fa98dbe804cbde1a0dc --- /dev/null +++ b/tests/test_controller/.pytest_cache/v/cache/stepwise @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/tests/test_controller/__init__.py b/tests/test_controller/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/test_controller/__pycache__/__init__.cpython-310.pyc b/tests/test_controller/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..923fd66e459874d69bf0b2f76d39865931f1ee68 Binary files /dev/null and b/tests/test_controller/__pycache__/__init__.cpython-310.pyc differ diff --git a/tests/test_controller/__pycache__/__init__.cpython-311.pyc b/tests/test_controller/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e7d8d54d47d5f4c133d61ee6d9773d70c0b041f5 Binary files /dev/null and b/tests/test_controller/__pycache__/__init__.cpython-311.pyc differ diff --git a/tests/test_controller/__pycache__/test_ChatController.cpython-310-pytest-8.2.2.pyc b/tests/test_controller/__pycache__/test_ChatController.cpython-310-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2f031610557998d417c0fec1864c072f2b7c2d1 Binary files /dev/null and b/tests/test_controller/__pycache__/test_ChatController.cpython-310-pytest-8.2.2.pyc differ diff --git a/tests/test_controller/__pycache__/test_ChatController.cpython-310.pyc b/tests/test_controller/__pycache__/test_ChatController.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..799715987bc72ddc57851f45d6914436db21dc5d Binary files /dev/null and b/tests/test_controller/__pycache__/test_ChatController.cpython-310.pyc differ diff --git a/tests/test_controller/__pycache__/test_ChatController.cpython-311-pytest-8.2.2.pyc b/tests/test_controller/__pycache__/test_ChatController.cpython-311-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..49b4a5e15092e58eed6e5d5d9792ce3395d64f52 Binary files /dev/null and b/tests/test_controller/__pycache__/test_ChatController.cpython-311-pytest-8.2.2.pyc differ diff --git a/tests/test_controller/__pycache__/test_DefaultController.cpython-310-pytest-8.2.2.pyc b/tests/test_controller/__pycache__/test_DefaultController.cpython-310-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da924cd3fa8af2c2691e762146e6f48a139a4089 Binary files /dev/null and b/tests/test_controller/__pycache__/test_DefaultController.cpython-310-pytest-8.2.2.pyc differ diff --git a/tests/test_controller/__pycache__/test_DefaultController.cpython-310.pyc b/tests/test_controller/__pycache__/test_DefaultController.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..98d4d8e7bdc5d9643a974af4681b0d9a9373ac81 Binary files /dev/null and b/tests/test_controller/__pycache__/test_DefaultController.cpython-310.pyc differ diff --git a/tests/test_controller/__pycache__/test_DefaultController.cpython-311-pytest-8.2.2.pyc b/tests/test_controller/__pycache__/test_DefaultController.cpython-311-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..62b846ea6d0315c3cdf32ac83c25b4e2a47d7a3f Binary files /dev/null and b/tests/test_controller/__pycache__/test_DefaultController.cpython-311-pytest-8.2.2.pyc differ diff --git a/tests/test_controller/__pycache__/test_FileController.cpython-310-pytest-8.2.2.pyc b/tests/test_controller/__pycache__/test_FileController.cpython-310-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d14001004e6656d90a8652c9736591c7c3d0337a Binary files /dev/null and b/tests/test_controller/__pycache__/test_FileController.cpython-310-pytest-8.2.2.pyc differ diff --git a/tests/test_controller/__pycache__/test_FileController.cpython-310.pyc b/tests/test_controller/__pycache__/test_FileController.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8791e30f3e3a8026bb14ffa5a5c223f4d24acefd Binary files /dev/null and b/tests/test_controller/__pycache__/test_FileController.cpython-310.pyc differ diff --git a/tests/test_controller/__pycache__/test_FileController.cpython-311-pytest-8.2.2.pyc b/tests/test_controller/__pycache__/test_FileController.cpython-311-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b65b7a10101f1c6d902052da18ead3eef1637b5d Binary files /dev/null and b/tests/test_controller/__pycache__/test_FileController.cpython-311-pytest-8.2.2.pyc differ diff --git a/tests/test_controller/__pycache__/test_LoginController.cpython-310-pytest-8.2.2.pyc b/tests/test_controller/__pycache__/test_LoginController.cpython-310-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..482de760d270eb48f7ab2a9db42e99d5c9e785ec Binary files /dev/null and b/tests/test_controller/__pycache__/test_LoginController.cpython-310-pytest-8.2.2.pyc differ diff --git a/tests/test_controller/__pycache__/test_LoginController.cpython-310.pyc b/tests/test_controller/__pycache__/test_LoginController.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..015f342b3293a7c9c9c38ba24f59f06891fced5a Binary files /dev/null and b/tests/test_controller/__pycache__/test_LoginController.cpython-310.pyc differ diff --git a/tests/test_controller/__pycache__/test_LoginController.cpython-311-pytest-8.2.2.pyc b/tests/test_controller/__pycache__/test_LoginController.cpython-311-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8b6ee798dea0592aceb4bbff4fffffa297d6e736 Binary files /dev/null and b/tests/test_controller/__pycache__/test_LoginController.cpython-311-pytest-8.2.2.pyc differ diff --git a/tests/test_controller/__pycache__/test_MySQLController.cpython-310-pytest-8.2.2.pyc b/tests/test_controller/__pycache__/test_MySQLController.cpython-310-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef57b724a93d5e999cff5a0492ca3ca007eab603 Binary files /dev/null and b/tests/test_controller/__pycache__/test_MySQLController.cpython-310-pytest-8.2.2.pyc differ diff --git a/tests/test_controller/__pycache__/test_MySQLController.cpython-310.pyc b/tests/test_controller/__pycache__/test_MySQLController.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..86f8cb7fccd711879a5677e4e34c2a903f473c7e Binary files /dev/null and b/tests/test_controller/__pycache__/test_MySQLController.cpython-310.pyc differ diff --git a/tests/test_controller/__pycache__/test_MySQLController.cpython-311-pytest-8.2.2.pyc b/tests/test_controller/__pycache__/test_MySQLController.cpython-311-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..266427b64c2fd41f1a1790189229cba9ad0d9093 Binary files /dev/null and b/tests/test_controller/__pycache__/test_MySQLController.cpython-311-pytest-8.2.2.pyc differ diff --git a/tests/test_controller/__pycache__/test_OTPController.cpython-310-pytest-8.2.2.pyc b/tests/test_controller/__pycache__/test_OTPController.cpython-310-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2331288ff2b1c1e92acf1f7eee44fd74cebc2ca5 Binary files /dev/null and b/tests/test_controller/__pycache__/test_OTPController.cpython-310-pytest-8.2.2.pyc differ diff --git a/tests/test_controller/__pycache__/test_OTPController.cpython-310.pyc b/tests/test_controller/__pycache__/test_OTPController.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3a635cc1961793a51191cb589137ec53bd8b7519 Binary files /dev/null and b/tests/test_controller/__pycache__/test_OTPController.cpython-310.pyc differ diff --git a/tests/test_controller/__pycache__/test_OTPController.cpython-311-pytest-8.2.2.pyc b/tests/test_controller/__pycache__/test_OTPController.cpython-311-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5c1c52c6f1d650461e1b84ce9cad24de6aa7ff46 Binary files /dev/null and b/tests/test_controller/__pycache__/test_OTPController.cpython-311-pytest-8.2.2.pyc differ diff --git a/tests/test_controller/test_ChatController.py b/tests/test_controller/test_ChatController.py new file mode 100644 index 0000000000000000000000000000000000000000..26cfd780fe291e7affa0be1c5c113fef6d94f253 --- /dev/null +++ b/tests/test_controller/test_ChatController.py @@ -0,0 +1,267 @@ +import os +import sys +from unittest.mock import patch +from fastapi.testclient import TestClient +app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) +sys.path.insert(0, app_path) +from controller import ChatController +import json +client = TestClient(ChatController.router) + +text_all = [{ + "page_content": "Thành lập vào năm 2012, VMO Holdings (VMO) là công ty cung cấp dịch vụ CNTT chuyên nghiệp có trụ sở tại Việt Nam, Nhật Bản, Thái Lan và Mỹ. Với hơn 10 năm hoạt động trong lĩnh vực tư vấn và phát triển phần mềm, VMO hiện có hơn 1200 nhân sự và 9 văn phòng tại Việt Nam.\n\nHoàn thiện hệ sinh thái VMO và hướng tới giá trị cốt lõi trong tất cả các hoạt động, VMO tự tin trao quyền và niềm tin cho thế hệ kế cận. Chúng tôi luôn sẵn sàng chào đón các nhân tài cùng tham gia chinh phục thử thách trên những chặng đường sắp tới.\n\nTìm hiểu thêm về VMO Holdings qua:\n\n LinkedIn  Facebook  Website\n\nTHÔNG TIN TUYỂN DỤNG\n\nVị trí:\n\nĐịa điểm:\n\nBusiness Development Intern\n\nHà Nội\n\nKinh nghiệm:\n\nSố lượng:\n\nKhông yêu cầu kinh nghiệm 12\n\nMỨC HỖ TRỢ\n\nUpto 3M (Tùy theo năng lực) + Thưởng hoa hồng\n\nMÔ TẢ CÔNG VIỆC\n\nTham gia chương trình đào tạo miễn phí trong vòng 3 tháng theo lộ trình được\n\nxây dựng bài bản của công ty\n\nTham gia đào tạo các kỹ năng mềm, quy trình làm việc chuyên nghiệp  Trải nghiệm thực tế các công việc của một Business Developer như: + Tìm kiếm và kết nối với khách hàng + Giới thiệu sơ bộ về sản phẩm và dịch vụ công ty với khách hàng + Khai thác dữ liệu khách hàng\n\n[Type here]\n\nYÊU CẦU CÔNG VIỆC\n\nSử dụng Tiếng Anh thành thạo\n\nChăm chỉ, kiên nhẫn  Năng động, cởi mở, hòa đồng \n\nThông minh, tiếp thu nhanh, tư duy nhạy bén\n\nCó tinh thần cầu tiến trong công việc  Có kỹ năng giao tiếp và giải quyết vấn đề tốt  Có khả năng làm việc nhóm tốt  Đảm bảo làm việc full-time sau quá trình đào tạo\n\nQUYỀN LỢI\n\nCó cơ hội trở thành nhân viên chính thức tại VMO sau quá trình đào tạo   Được học tập với đội ngũ Mentors là Sales Manager, Teamlead có nhiều kinh nghiệm trong ngành Sales IT Global\n\nĐược tham gia các chương trình đào tạo nâng cao kỹ năng chuyên môn định kỳ\n\nhàng tháng\n\nĐược làm việc trực tiếp với khách hàng đa quốc gia thuộc nhiều lĩnh vực khác\n\nnhau\n\nĐược đào tạo trong môi trường năng động, trẻ trung, hiện đại và chuyên nghiệp\n\nCƠ HỘI VÀ THỬ THÁCH\n\nCơ hội được thử sức với các dự án hấp dẫn, thử thách đủ lớn trong và ngoài nước.  Cơ hội làm trải nghiệm môi trường làm việc cởi mở và năng động, khuyến khích trao đổi ý tưởng, trao quyền, cho phép làm việc, sáng tạo theo cách riêng. Tài năng và thành tích của từng nhân viên được trân trọng, nhân viên xuất sắc được khen thưởng hàng năm.\n\nCơ hội phát triển năng lực, được hỗ trợ phụ cấp chứng chỉ chuyên môn phục vụ công việc. Một số chứng chỉ cấp cao sẽ được chi trả toàn bộ chi phí từ học và thi.  Dự án khủng với domain hot-trend, liên tục cập nhật những công nghệ mới nhất Được làm việc trong môi trường có quy trình chuyên nghiệp, cùng những chuyên gia công nghệ đến từ các nước và khu vực khác nhau\n\n[Type here]\n\nVui lòng gửi CV của bạn về địa chỉ email: minhdn4@vmogroup.com\n\nEmail: minhdn4@vmogroup.com\n\nĐịa chỉ: Phòng Tuyển dụng – VMO Holdings, Tầng 20, Tòa IDMC, Số 18 Tôn Thất Thuyết, Mỹ Đình, Hà Nội.\n\n[Type here]", + "metadata": {"source": "/code/temp/vonhuytest123456789@gmail.com/JD_BD-Intern.pdf"}, + "type": "Document"}] + +from response import ResponseChat as res +@patch('function.support_function.check_email_service') +def test_query2_upgrade_old_id_not_exist(mock_user_repo): + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Id not exist")) + response = client.post("/chatbot/query/", data={"user_id": 1, + "text_all": json.dumps(text_all), + "question": "12455", + "chat_name": "test"}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Id not exist" + +@patch('function.support_function.check_email_service') +def test_query2_upgrade_old_email_empty(mock_user_repo): + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + response = client.post("/chatbot/query/", data={"user_id": 1, + "text_all": json.dumps(text_all), + "question": "12455", + "chat_name": "test"}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is empty" + +@patch('function.support_function.check_email_service') +def test_query2_upgrade_old_email_in_valid(mock_user_repo): + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + response = client.post("/chatbot/query/", data={"user_id": 1, + "text_all": json.dumps(text_all), + "question": "12455", + "chat_name": "test"}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email invalid" + +@patch('function.support_function.check_email_service') +def test_query2_upgrade_old_question_empty(mock_user_repo): + mock_user_repo.return_value = "example@example.com" + response = client.post("/chatbot/query/", data={"user_id": 1, + "text_all": json.dumps(text_all), + "question": "", + "chat_name": "test"}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "question is empty" + +@patch('function.support_function.check_email_service') +def test_query2_upgrade_old_chat_history_empty(mock_user_repo): + mock_user_repo.return_value = "example@example.com" + response = client.post("/chatbot/query/", data={"user_id": 1, + "text_all": json.dumps(text_all), + "question": "123", + "chat_name": None}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "chat_name is empty" + +@patch('function.support_function.check_email_service') +@patch('service.ChatService.sf') +def test_query2_upgrade_old_no_answer(mock_function_chatbot, mock_user_repo): + mock_user_repo.return_value = ("example@example.com",) + list1 = [] + list2 = [] + mock_function_chatbot.handle_query_upgrade_keyword_old.return_value = None, list1, list2 + response = client.post("/chatbot/query/", data={"user_id": 1, + "text_all": json.dumps(text_all), + "question": "alo", + "chat_name": "test"}) + assert response.json()['status'] == 500 + assert response.json()['data']['message'] == "No answer" + +@patch('function.support_function.check_email_service') +@patch('service.ChatService.sf') +@patch('service.ChatService.ChatHistoryRepository') +@patch('service.ChatService.DetailChatRepository') +def test_query2_upgrade_old_success(mock_detail_chat_repo, mock_chat_his_repo, mock_function_chatbot, mock_user_repo): + mock_user_repo.return_value = ("example@example.com",) + list1 = [] + list2 = [] + mock_function_chatbot.handle_query_upgrade_keyword_old.return_value = "success",list1,list2 + mock_chat_his_repo.getIdChatHistoryByUserIdAndNameChat.return_value = True + mock_detail_chat_repo.addDetailChat.return_value = True + response = client.post("/chatbot/query/", data={"user_id": 1, + "text_all": json.dumps(text_all), + "question": "123", + "chat_name": "test"}) + assert response.json()['status'] == 200 + assert response.json()['data']['answer'] == "success" + +@patch('function.support_function.check_email_service') +@patch('service.ChatService.sf') +def test_extract_file_success(mock_function_chatbot, mock_user_repo): + user_id = 1 + mock_user_repo.return_value = ("example@example.com",) + mock_function_chatbot.extract_data2.return_value = "Success" + response = client.get("/chatbot/extract_file/", params={"user_id": user_id}) + assert response.json()['status'] == 200 + assert response.json()['data']['text_all'] == "Success" + + + +@patch('function.support_function.check_email_service') +def test_extract_file_id_not_exist(mock_user_repo): + user_id = 1 + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Id not exist")) + response = client.get("/chatbot/extract_file/", params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Id not exist" + +@patch('function.support_function.check_email_service') +def test_extract_file_email_empty(mock_user_repo): + user_id = 1 + email = "" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + response = client.get("/chatbot/extract_file/", params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is empty" + +@patch('function.support_function.check_email_service') +def test_extract_file_email_in_valid(mock_user_repo): + user_id = 1 + email = "202133123" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + response = client.get("/chatbot/extract_file/", params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email invalid" + +@patch('function.support_function.check_email_service') +@patch('service.ChatService.sf') +def test_extract_file_no_data(mock_function_chatbot, mock_user_repo): + user_id = 1 + email = "2021330@gmail.com" + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + mock_function_chatbot.extract_data2.return_value = False + response = client.get("/chatbot/extract_file/", params={"user_id": user_id}) + assert response.json()['status'] == 200 + assert response.json()['data']['text_all'] == "No data response" + +@patch('function.support_function.check_email_service') +@patch('service.ChatService.sf') +def test_generate_question_success(mock_function_chatbot, mock_user_repo): + user_id = 1 + mock_user_repo.return_value = ("example@example.com",) + mock_function_chatbot.generate_question.return_value = ["Success"] + response = client.get("/chatbot/generate_question/", params={"user_id": user_id}) + assert response.json()['status'] == 200 + assert response.json()['data']['question'] == ["Success"] + +@patch('function.support_function.check_email_service') +def test_generate_question_id_not_exist(mock_user_repo): + user_id = 1 + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Id not exist")) + response = client.get("/chatbot/generate_question/", params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Id not exist" + +@patch('function.support_function.check_email_service') +def test_generate_question_email_empty(mock_user_repo): + user_id = 1 + email = "" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + response = client.get("/chatbot/generate_question/", params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is empty" + + +@patch('function.support_function.check_email_service') +def test_generate_question_email_in_valid(mock_user_repo): + user_id = 1 + email = "202133123" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + response = client.get("/chatbot/generate_question/", params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email invalid" + +@patch('function.support_function.check_email_service') +@patch('service.ChatService.sf') +def test_generate_question_no_data(mock_function_chatbot, mock_user_repo): + user_id = 1 + email = "2021330@gmail.com" + mock_user_repo.return_value = (email,) + mock_function_chatbot.generate_question.return_value = False + response = client.get("/chatbot/generate_question/", params={"user_id": user_id}) + assert response.json()['status'] == 200 + assert response.json()['data']['question'] == False + +def test_query_chatbot_user_id_required(): + user_id = None + response = client.post("/chatbot/query/", data={"user_id": user_id, + "text_all": json.dumps(text_all), + "question": "12455", + "chat_name": "test"}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_query_chatbot_user_id_interger(): + user_id = "aaaaa" + response = client.post("/chatbot/query/", data={"user_id": user_id, + "text_all": json.dumps(text_all), + "question": "12455", + "chat_name": "test"}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be an integer" + +def test_query_chatbot_user_id_greater_0(): + user_id = "0" + response = client.post("/chatbot/query/", data={"user_id": user_id, + "text_all": json.dumps(text_all), + "question": "12455", + "chat_name": "test"}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be greater than 0" + + +def test_extract_file_user_id_required(): + user_id = None + response = client.get("/chatbot/extract_file/", params = {"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_extract_file_user_id_interger(): + user_id = "aaaaa" + response = client.get("/chatbot/extract_file/", params = {"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be an integer" + +def test_extract_file_user_id_greater_0(): + user_id = "0" + response = client.get("/chatbot/extract_file/", params = {"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be greater than 0" + +def test_generate_question_user_id_required(): + user_id = None + response = client.get("/chatbot/generate_question/", params = {"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_generate_question_user_id_interger(): + user_id = "aaaaa" + response = client.get("/chatbot/generate_question/", params = {"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be an integer" + +def test_generate_question_user_id_greater_0(): + user_id = "0" + response = client.get("/chatbot/generate_question/", params = {"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be greater than 0" \ No newline at end of file diff --git a/tests/test_controller/test_DefaultController.py b/tests/test_controller/test_DefaultController.py new file mode 100644 index 0000000000000000000000000000000000000000..82948bf980e323624340f7e7d24092fce4a66ccd --- /dev/null +++ b/tests/test_controller/test_DefaultController.py @@ -0,0 +1,373 @@ +import json +import os +import sys +from unittest.mock import patch, Mock + +from fastapi.testclient import TestClient + +app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) +sys.path.insert(0, app_path) +from controller import DefaultController +client = TestClient(DefaultController.router) + +def test_create_firebase_user_null_email(): + request_payload = {"email": None} + response = client.post("/create_firebase_user_google", json=request_payload) + assert response.json()['status'] == 400 + try: + response_data = response.json()['data'] + assert response_data['message'] == "Email is required." + except json.decoder.JSONDecodeError: + assert response.text == "Email cannot be 'null'." + +def test_invalid_email(): + email = "invalid-email" + response = client.post("/create_firebase_user_google", json={"email": email}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email invalid" + +@patch('service.DefaultService.sf.check_email_empty_invalid', return_value=True) +@patch('service.DefaultService.get_user') +def test_create_firebase_user_success(mock_get_user, mock_check_email): + email = "20133118@gmail.com" + user = Mock() + user.email = "test@example.com" + user.display_name = "Test User" + user.uid = "123456" + user.photo_url = "http://example.com/photo.jpg" + mock_get_user.return_value = user + response = client.post("/create_firebase_user_google", json={"email": email}) + assert response.json()['status'] == 200 + assert response.json()['data']['localId'] == "123456" + assert response.json()['data']['displayName'] == user.display_name + assert response.json()['data']['email'] == user.email + assert response.json()['data']['photoUrl'] == user.photo_url + +@patch('service.DefaultService.sf.check_email_empty_invalid', return_value=True) +@patch('service.DefaultService.get_user', return_value=None) +def test_create_firebase_user_error(mock_get_user, mock_check_email): + email = "20133118@gmail.com" + response = client.post("/create_firebase_user_google", json={"email": email}) + assert response.json()['status'] == 500 + assert response.json()['data']['message'] == "Error" + +@patch('service.DefaultService.sf.check_email_empty_invalid',return_value=True) +@patch('service.DefaultService.get_user') +def test_create_firebase_server_error(mock_get_user, mock_check_email): + email = "20133118@gmail.com" + mock_get_user.side_effect = Exception("Unexpected Error") + response = client.post("/create_firebase_user_google", json={"email": email}) + assert response.json()['status'] == 500 + assert response.json()['data']['message'] == "Server Error" + +from response import ResponseDefault as res +@patch('service.DefaultService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Id not exist"))) +@patch('service.DefaultService.get_user') +@patch('service.DefaultService.check_email') +def test_id_not_exist(mock_check_email, mock_get_user, mock_getEmailUserByIdFix): + user_id = "1" + response = client.get("/info_user", params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Id not exist" + +@patch('service.DefaultService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty"))) +@patch('service.DefaultService.get_user') +@patch('service.DefaultService.check_email') +def test_info_user_email_empty(mock_check_email, mock_get_user, mock_getEmailUserByIdFix): + user_id = "1" + response = client.get("/info_user", params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is empty" + +@patch('service.DefaultService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid"))) +@patch('service.DefaultService.get_user') +@patch('service.DefaultService.check_email') +def test_info_user_email_invalid(mock_check_email, mock_get_user, mock_getEmailUserByIdFix): + user_id = "1" + email = "20133118" + response = client.get("/info_user", params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email invalid" + +@patch('service.DefaultService.UserRepository.getEmailUserByIdFix') +@patch('service.DefaultService.get_user', return_value=None) +@patch('service.DefaultService.check_email', return_value=True) +@patch('service.DefaultService.sf.check_email_service',return_value="20133118@gmail.com") +def test_info_user_user_not_found(mock_check,mock_check_email, mock_get_user, mock_getEmailUserByIdFix): + user_id = "1" + email = "20133118@gmail.com" + response = client.get("/info_user", params={"user_id": user_id}) + assert response.json()['status'] == 404 + assert response.json()['data']['message'] == "User not found" + +@patch('service.DefaultService.UserRepository.getEmailUserByIdFix') +@patch('service.DefaultService.get_user') +@patch('service.DefaultService.check_email', return_value=True) +@patch('service.DefaultService.sf.check_email_service',return_value="20133118@gmail.com") +def test_info_success(mock_check,mock_check_email, mock_get_user, mock_getEmailUserByIdFix): + user_id = "1" + email = "20133118@gmail.com" + user = Mock() + user.uid = "12345" + user.email = "test@example.com" + user.display_name = "Test User" + user.photo_url = "http://example.com/photo.jpg" + mock_get_user.return_value = user + response = client.get("/info_user", params={"user_id": user_id}) + assert response.json()['status'] == 200 + assert response.json()['data']['uid'] == user.uid + assert response.json()['data']['email'] == user.email + assert response.json()['data']['display_name'] == user.display_name + assert response.json()['data']['photo_url'] == user.photo_url + +@patch('service.DefaultService.sf.check_email_service') +@patch('service.DefaultService.get_user') +@patch('service.DefaultService.check_email') +def test_user_info_server_error(mock_check_email, mock_get_user, mock_getEmailUserByIdFix): + user_id = "1" + email = "20133118@gmail.com" + mock_getEmailUserByIdFix.side_effect = Exception("Unexpected Error") + response = client.get("/info_user", params={"user_id": user_id}) + assert response.json()['status'] == 500 + assert response.json()['data']['message'] == "Server Error: Unexpected Error" + +@patch('service.DefaultService.check_email_token', return_value=False) +def test_is_me_none_token(mock_check_email_token): + token = "" + response = client.get("/is_me/", params={"token": token}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Token field is required." + +@patch('service.DefaultService.check_email_token', return_value=False) +def test_is_me_invalid_token(mock_check_email_token): + token = "invalid_token" + response = client.get("/is_me/", params={"token": token}) + assert response.json()['status'] == 500 + assert response.json()['data']['message'] == "Server Error" + +@patch('service.DefaultService.UserRepository.getUserByEmail') +@patch('service.DefaultService.check_email_token') +def test_is_me_success(mock_check_email_token, mock_getUserByEmail): + token = "token" + mock_check_email_token.return_value = "user@example.com" + user = Mock() + user.id = "1" + mock_getUserByEmail.return_value = user + response = client.get("/is_me/", params={"token": token}) + assert response.json()['status'] == 200 + assert response.json()['data']['user_id'] == 1 + +@patch('service.DefaultService.check_email_token') +def test_is_me_server_error(mock_check_email_token): + token = "token" + mock_check_email_token.side_effect = Exception("Unexpected Error") + response = client.get("/is_me/", params={"token": token}) + assert response.json()['status'] == 500 + assert response.json()['data']['message'] == "Server Error" + +from fastapi import UploadFile +from io import BytesIO +import tempfile, io +@patch('service.DefaultService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Id not exist"))) +def test_upload_image_id_not_exist(mock_getUserByEmail): + user_id = "1" + file_content = b"test image content" + file = io.BytesIO(file_content) + file.name = "test_image.png" + + data = { + "user_id": user_id, + } + files = {"file": ("test_image.png", file, "image/png")} + response = client.post("/upload_image/", data=data, files=files) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Id not exist" + +@patch('service.DefaultService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty"))) +def test_upload_image_email_empty(mock_getUserByEmail): + user_id = "1" + file_content = b"test image content" + file = io.BytesIO(file_content) + file.name = "test_image.png" + + data = { + "user_id": user_id, + } + files = {"file": ("test_image.png", file, "image/png")} + response = client.post("/upload_image/", data=data, files=files) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is empty" + +@patch('service.DefaultService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid"))) +def test_upload_image_email_invalid(mock_getUserByEmail): + user_id = "1" + file_content = b"test image content" + file = io.BytesIO(file_content) + file.name = "test_image.png" + data = { + "user_id": user_id, + } + files = {"file": ("test_image.png", file, "image/png")} + response = client.post("/upload_image/", data=data, files=files) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email invalid" + +@patch('service.DefaultService.sf.check_email_service', return_value="test1333@gmail.com") +@patch('service.DefaultService.cloudinary.uploader.upload') +@patch('service.DefaultService.check_email') +@patch('service.DefaultService.allowed_file') +def test_upload_image_server_err(mock_allowed_file, mock_check_email, mock_upload, mock_get_email): + mock_check_email.return_value = True + mock_allowed_file.return_value = False + user_id = "1" + file_content = b"test image content" + file = io.BytesIO(file_content) + file.name = "test_image.pdf" + + data = { + "user_id": user_id, + } + files = {"file": ("test_image.png", file, "aplication/pdf")} + response = client.post("/upload_image/", data=data, files=files) + assert response.json()['status'] == 415 + assert response.json()['data']['message'] == "File type not allow" + +@patch('service.DefaultService.sf.check_email_service', return_value="test@example.com") +@patch('service.DefaultService.cloudinary.uploader.upload') +@patch('service.DefaultService.check_email') +@patch('service.DefaultService.allowed_file') +def test_upload_image_success(mock_allowed_file, mock_check_email, mock_upload, mock_get_email): + mock_allowed_file.return_value = True + mock_upload.return_value = {"secure_url": "https://example.com/image.png"} + user_id = "1" + file_content = b"test image content" + file = io.BytesIO(file_content) + file.name = "test_image.png" + + data = { + "user_id": user_id, + } + files = {"file": ("test_image.png", file, "image/png")} + response = client.post("/upload_image/", data=data, files=files) + assert response.json()['status'] == 200 + assert response.json()['data']['url'] == 'https://example.com/image.png' + +def test_is_me_token_is_required(): + token = None + response = client.get("/is_me/",params={'token':token}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Token field is required." + +def test_is_me_token_must_be_string(): + token = "013333" + response = client.get("/is_me/",params={'token':token}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Token must be a string, not a number." + +def test_create_firebase_user_google_is_None(): + email = None + response = client.post("/create_firebase_user_google/",json={'email':email}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is required." + +def test_create_firebase_user_google_email_must_be_string(): + email = "20133" + response = client.post("/create_firebase_user_google/",json={'email':email}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email must be a string, not a number." + +def test_info_user_user_id_required(): + user_id = None + response = client.get("/info_user/",params={'user_id':user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_info_user_user_id_must_be_string(): + user_id = "abddd" + response = client.get("/info_user/",params={'user_id':user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Value must be an integer" + +def test_info_user_user_id_must_be_string(): + user_id = "0" + response = client.get("/info_user/",params={'user_id':user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be greater than 0" + +def test_upload_image_user_id_required(): + user_id = None + file_content = b"test image content" + file = io.BytesIO(file_content) + file.name = "test_image.png" + + data = { + "user_id": user_id, + } + files = {"file": ("test_image.png", file, "image/png")} + response = client.post("/upload_image/", data=data, files=files) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_upload_image_user_id_required(): + user_id = None + file_content = b"test image content" + file = io.BytesIO(file_content) + file.name = "test_image.png" + + data = { + "user_id": user_id, + } + files = {"file": ("test_image.png", file, "image/png")} + response = client.post("/upload_image/", data=data, files=files) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_upload_image_user_id_integer(): + user_id = "aaaa" + file_content = b"test image content" + file = io.BytesIO(file_content) + file.name = "test_image.png" + + data = { + "user_id": user_id, + } + files = {"file": ("test_image.png", file, "image/png")} + response = client.post("/upload_image/", data=data, files=files) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Value must be an integer" + +def test_upload_image_user_id_integer(): + user_id = "aaaa" + file_content = b"test image content" + file = io.BytesIO(file_content) + file.name = "test_image.png" + + data = { + "user_id": user_id, + } + files = {"file": ("test_image.png", file, "image/png")} + response = client.post("/upload_image/", data=data, files=files) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be an integer" + +def test_upload_image_user_id_greater_than_0(): + user_id = "0" + file_content = b"test image content" + file = io.BytesIO(file_content) + file.name = "test_image.png" + + data = { + "user_id": user_id, + } + files = {"file": ("test_image.png", file, "image/png")} + response = client.post("/upload_image/", data=data, files=files) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be greater than 0" + + diff --git a/tests/test_controller/test_FileController.py b/tests/test_controller/test_FileController.py new file mode 100644 index 0000000000000000000000000000000000000000..ea12117475def0555c29001762f407df2d37c91e --- /dev/null +++ b/tests/test_controller/test_FileController.py @@ -0,0 +1,479 @@ +import os +import sys +import tempfile +import unittest +from io import BytesIO +from unittest.mock import patch +from fastapi import UploadFile +from fastapi.testclient import TestClient +from response import ResponseFile as res +app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) +sys.path.insert(0, app_path) +from controller import FileController +client = TestClient(FileController.router) + +@patch('repository.UserRepository.getEmailUserByIdFix') +def test_delete_file_success(mock_user_repo): + user_id = "1" + email = 'example@example.com' + name_file = "test1.pdf" + mock_user_repo.return_value = (email,) + response = client.request("DELETE", "/delete_one_file", json={"user_id": user_id, "name_file": name_file}) + assert response.json()['status'] == 200 + +@patch('function.support_function.check_email_service') +def test_delete_file_id_not_exist(mock_user_repo): + user_id = "1" + email = 'example@example.com' + name_file = "test1.pdf" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Id not exist")) + response = client.request("DELETE", "/delete_one_file", json={"user_id": user_id, "name_file": name_file}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Id not exist" + +@patch('function.support_function.check_email_service') +def test_delete_file_email_empty(mock_user_repo): + user_id = "1" + name_file = "test1.pdf" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + response = client.request("DELETE", "/delete_one_file", json={"user_id": user_id, "name_file": name_file}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is empty" + +@patch('function.support_function.check_email_service') +def test_delete_file_email_invalid(mock_user_repo): + user_id = "1" + email = "20133" + name_file = "test1.pdf" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + response = client.request("DELETE", "/delete_one_file", json={"user_id": user_id, "name_file": name_file}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email invalid" + +@patch('function.support_function.check_email_service') +def test_delete_file_namefile_empty(mock_user_repo): + user_id = "1" + email = "201333@gmail.com" + name_file = "" + mock_user_repo.return_value = (email,) + response = client.request("DELETE", "/delete_one_file", json={"user_id": user_id, "name_file": name_file}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Name file is required." + +@patch('function.support_function.check_email_service') +def test_delete_all_file_success(mock_user_repo): + user_id = "1" + email = "201333@gmail.com" + mock_user_repo.return_value = (email,) + response = client.request("DELETE", "/delete_all_file/", json={"user_id": user_id}) + assert response.json()['status'] == 200 + assert response.json()['data']['message'] == "Delete all file success" + +@patch('function.support_function.check_email_service') +def test_delete_all_file_email_empty(mock_user_repo): + user_id = "1" + email = None + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + response = client.request("DELETE", "/delete_all_file/", json={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is empty" + +@patch('function.support_function.check_email_service') +def test_delete_all_file_email_invalid(mock_user_repo): + user_id = "1" + email = "20133" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + response = client.request("DELETE", "/delete_all_file/", json={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email invalid" + +@patch('function.support_function.check_email_service') +@patch('service.FileService.sf_dropbox.list_files') +def test_list_name_file_success(mock_list_files, mock_user_repo): + user_id = "1" + email = "quangphuc@gmail.com" + mock_user_repo.return_value = (email,) + list_files = [ + 'demo1.pdf', 'CV_VoNhuY_Java.pdf', 'VanHoangLuong_DangXuanBach_TLCN.docx', + 'THÔNG-TIN-TUYỂN-DỤNG-Java.pdf', 'baitap_qlpv_nhom14.docx', 'PMBOK2012-5rd Edition.pdf', + 'BaoCaoThucTapTotnghiep_20133059_Fpt_Software.docx' + ] + mock_list_files.return_value = list_files + response = client.get("/list_name_files/", params={"user_id": user_id}) + assert response.json()['status'] == 200 + assert response.json()['data']['files'] == list_files + assert len(response.json()['data']['files']) == 7 + +@patch('function.support_function.check_email_service') +@patch('service.FileService.sf_dropbox.list_files') +def test_list_name_file_id_not_exist(mock_list_files, mock_user_repo): + user_id = "1" + email = "quangphuc@gmail.com" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Id not exist")) + response = client.get("/list_name_files/", params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Id not exist" + +@patch('function.support_function.check_email_service') +@patch('service.FileService.sf_dropbox.list_files') +def test_list_name_file_email_empty(mock_list_files, mock_user_repo): + user_id = "1" + email = None + name_file = "test1.pdf" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + response = client.get("/list_name_files/", params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is empty" + +@patch('function.support_function.check_email_service') +@patch('service.FileService.sf_dropbox.list_files') +def test_list_name_file_email_invalid(mock_list_files, mock_user_repo): + user_id = "1" + email = "20133" + name_file = "test1.pdf" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + response = client.get("/list_name_files/", params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email invalid" + +@patch('function.support_function.check_email_service') +def test_download_folder_success(mock_user_repo): + user_id = "1" + email = 'example@example.com' + mock_user_repo.return_value = email + response = client.post("/chatbot/download_folder/", json={"user_id": user_id}) + assert response.json()['status'] == 200 + assert response.json()['data']['message'] == f'Downloaded folder {email} success' + +@patch('function.support_function.check_email_service') +def test_download_folder_id_not_exist(mock_user_repo): + user_id = "1" + email = 'example@example.com' + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Id not exist")) + response = client.post("/chatbot/download_folder/", json={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Id not exist" + +@patch('function.support_function.check_email_service') +def test_download_folder_email_empty(mock_user_repo): + user_id = "1" + email = None + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + response = client.post("/chatbot/download_folder/", json={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is empty" + +@patch('function.support_function.check_email_service') +def test_download_folder_email_invalid(mock_user_repo): + user_id = "1" + email = "20133" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + response = client.post("/chatbot/download_folder/", json={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email invalid" + +@patch('function.support_function.check_email_service') +def test_download_file_success(mock_user_repo): + user_id = "1" + email = "quangphuc@gmail.com" + name_file = "demo1.pdf" + mock_user_repo.return_value = email + response = client.post("/chatbot/download_files/", json={"user_id": user_id, "name_file": name_file}) + assert response.json()['status'] == 200 + assert response.json()['data']['message'] == f"Downloaded file '{name_file}' by email: '{email}' success" + +@patch('function.support_function.check_email_service') +def test_download_file_id_not_exist(mock_user_repo): + user_id = "1" + email = "quangphuc@gmail.com" + name_file = "demo1.pdf" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Id not exist")) + response = client.post("/chatbot/download_files/", json={"user_id": user_id, "name_file": name_file}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Id not exist" + +@patch('function.support_function.check_email_service') +def test_download_file_email_empty(mock_user_repo): + user_id = "1" + email = None + name_file = "demo1.pdf" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + response = client.post("/chatbot/download_files/", json={"user_id": user_id, "name_file": name_file}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is empty" + +@patch('function.support_function.check_email_service') +def test_download_file_email_invalid(mock_user_repo): + user_id = "1" + email = "quangphuc" + name_file = "demo1.pdf" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + response = client.post("/chatbot/download_files/", json={"user_id": user_id, "name_file": name_file}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email invalid" + +@patch('function.support_function.check_email_service') +def test_download_file_name_file_empty(mock_user_repo): + user_id = "1" + email = "quangphuc@gmail.com" + name_file = "" + mock_user_repo.return_value = email + response = client.post("/chatbot/download_files/", json={"user_id": user_id, "name_file": name_file}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "name_file is empty" + +@patch('function.support_function.check_email_service') +def test_upload_files_invalid_email(mock_user_repo): + user_id = "1" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + data = { + 'user_id': user_id + } + response = client.post("/upload_files/", data=data, files=[]) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email invalid" + +@patch('function.support_function.check_email_service') +def test_upload_files_empty_email(mock_user_repo): + user_id = "1" + email = None + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + data = { + 'user_id': user_id + } + response = client.post("/upload_files/", data=data, files=[]) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is empty" + +@patch('function.support_function.check_email_service') +def test_upload_files_id_not_exist(mock_user_repo): + user_id = "1" + email = 'mang1@gmail.com' + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Id not exist")) + data = { + 'user_id': user_id + } + response = client.post("/upload_files/", data=data, files=[]) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Id not exist" + +@patch('service.FileService.sf_dropbox.upload_file') +@patch('function.support_function.check_email_service') +@patch('service.FileService.allowed_file') +@patch('service.FileService.check_email') +@patch('service.FileService.os.makedirs') +@patch('builtins.open', new_callable=unittest.mock.mock_open) +def test_upload_files_success(mock_open, mock_makedirs, mock_check_email, mock_allowed_file, mock_get_email_user_by_id, + mock_upload_file): + user_id = "1" + email = 'mang1@gmail.com' + mock_get_email_user_by_id.return_value = email + mock_check_email.return_value = True + mock_allowed_file.return_value = True + + file_content = b"Test file content" + file = UploadFile(filename='test.pdf', file=BytesIO(file_content)) + + with tempfile.TemporaryDirectory() as temp_dir: + temp_dir_path = os.path.join(temp_dir, email) + os.makedirs(temp_dir_path, exist_ok=True) + file_path = os.path.join(temp_dir_path, file.filename) + mock_open.return_value.write.side_effect = lambda content: None if content == file_content else None + mock_upload_file.side_effect = lambda src, dst: None + mock_makedirs.side_effect = lambda path, exist_ok: None + data = { + 'user_id': user_id + } + files = { + 'files': (file.filename, file.file, 'application/pdf') + } + response = client.post("/upload_files/", data=data, files=files) + assert response.status_code == 200 + assert response.json()['status'] == 200 + assert response.json()['data']['message'] == "Load file success" + # expected_src_path = os.path.join(temp_dir_path, file.filename).replace("\\", "/") + # expected_dst_path = f"/{email}/{file.filename}" + # actual_src_path, actual_dst_path = mock_upload_file.call_args[0] + # actual_src_path = actual_src_path.replace("\\", "/") + # assert expected_src_path == actual_src_path and expected_dst_path == actual_dst_path +@patch('service.FileService.sf_dropbox.upload_file') +@patch('function.support_function.check_email_service') +@patch('service.FileService.allowed_file') +@patch('service.FileService.check_email') +@patch('service.FileService.os.makedirs') +@patch('service.FileService.shutil.copyfileobj') +def test_upload_files_invalid_file_type(mock_copyfileobj, mock_makedirs, mock_check_email, mock_allowed_file, + mock_get_email_user_by_id, mock_upload_file): + user_id = "1" + email = 'mang1@gmail.com' + mock_get_email_user_by_id.return_value = email + mock_allowed_file.return_value = False + file_content = b"Test file content" + file = UploadFile(filename='test.exe', file=BytesIO(file_content)) + data = { + 'user_id': user_id + } + files = { + 'files': (file.filename, file.file) + } + response = client.post("/upload_files/", data=data, files=files) + assert response.json()['status'] == 415 + assert response.json()['data']['message'] == "File type not allow" + +def test_delete__all_file_user_id_required(): + user_id = None + response = client.request("DELETE", "/delete_all_file/", json={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_delete_all_file_user_id_is_integer(): + user_id = "aaaa" + response = client.request("DELETE", "/delete_all_file/", json={"user_id": "aaaa"}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be an integer" + +def test_delete_all_file_user_id_is_greater_0(): + response = client.request("DELETE", "/delete_all_file/", json={"user_id": "0"}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be greater than 0" + +def test_list_name_files_user_id_required(): + user_id = None + response = client.request("GET", "/list_name_files/", params ={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_list_name_files_user_id_is_integer(): + user_id = "aaaa" + response = client.request("GET", "/list_name_files/", params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be an integer" + +def test_list_name_files_user_id_is_greater_0(): + user_id = "-100" + response = client.request("GET", "/list_name_files/", params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be greater than 0" + +def test_delete_one_file_user_id_required(): + user_id = None + name_file = "abcd" + response = client.request("DELETE", "/delete_one_file/", json ={"user_id": user_id,"name_file": name_file}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_delete_one_file_user_id_is_integer(): + user_id = "aaaa" + name_file = "abcd" + response = client.request("DELETE", "/delete_one_file/", json={"user_id": user_id, "name_file": name_file}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be an integer" + +def test_delete_one_file_user_id_is_greater_0(): + user_id = 0 + name_file = "abcd" + response = client.request("DELETE", "/delete_one_file/", json={"user_id": user_id, "name_file": name_file}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be greater than 0" + +def test_delete_one_file_name_file_required(): + user_id = 1 + name_file = None + response = client.request("DELETE", "/delete_one_file/", json ={"user_id": user_id,"name_file": name_file}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Name file is required." + +def test_download_folder_user_id_required(): + user_id = None + response = client.request("POST", "/chatbot/download_folder/", json ={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_download_folder_user_id_is_integer(): + user_id = "aaaa" + response = client.request("POST", "/chatbot/download_folder/", json={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be an integer" + +def test_download_folder_user_id_is_greater_0(): + user_id = "0" + response = client.request("POST", "/chatbot/download_folder/", json={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be greater than 0" + +def test_download_file_user_id_required(): + user_id = None + response = client.request("POST", "/chatbot/download_files/", json ={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_download_files_user_id_is_integer(): + user_id = "aaaa" + response = client.request("POST", "/chatbot/download_files/", json={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be an integer" + +def test_download_files_user_id_is_greater_0(): + user_id = "0" + response = client.request("POST", "/chatbot/download_files/", json={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be greater than 0" + +def test_upload_file_user_id_required(): + user_id = None + file_content = b"Test file content" + file = UploadFile(filename='test.pdf', file=BytesIO(file_content)) + data = { + 'user_id': user_id + } + files = { + 'files': (file.filename, file.file) + } + response = client.post("/upload_files/", data=data, files=files) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_upload_files_user_id_is_integer(): + user_id = "aaaa" + file_content = b"Test file content" + file = UploadFile(filename='test.pdf', file=BytesIO(file_content)) + data = { + 'user_id': user_id + } + files = { + 'files': (file.filename, file.file) + } + response = client.post("/upload_files/", data=data, files=files) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be an integer" + +def test_upload_files_user_id_is_greater_0(): + user_id = "0" + file_content = b"Test file content" + file = UploadFile(filename='test.pdf', file=BytesIO(file_content)) + data = { + 'user_id': user_id + } + files = { + 'files': (file.filename, file.file) + } + response = client.post("/upload_files/", data=data, files=files) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be greater than 0" \ No newline at end of file diff --git a/tests/test_controller/test_LoginController.py b/tests/test_controller/test_LoginController.py new file mode 100644 index 0000000000000000000000000000000000000000..2f6aaa32fff06ce8d8709e8934a2b4c2b1e85963 --- /dev/null +++ b/tests/test_controller/test_LoginController.py @@ -0,0 +1,1076 @@ +import os +import sys +from unittest.mock import patch, Mock, MagicMock +from fastapi.testclient import TestClient +app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) +sys.path.insert(0, app_path) +from controller import LoginController +client = TestClient(LoginController.router) + +@patch('function.support_function.check_email_empty_invalid') +@patch('service.LoginService.sign_in_with_email_and_password') +@patch('service.LoginService.signJWT') +@patch('service.LoginService.get_user1') +def test_login_success(mock_get_user1,mock_signJWT,mock_sign_in_with_email_and_password,mock_check_email): + mock_check_email.return_value = True + mock_get_user1.return_value = Mock() + mock_sign_in_with_email_and_password.return_value = Mock() + mock_signJWT.return_value = { + "access_token": "fake_access_token", + "refresh_token": "fake_refresh_token", + "expires_in": 3600, + "session_id": "fake_session_id" + } + response = client.post("/login", json={"email": "email1@gmail.com", "password": "old_name"}) + assert response.json()['status'] == 200 + assert response.json() == { + "status": 200, + "data": { + "access_token": "fake_access_token", + "refresh_token": "fake_refresh_token", + "expires_in": 3600, + "session_id": "fake_session_id" + } + } + +def test_login_email_empty(): + response = client.post("/login", json={"email": None, "password": "old_name"}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Email is required.", + } + } + + +def test_login_email_invalid(): + response = client.post("/login", json={"email":"20133", "password": "old_name"}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Email must be a string, not a number.", + } + } + + +def test_login_password_empty(): + response = client.post("/login", json={"email":"20133118@gmail.com", "password": None}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Password is required.", + } + } + +@patch('function.support_function.check_email_empty_invalid') +@patch('service.LoginService.get_user1') +def test_login_email_not_exist(mock_get_user,mock_check_email): + mock_check_email.return_value = True + mock_get_user.return_value = None + response = client.post("/login", json={"email":"20133118@gmail.com", "password": "20133"}) + assert response.json()['status'] == 425 + assert response.json() == { + "status": 425, + "data": { + "message": "Email not exits", + } + } + +@patch('function.support_function.check_email_empty_invalid') +@patch('service.LoginService.get_user1') +@patch('service.LoginService.sign_in_with_email_and_password') +def test_login_email_password_error(mock_sign_in,mock_get_user,mock_check_email): + mock_check_email.return_value = True + mock_get_user.return_value = Mock() + mock_sign_in.return_value = None + response = client.post("/login", json={"email":"20133118@gmail.com", "password": "20133"}) + assert response.json()['status'] == 425 + assert response.json() == { + "status": 425, + "data": { + "message": "Passwords do not match", + } + } +@patch('function.support_function.check_email_empty_invalid') +@patch('service.LoginService.get_user1') +@patch('service.LoginService.sign_in_with_email_and_password') +@patch('service.LoginService.signJWT') +def test_login_invalid_authorization_code(mock_signJWT, mock_sign_in, mock_get_user, mock_check_email): + mock_check_email.return_value = True + mock_get_user.return_value = Mock() + mock_sign_in.return_value = Mock() + mock_signJWT.return_value = False + response = client.post("/login", json={"email":"20133118@gmail.com", "password": "20133"}) + assert response.json()['status'] == 500 + assert response.json() == { + "status": 500, + "data": { + "message": "Invalid authorization code.", + } + } + +@patch('function.support_function.check_email_empty_invalid') +@patch('service.LoginService.sign_in_with_email_and_password') +@patch('service.LoginService.signJWT') +@patch('service.LoginService.get_user1') +@patch('service.LoginService.verify_token_google',return_value=True) +def test_login_google_success(mock_check_gg,mock_get_user1,mock_signJWT,mock_sign_in_with_email_and_password,mock_check_email): + mock_check_email.return_value = True + mock_get_user1.return_value = Mock() + mock_sign_in_with_email_and_password.return_value = Mock() + mock_signJWT.return_value = { + "access_token": "fake_access_token", + "refresh_token": "fake_refresh_token", + "expires_in": 3600, + "session_id": "fake_session_id" + } + response = client.post("/login_google", json={"email": "email1@gmail.com", "token_google": "abcd"}) + assert response.json()['status'] == 200 + assert response.json() == { + "status": 200, + "data": { + "access_token": "fake_access_token", + "refresh_token": "fake_refresh_token", + "expires_in": 3600, + "session_id": "fake_session_id" + } + } + +def test_login_google_email_empty(): + response = client.post("/login_google", json={"email": "", "token_google": "abcd"}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Email is required.", + } + } + +def test_login_google_email_invalid(): + response = client.post("/login_google", json={"email": "12345", "token_google": "abcd"}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Email must be a string, not a number.", + } + } + +@patch('function.support_function.check_email_service') +@patch('function.support_function.check_email_empty_invalid', return_value = True) +@patch('service.LoginService.check_email') +@patch('service.LoginService.get_user1') +@patch('repository.UserInfoRepository.getUserInfo') +@patch('repository.UserInfoRepository.updateUserInfo') +@patch('repository.UserInfoRepository.addUserInfo') +@patch('service.LoginService.update_info_user') +def test_update_user_info_success(mock_update_info_user, mock_add_user_info, mock_update_user_info, mock_get_user_info, mock_get_user, mock_check_email, mock_check1, mock_get_email_by_id): + mock_get_email_by_id.return_value = "old_email@example.com" + mock_get_user.return_value = Mock() # Simulate user exists + mock_get_user_info.return_value = Mock() + response = client.post("/update_user_info", json={"user_id":1, + "email": "new_email@example.com", + "uid":"uid123", + "display_name":"New Name", + "photo_url":"http://photo.url"}) + assert response.json()['status'] == 200 + assert response.json() == { + "status": 200, + "data": { + "message": "User info updated successfully", + } + + } +from response import ResponseLogin as res +@patch('function.support_function.check_email_service') +@patch('function.support_function.check_email_empty_invalid',return_value = True) +@patch('repository.UserRepository.getEmailUserByIdFix') +def test_update_user_info_id_not_exist(mock_get_email_by_id,mock_check1,mock_check2): + mock_check2.return_value = res.ReponseError(status=400, data=res.Message( + message="Id not exist")) + response = client.post("/update_user_info", json={"user_id":1, + "email": "new_email@example.com", + "uid":"uid123", + "display_name":"New Name", + "photo_url":"http://photo.url"}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Id not exist", + } + + } + + +def test_update_user_info_email_empty(): + response = client.post("/update_user_info", json={"user_id":1, + "email": None, + "uid":"uid123", + "display_name":"New Name", + "photo_url":"http://photo.url"}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "email field is required.", + } + } + + +@patch('function.support_function.check_email_service', return_value = "20133118@gmail.com") +@patch('service.LoginService.sf.check_email_empty_invalid') +def test_update_user_info_email_invalid(mock_check,mock_service): + mock_check.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + response = client.post("/update_user_info", json={"user_id":1, + "email": "20133", + "uid":"uid123", + "display_name":"New Name", + "photo_url":"http://photo.url"}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Email invalid", + } + } + +@patch('function.support_function.check_email_service', return_value = "20133118@gmail.com") +@patch('service.LoginService.sf.check_email_empty_invalid') +@patch('service.LoginService.get_user1') +def test_update_user_info_email_or_password_error(mock_get_user, mock_check_email, mock_get_email_by_id): + mock_get_email_by_id.return_value = "old_email@example.com" + mock_check_email.return_value = True + mock_get_user.return_value = None + response = client.post("/update_user_info", json={"user_id":1, + "email": "nhuy@gmail.com", + "uid":"uid123", + "display_name":"New Name", + "photo_url":"http://photo.url"}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Not found user", + } + } +@patch('function.support_function.check_email_service', return_value = "20133118@gmail.com") +@patch('service.LoginService.check_email') +@patch('repository.UserInfoRepository.getUserInfo') +@patch('repository.UserRepository.getEmailUserByIdFix', return_value = "20133118@gmail.com") +def test_check_info_google_success(mock_check,mock_user_info_repo, mock_check_email,mock_user_repo_email): + mock_user_info_repo.return_value = Mock() + user_id = "1" + response = client.get("/check_info_google", params={"user_id": user_id}) + assert response.json()['status'] == 200 + assert response.json() == { + "status": 200, + "data": { + "check": True, + } + } + +@patch('function.support_function.check_email_service', return_value = res.ReponseError(status=400, data=res.Message( + message="Id not exist"))) + +@patch('repository.UserRepository.getEmailUserByIdFix', return_value = "20133118@gmail.com") +def test_check_info_google_id_not_exist(mock_check1,mock_user_repo): + user_id = "1" + response = client.get("/check_info_google", params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Id not exist", + } + } + + +@patch('function.support_function.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty"))) + +@patch('repository.UserRepository.getEmailUserByIdFix', return_value = "20133118@gmail.com") +def test_check_info_google_email_empty(mock_check1,mock_user_repo_id): + user_id = "1" + response = client.get("/check_info_google", params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Email is empty", + } + } + +@patch('function.support_function.check_email_service', return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid"))) + +@patch('repository.UserRepository.getEmailUserByIdFix', return_value = "20133118@gmail.com") +def test_check_info_google_email_invalid(mock_check_1,mock_user_repo): + user_id = "1" + response = client.get("/check_info_google", params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Email invalid", + } + } + + +@patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) +@patch('service.LoginService.UserInfoRepository') +def test_check_info_google_by_email_success(mock_user_info_repo, mock_check_email): + email = "test@gmail.com" + mock_user_info_repo.getUserInfo.return_value = Mock() + response = client.get("/check_info_google_signup", params={"email": email}) + assert response.json()['status'] == 200 + assert response.json() == { + "status": 200, + "data": { + "check": True, + } + } + +def test_check_info_google_signup_email_empty(): + email = "" + response = client.get("/check_info_google_signup", params={"email": None}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Email is required.", + } + } + +def test_check_info_google_signup_email_invalid(): + email ="quangphuc" + response = client.get("/check_info_google_signup", params={"email": email}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Email invalid", + } + } +@patch('service.LoginService.sf.check_email_service') +@patch('service.LoginService.check_email') +@patch('service.LoginService.get_user1') +@patch('repository.UserLoginRepository.getUserSessionIdByUserEmail') +def test_check_state_login_success(mock_user_login_repo,mock_get_user1,mock_check_email,mock_user_repo): + user_id = "1" + email ="test@gmail.com" + session_id = "session" + mock_user_repo.return_value = email + mock_check_email.return_value = True + mock_get_user1.return_value = Mock() + mock_user_login_repo.return_value = session_id + response = client.get("/check_state_login", params={"user_id": user_id,"session_id_now" :session_id}) + assert response.json()['status'] == 200 + assert response.json() == { + "status": 200, + "data": { + "check": True, + } + } + +@patch('service.LoginService.sf.check_email_service') +def test_check_state_login_id_not_exits(mock_user_repo): + user_id = "1" + email ="test@gmail.com" + session_id = "session" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Id not exist")) + response = client.get("/check_state_login", params={"user_id": user_id, + "session_id_now" :session_id}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Id not exist", + } + } + +@patch('service.LoginService.sf.check_email_service') +def test_check_state_login_email_empty(mock_user_repo): + user_id = "1" + email =None + session_id = "session" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + response = client.get("/check_state_login", params={"user_id": user_id, + "session_id_now" :session_id}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Email is empty", + } + } + +@patch('service.LoginService.sf.check_email_service') +@patch('service.LoginService.check_email') +def test_check_state_login_email_invalid(mock_check_email,mock_user_repo): + user_id = "1" + email = "20133118" + session_id = "session" + mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + response = client.get("/check_state_login", params={"user_id": user_id, + "session_id_now" :session_id}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Email invalid", + } + } + +@patch('service.LoginService.sf.check_email_service') +@patch('service.LoginService.check_email') +@patch('repository.UserLoginRepository.getUserSessionIdByUserEmail') +def test_check_state_session_empty(mock_user_login_repo,mock_check_email, mock_user_repo): + user_id = "1" + email = "20133@gmail.com" + session_id = None + + mock_user_repo.return_value = email + mock_user_login_repo.return_value = "some_session_id" + + response = client.get("/check_state_login", params={"user_id": user_id, + "session_id_now": session_id}) + + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Session Id is required.", + } + } + +@patch('service.LoginService.sf.check_email_service') +@patch('service.LoginService.check_email') +@patch('service.LoginService.get_user1') +@patch('repository.UserLoginRepository.getUserSessionIdByUserEmail') +def test_check_state_login_not_found(mock_user_login_repo,mock_get_user1,mock_check_email,mock_user_repo): + user_id = "1" + email ="test@gmail.com" + session_id = "session" + mock_user_repo.return_value = email + mock_check_email.return_value = True + mock_get_user1.return_value = None + mock_user_login_repo.return_value = session_id + response = client.get("/check_state_login", params={"user_id": user_id, + "session_id_now" : session_id}) + assert response.json()['status'] == 500 + assert response.json() == { + "status": 500, + "data": { + "message": "Not found user", + } + } + +@patch('service.LoginService.sign_up_with_email_and_password') +@patch('service.LoginService.get_user1') +@patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) +def test_sign_up_success( mock_check_email, mock_get_user1, mock_sign_up_with_email_and_password): + email="new_user@example.com" + password="securepassword" + username="newuser" + mock_check_email.return_value = True + mock_get_user1.return_value = None # Simulate email does not exist + mock_sign_up_with_email_and_password.return_value = "new_user@example.com" + response = client.post("/sign_up", json={"email": email, + "password" : password, + "username": username}) + assert response.json()['status'] == 200 + assert response.json()['data']['email'] == "new_user@example.com" + +def test_sign_up_email_is_empty(): + email=None + password="securepassword" + username="newuser" + response = client.post("/sign_up", json={"email": email, + "password" : password, + "username": username}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is required." + + +def test_sign_up_email_invadlid(): + email="20133" + password="securepassword" + username="newuser" + response = client.post("/sign_up", json={"email": email, + "password" : password, + "username": username}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email must be a string, not a number." + + +def test_sign_up_password_empty(): + email="20133@gmail.com" + password=None + username="newuser" + response = client.post("/sign_up", json={"email": email, + "password" : password, + "username": username}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Password is required." + +@patch('service.LoginService.get_user1') +@patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) +def test_sign_up_email_exist(mock_check_email,mock_get_user1): + email="20133@gmail.com" + password="password" + username="newuser" + mock_get_user1.return_value = Mock() + response = client.post("/sign_up", json={"email": email, + "password" : password, + "username": username}) + assert response.json()['status'] == 500 + assert response.json()['data']['message'] == "Email exist" + +@patch('service.LoginService.sign_up_with_email_and_password') +@patch('service.LoginService.get_user1') +@patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) +def test_sign_up_error(mock_check_email,mock_get_user1,mock_sign_up_with_email_password): + email="new_user@example.com" + password="securepassword" + username="newuser" + mock_get_user1.return_value = None # Simulate email does not exist + mock_sign_up_with_email_password.return_value = None + response = client.post("/sign_up", json={"email": email, + "password" : password, + "username": username}) + assert response.json()['status'] == 500 + assert response.json()['data']['message'] == "Internal Server Error" + +@patch('service.LoginService.sf.check_email_service',return_value= "test@example.com") +@patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) +@patch('service.LoginService.sign_in_with_email_and_password') +@patch('service.LoginService.auth') +def test_change_password_success(mock_auth, mock_sign_in, mock_check_email, mock_get_email): + user_id='123' + new_password='new_password' + current_password='current_password' + mock_sign_in.return_value = MagicMock() + mock_auth.get_user_by_email.return_value = MagicMock(uid='user_uid') + response = client.put("/change_password", json={"user_id": user_id, + "new_password" : new_password, + "current_password": current_password}) + assert response.json()['status'] == 200 + assert response.json()['data']['message'] == "Update password success" + +@patch('service.LoginService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Id not exist"))) +def test_change_password_id_not_exist(mock_get_email): + user_id='123' + new_password='new_password' + current_password='current_password' + response = client.put("/change_password", json={"user_id": user_id, + "new_password" : new_password, + "current_password": current_password}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Id not exist" + +@patch('service.LoginService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty"))) +def test_change_password_email_is_empty(mock_get_email): + user_id='123' + new_password='new_password' + current_password='current_password' + response = client.put("/change_password", json={"user_id": user_id, + "new_password" : new_password, + "current_password": current_password}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is empty" + +@patch('service.LoginService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid"))) +def test_change_password_email_invalid(mock_check_email): + user_id='123' + new_password='new_password' + current_password='current_password' + response = client.put("/change_password", json={"user_id": user_id, + "new_password" : new_password, + "current_password": current_password}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email invalid" + +@patch('service.LoginService.sf.check_email_service') +def test_change_password_new_password_empty( mock_get_email): + user_id='123' + new_password= None + current_password='current_password' + mock_get_email.return_value = "20133@gmail.com" + response = client.put("/change_password", json={"user_id": user_id, + "new_password" : new_password, + "current_password": current_password}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "New password field is required." + +@patch('service.LoginService.sf.check_email_service') +def test_change_password_current_password_empty(mock_get_email): + user_id='123' + new_password= "new" + current_password= None + mock_get_email.return_value = "20133@gmail.com" + response = client.put("/change_password", json={"user_id": user_id, + "new_password" : new_password, + "current_password": current_password}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Current password field is required." + +@patch('service.LoginService.sf.check_email_service') +@patch('service.LoginService.sign_in_with_email_and_password') +def test_change_password_current_password_not_valid(mock_sign_in, mock_get_email): + user_id='123' + new_password= "new" + current_password= "old" + mock_get_email.return_value = 'test@example.com' + mock_sign_in.return_value = None + response = client.put("/change_password", json={"user_id": user_id, + "new_password" : new_password, + "current_password": current_password}) + assert response.json()['status'] == 500 + assert response.json()['data']['message'] == "Current password not valid" + +@patch('service.LoginService.UserRepository') +@patch('service.LoginService.auth123') +@patch('service.LoginService.sf.check_email_service') +def test_refresh_token_success(mock_check,mock_auth123, mock_UserRepository): + user_id = "1" + token = "valid_token" + mock_UserRepository.getRefreshTokenUserById.return_value = "valid_refresh_token" + mock_check.return_value = "user@example.com" + mock_auth123.get_refresh_token.return_value = { + "access_token": "new_access_token", + "refresh_token": "new_refresh_token", + "expires_in": 3600, + "session_id": "AAAAAA" + } + response = client.post("/refresh_token/", json={"user_id": user_id,"token" : token}) + assert response.json()['status'] == 200 + assert response.json()['data']['token_new'] == "new_access_token" + +@patch('service.LoginService.UserRepository') +@patch('service.LoginService.sf.check_email_service') +def test_refresh_token_user_id_not_exist(mock_check,mock_UserRepository): + user_id = "1" + token = "valid_token" + mock_check.return_value = res.ReponseError(status=400, data=res.Message( + message="Id not exist")) + + mock_UserRepository.getEmailUserByIdFix.return_value = None + response = client.post("/refresh_token/", json={"user_id": user_id,"token" : token}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Id not exist" + +@patch('service.LoginService.UserRepository') +@patch('service.LoginService.sf.check_email_service') +def test_refresh_token_email_empty(mock_check,mock_UserRepository): + user_id = "1" + token = "valid_token" + mock_check.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + mock_UserRepository.getEmailUserByIdFix.return_value = [None] + response = client.post("/refresh_token/", json={"user_id": user_id,"token" : token}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is empty" + +@patch('service.LoginService.UserRepository') +@patch('service.LoginService.check_email') +@patch('service.LoginService.sf.check_email_service') +def test_refresh_token_email_invalid(mock_check,mock_check_email, mock_UserRepository): + user_id = "1" + token = "valid_token" + mock_UserRepository.getEmailUserByIdFix.return_value = ["invalid_email"] + mock_check.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + mock_check_email.return_value = False + response = client.post("/refresh_token/", json={"user_id": user_id,"token" : token}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email invalid" + +@patch('service.LoginService.UserRepository') +@patch('service.LoginService.sf.check_email_service') +def test_refresh_token_token_empty(mock_check,mock_UserRepository): + user_id = "1" + token = "" + mock_UserRepository.getEmailUserByIdFix.return_value = ["user@example.com"] + mock_check.return_value = "user@example.com" + response = client.post("/refresh_token/", json={"user_id": user_id,"token" : token}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "token is required." + +@patch('service.LoginService.UserRepository') +@patch('service.LoginService.auth123') +@patch('service.LoginService.sf.check_email_service') +def test_refresh_token_token_errror(mock_check,mock_auth123, mock_UserRepository): + user_id = "1" + token = "valid_token" + mock_UserRepository.getRefreshTokenUserById.return_value = "valid_refresh_token" + mock_check.return_value = "user@example.com" + mock_auth123.get_refresh_token.return_value = { + "access_token": False, + "refresh_token": False, + "expires_in": 3600, + "session_id":"abcde" + } + response = client.post("/refresh_token/", json={"user_id": user_id,"token" : token}) + assert response.json()['status'] == 406 + assert response.json()['data']['message'] == "Refresh token error" + +@patch('service.LoginService.check_email') +@patch('service.LoginService.get_user1') +@patch('service.LoginService.createOTPReset') +@patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) +def test_reset_password_success(mock_check,mock_createOTPReset, mock_get_user1, mock_check_email): + email = "user@example.com" + mock_get_user1.return_value = {"email": "user@example.com"} + mock_createOTPReset.return_value = "123456" + response = client.post("/reset_password", json={"email": email}) + assert response.json()['status'] == 200 + assert response.json()['data']['check'] == True + assert response.json()['otp'] == "123456" + +def test_reset_password_invalid_email(): + email = "invalid" + response = client.post("/reset_password", json={"email": email}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email invalid" + +def test_reset_password_user_not_found(): + email = "nonexistent@example.com" + response = client.post("/reset_password", json={"email": email}) + assert response.json()['status'] == 500 + assert response.json()['data']['message'] == "Email not exist" + +def test_reset_password_email_is_None(): + email = None + response = client.post("/reset_password", json={"email": email}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is required." + +def test_login_email_required(): + email = None + password = "ABC" + response = client.post("/login", json={"email": email, "password": password}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is required." + +def test_login_email_required_str(): + email = "123" + password = "ABC" + response = client.post("/login", json={"email": email, "password": password}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email must be a string, not a number." + +def test_login_password_required(): + password = None + email = "20133118@gmail.com" + response = client.post("/login", json={"email": email, "password": password}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Password is required." + +def test_login_email_can_not_empty(): + email ="" + password ="12aa" + response = client.post("/login", json={"email": email, "password": password}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is required." + +def test_login_google_email_required(): + email = None + token_google = "abcd" + response = client.post("/login_google", json={"email": email, "token_google": token_google}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is required." + +def test_login_google_token_google_required(): + email = "abc@gmail.com" + token_google = "" + response = client.post("/login_google", json={"email": email,"token_google": token_google}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "token_google oauth2 is required." + +def test_login_google_email_required_str_1(): + email = "123" + token_google = "abcd" + response = client.post("/login_google", json={"email": email, "token_google": token_google}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email must be a string, not a number." + +def test_login_google_email_token_required_str(): + email = "20133118@gmail.com" + token_google = "123456" + response = client.post("/login_google", json={"email": email, "token_google": token_google}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "token_google must be a string, not a number." + +def test_login_google_email_can_not_empty(): + email ="" + token_google = "abcd" + response = client.post("/login_google", json={"email": email, "token_google": token_google}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is required." + +def test_update_user_info_user_id_required(): + email = None + response = client.post("/update_user_info", json={"user_id": None, + "email": "new_email@example.com", + "uid": "uid123", + "display_name": "New Name", + "photo_url": "http://photo.url"}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_update_user_info_user_id_integer_required(): + response = client.post("/update_user_info", json={"user_id": "aaaa", + "email": "new_email@example.com", + "uid": "uid123", + "display_name": "New Name", + "photo_url": "http://photo.url"}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be an integer" + +def test_update_user_info_user_id_greater_than_0(): + response = client.post("/update_user_info", json={"user_id": 0, + "email": "new_email@example.com", + "uid": "uid123", + "display_name": "New Name", + "photo_url": "http://photo.url"}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be greater than 0" + +def test_update_user_info_uid_field_required(): + response = client.post("/update_user_info", json={"user_id": 1, + "email": "new_email@example.com", + "uid": "", + "display_name": "New Name", + "photo_url": "http://photo.url"}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "uid field is required." + +def test_update_user_info_email_field_required(): + response = client.post("/update_user_info", json={"user_id": 1, + "email": None, + "uid": "aaaa", + "display_name": "New Name", + "photo_url": "http://photo.url"}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "email field is required." + +def test_update_user_info_dis_play_name_field_required(): + response = client.post("/update_user_info", json={"user_id": 1, + "email": "test@gmail.com", + "uid": "aaaa", + "display_name": "", + "photo_url": "http://photo.url"}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "display_name field is required." + +def test_update_user_info_photo_url_field_required(): + response = client.post("/update_user_info", json={"user_id": 1, + "email": "test@gmail.com", + "uid": "aaaa", + "display_name": "aaaa", + "photo_url": ""}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "photo_url field is required." + +def test_check_info_google_user_id_required(): + user_id = None + response = client.get("/check_info_google",params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_check_info_google_user_id_must_integer(): + user_id = "aaaa" + response = client.get("/check_info_google",params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be an integer" + +def test_check_info_google_user_id_must_integer_greater_than_0(): + user_id = "0" + response = client.get("/check_info_google",params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be greater than 0" + +def test_check_info_google_sign_up_email_is_required(): + email = None + response = client.get("/check_info_google_signup", params={"email": email}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is required." + +def test_check_info_google_sign_up_email_must_str(): + email = "777" + response = client.get("/check_info_google_signup", params={"email": email}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email must be a string, not a number." + +def test_check_state_login_user_id_required(): + user_id = None + session_id_now = "abcde" + response = client.get("/check_state_login", params={"user_id": user_id,"session_id_now":session_id_now}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_check_state_login_user_id_must_integer(): + user_id = "aaaa" + session_id_now = "abcde" + response = client.get("/check_state_login", params={"user_id": user_id, "session_id_now": session_id_now}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be an integer" + +def test_check_state_login_user_id_must_integer_greater_than_0(): + user_id = "0" + session_id_now = "abcde" + response = client.get("/check_state_login", params={"user_id": user_id, "session_id_now": session_id_now}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be greater than 0" + +def test_check_state_login_session_id_required(): + user_id = 1 + session_id_now = None + response = client.get("/check_state_login", params={"user_id": user_id,"session_id_now":session_id_now}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Session Id is required." + +def test_check_state_login_session_id_must_str(): + user_id = 1 + session_id_now = "134" + response = client.get("/check_state_login", params={"user_id": user_id, "session_id_now": session_id_now}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Session Id must be a string, not a number." + +def test_signup_email_is_required(): + email = None + password = "abcde" + username ="VoY" + response = client.post("/sign_up", json={"email": email, + "password": password, + "username": username}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is required." + +def test_signup_email_must_str(): + email = "20133" + password = None + username = "VoY" + response = client.post("/sign_up", json={"email": email, + "password": password, + "username": username}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email must be a string, not a number." + +def test_signup_password_required(): + email = "20133@gmail.com" + password = None + username = "VoY" + response = client.post("/sign_up", json={"email": email, + "password": password, + "username": username}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Password is required." + +def test_reset_email_required(): + email = None + response = client.post("/reset_password", json={"email": email}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is required." + +def test_reset_email_must_str(): + email = "20133" + response = client.post("/reset_password", json={"email": email }) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email must be a string, not a number." + +def test_change_password_user_id_required(): + user_id = None + new_password = "ABC" + current_password = "abc" + response = client.put("/change_password", json={"user_id": user_id, + "new_password": new_password, + "current_password": current_password}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_change_password_user_id_integer(): + user_id = "aaa" + new_password = "ABC" + current_password = "abc" + response = client.put("/change_password", json={"user_id": user_id, + "new_password": new_password, + "current_password": current_password}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be an integer" + +def test_change_password_user_id_integer_greater_than_0(): + user_id = "0" + new_password = "ABC" + current_password = "abc" + response = client.put("/change_password", json={"user_id": user_id, + "new_password": new_password, + "current_password": current_password}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be greater than 0" + +def test_change_password_new_password_required(): + user_id = "1" + new_password = None + current_password = "abc" + response = client.put("/change_password", json={"user_id": user_id, + "new_password": new_password, + "current_password": current_password}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "New password field is required." + +def test_change_password_current_password_required(): + user_id = "1" + new_password = "abc" + current_password = None + response = client.put("/change_password", json={"user_id": user_id, + "new_password": new_password, + "current_password": current_password}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Current password field is required." + +def test_refresh_token_user_id_required(): + user_id = None + token = "abc" + response = client.post("/refresh_token/", json={"user_id": user_id, "token": token}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_refresh_token_user_id_integer(): + user_id = "aaa" + token = "abc" + response = client.post("/refresh_token/", json={"user_id": user_id, "token": token}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be an integer" + +def test_refresh_token_user_id_integer_greater_than_0(): + user_id = "0" + token = "abc" + response = client.post("/refresh_token/", json={"user_id": user_id, "token": token}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be greater than 0" + +def test_refresh_token_token_must_be_str(): + user_id = "1" + token = "1234" + response = client.post("/refresh_token/", json={"user_id": user_id, "token": token}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "token must be string" + +def test_refresh_token_token_is_required(): + user_id = "1" + token = None + response = client.post("/refresh_token/", json={"user_id": user_id, "token": token}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "token is required." \ No newline at end of file diff --git a/tests/test_controller/test_MySQLController.py b/tests/test_controller/test_MySQLController.py new file mode 100644 index 0000000000000000000000000000000000000000..07f736a576c6a3d4fed748fb82c4ef49a8171c2d --- /dev/null +++ b/tests/test_controller/test_MySQLController.py @@ -0,0 +1,358 @@ +import os +import sys +from unittest.mock import patch + +from fastapi.testclient import TestClient + +app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) +sys.path.insert(0, app_path) +from controller import MySQLController +from entity import Database_Entity +from response import ResponseMySQL as res +client = TestClient(MySQLController.router) + +def test_render_chat_history(): + with patch('repository.UserRepository.getEmailUserByIdFix') as mock_get_email_user_by_id: + mock_get_email_user_by_id.return_value = ("example@example.com",) + with patch('repository.ChatHistoryRepository.getChatHistoryById') as mock_get_chat_history_by_id: + mock_get_chat_history_by_id.return_value = [Database_Entity.ChatHistory(id = 1, + email = "example@example.com", + name_chat = "chat1") ] + response = client.get("/render_chat_history?user_id=1") + assert response.status_code == 200 + assert response.json() == { + "status": 200, + "data": { + "chat": [ + { + "id": 1, + "email": "example@example.com", + "chat_name": "chat1" + } + ] + } + } +@patch('repository.ChatHistoryRepository.getChatHistoryByChatIdAndUserId', return_value = True) +@patch('repository.UserRepository.getEmailUserByIdFix', return_value = "20133118@gmail.com") +def test_load_chat_history(mokc1,mock_check_exist): + with patch('repository.DetailChatRepository.getListDetailChatByChatId') as mock_get_list_detail_chat_by_chat_id: + mock_get_list_detail_chat_by_chat_id.return_value = [Database_Entity.DetailChat(id=1, chat_id=1, + YouMessage="question1", + AiMessage="AImessage1", + data_relevant="abcd", + source_file="/demo1.pdf")] + response = client.get("/load_chat_history?chat_id=1&user_id=1") + assert response.status_code == 200 + assert response.json() == { + "status": 200, + "data": { + "detail_chat": [ + { + "id": 1, + "chat_id": 1, + "question": "question1", + "answer": "AImessage1", + 'data_relevant': 'abcd', + 'source_file': '/demo1.pdf' + } + ] + } + } + +def test_render_chat_empty(): + response = client.get("/render_chat_history") + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "user_id field is required." + } + } + +def test_load_chat_history_empty(): + response = client.get("/load_chat_history?user_id=1") + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Chat id field is required." + } + } + +def test_load_chat_history_empty1(): + response = client.get("/load_chat_history?chat_id=1") + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "user_id field is required." + } + } + +def test_load_chat_history_user_id_must_be_integer(): + response = client.get("/load_chat_history?chat_id=1&user_id='aaaaaa'") + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "user_id must be an integer" + } + } + +def test_load_chat_history_user_id_greater_than0(): + response = client.get("/load_chat_history?chat_id=1&user_id='0'") + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "user_id must be greater than 0" + } + } + +def test_edit_chat_success(): + with patch('service.MySQLService.edit_chat') as mock_edit_chat: + mock_edit_chat.return_value = res.ResponseEditChat(status=200, data=res.Message(message="Edit chat success")) + response = client.put("/edit_chat/", json={"user_id": 1, "name_old": "old_name", "name_new": "new_name"}) + assert response.status_code == 200 + assert response.json() == { + "status": 200, + "data": { + "message": "Edit chat success" + } + } + +@patch('service.MySQLService.edit_chat') +def test_edit_chat_invalid_id(mock_edit_chat): + with patch('repository.UserRepository.getEmailUserByIdFix') as mock_get_email_user_by_id: + mock_get_email_user_by_id.return_value = None + mock_edit_chat.return_value = res.ReponseError(status= 400, data=res.Message(message="Id not exist")) + response = client.put("/edit_chat/", json={"user_id": 1, "name_old": "old_name", "name_new": "new_name"}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Id not exist" + } + } + +@patch('repository.UserRepository.getEmailUserByIdFix') +@patch('service.MySQLService.edit_chat') +def test_edit_chat_email_empty(mock_edit_chat,mock_get_email_user_by_id): + email = "" + mock_get_email_user_by_id.return_value = (email,) + mock_edit_chat.return_value = res.ReponseError(status= 400, data=res.Message(message="Email is empty")) + response = client.put("/edit_chat/", json={"user_id": 1, "name_old": "old_name", "name_new": "new_name"}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Email is empty" + } + } + +@patch('repository.UserRepository.getEmailUserByIdFix') +@patch('service.MySQLService.edit_chat') +def test_edit_chat_email_invalid(mock_edit_chat,mock_get_email_user_by_id): + email = "20133118" + mock_get_email_user_by_id.return_value = (email,) + mock_edit_chat.return_value = res.ReponseError(status= 400, data=res.Message(message="Email invalid")) + response = client.put("/edit_chat/", json={"user_id": 1, "name_old": "old_name", "name_new": "new_name"}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Email invalid" + } + } + +@patch('repository.UserRepository.getEmailUserByIdFix') +@patch('service.MySQLService.edit_chat') +def test_edit_chat_name_old(mock_edit_chat,mock_get_email_user_by_id): + email = "20133118@gmail.com" + mock_get_email_user_by_id.return_value = (email,) + mock_edit_chat.return_value = res.ReponseError(status= 400, data=res.Message(message="Name old is empty")) + response = client.put("/edit_chat/", json={"user_id": 1, "name_old": "", "name_new": "new_name"}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Name old is empty" + } + } + +@patch('repository.UserRepository.getEmailUserByIdFix') +@patch('service.MySQLService.edit_chat') +def test_edit_chat_name_new(mock_edit_chat,mock_get_email_user_by_id): + email = "20133118@gmail.com" + mock_get_email_user_by_id.return_value = (email,) + mock_edit_chat.return_value = res.ReponseError(status= 400, data=res.Message(message="Name new is empty")) + response = client.put("/edit_chat/", json={"user_id": 1, "name_old": "123", "name_new": ""}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Name new is empty" + } + } + +@patch('repository.ChatHistoryRepository.getIdChatHistoryByUserIdAndNameChat') +@patch('repository.UserRepository.getEmailUserByIdFix') +@patch('service.MySQLService.edit_chat') +def test_edit_chat1_error(mock_edit_chat,mock_get_email_user_by_id,mock_get_chat_id): + email = "20133118@gmail.com" + mock_get_email_user_by_id.return_value = (email,) + mock_get_chat_id.return_value = False + mock_edit_chat.return_value = res.ReponseError(status=500,data= res.Message(message="Update chat name error")) + response = client.put("/edit_chat/", json={"user_id": 1, "name_old": "123", "name_new": "1234"}) + assert response.json()['status'] == 500 + assert response.json() == { + "status": 500, + "data": { + "message": "Update chat name error" + } + } + +def test_delete_chat_success(): + with patch('service.MySQLService.delete_chat') as mock_delete_chat: + mock_delete_chat.return_value = res.ResponseDeleteChat(status=200, data=res.Message(message="Delete chat success")) + response = client.request("DELETE", "/delete_chat/", json={"user_id": 1, "chat_name": "chat_name"}) + assert response.status_code == 200 + assert response.json() == { + "status": 200, + "data": { + "message": "Delete chat success" + } + } + +@patch('service.MySQLService.delete_chat') +def test_delete_chat_id_not_exits(mock_delete_chat): + with patch('repository.UserRepository.getEmailUserByIdFix') as mock_get_email_user_by_id: + mock_get_email_user_by_id.return_value = None + mock_delete_chat.return_value = res.ReponseError(status= 400, data=res.Message(message="Id not exist")) + response = client.request("DELETE", "/delete_chat/", json={"user_id": 1, "chat_name": "chat_name"}) + assert response.json()['status']== 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Id not exist" + } + } + +@patch('repository.UserRepository.getEmailUserByIdFix') +@patch('service.MySQLService.delete_chat') +def test_delete_chat_email_empty(mock_delete_chat,mock_get_email_user_by_id): + email = "" + mock_get_email_user_by_id.return_value = (email,) + mock_delete_chat.return_value = res.ResponseDeleteChat(status=400, data=res.Message(message="Email is empty")) + response = client.request("DELETE", "/delete_chat/", json={"user_id": 1, "chat_name": "chat_name"}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Email is empty" + } + } + +@patch('repository.UserRepository.getEmailUserByIdFix') +@patch('service.MySQLService.delete_chat') +def test_delete_chat_email_invalid(mock_delete_chat,mock_get_email_user_by_id): + email = "20133118" + mock_get_email_user_by_id.return_value = (email,) + mock_delete_chat.return_value = res.ReponseError(status= 400, data=res.Message(message="Email invalid")) + response = client.request("DELETE", "/delete_chat/", json={"user_id": 1, "chat_name": "chat_name"}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Email invalid" + } + } + +@patch('repository.UserRepository.getEmailUserByIdFix') +@patch('service.MySQLService.delete_chat') +def test_delete_chat_name_empty(mock_delete_chat,mock_get_email_user_by_id): + email = "20133118@gmail.com" + mock_get_email_user_by_id.return_value = (email,) + mock_delete_chat.return_value = res.ReponseError(status= 400, data=res.Message(message="Chat name is empty")) + response = client.request("DELETE", "/delete_chat/", json={"user_id": 1, "chat_name": ""}) + assert response.json()['status'] == 400 + assert response.json() == { + "status": 400, + "data": { + "message": "Chat name is empty" + } + } + +@patch('repository.UserRepository.getEmailUserByIdFix') +@patch('repository.ChatHistoryRepository.deleteChatHistory') +@patch('service.MySQLService.delete_chat') +def test_delete_chat_name_error_500(mock_delete_chat,mock_chat_history_repo,mock_get_email_user_by_id): + email = "20133118@gmail.com" + mock_get_email_user_by_id.return_value = (email,) + mock_chat_history_repo.return_value = False + mock_delete_chat.return_value = res.ResponseDeleteChat(status=500, data=res.Message(message="Delete chat error")) + response = client.request("DELETE", "/delete_chat/", json={"user_id": 1, "chat_name": "1234"}) + assert response.json()['status'] == 500 + assert response.json() == { + "status": 500, + "data": { + "message": "Delete chat error" + } + } + +def test_render_chat_user_id_required(): + user_id = None + response = client.get("/render_chat_history",params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_render_chat_value_mustbe_interger(): + user_id = "aaaa" + response = client.get("/render_chat_history",params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be an integer" + +def test_render_chat_user_id_greater_than_inter(): + user_id = "0" + response = client.get("/render_chat_history",params={"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be greater than 0" + +def test_load_chat_history_chat_id_is_required(): + chat_id = None + response = client.get("/load_chat_history", params={"chat_id": chat_id,"user_id":"1"}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Chat id field is required." + +def test_load_chat_history_chat_id_greater_than_inter(): + chat_id = "0" + response = client.get("/load_chat_history", params={"chat_id": chat_id,"user_id":"1"}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Value must be greater than 0" + +def test_load_chat_history_value_mustbe_inter(): + chat_id = "aaaa" + response = client.get("/load_chat_history", params={"chat_id": chat_id,"user_id":"1"}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Value must be an integer" + +def test_load_chat_history_user_id_is_required(): + chat_id = "1" + user_id = None + response = client.get("/load_chat_history", params={"chat_id": chat_id,"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id field is required." + +def test_load_chat_history_user_id_greater_than_inter(): + chat_id = "1" + user_id = 0 + response = client.get("/load_chat_history", params={"chat_id": chat_id,"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be greater than 0" + +def test_load_chat_history_user_id_mustbe_inter(): + chat_id = "1" + user_id = "aaaaa" + response = client.get("/load_chat_history", params={"chat_id": chat_id,"user_id": user_id}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "user_id must be an integer" diff --git a/tests/test_controller/test_OTPController.py b/tests/test_controller/test_OTPController.py new file mode 100644 index 0000000000000000000000000000000000000000..b9602c931bb1a8e5cf0bc860794d164b105f9d7b --- /dev/null +++ b/tests/test_controller/test_OTPController.py @@ -0,0 +1,292 @@ +import os +import sys +from unittest.mock import patch, MagicMock + +from fastapi.testclient import TestClient + +app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) +sys.path.insert(0, app_path) +from controller import OTPController +client = TestClient(OTPController.router) + +@patch('service.OTPService.check_email') +@patch('service.OTPService.get_user1') +@patch('repository.OTPRepository.addOTP') +@patch('service.OTPService.generate_otp') +@patch('service.OTPService.sf') +def test_createOTPReset_success(mock_support_function, mock_generate_otp,mock_addOTP, mock_get_user1, mock_check_email): + mock_get_user1.return_value = MagicMock() + email = "user@example.com" + mock_support_function.check_email_empty_invalid.return_value = True + mock_generate_otp.return_value = "123456" + response = client.post("/create_otp", json={"email": email}) + assert response.json()['status'] == 200 + assert response.json()['data']['check'] == True + assert response.json()['otp'] == "123456" + + +def test_createOTPReset_email_empty(): + email = "" + response = client.post("/create_otp", json={"email": email}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is required." + + +def test_createOTPReset_email_invalid(): + email = "201333" + response =client.post("/create_otp", json={"email": email}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email must be a string, not a number." + +@patch('service.OTPService.generate_otp') +@patch('service.OTPService.check_email') +@patch('repository.OTPRepository.addOTP') +@patch('service.OTPService.sf') +def test_createOTP_success(mock_support_function,mock_addOTP, mock_check_email, mock_generate_otp): + mock_generate_otp.return_value = "123AB6" + email = "20133118@gmail.com" + otp = "123AB6" + mock_support_function.check_email_empty_invalid.return_value = True + mock_addOTP(email,otp) + response =client.post("/create_otp", json={"email": email}) + assert response.json()['status'] == 200 + assert response.json()['data']['check'] == True + assert response.json()['otp'] == "123AB6" + +def test_createOTP_failed_empty_email(): + email = "" + response =client.post("/create_otp", json={"email": email}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is required." + + +def test_createOTP_failed_empty_invalid(): + email = "20133" + response =client.post("/create_otp", json={"email": email}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email must be a string, not a number." +from datetime import datetime,timedelta +@patch('service.OTPService.sf.check_email_empty_invalid', return_value=True) +@patch('repository.OTPRepository.getOtpByEmail') +@patch('repository.OTPRepository.deleteOTP') +def test_verifyOTP_success(mock_deleteOTP, mock_getOtpByEmail, mock_check_email): + current_time = datetime.now() + mock_getOtpByEmail.return_value = MagicMock(otp="abcdef", created_at=current_time - timedelta(minutes=5)) + email = "user@example.com" + otp = "abcdef" + response = client.post("/verify_otp", json={"email": email,"otp": otp}) + mock_deleteOTP(email,otp) + assert response.json()['status'] == 200 + assert response.json()['data']['message'] == "OTP is valid" + +@patch('service.OTPService.sf.check_email_empty_invalid', return_value=True) +@patch('repository.OTPRepository.getOtpByEmail') +def test_verifyOTP_failed_invalid_otp(mock_getOtpByEmail, mock_check_email): + current_time = datetime.now() + mock_getOtpByEmail.return_value = MagicMock(otp="654321", created_at=current_time - timedelta(minutes=5)) + email = "user@example.com" + otp = "123456" + response =client.post("/verify_otp", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "OTP must be a string, not a number." + +def test_verifyOTP_failed_invalid_email(): + email = "invalidemail" + otp = "123456" + response =client.post("/verify_otp", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "OTP must be a string, not a number." + +def test_verifyOTP_failed_empty_email(): + email = None + otp = "123456" + response =client.post("/verify_otp", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is required." + + +def test_verifyOTP_failed_empty_otp(): + email = "user@example.com" + otp = None + response = client.post("/verify_otp", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "OTP is required" + +@patch('service.OTPService.sf.check_email_empty_invalid', return_value=True) +@patch('repository.OTPRepository.getOtpByEmail') +def test_verifyOTP_failed_no_otp_found(mock_getOtpByEmail, mock_check_email): + mock_getOtpByEmail.return_value = None + email = "user@example.com" + otp = "1234ab" + response =client.post("/verify_otp", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "No OTP found for this email" + +@patch('service.OTPService.sf.check_email_empty_invalid', return_value=True) +@patch('repository.OTPRepository.getOtpByEmail') +def test_verifyOTP_has_expired( mock_getOtpByEmail, mock_check_email): + current_time = datetime.now() + mock_getOtpByEmail.return_value = MagicMock(otp="1234ab", created_at=current_time - timedelta(minutes=100)) + email = "user@example.com" + otp = "1234ab" + response =client.post("/verify_otp", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "OTP has expired" + +@patch('service.OTPService.sf.check_email_empty_invalid', return_value=True) +@patch('repository.OTPRepository.getOtpByEmail') +@patch('repository.OTPRepository.deleteOTP') +@patch('service.OTPService.auth.get_user_by_email') +@patch('service.OTPService.auth') +@patch('service.OTPService.generate_random_password') +def test_verifyOTPReset1_success( mock_generate_password,mock_update_user, mock_get_user_by_email, mock_deleteOTP, mock_getOtpByEmail, mock_check_email): + current_time = datetime.now() + mock_getOtpByEmail.return_value = MagicMock(otp="abcd12", created_at=current_time - timedelta(minutes=5)) + mock_get_user_by_email.return_value = MagicMock(uid="12345") + email = "user@example.com" + otp = "abcd12" + mock_generate_password.return_value = "ABC123" + mock_update_user.update_user(uid="12345",) + mock_deleteOTP("user@example.com", "abcd12") + response = client.post("/verify_otp_reset_password", json={"email": email,"otp": otp}) + assert response.json()['status'] == 200 + assert response.json()['data']['message'] == "New Password send to Email" + assert response.json()['newpassword'] == "ABC123" + +@patch('service.OTPService.sf.check_email_empty_invalid', return_value=True) +@patch('repository.OTPRepository.getOtpByEmail') +def test_verifyOTPReset_failed_invalid_otp(mock_getOtpByEmail, mock_check_email): + current_time = datetime.now() + mock_getOtpByEmail.return_value = MagicMock(otp="654321", created_at=current_time - timedelta(minutes=5)) + email = "user@example.com" + otp = "abcd12" + response =client.post("/verify_otp_reset_password", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Invalid OTP" + +@patch('service.OTPService.sf.check_email_empty_invalid', return_value=True) +@patch('repository.OTPRepository.getOtpByEmail') +def test_verifyOTPReset_failed_no_otp_found(mock_getOtpByEmail, mock_check_email): + mock_getOtpByEmail.return_value = None + email = "user@example.com" + otp = "abcd12" + response = client.post("/verify_otp_reset_password", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "No OTP found for this email" + +@patch('service.OTPService.sf.check_email_empty_invalid', return_value=True) +@patch('repository.OTPRepository.getOtpByEmail') +def test_verifyOTPReset_has_expired(mock_getOtpByEmail, mock_check_email): + current_time = datetime.now() + mock_getOtpByEmail.return_value = MagicMock(otp="1234ab", created_at=current_time - timedelta(minutes=100)) + email = "vonhuy@gmail.com" + otp = "1234ab" + response = client.post("/verify_otp_reset_password", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "OTP has expired" + +def test_verifyOTPReset_failed_invalid_email(): + email = "invalidemail" + otp = "abcd12" + response =client.post("/verify_otp_reset_password", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email invalid" + + +def test_verifyOTPReset_failed_empty_email(): + email = None + otp = "123456" + response =client.post("/verify_otp_reset_password", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is required." + + +def test_verifyOTPReset_failed_empty_otp(): + email = "user@example.com" + otp = None + response = client.post("/verify_otp_reset_password", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "OTP is required" + + +def test_createOTP_email_required(): + email = None + response = client.post("/create_otp", json={"email": email}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is required." + +def test_createOTP_email_must_be_string(): + email = "20133" + response = client.post("/create_otp", json={"email": email}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email must be a string, not a number." + +def test_verifyOTP_email_is_required(): + email = None + otp ="123abc" + response = client.post("/verify_otp", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is required." + +def test_verifyOTP_otp_is_required(): + email = "test@gmail.com" + otp = None + response = client.post("/verify_otp", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "OTP is required" + +def test_verifyOTP_otp_email_must_be_string(): + email = "20133" + otp = "123abc" + response = client.post("/verify_otp", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email must be a string, not a number." + +def test_verifyOTP_otp_must_be_string(): + email = "20133@gmail.com" + otp = "123456" + response = client.post("/verify_otp", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "OTP must be a string, not a number." + +def test_verifyOTP_otp_max_length(): + email = "20133@gmail.com" + otp = "abcdef1" + response = client.post("/verify_otp", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "OTP max length is 6" + +def test_verifyOTPReset_email_is_required(): + email = None + otp ="123abc" + response = client.post("/verify_otp_reset_password", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email is required." + +def test_verifyOTPReset_otp_is_required(): + email = "test@gmail.com" + otp = None + response = client.post("/verify_otp_reset_password", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "OTP is required" + +def test_verifyOTPReset_otp_email_must_be_string(): + email = "20133" + otp = "123abc" + response = client.post("/verify_otp_reset_password", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "Email must be a string, not a number." + +def test_verifyOTPReset_otp_must_be_string(): + email = "20133@gmail.com" + otp = "123456" + response = client.post("/verify_otp_reset_password", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "OTP must be a string, not a number." + +def test_verifyOTPReset_otp_max_length(): + email = "20133@gmail.com" + otp = "abcdef1" + response = client.post("/verify_otp_reset_password", json={"email": email,"otp": otp}) + assert response.json()['status'] == 400 + assert response.json()['data']['message'] == "OTP max length is 6" \ No newline at end of file diff --git a/tests/test_controller/user_file/quangphuc@gmail.com/demo1.pdf b/tests/test_controller/user_file/quangphuc@gmail.com/demo1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..43597a9147dba9bf9befd7886997e1ceb1413702 --- /dev/null +++ b/tests/test_controller/user_file/quangphuc@gmail.com/demo1.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:367daadbb1bb652bda103a21a632b36a2821348931c3c11b37fa315c9843af4a +size 7289174 diff --git a/tests/test_service/.pytest_cache/.gitignore b/tests/test_service/.pytest_cache/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..08a7f458f1f002823bc794c47ca1996a57e72c86 --- /dev/null +++ b/tests/test_service/.pytest_cache/.gitignore @@ -0,0 +1,2 @@ +# Created by pytest automatically. +* diff --git a/tests/test_service/.pytest_cache/CACHEDIR.TAG b/tests/test_service/.pytest_cache/CACHEDIR.TAG new file mode 100644 index 0000000000000000000000000000000000000000..fce15ad7eaa74e5682b644c84efb75334c112f95 --- /dev/null +++ b/tests/test_service/.pytest_cache/CACHEDIR.TAG @@ -0,0 +1,4 @@ +Signature: 8a477f597d28d172789f06886806bc55 +# This file is a cache directory tag created by pytest. +# For information about cache directory tags, see: +# https://bford.info/cachedir/spec.html diff --git a/tests/test_service/.pytest_cache/README.md b/tests/test_service/.pytest_cache/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c7526af2448672de4537dfed042ed74daadb17bf --- /dev/null +++ b/tests/test_service/.pytest_cache/README.md @@ -0,0 +1,8 @@ +# pytest cache directory # + +This directory contains data from the pytest's cache plugin, +which provides the `--lf` and `--ff` options, as well as the `cache` fixture. + +**Do not** commit this to version control. + +See [the docs](https://docs.pytest.org/en/stable/how-to/cache.html) for more information. diff --git a/tests/test_service/.pytest_cache/v/cache/lastfailed b/tests/test_service/.pytest_cache/v/cache/lastfailed new file mode 100644 index 0000000000000000000000000000000000000000..9e26dfeeb6e641a33dae4961196235bdb965b21b --- /dev/null +++ b/tests/test_service/.pytest_cache/v/cache/lastfailed @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/test_service/.pytest_cache/v/cache/nodeids b/tests/test_service/.pytest_cache/v/cache/nodeids new file mode 100644 index 0000000000000000000000000000000000000000..b6dd0f4b235e9ec0cf9bee7b01bc4ba3d9e49f88 --- /dev/null +++ b/tests/test_service/.pytest_cache/v/cache/nodeids @@ -0,0 +1,206 @@ +[ + "test_ChatService.py::TestDeleteChat::test_delete_chat_chat_name_empty", + "test_ChatService.py::TestDeleteChat::test_delete_chat_failed", + "test_ChatService.py::TestDeleteChat::test_delete_chat_id_not_exist", + "test_ChatService.py::TestDeleteChat::test_delete_chat_server_err", + "test_ChatService.py::TestDeleteChat::test_delete_chat_success", + "test_ChatService.py::TestExtractFile::test_extract_file_email_empty", + "test_ChatService.py::TestExtractFile::test_extract_file_email_in_valid", + "test_ChatService.py::TestExtractFile::test_extract_file_id_not_exist", + "test_ChatService.py::TestExtractFile::test_extract_file_no_data", + "test_ChatService.py::TestExtractFile::test_extract_file_server_error_sf", + "test_ChatService.py::TestExtractFile::test_extract_file_server_user_repo", + "test_ChatService.py::TestExtractFile::test_extract_file_success", + "test_ChatService.py::TestGenerateQuestion::test_generate_question_email_empty", + "test_ChatService.py::TestGenerateQuestion::test_generate_question_email_in_valid", + "test_ChatService.py::TestGenerateQuestion::test_generate_question_id_not_exist", + "test_ChatService.py::TestGenerateQuestion::test_generate_question_no_data", + "test_ChatService.py::TestGenerateQuestion::test_generate_question_server_err_sf", + "test_ChatService.py::TestGenerateQuestion::test_generate_question_server_err_user_repo", + "test_ChatService.py::TestGenerateQuestion::test_generate_question_success", + "test_ChatService.py::TestQuery2Upgrade::test_query2_upgrade_chat_history_empty", + "test_ChatService.py::TestQuery2Upgrade::test_query2_upgrade_email_empty", + "test_ChatService.py::TestQuery2Upgrade::test_query2_upgrade_id_not_exist", + "test_ChatService.py::TestQuery2Upgrade::test_query2_upgrade_no_answer", + "test_ChatService.py::TestQuery2Upgrade::test_query2_upgrade_question_empty", + "test_ChatService.py::TestQuery2Upgrade::test_query2_upgrade_server_error_function_chatbot_err", + "test_ChatService.py::TestQuery2Upgrade::test_query2_upgrade_server_error_user_repo_err", + "test_ChatService.py::TestQuery2Upgrade::test_query2_upgrade_success", + "test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_chat_empty", + "test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_email_empty", + "test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_email_in_valid", + "test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_id_not_exist", + "test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_no_answer", + "test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_question_empty", + "test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_server_error_chathistory_repo", + "test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_server_error_detailchat_repo", + "test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_server_error_function_repo", + "test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_server_error_user_repo", + "test_ChatService.py::TestQuery2UpgradeOld::test_query2_upgrade_old_success", + "test_DefaultService.py::TestCreateFireBaseUser::test_email_none", + "test_DefaultService.py::TestCreateFireBaseUser::test_existing_user", + "test_DefaultService.py::TestCreateFireBaseUser::test_invalid_email", + "test_DefaultService.py::TestCreateFireBaseUser::test_non_existing_user", + "test_DefaultService.py::TestCreateFireBaseUser::test_server_error", + "test_DefaultService.py::TestInfoUser::test_email_is_none", + "test_DefaultService.py::TestInfoUser::test_id_not_exist", + "test_DefaultService.py::TestInfoUser::test_invalid_email", + "test_DefaultService.py::TestInfoUser::test_server_error", + "test_DefaultService.py::TestInfoUser::test_successful_user_retrieval", + "test_DefaultService.py::TestInfoUser::test_user_not_found", + "test_DefaultService.py::TestIsMe::test_invalid_token", + "test_DefaultService.py::TestIsMe::test_none_token", + "test_DefaultService.py::TestIsMe::test_server_error", + "test_DefaultService.py::TestIsMe::test_valid_token", + "test_DefaultService.py::TestUpLoadFile::test_upload_image_email_empty", + "test_DefaultService.py::TestUpLoadFile::test_upload_image_email_invalid", + "test_DefaultService.py::TestUpLoadFile::test_upload_image_id_not_exist", + "test_DefaultService.py::TestUpLoadFile::test_upload_image_invalid_filetype", + "test_DefaultService.py::TestUpLoadFile::test_upload_image_server_err", + "test_DefaultService.py::TestUpLoadFile::test_upload_image_success", + "test_FileService.py::TestDeleteAllFile::test_delete_all_file_email_empty", + "test_FileService.py::TestDeleteAllFile::test_delete_all_file_email_invalid", + "test_FileService.py::TestDeleteAllFile::test_delete_all_file_id_not_exist", + "test_FileService.py::TestDeleteAllFile::test_delete_all_file_server_err", + "test_FileService.py::TestDeleteAllFile::test_delete_all_file_success", + "test_FileService.py::TestDeleteFile::test_delete_file_email_empty", + "test_FileService.py::TestDeleteFile::test_delete_file_email_invalid", + "test_FileService.py::TestDeleteFile::test_delete_file_id_not_exist", + "test_FileService.py::TestDeleteFile::test_delete_file_namefile_empty", + "test_FileService.py::TestDeleteFile::test_delete_file_server_error", + "test_FileService.py::TestDeleteFile::test_delete_file_success", + "test_FileService.py::TestDownLoadFile::test_download_file_email_empty", + "test_FileService.py::TestDownLoadFile::test_download_file_email_invalid", + "test_FileService.py::TestDownLoadFile::test_download_file_id_not_exist", + "test_FileService.py::TestDownLoadFile::test_download_file_name_file_empty", + "test_FileService.py::TestDownLoadFile::test_download_file_server_error", + "test_FileService.py::TestDownLoadFile::test_download_file_success", + "test_FileService.py::TestDownLoadFolder::test_download_folder_email_empty", + "test_FileService.py::TestDownLoadFolder::test_download_folder_email_invalid", + "test_FileService.py::TestDownLoadFolder::test_download_folder_id_not_exist", + "test_FileService.py::TestDownLoadFolder::test_download_folder_server_error", + "test_FileService.py::TestDownLoadFolder::test_download_folder_success", + "test_FileService.py::TestFileService::test_upload_files_empty_email", + "test_FileService.py::TestFileService::test_upload_files_error_handling", + "test_FileService.py::TestFileService::test_upload_files_id_not_exist", + "test_FileService.py::TestFileService::test_upload_files_invalid_email", + "test_FileService.py::TestFileService::test_upload_files_invalid_file_type", + "test_FileService.py::TestFileService::test_upload_files_success", + "test_FileService.py::TestListNameFiles::test_listNameFiles_server_error", + "test_FileService.py::TestListNameFiles::test_list_name_file_success", + "test_FileService.py::TestListNameFiles::test_list_name_files_email_empty", + "test_FileService.py::TestListNameFiles::test_list_name_files_email_invalid", + "test_FileService.py::TestListNameFiles::test_list_name_files_id_not_exist", + "test_FileService.py::TestUploadFileService::test_upload_files_empty_email", + "test_FileService.py::TestUploadFileService::test_upload_files_error_handling", + "test_FileService.py::TestUploadFileService::test_upload_files_id_not_exist", + "test_FileService.py::TestUploadFileService::test_upload_files_invalid_email", + "test_FileService.py::TestUploadFileService::test_upload_files_invalid_file_type", + "test_FileService.py::TestUploadFileService::test_upload_files_success", + "test_LoginService.py::TestChangePassword::test_change_password_current_password_empty", + "test_LoginService.py::TestChangePassword::test_change_password_current_password_not_valid", + "test_LoginService.py::TestChangePassword::test_change_password_email_invalid", + "test_LoginService.py::TestChangePassword::test_change_password_email_is_empty", + "test_LoginService.py::TestChangePassword::test_change_password_id_not_exist", + "test_LoginService.py::TestChangePassword::test_change_password_new_password_empty", + "test_LoginService.py::TestChangePassword::test_change_password_server_error", + "test_LoginService.py::TestChangePassword::test_change_password_success", + "test_LoginService.py::TestCheckInfoGoogle::test_check_info_google_email_empty", + "test_LoginService.py::TestCheckInfoGoogle::test_check_info_google_email_invalid", + "test_LoginService.py::TestCheckInfoGoogle::test_check_info_google_id_not_exist", + "test_LoginService.py::TestCheckInfoGoogle::test_check_info_google_server_error", + "test_LoginService.py::TestCheckInfoGoogle::test_check_info_google_success", + "test_LoginService.py::TestCheckInfoGoogleEmail::test_check_info_google_by_email_email_empty", + "test_LoginService.py::TestCheckInfoGoogleEmail::test_check_info_google_email_invalid", + "test_LoginService.py::TestCheckInfoGoogleEmail::test_check_info_google_email_server_error", + "test_LoginService.py::TestCheckInfoGoogleEmail::test_check_info_google_email_success", + "test_LoginService.py::TestCheckStateLogin::test_check_state_login_email_empty", + "test_LoginService.py::TestCheckStateLogin::test_check_state_login_email_invalid", + "test_LoginService.py::TestCheckStateLogin::test_check_state_login_id_not_exits", + "test_LoginService.py::TestCheckStateLogin::test_check_state_login_not_found", + "test_LoginService.py::TestCheckStateLogin::test_check_state_login_server_error", + "test_LoginService.py::TestCheckStateLogin::test_check_state_login_success", + "test_LoginService.py::TestCheckStateLogin::test_check_state_session_empty", + "test_LoginService.py::TestLoginFunction::test_login_email_empty", + "test_LoginService.py::TestLoginFunction::test_login_email_invalid", + "test_LoginService.py::TestLoginFunction::test_login_email_not_exists", + "test_LoginService.py::TestLoginFunction::test_login_email_or_password_error", + "test_LoginService.py::TestLoginFunction::test_login_invalid_authorization_code", + "test_LoginService.py::TestLoginFunction::test_login_password_empty", + "test_LoginService.py::TestLoginFunction::test_login_server_error", + "test_LoginService.py::TestLoginFunction::test_login_success", + "test_LoginService.py::TestLoginGoogle::test_login_email_invalid", + "test_LoginService.py::TestLoginGoogle::test_login_google_email_empty", + "test_LoginService.py::TestLoginGoogle::test_login_google_email_not_exists", + "test_LoginService.py::TestLoginGoogle::test_login_google_server_error", + "test_LoginService.py::TestLoginGoogle::test_login_google_success", + "test_LoginService.py::TestLoginGoogle::test_login_invalid_authorization_code", + "test_LoginService.py::TestRefreshToken::test_refresh_token_email_empty", + "test_LoginService.py::TestRefreshToken::test_refresh_token_email_invalid", + "test_LoginService.py::TestRefreshToken::test_refresh_token_refresh_token_error", + "test_LoginService.py::TestRefreshToken::test_refresh_token_server_error", + "test_LoginService.py::TestRefreshToken::test_refresh_token_success", + "test_LoginService.py::TestRefreshToken::test_refresh_token_token_empty", + "test_LoginService.py::TestRefreshToken::test_refresh_token_user_id_not_exist", + "test_LoginService.py::TestResetPassword::test_reset_password_invalid_email", + "test_LoginService.py::TestResetPassword::test_reset_password_server_error", + "test_LoginService.py::TestResetPassword::test_reset_password_success", + "test_LoginService.py::TestResetPassword::test_reset_password_user_not_found", + "test_LoginService.py::TestSignUpFunction::test_sign_up_email_exist", + "test_LoginService.py::TestSignUpFunction::test_sign_up_email_invalid", + "test_LoginService.py::TestSignUpFunction::test_sign_up_email_is_empty", + "test_LoginService.py::TestSignUpFunction::test_sign_up_error", + "test_LoginService.py::TestSignUpFunction::test_sign_up_password_empty", + "test_LoginService.py::TestSignUpFunction::test_sign_up_server_error", + "test_LoginService.py::TestSignUpFunction::test_sign_up_success", + "test_LoginService.py::TestUpdateUserInfoFunction::test_update_user_info_email_empty", + "test_LoginService.py::TestUpdateUserInfoFunction::test_update_user_info_email_invalid", + "test_LoginService.py::TestUpdateUserInfoFunction::test_update_user_info_email_or_password_error", + "test_LoginService.py::TestUpdateUserInfoFunction::test_update_user_info_id_not_exist", + "test_LoginService.py::TestUpdateUserInfoFunction::test_update_user_info_server_error", + "test_LoginService.py::TestUpdateUserInfoFunction::test_update_user_info_success_existing_user", + "test_LoginService.py::TestUpdateUserInfoFunction::test_update_user_info_success_new_user_info", + "test_MySQLService.py::TestDeleteChat::test_delete_chat_chatname_empty", + "test_MySQLService.py::TestDeleteChat::test_delete_chat_email_empty", + "test_MySQLService.py::TestDeleteChat::test_delete_chat_email_invalid", + "test_MySQLService.py::TestDeleteChat::test_delete_chat_error_1", + "test_MySQLService.py::TestDeleteChat::test_delete_chat_id_not_exist", + "test_MySQLService.py::TestDeleteChat::test_delete_chat_server_error", + "test_MySQLService.py::TestDeleteChat::test_delete_chat_success", + "test_MySQLService.py::TestLoadChatHistory::test_load_chat_history_error", + "test_MySQLService.py::TestLoadChatHistory::test_load_chat_history_not_found_chat", + "test_MySQLService.py::TestLoadChatHistory::test_load_chat_history_server_err", + "test_MySQLService.py::TestLoadChatHistory::test_load_chat_history_success", + "test_MySQLService.py::TestLoadChatHistory::test_load_chat_history_user_id_str", + "test_MySQLService.py::TestMySQLService::test_edit_chat_email_empty", + "test_MySQLService.py::TestMySQLService::test_edit_chat_email_in_valid", + "test_MySQLService.py::TestMySQLService::test_edit_chat_id_not_exist", + "test_MySQLService.py::TestMySQLService::test_edit_chat_name_new_empty", + "test_MySQLService.py::TestMySQLService::test_edit_chat_name_old_empty", + "test_MySQLService.py::TestMySQLService::test_edit_chat_server_error", + "test_MySQLService.py::TestMySQLService::test_edit_chat_success", + "test_MySQLService.py::TestMySQLService::test_edit_chat_update_error", + "test_MySQLService.py::TestRenderChatHistory::test_render_chat_history_id_not_exist", + "test_MySQLService.py::TestRenderChatHistory::test_render_chat_history_server_err", + "test_MySQLService.py::TestRenderChatHistory::test_render_chat_history_success", + "test_OTPService.py::TestCreateOTPFunctions::test_createOTP_failed_empty_email", + "test_OTPService.py::TestCreateOTPFunctions::test_createOTP_failed_empty_invalid", + "test_OTPService.py::TestCreateOTPFunctions::test_createOTP_success", + "test_OTPService.py::TestCreateOTPReset::test_createOTPReset_email_empty", + "test_OTPService.py::TestCreateOTPReset::test_createOTPReset_email_invalid", + "test_OTPService.py::TestCreateOTPReset::test_createOTPReset_success", + "test_OTPService.py::TestVerifyOTPFunctions::test_verifyOTP_failed_empty_email", + "test_OTPService.py::TestVerifyOTPFunctions::test_verifyOTP_failed_empty_otp", + "test_OTPService.py::TestVerifyOTPFunctions::test_verifyOTP_failed_invalid_email", + "test_OTPService.py::TestVerifyOTPFunctions::test_verifyOTP_failed_invalid_otp", + "test_OTPService.py::TestVerifyOTPFunctions::test_verifyOTP_failed_no_otp_found", + "test_OTPService.py::TestVerifyOTPFunctions::test_verifyOTP_has_expired", + "test_OTPService.py::TestVerifyOTPFunctions::test_verifyOTP_success", + "test_OTPService.py::TestVerifyOTPReset::test_verifyOTPReset_failed_empty_email", + "test_OTPService.py::TestVerifyOTPReset::test_verifyOTPReset_failed_empty_otp", + "test_OTPService.py::TestVerifyOTPReset::test_verifyOTPReset_failed_invalid_email", + "test_OTPService.py::TestVerifyOTPReset::test_verifyOTPReset_failed_invalid_otp", + "test_OTPService.py::TestVerifyOTPReset::test_verifyOTPReset_failed_no_otp_found", + "test_OTPService.py::TestVerifyOTPReset::test_verifyOTPReset_has_expired", + "test_OTPService.py::TestVerifyOTPReset::test_verifyOTPReset_success" +] \ No newline at end of file diff --git a/tests/test_service/.pytest_cache/v/cache/stepwise b/tests/test_service/.pytest_cache/v/cache/stepwise new file mode 100644 index 0000000000000000000000000000000000000000..0637a088a01e8ddab3bf3fa98dbe804cbde1a0dc --- /dev/null +++ b/tests/test_service/.pytest_cache/v/cache/stepwise @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/tests/test_service/__pycache__/test_ChatService.cpython-310-pytest-8.2.2.pyc b/tests/test_service/__pycache__/test_ChatService.cpython-310-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2de5e80307e162dce4a38bc66b0623821e39fbf8 Binary files /dev/null and b/tests/test_service/__pycache__/test_ChatService.cpython-310-pytest-8.2.2.pyc differ diff --git a/tests/test_service/__pycache__/test_ChatService.cpython-311-pytest-8.2.2.pyc b/tests/test_service/__pycache__/test_ChatService.cpython-311-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9419c73374b37babdfe6f7edb53ed06733eb1858 Binary files /dev/null and b/tests/test_service/__pycache__/test_ChatService.cpython-311-pytest-8.2.2.pyc differ diff --git a/tests/test_service/__pycache__/test_DefaultService.cpython-310-pytest-8.2.2.pyc b/tests/test_service/__pycache__/test_DefaultService.cpython-310-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..adb4e5e25cffd287ce136b909e825824637b7def Binary files /dev/null and b/tests/test_service/__pycache__/test_DefaultService.cpython-310-pytest-8.2.2.pyc differ diff --git a/tests/test_service/__pycache__/test_DefaultService.cpython-311-pytest-8.2.2.pyc b/tests/test_service/__pycache__/test_DefaultService.cpython-311-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ac55abc3a8f13a772e982e810ece1d6ce3bc75f7 Binary files /dev/null and b/tests/test_service/__pycache__/test_DefaultService.cpython-311-pytest-8.2.2.pyc differ diff --git a/tests/test_service/__pycache__/test_FileService.cpython-310-pytest-8.2.2.pyc b/tests/test_service/__pycache__/test_FileService.cpython-310-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6273927b39e7cf2be1527fa798659a75239414b1 Binary files /dev/null and b/tests/test_service/__pycache__/test_FileService.cpython-310-pytest-8.2.2.pyc differ diff --git a/tests/test_service/__pycache__/test_FileService.cpython-311-pytest-8.2.2.pyc b/tests/test_service/__pycache__/test_FileService.cpython-311-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..77a9574c4c24d4cf4c5bf63db4404b165321c35d Binary files /dev/null and b/tests/test_service/__pycache__/test_FileService.cpython-311-pytest-8.2.2.pyc differ diff --git a/tests/test_service/__pycache__/test_LoginService.cpython-310-pytest-8.2.2.pyc b/tests/test_service/__pycache__/test_LoginService.cpython-310-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fd0c3e3fbde34536da2cb213c331679db6bc8069 Binary files /dev/null and b/tests/test_service/__pycache__/test_LoginService.cpython-310-pytest-8.2.2.pyc differ diff --git a/tests/test_service/__pycache__/test_LoginService.cpython-311-pytest-8.2.2.pyc b/tests/test_service/__pycache__/test_LoginService.cpython-311-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f84f20c56d66cef9b340096e0316883775a6178e Binary files /dev/null and b/tests/test_service/__pycache__/test_LoginService.cpython-311-pytest-8.2.2.pyc differ diff --git a/tests/test_service/__pycache__/test_MySQLService.cpython-310-pytest-8.2.2.pyc b/tests/test_service/__pycache__/test_MySQLService.cpython-310-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0eea189718aec034b64257d06b49311e0f04ffce Binary files /dev/null and b/tests/test_service/__pycache__/test_MySQLService.cpython-310-pytest-8.2.2.pyc differ diff --git a/tests/test_service/__pycache__/test_MySQLService.cpython-310.pyc b/tests/test_service/__pycache__/test_MySQLService.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..75c96b98ac18df3f7ed14c3bf1c441410a698a2e Binary files /dev/null and b/tests/test_service/__pycache__/test_MySQLService.cpython-310.pyc differ diff --git a/tests/test_service/__pycache__/test_MySQLService.cpython-311-pytest-8.2.2.pyc b/tests/test_service/__pycache__/test_MySQLService.cpython-311-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ee113ea5b21117c1b94e572cd70265b327f97ea1 Binary files /dev/null and b/tests/test_service/__pycache__/test_MySQLService.cpython-311-pytest-8.2.2.pyc differ diff --git a/tests/test_service/__pycache__/test_OTPService.cpython-310-pytest-8.2.2.pyc b/tests/test_service/__pycache__/test_OTPService.cpython-310-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1b689b7ad43aa758e3e98729cc2e456f7dca8fc1 Binary files /dev/null and b/tests/test_service/__pycache__/test_OTPService.cpython-310-pytest-8.2.2.pyc differ diff --git a/tests/test_service/__pycache__/test_OTPService.cpython-311-pytest-8.2.2.pyc b/tests/test_service/__pycache__/test_OTPService.cpython-311-pytest-8.2.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5a70614e119f35e4dbe40f53dcaed02cbb9412c6 Binary files /dev/null and b/tests/test_service/__pycache__/test_OTPService.cpython-311-pytest-8.2.2.pyc differ diff --git a/tests/test_service/_init__.py b/tests/test_service/_init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/test_service/test_ChatService.py b/tests/test_service/test_ChatService.py new file mode 100644 index 0000000000000000000000000000000000000000..8900fd97c9ea5922f2134cf25619e88b02c89c27 --- /dev/null +++ b/tests/test_service/test_ChatService.py @@ -0,0 +1,462 @@ +import unittest +from unittest.mock import patch +import sys +import os +app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) +sys.path.insert(0, app_path) +from service.ChatService import * +from request.RequestChat import * +from response.ResponseChat import * + +class TestQuery2UpgradeOld(unittest.TestCase): + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.support_function') + def test_query2_upgrade_old_id_not_exist(self,mock_support_function, mock_function_chatbot, mock_user_repo): + user_id = "1" + text_all = 'aaa' + question = 'chatbot la gi' + chat_name = 'test' + list1 = [] + list2 = [] + mock_function_chatbot.handle_query_upgrade_keyword_old.return_value = None, list1, list2 + mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message( + message="Id not exist")) + request = RequestQuery2UpgradeOld(user_id=user_id, text_all=text_all, question=question, chat_name=chat_name) + response = query2_upgrade_old(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Id not exist')) + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.support_function') + def test_query2_upgrade_old_email_empty(self,mock_support_function, mock_function_chatbot, mock_user_repo): + user_id = "1" + email = None + text_all = 'aaa' + question = 'chatbot la gi' + chat_name = 'test' + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + list1 = [] + list2 = [] + mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + mock_function_chatbot.handle_query_upgrade_keyword_old.return_value = None, list1, list2 + + request = RequestQuery2UpgradeOld(user_id=user_id, text_all=text_all, question=question, chat_name=chat_name) + response = query2_upgrade_old(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Email is empty')) + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.support_function') + def test_query2_upgrade_old_email_in_valid(self,mock_support_function,mock_function_chatbot,mock_user_repo): + user_id = "1" + email = "20133118" + text_all = 'aaa' + question = 'chatbot la gi' + chat_name = 'test' + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + list1 = [] + list2 = [] + mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + mock_function_chatbot.handle_query_upgrade_keyword_old.return_value = None, list1, list2 + request = RequestQuery2UpgradeOld(user_id=user_id, text_all=text_all, question=question, chat_name=chat_name) + response = query2_upgrade_old(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Email invalid')) + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.support_function') + def test_query2_upgrade_old_question_empty(self,mock_support_function,mock_function_chatbot, mock_user_repo): + email = 'example@example.com' + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + list1 = [] + list2 = [] + mock_support_function.check_email_service.return_value = email + mock_function_chatbot.handle_query_upgrade_keyword_old.return_value = None, list1, list2 + request = RequestQuery2UpgradeOld(user_id="1", text_all="text aaa all", question=None, chat_name="test") + response = query2_upgrade_old(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='question is empty')) + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.support_function') + def test_query2_upgrade_old_chat_empty(self,mock_support_function, mock_user_repo): + email = 'example@example.com' + mock_support_function.check_email_service.return_value = email + request = RequestQuery2UpgradeOld(user_id= "1", text_all="aaa bbb", question="aaa bbb", chat_name=None) + response = query2_upgrade_old(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='chat_name is empty')) + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.support_function') + def test_query2_upgrade_old_no_answer(self,mock_support_function, mock_function_chatbot, mock_user_repo): + user_id = "1" + email = 'example@example.com' + text_all = [{"page_content":"Thành lập vào năm 2012, VMO Holdings (VMO) là công ty cung cấp dịch vụ CNTT chuyên nghiệp có trụ sở tại Việt Nam, Nhật Bản, Thái Lan và Mỹ. Với hơn 10 năm hoạt động trong lĩnh vực tư vấn và phát triển phần mềm, VMO hiện có hơn 1200 nhân sự và 9 văn phòng tại Việt Nam.\n\nHoàn thiện hệ sinh thái VMO và hướng tới giá trị cốt lõi trong tất cả các hoạt động, VMO tự tin trao quyền và niềm tin cho thế hệ kế cận. Chúng tôi luôn sẵn sàng chào đón các nhân tài cùng tham gia chinh phục thử thách trên những chặng đường sắp tới.\n\nTìm hiểu thêm về VMO Holdings qua:\n\n LinkedIn  Facebook  Website\n\nTHÔNG TIN TUYỂN DỤNG\n\nVị trí:\n\nĐịa điểm:\n\nBusiness Development Intern\n\nHà Nội\n\nKinh nghiệm:\n\nSố lượng:\n\nKhông yêu cầu kinh nghiệm 12\n\nMỨC HỖ TRỢ\n\nUpto 3M (Tùy theo năng lực) + Thưởng hoa hồng\n\nMÔ TẢ CÔNG VIỆC\n\nTham gia chương trình đào tạo miễn phí trong vòng 3 tháng theo lộ trình được\n\nxây dựng bài bản của công ty\n\nTham gia đào tạo các kỹ năng mềm, quy trình làm việc chuyên nghiệp  Trải nghiệm thực tế các công việc của một Business Developer như: + Tìm kiếm và kết nối với khách hàng + Giới thiệu sơ bộ về sản phẩm và dịch vụ công ty với khách hàng + Khai thác dữ liệu khách hàng\n\n[Type here]\n\nYÊU CẦU CÔNG VIỆC\n\nSử dụng Tiếng Anh thành thạo\n\nChăm chỉ, kiên nhẫn  Năng động, cởi mở, hòa đồng \n\nThông minh, tiếp thu nhanh, tư duy nhạy bén\n\nCó tinh thần cầu tiến trong công việc  Có kỹ năng giao tiếp và giải quyết vấn đề tốt  Có khả năng làm việc nhóm tốt  Đảm bảo làm việc full-time sau quá trình đào tạo\n\nQUYỀN LỢI\n\nCó cơ hội trở thành nhân viên chính thức tại VMO sau quá trình đào tạo   Được học tập với đội ngũ Mentors là Sales Manager, Teamlead có nhiều kinh nghiệm trong ngành Sales IT Global\n\nĐược tham gia các chương trình đào tạo nâng cao kỹ năng chuyên môn định kỳ\n\nhàng tháng\n\nĐược làm việc trực tiếp với khách hàng đa quốc gia thuộc nhiều lĩnh vực khác\n\nnhau\n\nĐược đào tạo trong môi trường năng động, trẻ trung, hiện đại và chuyên nghiệp\n\nCƠ HỘI VÀ THỬ THÁCH\n\nCơ hội được thử sức với các dự án hấp dẫn, thử thách đủ lớn trong và ngoài nước.  Cơ hội làm trải nghiệm môi trường làm việc cởi mở và năng động, khuyến khích trao đổi ý tưởng, trao quyền, cho phép làm việc, sáng tạo theo cách riêng. Tài năng và thành tích của từng nhân viên được trân trọng, nhân viên xuất sắc được khen thưởng hàng năm.\n\nCơ hội phát triển năng lực, được hỗ trợ phụ cấp chứng chỉ chuyên môn phục vụ công việc. Một số chứng chỉ cấp cao sẽ được chi trả toàn bộ chi phí từ học và thi.  Dự án khủng với domain hot-trend, liên tục cập nhật những công nghệ mới nhất Được làm việc trong môi trường có quy trình chuyên nghiệp, cùng những chuyên gia công nghệ đến từ các nước và khu vực khác nhau\n\n[Type here]\n\nVui lòng gửi CV của bạn về địa chỉ email: minhdn4@vmogroup.com\n\nEmail: minhdn4@vmogroup.com\n\nĐịa chỉ: Phòng Tuyển dụng – VMO Holdings, Tầng 20, Tòa IDMC, Số 18 Tôn Thất Thuyết, Mỹ Đình, Hà Nội.\n\n[Type here]","metadata":{"source":"/code/temp/vonhuytest123456789@gmail.com/JD_BD-Intern.pdf"},"type":"Document"}] + question = "aaa bbb" + chat_name = "test" + mock_support_function.check_email_service.return_value = email + list1 = [] + list2 = [] + mock_function_chatbot.handle_query_upgrade_keyword_old.return_value = None, list1, list2 + request = RequestQuery2UpgradeOld(user_id=user_id, text_all = json.dumps(text_all), question=question, chat_name=chat_name) + response = query2_upgrade_old(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "No answer") + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.ChatHistoryRepository') + @patch('service.ChatService.DetailChatRepository') + @patch('service.ChatService.support_function') + def test_query2_upgrade_old_success(self,mock_support_function,mock_detail_chat_repo, mock_chat_his_repo, mock_function_chatbot, mock_user_repo): + user_id = "1" + email = 'example@example.com' + text_all = [{"page_content":"Thành lập vào năm 2012, VMO Holdings (VMO) là công ty cung cấp dịch vụ CNTT chuyên nghiệp có trụ sở tại Việt Nam, Nhật Bản, Thái Lan và Mỹ. Với hơn 10 năm hoạt động trong lĩnh vực tư vấn và phát triển phần mềm, VMO hiện có hơn 1200 nhân sự và 9 văn phòng tại Việt Nam.\n\nHoàn thiện hệ sinh thái VMO và hướng tới giá trị cốt lõi trong tất cả các hoạt động, VMO tự tin trao quyền và niềm tin cho thế hệ kế cận. Chúng tôi luôn sẵn sàng chào đón các nhân tài cùng tham gia chinh phục thử thách trên những chặng đường sắp tới.\n\nTìm hiểu thêm về VMO Holdings qua:\n\n LinkedIn  Facebook  Website\n\nTHÔNG TIN TUYỂN DỤNG\n\nVị trí:\n\nĐịa điểm:\n\nBusiness Development Intern\n\nHà Nội\n\nKinh nghiệm:\n\nSố lượng:\n\nKhông yêu cầu kinh nghiệm 12\n\nMỨC HỖ TRỢ\n\nUpto 3M (Tùy theo năng lực) + Thưởng hoa hồng\n\nMÔ TẢ CÔNG VIỆC\n\nTham gia chương trình đào tạo miễn phí trong vòng 3 tháng theo lộ trình được\n\nxây dựng bài bản của công ty\n\nTham gia đào tạo các kỹ năng mềm, quy trình làm việc chuyên nghiệp  Trải nghiệm thực tế các công việc của một Business Developer như: + Tìm kiếm và kết nối với khách hàng + Giới thiệu sơ bộ về sản phẩm và dịch vụ công ty với khách hàng + Khai thác dữ liệu khách hàng\n\n[Type here]\n\nYÊU CẦU CÔNG VIỆC\n\nSử dụng Tiếng Anh thành thạo\n\nChăm chỉ, kiên nhẫn  Năng động, cởi mở, hòa đồng \n\nThông minh, tiếp thu nhanh, tư duy nhạy bén\n\nCó tinh thần cầu tiến trong công việc  Có kỹ năng giao tiếp và giải quyết vấn đề tốt  Có khả năng làm việc nhóm tốt  Đảm bảo làm việc full-time sau quá trình đào tạo\n\nQUYỀN LỢI\n\nCó cơ hội trở thành nhân viên chính thức tại VMO sau quá trình đào tạo   Được học tập với đội ngũ Mentors là Sales Manager, Teamlead có nhiều kinh nghiệm trong ngành Sales IT Global\n\nĐược tham gia các chương trình đào tạo nâng cao kỹ năng chuyên môn định kỳ\n\nhàng tháng\n\nĐược làm việc trực tiếp với khách hàng đa quốc gia thuộc nhiều lĩnh vực khác\n\nnhau\n\nĐược đào tạo trong môi trường năng động, trẻ trung, hiện đại và chuyên nghiệp\n\nCƠ HỘI VÀ THỬ THÁCH\n\nCơ hội được thử sức với các dự án hấp dẫn, thử thách đủ lớn trong và ngoài nước.  Cơ hội làm trải nghiệm môi trường làm việc cởi mở và năng động, khuyến khích trao đổi ý tưởng, trao quyền, cho phép làm việc, sáng tạo theo cách riêng. Tài năng và thành tích của từng nhân viên được trân trọng, nhân viên xuất sắc được khen thưởng hàng năm.\n\nCơ hội phát triển năng lực, được hỗ trợ phụ cấp chứng chỉ chuyên môn phục vụ công việc. Một số chứng chỉ cấp cao sẽ được chi trả toàn bộ chi phí từ học và thi.  Dự án khủng với domain hot-trend, liên tục cập nhật những công nghệ mới nhất Được làm việc trong môi trường có quy trình chuyên nghiệp, cùng những chuyên gia công nghệ đến từ các nước và khu vực khác nhau\n\n[Type here]\n\nVui lòng gửi CV của bạn về địa chỉ email: minhdn4@vmogroup.com\n\nEmail: minhdn4@vmogroup.com\n\nĐịa chỉ: Phòng Tuyển dụng – VMO Holdings, Tầng 20, Tòa IDMC, Số 18 Tôn Thất Thuyết, Mỹ Đình, Hà Nội.\n\n[Type here]","metadata":{"source":"/code/temp/vonhuytest123456789@gmail.com/JD_BD-Intern.pdf"},"type":"Document"}] + question = "aaa bbb" + chat_name = "test" + mock_support_function.check_email_service.return_value = email + list1 = [] + list2 = [] + mock_function_chatbot.handle_query_upgrade_keyword_old.return_value = "success",list1,list2 + mock_chat_his_repo.getIdChatHistoryByUserIdAndNameChat.return_value = True + mock_detail_chat_repo.addDetailChat.return_value = True + request = RequestQuery2UpgradeOld(user_id=user_id, text_all = json.dumps(text_all), question=question, chat_name=chat_name) + response = query2_upgrade_old(request) + self.assertIsInstance(response, ResponseQuery2UpgradeOld) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.answer, "success") + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.ChatHistoryRepository') + @patch('service.ChatService.DetailChatRepository') + @patch('service.ChatService.support_function') + def test_query2_upgrade_old_server_error_user_repo(self,mock_support_function,mock_detail_chat_repo, mock_chat_his_repo, mock_function_chatbot, mock_user_repo): + user_id = "1" + email = 'example@example.com' + text_all = [{"page_content":"Thành lập vào năm 2012, VMO Holdings (VMO) là công ty cung cấp dịch vụ CNTT chuyên nghiệp có trụ sở tại Việt Nam, Nhật Bản, Thái Lan và Mỹ. Với hơn 10 năm hoạt động trong lĩnh vực tư vấn và phát triển phần mềm, VMO hiện có hơn 1200 nhân sự và 9 văn phòng tại Việt Nam.\n\nHoàn thiện hệ sinh thái VMO và hướng tới giá trị cốt lõi trong tất cả các hoạt động, VMO tự tin trao quyền và niềm tin cho thế hệ kế cận. Chúng tôi luôn sẵn sàng chào đón các nhân tài cùng tham gia chinh phục thử thách trên những chặng đường sắp tới.\n\nTìm hiểu thêm về VMO Holdings qua:\n\n LinkedIn  Facebook  Website\n\nTHÔNG TIN TUYỂN DỤNG\n\nVị trí:\n\nĐịa điểm:\n\nBusiness Development Intern\n\nHà Nội\n\nKinh nghiệm:\n\nSố lượng:\n\nKhông yêu cầu kinh nghiệm 12\n\nMỨC HỖ TRỢ\n\nUpto 3M (Tùy theo năng lực) + Thưởng hoa hồng\n\nMÔ TẢ CÔNG VIỆC\n\nTham gia chương trình đào tạo miễn phí trong vòng 3 tháng theo lộ trình được\n\nxây dựng bài bản của công ty\n\nTham gia đào tạo các kỹ năng mềm, quy trình làm việc chuyên nghiệp  Trải nghiệm thực tế các công việc của một Business Developer như: + Tìm kiếm và kết nối với khách hàng + Giới thiệu sơ bộ về sản phẩm và dịch vụ công ty với khách hàng + Khai thác dữ liệu khách hàng\n\n[Type here]\n\nYÊU CẦU CÔNG VIỆC\n\nSử dụng Tiếng Anh thành thạo\n\nChăm chỉ, kiên nhẫn  Năng động, cởi mở, hòa đồng \n\nThông minh, tiếp thu nhanh, tư duy nhạy bén\n\nCó tinh thần cầu tiến trong công việc  Có kỹ năng giao tiếp và giải quyết vấn đề tốt  Có khả năng làm việc nhóm tốt  Đảm bảo làm việc full-time sau quá trình đào tạo\n\nQUYỀN LỢI\n\nCó cơ hội trở thành nhân viên chính thức tại VMO sau quá trình đào tạo   Được học tập với đội ngũ Mentors là Sales Manager, Teamlead có nhiều kinh nghiệm trong ngành Sales IT Global\n\nĐược tham gia các chương trình đào tạo nâng cao kỹ năng chuyên môn định kỳ\n\nhàng tháng\n\nĐược làm việc trực tiếp với khách hàng đa quốc gia thuộc nhiều lĩnh vực khác\n\nnhau\n\nĐược đào tạo trong môi trường năng động, trẻ trung, hiện đại và chuyên nghiệp\n\nCƠ HỘI VÀ THỬ THÁCH\n\nCơ hội được thử sức với các dự án hấp dẫn, thử thách đủ lớn trong và ngoài nước.  Cơ hội làm trải nghiệm môi trường làm việc cởi mở và năng động, khuyến khích trao đổi ý tưởng, trao quyền, cho phép làm việc, sáng tạo theo cách riêng. Tài năng và thành tích của từng nhân viên được trân trọng, nhân viên xuất sắc được khen thưởng hàng năm.\n\nCơ hội phát triển năng lực, được hỗ trợ phụ cấp chứng chỉ chuyên môn phục vụ công việc. Một số chứng chỉ cấp cao sẽ được chi trả toàn bộ chi phí từ học và thi.  Dự án khủng với domain hot-trend, liên tục cập nhật những công nghệ mới nhất Được làm việc trong môi trường có quy trình chuyên nghiệp, cùng những chuyên gia công nghệ đến từ các nước và khu vực khác nhau\n\n[Type here]\n\nVui lòng gửi CV của bạn về địa chỉ email: minhdn4@vmogroup.com\n\nEmail: minhdn4@vmogroup.com\n\nĐịa chỉ: Phòng Tuyển dụng – VMO Holdings, Tầng 20, Tòa IDMC, Số 18 Tôn Thất Thuyết, Mỹ Đình, Hà Nội.\n\n[Type here]","metadata":{"source":"/code/temp/vonhuytest123456789@gmail.com/JD_BD-Intern.pdf"},"type":"Document"}] + question = "aaa bbb" + chat_name = "test" + mock_support_function.check_email_service.side_effect = Exception("Unexpected Error") + list1 = [] + list2 = [] + mock_function_chatbot.handle_query_upgrade_keyword_old.return_value = None, list1, list2 + request = RequestQuery2UpgradeOld(user_id=user_id, text_all = json.dumps(text_all), question=question, chat_name=chat_name) + response = query2_upgrade_old(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.ChatHistoryRepository') + @patch('service.ChatService.DetailChatRepository') + @patch('service.ChatService.support_function') + def test_query2_upgrade_old_server_error_chathistory_repo(self,mock_support_function,mock_detail_chat_repo, mock_chat_his_repo, mock_function_chatbot, mock_user_repo): + user_id = "1" + email = 'example@example.com' + text_all = [{"page_content":"Thành lập vào năm 2012, VMO Holdings (VMO) là công ty cung cấp dịch vụ CNTT chuyên nghiệp có trụ sở tại Việt Nam, Nhật Bản, Thái Lan và Mỹ. Với hơn 10 năm hoạt động trong lĩnh vực tư vấn và phát triển phần mềm, VMO hiện có hơn 1200 nhân sự và 9 văn phòng tại Việt Nam.\n\nHoàn thiện hệ sinh thái VMO và hướng tới giá trị cốt lõi trong tất cả các hoạt động, VMO tự tin trao quyền và niềm tin cho thế hệ kế cận. Chúng tôi luôn sẵn sàng chào đón các nhân tài cùng tham gia chinh phục thử thách trên những chặng đường sắp tới.\n\nTìm hiểu thêm về VMO Holdings qua:\n\n LinkedIn  Facebook  Website\n\nTHÔNG TIN TUYỂN DỤNG\n\nVị trí:\n\nĐịa điểm:\n\nBusiness Development Intern\n\nHà Nội\n\nKinh nghiệm:\n\nSố lượng:\n\nKhông yêu cầu kinh nghiệm 12\n\nMỨC HỖ TRỢ\n\nUpto 3M (Tùy theo năng lực) + Thưởng hoa hồng\n\nMÔ TẢ CÔNG VIỆC\n\nTham gia chương trình đào tạo miễn phí trong vòng 3 tháng theo lộ trình được\n\nxây dựng bài bản của công ty\n\nTham gia đào tạo các kỹ năng mềm, quy trình làm việc chuyên nghiệp  Trải nghiệm thực tế các công việc của một Business Developer như: + Tìm kiếm và kết nối với khách hàng + Giới thiệu sơ bộ về sản phẩm và dịch vụ công ty với khách hàng + Khai thác dữ liệu khách hàng\n\n[Type here]\n\nYÊU CẦU CÔNG VIỆC\n\nSử dụng Tiếng Anh thành thạo\n\nChăm chỉ, kiên nhẫn  Năng động, cởi mở, hòa đồng \n\nThông minh, tiếp thu nhanh, tư duy nhạy bén\n\nCó tinh thần cầu tiến trong công việc  Có kỹ năng giao tiếp và giải quyết vấn đề tốt  Có khả năng làm việc nhóm tốt  Đảm bảo làm việc full-time sau quá trình đào tạo\n\nQUYỀN LỢI\n\nCó cơ hội trở thành nhân viên chính thức tại VMO sau quá trình đào tạo   Được học tập với đội ngũ Mentors là Sales Manager, Teamlead có nhiều kinh nghiệm trong ngành Sales IT Global\n\nĐược tham gia các chương trình đào tạo nâng cao kỹ năng chuyên môn định kỳ\n\nhàng tháng\n\nĐược làm việc trực tiếp với khách hàng đa quốc gia thuộc nhiều lĩnh vực khác\n\nnhau\n\nĐược đào tạo trong môi trường năng động, trẻ trung, hiện đại và chuyên nghiệp\n\nCƠ HỘI VÀ THỬ THÁCH\n\nCơ hội được thử sức với các dự án hấp dẫn, thử thách đủ lớn trong và ngoài nước.  Cơ hội làm trải nghiệm môi trường làm việc cởi mở và năng động, khuyến khích trao đổi ý tưởng, trao quyền, cho phép làm việc, sáng tạo theo cách riêng. Tài năng và thành tích của từng nhân viên được trân trọng, nhân viên xuất sắc được khen thưởng hàng năm.\n\nCơ hội phát triển năng lực, được hỗ trợ phụ cấp chứng chỉ chuyên môn phục vụ công việc. Một số chứng chỉ cấp cao sẽ được chi trả toàn bộ chi phí từ học và thi.  Dự án khủng với domain hot-trend, liên tục cập nhật những công nghệ mới nhất Được làm việc trong môi trường có quy trình chuyên nghiệp, cùng những chuyên gia công nghệ đến từ các nước và khu vực khác nhau\n\n[Type here]\n\nVui lòng gửi CV của bạn về địa chỉ email: minhdn4@vmogroup.com\n\nEmail: minhdn4@vmogroup.com\n\nĐịa chỉ: Phòng Tuyển dụng – VMO Holdings, Tầng 20, Tòa IDMC, Số 18 Tôn Thất Thuyết, Mỹ Đình, Hà Nội.\n\n[Type here]","metadata":{"source":"/code/temp/vonhuytest123456789@gmail.com/JD_BD-Intern.pdf"},"type":"Document"}] + question = "aaa bbb" + chat_name = "test" + mock_chat_his_repo.side_effect = Exception("Unexpected Error") + request = RequestQuery2UpgradeOld(user_id=user_id, text_all = json.dumps(text_all), question=question, chat_name=chat_name) + response = query2_upgrade_old(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.ChatHistoryRepository') + @patch('service.ChatService.DetailChatRepository') + @patch('service.ChatService.support_function') + def test_query2_upgrade_old_server_error_detailchat_repo(self,mock_support_function,mock_detail_chat_repo, mock_chat_his_repo, mock_function_chatbot, mock_user_repo): + user_id = "1" + email = 'example@example.com' + text_all = [{"page_content":"Thành lập vào năm 2012, VMO Holdings (VMO) là công ty cung cấp dịch vụ CNTT chuyên nghiệp có trụ sở tại Việt Nam, Nhật Bản, Thái Lan và Mỹ. Với hơn 10 năm hoạt động trong lĩnh vực tư vấn và phát triển phần mềm, VMO hiện có hơn 1200 nhân sự và 9 văn phòng tại Việt Nam.\n\nHoàn thiện hệ sinh thái VMO và hướng tới giá trị cốt lõi trong tất cả các hoạt động, VMO tự tin trao quyền và niềm tin cho thế hệ kế cận. Chúng tôi luôn sẵn sàng chào đón các nhân tài cùng tham gia chinh phục thử thách trên những chặng đường sắp tới.\n\nTìm hiểu thêm về VMO Holdings qua:\n\n LinkedIn  Facebook  Website\n\nTHÔNG TIN TUYỂN DỤNG\n\nVị trí:\n\nĐịa điểm:\n\nBusiness Development Intern\n\nHà Nội\n\nKinh nghiệm:\n\nSố lượng:\n\nKhông yêu cầu kinh nghiệm 12\n\nMỨC HỖ TRỢ\n\nUpto 3M (Tùy theo năng lực) + Thưởng hoa hồng\n\nMÔ TẢ CÔNG VIỆC\n\nTham gia chương trình đào tạo miễn phí trong vòng 3 tháng theo lộ trình được\n\nxây dựng bài bản của công ty\n\nTham gia đào tạo các kỹ năng mềm, quy trình làm việc chuyên nghiệp  Trải nghiệm thực tế các công việc của một Business Developer như: + Tìm kiếm và kết nối với khách hàng + Giới thiệu sơ bộ về sản phẩm và dịch vụ công ty với khách hàng + Khai thác dữ liệu khách hàng\n\n[Type here]\n\nYÊU CẦU CÔNG VIỆC\n\nSử dụng Tiếng Anh thành thạo\n\nChăm chỉ, kiên nhẫn  Năng động, cởi mở, hòa đồng \n\nThông minh, tiếp thu nhanh, tư duy nhạy bén\n\nCó tinh thần cầu tiến trong công việc  Có kỹ năng giao tiếp và giải quyết vấn đề tốt  Có khả năng làm việc nhóm tốt  Đảm bảo làm việc full-time sau quá trình đào tạo\n\nQUYỀN LỢI\n\nCó cơ hội trở thành nhân viên chính thức tại VMO sau quá trình đào tạo   Được học tập với đội ngũ Mentors là Sales Manager, Teamlead có nhiều kinh nghiệm trong ngành Sales IT Global\n\nĐược tham gia các chương trình đào tạo nâng cao kỹ năng chuyên môn định kỳ\n\nhàng tháng\n\nĐược làm việc trực tiếp với khách hàng đa quốc gia thuộc nhiều lĩnh vực khác\n\nnhau\n\nĐược đào tạo trong môi trường năng động, trẻ trung, hiện đại và chuyên nghiệp\n\nCƠ HỘI VÀ THỬ THÁCH\n\nCơ hội được thử sức với các dự án hấp dẫn, thử thách đủ lớn trong và ngoài nước.  Cơ hội làm trải nghiệm môi trường làm việc cởi mở và năng động, khuyến khích trao đổi ý tưởng, trao quyền, cho phép làm việc, sáng tạo theo cách riêng. Tài năng và thành tích của từng nhân viên được trân trọng, nhân viên xuất sắc được khen thưởng hàng năm.\n\nCơ hội phát triển năng lực, được hỗ trợ phụ cấp chứng chỉ chuyên môn phục vụ công việc. Một số chứng chỉ cấp cao sẽ được chi trả toàn bộ chi phí từ học và thi.  Dự án khủng với domain hot-trend, liên tục cập nhật những công nghệ mới nhất Được làm việc trong môi trường có quy trình chuyên nghiệp, cùng những chuyên gia công nghệ đến từ các nước và khu vực khác nhau\n\n[Type here]\n\nVui lòng gửi CV của bạn về địa chỉ email: minhdn4@vmogroup.com\n\nEmail: minhdn4@vmogroup.com\n\nĐịa chỉ: Phòng Tuyển dụng – VMO Holdings, Tầng 20, Tòa IDMC, Số 18 Tôn Thất Thuyết, Mỹ Đình, Hà Nội.\n\n[Type here]","metadata":{"source":"/code/temp/vonhuytest123456789@gmail.com/JD_BD-Intern.pdf"},"type":"Document"}] + question = "aaa bbb" + chat_name = "test" + mock_support_function.check_email_service.return_value = email + mock_detail_chat_repo.side_effect = Exception("Unexpected Error") + request = RequestQuery2UpgradeOld(user_id=user_id, text_all = json.dumps(text_all), question=question, chat_name=chat_name) + response = query2_upgrade_old(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.ChatHistoryRepository') + @patch('service.ChatService.DetailChatRepository') + @patch('service.ChatService.support_function') + def test_query2_upgrade_old_server_error_function_repo(self,mock_support_function,mock_detail_chat_repo, mock_chat_his_repo, mock_function_chatbot, mock_user_repo): + user_id = "1" + email = 'example@example.com' + text_all = [{"page_content":"Thành lập vào năm 2012, VMO Holdings (VMO) là công ty cung cấp dịch vụ CNTT chuyên nghiệp có trụ sở tại Việt Nam, Nhật Bản, Thái Lan và Mỹ. Với hơn 10 năm hoạt động trong lĩnh vực tư vấn và phát triển phần mềm, VMO hiện có hơn 1200 nhân sự và 9 văn phòng tại Việt Nam.\n\nHoàn thiện hệ sinh thái VMO và hướng tới giá trị cốt lõi trong tất cả các hoạt động, VMO tự tin trao quyền và niềm tin cho thế hệ kế cận. Chúng tôi luôn sẵn sàng chào đón các nhân tài cùng tham gia chinh phục thử thách trên những chặng đường sắp tới.\n\nTìm hiểu thêm về VMO Holdings qua:\n\n LinkedIn  Facebook  Website\n\nTHÔNG TIN TUYỂN DỤNG\n\nVị trí:\n\nĐịa điểm:\n\nBusiness Development Intern\n\nHà Nội\n\nKinh nghiệm:\n\nSố lượng:\n\nKhông yêu cầu kinh nghiệm 12\n\nMỨC HỖ TRỢ\n\nUpto 3M (Tùy theo năng lực) + Thưởng hoa hồng\n\nMÔ TẢ CÔNG VIỆC\n\nTham gia chương trình đào tạo miễn phí trong vòng 3 tháng theo lộ trình được\n\nxây dựng bài bản của công ty\n\nTham gia đào tạo các kỹ năng mềm, quy trình làm việc chuyên nghiệp  Trải nghiệm thực tế các công việc của một Business Developer như: + Tìm kiếm và kết nối với khách hàng + Giới thiệu sơ bộ về sản phẩm và dịch vụ công ty với khách hàng + Khai thác dữ liệu khách hàng\n\n[Type here]\n\nYÊU CẦU CÔNG VIỆC\n\nSử dụng Tiếng Anh thành thạo\n\nChăm chỉ, kiên nhẫn  Năng động, cởi mở, hòa đồng \n\nThông minh, tiếp thu nhanh, tư duy nhạy bén\n\nCó tinh thần cầu tiến trong công việc  Có kỹ năng giao tiếp và giải quyết vấn đề tốt  Có khả năng làm việc nhóm tốt  Đảm bảo làm việc full-time sau quá trình đào tạo\n\nQUYỀN LỢI\n\nCó cơ hội trở thành nhân viên chính thức tại VMO sau quá trình đào tạo   Được học tập với đội ngũ Mentors là Sales Manager, Teamlead có nhiều kinh nghiệm trong ngành Sales IT Global\n\nĐược tham gia các chương trình đào tạo nâng cao kỹ năng chuyên môn định kỳ\n\nhàng tháng\n\nĐược làm việc trực tiếp với khách hàng đa quốc gia thuộc nhiều lĩnh vực khác\n\nnhau\n\nĐược đào tạo trong môi trường năng động, trẻ trung, hiện đại và chuyên nghiệp\n\nCƠ HỘI VÀ THỬ THÁCH\n\nCơ hội được thử sức với các dự án hấp dẫn, thử thách đủ lớn trong và ngoài nước.  Cơ hội làm trải nghiệm môi trường làm việc cởi mở và năng động, khuyến khích trao đổi ý tưởng, trao quyền, cho phép làm việc, sáng tạo theo cách riêng. Tài năng và thành tích của từng nhân viên được trân trọng, nhân viên xuất sắc được khen thưởng hàng năm.\n\nCơ hội phát triển năng lực, được hỗ trợ phụ cấp chứng chỉ chuyên môn phục vụ công việc. Một số chứng chỉ cấp cao sẽ được chi trả toàn bộ chi phí từ học và thi.  Dự án khủng với domain hot-trend, liên tục cập nhật những công nghệ mới nhất Được làm việc trong môi trường có quy trình chuyên nghiệp, cùng những chuyên gia công nghệ đến từ các nước và khu vực khác nhau\n\n[Type here]\n\nVui lòng gửi CV của bạn về địa chỉ email: minhdn4@vmogroup.com\n\nEmail: minhdn4@vmogroup.com\n\nĐịa chỉ: Phòng Tuyển dụng – VMO Holdings, Tầng 20, Tòa IDMC, Số 18 Tôn Thất Thuyết, Mỹ Đình, Hà Nội.\n\n[Type here]","metadata":{"source":"/code/temp/vonhuytest123456789@gmail.com/JD_BD-Intern.pdf"},"type":"Document"}] + question = "aaa bbb" + chat_name = "test" + mock_support_function.check_email_service.return_value = email + mock_function_chatbot.side_effect = Exception("Unexpected Error") + request = RequestQuery2UpgradeOld(user_id=user_id, text_all = json.dumps(text_all), question=question, chat_name=chat_name) + response = query2_upgrade_old(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + +class TestExtractFile(unittest.TestCase): + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.support_function') + def test_extract_file_success(self,mock_support_function, mock_function_chatbot, mock_user_repo): + user_id = "1" + email = 'example@example.com' + mock_support_function.check_email_service.return_value = email + mock_function_chatbot.extract_data2.return_value = True + request = RequestExtractFile(user_id=user_id) + response = extract_file(request) + self.assertIsInstance(response, ResponseExtractFile) + self.assertEqual(response.status, 200) + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.support_function') + def test_extract_file_id_not_exist(self,mock_support_function, mock_function_chatbot, mock_user_repo): + user_id = "1" + mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message( + message="Id not exist")) + request = RequestExtractFile(user_id=user_id) + response = extract_file(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Id not exist')) + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.support_function') + def test_extract_file_email_empty(self,mock_support_function,mock_function_chatbot, mock_user_repo): + user_id = "1" + email = None + mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + request = RequestExtractFile(user_id=user_id) + response = extract_file(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Email is empty')) + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.support_function') + def test_extract_file_email_in_valid(self,mock_support_function +, mock_function_chatbot, mock_user_repo): + user_id = "1" + mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + request = RequestExtractFile(user_id=user_id) + response = extract_file(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Email invalid')) + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.support_function') + def test_extract_file_no_data(self, mock_support_function, mock_function_chatbot, mock_user_repo): + user_id = "1" + email = 'example@example.com' + mock_support_function.check_email_service.return_value = email + mock_function_chatbot.extract_data2.return_value = False + request = RequestExtractFile(user_id=user_id) + response = extract_file(request) + self.assertIsInstance(response, ResponseExtractFile) + self.assertEqual(response.status, 200) + self.assertEqual(response.data, DataExtractFile(text_all="No data response")) + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.support_function') + def test_extract_file_server_error_sf(self, mock_support_function,mock_function_chatbot, mock_user_repo): + user_id = "1" + email = None + mock_support_function.check_email_service.side_effect = Exception("Unexpected Error") + request = RequestExtractFile(user_id=user_id) + response = extract_file(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 500) + self.assertEqual(response.data, Message(message='Server Error')) + +class TestGenerateQuestion(unittest.TestCase): + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.support_function') + def test_generate_question_success(self,mock_support_function, mock_function_chatbot, mock_user_repo): + user_id = "1" + email = 'example@example.com' + mock_support_function.check_email_service.return_value = email + mock_function_chatbot.generate_question.return_value = True + request = RequestGenerateQuestion(user_id=user_id) + response = generate_question(request) + self.assertIsInstance(response, ResponseGenerateQuestion) + self.assertEqual(response.status, 200) + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.support_function') + def test_generate_question_id_not_exist(self,mock_support_function, mock_function_chatbot, mock_user_repo): + user_id = "1" + mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message( + message="Id not exist")) + request = RequestGenerateQuestion(user_id=user_id) + response = generate_question(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Id not exist')) + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.support_function') + def test_generate_question_email_empty(self,mock_support_function, mock_function_chatbot, mock_user_repo): + user_id = "1" + mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + request = RequestGenerateQuestion(user_id=user_id) + response = generate_question(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Email is empty')) + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.support_function') + def test_generate_question_email_in_valid(self,mock_support_function, mock_function_chatbot, mock_user_repo): + user_id = "1" + email = "20133118" + mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + request = RequestGenerateQuestion(user_id=user_id) + response = generate_question(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Email invalid')) + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.support_function') + def test_generate_question_no_data(self,mock_support_function, mock_function_chatbot, mock_user_repo): + user_id = "1" + email = 'example@example.com' + mock_support_function.check_email_service.return_value = email + mock_function_chatbot.generate_question.return_value = False + request = RequestGenerateQuestion(user_id=user_id) + response = generate_question(request) + self.assertIsInstance(response, ResponseGenerateQuestion) + self.assertEqual(response.status, 200) + self.assertEqual(response.data, GenerateQuestion(question=False)) + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.sf') + @patch('service.ChatService.support_function') + def test_generate_question_server_err_user_repo(self,mock_support_function +, mock_function_chatbot, mock_user_repo): + user_id = "1" + email = None + mock_support_function.side_effect = Exception("Unexpected Error") + request = RequestGenerateQuestion(user_id=user_id) + response = generate_question(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 500) + self.assertEqual(response.data, Message(message='Server Error')) + +class TestDeleteChat(unittest.TestCase): + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.DetailChatRepository') + @patch('service.ChatService.ChatHistoryRepository') + @patch('service.ChatService.support_function') + def test_delete_chat_success(self, mock_support_function, mock_detail_chat_repo, mock_chat_history_repo, mock_user_repo): + user_id = "1" + email = 'example@example.com' + chat_name = 'test' + mock_support_function.check_email_service.return_value = email + mock_detail_chat_repo.delete_chat_detail.return_value = True + mock_chat_history_repo.deleteChatHistory.return_value = True + request = RequestDeleteChat(user_id=user_id, chat_name=chat_name) + response = delete_chat(request) + self.assertIsInstance(response, ResponseDeleteChat) + self.assertEqual(response.status, 200) + self.assertEqual(response.data, Message(message="Delete conversation chat success")) + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.support_function') + def test_delete_chat_id_not_exist(self,mock_support_function, mock_user_repo): + user_id = "1" + chat_name = 'test' + mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message( + message="Id not exist")) + request = RequestDeleteChat(user_id=user_id, chat_name=chat_name) + response = delete_chat(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Id not exist')) + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.support_function') + def test_delete_chat_chat_name_empty(self, mock_support_function, mock_user_repo): + user_id = "1" + email = 'example@example.com' + chat_name = None + mock_support_function.check_email_service.return_value = email + request = RequestDeleteChat(user_id=user_id, chat_name=chat_name) + response = delete_chat(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "chat_name is empty") + + @patch('service.ChatService.UserRepository') + @patch('service.ChatService.ChatHistoryRepository') + @patch('service.ChatService.support_function') + def test_delete_chat_failed(self,mock_support_function, mock_chat_history_repo, mock_user_repo): + user_id = "1" + email = 'example@example.com' + chat_name = 'test' + mock_support_function.check_email_service.return_value = email + mock_chat_history_repo.deleteChatHistory.return_value = False + request = RequestDeleteChat(user_id=user_id, chat_name=chat_name) + response = delete_chat(request) + self.assertIsInstance(response, ResponseDeleteChat) + self.assertEqual(response.status, 500) + self.assertEqual(response.data, Message(message="Delete conversation chat failed")) + + @patch('service.ChatService.support_function') + @patch('service.ChatService.DetailChatRepository.delete_chat_detail') + @patch('service.ChatService.ChatHistoryRepository.deleteChatHistory') + def test_delete_chat_server_err(self, mock_chat_history_repo, mock_detail_chat_repo, mock_support_function): + user_id = "1" + chat_name = 'test' + + mock_support_function.check_email_service.side_effect = Exception("Unexpected Error") + + request = RequestDeleteChat(user_id=user_id, chat_name=chat_name) + response = delete_chat(request) + + # Assuming ReponseError is the correct class name + self.assertIsInstance(response, res.ReponseError) # Check against ReponseError + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/tests/test_service/test_DefaultService.py b/tests/test_service/test_DefaultService.py new file mode 100644 index 0000000000000000000000000000000000000000..5f1d265f64db7daef1bd0a8aeeee9fb857220218 --- /dev/null +++ b/tests/test_service/test_DefaultService.py @@ -0,0 +1,306 @@ +import os +import sys +import unittest +from unittest.mock import patch, Mock,MagicMock +app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) +sys.path.insert(0, app_path) +from service.DefaultService import * +from request.RequestDefault import * +from response.ResponseDefault import * + +class TestCreateFireBaseUser(unittest.TestCase): + def test_email_none(self): + request = RequestCreateFireBaseUserGoogle(email=None) + response = create_firebase_user(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email is empty") + + @patch('service.DefaultService.check_email', return_value=False) + @patch('service.DefaultService.get_user') + def test_invalid_email(self, mock_get_user, mock_check_email): + request = Mock(spec=req.RequestCreateFireBaseUserGoogle) + request.email = "invalid-email" + response = create_firebase_user(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email invalid") + + @patch('service.DefaultService.check_email', return_value=True) + @patch('service.DefaultService.get_user') + def test_existing_user(self, mock_get_user, mock_check_email): + request = Mock(spec=req.RequestCreateFireBaseUserGoogle) + request.email = "test@example.com" + user = Mock() + user.email = "test@example.com" + user.display_name = "Test User" + user.uid = "123456" + user.photo_url = "http://example.com/photo.jpg" + mock_get_user.return_value = user + response = create_firebase_user(request) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.localId, "123456") + self.assertEqual(response.data.email, user.email) + self.assertEqual(response.data.displayName, user.display_name) + self.assertEqual(response.data.photoUrl, user.photo_url) + + @patch('service.DefaultService.check_email', return_value=True) + @patch('service.DefaultService.get_user', return_value=None) + def test_non_existing_user(self, mock_get_user, mock_check_email): + request = Mock(spec=req.RequestCreateFireBaseUserGoogle) + request.email = "test@example.com" + response = create_firebase_user(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Error") + + @patch('service.DefaultService.check_email') + @patch('service.DefaultService.get_user') + def test_server_error(self, mock_get_user, mock_check_email): + request = Mock(spec=req.RequestCreateFireBaseUserGoogle) + request.email = "test@example.com" + #1 of the 2 cases below + mock_check_email.side_effect = Exception("Unexpected Error") + # mock_get_user.side_effect = Exception("Unexpected Error") + response = create_firebase_user(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + +class TestInfoUser(unittest.TestCase): + @patch('service.DefaultService.UserRepository.getEmailUserByIdFix') + @patch('service.DefaultService.get_user') + @patch('service.DefaultService.check_email') + def test_id_not_exist(self, mock_check_email, mock_get_user, mock_getEmailUserByIdFix): + request = Mock(spec=req.RequestInfoUser) + request.user_id = '1' + mock_getEmailUserByIdFix.return_value = None + response = info_user(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Id not exist") + + @patch('service.DefaultService.UserRepository.getEmailUserByIdFix') + @patch('service.DefaultService.get_user') + @patch('service.DefaultService.check_email') + def test_email_is_none(self, mock_check_email, mock_get_user, mock_getEmailUserByIdFix): + request = Mock(spec=req.RequestInfoUser) + request.user_id = '1' + mock_getEmailUserByIdFix.return_value = [None] + response = info_user(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email is empty") + + @patch('service.DefaultService.UserRepository.getEmailUserByIdFix') + @patch('service.DefaultService.get_user') + @patch('service.DefaultService.check_email', return_value=False) + def test_invalid_email(self, mock_check_email, mock_get_user, mock_getEmailUserByIdFix): + request = Mock(spec=req.RequestInfoUser) + request.user_id = '1' + mock_getEmailUserByIdFix.return_value = ["invalid-email"] + response = info_user(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email invalid") + + @patch('service.DefaultService.UserRepository.getEmailUserByIdFix') + @patch('service.DefaultService.get_user', return_value=None) + @patch('service.DefaultService.check_email', return_value=True) + def test_user_not_found(self, mock_check_email, mock_get_user, mock_getEmailUserByIdFix): + request = Mock(spec=req.RequestInfoUser) + request.user_id = '1' + mock_getEmailUserByIdFix.return_value = ["test@example.com"] + response = info_user(request) + self.assertEqual(response.status, 404) + self.assertEqual(response.data.message, "User not found") + + @patch('service.DefaultService.UserRepository.getEmailUserByIdFix') + @patch('service.DefaultService.get_user') + @patch('service.DefaultService.check_email', return_value=True) + def test_successful_user_retrieval(self, mock_check_email, mock_get_user, mock_getEmailUserByIdFix): + request = Mock(spec=req.RequestInfoUser) + request.user_id = '1' + mock_getEmailUserByIdFix.return_value = ["test@example.com"] + user = Mock() + user.uid = "12345" + user.email = "test@example.com" + user.display_name = "Test User" + user.photo_url = "http://example.com/photo.jpg" + mock_get_user.return_value = user + response = info_user(request) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.uid, user.uid) + self.assertEqual(response.data.email, user.email) + self.assertEqual(response.data.display_name, user.display_name) + self.assertEqual(response.data.photo_url, user.photo_url) + + @patch('service.DefaultService.UserRepository.getEmailUserByIdFix') + @patch('service.DefaultService.get_user') + @patch('service.DefaultService.check_email') + @patch('service.DefaultService.sf.check_email_service',side_effect=Exception("Unexpected Error")) + def test_server_error(self, mock_support_function,mock_check_email, mock_get_user, mock_getEmailUserByIdFix): + request = Mock(spec=req.RequestInfoUser) + request.user_id = '1' + #1 of the 3 cases below + # mock_get_user.side_effect = Exception("Unexpected Error") + # mock_getEmailUserByIdFix.side_effect = Exception("Unexpected Error") + response = info_user(request) + self.assertEqual(response.status, 500) + self.assertIn("Server Error: Unexpected Error", response.data.message) + +class TestIsMe(unittest.TestCase): + + @patch('service.DefaultService.check_email_token', return_value=False) + def test_none_token(self, mock_check_email_token): + request = Mock(spec=req.RequestIsMe) + request.token = None + response = is_me(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "token is empty") + + @patch('service.DefaultService.check_email_token', return_value=False) + def test_invalid_token(self, mock_check_email_token): + request = Mock(spec=req.RequestIsMe) + request.token = "invalid_token" + response = is_me(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + + @patch('service.DefaultService.UserRepository.getUserByEmail') + @patch('service.DefaultService.check_email_token') + def test_valid_token(self, mock_check_email_token, mock_getUserByEmail): + request = Mock(spec=req.RequestIsMe) + request.token = "valid_token" + mock_check_email_token.return_value = "user@example.com" + user = Mock() + user.id = "1" + mock_getUserByEmail.return_value = user + response = is_me(request) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.user_id, 1) + + @patch('service.DefaultService.check_email_token') + @patch('service.DefaultService.UserRepository.getUserByEmail') + def test_server_error(self,mock_user_repo, mock_check_email_token): + request = Mock(spec=req.RequestIsMe) + request.token = "some_token" + #1 of the 2 cases below or all cases + mock_user_repo.side_effect = Exception("Unexpected Error") + # mock_check_email_token.side_effect = Exception("Unexpected Error") + response = is_me(request) + self.assertEqual(response.status, 500) + self.assertIn("Server Error", response.data.message) + +import io +from io import BytesIO +from fastapi import UploadFile +from io import BytesIO +import tempfile +class TestUpLoadFile(unittest.TestCase): + @patch('service.DefaultService.UserRepository.getEmailUserByIdFix') + @patch('service.DefaultService.cloudinary.uploader.upload') + @patch('service.DefaultService.check_email') + @patch('service.DefaultService.allowed_file') + def test_upload_image_success(self, mock_allowed_file, mock_check_email, mock_upload, mock_get_email): + mock_get_email.return_value = ["test@example.com"] + mock_check_email.return_value = True + mock_allowed_file.return_value = True + mock_upload.return_value = {"secure_url": "https://example.com/image.png"} + + file_content = b"test image content" + file = io.BytesIO(file_content) + file.name = "test_image.png" + + mock_request = MagicMock() + mock_request.user_id = 1 + mock_request.files = MagicMock() + mock_request.files.file = file + mock_request.files.filename = file.name + response = upload_image_service(mock_request) + + self.assertIsInstance(response, ResponseUploadImage) + self.assertEqual(response.status, 200) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.url, "https://example.com/image.png") + + @patch('service.DefaultService.UserRepository.getEmailUserByIdFix') + @patch('service.DefaultService.cloudinary.uploader.upload') + @patch('service.DefaultService.check_email') + @patch('service.DefaultService.allowed_file') + def test_upload_image_invalid_filetype(self, mock_allowed_file, mock_check_email, mock_upload, mock_get_email): + mock_get_email.return_value = ["test@example.com"] + mock_check_email.return_value = True + mock_allowed_file.return_value = False + mock_upload.return_value = {"secure_url": "https://example.com/image.png"} + + file_content = b"test image content" + file = io.BytesIO(file_content) + file.name = "test_image.txt" + + mock_request = MagicMock() + mock_request.user_id = 1 + mock_request.files = MagicMock() + mock_request.files.file = file + mock_request.files.filename = file.name + response = upload_image_service(mock_request) + + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 415) + self.assertEqual(response.data.message, "File type not allow") + + @patch('service.DefaultService.UserRepository.getEmailUserByIdFix') + @patch('service.DefaultService.cloudinary.uploader.upload') + @patch('service.DefaultService.check_email') + @patch('service.DefaultService.allowed_file') + def test_upload_image_id_not_exist(self, mock_allowed_file, mock_check_email, mock_upload, mock_get_email): + mock_get_email.return_value = None + mock_request = MagicMock() + mock_request.user_id = 1 + mock_request.files = [] + response = upload_image_service(mock_request) + + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Id not exist") + + @patch('service.DefaultService.UserRepository.getEmailUserByIdFix') + @patch('service.DefaultService.cloudinary.uploader.upload') + @patch('service.DefaultService.check_email') + @patch('service.DefaultService.allowed_file') + def test_upload_image_email_empty(self, mock_allowed_file, mock_check_email, mock_upload, mock_get_email): + mock_get_email.return_value = (None,) + mock_request = MagicMock() + mock_request.user_id = 1 + mock_request.files = [] + response = upload_image_service(mock_request) + + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email is empty") + + @patch('service.DefaultService.UserRepository.getEmailUserByIdFix') + @patch('service.DefaultService.cloudinary.uploader.upload') + @patch('service.DefaultService.check_email',return_value=False) + @patch('service.DefaultService.allowed_file') + def test_upload_image_email_invalid(self, mock_allowed_file, mock_check_email, mock_upload, mock_get_email): + mock_get_email.return_value = ("20133118",) + mock_request = MagicMock() + mock_request.user_id = 1 + mock_request.files = [] + response = upload_image_service(mock_request) + + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email invalid") + + @patch('service.DefaultService.UserRepository.getEmailUserByIdFix') + @patch('service.DefaultService.cloudinary.uploader.upload') + @patch('service.DefaultService.check_email', return_value=False) + @patch('service.DefaultService.allowed_file') + def test_upload_image_server_err(self, mock_allowed_file, mock_check_email, mock_upload, mock_get_email): + mock_get_email.side_effect = Exception("Unexpected Error") + mock_request = MagicMock() + mock_request.user_id = 1 + mock_request.files = [] + response = upload_image_service(mock_request) + + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/tests/test_service/test_FileService.py b/tests/test_service/test_FileService.py new file mode 100644 index 0000000000000000000000000000000000000000..1226b815a6160a04917dcbfbc167c0a9e0a8b684 --- /dev/null +++ b/tests/test_service/test_FileService.py @@ -0,0 +1,470 @@ +import unittest +from unittest.mock import patch,MagicMock +import sys +import os +app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) +sys.path.insert(0, app_path) +from fastapi import UploadFile +from io import BytesIO +import tempfile +from service.FileService import deleteFile,download_folder,download_file,upload_files,deleteAllFile,listNameFiles +from request.RequestFile import RequestDeleteAllFile,RequestDeleteFile,RequestDownLoadFile,RequestDownLoadFolder,RequestGetNameFile,RequestUploadFile +from response import ResponseFile as res + +class TestDeleteFile(unittest.TestCase): + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service',return_value = 'example@example.com') + def test_delete_file_success(self,mock_support_function,mock_user_repo): + user_id = "1" + email = 'example@example.com' + name_file = "test1.pdf" + request = RequestDeleteFile(user_id=user_id,name_file=name_file) + response = deleteFile(request) + self.assertIsInstance(response, res.ResponseDeleteFile) + self.assertEqual(response.status, 200) + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400,data=res.Message( + message="Id not exist"))) + def test_delete_file_id_not_exist(self, mock_support_function, mock_user_repo): + user_id = "1" + email = 'example@example.com' + name_file = "test1.pdf" + + request = RequestDeleteFile(user_id=user_id,name_file=name_file) + response = deleteFile(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='Id not exist')) + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty"))) + def test_delete_file_email_empty(self,mock_support_function, mock_user_repo): + user_id = "1" + email = None + name_file = "test1.pdf" + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + request = RequestDeleteFile(user_id=user_id,name_file=name_file) + response = deleteFile(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='Email is empty')) + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid"))) + def test_delete_file_email_invalid(self,mock_support_function, mock_user_repo): + user_id = "1" + email = "201333" + name_file = "test1.pdf" + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + request = RequestDeleteFile(user_id=user_id,name_file=name_file) + response = deleteFile(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='Email invalid')) + + @patch('service.FileService.UserRepository.getEmailUserByIdFix') + @patch('service.FileService.sf_dropbox.delete_file') + @patch('service.FileService.sf.check_email_service', return_value='example@example.com') + def test_delete_file_server_error(self, mock_support_function, mock_delete_file,mock_user_repo): + user_id = "1" + name_file = "test1.pdf" + mock_delete_file.side_effect = Exception("Some error") + request = RequestDeleteFile(user_id=user_id,name_file=name_file) + response = deleteFile(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, f"delete {name_file} error") + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value='example@example.com') + def test_delete_file_namefile_empty(self,mock_support_function, mock_user_repo): + user_id = "1" + email = "201333@gmail.com" + name_file = "" + request = RequestDeleteFile(user_id=user_id,name_file=name_file) + response = deleteFile(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='Name file is empty')) + +class TestDeleteAllFile(unittest.TestCase): + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf_dropbox.delete_all_files_in_folder',return_value = True) + @patch('service.FileService.sf.check_email_service', return_value='example@example.com') + def test_delete_all_file_success(self,mock_sf,mock_delete_folder,mock_user_repo): + user_id = "1" + email = 'example@example.com' + request = RequestDeleteAllFile(user_id=user_id) + response = deleteAllFile(request) + self.assertIsInstance(response, res.ResponseDeleteAllFile) + self.assertEqual(response.status, 200) + self.assertEqual(response.data, res.Message(message='Delete all file success')) + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Id not exist"))) + def test_delete_all_file_id_not_exist(self,mock_sf,mock_user_repo): + user_id = "1" + request = RequestDeleteAllFile(user_id=user_id) + response = deleteAllFile(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='Id not exist')) + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty"))) + def test_delete_all_file_email_empty(self,mock_sf,mock_user_repo): + user_id = "1" + email = None + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + request = RequestDeleteAllFile(user_id=user_id) + response = deleteAllFile(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='Email is empty')) + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid"))) + def test_delete_all_file_email_invalid(self, mock_sf, mock_user_repo): + user_id = "1" + email = "201333" + request = RequestDeleteAllFile(user_id=user_id) + response = deleteAllFile(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='Email invalid')) + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf_dropbox.delete_all_files_in_folder') + @patch('service.FileService.sf.check_email_service', return_value="20133@gmail.com") + def test_delete_all_file_server_err(self,mock_sf,mock_delete_folder,mock_user_repo): + user_id = "1" + mock_delete_folder.side_effect = Exception("Some error") + request = RequestDeleteAllFile(user_id=user_id) + response = deleteAllFile(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 500) + self.assertEqual(response.data, res.Message(message='Delete all file error')) + +class TestListNameFiles(unittest.TestCase): + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf_dropbox.list_files') + @patch('service.FileService.sf.check_email_service', return_value="20133118@gmail.com") + def test_list_name_file_success(self,mock_sf, mock_list_files, mock_user_repo): + user_id = "1" + email = "quangphuc@gmail.com" + list_files = [ + 'demo1.pdf', 'CV_VoNhuY_Java.pdf', 'VanHoangLuong_DangXuanBach_TLCN.docx', + 'THÔNG-TIN-TUYỂN-DỤNG-Java.pdf', 'baitap_qlpv_nhom14.docx', 'PMBOK2012-5rd Edition.pdf', + 'BaoCaoThucTapTotnghiep_20133059_Fpt_Software.docx' + ] + mock_list_files.return_value = list_files + request = RequestGetNameFile(user_id=user_id) + response = listNameFiles(request) + self.assertIsInstance(response, res.ResponseGetNameFile) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.files, list_files) + self.assertEqual(len(response.data.files), 7) + + @patch('service.FileService.UserRepository.getEmailUserByIdFix') + @patch('service.FileService.sf_dropbox.list_files') + @patch('service.FileService.sf.check_email_service', side_effect=Exception("Some error")) + def test_listNameFiles_server_error(self, mock_sf, mock_list_files, mock_getEmailUserByIdFix): + request = RequestGetNameFile(user_id="1") + response = listNameFiles(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Id not exist"))) + def test_list_name_files_id_not_exist(self, mock_sf, mock_user_repo): + user_id = "1" + email = 'example@example.com' + name_file = "test1.pdf" + request = RequestGetNameFile(user_id=user_id) + response = listNameFiles(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='Id not exist')) + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty"))) + def test_list_name_files_email_empty(self,mock_sf, mock_user_repo): + user_id = "1" + email = None + name_file = "test1.pdf" + request = RequestGetNameFile(user_id=user_id) + response = listNameFiles(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='Email is empty')) + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid"))) + def test_list_name_files_email_invalid(self, mock_sf, mock_user_repo): + user_id = "1" + email = "201333" + name_file = "test1.pdf" + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + request = RequestGetNameFile(user_id=user_id) + response = listNameFiles(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='Email invalid')) + +class TestDownLoadFolder(unittest.TestCase): + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service',return_value="example@example.com") + def test_download_folder_success(self,mock_sf, mock_user_repo): + user_id = "1" + email = 'example@example.com' + request = RequestDownLoadFolder(user_id=user_id) + response = download_folder(request) + self.assertIsInstance(response, res.ResponseDownloadFolder) + self.assertEqual(response.status, 200) + self.assertEqual(response.data, res.Message(message=f'Downloaded folder {email} success')) + + @patch('service.FileService.UserRepository.getEmailUserByIdFix') + @patch('service.FileService.sf_dropbox.download_folder') + @patch('service.FileService.sf.check_email_service', return_value="example@gmail.com") + def test_download_folder_server_error(self, mock_sf, mock_download_folder, mock_getEmailUserByIdFix): + mock_download_folder.side_effect = Exception('Test exception') + request = RequestDownLoadFolder(user_id= "1") + response = download_folder(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server error") + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Id not exist"))) + def test_download_folder_id_not_exist(self,mock_sf,mock_user_repo): + user_id = "1" + request = RequestDownLoadFolder(user_id=user_id) + response = download_folder(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='Id not exist')) + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty"))) + def test_download_folder_email_empty(self,mock_sf, mock_user_repo): + user_id = "1" + email = None + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + request = RequestDownLoadFolder(user_id=user_id) + response = download_folder(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='Email is empty')) + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid"))) + def test_download_folder_email_invalid(self,mock_sf, mock_user_repo): + user_id = "1" + email = "201333" + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + request = RequestDownLoadFolder(user_id=user_id) + response = download_folder(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='Email invalid')) + +class TestDownLoadFile(unittest.TestCase): + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value="quangphuc@gmail.com") + def test_download_file_success(self, mock_sf, mock_user_repo): + user_id = "1" + email = "quangphuc@gmail.com" + name_file = "demo1.pdf" + request = RequestDownLoadFile(user_id=user_id,name_file=name_file) + response = download_file(request) + self.assertIsInstance(response, res.ResponseDownloadFile) + self.assertEqual(response.status, 200) + self.assertEqual(response.data, res.Message(message=f"Downloaded file '{name_file}' by email: '{email}' success")) + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Id not exist"))) + def test_download_file_id_not_exist(self, mock_sf,mock_user_repo): + user_id = "1" + email = "quangphuc@gmail.com" + name_file = "demo1.pdf" + request = RequestDownLoadFile(user_id=user_id,name_file=name_file) + response = download_file(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='Id not exist')) + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty"))) + def test_download_file_email_empty(self,mock_sf, mock_user_repo): + user_id = "1" + email = None + name_file = "demo1.pdf" + request = RequestDownLoadFile(user_id=user_id,name_file=name_file) + response = download_file(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='Email is empty')) + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid"))) + def test_download_file_email_invalid(self, mock_sf, mock_user_repo): + user_id = "1" + email = "201333" + name_file = "demo1.pdf" + request = RequestDownLoadFile(user_id=user_id,name_file=name_file) + response = download_file(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='Email invalid')) + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value="20133@gmail.com") + def test_download_file_name_file_empty(self,mock_sf, mock_user_repo): + user_id = "1" + email = "201333@gmail.com" + name_file = "" + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + request = RequestDownLoadFile(user_id=user_id,name_file=name_file) + response = download_file(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='name_file is empty')) + + @patch('service.FileService.UserRepository.getEmailUserByIdFix') + @patch('service.FileService.sf_dropbox.search_and_download_file') + @patch('service.FileService.sf.check_email_service', return_value="20133@gmail.com") + def test_download_file_server_error(self,mock_sf, mock_search_and_download_file, mock_getEmailUserByIdFix): + # mock_getEmailUserByIdFix.side_effect = Exception('Test exception') + mock_search_and_download_file.side_effect = Exception('Test exception') + request = RequestDownLoadFile(user_id= "1",name_file="test1.txt") + response = download_file(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server error") + +class TestUploadFileService(unittest.TestCase): + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid"))) + def test_upload_files_invalid_email(self, mock_sf, mock_user_repo): + user_id = "1" + email = "20133118" + request = RequestUploadFile(user_id=user_id, files=[]) + response = upload_files(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email invalid") + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty"))) + def test_upload_files_empty_email(self, mock_sf, mock_user_repo): + user_id = "1" + email = None + request = RequestUploadFile(user_id=user_id, files=[]) + response = upload_files(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email is empty") + + @patch('service.FileService.UserRepository') + @patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Id not exist"))) + def test_upload_files_id_not_exist(self, mock_sf, mock_user_repo): + user_id = "1" + email = 'mang1@gmail.com' + mock_user_repo.getEmailUserByIdFix.return_value = None + request = RequestUploadFile(user_id=user_id, files=[]) + response = upload_files(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Id not exist") + + @patch('service.FileService.sf_dropbox.upload_file') + @patch('service.FileService.UserRepository.getEmailUserByIdFix') + @patch('service.FileService.allowed_file') + @patch('service.FileService.check_email') + @patch('service.FileService.os.makedirs') + @patch('service.FileService.sf.check_email_service', return_value="mang1@gmail.com") + @patch('builtins.open', new_callable=unittest.mock.mock_open) + def test_upload_files_success(self, mock_open,mock_sf, mock_makedirs, mock_check_email, mock_allowed_file, mock_get_email_user_by_id, mock_upload_file): + user_id = "1" + email = 'mang1@gmail.com' + mock_get_email_user_by_id.return_value = (email,) + mock_check_email.return_value = True + mock_allowed_file.return_value = True + file_content = b"Test file content" + file = UploadFile(filename='test.pdf', file=BytesIO(file_content)) + with tempfile.TemporaryDirectory() as temp_dir: + temp_dir_path = os.path.join(temp_dir, email) + os.makedirs(temp_dir_path, exist_ok=True) + file_path = os.path.join(temp_dir_path, file.filename) + mock_open.return_value.write.side_effect = lambda content: None if content == file_content else None + mock_upload_file.side_effect = lambda src, dst: None + request = RequestUploadFile(user_id=user_id, files=[file]) + mock_makedirs.side_effect = lambda path, exist_ok: None + response = upload_files(request) + self.assertIsInstance(response, res.ResponseUploadedFile) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.message, "Load file success") + # Adjust the expected call to match the actual call + expected_src_path = os.path.join("/code/temp", email, file.filename).replace("\\", "/") + expected_dst_path = f"/{email}/{file.filename}" + actual_src_path, actual_dst_path = mock_upload_file.call_args[0] + actual_src_path = actual_src_path.replace("\\", "/") + print(actual_dst_path) + print(actual_src_path) + assert expected_src_path == actual_src_path and expected_dst_path == actual_dst_path + + @patch('service.FileService.sf_dropbox.upload_file') + @patch('service.FileService.UserRepository.getEmailUserByIdFix') + @patch('service.FileService.allowed_file') + @patch('service.FileService.check_email') + @patch('service.FileService.os.makedirs') + @patch('service.FileService.shutil.copyfileobj') + @patch('service.FileService.sf.check_email_service', return_value="mang1@gmail.com") + def test_upload_files_invalid_file_type(self,mock_sf, mock_copyfileobj, mock_makedirs, mock_check_email, mock_allowed_file, mock_get_email_user_by_id, mock_upload_file): + user_id = "1" + email = 'mang1@gmail.com' + mock_get_email_user_by_id.return_value = (email,) + mock_check_email.return_value = True + mock_allowed_file.return_value = False + file_content = b"Test file content" + file = UploadFile(filename='test.exe', file=BytesIO(file_content)) + request = RequestUploadFile(user_id=user_id, files=[file]) + response = upload_files(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 415) + self.assertEqual(response.data.message, "File type not allow") + mock_upload_file.assert_not_called() + + @patch('service.FileService.UserRepository.getEmailUserByIdFix') + @patch('service.FileService.sf_dropbox.upload_file') + @patch('service.FileService.sf.check_email_service', return_value="test_email@example.com") + def test_upload_files_error_handling(self,mock_sf, mock_upload_file, mock_getEmailUserByIdFix): + mock_upload_file.side_effect = Exception('Test exception') + request = MagicMock() + request.user_id = "1" + request.files = [ + MagicMock(filename='test_file.txt', file=MagicMock()) + ] + response = upload_files(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Load file error") + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/tests/test_service/test_LoginService.py b/tests/test_service/test_LoginService.py new file mode 100644 index 0000000000000000000000000000000000000000..b91a8e8cd9e43e32c9fe0162ee29bc1effad8d9d --- /dev/null +++ b/tests/test_service/test_LoginService.py @@ -0,0 +1,934 @@ +import unittest +import sys +import os +app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) +sys.path.insert(0, app_path) +from service import LoginService +from request import RequestLogin as req +from response import ResponseLogin as res +from unittest.mock import patch, Mock,MagicMock +from typing import Optional + +class TestLoginFunction(unittest.TestCase): + @patch('service.LoginService.check_email') + @patch('service.LoginService.get_user1') + @patch('service.LoginService.sign_in_with_email_and_password') + @patch('service.LoginService.signJWT') + @patch('service.LoginService.sf.check_email_empty_invalid',return_value=True) + def test_login_success(self,mock_sf, mock_signJWT, mock_sign_in, mock_get_user, mock_check_email): + request = req.RequestLoginEmail(email="test@example.com", password="password123") + mock_check_email.return_value = True + mock_get_user.return_value = Mock() + mock_sign_in.return_value = Mock() + mock_signJWT.return_value = { + "access_token": "fake_access_token", + "refresh_token": "fake_refresh_token", + "expires_in": 3600, + "session_id": "fake_session_id" + } + response = LoginService.login(request) + self.assertIsInstance(response, res.ResponseLoginEmail) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.access_token, "fake_access_token") + self.assertEqual(response.data.refresh_token, "fake_refresh_token") + self.assertEqual(response.data.expires_in, 3600) + self.assertEqual(response.data.session_id, "fake_session_id") + + @patch('service.LoginService.get_user1') + @patch('service.LoginService.sign_in_with_email_and_password') + @patch('service.LoginService.signJWT') + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) + def test_login_server_error(self, mock_sf,mock_signJWT, mock_sign_in_with_email_and_password, mock_get_user1): + mock_signJWT.side_effect = Exception("Error") + mock_sign_in_with_email_and_password.side_effect = Exception("Error") + mock_get_user1.side_effect = Exception("Error") + request = MagicMock() + request.email = 'test@example.com' + request.password = 'password' + response = LoginService.login(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty")) +) + def test_login_email_empty(self,mock_sf): + request = req.RequestLoginEmail(email=None, password="password123") + response = LoginService.login(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email is empty") + + @patch('service.LoginService.check_email') + @patch('service.LoginService.sf.check_email_empty_invalid', + return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + ) + def test_login_email_invalid(self,mock_sf, mock_check_email): + request = req.RequestLoginEmail(email="20133118", password="password123") + mock_check_email.return_value = False + response = LoginService.login(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email invalid") + + @patch('service.LoginService.check_email') + @patch('service.LoginService.sf.check_email_empty_invalid', + return_value= True) + def test_login_password_empty(self, mock_sf, mock_check_email): + request = req.RequestLoginEmail(email="test@example.com", password=None) + mock_check_email.return_value = True + response = LoginService.login(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Password is empty") + + @patch('service.LoginService.check_email') + @patch('service.LoginService.get_user1') + @patch('service.LoginService.sf.check_email_empty_invalid', + return_value=True) + def test_login_email_not_exists(self,mock_sf, mock_get_user, mock_check_email): + request = req.RequestLoginEmail(email="test@example.com", password="password123") + mock_check_email.return_value = True + mock_get_user.return_value = None + response = LoginService.login(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 425) + self.assertEqual(response.data.message, "Email not exits") + + @patch('service.LoginService.check_email') + @patch('service.LoginService.get_user1') + @patch('service.LoginService.sign_in_with_email_and_password') + @patch('service.LoginService.sf.check_email_empty_invalid', + return_value=True) + def test_login_email_or_password_error(self,mock_sf, mock_sign_in, mock_get_user, mock_check_email): + request = req.RequestLoginEmail(email="test@example.com", password="wrongpassword") + mock_get_user.return_value = Mock() + mock_sign_in.return_value = None + response = LoginService.login(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 425) + self.assertEqual(response.data.message, "Passwords do not match") + + @patch('service.LoginService.check_email') + @patch('service.LoginService.get_user1') + @patch('service.LoginService.sign_in_with_email_and_password') + @patch('service.LoginService.signJWT') + @patch('service.LoginService.sf.check_email_empty_invalid', + return_value=True) + def test_login_invalid_authorization_code(self,mock_sf, mock_signJWT, mock_sign_in, mock_get_user, mock_check_email): + request = req.RequestLoginEmail(email="test@example.com", password="password123") + mock_get_user.return_value = Mock() + mock_sign_in.return_value = Mock() + mock_signJWT.return_value = False + response = LoginService.login(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Invalid authorization code.") + +class TestLoginGoogle(unittest.TestCase): + @patch('service.LoginService.check_email') + @patch('service.LoginService.get_user1') + @patch('service.LoginService.sign_in_with_email_and_password') + @patch('service.LoginService.signJWT') + @patch('service.LoginService.sf.check_email_empty_invalid', + return_value=True) + @patch('service.LoginService.verify_token_google',return_value=True) + def test_login_google_success(self, mock_check_gg,mock_sf, mock_signJWT, mock_sign_in, mock_get_user, mock_check_email): + request = req.RequestLoginGoogle(email="test@example.com",token_google ="abcde") + mock_get_user.return_value = Mock() + mock_sign_in.return_value = Mock() + mock_signJWT.return_value = { + "access_token": "fake_access_token", + "refresh_token": "fake_refresh_token", + "expires_in": 3600, + "session_id": "fake_session_id" + } + response = LoginService.login_google(request) + self.assertIsInstance(response, res.ResponseLoginGoogle) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.access_token, "fake_access_token") + self.assertEqual(response.data.refresh_token, "fake_refresh_token") + self.assertEqual(response.data.expires_in, 3600) + self.assertEqual(response.data.session_id, "fake_session_id") + + @patch('service.LoginService.get_user1') + @patch('service.LoginService.signJWT') + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) + @patch('service.LoginService.verify_token_google', return_value=True) + def test_login_google_server_error(self, mock_gg,mock_sf, mock_signJWT, mock_get_user1): + mock_signJWT.side_effect = Exception('Test exception') + request = MagicMock() + request.email = 'test@example.com' + response = LoginService.login_google(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty"))) + @patch('service.LoginService.verify_token_google', return_value=True) + def test_login_google_email_empty(self,mock_gg,mock_sf): + request = req.RequestLoginGoogle(email=None) + response = LoginService.login_google(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email is empty") + + @patch('service.LoginService.sf.check_email_empty_invalid', + return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid"))) + @patch('service.LoginService.verify_token_google', return_value=True) + def test_login_email_invalid(self,mock_gg,mock_sf): + request = req.RequestLoginGoogle(email="20133118") + response = LoginService.login_google(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email invalid") + + @patch('service.LoginService.check_email') + @patch('service.LoginService.get_user1') + @patch('service.LoginService.sf.check_email_empty_invalid', + return_value=True) + @patch('service.LoginService.verify_token_google', return_value=True) + def test_login_google_email_not_exists(self,mock_gg,mock_sf, mock_get_user, mock_check_email): + request = req.RequestLoginGoogle(email="test@example.com", token_google="abcde") + mock_check_email.return_value = True + mock_get_user.return_value = None + response = LoginService.login_google(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 425) + self.assertEqual(response.data.message, "Email not exist") + +class TestUpdateUserInfoFunction(unittest.TestCase): + @patch('service.LoginService.UserRepository.getEmailUserByIdFix') + @patch('service.LoginService.check_email') + @patch('service.LoginService.get_user1') + @patch('service.LoginService.UserInfoRepository.getUserInfo') + @patch('service.LoginService.UserInfoRepository.updateUserInfo') + @patch('service.LoginService.UserInfoRepository.addUserInfo') + @patch('service.LoginService.update_info_user') + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) + @patch('service.LoginService.sf.check_email_service', return_value="old_email@example.com") + def test_update_user_info_success_existing_user(self, mock_check1, mock_check2, mock_update_info_user, mock_add_user_info, mock_update_user_info, mock_get_user_info, mock_get_user, mock_check_email, mock_get_email_by_id): + request = req.RequestUpdateUserInfo( + user_id = "1", + email="new_email@example.com", + uid="uid123", + display_name="New Name", + photo_url="http://photo.url" + ) + mock_get_user.return_value = Mock() # Simulate user exists + mock_get_user_info.return_value = Mock() # Simulate user info exists + response = LoginService.update_user_info(request) + self.assertEqual(response.status, 200) + self.assertIsInstance(response, res.ResponseUpdateUserInfo) + self.assertEqual(response.data.message, "User info updated successfully") + + @patch('service.LoginService.get_user1') + @patch('service.LoginService.UserInfoRepository.getUserInfo') + @patch('service.LoginService.UserInfoRepository.updateUserInfo') + @patch('service.LoginService.UserInfoRepository.addUserInfo') + @patch('service.LoginService.update_info_user') + @patch('service.LoginService.UserRepository.getEmailUserByIdFix') + @patch('service.LoginService.sf.check_email_empty_invalid', side_effect=Exception("Error")) + @patch('service.LoginService.sf.check_email_service', return_value="old_email@example.com") + def test_update_user_info_server_error(self,mock_check,mock_check_2,mock_get_email, mock_update_info_user, mock_addUserInfo, mock_updateUserInfo, mock_getUserInfo, mock_get_user1): + request = MagicMock() + request.email = 'test@example.com' + request.user_id = 'test_user_id' + request.uid = 'test_uid' + request.display_name = 'Test User' + request.photo_url = 'https://example.com/photo.jpg' + response = LoginService.update_user_info(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + + @patch('service.LoginService.UserRepository.getEmailUserByIdFix') + @patch('service.LoginService.check_email') + @patch('service.LoginService.get_user1') + @patch('service.LoginService.UserInfoRepository.getUserInfo') + @patch('service.LoginService.UserInfoRepository.updateUserInfo') + @patch('service.LoginService.UserInfoRepository.addUserInfo') + @patch('service.LoginService.update_info_user') + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) + @patch('service.LoginService.sf.check_email_service', return_value="old_email@example.com") + def test_update_user_info_success_new_user_info(self,mock_check1, mock_check2, mock_update_info_user, mock_add_user_info, mock_update_user_info, mock_get_user_info, mock_get_user, mock_check_email, mock_get_email_by_id): + request = req.RequestUpdateUserInfo( + user_id = "1", + email = "new_email@example.com", + uid="uid123", + display_name="New Name", + photo_url="http://photo.url" + ) + mock_get_user.return_value = Mock() + mock_get_user_info.return_value = None + response = LoginService.update_user_info(request) + self.assertEqual(response.status, 200) + self.assertIsInstance(response, res.ResponseUpdateUserInfo) + self.assertEqual(response.data.message, "User info updated successfully") + mock_update_user_info.assert_not_called() + mock_add_user_info.assert_called_once() + mock_update_info_user.assert_called_once() + + + @patch('service.LoginService.UserRepository.getEmailUserByIdFix') + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) + @patch('service.LoginService.sf.check_email_service', return_value= res.ReponseError(status=400, data=res.Message( + message="Id not exist"))) + def test_update_user_info_id_not_exist(self, mock_check1,mock_check2,mock_get_email_by_id): + request = req.RequestUpdateUserInfo( + user_id= "1", + email="new_email@example.com", + uid="uid123", + display_name="New Name", + photo_url="http://photo.url" + ) + response = LoginService.update_user_info(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Id not exist") + + @patch('service.LoginService.UserRepository.getEmailUserByIdFix') + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) + @patch('service.LoginService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty"))) + def test_update_user_info_email_empty(self,mock_check1,mock_check2, mock_get_email_by_id): + request = req.RequestUpdateUserInfo( + user_id= "1", + email=None, + uid="uid123", + display_name="New Name", + photo_url="http://photo.url" + ) + response = LoginService.update_user_info(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email is empty") + + @patch('service.LoginService.UserRepository.getEmailUserByIdFix') + @patch('service.LoginService.check_email') + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) + @patch('service.LoginService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid"))) + def test_update_user_info_email_invalid(self, mock_check1, mock_check2, mock_check_email, mock_get_email_by_id): + request = req.RequestUpdateUserInfo( + email="invalid_email", + user_id= "1", + uid="uid123", + display_name="New Name", + photo_url="http://photo.url" + ) + response = LoginService.update_user_info(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email invalid") + + @patch('service.LoginService.UserRepository.getEmailUserByIdFix') + @patch('service.LoginService.check_email') + @patch('service.LoginService.get_user1') + @patch('service.LoginService.sf.check_email_service',return_value="new_email@example.com") + def test_update_user_info_email_or_password_error(self,mock_check1, mock_get_user, mock_check_email, mock_get_email_by_id): + request = req.RequestUpdateUserInfo( + user_id= "1", + email="new_email@example.com", + uid="uid123", + display_name="New Name", + photo_url="http://photo.url" + ) + mock_get_user.return_value = None + response = LoginService.update_user_info(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Not found user") + +class TestCheckInfoGoogle(unittest.TestCase): + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.check_email') + @patch('service.LoginService.UserInfoRepository') + @patch('service.LoginService.sf.check_email_service', return_value="test@gmail.com") + def test_check_info_google_success(self,mock_check1,mock_user_info_repo,mock_check_email,mock_user_repo): + user_id = "1" + email ="test@gmail.com" + mock_user_info_repo.getUserInfo.return_value = Mock() + request = req.RequestCheckInfoGoogle(user_id=user_id) + response = LoginService.check_info_google(request) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.check, True) + + @patch('service.LoginService.UserRepository.getEmailUserByIdFix') + @patch('service.LoginService.UserRepository.getEmailUserById') + @patch('service.LoginService.UserInfoRepository.getUserInfo') + @patch('service.LoginService.sf.check_email_service', side_effect = Exception("error")) + def test_check_info_google_server_error(self,mock_check1, mock_getUserInfo, mock_getEmailUserById, mock_getEmailUserByIdFix): + mock_getEmailUserByIdFix.side_effect = Exception('Test exception') + request = MagicMock() + request.user_id = "1" + response = LoginService.check_info_google(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.check_email') + @patch('service.LoginService.UserInfoRepository') + @patch('service.LoginService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Id not exist"))) + def test_check_info_google_id_not_exist(self,mock_check1, mock_user_info_repo,mock_check_email,mock_user_repo): + user_id = "1" + request = req.RequestCheckInfoGoogle(user_id=user_id) + response = LoginService.check_info_google(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Id not exist") + + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.check_email') + @patch('service.LoginService.UserInfoRepository') + @patch('service.LoginService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty"))) + def test_check_info_google_email_empty(self, mock_check1, mock_user_info_repo, mock_check_email,mock_user_repo): + user_id = "1" + email ="quangphuc@gmail.com" + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + mock_user_repo.getEmailUserById.return_value = None + request = req.RequestCheckInfoGoogle(user_id=user_id) + response = LoginService.check_info_google(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email is empty") + + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.check_email') + @patch('service.LoginService.UserInfoRepository') + @patch('service.LoginService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid"))) + def test_check_info_google_email_invalid(self,mock_check_1,mock_user_info_repo, mock_check_email,mock_user_repo): + user_id = "1" + email ="quangphuc" + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + mock_user_repo.getEmailUserById.return_value = (email,) + mock_check_email.return_value = False + request = req.RequestCheckInfoGoogle(user_id=user_id) + response = LoginService.check_info_google(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email invalid") + +class TestCheckInfoGoogleEmail(unittest.TestCase): + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.check_email') + @patch('service.LoginService.UserInfoRepository') + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) + def test_check_info_google_email_success(self,mock_check1, mock_user_info_repo,mock_check_email,mock_user_repo): + email ="test@gmail.com" + mock_user_info_repo.getUserInfo.return_value = Mock() + request = req.RequestCheckInfoGoogleEmail(email=email) + response = LoginService.check_info_google_email(request) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.check, True) + + @patch('service.LoginService.UserInfoRepository.getUserInfoByEmail') + @patch('service.LoginService.sf.check_email_empty_invalid', side_effect=Exception("error")) + def test_check_info_google_email_server_error(self, mock_check, mock_getUserInfoByEmail): + request = MagicMock() + request.email = 'test@example.com' + response = LoginService.check_info_google_email(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.check_email') + @patch('service.LoginService.UserInfoRepository') + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty")) +) + def test_check_info_google_by_email_email_empty(self,mock_check,mock_user_info_repo,mock_check_email,mock_user_repo): + email = None + request = req.RequestCheckInfoGoogleEmail(email=email) + response = LoginService.check_info_google_email(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email is empty") + + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.check_email') + @patch('service.LoginService.UserInfoRepository') + @patch('service.LoginService.sf.check_email_empty_invalid', + return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + ) + def test_check_info_google_email_invalid(self,mock_check,mock_user_info_repo,mock_check_email,mock_user_repo): + email ="quangphuc" + mock_check_email.return_value = False + request = req.RequestCheckInfoGoogleEmail(email=email) + response = LoginService.check_info_google_email(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email invalid") + +class TestCheckStateLogin(unittest.TestCase): + + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.check_email') + @patch('service.LoginService.UserInfoRepository') + @patch('service.LoginService.get_user1') + @patch('service.LoginService.UserLoginRepository') + @patch('service.LoginService.sf.check_email_service', return_value=True) + def test_check_state_login_success(self,mock_check,mock_user_login_repo,mock_get_user1,mock_user_info_repo,mock_check_email,mock_user_repo): + user_id = "1" + email ="test@gmail.com" + session_id = "session" + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + mock_check_email.return_value = True + mock_get_user1.return_value = Mock() + mock_user_login_repo.getUserSessionIdByUserEmail.return_value = session_id + request = req.RequestCheckStateLogin(user_id=user_id,session_id_now=session_id) + response = LoginService.check_state_login(request) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.check, True) + + @patch('service.LoginService.UserRepository.getEmailUserByIdFix') + @patch('service.LoginService.get_user1') + @patch('service.LoginService.UserLoginRepository.getUserSessionIdByUserEmail') + @patch('service.LoginService.sf.check_email_service', side_effect=Exception("error")) + def test_check_state_login_server_error(self,mock_check, mock_getUserSessionIdByUserEmail, mock_get_user1, mock_getEmailUserByIdFix): + request = MagicMock() + request.user_id = 'test_user_id' + request.session_id_now = 'test_session_id' + response = LoginService.check_state_login(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.check_email') + @patch('service.LoginService.UserInfoRepository') + @patch('service.LoginService.get_user1') + @patch('service.LoginService.UserLoginRepository') + @patch('service.LoginService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Id not exist"))) + def test_check_state_login_id_not_exits(self,mock_check,mock_user_login_repo,mock_get_user1,mock_user_info_repo,mock_check_email,mock_user_repo): + user_id = "1" + email ="test@gmail.com" + session_id = "session" + mock_user_repo.getEmailUserByIdFix.return_value = None + request = req.RequestCheckStateLogin(user_id=user_id,session_id_now=session_id) + response = LoginService.check_state_login(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Id not exist") + + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.check_email') + @patch('service.LoginService.UserInfoRepository') + @patch('service.LoginService.get_user1') + @patch('service.LoginService.UserLoginRepository') + @patch('service.LoginService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty"))) + def test_check_state_login_email_empty(self, mock_check, mock_user_login_repo,mock_get_user1,mock_user_info_repo,mock_check_email,mock_user_repo): + user_id = "1" + email = None + session_id = "session" + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + request = req.RequestCheckStateLogin(user_id=user_id,session_id_now=session_id) + response = LoginService.check_state_login(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email is empty") + + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.check_email') + @patch('service.LoginService.UserInfoRepository') + @patch('service.LoginService.get_user1') + @patch('service.LoginService.UserLoginRepository') + @patch('service.LoginService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid"))) + def test_check_state_login_email_invalid(self,mock_check,mock_user_login_repo,mock_get_user1,mock_user_info_repo,mock_check_email,mock_user_repo): + user_id = "1" + email = "20133" + session_id = "session" + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + mock_check_email.return_value = False + request = req.RequestCheckStateLogin(user_id=user_id,session_id_now=session_id) + response = LoginService.check_state_login(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email invalid") + + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.check_email') + @patch('service.LoginService.UserInfoRepository') + @patch('service.LoginService.get_user1') + @patch('service.LoginService.UserLoginRepository') + @patch('service.LoginService.sf.check_email_service', return_value=True) + def test_check_state_session_empty(self,mock_check,mock_user_login_repo,mock_get_user1,mock_user_info_repo,mock_check_email,mock_user_repo): + user_id = "1" + email = "20133@gmail.com" + session_id = None + request = req.RequestCheckStateLogin(user_id=user_id,session_id_now=session_id) + response = LoginService.check_state_login(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "session_id is empty") + + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.check_email') + @patch('service.LoginService.UserInfoRepository') + @patch('service.LoginService.get_user1') + @patch('service.LoginService.UserLoginRepository') + @patch('service.LoginService.sf.check_email_service', return_value=True) + def test_check_state_login_not_found(self, mock_check, mock_user_login_repo,mock_get_user1,mock_user_info_repo,mock_check_email,mock_user_repo): + user_id = "1" + email ="test@gmail.com" + session_id = "session" + mock_get_user1.return_value = None + mock_user_login_repo.getUserSessionIdByUserEmail.return_value = session_id + request = req.RequestCheckStateLogin(user_id=user_id,session_id_now=session_id) + response = LoginService.check_state_login(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Not found user") + +class TestSignUpFunction(unittest.TestCase): + + @patch('service.LoginService.sign_up_with_email_and_password') + @patch('service.LoginService.get_user1') + @patch('service.LoginService.check_email') + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) + def test_sign_up_success(self, mock_check, mock_check_email,mock_get_user1, mock_sign_up_with_email_and_password): + request = req.RequestSignUp( + email="new_user@example.com", + password="securepassword", + username="newuser" + ) + mock_get_user1.return_value = None # Simulate email does not exist + mock_sign_up_with_email_and_password.return_value = "new_user@example.com" + response = LoginService.sign_up(request) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.email, "new_user@example.com") + + @patch('service.LoginService.get_user1') + @patch('service.LoginService.sign_up_with_email_and_password') + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) + def test_sign_up_server_error(self, mock_check, mock_sign_up_with_email_and_password, mock_get_user1): + mock_get_user1.return_value = None + mock_sign_up_with_email_and_password.side_effect = Exception('Test exception') + request = MagicMock() + request.email = 'test@example.com' + request.password = 'test_password' + request.username = 'test_username' + response = LoginService.sign_up(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + + @patch('service.LoginService.check_email') + @patch('service.LoginService.sf.check_email_empty_invalid',return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty"))) + def test_sign_up_email_is_empty(self,mock_check, mock_check_email): + request = req.RequestSignUp( + email=None, + password="securepassword", + username="newuser" + ) + response = LoginService.sign_up(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email is empty") + + @patch('service.LoginService.check_email') + @patch('service.LoginService.sf.check_email_empty_invalid', + return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid"))) + def test_sign_up_email_invalid(self, mock_check, mock_check_email): + request = req.RequestSignUp( + email="invalid_email", + password="securepassword", + username="newuser" + ) + response = LoginService.sign_up(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email invalid") + + @patch('service.LoginService.check_email') + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) + def test_sign_up_password_empty(self,mock_check, mock_check_email): + request = req.RequestSignUp( + email="20133118@gmail.com", + password=None, + username="newuser" + ) + response = LoginService.sign_up(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "password is empty") + + @patch('service.LoginService.get_user1') + @patch('service.LoginService.check_email') + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) + def test_sign_up_email_exist(self, mock_check, mock_check_email, mock_get_user1): + request = req.RequestSignUp( + email="20133118@gmail.com", + password="password", + username="newuser" + ) + mock_get_user1.return_value = Mock() + response = LoginService.sign_up(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Email exist") + + @patch('service.LoginService.sign_up_with_email_and_password') + @patch('service.LoginService.get_user1') + @patch('service.LoginService.check_email') + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) + def test_sign_up_error(self, mock_check, mock_check_email,mock_get_user1,mock_sign_up_with_email_password): + request = req.RequestSignUp( + email="new_user@example.com", + password="securepassword", + username="newuser" + ) + mock_check_email.return_value = True + mock_get_user1.return_value = None # Simulate email does not exist + mock_sign_up_with_email_password.return_value = None + response = LoginService.sign_up(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Internal Server Error") + +class TestChangePassword(unittest.TestCase): + + @patch('service.LoginService.UserRepository.getEmailUserByIdFix') + @patch('service.LoginService.check_email') + @patch('service.LoginService.sign_in_with_email_and_password') + @patch('service.LoginService.auth') + @patch('service.LoginService.sf.check_email_service', return_value = "test@example.com") + def test_change_password_success(self,mock_check, mock_auth, mock_sign_in, mock_check_email, mock_get_email): + request = req.RequestChangePassword(user_id='123', new_password='new_password', current_password='current_password') + mock_get_email.return_value = ['test@example.com'] + mock_check_email.return_value = True + mock_sign_in.return_value = MagicMock() + mock_auth.get_user_by_email.return_value = MagicMock(uid='user_uid') + response = LoginService.change_password(request) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.message,"Update password success") + @patch('service.LoginService.UserRepository.getEmailUserByIdFix') + @patch('service.LoginService.sign_in_with_email_and_password') + @patch('service.LoginService.auth.get_user_by_email') + @patch('service.LoginService.auth.update_user') + @patch('service.LoginService.sf.check_email_empty_invalid', side_effect = Exception("error")) + def test_change_password_server_error(self, mock_check,mock_update_user, mock_get_user_by_email, mock_sign_in_with_email_and_password,mock_get_email): + request = MagicMock() + request.user_id = 'test_user_id' + request.new_password = 'new_password' + request.current_password = 'current_password' + response = LoginService.change_password(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error!!") + + @patch('service.LoginService.UserRepository.getEmailUserByIdFix') + @patch('service.LoginService.check_email') + @patch('service.LoginService.sign_in_with_email_and_password') + @patch('service.LoginService.auth') + + @patch('service.LoginService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Id not exist"))) + def test_change_password_id_not_exist(self, mock_check, mock_auth, mock_sign_in, mock_check_email, mock_get_email): + request = req.RequestChangePassword(user_id='123', new_password='new_password', current_password='current_password') + mock_get_email.return_value = None + response = LoginService.change_password(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message,"Id not exist") + + @patch('service.LoginService.UserRepository.getEmailUserByIdFix') + @patch('service.LoginService.check_email') + @patch('service.LoginService.sign_in_with_email_and_password') + @patch('service.LoginService.auth') + @patch('service.LoginService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty"))) + def test_change_password_email_is_empty(self,mock_check, mock_auth, mock_sign_in, mock_check_email, mock_get_email): + request = req.RequestChangePassword(user_id='123', new_password='new_password', current_password='current_password') + mock_get_email.return_value = (None,) + response = LoginService.change_password(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message,"Email is empty") + + @patch('service.LoginService.UserRepository.getEmailUserByIdFix') + @patch('service.LoginService.check_email') + @patch('service.LoginService.sign_in_with_email_and_password') + @patch('service.LoginService.auth') + @patch('service.LoginService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid"))) + def test_change_password_email_invalid(self, mock_check,mock_auth, mock_sign_in, mock_check_email, mock_get_email): + request = req.RequestChangePassword(user_id='123', new_password='new_password', current_password='current_password') + mock_get_email.return_value = "20133" + mock_check_email.return_value = False + response = LoginService.change_password(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message,"Email invalid") + + @patch('service.LoginService.UserRepository.getEmailUserByIdFix') + @patch('service.LoginService.check_email') + @patch('service.LoginService.sign_in_with_email_and_password') + @patch('service.LoginService.auth') + @patch('service.LoginService.sf.check_email_service', return_value = True) + def test_change_password_new_password_empty(self, mock_check, mock_auth, mock_sign_in, mock_check_email, mock_get_email): + request = req.RequestChangePassword(user_id='123', new_password= None, current_password='current_password') + mock_get_email.return_value = "20133@gmail.com" + mock_check_email.return_value = True + response = LoginService.change_password(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message,"new_password is empty") + + @patch('service.LoginService.UserRepository.getEmailUserByIdFix') + @patch('service.LoginService.check_email') + @patch('service.LoginService.sign_in_with_email_and_password') + @patch('service.LoginService.auth') + @patch('service.LoginService.sf.check_email_service', return_value="test@email.com") + def test_change_password_current_password_empty(self, mock_check, mock_auth, mock_sign_in, mock_check_email, mock_get_email): + request = req.RequestChangePassword(user_id='123', new_password= "new_password", current_password=None) + mock_get_email.return_value = "20133@gmail.com" + mock_check_email.return_value = True + response = LoginService.change_password(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message,"current_password is empty") + + @patch('service.LoginService.UserRepository.getEmailUserByIdFix') + @patch('service.LoginService.check_email') + @patch('service.LoginService.sign_in_with_email_and_password') + @patch('service.LoginService.auth') + @patch('service.LoginService.sf.check_email_service', return_value="test@email.com") + def test_change_password_current_password_not_valid(self, mock_check, mock_auth, mock_sign_in, mock_check_email, mock_get_email): + request = req.RequestChangePassword(user_id='123', new_password='new_password', current_password='current_password') + mock_check_email.return_value = True + mock_sign_in.return_value = None + response = LoginService.change_password(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message,"Current password not valid") + +class TestRefreshToken(unittest.TestCase): + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.auth123') + @patch('service.LoginService.sf.check_email_service', return_value="test@email.com") + def test_refresh_token_success(self,mock_check, mock_auth123, mock_UserRepository): + request = MagicMock() + request.user_id = "1" + request.token = "valid_token" + mock_UserRepository.getRefreshTokenUserById.return_value = "valid_refresh_token" + mock_auth123.get_refresh_token.return_value = { + "access_token": "new_access_token", + "refresh_token": "new_refresh_token", + "expires_in": 3600, + "session_id": "ABCDEF" + } + response = LoginService.refresh_token(request) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.token_new, "new_access_token") + + @patch('service.LoginService.UserRepository.getRefreshTokenUserById') + @patch('service.LoginService.UserRepository.getEmailUserByIdFix') + @patch('service.LoginService.check_email') + @patch('service.LoginService.auth123.get_refresh_token') + @patch('service.LoginService.UserRepository.updateAccessToken') + @patch('service.LoginService.sf.check_email_service', side_effect=Exception("Unexpected Error")) + def test_refresh_token_server_error(self, mock_check, mock_updateAccessToken, mock_get_refresh_token, + mock_check_email, mock_getEmailUserByIdFix, mock_getRefreshTokenUserById): + request = MagicMock() + request.user_id = '1' + request.token = 'test_token' + response = LoginService.refresh_token(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Id not exist"))) + def test_refresh_token_user_id_not_exist(self, mock_check, mock_UserRepository): + request = MagicMock() + request.user_id = 1 + request.token = "valid_token" + mock_UserRepository.getEmailUserByIdFix.return_value = None + response = LoginService.refresh_token(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Id not exist") + + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email is empty"))) + def test_refresh_token_email_empty(self, mock_check, mock_UserRepository): + request = MagicMock() + request.user_id = "1" + request.token = "valid_token" + mock_UserRepository.getEmailUserByIdFix.return_value = [None] + response = LoginService.refresh_token(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email is empty") + + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid"))) + def test_refresh_token_email_invalid(self, mock_check, mock_UserRepository): + request = MagicMock() + request.user_id = "1" + request.token = "valid_token" + mock_UserRepository.getEmailUserByIdFix.return_value = ["invalid_email"] + with patch('service.LoginService.check_email', return_value=False): + response = LoginService.refresh_token(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email invalid") + + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.sf.check_email_service', return_value="test@email.com") + def test_refresh_token_token_empty(self, mock_check, mock_UserRepository): + request = MagicMock() + request.user_id = "1" + request.token = None + mock_UserRepository.getEmailUserByIdFix.return_value = ["user@example.com"] + response = LoginService.refresh_token(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "token is empty") + + @patch('service.LoginService.UserRepository') + @patch('service.LoginService.auth123') + @patch('service.LoginService.sf.check_email_service', return_value="test@email.com") + def test_refresh_token_refresh_token_error(self, mock_check,mock_auth123, mock_UserRepository): + request = MagicMock() + request.user_id = "1" + request.token = "valid_token" + mock_UserRepository.getRefreshTokenUserById.return_value = "valid_refresh_token" + mock_auth123.get_refresh_token.return_value = { + "access_token": False, + "refresh_token": False, + "expires_in": 3600, + "session_id": "ABCDE" + } + response = LoginService.refresh_token(request) + self.assertEqual(response.status, 406) + self.assertEqual(response.data.message, "Refresh token error") + +class TestResetPassword(unittest.TestCase): + @patch('service.LoginService.check_email', return_value=True) + @patch('service.LoginService.get_user1', return_value={"email": "user@example.com"}) + @patch('service.LoginService.createOTPReset', return_value="123456") + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) + def test_reset_password_success(self, mock_check,mock_createOTPReset, mock_get_user1, mock_check_email): + request = MagicMock() + request.email = "user@example.com" + response = LoginService.reset_password(request) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.check, True) + self.assertEqual(response.otp, "123456") + + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=res.ReponseError(status=400, data=res.Message( + message="Email invalid"))) + + def test_reset_password_invalid_email(self, mock_check_email): + request = MagicMock() + request.email = "invalid_email" + response = LoginService.reset_password(request) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email invalid") + + @patch('service.LoginService.check_email', return_value=True) + @patch('service.LoginService.get_user1', return_value=None) + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) + def test_reset_password_user_not_found(self, mock_check, mock_get_user1, mock_check_email): + request = MagicMock() + request.email = "nonexistent@example.com" + response = LoginService.reset_password(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Email not exist") + + @patch('service.LoginService.check_email', return_value=True) + @patch('service.LoginService.get_user1') + @patch('service.LoginService.sf.check_email_empty_invalid', return_value=True) + def test_reset_password_server_error(self, mock_check, mock_get_user1, mock_check_email): + request = MagicMock() + mock_get_user1.side_effect = Exception("Error") + request.email = "nonexistent@example.com" + response = LoginService.reset_password(request) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/tests/test_service/test_MySQLService.py b/tests/test_service/test_MySQLService.py new file mode 100644 index 0000000000000000000000000000000000000000..64f64fcb77aa99b3367abac4ac322f884d22ef66 --- /dev/null +++ b/tests/test_service/test_MySQLService.py @@ -0,0 +1,426 @@ +import unittest +from unittest.mock import patch +from response import ResponseMySQL as res +import sys +import os + +app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) +sys.path.insert(0, app_path) +from entity import Database_Entity +from service.MySQLService import edit_chat, delete_chat, render_chat_history, load_chat_history +from request.RequestMySQL import RequestEditNameChat, RequestDeleteChat, RequestRenderChatHistory, \ + RequestLoadChatHistory +from response.ResponseMySQL import ResponseEditChat, ResponseDeleteChat, ReponseError, Message, \ + ResponseRenderChatHistory, UserInfoListResponse, ListUserChat, ResponseLoadChatHistory, ChatDetail, ListChatDeTail + + +class TestMySQLService(unittest.TestCase): + @patch('service.MySQLService.UserRepository') + @patch('service.MySQLService.ChatHistoryRepository') + @patch('service.MySQLService.sf') + def test_edit_chat_success(self, mock_support_function, mock_chat_history_repo, mock_user_repo): + user_id = "1" + email = 'example@example.com' + name_old = 'chat123' + name_new = 'chat1234' + mock_support_function.check_email_service.return_value = email + mock_chat_history_repo.getIdChatHistoryByUserIdAndNameChat.return_value = True + mock_chat_history_repo.getIdChatHistoryByUserIdAndNameChatNew.return_value = None + request = RequestEditNameChat(user_id=user_id, name_old=name_old, name_new=name_new) + response = edit_chat(request) + self.assertIsInstance(response, ResponseEditChat) + self.assertEqual(response.status, 200) + + @patch('service.MySQLService.UserRepository.getEmailUserByIdFix') + @patch('service.MySQLService.ChatHistoryRepository') + @patch('service.MySQLService.sf') + def test_edit_chat_server_error(self, mock_support_function, mock_chat_history_repo, mock_user_repo): + user_id = "1" + email = 'example@example.com' + name_old = 'chat123' + name_new = 'chat1234' + mock_support_function.check_email_service.side_effect = Exception("error") + request = RequestEditNameChat(user_id=user_id, name_old=name_old, name_new=name_new) + response = edit_chat(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + + @patch('service.MySQLService.UserRepository') + @patch('service.MySQLService.ChatHistoryRepository') + @patch('service.MySQLService.sf') + def test_edit_chat_id_not_exist(self, mock_support_function, mock_chat_history_repo, mock_user_repo): + user_id = "1" + name_old = 'chat123' + name_new = 'chat1234' + mock_support_function.check_email_service.return_value = ReponseError(status=400, data=res.Message( + message="Id not exist")) + request = RequestEditNameChat(user_id=user_id, name_old=name_old, name_new=name_new) + response = edit_chat(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Id not exist')) + + @patch('service.MySQLService.UserRepository') + @patch('service.MySQLService.ChatHistoryRepository') + @patch('service.MySQLService.sf') + def test_edit_chat_email_empty(self, mock_support_function, mock_chat_history_repo, mock_user_repo): + user_id = '1' + email = None + name_old = 'chat123' + name_new = 'chat1234' + mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + request = RequestEditNameChat(user_id=user_id, name_old=name_old, name_new=name_new) + response = edit_chat(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Email is empty')) + + @patch('service.MySQLService.UserRepository') + @patch('service.MySQLService.ChatHistoryRepository') + @patch('service.MySQLService.sf') + def test_edit_chat_email_in_valid(self, mock_support_function, mock_chat_history_repo, mock_user_repo): + user_id = "1" + email = "20133118" + name_old = 'chat123' + name_new = 'chat1234' + mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + + request = RequestEditNameChat(user_id=user_id, name_old=name_old, name_new=name_new) + response = edit_chat(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Email invalid')) + + @patch('service.MySQLService.UserRepository') + @patch('service.MySQLService.ChatHistoryRepository') + @patch('service.MySQLService.sf.check_email_service', return_value=True) + def test_edit_chat_name_old_empty(self, mock_support_function, mock_chat_history_repo, mock_user_repo): + user_id = "1" + email = "20133118@gmail.com" + name_old = "" + name_new = 'chat1234' + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + request = RequestEditNameChat(user_id=user_id, name_old=name_old, name_new=name_new) + response = edit_chat(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='name_old is empty')) + + @patch('service.MySQLService.UserRepository') + @patch('service.MySQLService.ChatHistoryRepository') + @patch('service.MySQLService.sf.check_email_service', return_value=True) + def test_edit_chat_name_new_empty(self, mock_support_function, mock_chat_history_repo, mock_user_repo): + user_id = "1" + email = "20133118@gmail.com" + name_old = 'chat123' + name_new = '' + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + request = RequestEditNameChat(user_id=user_id, name_old=name_old, name_new=name_new) + response = edit_chat(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='name_new is empty')) + + @patch('service.MySQLService.UserRepository') + @patch('service.MySQLService.ChatHistoryRepository') + @patch('service.MySQLService.sf.check_email_service', return_value=True) + def test_edit_chat_update_error(self, mock_support_function, mock_chat_history_repo, mock_user_repo): + user_id = "1" + email = "20133118@gmail.com" + name_old = 'chat123' + name_new = 'chat1234' + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + mock_chat_history_repo.getIdChatHistoryByUserIdAndNameChat.return_value = False + mock_chat_history_repo.getIdChatHistoryByUserIdAndNameChatNew.return_value = None + request = RequestEditNameChat(user_id=user_id, name_old=name_old, name_new=name_new) + response = edit_chat(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 500) + self.assertEqual(response.data, Message(message='Update chat error')) + + +class TestDeleteChat(unittest.TestCase): + @patch('service.MySQLService.UserRepository') + @patch('service.MySQLService.ChatHistoryRepository') + @patch('service.MySQLService.DetailChatRepository') + @patch('service.MySQLService.sf.check_email_service', return_value=True) + def test_delete_chat_success(self, mock_support_function, mock_detail_chat_repo, mock_chat_history_repo, + mock_user_repo): + user_id = "1" + email = 'example@example.com' + chat_name = 'test' + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + mock_detail_chat_repo.delete_chat_detail.return_value = True + mock_chat_history_repo.deleteChatHistory.return_value = True + request = RequestDeleteChat(user_id=user_id, chat_name=chat_name) + response = delete_chat(request) + self.assertIsInstance(response, ResponseDeleteChat) + self.assertEqual(response.status, 200) + + @patch('service.MySQLService.UserRepository') + @patch('service.MySQLService.ChatHistoryRepository') + @patch('service.MySQLService.DetailChatRepository') + @patch('service.MySQLService.sf.check_email_service', side_effect=Exception("Error")) + def test_delete_chat_server_error(self, mock_support_function, mock_detail_chat_repo, mock_chat_history_repo, + mock_user_repo): + user_id = "1" + email = 'example@example.com' + chat_name = 'test' + + mock_detail_chat_repo.delete_chat_detail.return_value = True + mock_chat_history_repo.deleteChatHistory.return_value = True + request = RequestDeleteChat(user_id=user_id, chat_name=chat_name) + response = delete_chat(request) + self.assertIsInstance(response, ResponseDeleteChat) + self.assertEqual(response.status, 500) + + @patch('service.MySQLService.UserRepository') + @patch('service.MySQLService.ChatHistoryRepository') + @patch('service.MySQLService.DetailChatRepository') + @patch('service.MySQLService.sf.check_email_service', return_value=ReponseError(status=400, data=res.Message( + message="Id not exist"))) + def test_delete_chat_id_not_exist(self, mock_support_function, mock_detail_chat_repo, mock_chat_history_repo, + mock_user_repo): + user_id = "1" + email = 'example@example.com' + chat_name = 'test' + mock_user_repo.getEmailUserByIdFix.return_value = None + request = RequestDeleteChat(user_id=user_id, chat_name=chat_name) + response = delete_chat(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Id not exist')) + + @patch('service.MySQLService.UserRepository') + @patch('service.MySQLService.ChatHistoryRepository') + @patch('service.MySQLService.DetailChatRepository') + @patch('service.MySQLService.sf.check_email_service', return_value=ReponseError(status=400, data=res.Message( + message="Email is empty"))) + def test_delete_chat_email_empty(self, mock_support_function, mock_detail_chat_repo, mock_chat_history_repo, + mock_user_repo): + user_id = "1" + email = "" + chat_name = 'test' + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + request = RequestDeleteChat(user_id=user_id, chat_name=chat_name) + response = delete_chat(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Email is empty')) + + @patch('service.MySQLService.UserRepository') + @patch('service.MySQLService.ChatHistoryRepository') + @patch('service.MySQLService.DetailChatRepository') + @patch('service.MySQLService.sf.check_email_service', return_value=ReponseError(status=400, data=res.Message( + message="Email invalid"))) + def test_delete_chat_email_invalid(self, mock_support_function, mock_detail_chat_repo, mock_chat_history_repo, + mock_user_repo): + user_id = "1" + email = "20133118" + chat_name = 'test' + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + request = RequestDeleteChat(user_id=user_id, chat_name=chat_name) + response = delete_chat(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Email invalid')) + + @patch('service.MySQLService.UserRepository') + @patch('service.MySQLService.ChatHistoryRepository') + @patch('service.MySQLService.DetailChatRepository') + @patch('service.MySQLService.sf.check_email_service', return_value=True) + def test_delete_chat_chatname_empty(self, mock_support_function, mock_detail_chat_repo, mock_chat_history_repo, + mock_user_repo): + user_id = "1" + email = "20133118@gmail.com" + chat_name = "" + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + request = RequestDeleteChat(user_id=user_id, chat_name=chat_name) + response = delete_chat(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='chat_name is empty')) + + @patch('service.MySQLService.UserRepository') + @patch('service.MySQLService.ChatHistoryRepository') + @patch('service.MySQLService.DetailChatRepository') + @patch('service.MySQLService.sf.check_email_service', return_value=True) + def test_delete_chat_error_1(self, mock_support_function, mock_detail_chat_repo, mock_chat_history_repo, + mock_user_repo): + user_id = "1" + email = "20133118@gmail.com" + chat_name = 'test' + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + mock_chat_history_repo.deleteChatHistory.return_value = False + request = RequestDeleteChat(user_id=user_id, chat_name=chat_name) + response = delete_chat(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 500) + self.assertEqual(response.data, Message(message='Delete conversation chat error')) + + +class TestRenderChatHistory(unittest.TestCase): + @patch('service.MySQLService.UserRepository') + @patch('service.MySQLService.ChatHistoryRepository') + @patch('service.MySQLService.sf.check_email_service', return_value=True) + def test_render_chat_history_success(self, mock_support_function, mock_chat_history_repo, mock_user_repo): + user_id = "1" + email = 'example@example.com' + chat_detail = [Database_Entity.ChatHistory(id=1, email="example@example.com", name_chat="chat1"), + Database_Entity.ChatHistory(id=2, email="example@example.com", name_chat="chat2")] + mock_user_repo.getEmailUserByIdFix.return_value = (email,) + mock_chat_history_repo.getChatHistoryById.return_value = chat_detail + request = RequestRenderChatHistory(user_id=user_id) + response = render_chat_history(request) + self.assertIsInstance(response, ResponseRenderChatHistory) + self.assertEqual(response.status, 200) + self.assertIsInstance(response.data, UserInfoListResponse) + self.assertEqual(len(response.data.chat), 2) # Kiểm tra số lượng chat được trả về + self.assertIsInstance(response.data.chat[0], ListUserChat) + + @patch('service.MySQLService.UserRepository') + @patch('service.MySQLService.ChatHistoryRepository') + @patch('service.MySQLService.sf.check_email_service', side_effect=Exception("Error")) + def test_render_chat_history_server_err(self, mock_support_function, mock_chat_history_repo, mock_user_repo): + user_id = "1" + email = 'example@example.com' + chat_detail = [Database_Entity.ChatHistory(id=1, email="example@example.com", name_chat="chat1"), + Database_Entity.ChatHistory(id=2, email="example@example.com", name_chat="chat2")] + mock_user_repo.getEmailUserByIdFix.side_effect = Exception("error") + request = RequestRenderChatHistory(user_id=user_id) + response = render_chat_history(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + + @patch('service.MySQLService.UserRepository') + @patch('service.MySQLService.ChatHistoryRepository') + @patch('service.MySQLService.sf.check_email_service', return_value=ReponseError(status=400, data=res.Message( + message="Id not exist"))) + def test_render_chat_history_id_not_exist(self, mock_support_function, mock_chat_history_repo, mock_user_repo): + user_id = "1" + email = 'example@example.com' + chat_detail = [Database_Entity.ChatHistory(id=1, email="example@example.com", name_chat="chat1"), + Database_Entity.ChatHistory(id=2, email="example@example.com", name_chat="chat2")] + mock_user_repo.getEmailUserByIdFix.return_value = None + request = RequestRenderChatHistory(user_id=user_id) + response = render_chat_history(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Id not exist')) + + +class TestLoadChatHistory(unittest.TestCase): + @patch('service.MySQLService.DetailChatRepository') + @patch('service.MySQLService.sf.check_email_service', return_value=True) + @patch('service.MySQLService.ChatHistoryRepository') + def test_load_chat_history_success(self, mock_chat_history_repo, mock_support_functon, mock_detail_chat_repo): + chat_id = "1" + user_id = "1" + chat_detail = [Database_Entity.DetailChat(id=1, chat_id=1, YouMessage="question1", AiMessage="AImessage1", + data_relevant="abc", source_file="abcd"), + Database_Entity.DetailChat(id=2, chat_id=1, YouMessage="question2", AiMessage="AImessage2", + data_relevant="abc", source_file="abcd")] + mock_chat_history_repo.getChatHistoryByChatIdAndUserId.return_value = True + mock_detail_chat_repo.getListDetailChatByChatId.return_value = chat_detail + request = RequestLoadChatHistory(user_id=user_id, chat_id=chat_id) + response = load_chat_history(request) + self.assertIsInstance(response, ResponseLoadChatHistory) + self.assertEqual(response.status, 200) + self.assertIsInstance(response.data, ListChatDeTail) + self.assertEqual(len(response.data.detail_chat), 2) + self.assertIsInstance(response.data.detail_chat[0], ChatDetail) + + @patch('service.MySQLService.DetailChatRepository') + @patch('service.MySQLService.ChatHistoryRepository', return_value=True) + @patch('service.MySQLService.sf.check_email_service', side_effect=Exception("Error")) + def test_load_chat_history_server_err(self, mock_support_function, mock_chat_history_repo, mock_detail_chat_repo): + chat_id = "1" + user_id = "1" + chat_detail = [Database_Entity.DetailChat(id=1, chat_id=1, YouMessage="question1", AiMessage="AImessage1", + data_relevant="abc", source_file="abcd"), + Database_Entity.DetailChat(id=2, chat_id=1, YouMessage="question2", AiMessage="AImessage2", + data_relevant="abc", source_file="abcd")] + mock_chat_history_repo.getChatHistoryByChatIdAndUserId.return_value = True + mock_detail_chat_repo.getListDetailChatByChatId.side_effect = Exception("error") + request = RequestLoadChatHistory(user_id=user_id, chat_id=chat_id) + response = load_chat_history(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 500) + self.assertEqual(response.data.message, "Server Error") + + @patch('service.MySQLService.DetailChatRepository') + @patch('service.MySQLService.sf.check_email_service', return_value="20133118@gmail.com") + @patch('service.MySQLService.ChatHistoryRepository', return_value=True) + def test_load_chat_history_error(self, mock_repo1, mock_support_function, mock_detail_chat_repo): + chat_id = None + user_id = "1" + request = RequestLoadChatHistory(user_id=user_id, chat_id=chat_id) + mock_repo1.getChatHistoryByChatIdAndUserId.return_value = None + response = load_chat_history(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='chat_id is empty')) + + @patch('service.MySQLService.DetailChatRepository') + @patch('service.MySQLService.sf.check_email_service', return_value="12345@gmail.com") + @patch('service.MySQLService.ChatHistoryRepository') + def test_load_chat_history_not_found_chat(self, mock_repo1, mock_support_function, mock_detail_chat_repo): + chat_id = "1" + user_id = None + mock_repo1.getChatHistoryByChatIdAndUserId.return_value = None + request = RequestLoadChatHistory(user_id=user_id, chat_id=chat_id) + response = load_chat_history(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Not found chat width chat_id and user_id')) + + @patch('service.MySQLService.DetailChatRepository') + @patch('service.MySQLService.sf.check_email_service', return_value=res.ReponseError(status=400, + data=res.Message(message="user_id must be an integer"))) + @patch('service.MySQLService.ChatHistoryRepository') + def test_load_chat_history_user_id_str(self, mock_repo1, mock_support_function, mock_detail_chat_repo): + chat_id = "1" + user_id = None + mock_repo1.getChatHistoryByChatIdAndUserId.return_value = None + request = RequestLoadChatHistory(user_id=user_id, chat_id=chat_id) + response = load_chat_history(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='user_id must be an integer')) + + @patch('service.MySQLService.DetailChatRepository') + @patch('service.MySQLService.sf.check_email_service', return_value=res.ReponseError(status=400, + data=res.Message( + message="Id not exist"))) + @patch('service.MySQLService.ChatHistoryRepository') + def test_load_chat_history_user_id_str(self, mock_repo1, mock_support_function, mock_detail_chat_repo): + chat_id = "1" + user_id = None + mock_repo1.getChatHistoryByChatIdAndUserId.return_value = None + request = RequestLoadChatHistory(user_id=user_id, chat_id=chat_id) + response = load_chat_history(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Id not exist')) + + @patch('service.MySQLService.DetailChatRepository') + @patch('service.MySQLService.sf.check_email_service', return_value=res.ReponseError(status=400, + data=res.Message( + message="Id not exist"))) + @patch('service.MySQLService.ChatHistoryRepository') + def test_load_chat_history_user_id_str(self, mock_repo1, mock_support_function, mock_detail_chat_repo): + chat_id = "1" + user_id = None + mock_repo1.getChatHistoryByChatIdAndUserId.return_value = None + request = RequestLoadChatHistory(user_id=user_id, chat_id=chat_id) + response = load_chat_history(request) + self.assertIsInstance(response, ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, Message(message='Id not exist')) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/tests/test_service/test_OTPService.py b/tests/test_service/test_OTPService.py new file mode 100644 index 0000000000000000000000000000000000000000..477ac796281b961b003bbaf7f42280be362e57a0 --- /dev/null +++ b/tests/test_service/test_OTPService.py @@ -0,0 +1,311 @@ +import unittest +import sys +import os +app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) +sys.path.insert(0, app_path) +from request import RequestOTP as req +from response import ResponseOTP as res +from unittest.mock import patch, MagicMock +from datetime import datetime, timedelta +from service.OTPService import createOTP, verifyOTP, createOTPReset, verifyOTPReset + +class TestCreateOTPReset(unittest.TestCase): + @patch('service.OTPService.check_email') + @patch('service.OTPService.get_user1') + @patch('service.OTPService.OTPRepository.addOTP') + @patch('service.OTPService.generate_otp') + @patch('service.OTPService.sf') + def test_createOTPReset_success(self,mock_support_function, mock_generate_otp, mock_addOTP, mock_get_user1, mock_check_email): + mock_get_user1.return_value = MagicMock() + email = "user@example.com" + mock_support_function.check_email_empty_invalid.return_value = True + mock_generate_otp.return_value = "123456" + response = createOTPReset(email) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.check, True) + self.assertEqual(response.otp, "123456") + + @patch('service.OTPService.check_email') + @patch('service.OTPService.get_user1') + @patch('service.OTPService.OTPRepository.addOTP') + @patch('service.OTPService.sf') + def test_createOTPReset_email_empty(self,mock_support_function, mock_addOTP, mock_get_user1, mock_check_email): + email = None + mock_support_function.check_email_empty_invalid.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + response = createOTPReset(email) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='Email is empty')) + + @patch('service.OTPService.check_email') + @patch('service.OTPService.sf') + def test_createOTPReset_email_invalid(self,mock_support_function, mock_check_email): + email = "201333" + mock_support_function.check_email_empty_invalid.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + response = createOTPReset(email) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data, res.Message(message='Email invalid')) + +class TestCreateOTPFunctions(unittest.TestCase): + @patch('service.OTPService.generate_otp') + @patch('service.OTPService.check_email') + @patch('service.OTPService.OTPRepository') + @patch('service.OTPService.sf') + def test_createOTP_success(self,mock_support_function, mock_addOTP, mock_check_email, mock_generate_otp): + mock_generate_otp.return_value = "123AB6" + email = "20133118@gmail.com" + otp = "123AB6" + mock_support_function.check_email_empty_invalid.return_value = True + mock_addOTP.addOTP(email, otp) + request = req.RequestCreateOTP(email=email) + response = createOTP(request) + self.assertIsInstance(response, res.ResponseCreateOTP) + self.assertEqual(response.status, 200) + self.assertTrue(response.data.check) + self.assertEqual(response.otp, "123AB6") + + @patch('service.OTPService.check_email') + @patch('service.OTPService.sf') + def test_createOTP_failed_empty_email(self,mock_support_function, mock_check_email): + email = None + mock_support_function.check_email_empty_invalid.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + request = req.RequestCreateOTP(email=email) + response = createOTP(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email is empty") + + @patch('service.OTPService.check_email') + @patch('service.OTPService.OTPRepository.addOTP') + @patch('service.OTPService.sf') + def test_createOTP_failed_empty_invalid(self,mock_support_function, mock_addOTP, mock_check_email): + email = "20133" + mock_support_function.check_email_empty_invalid.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + request = req.RequestCreateOTP(email=email) + mock_check_email.return_value = False + response = createOTP(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email invalid") + mock_addOTP.assert_not_called() + +class TestVerifyOTPFunctions(unittest.TestCase): + @patch('service.OTPService.check_email', return_value=True) + @patch('service.OTPService.OTPRepository.getOtpByEmail') + @patch('service.OTPService.OTPRepository.deleteOTP') + @patch('service.OTPService.sf') + def test_verifyOTP_success(self,mock_support_function, mock_deleteOTP, mock_getOtpByEmail, mock_check_email): + current_time = datetime.now() + mock_support_function.check_email_empty_invalid.return_value = True + mock_getOtpByEmail.return_value = MagicMock(otp="123456", created_at=current_time - timedelta(minutes=5)) + + email = "user@example.com" + otp = "123456" + request = req.RequestVerifyOTP(email=email, otp=otp) + response = verifyOTP(request) + mock_deleteOTP(email, otp) + self.assertIsInstance(response, res.ResponseVerifyOTPSignUp) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.message, "OTP is valid") + + @patch('service.OTPService.check_email', return_value=True) + @patch('service.OTPService.OTPRepository.getOtpByEmail') + @patch('service.OTPService.sf') + def test_verifyOTP_failed_invalid_otp(self,mock_support_function, mock_getOtpByEmail, mock_check_email): + current_time = datetime.now() + mock_support_function.check_email_empty_invalid.return_value = True + mock_getOtpByEmail.return_value = MagicMock(otp="654321", created_at=current_time - timedelta(minutes=5)) + + email = "user@example.com" + otp = "123456" + request = req.RequestVerifyOTP(email=email, otp=otp) + response = verifyOTP(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Invalid OTP") + + @patch('service.OTPService.check_email') + @patch('service.OTPService.sf') + def test_verifyOTP_failed_invalid_email(self,mock_support_function, mock_check_email): + email = "invalidemail" + otp = "123456" + mock_support_function.check_email_empty_invalid.return_value =res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + + request = req.RequestVerifyOTP(email=email, otp=otp) + + response = verifyOTP(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email invalid") + + @patch('service.OTPService.sf') + def test_verifyOTP_failed_empty_email(self,mock_support_function): + email = None + otp = "123456" + mock_support_function.check_email_empty_invalid.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + request = req.RequestVerifyOTP(email=email, otp=otp) + response = verifyOTP(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email is empty") + + @patch('service.OTPService.check_email') + @patch('service.OTPService.sf') + def test_verifyOTP_failed_empty_otp(self,mock_support_function, mock_check_email): + email = "user@example.com" + otp = None + mock_support_function.check_email_empty_invalid.return_value = True + request = req.RequestVerifyOTP(email=email, otp=otp) + mock_check_email.return_value = True + response = verifyOTP(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "otp is empty") + + @patch('service.OTPService.check_email', return_value=True) + @patch('service.OTPService.OTPRepository.getOtpByEmail') + @patch('service.OTPService.sf') + def test_verifyOTP_failed_no_otp_found(self,mock_support_function, mock_getOtpByEmail, mock_check_email): + mock_getOtpByEmail.return_value = None + email = "user@example.com" + otp = "123456" + mock_support_function.check_email_empty_invalid.return_value = True + request = req.RequestVerifyOTP(email=email, otp=otp) + response = verifyOTP(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "No OTP found for this email") + + @patch('service.OTPService.check_email') + @patch('service.OTPService.OTPRepository.getOtpByEmail') + @patch('service.OTPService.sf') + def test_verifyOTP_has_expired(self,mock_support_function, mock_getOtpByEmail, mock_check_email): + current_time = datetime.now() + mock_getOtpByEmail.return_value = MagicMock(otp="123456", created_at=current_time - timedelta(minutes=100)) + email = "user@example.com" + otp = "123456" + mock_support_function.check_email_empty_invalid.return_value = True + request = req.RequestVerifyOTP(email=email, otp=otp) + response = verifyOTP(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "OTP has expired") + +class TestVerifyOTPReset(unittest.TestCase): + @patch('service.OTPService.check_email') + @patch('service.OTPService.OTPRepository.getOtpByEmail') + @patch('service.OTPService.OTPRepository') + @patch('service.OTPService.auth.get_user_by_email') + @patch('service.OTPService.auth') + @patch('service.OTPService.sf') + def test_verifyOTPReset_success(self,mock_support_function, mock_update_user, mock_get_user_by_email, mock_deleteOTP, mock_getOtpByEmail, + mock_check_email): + current_time = datetime.now() + mock_support_function.check_email_empty_invalid.return_value = True + mock_getOtpByEmail.return_value = MagicMock(otp="123456", created_at=current_time - timedelta(minutes=5)) + mock_get_user_by_email.return_value = MagicMock(uid="12345") + email = "user@example.com" + otp = "123456" + mock_check_email.return_value = True + request = req.RequestVerifyOTP(email=email, otp=otp) + mock_update_user.update_user(uid="12345", ) + response = verifyOTPReset(request) + mock_deleteOTP.deleteOTP("user@example.com", "123456") + self.assertIsInstance(response, res.ResponseVerifyOTP) + self.assertEqual(response.status, 200) + self.assertEqual(response.data.message, "New Password send to Email") + + @patch('service.OTPService.check_email') + @patch('service.OTPService.OTPRepository.getOtpByEmail') + @patch('service.OTPService.sf') + def test_verifyOTPReset_failed_invalid_otp(self,mock_support_function, mock_getOtpByEmail, mock_check_email): + current_time = datetime.now() + mock_support_function.check_email_empty_invalid.return_value = True + mock_getOtpByEmail.return_value = MagicMock(otp="654321", created_at=current_time - timedelta(minutes=5)) + email = "user@example.com" + otp = "123456" + mock_check_email.return_value = True + request = req.RequestVerifyOTP(email=email, otp=otp) + response = verifyOTPReset(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Invalid OTP") + + @patch('service.OTPService.check_email') + @patch('service.OTPService.OTPRepository.getOtpByEmail') + @patch('service.OTPService.sf') + def test_verifyOTPReset_failed_no_otp_found(self,mock_support_function, mock_getOtpByEmail, mock_check_email): + mock_getOtpByEmail.return_value = None + email = "user@example.com" + otp = "123456" + request = req.RequestVerifyOTP(email=email, otp=otp) + mock_support_function.check_email_empty_invalid.return_value = True + response = verifyOTPReset(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "No OTP found for this email") + + @patch('service.OTPService.check_email') + @patch('service.OTPService.OTPRepository.getOtpByEmail') + @patch('service.OTPService.sf') + def test_verifyOTPReset_has_expired(self,mock_support_function, mock_getOtpByEmail, mock_check_email): + current_time = datetime.now() + mock_getOtpByEmail.return_value = MagicMock(otp="123456", created_at=current_time - timedelta(minutes=100)) + email = "vonhuy@gmail.com" + otp = "123456" + mock_support_function.check_email_empty_invalid.return_value = True + request = req.RequestVerifyOTP(email=email, otp=otp) + response = verifyOTPReset(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "OTP has expired") + + @patch('service.OTPService.check_email') + @patch('service.OTPService.sf') + def test_verifyOTPReset_failed_invalid_email(self,mock_support_function, mock_check_email): + email = "invalidemail" + otp = "123456" + mock_support_function.check_email_empty_invalid.return_value = res.ReponseError(status=400, data=res.Message( + message="Email invalid")) + request = req.RequestVerifyOTP(email=email, otp=otp) + response = verifyOTPReset(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email invalid") + + @patch('service.OTPService.check_email') + @patch('service.OTPService.OTPRepository.getOtpByEmail') + @patch('service.OTPService.sf') + def test_verifyOTPReset_failed_empty_email(self,mock_support_function, mock_getOtpByEmail, mock_check_email): + email = None + otp = "123456" + request = req.RequestVerifyOTP(email=email, otp=otp) + mock_support_function.check_email_empty_invalid.return_value = res.ReponseError(status=400, data=res.Message( + message="Email is empty")) + response = verifyOTPReset(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "Email is empty") + + @patch('service.OTPService.check_email', return_value=True) + @patch('service.OTPService.sf') + def test_verifyOTPReset_failed_empty_otp(self,mock_support_function, mock_check_email): + email = "user@example.com" + otp = None + mock_support_function.check_email_empty_invalid.return_value = True + request = req.RequestVerifyOTP(email=email, otp=otp) + response = verifyOTPReset(request) + self.assertIsInstance(response, res.ReponseError) + self.assertEqual(response.status, 400) + self.assertEqual(response.data.message, "OTP is empty") + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_service/user_file/quangphuc@gmail.com/demo1.pdf b/tests/test_service/user_file/quangphuc@gmail.com/demo1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..43597a9147dba9bf9befd7886997e1ceb1413702 --- /dev/null +++ b/tests/test_service/user_file/quangphuc@gmail.com/demo1.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:367daadbb1bb652bda103a21a632b36a2821348931c3c11b37fa315c9843af4a +size 7289174 diff --git a/tests/user_file/quangphuc@gmail.com/demo1.pdf b/tests/user_file/quangphuc@gmail.com/demo1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..43597a9147dba9bf9befd7886997e1ceb1413702 --- /dev/null +++ b/tests/user_file/quangphuc@gmail.com/demo1.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:367daadbb1bb652bda103a21a632b36a2821348931c3c11b37fa315c9843af4a +size 7289174 diff --git a/vector_database/FAISS/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/index.faiss b/vector_database/FAISS/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/index.faiss new file mode 100644 index 0000000000000000000000000000000000000000..569afbaf8902bd9ffbbbc85e4ca3d9243a7a6b2f Binary files /dev/null and b/vector_database/FAISS/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/index.faiss differ diff --git a/vector_database/FAISS/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/index.pkl b/vector_database/FAISS/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/index.pkl new file mode 100644 index 0000000000000000000000000000000000000000..183e283bda5d17a597e143cc70ee312e2f542b85 --- /dev/null +++ b/vector_database/FAISS/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/index.pkl @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c59f629c0a17c98bcea693984423db08ef92181e409b2918526157cceed3146 +size 16076 diff --git a/vector_database/FAISS/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/index.faiss b/vector_database/FAISS/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/index.faiss new file mode 100644 index 0000000000000000000000000000000000000000..55739e292a9134eec27be7001e591d60ab47da72 Binary files /dev/null and b/vector_database/FAISS/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/index.faiss differ diff --git a/vector_database/FAISS/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/index.pkl b/vector_database/FAISS/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/index.pkl new file mode 100644 index 0000000000000000000000000000000000000000..29c39ca73da521dd4f9273b49892fa3e02bb8346 --- /dev/null +++ b/vector_database/FAISS/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/index.pkl @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90bdb3e0dd3ae3c3b83f3bd21c404a28bcd3ff136f4014995245da57de09227b +size 2697 diff --git a/vector_database/vonhuy5112002@gmail.com/1a428581-41d1-4966-93a5-a90611270aaa/data_level0.bin b/vector_database/vonhuy5112002@gmail.com/1a428581-41d1-4966-93a5-a90611270aaa/data_level0.bin new file mode 100644 index 0000000000000000000000000000000000000000..8d59af8d46593f309b55ca904928b8064fded705 --- /dev/null +++ b/vector_database/vonhuy5112002@gmail.com/1a428581-41d1-4966-93a5-a90611270aaa/data_level0.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a13e72541800c513c73dccea69f79e39cf4baef4fa23f7e117c0d6b0f5f99670 +size 3212000 diff --git a/vector_database/vonhuy5112002@gmail.com/1a428581-41d1-4966-93a5-a90611270aaa/header.bin b/vector_database/vonhuy5112002@gmail.com/1a428581-41d1-4966-93a5-a90611270aaa/header.bin new file mode 100644 index 0000000000000000000000000000000000000000..5e3435b012ee69310b8100812b2faf2bd6a11f73 --- /dev/null +++ b/vector_database/vonhuy5112002@gmail.com/1a428581-41d1-4966-93a5-a90611270aaa/header.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ec6df10978b056a10062ed99efeef2702fa4a1301fad702b53dd2517103c746 +size 100 diff --git a/vector_database/vonhuy5112002@gmail.com/1a428581-41d1-4966-93a5-a90611270aaa/length.bin b/vector_database/vonhuy5112002@gmail.com/1a428581-41d1-4966-93a5-a90611270aaa/length.bin new file mode 100644 index 0000000000000000000000000000000000000000..d9be46b9c392aeca648e2d132a8e5479b316784f --- /dev/null +++ b/vector_database/vonhuy5112002@gmail.com/1a428581-41d1-4966-93a5-a90611270aaa/length.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ade2e5136273266c12c673d9d2babb1c7edbb6d1a84654e5cd585a3c923f565f +size 4000 diff --git a/vector_database/vonhuy5112002@gmail.com/1a428581-41d1-4966-93a5-a90611270aaa/link_lists.bin b/vector_database/vonhuy5112002@gmail.com/1a428581-41d1-4966-93a5-a90611270aaa/link_lists.bin new file mode 100644 index 0000000000000000000000000000000000000000..fc8e42b32efb9a9bf3ae0234a18a948e499490f8 --- /dev/null +++ b/vector_database/vonhuy5112002@gmail.com/1a428581-41d1-4966-93a5-a90611270aaa/link_lists.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +size 0 diff --git a/vector_database/vonhuy5112002@gmail.com/chroma.sqlite3 b/vector_database/vonhuy5112002@gmail.com/chroma.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..ce386ee7e4dcf73fba64ec7eb7e3c5f22bfed734 --- /dev/null +++ b/vector_database/vonhuy5112002@gmail.com/chroma.sqlite3 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b03a18f635381ac713165528508a5d6105a76520939e08abe2780e1e052ef37 +size 15536128 diff --git a/vector_database/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/c6052a6d-fdff-4978-83bf-41d5fc365aaf/data_level0.bin b/vector_database/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/c6052a6d-fdff-4978-83bf-41d5fc365aaf/data_level0.bin new file mode 100644 index 0000000000000000000000000000000000000000..8d59af8d46593f309b55ca904928b8064fded705 --- /dev/null +++ b/vector_database/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/c6052a6d-fdff-4978-83bf-41d5fc365aaf/data_level0.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a13e72541800c513c73dccea69f79e39cf4baef4fa23f7e117c0d6b0f5f99670 +size 3212000 diff --git a/vector_database/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/c6052a6d-fdff-4978-83bf-41d5fc365aaf/header.bin b/vector_database/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/c6052a6d-fdff-4978-83bf-41d5fc365aaf/header.bin new file mode 100644 index 0000000000000000000000000000000000000000..5e3435b012ee69310b8100812b2faf2bd6a11f73 --- /dev/null +++ b/vector_database/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/c6052a6d-fdff-4978-83bf-41d5fc365aaf/header.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ec6df10978b056a10062ed99efeef2702fa4a1301fad702b53dd2517103c746 +size 100 diff --git a/vector_database/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/c6052a6d-fdff-4978-83bf-41d5fc365aaf/length.bin b/vector_database/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/c6052a6d-fdff-4978-83bf-41d5fc365aaf/length.bin new file mode 100644 index 0000000000000000000000000000000000000000..51351ed8ea6a068aca6e75040e3c0891344624f0 --- /dev/null +++ b/vector_database/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/c6052a6d-fdff-4978-83bf-41d5fc365aaf/length.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:931eb803f5184ae704829697b218545140c1cc15d07f398626c6d9f1236f0c97 +size 4000 diff --git a/vector_database/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/c6052a6d-fdff-4978-83bf-41d5fc365aaf/link_lists.bin b/vector_database/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/c6052a6d-fdff-4978-83bf-41d5fc365aaf/link_lists.bin new file mode 100644 index 0000000000000000000000000000000000000000..fc8e42b32efb9a9bf3ae0234a18a948e499490f8 --- /dev/null +++ b/vector_database/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/c6052a6d-fdff-4978-83bf-41d5fc365aaf/link_lists.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +size 0 diff --git a/vector_database/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/chroma.sqlite3 b/vector_database/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/chroma.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..ced2b6eba00f4592b160ce72d278969dc744f810 Binary files /dev/null and b/vector_database/vonhuy777@gmail.com/2023UTE_ResearchReport_Talk.pdf/chroma.sqlite3 differ diff --git a/vector_database/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/a99e418d-02c8-411f-aa4a-9a09d7bcc518/data_level0.bin b/vector_database/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/a99e418d-02c8-411f-aa4a-9a09d7bcc518/data_level0.bin new file mode 100644 index 0000000000000000000000000000000000000000..8d59af8d46593f309b55ca904928b8064fded705 --- /dev/null +++ b/vector_database/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/a99e418d-02c8-411f-aa4a-9a09d7bcc518/data_level0.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a13e72541800c513c73dccea69f79e39cf4baef4fa23f7e117c0d6b0f5f99670 +size 3212000 diff --git a/vector_database/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/a99e418d-02c8-411f-aa4a-9a09d7bcc518/header.bin b/vector_database/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/a99e418d-02c8-411f-aa4a-9a09d7bcc518/header.bin new file mode 100644 index 0000000000000000000000000000000000000000..5e3435b012ee69310b8100812b2faf2bd6a11f73 --- /dev/null +++ b/vector_database/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/a99e418d-02c8-411f-aa4a-9a09d7bcc518/header.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ec6df10978b056a10062ed99efeef2702fa4a1301fad702b53dd2517103c746 +size 100 diff --git a/vector_database/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/a99e418d-02c8-411f-aa4a-9a09d7bcc518/length.bin b/vector_database/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/a99e418d-02c8-411f-aa4a-9a09d7bcc518/length.bin new file mode 100644 index 0000000000000000000000000000000000000000..fb155d822b6ca4351e2925bbc2dba0f49f05e0ab --- /dev/null +++ b/vector_database/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/a99e418d-02c8-411f-aa4a-9a09d7bcc518/length.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc19b1997119425765295aeab72d76faa6927d4f83985d328c26f20468d6cc76 +size 4000 diff --git a/vector_database/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/a99e418d-02c8-411f-aa4a-9a09d7bcc518/link_lists.bin b/vector_database/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/a99e418d-02c8-411f-aa4a-9a09d7bcc518/link_lists.bin new file mode 100644 index 0000000000000000000000000000000000000000..fc8e42b32efb9a9bf3ae0234a18a948e499490f8 --- /dev/null +++ b/vector_database/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/a99e418d-02c8-411f-aa4a-9a09d7bcc518/link_lists.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +size 0 diff --git a/vector_database/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/chroma.sqlite3 b/vector_database/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/chroma.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..bb9fb0a668ef3ffcd9cb6903a62caa4662a79b2e Binary files /dev/null and b/vector_database/vonhuy777@gmail.com/HK02_Lich-bao-ve-KLTN_2023-24_THONGBAO.docx/chroma.sqlite3 differ diff --git a/vector_database/vonhuy777@gmail.com/chroma.sqlite3 b/vector_database/vonhuy777@gmail.com/chroma.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..fb72a2d7fcc6d5685b2d2966683de47d440518f0 --- /dev/null +++ b/vector_database/vonhuy777@gmail.com/chroma.sqlite3 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98a6e66fe499b48b8b5ee522168a6c3a1e0a401230b3bae752f1647efc3cfc1d +size 10194944 diff --git a/vector_database/vonhuy777@gmail.com/fd208400-b147-4be6-870c-5df9d685075f/data_level0.bin b/vector_database/vonhuy777@gmail.com/fd208400-b147-4be6-870c-5df9d685075f/data_level0.bin new file mode 100644 index 0000000000000000000000000000000000000000..8d59af8d46593f309b55ca904928b8064fded705 --- /dev/null +++ b/vector_database/vonhuy777@gmail.com/fd208400-b147-4be6-870c-5df9d685075f/data_level0.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a13e72541800c513c73dccea69f79e39cf4baef4fa23f7e117c0d6b0f5f99670 +size 3212000 diff --git a/vector_database/vonhuy777@gmail.com/fd208400-b147-4be6-870c-5df9d685075f/header.bin b/vector_database/vonhuy777@gmail.com/fd208400-b147-4be6-870c-5df9d685075f/header.bin new file mode 100644 index 0000000000000000000000000000000000000000..5e3435b012ee69310b8100812b2faf2bd6a11f73 --- /dev/null +++ b/vector_database/vonhuy777@gmail.com/fd208400-b147-4be6-870c-5df9d685075f/header.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ec6df10978b056a10062ed99efeef2702fa4a1301fad702b53dd2517103c746 +size 100 diff --git a/vector_database/vonhuy777@gmail.com/fd208400-b147-4be6-870c-5df9d685075f/length.bin b/vector_database/vonhuy777@gmail.com/fd208400-b147-4be6-870c-5df9d685075f/length.bin new file mode 100644 index 0000000000000000000000000000000000000000..fb155d822b6ca4351e2925bbc2dba0f49f05e0ab --- /dev/null +++ b/vector_database/vonhuy777@gmail.com/fd208400-b147-4be6-870c-5df9d685075f/length.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc19b1997119425765295aeab72d76faa6927d4f83985d328c26f20468d6cc76 +size 4000 diff --git a/vector_database/vonhuy777@gmail.com/fd208400-b147-4be6-870c-5df9d685075f/link_lists.bin b/vector_database/vonhuy777@gmail.com/fd208400-b147-4be6-870c-5df9d685075f/link_lists.bin new file mode 100644 index 0000000000000000000000000000000000000000..fc8e42b32efb9a9bf3ae0234a18a948e499490f8 --- /dev/null +++ b/vector_database/vonhuy777@gmail.com/fd208400-b147-4be6-870c-5df9d685075f/link_lists.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +size 0