kltn20133118 commited on
Commit
6b725f7
·
verified ·
1 Parent(s): 5f0f3a6

Upload 48 files

Browse files
Files changed (48) hide show
  1. auth/authentication.py +133 -0
  2. controller/AuthenticationController.py +62 -0
  3. controller/ChatController.py +35 -0
  4. controller/DefaultController.py +70 -0
  5. controller/FileController.py +63 -0
  6. controller/MySQLController.py +76 -0
  7. controller/OTPController.py +33 -0
  8. controller/UserController.py +94 -0
  9. function/chatbot.py +685 -0
  10. function/dropbox.py +155 -0
  11. function/support_function.py +128 -0
  12. models/Database_Entity.py +68 -0
  13. request/RequestAuth.py +19 -0
  14. request/RequestChat.py +18 -0
  15. request/RequestDefault.py +15 -0
  16. request/RequestFile.py +20 -0
  17. request/RequestMySQL.py +25 -0
  18. request/RequestOTP.py +9 -0
  19. request/RequestUser.py +52 -0
  20. response/ResponseAuth.py +42 -0
  21. response/ResponseChat.py +55 -0
  22. response/ResponseDefault.py +44 -0
  23. response/ResponseFile.py +39 -0
  24. response/ResponseMySQL.py +59 -0
  25. response/ResponseOTP.py +25 -0
  26. response/ResponseUser.py +74 -0
  27. service/AuthService.py +292 -0
  28. service/ChatService.py +141 -0
  29. service/DefaultService.py +205 -0
  30. service/FileService.py +151 -0
  31. service/MySQLService.py +201 -0
  32. service/OTPService.py +168 -0
  33. service/UserService.py +322 -0
  34. service/app/firebase_certificate.json +0 -0
  35. tests/test_controller/__init__.py +0 -0
  36. tests/test_controller/test_ChatController.py +258 -0
  37. tests/test_controller/test_DefaultController.py +330 -0
  38. tests/test_controller/test_FileController.py +478 -0
  39. tests/test_controller/test_LoginController.py +650 -0
  40. tests/test_controller/test_MySQLController.py +314 -0
  41. tests/test_controller/test_OTPController.py +292 -0
  42. tests/test_service/_init__.py +0 -0
  43. tests/test_service/test_ChatService.py +462 -0
  44. tests/test_service/test_DefaultService.py +344 -0
  45. tests/test_service/test_FileService.py +471 -0
  46. tests/test_service/test_LoginService.py +560 -0
  47. tests/test_service/test_MySQLService.py +382 -0
  48. 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()