iatoolkit 0.8.1__py3-none-any.whl → 0.63.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of iatoolkit might be problematic. Click here for more details.
- iatoolkit/__init__.py +8 -34
- iatoolkit/base_company.py +14 -3
- iatoolkit/common/routes.py +83 -52
- iatoolkit/common/session_manager.py +0 -1
- iatoolkit/common/util.py +0 -27
- iatoolkit/iatoolkit.py +61 -46
- iatoolkit/infra/llm_client.py +7 -8
- iatoolkit/infra/openai_adapter.py +1 -1
- iatoolkit/infra/redis_session_manager.py +48 -2
- iatoolkit/repositories/database_manager.py +17 -2
- iatoolkit/repositories/models.py +31 -6
- iatoolkit/repositories/profile_repo.py +7 -2
- iatoolkit/services/auth_service.py +188 -0
- iatoolkit/services/branding_service.py +147 -0
- iatoolkit/services/dispatcher_service.py +10 -40
- iatoolkit/services/excel_service.py +15 -15
- iatoolkit/services/history_service.py +3 -12
- iatoolkit/services/jwt_service.py +15 -24
- iatoolkit/services/onboarding_service.py +43 -0
- iatoolkit/services/profile_service.py +97 -44
- iatoolkit/services/query_service.py +124 -81
- iatoolkit/services/tasks_service.py +1 -1
- iatoolkit/services/user_feedback_service.py +67 -31
- iatoolkit/services/user_session_context_service.py +112 -54
- iatoolkit/static/images/fernando.jpeg +0 -0
- iatoolkit/static/js/{chat_feedback.js → chat_feedback_button.js} +6 -11
- iatoolkit/static/js/chat_history_button.js +126 -0
- iatoolkit/static/js/chat_logout_button.js +36 -0
- iatoolkit/static/js/chat_main.js +130 -220
- iatoolkit/static/js/chat_onboarding_button.js +97 -0
- iatoolkit/static/js/chat_prompt_manager.js +94 -0
- iatoolkit/static/js/chat_reload_button.js +52 -0
- iatoolkit/static/styles/chat_iatoolkit.css +329 -507
- iatoolkit/static/styles/chat_modal.css +95 -56
- iatoolkit/static/styles/landing_page.css +182 -0
- iatoolkit/static/styles/onboarding.css +169 -0
- iatoolkit/system_prompts/query_main.prompt +3 -12
- iatoolkit/templates/_company_header.html +20 -0
- iatoolkit/templates/_login_widget.html +40 -0
- iatoolkit/templates/base.html +8 -3
- iatoolkit/templates/change_password.html +54 -37
- iatoolkit/templates/chat.html +149 -66
- iatoolkit/templates/chat_modals.html +47 -18
- iatoolkit/templates/error.html +41 -8
- iatoolkit/templates/forgot_password.html +37 -24
- iatoolkit/templates/index.html +140 -0
- iatoolkit/templates/login_simulation.html +34 -0
- iatoolkit/templates/onboarding_shell.html +105 -0
- iatoolkit/templates/signup.html +64 -66
- iatoolkit/views/base_login_view.py +81 -0
- iatoolkit/views/change_password_view.py +23 -12
- iatoolkit/views/external_login_view.py +61 -28
- iatoolkit/views/{file_store_view.py → file_store_api_view.py} +9 -2
- iatoolkit/views/forgot_password_view.py +23 -13
- iatoolkit/views/history_api_view.py +52 -0
- iatoolkit/views/home_view.py +58 -25
- iatoolkit/views/index_view.py +14 -0
- iatoolkit/views/init_context_api_view.py +68 -0
- iatoolkit/views/llmquery_api_view.py +45 -0
- iatoolkit/views/login_simulation_view.py +81 -0
- iatoolkit/views/login_view.py +118 -34
- iatoolkit/views/logout_api_view.py +45 -0
- iatoolkit/views/{prompt_view.py → prompt_api_view.py} +7 -7
- iatoolkit/views/signup_view.py +38 -29
- iatoolkit/views/{tasks_view.py → tasks_api_view.py} +10 -36
- iatoolkit/views/tasks_review_api_view.py +55 -0
- iatoolkit/views/{user_feedback_view.py → user_feedback_api_view.py} +16 -31
- iatoolkit/views/verify_user_view.py +13 -8
- {iatoolkit-0.8.1.dist-info → iatoolkit-0.63.4.dist-info}/METADATA +2 -2
- iatoolkit-0.63.4.dist-info/RECORD +113 -0
- {iatoolkit-0.8.1.dist-info → iatoolkit-0.63.4.dist-info}/top_level.txt +0 -1
- iatoolkit/common/auth.py +0 -200
- iatoolkit/static/images/arrow_up.png +0 -0
- iatoolkit/static/images/diagrama_iatoolkit.jpg +0 -0
- iatoolkit/static/images/logo_clinica.png +0 -0
- iatoolkit/static/images/logo_iatoolkit.png +0 -0
- iatoolkit/static/images/logo_maxxa.png +0 -0
- iatoolkit/static/images/logo_notaria.png +0 -0
- iatoolkit/static/images/logo_tarjeta.png +0 -0
- iatoolkit/static/images/logo_umayor.png +0 -0
- iatoolkit/static/images/upload.png +0 -0
- iatoolkit/static/js/chat_history.js +0 -117
- iatoolkit/templates/home.html +0 -201
- iatoolkit/templates/login.html +0 -43
- iatoolkit/views/chat_token_request_view.py +0 -98
- iatoolkit/views/chat_view.py +0 -51
- iatoolkit/views/download_file_view.py +0 -58
- iatoolkit/views/external_chat_login_view.py +0 -88
- iatoolkit/views/history_view.py +0 -57
- iatoolkit/views/llmquery_view.py +0 -65
- iatoolkit/views/tasks_review_view.py +0 -83
- iatoolkit-0.8.1.dist-info/RECORD +0 -175
- tests/__init__.py +0 -5
- tests/common/__init__.py +0 -0
- tests/common/test_auth.py +0 -279
- tests/common/test_routes.py +0 -42
- tests/common/test_session_manager.py +0 -59
- tests/common/test_util.py +0 -444
- tests/companies/__init__.py +0 -5
- tests/conftest.py +0 -36
- tests/infra/__init__.py +0 -5
- tests/infra/connectors/__init__.py +0 -5
- tests/infra/connectors/test_google_drive_connector.py +0 -107
- tests/infra/connectors/test_local_file_connector.py +0 -85
- tests/infra/connectors/test_s3_connector.py +0 -95
- tests/infra/test_call_service.py +0 -92
- tests/infra/test_database_manager.py +0 -59
- tests/infra/test_gemini_adapter.py +0 -137
- tests/infra/test_google_chat_app.py +0 -68
- tests/infra/test_llm_client.py +0 -165
- tests/infra/test_llm_proxy.py +0 -122
- tests/infra/test_mail_app.py +0 -94
- tests/infra/test_openai_adapter.py +0 -105
- tests/infra/test_redis_session_manager_service.py +0 -117
- tests/repositories/__init__.py +0 -5
- tests/repositories/test_database_manager.py +0 -87
- tests/repositories/test_document_repo.py +0 -76
- tests/repositories/test_llm_query_repo.py +0 -340
- tests/repositories/test_models.py +0 -38
- tests/repositories/test_profile_repo.py +0 -142
- tests/repositories/test_tasks_repo.py +0 -76
- tests/repositories/test_vs_repo.py +0 -107
- tests/services/__init__.py +0 -5
- tests/services/test_dispatcher_service.py +0 -274
- tests/services/test_document_service.py +0 -181
- tests/services/test_excel_service.py +0 -208
- tests/services/test_file_processor_service.py +0 -121
- tests/services/test_history_service.py +0 -164
- tests/services/test_jwt_service.py +0 -255
- tests/services/test_load_documents_service.py +0 -112
- tests/services/test_mail_service.py +0 -70
- tests/services/test_profile_service.py +0 -379
- tests/services/test_prompt_manager_service.py +0 -190
- tests/services/test_query_service.py +0 -243
- tests/services/test_search_service.py +0 -39
- tests/services/test_sql_service.py +0 -160
- tests/services/test_tasks_service.py +0 -252
- tests/services/test_user_feedback_service.py +0 -389
- tests/services/test_user_session_context_service.py +0 -132
- tests/views/__init__.py +0 -5
- tests/views/test_change_password_view.py +0 -191
- tests/views/test_chat_token_request_view.py +0 -188
- tests/views/test_chat_view.py +0 -98
- tests/views/test_download_file_view.py +0 -149
- tests/views/test_external_chat_login_view.py +0 -120
- tests/views/test_external_login_view.py +0 -102
- tests/views/test_file_store_view.py +0 -128
- tests/views/test_forgot_password_view.py +0 -142
- tests/views/test_history_view.py +0 -336
- tests/views/test_home_view.py +0 -61
- tests/views/test_llm_query_view.py +0 -154
- tests/views/test_login_view.py +0 -114
- tests/views/test_prompt_view.py +0 -111
- tests/views/test_signup_view.py +0 -140
- tests/views/test_tasks_review_view.py +0 -104
- tests/views/test_tasks_view.py +0 -130
- tests/views/test_user_feedback_view.py +0 -214
- tests/views/test_verify_user_view.py +0 -110
- {iatoolkit-0.8.1.dist-info → iatoolkit-0.63.4.dist-info}/WHEEL +0 -0
tests/views/test_history_view.py
DELETED
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2024 Fernando Libedinsky
|
|
2
|
-
# Product: IAToolkit
|
|
3
|
-
#
|
|
4
|
-
# IAToolkit is open source software.
|
|
5
|
-
|
|
6
|
-
import pytest
|
|
7
|
-
from unittest.mock import MagicMock, patch
|
|
8
|
-
from flask import Flask
|
|
9
|
-
from iatoolkit.views.history_view import HistoryView
|
|
10
|
-
from iatoolkit.services.history_service import HistoryService
|
|
11
|
-
from iatoolkit.common.auth import IAuthentication
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class TestHistoryView:
|
|
15
|
-
@staticmethod
|
|
16
|
-
def create_app():
|
|
17
|
-
app = Flask(__name__)
|
|
18
|
-
app.testing = True
|
|
19
|
-
return app
|
|
20
|
-
|
|
21
|
-
@pytest.fixture(autouse=True)
|
|
22
|
-
def setup(self):
|
|
23
|
-
self.app = self.create_app()
|
|
24
|
-
self.client = self.app.test_client()
|
|
25
|
-
self.history_service = MagicMock(spec=HistoryService)
|
|
26
|
-
self.iauthentication = MagicMock(spec=IAuthentication)
|
|
27
|
-
|
|
28
|
-
self.iauthentication.verify.return_value = {
|
|
29
|
-
'success': True,
|
|
30
|
-
'company_id': 101,
|
|
31
|
-
'external_user_id': 'test_user_id'
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
# register the view
|
|
35
|
-
self.history_view = HistoryView.as_view("history",
|
|
36
|
-
history_service=self.history_service,
|
|
37
|
-
iauthentication=self.iauthentication)
|
|
38
|
-
self.app.add_url_rule('/<company_short_name>/history',
|
|
39
|
-
view_func=self.history_view,
|
|
40
|
-
methods=["POST"])
|
|
41
|
-
|
|
42
|
-
def test_post_when_missing_data(self):
|
|
43
|
-
"""Test when no JSON data is provided"""
|
|
44
|
-
response = self.client.post('/my_company/history',
|
|
45
|
-
json={})
|
|
46
|
-
|
|
47
|
-
assert response.status_code == 400
|
|
48
|
-
assert response.json["error_message"] == "Cuerpo de la solicitud JSON inválido o faltante"
|
|
49
|
-
self.history_service.get_history.assert_not_called()
|
|
50
|
-
|
|
51
|
-
def test_post_when_invalid_json(self):
|
|
52
|
-
"""Test when invalid JSON is provided"""
|
|
53
|
-
response = self.client.post('/my_company/history',
|
|
54
|
-
data='invalid json',
|
|
55
|
-
content_type='application/json')
|
|
56
|
-
|
|
57
|
-
assert response.status_code == 400
|
|
58
|
-
assert response.json["error_message"] == "Cuerpo de la solicitud JSON inválido o faltante"
|
|
59
|
-
self.history_service.get_history.assert_not_called()
|
|
60
|
-
|
|
61
|
-
def test_post_when_auth_error(self):
|
|
62
|
-
"""Test when authentication fails"""
|
|
63
|
-
self.iauthentication.verify.return_value = {
|
|
64
|
-
'success': False,
|
|
65
|
-
'error_message': 'Usuario no autenticado'
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
response = self.client.post('/my_company/history',
|
|
69
|
-
json={'external_user_id': 'flibe'})
|
|
70
|
-
|
|
71
|
-
assert response.status_code == 401
|
|
72
|
-
assert response.json["error_message"] == 'Usuario no autenticado'
|
|
73
|
-
self.history_service.get_history.assert_not_called()
|
|
74
|
-
|
|
75
|
-
def test_post_when_missing_external_user_id(self):
|
|
76
|
-
"""Test when external_user_id is missing"""
|
|
77
|
-
response = self.client.post('/my_company/history',
|
|
78
|
-
json={})
|
|
79
|
-
|
|
80
|
-
assert response.status_code == 400
|
|
81
|
-
assert response.json["error_message"] == "Cuerpo de la solicitud JSON inválido o faltante"
|
|
82
|
-
self.history_service.get_history.assert_not_called()
|
|
83
|
-
|
|
84
|
-
def test_post_when_service_error(self):
|
|
85
|
-
"""Test when service returns an error"""
|
|
86
|
-
self.history_service.get_history.return_value = {
|
|
87
|
-
'error': 'Error al obtener historial'
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
response = self.client.post('/my_company/history',
|
|
91
|
-
json={'external_user_id': 'flibe'})
|
|
92
|
-
|
|
93
|
-
assert response.status_code == 402
|
|
94
|
-
assert response.json == {'error_message': 'Error al obtener historial'}
|
|
95
|
-
|
|
96
|
-
def test_post_when_service_exception(self):
|
|
97
|
-
"""Test when service raises an exception"""
|
|
98
|
-
self.history_service.get_history.side_effect = Exception('Service error')
|
|
99
|
-
|
|
100
|
-
response = self.client.post('/my_company/history',
|
|
101
|
-
json={'external_user_id': 'flibe'})
|
|
102
|
-
|
|
103
|
-
assert response.status_code == 500
|
|
104
|
-
assert response.json["error_message"] == 'Service error'
|
|
105
|
-
|
|
106
|
-
def test_post_when_ok_with_external_user_id(self):
|
|
107
|
-
"""Test successful request with external_user_id"""
|
|
108
|
-
mock_history = {
|
|
109
|
-
'success': True,
|
|
110
|
-
'history': [
|
|
111
|
-
{
|
|
112
|
-
'id': 1,
|
|
113
|
-
'question': 'Test question',
|
|
114
|
-
'answer': 'Test answer',
|
|
115
|
-
'created_at': '2024-01-15T10:30:00Z'
|
|
116
|
-
}
|
|
117
|
-
],
|
|
118
|
-
'count': 1
|
|
119
|
-
}
|
|
120
|
-
self.history_service.get_history.return_value = mock_history
|
|
121
|
-
|
|
122
|
-
response = self.client.post('/my_company/history',
|
|
123
|
-
json={'external_user_id': 'flibe'})
|
|
124
|
-
|
|
125
|
-
assert response.status_code == 200
|
|
126
|
-
assert response.json == mock_history
|
|
127
|
-
|
|
128
|
-
# Verify service was called correctly
|
|
129
|
-
self.history_service.get_history.assert_called_once_with(
|
|
130
|
-
company_short_name='my_company',
|
|
131
|
-
external_user_id='flibe',
|
|
132
|
-
local_user_id=0
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
def test_post_when_ok_with_local_user_id(self):
|
|
136
|
-
"""Test successful request with local_user_id"""
|
|
137
|
-
mock_history = {
|
|
138
|
-
'success': True,
|
|
139
|
-
'history': [
|
|
140
|
-
{
|
|
141
|
-
'id': 1,
|
|
142
|
-
'question': 'Test question',
|
|
143
|
-
'answer': 'Test answer',
|
|
144
|
-
'created_at': '2024-01-15T10:30:00Z'
|
|
145
|
-
}
|
|
146
|
-
],
|
|
147
|
-
'count': 1
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
self.history_service.get_history.return_value = mock_history
|
|
151
|
-
|
|
152
|
-
response = self.client.post('/my_company/history',
|
|
153
|
-
json={
|
|
154
|
-
'external_user_id': 'flibe',
|
|
155
|
-
'local_user_id': 123
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
assert response.status_code == 200
|
|
159
|
-
assert response.json == mock_history
|
|
160
|
-
|
|
161
|
-
# Verify service was called correctly
|
|
162
|
-
self.history_service.get_history.assert_called_once_with(
|
|
163
|
-
company_short_name='my_company',
|
|
164
|
-
external_user_id='flibe',
|
|
165
|
-
local_user_id=123
|
|
166
|
-
)
|
|
167
|
-
|
|
168
|
-
def test_post_when_ok_with_both_user_ids(self):
|
|
169
|
-
"""Test successful request with both user IDs"""
|
|
170
|
-
mock_history = {
|
|
171
|
-
'success': True,
|
|
172
|
-
'history': [
|
|
173
|
-
{
|
|
174
|
-
'id': 1,
|
|
175
|
-
'question': 'Test question',
|
|
176
|
-
'answer': 'Test answer',
|
|
177
|
-
'created_at': '2024-01-15T10:30:00Z'
|
|
178
|
-
}
|
|
179
|
-
],
|
|
180
|
-
'count': 1
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
self.history_service.get_history.return_value = mock_history
|
|
184
|
-
|
|
185
|
-
response = self.client.post('/my_company/history',
|
|
186
|
-
json={
|
|
187
|
-
'external_user_id': 'flibe',
|
|
188
|
-
'local_user_id': 456
|
|
189
|
-
})
|
|
190
|
-
|
|
191
|
-
assert response.status_code == 200
|
|
192
|
-
assert response.json == mock_history
|
|
193
|
-
|
|
194
|
-
# Verify service was called correctly
|
|
195
|
-
self.history_service.get_history.assert_called_once_with(
|
|
196
|
-
company_short_name='my_company',
|
|
197
|
-
external_user_id='flibe',
|
|
198
|
-
local_user_id=456
|
|
199
|
-
)
|
|
200
|
-
|
|
201
|
-
def test_post_with_empty_history(self):
|
|
202
|
-
"""Test when service returns empty history"""
|
|
203
|
-
mock_history = {
|
|
204
|
-
'success': True,
|
|
205
|
-
'history': [],
|
|
206
|
-
'count': 0
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
self.history_service.get_history.return_value = mock_history
|
|
210
|
-
|
|
211
|
-
response = self.client.post('/my_company/history',
|
|
212
|
-
json={'external_user_id': 'flibe'})
|
|
213
|
-
|
|
214
|
-
assert response.status_code == 200
|
|
215
|
-
assert response.json == mock_history
|
|
216
|
-
assert response.json['count'] == 0
|
|
217
|
-
|
|
218
|
-
def test_post_with_large_history(self):
|
|
219
|
-
"""Test with large history response"""
|
|
220
|
-
mock_history = {
|
|
221
|
-
'success': True,
|
|
222
|
-
'history': [
|
|
223
|
-
{
|
|
224
|
-
'id': i,
|
|
225
|
-
'question': f'Question {i}',
|
|
226
|
-
'answer': f'Answer {i}',
|
|
227
|
-
'created_at': '2024-01-15T10:30:00Z'
|
|
228
|
-
} for i in range(1, 11)
|
|
229
|
-
],
|
|
230
|
-
'count': 10
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
self.history_service.get_history.return_value = mock_history
|
|
234
|
-
|
|
235
|
-
response = self.client.post('/my_company/history',
|
|
236
|
-
json={'external_user_id': 'flibe'})
|
|
237
|
-
|
|
238
|
-
assert response.status_code == 200
|
|
239
|
-
assert response.json == mock_history
|
|
240
|
-
assert response.json['count'] == 10
|
|
241
|
-
assert len(response.json['history']) == 10
|
|
242
|
-
|
|
243
|
-
@patch("iatoolkit.views.history_view.render_template")
|
|
244
|
-
def test_post_exception_with_local_user_id(self, mock_render_template):
|
|
245
|
-
"""Test exception handling when local_user_id is present"""
|
|
246
|
-
mock_render_template.return_value = "<html><body>Error</body></html>"
|
|
247
|
-
self.history_service.get_history.side_effect = Exception('Service error')
|
|
248
|
-
|
|
249
|
-
response = self.client.post('/my_company/history',
|
|
250
|
-
json={
|
|
251
|
-
'external_user_id': 'flibe',
|
|
252
|
-
'local_user_id': 123
|
|
253
|
-
})
|
|
254
|
-
|
|
255
|
-
assert response.status_code == 500
|
|
256
|
-
mock_render_template.assert_called_once_with(
|
|
257
|
-
"error.html",
|
|
258
|
-
message="Ha ocurrido un error inesperado."
|
|
259
|
-
)
|
|
260
|
-
|
|
261
|
-
def test_post_exception_without_local_user_id(self):
|
|
262
|
-
"""Test exception handling when local_user_id is not present"""
|
|
263
|
-
self.history_service.get_history.side_effect = Exception('Service error')
|
|
264
|
-
|
|
265
|
-
response = self.client.post('/my_company/history',
|
|
266
|
-
json={'external_user_id': 'flibe'})
|
|
267
|
-
|
|
268
|
-
assert response.status_code == 500
|
|
269
|
-
assert response.json["error_message"] == 'Service error'
|
|
270
|
-
|
|
271
|
-
def test_post_authentication_verification_called(self):
|
|
272
|
-
"""Test that authentication verification is called correctly"""
|
|
273
|
-
mock_history = {
|
|
274
|
-
'success': True,
|
|
275
|
-
'history': [],
|
|
276
|
-
'count': 0
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
self.history_service.get_history.return_value = mock_history
|
|
280
|
-
|
|
281
|
-
response = self.client.post('/my_company/history',
|
|
282
|
-
json={'external_user_id': 'test_user'})
|
|
283
|
-
|
|
284
|
-
assert response.status_code == 200
|
|
285
|
-
|
|
286
|
-
# Verify authentication was called correctly
|
|
287
|
-
self.iauthentication.verify.assert_called_once_with('my_company', 'test_user')
|
|
288
|
-
|
|
289
|
-
def test_post_different_company(self):
|
|
290
|
-
"""Test with different company short name"""
|
|
291
|
-
mock_history = {
|
|
292
|
-
'success': True,
|
|
293
|
-
'history': [],
|
|
294
|
-
'count': 0
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
self.history_service.get_history.return_value = mock_history
|
|
298
|
-
|
|
299
|
-
response = self.client.post('/test_company/history',
|
|
300
|
-
json={'external_user_id': 'flibe'})
|
|
301
|
-
|
|
302
|
-
assert response.status_code == 200
|
|
303
|
-
|
|
304
|
-
# Verify service was called with correct company
|
|
305
|
-
self.history_service.get_history.assert_called_once_with(
|
|
306
|
-
company_short_name='test_company',
|
|
307
|
-
external_user_id='flibe',
|
|
308
|
-
local_user_id=0
|
|
309
|
-
)
|
|
310
|
-
|
|
311
|
-
def test_post_with_additional_fields_ignored(self):
|
|
312
|
-
"""Test that additional fields in JSON are ignored"""
|
|
313
|
-
mock_history = {
|
|
314
|
-
'success': True,
|
|
315
|
-
'history': [],
|
|
316
|
-
'count': 0
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
self.history_service.get_history.return_value = mock_history
|
|
320
|
-
|
|
321
|
-
response = self.client.post('/my_company/history',
|
|
322
|
-
json={
|
|
323
|
-
'external_user_id': 'flibe',
|
|
324
|
-
'local_user_id': 123,
|
|
325
|
-
'extra_field': 'should_be_ignored',
|
|
326
|
-
'another_field': 456
|
|
327
|
-
})
|
|
328
|
-
|
|
329
|
-
assert response.status_code == 200
|
|
330
|
-
|
|
331
|
-
# Verify only expected fields are passed to service
|
|
332
|
-
self.history_service.get_history.assert_called_once_with(
|
|
333
|
-
company_short_name='my_company',
|
|
334
|
-
external_user_id='flibe',
|
|
335
|
-
local_user_id=123
|
|
336
|
-
)
|
tests/views/test_home_view.py
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
from flask import Flask
|
|
3
|
-
from unittest.mock import MagicMock, patch
|
|
4
|
-
import os
|
|
5
|
-
|
|
6
|
-
# Asegúrate de que las importaciones sean correctas y existan
|
|
7
|
-
from iatoolkit.views.home_view import HomeView
|
|
8
|
-
from iatoolkit.services.profile_service import ProfileService
|
|
9
|
-
from iatoolkit.repositories.models import Company
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
# Ya no necesitamos JWTService, ChatTokenRequestView, etc.
|
|
13
|
-
|
|
14
|
-
class TestHomeView:
|
|
15
|
-
@staticmethod
|
|
16
|
-
def create_app():
|
|
17
|
-
"""Configura la aplicación Flask para pruebas."""
|
|
18
|
-
app = Flask(__name__)
|
|
19
|
-
app.testing = True
|
|
20
|
-
return app
|
|
21
|
-
|
|
22
|
-
@pytest.fixture(autouse=True)
|
|
23
|
-
def setup(self):
|
|
24
|
-
"""Configura el cliente y el mock antes de cada test."""
|
|
25
|
-
self.app = self.create_app()
|
|
26
|
-
self.client = self.app.test_client()
|
|
27
|
-
self.profile_service = MagicMock(spec=ProfileService)
|
|
28
|
-
self.test_company = Company(id=1, name='a company', short_name='test_company')
|
|
29
|
-
self.profile_service.get_companies.return_value = [self.test_company]
|
|
30
|
-
|
|
31
|
-
# Registrar únicamente la vista que estamos probando.
|
|
32
|
-
# No necesitamos registrar las otras vistas que han sido eliminadas.
|
|
33
|
-
view = HomeView.as_view("home", profile_service=self.profile_service)
|
|
34
|
-
self.app.add_url_rule("/", view_func=view, methods=["GET"])
|
|
35
|
-
|
|
36
|
-
@patch("iatoolkit.views.home_view.render_template")
|
|
37
|
-
@patch.dict(os.environ, {"IATOOLKIT_API_KEY": "una_api_key_de_prueba_segura"})
|
|
38
|
-
def test_get_home_page(self, mock_render_template):
|
|
39
|
-
"""
|
|
40
|
-
Prueba que la página de inicio se renderice correctamente sin los parámetros obsoletos.
|
|
41
|
-
"""
|
|
42
|
-
mock_render_template.return_value = "<html><body><h1>Home Page</h1></body></html>"
|
|
43
|
-
|
|
44
|
-
# Ya no necesitamos el contexto de la petición para generar las URLs
|
|
45
|
-
response = self.client.get("/")
|
|
46
|
-
|
|
47
|
-
assert response.status_code == 200
|
|
48
|
-
assert b"<h1>Home Page</h1>" in response.data
|
|
49
|
-
|
|
50
|
-
# La aserción ahora debe reflejar los argumentos actuales de render_template en HomeView
|
|
51
|
-
mock_render_template.assert_called_once_with(
|
|
52
|
-
"home.html",
|
|
53
|
-
companies=[self.test_company],
|
|
54
|
-
is_mobile=False,
|
|
55
|
-
alert_icon=None,
|
|
56
|
-
alert_message=None,
|
|
57
|
-
api_key="una_api_key_de_prueba_segura",
|
|
58
|
-
# Hemos eliminado los siguientes parámetros obsoletos:
|
|
59
|
-
# chat_token_request_url=...
|
|
60
|
-
# public_chat_url_template=...
|
|
61
|
-
)
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2024 Fernando Libedinsky
|
|
2
|
-
# Product: IAToolkit
|
|
3
|
-
#
|
|
4
|
-
# IAToolkit is open source software.
|
|
5
|
-
|
|
6
|
-
import pytest
|
|
7
|
-
from unittest.mock import MagicMock, patch
|
|
8
|
-
from flask import Flask
|
|
9
|
-
from iatoolkit.repositories.models import ApiKey, Company
|
|
10
|
-
from iatoolkit.services.query_service import QueryService
|
|
11
|
-
from iatoolkit.views.llmquery_view import LLMQueryView
|
|
12
|
-
from datetime import datetime, timezone
|
|
13
|
-
from iatoolkit.common.session_manager import SessionManager
|
|
14
|
-
from iatoolkit.common.auth import IAuthentication
|
|
15
|
-
|
|
16
|
-
class TestLLMQueryView:
|
|
17
|
-
@staticmethod
|
|
18
|
-
def create_app():
|
|
19
|
-
"""Configura la aplicación Flask para pruebas."""
|
|
20
|
-
app = Flask(__name__)
|
|
21
|
-
app.testing = True
|
|
22
|
-
app.config['TESTING'] = True
|
|
23
|
-
app.config['SECRET_KEY'] = 'test_key'
|
|
24
|
-
|
|
25
|
-
return app
|
|
26
|
-
|
|
27
|
-
@pytest.fixture(autouse=True)
|
|
28
|
-
def setup(self):
|
|
29
|
-
self.app = self.create_app()
|
|
30
|
-
self.client = self.app.test_client()
|
|
31
|
-
self.query_service = MagicMock(spec=QueryService)
|
|
32
|
-
self.iauthentication = MagicMock(spec=IAuthentication)
|
|
33
|
-
|
|
34
|
-
self.iauthentication.verify.return_value = {
|
|
35
|
-
'success': True,
|
|
36
|
-
'company_id': 101,
|
|
37
|
-
'external_user_id': 'test_user_id'
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
self.test_data = {
|
|
41
|
-
"question": "¿Pregunta con error?",
|
|
42
|
-
"files": []
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
@self.app.route('/login')
|
|
46
|
-
def login():
|
|
47
|
-
return "Login Page", 200
|
|
48
|
-
|
|
49
|
-
# Configurar la vista
|
|
50
|
-
view = LLMQueryView.as_view('llm_query',
|
|
51
|
-
query_service=self.query_service,
|
|
52
|
-
iauthentication=self.iauthentication)
|
|
53
|
-
self.app.add_url_rule('/<company_short_name>/query', view_func=view)
|
|
54
|
-
|
|
55
|
-
self.query_service.llm_query.return_value = {
|
|
56
|
-
"answer": "Respuesta exitosa",
|
|
57
|
-
"aditional_data": {}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
# Mock values
|
|
61
|
-
self.api_key = ApiKey(key="test_key", company_id=100)
|
|
62
|
-
self.api_key.company = Company(id=100, name="Test Company", short_name="test_company")
|
|
63
|
-
|
|
64
|
-
mock_session_values = {
|
|
65
|
-
'user': {'id': 1, 'username': 'test_user'},
|
|
66
|
-
'user_id': 1,
|
|
67
|
-
'company_id': 100,
|
|
68
|
-
'company_short_name': 'test_company',
|
|
69
|
-
'last_activity': datetime.now(timezone.utc).timestamp()
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
# Mockear SessionManager.get
|
|
73
|
-
mock_session_manager = MagicMock(spec=SessionManager) # <- Mock de la clase
|
|
74
|
-
mock_session_manager.get.side_effect = lambda key, default=None: mock_session_values.get(key, default)
|
|
75
|
-
|
|
76
|
-
with patch('iatoolkit.common.auth.SessionManager', new=mock_session_manager):
|
|
77
|
-
with self.app.test_request_context(): # Necesario para Flask
|
|
78
|
-
yield
|
|
79
|
-
|
|
80
|
-
def test_post_success(self):
|
|
81
|
-
api_data = {
|
|
82
|
-
"question": "¿Cuál es el significado de la vida?",
|
|
83
|
-
"external_user_id": "test_user_id",
|
|
84
|
-
"files": ["archivo1.txt", "archivo2.txt"]
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
# Realizar la solicitud
|
|
88
|
-
response = self.client.post(
|
|
89
|
-
'/test_company/query',
|
|
90
|
-
json=api_data
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
# Verificaciones
|
|
94
|
-
assert response.status_code == 200
|
|
95
|
-
assert response.json['answer'] == "Respuesta exitosa"
|
|
96
|
-
|
|
97
|
-
self.query_service.llm_query.assert_called_once_with(
|
|
98
|
-
company_short_name='test_company',
|
|
99
|
-
local_user_id=None,
|
|
100
|
-
external_user_id='test_user_id',
|
|
101
|
-
question=api_data["question"],
|
|
102
|
-
prompt_name= None,
|
|
103
|
-
client_data={},
|
|
104
|
-
files=api_data["files"]
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def test_post_when_missing_data(self):
|
|
109
|
-
response = self.client.post(
|
|
110
|
-
'/test_company/query',
|
|
111
|
-
json={}
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
assert response.status_code == 400
|
|
115
|
-
assert response.json["error_message"] == "Cuerpo de la solicitud JSON inválido o faltante"
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
def test_post_when_auth_error(self):
|
|
119
|
-
self.iauthentication.verify.return_value = {'error_message': 'error in authentication'}
|
|
120
|
-
response = self.client.post(
|
|
121
|
-
'/test_company/query',
|
|
122
|
-
json=self.test_data
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
assert response.status_code == 401
|
|
126
|
-
assert response.json["error_message"] == 'error in authentication'
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
def test_post_service_error(self):
|
|
130
|
-
"""Prueba el manejo de errores del servicio."""
|
|
131
|
-
self.query_service.llm_query.return_value = {
|
|
132
|
-
"error": True,
|
|
133
|
-
"error_message": "Error de proceso"
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
response = self.client.post(
|
|
137
|
-
'/test_company/query',
|
|
138
|
-
json=self.test_data
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
assert response.status_code == 401
|
|
142
|
-
assert response.json["error_message"] == "Error de proceso"
|
|
143
|
-
|
|
144
|
-
@patch("iatoolkit.views.llmquery_view.render_template")
|
|
145
|
-
def test_post_unexpected_error(self, mock_render):
|
|
146
|
-
self.query_service.llm_query.side_effect = Exception("Error inesperado")
|
|
147
|
-
|
|
148
|
-
test_data = {
|
|
149
|
-
"question": "¿Pregunta con error?",
|
|
150
|
-
"files": []
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
response = self.client.post('/test_company/query',json=test_data)
|
|
154
|
-
assert response.status_code == 500
|
tests/views/test_login_view.py
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2024 Fernando Libedinsky
|
|
2
|
-
# Product: IAToolkit
|
|
3
|
-
#
|
|
4
|
-
# IAToolkit is open source software.
|
|
5
|
-
|
|
6
|
-
import pytest
|
|
7
|
-
from flask import Flask, jsonify
|
|
8
|
-
from unittest.mock import MagicMock, patch
|
|
9
|
-
from iatoolkit.services.profile_service import ProfileService
|
|
10
|
-
from iatoolkit.views.login_view import LoginView
|
|
11
|
-
from iatoolkit.repositories.models import Company
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class TestLoginView:
|
|
15
|
-
@staticmethod
|
|
16
|
-
def create_app():
|
|
17
|
-
"""Configura la aplicación Flask para pruebas."""
|
|
18
|
-
app = Flask(__name__)
|
|
19
|
-
app.testing = True
|
|
20
|
-
|
|
21
|
-
return app
|
|
22
|
-
|
|
23
|
-
@pytest.fixture(autouse=True)
|
|
24
|
-
def setup(self):
|
|
25
|
-
"""Configura el cliente y el mock antes de cada test."""
|
|
26
|
-
self.app = self.create_app()
|
|
27
|
-
self.client = self.app.test_client()
|
|
28
|
-
self.profile_service = MagicMock(spec=ProfileService)
|
|
29
|
-
self.test_company = Company(
|
|
30
|
-
id=1,
|
|
31
|
-
name="Empresa de Prueba",
|
|
32
|
-
short_name="test_company",
|
|
33
|
-
logo_file="test_logo.png"
|
|
34
|
-
)
|
|
35
|
-
self.profile_service.get_company_by_short_name.return_value = self.test_company
|
|
36
|
-
|
|
37
|
-
# Registrar la vista
|
|
38
|
-
view = LoginView.as_view("login", profile_service=self.profile_service)
|
|
39
|
-
self.app.add_url_rule("/<company_short_name>/login", view_func=view, methods=["GET", "POST"])
|
|
40
|
-
|
|
41
|
-
# Registrar un endpoint temporal para el test
|
|
42
|
-
@self.app.route("/test_company/chat")
|
|
43
|
-
def chat():
|
|
44
|
-
return jsonify({"message": "Bienvenido al chat"}), 200
|
|
45
|
-
|
|
46
|
-
@patch("iatoolkit.views.login_view.render_template")
|
|
47
|
-
def test_get_and_post_invalid_company(self, mock_render):
|
|
48
|
-
self.profile_service.get_company_by_short_name.return_value = None
|
|
49
|
-
response = self.client.get("/test_company/login")
|
|
50
|
-
assert response.status_code == 404
|
|
51
|
-
|
|
52
|
-
response = self.client.post("/test_company/login",
|
|
53
|
-
data={"email": "fer", "password": "123456"},
|
|
54
|
-
content_type="application/x-www-form-urlencoded")
|
|
55
|
-
|
|
56
|
-
assert response.status_code == 404
|
|
57
|
-
|
|
58
|
-
@patch("iatoolkit.views.login_view.render_template")
|
|
59
|
-
def test_get_login_page(self, mock_render_template):
|
|
60
|
-
mock_render_template.return_value = "<html><body><h1>Login Page</h1></body></html>"
|
|
61
|
-
response = self.client.get("/test_company/login")
|
|
62
|
-
|
|
63
|
-
mock_render_template.assert_called_once_with(
|
|
64
|
-
"login.html",
|
|
65
|
-
company=self.test_company,
|
|
66
|
-
company_short_name='test_company'
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
assert response.status_code == 200
|
|
70
|
-
assert b"<h1>Login Page</h1>" in response.data
|
|
71
|
-
|
|
72
|
-
@patch("iatoolkit.views.login_view.render_template")
|
|
73
|
-
def test_post_with_error(self, mock_render_template):
|
|
74
|
-
self.profile_service.login.return_value = {'error': 'login error'}
|
|
75
|
-
mock_render_template.return_value = "<html><body><h1>Login Page</h1></body></html>"
|
|
76
|
-
response = self.client.post("/test_company/login",
|
|
77
|
-
data={"email": "fer", "password": "123456"},
|
|
78
|
-
content_type="application/x-www-form-urlencoded")
|
|
79
|
-
|
|
80
|
-
mock_render_template.assert_called_once_with(
|
|
81
|
-
"login.html",
|
|
82
|
-
company=self.test_company,
|
|
83
|
-
company_short_name='test_company',
|
|
84
|
-
form_data={"email": "fer", "password": "123456"},
|
|
85
|
-
alert_message='login error'
|
|
86
|
-
)
|
|
87
|
-
assert response.status_code == 400
|
|
88
|
-
|
|
89
|
-
def test_post_successful_login(self):
|
|
90
|
-
self.profile_service.login.return_value = {"message": "Login exitoso"}
|
|
91
|
-
response = self.client.post("/test_company/login",
|
|
92
|
-
data={"email": "test@email.com", "password": "password"},
|
|
93
|
-
content_type="application/x-www-form-urlencoded")
|
|
94
|
-
|
|
95
|
-
assert response.status_code == 302 # Redirección exitosa
|
|
96
|
-
assert response.location == "/test_company/chat?company_short_name=test_company"
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
@patch("iatoolkit.views.login_view.render_template")
|
|
100
|
-
def test_post_unexpected_error(self, mock_render_template):
|
|
101
|
-
"""Prueba que se maneje correctamente un error inesperado."""
|
|
102
|
-
self.profile_service.login.side_effect = Exception("Unexpected error")
|
|
103
|
-
mock_render_template.return_value = "<html><body><h1>Error Page</h1></body></html>"
|
|
104
|
-
response = self.client.post("/test_company/login",
|
|
105
|
-
data={"email": "test@mail.com", "password": "any"},
|
|
106
|
-
content_type="application/x-www-form-urlencoded")
|
|
107
|
-
|
|
108
|
-
mock_render_template.assert_called_once_with(
|
|
109
|
-
"error.html",
|
|
110
|
-
company=self.test_company,
|
|
111
|
-
company_short_name='test_company',
|
|
112
|
-
message="Ha ocurrido un error inesperado."
|
|
113
|
-
)
|
|
114
|
-
assert response.status_code == 500
|