Spaces:
Sleeping
Sleeping
Upload 48 files
Browse files- auth/authentication.py +133 -0
- controller/AuthenticationController.py +62 -0
- controller/ChatController.py +35 -0
- controller/DefaultController.py +70 -0
- controller/FileController.py +63 -0
- controller/MySQLController.py +76 -0
- controller/OTPController.py +33 -0
- controller/UserController.py +94 -0
- function/chatbot.py +685 -0
- function/dropbox.py +155 -0
- function/support_function.py +128 -0
- models/Database_Entity.py +68 -0
- request/RequestAuth.py +19 -0
- request/RequestChat.py +18 -0
- request/RequestDefault.py +15 -0
- request/RequestFile.py +20 -0
- request/RequestMySQL.py +25 -0
- request/RequestOTP.py +9 -0
- request/RequestUser.py +52 -0
- response/ResponseAuth.py +42 -0
- response/ResponseChat.py +55 -0
- response/ResponseDefault.py +44 -0
- response/ResponseFile.py +39 -0
- response/ResponseMySQL.py +59 -0
- response/ResponseOTP.py +25 -0
- response/ResponseUser.py +74 -0
- service/AuthService.py +292 -0
- service/ChatService.py +141 -0
- service/DefaultService.py +205 -0
- service/FileService.py +151 -0
- service/MySQLService.py +201 -0
- service/OTPService.py +168 -0
- service/UserService.py +322 -0
- service/app/firebase_certificate.json +0 -0
- tests/test_controller/__init__.py +0 -0
- tests/test_controller/test_ChatController.py +258 -0
- tests/test_controller/test_DefaultController.py +330 -0
- tests/test_controller/test_FileController.py +478 -0
- tests/test_controller/test_LoginController.py +650 -0
- tests/test_controller/test_MySQLController.py +314 -0
- tests/test_controller/test_OTPController.py +292 -0
- tests/test_service/_init__.py +0 -0
- tests/test_service/test_ChatService.py +462 -0
- tests/test_service/test_DefaultService.py +344 -0
- tests/test_service/test_FileService.py +471 -0
- tests/test_service/test_LoginService.py +560 -0
- tests/test_service/test_MySQLService.py +382 -0
- tests/test_service/test_OTPService.py +311 -0
auth/authentication.py
ADDED
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import time
|
2 |
+
from typing import Dict
|
3 |
+
import jwt
|
4 |
+
import secrets
|
5 |
+
import logging
|
6 |
+
from fastapi import Depends, HTTPException
|
7 |
+
import base64
|
8 |
+
from datetime import datetime, timedelta
|
9 |
+
from repository import UserRepository, UserLoginRepository
|
10 |
+
import string, random
|
11 |
+
|
12 |
+
def check_token_is_valid(token):
|
13 |
+
check = UserRepository.getEmailUserByAccessToken(token)
|
14 |
+
if check is None:
|
15 |
+
return False
|
16 |
+
return True
|
17 |
+
|
18 |
+
def unique_string(byte: int = 8) -> str:
|
19 |
+
return secrets.token_urlsafe(byte)
|
20 |
+
JWT_SECRET = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
|
21 |
+
JWT_ALGORITHM = "HS512"
|
22 |
+
SECRET_KEY="8deadce9449770680910741063cd0a3fe0acb62a8978661f421bbcbb66dc41f1"
|
23 |
+
|
24 |
+
def token_response(token: str):
|
25 |
+
return {
|
26 |
+
"access_token": token
|
27 |
+
}
|
28 |
+
def str_encode(string: str) -> str:
|
29 |
+
return base64.b85encode(string.encode('ascii')).decode('ascii')
|
30 |
+
|
31 |
+
def get_token_payload(token: str, secret: str, algo: str):
|
32 |
+
try:
|
33 |
+
payload = jwt.decode(token, secret, algorithms=algo)
|
34 |
+
except Exception as jwt_exec:
|
35 |
+
logging.debug(f"JWT Error: {str(jwt_exec)}")
|
36 |
+
payload = None
|
37 |
+
return payload
|
38 |
+
|
39 |
+
from datetime import datetime
|
40 |
+
def generate_token(payload: dict, secret: str, algo: str, expiry: timedelta):
|
41 |
+
expire = datetime.now() + expiry
|
42 |
+
payload.update({"exp": expire})
|
43 |
+
return jwt.encode(payload, secret, algorithm=algo)
|
44 |
+
|
45 |
+
def str_decode(string: str) -> str:
|
46 |
+
return base64.b85decode(string.encode('ascii')).decode('ascii')
|
47 |
+
|
48 |
+
def generate_random_string(length=12):
|
49 |
+
characters = string.ascii_letters + string.digits
|
50 |
+
random_string = ''.join(random.choice(characters) for i in range(length))
|
51 |
+
return random_string
|
52 |
+
|
53 |
+
import pytz
|
54 |
+
from datetime import datetime
|
55 |
+
def signJWT(user_email: str) -> Dict[str, str]:
|
56 |
+
rt_expires = timedelta(days=3)
|
57 |
+
refresh_key = unique_string(100)
|
58 |
+
access_key = unique_string(50)
|
59 |
+
at_expires = timedelta(minutes=180)
|
60 |
+
at_payload = {
|
61 |
+
"sub": str_encode(str(user_email)),
|
62 |
+
'a': access_key,
|
63 |
+
}
|
64 |
+
access_token = generate_token(at_payload, JWT_SECRET, JWT_ALGORITHM, at_expires)
|
65 |
+
rt_payload = {"sub": str_encode(str(user_email)), "t": refresh_key, 'a': access_key}
|
66 |
+
refresh_token = generate_token(rt_payload, SECRET_KEY,JWT_ALGORITHM, rt_expires)
|
67 |
+
expires_in = at_expires.seconds
|
68 |
+
vn_timezone = pytz.timezone('Asia/Ho_Chi_Minh')
|
69 |
+
current_time = datetime.now().replace(tzinfo=pytz.utc).astimezone(vn_timezone) + timedelta(seconds=expires_in)
|
70 |
+
formatted_time = current_time.strftime('%Y-%m-%d %H:%M:%S ')
|
71 |
+
existing_user = UserRepository.getUserByEmail(user_email)
|
72 |
+
if existing_user is None:
|
73 |
+
UserRepository.addUser(user_email, access_token, refresh_token, formatted_time)
|
74 |
+
else:
|
75 |
+
UserRepository.updateUserLogin(user_email, access_token, refresh_token, formatted_time)
|
76 |
+
user_record = UserRepository.getUserByEmail(user_email)
|
77 |
+
session_id = ""
|
78 |
+
if user_record:
|
79 |
+
session_id = generate_random_string()
|
80 |
+
existing_userlogin = UserLoginRepository.getUserLogin(user_email)
|
81 |
+
if existing_userlogin is None:
|
82 |
+
UserLoginRepository.addUserLogin(user_email,session_id=session_id)
|
83 |
+
else:
|
84 |
+
UserLoginRepository.updateUserLogin(user_email, session_id)
|
85 |
+
return {
|
86 |
+
"access_token": access_token,
|
87 |
+
"refresh_token": refresh_token,
|
88 |
+
"expires_in": at_expires.seconds,
|
89 |
+
"session_id": session_id
|
90 |
+
}
|
91 |
+
|
92 |
+
def returnAccessToken(user_email: str, refresh_token: str) -> Dict[str, str]:
|
93 |
+
access_key = unique_string(50)
|
94 |
+
at_expires = timedelta(minutes=180)
|
95 |
+
at_payload = {
|
96 |
+
"sub": str_encode(str(user_email)),
|
97 |
+
'a': access_key,
|
98 |
+
}
|
99 |
+
access_token = generate_token(at_payload, JWT_SECRET, JWT_ALGORITHM, at_expires)
|
100 |
+
user_record = UserRepository.getUserByEmail(user_email)
|
101 |
+
session_id = ""
|
102 |
+
if user_record:
|
103 |
+
email1 = user_record.email
|
104 |
+
if email1:
|
105 |
+
session_id = generate_random_string()
|
106 |
+
existing_userlogin = UserLoginRepository.getUserLogin(user_email)
|
107 |
+
if existing_userlogin is None:
|
108 |
+
UserLoginRepository.addUserLogin(user_email,session_id=session_id)
|
109 |
+
else:
|
110 |
+
UserLoginRepository.updateUserLogin(user_email,session_id)
|
111 |
+
return {
|
112 |
+
"access_token": access_token,
|
113 |
+
"refresh_token": refresh_token,
|
114 |
+
"expires_in": at_expires.seconds,
|
115 |
+
"session_id": session_id
|
116 |
+
}
|
117 |
+
|
118 |
+
def decodeJWT(token: str) -> dict:
|
119 |
+
try:
|
120 |
+
decoded_token = jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM])
|
121 |
+
return decoded_token if decoded_token["exp"] >= time.time() else None
|
122 |
+
except:
|
123 |
+
return {}
|
124 |
+
|
125 |
+
def get_refresh_token(refresh_token, email):
|
126 |
+
token_payload = get_token_payload(refresh_token, SECRET_KEY, JWT_ALGORITHM)
|
127 |
+
if not token_payload:
|
128 |
+
raise HTTPException(status_code=400, detail="Invalid Request.")
|
129 |
+
exp = token_payload.get('exp')
|
130 |
+
if exp >= time.time() and token_payload:
|
131 |
+
return returnAccessToken(email,refresh_token)
|
132 |
+
elif not token_payload:
|
133 |
+
return signJWT(email)
|
controller/AuthenticationController.py
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import APIRouter
|
2 |
+
from request import RequestAuth
|
3 |
+
from response import ResponseAuth as res
|
4 |
+
from service import AuthService
|
5 |
+
from function import support_function
|
6 |
+
router = APIRouter()
|
7 |
+
|
8 |
+
@router.post('/login', tags=["Authentication"])
|
9 |
+
async def login(request: RequestAuth.RequestLoginEmail):
|
10 |
+
email = request.email
|
11 |
+
check = support_function.check_value_email_controller(email)
|
12 |
+
if check is not True:
|
13 |
+
return check
|
14 |
+
password = request.password
|
15 |
+
if password is None or password.strip() == "":
|
16 |
+
return res.ReponseError(status=400,
|
17 |
+
data=res.Message(message="Password is required."))
|
18 |
+
return AuthService.login(request)
|
19 |
+
|
20 |
+
@router.post('/login_google', tags=["Authentication"])
|
21 |
+
async def login_google(request: RequestAuth.RequestLoginGoogle):
|
22 |
+
email = request.email
|
23 |
+
token_google = request.token_google
|
24 |
+
check = support_function.check_value_email_controller(email)
|
25 |
+
if check is not True:
|
26 |
+
return check
|
27 |
+
if token_google is None or token_google.strip() == "":
|
28 |
+
return res.ReponseError(status=400,
|
29 |
+
data=res.Message(message="token_google oauth2 is required."))
|
30 |
+
if token_google.isdigit():
|
31 |
+
return res.ReponseError(status=400,
|
32 |
+
data=res.Message(message="token_google must be a string, not a number."))
|
33 |
+
return AuthService.login_google(request)
|
34 |
+
|
35 |
+
@router.post('/sign_up', tags=["Authentication"])
|
36 |
+
async def signup(request: RequestAuth.RequestRegister):
|
37 |
+
email = request.email
|
38 |
+
check = support_function.check_value_email_controller(email)
|
39 |
+
if check is not True:
|
40 |
+
return check
|
41 |
+
password = request.password
|
42 |
+
confirm_password = request.confirm_password
|
43 |
+
if password is None or password.strip( )== "":
|
44 |
+
return res.ReponseError(status=400,
|
45 |
+
data=res.Message(message="Password is required."))
|
46 |
+
if confirm_password is None or confirm_password.strip() == "":
|
47 |
+
return res.ReponseError(status=400,
|
48 |
+
data=res.Message(message="Confirm Password is required."))
|
49 |
+
return AuthService.sign_up(request)
|
50 |
+
|
51 |
+
|
52 |
+
@router.post('/refresh_token', tags=["Authentication"])
|
53 |
+
async def refresh_token_account(request: RequestAuth.RequestRefreshTokenLogin):
|
54 |
+
token = request.refresh_token
|
55 |
+
if token is None or token.strip() == "":
|
56 |
+
return res.ReponseError(status=400,
|
57 |
+
data=res.Message(message="token is required."))
|
58 |
+
elif token.isdigit():
|
59 |
+
return res.ReponseError(status=400,
|
60 |
+
data=res.Message(message="token must be string"))
|
61 |
+
|
62 |
+
return AuthService.refresh_token(request)
|
controller/ChatController.py
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import APIRouter, Form, Request
|
2 |
+
from service import ChatService
|
3 |
+
from request import RequestChat
|
4 |
+
from typing import Optional
|
5 |
+
from fastapi.requests import Request
|
6 |
+
from function import support_function
|
7 |
+
router = APIRouter()
|
8 |
+
|
9 |
+
@router.post("/chatbot/query", tags=["Chat"])
|
10 |
+
async def handle_query2_upgrade_old(request: Request,
|
11 |
+
user_id: str = Form(None),
|
12 |
+
text_all: str = Form(...),
|
13 |
+
question: Optional[str] = Form(None),
|
14 |
+
chat_name: Optional[str] = Form(None)):
|
15 |
+
check = support_function.check_value_user_id_controller(user_id)
|
16 |
+
if check is not True:
|
17 |
+
return check
|
18 |
+
request = RequestChat.RequestQuery2UpgradeOld(user_id=user_id, text_all=text_all, question=question, chat_name=chat_name)
|
19 |
+
return ChatService.query2_upgrade_old(request)
|
20 |
+
|
21 |
+
@router.get("/chatbot/extract_file/{user_id}", tags=["Chat"])
|
22 |
+
async def extract_file(user_id: str):
|
23 |
+
check = support_function.check_value_user_id_controller(user_id)
|
24 |
+
if check is not True:
|
25 |
+
return check
|
26 |
+
request = RequestChat.RequestExtractFile(user_id=user_id)
|
27 |
+
return ChatService.extract_file(request)
|
28 |
+
|
29 |
+
@router.get("/chatbot/generate_question/{user_id}",tags=["Chat"])
|
30 |
+
async def generate_question(user_id: str):
|
31 |
+
check = support_function.check_value_user_id_controller(user_id)
|
32 |
+
if check is not True:
|
33 |
+
return check
|
34 |
+
request = RequestChat.RequestGenerateQuestion(user_id=user_id)
|
35 |
+
return ChatService.generate_question(request)
|
controller/DefaultController.py
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import Query,APIRouter
|
2 |
+
from service import DefaultService
|
3 |
+
from request import RequestDefault
|
4 |
+
from request import RequestDefault as req
|
5 |
+
from function import support_function
|
6 |
+
from response import ResponseDefault as res
|
7 |
+
from fastapi import File, UploadFile, Form
|
8 |
+
router = APIRouter()
|
9 |
+
|
10 |
+
@router.get("/is_me", tags=["Default"])
|
11 |
+
async def is_me(token: str = Query(...)):
|
12 |
+
if token.strip() == "" or token is None:
|
13 |
+
return res.ReponseError(status=400,
|
14 |
+
data=res.Message(message="Token field is required."))
|
15 |
+
if token.lower() == "none":
|
16 |
+
return res.ReponseError(status=400,
|
17 |
+
data=res.Message(message="Token cannot be None."))
|
18 |
+
if not isinstance(token, str):
|
19 |
+
return res.ReponseError(status=400,
|
20 |
+
data=res.Message(message="Token must be a non-empty string."))
|
21 |
+
try:
|
22 |
+
float(token)
|
23 |
+
return res.ReponseError(status=400,
|
24 |
+
data=res.Message(message="Token must be a string, not a number."))
|
25 |
+
except ValueError:
|
26 |
+
pass
|
27 |
+
request = RequestDefault.RequestIsMe(token=token)
|
28 |
+
return DefaultService.is_me(request)
|
29 |
+
|
30 |
+
@router.post('/create_firebase_user_google', tags=["Default"])
|
31 |
+
async def get_or_create_firebase_user(request: RequestDefault.RequestCreateFireBaseUserGoogle):
|
32 |
+
email = request.email
|
33 |
+
check = support_function.check_value_email_controller(request.email)
|
34 |
+
if check is not True:
|
35 |
+
return check
|
36 |
+
token_google = request.token_google
|
37 |
+
if token_google == "" or token_google is None:
|
38 |
+
return res.ReponseError(status=400,
|
39 |
+
data=res.Message(message="Token field is required."))
|
40 |
+
if not isinstance(token_google, str):
|
41 |
+
return res.ReponseError(status=400,
|
42 |
+
data=res.Message(message="Token must be a non-empty string."))
|
43 |
+
try:
|
44 |
+
float(token_google)
|
45 |
+
return res.ReponseError(status=400,
|
46 |
+
data=res.Message(message="Token must be a string, not a number."))
|
47 |
+
except ValueError:
|
48 |
+
pass
|
49 |
+
return DefaultService.create_firebase_user(request)
|
50 |
+
|
51 |
+
@router.get("/info_user/{user_id}", tags=["Default"])
|
52 |
+
async def get_user(user_id: str):
|
53 |
+
check = support_function.check_value_user_id_controller(user_id)
|
54 |
+
if check is not True:
|
55 |
+
return check
|
56 |
+
request = RequestDefault.RequestInfoUser(user_id=user_id)
|
57 |
+
return DefaultService.info_user(request)
|
58 |
+
|
59 |
+
ALLOWED_IMAGE_EXTENSIONS = {"jpeg", "jpg", "png"}
|
60 |
+
|
61 |
+
def allowed_file(filename: str) -> bool:
|
62 |
+
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_IMAGE_EXTENSIONS
|
63 |
+
|
64 |
+
@router.post("/upload_image", tags=["Default"])
|
65 |
+
async def upload_image(user_id: str = Form(None), file: UploadFile = File(...)):
|
66 |
+
check = support_function.check_value_user_id_controller(user_id)
|
67 |
+
if check is not True:
|
68 |
+
return check
|
69 |
+
request = req.RequestUpLoadImage(user_id=user_id, files= file)
|
70 |
+
return DefaultService.upload_image_service(request)
|
controller/FileController.py
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import APIRouter, Form, File, UploadFile
|
2 |
+
from typing import List,Optional
|
3 |
+
from service import FileService
|
4 |
+
from function import support_function
|
5 |
+
from response import ResponseFile as res
|
6 |
+
from request import RequestFile
|
7 |
+
router = APIRouter()
|
8 |
+
|
9 |
+
ALLOWED_EXTENSIONS = {'csv', 'txt', 'doc', 'docx', 'pdf', 'xlsx', 'pptx', 'json', 'html'}
|
10 |
+
def allowed_file(filename):
|
11 |
+
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
12 |
+
|
13 |
+
@router.delete("/delete", tags=["File"])
|
14 |
+
async def delete_folder(request: RequestFile.RequestDeleteAllFile):
|
15 |
+
check = support_function.check_value_user_id_controller(request.user_id)
|
16 |
+
if check is not True:
|
17 |
+
return check
|
18 |
+
# request = RequestFile.RequestDeleteAllFile(user_id=user_id)
|
19 |
+
return FileService.deleteAllFile(request)
|
20 |
+
|
21 |
+
@router.get("/list_name_files", tags=["File"])
|
22 |
+
async def get_name(user_id: str):
|
23 |
+
check = support_function.check_value_user_id_controller(user_id)
|
24 |
+
if check is not True:
|
25 |
+
return check
|
26 |
+
request = RequestFile.RequestGetNameFile(user_id=user_id)
|
27 |
+
return FileService.listNameFiles(request)
|
28 |
+
|
29 |
+
@router.delete("/delete_file", tags=["File"])
|
30 |
+
async def delete_one_file(request: RequestFile.RequestDeleteFile):
|
31 |
+
user_id = request.user_id
|
32 |
+
check = support_function.check_value_user_id_controller(user_id)
|
33 |
+
if check is not True:
|
34 |
+
return check
|
35 |
+
name_file = request.name_file
|
36 |
+
if name_file is None or name_file.strip() == "":
|
37 |
+
return res.ReponseError(status=400,
|
38 |
+
data=res.Message(message="Name file is required."))
|
39 |
+
return FileService.deleteFile(request)
|
40 |
+
|
41 |
+
@router.post("/chatbot/download_folder", tags=["File"])
|
42 |
+
async def download_folder_from_dropbox(request: RequestFile.RequestDownLoadFolder):
|
43 |
+
user_id = request.user_id
|
44 |
+
check = support_function.check_value_user_id_controller(user_id)
|
45 |
+
if check is not True:
|
46 |
+
return check
|
47 |
+
return FileService.download_folder(request)
|
48 |
+
|
49 |
+
@router.post("/chatbot/download_files", tags=["File"])
|
50 |
+
async def download_file_by_id(request: RequestFile.RequestDownLoadFile):
|
51 |
+
user_id = request.user_id
|
52 |
+
check = support_function.check_value_user_id_controller(user_id)
|
53 |
+
if check is not True:
|
54 |
+
return check
|
55 |
+
return FileService.download_file(request)
|
56 |
+
|
57 |
+
@router.post("/upload_files", tags=["File"])
|
58 |
+
async def upload_files_dropbox(user_id: str = Form(None), files: Optional[List[UploadFile]] = File(None)):
|
59 |
+
check = support_function.check_value_user_id_controller(user_id)
|
60 |
+
if check is not True:
|
61 |
+
return check
|
62 |
+
request = RequestFile.RequestUploadFile(files=files, user_id=user_id)
|
63 |
+
return FileService.upload_files(request)
|
controller/MySQLController.py
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import Query, APIRouter
|
2 |
+
from service import MySQLService
|
3 |
+
from request import RequestMySQL
|
4 |
+
from response import ResponseMySQL as res
|
5 |
+
from request import RequestMySQL as req
|
6 |
+
from function import support_function
|
7 |
+
router = APIRouter()
|
8 |
+
|
9 |
+
@router.get("/chat_history/{user_id}", tags=["MySQL"])
|
10 |
+
async def render_chat(user_id: str):
|
11 |
+
check = support_function.check_value_user_id_controller(user_id)
|
12 |
+
if check is not True:
|
13 |
+
return check
|
14 |
+
request = RequestMySQL.RequestRenderChatHistory(user_id=user_id)
|
15 |
+
return MySQLService.render_chat_history(request)
|
16 |
+
|
17 |
+
@router.get("/data_relevant/{detail_chat_id}", tags=["MySQL"])
|
18 |
+
async def render_chat_1(detail_chat_id: str):
|
19 |
+
if detail_chat_id is None or detail_chat_id.strip() == "":
|
20 |
+
return res.ReponseError(status=400,
|
21 |
+
data=res.Message(message="Id field is required."))
|
22 |
+
detail_chat_id = detail_chat_id.strip("'").strip('"')
|
23 |
+
try:
|
24 |
+
detail_chat_id_int = int(detail_chat_id)
|
25 |
+
except ValueError:
|
26 |
+
return res.ReponseError(status=400,
|
27 |
+
data=res.Message(message="Value must be an integer"))
|
28 |
+
if not support_function.is_positive_integer(detail_chat_id_int):
|
29 |
+
return res.ReponseError(status=400,
|
30 |
+
data=res.Message(message="Value must be greater than 0"))
|
31 |
+
request = req.RequestGetChatDetails(id=detail_chat_id)
|
32 |
+
return MySQLService.get_detail_chat_by_chat_id(request)
|
33 |
+
|
34 |
+
@router.get("/detail_chat/{user_id}/{chat_id}", tags=["MySQL"])
|
35 |
+
async def load_chat(chat_id: str, user_id: str):
|
36 |
+
check = support_function.check_value_user_id_controller(user_id)
|
37 |
+
if check is not True:
|
38 |
+
return check
|
39 |
+
if chat_id is None or chat_id.strip() == "":
|
40 |
+
return res.ReponseError(status=400,
|
41 |
+
data=res.Message(message="Chat id field is required."))
|
42 |
+
chat_id = chat_id.strip("'").strip('"')
|
43 |
+
try:
|
44 |
+
chat_id_int = int(chat_id)
|
45 |
+
except ValueError:
|
46 |
+
return res.ReponseError(status=400,
|
47 |
+
data=res.Message(message="Value must be an integer"))
|
48 |
+
if not support_function.is_positive_integer(chat_id_int):
|
49 |
+
return res.ReponseError(status=400,
|
50 |
+
data=res.Message(message="Value must be greater than 0"))
|
51 |
+
request = req.RequestLoadChatHistory(chat_id=chat_id,user_id = user_id)
|
52 |
+
return MySQLService.load_chat_history(request)
|
53 |
+
|
54 |
+
@router.put("/edit_chat", tags=["MySQL"])
|
55 |
+
async def edit_chat(request: RequestMySQL.RequestEditNameChat):
|
56 |
+
user_id = request.user_id
|
57 |
+
check = support_function.check_value_user_id_controller(user_id)
|
58 |
+
if check is not True:
|
59 |
+
return check
|
60 |
+
return MySQLService.edit_chat(request)
|
61 |
+
|
62 |
+
@router.delete("/chat_history/delete", tags=["MySQL"])
|
63 |
+
async def delete_chat(request: RequestMySQL.RequestDeleteChat):
|
64 |
+
user_id = request.user_id
|
65 |
+
check = support_function.check_value_user_id_controller(user_id)
|
66 |
+
if check is not True:
|
67 |
+
return check
|
68 |
+
return MySQLService.delete_chat(request)
|
69 |
+
|
70 |
+
@router.delete("/detail_chat/delete", tags=["MySQL"])
|
71 |
+
async def delete_chat_detail(request: RequestMySQL.RequestDeleteDetailChat):
|
72 |
+
user_id = request.user_id
|
73 |
+
check = support_function.check_value_user_id_controller(user_id)
|
74 |
+
if check is not True:
|
75 |
+
return check
|
76 |
+
return MySQLService.delete_chat_detail_by_id(request)
|
controller/OTPController.py
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import APIRouter
|
2 |
+
from function import support_function
|
3 |
+
from request import RequestOTP
|
4 |
+
from service import OTPService
|
5 |
+
router = APIRouter()
|
6 |
+
|
7 |
+
@router.post('/create_otp', tags=["OTP"])
|
8 |
+
async def create_otp(request: RequestOTP.RequestCreateOTP):
|
9 |
+
email = request.email
|
10 |
+
check = support_function.check_value_email_controller(email)
|
11 |
+
if check is not True:
|
12 |
+
return check
|
13 |
+
return OTPService.createOTP(request)
|
14 |
+
|
15 |
+
@router.post('/verify_otp', tags=["OTP"])
|
16 |
+
async def verify_otp(request: RequestOTP.RequestVerifyOTP):
|
17 |
+
check = support_function.check_value_email_controller(request.email)
|
18 |
+
if check is not True:
|
19 |
+
return check
|
20 |
+
check_otp = support_function.check_value_otp(request.otp)
|
21 |
+
if check_otp is not True:
|
22 |
+
return check_otp
|
23 |
+
return OTPService.verifyOTP(request)
|
24 |
+
|
25 |
+
@router.post('/verify_otp_reset_password', tags=["OTP"])
|
26 |
+
async def verify_otp_reset(request: RequestOTP.RequestVerifyOTP):
|
27 |
+
check = support_function.check_value_email_controller(request.email)
|
28 |
+
if check is not True:
|
29 |
+
return check
|
30 |
+
check_otp = support_function.check_value_otp(request.otp)
|
31 |
+
if check_otp is not True:
|
32 |
+
return check_otp
|
33 |
+
return OTPService.verifyOTPReset(request)
|
controller/UserController.py
ADDED
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import APIRouter, Query
|
2 |
+
from request import RequestUser
|
3 |
+
from response import ResponseUser as res
|
4 |
+
from service import UserService
|
5 |
+
from function import support_function
|
6 |
+
router = APIRouter()
|
7 |
+
|
8 |
+
@router.post("/update_user_info", tags=["User"])
|
9 |
+
async def update_user_info(request:RequestUser.RequestUpdateUserInfo):
|
10 |
+
user_id = request.user_id
|
11 |
+
check = support_function.check_value_user_id_controller(user_id)
|
12 |
+
if check is not True:
|
13 |
+
return check
|
14 |
+
uid = request.uid
|
15 |
+
email = request.email
|
16 |
+
display_name = request.display_name
|
17 |
+
photo_url = request.photo_url
|
18 |
+
if uid is None or uid.strip() == "":
|
19 |
+
return res.ReponseError(status=400,
|
20 |
+
data=res.Message(message="uid field is required."))
|
21 |
+
if email is None or email.strip() == "":
|
22 |
+
return res.ReponseError(status=400,
|
23 |
+
data=res.Message(message="email field is required."))
|
24 |
+
if display_name is None or display_name.strip() == "":
|
25 |
+
return res.ReponseError(status=400,
|
26 |
+
data=res.Message(message="display_name field is required."))
|
27 |
+
if photo_url is None or photo_url.strip() == "":
|
28 |
+
return res.ReponseError(status=400,
|
29 |
+
data=res.Message(message="photo_url field is required."))
|
30 |
+
return UserService.update_user_info(request)
|
31 |
+
|
32 |
+
@router.get('/check_info_google', tags=["User"])
|
33 |
+
async def check_info_google(user_id: str = Query(None)):
|
34 |
+
check = support_function.check_value_user_id_controller(user_id)
|
35 |
+
if check is not True:
|
36 |
+
return check
|
37 |
+
request =RequestUser.RequestCheckInfoGoogle(user_id=user_id)
|
38 |
+
return UserService.check_info_google(request)
|
39 |
+
|
40 |
+
@router.get('/check_info_google_signup', tags=["User"])
|
41 |
+
async def check_info_google_signup(email: str = None):
|
42 |
+
check = support_function.check_value_email_controller(email)
|
43 |
+
if check is not True:
|
44 |
+
return check
|
45 |
+
request =RequestUser.RequestCheckInfoGoogleEmail(email=email)
|
46 |
+
return UserService.check_info_google_email(request)
|
47 |
+
|
48 |
+
@router.get('/check_state_login', tags=["User"])
|
49 |
+
async def check_state_login(user_id: str = Query(None), session_id_now: str = Query(None)):
|
50 |
+
check = support_function.check_value_user_id_controller(user_id)
|
51 |
+
if check is not True:
|
52 |
+
return check
|
53 |
+
if session_id_now is None or session_id_now.strip() == "":
|
54 |
+
return res.ReponseError(status=400,
|
55 |
+
data=res.Message(message="Session Id is required."))
|
56 |
+
try:
|
57 |
+
int(session_id_now)
|
58 |
+
return res.ReponseError(status=400,
|
59 |
+
data=res.Message(message="Session Id must be a string, not a number."))
|
60 |
+
except ValueError:
|
61 |
+
pass
|
62 |
+
request =RequestUser.RequestCheckStateLogin(user_id=user_id, session_id_now=session_id_now)
|
63 |
+
return UserService.check_state_login(request)
|
64 |
+
|
65 |
+
|
66 |
+
@router.post('/reset_password', tags=["User"])
|
67 |
+
async def reset_password(request:RequestUser.RequestResetPassword):
|
68 |
+
email = request.email
|
69 |
+
check = support_function.check_value_email_controller(email)
|
70 |
+
if check is not True:
|
71 |
+
return check
|
72 |
+
return UserService.reset_password(request)
|
73 |
+
|
74 |
+
@router.put('/change_password', tags=["User"])
|
75 |
+
async def reset_password_firebase(request:RequestUser.RequestChangePassword):
|
76 |
+
user_id = request.user_id
|
77 |
+
check = support_function.check_value_user_id_controller(user_id)
|
78 |
+
if check is not True:
|
79 |
+
return check
|
80 |
+
new_password = request.new_password
|
81 |
+
current_password = request.current_password
|
82 |
+
confirm_new_password = request.confirm_new_password
|
83 |
+
if confirm_new_password is None or confirm_new_password.strip() == "":
|
84 |
+
return res.ReponseError(status=400,
|
85 |
+
data=res.Message(message="Confirm New password field is required."))
|
86 |
+
elif new_password is None or new_password.strip() == "":
|
87 |
+
return res.ReponseError(status=400,
|
88 |
+
data=res.Message(message="New password field is required."))
|
89 |
+
elif current_password is None or current_password.strip() == "":
|
90 |
+
return res.ReponseError(status=400,
|
91 |
+
data=res.Message(message="Current password field is required."))
|
92 |
+
return UserService.change_password(request)
|
93 |
+
|
94 |
+
|
function/chatbot.py
ADDED
@@ -0,0 +1,685 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from langchain.text_splitter import CharacterTextSplitter
|
2 |
+
import json
|
3 |
+
import os
|
4 |
+
import random
|
5 |
+
import re
|
6 |
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
7 |
+
import google.generativeai as genai
|
8 |
+
import nltk
|
9 |
+
import pandas as pd
|
10 |
+
from groq import Groq
|
11 |
+
from langchain.chains.summarize import load_summarize_chain
|
12 |
+
from langchain.docstore.document import Document
|
13 |
+
from langchain.prompts import PromptTemplate
|
14 |
+
from langchain.retrievers import BM25Retriever, EnsembleRetriever
|
15 |
+
from langchain.retrievers.contextual_compression import ContextualCompressionRetriever
|
16 |
+
from langchain.text_splitter import CharacterTextSplitter
|
17 |
+
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
18 |
+
from langchain_cohere import CohereRerank
|
19 |
+
from langchain_community.document_loaders import Docx2txtLoader
|
20 |
+
from langchain_community.document_loaders import TextLoader
|
21 |
+
from langchain_community.document_loaders import UnstructuredCSVLoader
|
22 |
+
from langchain_community.document_loaders import UnstructuredExcelLoader
|
23 |
+
from langchain_community.document_loaders import UnstructuredHTMLLoader
|
24 |
+
from langchain_community.document_loaders import UnstructuredMarkdownLoader
|
25 |
+
from langchain_community.document_loaders import UnstructuredPDFLoader
|
26 |
+
from langchain_community.document_loaders import UnstructuredPowerPointLoader
|
27 |
+
from langchain_community.document_loaders import UnstructuredXMLLoader
|
28 |
+
from langchain_community.document_loaders.csv_loader import CSVLoader
|
29 |
+
from langchain_community.llms import Cohere
|
30 |
+
from langchain_community.vectorstores import Chroma
|
31 |
+
from langchain_core.output_parsers.openai_tools import PydanticToolsParser
|
32 |
+
from langchain_core.prompts import ChatPromptTemplate
|
33 |
+
from langchain_core.pydantic_v1 import BaseModel, Field
|
34 |
+
from langchain_core.runnables import RunnablePassthrough
|
35 |
+
from langchain_openai import ChatOpenAI
|
36 |
+
from typing import List
|
37 |
+
nltk.download('punkt')
|
38 |
+
|
39 |
+
def process_json_file(file_path):
|
40 |
+
json_data = []
|
41 |
+
with open(file_path, 'r') as file:
|
42 |
+
for line in file:
|
43 |
+
try:
|
44 |
+
data = json.loads(line)
|
45 |
+
json_data.append(data)
|
46 |
+
except json.JSONDecodeError:
|
47 |
+
try:
|
48 |
+
data = json.loads(line[:-1])
|
49 |
+
json_data.append(data)
|
50 |
+
except json.JSONDecodeError as e:
|
51 |
+
print(f"Error decoding JSON: {e}")
|
52 |
+
return json_data
|
53 |
+
|
54 |
+
|
55 |
+
from dotenv import load_dotenv
|
56 |
+
import os
|
57 |
+
load_dotenv()
|
58 |
+
GROQ_API_KEY = os.getenv("GROQ_API_KEY")
|
59 |
+
COHERE_API_KEY = os.getenv("COHERE_API_KEY")
|
60 |
+
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
|
61 |
+
GOOGLE_API_KEY1= os.getenv("GOOGLE_API_KEY_1")
|
62 |
+
GOOGLE_API_KEY= os.getenv("GOOGLE_API_KEY")
|
63 |
+
os.environ["COHERE_API_KEY"] = COHERE_API_KEY
|
64 |
+
os.environ["OPENAI_API_KEY"] = OPENAI_API_KEY
|
65 |
+
client = Groq(
|
66 |
+
api_key= GROQ_API_KEY,
|
67 |
+
)
|
68 |
+
genai.configure(api_key=GOOGLE_API_KEY1)
|
69 |
+
os.environ["GOOGLE_API_KEY"] = GOOGLE_API_KEY
|
70 |
+
from langchain_google_genai import GoogleGenerativeAIEmbeddings, ChatGoogleGenerativeAI
|
71 |
+
embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
|
72 |
+
llm = ChatGoogleGenerativeAI(model='gemini-pro',
|
73 |
+
max_output_tokens=2048,
|
74 |
+
temperature=0.3,
|
75 |
+
convert_system_message_to_human=True)
|
76 |
+
def extract_multi_metadata_content(texts, tests):
|
77 |
+
extracted_content = []
|
78 |
+
precomputed_metadata = [x.metadata['source'].lower() for x in texts]
|
79 |
+
for idx, test in enumerate(tests):
|
80 |
+
temp_content = []
|
81 |
+
test_terms = set(test.lower().split()) # Use set for faster lookup
|
82 |
+
for metadata_lower, x in zip(precomputed_metadata, texts):
|
83 |
+
if any(term in metadata_lower for term in test_terms):
|
84 |
+
temp_content.append(x.page_content)
|
85 |
+
if idx == 0:
|
86 |
+
extracted_content.append(f"Dữ liệu của {test}:\n{''.join(temp_content)}")
|
87 |
+
else:
|
88 |
+
extracted_content.append(''.join(temp_content))
|
89 |
+
return '\n'.join(extracted_content)
|
90 |
+
|
91 |
+
def find_matching_files_in_docs_12_id(text, id):
|
92 |
+
folder_path = f"./user_file/{id}"
|
93 |
+
search_terms = []
|
94 |
+
search_terms_old = []
|
95 |
+
matching_index = []
|
96 |
+
search_origin = re.findall(r'\b\w+\.\w+\b|\b\w+\b', text)
|
97 |
+
search_terms_origin = []
|
98 |
+
for word in search_origin:
|
99 |
+
if '.' in word:
|
100 |
+
search_terms_origin.append(word)
|
101 |
+
else:
|
102 |
+
search_terms_origin.extend(re.findall(r'\b\w+\b', word))
|
103 |
+
|
104 |
+
file_names_with_extension = re.findall(r'\b\w+\.\w+\b|\b\w+\b', text.lower())
|
105 |
+
file_names_with_extension_old = re.findall(r'\b(\w+\.\w+)\b', text)
|
106 |
+
for file_name in search_terms_origin:
|
107 |
+
if "." in file_name:
|
108 |
+
term_position = search_terms_origin.index(file_name)
|
109 |
+
search_terms_old.append(file_name)
|
110 |
+
for file_name in file_names_with_extension_old:
|
111 |
+
if "." in file_name:
|
112 |
+
search_terms_old.append(file_name)
|
113 |
+
for file_name in file_names_with_extension:
|
114 |
+
search_terms.append(file_name)
|
115 |
+
clean_text_old = text
|
116 |
+
clean_text = text.lower()
|
117 |
+
search_terms_old1 = list(set(search_terms_old))
|
118 |
+
for term in search_terms_old:
|
119 |
+
clean_text_old = clean_text_old.replace(term, '')
|
120 |
+
for term in search_terms:
|
121 |
+
clean_text = clean_text.replace(term, '')
|
122 |
+
words_old = re.findall(r'\b\w+\b', clean_text_old)
|
123 |
+
search_terms_old.extend(words_old)
|
124 |
+
matching_files = set()
|
125 |
+
matching_files_old = set()
|
126 |
+
for root, dirs, files in os.walk(folder_path):
|
127 |
+
for file in files:
|
128 |
+
for term in search_terms:
|
129 |
+
if term.lower() in file.lower():
|
130 |
+
term_position = search_terms.index(term)
|
131 |
+
term_value = search_terms_origin[term_position]
|
132 |
+
matching_files.add(file)
|
133 |
+
matching_index.append(term_position)
|
134 |
+
break
|
135 |
+
matching_files_old1 = []
|
136 |
+
matching_index.sort()
|
137 |
+
for x in matching_index:
|
138 |
+
matching_files_old1.append(search_terms_origin[x])
|
139 |
+
return matching_files, matching_files_old1
|
140 |
+
|
141 |
+
def convert_xlsx_to_csv(xlsx_file_path, csv_file_path):
|
142 |
+
df = pd.read_excel(xlsx_file_path)
|
143 |
+
df.to_csv(csv_file_path, index=False)
|
144 |
+
|
145 |
+
def save_list_CSV_id(file_list, id):
|
146 |
+
text = ""
|
147 |
+
for x in file_list:
|
148 |
+
if x.endswith('.xlsx'):
|
149 |
+
old = f"./user_file/{id}/{x}"
|
150 |
+
new = old.replace(".xlsx", ".csv")
|
151 |
+
convert_xlsx_to_csv(old, new)
|
152 |
+
x = x.replace(".xlsx", ".csv")
|
153 |
+
loader1 = CSVLoader(f"./user_file/{id}/{x}")
|
154 |
+
docs1 = loader1.load()
|
155 |
+
text += f"Dữ liệu file {x}:\n"
|
156 |
+
for z in docs1:
|
157 |
+
text += z.page_content + "\n"
|
158 |
+
return text
|
159 |
+
|
160 |
+
def merge_files(file_set, file_list):
|
161 |
+
"""Hàm này ghép lại các tên file dựa trên điều kiện đã cho."""
|
162 |
+
merged_files = {}
|
163 |
+
for file_name in file_list:
|
164 |
+
name = file_name.split('.')[0]
|
165 |
+
for f in file_set:
|
166 |
+
if name in f:
|
167 |
+
merged_files[name] = f
|
168 |
+
break
|
169 |
+
return merged_files
|
170 |
+
|
171 |
+
def replace_keys_with_values(original_dict, replacement_dict):
|
172 |
+
new_dict = {}
|
173 |
+
for key, value in original_dict.items():
|
174 |
+
if key in replacement_dict:
|
175 |
+
new_key = replacement_dict[key]
|
176 |
+
new_dict[new_key] = value
|
177 |
+
else:
|
178 |
+
new_dict[key] = value
|
179 |
+
return new_dict
|
180 |
+
|
181 |
+
def aws1_csv_id(new_dict_csv, id):
|
182 |
+
text = ""
|
183 |
+
query_all = ""
|
184 |
+
keyword = []
|
185 |
+
for key, value in new_dict_csv.items():
|
186 |
+
print(key, value)
|
187 |
+
query_all += value
|
188 |
+
keyword.append(key)
|
189 |
+
test = save_list_CSV_id(keyword, id)
|
190 |
+
text += test
|
191 |
+
sources = ",".join(keyword)
|
192 |
+
return text, query_all, sources
|
193 |
+
|
194 |
+
def chat_llama3(prompt_query):
|
195 |
+
try:
|
196 |
+
chat_completion = client.chat.completions.create(
|
197 |
+
messages=[
|
198 |
+
{
|
199 |
+
"role": "system",
|
200 |
+
"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."
|
201 |
+
},
|
202 |
+
{
|
203 |
+
"role": "user",
|
204 |
+
"content": f"{prompt_query}",
|
205 |
+
}
|
206 |
+
],
|
207 |
+
model="llama3-70b-8192",
|
208 |
+
temperature=0.0,
|
209 |
+
max_tokens=9000,
|
210 |
+
stop=None,
|
211 |
+
stream=False,
|
212 |
+
)
|
213 |
+
return chat_completion.choices[0].message.content
|
214 |
+
except Exception as error:
|
215 |
+
return False
|
216 |
+
|
217 |
+
def chat_gemini(prompt):
|
218 |
+
generation_config = {
|
219 |
+
"temperature": 0.0,
|
220 |
+
"top_p": 0.0,
|
221 |
+
"top_k": 0,
|
222 |
+
"max_output_tokens": 8192,
|
223 |
+
}
|
224 |
+
safety_settings = [
|
225 |
+
{
|
226 |
+
"category": "HARM_CATEGORY_HARASSMENT",
|
227 |
+
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
|
228 |
+
},
|
229 |
+
{
|
230 |
+
"category": "HARM_CATEGORY_HATE_SPEECH",
|
231 |
+
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
|
232 |
+
},
|
233 |
+
{
|
234 |
+
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
|
235 |
+
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
|
236 |
+
},
|
237 |
+
{
|
238 |
+
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
|
239 |
+
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
|
240 |
+
},
|
241 |
+
]
|
242 |
+
model = genai.GenerativeModel(model_name="gemini-1.5-pro-latest",
|
243 |
+
generation_config=generation_config,
|
244 |
+
safety_settings=safety_settings)
|
245 |
+
convo = model.start_chat(history=[])
|
246 |
+
convo.send_message(prompt)
|
247 |
+
return convo.last.text
|
248 |
+
|
249 |
+
def question_answer(question):
|
250 |
+
completion = chat_llama3(question)
|
251 |
+
if completion:
|
252 |
+
return completion
|
253 |
+
else:
|
254 |
+
answer = chat_gemini(question)
|
255 |
+
return answer
|
256 |
+
|
257 |
+
def check_persist_directory(id, file_name):
|
258 |
+
directory_path = f"./vector_database/{id}/{file_name}"
|
259 |
+
return os.path.exists(directory_path)
|
260 |
+
|
261 |
+
from langchain_community.vectorstores import FAISS
|
262 |
+
|
263 |
+
def check_path_exists(path):
|
264 |
+
return os.path.exists(path)
|
265 |
+
def aws1_all_id(new_dict, text_alls, id, thread_id):
|
266 |
+
answer = ""
|
267 |
+
COHERE_API_KEY1 = os.getenv("COHERE_API_KEY_1")
|
268 |
+
os.environ["COHERE_API_KEY"] = COHERE_API_KEY1
|
269 |
+
answer_relevant = ""
|
270 |
+
directory = ""
|
271 |
+
|
272 |
+
for key, value in new_dict.items():
|
273 |
+
query = value
|
274 |
+
keyword, keyword2 = find_matching_files_in_docs_12_id(query, id)
|
275 |
+
data = extract_multi_metadata_content(text_alls, keyword)
|
276 |
+
if keyword:
|
277 |
+
file_name = next(iter(keyword))
|
278 |
+
text_splitter = CharacterTextSplitter(chunk_size=3200, chunk_overlap=1500)
|
279 |
+
texts_data = text_splitter.split_text(data)
|
280 |
+
|
281 |
+
if check_persist_directory(id, file_name):
|
282 |
+
vectordb_query = Chroma(persist_directory=f"./vector_database/{id}/{file_name}", embedding_function=embeddings)
|
283 |
+
else:
|
284 |
+
vectordb_query = Chroma.from_texts(texts_data,
|
285 |
+
embedding=embeddings,
|
286 |
+
persist_directory=f"./vector_database/{id}/{file_name}")
|
287 |
+
|
288 |
+
k_1 = len(texts_data)
|
289 |
+
retriever = vectordb_query.as_retriever(search_kwargs={f"k": k_1})
|
290 |
+
bm25_retriever = BM25Retriever.from_texts(texts_data)
|
291 |
+
bm25_retriever.k = k_1
|
292 |
+
ensemble_retriever = EnsembleRetriever(retrievers=[bm25_retriever, retriever],
|
293 |
+
weights=[0.6, 0.4])
|
294 |
+
docs = ensemble_retriever.get_relevant_documents(f"{query}")
|
295 |
+
|
296 |
+
path = f"./vector_database/FAISS/{id}/{file_name}"
|
297 |
+
if check_path_exists(path):
|
298 |
+
docsearch = FAISS.load_local(path, embeddings, allow_dangerous_deserialization=True)
|
299 |
+
else:
|
300 |
+
docsearch = FAISS.from_documents(docs, embeddings)
|
301 |
+
docsearch.save_local(f"./vector_database/FAISS/{id}/{file_name}")
|
302 |
+
docsearch = FAISS.load_local(path, embeddings, allow_dangerous_deserialization=True)
|
303 |
+
|
304 |
+
k_2 = len(docs)
|
305 |
+
compressor = CohereRerank(top_n=5)
|
306 |
+
retrieve3 = docsearch.as_retriever(search_kwargs={f"k": k_2})
|
307 |
+
compression_retriever = ContextualCompressionRetriever(
|
308 |
+
base_compressor=compressor, base_retriever=retrieve3
|
309 |
+
)
|
310 |
+
compressed_docs = compression_retriever.get_relevant_documents(f"{query}")
|
311 |
+
|
312 |
+
if compressed_docs:
|
313 |
+
data = compressed_docs[0].page_content
|
314 |
+
text = ''.join(map(lambda x: x.page_content, compressed_docs))
|
315 |
+
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"
|
316 |
+
answer_for = question_answer(prompt_document)
|
317 |
+
answer += answer_for + "\n"
|
318 |
+
answer_relevant = data
|
319 |
+
directory = file_name
|
320 |
+
|
321 |
+
return answer, answer_relevant, directory
|
322 |
+
|
323 |
+
def extract_content_between_keywords(query, keywords):
|
324 |
+
contents = {}
|
325 |
+
num_keywords = len(keywords)
|
326 |
+
keyword_positions = []
|
327 |
+
for i in range(num_keywords):
|
328 |
+
keyword = keywords[i]
|
329 |
+
keyword_position = query.find(keyword)
|
330 |
+
keyword_positions.append(keyword_position)
|
331 |
+
if keyword_position == -1:
|
332 |
+
continue
|
333 |
+
next_keyword_position = len(query)
|
334 |
+
for j in range(i + 1, num_keywords):
|
335 |
+
next_keyword = keywords[j]
|
336 |
+
next_keyword_position = query.find(next_keyword)
|
337 |
+
if next_keyword_position != -1:
|
338 |
+
break
|
339 |
+
if i == 0:
|
340 |
+
content_before = query[:keyword_position].strip()
|
341 |
+
else:
|
342 |
+
content_before = query[keyword_positions[i - 1] + len(keywords[i - 1]):keyword_position].strip()
|
343 |
+
if i == num_keywords - 1:
|
344 |
+
content_after = query[keyword_position + len(keyword):].strip()
|
345 |
+
else:
|
346 |
+
content_after = query[keyword_position + len(keyword):next_keyword_position].strip()
|
347 |
+
content = f"{content_before} {keyword} {content_after}"
|
348 |
+
contents[keyword] = content
|
349 |
+
return contents
|
350 |
+
|
351 |
+
def generate_random_questions(filtered_ques_list):
|
352 |
+
if len(filtered_ques_list) >= 2:
|
353 |
+
random_questions = random.sample(filtered_ques_list, 2)
|
354 |
+
else:
|
355 |
+
random_questions = filtered_ques_list
|
356 |
+
return random_questions
|
357 |
+
|
358 |
+
def generate_question_main(loader, name_file):
|
359 |
+
text_splitter = RecursiveCharacterTextSplitter(chunk_size=4500, chunk_overlap=2500)
|
360 |
+
texts = text_splitter.split_documents(loader)
|
361 |
+
question_gen = f"nội dung {name_file} : \n"
|
362 |
+
question_gen += texts[0].page_content
|
363 |
+
splitter_ques_gen = RecursiveCharacterTextSplitter(
|
364 |
+
chunk_size=4500,
|
365 |
+
chunk_overlap=2200
|
366 |
+
)
|
367 |
+
chunks_ques_gen = splitter_ques_gen.split_text(question_gen)
|
368 |
+
document_ques_gen = [Document(page_content=t) for t in chunks_ques_gen]
|
369 |
+
llm_ques_gen_pipeline = llm
|
370 |
+
prompt_template_vn = """
|
371 |
+
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.
|
372 |
+
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:
|
373 |
+
|
374 |
+
------------
|
375 |
+
{text}
|
376 |
+
------------
|
377 |
+
|
378 |
+
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.
|
379 |
+
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.
|
380 |
+
|
381 |
+
CÁC CÂU HỎI:
|
382 |
+
"""
|
383 |
+
|
384 |
+
PROMPT_QUESTIONS_VN = PromptTemplate(template=prompt_template_vn, input_variables=["text"])
|
385 |
+
refine_template_vn = ("""
|
386 |
+
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.
|
387 |
+
Mục tiêu của bạn là giúp người học chuẩn bị cho một kỳ thi.
|
388 |
+
Chúng tôi đã nhận được một số câu hỏi thực hành ở mức độ nào đó: {existing_answer}.
|
389 |
+
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
|
390 |
+
(chỉ khi cần thiết) với một số ngữ cảnh bổ sung dưới đây.
|
391 |
+
------------
|
392 |
+
{text}
|
393 |
+
------------
|
394 |
+
|
395 |
+
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.
|
396 |
+
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.
|
397 |
+
CÁC CÂU HỎI:
|
398 |
+
"""
|
399 |
+
)
|
400 |
+
|
401 |
+
REFINE_PROMPT_QUESTIONS = PromptTemplate(
|
402 |
+
input_variables=["existing_answer", "text"],
|
403 |
+
template=refine_template_vn,
|
404 |
+
)
|
405 |
+
ques_gen_chain = load_summarize_chain(llm=llm_ques_gen_pipeline,
|
406 |
+
chain_type="refine",
|
407 |
+
verbose=True,
|
408 |
+
question_prompt=PROMPT_QUESTIONS_VN,
|
409 |
+
refine_prompt=REFINE_PROMPT_QUESTIONS)
|
410 |
+
ques = ques_gen_chain.run(document_ques_gen)
|
411 |
+
ques_list = ques.split("\n")
|
412 |
+
filtered_ques_list = ["{}: {}".format(name_file, re.sub(r'^\d+\.\s*', '', element)) for element in ques_list if
|
413 |
+
element.endswith('?') or element.endswith('.')]
|
414 |
+
return generate_random_questions(filtered_ques_list)
|
415 |
+
|
416 |
+
def load_file(loader):
|
417 |
+
return loader.load()
|
418 |
+
|
419 |
+
def extract_data2(id):
|
420 |
+
documents = []
|
421 |
+
directory_path = f"./user_file/{id}"
|
422 |
+
if not os.path.exists(directory_path) or not any(
|
423 |
+
os.path.isfile(os.path.join(directory_path, f)) for f in os.listdir(directory_path)):
|
424 |
+
return False
|
425 |
+
tasks = []
|
426 |
+
with ThreadPoolExecutor() as executor:
|
427 |
+
for file in os.listdir(directory_path):
|
428 |
+
if file.endswith(".pdf"):
|
429 |
+
pdf_path = os.path.join(directory_path, file)
|
430 |
+
loader = UnstructuredPDFLoader(pdf_path)
|
431 |
+
tasks.append(executor.submit(load_file, loader))
|
432 |
+
elif file.endswith('.docx') or file.endswith('.doc'):
|
433 |
+
doc_path = os.path.join(directory_path, file)
|
434 |
+
loader = Docx2txtLoader(doc_path)
|
435 |
+
tasks.append(executor.submit(load_file, loader))
|
436 |
+
elif file.endswith('.txt'):
|
437 |
+
txt_path = os.path.join(directory_path, file)
|
438 |
+
loader = TextLoader(txt_path, encoding="utf8")
|
439 |
+
tasks.append(executor.submit(load_file, loader))
|
440 |
+
elif file.endswith('.pptx'):
|
441 |
+
ppt_path = os.path.join(directory_path, file)
|
442 |
+
loader = UnstructuredPowerPointLoader(ppt_path)
|
443 |
+
tasks.append(executor.submit(load_file, loader))
|
444 |
+
elif file.endswith('.csv'):
|
445 |
+
csv_path = os.path.join(directory_path, file)
|
446 |
+
loader = UnstructuredCSVLoader(csv_path)
|
447 |
+
tasks.append(executor.submit(load_file, loader))
|
448 |
+
elif file.endswith('.xlsx'):
|
449 |
+
excel_path = os.path.join(directory_path, file)
|
450 |
+
loader = UnstructuredExcelLoader(excel_path)
|
451 |
+
tasks.append(executor.submit(load_file, loader))
|
452 |
+
elif file.endswith('.json'):
|
453 |
+
json_path = os.path.join(directory_path, file)
|
454 |
+
loader = TextLoader(json_path)
|
455 |
+
tasks.append(executor.submit(load_file, loader))
|
456 |
+
elif file.endswith('.md'):
|
457 |
+
md_path = os.path.join(directory_path, file)
|
458 |
+
loader = UnstructuredMarkdownLoader(md_path)
|
459 |
+
tasks.append(executor.submit(load_file, loader))
|
460 |
+
for future in as_completed(tasks):
|
461 |
+
result = future.result()
|
462 |
+
documents.extend(result)
|
463 |
+
text_splitter = CharacterTextSplitter(chunk_size=4500, chunk_overlap=2500)
|
464 |
+
texts = text_splitter.split_documents(documents)
|
465 |
+
Chroma.from_documents(documents=texts,
|
466 |
+
embedding=embeddings,
|
467 |
+
persist_directory=f"./vector_database/{id}")
|
468 |
+
return texts
|
469 |
+
|
470 |
+
def generate_question(id):
|
471 |
+
directory_path = f"./user_file/{id}"
|
472 |
+
if not os.path.exists(directory_path) or not any(
|
473 |
+
os.path.isfile(os.path.join(directory_path, f)) for f in os.listdir(directory_path)):
|
474 |
+
return False
|
475 |
+
all_questions = []
|
476 |
+
tasks = []
|
477 |
+
with ThreadPoolExecutor() as executor:
|
478 |
+
for file in os.listdir(directory_path):
|
479 |
+
if file.endswith(".pdf"):
|
480 |
+
pdf_path = os.path.join(directory_path, file)
|
481 |
+
loader = UnstructuredPDFLoader(pdf_path).load()
|
482 |
+
tasks.append(executor.submit(generate_question_main, loader, file))
|
483 |
+
elif file.endswith('.docx') or file.endswith('.doc'):
|
484 |
+
doc_path = os.path.join(directory_path, file)
|
485 |
+
loader = Docx2txtLoader(doc_path).load()
|
486 |
+
tasks.append(executor.submit(generate_question_main, loader, file))
|
487 |
+
elif file.endswith('.txt'):
|
488 |
+
txt_path = os.path.join(directory_path, file)
|
489 |
+
loader = TextLoader(txt_path, encoding="utf8").load()
|
490 |
+
tasks.append(executor.submit(generate_question_main, loader, file))
|
491 |
+
elif file.endswith('.pptx'):
|
492 |
+
ppt_path = os.path.join(directory_path, file)
|
493 |
+
loader = UnstructuredPowerPointLoader(ppt_path).load()
|
494 |
+
tasks.append(executor.submit(generate_question_main, loader, file))
|
495 |
+
elif file.endswith('.json'):
|
496 |
+
json_path = os.path.join(directory_path, file)
|
497 |
+
loader = TextLoader(json_path, encoding="utf8").load()
|
498 |
+
tasks.append(executor.submit(generate_question_main, loader, file))
|
499 |
+
elif file.endswith('.md'):
|
500 |
+
md_path = os.path.join(directory_path, file)
|
501 |
+
loader = UnstructuredMarkdownLoader(md_path).load()
|
502 |
+
tasks.append(executor.submit(generate_question_main, loader, file))
|
503 |
+
for future in as_completed(tasks):
|
504 |
+
result = future.result()
|
505 |
+
all_questions.extend(result)
|
506 |
+
return all_questions
|
507 |
+
|
508 |
+
class Search(BaseModel):
|
509 |
+
queries: List[str] = Field(
|
510 |
+
...,
|
511 |
+
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",
|
512 |
+
)
|
513 |
+
|
514 |
+
def query_analyzer(query):
|
515 |
+
output_parser = PydanticToolsParser(tools=[Search])
|
516 |
+
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.
|
517 |
+
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"""
|
518 |
+
prompt = ChatPromptTemplate.from_messages(
|
519 |
+
[
|
520 |
+
("system", system),
|
521 |
+
("human", "{question}"),
|
522 |
+
]
|
523 |
+
)
|
524 |
+
llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0.0)
|
525 |
+
structured_llm = llm.with_structured_output(Search)
|
526 |
+
query_analyzer = {"question": RunnablePassthrough()} | prompt | structured_llm
|
527 |
+
text = query_analyzer.invoke(query)
|
528 |
+
return text
|
529 |
+
|
530 |
+
def handle_query(question, text_all, compression_retriever, id, thread_id):
|
531 |
+
COHERE_API_KEY_3 = os.environ["COHERE_API_KEY_3"]
|
532 |
+
os.environ["COHERE_API_KEY"] = COHERE_API_KEY_3
|
533 |
+
query = question
|
534 |
+
x = query
|
535 |
+
keyword, key_words_old = find_matching_files_in_docs_12_id(query, id)
|
536 |
+
# if keyword == set() or key_words_old == list():
|
537 |
+
# return "Not found file"
|
538 |
+
file_list = keyword
|
539 |
+
|
540 |
+
if file_list:
|
541 |
+
list_keywords2 = list(key_words_old)
|
542 |
+
contents1 = extract_content_between_keywords(query, list_keywords2)
|
543 |
+
merged_result = merge_files(keyword, list_keywords2)
|
544 |
+
original_dict = contents1
|
545 |
+
replacement_dict = merged_result
|
546 |
+
new_dict = replace_keys_with_values(original_dict, replacement_dict)
|
547 |
+
files_to_remove = [filename for filename in new_dict.keys() if
|
548 |
+
filename.endswith('.xlsx') or filename.endswith('.csv')]
|
549 |
+
removed_files = {}
|
550 |
+
for filename in files_to_remove:
|
551 |
+
removed_files[filename] = new_dict[filename]
|
552 |
+
for filename in files_to_remove:
|
553 |
+
new_dict.pop(filename)
|
554 |
+
test_csv = ""
|
555 |
+
text_csv, query_csv, source = aws1_csv_id(removed_files, id)
|
556 |
+
prompt_csv = ""
|
557 |
+
answer_csv = ""
|
558 |
+
if test_csv:
|
559 |
+
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"
|
560 |
+
answer_csv = question_answer(prompt_csv)
|
561 |
+
answer_document, data_relevant, source = aws1_all_id(new_dict, text_all, id, thread_id)
|
562 |
+
answer_all1 = answer_document + answer_csv
|
563 |
+
return answer_all1, data_relevant, source
|
564 |
+
else:
|
565 |
+
compressed_docs = compression_retriever.get_relevant_documents(f"{query}")
|
566 |
+
relevance_score_float = float(compressed_docs[0].metadata['relevance_score'])
|
567 |
+
print(relevance_score_float)
|
568 |
+
if relevance_score_float <= 0.12:
|
569 |
+
documents1 = []
|
570 |
+
for file in os.listdir(f"./user_file/{id}"):
|
571 |
+
if file.endswith('.csv'):
|
572 |
+
csv_path = f"./user_file/{id}/" + file
|
573 |
+
loader = UnstructuredCSVLoader(csv_path)
|
574 |
+
documents1.extend(loader.load())
|
575 |
+
elif file.endswith('.xlsx'):
|
576 |
+
excel_path = f"./user_file/{id}/" + file
|
577 |
+
loader = UnstructuredExcelLoader(excel_path)
|
578 |
+
documents1.extend(loader.load())
|
579 |
+
text_splitter_csv = CharacterTextSplitter.from_tiktoken_encoder(chunk_size=2200, chunk_overlap=1500)
|
580 |
+
texts_csv = text_splitter_csv.split_documents(documents1)
|
581 |
+
vectordb_csv = Chroma.from_documents(documents=texts_csv,
|
582 |
+
embedding=embeddings, persist_directory=f'./vector_database/csv/{thread_id}')
|
583 |
+
k = len(texts_csv)
|
584 |
+
retriever_csv = vectordb_csv.as_retriever(search_kwargs={"k": k})
|
585 |
+
llm = Cohere(temperature=0)
|
586 |
+
compressor_csv = CohereRerank(top_n=3, model="rerank-english-v2.0")
|
587 |
+
compression_retriever_csv = ContextualCompressionRetriever(
|
588 |
+
base_compressor=compressor_csv, base_retriever=retriever_csv
|
589 |
+
)
|
590 |
+
compressed_docs_csv = compression_retriever_csv.get_relevant_documents(f"{query}")
|
591 |
+
file_path = compressed_docs_csv[0].metadata['source']
|
592 |
+
print(file_path)
|
593 |
+
if file_path.endswith('.xlsx'):
|
594 |
+
new = file_path.replace(".xlsx", ".csv")
|
595 |
+
convert_xlsx_to_csv(file_path, new)
|
596 |
+
loader1 = CSVLoader(new)
|
597 |
+
else:
|
598 |
+
loader1 = CSVLoader(file_path)
|
599 |
+
docs1 = loader1.load()
|
600 |
+
text = " "
|
601 |
+
for z in docs1:
|
602 |
+
text += z.page_content + "\n"
|
603 |
+
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"
|
604 |
+
answer_csv = question_answer(prompt_csv)
|
605 |
+
return answer_csv
|
606 |
+
else:
|
607 |
+
file_path = compressed_docs[0].metadata['source']
|
608 |
+
file_path = file_path.replace('\\', '/')
|
609 |
+
print(file_path)
|
610 |
+
if file_path.endswith(".pdf"):
|
611 |
+
loader = UnstructuredPDFLoader(file_path)
|
612 |
+
elif file_path.endswith('.docx') or file_path.endswith('doc'):
|
613 |
+
loader = Docx2txtLoader(file_path)
|
614 |
+
elif file_path.endswith('.txt'):
|
615 |
+
loader = TextLoader(file_path, encoding="utf8")
|
616 |
+
elif file_path.endswith('.pptx'):
|
617 |
+
loader = UnstructuredPowerPointLoader(file_path)
|
618 |
+
elif file_path.endswith('.xml'):
|
619 |
+
loader = UnstructuredXMLLoader(file_path)
|
620 |
+
elif file_path.endswith('.html'):
|
621 |
+
loader = UnstructuredHTMLLoader(file_path)
|
622 |
+
elif file_path.endswith('.json'):
|
623 |
+
loader = TextLoader(file_path)
|
624 |
+
elif file_path.endswith('.md'):
|
625 |
+
loader = UnstructuredMarkdownLoader(file_path)
|
626 |
+
elif file_path.endswith('.xlsx'):
|
627 |
+
file_path_new = file_path.replace(".xlsx", ".csv")
|
628 |
+
convert_xlsx_to_csv(file_path, file_path_new)
|
629 |
+
loader = CSVLoader(file_path_new)
|
630 |
+
elif file_path.endswith('.csv'):
|
631 |
+
loader = CSVLoader(file_path)
|
632 |
+
text_splitter = CharacterTextSplitter(chunk_size=3200, chunk_overlap=1500)
|
633 |
+
texts = text_splitter.split_documents(loader.load())
|
634 |
+
k_1 = len(texts)
|
635 |
+
file_name = os.path.basename(file_path)
|
636 |
+
if check_persist_directory(id, file_name):
|
637 |
+
vectordb_file = Chroma(persist_directory=f"./vector_database/{id}/{file_name}",
|
638 |
+
embedding_function=embeddings)
|
639 |
+
else:
|
640 |
+
vectordb_file = Chroma.from_documents(texts,
|
641 |
+
embedding=embeddings,
|
642 |
+
persist_directory=f"./vector_database/{id}/{file_name}")
|
643 |
+
retriever_file = vectordb_file.as_retriever(search_kwargs={f"k": k_1})
|
644 |
+
compressor_file = CohereRerank(top_n=5, model="rerank-english-v2.0")
|
645 |
+
compression_retriever_file = ContextualCompressionRetriever(
|
646 |
+
base_compressor=compressor_file, base_retriever=retriever_file
|
647 |
+
)
|
648 |
+
compressed_docs_file = compression_retriever_file.get_relevant_documents(f"{x}")
|
649 |
+
query = question
|
650 |
+
text = ''.join(map(lambda x: x.page_content, compressed_docs_file))
|
651 |
+
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"
|
652 |
+
answer = question_answer(prompt)
|
653 |
+
list_relevant = compressed_docs_file[0].page_content
|
654 |
+
source = file_name
|
655 |
+
return answer, list_relevant, source
|
656 |
+
|
657 |
+
def handle_query_upgrade_keyword_old(query_all, text_all, id):
|
658 |
+
COHERE_API_KEY_2 = os.environ["COHERE_API_KEY_2"]
|
659 |
+
os.environ["COHERE_API_KEY"] = COHERE_API_KEY_2
|
660 |
+
test = query_analyzer(query_all)
|
661 |
+
test_string = str(test)
|
662 |
+
matches = re.findall(r"'([^']*)'", test_string)
|
663 |
+
vectordb = Chroma(persist_directory=f"./vector_database/{id}", embedding_function=embeddings)
|
664 |
+
k = len(text_all)
|
665 |
+
retriever = vectordb.as_retriever(search_kwargs={"k": k})
|
666 |
+
compressor = CohereRerank(top_n=5, model="rerank-english-v2.0")
|
667 |
+
compression_retriever = ContextualCompressionRetriever(base_compressor=compressor, base_retriever= retriever)
|
668 |
+
with ThreadPoolExecutor() as executor:
|
669 |
+
futures = {executor.submit(handle_query, query, text_all, compression_retriever, id, i): query for i, query in
|
670 |
+
enumerate(matches)}
|
671 |
+
results = []
|
672 |
+
data_relevant = []
|
673 |
+
sources = []
|
674 |
+
for future in as_completed(futures):
|
675 |
+
try:
|
676 |
+
result, list_data, list_source = future.result()
|
677 |
+
results.append(result)
|
678 |
+
data_relevant.append(list_data)
|
679 |
+
sources.append(list_source)
|
680 |
+
except Exception as e:
|
681 |
+
print(f'An error occurred: {e}')
|
682 |
+
answer_all = ''.join(results)
|
683 |
+
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"
|
684 |
+
answer1 = question_answer(prompt1)
|
685 |
+
return answer1, data_relevant, sources
|
function/dropbox.py
ADDED
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import dropbox.files
|
2 |
+
import os
|
3 |
+
import shutil
|
4 |
+
import requests, base64
|
5 |
+
from fastapi import HTTPException
|
6 |
+
from dotenv import load_dotenv
|
7 |
+
import os
|
8 |
+
load_dotenv()
|
9 |
+
DROPBOX_APP_KEY=os.getenv('DROPBOX_APP_KEY')
|
10 |
+
DROPBOX_APP_SECRET=os.getenv('DROPBOX_APP_SECRET')
|
11 |
+
DROPBOX_REFRESH_TOKEN=os.getenv('DROPBOX_REFRESH_TOKEN')
|
12 |
+
|
13 |
+
def refresh_token_dropbox():
|
14 |
+
app_key = DROPBOX_APP_KEY
|
15 |
+
app_secret = DROPBOX_APP_SECRET
|
16 |
+
refresh_token = DROPBOX_REFRESH_TOKEN
|
17 |
+
url = 'https://api.dropbox.com/oauth2/token'
|
18 |
+
auth_string = f"{app_key}:{app_secret}"
|
19 |
+
base64authorization = base64.b64encode(auth_string.encode()).decode('utf-8')
|
20 |
+
headers = {
|
21 |
+
'Authorization': f'Basic {base64authorization}',
|
22 |
+
'Content-Type': 'application/x-www-form-urlencoded'
|
23 |
+
}
|
24 |
+
data = {
|
25 |
+
'refresh_token': refresh_token,
|
26 |
+
'grant_type': 'refresh_token'
|
27 |
+
}
|
28 |
+
response = requests.post(url, headers=headers, data=data)
|
29 |
+
response_json = response.json()
|
30 |
+
access_token = response_json.get('access_token', None)
|
31 |
+
return access_token
|
32 |
+
|
33 |
+
def delete_file(id,name_file):
|
34 |
+
try:
|
35 |
+
TOKEN = refresh_token_dropbox()
|
36 |
+
dbx=dropbox.Dropbox(TOKEN)
|
37 |
+
file_path = f"/{id}/{name_file}"
|
38 |
+
dbx.files_delete_v2(file_path)
|
39 |
+
print(f"Xóa file '{file_path}' thành công.")
|
40 |
+
except dropbox.exceptions.ApiError as e:
|
41 |
+
print(f"Lỗi khi xóa file '{file_path}': {e}")
|
42 |
+
|
43 |
+
def list_files(id):
|
44 |
+
file_names = []
|
45 |
+
try:
|
46 |
+
TOKEN = refresh_token_dropbox()
|
47 |
+
dbx=dropbox.Dropbox(TOKEN)
|
48 |
+
result = dbx.files_list_folder(f"/{id}")
|
49 |
+
for entry in result.entries:
|
50 |
+
if isinstance(entry, dropbox.files.FileMetadata):
|
51 |
+
file_names.append(os.path.basename(entry.path_display))
|
52 |
+
except dropbox.exceptions.ApiError as e:
|
53 |
+
print(f"Error listing files: {e}")
|
54 |
+
return file_names
|
55 |
+
|
56 |
+
def upload_file_fix(local_path,cloud_path,token):
|
57 |
+
try:
|
58 |
+
TOKEN = refresh_token_dropbox()
|
59 |
+
dbx=dropbox.Dropbox(TOKEN)
|
60 |
+
with open(local_path, "rb") as f:
|
61 |
+
data = f.read()
|
62 |
+
dbx.files_upload(data, cloud_path)
|
63 |
+
print(f"Uploaded file '{local_path}' to '{cloud_path}'")
|
64 |
+
except dropbox.exceptions.ApiError as e:
|
65 |
+
print(f"Error uploading file '{local_path}': {e}")
|
66 |
+
|
67 |
+
def upload_file(local_path, cloud_path):
|
68 |
+
try:
|
69 |
+
TOKEN = refresh_token_dropbox()
|
70 |
+
dbx=dropbox.Dropbox(TOKEN)
|
71 |
+
with open(local_path, "rb") as f:
|
72 |
+
data = f.read()
|
73 |
+
dbx.files_upload(data, cloud_path)
|
74 |
+
print(f"Uploaded file '{local_path}' to '{cloud_path}'")
|
75 |
+
except dropbox.exceptions.ApiError as e:
|
76 |
+
upload_file_fix()
|
77 |
+
|
78 |
+
def clear_local_folder(path):
|
79 |
+
try:
|
80 |
+
for filename in os.listdir(path):
|
81 |
+
file_path = os.path.join(path, filename)
|
82 |
+
if os.path.isfile(file_path) or os.path.islink(file_path):
|
83 |
+
os.unlink(file_path)
|
84 |
+
elif os.path.isdir(file_path):
|
85 |
+
shutil.rmtree(file_path)
|
86 |
+
except Exception as e:
|
87 |
+
print(f"Failed to delete contents of {path}. Reason: {e}")
|
88 |
+
|
89 |
+
def download_folder(id):
|
90 |
+
try:
|
91 |
+
TOKEN = refresh_token_dropbox()
|
92 |
+
dbx = dropbox.Dropbox(TOKEN)
|
93 |
+
local_path = f"./user_file/{id}"
|
94 |
+
os.makedirs(local_path, exist_ok=True)
|
95 |
+
clear_local_folder(local_path)
|
96 |
+
result = dbx.files_list_folder(f"/{id}")
|
97 |
+
for entry in result.entries:
|
98 |
+
if isinstance(entry, dropbox.files.FileMetadata):
|
99 |
+
cloud_file_path = entry.path_display
|
100 |
+
file_name = os.path.basename(cloud_file_path)
|
101 |
+
local_file_path = os.path.join(local_path, file_name)
|
102 |
+
dbx.files_download_to_file(local_file_path, cloud_file_path)
|
103 |
+
print(f"Downloaded file '{file_name}' to '{local_file_path}'")
|
104 |
+
except dropbox.exceptions.ApiError as e:
|
105 |
+
print(f"Error downloading file '{id}': {e}")
|
106 |
+
|
107 |
+
def download_file_id(file_name, id):
|
108 |
+
try:
|
109 |
+
TOKEN = refresh_token_dropbox()
|
110 |
+
dbx = dropbox.Dropbox(TOKEN)
|
111 |
+
local_folder_path = f"./user_file/{id}"
|
112 |
+
os.makedirs(local_folder_path, exist_ok=True)
|
113 |
+
local_file_path = os.path.join(local_folder_path, file_name)
|
114 |
+
with open(local_file_path, "wb") as f:
|
115 |
+
metadata, response = dbx.files_download(f"/{id}/{file_name}")
|
116 |
+
f.write(response.content)
|
117 |
+
print(f"Downloaded file '{file_name}' to '{local_file_path}'")
|
118 |
+
except dropbox.exceptions.ApiError as e:
|
119 |
+
print(f"Error downloading file '{file_name}': {e}")
|
120 |
+
raise HTTPException(status_code=500, detail="Internal Server Error")
|
121 |
+
|
122 |
+
def search_and_download_file(start_char, id):
|
123 |
+
try:
|
124 |
+
TOKEN = refresh_token_dropbox()
|
125 |
+
dbx = dropbox.Dropbox(TOKEN)
|
126 |
+
result = dbx.files_list_folder(f"/{id}")
|
127 |
+
files_starting_with_char = [entry.name for entry in result.entries if entry.name.startswith(start_char)]
|
128 |
+
if len(files_starting_with_char) == 0:
|
129 |
+
print(f"No file found starting with '{start_char}' in folder '{id}'")
|
130 |
+
return
|
131 |
+
file_name = files_starting_with_char[0]
|
132 |
+
local_folder_path = f"./user_file/{id}"
|
133 |
+
os.makedirs(local_folder_path, exist_ok=True)
|
134 |
+
local_file_path = os.path.join(local_folder_path, file_name)
|
135 |
+
with open(local_file_path, "wb") as f:
|
136 |
+
metadata, response = dbx.files_download(f"/{id}/{file_name}")
|
137 |
+
f.write(response.content)
|
138 |
+
print(f"Downloaded file '{file_name}' to '{local_file_path}'")
|
139 |
+
except dropbox.exceptions.ApiError as e:
|
140 |
+
print(f"Error searching or downloading file: {e}")
|
141 |
+
raise HTTPException(status_code=500, detail="Internal Server Error")
|
142 |
+
|
143 |
+
def delete_all_files_in_folder(folder_id):
|
144 |
+
try:
|
145 |
+
TOKEN = refresh_token_dropbox()
|
146 |
+
dbx = dropbox.Dropbox(TOKEN)
|
147 |
+
result = dbx.files_list_folder(f"/{folder_id}")
|
148 |
+
for entry in result.entries:
|
149 |
+
if isinstance(entry, dropbox.files.FileMetadata):
|
150 |
+
file_path = entry.path_display
|
151 |
+
dbx.files_delete_v2(file_path)
|
152 |
+
print(f"Deleted file '{file_path}'")
|
153 |
+
print(f"All files in folder '{folder_id}' have been deleted.")
|
154 |
+
except dropbox.exceptions.ApiError as e:
|
155 |
+
print(f"Error deleting files: {e}")
|
function/support_function.py
ADDED
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic.error_wrappers import ErrorWrapper
|
2 |
+
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
3 |
+
from service import MySQLService,UserService,ChatService
|
4 |
+
from request import RequestMySQL,RequestUser,RequestDefault
|
5 |
+
from auth.authentication import decodeJWT
|
6 |
+
from repository import UserRepository
|
7 |
+
from auth import authentication
|
8 |
+
from datetime import datetime, timedelta
|
9 |
+
from fastapi import Depends, HTTPException, Form, File, UploadFile
|
10 |
+
from typing import List
|
11 |
+
from service import FileService,DefaultService,UserService
|
12 |
+
from request import RequestFile,RequestChat,RequestDefault
|
13 |
+
from fastapi import FastAPI, Request, HTTPException
|
14 |
+
from fastapi.responses import JSONResponse
|
15 |
+
from pydantic.error_wrappers import ErrorWrapper
|
16 |
+
import json
|
17 |
+
from function import support_function
|
18 |
+
from repository import UserRepository
|
19 |
+
from response import ResponseDefault as res
|
20 |
+
import re
|
21 |
+
|
22 |
+
def is_positive_integer(value):
|
23 |
+
if isinstance(value, int) and value > 0:
|
24 |
+
return True
|
25 |
+
else:
|
26 |
+
return False
|
27 |
+
|
28 |
+
def check_value_user_id_controller(user_id: str):
|
29 |
+
if user_id is None or user_id.strip() == "":
|
30 |
+
return res.ReponseError(status=400,
|
31 |
+
data=res.Message(message="user_id field is required."))
|
32 |
+
user_id = user_id.strip("'").strip('"')
|
33 |
+
try:
|
34 |
+
user_id_int = int(user_id)
|
35 |
+
except ValueError:
|
36 |
+
return res.ReponseError(status=400,
|
37 |
+
data=res.Message(message="user_id must be an integer"))
|
38 |
+
|
39 |
+
if not support_function.is_positive_integer(user_id_int):
|
40 |
+
return res.ReponseError(status=400,
|
41 |
+
data=res.Message(message="user_id must be greater than 0"))
|
42 |
+
return True
|
43 |
+
|
44 |
+
def check_value_user_id(user_id: str, current_user_email: str):
|
45 |
+
if user_id is None or user_id.strip() == "":
|
46 |
+
return res.ReponseError(status=400,
|
47 |
+
data=res.Message(message="user_id field is required."))
|
48 |
+
user_id = user_id.strip("'").strip('"')
|
49 |
+
try:
|
50 |
+
user_id_int = int(user_id)
|
51 |
+
except ValueError:
|
52 |
+
return res.ReponseError(status=400,
|
53 |
+
data=res.Message(message="user_id must be an integer"))
|
54 |
+
|
55 |
+
if not support_function.is_positive_integer(user_id_int):
|
56 |
+
return res.ReponseError(status=400,
|
57 |
+
data=res.Message(message="user_id must be greater than 0"))
|
58 |
+
email = UserRepository.getEmailUserByIdFix(user_id)
|
59 |
+
if email is None:
|
60 |
+
return res.ReponseError(status=404,
|
61 |
+
data=res.Message(message="user_id not exist"))
|
62 |
+
email = email[0]
|
63 |
+
if email != current_user_email:
|
64 |
+
raise HTTPException(status_code=403, detail="Sorry, you can't perform actions with this user id.")
|
65 |
+
return True
|
66 |
+
|
67 |
+
def check_value_email_controller(email: str):
|
68 |
+
if email is None or email.strip() == "":
|
69 |
+
return res.ReponseError(status = 400,
|
70 |
+
data = res.Message(message="Email is required."))
|
71 |
+
try:
|
72 |
+
int(email)
|
73 |
+
return res.ReponseError(status=400,
|
74 |
+
data=res.Message(message="Email must be a string, not a number."))
|
75 |
+
except ValueError:
|
76 |
+
pass
|
77 |
+
return True
|
78 |
+
|
79 |
+
def check_value_otp(otp: str):
|
80 |
+
if otp is None:
|
81 |
+
return res.ReponseError(status=400,
|
82 |
+
data=res.Message(message="OTP is required"))
|
83 |
+
if otp.isdigit():
|
84 |
+
return res.ReponseError(status=400,
|
85 |
+
data=res.Message(message="OTP must be a string, not a number."))
|
86 |
+
if len(otp) != 6:
|
87 |
+
return res.ReponseError(status=400,
|
88 |
+
data=res.Message(message="OTP max length is 6"))
|
89 |
+
return True
|
90 |
+
|
91 |
+
regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
|
92 |
+
def check_email(email):
|
93 |
+
if(re.fullmatch(regex, email)):
|
94 |
+
return True
|
95 |
+
else:
|
96 |
+
return False
|
97 |
+
def check_email_service(user_id: str):
|
98 |
+
email1 = UserRepository.getEmailUserByIdFix(user_id)
|
99 |
+
if email1 is None:
|
100 |
+
return res.ReponseError(
|
101 |
+
status=404,
|
102 |
+
data=res.Message(message="Id not exist")
|
103 |
+
)
|
104 |
+
email = email1[0]
|
105 |
+
if email is None:
|
106 |
+
return res.ReponseError(
|
107 |
+
status=400,
|
108 |
+
data=res.Message(message="Email is empty")
|
109 |
+
)
|
110 |
+
if check_email(email) == False:
|
111 |
+
return res.ReponseError(
|
112 |
+
status=400,
|
113 |
+
data=res.Message(message="Email invalid")
|
114 |
+
)
|
115 |
+
return email
|
116 |
+
|
117 |
+
def check_email_empty_invalid(email: str):
|
118 |
+
if email is None or email == "":
|
119 |
+
return res.ReponseError(
|
120 |
+
status=400,
|
121 |
+
data=res.Message(message="Email is empty")
|
122 |
+
)
|
123 |
+
if check_email(email) == False:
|
124 |
+
return res.ReponseError(
|
125 |
+
status=400,
|
126 |
+
data =res.Message(message="Email invalid")
|
127 |
+
)
|
128 |
+
return True
|
models/Database_Entity.py
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sqlalchemy import Column, String, Text, DateTime, Integer, ForeignKey, TIMESTAMP
|
2 |
+
from sqlalchemy.orm import relationship
|
3 |
+
from sqlalchemy.orm import DeclarativeBase
|
4 |
+
from sqlalchemy.sql import func
|
5 |
+
class Base(DeclarativeBase):
|
6 |
+
pass
|
7 |
+
|
8 |
+
class User(Base):
|
9 |
+
__tablename__ = 'users'
|
10 |
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
11 |
+
email = Column(String(255))
|
12 |
+
access_token = Column(Text)
|
13 |
+
refresh_token = Column(Text)
|
14 |
+
expires_at = Column(DateTime)
|
15 |
+
|
16 |
+
chat_histories = relationship("ChatHistory", back_populates="user")
|
17 |
+
user_logins = relationship("UserLogin", back_populates="user")
|
18 |
+
user_infos = relationship("UserInfo", back_populates="user")
|
19 |
+
|
20 |
+
class ChatHistory(Base):
|
21 |
+
__tablename__ = 'chat_history'
|
22 |
+
|
23 |
+
id = Column(Integer, primary_key=True,autoincrement=True)
|
24 |
+
email = Column(String(255), ForeignKey('users.email'))
|
25 |
+
name_chat = Column(String(255), unique=True)
|
26 |
+
|
27 |
+
user = relationship("User", back_populates="chat_histories")
|
28 |
+
detail_chats = relationship("DetailChat", back_populates="chat_history")
|
29 |
+
|
30 |
+
class UserLogin(Base):
|
31 |
+
__tablename__ = 'user_login'
|
32 |
+
|
33 |
+
id = Column(Integer, primary_key=True,autoincrement=True)
|
34 |
+
user_email = Column(String(100), ForeignKey('users.email'), primary_key=True)
|
35 |
+
user_session_id = Column(String(100), primary_key=True)
|
36 |
+
|
37 |
+
user = relationship("User", back_populates="user_logins")
|
38 |
+
|
39 |
+
class UserInfo(Base):
|
40 |
+
__tablename__ = 'user_info'
|
41 |
+
|
42 |
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
43 |
+
uid = Column(Text)
|
44 |
+
email = Column(String(255), ForeignKey('users.email'), unique=True)
|
45 |
+
display_name = Column(Text)
|
46 |
+
photo_url = Column(Text)
|
47 |
+
|
48 |
+
user = relationship("User", back_populates="user_infos")
|
49 |
+
|
50 |
+
class DetailChat(Base):
|
51 |
+
__tablename__ = 'detail_chat'
|
52 |
+
|
53 |
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
54 |
+
chat_id = Column(Integer, ForeignKey('chat_history.id'))
|
55 |
+
YouMessage = Column(Text)
|
56 |
+
AiMessage = Column(Text)
|
57 |
+
data_relevant = Column(Text)
|
58 |
+
source_file = Column(Text)
|
59 |
+
|
60 |
+
chat_history = relationship("ChatHistory", back_populates="detail_chats")
|
61 |
+
|
62 |
+
class OTP(Base):
|
63 |
+
__tablename__ = 'otp'
|
64 |
+
|
65 |
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
66 |
+
email = Column(String(255), nullable=False)
|
67 |
+
otp = Column(String(6), nullable=False)
|
68 |
+
created_at = Column(TIMESTAMP, server_default=func.now())
|
request/RequestAuth.py
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel
|
2 |
+
from typing import Optional
|
3 |
+
|
4 |
+
class RequestLoginEmail(BaseModel):
|
5 |
+
email: Optional[str]
|
6 |
+
password: Optional[str]
|
7 |
+
|
8 |
+
class RequestLoginGoogle(BaseModel):
|
9 |
+
email: Optional[str]
|
10 |
+
token_google: Optional[str]
|
11 |
+
|
12 |
+
class RequestRefreshTokenLogin(BaseModel):
|
13 |
+
refresh_token: Optional[str]
|
14 |
+
|
15 |
+
class RequestRegister(BaseModel):
|
16 |
+
email: Optional[str]
|
17 |
+
password: Optional[str]
|
18 |
+
confirm_password: Optional[str]
|
19 |
+
username: Optional[str]
|
request/RequestChat.py
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel
|
2 |
+
from typing import Optional
|
3 |
+
|
4 |
+
class RequestQuery2UpgradeOld(BaseModel):
|
5 |
+
user_id: int
|
6 |
+
text_all: str
|
7 |
+
question: Optional[str]
|
8 |
+
chat_name: Optional[str]
|
9 |
+
|
10 |
+
class RequestExtractFile(BaseModel):
|
11 |
+
user_id: int
|
12 |
+
|
13 |
+
class RequestDeleteChat(BaseModel):
|
14 |
+
user_id: int
|
15 |
+
chat_name: Optional[str]
|
16 |
+
|
17 |
+
class RequestGenerateQuestion(BaseModel):
|
18 |
+
user_id: int
|
request/RequestDefault.py
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel, EmailStr
|
2 |
+
from typing import Optional, List
|
3 |
+
from fastapi import UploadFile
|
4 |
+
|
5 |
+
class RequestCreateFireBaseUserGoogle(BaseModel):
|
6 |
+
email: Optional[str] = None
|
7 |
+
token_google: Optional[str] = None
|
8 |
+
class RequestInfoUser(BaseModel):
|
9 |
+
user_id: str
|
10 |
+
class RequestIsMe(BaseModel):
|
11 |
+
token: Optional[str]
|
12 |
+
|
13 |
+
class RequestUpLoadImage(BaseModel):
|
14 |
+
user_id: Optional[str]
|
15 |
+
files: UploadFile = None
|
request/RequestFile.py
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel
|
2 |
+
from typing import List, Optional
|
3 |
+
from fastapi import UploadFile
|
4 |
+
|
5 |
+
class RequestGetNameFile(BaseModel):
|
6 |
+
user_id: Optional[str]
|
7 |
+
class RequestDeleteFile(BaseModel):
|
8 |
+
user_id: Optional[str]
|
9 |
+
name_file: Optional[str]
|
10 |
+
class RequestDeleteAllFile(BaseModel):
|
11 |
+
user_id: Optional[str]
|
12 |
+
class RequestDownLoadFolder(BaseModel):
|
13 |
+
user_id: Optional[str]
|
14 |
+
|
15 |
+
class RequestDownLoadFile(BaseModel):
|
16 |
+
user_id: Optional[str]
|
17 |
+
name_file: Optional[str]
|
18 |
+
class RequestUploadFile(BaseModel):
|
19 |
+
files: Optional[List[UploadFile]] = None
|
20 |
+
user_id: Optional[str]
|
request/RequestMySQL.py
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel
|
2 |
+
from typing import Optional
|
3 |
+
|
4 |
+
class RequestRenderChatHistory(BaseModel):
|
5 |
+
user_id: Optional[int]
|
6 |
+
|
7 |
+
class RequestLoadChatHistory(BaseModel):
|
8 |
+
user_id: Optional[int]
|
9 |
+
chat_id: Optional[int]
|
10 |
+
|
11 |
+
class RequestGetChatDetails(BaseModel):
|
12 |
+
id: Optional[str]
|
13 |
+
|
14 |
+
class RequestEditNameChat(BaseModel):
|
15 |
+
user_id: Optional[str]
|
16 |
+
name_old: Optional[str]
|
17 |
+
name_new: Optional[str]
|
18 |
+
|
19 |
+
class RequestDeleteChat(BaseModel):
|
20 |
+
user_id: Optional[str]
|
21 |
+
chat_name: Optional[str]
|
22 |
+
|
23 |
+
class RequestDeleteDetailChat(BaseModel):
|
24 |
+
user_id: Optional[str]
|
25 |
+
id_chat_detail: Optional[str]
|
request/RequestOTP.py
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel
|
2 |
+
from typing import Optional
|
3 |
+
|
4 |
+
class RequestCreateOTP(BaseModel):
|
5 |
+
email: Optional[str]
|
6 |
+
|
7 |
+
class RequestVerifyOTP(BaseModel):
|
8 |
+
email: Optional[str]
|
9 |
+
otp: Optional[str]
|
request/RequestUser.py
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel
|
2 |
+
from typing import Optional
|
3 |
+
|
4 |
+
class RequestLoginEmail(BaseModel):
|
5 |
+
email: Optional[str]
|
6 |
+
password: Optional[str]
|
7 |
+
|
8 |
+
class RequestLoginGoogle(BaseModel):
|
9 |
+
email: Optional[str]
|
10 |
+
token_google: Optional[str]
|
11 |
+
|
12 |
+
class RequestUpdateUserInfo(BaseModel):
|
13 |
+
user_id: Optional[str]
|
14 |
+
uid: Optional[str]
|
15 |
+
email: Optional[str]
|
16 |
+
display_name: Optional[str]
|
17 |
+
photo_url: Optional[str]
|
18 |
+
|
19 |
+
class RequestCheckInfoGoogle(BaseModel):
|
20 |
+
user_id: int
|
21 |
+
|
22 |
+
class RequestCheckInfoGoogleEmail(BaseModel):
|
23 |
+
email:Optional[str]
|
24 |
+
|
25 |
+
class RequestCreateOTP(BaseModel):
|
26 |
+
email: Optional[str]
|
27 |
+
|
28 |
+
class RequestVerifyOTP(BaseModel):
|
29 |
+
email: Optional[str]
|
30 |
+
otp: Optional[str]
|
31 |
+
|
32 |
+
class RequestCheckStateLogin(BaseModel):
|
33 |
+
user_id: Optional[int]
|
34 |
+
session_id_now: Optional[str]
|
35 |
+
|
36 |
+
class RequestSignUp(BaseModel):
|
37 |
+
email: Optional[str]
|
38 |
+
password: Optional[str]
|
39 |
+
confirm_password: Optional[str]
|
40 |
+
username: Optional[str]
|
41 |
+
|
42 |
+
class RequestResetPassword(BaseModel):
|
43 |
+
email: Optional[str]
|
44 |
+
|
45 |
+
class RequestChangePassword(BaseModel):
|
46 |
+
user_id: Optional[str]
|
47 |
+
current_password: Optional[str]
|
48 |
+
new_password: Optional[str]
|
49 |
+
confirm_new_password: Optional[str]
|
50 |
+
|
51 |
+
class RequestRefreshTokenLogin(BaseModel):
|
52 |
+
refresh_token: Optional[str]
|
response/ResponseAuth.py
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel
|
2 |
+
from typing import List, Union, Optional
|
3 |
+
|
4 |
+
class Message(BaseModel):
|
5 |
+
message: str
|
6 |
+
|
7 |
+
class DataLogin(BaseModel):
|
8 |
+
access_token: str
|
9 |
+
refresh_token: str
|
10 |
+
expires_in: int
|
11 |
+
session_id: str
|
12 |
+
|
13 |
+
class CheckModel(BaseModel):
|
14 |
+
check: bool
|
15 |
+
|
16 |
+
class DataRefreshToken(BaseModel):
|
17 |
+
token_new: str
|
18 |
+
session_id: str
|
19 |
+
|
20 |
+
class ResponseCreateOTP(BaseModel):
|
21 |
+
status: int
|
22 |
+
data: CheckModel
|
23 |
+
otp: str
|
24 |
+
|
25 |
+
class ResponseLoginGoogle(BaseModel):
|
26 |
+
status: int
|
27 |
+
data: DataLogin
|
28 |
+
|
29 |
+
class ResponseRefreshToken(BaseModel):
|
30 |
+
status: int
|
31 |
+
data: DataRefreshToken
|
32 |
+
|
33 |
+
class DataSignUp(BaseModel):
|
34 |
+
email: str
|
35 |
+
|
36 |
+
class ResponseRegister(BaseModel):
|
37 |
+
status: int
|
38 |
+
data: DataSignUp
|
39 |
+
|
40 |
+
class ReponseError(BaseModel):
|
41 |
+
status: int
|
42 |
+
data: Message
|
response/ResponseChat.py
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel
|
2 |
+
from typing import List, Union, Optional
|
3 |
+
|
4 |
+
class DataAnswer(BaseModel):
|
5 |
+
answer: str
|
6 |
+
|
7 |
+
class DataAnswer1(BaseModel):
|
8 |
+
id: int
|
9 |
+
answer: str
|
10 |
+
data_relevant: List[str]
|
11 |
+
sources: List[str]
|
12 |
+
|
13 |
+
class FileMetadata(BaseModel):
|
14 |
+
source: str
|
15 |
+
|
16 |
+
class FileResponse(BaseModel):
|
17 |
+
page_content: str
|
18 |
+
metadata: FileMetadata
|
19 |
+
type: str
|
20 |
+
|
21 |
+
class DataExtractFile(BaseModel):
|
22 |
+
text_all: Union[List[FileResponse], None, str]
|
23 |
+
|
24 |
+
class Message(BaseModel):
|
25 |
+
message: str
|
26 |
+
|
27 |
+
class CheckModel(BaseModel):
|
28 |
+
check: bool
|
29 |
+
|
30 |
+
class ResponseQuery2Upgrade(BaseModel):
|
31 |
+
status: int
|
32 |
+
data: DataAnswer
|
33 |
+
|
34 |
+
class GenerateQuestion(BaseModel):
|
35 |
+
question: Union[List[str], bool]
|
36 |
+
|
37 |
+
class ResponseGenerateQuestion(BaseModel):
|
38 |
+
status: int
|
39 |
+
data: GenerateQuestion
|
40 |
+
|
41 |
+
class ResponseQuery2UpgradeOld(BaseModel):
|
42 |
+
status: int
|
43 |
+
data: DataAnswer1
|
44 |
+
|
45 |
+
class ResponseExtractFile(BaseModel):
|
46 |
+
status: int
|
47 |
+
data: DataExtractFile
|
48 |
+
|
49 |
+
class ResponseDeleteChat(BaseModel):
|
50 |
+
status: int
|
51 |
+
data: Message
|
52 |
+
|
53 |
+
class ReponseError(BaseModel):
|
54 |
+
status: int
|
55 |
+
data: Message
|
response/ResponseDefault.py
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel
|
2 |
+
|
3 |
+
class DataInfoUser(BaseModel):
|
4 |
+
uid: str
|
5 |
+
email: str
|
6 |
+
display_name: str
|
7 |
+
photo_url: str
|
8 |
+
|
9 |
+
class DataIsMe(BaseModel):
|
10 |
+
user_id: int
|
11 |
+
|
12 |
+
class DataUploadImage(BaseModel):
|
13 |
+
url: str
|
14 |
+
class Message(BaseModel):
|
15 |
+
message: str
|
16 |
+
|
17 |
+
class CheckModel(BaseModel):
|
18 |
+
check: bool
|
19 |
+
|
20 |
+
class DataCreateFireBaseUser(BaseModel):
|
21 |
+
localId: str
|
22 |
+
email: str
|
23 |
+
displayName: str
|
24 |
+
photoUrl: str
|
25 |
+
|
26 |
+
class ResponseCreateFireBaseUser(BaseModel):
|
27 |
+
status: int
|
28 |
+
data: DataCreateFireBaseUser
|
29 |
+
|
30 |
+
class ResponseInfoUser(BaseModel):
|
31 |
+
status: int
|
32 |
+
data: DataInfoUser
|
33 |
+
|
34 |
+
class ResponseIsMe(BaseModel):
|
35 |
+
status: int
|
36 |
+
data: DataIsMe
|
37 |
+
|
38 |
+
class ResponseUploadImage(BaseModel):
|
39 |
+
status: int
|
40 |
+
data: DataUploadImage
|
41 |
+
|
42 |
+
class ReponseError(BaseModel):
|
43 |
+
status: int
|
44 |
+
data: Message
|
response/ResponseFile.py
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel
|
2 |
+
from typing import List
|
3 |
+
|
4 |
+
class Message(BaseModel):
|
5 |
+
message: str
|
6 |
+
|
7 |
+
class CheckModel(BaseModel):
|
8 |
+
check: bool
|
9 |
+
|
10 |
+
class DataGetNameFile(BaseModel):
|
11 |
+
files: List[str]
|
12 |
+
|
13 |
+
class ResponseGetNameFile(BaseModel):
|
14 |
+
status: int
|
15 |
+
data: DataGetNameFile
|
16 |
+
|
17 |
+
class ResponseDeleteFile(BaseModel):
|
18 |
+
status: int
|
19 |
+
data: Message
|
20 |
+
|
21 |
+
class ResponseDownloadFolder(BaseModel):
|
22 |
+
status: int
|
23 |
+
data: Message
|
24 |
+
|
25 |
+
class ResponseDeleteAllFile(BaseModel):
|
26 |
+
status: int
|
27 |
+
data: Message
|
28 |
+
|
29 |
+
class ResponseDownloadFile(BaseModel):
|
30 |
+
status: int
|
31 |
+
data: Message
|
32 |
+
|
33 |
+
class ResponseUploadedFile(BaseModel):
|
34 |
+
status: int
|
35 |
+
data: Message
|
36 |
+
|
37 |
+
class ReponseError(BaseModel):
|
38 |
+
status: int
|
39 |
+
data: Message
|
response/ResponseMySQL.py
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel
|
2 |
+
from typing import List
|
3 |
+
|
4 |
+
class ListUserChat(BaseModel):
|
5 |
+
id: int
|
6 |
+
email: str
|
7 |
+
chat_name: str
|
8 |
+
|
9 |
+
class ChatDetail(BaseModel):
|
10 |
+
id: int
|
11 |
+
chat_id: int
|
12 |
+
question: str
|
13 |
+
answer: str
|
14 |
+
data_relevant: str
|
15 |
+
source_file: str
|
16 |
+
|
17 |
+
class ChatDetailById(BaseModel):
|
18 |
+
id: int
|
19 |
+
data_relevant: str
|
20 |
+
source_file: str
|
21 |
+
|
22 |
+
class ListChatDeTail(BaseModel):
|
23 |
+
detail_chat: List[ChatDetail]
|
24 |
+
|
25 |
+
class UserInfoListResponse(BaseModel):
|
26 |
+
chat: List[ListUserChat]
|
27 |
+
|
28 |
+
class Message(BaseModel):
|
29 |
+
message: str
|
30 |
+
|
31 |
+
class CheckModel(BaseModel):
|
32 |
+
check: bool
|
33 |
+
|
34 |
+
class ResponseRenderChatHistory(BaseModel):
|
35 |
+
status: int
|
36 |
+
data: UserInfoListResponse
|
37 |
+
|
38 |
+
class ResponseChatDetailById(BaseModel):
|
39 |
+
status: int
|
40 |
+
data: ChatDetailById
|
41 |
+
class ResponseLoadChatHistory(BaseModel):
|
42 |
+
status: int
|
43 |
+
data: ListChatDeTail
|
44 |
+
|
45 |
+
class ResponseEditChat(BaseModel):
|
46 |
+
status: int
|
47 |
+
data: Message
|
48 |
+
|
49 |
+
class ResponseDeleteChat(BaseModel):
|
50 |
+
status: int
|
51 |
+
data: Message
|
52 |
+
|
53 |
+
class ResponseDeleteChatDetailById(BaseModel):
|
54 |
+
status: int
|
55 |
+
data: CheckModel
|
56 |
+
|
57 |
+
class ReponseError(BaseModel):
|
58 |
+
status: int
|
59 |
+
data: Message
|
response/ResponseOTP.py
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel
|
2 |
+
|
3 |
+
class Message(BaseModel):
|
4 |
+
message: str
|
5 |
+
|
6 |
+
class CheckModel(BaseModel):
|
7 |
+
check: bool
|
8 |
+
|
9 |
+
class ResponseCreateOTP(BaseModel):
|
10 |
+
status: int
|
11 |
+
data: CheckModel
|
12 |
+
otp: str
|
13 |
+
|
14 |
+
class ResponseVerifyOTP(BaseModel):
|
15 |
+
status: int
|
16 |
+
data: Message
|
17 |
+
newpassword: str
|
18 |
+
|
19 |
+
class ResponseVerifyOTPSignUp(BaseModel):
|
20 |
+
status: int
|
21 |
+
data: Message
|
22 |
+
|
23 |
+
class ReponseError(BaseModel):
|
24 |
+
status: int
|
25 |
+
data: Message
|
response/ResponseUser.py
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel
|
2 |
+
|
3 |
+
class DataLogin(BaseModel):
|
4 |
+
access_token: str
|
5 |
+
refresh_token: str
|
6 |
+
expires_in: int
|
7 |
+
session_id: str
|
8 |
+
|
9 |
+
class DataRefreshToken(BaseModel):
|
10 |
+
token_new: str
|
11 |
+
session_id: str
|
12 |
+
|
13 |
+
class DataSignUp(BaseModel):
|
14 |
+
email: str
|
15 |
+
|
16 |
+
class Message(BaseModel):
|
17 |
+
message: str
|
18 |
+
|
19 |
+
class CheckModel(BaseModel):
|
20 |
+
check: bool
|
21 |
+
|
22 |
+
class ResponseLoginEmail(BaseModel):
|
23 |
+
status: int
|
24 |
+
data: DataLogin
|
25 |
+
|
26 |
+
class ResponseLoginGoogle(BaseModel):
|
27 |
+
status: int
|
28 |
+
data: DataLogin
|
29 |
+
|
30 |
+
class ResponseUpdateUserInfo(BaseModel):
|
31 |
+
status : int
|
32 |
+
data: Message
|
33 |
+
|
34 |
+
class ResponseCreateOTP(BaseModel):
|
35 |
+
status: int
|
36 |
+
data: CheckModel
|
37 |
+
otp: str
|
38 |
+
|
39 |
+
class ResponseVerifyOTP(BaseModel):
|
40 |
+
status: int
|
41 |
+
data: Message
|
42 |
+
newpassword: str
|
43 |
+
|
44 |
+
class ResponseVerifyOTPSignUp(BaseModel):
|
45 |
+
status: int
|
46 |
+
data: Message
|
47 |
+
|
48 |
+
class ResponseCheckInfoGoogle(BaseModel):
|
49 |
+
status: int
|
50 |
+
data: CheckModel
|
51 |
+
|
52 |
+
class ResponseCheckStateLogin(BaseModel):
|
53 |
+
status: int
|
54 |
+
data: CheckModel
|
55 |
+
|
56 |
+
class ResponseSignUp(BaseModel):
|
57 |
+
status: int
|
58 |
+
data: DataSignUp
|
59 |
+
|
60 |
+
class ResponseResetPassword(BaseModel):
|
61 |
+
status: int
|
62 |
+
data: Message
|
63 |
+
|
64 |
+
class ResponseChangePassword(BaseModel):
|
65 |
+
status: int
|
66 |
+
data: Message
|
67 |
+
|
68 |
+
class ResponseRefreshTokenLogin(BaseModel):
|
69 |
+
status: int
|
70 |
+
data: DataRefreshToken
|
71 |
+
|
72 |
+
class ReponseError(BaseModel):
|
73 |
+
status: int
|
74 |
+
data: Message
|
service/AuthService.py
ADDED
@@ -0,0 +1,292 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from datetime import timedelta, datetime
|
2 |
+
from request import RequestAuth as req
|
3 |
+
from response import ResponseAuth as res
|
4 |
+
import requests
|
5 |
+
import json, re
|
6 |
+
from auth.authentication import signJWT
|
7 |
+
from firebase_admin import credentials, auth, exceptions
|
8 |
+
import firebase_admin
|
9 |
+
from repository import UserLoginRepository, UserRepository, UserInfoRepository, OTPRepository
|
10 |
+
import service.OTPService
|
11 |
+
from function import support_function as sf
|
12 |
+
from dotenv import load_dotenv
|
13 |
+
import os
|
14 |
+
from response import ResponseUser as res
|
15 |
+
load_dotenv()
|
16 |
+
CLIENT_ID_GOOGLE = os.getenv('CLIENT_ID')
|
17 |
+
API_SIGN_UP_FIREBASE_PATH = os.getenv('API_SIGN_UP_FIREBASE')
|
18 |
+
regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
|
19 |
+
def get_user1(email):
|
20 |
+
try:
|
21 |
+
user = auth.get_user_by_email(email)
|
22 |
+
return user
|
23 |
+
except exceptions.FirebaseError as e:
|
24 |
+
return None
|
25 |
+
|
26 |
+
def check_email(email):
|
27 |
+
if isinstance(email, str) and re.fullmatch(regex, email):
|
28 |
+
return True
|
29 |
+
else:
|
30 |
+
return False
|
31 |
+
from pathlib import Path
|
32 |
+
try:
|
33 |
+
if not firebase_admin._apps:
|
34 |
+
json_path = Path(__file__).resolve().parent / 'app' / 'firebase_certificate.json'
|
35 |
+
cred = credentials.Certificate(str(json_path))
|
36 |
+
fred = firebase_admin.initialize_app(cred)
|
37 |
+
except:
|
38 |
+
if not firebase_admin._apps:
|
39 |
+
cred = credentials.Certificate("firebase_certificate.json")
|
40 |
+
fred = firebase_admin.initialize_app(cred)
|
41 |
+
def sign_up_with_email_and_password(email, password, username=None, return_secure_token=True):
|
42 |
+
try:
|
43 |
+
rest_api_url = "https://identitytoolkit.googleapis.com/v1/accounts:signUp"
|
44 |
+
payload = {
|
45 |
+
"email": email,
|
46 |
+
"password": password,
|
47 |
+
"returnSecureToken": return_secure_token
|
48 |
+
}
|
49 |
+
if username:
|
50 |
+
payload["displayName"] = username
|
51 |
+
payload = json.dumps(payload)
|
52 |
+
r = requests.post(rest_api_url, params={"key": API_SIGN_UP_FIREBASE_PATH}, data=payload)
|
53 |
+
try:
|
54 |
+
if r.status_code == 200:
|
55 |
+
response_data = r.json()
|
56 |
+
email = response_data.get('email')
|
57 |
+
display_name = response_data.get('displayName')
|
58 |
+
return email, display_name
|
59 |
+
except Exception as e:
|
60 |
+
pass
|
61 |
+
except Exception as e:
|
62 |
+
pass
|
63 |
+
|
64 |
+
def sign_in_with_email_and_password(email=None, password=None, return_secure_token=True):
|
65 |
+
rest_api_url = "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword"
|
66 |
+
try:
|
67 |
+
payload = {
|
68 |
+
"returnSecureToken": return_secure_token
|
69 |
+
}
|
70 |
+
if email:
|
71 |
+
payload["email"] = email
|
72 |
+
if password:
|
73 |
+
payload["password"] = password
|
74 |
+
payload = json.dumps(payload)
|
75 |
+
r = requests.post(rest_api_url, params={"key": API_SIGN_UP_FIREBASE_PATH}, data=payload)
|
76 |
+
r.raise_for_status()
|
77 |
+
data = r.json()
|
78 |
+
if 'idToken' in data:
|
79 |
+
return data['email']
|
80 |
+
else:
|
81 |
+
return False
|
82 |
+
except requests.exceptions.RequestException as e:
|
83 |
+
print(f"Error signing in: {e}")
|
84 |
+
return False
|
85 |
+
|
86 |
+
|
87 |
+
def login(request: req.RequestLoginEmail):
|
88 |
+
try:
|
89 |
+
email = request.email
|
90 |
+
password = request.password
|
91 |
+
check_email_fc = sf.check_email_empty_invalid(email)
|
92 |
+
if check_email_fc is not True:
|
93 |
+
return check_email_fc
|
94 |
+
if password is None:
|
95 |
+
return res.ReponseError(
|
96 |
+
status=400,
|
97 |
+
data=res.Message(message="Password is empty")
|
98 |
+
)
|
99 |
+
user_check = get_user1(email)
|
100 |
+
if user_check is None:
|
101 |
+
return res.ReponseError(
|
102 |
+
status=404,
|
103 |
+
data=res.Message(message="Email not exits")
|
104 |
+
)
|
105 |
+
user = sign_in_with_email_and_password(email, password)
|
106 |
+
|
107 |
+
if user:
|
108 |
+
check = signJWT(user)
|
109 |
+
if check is False:
|
110 |
+
return res.ReponseError(
|
111 |
+
status=500,
|
112 |
+
data=res.Message(message="Invalid authorization code.")
|
113 |
+
)
|
114 |
+
else:
|
115 |
+
access_token = check["access_token"]
|
116 |
+
refresh_token = check["refresh_token"]
|
117 |
+
expires_in = check["expires_in"]
|
118 |
+
session_id = check["session_id"]
|
119 |
+
return res.ResponseLoginEmail(
|
120 |
+
status=200,
|
121 |
+
data=res.DataLogin(access_token=access_token, refresh_token=refresh_token, expires_in=expires_in,
|
122 |
+
session_id=session_id)
|
123 |
+
)
|
124 |
+
else:
|
125 |
+
return res.ReponseError(
|
126 |
+
status=400,
|
127 |
+
data=res.Message(message="Passwords do not match")
|
128 |
+
)
|
129 |
+
except:
|
130 |
+
return res.ReponseError(
|
131 |
+
status=500,
|
132 |
+
data=res.Message(message="Server Error")
|
133 |
+
)
|
134 |
+
|
135 |
+
def verify_token_google(token):
|
136 |
+
from google.oauth2 import id_token
|
137 |
+
from google.auth.transport import requests
|
138 |
+
try:
|
139 |
+
CLIENT_ID = CLIENT_ID_GOOGLE
|
140 |
+
id_info = id_token.verify_oauth2_token(token, requests.Request(), CLIENT_ID)
|
141 |
+
check = id_info['email_verified']
|
142 |
+
if check is True:
|
143 |
+
return True
|
144 |
+
except ValueError as e:
|
145 |
+
return False
|
146 |
+
|
147 |
+
def login_google(request: req.RequestLoginGoogle):
|
148 |
+
try:
|
149 |
+
email = request.email
|
150 |
+
token_google = request.token_google
|
151 |
+
check_google = verify_token_google(token_google)
|
152 |
+
if check_google is False:
|
153 |
+
return res.ReponseError(
|
154 |
+
status=400,
|
155 |
+
data =res.Message(message="Login google failed")
|
156 |
+
)
|
157 |
+
check_email_fc = sf.check_email_empty_invalid(email)
|
158 |
+
if check_email_fc is not True:
|
159 |
+
return check_email_fc
|
160 |
+
user = get_user1(email)
|
161 |
+
if user:
|
162 |
+
check = signJWT(email)
|
163 |
+
if check == False:
|
164 |
+
return res.ReponseError(
|
165 |
+
status=500,
|
166 |
+
data =res.Message(message="Invalid authorization code.")
|
167 |
+
)
|
168 |
+
else:
|
169 |
+
access_token = check["access_token"]
|
170 |
+
refresh_token = check["refresh_token"]
|
171 |
+
expires_in = check["expires_in"]
|
172 |
+
session_id = check["session_id"]
|
173 |
+
return res.ResponseLoginGoogle(
|
174 |
+
status= 200,
|
175 |
+
data = res.DataLogin(access_token=access_token,refresh_token=refresh_token,expires_in=expires_in,session_id=session_id)
|
176 |
+
)
|
177 |
+
else:
|
178 |
+
return res.ReponseError(
|
179 |
+
status= 404,
|
180 |
+
data = res.Message(message="Email not exist")
|
181 |
+
)
|
182 |
+
except:
|
183 |
+
return res.ReponseError(
|
184 |
+
status=500,
|
185 |
+
data=res.Message(message="Server Error")
|
186 |
+
)
|
187 |
+
|
188 |
+
def sign_up(request: req.RequestRegister):
|
189 |
+
try:
|
190 |
+
email = request.email
|
191 |
+
password = request.password
|
192 |
+
confirm_password = request.confirm_password
|
193 |
+
username = request.username
|
194 |
+
check_email_fc = sf.check_email_empty_invalid(email)
|
195 |
+
if check_email_fc is not True:
|
196 |
+
return check_email_fc
|
197 |
+
if password is None or password == "":
|
198 |
+
return res.ReponseError(
|
199 |
+
status=400,
|
200 |
+
data =res.Message(message="password is empty")
|
201 |
+
)
|
202 |
+
if confirm_password is None or confirm_password == "":
|
203 |
+
return res.ReponseError(
|
204 |
+
status=400,
|
205 |
+
data =res.Message(message="confirm password is empty")
|
206 |
+
)
|
207 |
+
if confirm_password != password:
|
208 |
+
return res.ReponseError(status=400,
|
209 |
+
data =res.Message(message="password and confirm_password do not match"))
|
210 |
+
user_signup = get_user1(email)
|
211 |
+
if user_signup is not None:
|
212 |
+
return res.ReponseError(
|
213 |
+
status=400,
|
214 |
+
data =res.Message(message="Email exist")
|
215 |
+
)
|
216 |
+
|
217 |
+
user_info, display_name = sign_up_with_email_and_password(email, password, username)
|
218 |
+
if user_info:
|
219 |
+
return res.ResponseSignUp(
|
220 |
+
status=200,
|
221 |
+
data =res.DataSignUp(email=user_info)
|
222 |
+
)
|
223 |
+
else:
|
224 |
+
return res.ReponseError(
|
225 |
+
status=500,
|
226 |
+
data =res.Message(message="Internal Server Error")
|
227 |
+
)
|
228 |
+
except:
|
229 |
+
return res.ReponseError(
|
230 |
+
status=500,
|
231 |
+
data=res.Message(message="Server Error")
|
232 |
+
)
|
233 |
+
|
234 |
+
import pytz, datetime
|
235 |
+
import auth.authentication as auth123
|
236 |
+
from response import ResponseDefault as res1
|
237 |
+
def refresh_token(request: req.RequestRefreshTokenLogin):
|
238 |
+
try:
|
239 |
+
token = request.refresh_token
|
240 |
+
if token is None:
|
241 |
+
return res.ReponseError(
|
242 |
+
status=400,
|
243 |
+
data=res.Message(message="token is empty")
|
244 |
+
)
|
245 |
+
user_token = UserRepository.getUserIdByRefreshToken(token)
|
246 |
+
if user_token is None:
|
247 |
+
return res.ReponseError(
|
248 |
+
status=404,
|
249 |
+
data=res.Message(message="Not found refresh token")
|
250 |
+
)
|
251 |
+
email = UserRepository.getEmailUserById(user_token)
|
252 |
+
if email:
|
253 |
+
rf_token = token
|
254 |
+
result = auth123.get_refresh_token(token, email)
|
255 |
+
token_new = result["access_token"]
|
256 |
+
rf_token_new = result["refresh_token"]
|
257 |
+
seconds1 = result["expires_in"]
|
258 |
+
session_id = result["session_id"]
|
259 |
+
vn_timezone = pytz.timezone('Asia/Ho_Chi_Minh')
|
260 |
+
current_time = datetime.datetime.utcnow().replace(tzinfo=pytz.utc).astimezone(vn_timezone) + timedelta(
|
261 |
+
seconds=seconds1)
|
262 |
+
formatted_time = current_time.strftime('%Y-%m-%d %H:%M:%S ')
|
263 |
+
if rf_token == rf_token_new:
|
264 |
+
UserRepository.updateAccessToken(user_token, token_new, formatted_time)
|
265 |
+
else:
|
266 |
+
UserRepository.UpdateAccessTokenRefreshTokenById(user_token, token_new, rf_token_new, formatted_time)
|
267 |
+
user = token_new
|
268 |
+
if user == False:
|
269 |
+
return res.ReponseError(
|
270 |
+
status=400,
|
271 |
+
data=res.Message(message="Refresh token error")
|
272 |
+
)
|
273 |
+
return res.ResponseRefreshTokenLogin(
|
274 |
+
status=200,
|
275 |
+
data=res.DataRefreshToken(token_new=user, session_id=session_id)
|
276 |
+
)
|
277 |
+
except:
|
278 |
+
return res.ReponseError(
|
279 |
+
status=500,
|
280 |
+
data=res.Message(message="Server Error")
|
281 |
+
)
|
282 |
+
def check_token_is_valid(token):
|
283 |
+
try:
|
284 |
+
check = UserRepository.getEmailUserByAccessToken(token)
|
285 |
+
if check is None:
|
286 |
+
return False
|
287 |
+
return True
|
288 |
+
except:
|
289 |
+
return res.ReponseError(
|
290 |
+
status=500,
|
291 |
+
data=res.Message(message="Server Error")
|
292 |
+
)
|
service/ChatService.py
ADDED
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Union
|
2 |
+
from datetime import timedelta
|
3 |
+
from request import RequestChat as req
|
4 |
+
from response import ResponseChat as res
|
5 |
+
from repository import ChatHistoryRepository, DetailChatRepository, UserRepository
|
6 |
+
import function.chatbot as sf
|
7 |
+
from typing import Dict
|
8 |
+
import json, re
|
9 |
+
from pydantic import BaseModel
|
10 |
+
from function import support_function
|
11 |
+
regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
|
12 |
+
|
13 |
+
def check_email(email):
|
14 |
+
if(re.fullmatch(regex, email)):
|
15 |
+
return True
|
16 |
+
else:
|
17 |
+
return False
|
18 |
+
|
19 |
+
class Document(BaseModel):
|
20 |
+
page_content: str
|
21 |
+
metadata: Dict[str, str]
|
22 |
+
type: str
|
23 |
+
|
24 |
+
def query2_upgrade_old(request: req.RequestQuery2UpgradeOld):
|
25 |
+
try:
|
26 |
+
user_id = request.user_id
|
27 |
+
question = request.question
|
28 |
+
text_all = request.text_all
|
29 |
+
chat_name = request.chat_name
|
30 |
+
email = support_function.check_email_service(str(user_id))
|
31 |
+
if isinstance(email, res.ReponseError):
|
32 |
+
return email
|
33 |
+
if question is None:
|
34 |
+
return res.ReponseError(
|
35 |
+
status=400,
|
36 |
+
data =res.Message(message="question is empty")
|
37 |
+
)
|
38 |
+
if chat_name is None:
|
39 |
+
return res.ReponseError(
|
40 |
+
status=400,
|
41 |
+
data =res.Message(message="chat_name is empty")
|
42 |
+
)
|
43 |
+
text_all_dicts = json.loads(text_all)
|
44 |
+
text_all1 = [Document(**doc) for doc in text_all_dicts]
|
45 |
+
test, list1, list2 = sf.handle_query_upgrade_keyword_old(question, text_all1, email)
|
46 |
+
text1 = "<Data_Relevant>".join(list1)
|
47 |
+
text2 = "<Source_File>".join(list2)
|
48 |
+
id = 0
|
49 |
+
if test:
|
50 |
+
chat_id = ChatHistoryRepository.getIdChatHistoryByUserIdAndNameChat(user_id,chat_name)
|
51 |
+
if chat_id:
|
52 |
+
id = DetailChatRepository.addDetailChat(chat_id,question, test, text1, text2)
|
53 |
+
if chat_id is None:
|
54 |
+
ChatHistoryRepository.addChatHistory(user_id,chat_name)
|
55 |
+
chat_id_new = ChatHistoryRepository.getIdChatHistoryByUserIdAndNameChat(user_id,chat_name)
|
56 |
+
id = DetailChatRepository.addDetailChat(chat_id_new, question, test, text1, text2)
|
57 |
+
return res.ResponseQuery2UpgradeOld(
|
58 |
+
status= 200,
|
59 |
+
data = res.DataAnswer1(id = id,
|
60 |
+
answer=test,
|
61 |
+
data_relevant=list1,
|
62 |
+
sources=list2))
|
63 |
+
if test is None or test == "":
|
64 |
+
return res.ReponseError(
|
65 |
+
status=500,
|
66 |
+
data =res.Message(message="No answer")
|
67 |
+
)
|
68 |
+
except:
|
69 |
+
return res.ReponseError(
|
70 |
+
status=500,
|
71 |
+
data =res.Message(message="Server Error")
|
72 |
+
)
|
73 |
+
|
74 |
+
def extract_file(request: req.RequestExtractFile):
|
75 |
+
try:
|
76 |
+
user_id = request.user_id
|
77 |
+
email = support_function.check_email_service(str(user_id))
|
78 |
+
if isinstance(email, res.ReponseError):
|
79 |
+
return email
|
80 |
+
text_all1 = sf.extract_data2(email)
|
81 |
+
if text_all1 is False:
|
82 |
+
return res.ResponseExtractFile(
|
83 |
+
status= 200,
|
84 |
+
data = res.DataExtractFile(text_all="No data response"))
|
85 |
+
return res.ResponseExtractFile(
|
86 |
+
status= 200,
|
87 |
+
data = res.DataExtractFile(text_all=text_all1))
|
88 |
+
except:
|
89 |
+
return res.ReponseError(
|
90 |
+
status=500,
|
91 |
+
data =res.Message(message="Server Error")
|
92 |
+
)
|
93 |
+
|
94 |
+
def generate_question(request: req.RequestGenerateQuestion):
|
95 |
+
try:
|
96 |
+
user_id = request.user_id
|
97 |
+
email = support_function.check_email_service(str(user_id))
|
98 |
+
if isinstance(email, res.ReponseError):
|
99 |
+
return email
|
100 |
+
text_all1 = sf.generate_question(email)
|
101 |
+
if text_all1 is False:
|
102 |
+
return res.ResponseGenerateQuestion(
|
103 |
+
status= 200,
|
104 |
+
data = res.GenerateQuestion(question=False))
|
105 |
+
|
106 |
+
return res.ResponseGenerateQuestion(
|
107 |
+
status= 200,
|
108 |
+
data = res.GenerateQuestion(question=text_all1))
|
109 |
+
except:
|
110 |
+
return res.ReponseError(
|
111 |
+
status=500,
|
112 |
+
data=res.Message(message="Server Error")
|
113 |
+
)
|
114 |
+
|
115 |
+
def delete_chat(request: req.RequestDeleteChat):
|
116 |
+
try:
|
117 |
+
user_id = request.user_id
|
118 |
+
email = support_function.check_email_service(str(user_id))
|
119 |
+
if isinstance(email, res.ReponseError):
|
120 |
+
return email
|
121 |
+
chat_name = request.chat_name
|
122 |
+
if chat_name is None:
|
123 |
+
return res.ReponseError(
|
124 |
+
status=400,
|
125 |
+
data =res.Message(message="chat_name is empty")
|
126 |
+
)
|
127 |
+
DetailChatRepository.delete_chat_detail(chat_name)
|
128 |
+
check = ChatHistoryRepository.deleteChatHistory(user_id,chat_name)
|
129 |
+
if check is False:
|
130 |
+
return res.ResponseDeleteChat(
|
131 |
+
status = 500,
|
132 |
+
data = res.Message(message="Delete conversation chat failed"))
|
133 |
+
else:
|
134 |
+
return res.ResponseDeleteChat(
|
135 |
+
status = 200,
|
136 |
+
data = res.Message(message="Delete conversation chat success"))
|
137 |
+
except:
|
138 |
+
return res.ReponseError(
|
139 |
+
status= 500,
|
140 |
+
data = res.Message(message="Server Error")
|
141 |
+
)
|
service/DefaultService.py
ADDED
@@ -0,0 +1,205 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Union
|
2 |
+
from datetime import timedelta
|
3 |
+
from request import RequestDefault as req
|
4 |
+
from response import ResponseDefault as res
|
5 |
+
from response import ResponseUser as res_login
|
6 |
+
from firebase_admin import credentials, auth, exceptions
|
7 |
+
import firebase_admin
|
8 |
+
import base64
|
9 |
+
import auth.authentication as auth123
|
10 |
+
import re
|
11 |
+
from repository import UserRepository, UserInfoRepository
|
12 |
+
from pathlib import Path
|
13 |
+
import cloudinary
|
14 |
+
import cloudinary.uploader
|
15 |
+
from fastapi import FastAPI, File, UploadFile
|
16 |
+
from function import support_function as sf
|
17 |
+
from dotenv import load_dotenv
|
18 |
+
from service import AuthService as authservice
|
19 |
+
import os
|
20 |
+
load_dotenv()
|
21 |
+
CLOUDINARY_CLOUD_NAME=os.getenv("CLOUDINARY_CLOUD_NAME")
|
22 |
+
CLOUDINARY_API_KEY=os.getenv("CLOUDINARY_API_KEY")
|
23 |
+
CLOUDINARY_API_SECRET=os.getenv("CLOUDINARY_API_SECRET")
|
24 |
+
|
25 |
+
cloudinary.config(
|
26 |
+
cloud_name=CLOUDINARY_CLOUD_NAME,
|
27 |
+
api_key=CLOUDINARY_API_KEY,
|
28 |
+
api_secret=CLOUDINARY_API_SECRET
|
29 |
+
)
|
30 |
+
import os
|
31 |
+
|
32 |
+
try:
|
33 |
+
if not firebase_admin._apps:
|
34 |
+
cred = credentials.Certificate("../certificate/firebase_certificate.json")
|
35 |
+
fred = firebase_admin.initialize_app(cred)
|
36 |
+
except:
|
37 |
+
try:
|
38 |
+
if not firebase_admin._apps:
|
39 |
+
cred = credentials.Certificate("firebase_certificate.json")
|
40 |
+
fred = firebase_admin.initialize_app(cred)
|
41 |
+
except:
|
42 |
+
if not firebase_admin._apps:
|
43 |
+
json_path = Path(__file__).resolve().parent / 'app' / 'firebase_certificate.json'
|
44 |
+
cred = credentials.Certificate(str(json_path))
|
45 |
+
fred = firebase_admin.initialize_app(cred)
|
46 |
+
|
47 |
+
regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
|
48 |
+
|
49 |
+
def check_email(email):
|
50 |
+
if(re.fullmatch(regex, email)):
|
51 |
+
return True
|
52 |
+
else:
|
53 |
+
return False
|
54 |
+
|
55 |
+
def get_user(email):
|
56 |
+
try:
|
57 |
+
user = auth.get_user_by_email(email)
|
58 |
+
return user
|
59 |
+
except exceptions.FirebaseError as e:
|
60 |
+
return None
|
61 |
+
|
62 |
+
def create_user(email):
|
63 |
+
user = auth.create_user(email=email)
|
64 |
+
return user
|
65 |
+
|
66 |
+
def get_user1(email):
|
67 |
+
try:
|
68 |
+
user = auth.get_user_by_email(email)
|
69 |
+
return user
|
70 |
+
except exceptions.FirebaseError as e:
|
71 |
+
return None
|
72 |
+
|
73 |
+
def create_firebase_user(request: req.RequestCreateFireBaseUserGoogle):
|
74 |
+
try:
|
75 |
+
email = request.email
|
76 |
+
token_google = request.token_google
|
77 |
+
check_email_fc = sf.check_email_empty_invalid(email)
|
78 |
+
if check_email_fc is not True:
|
79 |
+
return check_email_fc
|
80 |
+
user = get_user(email)
|
81 |
+
if token_google is None or token_google == "":
|
82 |
+
return res.ReponseError(
|
83 |
+
status=400,
|
84 |
+
data=res.Message(message="token google not empty")
|
85 |
+
)
|
86 |
+
check_google = authservice.verify_token_google(token_google)
|
87 |
+
if check_google == False:
|
88 |
+
return res.ReponseError(
|
89 |
+
status=400,
|
90 |
+
data=res.Message(message="Create user failed")
|
91 |
+
)
|
92 |
+
if user:
|
93 |
+
email1 = user.email
|
94 |
+
display_name = user.display_name
|
95 |
+
uid = user.uid
|
96 |
+
photo_url = user.photo_url
|
97 |
+
return res.ResponseCreateFireBaseUser(
|
98 |
+
status=200,
|
99 |
+
data = res.DataCreateFireBaseUser(localId=uid,
|
100 |
+
email=email1,
|
101 |
+
displayName=display_name,
|
102 |
+
photoUrl=photo_url)
|
103 |
+
)
|
104 |
+
else:
|
105 |
+
return res.ReponseError(
|
106 |
+
status=500,
|
107 |
+
data =res.Message(message="Error")
|
108 |
+
)
|
109 |
+
except:
|
110 |
+
return res.ReponseError(
|
111 |
+
status=500,
|
112 |
+
data =res.Message(message="Server Error")
|
113 |
+
)
|
114 |
+
|
115 |
+
def info_user(request: req.RequestInfoUser):
|
116 |
+
try:
|
117 |
+
user_id = request.user_id
|
118 |
+
email = sf.check_email_service(user_id)
|
119 |
+
if isinstance(email, res.ReponseError):
|
120 |
+
return email
|
121 |
+
user = get_user(email)
|
122 |
+
if user is None:
|
123 |
+
return res.ReponseError(
|
124 |
+
status=404,
|
125 |
+
data=res.Message(message="User not found")
|
126 |
+
)
|
127 |
+
uid = user.uid if user.uid else ""
|
128 |
+
email = user.email if user.email else ""
|
129 |
+
display_name = user.display_name if user.display_name else "N/A"
|
130 |
+
photo_url = user.photo_url if user.photo_url else "N/A"
|
131 |
+
return res.ResponseInfoUser(
|
132 |
+
status=200,
|
133 |
+
data=res.DataInfoUser(
|
134 |
+
uid=uid,
|
135 |
+
email=email,
|
136 |
+
display_name=display_name,
|
137 |
+
photo_url=photo_url
|
138 |
+
)
|
139 |
+
)
|
140 |
+
except Exception as e:
|
141 |
+
return res.ReponseError(
|
142 |
+
status=500,
|
143 |
+
data=res.Message(message="Server Error: " + str(e))
|
144 |
+
)
|
145 |
+
|
146 |
+
def check_email_token(token):
|
147 |
+
try:
|
148 |
+
decoded_token = auth123.decodeJWT(token)
|
149 |
+
sub_value = decoded_token.get("sub")
|
150 |
+
name_user = base64.b85decode(sub_value.encode('ascii')).decode('ascii')
|
151 |
+
return name_user
|
152 |
+
except:
|
153 |
+
return False
|
154 |
+
|
155 |
+
def is_me(request: req.RequestIsMe):
|
156 |
+
try:
|
157 |
+
token = request.token
|
158 |
+
if token is None or token == "":
|
159 |
+
return res.ReponseError(
|
160 |
+
status=400,
|
161 |
+
data =res.Message(message="token is empty")
|
162 |
+
)
|
163 |
+
test = check_email_token(token)
|
164 |
+
if test is not False:
|
165 |
+
user_id = UserRepository.getUserByEmail(test).id
|
166 |
+
return res.ResponseIsMe(
|
167 |
+
status=200,
|
168 |
+
data = res.DataIsMe(user_id = user_id))
|
169 |
+
except:
|
170 |
+
return res.ReponseError(
|
171 |
+
status=500,
|
172 |
+
data=res.Message(message="Server Error")
|
173 |
+
)
|
174 |
+
|
175 |
+
ALLOWED_EXTENSIONS = {'png', 'jpg','jpeg'}
|
176 |
+
def allowed_file(filename):
|
177 |
+
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
178 |
+
|
179 |
+
def upload_image_service(request: req.RequestUpLoadImage):
|
180 |
+
try:
|
181 |
+
user_id = request.user_id
|
182 |
+
file = request.files
|
183 |
+
email = sf.check_email_service(user_id)
|
184 |
+
if isinstance(email, res.ReponseError):
|
185 |
+
return email
|
186 |
+
if not allowed_file(file.filename):
|
187 |
+
return res.ReponseError(
|
188 |
+
status=415,
|
189 |
+
data=res.Message(message=f"File type not allow")
|
190 |
+
)
|
191 |
+
temp_file_path = f"temp_image_{email}.png"
|
192 |
+
contents = file.file.read()
|
193 |
+
with open(temp_file_path, "wb") as temp_file:
|
194 |
+
temp_file.write(contents)
|
195 |
+
upload_result = cloudinary.uploader.upload(temp_file_path, public_id=email)
|
196 |
+
os.remove(temp_file_path)
|
197 |
+
return res.ResponseUploadImage(
|
198 |
+
status=200,
|
199 |
+
data=res.DataUploadImage(url=upload_result["secure_url"])
|
200 |
+
)
|
201 |
+
except:
|
202 |
+
return res.ReponseError(
|
203 |
+
status=500,
|
204 |
+
data=res.Message(message="Server Error")
|
205 |
+
)
|
service/FileService.py
ADDED
@@ -0,0 +1,151 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from request import RequestFile as req
|
2 |
+
from response import ResponseFile as res
|
3 |
+
from response import ResponseDefault as res1
|
4 |
+
import function.dropbox as sf_dropbox
|
5 |
+
import os
|
6 |
+
import shutil
|
7 |
+
import re
|
8 |
+
from repository import UserRepository
|
9 |
+
from function import support_function as sf
|
10 |
+
ALLOWED_EXTENSIONS = {'csv', 'txt', 'doc', 'docx', 'pdf', 'xlsx', 'pptx', 'json','md'}
|
11 |
+
regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
|
12 |
+
|
13 |
+
def check_email(email):
|
14 |
+
if(re.fullmatch(regex, email)):
|
15 |
+
return True
|
16 |
+
else:
|
17 |
+
return False
|
18 |
+
|
19 |
+
def allowed_file(filename):
|
20 |
+
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
21 |
+
|
22 |
+
def listNameFiles(request: req.RequestGetNameFile ):
|
23 |
+
try:
|
24 |
+
user_id = request.user_id
|
25 |
+
email = sf.check_email_service(user_id)
|
26 |
+
if isinstance(email,res1.ReponseError):
|
27 |
+
return email
|
28 |
+
list_files = sf_dropbox.list_files(email)
|
29 |
+
return res.ResponseGetNameFile(
|
30 |
+
status= 200,
|
31 |
+
data = res.DataGetNameFile(files=list_files)
|
32 |
+
)
|
33 |
+
except:
|
34 |
+
return res.ReponseError(
|
35 |
+
status=500,
|
36 |
+
data =res.Message(message="Server Error")
|
37 |
+
)
|
38 |
+
|
39 |
+
def deleteFile(request: req.RequestDeleteFile):
|
40 |
+
try:
|
41 |
+
user_id = request.user_id
|
42 |
+
name_file = request.name_file
|
43 |
+
email = sf.check_email_service(user_id)
|
44 |
+
if isinstance(email, res1.ReponseError):
|
45 |
+
return email
|
46 |
+
if name_file is None or name_file == "":
|
47 |
+
return res.ReponseError(
|
48 |
+
status=400,
|
49 |
+
data =res.Message(message="Name file is empty")
|
50 |
+
)
|
51 |
+
sf_dropbox.delete_file(email,name_file)
|
52 |
+
return res.ResponseDeleteFile(
|
53 |
+
status=200,
|
54 |
+
data =res.Message(message=f"delete {name_file} success")
|
55 |
+
)
|
56 |
+
except:
|
57 |
+
return res.ReponseError(
|
58 |
+
status=500,
|
59 |
+
data =res.Message(message=f"delete {name_file} error")
|
60 |
+
)
|
61 |
+
|
62 |
+
def download_folder(request:req.RequestDownLoadFolder):
|
63 |
+
try:
|
64 |
+
user_id = request.user_id
|
65 |
+
email = sf.check_email_service(user_id)
|
66 |
+
if isinstance(email, res1.ReponseError):
|
67 |
+
return email
|
68 |
+
sf_dropbox.download_folder(email)
|
69 |
+
return res.ResponseDownloadFolder(
|
70 |
+
status=200,
|
71 |
+
data =res.Message(message=f"Downloaded folder {email} success")
|
72 |
+
)
|
73 |
+
except:
|
74 |
+
return res.ReponseError(
|
75 |
+
status=500,
|
76 |
+
data =res.Message(message=f"Server error")
|
77 |
+
)
|
78 |
+
|
79 |
+
def download_file(request:req.RequestDownLoadFile):
|
80 |
+
try:
|
81 |
+
user_id = request.user_id
|
82 |
+
name_file = request.name_file
|
83 |
+
email = sf.check_email_service(user_id)
|
84 |
+
if isinstance(email, res1.ReponseError):
|
85 |
+
return email
|
86 |
+
if name_file is None or name_file == "":
|
87 |
+
return res.ReponseError(
|
88 |
+
status=400,
|
89 |
+
data =res.Message(message="name_file is empty")
|
90 |
+
)
|
91 |
+
sf_dropbox.search_and_download_file(name_file,email)
|
92 |
+
return res.ResponseDownloadFile(
|
93 |
+
status=200,
|
94 |
+
data =res.Message(message=f"Downloaded file '{name_file}' by email: '{email}' success")
|
95 |
+
)
|
96 |
+
except:
|
97 |
+
return res.ReponseError(
|
98 |
+
status=500,
|
99 |
+
data =res.Message(message=f"Server error")
|
100 |
+
)
|
101 |
+
|
102 |
+
ALLOWED_EXTENSIONS = {'csv', 'txt', 'doc', 'docx', 'pdf', 'xlsx', 'pptx', 'json','md'}
|
103 |
+
|
104 |
+
def allowed_file1(filename):
|
105 |
+
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
106 |
+
def upload_files(request: req.RequestUploadFile):
|
107 |
+
try:
|
108 |
+
user_id = request.user_id
|
109 |
+
files = request.files
|
110 |
+
email = sf.check_email_service(user_id)
|
111 |
+
if isinstance(email, res1.ReponseError):
|
112 |
+
return email
|
113 |
+
for file in files:
|
114 |
+
if not allowed_file(file.filename):
|
115 |
+
return res.ReponseError(
|
116 |
+
status=415,
|
117 |
+
data =res.Message(message=f"File type not allow")
|
118 |
+
)
|
119 |
+
temp_dir = f"/code/temp/{email}"
|
120 |
+
os.makedirs(temp_dir, exist_ok=True)
|
121 |
+
file_path = os.path.join(temp_dir, file.filename)
|
122 |
+
with open(file_path, "wb") as buffer:
|
123 |
+
shutil.copyfileobj(file.file, buffer)
|
124 |
+
cloud_path = f"/{email}/{file.filename}"
|
125 |
+
sf_dropbox.upload_file(file_path, cloud_path)
|
126 |
+
return res.ResponseUploadedFile(
|
127 |
+
status=200,
|
128 |
+
data =res.Message(message=f"Load file success")
|
129 |
+
)
|
130 |
+
except:
|
131 |
+
return res.ReponseError(
|
132 |
+
status=500,
|
133 |
+
data =res.Message(message=f"Load file error")
|
134 |
+
)
|
135 |
+
|
136 |
+
def deleteAllFile(request: req.RequestDeleteAllFile):
|
137 |
+
try:
|
138 |
+
user_id = request.user_id
|
139 |
+
email = sf.check_email_service(user_id)
|
140 |
+
if isinstance(email, res.ReponseError):
|
141 |
+
return email
|
142 |
+
sf_dropbox.delete_all_files_in_folder(email)
|
143 |
+
return res.ResponseDeleteAllFile(
|
144 |
+
status=200,
|
145 |
+
data=res.Message(message=f"Delete all file success")
|
146 |
+
)
|
147 |
+
except:
|
148 |
+
return res.ReponseError(
|
149 |
+
status=500,
|
150 |
+
data=res.Message(message=f"Delete all file error")
|
151 |
+
)
|
service/MySQLService.py
ADDED
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
|
3 |
+
from request import RequestMySQL as req
|
4 |
+
from response import ResponseMySQL as res
|
5 |
+
from response import ResponseDefault as res1
|
6 |
+
from repository import ChatHistoryRepository
|
7 |
+
from repository import DetailChatRepository,UserRepository
|
8 |
+
from fastapi.responses import JSONResponse
|
9 |
+
from function import support_function as sf
|
10 |
+
import re
|
11 |
+
regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
|
12 |
+
|
13 |
+
def check_email(email):
|
14 |
+
if(re.fullmatch(regex, email)):
|
15 |
+
return True
|
16 |
+
else:
|
17 |
+
return False
|
18 |
+
|
19 |
+
def edit_chat(request: req.RequestEditNameChat):
|
20 |
+
try:
|
21 |
+
user_id = request.user_id
|
22 |
+
name_old = request.name_old
|
23 |
+
name_new = request.name_new
|
24 |
+
email = sf.check_email_service(user_id)
|
25 |
+
if isinstance(email, res1.ReponseError):
|
26 |
+
return email
|
27 |
+
if name_old is None or name_old =="":
|
28 |
+
return res.ReponseError(
|
29 |
+
status=400,
|
30 |
+
data =res.Message(message="name_old is empty")
|
31 |
+
)
|
32 |
+
if name_new is None or name_new == "":
|
33 |
+
return res.ReponseError(
|
34 |
+
status=400,
|
35 |
+
data =res.Message(message="name_new is empty")
|
36 |
+
)
|
37 |
+
chat_exist = ChatHistoryRepository.getIdChatHistoryByUserIdAndNameChatNew(user_id, name_new)
|
38 |
+
if chat_exist:
|
39 |
+
return res.ReponseError(
|
40 |
+
status=400,
|
41 |
+
data=res.Message(message="name_new duplicate")
|
42 |
+
)
|
43 |
+
id_chat = ChatHistoryRepository.getIdChatHistoryByUserIdAndNameChat(user_id, name_old)
|
44 |
+
if id_chat:
|
45 |
+
ChatHistoryRepository.updateNameChatHistory(user_id,name_old,name_new)
|
46 |
+
check = True
|
47 |
+
else:
|
48 |
+
check = False
|
49 |
+
if check is True:
|
50 |
+
return res.ResponseEditChat(
|
51 |
+
status= 200,
|
52 |
+
data= res.Message(message=check)
|
53 |
+
)
|
54 |
+
else:
|
55 |
+
return res.ReponseError(
|
56 |
+
status=500,
|
57 |
+
data =res.Message(message="Update chat error")
|
58 |
+
)
|
59 |
+
except:
|
60 |
+
return res.ReponseError(
|
61 |
+
status=500,
|
62 |
+
data =res.Message(message="Server Error")
|
63 |
+
)
|
64 |
+
|
65 |
+
def delete_chat(request: req.RequestDeleteChat):
|
66 |
+
try:
|
67 |
+
user_id = request.user_id
|
68 |
+
chat_name = request.chat_name
|
69 |
+
email = sf.check_email_service(user_id)
|
70 |
+
if isinstance(email, res1.ReponseError):
|
71 |
+
return email
|
72 |
+
if chat_name is None or chat_name =="":
|
73 |
+
return res.ReponseError(
|
74 |
+
status=400,
|
75 |
+
data =res.Message(message="chat_name is empty")
|
76 |
+
)
|
77 |
+
DetailChatRepository.delete_chat_detail(chat_name)
|
78 |
+
chat_exist = ChatHistoryRepository.getIdChatHistoryByUserIdAndNameChat(user_id, chat_name)
|
79 |
+
if chat_exist is None:
|
80 |
+
return res.ReponseError(
|
81 |
+
status=404,
|
82 |
+
data=res.Message(message="chat_name not exist")
|
83 |
+
)
|
84 |
+
check = ChatHistoryRepository.deleteChatHistory(user_id,chat_name)
|
85 |
+
if check is True:
|
86 |
+
return res.ResponseDeleteChat(
|
87 |
+
status= 200,
|
88 |
+
data= res.Message(message="Delete conversation chat success")
|
89 |
+
)
|
90 |
+
else:
|
91 |
+
return res.ReponseError(
|
92 |
+
status=500,
|
93 |
+
data =res.Message(message="Delete conversation chat error")
|
94 |
+
)
|
95 |
+
except Exception as e:
|
96 |
+
return res.ResponseDeleteChat(
|
97 |
+
status=500,
|
98 |
+
data=res.Message(message=str(e))
|
99 |
+
)
|
100 |
+
|
101 |
+
def delete_chat_detail_by_id(request: req.RequestDeleteDetailChat):
|
102 |
+
try:
|
103 |
+
user_id = request.user_id
|
104 |
+
chat_detail_id = request.id_chat_detail
|
105 |
+
email = sf.check_email_service(user_id)
|
106 |
+
if isinstance(email, res1.ReponseError):
|
107 |
+
return email
|
108 |
+
if chat_detail_id is None or chat_detail_id == " ":
|
109 |
+
return res.ReponseError(
|
110 |
+
status=400,
|
111 |
+
data=res.Message(message="id chat_detail is empty")
|
112 |
+
)
|
113 |
+
check = DetailChatRepository.delete_chat_detail_by_id((chat_detail_id))
|
114 |
+
if check is True:
|
115 |
+
return res.ResponseDeleteChatDetailById(
|
116 |
+
status= 200,
|
117 |
+
data= res.CheckModel(check=check)
|
118 |
+
)
|
119 |
+
else:
|
120 |
+
return res.ResponseDeleteChatDetailById(
|
121 |
+
status=200,
|
122 |
+
data=res.CheckModel(check=check)
|
123 |
+
)
|
124 |
+
except Exception as e:
|
125 |
+
return res.ResponseDeleteChat(
|
126 |
+
status=500,
|
127 |
+
data=res.Message(message=str(e))
|
128 |
+
)
|
129 |
+
|
130 |
+
def render_chat_history(request: req.RequestRenderChatHistory):
|
131 |
+
try:
|
132 |
+
user_id = request.user_id
|
133 |
+
email = sf.check_email_service(user_id)
|
134 |
+
if isinstance(email, res1.ReponseError):
|
135 |
+
return email
|
136 |
+
chat_detail = ChatHistoryRepository.getChatHistoryById(user_id)
|
137 |
+
for item in chat_detail:
|
138 |
+
print(item)
|
139 |
+
chat1 = [res.ListUserChat(id=item.id, email=item.email, chat_name=item.name_chat) for item in chat_detail]
|
140 |
+
return res.ResponseRenderChatHistory(
|
141 |
+
status=200,
|
142 |
+
data=res.UserInfoListResponse(chat=chat1)
|
143 |
+
)
|
144 |
+
except Exception as e:
|
145 |
+
return res.ReponseError(
|
146 |
+
status=500,
|
147 |
+
data=res.Message(message="Server Error")
|
148 |
+
)
|
149 |
+
|
150 |
+
def get_detail_chat_by_chat_id(request: req.RequestGetChatDetails):
|
151 |
+
id = request.id
|
152 |
+
if id is None or id == "":
|
153 |
+
return res.ReponseError(
|
154 |
+
status=400,
|
155 |
+
data=res.Message(message="Id is empty")
|
156 |
+
)
|
157 |
+
chat_detail1 = DetailChatRepository.getDetailChatByChatId(id)
|
158 |
+
if chat_detail1:
|
159 |
+
return res.ResponseChatDetailById(
|
160 |
+
status=200,
|
161 |
+
data=res.ChatDetailById(
|
162 |
+
id = chat_detail1.id,
|
163 |
+
data_relevant = chat_detail1.data_relevant,
|
164 |
+
source_file = chat_detail1.source_file
|
165 |
+
)
|
166 |
+
)
|
167 |
+
else:
|
168 |
+
return res.ReponseError(
|
169 |
+
status=404,
|
170 |
+
data=res.Message(message="Chat not exist")
|
171 |
+
)
|
172 |
+
|
173 |
+
def load_chat_history(request: req.RequestLoadChatHistory):
|
174 |
+
try:
|
175 |
+
chat_id = request.chat_id
|
176 |
+
user_id = request.user_id
|
177 |
+
email = sf.check_email_service(str(user_id))
|
178 |
+
if isinstance(email, res1.ReponseError):
|
179 |
+
return email
|
180 |
+
if chat_id is None or chat_id == "":
|
181 |
+
return res.ReponseError(
|
182 |
+
status = 400,
|
183 |
+
data = res.Message(message="chat_id is empty")
|
184 |
+
)
|
185 |
+
check_exist_chatid_width_user_id = ChatHistoryRepository.getChatHistoryByChatIdAndUserId(chat_id,user_id)
|
186 |
+
if check_exist_chatid_width_user_id is None:
|
187 |
+
return res.ReponseError(
|
188 |
+
status=404,
|
189 |
+
data=res.Message(message="Not found chat width chat_id and user_id")
|
190 |
+
)
|
191 |
+
result = DetailChatRepository.getListDetailChatByChatId(chat_id)
|
192 |
+
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]
|
193 |
+
return res.ResponseLoadChatHistory(
|
194 |
+
status = 200,
|
195 |
+
data = res.ListChatDeTail(detail_chat=chat1)
|
196 |
+
)
|
197 |
+
except:
|
198 |
+
return res.ReponseError(
|
199 |
+
status=500,
|
200 |
+
data=res.Message(message="Server Error")
|
201 |
+
)
|
service/OTPService.py
ADDED
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from datetime import timedelta,datetime
|
2 |
+
from request import RequestOTP as req
|
3 |
+
from response import ResponseOTP as res
|
4 |
+
import re
|
5 |
+
from firebase_admin import auth, exceptions
|
6 |
+
from repository import OTPRepository
|
7 |
+
from datetime import datetime, timedelta
|
8 |
+
import datetime, string,random
|
9 |
+
from function import support_function as sf
|
10 |
+
regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
|
11 |
+
|
12 |
+
def get_user1(email):
|
13 |
+
try:
|
14 |
+
user = auth.get_user_by_email(email)
|
15 |
+
return user
|
16 |
+
except exceptions.FirebaseError as e:
|
17 |
+
return None
|
18 |
+
|
19 |
+
def check_email(email):
|
20 |
+
if isinstance(email, str) and re.fullmatch(regex, email):
|
21 |
+
return True
|
22 |
+
else:
|
23 |
+
return False
|
24 |
+
|
25 |
+
def generate_otp(length=6):
|
26 |
+
characters = string.ascii_uppercase + string.digits
|
27 |
+
otp = ''.join(random.choice(characters) for _ in range(length))
|
28 |
+
return otp
|
29 |
+
|
30 |
+
def createOTP(request: req.RequestCreateOTP):
|
31 |
+
try:
|
32 |
+
email = request.email
|
33 |
+
otp = generate_otp()
|
34 |
+
check_email_fc = sf.check_email_empty_invalid(email)
|
35 |
+
if check_email_fc is not True:
|
36 |
+
return check_email_fc
|
37 |
+
OTPRepository.addOTP(email,otp)
|
38 |
+
return res.ResponseCreateOTP(
|
39 |
+
status=200,
|
40 |
+
data = res.CheckModel(check=True),
|
41 |
+
otp = otp
|
42 |
+
)
|
43 |
+
except:
|
44 |
+
return res.ReponseError(
|
45 |
+
status=500,
|
46 |
+
data=res.Message(message="Server Error")
|
47 |
+
)
|
48 |
+
|
49 |
+
def verifyOTP(request: req.RequestVerifyOTP):
|
50 |
+
try:
|
51 |
+
email = request.email
|
52 |
+
otp = request.otp
|
53 |
+
check_email_fc = sf.check_email_empty_invalid(email)
|
54 |
+
if check_email_fc is not True:
|
55 |
+
return check_email_fc
|
56 |
+
if otp is None:
|
57 |
+
return res.ReponseError(
|
58 |
+
status=400,
|
59 |
+
data=res.Message(message="otp is empty")
|
60 |
+
)
|
61 |
+
user_otp = OTPRepository.getOtpByEmail(email)
|
62 |
+
if user_otp:
|
63 |
+
otp_db = user_otp.otp
|
64 |
+
otp_created_at = user_otp.created_at
|
65 |
+
if otp == otp_db:
|
66 |
+
current_time = datetime.datetime.now()
|
67 |
+
otp_expiry_time = otp_created_at + timedelta(minutes=15)
|
68 |
+
if current_time <= otp_expiry_time:
|
69 |
+
OTPRepository.deleteOTP(email, otp)
|
70 |
+
return res.ResponseVerifyOTPSignUp(
|
71 |
+
status=200,
|
72 |
+
data=res.Message(message="OTP is valid")
|
73 |
+
)
|
74 |
+
else:
|
75 |
+
return res.ReponseError(
|
76 |
+
status=400,
|
77 |
+
data=res.Message(message="OTP has expired")
|
78 |
+
)
|
79 |
+
else:
|
80 |
+
return res.ReponseError(
|
81 |
+
status=400,
|
82 |
+
data=res.Message(message="Invalid OTP")
|
83 |
+
)
|
84 |
+
else:
|
85 |
+
return res.ReponseError(
|
86 |
+
status=404,
|
87 |
+
data=res.Message(message="No OTP found for this email")
|
88 |
+
)
|
89 |
+
except:
|
90 |
+
return res.ReponseError(
|
91 |
+
status=500,
|
92 |
+
data=res.Message(message="Server Error")
|
93 |
+
)
|
94 |
+
|
95 |
+
def createOTPReset(email):
|
96 |
+
try:
|
97 |
+
otp = generate_otp()
|
98 |
+
check_email_fc = sf.check_email_empty_invalid(email)
|
99 |
+
if check_email_fc is not True:
|
100 |
+
return check_email_fc
|
101 |
+
OTPRepository.addOTP(email,otp)
|
102 |
+
return res.ResponseCreateOTP(
|
103 |
+
status=200,
|
104 |
+
data = res.CheckModel(check=True),
|
105 |
+
otp = otp
|
106 |
+
)
|
107 |
+
except:
|
108 |
+
return res.ReponseError(
|
109 |
+
status=500,
|
110 |
+
data=res.Message(message="Server Error")
|
111 |
+
)
|
112 |
+
|
113 |
+
def generate_random_password(length=8):
|
114 |
+
characters = string.ascii_letters + string.digits
|
115 |
+
password = ''.join(random.choice(characters) for i in range(length))
|
116 |
+
return password
|
117 |
+
|
118 |
+
def verifyOTPReset(request: req.RequestVerifyOTP):
|
119 |
+
try:
|
120 |
+
email = request.email
|
121 |
+
otp = request.otp
|
122 |
+
check_email_fc = sf.check_email_empty_invalid(email)
|
123 |
+
if check_email_fc is not True:
|
124 |
+
return check_email_fc
|
125 |
+
if otp is None:
|
126 |
+
return res.ReponseError(
|
127 |
+
status=400,
|
128 |
+
data=res.Message(message="OTP is empty")
|
129 |
+
)
|
130 |
+
user_otp = OTPRepository.getOtpByEmail(email)
|
131 |
+
if user_otp:
|
132 |
+
otp_db = user_otp.otp
|
133 |
+
otp_created_at = user_otp.created_at
|
134 |
+
if otp == otp_db:
|
135 |
+
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)
|
136 |
+
otp_expiry_time = otp_created_at + timedelta(minutes=15)
|
137 |
+
new_password = generate_random_password()
|
138 |
+
if current_time <= otp_expiry_time:
|
139 |
+
OTPRepository.deleteOTP(email, otp)
|
140 |
+
user_email = auth.get_user_by_email(email)
|
141 |
+
auth.update_user(
|
142 |
+
user_email.uid,
|
143 |
+
password=new_password)
|
144 |
+
return res.ResponseVerifyOTP(
|
145 |
+
status=200,
|
146 |
+
data=res.Message(message="New Password send to Email"),
|
147 |
+
newpassword=new_password
|
148 |
+
)
|
149 |
+
else:
|
150 |
+
return res.ReponseError(
|
151 |
+
status=400,
|
152 |
+
data=res.Message(message="OTP has expired")
|
153 |
+
)
|
154 |
+
else:
|
155 |
+
return res.ReponseError(
|
156 |
+
status=400,
|
157 |
+
data=res.Message(message="Invalid OTP")
|
158 |
+
)
|
159 |
+
else:
|
160 |
+
return res.ReponseError(
|
161 |
+
status=404,
|
162 |
+
data=res.Message(message="No OTP found for this email")
|
163 |
+
)
|
164 |
+
except:
|
165 |
+
return res.ReponseError(
|
166 |
+
status=500,
|
167 |
+
data=res.Message(message="Server Error")
|
168 |
+
)
|
service/UserService.py
ADDED
@@ -0,0 +1,322 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from datetime import timedelta, datetime
|
2 |
+
from request import RequestUser as req_login
|
3 |
+
from response import ResponseUser as res_login
|
4 |
+
import requests
|
5 |
+
import json, re
|
6 |
+
from auth.authentication import signJWT
|
7 |
+
from firebase_admin import credentials, auth, exceptions
|
8 |
+
import firebase_admin
|
9 |
+
from repository import UserLoginRepository, UserRepository, UserInfoRepository, OTPRepository
|
10 |
+
import service.OTPService
|
11 |
+
from function import support_function as sf
|
12 |
+
from dotenv import load_dotenv
|
13 |
+
import os
|
14 |
+
from response import ResponseUser as res
|
15 |
+
from response import ResponseDefault as res1
|
16 |
+
load_dotenv()
|
17 |
+
CLIENT_ID_GOOGLE = os.getenv('CLIENT_ID')
|
18 |
+
API_SIGN_UP_FIREBASE_PATH = os.getenv('API_SIGN_UP_FIREBASE')
|
19 |
+
regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
|
20 |
+
|
21 |
+
def get_user1(email):
|
22 |
+
try:
|
23 |
+
user = auth.get_user_by_email(email)
|
24 |
+
return user
|
25 |
+
except exceptions.FirebaseError as e:
|
26 |
+
return None
|
27 |
+
|
28 |
+
def check_email(email):
|
29 |
+
if isinstance(email, str) and re.fullmatch(regex, email):
|
30 |
+
return True
|
31 |
+
else:
|
32 |
+
return False
|
33 |
+
from pathlib import Path
|
34 |
+
try:
|
35 |
+
if not firebase_admin._apps:
|
36 |
+
json_path = Path(__file__).resolve().parent / 'app' / 'firebase_certificate.json'
|
37 |
+
cred = credentials.Certificate(str(json_path))
|
38 |
+
fred = firebase_admin.initialize_app(cred)
|
39 |
+
except:
|
40 |
+
if not firebase_admin._apps:
|
41 |
+
cred = credentials.Certificate("firebase_certificate.json")
|
42 |
+
fred = firebase_admin.initialize_app(cred)
|
43 |
+
|
44 |
+
def sign_up_with_email_and_password(email, password, username=None, return_secure_token=True):
|
45 |
+
try:
|
46 |
+
rest_api_url = "https://identitytoolkit.googleapis.com/v1/accounts:signUp"
|
47 |
+
payload = {
|
48 |
+
"email": email,
|
49 |
+
"password": password,
|
50 |
+
"returnSecureToken": return_secure_token
|
51 |
+
}
|
52 |
+
if username:
|
53 |
+
payload["displayName"] = username
|
54 |
+
payload = json.dumps(payload)
|
55 |
+
r = requests.post(rest_api_url, params={"key": API_SIGN_UP_FIREBASE_PATH}, data=payload)
|
56 |
+
try:
|
57 |
+
return r.json()['email']
|
58 |
+
except Exception as e:
|
59 |
+
pass
|
60 |
+
except Exception as e:
|
61 |
+
pass
|
62 |
+
|
63 |
+
def sign_in_with_email_and_password(email=None, password=None, return_secure_token=True):
|
64 |
+
rest_api_url = "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword"
|
65 |
+
try:
|
66 |
+
payload = {
|
67 |
+
"returnSecureToken": return_secure_token
|
68 |
+
}
|
69 |
+
if email:
|
70 |
+
payload["email"] = email
|
71 |
+
if password:
|
72 |
+
payload["password"] = password
|
73 |
+
payload = json.dumps(payload)
|
74 |
+
r = requests.post(rest_api_url, params={"key": API_SIGN_UP_FIREBASE_PATH}, data=payload)
|
75 |
+
r.raise_for_status()
|
76 |
+
data = r.json()
|
77 |
+
if 'idToken' in data:
|
78 |
+
return data['email']
|
79 |
+
else:
|
80 |
+
return False
|
81 |
+
except requests.exceptions.RequestException as e:
|
82 |
+
print(f"Error signing in: {e}")
|
83 |
+
return False
|
84 |
+
|
85 |
+
def update_info_user(uid, email=None, user_name=None, photo_url=None):
|
86 |
+
user_data = {}
|
87 |
+
if email is not None:
|
88 |
+
user_data['email'] = email
|
89 |
+
if user_name is not None:
|
90 |
+
user_data['display_name'] = user_name
|
91 |
+
if photo_url is not None and photo_url != 'N/A':
|
92 |
+
user_data['photo_url'] = photo_url
|
93 |
+
if user_data:
|
94 |
+
auth.update_user(uid, **user_data)
|
95 |
+
|
96 |
+
def update_user_info(request: req_login.RequestUpdateUserInfo):
|
97 |
+
try:
|
98 |
+
email = request.email
|
99 |
+
user_id = request.user_id
|
100 |
+
email_check = sf.check_email_service(user_id)
|
101 |
+
if isinstance(email_check, res1.ReponseError):
|
102 |
+
return email_check
|
103 |
+
check_email_fc = sf.check_email_empty_invalid(email)
|
104 |
+
if check_email_fc is not True:
|
105 |
+
return check_email_fc
|
106 |
+
user = get_user1(email)
|
107 |
+
if user:
|
108 |
+
user_info = UserInfoRepository.getUserInfo(user_id)
|
109 |
+
if user_info:
|
110 |
+
UserInfoRepository.updateUserInfo(
|
111 |
+
request.user_id,
|
112 |
+
request.uid,
|
113 |
+
request.email,
|
114 |
+
request.display_name,
|
115 |
+
request.photo_url)
|
116 |
+
else:
|
117 |
+
UserInfoRepository.addUserInfo(
|
118 |
+
request.uid,
|
119 |
+
request.email,
|
120 |
+
request.display_name,
|
121 |
+
request.photo_url
|
122 |
+
)
|
123 |
+
update_info_user(request.uid,
|
124 |
+
request.email,
|
125 |
+
request.display_name,
|
126 |
+
request.photo_url
|
127 |
+
)
|
128 |
+
return res_login.ResponseUpdateUserInfo(status=200,
|
129 |
+
data = res_login.Message(message=f"User info updated successfully"))
|
130 |
+
else:
|
131 |
+
return res_login.ReponseError(
|
132 |
+
status = 404,
|
133 |
+
data = res_login.Message(message="Not found user")
|
134 |
+
)
|
135 |
+
except:
|
136 |
+
return res_login.ReponseError(
|
137 |
+
status=500,
|
138 |
+
data=res_login.Message(message="Server Error")
|
139 |
+
)
|
140 |
+
|
141 |
+
def check_info_google(request: req_login.RequestCheckInfoGoogle):
|
142 |
+
try:
|
143 |
+
user_id = request.user_id
|
144 |
+
check = UserRepository.getEmailUserByIdFix(user_id)
|
145 |
+
if check is None:
|
146 |
+
return res_login.ReponseError(
|
147 |
+
status = 404,
|
148 |
+
data = res_login.Message(message="user_id not exist")
|
149 |
+
)
|
150 |
+
email = sf.check_email_service(str(user_id))
|
151 |
+
if isinstance(email, res.ReponseError):
|
152 |
+
return email
|
153 |
+
user_info = UserInfoRepository.getUserInfo(user_id)
|
154 |
+
if user_info is not None:
|
155 |
+
email_check = True
|
156 |
+
else:
|
157 |
+
email_check = False
|
158 |
+
if email_check is not None:
|
159 |
+
return res_login.ResponseCheckInfoGoogle(status= 200,data = res_login.CheckModel(check=email_check))
|
160 |
+
except:
|
161 |
+
return res_login.ReponseError(
|
162 |
+
status=500,
|
163 |
+
data=res_login.Message(message="Server Error")
|
164 |
+
)
|
165 |
+
|
166 |
+
def check_info_google_email(request: req_login.RequestCheckInfoGoogleEmail):
|
167 |
+
try:
|
168 |
+
email = request.email
|
169 |
+
check_email_fc = sf.check_email_empty_invalid(email)
|
170 |
+
if check_email_fc is not True:
|
171 |
+
return check_email_fc
|
172 |
+
user_info = UserInfoRepository.getUserInfoByEmail(email)
|
173 |
+
if user_info is not None:
|
174 |
+
email_check = True
|
175 |
+
else:
|
176 |
+
email_check = False
|
177 |
+
if email_check is not None:
|
178 |
+
return res_login.ResponseCheckInfoGoogle(status= 200,data = res_login.CheckModel(check=email_check))
|
179 |
+
except:
|
180 |
+
return res_login.ReponseError(
|
181 |
+
status=500,
|
182 |
+
data=res_login.Message(message="Server Error")
|
183 |
+
)
|
184 |
+
|
185 |
+
def check_state_login(request: req_login.RequestCheckStateLogin):
|
186 |
+
try:
|
187 |
+
user_id = request.user_id
|
188 |
+
session_id_now = request.session_id_now
|
189 |
+
email = sf.check_email_service(user_id)
|
190 |
+
if isinstance(email, res1.ReponseError):
|
191 |
+
return email
|
192 |
+
elif session_id_now is None or session_id_now=="":
|
193 |
+
return res_login.ReponseError(
|
194 |
+
status= 400,
|
195 |
+
data =res_login.Message(message="session_id is empty")
|
196 |
+
)
|
197 |
+
user = get_user1(email)
|
198 |
+
if user:
|
199 |
+
check1 = False
|
200 |
+
session_id = UserLoginRepository.getUserSessionIdByUserEmail(user_id)
|
201 |
+
print(f"session_id: {session_id}")
|
202 |
+
if session_id != session_id_now:
|
203 |
+
check1 = False
|
204 |
+
else:
|
205 |
+
check1 = True
|
206 |
+
return res_login.ResponseCheckInfoGoogle(status= 200,data = res_login.CheckModel(check = check1))
|
207 |
+
else:
|
208 |
+
return res_login.ReponseError(
|
209 |
+
status=404,
|
210 |
+
data =res_login.Message(message="Not found user")
|
211 |
+
)
|
212 |
+
except:
|
213 |
+
return res_login.ReponseError(
|
214 |
+
status=500,
|
215 |
+
data=res_login.Message(message="Server Error")
|
216 |
+
)
|
217 |
+
|
218 |
+
import string, random
|
219 |
+
def generate_otp(length=6):
|
220 |
+
characters = string.ascii_uppercase + string.digits
|
221 |
+
otp = ''.join(random.choice(characters) for _ in range(length))
|
222 |
+
return otp
|
223 |
+
|
224 |
+
def createOTPReset(email):
|
225 |
+
otp = generate_otp()
|
226 |
+
check_email_fc = sf.check_email_empty_invalid(email)
|
227 |
+
if check_email_fc is not True:
|
228 |
+
return check_email_fc
|
229 |
+
OTPRepository.addOTP(email,otp)
|
230 |
+
return otp
|
231 |
+
|
232 |
+
def reset_password(request: req_login.RequestResetPassword):
|
233 |
+
try:
|
234 |
+
email = request.email
|
235 |
+
check_email_fc = sf.check_email_empty_invalid(email)
|
236 |
+
if check_email_fc is not True:
|
237 |
+
return check_email_fc
|
238 |
+
try:
|
239 |
+
user = get_user1(email)
|
240 |
+
if user is not None:
|
241 |
+
otp = createOTPReset(email)
|
242 |
+
return res_login.ResponseCreateOTP(
|
243 |
+
status= 200,
|
244 |
+
data= res_login.CheckModel(check = True),
|
245 |
+
otp = otp
|
246 |
+
)
|
247 |
+
else:
|
248 |
+
return res_login.ReponseError(
|
249 |
+
status= 404,
|
250 |
+
data =res_login.Message(message="Email not exist")
|
251 |
+
)
|
252 |
+
except auth.UserNotFoundError as e:
|
253 |
+
return res_login.ReponseError(
|
254 |
+
status=500,
|
255 |
+
data =res_login.Message(message=str(e))
|
256 |
+
)
|
257 |
+
except:
|
258 |
+
return res_login.ReponseError(
|
259 |
+
status=500,
|
260 |
+
data=res_login.Message(message="Server Error")
|
261 |
+
)
|
262 |
+
|
263 |
+
def change_password(request: req_login.RequestChangePassword):
|
264 |
+
try:
|
265 |
+
user_id = request.user_id
|
266 |
+
email = sf.check_email_service(user_id)
|
267 |
+
new_password = request.new_password
|
268 |
+
current_password= request.current_password
|
269 |
+
confirm_new_password = request.confirm_new_password
|
270 |
+
if isinstance(email, res1.ReponseError):
|
271 |
+
return email
|
272 |
+
if new_password is None:
|
273 |
+
return res_login.ReponseError(
|
274 |
+
status=400,
|
275 |
+
data =res_login.Message(message="new_password is empty")
|
276 |
+
)
|
277 |
+
if current_password is None or confirm_new_password == "":
|
278 |
+
return res_login.ReponseError(
|
279 |
+
status=400,
|
280 |
+
data =res_login.Message(message="current_password is empty")
|
281 |
+
)
|
282 |
+
if confirm_new_password is None or confirm_new_password == "":
|
283 |
+
return res_login.ReponseError(
|
284 |
+
status=400,
|
285 |
+
data =res_login.Message(message="confirm_new_password is empty")
|
286 |
+
)
|
287 |
+
if current_password == new_password:
|
288 |
+
return res_login.ReponseError(
|
289 |
+
status=400,
|
290 |
+
data=res_login.Message(message="The new_password and the current_password must be different")
|
291 |
+
)
|
292 |
+
if confirm_new_password != new_password:
|
293 |
+
return res_login.ReponseError(
|
294 |
+
status=400,
|
295 |
+
data=res_login.Message(message="The new_password and the confirm_new_password must be similar")
|
296 |
+
)
|
297 |
+
user = sign_in_with_email_and_password(email, current_password)
|
298 |
+
try:
|
299 |
+
if user:
|
300 |
+
user_email = auth.get_user_by_email(email)
|
301 |
+
auth.update_user(
|
302 |
+
user_email.uid,
|
303 |
+
password=new_password
|
304 |
+
)
|
305 |
+
return res_login.ResponseChangePassword(
|
306 |
+
status= 200,
|
307 |
+
data = res_login.Message(message=f"Update password success"))
|
308 |
+
else:
|
309 |
+
return res_login.ReponseError(
|
310 |
+
status=400,
|
311 |
+
data =res_login.Message(message="Current password not valid")
|
312 |
+
)
|
313 |
+
except :
|
314 |
+
return res_login.ReponseError(
|
315 |
+
status=500,
|
316 |
+
data =res_login.Message(message="Server Error")
|
317 |
+
)
|
318 |
+
except:
|
319 |
+
return res_login.ReponseError(
|
320 |
+
status=500,
|
321 |
+
data=res_login.Message(message="Server Error!!")
|
322 |
+
)
|
service/app/firebase_certificate.json
ADDED
File without changes
|
tests/test_controller/__init__.py
ADDED
File without changes
|
tests/test_controller/test_ChatController.py
ADDED
@@ -0,0 +1,258 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import sys
|
3 |
+
from unittest.mock import patch
|
4 |
+
from fastapi import Path
|
5 |
+
from fastapi.testclient import TestClient
|
6 |
+
app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
7 |
+
sys.path.insert(0, app_path)
|
8 |
+
from controller import ChatController
|
9 |
+
import json
|
10 |
+
client = TestClient(ChatController.router)
|
11 |
+
|
12 |
+
text_all = [{
|
13 |
+
"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]",
|
14 |
+
"metadata": {"source": "/code/temp/vonhuytest123456789@gmail.com/JD_BD-Intern.pdf"},
|
15 |
+
"type": "Document"}]
|
16 |
+
|
17 |
+
from response import ResponseChat as res
|
18 |
+
@patch('function.support_function.check_email_service')
|
19 |
+
def test_query2_upgrade_old_id_not_exist(mock_user_repo):
|
20 |
+
mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message(
|
21 |
+
message="Id not exist"))
|
22 |
+
response = client.post("/chatbot/query/", data={"user_id": 1,
|
23 |
+
"text_all": json.dumps(text_all),
|
24 |
+
"question": "12455",
|
25 |
+
"chat_name": "test"})
|
26 |
+
assert response.json()['status'] == 400
|
27 |
+
assert response.json()['data']['message'] == "Id not exist"
|
28 |
+
|
29 |
+
@patch('function.support_function.check_email_service')
|
30 |
+
def test_query2_upgrade_old_email_empty(mock_user_repo):
|
31 |
+
mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message(
|
32 |
+
message="Email is empty"))
|
33 |
+
response = client.post("/chatbot/query/", data={"user_id": 1,
|
34 |
+
"text_all": json.dumps(text_all),
|
35 |
+
"question": "12455",
|
36 |
+
"chat_name": "test"})
|
37 |
+
assert response.json()['status'] == 400
|
38 |
+
assert response.json()['data']['message'] == "Email is empty"
|
39 |
+
|
40 |
+
@patch('function.support_function.check_email_service')
|
41 |
+
def test_query2_upgrade_old_email_in_valid(mock_user_repo):
|
42 |
+
mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message(
|
43 |
+
message="Email invalid"))
|
44 |
+
response = client.post("/chatbot/query/", data={"user_id": 1,
|
45 |
+
"text_all": json.dumps(text_all),
|
46 |
+
"question": "12455",
|
47 |
+
"chat_name": "test"})
|
48 |
+
assert response.json()['status'] == 400
|
49 |
+
assert response.json()['data']['message'] == "Email invalid"
|
50 |
+
|
51 |
+
@patch('function.support_function.check_email_service')
|
52 |
+
def test_query2_upgrade_old_question_empty(mock_user_repo):
|
53 |
+
mock_user_repo.return_value = "example@example.com"
|
54 |
+
response = client.post("/chatbot/query/", data={"user_id": 1,
|
55 |
+
"text_all": json.dumps(text_all),
|
56 |
+
"question": "",
|
57 |
+
"chat_name": "test"})
|
58 |
+
assert response.json()['status'] == 400
|
59 |
+
assert response.json()['data']['message'] == "question is empty"
|
60 |
+
|
61 |
+
@patch('function.support_function.check_email_service')
|
62 |
+
def test_query2_upgrade_old_chat_history_empty(mock_user_repo):
|
63 |
+
mock_user_repo.return_value = "example@example.com"
|
64 |
+
response = client.post("/chatbot/query/", data={"user_id": 1,
|
65 |
+
"text_all": json.dumps(text_all),
|
66 |
+
"question": "123",
|
67 |
+
"chat_name": None})
|
68 |
+
assert response.json()['status'] == 400
|
69 |
+
assert response.json()['data']['message'] == "chat_name is empty"
|
70 |
+
|
71 |
+
@patch('function.support_function.check_email_service')
|
72 |
+
@patch('service.ChatService.sf')
|
73 |
+
def test_query2_upgrade_old_no_answer(mock_function_chatbot, mock_user_repo):
|
74 |
+
mock_user_repo.return_value = ("example@example.com",)
|
75 |
+
list1 = []
|
76 |
+
list2 = []
|
77 |
+
mock_function_chatbot.handle_query_upgrade_keyword_old.return_value = None, list1, list2
|
78 |
+
response = client.post("/chatbot/query/", data={"user_id": 1,
|
79 |
+
"text_all": json.dumps(text_all),
|
80 |
+
"question": "alo",
|
81 |
+
"chat_name": "test"})
|
82 |
+
assert response.json()['status'] == 500
|
83 |
+
assert response.json()['data']['message'] == "No answer"
|
84 |
+
|
85 |
+
@patch('function.support_function.check_email_service')
|
86 |
+
@patch('service.ChatService.sf')
|
87 |
+
@patch('service.ChatService.ChatHistoryRepository')
|
88 |
+
@patch('service.ChatService.DetailChatRepository')
|
89 |
+
def test_query2_upgrade_old_success(mock_detail_chat_repo, mock_chat_his_repo, mock_function_chatbot, mock_user_repo):
|
90 |
+
mock_user_repo.return_value = ("example@example.com",)
|
91 |
+
list1 = []
|
92 |
+
list2 = []
|
93 |
+
mock_function_chatbot.handle_query_upgrade_keyword_old.return_value = "success",list1,list2
|
94 |
+
mock_chat_his_repo.getIdChatHistoryByUserIdAndNameChat.return_value = True
|
95 |
+
mock_detail_chat_repo.addDetailChat.return_value = True
|
96 |
+
response = client.post("/chatbot/query/", data={"user_id": 1,
|
97 |
+
"text_all": json.dumps(text_all),
|
98 |
+
"question": "123",
|
99 |
+
"chat_name": "test"})
|
100 |
+
assert response.json()['status'] == 200
|
101 |
+
assert response.json()['data']['answer'] == "success"
|
102 |
+
|
103 |
+
@patch('function.support_function.check_email_service')
|
104 |
+
@patch('service.ChatService.sf')
|
105 |
+
def test_extract_file_success(mock_function_chatbot, mock_user_repo):
|
106 |
+
user_id = 1
|
107 |
+
mock_user_repo.return_value = ("example@example.com",)
|
108 |
+
mock_function_chatbot.extract_data2.return_value = "Success"
|
109 |
+
response = client.get(f"/chatbot/extract_file/{user_id}")
|
110 |
+
assert response.json()['status'] == 200
|
111 |
+
assert response.json()['data']['text_all'] == "Success"
|
112 |
+
|
113 |
+
|
114 |
+
|
115 |
+
@patch('function.support_function.check_email_service')
|
116 |
+
def test_extract_file_id_not_exist(mock_user_repo):
|
117 |
+
user_id = 1
|
118 |
+
mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message(
|
119 |
+
message="Id not exist"))
|
120 |
+
response = client.get(f"/chatbot/extract_file/{user_id}")
|
121 |
+
assert response.json()['status'] == 400
|
122 |
+
assert response.json()['data']['message'] == "Id not exist"
|
123 |
+
|
124 |
+
@patch('function.support_function.check_email_service')
|
125 |
+
def test_extract_file_email_empty(mock_user_repo):
|
126 |
+
user_id = 1
|
127 |
+
email = ""
|
128 |
+
mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message(
|
129 |
+
message="Email is empty"))
|
130 |
+
response = client.get(f"/chatbot/extract_file/{user_id}")
|
131 |
+
assert response.json()['status'] == 400
|
132 |
+
assert response.json()['data']['message'] == "Email is empty"
|
133 |
+
|
134 |
+
@patch('function.support_function.check_email_service')
|
135 |
+
def test_extract_file_email_in_valid(mock_user_repo):
|
136 |
+
user_id = 1
|
137 |
+
email = "202133123"
|
138 |
+
mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message(
|
139 |
+
message="Email invalid"))
|
140 |
+
response = client.get(f"/chatbot/extract_file/{user_id}")
|
141 |
+
assert response.json()['status'] == 400
|
142 |
+
assert response.json()['data']['message'] == "Email invalid"
|
143 |
+
|
144 |
+
@patch('function.support_function.check_email_service')
|
145 |
+
@patch('service.ChatService.sf')
|
146 |
+
def test_extract_file_no_data(mock_function_chatbot, mock_user_repo):
|
147 |
+
user_id = 1
|
148 |
+
email = "2021330@gmail.com"
|
149 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
150 |
+
mock_function_chatbot.extract_data2.return_value = False
|
151 |
+
response = client.get(f"/chatbot/extract_file/{user_id}")
|
152 |
+
assert response.json()['status'] == 200
|
153 |
+
assert response.json()['data']['text_all'] == "No data response"
|
154 |
+
|
155 |
+
@patch('function.support_function.check_email_service')
|
156 |
+
@patch('service.ChatService.sf')
|
157 |
+
def test_generate_question_success(mock_function_chatbot, mock_user_repo):
|
158 |
+
user_id = 1
|
159 |
+
mock_user_repo.return_value = ("example@example.com",)
|
160 |
+
mock_function_chatbot.generate_question.return_value = ["Success"]
|
161 |
+
response = client.get(f"/chatbot/generate_question/{user_id}")
|
162 |
+
assert response.json()['status'] == 200
|
163 |
+
assert response.json()['data']['question'] == ["Success"]
|
164 |
+
|
165 |
+
@patch('function.support_function.check_email_service')
|
166 |
+
def test_generate_question_id_not_exist(mock_user_repo):
|
167 |
+
user_id = 1
|
168 |
+
mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message(
|
169 |
+
message="Id not exist"))
|
170 |
+
response = client.get(f"/chatbot/generate_question/{user_id}")
|
171 |
+
assert response.json()['status'] == 400
|
172 |
+
assert response.json()['data']['message'] == "Id not exist"
|
173 |
+
|
174 |
+
@patch('function.support_function.check_email_service')
|
175 |
+
def test_generate_question_email_empty(mock_user_repo):
|
176 |
+
user_id = 1
|
177 |
+
email = ""
|
178 |
+
mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message(
|
179 |
+
message="Email is empty"))
|
180 |
+
response = client.get(f"/chatbot/generate_question/{user_id}")
|
181 |
+
assert response.json()['status'] == 400
|
182 |
+
assert response.json()['data']['message'] == "Email is empty"
|
183 |
+
|
184 |
+
|
185 |
+
@patch('function.support_function.check_email_service')
|
186 |
+
def test_generate_question_email_in_valid(mock_user_repo):
|
187 |
+
user_id = 1
|
188 |
+
email = "202133123"
|
189 |
+
mock_user_repo.return_value = res.ReponseError(status=400, data=res.Message(
|
190 |
+
message="Email invalid"))
|
191 |
+
response = client.get(f"/chatbot/generate_question/{user_id}")
|
192 |
+
assert response.json()['status'] == 400
|
193 |
+
assert response.json()['data']['message'] == "Email invalid"
|
194 |
+
|
195 |
+
@patch('function.support_function.check_email_service')
|
196 |
+
@patch('service.ChatService.sf')
|
197 |
+
def test_generate_question_no_data(mock_function_chatbot, mock_user_repo):
|
198 |
+
user_id = 1
|
199 |
+
email = "2021330@gmail.com"
|
200 |
+
mock_user_repo.return_value = (email,)
|
201 |
+
mock_function_chatbot.generate_question.return_value = False
|
202 |
+
response = client.get(f"/chatbot/generate_question/{user_id}")
|
203 |
+
assert response.json()['status'] == 200
|
204 |
+
assert response.json()['data']['question'] == False
|
205 |
+
|
206 |
+
def test_query_chatbot_user_id_required():
|
207 |
+
user_id = None
|
208 |
+
response = client.post("/chatbot/query/", data={"user_id": user_id,
|
209 |
+
"text_all": json.dumps(text_all),
|
210 |
+
"question": "12455",
|
211 |
+
"chat_name": "test"})
|
212 |
+
assert response.json()['status'] == 400
|
213 |
+
assert response.json()['data']['message'] == "user_id field is required."
|
214 |
+
|
215 |
+
def test_query_chatbot_user_id_interger():
|
216 |
+
user_id = "aaaaa"
|
217 |
+
response = client.post("/chatbot/query/", data={"user_id": user_id,
|
218 |
+
"text_all": json.dumps(text_all),
|
219 |
+
"question": "12455",
|
220 |
+
"chat_name": "test"})
|
221 |
+
assert response.json()['status'] == 400
|
222 |
+
assert response.json()['data']['message'] == "user_id must be an integer"
|
223 |
+
|
224 |
+
def test_query_chatbot_user_id_greater_0():
|
225 |
+
user_id = "0"
|
226 |
+
response = client.post("/chatbot/query/", data={"user_id": user_id,
|
227 |
+
"text_all": json.dumps(text_all),
|
228 |
+
"question": "12455",
|
229 |
+
"chat_name": "test"})
|
230 |
+
assert response.json()['status'] == 400
|
231 |
+
assert response.json()['data']['message'] == "user_id must be greater than 0"
|
232 |
+
|
233 |
+
|
234 |
+
|
235 |
+
|
236 |
+
def test_extract_file_user_id_interger():
|
237 |
+
user_id = "aaaaa"
|
238 |
+
response = client.get(f"/chatbot/extract_file/{user_id}")
|
239 |
+
assert response.json()['status'] == 400
|
240 |
+
assert response.json()['data']['message'] == "user_id must be an integer"
|
241 |
+
|
242 |
+
def test_extract_file_user_id_greater_0():
|
243 |
+
user_id = "0"
|
244 |
+
response = client.get(f"/chatbot/extract_file/{user_id}")
|
245 |
+
assert response.json()['status'] == 400
|
246 |
+
assert response.json()['data']['message'] == "user_id must be greater than 0"
|
247 |
+
|
248 |
+
def test_generate_question_user_id_interger():
|
249 |
+
user_id = "aaaaa"
|
250 |
+
response = client.get(f"/chatbot/generate_question/{user_id}")
|
251 |
+
assert response.json()['status'] == 400
|
252 |
+
assert response.json()['data']['message'] == "user_id must be an integer"
|
253 |
+
|
254 |
+
def test_generate_question_user_id_greater_0():
|
255 |
+
user_id = "0"
|
256 |
+
response = client.get(f"/chatbot/generate_question/{user_id}")
|
257 |
+
assert response.json()['status'] == 400
|
258 |
+
assert response.json()['data']['message'] == "user_id must be greater than 0"
|
tests/test_controller/test_DefaultController.py
ADDED
@@ -0,0 +1,330 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
import os
|
3 |
+
import sys
|
4 |
+
from unittest.mock import patch, Mock
|
5 |
+
|
6 |
+
from fastapi.testclient import TestClient
|
7 |
+
|
8 |
+
app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
9 |
+
sys.path.insert(0, app_path)
|
10 |
+
from controller import DefaultController
|
11 |
+
client = TestClient(DefaultController.router)
|
12 |
+
|
13 |
+
def test_create_firebase_user_null_email():
|
14 |
+
request_payload = {"email": None}
|
15 |
+
response = client.post("/create_firebase_user_google", json=request_payload)
|
16 |
+
assert response.json()['status'] == 400
|
17 |
+
try:
|
18 |
+
response_data = response.json()['data']
|
19 |
+
assert response_data['message'] == "Email is required."
|
20 |
+
except json.decoder.JSONDecodeError:
|
21 |
+
assert response.text == "Email cannot be 'null'."
|
22 |
+
|
23 |
+
def test_invalid_email():
|
24 |
+
email = "invalid-email"
|
25 |
+
token= "token123455"
|
26 |
+
response = client.post("/create_firebase_user_google", json={"email": email,"token_google": token})
|
27 |
+
assert response.json()['status'] == 400
|
28 |
+
assert response.json()['data']['message'] == "Email invalid"
|
29 |
+
|
30 |
+
@patch('service.DefaultService.sf.check_email_empty_invalid',return_value=True)
|
31 |
+
@patch('service.DefaultService.get_user')
|
32 |
+
def test_create_firebase_server_error(mock_get_user, mock_check_email):
|
33 |
+
email = "20133118@gmail.com"
|
34 |
+
mock_get_user.side_effect = Exception("Unexpected Error")
|
35 |
+
token = "token"
|
36 |
+
response = client.post("/create_firebase_user_google", json={"email": email, "token_google": token})
|
37 |
+
assert response.json()['status'] == 500
|
38 |
+
assert response.json()['data']['message'] == "Server Error"
|
39 |
+
|
40 |
+
from response import ResponseDefault as res
|
41 |
+
@patch('service.DefaultService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message(
|
42 |
+
message="Id not exist")))
|
43 |
+
@patch('service.DefaultService.get_user')
|
44 |
+
@patch('service.DefaultService.check_email')
|
45 |
+
def test_id_not_exist(mock_check_email, mock_get_user, mock_getEmailUserByIdFix):
|
46 |
+
user_id = "1"
|
47 |
+
response = client.get(f"/info_user/{user_id}")
|
48 |
+
assert response.json()['status'] == 400
|
49 |
+
assert response.json()['data']['message'] == "Id not exist"
|
50 |
+
|
51 |
+
@patch('service.DefaultService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message(
|
52 |
+
message="Email is empty")))
|
53 |
+
@patch('service.DefaultService.get_user')
|
54 |
+
@patch('service.DefaultService.check_email')
|
55 |
+
def test_info_user_email_empty(mock_check_email, mock_get_user, mock_getEmailUserByIdFix):
|
56 |
+
user_id = "1"
|
57 |
+
response = client.get(f"/info_user/{user_id}")
|
58 |
+
assert response.json()['status'] == 400
|
59 |
+
assert response.json()['data']['message'] == "Email is empty"
|
60 |
+
|
61 |
+
@patch('service.DefaultService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message(
|
62 |
+
message="Email invalid")))
|
63 |
+
@patch('service.DefaultService.get_user')
|
64 |
+
@patch('service.DefaultService.check_email')
|
65 |
+
def test_info_user_email_invalid(mock_check_email, mock_get_user, mock_getEmailUserByIdFix):
|
66 |
+
user_id = "1"
|
67 |
+
email = "20133118"
|
68 |
+
response = client.get(f"/info_user/{user_id}")
|
69 |
+
assert response.json()['status'] == 400
|
70 |
+
assert response.json()['data']['message'] == "Email invalid"
|
71 |
+
|
72 |
+
@patch('service.DefaultService.UserRepository.getEmailUserByIdFix')
|
73 |
+
@patch('service.DefaultService.get_user', return_value=None)
|
74 |
+
@patch('service.DefaultService.check_email', return_value=True)
|
75 |
+
@patch('service.DefaultService.sf.check_email_service',return_value="20133118@gmail.com")
|
76 |
+
def test_info_user_user_not_found(mock_check,mock_check_email, mock_get_user, mock_getEmailUserByIdFix):
|
77 |
+
user_id = "1"
|
78 |
+
email = "20133118@gmail.com"
|
79 |
+
response = client.get(f"/info_user/{user_id}")
|
80 |
+
assert response.json()['status'] == 404
|
81 |
+
assert response.json()['data']['message'] == "User not found"
|
82 |
+
|
83 |
+
@patch('service.DefaultService.UserRepository.getEmailUserByIdFix')
|
84 |
+
@patch('service.DefaultService.get_user')
|
85 |
+
@patch('service.DefaultService.check_email', return_value=True)
|
86 |
+
@patch('service.DefaultService.sf.check_email_service',return_value="20133118@gmail.com")
|
87 |
+
def test_info_success(mock_check,mock_check_email, mock_get_user, mock_getEmailUserByIdFix):
|
88 |
+
user_id = "1"
|
89 |
+
email = "20133118@gmail.com"
|
90 |
+
user = Mock()
|
91 |
+
user.uid = "12345"
|
92 |
+
user.email = "test@example.com"
|
93 |
+
user.display_name = "Test User"
|
94 |
+
user.photo_url = "http://example.com/photo.jpg"
|
95 |
+
mock_get_user.return_value = user
|
96 |
+
response = client.get(f"/info_user/{user_id}")
|
97 |
+
assert response.json()['status'] == 200
|
98 |
+
assert response.json()['data']['uid'] == user.uid
|
99 |
+
assert response.json()['data']['email'] == user.email
|
100 |
+
assert response.json()['data']['display_name'] == user.display_name
|
101 |
+
assert response.json()['data']['photo_url'] == user.photo_url
|
102 |
+
|
103 |
+
@patch('service.DefaultService.sf.check_email_service')
|
104 |
+
@patch('service.DefaultService.get_user')
|
105 |
+
@patch('service.DefaultService.check_email')
|
106 |
+
def test_user_info_server_error(mock_check_email, mock_get_user, mock_getEmailUserByIdFix):
|
107 |
+
user_id = "1"
|
108 |
+
email = "20133118@gmail.com"
|
109 |
+
mock_getEmailUserByIdFix.side_effect = Exception("Unexpected Error")
|
110 |
+
response = client.get(f"/info_user/{user_id}")
|
111 |
+
assert response.json()['status'] == 500
|
112 |
+
assert response.json()['data']['message'] == "Server Error: Unexpected Error"
|
113 |
+
|
114 |
+
@patch('service.DefaultService.check_email_token', return_value=False)
|
115 |
+
def test_is_me_none_token(mock_check_email_token):
|
116 |
+
token = ""
|
117 |
+
response = client.get("/is_me/", params={"token": token})
|
118 |
+
assert response.json()['status'] == 400
|
119 |
+
assert response.json()['data']['message'] == "Token field is required."
|
120 |
+
|
121 |
+
@patch('service.DefaultService.check_email_token', return_value=Exception("Error"))
|
122 |
+
def test_is_me_invalid_token(mock_check_email_token):
|
123 |
+
token = "invalid_token"
|
124 |
+
response = client.get("/is_me/", params={"token": token})
|
125 |
+
assert response.json()['status'] == 500
|
126 |
+
assert response.json()['data']['message'] == "Server Error"
|
127 |
+
|
128 |
+
@patch('service.DefaultService.UserRepository.getUserByEmail')
|
129 |
+
@patch('service.DefaultService.check_email_token')
|
130 |
+
def test_is_me_success(mock_check_email_token, mock_getUserByEmail):
|
131 |
+
token = "token"
|
132 |
+
mock_check_email_token.return_value = "user@example.com"
|
133 |
+
user = Mock()
|
134 |
+
user.id = "1"
|
135 |
+
mock_getUserByEmail.return_value = user
|
136 |
+
response = client.get("/is_me/", params={"token": token})
|
137 |
+
assert response.json()['status'] == 200
|
138 |
+
assert response.json()['data']['user_id'] == 1
|
139 |
+
|
140 |
+
@patch('service.DefaultService.check_email_token')
|
141 |
+
def test_is_me_server_error(mock_check_email_token):
|
142 |
+
token = "token"
|
143 |
+
mock_check_email_token.side_effect = Exception("Unexpected Error")
|
144 |
+
response = client.get("/is_me/", params={"token": token})
|
145 |
+
assert response.json()['status'] == 500
|
146 |
+
assert response.json()['data']['message'] == "Server Error"
|
147 |
+
|
148 |
+
from fastapi import UploadFile
|
149 |
+
from io import BytesIO
|
150 |
+
import tempfile, io
|
151 |
+
@patch('service.DefaultService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message(
|
152 |
+
message="Id not exist")))
|
153 |
+
def test_upload_image_id_not_exist(mock_getUserByEmail):
|
154 |
+
user_id = "1"
|
155 |
+
file_content = b"test image content"
|
156 |
+
file = io.BytesIO(file_content)
|
157 |
+
file.name = "test_image.png"
|
158 |
+
|
159 |
+
data = {
|
160 |
+
"user_id": user_id,
|
161 |
+
}
|
162 |
+
files = {"file": ("test_image.png", file, "image/png")}
|
163 |
+
response = client.post("/upload_image", data=data, files=files)
|
164 |
+
assert response.json()['status'] == 400
|
165 |
+
assert response.json()['data']['message'] == "Id not exist"
|
166 |
+
|
167 |
+
@patch('service.DefaultService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message(
|
168 |
+
message="Email is empty")))
|
169 |
+
def test_upload_image_email_empty(mock_getUserByEmail):
|
170 |
+
user_id = "1"
|
171 |
+
file_content = b"test image content"
|
172 |
+
file = io.BytesIO(file_content)
|
173 |
+
file.name = "test_image.png"
|
174 |
+
|
175 |
+
data = {
|
176 |
+
"user_id": user_id,
|
177 |
+
}
|
178 |
+
files = {"file": ("test_image.png", file, "image/png")}
|
179 |
+
response = client.post("/upload_image", data=data, files=files)
|
180 |
+
assert response.json()['status'] == 400
|
181 |
+
assert response.json()['data']['message'] == "Email is empty"
|
182 |
+
|
183 |
+
@patch('service.DefaultService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message(
|
184 |
+
message="Email invalid")))
|
185 |
+
def test_upload_image_email_invalid(mock_getUserByEmail):
|
186 |
+
user_id = "1"
|
187 |
+
file_content = b"test image content"
|
188 |
+
file = io.BytesIO(file_content)
|
189 |
+
file.name = "test_image.png"
|
190 |
+
data = {
|
191 |
+
"user_id": user_id,
|
192 |
+
}
|
193 |
+
files = {"file": ("test_image.png", file, "image/png")}
|
194 |
+
response = client.post("/upload_image", data=data, files=files)
|
195 |
+
assert response.json()['status'] == 400
|
196 |
+
assert response.json()['data']['message'] == "Email invalid"
|
197 |
+
|
198 |
+
@patch('service.DefaultService.sf.check_email_service', return_value="test1333@gmail.com")
|
199 |
+
@patch('service.DefaultService.cloudinary.uploader.upload')
|
200 |
+
@patch('service.DefaultService.check_email')
|
201 |
+
@patch('service.DefaultService.allowed_file')
|
202 |
+
def test_upload_image_server_err(mock_allowed_file, mock_check_email, mock_upload, mock_get_email):
|
203 |
+
mock_check_email.return_value = True
|
204 |
+
mock_allowed_file.return_value = False
|
205 |
+
user_id = "1"
|
206 |
+
file_content = b"test image content"
|
207 |
+
file = io.BytesIO(file_content)
|
208 |
+
file.name = "test_image.pdf"
|
209 |
+
|
210 |
+
data = {
|
211 |
+
"user_id": user_id,
|
212 |
+
}
|
213 |
+
files = {"file": ("test_image.png", file, "aplication/pdf")}
|
214 |
+
response = client.post("/upload_image", data=data, files=files)
|
215 |
+
assert response.json()['status'] == 415
|
216 |
+
assert response.json()['data']['message'] == "File type not allow"
|
217 |
+
|
218 |
+
@patch('service.DefaultService.sf.check_email_service', return_value="test@example.com")
|
219 |
+
@patch('service.DefaultService.cloudinary.uploader.upload')
|
220 |
+
@patch('service.DefaultService.check_email')
|
221 |
+
@patch('service.DefaultService.allowed_file')
|
222 |
+
def test_upload_image_success(mock_allowed_file, mock_check_email, mock_upload, mock_get_email):
|
223 |
+
mock_allowed_file.return_value = True
|
224 |
+
mock_upload.return_value = {"secure_url": "https://example.com/image.png"}
|
225 |
+
user_id = "1"
|
226 |
+
file_content = b"test image content"
|
227 |
+
file = io.BytesIO(file_content)
|
228 |
+
file.name = "test_image.png"
|
229 |
+
|
230 |
+
data = {
|
231 |
+
"user_id": user_id,
|
232 |
+
}
|
233 |
+
files = {"file": ("test_image.png", file, "image/png")}
|
234 |
+
response = client.post("/upload_image", data=data, files=files)
|
235 |
+
assert response.json()['status'] == 200
|
236 |
+
assert response.json()['data']['url'] == 'https://example.com/image.png'
|
237 |
+
|
238 |
+
def test_is_me_token_is_required():
|
239 |
+
token = None
|
240 |
+
response = client.get("/is_me/",params={'token':token})
|
241 |
+
assert response.json()['status'] == 400
|
242 |
+
assert response.json()['data']['message'] == "Token field is required."
|
243 |
+
|
244 |
+
def test_is_me_token_must_be_string():
|
245 |
+
token = "013333"
|
246 |
+
response = client.get("/is_me/",params={'token':token})
|
247 |
+
assert response.json()['status'] == 400
|
248 |
+
assert response.json()['data']['message'] == "Token must be a string, not a number."
|
249 |
+
|
250 |
+
def test_create_firebase_user_google_is_None():
|
251 |
+
email = None
|
252 |
+
response = client.post("/create_firebase_user_google/",json={'email':email})
|
253 |
+
assert response.json()['status'] == 400
|
254 |
+
assert response.json()['data']['message'] == "Email is required."
|
255 |
+
|
256 |
+
def test_create_firebase_user_google_email_must_be_string():
|
257 |
+
email = "20133"
|
258 |
+
response = client.post("/create_firebase_user_google/",json={'email':email})
|
259 |
+
assert response.json()['status'] == 400
|
260 |
+
assert response.json()['data']['message'] == "Email must be a string, not a number."
|
261 |
+
|
262 |
+
def test_create_firebase_user_google_token_is_required():
|
263 |
+
email = "abcd@gmail.com"
|
264 |
+
response = client.post("/create_firebase_user_google/",json={'email':email,"token_google": None})
|
265 |
+
assert response.json()['status'] == 400
|
266 |
+
assert response.json()['data']['message'] == "Token field is required."
|
267 |
+
|
268 |
+
def test_create_firebase_user_google_token_must_be_str():
|
269 |
+
email = "abcd@gmail.com"
|
270 |
+
response = client.post("/create_firebase_user_google/",json={'email':email,"token_google": "123"})
|
271 |
+
assert response.json()['status'] == 400
|
272 |
+
assert response.json()['data']['message'] == "Token must be a string, not a number."
|
273 |
+
|
274 |
+
def test_create_firebase_user_google_token_must_be_str_1():
|
275 |
+
email = "abcd@gmail.com"
|
276 |
+
response = client.post("/create_firebase_user_google/",json={'email':email,"token_google": 123})
|
277 |
+
assert response.json()['status'] == 400
|
278 |
+
assert response.json()['data']['message'] == "Token must be a string, not a number."
|
279 |
+
|
280 |
+
|
281 |
+
|
282 |
+
|
283 |
+
|
284 |
+
def test_info_user_user_id_must_be_string():
|
285 |
+
user_id = "0"
|
286 |
+
response = client.get(f"/info_user/{user_id}")
|
287 |
+
assert response.json()['status'] == 400
|
288 |
+
assert response.json()['data']['message'] == "user_id must be greater than 0"
|
289 |
+
|
290 |
+
def test_upload_image_user_id_integer():
|
291 |
+
user_id = "aaaa"
|
292 |
+
file_content = b"test image content"
|
293 |
+
file = io.BytesIO(file_content)
|
294 |
+
file.name = "test_image.png"
|
295 |
+
|
296 |
+
data = {
|
297 |
+
"user_id": user_id,
|
298 |
+
}
|
299 |
+
files = {"file": ("test_image.png", file, "image/png")}
|
300 |
+
response = client.post("/upload_image/", data=data, files=files)
|
301 |
+
assert response.json()['status'] == 400
|
302 |
+
assert response.json()['data']['message'] == "Value must be an integer"
|
303 |
+
|
304 |
+
def test_upload_image_user_id_integer():
|
305 |
+
user_id = "aaaa"
|
306 |
+
file_content = b"test image content"
|
307 |
+
file = io.BytesIO(file_content)
|
308 |
+
file.name = "test_image.png"
|
309 |
+
|
310 |
+
data = {
|
311 |
+
"user_id": user_id,
|
312 |
+
}
|
313 |
+
files = {"file": ("test_image.png", file, "image/png")}
|
314 |
+
response = client.post("/upload_image", data=data, files=files)
|
315 |
+
assert response.json()['status'] == 400
|
316 |
+
assert response.json()['data']['message'] == "user_id must be an integer"
|
317 |
+
|
318 |
+
def test_upload_image_user_id_greater_than_0():
|
319 |
+
user_id = "0"
|
320 |
+
file_content = b"test image content"
|
321 |
+
file = io.BytesIO(file_content)
|
322 |
+
file.name = "test_image.png"
|
323 |
+
|
324 |
+
data = {
|
325 |
+
"user_id": user_id,
|
326 |
+
}
|
327 |
+
files = {"file": ("test_image.png", file, "image/png")}
|
328 |
+
response = client.post("/upload_image", data=data, files=files)
|
329 |
+
assert response.json()['status'] == 400
|
330 |
+
assert response.json()['data']['message'] == "user_id must be greater than 0"
|
tests/test_controller/test_FileController.py
ADDED
@@ -0,0 +1,478 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import sys
|
3 |
+
import tempfile
|
4 |
+
import unittest
|
5 |
+
from io import BytesIO
|
6 |
+
from unittest.mock import patch
|
7 |
+
from fastapi import UploadFile
|
8 |
+
from fastapi.testclient import TestClient
|
9 |
+
from response import ResponseFile as res
|
10 |
+
from response import ResponseDefault as res1
|
11 |
+
app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
12 |
+
sys.path.insert(0, app_path)
|
13 |
+
from controller import FileController
|
14 |
+
client = TestClient(FileController.router)
|
15 |
+
|
16 |
+
@patch('repository.UserRepository.getEmailUserByIdFix')
|
17 |
+
def test_delete_file_success(mock_user_repo):
|
18 |
+
user_id = "1"
|
19 |
+
email = 'example@example.com'
|
20 |
+
name_file = "test1.pdf"
|
21 |
+
mock_user_repo.return_value = (email,)
|
22 |
+
response = client.request("DELETE", "/delete_file", json={"user_id": user_id, "name_file": name_file})
|
23 |
+
assert response.json()['status'] == 200
|
24 |
+
|
25 |
+
@patch('function.support_function.check_email_service')
|
26 |
+
def test_delete_file_id_not_exist(mock_user_repo):
|
27 |
+
user_id = "1"
|
28 |
+
email = 'example@example.com'
|
29 |
+
name_file = "test1.pdf"
|
30 |
+
mock_user_repo.return_value = res1.ReponseError(status=400, data=res.Message(
|
31 |
+
message="Id not exist"))
|
32 |
+
response = client.request("DELETE", "/delete_file", json={"user_id": user_id, "name_file": name_file})
|
33 |
+
assert response.json()['status'] == 400
|
34 |
+
assert response.json()['data']['message'] == "Id not exist"
|
35 |
+
|
36 |
+
@patch('function.support_function.check_email_service')
|
37 |
+
def test_delete_file_email_empty(mock_user_repo):
|
38 |
+
user_id = "1"
|
39 |
+
name_file = "test1.pdf"
|
40 |
+
mock_user_repo.return_value = res1.ReponseError(status=400, data=res.Message(
|
41 |
+
message="Email is empty"))
|
42 |
+
response = client.request("DELETE", "/delete_file", json={"user_id": user_id, "name_file": name_file})
|
43 |
+
assert response.json()['status'] == 400
|
44 |
+
assert response.json()['data']['message'] == "Email is empty"
|
45 |
+
|
46 |
+
@patch('function.support_function.check_email_service')
|
47 |
+
def test_delete_file_email_invalid(mock_user_repo):
|
48 |
+
user_id = "1"
|
49 |
+
email = "20133"
|
50 |
+
name_file = "test1.pdf"
|
51 |
+
mock_user_repo.return_value = res1.ReponseError(status=400, data=res.Message(
|
52 |
+
message="Email invalid"))
|
53 |
+
response = client.request("DELETE", "/delete_file", json={"user_id": user_id, "name_file": name_file})
|
54 |
+
assert response.json()['status'] == 400
|
55 |
+
assert response.json()['data']['message'] == "Email invalid"
|
56 |
+
|
57 |
+
@patch('function.support_function.check_email_service')
|
58 |
+
def test_delete_file_namefile_empty(mock_user_repo):
|
59 |
+
user_id = "1"
|
60 |
+
email = "201333@gmail.com"
|
61 |
+
name_file = ""
|
62 |
+
mock_user_repo.return_value = (email,)
|
63 |
+
response = client.request("DELETE", "/delete_file", json={"user_id": user_id, "name_file": name_file})
|
64 |
+
assert response.json()['status'] == 400
|
65 |
+
assert response.json()['data']['message'] == "Name file is required."
|
66 |
+
|
67 |
+
@patch('function.support_function.check_email_service')
|
68 |
+
def test_delete_all_file_success(mock_user_repo):
|
69 |
+
user_id = "1"
|
70 |
+
email = "201333@gmail.com"
|
71 |
+
mock_user_repo.return_value = (email,)
|
72 |
+
response = client.request("DELETE", "/delete", json={"user_id": user_id})
|
73 |
+
assert response.json()['status'] == 200
|
74 |
+
assert response.json()['data']['message'] == "Delete all file success"
|
75 |
+
|
76 |
+
@patch('function.support_function.check_email_service')
|
77 |
+
def test_delete_all_file_email_empty(mock_user_repo):
|
78 |
+
user_id = "1"
|
79 |
+
mock_user_repo.return_value = res.ReponseError(status=400, data=res1.Message(
|
80 |
+
message="Email is empty"))
|
81 |
+
response = client.request("DELETE", "/delete", json={"user_id": user_id})
|
82 |
+
assert response.json()['status'] == 400
|
83 |
+
assert response.json()['data']['message'] == "Email is empty"
|
84 |
+
|
85 |
+
@patch('function.support_function.check_email_service')
|
86 |
+
def test_delete_all_file_email_invalid(mock_user_repo):
|
87 |
+
user_id = "1"
|
88 |
+
mock_user_repo.return_value = res.ReponseError(status=400, data=res1.Message(
|
89 |
+
message="Email invalid"))
|
90 |
+
response = client.request("DELETE", "/delete", json={"user_id": user_id})
|
91 |
+
assert response.json()['status'] == 400
|
92 |
+
assert response.json()['data']['message'] == "Email invalid"
|
93 |
+
|
94 |
+
@patch('function.support_function.check_email_service')
|
95 |
+
@patch('service.FileService.sf_dropbox.list_files')
|
96 |
+
def test_list_name_file_success(mock_list_files, mock_user_repo):
|
97 |
+
user_id = "1"
|
98 |
+
email = "quangphuc@gmail.com"
|
99 |
+
mock_user_repo.return_value = (email,)
|
100 |
+
list_files = [
|
101 |
+
'demo1.pdf', 'CV_VoNhuY_Java.pdf', 'VanHoangLuong_DangXuanBach_TLCN.docx',
|
102 |
+
'THÔNG-TIN-TUYỂN-DỤNG-Java.pdf', 'baitap_qlpv_nhom14.docx', 'PMBOK2012-5rd Edition.pdf',
|
103 |
+
'BaoCaoThucTapTotnghiep_20133059_Fpt_Software.docx'
|
104 |
+
]
|
105 |
+
mock_list_files.return_value = list_files
|
106 |
+
response = client.get("/list_name_files", params={"user_id": user_id})
|
107 |
+
assert response.json()['status'] == 200
|
108 |
+
assert response.json()['data']['files'] == list_files
|
109 |
+
assert len(response.json()['data']['files']) == 7
|
110 |
+
|
111 |
+
@patch('function.support_function.check_email_service')
|
112 |
+
@patch('service.FileService.sf_dropbox.list_files')
|
113 |
+
def test_list_name_file_id_not_exist(mock_list_files, mock_user_repo):
|
114 |
+
user_id = "1"
|
115 |
+
email = "quangphuc@gmail.com"
|
116 |
+
mock_user_repo.return_value = res1.ReponseError(status=400, data=res.Message(
|
117 |
+
message="Id not exist"))
|
118 |
+
response = client.get("/list_name_files", params={"user_id": user_id})
|
119 |
+
assert response.json()['status'] == 400
|
120 |
+
assert response.json()['data']['message'] == "Id not exist"
|
121 |
+
|
122 |
+
@patch('function.support_function.check_email_service')
|
123 |
+
@patch('service.FileService.sf_dropbox.list_files')
|
124 |
+
def test_list_name_file_email_empty(mock_list_files, mock_user_repo):
|
125 |
+
user_id = "1"
|
126 |
+
email = None
|
127 |
+
name_file = "test1.pdf"
|
128 |
+
mock_user_repo.return_value = res1.ReponseError(status=400, data=res.Message(
|
129 |
+
message="Email is empty"))
|
130 |
+
response = client.get("/list_name_files", params={"user_id": user_id})
|
131 |
+
assert response.json()['status'] == 400
|
132 |
+
assert response.json()['data']['message'] == "Email is empty"
|
133 |
+
|
134 |
+
@patch('function.support_function.check_email_service')
|
135 |
+
@patch('service.FileService.sf_dropbox.list_files')
|
136 |
+
def test_list_name_file_email_invalid(mock_list_files, mock_user_repo):
|
137 |
+
user_id = "1"
|
138 |
+
email = "20133"
|
139 |
+
name_file = "test1.pdf"
|
140 |
+
mock_user_repo.return_value = res1.ReponseError(status=400, data=res.Message(
|
141 |
+
message="Email invalid"))
|
142 |
+
response = client.get("/list_name_files", params={"user_id": user_id})
|
143 |
+
assert response.json()['status'] == 400
|
144 |
+
assert response.json()['data']['message'] == "Email invalid"
|
145 |
+
|
146 |
+
@patch('function.support_function.check_email_service')
|
147 |
+
def test_download_folder_success(mock_user_repo):
|
148 |
+
user_id = "1"
|
149 |
+
email = 'example@example.com'
|
150 |
+
mock_user_repo.return_value = email
|
151 |
+
response = client.post("/chatbot/download_folder/", json={"user_id": user_id})
|
152 |
+
assert response.json()['status'] == 200
|
153 |
+
assert response.json()['data']['message'] == f'Downloaded folder {email} success'
|
154 |
+
|
155 |
+
@patch('function.support_function.check_email_service')
|
156 |
+
def test_download_folder_id_not_exist(mock_user_repo):
|
157 |
+
user_id = "1"
|
158 |
+
email = 'example@example.com'
|
159 |
+
mock_user_repo.return_value = res1.ReponseError(status=400, data=res.Message(
|
160 |
+
message="Id not exist"))
|
161 |
+
response = client.post("/chatbot/download_folder/", json={"user_id": user_id})
|
162 |
+
assert response.json()['status'] == 400
|
163 |
+
assert response.json()['data']['message'] == "Id not exist"
|
164 |
+
|
165 |
+
@patch('function.support_function.check_email_service')
|
166 |
+
def test_download_folder_email_empty(mock_user_repo):
|
167 |
+
user_id = "1"
|
168 |
+
email = None
|
169 |
+
mock_user_repo.return_value = res1.ReponseError(status=400, data=res.Message(
|
170 |
+
message="Email is empty"))
|
171 |
+
response = client.post("/chatbot/download_folder/", json={"user_id": user_id})
|
172 |
+
assert response.json()['status'] == 400
|
173 |
+
assert response.json()['data']['message'] == "Email is empty"
|
174 |
+
|
175 |
+
@patch('function.support_function.check_email_service')
|
176 |
+
def test_download_folder_email_invalid(mock_user_repo):
|
177 |
+
user_id = "1"
|
178 |
+
email = "20133"
|
179 |
+
mock_user_repo.return_value = res1.ReponseError(status=400, data=res.Message(
|
180 |
+
message="Email invalid"))
|
181 |
+
response = client.post("/chatbot/download_folder/", json={"user_id": user_id})
|
182 |
+
assert response.json()['status'] == 400
|
183 |
+
assert response.json()['data']['message'] == "Email invalid"
|
184 |
+
|
185 |
+
@patch('function.support_function.check_email_service')
|
186 |
+
def test_download_file_success(mock_user_repo):
|
187 |
+
user_id = "1"
|
188 |
+
email = "quangphuc@gmail.com"
|
189 |
+
name_file = "demo1.pdf"
|
190 |
+
mock_user_repo.return_value = email
|
191 |
+
response = client.post("/chatbot/download_files/", json={"user_id": user_id, "name_file": name_file})
|
192 |
+
assert response.json()['status'] == 200
|
193 |
+
assert response.json()['data']['message'] == f"Downloaded file '{name_file}' by email: '{email}' success"
|
194 |
+
|
195 |
+
@patch('function.support_function.check_email_service')
|
196 |
+
def test_download_file_id_not_exist(mock_user_repo):
|
197 |
+
user_id = "1"
|
198 |
+
email = "quangphuc@gmail.com"
|
199 |
+
name_file = "demo1.pdf"
|
200 |
+
mock_user_repo.return_value = res1.ReponseError(status=400, data=res.Message(
|
201 |
+
message="Id not exist"))
|
202 |
+
response = client.post("/chatbot/download_files/", json={"user_id": user_id, "name_file": name_file})
|
203 |
+
assert response.json()['status'] == 400
|
204 |
+
assert response.json()['data']['message'] == "Id not exist"
|
205 |
+
|
206 |
+
@patch('function.support_function.check_email_service')
|
207 |
+
def test_download_file_email_empty(mock_user_repo):
|
208 |
+
user_id = "1"
|
209 |
+
email = None
|
210 |
+
name_file = "demo1.pdf"
|
211 |
+
mock_user_repo.return_value = res1.ReponseError(status=400, data=res.Message(
|
212 |
+
message="Email is empty"))
|
213 |
+
response = client.post("/chatbot/download_files/", json={"user_id": user_id, "name_file": name_file})
|
214 |
+
assert response.json()['status'] == 400
|
215 |
+
assert response.json()['data']['message'] == "Email is empty"
|
216 |
+
|
217 |
+
@patch('function.support_function.check_email_service')
|
218 |
+
def test_download_file_email_invalid(mock_user_repo):
|
219 |
+
user_id = "1"
|
220 |
+
email = "quangphuc"
|
221 |
+
name_file = "demo1.pdf"
|
222 |
+
mock_user_repo.return_value = res1.ReponseError(status=400, data=res.Message(
|
223 |
+
message="Email invalid"))
|
224 |
+
response = client.post("/chatbot/download_files/", json={"user_id": user_id, "name_file": name_file})
|
225 |
+
assert response.json()['status'] == 400
|
226 |
+
assert response.json()['data']['message'] == "Email invalid"
|
227 |
+
|
228 |
+
@patch('function.support_function.check_email_service')
|
229 |
+
def test_download_file_name_file_empty(mock_user_repo):
|
230 |
+
user_id = "1"
|
231 |
+
email = "quangphuc@gmail.com"
|
232 |
+
name_file = ""
|
233 |
+
mock_user_repo.return_value = email
|
234 |
+
response = client.post("/chatbot/download_files/", json={"user_id": user_id, "name_file": name_file})
|
235 |
+
assert response.json()['status'] == 400
|
236 |
+
assert response.json()['data']['message'] == "name_file is empty"
|
237 |
+
|
238 |
+
@patch('function.support_function.check_email_service')
|
239 |
+
def test_upload_files_invalid_email(mock_user_repo):
|
240 |
+
user_id = "1"
|
241 |
+
mock_user_repo.return_value = res1.ReponseError(status=400, data=res.Message(
|
242 |
+
message="Email invalid"))
|
243 |
+
data = {
|
244 |
+
'user_id': user_id
|
245 |
+
}
|
246 |
+
response = client.post("/upload_files/", data=data, files=[])
|
247 |
+
assert response.json()['status'] == 400
|
248 |
+
assert response.json()['data']['message'] == "Email invalid"
|
249 |
+
|
250 |
+
@patch('function.support_function.check_email_service')
|
251 |
+
def test_upload_files_empty_email(mock_user_repo):
|
252 |
+
user_id = "1"
|
253 |
+
email = None
|
254 |
+
mock_user_repo.return_value = res1.ReponseError(status=400, data=res.Message(
|
255 |
+
message="Email is empty"))
|
256 |
+
data = {
|
257 |
+
'user_id': user_id
|
258 |
+
}
|
259 |
+
response = client.post("/upload_files/", data=data, files=[])
|
260 |
+
assert response.json()['status'] == 400
|
261 |
+
assert response.json()['data']['message'] == "Email is empty"
|
262 |
+
|
263 |
+
@patch('function.support_function.check_email_service')
|
264 |
+
def test_upload_files_id_not_exist(mock_user_repo):
|
265 |
+
user_id = "1"
|
266 |
+
email = 'mang1@gmail.com'
|
267 |
+
mock_user_repo.return_value = res1.ReponseError(status=400, data=res.Message(
|
268 |
+
message="Id not exist"))
|
269 |
+
data = {
|
270 |
+
'user_id': user_id
|
271 |
+
}
|
272 |
+
response = client.post("/upload_files/", data=data, files=[])
|
273 |
+
assert response.json()['status'] == 400
|
274 |
+
assert response.json()['data']['message'] == "Id not exist"
|
275 |
+
|
276 |
+
@patch('service.FileService.sf_dropbox.upload_file')
|
277 |
+
@patch('function.support_function.check_email_service')
|
278 |
+
@patch('service.FileService.allowed_file')
|
279 |
+
@patch('service.FileService.check_email')
|
280 |
+
@patch('service.FileService.os.makedirs')
|
281 |
+
@patch('builtins.open', new_callable=unittest.mock.mock_open)
|
282 |
+
def test_upload_files_success(mock_open, mock_makedirs, mock_check_email, mock_allowed_file, mock_get_email_user_by_id,
|
283 |
+
mock_upload_file):
|
284 |
+
user_id = "1"
|
285 |
+
email = 'mang1@gmail.com'
|
286 |
+
mock_get_email_user_by_id.return_value = email
|
287 |
+
mock_check_email.return_value = True
|
288 |
+
mock_allowed_file.return_value = True
|
289 |
+
|
290 |
+
file_content = b"Test file content"
|
291 |
+
file = UploadFile(filename='test.pdf', file=BytesIO(file_content))
|
292 |
+
|
293 |
+
with tempfile.TemporaryDirectory() as temp_dir:
|
294 |
+
temp_dir_path = os.path.join(temp_dir, email)
|
295 |
+
os.makedirs(temp_dir_path, exist_ok=True)
|
296 |
+
file_path = os.path.join(temp_dir_path, file.filename)
|
297 |
+
mock_open.return_value.write.side_effect = lambda content: None if content == file_content else None
|
298 |
+
mock_upload_file.side_effect = lambda src, dst: None
|
299 |
+
mock_makedirs.side_effect = lambda path, exist_ok: None
|
300 |
+
data = {
|
301 |
+
'user_id': user_id
|
302 |
+
}
|
303 |
+
files = {
|
304 |
+
'files': (file.filename, file.file, 'application/pdf')
|
305 |
+
}
|
306 |
+
response = client.post("/upload_files/", data=data, files=files)
|
307 |
+
assert response.status_code == 200
|
308 |
+
assert response.json()['status'] == 200
|
309 |
+
assert response.json()['data']['message'] == "Load file success"
|
310 |
+
# expected_src_path = os.path.join(temp_dir_path, file.filename).replace("\\", "/")
|
311 |
+
# expected_dst_path = f"/{email}/{file.filename}"
|
312 |
+
# actual_src_path, actual_dst_path = mock_upload_file.call_args[0]
|
313 |
+
# actual_src_path = actual_src_path.replace("\\", "/")
|
314 |
+
# assert expected_src_path == actual_src_path and expected_dst_path == actual_dst_path
|
315 |
+
@patch('service.FileService.sf_dropbox.upload_file')
|
316 |
+
@patch('function.support_function.check_email_service')
|
317 |
+
@patch('service.FileService.allowed_file')
|
318 |
+
@patch('service.FileService.check_email')
|
319 |
+
@patch('service.FileService.os.makedirs')
|
320 |
+
@patch('service.FileService.shutil.copyfileobj')
|
321 |
+
def test_upload_files_invalid_file_type(mock_copyfileobj, mock_makedirs, mock_check_email, mock_allowed_file,
|
322 |
+
mock_get_email_user_by_id, mock_upload_file):
|
323 |
+
user_id = "1"
|
324 |
+
email = 'mang1@gmail.com'
|
325 |
+
mock_get_email_user_by_id.return_value = email
|
326 |
+
mock_allowed_file.return_value = False
|
327 |
+
file_content = b"Test file content"
|
328 |
+
file = UploadFile(filename='test.exe', file=BytesIO(file_content))
|
329 |
+
data = {
|
330 |
+
'user_id': user_id
|
331 |
+
}
|
332 |
+
files = {
|
333 |
+
'files': (file.filename, file.file)
|
334 |
+
}
|
335 |
+
response = client.post("/upload_files/", data=data, files=files)
|
336 |
+
assert response.json()['status'] == 415
|
337 |
+
assert response.json()['data']['message'] == "File type not allow"
|
338 |
+
|
339 |
+
def test_delete__all_file_user_id_required():
|
340 |
+
user_id = None
|
341 |
+
response = client.request("DELETE", "/delete", json={"user_id": user_id})
|
342 |
+
assert response.json()['status'] == 400
|
343 |
+
assert response.json()['data']['message'] == "user_id field is required."
|
344 |
+
|
345 |
+
def test_delete_all_file_user_id_is_integer():
|
346 |
+
user_id = "aaaa"
|
347 |
+
response = client.request("DELETE", "/delete", json={"user_id": "aaaa"})
|
348 |
+
assert response.json()['status'] == 400
|
349 |
+
assert response.json()['data']['message'] == "user_id must be an integer"
|
350 |
+
|
351 |
+
def test_delete_all_file_user_id_is_greater_0():
|
352 |
+
response = client.request("DELETE", "/delete", json={"user_id": "0"})
|
353 |
+
assert response.json()['status'] == 400
|
354 |
+
assert response.json()['data']['message'] == "user_id must be greater than 0"
|
355 |
+
|
356 |
+
def test_list_name_files_user_id_required():
|
357 |
+
user_id = None
|
358 |
+
response = client.request("GET", "/list_name_files/", params ={"user_id": user_id})
|
359 |
+
assert response.json()['status'] == 400
|
360 |
+
assert response.json()['data']['message'] == "user_id field is required."
|
361 |
+
|
362 |
+
def test_list_name_files_user_id_is_integer():
|
363 |
+
user_id = "aaaa"
|
364 |
+
response = client.request("GET", "/list_name_files/", params={"user_id": user_id})
|
365 |
+
assert response.json()['status'] == 400
|
366 |
+
assert response.json()['data']['message'] == "user_id must be an integer"
|
367 |
+
|
368 |
+
def test_list_name_files_user_id_is_greater_0():
|
369 |
+
user_id = "-100"
|
370 |
+
response = client.request("GET", "/list_name_files/", params={"user_id": user_id})
|
371 |
+
assert response.json()['status'] == 400
|
372 |
+
assert response.json()['data']['message'] == "user_id must be greater than 0"
|
373 |
+
|
374 |
+
def test_delete_one_file_user_id_required():
|
375 |
+
user_id = None
|
376 |
+
name_file = "abcd"
|
377 |
+
response = client.request("DELETE", "/delete_file/", json ={"user_id": user_id,"name_file": name_file})
|
378 |
+
assert response.json()['status'] == 400
|
379 |
+
assert response.json()['data']['message'] == "user_id field is required."
|
380 |
+
|
381 |
+
def test_delete_one_file_user_id_is_integer():
|
382 |
+
user_id = "aaaa"
|
383 |
+
name_file = "abcd"
|
384 |
+
response = client.request("DELETE", "/delete_file/", json={"user_id": user_id, "name_file": name_file})
|
385 |
+
assert response.json()['status'] == 400
|
386 |
+
assert response.json()['data']['message'] == "user_id must be an integer"
|
387 |
+
|
388 |
+
def test_delete_one_file_user_id_is_greater_0():
|
389 |
+
user_id = 0
|
390 |
+
name_file = "abcd"
|
391 |
+
response = client.request("DELETE", "/delete_file/", json={"user_id": user_id, "name_file": name_file})
|
392 |
+
assert response.json()['status'] == 400
|
393 |
+
assert response.json()['data']['message'] == "user_id must be greater than 0"
|
394 |
+
|
395 |
+
def test_delete_one_file_name_file_required():
|
396 |
+
user_id = 1
|
397 |
+
name_file = None
|
398 |
+
response = client.request("DELETE", "/delete_file/", json ={"user_id": user_id,"name_file": name_file})
|
399 |
+
assert response.json()['status'] == 400
|
400 |
+
assert response.json()['data']['message'] == "Name file is required."
|
401 |
+
|
402 |
+
def test_download_folder_user_id_required():
|
403 |
+
user_id = None
|
404 |
+
response = client.request("POST", "/chatbot/download_folder/", json ={"user_id": user_id})
|
405 |
+
assert response.json()['status'] == 400
|
406 |
+
assert response.json()['data']['message'] == "user_id field is required."
|
407 |
+
|
408 |
+
def test_download_folder_user_id_is_integer():
|
409 |
+
user_id = "aaaa"
|
410 |
+
response = client.request("POST", "/chatbot/download_folder/", json={"user_id": user_id})
|
411 |
+
assert response.json()['status'] == 400
|
412 |
+
assert response.json()['data']['message'] == "user_id must be an integer"
|
413 |
+
|
414 |
+
def test_download_folder_user_id_is_greater_0():
|
415 |
+
user_id = "0"
|
416 |
+
response = client.request("POST", "/chatbot/download_folder/", json={"user_id": user_id})
|
417 |
+
assert response.json()['status'] == 400
|
418 |
+
assert response.json()['data']['message'] == "user_id must be greater than 0"
|
419 |
+
|
420 |
+
def test_download_file_user_id_required():
|
421 |
+
user_id = None
|
422 |
+
response = client.request("POST", "/chatbot/download_files/", json ={"user_id": user_id})
|
423 |
+
assert response.json()['status'] == 400
|
424 |
+
assert response.json()['data']['message'] == "user_id field is required."
|
425 |
+
|
426 |
+
def test_download_files_user_id_is_integer():
|
427 |
+
user_id = "aaaa"
|
428 |
+
response = client.request("POST", "/chatbot/download_files/", json={"user_id": user_id})
|
429 |
+
assert response.json()['status'] == 400
|
430 |
+
assert response.json()['data']['message'] == "user_id must be an integer"
|
431 |
+
|
432 |
+
def test_download_files_user_id_is_greater_0():
|
433 |
+
user_id = "0"
|
434 |
+
response = client.request("POST", "/chatbot/download_files/", json={"user_id": user_id})
|
435 |
+
assert response.json()['status'] == 400
|
436 |
+
assert response.json()['data']['message'] == "user_id must be greater than 0"
|
437 |
+
|
438 |
+
def test_upload_file_user_id_required():
|
439 |
+
user_id = None
|
440 |
+
file_content = b"Test file content"
|
441 |
+
file = UploadFile(filename='test.pdf', file=BytesIO(file_content))
|
442 |
+
data = {
|
443 |
+
'user_id': user_id
|
444 |
+
}
|
445 |
+
files = {
|
446 |
+
'files': (file.filename, file.file)
|
447 |
+
}
|
448 |
+
response = client.post("/upload_files/", data=data, files=files)
|
449 |
+
assert response.json()['status'] == 400
|
450 |
+
assert response.json()['data']['message'] == "user_id field is required."
|
451 |
+
|
452 |
+
def test_upload_files_user_id_is_integer():
|
453 |
+
user_id = "aaaa"
|
454 |
+
file_content = b"Test file content"
|
455 |
+
file = UploadFile(filename='test.pdf', file=BytesIO(file_content))
|
456 |
+
data = {
|
457 |
+
'user_id': user_id
|
458 |
+
}
|
459 |
+
files = {
|
460 |
+
'files': (file.filename, file.file)
|
461 |
+
}
|
462 |
+
response = client.post("/upload_files/", data=data, files=files)
|
463 |
+
assert response.json()['status'] == 400
|
464 |
+
assert response.json()['data']['message'] == "user_id must be an integer"
|
465 |
+
|
466 |
+
def test_upload_files_user_id_is_greater_0():
|
467 |
+
user_id = "0"
|
468 |
+
file_content = b"Test file content"
|
469 |
+
file = UploadFile(filename='test.pdf', file=BytesIO(file_content))
|
470 |
+
data = {
|
471 |
+
'user_id': user_id
|
472 |
+
}
|
473 |
+
files = {
|
474 |
+
'files': (file.filename, file.file)
|
475 |
+
}
|
476 |
+
response = client.post("/upload_files/", data=data, files=files)
|
477 |
+
assert response.json()['status'] == 400
|
478 |
+
assert response.json()['data']['message'] == "user_id must be greater than 0"
|
tests/test_controller/test_LoginController.py
ADDED
@@ -0,0 +1,650 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import sys
|
3 |
+
from unittest.mock import patch, Mock, MagicMock
|
4 |
+
from fastapi.testclient import TestClient
|
5 |
+
app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
6 |
+
sys.path.insert(0, app_path)
|
7 |
+
from controller import UserController
|
8 |
+
from response import ResponseDefault as res1
|
9 |
+
client = TestClient(UserController.router)
|
10 |
+
|
11 |
+
|
12 |
+
|
13 |
+
@patch('function.support_function.check_email_service')
|
14 |
+
@patch('function.support_function.check_email_empty_invalid', return_value = True)
|
15 |
+
@patch('service.UserService.check_email')
|
16 |
+
@patch('service.UserService.get_user1')
|
17 |
+
@patch('repository.UserInfoRepository.getUserInfo')
|
18 |
+
@patch('repository.UserInfoRepository.updateUserInfo')
|
19 |
+
@patch('repository.UserInfoRepository.addUserInfo')
|
20 |
+
@patch('service.UserService.update_info_user')
|
21 |
+
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):
|
22 |
+
mock_get_email_by_id.return_value = "old_email@example.com"
|
23 |
+
mock_get_user.return_value = Mock() # Simulate user exists
|
24 |
+
mock_get_user_info.return_value = Mock()
|
25 |
+
response = client.post("/update_user_info", json={"user_id":1,
|
26 |
+
"email": "new_email@example.com",
|
27 |
+
"uid":"uid123",
|
28 |
+
"display_name":"New Name",
|
29 |
+
"photo_url":"http://photo.url"})
|
30 |
+
assert response.json()['status'] == 200
|
31 |
+
assert response.json() == {
|
32 |
+
"status": 200,
|
33 |
+
"data": {
|
34 |
+
"message": "User info updated successfully",
|
35 |
+
}
|
36 |
+
|
37 |
+
}
|
38 |
+
from response import ResponseUser as res
|
39 |
+
@patch('function.support_function.check_email_service')
|
40 |
+
@patch('function.support_function.check_email_empty_invalid',return_value = True)
|
41 |
+
@patch('repository.UserRepository.getEmailUserByIdFix')
|
42 |
+
def test_update_user_info_id_not_exist(mock_get_email_by_id,mock_check1,mock_check2):
|
43 |
+
mock_check2.return_value = res1.ReponseError(status=400, data=res.Message(
|
44 |
+
message="Id not exist"))
|
45 |
+
response = client.post("/update_user_info", json={"user_id":1,
|
46 |
+
"email": "new_email@example.com",
|
47 |
+
"uid":"uid123",
|
48 |
+
"display_name":"New Name",
|
49 |
+
"photo_url":"http://photo.url"})
|
50 |
+
assert response.json()['status'] == 400
|
51 |
+
assert response.json() == {
|
52 |
+
"status": 400,
|
53 |
+
"data": {
|
54 |
+
"message": "Id not exist",
|
55 |
+
}
|
56 |
+
|
57 |
+
}
|
58 |
+
|
59 |
+
|
60 |
+
def test_update_user_info_email_empty():
|
61 |
+
response = client.post("/update_user_info", json={"user_id":1,
|
62 |
+
"email": None,
|
63 |
+
"uid":"uid123",
|
64 |
+
"display_name":"New Name",
|
65 |
+
"photo_url":"http://photo.url"})
|
66 |
+
assert response.json()['status'] == 400
|
67 |
+
assert response.json() == {
|
68 |
+
"status": 400,
|
69 |
+
"data": {
|
70 |
+
"message": "email field is required.",
|
71 |
+
}
|
72 |
+
}
|
73 |
+
|
74 |
+
|
75 |
+
@patch('function.support_function.check_email_service', return_value = "20133118@gmail.com")
|
76 |
+
@patch('service.UserService.sf.check_email_empty_invalid')
|
77 |
+
def test_update_user_info_email_invalid(mock_check,mock_service):
|
78 |
+
mock_check.return_value = res.ReponseError(status=400, data=res.Message(
|
79 |
+
message="Email invalid"))
|
80 |
+
response = client.post("/update_user_info", json={"user_id":1,
|
81 |
+
"email": "20133",
|
82 |
+
"uid":"uid123",
|
83 |
+
"display_name":"New Name",
|
84 |
+
"photo_url":"http://photo.url"})
|
85 |
+
assert response.json()['status'] == 400
|
86 |
+
assert response.json() == {
|
87 |
+
"status": 400,
|
88 |
+
"data": {
|
89 |
+
"message": "Email invalid",
|
90 |
+
}
|
91 |
+
}
|
92 |
+
|
93 |
+
@patch('function.support_function.check_email_service', return_value = "20133118@gmail.com")
|
94 |
+
@patch('service.UserService.sf.check_email_empty_invalid')
|
95 |
+
@patch('service.UserService.get_user1')
|
96 |
+
def test_update_user_info_email_or_password_error(mock_get_user, mock_check_email, mock_get_email_by_id):
|
97 |
+
mock_get_email_by_id.return_value = "old_email@example.com"
|
98 |
+
mock_check_email.return_value = True
|
99 |
+
mock_get_user.return_value = None
|
100 |
+
response = client.post("/update_user_info", json={"user_id":1,
|
101 |
+
"email": "nhuy@gmail.com",
|
102 |
+
"uid":"uid123",
|
103 |
+
"display_name":"New Name",
|
104 |
+
"photo_url":"http://photo.url"})
|
105 |
+
assert response.json()['status'] == 404
|
106 |
+
assert response.json() == {
|
107 |
+
"status": 404,
|
108 |
+
"data": {
|
109 |
+
"message": "Not found user",
|
110 |
+
}
|
111 |
+
}
|
112 |
+
@patch('function.support_function.check_email_service', return_value = "20133118@gmail.com")
|
113 |
+
@patch('service.UserService.check_email')
|
114 |
+
@patch('repository.UserInfoRepository.getUserInfo')
|
115 |
+
@patch('repository.UserRepository.getEmailUserByIdFix', return_value = "20133118@gmail.com")
|
116 |
+
def test_check_info_google_success(mock_check,mock_user_info_repo, mock_check_email,mock_user_repo_email):
|
117 |
+
mock_user_info_repo.return_value = Mock()
|
118 |
+
user_id = "1"
|
119 |
+
response = client.get("/check_info_google", params={"user_id": user_id})
|
120 |
+
assert response.json()['status'] == 200
|
121 |
+
assert response.json() == {
|
122 |
+
"status": 200,
|
123 |
+
"data": {
|
124 |
+
"check": True,
|
125 |
+
}
|
126 |
+
}
|
127 |
+
|
128 |
+
@patch('function.support_function.check_email_service', return_value = res.ReponseError(status=400, data=res.Message(
|
129 |
+
message="Id not exist")))
|
130 |
+
|
131 |
+
@patch('repository.UserRepository.getEmailUserByIdFix', return_value = "20133118@gmail.com")
|
132 |
+
def test_check_info_google_id_not_exist(mock_check1,mock_user_repo):
|
133 |
+
user_id = "1"
|
134 |
+
response = client.get("/check_info_google", params={"user_id": user_id})
|
135 |
+
assert response.json()['status'] == 400
|
136 |
+
assert response.json() == {
|
137 |
+
"status": 400,
|
138 |
+
"data": {
|
139 |
+
"message": "Id not exist",
|
140 |
+
}
|
141 |
+
}
|
142 |
+
|
143 |
+
|
144 |
+
@patch('function.support_function.check_email_service', return_value=res.ReponseError(status=400, data=res.Message(
|
145 |
+
message="Email is empty")))
|
146 |
+
|
147 |
+
@patch('repository.UserRepository.getEmailUserByIdFix', return_value = "20133118@gmail.com")
|
148 |
+
def test_check_info_google_email_empty(mock_check1,mock_user_repo_id):
|
149 |
+
user_id = "1"
|
150 |
+
response = client.get("/check_info_google", params={"user_id": user_id})
|
151 |
+
assert response.json()['status'] == 400
|
152 |
+
assert response.json() == {
|
153 |
+
"status": 400,
|
154 |
+
"data": {
|
155 |
+
"message": "Email is empty",
|
156 |
+
}
|
157 |
+
}
|
158 |
+
|
159 |
+
@patch('function.support_function.check_email_service', return_value = res.ReponseError(status=400, data=res.Message(
|
160 |
+
message="Email invalid")))
|
161 |
+
|
162 |
+
@patch('repository.UserRepository.getEmailUserByIdFix', return_value = "20133118@gmail.com")
|
163 |
+
def test_check_info_google_email_invalid(mock_check_1,mock_user_repo):
|
164 |
+
user_id = "1"
|
165 |
+
response = client.get("/check_info_google", params={"user_id": user_id})
|
166 |
+
assert response.json()['status'] == 400
|
167 |
+
assert response.json() == {
|
168 |
+
"status": 400,
|
169 |
+
"data": {
|
170 |
+
"message": "Email invalid",
|
171 |
+
}
|
172 |
+
}
|
173 |
+
|
174 |
+
|
175 |
+
@patch('service.UserService.sf.check_email_empty_invalid', return_value=True)
|
176 |
+
@patch('service.UserService.UserInfoRepository')
|
177 |
+
def test_check_info_google_by_email_success(mock_user_info_repo, mock_check_email):
|
178 |
+
email = "test@gmail.com"
|
179 |
+
mock_user_info_repo.getUserInfo.return_value = Mock()
|
180 |
+
response = client.get("/check_info_google_signup", params={"email": email})
|
181 |
+
assert response.json()['status'] == 200
|
182 |
+
assert response.json() == {
|
183 |
+
"status": 200,
|
184 |
+
"data": {
|
185 |
+
"check": True,
|
186 |
+
}
|
187 |
+
}
|
188 |
+
|
189 |
+
def test_check_info_google_signup_email_empty():
|
190 |
+
email = ""
|
191 |
+
response = client.get("/check_info_google_signup", params={"email": None})
|
192 |
+
assert response.json()['status'] == 400
|
193 |
+
assert response.json() == {
|
194 |
+
"status": 400,
|
195 |
+
"data": {
|
196 |
+
"message": "Email is required.",
|
197 |
+
}
|
198 |
+
}
|
199 |
+
|
200 |
+
def test_check_info_google_signup_email_invalid():
|
201 |
+
email ="quangphuc"
|
202 |
+
response = client.get("/check_info_google_signup", params={"email": email})
|
203 |
+
assert response.json()['status'] == 400
|
204 |
+
assert response.json() == {
|
205 |
+
"status": 400,
|
206 |
+
"data": {
|
207 |
+
"message": "Email invalid",
|
208 |
+
}
|
209 |
+
}
|
210 |
+
@patch('service.UserService.sf.check_email_service')
|
211 |
+
@patch('service.UserService.check_email')
|
212 |
+
@patch('service.UserService.get_user1')
|
213 |
+
@patch('repository.UserLoginRepository.getUserSessionIdByUserEmail')
|
214 |
+
def test_check_state_login_success(mock_user_login_repo,mock_get_user1,mock_check_email,mock_user_repo):
|
215 |
+
user_id = "1"
|
216 |
+
email ="test@gmail.com"
|
217 |
+
session_id = "session"
|
218 |
+
mock_user_repo.return_value = email
|
219 |
+
mock_check_email.return_value = True
|
220 |
+
mock_get_user1.return_value = Mock()
|
221 |
+
mock_user_login_repo.return_value = session_id
|
222 |
+
response = client.get("/check_state_login", params={"user_id": user_id,"session_id_now" :session_id})
|
223 |
+
assert response.json()['status'] == 200
|
224 |
+
assert response.json() == {
|
225 |
+
"status": 200,
|
226 |
+
"data": {
|
227 |
+
"check": True,
|
228 |
+
}
|
229 |
+
}
|
230 |
+
|
231 |
+
@patch('service.UserService.sf.check_email_service')
|
232 |
+
def test_check_state_login_id_not_exits(mock_user_repo):
|
233 |
+
user_id = "1"
|
234 |
+
email ="test@gmail.com"
|
235 |
+
session_id = "session"
|
236 |
+
mock_user_repo.return_value = res1.ReponseError(status=400, data=res.Message(
|
237 |
+
message="Id not exist"))
|
238 |
+
response = client.get("/check_state_login", params={"user_id": user_id,
|
239 |
+
"session_id_now" :session_id})
|
240 |
+
assert response.json()['status'] == 400
|
241 |
+
assert response.json() == {
|
242 |
+
"status": 400,
|
243 |
+
"data": {
|
244 |
+
"message": "Id not exist",
|
245 |
+
}
|
246 |
+
}
|
247 |
+
|
248 |
+
@patch('service.UserService.sf.check_email_service')
|
249 |
+
def test_check_state_login_email_empty(mock_user_repo):
|
250 |
+
user_id = "1"
|
251 |
+
email =None
|
252 |
+
session_id = "session"
|
253 |
+
mock_user_repo.return_value = res1.ReponseError(status=400, data=res.Message(
|
254 |
+
message="Email is empty"))
|
255 |
+
response = client.get("/check_state_login", params={"user_id": user_id,
|
256 |
+
"session_id_now" :session_id})
|
257 |
+
assert response.json()['status'] == 400
|
258 |
+
assert response.json() == {
|
259 |
+
"status": 400,
|
260 |
+
"data": {
|
261 |
+
"message": "Email is empty",
|
262 |
+
}
|
263 |
+
}
|
264 |
+
|
265 |
+
@patch('service.UserService.sf.check_email_service')
|
266 |
+
@patch('service.UserService.check_email')
|
267 |
+
def test_check_state_login_email_invalid(mock_check_email,mock_user_repo):
|
268 |
+
user_id = "1"
|
269 |
+
email = "20133118"
|
270 |
+
session_id = "session"
|
271 |
+
mock_user_repo.return_value = res1.ReponseError(status=400, data=res.Message(
|
272 |
+
message="Email invalid"))
|
273 |
+
response = client.get("/check_state_login", params={"user_id": user_id,
|
274 |
+
"session_id_now" :session_id})
|
275 |
+
assert response.json()['status'] == 400
|
276 |
+
assert response.json() == {
|
277 |
+
"status": 400,
|
278 |
+
"data": {
|
279 |
+
"message": "Email invalid",
|
280 |
+
}
|
281 |
+
}
|
282 |
+
|
283 |
+
@patch('service.UserService.sf.check_email_service')
|
284 |
+
@patch('service.UserService.check_email')
|
285 |
+
@patch('repository.UserLoginRepository.getUserSessionIdByUserEmail')
|
286 |
+
def test_check_state_session_empty(mock_user_login_repo,mock_check_email, mock_user_repo):
|
287 |
+
user_id = "1"
|
288 |
+
email = "20133@gmail.com"
|
289 |
+
session_id = None
|
290 |
+
|
291 |
+
mock_user_repo.return_value = email
|
292 |
+
mock_user_login_repo.return_value = "some_session_id"
|
293 |
+
|
294 |
+
response = client.get("/check_state_login", params={"user_id": user_id,
|
295 |
+
"session_id_now": session_id})
|
296 |
+
|
297 |
+
assert response.json()['status'] == 400
|
298 |
+
assert response.json() == {
|
299 |
+
"status": 400,
|
300 |
+
"data": {
|
301 |
+
"message": "Session Id is required.",
|
302 |
+
}
|
303 |
+
}
|
304 |
+
|
305 |
+
@patch('service.UserService.sf.check_email_service')
|
306 |
+
@patch('service.UserService.check_email')
|
307 |
+
@patch('service.UserService.get_user1')
|
308 |
+
@patch('repository.UserLoginRepository.getUserSessionIdByUserEmail')
|
309 |
+
def test_check_state_login_not_found(mock_user_login_repo,mock_get_user1,mock_check_email,mock_user_repo):
|
310 |
+
user_id = "1"
|
311 |
+
email ="test@gmail.com"
|
312 |
+
session_id = "session"
|
313 |
+
mock_user_repo.return_value = email
|
314 |
+
mock_check_email.return_value = True
|
315 |
+
mock_get_user1.return_value = None
|
316 |
+
mock_user_login_repo.return_value = session_id
|
317 |
+
response = client.get("/check_state_login", params={"user_id": user_id,
|
318 |
+
"session_id_now" : session_id})
|
319 |
+
assert response.json()['status'] == 404
|
320 |
+
assert response.json() == {
|
321 |
+
"status": 404,
|
322 |
+
"data": {
|
323 |
+
"message": "Not found user",
|
324 |
+
}
|
325 |
+
}
|
326 |
+
|
327 |
+
|
328 |
+
|
329 |
+
@patch('service.UserService.sf.check_email_service',return_value= "test@example.com")
|
330 |
+
@patch('service.UserService.sf.check_email_empty_invalid', return_value=True)
|
331 |
+
@patch('service.UserService.sign_in_with_email_and_password')
|
332 |
+
@patch('service.UserService.auth')
|
333 |
+
def test_change_password_success(mock_auth, mock_sign_in, mock_check_email, mock_get_email):
|
334 |
+
user_id='123'
|
335 |
+
new_password='new_password'
|
336 |
+
current_password='current_password'
|
337 |
+
confirm_new_password = 'new_password'
|
338 |
+
mock_sign_in.return_value = MagicMock()
|
339 |
+
mock_auth.get_user_by_email.return_value = MagicMock(uid='user_uid')
|
340 |
+
response = client.put("/change_password", json={"user_id": user_id,
|
341 |
+
"new_password" : new_password,
|
342 |
+
"current_password": current_password,
|
343 |
+
"confirm_new_password": confirm_new_password})
|
344 |
+
assert response.json()['status'] == 200
|
345 |
+
assert response.json()['data']['message'] == "Update password success"
|
346 |
+
|
347 |
+
@patch('service.UserService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
348 |
+
message="Id not exist")))
|
349 |
+
def test_change_password_id_not_exist(mock_get_email):
|
350 |
+
user_id='123'
|
351 |
+
new_password='new_password'
|
352 |
+
current_password='current_password'
|
353 |
+
confirm_new_password = 'new_password'
|
354 |
+
response = client.put("/change_password", json={"user_id": user_id,
|
355 |
+
"new_password": new_password,
|
356 |
+
"current_password": current_password,
|
357 |
+
"confirm_new_password": confirm_new_password})
|
358 |
+
assert response.json()['status'] == 400
|
359 |
+
assert response.json()['data']['message'] == "Id not exist"
|
360 |
+
|
361 |
+
@patch('service.UserService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
362 |
+
message="Email is empty")))
|
363 |
+
def test_change_password_email_is_empty(mock_get_email):
|
364 |
+
user_id='123'
|
365 |
+
new_password='new_password'
|
366 |
+
current_password='current_password'
|
367 |
+
confirm_new_password = 'new_password'
|
368 |
+
response = client.put("/change_password", json={"user_id": user_id,
|
369 |
+
"new_password": new_password,
|
370 |
+
"current_password": current_password,
|
371 |
+
"confirm_new_password": confirm_new_password})
|
372 |
+
assert response.json()['status'] == 400
|
373 |
+
assert response.json()['data']['message'] == "Email is empty"
|
374 |
+
|
375 |
+
@patch('service.UserService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
376 |
+
message="Email invalid")))
|
377 |
+
def test_change_password_email_invalid(mock_check_email):
|
378 |
+
user_id='123'
|
379 |
+
new_password='new_password'
|
380 |
+
current_password='current_password'
|
381 |
+
confirm_new_password = 'new_password'
|
382 |
+
response = client.put("/change_password", json={"user_id": user_id,
|
383 |
+
"new_password" : new_password,
|
384 |
+
"current_password": current_password,
|
385 |
+
"confirm_new_password": confirm_new_password})
|
386 |
+
assert response.json()['status'] == 400
|
387 |
+
assert response.json()['data']['message'] == "Email invalid"
|
388 |
+
|
389 |
+
@patch('service.UserService.sf.check_email_service')
|
390 |
+
def test_change_password_new_password_empty( mock_get_email):
|
391 |
+
user_id='123'
|
392 |
+
new_password= None
|
393 |
+
current_password='current_password'
|
394 |
+
mock_get_email.return_value = "20133@gmail.com"
|
395 |
+
confirm_new_password = 'new_password'
|
396 |
+
response = client.put("/change_password", json={"user_id": user_id,
|
397 |
+
"new_password": new_password,
|
398 |
+
"current_password": current_password,
|
399 |
+
"confirm_new_password": confirm_new_password})
|
400 |
+
assert response.json()['status'] == 400
|
401 |
+
assert response.json()['data']['message'] == "New password field is required."
|
402 |
+
|
403 |
+
@patch('service.UserService.sf.check_email_service')
|
404 |
+
def test_change_password_current_password_empty(mock_get_email):
|
405 |
+
user_id='123'
|
406 |
+
new_password= "new"
|
407 |
+
current_password= None
|
408 |
+
mock_get_email.return_value = "20133@gmail.com"
|
409 |
+
confirm_new_password = 'new_password'
|
410 |
+
response = client.put("/change_password", json={"user_id": user_id,
|
411 |
+
"new_password": new_password,
|
412 |
+
"current_password": current_password,
|
413 |
+
"confirm_new_password": confirm_new_password})
|
414 |
+
assert response.json()['status'] == 400
|
415 |
+
assert response.json()['data']['message'] == "Current password field is required."
|
416 |
+
|
417 |
+
@patch('service.UserService.check_email')
|
418 |
+
@patch('service.UserService.get_user1')
|
419 |
+
@patch('service.UserService.createOTPReset')
|
420 |
+
@patch('service.UserService.sf.check_email_empty_invalid', return_value=True)
|
421 |
+
def test_reset_password_success(mock_check,mock_createOTPReset, mock_get_user1, mock_check_email):
|
422 |
+
email = "user@example.com"
|
423 |
+
mock_get_user1.return_value = {"email": "user@example.com"}
|
424 |
+
mock_createOTPReset.return_value = "123456"
|
425 |
+
response = client.post("/reset_password", json={"email": email})
|
426 |
+
assert response.json()['status'] == 200
|
427 |
+
assert response.json()['data']['check'] == True
|
428 |
+
assert response.json()['otp'] == "123456"
|
429 |
+
|
430 |
+
def test_reset_password_invalid_email():
|
431 |
+
email = "invalid"
|
432 |
+
response = client.post("/reset_password", json={"email": email})
|
433 |
+
assert response.json()['status'] == 400
|
434 |
+
assert response.json()['data']['message'] == "Email invalid"
|
435 |
+
|
436 |
+
def test_reset_password_user_not_found():
|
437 |
+
email = "nonexistent@example.com"
|
438 |
+
response = client.post("/reset_password", json={"email": email})
|
439 |
+
assert response.json()['status'] == 404
|
440 |
+
assert response.json()['data']['message'] == "Email not exist"
|
441 |
+
|
442 |
+
def test_reset_password_email_is_None():
|
443 |
+
email = None
|
444 |
+
response = client.post("/reset_password", json={"email": email})
|
445 |
+
assert response.json()['status'] == 400
|
446 |
+
assert response.json()['data']['message'] == "Email is required."
|
447 |
+
|
448 |
+
|
449 |
+
|
450 |
+
def test_update_user_info_user_id_required():
|
451 |
+
email = None
|
452 |
+
response = client.post("/update_user_info", json={"user_id": None,
|
453 |
+
"email": "new_email@example.com",
|
454 |
+
"uid": "uid123",
|
455 |
+
"display_name": "New Name",
|
456 |
+
"photo_url": "http://photo.url"})
|
457 |
+
assert response.json()['status'] == 400
|
458 |
+
assert response.json()['data']['message'] == "user_id field is required."
|
459 |
+
|
460 |
+
def test_update_user_info_user_id_integer_required():
|
461 |
+
response = client.post("/update_user_info", json={"user_id": "aaaa",
|
462 |
+
"email": "new_email@example.com",
|
463 |
+
"uid": "uid123",
|
464 |
+
"display_name": "New Name",
|
465 |
+
"photo_url": "http://photo.url"})
|
466 |
+
assert response.json()['status'] == 400
|
467 |
+
assert response.json()['data']['message'] == "user_id must be an integer"
|
468 |
+
|
469 |
+
def test_update_user_info_user_id_greater_than_0():
|
470 |
+
response = client.post("/update_user_info", json={"user_id": 0,
|
471 |
+
"email": "new_email@example.com",
|
472 |
+
"uid": "uid123",
|
473 |
+
"display_name": "New Name",
|
474 |
+
"photo_url": "http://photo.url"})
|
475 |
+
assert response.json()['status'] == 400
|
476 |
+
assert response.json()['data']['message'] == "user_id must be greater than 0"
|
477 |
+
|
478 |
+
def test_update_user_info_uid_field_required():
|
479 |
+
response = client.post("/update_user_info", json={"user_id": 1,
|
480 |
+
"email": "new_email@example.com",
|
481 |
+
"uid": "",
|
482 |
+
"display_name": "New Name",
|
483 |
+
"photo_url": "http://photo.url"})
|
484 |
+
assert response.json()['status'] == 400
|
485 |
+
assert response.json()['data']['message'] == "uid field is required."
|
486 |
+
|
487 |
+
def test_update_user_info_email_field_required():
|
488 |
+
response = client.post("/update_user_info", json={"user_id": 1,
|
489 |
+
"email": None,
|
490 |
+
"uid": "aaaa",
|
491 |
+
"display_name": "New Name",
|
492 |
+
"photo_url": "http://photo.url"})
|
493 |
+
assert response.json()['status'] == 400
|
494 |
+
assert response.json()['data']['message'] == "email field is required."
|
495 |
+
|
496 |
+
def test_update_user_info_dis_play_name_field_required():
|
497 |
+
response = client.post("/update_user_info", json={"user_id": 1,
|
498 |
+
"email": "test@gmail.com",
|
499 |
+
"uid": "aaaa",
|
500 |
+
"display_name": "",
|
501 |
+
"photo_url": "http://photo.url"})
|
502 |
+
assert response.json()['status'] == 400
|
503 |
+
assert response.json()['data']['message'] == "display_name field is required."
|
504 |
+
|
505 |
+
def test_update_user_info_photo_url_field_required():
|
506 |
+
response = client.post("/update_user_info", json={"user_id": 1,
|
507 |
+
"email": "test@gmail.com",
|
508 |
+
"uid": "aaaa",
|
509 |
+
"display_name": "aaaa",
|
510 |
+
"photo_url": ""})
|
511 |
+
assert response.json()['status'] == 400
|
512 |
+
assert response.json()['data']['message'] == "photo_url field is required."
|
513 |
+
|
514 |
+
def test_check_info_google_user_id_required():
|
515 |
+
user_id = None
|
516 |
+
response = client.get("/check_info_google",params={"user_id": user_id})
|
517 |
+
assert response.json()['status'] == 400
|
518 |
+
assert response.json()['data']['message'] == "user_id field is required."
|
519 |
+
|
520 |
+
def test_check_info_google_user_id_must_integer():
|
521 |
+
user_id = "aaaa"
|
522 |
+
response = client.get("/check_info_google",params={"user_id": user_id})
|
523 |
+
assert response.json()['status'] == 400
|
524 |
+
assert response.json()['data']['message'] == "user_id must be an integer"
|
525 |
+
|
526 |
+
def test_check_info_google_user_id_must_integer_greater_than_0():
|
527 |
+
user_id = "0"
|
528 |
+
response = client.get("/check_info_google",params={"user_id": user_id})
|
529 |
+
assert response.json()['status'] == 400
|
530 |
+
assert response.json()['data']['message'] == "user_id must be greater than 0"
|
531 |
+
|
532 |
+
def test_check_info_google_sign_up_email_is_required():
|
533 |
+
email = None
|
534 |
+
response = client.get("/check_info_google_signup", params={"email": email})
|
535 |
+
assert response.json()['status'] == 400
|
536 |
+
assert response.json()['data']['message'] == "Email is required."
|
537 |
+
|
538 |
+
def test_check_info_google_sign_up_email_must_str():
|
539 |
+
email = "777"
|
540 |
+
response = client.get("/check_info_google_signup", params={"email": email})
|
541 |
+
assert response.json()['status'] == 400
|
542 |
+
assert response.json()['data']['message'] == "Email must be a string, not a number."
|
543 |
+
|
544 |
+
def test_check_state_login_user_id_required():
|
545 |
+
user_id = None
|
546 |
+
session_id_now = "abcde"
|
547 |
+
response = client.get("/check_state_login", params={"user_id": user_id,"session_id_now":session_id_now})
|
548 |
+
assert response.json()['status'] == 400
|
549 |
+
assert response.json()['data']['message'] == "user_id field is required."
|
550 |
+
|
551 |
+
def test_check_state_login_user_id_must_integer():
|
552 |
+
user_id = "aaaa"
|
553 |
+
session_id_now = "abcde"
|
554 |
+
response = client.get("/check_state_login", params={"user_id": user_id, "session_id_now": session_id_now})
|
555 |
+
assert response.json()['status'] == 400
|
556 |
+
assert response.json()['data']['message'] == "user_id must be an integer"
|
557 |
+
|
558 |
+
def test_check_state_login_user_id_must_integer_greater_than_0():
|
559 |
+
user_id = "0"
|
560 |
+
session_id_now = "abcde"
|
561 |
+
response = client.get("/check_state_login", params={"user_id": user_id, "session_id_now": session_id_now})
|
562 |
+
assert response.json()['status'] == 400
|
563 |
+
assert response.json()['data']['message'] == "user_id must be greater than 0"
|
564 |
+
|
565 |
+
def test_check_state_login_session_id_required():
|
566 |
+
user_id = 1
|
567 |
+
session_id_now = None
|
568 |
+
response = client.get("/check_state_login", params={"user_id": user_id,"session_id_now":session_id_now})
|
569 |
+
assert response.json()['status'] == 400
|
570 |
+
assert response.json()['data']['message'] == "Session Id is required."
|
571 |
+
|
572 |
+
def test_check_state_login_session_id_must_str():
|
573 |
+
user_id = 1
|
574 |
+
session_id_now = "134"
|
575 |
+
response = client.get("/check_state_login", params={"user_id": user_id, "session_id_now": session_id_now})
|
576 |
+
assert response.json()['status'] == 400
|
577 |
+
assert response.json()['data']['message'] == "Session Id must be a string, not a number."
|
578 |
+
|
579 |
+
|
580 |
+
def test_reset_email_required():
|
581 |
+
email = None
|
582 |
+
response = client.post("/reset_password", json={"email": email})
|
583 |
+
assert response.json()['status'] == 400
|
584 |
+
assert response.json()['data']['message'] == "Email is required."
|
585 |
+
|
586 |
+
def test_reset_email_must_str():
|
587 |
+
email = "20133"
|
588 |
+
response = client.post("/reset_password", json={"email": email })
|
589 |
+
assert response.json()['status'] == 400
|
590 |
+
assert response.json()['data']['message'] == "Email must be a string, not a number."
|
591 |
+
|
592 |
+
def test_change_password_user_id_required():
|
593 |
+
user_id = None
|
594 |
+
new_password = "ABC"
|
595 |
+
current_password = "abc"
|
596 |
+
response = client.put("/change_password", json={"user_id": user_id,
|
597 |
+
"new_password": new_password,
|
598 |
+
"current_password": current_password})
|
599 |
+
assert response.json()['status'] == 400
|
600 |
+
assert response.json()['data']['message'] == "user_id field is required."
|
601 |
+
|
602 |
+
def test_change_password_user_id_integer():
|
603 |
+
user_id = "aaa"
|
604 |
+
new_password = "ABC"
|
605 |
+
current_password = "abc"
|
606 |
+
response = client.put("/change_password", json={"user_id": user_id,
|
607 |
+
"new_password": new_password,
|
608 |
+
"current_password": current_password})
|
609 |
+
assert response.json()['status'] == 400
|
610 |
+
assert response.json()['data']['message'] == "user_id must be an integer"
|
611 |
+
|
612 |
+
def test_change_password_user_id_integer_greater_than_0():
|
613 |
+
user_id = "0"
|
614 |
+
new_password = "ABC"
|
615 |
+
current_password = "abc"
|
616 |
+
confirm_password = "abc"
|
617 |
+
response = client.put("/change_password", json={"user_id": user_id,
|
618 |
+
"new_password": new_password,
|
619 |
+
"current_password": current_password,
|
620 |
+
"confirm_new_password": confirm_password})
|
621 |
+
assert response.json()['status'] == 400
|
622 |
+
assert response.json()['data']['message'] == "user_id must be greater than 0"
|
623 |
+
|
624 |
+
def test_change_password_new_password_required():
|
625 |
+
user_id = "1"
|
626 |
+
new_password = None
|
627 |
+
current_password = "abc"
|
628 |
+
confirm_password = "abc"
|
629 |
+
response = client.put("/change_password", json={"user_id": user_id,
|
630 |
+
"new_password": new_password,
|
631 |
+
"current_password": current_password,
|
632 |
+
"confirm_new_password": confirm_password})
|
633 |
+
assert response.json()['status'] == 400
|
634 |
+
assert response.json()['data']['message'] == "New password field is required."
|
635 |
+
|
636 |
+
def test_change_password_current_password_required():
|
637 |
+
user_id = "1"
|
638 |
+
new_password = "abc"
|
639 |
+
current_password = None
|
640 |
+
confirm_password = "abc"
|
641 |
+
response = client.put("/change_password", json={"user_id": user_id,
|
642 |
+
"new_password": new_password,
|
643 |
+
"current_password": current_password,
|
644 |
+
"confirm_new_password": confirm_password})
|
645 |
+
assert response.json()['status'] == 400
|
646 |
+
assert response.json()['data']['message'] == "Current password field is required."
|
647 |
+
|
648 |
+
|
649 |
+
|
650 |
+
|
tests/test_controller/test_MySQLController.py
ADDED
@@ -0,0 +1,314 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import sys
|
3 |
+
from unittest.mock import patch
|
4 |
+
|
5 |
+
from fastapi.testclient import TestClient
|
6 |
+
|
7 |
+
app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
8 |
+
sys.path.insert(0, app_path)
|
9 |
+
from controller import MySQLController
|
10 |
+
from models import Database_Entity
|
11 |
+
from response import ResponseMySQL as res
|
12 |
+
client = TestClient(MySQLController.router)
|
13 |
+
|
14 |
+
def test_render_chat_history():
|
15 |
+
with patch('repository.UserRepository.getEmailUserByIdFix') as mock_get_email_user_by_id:
|
16 |
+
mock_get_email_user_by_id.return_value = ("example@example.com",)
|
17 |
+
with patch('repository.ChatHistoryRepository.getChatHistoryById') as mock_get_chat_history_by_id:
|
18 |
+
mock_get_chat_history_by_id.return_value = [Database_Entity.ChatHistory(id = 1,
|
19 |
+
email = "example@example.com",
|
20 |
+
name_chat = "chat1") ]
|
21 |
+
response = client.get("/chat_history/1")
|
22 |
+
assert response.status_code == 200
|
23 |
+
assert response.json() == {
|
24 |
+
"status": 200,
|
25 |
+
"data": {
|
26 |
+
"chat": [
|
27 |
+
{
|
28 |
+
"id": 1,
|
29 |
+
"email": "example@example.com",
|
30 |
+
"chat_name": "chat1"
|
31 |
+
}
|
32 |
+
]
|
33 |
+
}
|
34 |
+
}
|
35 |
+
@patch('repository.ChatHistoryRepository.getChatHistoryByChatIdAndUserId', return_value = True)
|
36 |
+
@patch('repository.UserRepository.getEmailUserByIdFix', return_value = "20133118@gmail.com")
|
37 |
+
@patch('function.support_function.check_email_service', return_value = "20133118@gmail.com")
|
38 |
+
def test_load_chat_history(mock3,mokc1,mock_check_exist):
|
39 |
+
with patch('repository.DetailChatRepository.getListDetailChatByChatId') as mock_get_list_detail_chat_by_chat_id:
|
40 |
+
mock_get_list_detail_chat_by_chat_id.return_value = [Database_Entity.DetailChat(id=1, chat_id=1,
|
41 |
+
YouMessage="question1",
|
42 |
+
AiMessage="AImessage1",
|
43 |
+
data_relevant="abcd",
|
44 |
+
source_file="/demo1.pdf")]
|
45 |
+
response = client.get("/detail_chat/1/1")
|
46 |
+
assert response.status_code == 200
|
47 |
+
assert response.json() == {
|
48 |
+
"status": 200,
|
49 |
+
"data": {
|
50 |
+
"detail_chat": [
|
51 |
+
{
|
52 |
+
"id": 1,
|
53 |
+
"chat_id": 1,
|
54 |
+
"question": "question1",
|
55 |
+
"answer": "AImessage1",
|
56 |
+
'data_relevant': 'abcd',
|
57 |
+
'source_file': '/demo1.pdf'
|
58 |
+
}
|
59 |
+
]
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
def test_load_chat_history_user_id_must_be_integer():
|
64 |
+
response = client.get("/detail_chat/aaaa/1")
|
65 |
+
assert response.json()['status'] == 400
|
66 |
+
assert response.json() == {
|
67 |
+
"status": 400,
|
68 |
+
"data": {
|
69 |
+
"message": "user_id must be an integer"
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
def test_load_chat_history_user_id_greater_than0():
|
74 |
+
response = client.get("/detail_chat/0/1")
|
75 |
+
assert response.json()['status'] == 400
|
76 |
+
assert response.json() == {
|
77 |
+
"status": 400,
|
78 |
+
"data": {
|
79 |
+
"message": "user_id must be greater than 0"
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
+
def test_edit_chat_success():
|
84 |
+
with patch('service.MySQLService.edit_chat') as mock_edit_chat:
|
85 |
+
mock_edit_chat.return_value = res.ResponseEditChat(status=200, data=res.Message(message="Edit chat success"))
|
86 |
+
response = client.put("/edit_chat/", json={"user_id": 1, "name_old": "old_name", "name_new": "new_name"})
|
87 |
+
assert response.status_code == 200
|
88 |
+
assert response.json() == {
|
89 |
+
"status": 200,
|
90 |
+
"data": {
|
91 |
+
"message": "Edit chat success"
|
92 |
+
}
|
93 |
+
}
|
94 |
+
|
95 |
+
@patch('service.MySQLService.edit_chat')
|
96 |
+
def test_edit_chat_invalid_id(mock_edit_chat):
|
97 |
+
with patch('repository.UserRepository.getEmailUserByIdFix') as mock_get_email_user_by_id:
|
98 |
+
mock_get_email_user_by_id.return_value = None
|
99 |
+
mock_edit_chat.return_value = res.ReponseError(status= 400, data=res.Message(message="Id not exist"))
|
100 |
+
response = client.put("/edit_chat/", json={"user_id": 1, "name_old": "old_name", "name_new": "new_name"})
|
101 |
+
assert response.json()['status'] == 400
|
102 |
+
assert response.json() == {
|
103 |
+
"status": 400,
|
104 |
+
"data": {
|
105 |
+
"message": "Id not exist"
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
+
@patch('repository.UserRepository.getEmailUserByIdFix')
|
110 |
+
@patch('service.MySQLService.edit_chat')
|
111 |
+
def test_edit_chat_email_empty(mock_edit_chat,mock_get_email_user_by_id):
|
112 |
+
email = ""
|
113 |
+
mock_get_email_user_by_id.return_value = (email,)
|
114 |
+
mock_edit_chat.return_value = res.ReponseError(status= 400, data=res.Message(message="Email is empty"))
|
115 |
+
response = client.put("/edit_chat/", json={"user_id": 1, "name_old": "old_name", "name_new": "new_name"})
|
116 |
+
assert response.json()['status'] == 400
|
117 |
+
assert response.json() == {
|
118 |
+
"status": 400,
|
119 |
+
"data": {
|
120 |
+
"message": "Email is empty"
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
@patch('repository.UserRepository.getEmailUserByIdFix')
|
125 |
+
@patch('service.MySQLService.edit_chat')
|
126 |
+
def test_edit_chat_email_invalid(mock_edit_chat,mock_get_email_user_by_id):
|
127 |
+
email = "20133118"
|
128 |
+
mock_get_email_user_by_id.return_value = (email,)
|
129 |
+
mock_edit_chat.return_value = res.ReponseError(status= 400, data=res.Message(message="Email invalid"))
|
130 |
+
response = client.put("/edit_chat/", json={"user_id": 1, "name_old": "old_name", "name_new": "new_name"})
|
131 |
+
assert response.json()['status'] == 400
|
132 |
+
assert response.json() == {
|
133 |
+
"status": 400,
|
134 |
+
"data": {
|
135 |
+
"message": "Email invalid"
|
136 |
+
}
|
137 |
+
}
|
138 |
+
|
139 |
+
@patch('repository.UserRepository.getEmailUserByIdFix')
|
140 |
+
@patch('service.MySQLService.edit_chat')
|
141 |
+
def test_edit_chat_name_old(mock_edit_chat,mock_get_email_user_by_id):
|
142 |
+
email = "20133118@gmail.com"
|
143 |
+
mock_get_email_user_by_id.return_value = (email,)
|
144 |
+
mock_edit_chat.return_value = res.ReponseError(status= 400, data=res.Message(message="Name old is empty"))
|
145 |
+
response = client.put("/edit_chat/", json={"user_id": 1, "name_old": "", "name_new": "new_name"})
|
146 |
+
assert response.json()['status'] == 400
|
147 |
+
assert response.json() == {
|
148 |
+
"status": 400,
|
149 |
+
"data": {
|
150 |
+
"message": "Name old is empty"
|
151 |
+
}
|
152 |
+
}
|
153 |
+
|
154 |
+
@patch('repository.UserRepository.getEmailUserByIdFix')
|
155 |
+
@patch('service.MySQLService.edit_chat')
|
156 |
+
def test_edit_chat_name_new(mock_edit_chat,mock_get_email_user_by_id):
|
157 |
+
email = "20133118@gmail.com"
|
158 |
+
mock_get_email_user_by_id.return_value = (email,)
|
159 |
+
mock_edit_chat.return_value = res.ReponseError(status= 400, data=res.Message(message="Name new is empty"))
|
160 |
+
response = client.put("/edit_chat", json={"user_id": 1, "name_old": "123", "name_new": ""})
|
161 |
+
assert response.json()['status'] == 400
|
162 |
+
assert response.json() == {
|
163 |
+
"status": 400,
|
164 |
+
"data": {
|
165 |
+
"message": "Name new is empty"
|
166 |
+
}
|
167 |
+
}
|
168 |
+
|
169 |
+
@patch('repository.ChatHistoryRepository.getIdChatHistoryByUserIdAndNameChat')
|
170 |
+
@patch('repository.UserRepository.getEmailUserByIdFix')
|
171 |
+
@patch('service.MySQLService.edit_chat')
|
172 |
+
def test_edit_chat1_error(mock_edit_chat,mock_get_email_user_by_id,mock_get_chat_id):
|
173 |
+
email = "20133118@gmail.com"
|
174 |
+
mock_get_email_user_by_id.return_value = (email,)
|
175 |
+
mock_get_chat_id.return_value = False
|
176 |
+
mock_edit_chat.return_value = res.ReponseError(status=500,data= res.Message(message="Update chat name error"))
|
177 |
+
response = client.put("/edit_chat/", json={"user_id": 1, "name_old": "123", "name_new": "1234"})
|
178 |
+
assert response.json()['status'] == 500
|
179 |
+
assert response.json() == {
|
180 |
+
"status": 500,
|
181 |
+
"data": {
|
182 |
+
"message": "Update chat name error"
|
183 |
+
}
|
184 |
+
}
|
185 |
+
|
186 |
+
def test_delete_chat_success():
|
187 |
+
with patch('service.MySQLService.delete_chat') as mock_delete_chat:
|
188 |
+
mock_delete_chat.return_value = res.ResponseDeleteChat(status=200, data=res.Message(message="Delete chat success"))
|
189 |
+
response = client.request("DELETE", "/chat_history/delete", json={"user_id": 1, "chat_name": "chat_name"})
|
190 |
+
assert response.status_code == 200
|
191 |
+
assert response.json() == {
|
192 |
+
"status": 200,
|
193 |
+
"data": {
|
194 |
+
"message": "Delete chat success"
|
195 |
+
}
|
196 |
+
}
|
197 |
+
|
198 |
+
@patch('service.MySQLService.delete_chat')
|
199 |
+
def test_delete_chat_id_not_exits(mock_delete_chat):
|
200 |
+
with patch('repository.UserRepository.getEmailUserByIdFix') as mock_get_email_user_by_id:
|
201 |
+
mock_get_email_user_by_id.return_value = None
|
202 |
+
mock_delete_chat.return_value = res.ReponseError(status= 400, data=res.Message(message="Id not exist"))
|
203 |
+
response = client.request("DELETE", "/chat_history/delete", json={"user_id": 1, "chat_name": "chat_name"})
|
204 |
+
assert response.json()['status']== 400
|
205 |
+
assert response.json() == {
|
206 |
+
"status": 400,
|
207 |
+
"data": {
|
208 |
+
"message": "Id not exist"
|
209 |
+
}
|
210 |
+
}
|
211 |
+
|
212 |
+
@patch('repository.UserRepository.getEmailUserByIdFix')
|
213 |
+
@patch('service.MySQLService.delete_chat')
|
214 |
+
def test_delete_chat_email_empty(mock_delete_chat,mock_get_email_user_by_id):
|
215 |
+
email = ""
|
216 |
+
mock_get_email_user_by_id.return_value = (email,)
|
217 |
+
mock_delete_chat.return_value = res.ResponseDeleteChat(status=400, data=res.Message(message="Email is empty"))
|
218 |
+
response = client.request("DELETE", "/chat_history/delete", json={"user_id": 1, "chat_name": "chat_name"})
|
219 |
+
assert response.json()['status'] == 400
|
220 |
+
assert response.json() == {
|
221 |
+
"status": 400,
|
222 |
+
"data": {
|
223 |
+
"message": "Email is empty"
|
224 |
+
}
|
225 |
+
}
|
226 |
+
|
227 |
+
@patch('repository.UserRepository.getEmailUserByIdFix')
|
228 |
+
@patch('service.MySQLService.delete_chat')
|
229 |
+
def test_delete_chat_email_invalid(mock_delete_chat,mock_get_email_user_by_id):
|
230 |
+
email = "20133118"
|
231 |
+
mock_get_email_user_by_id.return_value = (email,)
|
232 |
+
mock_delete_chat.return_value = res.ReponseError(status= 400, data=res.Message(message="Email invalid"))
|
233 |
+
response = client.request("DELETE", "/chat_history/delete", json={"user_id": 1, "chat_name": "chat_name"})
|
234 |
+
assert response.json()['status'] == 400
|
235 |
+
assert response.json() == {
|
236 |
+
"status": 400,
|
237 |
+
"data": {
|
238 |
+
"message": "Email invalid"
|
239 |
+
}
|
240 |
+
}
|
241 |
+
|
242 |
+
@patch('repository.UserRepository.getEmailUserByIdFix')
|
243 |
+
@patch('service.MySQLService.delete_chat')
|
244 |
+
def test_delete_chat_name_empty(mock_delete_chat,mock_get_email_user_by_id):
|
245 |
+
email = "20133118@gmail.com"
|
246 |
+
mock_get_email_user_by_id.return_value = (email,)
|
247 |
+
mock_delete_chat.return_value = res.ReponseError(status= 400, data=res.Message(message="Chat name is empty"))
|
248 |
+
response = client.request("DELETE", "/chat_history/delete", json={"user_id": 1, "chat_name": ""})
|
249 |
+
assert response.json()['status'] == 400
|
250 |
+
assert response.json() == {
|
251 |
+
"status": 400,
|
252 |
+
"data": {
|
253 |
+
"message": "Chat name is empty"
|
254 |
+
}
|
255 |
+
}
|
256 |
+
|
257 |
+
@patch('repository.UserRepository.getEmailUserByIdFix')
|
258 |
+
@patch('repository.ChatHistoryRepository.deleteChatHistory')
|
259 |
+
@patch('service.MySQLService.delete_chat')
|
260 |
+
def test_delete_chat_name_error_500(mock_delete_chat,mock_chat_history_repo,mock_get_email_user_by_id):
|
261 |
+
email = "20133118@gmail.com"
|
262 |
+
mock_get_email_user_by_id.return_value = (email,)
|
263 |
+
mock_chat_history_repo.return_value = False
|
264 |
+
mock_delete_chat.return_value = res.ResponseDeleteChat(status=500, data=res.Message(message="Delete chat error"))
|
265 |
+
response = client.request("DELETE", "/chat_history/delete", json={"user_id": 1, "chat_name": "1234"})
|
266 |
+
assert response.json()['status'] == 500
|
267 |
+
assert response.json() == {
|
268 |
+
"status": 500,
|
269 |
+
"data": {
|
270 |
+
"message": "Delete chat error"
|
271 |
+
}
|
272 |
+
}
|
273 |
+
|
274 |
+
def test_render_chat_value_mustbe_interger():
|
275 |
+
user_id = "aaaa"
|
276 |
+
response = client.get(f"/chat_history/{user_id}")
|
277 |
+
assert response.json()['status'] == 400
|
278 |
+
assert response.json()['data']['message'] == "user_id must be an integer"
|
279 |
+
|
280 |
+
def test_render_chat_user_id_greater_than_inter():
|
281 |
+
user_id = "0"
|
282 |
+
response = client.get(f"/chat_history/{user_id}")
|
283 |
+
assert response.json()['status'] == 400
|
284 |
+
assert response.json()['data']['message'] == "user_id must be greater than 0"
|
285 |
+
|
286 |
+
|
287 |
+
def test_load_chat_history_chat_id_greater_than_inter():
|
288 |
+
chat_id = "0"
|
289 |
+
user_id = 1
|
290 |
+
response = client.get(f"/detail_chat/{user_id}/{chat_id}")
|
291 |
+
assert response.json()['status'] == 400
|
292 |
+
assert response.json()['data']['message'] == "Value must be greater than 0"
|
293 |
+
|
294 |
+
def test_load_chat_history_value_mustbe_inter():
|
295 |
+
chat_id = "aaaa"
|
296 |
+
user_id = 1
|
297 |
+
response = client.get(f"/detail_chat/{user_id}/{chat_id}")
|
298 |
+
assert response.json()['status'] == 400
|
299 |
+
assert response.json()['data']['message'] == "Value must be an integer"
|
300 |
+
|
301 |
+
|
302 |
+
def test_load_chat_history_user_id_greater_than_inter():
|
303 |
+
chat_id = "1"
|
304 |
+
user_id = 0
|
305 |
+
response = client.get(f"/detail_chat/{user_id}/{chat_id}")
|
306 |
+
assert response.json()['status'] == 400
|
307 |
+
assert response.json()['data']['message'] == "user_id must be greater than 0"
|
308 |
+
|
309 |
+
def test_load_chat_history_user_id_mustbe_inter():
|
310 |
+
chat_id = "1"
|
311 |
+
user_id = "aaaaa"
|
312 |
+
response = client.get(f"/detail_chat/{user_id}/{chat_id}")
|
313 |
+
assert response.json()['status'] == 400
|
314 |
+
assert response.json()['data']['message'] == "user_id must be an integer"
|
tests/test_controller/test_OTPController.py
ADDED
@@ -0,0 +1,292 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import sys
|
3 |
+
from unittest.mock import patch, MagicMock
|
4 |
+
|
5 |
+
from fastapi.testclient import TestClient
|
6 |
+
|
7 |
+
app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
8 |
+
sys.path.insert(0, app_path)
|
9 |
+
from controller import OTPController
|
10 |
+
client = TestClient(OTPController.router)
|
11 |
+
|
12 |
+
@patch('service.OTPService.check_email')
|
13 |
+
@patch('service.OTPService.get_user1')
|
14 |
+
@patch('repository.OTPRepository.addOTP')
|
15 |
+
@patch('service.OTPService.generate_otp')
|
16 |
+
@patch('service.OTPService.sf')
|
17 |
+
def test_createOTPReset_success(mock_support_function, mock_generate_otp,mock_addOTP, mock_get_user1, mock_check_email):
|
18 |
+
mock_get_user1.return_value = MagicMock()
|
19 |
+
email = "user@example.com"
|
20 |
+
mock_support_function.check_email_empty_invalid.return_value = True
|
21 |
+
mock_generate_otp.return_value = "123456"
|
22 |
+
response = client.post("/create_otp", json={"email": email})
|
23 |
+
assert response.json()['status'] == 200
|
24 |
+
assert response.json()['data']['check'] == True
|
25 |
+
assert response.json()['otp'] == "123456"
|
26 |
+
|
27 |
+
|
28 |
+
def test_createOTPReset_email_empty():
|
29 |
+
email = ""
|
30 |
+
response = client.post("/create_otp", json={"email": email})
|
31 |
+
assert response.json()['status'] == 400
|
32 |
+
assert response.json()['data']['message'] == "Email is required."
|
33 |
+
|
34 |
+
|
35 |
+
def test_createOTPReset_email_invalid():
|
36 |
+
email = "201333"
|
37 |
+
response =client.post("/create_otp", json={"email": email})
|
38 |
+
assert response.json()['status'] == 400
|
39 |
+
assert response.json()['data']['message'] == "Email must be a string, not a number."
|
40 |
+
|
41 |
+
@patch('service.OTPService.generate_otp')
|
42 |
+
@patch('service.OTPService.check_email')
|
43 |
+
@patch('repository.OTPRepository.addOTP')
|
44 |
+
@patch('service.OTPService.sf')
|
45 |
+
def test_createOTP_success(mock_support_function,mock_addOTP, mock_check_email, mock_generate_otp):
|
46 |
+
mock_generate_otp.return_value = "123AB6"
|
47 |
+
email = "20133118@gmail.com"
|
48 |
+
otp = "123AB6"
|
49 |
+
mock_support_function.check_email_empty_invalid.return_value = True
|
50 |
+
mock_addOTP(email,otp)
|
51 |
+
response =client.post("/create_otp", json={"email": email})
|
52 |
+
assert response.json()['status'] == 200
|
53 |
+
assert response.json()['data']['check'] == True
|
54 |
+
assert response.json()['otp'] == "123AB6"
|
55 |
+
|
56 |
+
def test_createOTP_failed_empty_email():
|
57 |
+
email = ""
|
58 |
+
response =client.post("/create_otp", json={"email": email})
|
59 |
+
assert response.json()['status'] == 400
|
60 |
+
assert response.json()['data']['message'] == "Email is required."
|
61 |
+
|
62 |
+
|
63 |
+
def test_createOTP_failed_empty_invalid():
|
64 |
+
email = "20133"
|
65 |
+
response =client.post("/create_otp", json={"email": email})
|
66 |
+
assert response.json()['status'] == 400
|
67 |
+
assert response.json()['data']['message'] == "Email must be a string, not a number."
|
68 |
+
from datetime import datetime,timedelta
|
69 |
+
@patch('service.OTPService.sf.check_email_empty_invalid', return_value=True)
|
70 |
+
@patch('repository.OTPRepository.getOtpByEmail')
|
71 |
+
@patch('repository.OTPRepository.deleteOTP')
|
72 |
+
def test_verifyOTP_success(mock_deleteOTP, mock_getOtpByEmail, mock_check_email):
|
73 |
+
current_time = datetime.now()
|
74 |
+
mock_getOtpByEmail.return_value = MagicMock(otp="abcdef", created_at=current_time - timedelta(minutes=5))
|
75 |
+
email = "user@example.com"
|
76 |
+
otp = "abcdef"
|
77 |
+
response = client.post("/verify_otp", json={"email": email,"otp": otp})
|
78 |
+
mock_deleteOTP(email,otp)
|
79 |
+
assert response.json()['status'] == 200
|
80 |
+
assert response.json()['data']['message'] == "OTP is valid"
|
81 |
+
|
82 |
+
@patch('service.OTPService.sf.check_email_empty_invalid', return_value=True)
|
83 |
+
@patch('repository.OTPRepository.getOtpByEmail')
|
84 |
+
def test_verifyOTP_failed_invalid_otp(mock_getOtpByEmail, mock_check_email):
|
85 |
+
current_time = datetime.now()
|
86 |
+
mock_getOtpByEmail.return_value = MagicMock(otp="654321", created_at=current_time - timedelta(minutes=5))
|
87 |
+
email = "user@example.com"
|
88 |
+
otp = "123456"
|
89 |
+
response =client.post("/verify_otp", json={"email": email,"otp": otp})
|
90 |
+
assert response.json()['status'] == 400
|
91 |
+
assert response.json()['data']['message'] == "OTP must be a string, not a number."
|
92 |
+
|
93 |
+
def test_verifyOTP_failed_invalid_email():
|
94 |
+
email = "invalidemail"
|
95 |
+
otp = "123456"
|
96 |
+
response =client.post("/verify_otp", json={"email": email,"otp": otp})
|
97 |
+
assert response.json()['status'] == 400
|
98 |
+
assert response.json()['data']['message'] == "OTP must be a string, not a number."
|
99 |
+
|
100 |
+
def test_verifyOTP_failed_empty_email():
|
101 |
+
email = None
|
102 |
+
otp = "123456"
|
103 |
+
response =client.post("/verify_otp", json={"email": email,"otp": otp})
|
104 |
+
assert response.json()['status'] == 400
|
105 |
+
assert response.json()['data']['message'] == "Email is required."
|
106 |
+
|
107 |
+
|
108 |
+
def test_verifyOTP_failed_empty_otp():
|
109 |
+
email = "user@example.com"
|
110 |
+
otp = None
|
111 |
+
response = client.post("/verify_otp", json={"email": email,"otp": otp})
|
112 |
+
assert response.json()['status'] == 400
|
113 |
+
assert response.json()['data']['message'] == "OTP is required"
|
114 |
+
|
115 |
+
@patch('service.OTPService.sf.check_email_empty_invalid', return_value=True)
|
116 |
+
@patch('repository.OTPRepository.getOtpByEmail')
|
117 |
+
def test_verifyOTP_failed_no_otp_found(mock_getOtpByEmail, mock_check_email):
|
118 |
+
mock_getOtpByEmail.return_value = None
|
119 |
+
email = "user@example.com"
|
120 |
+
otp = "1234ab"
|
121 |
+
response =client.post("/verify_otp", json={"email": email,"otp": otp})
|
122 |
+
assert response.json()['status'] == 404
|
123 |
+
assert response.json()['data']['message'] == "No OTP found for this email"
|
124 |
+
|
125 |
+
@patch('service.OTPService.sf.check_email_empty_invalid', return_value=True)
|
126 |
+
@patch('repository.OTPRepository.getOtpByEmail')
|
127 |
+
def test_verifyOTP_has_expired( mock_getOtpByEmail, mock_check_email):
|
128 |
+
current_time = datetime.now()
|
129 |
+
mock_getOtpByEmail.return_value = MagicMock(otp="1234ab", created_at=current_time - timedelta(minutes=100))
|
130 |
+
email = "user@example.com"
|
131 |
+
otp = "1234ab"
|
132 |
+
response =client.post("/verify_otp", json={"email": email,"otp": otp})
|
133 |
+
assert response.json()['status'] == 400
|
134 |
+
assert response.json()['data']['message'] == "OTP has expired"
|
135 |
+
|
136 |
+
@patch('service.OTPService.sf.check_email_empty_invalid', return_value=True)
|
137 |
+
@patch('repository.OTPRepository.getOtpByEmail')
|
138 |
+
@patch('repository.OTPRepository.deleteOTP')
|
139 |
+
@patch('service.OTPService.auth.get_user_by_email')
|
140 |
+
@patch('service.OTPService.auth')
|
141 |
+
@patch('service.OTPService.generate_random_password')
|
142 |
+
def test_verifyOTPReset1_success( mock_generate_password,mock_update_user, mock_get_user_by_email, mock_deleteOTP, mock_getOtpByEmail, mock_check_email):
|
143 |
+
current_time = datetime.now()
|
144 |
+
mock_getOtpByEmail.return_value = MagicMock(otp="abcd12", created_at=current_time - timedelta(minutes=5))
|
145 |
+
mock_get_user_by_email.return_value = MagicMock(uid="12345")
|
146 |
+
email = "user@example.com"
|
147 |
+
otp = "abcd12"
|
148 |
+
mock_generate_password.return_value = "ABC123"
|
149 |
+
mock_update_user.update_user(uid="12345",)
|
150 |
+
mock_deleteOTP("user@example.com", "abcd12")
|
151 |
+
response = client.post("/verify_otp_reset_password", json={"email": email,"otp": otp})
|
152 |
+
assert response.json()['status'] == 200
|
153 |
+
assert response.json()['data']['message'] == "New Password send to Email"
|
154 |
+
assert response.json()['newpassword'] == "ABC123"
|
155 |
+
|
156 |
+
@patch('service.OTPService.sf.check_email_empty_invalid', return_value=True)
|
157 |
+
@patch('repository.OTPRepository.getOtpByEmail')
|
158 |
+
def test_verifyOTPReset_failed_invalid_otp(mock_getOtpByEmail, mock_check_email):
|
159 |
+
current_time = datetime.now()
|
160 |
+
mock_getOtpByEmail.return_value = MagicMock(otp="654321", created_at=current_time - timedelta(minutes=5))
|
161 |
+
email = "user@example.com"
|
162 |
+
otp = "abcd12"
|
163 |
+
response =client.post("/verify_otp_reset_password", json={"email": email,"otp": otp})
|
164 |
+
assert response.json()['status'] == 400
|
165 |
+
assert response.json()['data']['message'] == "Invalid OTP"
|
166 |
+
|
167 |
+
@patch('service.OTPService.sf.check_email_empty_invalid', return_value=True)
|
168 |
+
@patch('repository.OTPRepository.getOtpByEmail')
|
169 |
+
def test_verifyOTPReset_failed_no_otp_found(mock_getOtpByEmail, mock_check_email):
|
170 |
+
mock_getOtpByEmail.return_value = None
|
171 |
+
email = "user@example.com"
|
172 |
+
otp = "abcd12"
|
173 |
+
response = client.post("/verify_otp_reset_password", json={"email": email,"otp": otp})
|
174 |
+
assert response.json()['status'] == 404
|
175 |
+
assert response.json()['data']['message'] == "No OTP found for this email"
|
176 |
+
|
177 |
+
@patch('service.OTPService.sf.check_email_empty_invalid', return_value=True)
|
178 |
+
@patch('repository.OTPRepository.getOtpByEmail')
|
179 |
+
def test_verifyOTPReset_has_expired(mock_getOtpByEmail, mock_check_email):
|
180 |
+
current_time = datetime.now()
|
181 |
+
mock_getOtpByEmail.return_value = MagicMock(otp="1234ab", created_at=current_time - timedelta(minutes=100))
|
182 |
+
email = "vonhuy@gmail.com"
|
183 |
+
otp = "1234ab"
|
184 |
+
response = client.post("/verify_otp_reset_password", json={"email": email,"otp": otp})
|
185 |
+
assert response.json()['status'] == 400
|
186 |
+
assert response.json()['data']['message'] == "OTP has expired"
|
187 |
+
|
188 |
+
def test_verifyOTPReset_failed_invalid_email():
|
189 |
+
email = "invalidemail"
|
190 |
+
otp = "abcd12"
|
191 |
+
response =client.post("/verify_otp_reset_password", json={"email": email,"otp": otp})
|
192 |
+
assert response.json()['status'] == 400
|
193 |
+
assert response.json()['data']['message'] == "Email invalid"
|
194 |
+
|
195 |
+
|
196 |
+
def test_verifyOTPReset_failed_empty_email():
|
197 |
+
email = None
|
198 |
+
otp = "123456"
|
199 |
+
response =client.post("/verify_otp_reset_password", json={"email": email,"otp": otp})
|
200 |
+
assert response.json()['status'] == 400
|
201 |
+
assert response.json()['data']['message'] == "Email is required."
|
202 |
+
|
203 |
+
|
204 |
+
def test_verifyOTPReset_failed_empty_otp():
|
205 |
+
email = "user@example.com"
|
206 |
+
otp = None
|
207 |
+
response = client.post("/verify_otp_reset_password", json={"email": email,"otp": otp})
|
208 |
+
assert response.json()['status'] == 400
|
209 |
+
assert response.json()['data']['message'] == "OTP is required"
|
210 |
+
|
211 |
+
|
212 |
+
def test_createOTP_email_required():
|
213 |
+
email = None
|
214 |
+
response = client.post("/create_otp", json={"email": email})
|
215 |
+
assert response.json()['status'] == 400
|
216 |
+
assert response.json()['data']['message'] == "Email is required."
|
217 |
+
|
218 |
+
def test_createOTP_email_must_be_string():
|
219 |
+
email = "20133"
|
220 |
+
response = client.post("/create_otp", json={"email": email})
|
221 |
+
assert response.json()['status'] == 400
|
222 |
+
assert response.json()['data']['message'] == "Email must be a string, not a number."
|
223 |
+
|
224 |
+
def test_verifyOTP_email_is_required():
|
225 |
+
email = None
|
226 |
+
otp ="123abc"
|
227 |
+
response = client.post("/verify_otp", json={"email": email,"otp": otp})
|
228 |
+
assert response.json()['status'] == 400
|
229 |
+
assert response.json()['data']['message'] == "Email is required."
|
230 |
+
|
231 |
+
def test_verifyOTP_otp_is_required():
|
232 |
+
email = "test@gmail.com"
|
233 |
+
otp = None
|
234 |
+
response = client.post("/verify_otp", json={"email": email,"otp": otp})
|
235 |
+
assert response.json()['status'] == 400
|
236 |
+
assert response.json()['data']['message'] == "OTP is required"
|
237 |
+
|
238 |
+
def test_verifyOTP_otp_email_must_be_string():
|
239 |
+
email = "20133"
|
240 |
+
otp = "123abc"
|
241 |
+
response = client.post("/verify_otp", json={"email": email,"otp": otp})
|
242 |
+
assert response.json()['status'] == 400
|
243 |
+
assert response.json()['data']['message'] == "Email must be a string, not a number."
|
244 |
+
|
245 |
+
def test_verifyOTP_otp_must_be_string():
|
246 |
+
email = "20133@gmail.com"
|
247 |
+
otp = "123456"
|
248 |
+
response = client.post("/verify_otp", json={"email": email,"otp": otp})
|
249 |
+
assert response.json()['status'] == 400
|
250 |
+
assert response.json()['data']['message'] == "OTP must be a string, not a number."
|
251 |
+
|
252 |
+
def test_verifyOTP_otp_max_length():
|
253 |
+
email = "20133@gmail.com"
|
254 |
+
otp = "abcdef1"
|
255 |
+
response = client.post("/verify_otp", json={"email": email,"otp": otp})
|
256 |
+
assert response.json()['status'] == 400
|
257 |
+
assert response.json()['data']['message'] == "OTP max length is 6"
|
258 |
+
|
259 |
+
def test_verifyOTPReset_email_is_required():
|
260 |
+
email = None
|
261 |
+
otp ="123abc"
|
262 |
+
response = client.post("/verify_otp_reset_password", json={"email": email,"otp": otp})
|
263 |
+
assert response.json()['status'] == 400
|
264 |
+
assert response.json()['data']['message'] == "Email is required."
|
265 |
+
|
266 |
+
def test_verifyOTPReset_otp_is_required():
|
267 |
+
email = "test@gmail.com"
|
268 |
+
otp = None
|
269 |
+
response = client.post("/verify_otp_reset_password", json={"email": email,"otp": otp})
|
270 |
+
assert response.json()['status'] == 400
|
271 |
+
assert response.json()['data']['message'] == "OTP is required"
|
272 |
+
|
273 |
+
def test_verifyOTPReset_otp_email_must_be_string():
|
274 |
+
email = "20133"
|
275 |
+
otp = "123abc"
|
276 |
+
response = client.post("/verify_otp_reset_password", json={"email": email,"otp": otp})
|
277 |
+
assert response.json()['status'] == 400
|
278 |
+
assert response.json()['data']['message'] == "Email must be a string, not a number."
|
279 |
+
|
280 |
+
def test_verifyOTPReset_otp_must_be_string():
|
281 |
+
email = "20133@gmail.com"
|
282 |
+
otp = "123456"
|
283 |
+
response = client.post("/verify_otp_reset_password", json={"email": email,"otp": otp})
|
284 |
+
assert response.json()['status'] == 400
|
285 |
+
assert response.json()['data']['message'] == "OTP must be a string, not a number."
|
286 |
+
|
287 |
+
def test_verifyOTPReset_otp_max_length():
|
288 |
+
email = "20133@gmail.com"
|
289 |
+
otp = "abcdef1"
|
290 |
+
response = client.post("/verify_otp_reset_password", json={"email": email,"otp": otp})
|
291 |
+
assert response.json()['status'] == 400
|
292 |
+
assert response.json()['data']['message'] == "OTP max length is 6"
|
tests/test_service/_init__.py
ADDED
File without changes
|
tests/test_service/test_ChatService.py
ADDED
@@ -0,0 +1,462 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import unittest
|
2 |
+
from unittest.mock import patch
|
3 |
+
import sys
|
4 |
+
import os
|
5 |
+
app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
6 |
+
sys.path.insert(0, app_path)
|
7 |
+
from service.ChatService import *
|
8 |
+
from request.RequestChat import *
|
9 |
+
from response.ResponseChat import *
|
10 |
+
|
11 |
+
class TestQuery2UpgradeOld(unittest.TestCase):
|
12 |
+
@patch('service.ChatService.UserRepository')
|
13 |
+
@patch('service.ChatService.sf')
|
14 |
+
@patch('service.ChatService.support_function')
|
15 |
+
def test_query2_upgrade_old_id_not_exist(self,mock_support_function, mock_function_chatbot, mock_user_repo):
|
16 |
+
user_id = "1"
|
17 |
+
text_all = 'aaa'
|
18 |
+
question = 'chatbot la gi'
|
19 |
+
chat_name = 'test'
|
20 |
+
list1 = []
|
21 |
+
list2 = []
|
22 |
+
mock_function_chatbot.handle_query_upgrade_keyword_old.return_value = None, list1, list2
|
23 |
+
mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message(
|
24 |
+
message="Id not exist"))
|
25 |
+
request = RequestQuery2UpgradeOld(user_id=user_id, text_all=text_all, question=question, chat_name=chat_name)
|
26 |
+
response = query2_upgrade_old(request)
|
27 |
+
self.assertIsInstance(response, ReponseError)
|
28 |
+
self.assertEqual(response.status, 400)
|
29 |
+
self.assertEqual(response.data, Message(message='Id not exist'))
|
30 |
+
|
31 |
+
@patch('service.ChatService.UserRepository')
|
32 |
+
@patch('service.ChatService.sf')
|
33 |
+
@patch('service.ChatService.support_function')
|
34 |
+
def test_query2_upgrade_old_email_empty(self,mock_support_function, mock_function_chatbot, mock_user_repo):
|
35 |
+
user_id = "1"
|
36 |
+
email = None
|
37 |
+
text_all = 'aaa'
|
38 |
+
question = 'chatbot la gi'
|
39 |
+
chat_name = 'test'
|
40 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
41 |
+
list1 = []
|
42 |
+
list2 = []
|
43 |
+
mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message(
|
44 |
+
message="Email is empty"))
|
45 |
+
mock_function_chatbot.handle_query_upgrade_keyword_old.return_value = None, list1, list2
|
46 |
+
|
47 |
+
request = RequestQuery2UpgradeOld(user_id=user_id, text_all=text_all, question=question, chat_name=chat_name)
|
48 |
+
response = query2_upgrade_old(request)
|
49 |
+
self.assertIsInstance(response, ReponseError)
|
50 |
+
self.assertEqual(response.status, 400)
|
51 |
+
self.assertEqual(response.data, Message(message='Email is empty'))
|
52 |
+
|
53 |
+
@patch('service.ChatService.UserRepository')
|
54 |
+
@patch('service.ChatService.sf')
|
55 |
+
@patch('service.ChatService.support_function')
|
56 |
+
def test_query2_upgrade_old_email_in_valid(self,mock_support_function,mock_function_chatbot,mock_user_repo):
|
57 |
+
user_id = "1"
|
58 |
+
email = "20133118"
|
59 |
+
text_all = 'aaa'
|
60 |
+
question = 'chatbot la gi'
|
61 |
+
chat_name = 'test'
|
62 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
63 |
+
list1 = []
|
64 |
+
list2 = []
|
65 |
+
mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message(
|
66 |
+
message="Email invalid"))
|
67 |
+
mock_function_chatbot.handle_query_upgrade_keyword_old.return_value = None, list1, list2
|
68 |
+
request = RequestQuery2UpgradeOld(user_id=user_id, text_all=text_all, question=question, chat_name=chat_name)
|
69 |
+
response = query2_upgrade_old(request)
|
70 |
+
self.assertIsInstance(response, ReponseError)
|
71 |
+
self.assertEqual(response.status, 400)
|
72 |
+
self.assertEqual(response.data, Message(message='Email invalid'))
|
73 |
+
|
74 |
+
@patch('service.ChatService.UserRepository')
|
75 |
+
@patch('service.ChatService.sf')
|
76 |
+
@patch('service.ChatService.support_function')
|
77 |
+
def test_query2_upgrade_old_question_empty(self,mock_support_function,mock_function_chatbot, mock_user_repo):
|
78 |
+
email = 'example@example.com'
|
79 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
80 |
+
list1 = []
|
81 |
+
list2 = []
|
82 |
+
mock_support_function.check_email_service.return_value = email
|
83 |
+
mock_function_chatbot.handle_query_upgrade_keyword_old.return_value = None, list1, list2
|
84 |
+
request = RequestQuery2UpgradeOld(user_id="1", text_all="text aaa all", question=None, chat_name="test")
|
85 |
+
response = query2_upgrade_old(request)
|
86 |
+
self.assertIsInstance(response, ReponseError)
|
87 |
+
self.assertEqual(response.status, 400)
|
88 |
+
self.assertEqual(response.data, Message(message='question is empty'))
|
89 |
+
|
90 |
+
@patch('service.ChatService.UserRepository')
|
91 |
+
@patch('service.ChatService.support_function')
|
92 |
+
def test_query2_upgrade_old_chat_empty(self,mock_support_function, mock_user_repo):
|
93 |
+
email = 'example@example.com'
|
94 |
+
mock_support_function.check_email_service.return_value = email
|
95 |
+
request = RequestQuery2UpgradeOld(user_id= "1", text_all="aaa bbb", question="aaa bbb", chat_name=None)
|
96 |
+
response = query2_upgrade_old(request)
|
97 |
+
self.assertIsInstance(response, ReponseError)
|
98 |
+
self.assertEqual(response.status, 400)
|
99 |
+
self.assertEqual(response.data, Message(message='chat_name is empty'))
|
100 |
+
|
101 |
+
@patch('service.ChatService.UserRepository')
|
102 |
+
@patch('service.ChatService.sf')
|
103 |
+
@patch('service.ChatService.support_function')
|
104 |
+
def test_query2_upgrade_old_no_answer(self,mock_support_function, mock_function_chatbot, mock_user_repo):
|
105 |
+
user_id = "1"
|
106 |
+
email = 'example@example.com'
|
107 |
+
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"}]
|
108 |
+
question = "aaa bbb"
|
109 |
+
chat_name = "test"
|
110 |
+
mock_support_function.check_email_service.return_value = email
|
111 |
+
list1 = []
|
112 |
+
list2 = []
|
113 |
+
mock_function_chatbot.handle_query_upgrade_keyword_old.return_value = None, list1, list2
|
114 |
+
request = RequestQuery2UpgradeOld(user_id=user_id, text_all = json.dumps(text_all), question=question, chat_name=chat_name)
|
115 |
+
response = query2_upgrade_old(request)
|
116 |
+
self.assertIsInstance(response, ReponseError)
|
117 |
+
self.assertEqual(response.status, 500)
|
118 |
+
self.assertEqual(response.data.message, "No answer")
|
119 |
+
|
120 |
+
@patch('service.ChatService.UserRepository')
|
121 |
+
@patch('service.ChatService.sf')
|
122 |
+
@patch('service.ChatService.ChatHistoryRepository')
|
123 |
+
@patch('service.ChatService.DetailChatRepository')
|
124 |
+
@patch('service.ChatService.support_function')
|
125 |
+
def test_query2_upgrade_old_success(self,mock_support_function,mock_detail_chat_repo, mock_chat_his_repo, mock_function_chatbot, mock_user_repo):
|
126 |
+
user_id = "1"
|
127 |
+
email = 'example@example.com'
|
128 |
+
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"}]
|
129 |
+
question = "aaa bbb"
|
130 |
+
chat_name = "test"
|
131 |
+
mock_support_function.check_email_service.return_value = email
|
132 |
+
list1 = []
|
133 |
+
list2 = []
|
134 |
+
mock_function_chatbot.handle_query_upgrade_keyword_old.return_value = "success",list1,list2
|
135 |
+
mock_chat_his_repo.getIdChatHistoryByUserIdAndNameChat.return_value = True
|
136 |
+
mock_detail_chat_repo.addDetailChat.return_value = True
|
137 |
+
request = RequestQuery2UpgradeOld(user_id=user_id, text_all = json.dumps(text_all), question=question, chat_name=chat_name)
|
138 |
+
response = query2_upgrade_old(request)
|
139 |
+
self.assertIsInstance(response, ResponseQuery2UpgradeOld)
|
140 |
+
self.assertEqual(response.status, 200)
|
141 |
+
self.assertEqual(response.data.answer, "success")
|
142 |
+
|
143 |
+
@patch('service.ChatService.UserRepository')
|
144 |
+
@patch('service.ChatService.sf')
|
145 |
+
@patch('service.ChatService.ChatHistoryRepository')
|
146 |
+
@patch('service.ChatService.DetailChatRepository')
|
147 |
+
@patch('service.ChatService.support_function')
|
148 |
+
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):
|
149 |
+
user_id = "1"
|
150 |
+
email = 'example@example.com'
|
151 |
+
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"}]
|
152 |
+
question = "aaa bbb"
|
153 |
+
chat_name = "test"
|
154 |
+
mock_support_function.check_email_service.side_effect = Exception("Unexpected Error")
|
155 |
+
list1 = []
|
156 |
+
list2 = []
|
157 |
+
mock_function_chatbot.handle_query_upgrade_keyword_old.return_value = None, list1, list2
|
158 |
+
request = RequestQuery2UpgradeOld(user_id=user_id, text_all = json.dumps(text_all), question=question, chat_name=chat_name)
|
159 |
+
response = query2_upgrade_old(request)
|
160 |
+
self.assertIsInstance(response, ReponseError)
|
161 |
+
self.assertEqual(response.status, 500)
|
162 |
+
self.assertEqual(response.data.message, "Server Error")
|
163 |
+
|
164 |
+
@patch('service.ChatService.UserRepository')
|
165 |
+
@patch('service.ChatService.sf')
|
166 |
+
@patch('service.ChatService.ChatHistoryRepository')
|
167 |
+
@patch('service.ChatService.DetailChatRepository')
|
168 |
+
@patch('service.ChatService.support_function')
|
169 |
+
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):
|
170 |
+
user_id = "1"
|
171 |
+
email = 'example@example.com'
|
172 |
+
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"}]
|
173 |
+
question = "aaa bbb"
|
174 |
+
chat_name = "test"
|
175 |
+
mock_chat_his_repo.side_effect = Exception("Unexpected Error")
|
176 |
+
request = RequestQuery2UpgradeOld(user_id=user_id, text_all = json.dumps(text_all), question=question, chat_name=chat_name)
|
177 |
+
response = query2_upgrade_old(request)
|
178 |
+
self.assertIsInstance(response, ReponseError)
|
179 |
+
self.assertEqual(response.status, 500)
|
180 |
+
self.assertEqual(response.data.message, "Server Error")
|
181 |
+
|
182 |
+
@patch('service.ChatService.UserRepository')
|
183 |
+
@patch('service.ChatService.sf')
|
184 |
+
@patch('service.ChatService.ChatHistoryRepository')
|
185 |
+
@patch('service.ChatService.DetailChatRepository')
|
186 |
+
@patch('service.ChatService.support_function')
|
187 |
+
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):
|
188 |
+
user_id = "1"
|
189 |
+
email = 'example@example.com'
|
190 |
+
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"}]
|
191 |
+
question = "aaa bbb"
|
192 |
+
chat_name = "test"
|
193 |
+
mock_support_function.check_email_service.return_value = email
|
194 |
+
mock_detail_chat_repo.side_effect = Exception("Unexpected Error")
|
195 |
+
request = RequestQuery2UpgradeOld(user_id=user_id, text_all = json.dumps(text_all), question=question, chat_name=chat_name)
|
196 |
+
response = query2_upgrade_old(request)
|
197 |
+
self.assertIsInstance(response, ReponseError)
|
198 |
+
self.assertEqual(response.status, 500)
|
199 |
+
self.assertEqual(response.data.message, "Server Error")
|
200 |
+
|
201 |
+
@patch('service.ChatService.UserRepository')
|
202 |
+
@patch('service.ChatService.sf')
|
203 |
+
@patch('service.ChatService.ChatHistoryRepository')
|
204 |
+
@patch('service.ChatService.DetailChatRepository')
|
205 |
+
@patch('service.ChatService.support_function')
|
206 |
+
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):
|
207 |
+
user_id = "1"
|
208 |
+
email = 'example@example.com'
|
209 |
+
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"}]
|
210 |
+
question = "aaa bbb"
|
211 |
+
chat_name = "test"
|
212 |
+
mock_support_function.check_email_service.return_value = email
|
213 |
+
mock_function_chatbot.side_effect = Exception("Unexpected Error")
|
214 |
+
request = RequestQuery2UpgradeOld(user_id=user_id, text_all = json.dumps(text_all), question=question, chat_name=chat_name)
|
215 |
+
response = query2_upgrade_old(request)
|
216 |
+
self.assertIsInstance(response, ReponseError)
|
217 |
+
self.assertEqual(response.status, 500)
|
218 |
+
self.assertEqual(response.data.message, "Server Error")
|
219 |
+
|
220 |
+
class TestExtractFile(unittest.TestCase):
|
221 |
+
@patch('service.ChatService.UserRepository')
|
222 |
+
@patch('service.ChatService.sf')
|
223 |
+
@patch('service.ChatService.support_function')
|
224 |
+
def test_extract_file_success(self,mock_support_function, mock_function_chatbot, mock_user_repo):
|
225 |
+
user_id = "1"
|
226 |
+
email = 'example@example.com'
|
227 |
+
mock_support_function.check_email_service.return_value = email
|
228 |
+
mock_function_chatbot.extract_data2.return_value = True
|
229 |
+
request = RequestExtractFile(user_id=user_id)
|
230 |
+
response = extract_file(request)
|
231 |
+
self.assertIsInstance(response, ResponseExtractFile)
|
232 |
+
self.assertEqual(response.status, 200)
|
233 |
+
|
234 |
+
@patch('service.ChatService.UserRepository')
|
235 |
+
@patch('service.ChatService.sf')
|
236 |
+
@patch('service.ChatService.support_function')
|
237 |
+
def test_extract_file_id_not_exist(self,mock_support_function, mock_function_chatbot, mock_user_repo):
|
238 |
+
user_id = "1"
|
239 |
+
mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message(
|
240 |
+
message="Id not exist"))
|
241 |
+
request = RequestExtractFile(user_id=user_id)
|
242 |
+
response = extract_file(request)
|
243 |
+
self.assertIsInstance(response, ReponseError)
|
244 |
+
self.assertEqual(response.status, 400)
|
245 |
+
self.assertEqual(response.data, Message(message='Id not exist'))
|
246 |
+
|
247 |
+
@patch('service.ChatService.UserRepository')
|
248 |
+
@patch('service.ChatService.sf')
|
249 |
+
@patch('service.ChatService.support_function')
|
250 |
+
def test_extract_file_email_empty(self,mock_support_function,mock_function_chatbot, mock_user_repo):
|
251 |
+
user_id = "1"
|
252 |
+
email = None
|
253 |
+
mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message(
|
254 |
+
message="Email is empty"))
|
255 |
+
request = RequestExtractFile(user_id=user_id)
|
256 |
+
response = extract_file(request)
|
257 |
+
self.assertIsInstance(response, ReponseError)
|
258 |
+
self.assertEqual(response.status, 400)
|
259 |
+
self.assertEqual(response.data, Message(message='Email is empty'))
|
260 |
+
|
261 |
+
@patch('service.ChatService.UserRepository')
|
262 |
+
@patch('service.ChatService.sf')
|
263 |
+
@patch('service.ChatService.support_function')
|
264 |
+
def test_extract_file_email_in_valid(self,mock_support_function
|
265 |
+
, mock_function_chatbot, mock_user_repo):
|
266 |
+
user_id = "1"
|
267 |
+
mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message(
|
268 |
+
message="Email invalid"))
|
269 |
+
request = RequestExtractFile(user_id=user_id)
|
270 |
+
response = extract_file(request)
|
271 |
+
self.assertIsInstance(response, ReponseError)
|
272 |
+
self.assertEqual(response.status, 400)
|
273 |
+
self.assertEqual(response.data, Message(message='Email invalid'))
|
274 |
+
|
275 |
+
@patch('service.ChatService.UserRepository')
|
276 |
+
@patch('service.ChatService.sf')
|
277 |
+
@patch('service.ChatService.support_function')
|
278 |
+
def test_extract_file_no_data(self, mock_support_function, mock_function_chatbot, mock_user_repo):
|
279 |
+
user_id = "1"
|
280 |
+
email = 'example@example.com'
|
281 |
+
mock_support_function.check_email_service.return_value = email
|
282 |
+
mock_function_chatbot.extract_data2.return_value = False
|
283 |
+
request = RequestExtractFile(user_id=user_id)
|
284 |
+
response = extract_file(request)
|
285 |
+
self.assertIsInstance(response, ResponseExtractFile)
|
286 |
+
self.assertEqual(response.status, 200)
|
287 |
+
self.assertEqual(response.data, DataExtractFile(text_all="No data response"))
|
288 |
+
|
289 |
+
@patch('service.ChatService.UserRepository')
|
290 |
+
@patch('service.ChatService.sf')
|
291 |
+
@patch('service.ChatService.support_function')
|
292 |
+
def test_extract_file_server_error_sf(self, mock_support_function,mock_function_chatbot, mock_user_repo):
|
293 |
+
user_id = "1"
|
294 |
+
email = None
|
295 |
+
mock_support_function.check_email_service.side_effect = Exception("Unexpected Error")
|
296 |
+
request = RequestExtractFile(user_id=user_id)
|
297 |
+
response = extract_file(request)
|
298 |
+
self.assertIsInstance(response, ReponseError)
|
299 |
+
self.assertEqual(response.status, 500)
|
300 |
+
self.assertEqual(response.data, Message(message='Server Error'))
|
301 |
+
|
302 |
+
class TestGenerateQuestion(unittest.TestCase):
|
303 |
+
@patch('service.ChatService.UserRepository')
|
304 |
+
@patch('service.ChatService.sf')
|
305 |
+
@patch('service.ChatService.support_function')
|
306 |
+
def test_generate_question_success(self,mock_support_function, mock_function_chatbot, mock_user_repo):
|
307 |
+
user_id = "1"
|
308 |
+
email = 'example@example.com'
|
309 |
+
mock_support_function.check_email_service.return_value = email
|
310 |
+
mock_function_chatbot.generate_question.return_value = True
|
311 |
+
request = RequestGenerateQuestion(user_id=user_id)
|
312 |
+
response = generate_question(request)
|
313 |
+
self.assertIsInstance(response, ResponseGenerateQuestion)
|
314 |
+
self.assertEqual(response.status, 200)
|
315 |
+
|
316 |
+
@patch('service.ChatService.UserRepository')
|
317 |
+
@patch('service.ChatService.sf')
|
318 |
+
@patch('service.ChatService.support_function')
|
319 |
+
def test_generate_question_id_not_exist(self,mock_support_function, mock_function_chatbot, mock_user_repo):
|
320 |
+
user_id = "1"
|
321 |
+
mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message(
|
322 |
+
message="Id not exist"))
|
323 |
+
request = RequestGenerateQuestion(user_id=user_id)
|
324 |
+
response = generate_question(request)
|
325 |
+
self.assertIsInstance(response, ReponseError)
|
326 |
+
self.assertEqual(response.status, 400)
|
327 |
+
self.assertEqual(response.data, Message(message='Id not exist'))
|
328 |
+
|
329 |
+
@patch('service.ChatService.UserRepository')
|
330 |
+
@patch('service.ChatService.sf')
|
331 |
+
@patch('service.ChatService.support_function')
|
332 |
+
def test_generate_question_email_empty(self,mock_support_function, mock_function_chatbot, mock_user_repo):
|
333 |
+
user_id = "1"
|
334 |
+
mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message(
|
335 |
+
message="Email is empty"))
|
336 |
+
request = RequestGenerateQuestion(user_id=user_id)
|
337 |
+
response = generate_question(request)
|
338 |
+
self.assertIsInstance(response, ReponseError)
|
339 |
+
self.assertEqual(response.status, 400)
|
340 |
+
self.assertEqual(response.data, Message(message='Email is empty'))
|
341 |
+
|
342 |
+
@patch('service.ChatService.UserRepository')
|
343 |
+
@patch('service.ChatService.sf')
|
344 |
+
@patch('service.ChatService.support_function')
|
345 |
+
def test_generate_question_email_in_valid(self,mock_support_function, mock_function_chatbot, mock_user_repo):
|
346 |
+
user_id = "1"
|
347 |
+
email = "20133118"
|
348 |
+
mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message(
|
349 |
+
message="Email invalid"))
|
350 |
+
request = RequestGenerateQuestion(user_id=user_id)
|
351 |
+
response = generate_question(request)
|
352 |
+
self.assertIsInstance(response, ReponseError)
|
353 |
+
self.assertEqual(response.status, 400)
|
354 |
+
self.assertEqual(response.data, Message(message='Email invalid'))
|
355 |
+
|
356 |
+
@patch('service.ChatService.UserRepository')
|
357 |
+
@patch('service.ChatService.sf')
|
358 |
+
@patch('service.ChatService.support_function')
|
359 |
+
def test_generate_question_no_data(self,mock_support_function, mock_function_chatbot, mock_user_repo):
|
360 |
+
user_id = "1"
|
361 |
+
email = 'example@example.com'
|
362 |
+
mock_support_function.check_email_service.return_value = email
|
363 |
+
mock_function_chatbot.generate_question.return_value = False
|
364 |
+
request = RequestGenerateQuestion(user_id=user_id)
|
365 |
+
response = generate_question(request)
|
366 |
+
self.assertIsInstance(response, ResponseGenerateQuestion)
|
367 |
+
self.assertEqual(response.status, 200)
|
368 |
+
self.assertEqual(response.data, GenerateQuestion(question=False))
|
369 |
+
|
370 |
+
@patch('service.ChatService.UserRepository')
|
371 |
+
@patch('service.ChatService.sf')
|
372 |
+
@patch('service.ChatService.support_function')
|
373 |
+
def test_generate_question_server_err_user_repo(self,mock_support_function
|
374 |
+
, mock_function_chatbot, mock_user_repo):
|
375 |
+
user_id = "1"
|
376 |
+
email = None
|
377 |
+
mock_support_function.side_effect = Exception("Unexpected Error")
|
378 |
+
request = RequestGenerateQuestion(user_id=user_id)
|
379 |
+
response = generate_question(request)
|
380 |
+
self.assertIsInstance(response, ReponseError)
|
381 |
+
self.assertEqual(response.status, 500)
|
382 |
+
self.assertEqual(response.data, Message(message='Server Error'))
|
383 |
+
|
384 |
+
class TestDeleteChat(unittest.TestCase):
|
385 |
+
@patch('service.ChatService.UserRepository')
|
386 |
+
@patch('service.ChatService.DetailChatRepository')
|
387 |
+
@patch('service.ChatService.ChatHistoryRepository')
|
388 |
+
@patch('service.ChatService.support_function')
|
389 |
+
def test_delete_chat_success(self, mock_support_function, mock_detail_chat_repo, mock_chat_history_repo, mock_user_repo):
|
390 |
+
user_id = "1"
|
391 |
+
email = 'example@example.com'
|
392 |
+
chat_name = 'test'
|
393 |
+
mock_support_function.check_email_service.return_value = email
|
394 |
+
mock_detail_chat_repo.delete_chat_detail.return_value = True
|
395 |
+
mock_chat_history_repo.deleteChatHistory.return_value = True
|
396 |
+
request = RequestDeleteChat(user_id=user_id, chat_name=chat_name)
|
397 |
+
response = delete_chat(request)
|
398 |
+
self.assertIsInstance(response, ResponseDeleteChat)
|
399 |
+
self.assertEqual(response.status, 200)
|
400 |
+
self.assertEqual(response.data, Message(message="Delete conversation chat success"))
|
401 |
+
|
402 |
+
@patch('service.ChatService.UserRepository')
|
403 |
+
@patch('service.ChatService.support_function')
|
404 |
+
def test_delete_chat_id_not_exist(self,mock_support_function, mock_user_repo):
|
405 |
+
user_id = "1"
|
406 |
+
chat_name = 'test'
|
407 |
+
mock_support_function.check_email_service.return_value = res.ReponseError(status=400, data=res.Message(
|
408 |
+
message="Id not exist"))
|
409 |
+
request = RequestDeleteChat(user_id=user_id, chat_name=chat_name)
|
410 |
+
response = delete_chat(request)
|
411 |
+
self.assertIsInstance(response, ReponseError)
|
412 |
+
self.assertEqual(response.status, 400)
|
413 |
+
self.assertEqual(response.data, Message(message='Id not exist'))
|
414 |
+
|
415 |
+
@patch('service.ChatService.UserRepository')
|
416 |
+
@patch('service.ChatService.support_function')
|
417 |
+
def test_delete_chat_chat_name_empty(self, mock_support_function, mock_user_repo):
|
418 |
+
user_id = "1"
|
419 |
+
email = 'example@example.com'
|
420 |
+
chat_name = None
|
421 |
+
mock_support_function.check_email_service.return_value = email
|
422 |
+
request = RequestDeleteChat(user_id=user_id, chat_name=chat_name)
|
423 |
+
response = delete_chat(request)
|
424 |
+
self.assertIsInstance(response, ReponseError)
|
425 |
+
self.assertEqual(response.status, 400)
|
426 |
+
self.assertEqual(response.data.message, "chat_name is empty")
|
427 |
+
|
428 |
+
@patch('service.ChatService.UserRepository')
|
429 |
+
@patch('service.ChatService.ChatHistoryRepository')
|
430 |
+
@patch('service.ChatService.support_function')
|
431 |
+
def test_delete_chat_failed(self,mock_support_function, mock_chat_history_repo, mock_user_repo):
|
432 |
+
user_id = "1"
|
433 |
+
email = 'example@example.com'
|
434 |
+
chat_name = 'test'
|
435 |
+
mock_support_function.check_email_service.return_value = email
|
436 |
+
mock_chat_history_repo.deleteChatHistory.return_value = False
|
437 |
+
request = RequestDeleteChat(user_id=user_id, chat_name=chat_name)
|
438 |
+
response = delete_chat(request)
|
439 |
+
self.assertIsInstance(response, ResponseDeleteChat)
|
440 |
+
self.assertEqual(response.status, 500)
|
441 |
+
self.assertEqual(response.data, Message(message="Delete conversation chat failed"))
|
442 |
+
|
443 |
+
@patch('service.ChatService.support_function')
|
444 |
+
@patch('service.ChatService.DetailChatRepository.delete_chat_detail')
|
445 |
+
@patch('service.ChatService.ChatHistoryRepository.deleteChatHistory')
|
446 |
+
def test_delete_chat_server_err(self, mock_chat_history_repo, mock_detail_chat_repo, mock_support_function):
|
447 |
+
user_id = "1"
|
448 |
+
chat_name = 'test'
|
449 |
+
|
450 |
+
mock_support_function.check_email_service.side_effect = Exception("Unexpected Error")
|
451 |
+
|
452 |
+
request = RequestDeleteChat(user_id=user_id, chat_name=chat_name)
|
453 |
+
response = delete_chat(request)
|
454 |
+
|
455 |
+
# Assuming ReponseError is the correct class name
|
456 |
+
self.assertIsInstance(response, res.ReponseError) # Check against ReponseError
|
457 |
+
self.assertEqual(response.status, 500)
|
458 |
+
self.assertEqual(response.data.message, "Server Error")
|
459 |
+
|
460 |
+
|
461 |
+
if __name__ == '__main__':
|
462 |
+
unittest.main()
|
tests/test_service/test_DefaultService.py
ADDED
@@ -0,0 +1,344 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import sys
|
3 |
+
import unittest
|
4 |
+
from unittest.mock import patch, Mock,MagicMock
|
5 |
+
app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
6 |
+
sys.path.insert(0, app_path)
|
7 |
+
from service.DefaultService import *
|
8 |
+
from request.RequestDefault import *
|
9 |
+
from response.ResponseDefault import *
|
10 |
+
|
11 |
+
class TestCreateFireBaseUser(unittest.TestCase):
|
12 |
+
def test_email_none(self):
|
13 |
+
request = RequestCreateFireBaseUserGoogle(email=None)
|
14 |
+
response = create_firebase_user(request)
|
15 |
+
self.assertEqual(response.status, 400)
|
16 |
+
self.assertEqual(response.data.message, "Email is empty")
|
17 |
+
|
18 |
+
@patch('service.DefaultService.check_email', return_value=False)
|
19 |
+
@patch('service.DefaultService.get_user')
|
20 |
+
@patch('service.DefaultService.authservice.verify_token_google', return_value=True)
|
21 |
+
def test_invalid_email(self,mock_verify, mock_get_user, mock_check_email):
|
22 |
+
request = Mock(spec=req.RequestCreateFireBaseUserGoogle)
|
23 |
+
request.email = "invalid-email"
|
24 |
+
request.token_google = "token"
|
25 |
+
response = create_firebase_user(request)
|
26 |
+
self.assertEqual(response.status, 400)
|
27 |
+
self.assertEqual(response.data.message, "Email invalid")
|
28 |
+
|
29 |
+
@patch('service.DefaultService.check_email', return_value=True)
|
30 |
+
@patch('service.DefaultService.get_user')
|
31 |
+
@patch('service.DefaultService.authservice.verify_token_google',return_value=True)
|
32 |
+
def test_existing_user(self,mock_verify, mock_get_user, mock_check_email):
|
33 |
+
request = Mock(spec=req.RequestCreateFireBaseUserGoogle)
|
34 |
+
request.email = "test@example.com"
|
35 |
+
request.token_google = "token"
|
36 |
+
user = Mock()
|
37 |
+
user.email = "test@example.com"
|
38 |
+
user.display_name = "Test User"
|
39 |
+
user.uid = "123456"
|
40 |
+
user.photo_url = "http://example.com/photo.jpg"
|
41 |
+
mock_get_user.return_value = user
|
42 |
+
response = create_firebase_user(request)
|
43 |
+
self.assertEqual(response.status, 200)
|
44 |
+
self.assertEqual(response.data.localId, "123456")
|
45 |
+
self.assertEqual(response.data.email, user.email)
|
46 |
+
self.assertEqual(response.data.displayName, user.display_name)
|
47 |
+
self.assertEqual(response.data.photoUrl, user.photo_url)
|
48 |
+
|
49 |
+
@patch('service.DefaultService.check_email', return_value=True)
|
50 |
+
@patch('service.DefaultService.get_user', return_value=None)
|
51 |
+
@patch('service.DefaultService.authservice.verify_token_google', return_value=True)
|
52 |
+
def test_non_existing_user(self,mock_verify, mock_get_user, mock_check_email):
|
53 |
+
request = Mock(spec=req.RequestCreateFireBaseUserGoogle)
|
54 |
+
request.email = "test@example.com"
|
55 |
+
request.token_google = "token"
|
56 |
+
response = create_firebase_user(request)
|
57 |
+
self.assertEqual(response.status, 500)
|
58 |
+
self.assertEqual(response.data.message, "Error")
|
59 |
+
|
60 |
+
@patch('service.DefaultService.check_email', return_value=True)
|
61 |
+
@patch('service.DefaultService.get_user', return_value=None)
|
62 |
+
def test_token_google_empty(self,mock_get_user, mock_check_email):
|
63 |
+
request = Mock(spec=req.RequestCreateFireBaseUserGoogle)
|
64 |
+
request.email = "test@example.com"
|
65 |
+
request.token_google = ""
|
66 |
+
response = create_firebase_user(request)
|
67 |
+
self.assertEqual(response.status, 400)
|
68 |
+
self.assertEqual(response.data.message, "token google not empty")
|
69 |
+
|
70 |
+
@patch('service.DefaultService.check_email', return_value=True)
|
71 |
+
@patch('service.DefaultService.get_user', return_value=None)
|
72 |
+
def test_token_google_empty(self, mock_get_user, mock_check_email):
|
73 |
+
request = Mock(spec=req.RequestCreateFireBaseUserGoogle)
|
74 |
+
request.email = "test@example.com"
|
75 |
+
request.token_google = ""
|
76 |
+
response = create_firebase_user(request)
|
77 |
+
self.assertEqual(response.status, 400)
|
78 |
+
self.assertEqual(response.data.message, "token google not empty")
|
79 |
+
|
80 |
+
@patch('service.DefaultService.check_email', return_value=True)
|
81 |
+
@patch('service.DefaultService.get_user', return_value=None)
|
82 |
+
@patch('service.DefaultService.authservice.verify_token_google', return_value=False)
|
83 |
+
def test_oauth2_failed(self,mock_verify, mock_get_user, mock_check_email):
|
84 |
+
request = Mock(spec=req.RequestCreateFireBaseUserGoogle)
|
85 |
+
request.email = "test@example.com"
|
86 |
+
request.token_google = "aaaaa"
|
87 |
+
response = create_firebase_user(request)
|
88 |
+
self.assertEqual(response.status, 400)
|
89 |
+
self.assertEqual(response.data.message, "Create user failed")
|
90 |
+
|
91 |
+
@patch('service.DefaultService.sf.check_email_empty_invalid')
|
92 |
+
@patch('service.DefaultService.get_user')
|
93 |
+
def test_server_error(self, mock_get_user, mock_check_email):
|
94 |
+
request = Mock(spec=req.RequestCreateFireBaseUserGoogle)
|
95 |
+
request.email = "test@example.com"
|
96 |
+
request.token_google ="token"
|
97 |
+
#1 of the 2 cases below
|
98 |
+
mock_check_email.side_effect = Exception("Unexpected Error")
|
99 |
+
# mock_get_user.side_effect = Exception("Unexpected Error")
|
100 |
+
response = create_firebase_user(request)
|
101 |
+
self.assertEqual(response.status, 500)
|
102 |
+
self.assertEqual(response.data.message, "Server Error")
|
103 |
+
|
104 |
+
class TestInfoUser(unittest.TestCase):
|
105 |
+
@patch('service.DefaultService.UserRepository.getEmailUserByIdFix')
|
106 |
+
@patch('service.DefaultService.get_user')
|
107 |
+
@patch('service.DefaultService.check_email')
|
108 |
+
def test_id_not_exist(self, mock_check_email, mock_get_user, mock_getEmailUserByIdFix):
|
109 |
+
request = Mock(spec=req.RequestInfoUser)
|
110 |
+
request.user_id = '1'
|
111 |
+
mock_getEmailUserByIdFix.return_value = None
|
112 |
+
response = info_user(request)
|
113 |
+
self.assertEqual(response.status, 404)
|
114 |
+
self.assertEqual(response.data.message, "Id not exist")
|
115 |
+
|
116 |
+
@patch('service.DefaultService.UserRepository.getEmailUserByIdFix')
|
117 |
+
@patch('service.DefaultService.get_user')
|
118 |
+
@patch('service.DefaultService.check_email')
|
119 |
+
def test_email_is_none(self, mock_check_email, mock_get_user, mock_getEmailUserByIdFix):
|
120 |
+
request = Mock(spec=req.RequestInfoUser)
|
121 |
+
request.user_id = '1'
|
122 |
+
mock_getEmailUserByIdFix.return_value = [None]
|
123 |
+
response = info_user(request)
|
124 |
+
self.assertEqual(response.status, 400)
|
125 |
+
self.assertEqual(response.data.message, "Email is empty")
|
126 |
+
|
127 |
+
@patch('service.DefaultService.UserRepository.getEmailUserByIdFix')
|
128 |
+
@patch('service.DefaultService.get_user')
|
129 |
+
@patch('service.DefaultService.check_email', return_value=False)
|
130 |
+
def test_invalid_email(self, mock_check_email, mock_get_user, mock_getEmailUserByIdFix):
|
131 |
+
request = Mock(spec=req.RequestInfoUser)
|
132 |
+
request.user_id = '1'
|
133 |
+
mock_getEmailUserByIdFix.return_value = ["invalid-email"]
|
134 |
+
response = info_user(request)
|
135 |
+
self.assertEqual(response.status, 400)
|
136 |
+
self.assertEqual(response.data.message, "Email invalid")
|
137 |
+
|
138 |
+
@patch('service.DefaultService.UserRepository.getEmailUserByIdFix')
|
139 |
+
@patch('service.DefaultService.get_user', return_value=None)
|
140 |
+
@patch('service.DefaultService.check_email', return_value=True)
|
141 |
+
def test_user_not_found(self, mock_check_email, mock_get_user, mock_getEmailUserByIdFix):
|
142 |
+
request = Mock(spec=req.RequestInfoUser)
|
143 |
+
request.user_id = '1'
|
144 |
+
mock_getEmailUserByIdFix.return_value = ["test@example.com"]
|
145 |
+
response = info_user(request)
|
146 |
+
self.assertEqual(response.status, 404)
|
147 |
+
self.assertEqual(response.data.message, "User not found")
|
148 |
+
|
149 |
+
@patch('service.DefaultService.UserRepository.getEmailUserByIdFix')
|
150 |
+
@patch('service.DefaultService.get_user')
|
151 |
+
@patch('service.DefaultService.check_email', return_value=True)
|
152 |
+
def test_successful_user_retrieval(self, mock_check_email, mock_get_user, mock_getEmailUserByIdFix):
|
153 |
+
request = Mock(spec=req.RequestInfoUser)
|
154 |
+
request.user_id = '1'
|
155 |
+
mock_getEmailUserByIdFix.return_value = ["test@example.com"]
|
156 |
+
user = Mock()
|
157 |
+
user.uid = "12345"
|
158 |
+
user.email = "test@example.com"
|
159 |
+
user.display_name = "Test User"
|
160 |
+
user.photo_url = "http://example.com/photo.jpg"
|
161 |
+
mock_get_user.return_value = user
|
162 |
+
response = info_user(request)
|
163 |
+
self.assertEqual(response.status, 200)
|
164 |
+
self.assertEqual(response.data.uid, user.uid)
|
165 |
+
self.assertEqual(response.data.email, user.email)
|
166 |
+
self.assertEqual(response.data.display_name, user.display_name)
|
167 |
+
self.assertEqual(response.data.photo_url, user.photo_url)
|
168 |
+
|
169 |
+
@patch('service.DefaultService.UserRepository.getEmailUserByIdFix')
|
170 |
+
@patch('service.DefaultService.get_user')
|
171 |
+
@patch('service.DefaultService.check_email')
|
172 |
+
@patch('service.DefaultService.sf.check_email_service',side_effect=Exception("Unexpected Error"))
|
173 |
+
def test_server_error(self, mock_support_function,mock_check_email, mock_get_user, mock_getEmailUserByIdFix):
|
174 |
+
request = Mock(spec=req.RequestInfoUser)
|
175 |
+
request.user_id = '1'
|
176 |
+
#1 of the 3 cases below
|
177 |
+
# mock_get_user.side_effect = Exception("Unexpected Error")
|
178 |
+
# mock_getEmailUserByIdFix.side_effect = Exception("Unexpected Error")
|
179 |
+
response = info_user(request)
|
180 |
+
self.assertEqual(response.status, 500)
|
181 |
+
self.assertIn("Server Error: Unexpected Error", response.data.message)
|
182 |
+
|
183 |
+
class TestIsMe(unittest.TestCase):
|
184 |
+
|
185 |
+
@patch('service.DefaultService.check_email_token', return_value=False)
|
186 |
+
def test_none_token(self, mock_check_email_token):
|
187 |
+
request = Mock(spec=req.RequestIsMe)
|
188 |
+
request.token = None
|
189 |
+
response = is_me(request)
|
190 |
+
self.assertEqual(response.status, 400)
|
191 |
+
self.assertEqual(response.data.message, "token is empty")
|
192 |
+
|
193 |
+
@patch('service.DefaultService.check_email_token', return_value=Exception("Error"))
|
194 |
+
def test_invalid_token(self, mock_check_email_token):
|
195 |
+
request = Mock(spec=req.RequestIsMe)
|
196 |
+
request.token = "invalid_token"
|
197 |
+
response = is_me(request)
|
198 |
+
self.assertEqual(response.status, 500)
|
199 |
+
self.assertEqual(response.data.message, "Server Error")
|
200 |
+
|
201 |
+
@patch('service.DefaultService.UserRepository.getUserByEmail')
|
202 |
+
@patch('service.DefaultService.check_email_token')
|
203 |
+
def test_valid_token(self, mock_check_email_token, mock_getUserByEmail):
|
204 |
+
request = Mock(spec=req.RequestIsMe)
|
205 |
+
request.token = "valid_token"
|
206 |
+
mock_check_email_token.return_value = "user@example.com"
|
207 |
+
user = Mock()
|
208 |
+
user.id = "1"
|
209 |
+
mock_getUserByEmail.return_value = user
|
210 |
+
response = is_me(request)
|
211 |
+
self.assertEqual(response.status, 200)
|
212 |
+
self.assertEqual(response.data.user_id, 1)
|
213 |
+
|
214 |
+
@patch('service.DefaultService.check_email_token')
|
215 |
+
@patch('service.DefaultService.UserRepository.getUserByEmail')
|
216 |
+
def test_server_error(self,mock_user_repo, mock_check_email_token):
|
217 |
+
request = Mock(spec=req.RequestIsMe)
|
218 |
+
request.token = "some_token"
|
219 |
+
#1 of the 2 cases below or all cases
|
220 |
+
mock_user_repo.side_effect = Exception("Unexpected Error")
|
221 |
+
# mock_check_email_token.side_effect = Exception("Unexpected Error")
|
222 |
+
response = is_me(request)
|
223 |
+
self.assertEqual(response.status, 500)
|
224 |
+
self.assertIn("Server Error", response.data.message)
|
225 |
+
|
226 |
+
import io
|
227 |
+
from io import BytesIO
|
228 |
+
from fastapi import UploadFile
|
229 |
+
from io import BytesIO
|
230 |
+
import tempfile
|
231 |
+
class TestUpLoadFile(unittest.TestCase):
|
232 |
+
@patch('service.DefaultService.UserRepository.getEmailUserByIdFix')
|
233 |
+
@patch('service.DefaultService.cloudinary.uploader.upload')
|
234 |
+
@patch('service.DefaultService.check_email')
|
235 |
+
@patch('service.DefaultService.allowed_file')
|
236 |
+
def test_upload_image_success(self, mock_allowed_file, mock_check_email, mock_upload, mock_get_email):
|
237 |
+
mock_get_email.return_value = ["test@example.com"]
|
238 |
+
mock_check_email.return_value = True
|
239 |
+
mock_allowed_file.return_value = True
|
240 |
+
mock_upload.return_value = {"secure_url": "https://example.com/image.png"}
|
241 |
+
|
242 |
+
file_content = b"test image content"
|
243 |
+
file = io.BytesIO(file_content)
|
244 |
+
file.name = "test_image.png"
|
245 |
+
|
246 |
+
mock_request = MagicMock()
|
247 |
+
mock_request.user_id = 1
|
248 |
+
mock_request.files = MagicMock()
|
249 |
+
mock_request.files.file = file
|
250 |
+
mock_request.files.filename = file.name
|
251 |
+
response = upload_image_service(mock_request)
|
252 |
+
|
253 |
+
self.assertIsInstance(response, ResponseUploadImage)
|
254 |
+
self.assertEqual(response.status, 200)
|
255 |
+
self.assertEqual(response.status, 200)
|
256 |
+
self.assertEqual(response.data.url, "https://example.com/image.png")
|
257 |
+
|
258 |
+
@patch('service.DefaultService.UserRepository.getEmailUserByIdFix')
|
259 |
+
@patch('service.DefaultService.cloudinary.uploader.upload')
|
260 |
+
@patch('service.DefaultService.check_email')
|
261 |
+
@patch('service.DefaultService.allowed_file')
|
262 |
+
def test_upload_image_invalid_filetype(self, mock_allowed_file, mock_check_email, mock_upload, mock_get_email):
|
263 |
+
mock_get_email.return_value = ["test@example.com"]
|
264 |
+
mock_check_email.return_value = True
|
265 |
+
mock_allowed_file.return_value = False
|
266 |
+
mock_upload.return_value = {"secure_url": "https://example.com/image.png"}
|
267 |
+
|
268 |
+
file_content = b"test image content"
|
269 |
+
file = io.BytesIO(file_content)
|
270 |
+
file.name = "test_image.txt"
|
271 |
+
|
272 |
+
mock_request = MagicMock()
|
273 |
+
mock_request.user_id = 1
|
274 |
+
mock_request.files = MagicMock()
|
275 |
+
mock_request.files.file = file
|
276 |
+
mock_request.files.filename = file.name
|
277 |
+
response = upload_image_service(mock_request)
|
278 |
+
|
279 |
+
self.assertIsInstance(response, ReponseError)
|
280 |
+
self.assertEqual(response.status, 415)
|
281 |
+
self.assertEqual(response.data.message, "File type not allow")
|
282 |
+
|
283 |
+
@patch('service.DefaultService.UserRepository.getEmailUserByIdFix')
|
284 |
+
@patch('service.DefaultService.cloudinary.uploader.upload')
|
285 |
+
@patch('service.DefaultService.check_email')
|
286 |
+
@patch('service.DefaultService.allowed_file')
|
287 |
+
def test_upload_image_id_not_exist(self, mock_allowed_file, mock_check_email, mock_upload, mock_get_email):
|
288 |
+
mock_get_email.return_value = None
|
289 |
+
mock_request = MagicMock()
|
290 |
+
mock_request.user_id = 1
|
291 |
+
mock_request.files = []
|
292 |
+
response = upload_image_service(mock_request)
|
293 |
+
|
294 |
+
self.assertIsInstance(response, ReponseError)
|
295 |
+
self.assertEqual(response.status, 404)
|
296 |
+
self.assertEqual(response.data.message, "Id not exist")
|
297 |
+
|
298 |
+
@patch('service.DefaultService.UserRepository.getEmailUserByIdFix')
|
299 |
+
@patch('service.DefaultService.cloudinary.uploader.upload')
|
300 |
+
@patch('service.DefaultService.check_email')
|
301 |
+
@patch('service.DefaultService.allowed_file')
|
302 |
+
def test_upload_image_email_empty(self, mock_allowed_file, mock_check_email, mock_upload, mock_get_email):
|
303 |
+
mock_get_email.return_value = (None,)
|
304 |
+
mock_request = MagicMock()
|
305 |
+
mock_request.user_id = 1
|
306 |
+
mock_request.files = []
|
307 |
+
response = upload_image_service(mock_request)
|
308 |
+
|
309 |
+
self.assertIsInstance(response, ReponseError)
|
310 |
+
self.assertEqual(response.status, 400)
|
311 |
+
self.assertEqual(response.data.message, "Email is empty")
|
312 |
+
|
313 |
+
@patch('service.DefaultService.UserRepository.getEmailUserByIdFix')
|
314 |
+
@patch('service.DefaultService.cloudinary.uploader.upload')
|
315 |
+
@patch('service.DefaultService.check_email',return_value=False)
|
316 |
+
@patch('service.DefaultService.allowed_file')
|
317 |
+
def test_upload_image_email_invalid(self, mock_allowed_file, mock_check_email, mock_upload, mock_get_email):
|
318 |
+
mock_get_email.return_value = ("20133118",)
|
319 |
+
mock_request = MagicMock()
|
320 |
+
mock_request.user_id = 1
|
321 |
+
mock_request.files = []
|
322 |
+
response = upload_image_service(mock_request)
|
323 |
+
|
324 |
+
self.assertIsInstance(response, ReponseError)
|
325 |
+
self.assertEqual(response.status, 400)
|
326 |
+
self.assertEqual(response.data.message, "Email invalid")
|
327 |
+
|
328 |
+
@patch('service.DefaultService.UserRepository.getEmailUserByIdFix')
|
329 |
+
@patch('service.DefaultService.cloudinary.uploader.upload')
|
330 |
+
@patch('service.DefaultService.check_email', return_value=False)
|
331 |
+
@patch('service.DefaultService.allowed_file')
|
332 |
+
def test_upload_image_server_err(self, mock_allowed_file, mock_check_email, mock_upload, mock_get_email):
|
333 |
+
mock_get_email.side_effect = Exception("Unexpected Error")
|
334 |
+
mock_request = MagicMock()
|
335 |
+
mock_request.user_id = 1
|
336 |
+
mock_request.files = []
|
337 |
+
response = upload_image_service(mock_request)
|
338 |
+
|
339 |
+
self.assertIsInstance(response, ReponseError)
|
340 |
+
self.assertEqual(response.status, 500)
|
341 |
+
self.assertEqual(response.data.message, "Server Error")
|
342 |
+
|
343 |
+
if __name__ == '__main__':
|
344 |
+
unittest.main()
|
tests/test_service/test_FileService.py
ADDED
@@ -0,0 +1,471 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import unittest
|
2 |
+
from unittest.mock import patch,MagicMock
|
3 |
+
import sys
|
4 |
+
import os
|
5 |
+
app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
6 |
+
sys.path.insert(0, app_path)
|
7 |
+
from fastapi import UploadFile
|
8 |
+
from io import BytesIO
|
9 |
+
import tempfile
|
10 |
+
from service.FileService import deleteFile,download_folder,download_file,upload_files,deleteAllFile,listNameFiles
|
11 |
+
from request.RequestFile import RequestDeleteAllFile,RequestDeleteFile,RequestDownLoadFile,RequestDownLoadFolder,RequestGetNameFile,RequestUploadFile
|
12 |
+
from response import ResponseFile as res
|
13 |
+
from response import ResponseDefault as res1
|
14 |
+
|
15 |
+
class TestDeleteFile(unittest.TestCase):
|
16 |
+
@patch('service.FileService.UserRepository')
|
17 |
+
@patch('service.FileService.sf.check_email_service',return_value = 'example@example.com')
|
18 |
+
def test_delete_file_success(self,mock_support_function,mock_user_repo):
|
19 |
+
user_id = "1"
|
20 |
+
email = 'example@example.com'
|
21 |
+
name_file = "test1.pdf"
|
22 |
+
request = RequestDeleteFile(user_id=user_id,name_file=name_file)
|
23 |
+
response = deleteFile(request)
|
24 |
+
self.assertIsInstance(response, res.ResponseDeleteFile)
|
25 |
+
self.assertEqual(response.status, 200)
|
26 |
+
|
27 |
+
@patch('service.FileService.UserRepository')
|
28 |
+
@patch('service.FileService.sf.check_email_service', return_value=res1.ReponseError(status=400,data=res.Message(
|
29 |
+
message="Id not exist")))
|
30 |
+
def test_delete_file_id_not_exist(self, mock_support_function, mock_user_repo):
|
31 |
+
user_id = "1"
|
32 |
+
email = 'example@example.com'
|
33 |
+
name_file = "test1.pdf"
|
34 |
+
|
35 |
+
request = RequestDeleteFile(user_id=user_id,name_file=name_file)
|
36 |
+
response = deleteFile(request)
|
37 |
+
self.assertIsInstance(response, res1.ReponseError)
|
38 |
+
self.assertEqual(response.status, 400)
|
39 |
+
self.assertEqual(response.data, res.Message(message='Id not exist'))
|
40 |
+
|
41 |
+
@patch('service.FileService.UserRepository')
|
42 |
+
@patch('service.FileService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
43 |
+
message="Email is empty")))
|
44 |
+
def test_delete_file_email_empty(self,mock_support_function, mock_user_repo):
|
45 |
+
user_id = "1"
|
46 |
+
email = None
|
47 |
+
name_file = "test1.pdf"
|
48 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
49 |
+
request = RequestDeleteFile(user_id=user_id,name_file=name_file)
|
50 |
+
response = deleteFile(request)
|
51 |
+
self.assertIsInstance(response, res1.ReponseError)
|
52 |
+
self.assertEqual(response.status, 400)
|
53 |
+
self.assertEqual(response.data, res.Message(message='Email is empty'))
|
54 |
+
|
55 |
+
@patch('service.FileService.UserRepository')
|
56 |
+
@patch('service.FileService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
57 |
+
message="Email invalid")))
|
58 |
+
def test_delete_file_email_invalid(self,mock_support_function, mock_user_repo):
|
59 |
+
user_id = "1"
|
60 |
+
email = "201333"
|
61 |
+
name_file = "test1.pdf"
|
62 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
63 |
+
request = RequestDeleteFile(user_id=user_id,name_file=name_file)
|
64 |
+
response = deleteFile(request)
|
65 |
+
self.assertIsInstance(response, res1.ReponseError)
|
66 |
+
self.assertEqual(response.status, 400)
|
67 |
+
self.assertEqual(response.data, res.Message(message='Email invalid'))
|
68 |
+
|
69 |
+
@patch('service.FileService.UserRepository.getEmailUserByIdFix')
|
70 |
+
@patch('service.FileService.sf_dropbox.delete_file')
|
71 |
+
@patch('service.FileService.sf.check_email_service', return_value='example@example.com')
|
72 |
+
def test_delete_file_server_error(self, mock_support_function, mock_delete_file,mock_user_repo):
|
73 |
+
user_id = "1"
|
74 |
+
name_file = "test1.pdf"
|
75 |
+
mock_delete_file.side_effect = Exception("Some error")
|
76 |
+
request = RequestDeleteFile(user_id=user_id,name_file=name_file)
|
77 |
+
response = deleteFile(request)
|
78 |
+
self.assertIsInstance(response, res.ReponseError)
|
79 |
+
self.assertEqual(response.status, 500)
|
80 |
+
self.assertEqual(response.data.message, f"delete {name_file} error")
|
81 |
+
|
82 |
+
@patch('service.FileService.UserRepository')
|
83 |
+
@patch('service.FileService.sf.check_email_service', return_value='example@example.com')
|
84 |
+
def test_delete_file_namefile_empty(self,mock_support_function, mock_user_repo):
|
85 |
+
user_id = "1"
|
86 |
+
email = "201333@gmail.com"
|
87 |
+
name_file = ""
|
88 |
+
request = RequestDeleteFile(user_id=user_id,name_file=name_file)
|
89 |
+
response = deleteFile(request)
|
90 |
+
self.assertIsInstance(response, res.ReponseError)
|
91 |
+
self.assertEqual(response.status, 400)
|
92 |
+
self.assertEqual(response.data, res.Message(message='Name file is empty'))
|
93 |
+
|
94 |
+
class TestDeleteAllFile(unittest.TestCase):
|
95 |
+
@patch('service.FileService.UserRepository')
|
96 |
+
@patch('service.FileService.sf_dropbox.delete_all_files_in_folder',return_value = True)
|
97 |
+
@patch('service.FileService.sf.check_email_service', return_value='example@example.com')
|
98 |
+
def test_delete_all_file_success(self,mock_sf,mock_delete_folder,mock_user_repo):
|
99 |
+
user_id = "1"
|
100 |
+
email = 'example@example.com'
|
101 |
+
request = RequestDeleteAllFile(user_id=user_id)
|
102 |
+
response = deleteAllFile(request)
|
103 |
+
self.assertIsInstance(response, res.ResponseDeleteAllFile)
|
104 |
+
self.assertEqual(response.status, 200)
|
105 |
+
self.assertEqual(response.data, res.Message(message='Delete all file success'))
|
106 |
+
|
107 |
+
@patch('service.FileService.UserRepository')
|
108 |
+
@patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message(
|
109 |
+
message="Id not exist")))
|
110 |
+
def test_delete_all_file_id_not_exist(self,mock_sf,mock_user_repo):
|
111 |
+
user_id = "1"
|
112 |
+
request = RequestDeleteAllFile(user_id=user_id)
|
113 |
+
response = deleteAllFile(request)
|
114 |
+
self.assertIsInstance(response, res.ReponseError)
|
115 |
+
self.assertEqual(response.status, 400)
|
116 |
+
self.assertEqual(response.data, res.Message(message='Id not exist'))
|
117 |
+
|
118 |
+
@patch('service.FileService.UserRepository')
|
119 |
+
@patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message(
|
120 |
+
message="Email is empty")))
|
121 |
+
def test_delete_all_file_email_empty(self,mock_sf,mock_user_repo):
|
122 |
+
user_id = "1"
|
123 |
+
email = None
|
124 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
125 |
+
request = RequestDeleteAllFile(user_id=user_id)
|
126 |
+
response = deleteAllFile(request)
|
127 |
+
self.assertIsInstance(response, res.ReponseError)
|
128 |
+
self.assertEqual(response.status, 400)
|
129 |
+
self.assertEqual(response.data, res.Message(message='Email is empty'))
|
130 |
+
|
131 |
+
@patch('service.FileService.UserRepository')
|
132 |
+
@patch('service.FileService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message(
|
133 |
+
message="Email invalid")))
|
134 |
+
def test_delete_all_file_email_invalid(self, mock_sf, mock_user_repo):
|
135 |
+
user_id = "1"
|
136 |
+
email = "201333"
|
137 |
+
request = RequestDeleteAllFile(user_id=user_id)
|
138 |
+
response = deleteAllFile(request)
|
139 |
+
self.assertIsInstance(response, res.ReponseError)
|
140 |
+
self.assertEqual(response.status, 400)
|
141 |
+
self.assertEqual(response.data, res.Message(message='Email invalid'))
|
142 |
+
|
143 |
+
@patch('service.FileService.UserRepository')
|
144 |
+
@patch('service.FileService.sf_dropbox.delete_all_files_in_folder')
|
145 |
+
@patch('service.FileService.sf.check_email_service', return_value="20133@gmail.com")
|
146 |
+
def test_delete_all_file_server_err(self,mock_sf,mock_delete_folder,mock_user_repo):
|
147 |
+
user_id = "1"
|
148 |
+
mock_delete_folder.side_effect = Exception("Some error")
|
149 |
+
request = RequestDeleteAllFile(user_id=user_id)
|
150 |
+
response = deleteAllFile(request)
|
151 |
+
self.assertIsInstance(response, res.ReponseError)
|
152 |
+
self.assertEqual(response.status, 500)
|
153 |
+
self.assertEqual(response.data, res.Message(message='Delete all file error'))
|
154 |
+
|
155 |
+
class TestListNameFiles(unittest.TestCase):
|
156 |
+
@patch('service.FileService.UserRepository')
|
157 |
+
@patch('service.FileService.sf_dropbox.list_files')
|
158 |
+
@patch('service.FileService.sf.check_email_service', return_value="20133118@gmail.com")
|
159 |
+
def test_list_name_file_success(self,mock_sf, mock_list_files, mock_user_repo):
|
160 |
+
user_id = "1"
|
161 |
+
email = "quangphuc@gmail.com"
|
162 |
+
list_files = [
|
163 |
+
'demo1.pdf', 'CV_VoNhuY_Java.pdf', 'VanHoangLuong_DangXuanBach_TLCN.docx',
|
164 |
+
'THÔNG-TIN-TUYỂN-DỤNG-Java.pdf', 'baitap_qlpv_nhom14.docx', 'PMBOK2012-5rd Edition.pdf',
|
165 |
+
'BaoCaoThucTapTotnghiep_20133059_Fpt_Software.docx'
|
166 |
+
]
|
167 |
+
mock_list_files.return_value = list_files
|
168 |
+
request = RequestGetNameFile(user_id=user_id)
|
169 |
+
response = listNameFiles(request)
|
170 |
+
self.assertIsInstance(response, res.ResponseGetNameFile)
|
171 |
+
self.assertEqual(response.status, 200)
|
172 |
+
self.assertEqual(response.data.files, list_files)
|
173 |
+
self.assertEqual(len(response.data.files), 7)
|
174 |
+
|
175 |
+
@patch('service.FileService.UserRepository.getEmailUserByIdFix')
|
176 |
+
@patch('service.FileService.sf_dropbox.list_files')
|
177 |
+
@patch('service.FileService.sf.check_email_service', side_effect=Exception("Some error"))
|
178 |
+
def test_listNameFiles_server_error(self, mock_sf, mock_list_files, mock_getEmailUserByIdFix):
|
179 |
+
request = RequestGetNameFile(user_id="1")
|
180 |
+
response = listNameFiles(request)
|
181 |
+
self.assertEqual(response.status, 500)
|
182 |
+
self.assertEqual(response.data.message, "Server Error")
|
183 |
+
|
184 |
+
@patch('service.FileService.UserRepository')
|
185 |
+
@patch('service.FileService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
186 |
+
message="Id not exist")))
|
187 |
+
def test_list_name_files_id_not_exist(self, mock_sf, mock_user_repo):
|
188 |
+
user_id = "1"
|
189 |
+
email = 'example@example.com'
|
190 |
+
name_file = "test1.pdf"
|
191 |
+
request = RequestGetNameFile(user_id=user_id)
|
192 |
+
response = listNameFiles(request)
|
193 |
+
self.assertIsInstance(response, res1.ReponseError)
|
194 |
+
self.assertEqual(response.status, 400)
|
195 |
+
self.assertEqual(response.data, res1.Message(message='Id not exist'))
|
196 |
+
|
197 |
+
@patch('service.FileService.UserRepository')
|
198 |
+
@patch('service.FileService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
199 |
+
message="Email is empty")))
|
200 |
+
def test_list_name_files_email_empty(self,mock_sf, mock_user_repo):
|
201 |
+
user_id = "1"
|
202 |
+
email = None
|
203 |
+
name_file = "test1.pdf"
|
204 |
+
request = RequestGetNameFile(user_id=user_id)
|
205 |
+
response = listNameFiles(request)
|
206 |
+
self.assertIsInstance(response, res1.ReponseError)
|
207 |
+
self.assertEqual(response.status, 400)
|
208 |
+
self.assertEqual(response.data, res.Message(message='Email is empty'))
|
209 |
+
|
210 |
+
@patch('service.FileService.UserRepository')
|
211 |
+
@patch('service.FileService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
212 |
+
message="Email invalid")))
|
213 |
+
def test_list_name_files_email_invalid(self, mock_sf, mock_user_repo):
|
214 |
+
user_id = "1"
|
215 |
+
email = "201333"
|
216 |
+
name_file = "test1.pdf"
|
217 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
218 |
+
request = RequestGetNameFile(user_id=user_id)
|
219 |
+
response = listNameFiles(request)
|
220 |
+
self.assertIsInstance(response, res1.ReponseError)
|
221 |
+
self.assertEqual(response.status, 400)
|
222 |
+
self.assertEqual(response.data, res.Message(message='Email invalid'))
|
223 |
+
|
224 |
+
class TestDownLoadFolder(unittest.TestCase):
|
225 |
+
@patch('service.FileService.UserRepository')
|
226 |
+
@patch('service.FileService.sf.check_email_service',return_value="example@example.com")
|
227 |
+
def test_download_folder_success(self,mock_sf, mock_user_repo):
|
228 |
+
user_id = "1"
|
229 |
+
email = 'example@example.com'
|
230 |
+
request = RequestDownLoadFolder(user_id=user_id)
|
231 |
+
response = download_folder(request)
|
232 |
+
self.assertIsInstance(response, res.ResponseDownloadFolder)
|
233 |
+
self.assertEqual(response.status, 200)
|
234 |
+
self.assertEqual(response.data, res.Message(message=f'Downloaded folder {email} success'))
|
235 |
+
|
236 |
+
@patch('service.FileService.UserRepository.getEmailUserByIdFix')
|
237 |
+
@patch('service.FileService.sf_dropbox.download_folder')
|
238 |
+
@patch('service.FileService.sf.check_email_service', return_value="example@gmail.com")
|
239 |
+
def test_download_folder_server_error(self, mock_sf, mock_download_folder, mock_getEmailUserByIdFix):
|
240 |
+
mock_download_folder.side_effect = Exception('Test exception')
|
241 |
+
request = RequestDownLoadFolder(user_id= "1")
|
242 |
+
response = download_folder(request)
|
243 |
+
self.assertEqual(response.status, 500)
|
244 |
+
self.assertEqual(response.data.message, "Server error")
|
245 |
+
|
246 |
+
@patch('service.FileService.UserRepository')
|
247 |
+
@patch('service.FileService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
248 |
+
message="Id not exist")))
|
249 |
+
def test_download_folder_id_not_exist(self,mock_sf,mock_user_repo):
|
250 |
+
user_id = "1"
|
251 |
+
request = RequestDownLoadFolder(user_id=user_id)
|
252 |
+
response = download_folder(request)
|
253 |
+
self.assertIsInstance(response, res1.ReponseError)
|
254 |
+
self.assertEqual(response.status, 400)
|
255 |
+
self.assertEqual(response.data, res1.Message(message='Id not exist'))
|
256 |
+
|
257 |
+
@patch('service.FileService.UserRepository')
|
258 |
+
@patch('service.FileService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
259 |
+
message="Email is empty")))
|
260 |
+
def test_download_folder_email_empty(self,mock_sf, mock_user_repo):
|
261 |
+
user_id = "1"
|
262 |
+
email = None
|
263 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
264 |
+
request = RequestDownLoadFolder(user_id=user_id)
|
265 |
+
response = download_folder(request)
|
266 |
+
self.assertIsInstance(response, res1.ReponseError)
|
267 |
+
self.assertEqual(response.status, 400)
|
268 |
+
self.assertEqual(response.data, res.Message(message='Email is empty'))
|
269 |
+
|
270 |
+
@patch('service.FileService.UserRepository')
|
271 |
+
@patch('service.FileService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
272 |
+
message="Email invalid")))
|
273 |
+
def test_download_folder_email_invalid(self,mock_sf, mock_user_repo):
|
274 |
+
user_id = "1"
|
275 |
+
email = "201333"
|
276 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
277 |
+
request = RequestDownLoadFolder(user_id=user_id)
|
278 |
+
response = download_folder(request)
|
279 |
+
self.assertIsInstance(response, res1.ReponseError)
|
280 |
+
self.assertEqual(response.status, 400)
|
281 |
+
self.assertEqual(response.data, res1.Message(message='Email invalid'))
|
282 |
+
|
283 |
+
class TestDownLoadFile(unittest.TestCase):
|
284 |
+
@patch('service.FileService.UserRepository')
|
285 |
+
@patch('service.FileService.sf.check_email_service', return_value="quangphuc@gmail.com")
|
286 |
+
def test_download_file_success(self, mock_sf, mock_user_repo):
|
287 |
+
user_id = "1"
|
288 |
+
email = "quangphuc@gmail.com"
|
289 |
+
name_file = "demo1.pdf"
|
290 |
+
request = RequestDownLoadFile(user_id=user_id,name_file=name_file)
|
291 |
+
response = download_file(request)
|
292 |
+
self.assertIsInstance(response, res.ResponseDownloadFile)
|
293 |
+
self.assertEqual(response.status, 200)
|
294 |
+
self.assertEqual(response.data, res.Message(message=f"Downloaded file '{name_file}' by email: '{email}' success"))
|
295 |
+
|
296 |
+
@patch('service.FileService.UserRepository')
|
297 |
+
@patch('service.FileService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
298 |
+
message="Id not exist")))
|
299 |
+
def test_download_file_id_not_exist(self, mock_sf,mock_user_repo):
|
300 |
+
user_id = "1"
|
301 |
+
email = "quangphuc@gmail.com"
|
302 |
+
name_file = "demo1.pdf"
|
303 |
+
request = RequestDownLoadFile(user_id=user_id,name_file=name_file)
|
304 |
+
response = download_file(request)
|
305 |
+
self.assertIsInstance(response, res1.ReponseError)
|
306 |
+
self.assertEqual(response.status, 400)
|
307 |
+
self.assertEqual(response.data, res.Message(message='Id not exist'))
|
308 |
+
|
309 |
+
@patch('service.FileService.UserRepository')
|
310 |
+
@patch('service.FileService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
311 |
+
message="Email is empty")))
|
312 |
+
def test_download_file_email_empty(self,mock_sf, mock_user_repo):
|
313 |
+
user_id = "1"
|
314 |
+
email = None
|
315 |
+
name_file = "demo1.pdf"
|
316 |
+
request = RequestDownLoadFile(user_id=user_id,name_file=name_file)
|
317 |
+
response = download_file(request)
|
318 |
+
self.assertIsInstance(response, res1.ReponseError)
|
319 |
+
self.assertEqual(response.status, 400)
|
320 |
+
self.assertEqual(response.data, res1.Message(message='Email is empty'))
|
321 |
+
|
322 |
+
@patch('service.FileService.UserRepository')
|
323 |
+
@patch('service.FileService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
324 |
+
message="Email invalid")))
|
325 |
+
def test_download_file_email_invalid(self, mock_sf, mock_user_repo):
|
326 |
+
user_id = "1"
|
327 |
+
email = "201333"
|
328 |
+
name_file = "demo1.pdf"
|
329 |
+
request = RequestDownLoadFile(user_id=user_id,name_file=name_file)
|
330 |
+
response = download_file(request)
|
331 |
+
self.assertIsInstance(response, res1.ReponseError)
|
332 |
+
self.assertEqual(response.status, 400)
|
333 |
+
self.assertEqual(response.data, res.Message(message='Email invalid'))
|
334 |
+
|
335 |
+
@patch('service.FileService.UserRepository')
|
336 |
+
@patch('service.FileService.sf.check_email_service', return_value="20133@gmail.com")
|
337 |
+
def test_download_file_name_file_empty(self,mock_sf, mock_user_repo):
|
338 |
+
user_id = "1"
|
339 |
+
email = "201333@gmail.com"
|
340 |
+
name_file = ""
|
341 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
342 |
+
request = RequestDownLoadFile(user_id=user_id,name_file=name_file)
|
343 |
+
response = download_file(request)
|
344 |
+
self.assertIsInstance(response, res.ReponseError)
|
345 |
+
self.assertEqual(response.status, 400)
|
346 |
+
self.assertEqual(response.data, res.Message(message='name_file is empty'))
|
347 |
+
|
348 |
+
@patch('service.FileService.UserRepository.getEmailUserByIdFix')
|
349 |
+
@patch('service.FileService.sf_dropbox.search_and_download_file')
|
350 |
+
@patch('service.FileService.sf.check_email_service', return_value="20133@gmail.com")
|
351 |
+
def test_download_file_server_error(self,mock_sf, mock_search_and_download_file, mock_getEmailUserByIdFix):
|
352 |
+
# mock_getEmailUserByIdFix.side_effect = Exception('Test exception')
|
353 |
+
mock_search_and_download_file.side_effect = Exception('Test exception')
|
354 |
+
request = RequestDownLoadFile(user_id= "1",name_file="test1.txt")
|
355 |
+
response = download_file(request)
|
356 |
+
self.assertEqual(response.status, 500)
|
357 |
+
self.assertEqual(response.data.message, "Server error")
|
358 |
+
|
359 |
+
class TestUploadFileService(unittest.TestCase):
|
360 |
+
@patch('service.FileService.UserRepository')
|
361 |
+
@patch('service.FileService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
362 |
+
message="Email invalid")))
|
363 |
+
def test_upload_files_invalid_email(self, mock_sf, mock_user_repo):
|
364 |
+
user_id = "1"
|
365 |
+
email = "20133118"
|
366 |
+
request = RequestUploadFile(user_id=user_id, files=[])
|
367 |
+
response = upload_files(request)
|
368 |
+
self.assertIsInstance(response, res1.ReponseError)
|
369 |
+
self.assertEqual(response.status, 400)
|
370 |
+
self.assertEqual(response.data.message, "Email invalid")
|
371 |
+
|
372 |
+
@patch('service.FileService.UserRepository')
|
373 |
+
@patch('service.FileService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
374 |
+
message="Email is empty")))
|
375 |
+
def test_upload_files_empty_email(self, mock_sf, mock_user_repo):
|
376 |
+
user_id = "1"
|
377 |
+
email = None
|
378 |
+
request = RequestUploadFile(user_id=user_id, files=[])
|
379 |
+
response = upload_files(request)
|
380 |
+
self.assertIsInstance(response, res1.ReponseError)
|
381 |
+
self.assertEqual(response.status, 400)
|
382 |
+
self.assertEqual(response.data.message, "Email is empty")
|
383 |
+
|
384 |
+
@patch('service.FileService.UserRepository')
|
385 |
+
@patch('service.FileService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
386 |
+
message="Id not exist")))
|
387 |
+
def test_upload_files_id_not_exist(self, mock_sf, mock_user_repo):
|
388 |
+
user_id = "1"
|
389 |
+
email = 'mang1@gmail.com'
|
390 |
+
mock_user_repo.getEmailUserByIdFix.return_value = None
|
391 |
+
request = RequestUploadFile(user_id=user_id, files=[])
|
392 |
+
response = upload_files(request)
|
393 |
+
self.assertIsInstance(response, res1.ReponseError)
|
394 |
+
self.assertEqual(response.status, 400)
|
395 |
+
self.assertEqual(response.data.message, "Id not exist")
|
396 |
+
|
397 |
+
@patch('service.FileService.sf_dropbox.upload_file')
|
398 |
+
@patch('service.FileService.UserRepository.getEmailUserByIdFix')
|
399 |
+
@patch('service.FileService.allowed_file')
|
400 |
+
@patch('service.FileService.check_email')
|
401 |
+
@patch('service.FileService.os.makedirs')
|
402 |
+
@patch('service.FileService.sf.check_email_service', return_value="mang1@gmail.com")
|
403 |
+
@patch('builtins.open', new_callable=unittest.mock.mock_open)
|
404 |
+
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):
|
405 |
+
user_id = "1"
|
406 |
+
email = 'mang1@gmail.com'
|
407 |
+
mock_get_email_user_by_id.return_value = (email,)
|
408 |
+
mock_check_email.return_value = True
|
409 |
+
mock_allowed_file.return_value = True
|
410 |
+
file_content = b"Test file content"
|
411 |
+
file = UploadFile(filename='test.pdf', file=BytesIO(file_content))
|
412 |
+
with tempfile.TemporaryDirectory() as temp_dir:
|
413 |
+
temp_dir_path = os.path.join(temp_dir, email)
|
414 |
+
os.makedirs(temp_dir_path, exist_ok=True)
|
415 |
+
file_path = os.path.join(temp_dir_path, file.filename)
|
416 |
+
mock_open.return_value.write.side_effect = lambda content: None if content == file_content else None
|
417 |
+
mock_upload_file.side_effect = lambda src, dst: None
|
418 |
+
request = RequestUploadFile(user_id=user_id, files=[file])
|
419 |
+
mock_makedirs.side_effect = lambda path, exist_ok: None
|
420 |
+
response = upload_files(request)
|
421 |
+
self.assertIsInstance(response, res.ResponseUploadedFile)
|
422 |
+
self.assertEqual(response.status, 200)
|
423 |
+
self.assertEqual(response.data.message, "Load file success")
|
424 |
+
# Adjust the expected call to match the actual call
|
425 |
+
expected_src_path = os.path.join("/code/temp", email, file.filename).replace("\\", "/")
|
426 |
+
expected_dst_path = f"/{email}/{file.filename}"
|
427 |
+
actual_src_path, actual_dst_path = mock_upload_file.call_args[0]
|
428 |
+
actual_src_path = actual_src_path.replace("\\", "/")
|
429 |
+
print(actual_dst_path)
|
430 |
+
print(actual_src_path)
|
431 |
+
assert expected_src_path == actual_src_path and expected_dst_path == actual_dst_path
|
432 |
+
|
433 |
+
@patch('service.FileService.sf_dropbox.upload_file')
|
434 |
+
@patch('service.FileService.UserRepository.getEmailUserByIdFix')
|
435 |
+
@patch('service.FileService.allowed_file')
|
436 |
+
@patch('service.FileService.check_email')
|
437 |
+
@patch('service.FileService.os.makedirs')
|
438 |
+
@patch('service.FileService.shutil.copyfileobj')
|
439 |
+
@patch('service.FileService.sf.check_email_service', return_value="mang1@gmail.com")
|
440 |
+
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):
|
441 |
+
user_id = "1"
|
442 |
+
email = 'mang1@gmail.com'
|
443 |
+
mock_get_email_user_by_id.return_value = (email,)
|
444 |
+
mock_check_email.return_value = True
|
445 |
+
mock_allowed_file.return_value = False
|
446 |
+
file_content = b"Test file content"
|
447 |
+
file = UploadFile(filename='test.exe', file=BytesIO(file_content))
|
448 |
+
request = RequestUploadFile(user_id=user_id, files=[file])
|
449 |
+
response = upload_files(request)
|
450 |
+
self.assertIsInstance(response, res.ReponseError)
|
451 |
+
self.assertEqual(response.status, 415)
|
452 |
+
self.assertEqual(response.data.message, "File type not allow")
|
453 |
+
mock_upload_file.assert_not_called()
|
454 |
+
|
455 |
+
@patch('service.FileService.UserRepository.getEmailUserByIdFix')
|
456 |
+
@patch('service.FileService.sf_dropbox.upload_file')
|
457 |
+
@patch('service.FileService.sf.check_email_service', return_value="test_email@example.com")
|
458 |
+
def test_upload_files_error_handling(self,mock_sf, mock_upload_file, mock_getEmailUserByIdFix):
|
459 |
+
mock_upload_file.side_effect = Exception('Test exception')
|
460 |
+
request = MagicMock()
|
461 |
+
request.user_id = "1"
|
462 |
+
request.files = [
|
463 |
+
MagicMock(filename='test_file.txt', file=MagicMock())
|
464 |
+
]
|
465 |
+
response = upload_files(request)
|
466 |
+
self.assertEqual(response.status, 500)
|
467 |
+
self.assertEqual(response.data.message, "Load file error")
|
468 |
+
|
469 |
+
|
470 |
+
if __name__ == '__main__':
|
471 |
+
unittest.main()
|
tests/test_service/test_LoginService.py
ADDED
@@ -0,0 +1,560 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import unittest
|
2 |
+
import sys
|
3 |
+
import os
|
4 |
+
app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
5 |
+
sys.path.insert(0, app_path)
|
6 |
+
from service import UserService
|
7 |
+
from request import RequestUser as req
|
8 |
+
from response import ResponseUser as res
|
9 |
+
from unittest.mock import patch, Mock,MagicMock
|
10 |
+
from typing import Optional
|
11 |
+
from response import ResponseDefault as res1
|
12 |
+
|
13 |
+
|
14 |
+
class TestUpdateUserInfoFunction(unittest.TestCase):
|
15 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
16 |
+
@patch('service.UserService.check_email')
|
17 |
+
@patch('service.UserService.get_user1')
|
18 |
+
@patch('service.UserService.UserInfoRepository.getUserInfo')
|
19 |
+
@patch('service.UserService.UserInfoRepository.updateUserInfo')
|
20 |
+
@patch('service.UserService.UserInfoRepository.addUserInfo')
|
21 |
+
@patch('service.UserService.update_info_user')
|
22 |
+
@patch('service.UserService.sf.check_email_empty_invalid', return_value=True)
|
23 |
+
@patch('service.UserService.sf.check_email_service', return_value="old_email@example.com")
|
24 |
+
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):
|
25 |
+
request = req.RequestUpdateUserInfo(
|
26 |
+
user_id = "1",
|
27 |
+
email="new_email@example.com",
|
28 |
+
uid="uid123",
|
29 |
+
display_name="New Name",
|
30 |
+
photo_url="http://photo.url"
|
31 |
+
)
|
32 |
+
mock_get_user.return_value = Mock() # Simulate user exists
|
33 |
+
mock_get_user_info.return_value = Mock() # Simulate user info exists
|
34 |
+
response = UserService.update_user_info(request)
|
35 |
+
self.assertEqual(response.status, 200)
|
36 |
+
self.assertIsInstance(response, res.ResponseUpdateUserInfo)
|
37 |
+
self.assertEqual(response.data.message, "User info updated successfully")
|
38 |
+
|
39 |
+
@patch('service.UserService.get_user1')
|
40 |
+
@patch('service.UserService.UserInfoRepository.getUserInfo')
|
41 |
+
@patch('service.UserService.UserInfoRepository.updateUserInfo')
|
42 |
+
@patch('service.UserService.UserInfoRepository.addUserInfo')
|
43 |
+
@patch('service.UserService.update_info_user')
|
44 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
45 |
+
@patch('service.UserService.sf.check_email_empty_invalid', side_effect=Exception("Error"))
|
46 |
+
@patch('service.UserService.sf.check_email_service', return_value="old_email@example.com")
|
47 |
+
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):
|
48 |
+
request = MagicMock()
|
49 |
+
request.email = 'test@example.com'
|
50 |
+
request.user_id = 'test_user_id'
|
51 |
+
request.uid = 'test_uid'
|
52 |
+
request.display_name = 'Test User'
|
53 |
+
request.photo_url = 'https://example.com/photo.jpg'
|
54 |
+
response = UserService.update_user_info(request)
|
55 |
+
self.assertEqual(response.status, 500)
|
56 |
+
self.assertEqual(response.data.message, "Server Error")
|
57 |
+
|
58 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
59 |
+
@patch('service.UserService.check_email')
|
60 |
+
@patch('service.UserService.get_user1')
|
61 |
+
@patch('service.UserService.UserInfoRepository.getUserInfo')
|
62 |
+
@patch('service.UserService.UserInfoRepository.updateUserInfo')
|
63 |
+
@patch('service.UserService.UserInfoRepository.addUserInfo')
|
64 |
+
@patch('service.UserService.update_info_user')
|
65 |
+
@patch('service.UserService.sf.check_email_empty_invalid', return_value=True)
|
66 |
+
@patch('service.UserService.sf.check_email_service', return_value="old_email@example.com")
|
67 |
+
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):
|
68 |
+
request = req.RequestUpdateUserInfo(
|
69 |
+
user_id = "1",
|
70 |
+
email = "new_email@example.com",
|
71 |
+
uid="uid123",
|
72 |
+
display_name="New Name",
|
73 |
+
photo_url="http://photo.url"
|
74 |
+
)
|
75 |
+
mock_get_user.return_value = Mock()
|
76 |
+
mock_get_user_info.return_value = None
|
77 |
+
response = UserService.update_user_info(request)
|
78 |
+
self.assertEqual(response.status, 200)
|
79 |
+
self.assertIsInstance(response, res.ResponseUpdateUserInfo)
|
80 |
+
self.assertEqual(response.data.message, "User info updated successfully")
|
81 |
+
mock_update_user_info.assert_not_called()
|
82 |
+
mock_add_user_info.assert_called_once()
|
83 |
+
mock_update_info_user.assert_called_once()
|
84 |
+
|
85 |
+
|
86 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
87 |
+
@patch('service.UserService.sf.check_email_empty_invalid', return_value=True)
|
88 |
+
@patch('service.UserService.sf.check_email_service', return_value= res1.ReponseError(status=400, data=res.Message(
|
89 |
+
message="Id not exist")))
|
90 |
+
def test_update_user_info_id_not_exist(self, mock_check1,mock_check2,mock_get_email_by_id):
|
91 |
+
request = req.RequestUpdateUserInfo(
|
92 |
+
user_id= "1",
|
93 |
+
email="new_email@example.com",
|
94 |
+
uid="uid123",
|
95 |
+
display_name="New Name",
|
96 |
+
photo_url="http://photo.url"
|
97 |
+
)
|
98 |
+
response = UserService.update_user_info(request)
|
99 |
+
self.assertEqual(response.status, 400)
|
100 |
+
self.assertEqual(response.data.message, "Id not exist")
|
101 |
+
|
102 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
103 |
+
@patch('service.UserService.sf.check_email_empty_invalid', return_value=True)
|
104 |
+
@patch('service.UserService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
105 |
+
message="Email is empty")))
|
106 |
+
def test_update_user_info_email_empty(self,mock_check1,mock_check2, mock_get_email_by_id):
|
107 |
+
request = req.RequestUpdateUserInfo(
|
108 |
+
user_id= "1",
|
109 |
+
email=None,
|
110 |
+
uid="uid123",
|
111 |
+
display_name="New Name",
|
112 |
+
photo_url="http://photo.url"
|
113 |
+
)
|
114 |
+
response = UserService.update_user_info(request)
|
115 |
+
self.assertEqual(response.status, 400)
|
116 |
+
self.assertEqual(response.data.message, "Email is empty")
|
117 |
+
|
118 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
119 |
+
@patch('service.UserService.check_email')
|
120 |
+
@patch('service.UserService.sf.check_email_empty_invalid', return_value=True)
|
121 |
+
@patch('service.UserService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
122 |
+
message="Email invalid")))
|
123 |
+
def test_update_user_info_email_invalid(self, mock_check1, mock_check2, mock_check_email, mock_get_email_by_id):
|
124 |
+
request = req.RequestUpdateUserInfo(
|
125 |
+
email="invalid_email",
|
126 |
+
user_id= "1",
|
127 |
+
uid="uid123",
|
128 |
+
display_name="New Name",
|
129 |
+
photo_url="http://photo.url"
|
130 |
+
)
|
131 |
+
response = UserService.update_user_info(request)
|
132 |
+
self.assertEqual(response.status, 400)
|
133 |
+
self.assertEqual(response.data.message, "Email invalid")
|
134 |
+
|
135 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
136 |
+
@patch('service.UserService.check_email')
|
137 |
+
@patch('service.UserService.get_user1')
|
138 |
+
@patch('service.UserService.sf.check_email_service',return_value="new_email@example.com")
|
139 |
+
def test_update_user_info_email_or_password_error(self,mock_check1, mock_get_user, mock_check_email, mock_get_email_by_id):
|
140 |
+
request = req.RequestUpdateUserInfo(
|
141 |
+
user_id= "1",
|
142 |
+
email="new_email@example.com",
|
143 |
+
uid="uid123",
|
144 |
+
display_name="New Name",
|
145 |
+
photo_url="http://photo.url"
|
146 |
+
)
|
147 |
+
mock_get_user.return_value = None
|
148 |
+
response = UserService.update_user_info(request)
|
149 |
+
self.assertEqual(response.status, 404)
|
150 |
+
self.assertEqual(response.data.message, "Not found user")
|
151 |
+
|
152 |
+
class TestCheckInfoGoogle(unittest.TestCase):
|
153 |
+
@patch('service.UserService.UserRepository')
|
154 |
+
@patch('service.UserService.check_email')
|
155 |
+
@patch('service.UserService.UserInfoRepository')
|
156 |
+
@patch('service.UserService.sf.check_email_service', return_value="test@gmail.com")
|
157 |
+
def test_check_info_google_success(self,mock_check1,mock_user_info_repo,mock_check_email,mock_user_repo):
|
158 |
+
user_id = "1"
|
159 |
+
email ="test@gmail.com"
|
160 |
+
mock_user_info_repo.getUserInfo.return_value = Mock()
|
161 |
+
request = req.RequestCheckInfoGoogle(user_id=user_id)
|
162 |
+
response = UserService.check_info_google(request)
|
163 |
+
self.assertEqual(response.status, 200)
|
164 |
+
self.assertEqual(response.data.check, True)
|
165 |
+
|
166 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
167 |
+
@patch('service.UserService.UserRepository.getEmailUserById')
|
168 |
+
@patch('service.UserService.UserInfoRepository.getUserInfo')
|
169 |
+
@patch('service.UserService.sf.check_email_service', side_effect = Exception("error"))
|
170 |
+
def test_check_info_google_server_error(self,mock_check1, mock_getUserInfo, mock_getEmailUserById, mock_getEmailUserByIdFix):
|
171 |
+
mock_getEmailUserByIdFix.side_effect = Exception('Test exception')
|
172 |
+
request = MagicMock()
|
173 |
+
request.user_id = "1"
|
174 |
+
response = UserService.check_info_google(request)
|
175 |
+
self.assertEqual(response.status, 500)
|
176 |
+
self.assertEqual(response.data.message, "Server Error")
|
177 |
+
|
178 |
+
@patch('service.UserService.UserRepository')
|
179 |
+
@patch('service.UserService.check_email')
|
180 |
+
@patch('service.UserService.UserInfoRepository')
|
181 |
+
@patch('service.UserService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message(
|
182 |
+
message="Id not exist")))
|
183 |
+
def test_check_info_google_id_not_exist(self,mock_check1, mock_user_info_repo,mock_check_email,mock_user_repo):
|
184 |
+
user_id = "1"
|
185 |
+
request = req.RequestCheckInfoGoogle(user_id=user_id)
|
186 |
+
response = UserService.check_info_google(request)
|
187 |
+
self.assertEqual(response.status, 400)
|
188 |
+
self.assertEqual(response.data.message, "Id not exist")
|
189 |
+
|
190 |
+
@patch('service.UserService.UserRepository')
|
191 |
+
@patch('service.UserService.check_email')
|
192 |
+
@patch('service.UserService.UserInfoRepository')
|
193 |
+
@patch('service.UserService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message(
|
194 |
+
message="Email is empty")))
|
195 |
+
def test_check_info_google_email_empty(self, mock_check1, mock_user_info_repo, mock_check_email,mock_user_repo):
|
196 |
+
user_id = "1"
|
197 |
+
email ="quangphuc@gmail.com"
|
198 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
199 |
+
mock_user_repo.getEmailUserById.return_value = None
|
200 |
+
request = req.RequestCheckInfoGoogle(user_id=user_id)
|
201 |
+
response = UserService.check_info_google(request)
|
202 |
+
self.assertEqual(response.status, 400)
|
203 |
+
self.assertEqual(response.data.message, "Email is empty")
|
204 |
+
|
205 |
+
@patch('service.UserService.UserRepository')
|
206 |
+
@patch('service.UserService.check_email')
|
207 |
+
@patch('service.UserService.UserInfoRepository')
|
208 |
+
@patch('service.UserService.sf.check_email_service', return_value=res.ReponseError(status=400, data=res.Message(
|
209 |
+
message="Email invalid")))
|
210 |
+
def test_check_info_google_email_invalid(self,mock_check_1,mock_user_info_repo, mock_check_email,mock_user_repo):
|
211 |
+
user_id = "1"
|
212 |
+
email ="quangphuc"
|
213 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
214 |
+
mock_user_repo.getEmailUserById.return_value = (email,)
|
215 |
+
mock_check_email.return_value = False
|
216 |
+
request = req.RequestCheckInfoGoogle(user_id=user_id)
|
217 |
+
response = UserService.check_info_google(request)
|
218 |
+
self.assertEqual(response.status, 400)
|
219 |
+
self.assertEqual(response.data.message, "Email invalid")
|
220 |
+
|
221 |
+
class TestCheckInfoGoogleEmail(unittest.TestCase):
|
222 |
+
@patch('service.UserService.UserRepository')
|
223 |
+
@patch('service.UserService.check_email')
|
224 |
+
@patch('service.UserService.UserInfoRepository')
|
225 |
+
@patch('service.UserService.sf.check_email_empty_invalid', return_value=True)
|
226 |
+
def test_check_info_google_email_success(self,mock_check1, mock_user_info_repo,mock_check_email,mock_user_repo):
|
227 |
+
email ="test@gmail.com"
|
228 |
+
mock_user_info_repo.getUserInfo.return_value = Mock()
|
229 |
+
request = req.RequestCheckInfoGoogleEmail(email=email)
|
230 |
+
response = UserService.check_info_google_email(request)
|
231 |
+
self.assertEqual(response.status, 200)
|
232 |
+
self.assertEqual(response.data.check, True)
|
233 |
+
|
234 |
+
@patch('service.UserService.UserInfoRepository.getUserInfoByEmail')
|
235 |
+
@patch('service.UserService.sf.check_email_empty_invalid', side_effect=Exception("error"))
|
236 |
+
def test_check_info_google_email_server_error(self, mock_check, mock_getUserInfoByEmail):
|
237 |
+
request = MagicMock()
|
238 |
+
request.email = 'test@example.com'
|
239 |
+
response = UserService.check_info_google_email(request)
|
240 |
+
self.assertEqual(response.status, 500)
|
241 |
+
self.assertEqual(response.data.message, "Server Error")
|
242 |
+
|
243 |
+
@patch('service.UserService.UserRepository')
|
244 |
+
@patch('service.UserService.check_email')
|
245 |
+
@patch('service.UserService.UserInfoRepository')
|
246 |
+
@patch('service.UserService.sf.check_email_empty_invalid', return_value=res.ReponseError(status=400, data=res.Message(
|
247 |
+
message="Email is empty"))
|
248 |
+
)
|
249 |
+
def test_check_info_google_by_email_email_empty(self,mock_check,mock_user_info_repo,mock_check_email,mock_user_repo):
|
250 |
+
email = None
|
251 |
+
request = req.RequestCheckInfoGoogleEmail(email=email)
|
252 |
+
response = UserService.check_info_google_email(request)
|
253 |
+
self.assertEqual(response.status, 400)
|
254 |
+
self.assertEqual(response.data.message, "Email is empty")
|
255 |
+
|
256 |
+
@patch('service.UserService.UserRepository')
|
257 |
+
@patch('service.UserService.check_email')
|
258 |
+
@patch('service.UserService.UserInfoRepository')
|
259 |
+
@patch('service.UserService.sf.check_email_empty_invalid',
|
260 |
+
return_value=res.ReponseError(status=400, data=res.Message(
|
261 |
+
message="Email invalid"))
|
262 |
+
)
|
263 |
+
def test_check_info_google_email_invalid(self,mock_check,mock_user_info_repo,mock_check_email,mock_user_repo):
|
264 |
+
email ="quangphuc"
|
265 |
+
mock_check_email.return_value = False
|
266 |
+
request = req.RequestCheckInfoGoogleEmail(email=email)
|
267 |
+
response = UserService.check_info_google_email(request)
|
268 |
+
self.assertEqual(response.status, 400)
|
269 |
+
self.assertEqual(response.data.message, "Email invalid")
|
270 |
+
|
271 |
+
class TestCheckStateLogin(unittest.TestCase):
|
272 |
+
|
273 |
+
@patch('service.UserService.UserRepository')
|
274 |
+
@patch('service.UserService.check_email')
|
275 |
+
@patch('service.UserService.UserInfoRepository')
|
276 |
+
@patch('service.UserService.get_user1')
|
277 |
+
@patch('service.UserService.UserLoginRepository')
|
278 |
+
@patch('service.UserService.sf.check_email_service', return_value=True)
|
279 |
+
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):
|
280 |
+
user_id = "1"
|
281 |
+
email ="test@gmail.com"
|
282 |
+
session_id = "session"
|
283 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
284 |
+
mock_check_email.return_value = True
|
285 |
+
mock_get_user1.return_value = Mock()
|
286 |
+
mock_user_login_repo.getUserSessionIdByUserEmail.return_value = session_id
|
287 |
+
request = req.RequestCheckStateLogin(user_id=user_id,session_id_now=session_id)
|
288 |
+
response = UserService.check_state_login(request)
|
289 |
+
self.assertEqual(response.status, 200)
|
290 |
+
self.assertEqual(response.data.check, True)
|
291 |
+
|
292 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
293 |
+
@patch('service.UserService.get_user1')
|
294 |
+
@patch('service.UserService.UserLoginRepository.getUserSessionIdByUserEmail')
|
295 |
+
@patch('service.UserService.sf.check_email_service', side_effect=Exception("error"))
|
296 |
+
def test_check_state_login_server_error(self,mock_check, mock_getUserSessionIdByUserEmail, mock_get_user1, mock_getEmailUserByIdFix):
|
297 |
+
request = MagicMock()
|
298 |
+
request.user_id = 'test_user_id'
|
299 |
+
request.session_id_now = 'test_session_id'
|
300 |
+
response = UserService.check_state_login(request)
|
301 |
+
self.assertEqual(response.status, 500)
|
302 |
+
self.assertEqual(response.data.message, "Server Error")
|
303 |
+
|
304 |
+
|
305 |
+
|
306 |
+
@patch('service.UserService.UserRepository')
|
307 |
+
@patch('service.UserService.check_email')
|
308 |
+
@patch('service.UserService.UserInfoRepository')
|
309 |
+
@patch('service.UserService.get_user1')
|
310 |
+
@patch('service.UserService.UserLoginRepository')
|
311 |
+
@patch('service.UserService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
312 |
+
message="Email is empty")))
|
313 |
+
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):
|
314 |
+
user_id = "1"
|
315 |
+
email = None
|
316 |
+
session_id = "session"
|
317 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
318 |
+
request = req.RequestCheckStateLogin(user_id=user_id,session_id_now=session_id)
|
319 |
+
response = UserService.check_state_login(request)
|
320 |
+
self.assertEqual(response.status, 400)
|
321 |
+
self.assertEqual(response.data.message, "Email is empty")
|
322 |
+
|
323 |
+
@patch('service.UserService.UserRepository')
|
324 |
+
@patch('service.UserService.check_email')
|
325 |
+
@patch('service.UserService.UserInfoRepository')
|
326 |
+
@patch('service.UserService.get_user1')
|
327 |
+
@patch('service.UserService.UserLoginRepository')
|
328 |
+
@patch('service.UserService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
329 |
+
message="Email invalid")))
|
330 |
+
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):
|
331 |
+
user_id = "1"
|
332 |
+
email = "20133"
|
333 |
+
session_id = "session"
|
334 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
335 |
+
mock_check_email.return_value = False
|
336 |
+
request = req.RequestCheckStateLogin(user_id=user_id,session_id_now=session_id)
|
337 |
+
response = UserService.check_state_login(request)
|
338 |
+
self.assertEqual(response.status, 400)
|
339 |
+
self.assertEqual(response.data.message, "Email invalid")
|
340 |
+
|
341 |
+
@patch('service.UserService.UserRepository')
|
342 |
+
@patch('service.UserService.check_email')
|
343 |
+
@patch('service.UserService.UserInfoRepository')
|
344 |
+
@patch('service.UserService.get_user1')
|
345 |
+
@patch('service.UserService.UserLoginRepository')
|
346 |
+
@patch('service.UserService.sf.check_email_service', return_value=True)
|
347 |
+
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):
|
348 |
+
user_id = "1"
|
349 |
+
email = "20133@gmail.com"
|
350 |
+
session_id = None
|
351 |
+
request = req.RequestCheckStateLogin(user_id=user_id,session_id_now=session_id)
|
352 |
+
response = UserService.check_state_login(request)
|
353 |
+
self.assertEqual(response.status, 400)
|
354 |
+
self.assertEqual(response.data.message, "session_id is empty")
|
355 |
+
|
356 |
+
@patch('service.UserService.UserRepository')
|
357 |
+
@patch('service.UserService.check_email')
|
358 |
+
@patch('service.UserService.UserInfoRepository')
|
359 |
+
@patch('service.UserService.get_user1')
|
360 |
+
@patch('service.UserService.UserLoginRepository')
|
361 |
+
@patch('service.UserService.sf.check_email_service', return_value=True)
|
362 |
+
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):
|
363 |
+
user_id = "1"
|
364 |
+
email ="test@gmail.com"
|
365 |
+
session_id = "session"
|
366 |
+
mock_get_user1.return_value = None
|
367 |
+
mock_user_login_repo.getUserSessionIdByUserEmail.return_value = session_id
|
368 |
+
request = req.RequestCheckStateLogin(user_id=user_id,session_id_now=session_id)
|
369 |
+
response = UserService.check_state_login(request)
|
370 |
+
self.assertEqual(response.status, 404)
|
371 |
+
self.assertEqual(response.data.message, "Not found user")
|
372 |
+
|
373 |
+
class TestChangePassword(unittest.TestCase):
|
374 |
+
|
375 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
376 |
+
@patch('service.UserService.check_email')
|
377 |
+
@patch('service.UserService.sign_in_with_email_and_password')
|
378 |
+
@patch('service.UserService.auth')
|
379 |
+
@patch('service.UserService.sf.check_email_service', return_value = "test@example.com")
|
380 |
+
def test_change_password_success(self,mock_check, mock_auth, mock_sign_in, mock_check_email, mock_get_email):
|
381 |
+
request = req.RequestChangePassword(user_id='123', new_password='new_password', current_password='current_password',confirm_new_password = 'new_password')
|
382 |
+
mock_get_email.return_value = ['test@example.com']
|
383 |
+
mock_check_email.return_value = True
|
384 |
+
mock_sign_in.return_value = MagicMock()
|
385 |
+
mock_auth.get_user_by_email.return_value = MagicMock(uid='user_uid')
|
386 |
+
response = UserService.change_password(request)
|
387 |
+
self.assertEqual(response.status, 200)
|
388 |
+
self.assertEqual(response.data.message,"Update password success")
|
389 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
390 |
+
@patch('service.UserService.sign_in_with_email_and_password')
|
391 |
+
@patch('service.UserService.auth.get_user_by_email')
|
392 |
+
@patch('service.UserService.auth.update_user')
|
393 |
+
@patch('service.UserService.sf.check_email_empty_invalid', side_effect = Exception("error"))
|
394 |
+
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):
|
395 |
+
request = MagicMock()
|
396 |
+
request.user_id = 'test_user_id'
|
397 |
+
request.new_password = 'new_password'
|
398 |
+
request.current_password = 'current_password'
|
399 |
+
request.confirm_new_password='new_password'
|
400 |
+
response = UserService.change_password(request)
|
401 |
+
self.assertEqual(response.status, 500)
|
402 |
+
self.assertEqual(response.data.message, "Server Error!!")
|
403 |
+
|
404 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
405 |
+
@patch('service.UserService.check_email')
|
406 |
+
@patch('service.UserService.sign_in_with_email_and_password')
|
407 |
+
@patch('service.UserService.auth')
|
408 |
+
|
409 |
+
@patch('service.UserService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
410 |
+
message="Id not exist")))
|
411 |
+
def test_change_password_id_not_exist(self, mock_check, mock_auth, mock_sign_in, mock_check_email, mock_get_email):
|
412 |
+
request = req.RequestChangePassword(user_id='123', new_password='new_password', current_password='current_password',confirm_new_password='new_password')
|
413 |
+
mock_get_email.return_value = None
|
414 |
+
response = UserService.change_password(request)
|
415 |
+
self.assertEqual(response.status, 400)
|
416 |
+
self.assertEqual(response.data.message,"Id not exist")
|
417 |
+
|
418 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
419 |
+
@patch('service.UserService.check_email')
|
420 |
+
@patch('service.UserService.sign_in_with_email_and_password')
|
421 |
+
@patch('service.UserService.auth')
|
422 |
+
@patch('service.UserService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
423 |
+
message="Email is empty")))
|
424 |
+
def test_change_password_email_is_empty(self,mock_check, mock_auth, mock_sign_in, mock_check_email, mock_get_email):
|
425 |
+
request = req.RequestChangePassword(user_id='123', new_password='new_password', current_password='current_password',confirm_new_password='new_password')
|
426 |
+
mock_get_email.return_value = (None,)
|
427 |
+
response = UserService.change_password(request)
|
428 |
+
self.assertEqual(response.status, 400)
|
429 |
+
self.assertEqual(response.data.message,"Email is empty")
|
430 |
+
|
431 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
432 |
+
@patch('service.UserService.check_email')
|
433 |
+
@patch('service.UserService.sign_in_with_email_and_password')
|
434 |
+
@patch('service.UserService.auth')
|
435 |
+
@patch('service.UserService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
436 |
+
message="Email invalid")))
|
437 |
+
def test_change_password_email_invalid(self, mock_check,mock_auth, mock_sign_in, mock_check_email, mock_get_email):
|
438 |
+
request = req.RequestChangePassword(user_id='123', new_password='new_password', current_password='current_password',confirm_new_password='new_password')
|
439 |
+
mock_get_email.return_value = "20133"
|
440 |
+
mock_check_email.return_value = False
|
441 |
+
response = UserService.change_password(request)
|
442 |
+
self.assertEqual(response.status, 400)
|
443 |
+
self.assertEqual(response.data.message,"Email invalid")
|
444 |
+
|
445 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
446 |
+
@patch('service.UserService.check_email')
|
447 |
+
@patch('service.UserService.sign_in_with_email_and_password')
|
448 |
+
@patch('service.UserService.auth')
|
449 |
+
@patch('service.UserService.sf.check_email_service', return_value = True)
|
450 |
+
def test_change_password_new_password_empty(self, mock_check, mock_auth, mock_sign_in, mock_check_email, mock_get_email):
|
451 |
+
request = req.RequestChangePassword(user_id='123', new_password= None, current_password='current_password',confirm_new_password='new_password')
|
452 |
+
mock_get_email.return_value = "20133@gmail.com"
|
453 |
+
mock_check_email.return_value = True
|
454 |
+
response = UserService.change_password(request)
|
455 |
+
self.assertEqual(response.status, 400)
|
456 |
+
self.assertEqual(response.data.message,"new_password is empty")
|
457 |
+
|
458 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
459 |
+
@patch('service.UserService.check_email')
|
460 |
+
@patch('service.UserService.sign_in_with_email_and_password')
|
461 |
+
@patch('service.UserService.auth')
|
462 |
+
@patch('service.UserService.sf.check_email_service', return_value=True)
|
463 |
+
def test_change_password_confirm_new_password_empty(self, mock_check, mock_auth, mock_sign_in, mock_check_email,
|
464 |
+
mock_get_email):
|
465 |
+
request = req.RequestChangePassword(user_id='123', new_password="abc", current_password='current_password',
|
466 |
+
confirm_new_password=None)
|
467 |
+
mock_get_email.return_value = "20133@gmail.com"
|
468 |
+
mock_check_email.return_value = True
|
469 |
+
response = UserService.change_password(request)
|
470 |
+
self.assertEqual(response.status, 400)
|
471 |
+
self.assertEqual(response.data.message, "confirm_new_password is empty")
|
472 |
+
|
473 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
474 |
+
@patch('service.UserService.check_email')
|
475 |
+
@patch('service.UserService.sign_in_with_email_and_password')
|
476 |
+
@patch('service.UserService.auth')
|
477 |
+
@patch('service.UserService.sf.check_email_service', return_value=True)
|
478 |
+
def test_change_password_confirm_new_password_do_not_match_new_password(self, mock_check, mock_auth, mock_sign_in, mock_check_email,
|
479 |
+
mock_get_email):
|
480 |
+
request = req.RequestChangePassword(user_id='123', new_password="abc", current_password='current_password',
|
481 |
+
confirm_new_password="ab")
|
482 |
+
mock_get_email.return_value = "20133@gmail.com"
|
483 |
+
mock_check_email.return_value = True
|
484 |
+
response = UserService.change_password(request)
|
485 |
+
self.assertEqual(response.status, 400)
|
486 |
+
self.assertEqual(response.data.message, "The new_password and the confirm_new_password must be similar")
|
487 |
+
|
488 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
489 |
+
@patch('service.UserService.check_email')
|
490 |
+
@patch('service.UserService.sign_in_with_email_and_password')
|
491 |
+
@patch('service.UserService.auth')
|
492 |
+
@patch('service.UserService.sf.check_email_service', return_value="test@email.com")
|
493 |
+
def test_change_password_current_password_empty(self, mock_check, mock_auth, mock_sign_in, mock_check_email, mock_get_email):
|
494 |
+
request = req.RequestChangePassword(user_id='123', new_password= "new_password", current_password=None,confirm_new_password='new_password')
|
495 |
+
mock_get_email.return_value = "20133@gmail.com"
|
496 |
+
mock_check_email.return_value = True
|
497 |
+
response = UserService.change_password(request)
|
498 |
+
self.assertEqual(response.status, 400)
|
499 |
+
self.assertEqual(response.data.message,"current_password is empty")
|
500 |
+
|
501 |
+
@patch('service.UserService.UserRepository.getEmailUserByIdFix')
|
502 |
+
@patch('service.UserService.check_email')
|
503 |
+
@patch('service.UserService.sign_in_with_email_and_password')
|
504 |
+
@patch('service.UserService.auth')
|
505 |
+
@patch('service.UserService.sf.check_email_service', return_value="test@email.com")
|
506 |
+
def test_change_password_current_password_not_valid(self, mock_check, mock_auth, mock_sign_in, mock_check_email, mock_get_email):
|
507 |
+
request = req.RequestChangePassword(user_id='123', new_password='new_password', current_password='current_password', confirm_new_password = 'new_password')
|
508 |
+
mock_check_email.return_value = True
|
509 |
+
mock_sign_in.return_value = None
|
510 |
+
response = UserService.change_password(request)
|
511 |
+
self.assertEqual(response.status, 400)
|
512 |
+
self.assertEqual(response.data.message,"Current password not valid")
|
513 |
+
|
514 |
+
class TestResetPassword(unittest.TestCase):
|
515 |
+
@patch('service.UserService.check_email', return_value=True)
|
516 |
+
@patch('service.UserService.get_user1', return_value={"email": "user@example.com"})
|
517 |
+
@patch('service.UserService.createOTPReset', return_value="123456")
|
518 |
+
@patch('service.UserService.sf.check_email_empty_invalid', return_value=True)
|
519 |
+
def test_reset_password_success(self, mock_check,mock_createOTPReset, mock_get_user1, mock_check_email):
|
520 |
+
request = MagicMock()
|
521 |
+
request.email = "user@example.com"
|
522 |
+
response = UserService.reset_password(request)
|
523 |
+
self.assertEqual(response.status, 200)
|
524 |
+
self.assertEqual(response.data.check, True)
|
525 |
+
self.assertEqual(response.otp, "123456")
|
526 |
+
|
527 |
+
@patch('service.UserService.sf.check_email_empty_invalid', return_value=res.ReponseError(status=400, data=res.Message(
|
528 |
+
message="Email invalid")))
|
529 |
+
|
530 |
+
def test_reset_password_invalid_email(self, mock_check_email):
|
531 |
+
request = MagicMock()
|
532 |
+
request.email = "invalid_email"
|
533 |
+
response = UserService.reset_password(request)
|
534 |
+
self.assertEqual(response.status, 400)
|
535 |
+
self.assertEqual(response.data.message, "Email invalid")
|
536 |
+
|
537 |
+
@patch('service.UserService.check_email', return_value=True)
|
538 |
+
@patch('service.UserService.get_user1', return_value=None)
|
539 |
+
@patch('service.UserService.sf.check_email_empty_invalid', return_value=True)
|
540 |
+
def test_reset_password_user_not_found(self, mock_check, mock_get_user1, mock_check_email):
|
541 |
+
request = MagicMock()
|
542 |
+
request.email = "nonexistent@example.com"
|
543 |
+
response = UserService.reset_password(request)
|
544 |
+
self.assertEqual(response.status, 404)
|
545 |
+
self.assertEqual(response.data.message, "Email not exist")
|
546 |
+
|
547 |
+
@patch('service.UserService.check_email', return_value=True)
|
548 |
+
@patch('service.UserService.get_user1')
|
549 |
+
@patch('service.UserService.sf.check_email_empty_invalid', return_value=True)
|
550 |
+
def test_reset_password_server_error(self, mock_check, mock_get_user1, mock_check_email):
|
551 |
+
request = MagicMock()
|
552 |
+
mock_get_user1.side_effect = Exception("Error")
|
553 |
+
request.email = "nonexistent@example.com"
|
554 |
+
response = UserService.reset_password(request)
|
555 |
+
self.assertEqual(response.status, 500)
|
556 |
+
self.assertEqual(response.data.message, "Server Error")
|
557 |
+
|
558 |
+
|
559 |
+
if __name__ == '__main__':
|
560 |
+
unittest.main()
|
tests/test_service/test_MySQLService.py
ADDED
@@ -0,0 +1,382 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import unittest
|
2 |
+
from unittest.mock import patch
|
3 |
+
from response import ResponseMySQL as res
|
4 |
+
import sys
|
5 |
+
import os
|
6 |
+
from response import ResponseDefault as res1
|
7 |
+
|
8 |
+
app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
9 |
+
sys.path.insert(0, app_path)
|
10 |
+
from models import Database_Entity
|
11 |
+
from service.MySQLService import edit_chat, delete_chat, render_chat_history, load_chat_history
|
12 |
+
from request.RequestMySQL import RequestEditNameChat, RequestDeleteChat, RequestRenderChatHistory, \
|
13 |
+
RequestLoadChatHistory
|
14 |
+
from response.ResponseMySQL import ResponseEditChat, ResponseDeleteChat, ReponseError, Message, \
|
15 |
+
ResponseRenderChatHistory, UserInfoListResponse, ListUserChat, ResponseLoadChatHistory, ChatDetail, ListChatDeTail
|
16 |
+
|
17 |
+
|
18 |
+
class TestMySQLService(unittest.TestCase):
|
19 |
+
@patch('service.MySQLService.UserRepository')
|
20 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
21 |
+
@patch('service.MySQLService.sf')
|
22 |
+
def test_edit_chat_success(self, mock_support_function, mock_chat_history_repo, mock_user_repo):
|
23 |
+
user_id = "1"
|
24 |
+
email = 'example@example.com'
|
25 |
+
name_old = 'chat123'
|
26 |
+
name_new = 'chat1234'
|
27 |
+
mock_support_function.check_email_service.return_value = email
|
28 |
+
mock_chat_history_repo.getIdChatHistoryByUserIdAndNameChat.return_value = True
|
29 |
+
mock_chat_history_repo.getIdChatHistoryByUserIdAndNameChatNew.return_value = None
|
30 |
+
request = RequestEditNameChat(user_id=user_id, name_old=name_old, name_new=name_new)
|
31 |
+
response = edit_chat(request)
|
32 |
+
self.assertIsInstance(response, ResponseEditChat)
|
33 |
+
self.assertEqual(response.status, 200)
|
34 |
+
|
35 |
+
@patch('service.MySQLService.UserRepository.getEmailUserByIdFix')
|
36 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
37 |
+
@patch('service.MySQLService.sf')
|
38 |
+
def test_edit_chat_server_error(self, mock_support_function, mock_chat_history_repo, mock_user_repo):
|
39 |
+
user_id = "1"
|
40 |
+
email = 'example@example.com'
|
41 |
+
name_old = 'chat123'
|
42 |
+
name_new = 'chat1234'
|
43 |
+
mock_support_function.check_email_service.side_effect = Exception("error")
|
44 |
+
request = RequestEditNameChat(user_id=user_id, name_old=name_old, name_new=name_new)
|
45 |
+
response = edit_chat(request)
|
46 |
+
self.assertIsInstance(response, ReponseError)
|
47 |
+
self.assertEqual(response.status, 500)
|
48 |
+
self.assertEqual(response.data.message, "Server Error")
|
49 |
+
|
50 |
+
@patch('service.MySQLService.UserRepository')
|
51 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
52 |
+
@patch('service.MySQLService.sf')
|
53 |
+
def test_edit_chat_id_not_exist(self, mock_support_function, mock_chat_history_repo, mock_user_repo):
|
54 |
+
user_id = "1"
|
55 |
+
name_old = 'chat123'
|
56 |
+
name_new = 'chat1234'
|
57 |
+
mock_support_function.check_email_service.return_value = res1.ReponseError(status=400, data=res.Message(
|
58 |
+
message="Id not exist"))
|
59 |
+
request = RequestEditNameChat(user_id=user_id, name_old=name_old, name_new=name_new)
|
60 |
+
response = edit_chat(request)
|
61 |
+
self.assertIsInstance(response, res1.ReponseError)
|
62 |
+
self.assertEqual(response.status, 400)
|
63 |
+
self.assertEqual(response.data, Message(message='Id not exist'))
|
64 |
+
|
65 |
+
@patch('service.MySQLService.UserRepository')
|
66 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
67 |
+
@patch('service.MySQLService.sf')
|
68 |
+
def test_edit_chat_email_empty(self, mock_support_function, mock_chat_history_repo, mock_user_repo):
|
69 |
+
user_id = '1'
|
70 |
+
email = ""
|
71 |
+
name_old = 'chat123'
|
72 |
+
name_new = 'chat1234'
|
73 |
+
mock_support_function.check_email_service.return_value = res1.ReponseError(status=400, data=res.Message(
|
74 |
+
message="Email is empty"))
|
75 |
+
request = RequestEditNameChat(user_id=user_id, name_old=name_old, name_new=name_new)
|
76 |
+
response = edit_chat(request)
|
77 |
+
self.assertIsInstance(response, res1.ReponseError)
|
78 |
+
self.assertEqual(response.status, 400)
|
79 |
+
self.assertEqual(response.data, Message(message='Email is empty'))
|
80 |
+
|
81 |
+
@patch('service.MySQLService.UserRepository')
|
82 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
83 |
+
@patch('service.MySQLService.sf')
|
84 |
+
def test_edit_chat_email_in_valid(self, mock_support_function, mock_chat_history_repo, mock_user_repo):
|
85 |
+
user_id = "1"
|
86 |
+
email = "20133118"
|
87 |
+
name_old = 'chat123'
|
88 |
+
name_new = 'chat1234'
|
89 |
+
mock_support_function.check_email_service.return_value = res1.ReponseError(status=400, data=res.Message(
|
90 |
+
message="Email invalid"))
|
91 |
+
request = RequestEditNameChat(user_id=user_id, name_old=name_old, name_new=name_new)
|
92 |
+
response = edit_chat(request)
|
93 |
+
self.assertIsInstance(response, res1.ReponseError)
|
94 |
+
self.assertEqual(response.status, 400)
|
95 |
+
self.assertEqual(response.data, Message(message='Email invalid'))
|
96 |
+
|
97 |
+
@patch('service.MySQLService.UserRepository')
|
98 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
99 |
+
@patch('service.MySQLService.sf.check_email_service', return_value=True)
|
100 |
+
def test_edit_chat_name_old_empty(self, mock_support_function, mock_chat_history_repo, mock_user_repo):
|
101 |
+
user_id = "1"
|
102 |
+
email = "20133118@gmail.com"
|
103 |
+
name_old = ""
|
104 |
+
name_new = 'chat1234'
|
105 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
106 |
+
request = RequestEditNameChat(user_id=user_id, name_old=name_old, name_new=name_new)
|
107 |
+
response = edit_chat(request)
|
108 |
+
self.assertIsInstance(response, ReponseError)
|
109 |
+
self.assertEqual(response.status, 400)
|
110 |
+
self.assertEqual(response.data, Message(message='name_old is empty'))
|
111 |
+
|
112 |
+
@patch('service.MySQLService.UserRepository')
|
113 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
114 |
+
@patch('service.MySQLService.sf.check_email_service', return_value=True)
|
115 |
+
def test_edit_chat_name_new_empty(self, mock_support_function, mock_chat_history_repo, mock_user_repo):
|
116 |
+
user_id = "1"
|
117 |
+
email = "20133118@gmail.com"
|
118 |
+
name_old = 'chat123'
|
119 |
+
name_new = ''
|
120 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
121 |
+
request = RequestEditNameChat(user_id=user_id, name_old=name_old, name_new=name_new)
|
122 |
+
response = edit_chat(request)
|
123 |
+
self.assertIsInstance(response, ReponseError)
|
124 |
+
self.assertEqual(response.status, 400)
|
125 |
+
self.assertEqual(response.data, Message(message='name_new is empty'))
|
126 |
+
|
127 |
+
@patch('service.MySQLService.UserRepository')
|
128 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
129 |
+
@patch('service.MySQLService.sf.check_email_service', return_value=True)
|
130 |
+
def test_edit_chat_update_error(self, mock_support_function, mock_chat_history_repo, mock_user_repo):
|
131 |
+
user_id = "1"
|
132 |
+
email = "20133118@gmail.com"
|
133 |
+
name_old = 'chat123'
|
134 |
+
name_new = 'chat1234'
|
135 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
136 |
+
mock_chat_history_repo.getIdChatHistoryByUserIdAndNameChat.return_value = False
|
137 |
+
mock_chat_history_repo.getIdChatHistoryByUserIdAndNameChatNew.return_value = None
|
138 |
+
request = RequestEditNameChat(user_id=user_id, name_old=name_old, name_new=name_new)
|
139 |
+
response = edit_chat(request)
|
140 |
+
self.assertIsInstance(response, ReponseError)
|
141 |
+
self.assertEqual(response.status, 500)
|
142 |
+
self.assertEqual(response.data, Message(message='Update chat error'))
|
143 |
+
|
144 |
+
|
145 |
+
class TestDeleteChat(unittest.TestCase):
|
146 |
+
@patch('service.MySQLService.UserRepository')
|
147 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
148 |
+
@patch('service.MySQLService.DetailChatRepository')
|
149 |
+
@patch('service.MySQLService.sf.check_email_service', return_value=True)
|
150 |
+
def test_delete_chat_success(self, mock_support_function, mock_detail_chat_repo, mock_chat_history_repo,
|
151 |
+
mock_user_repo):
|
152 |
+
user_id = "1"
|
153 |
+
email = 'example@example.com'
|
154 |
+
chat_name = 'test'
|
155 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
156 |
+
mock_detail_chat_repo.delete_chat_detail.return_value = True
|
157 |
+
mock_chat_history_repo.deleteChatHistory.return_value = True
|
158 |
+
request = RequestDeleteChat(user_id=user_id, chat_name=chat_name)
|
159 |
+
response = delete_chat(request)
|
160 |
+
self.assertIsInstance(response, ResponseDeleteChat)
|
161 |
+
self.assertEqual(response.status, 200)
|
162 |
+
|
163 |
+
@patch('service.MySQLService.UserRepository')
|
164 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
165 |
+
@patch('service.MySQLService.DetailChatRepository')
|
166 |
+
@patch('service.MySQLService.sf.check_email_service', side_effect=Exception("Error"))
|
167 |
+
def test_delete_chat_server_error(self, mock_support_function, mock_detail_chat_repo, mock_chat_history_repo,
|
168 |
+
mock_user_repo):
|
169 |
+
user_id = "1"
|
170 |
+
email = 'example@example.com'
|
171 |
+
chat_name = 'test'
|
172 |
+
|
173 |
+
mock_detail_chat_repo.delete_chat_detail.return_value = True
|
174 |
+
mock_chat_history_repo.deleteChatHistory.return_value = True
|
175 |
+
request = RequestDeleteChat(user_id=user_id, chat_name=chat_name)
|
176 |
+
response = delete_chat(request)
|
177 |
+
self.assertIsInstance(response, ResponseDeleteChat)
|
178 |
+
self.assertEqual(response.status, 500)
|
179 |
+
|
180 |
+
@patch('service.MySQLService.UserRepository')
|
181 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
182 |
+
@patch('service.MySQLService.DetailChatRepository')
|
183 |
+
@patch('service.MySQLService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
184 |
+
message="Id not exist")))
|
185 |
+
def test_delete_chat_id_not_exist(self, mock_support_function, mock_detail_chat_repo, mock_chat_history_repo,
|
186 |
+
mock_user_repo):
|
187 |
+
user_id = "1"
|
188 |
+
email = 'example@example.com'
|
189 |
+
chat_name = 'test'
|
190 |
+
mock_user_repo.getEmailUserByIdFix.return_value = None
|
191 |
+
request = RequestDeleteChat(user_id=user_id, chat_name=chat_name)
|
192 |
+
response = delete_chat(request)
|
193 |
+
self.assertIsInstance(response, res1.ReponseError)
|
194 |
+
self.assertEqual(response.status, 400)
|
195 |
+
self.assertEqual(response.data, Message(message='Id not exist'))
|
196 |
+
|
197 |
+
@patch('service.MySQLService.UserRepository')
|
198 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
199 |
+
@patch('service.MySQLService.DetailChatRepository')
|
200 |
+
@patch('service.MySQLService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
201 |
+
message="Email is empty")))
|
202 |
+
def test_delete_chat_email_empty(self, mock_support_function, mock_detail_chat_repo, mock_chat_history_repo,
|
203 |
+
mock_user_repo):
|
204 |
+
user_id = "1"
|
205 |
+
email = ""
|
206 |
+
chat_name = 'test'
|
207 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
208 |
+
request = RequestDeleteChat(user_id=user_id, chat_name=chat_name)
|
209 |
+
response = delete_chat(request)
|
210 |
+
self.assertIsInstance(response, res1.ReponseError)
|
211 |
+
self.assertEqual(response.status, 400)
|
212 |
+
self.assertEqual(response.data, Message(message='Email is empty'))
|
213 |
+
|
214 |
+
@patch('service.MySQLService.UserRepository')
|
215 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
216 |
+
@patch('service.MySQLService.DetailChatRepository')
|
217 |
+
@patch('service.MySQLService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
218 |
+
message="Email invalid")))
|
219 |
+
def test_delete_chat_email_invalid(self, mock_support_function, mock_detail_chat_repo, mock_chat_history_repo,
|
220 |
+
mock_user_repo):
|
221 |
+
user_id = "1"
|
222 |
+
email = "20133118"
|
223 |
+
chat_name = 'test'
|
224 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
225 |
+
request = RequestDeleteChat(user_id=user_id, chat_name=chat_name)
|
226 |
+
response = delete_chat(request)
|
227 |
+
self.assertIsInstance(response, res1.ReponseError)
|
228 |
+
self.assertEqual(response.status, 400)
|
229 |
+
self.assertEqual(response.data, Message(message='Email invalid'))
|
230 |
+
|
231 |
+
@patch('service.MySQLService.UserRepository')
|
232 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
233 |
+
@patch('service.MySQLService.DetailChatRepository')
|
234 |
+
@patch('service.MySQLService.sf.check_email_service', return_value=True)
|
235 |
+
def test_delete_chat_chatname_empty(self, mock_support_function, mock_detail_chat_repo, mock_chat_history_repo,
|
236 |
+
mock_user_repo):
|
237 |
+
user_id = "1"
|
238 |
+
email = "20133118@gmail.com"
|
239 |
+
chat_name = ""
|
240 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
241 |
+
request = RequestDeleteChat(user_id=user_id, chat_name=chat_name)
|
242 |
+
response = delete_chat(request)
|
243 |
+
self.assertIsInstance(response, ReponseError)
|
244 |
+
self.assertEqual(response.status, 400)
|
245 |
+
self.assertEqual(response.data, Message(message='chat_name is empty'))
|
246 |
+
|
247 |
+
@patch('service.MySQLService.UserRepository')
|
248 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
249 |
+
@patch('service.MySQLService.DetailChatRepository')
|
250 |
+
@patch('service.MySQLService.sf.check_email_service', return_value=True)
|
251 |
+
def test_delete_chat_error_1(self, mock_support_function, mock_detail_chat_repo, mock_chat_history_repo,
|
252 |
+
mock_user_repo):
|
253 |
+
user_id = "1"
|
254 |
+
email = "20133118@gmail.com"
|
255 |
+
chat_name = 'test'
|
256 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
257 |
+
mock_chat_history_repo.deleteChatHistory.return_value = False
|
258 |
+
request = RequestDeleteChat(user_id=user_id, chat_name=chat_name)
|
259 |
+
response = delete_chat(request)
|
260 |
+
self.assertIsInstance(response, ReponseError)
|
261 |
+
self.assertEqual(response.status, 500)
|
262 |
+
self.assertEqual(response.data, Message(message='Delete conversation chat error'))
|
263 |
+
|
264 |
+
|
265 |
+
class TestRenderChatHistory(unittest.TestCase):
|
266 |
+
@patch('service.MySQLService.UserRepository')
|
267 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
268 |
+
@patch('service.MySQLService.sf.check_email_service', return_value=True)
|
269 |
+
def test_render_chat_history_success(self, mock_support_function, mock_chat_history_repo, mock_user_repo):
|
270 |
+
user_id = "1"
|
271 |
+
email = 'example@example.com'
|
272 |
+
chat_detail = [Database_Entity.ChatHistory(id=1, email="example@example.com", name_chat="chat1"),
|
273 |
+
Database_Entity.ChatHistory(id=2, email="example@example.com", name_chat="chat2")]
|
274 |
+
mock_user_repo.getEmailUserByIdFix.return_value = (email,)
|
275 |
+
mock_chat_history_repo.getChatHistoryById.return_value = chat_detail
|
276 |
+
request = RequestRenderChatHistory(user_id=user_id)
|
277 |
+
response = render_chat_history(request)
|
278 |
+
self.assertIsInstance(response, ResponseRenderChatHistory)
|
279 |
+
self.assertEqual(response.status, 200)
|
280 |
+
self.assertIsInstance(response.data, UserInfoListResponse)
|
281 |
+
self.assertEqual(len(response.data.chat), 2) # Kiểm tra số lượng chat được trả về
|
282 |
+
self.assertIsInstance(response.data.chat[0], ListUserChat)
|
283 |
+
|
284 |
+
@patch('service.MySQLService.UserRepository')
|
285 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
286 |
+
@patch('service.MySQLService.sf.check_email_service', side_effect=Exception("Error"))
|
287 |
+
def test_render_chat_history_server_err(self, mock_support_function, mock_chat_history_repo, mock_user_repo):
|
288 |
+
user_id = "1"
|
289 |
+
email = 'example@example.com'
|
290 |
+
chat_detail = [Database_Entity.ChatHistory(id=1, email="example@example.com", name_chat="chat1"),
|
291 |
+
Database_Entity.ChatHistory(id=2, email="example@example.com", name_chat="chat2")]
|
292 |
+
mock_user_repo.getEmailUserByIdFix.side_effect = Exception("error")
|
293 |
+
request = RequestRenderChatHistory(user_id=user_id)
|
294 |
+
response = render_chat_history(request)
|
295 |
+
self.assertIsInstance(response, ReponseError)
|
296 |
+
self.assertEqual(response.status, 500)
|
297 |
+
self.assertEqual(response.data.message, "Server Error")
|
298 |
+
|
299 |
+
@patch('service.MySQLService.UserRepository')
|
300 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
301 |
+
@patch('service.MySQLService.sf.check_email_service', return_value=res1.ReponseError(status=400, data=res.Message(
|
302 |
+
message="Id not exist")))
|
303 |
+
def test_render_chat_history_id_not_exist(self, mock_support_function, mock_chat_history_repo, mock_user_repo):
|
304 |
+
user_id = "1"
|
305 |
+
email = 'example@example.com'
|
306 |
+
chat_detail = [Database_Entity.ChatHistory(id=1, email="example@example.com", name_chat="chat1"),
|
307 |
+
Database_Entity.ChatHistory(id=2, email="example@example.com", name_chat="chat2")]
|
308 |
+
mock_user_repo.getEmailUserByIdFix.return_value = None
|
309 |
+
request = RequestRenderChatHistory(user_id=user_id)
|
310 |
+
response = render_chat_history(request)
|
311 |
+
self.assertIsInstance(response, res1.ReponseError)
|
312 |
+
self.assertEqual(response.status, 400)
|
313 |
+
self.assertEqual(response.data, Message(message='Id not exist'))
|
314 |
+
|
315 |
+
class TestLoadChatHistory(unittest.TestCase):
|
316 |
+
@patch('service.MySQLService.DetailChatRepository')
|
317 |
+
@patch('service.MySQLService.sf.check_email_service', return_value=True)
|
318 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
319 |
+
def test_load_chat_history_success(self, mock_chat_history_repo, mock_support_functon, mock_detail_chat_repo):
|
320 |
+
chat_id = "1"
|
321 |
+
user_id = "1"
|
322 |
+
chat_detail = [Database_Entity.DetailChat(id=1, chat_id=1, YouMessage="question1", AiMessage="AImessage1",
|
323 |
+
data_relevant="abc", source_file="abcd"),
|
324 |
+
Database_Entity.DetailChat(id=2, chat_id=1, YouMessage="question2", AiMessage="AImessage2",
|
325 |
+
data_relevant="abc", source_file="abcd")]
|
326 |
+
mock_chat_history_repo.getChatHistoryByChatIdAndUserId.return_value = True
|
327 |
+
mock_detail_chat_repo.getListDetailChatByChatId.return_value = chat_detail
|
328 |
+
request = RequestLoadChatHistory(user_id=user_id, chat_id=chat_id)
|
329 |
+
response = load_chat_history(request)
|
330 |
+
self.assertIsInstance(response, ResponseLoadChatHistory)
|
331 |
+
self.assertEqual(response.status, 200)
|
332 |
+
self.assertIsInstance(response.data, ListChatDeTail)
|
333 |
+
self.assertEqual(len(response.data.detail_chat), 2)
|
334 |
+
self.assertIsInstance(response.data.detail_chat[0], ChatDetail)
|
335 |
+
|
336 |
+
@patch('service.MySQLService.DetailChatRepository')
|
337 |
+
@patch('service.MySQLService.ChatHistoryRepository', return_value=True)
|
338 |
+
@patch('service.MySQLService.sf.check_email_service', side_effect=Exception("Error"))
|
339 |
+
def test_load_chat_history_server_err(self, mock_support_function, mock_chat_history_repo, mock_detail_chat_repo):
|
340 |
+
chat_id = "1"
|
341 |
+
user_id = "1"
|
342 |
+
chat_detail = [Database_Entity.DetailChat(id=1, chat_id=1, YouMessage="question1", AiMessage="AImessage1",
|
343 |
+
data_relevant="abc", source_file="abcd"),
|
344 |
+
Database_Entity.DetailChat(id=2, chat_id=1, YouMessage="question2", AiMessage="AImessage2",
|
345 |
+
data_relevant="abc", source_file="abcd")]
|
346 |
+
mock_chat_history_repo.getChatHistoryByChatIdAndUserId.return_value = True
|
347 |
+
mock_detail_chat_repo.getListDetailChatByChatId.side_effect = Exception("error")
|
348 |
+
request = RequestLoadChatHistory(user_id=user_id, chat_id=chat_id)
|
349 |
+
response = load_chat_history(request)
|
350 |
+
self.assertIsInstance(response, ReponseError)
|
351 |
+
self.assertEqual(response.status, 500)
|
352 |
+
self.assertEqual(response.data.message, "Server Error")
|
353 |
+
|
354 |
+
@patch('service.MySQLService.DetailChatRepository')
|
355 |
+
@patch('service.MySQLService.sf.check_email_service', return_value="20133118@gmail.com")
|
356 |
+
@patch('service.MySQLService.ChatHistoryRepository', return_value=True)
|
357 |
+
def test_load_chat_history_error(self, mock_repo1, mock_support_function, mock_detail_chat_repo):
|
358 |
+
chat_id = None
|
359 |
+
user_id = "1"
|
360 |
+
request = RequestLoadChatHistory(user_id=user_id, chat_id=chat_id)
|
361 |
+
mock_repo1.getChatHistoryByChatIdAndUserId.return_value = None
|
362 |
+
response = load_chat_history(request)
|
363 |
+
self.assertIsInstance(response, ReponseError)
|
364 |
+
self.assertEqual(response.status, 400)
|
365 |
+
self.assertEqual(response.data, Message(message='chat_id is empty'))
|
366 |
+
|
367 |
+
@patch('service.MySQLService.DetailChatRepository')
|
368 |
+
@patch('service.MySQLService.sf.check_email_service', return_value="12345@gmail.com")
|
369 |
+
@patch('service.MySQLService.ChatHistoryRepository')
|
370 |
+
def test_load_chat_history_not_found_chat(self, mock_repo1, mock_support_function, mock_detail_chat_repo):
|
371 |
+
chat_id = "1"
|
372 |
+
user_id = None
|
373 |
+
mock_repo1.getChatHistoryByChatIdAndUserId.return_value = None
|
374 |
+
request = RequestLoadChatHistory(user_id=user_id, chat_id=chat_id)
|
375 |
+
response = load_chat_history(request)
|
376 |
+
self.assertIsInstance(response, ReponseError)
|
377 |
+
self.assertEqual(response.status, 404)
|
378 |
+
self.assertEqual(response.data, Message(message='Not found chat width chat_id and user_id'))
|
379 |
+
|
380 |
+
|
381 |
+
if __name__ == '__main__':
|
382 |
+
unittest.main()
|
tests/test_service/test_OTPService.py
ADDED
@@ -0,0 +1,311 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import unittest
|
2 |
+
import sys
|
3 |
+
import os
|
4 |
+
app_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
5 |
+
sys.path.insert(0, app_path)
|
6 |
+
from request import RequestOTP as req
|
7 |
+
from response import ResponseOTP as res
|
8 |
+
from unittest.mock import patch, MagicMock
|
9 |
+
from datetime import datetime, timedelta
|
10 |
+
from service.OTPService import createOTP, verifyOTP, createOTPReset, verifyOTPReset
|
11 |
+
|
12 |
+
class TestCreateOTPReset(unittest.TestCase):
|
13 |
+
@patch('service.OTPService.check_email')
|
14 |
+
@patch('service.OTPService.get_user1')
|
15 |
+
@patch('service.OTPService.OTPRepository.addOTP')
|
16 |
+
@patch('service.OTPService.generate_otp')
|
17 |
+
@patch('service.OTPService.sf')
|
18 |
+
def test_createOTPReset_success(self,mock_support_function, mock_generate_otp, mock_addOTP, mock_get_user1, mock_check_email):
|
19 |
+
mock_get_user1.return_value = MagicMock()
|
20 |
+
email = "user@example.com"
|
21 |
+
mock_support_function.check_email_empty_invalid.return_value = True
|
22 |
+
mock_generate_otp.return_value = "123456"
|
23 |
+
response = createOTPReset(email)
|
24 |
+
self.assertEqual(response.status, 200)
|
25 |
+
self.assertEqual(response.data.check, True)
|
26 |
+
self.assertEqual(response.otp, "123456")
|
27 |
+
|
28 |
+
@patch('service.OTPService.check_email')
|
29 |
+
@patch('service.OTPService.get_user1')
|
30 |
+
@patch('service.OTPService.OTPRepository.addOTP')
|
31 |
+
@patch('service.OTPService.sf')
|
32 |
+
def test_createOTPReset_email_empty(self,mock_support_function, mock_addOTP, mock_get_user1, mock_check_email):
|
33 |
+
email = None
|
34 |
+
mock_support_function.check_email_empty_invalid.return_value = res.ReponseError(status=400, data=res.Message(
|
35 |
+
message="Email is empty"))
|
36 |
+
response = createOTPReset(email)
|
37 |
+
self.assertIsInstance(response, res.ReponseError)
|
38 |
+
self.assertEqual(response.status, 400)
|
39 |
+
self.assertEqual(response.data, res.Message(message='Email is empty'))
|
40 |
+
|
41 |
+
@patch('service.OTPService.check_email')
|
42 |
+
@patch('service.OTPService.sf')
|
43 |
+
def test_createOTPReset_email_invalid(self,mock_support_function, mock_check_email):
|
44 |
+
email = "201333"
|
45 |
+
mock_support_function.check_email_empty_invalid.return_value = res.ReponseError(status=400, data=res.Message(
|
46 |
+
message="Email invalid"))
|
47 |
+
response = createOTPReset(email)
|
48 |
+
self.assertIsInstance(response, res.ReponseError)
|
49 |
+
self.assertEqual(response.status, 400)
|
50 |
+
self.assertEqual(response.data, res.Message(message='Email invalid'))
|
51 |
+
|
52 |
+
class TestCreateOTPFunctions(unittest.TestCase):
|
53 |
+
@patch('service.OTPService.generate_otp')
|
54 |
+
@patch('service.OTPService.check_email')
|
55 |
+
@patch('service.OTPService.OTPRepository')
|
56 |
+
@patch('service.OTPService.sf')
|
57 |
+
def test_createOTP_success(self,mock_support_function, mock_addOTP, mock_check_email, mock_generate_otp):
|
58 |
+
mock_generate_otp.return_value = "123AB6"
|
59 |
+
email = "20133118@gmail.com"
|
60 |
+
otp = "123AB6"
|
61 |
+
mock_support_function.check_email_empty_invalid.return_value = True
|
62 |
+
mock_addOTP.addOTP(email, otp)
|
63 |
+
request = req.RequestCreateOTP(email=email)
|
64 |
+
response = createOTP(request)
|
65 |
+
self.assertIsInstance(response, res.ResponseCreateOTP)
|
66 |
+
self.assertEqual(response.status, 200)
|
67 |
+
self.assertTrue(response.data.check)
|
68 |
+
self.assertEqual(response.otp, "123AB6")
|
69 |
+
|
70 |
+
@patch('service.OTPService.check_email')
|
71 |
+
@patch('service.OTPService.sf')
|
72 |
+
def test_createOTP_failed_empty_email(self,mock_support_function, mock_check_email):
|
73 |
+
email = None
|
74 |
+
mock_support_function.check_email_empty_invalid.return_value = res.ReponseError(status=400, data=res.Message(
|
75 |
+
message="Email is empty"))
|
76 |
+
request = req.RequestCreateOTP(email=email)
|
77 |
+
response = createOTP(request)
|
78 |
+
self.assertIsInstance(response, res.ReponseError)
|
79 |
+
self.assertEqual(response.status, 400)
|
80 |
+
self.assertEqual(response.data.message, "Email is empty")
|
81 |
+
|
82 |
+
@patch('service.OTPService.check_email')
|
83 |
+
@patch('service.OTPService.OTPRepository.addOTP')
|
84 |
+
@patch('service.OTPService.sf')
|
85 |
+
def test_createOTP_failed_empty_invalid(self,mock_support_function, mock_addOTP, mock_check_email):
|
86 |
+
email = "20133"
|
87 |
+
mock_support_function.check_email_empty_invalid.return_value = res.ReponseError(status=400, data=res.Message(
|
88 |
+
message="Email invalid"))
|
89 |
+
request = req.RequestCreateOTP(email=email)
|
90 |
+
mock_check_email.return_value = False
|
91 |
+
response = createOTP(request)
|
92 |
+
self.assertIsInstance(response, res.ReponseError)
|
93 |
+
self.assertEqual(response.status, 400)
|
94 |
+
self.assertEqual(response.data.message, "Email invalid")
|
95 |
+
mock_addOTP.assert_not_called()
|
96 |
+
|
97 |
+
class TestVerifyOTPFunctions(unittest.TestCase):
|
98 |
+
@patch('service.OTPService.check_email', return_value=True)
|
99 |
+
@patch('service.OTPService.OTPRepository.getOtpByEmail')
|
100 |
+
@patch('service.OTPService.OTPRepository.deleteOTP')
|
101 |
+
@patch('service.OTPService.sf')
|
102 |
+
def test_verifyOTP_success(self,mock_support_function, mock_deleteOTP, mock_getOtpByEmail, mock_check_email):
|
103 |
+
current_time = datetime.now()
|
104 |
+
mock_support_function.check_email_empty_invalid.return_value = True
|
105 |
+
mock_getOtpByEmail.return_value = MagicMock(otp="123456", created_at=current_time - timedelta(minutes=5))
|
106 |
+
|
107 |
+
email = "user@example.com"
|
108 |
+
otp = "123456"
|
109 |
+
request = req.RequestVerifyOTP(email=email, otp=otp)
|
110 |
+
response = verifyOTP(request)
|
111 |
+
mock_deleteOTP(email, otp)
|
112 |
+
self.assertIsInstance(response, res.ResponseVerifyOTPSignUp)
|
113 |
+
self.assertEqual(response.status, 200)
|
114 |
+
self.assertEqual(response.data.message, "OTP is valid")
|
115 |
+
|
116 |
+
@patch('service.OTPService.check_email', return_value=True)
|
117 |
+
@patch('service.OTPService.OTPRepository.getOtpByEmail')
|
118 |
+
@patch('service.OTPService.sf')
|
119 |
+
def test_verifyOTP_failed_invalid_otp(self,mock_support_function, mock_getOtpByEmail, mock_check_email):
|
120 |
+
current_time = datetime.now()
|
121 |
+
mock_support_function.check_email_empty_invalid.return_value = True
|
122 |
+
mock_getOtpByEmail.return_value = MagicMock(otp="654321", created_at=current_time - timedelta(minutes=5))
|
123 |
+
|
124 |
+
email = "user@example.com"
|
125 |
+
otp = "123456"
|
126 |
+
request = req.RequestVerifyOTP(email=email, otp=otp)
|
127 |
+
response = verifyOTP(request)
|
128 |
+
self.assertIsInstance(response, res.ReponseError)
|
129 |
+
self.assertEqual(response.status, 400)
|
130 |
+
self.assertEqual(response.data.message, "Invalid OTP")
|
131 |
+
|
132 |
+
@patch('service.OTPService.check_email')
|
133 |
+
@patch('service.OTPService.sf')
|
134 |
+
def test_verifyOTP_failed_invalid_email(self,mock_support_function, mock_check_email):
|
135 |
+
email = "invalidemail"
|
136 |
+
otp = "123456"
|
137 |
+
mock_support_function.check_email_empty_invalid.return_value =res.ReponseError(status=400, data=res.Message(
|
138 |
+
message="Email invalid"))
|
139 |
+
|
140 |
+
request = req.RequestVerifyOTP(email=email, otp=otp)
|
141 |
+
|
142 |
+
response = verifyOTP(request)
|
143 |
+
self.assertIsInstance(response, res.ReponseError)
|
144 |
+
self.assertEqual(response.status, 400)
|
145 |
+
self.assertEqual(response.data.message, "Email invalid")
|
146 |
+
|
147 |
+
@patch('service.OTPService.sf')
|
148 |
+
def test_verifyOTP_failed_empty_email(self,mock_support_function):
|
149 |
+
email = None
|
150 |
+
otp = "123456"
|
151 |
+
mock_support_function.check_email_empty_invalid.return_value = res.ReponseError(status=400, data=res.Message(
|
152 |
+
message="Email is empty"))
|
153 |
+
request = req.RequestVerifyOTP(email=email, otp=otp)
|
154 |
+
response = verifyOTP(request)
|
155 |
+
self.assertIsInstance(response, res.ReponseError)
|
156 |
+
self.assertEqual(response.status, 400)
|
157 |
+
self.assertEqual(response.data.message, "Email is empty")
|
158 |
+
|
159 |
+
@patch('service.OTPService.check_email')
|
160 |
+
@patch('service.OTPService.sf')
|
161 |
+
def test_verifyOTP_failed_empty_otp(self,mock_support_function, mock_check_email):
|
162 |
+
email = "user@example.com"
|
163 |
+
otp = None
|
164 |
+
mock_support_function.check_email_empty_invalid.return_value = True
|
165 |
+
request = req.RequestVerifyOTP(email=email, otp=otp)
|
166 |
+
mock_check_email.return_value = True
|
167 |
+
response = verifyOTP(request)
|
168 |
+
self.assertIsInstance(response, res.ReponseError)
|
169 |
+
self.assertEqual(response.status, 400)
|
170 |
+
self.assertEqual(response.data.message, "otp is empty")
|
171 |
+
|
172 |
+
@patch('service.OTPService.check_email', return_value=True)
|
173 |
+
@patch('service.OTPService.OTPRepository.getOtpByEmail')
|
174 |
+
@patch('service.OTPService.sf')
|
175 |
+
def test_verifyOTP_failed_no_otp_found(self,mock_support_function, mock_getOtpByEmail, mock_check_email):
|
176 |
+
mock_getOtpByEmail.return_value = None
|
177 |
+
email = "user@example.com"
|
178 |
+
otp = "123456"
|
179 |
+
mock_support_function.check_email_empty_invalid.return_value = True
|
180 |
+
request = req.RequestVerifyOTP(email=email, otp=otp)
|
181 |
+
response = verifyOTP(request)
|
182 |
+
self.assertIsInstance(response, res.ReponseError)
|
183 |
+
self.assertEqual(response.status, 404)
|
184 |
+
self.assertEqual(response.data.message, "No OTP found for this email")
|
185 |
+
|
186 |
+
@patch('service.OTPService.check_email')
|
187 |
+
@patch('service.OTPService.OTPRepository.getOtpByEmail')
|
188 |
+
@patch('service.OTPService.sf')
|
189 |
+
def test_verifyOTP_has_expired(self,mock_support_function, mock_getOtpByEmail, mock_check_email):
|
190 |
+
current_time = datetime.now()
|
191 |
+
mock_getOtpByEmail.return_value = MagicMock(otp="123456", created_at=current_time - timedelta(minutes=100))
|
192 |
+
email = "user@example.com"
|
193 |
+
otp = "123456"
|
194 |
+
mock_support_function.check_email_empty_invalid.return_value = True
|
195 |
+
request = req.RequestVerifyOTP(email=email, otp=otp)
|
196 |
+
response = verifyOTP(request)
|
197 |
+
self.assertIsInstance(response, res.ReponseError)
|
198 |
+
self.assertEqual(response.status, 400)
|
199 |
+
self.assertEqual(response.data.message, "OTP has expired")
|
200 |
+
|
201 |
+
class TestVerifyOTPReset(unittest.TestCase):
|
202 |
+
@patch('service.OTPService.check_email')
|
203 |
+
@patch('service.OTPService.OTPRepository.getOtpByEmail')
|
204 |
+
@patch('service.OTPService.OTPRepository')
|
205 |
+
@patch('service.OTPService.auth.get_user_by_email')
|
206 |
+
@patch('service.OTPService.auth')
|
207 |
+
@patch('service.OTPService.sf')
|
208 |
+
def test_verifyOTPReset_success(self,mock_support_function, mock_update_user, mock_get_user_by_email, mock_deleteOTP, mock_getOtpByEmail,
|
209 |
+
mock_check_email):
|
210 |
+
current_time = datetime.now()
|
211 |
+
mock_support_function.check_email_empty_invalid.return_value = True
|
212 |
+
mock_getOtpByEmail.return_value = MagicMock(otp="123456", created_at=current_time - timedelta(minutes=5))
|
213 |
+
mock_get_user_by_email.return_value = MagicMock(uid="12345")
|
214 |
+
email = "user@example.com"
|
215 |
+
otp = "123456"
|
216 |
+
mock_check_email.return_value = True
|
217 |
+
request = req.RequestVerifyOTP(email=email, otp=otp)
|
218 |
+
mock_update_user.update_user(uid="12345", )
|
219 |
+
response = verifyOTPReset(request)
|
220 |
+
mock_deleteOTP.deleteOTP("user@example.com", "123456")
|
221 |
+
self.assertIsInstance(response, res.ResponseVerifyOTP)
|
222 |
+
self.assertEqual(response.status, 200)
|
223 |
+
self.assertEqual(response.data.message, "New Password send to Email")
|
224 |
+
|
225 |
+
@patch('service.OTPService.check_email')
|
226 |
+
@patch('service.OTPService.OTPRepository.getOtpByEmail')
|
227 |
+
@patch('service.OTPService.sf')
|
228 |
+
def test_verifyOTPReset_failed_invalid_otp(self,mock_support_function, mock_getOtpByEmail, mock_check_email):
|
229 |
+
current_time = datetime.now()
|
230 |
+
mock_support_function.check_email_empty_invalid.return_value = True
|
231 |
+
mock_getOtpByEmail.return_value = MagicMock(otp="654321", created_at=current_time - timedelta(minutes=5))
|
232 |
+
email = "user@example.com"
|
233 |
+
otp = "123456"
|
234 |
+
mock_check_email.return_value = True
|
235 |
+
request = req.RequestVerifyOTP(email=email, otp=otp)
|
236 |
+
response = verifyOTPReset(request)
|
237 |
+
self.assertIsInstance(response, res.ReponseError)
|
238 |
+
self.assertEqual(response.status, 400)
|
239 |
+
self.assertEqual(response.data.message, "Invalid OTP")
|
240 |
+
|
241 |
+
@patch('service.OTPService.check_email')
|
242 |
+
@patch('service.OTPService.OTPRepository.getOtpByEmail')
|
243 |
+
@patch('service.OTPService.sf')
|
244 |
+
def test_verifyOTPReset_failed_no_otp_found(self,mock_support_function, mock_getOtpByEmail, mock_check_email):
|
245 |
+
mock_getOtpByEmail.return_value = None
|
246 |
+
email = "user@example.com"
|
247 |
+
otp = "123456"
|
248 |
+
request = req.RequestVerifyOTP(email=email, otp=otp)
|
249 |
+
mock_support_function.check_email_empty_invalid.return_value = True
|
250 |
+
response = verifyOTPReset(request)
|
251 |
+
self.assertIsInstance(response, res.ReponseError)
|
252 |
+
self.assertEqual(response.status, 404)
|
253 |
+
self.assertEqual(response.data.message, "No OTP found for this email")
|
254 |
+
|
255 |
+
@patch('service.OTPService.check_email')
|
256 |
+
@patch('service.OTPService.OTPRepository.getOtpByEmail')
|
257 |
+
@patch('service.OTPService.sf')
|
258 |
+
def test_verifyOTPReset_has_expired(self,mock_support_function, mock_getOtpByEmail, mock_check_email):
|
259 |
+
current_time = datetime.now()
|
260 |
+
mock_getOtpByEmail.return_value = MagicMock(otp="123456", created_at=current_time - timedelta(minutes=100))
|
261 |
+
email = "vonhuy@gmail.com"
|
262 |
+
otp = "123456"
|
263 |
+
mock_support_function.check_email_empty_invalid.return_value = True
|
264 |
+
request = req.RequestVerifyOTP(email=email, otp=otp)
|
265 |
+
response = verifyOTPReset(request)
|
266 |
+
self.assertIsInstance(response, res.ReponseError)
|
267 |
+
self.assertEqual(response.status, 400)
|
268 |
+
self.assertEqual(response.data.message, "OTP has expired")
|
269 |
+
|
270 |
+
@patch('service.OTPService.check_email')
|
271 |
+
@patch('service.OTPService.sf')
|
272 |
+
def test_verifyOTPReset_failed_invalid_email(self,mock_support_function, mock_check_email):
|
273 |
+
email = "invalidemail"
|
274 |
+
otp = "123456"
|
275 |
+
mock_support_function.check_email_empty_invalid.return_value = res.ReponseError(status=400, data=res.Message(
|
276 |
+
message="Email invalid"))
|
277 |
+
request = req.RequestVerifyOTP(email=email, otp=otp)
|
278 |
+
response = verifyOTPReset(request)
|
279 |
+
self.assertIsInstance(response, res.ReponseError)
|
280 |
+
self.assertEqual(response.status, 400)
|
281 |
+
self.assertEqual(response.data.message, "Email invalid")
|
282 |
+
|
283 |
+
@patch('service.OTPService.check_email')
|
284 |
+
@patch('service.OTPService.OTPRepository.getOtpByEmail')
|
285 |
+
@patch('service.OTPService.sf')
|
286 |
+
def test_verifyOTPReset_failed_empty_email(self,mock_support_function, mock_getOtpByEmail, mock_check_email):
|
287 |
+
email = None
|
288 |
+
otp = "123456"
|
289 |
+
request = req.RequestVerifyOTP(email=email, otp=otp)
|
290 |
+
mock_support_function.check_email_empty_invalid.return_value = res.ReponseError(status=400, data=res.Message(
|
291 |
+
message="Email is empty"))
|
292 |
+
response = verifyOTPReset(request)
|
293 |
+
self.assertIsInstance(response, res.ReponseError)
|
294 |
+
self.assertEqual(response.status, 400)
|
295 |
+
self.assertEqual(response.data.message, "Email is empty")
|
296 |
+
|
297 |
+
@patch('service.OTPService.check_email', return_value=True)
|
298 |
+
@patch('service.OTPService.sf')
|
299 |
+
def test_verifyOTPReset_failed_empty_otp(self,mock_support_function, mock_check_email):
|
300 |
+
email = "user@example.com"
|
301 |
+
otp = None
|
302 |
+
mock_support_function.check_email_empty_invalid.return_value = True
|
303 |
+
request = req.RequestVerifyOTP(email=email, otp=otp)
|
304 |
+
response = verifyOTPReset(request)
|
305 |
+
self.assertIsInstance(response, res.ReponseError)
|
306 |
+
self.assertEqual(response.status, 400)
|
307 |
+
self.assertEqual(response.data.message, "OTP is empty")
|
308 |
+
|
309 |
+
|
310 |
+
if __name__ == '__main__':
|
311 |
+
unittest.main()
|