fix
Some checks failed
K8S Fission Deployment / Deployment fission functions (push) Failing after 17s

This commit is contained in:
Nguyen Duc Thao
2026-01-26 23:35:47 +07:00
parent 68cb816208
commit ab38579758
2 changed files with 123 additions and 126 deletions

View File

@@ -60,8 +60,15 @@ def make_insert_request():
try: try:
body = AiUserCreate(**(request.get_json(silent=True) or {})) body = AiUserCreate(**(request.get_json(silent=True) or {}))
except ValidationError as e: except ValidationError as e:
errors = []
for err in e.errors():
errors.append({
"loc": err.get("loc", []),
"msg": err.get("msg", ""),
"type": err.get("type", ""),
})
return ( return (
jsonify({"errorCode": "VALIDATION_ERROR", "details": e.errors()}), jsonify({"errorCode": "VALIDATION_ERROR", "details": errors}),
400, 400,
CORS_HEADERS, CORS_HEADERS,
) )

View File

@@ -5,34 +5,33 @@ from unittest.mock import MagicMock, patch
class TestMain: class TestMain:
"""Test cases for the main() function""" """Test cases for the main() function"""
@patch("filter_insert.make_filter_request") def test_main_get_method(self):
def test_main_get_method(self, mock_filter_request):
"""Test main() with GET method calls make_filter_request()""" """Test main() with GET method calls make_filter_request()"""
from flask import Flask from flask import Flask
from filter_insert import main from filter_insert import main
# Create a test app context
app = Flask(__name__) app = Flask(__name__)
with app.test_request_context("/ai/admin/users", method="GET"): with app.test_request_context("/ai/admin/users", method="GET"):
mock_filter_request.return_value = ({"data": "test"}, 200, {}) with patch("filter_insert.make_filter_request") as mock_filter:
result = main() mock_filter.return_value = ({"data": "test"}, 200, {})
result = main()
mock_filter_request.assert_called_once() mock_filter.assert_called_once()
assert result == ({"data": "test"}, 200, {}) assert result == ({"data": "test"}, 200, {})
@patch("filter_insert.make_insert_request") def test_main_post_method(self):
def test_main_post_method(self, mock_insert_request):
"""Test main() with POST method calls make_insert_request()""" """Test main() with POST method calls make_insert_request()"""
from flask import Flask from flask import Flask
from filter_insert import main from filter_insert import main
app = Flask(__name__) app = Flask(__name__)
with app.test_request_context("/ai/admin/users", method="POST", json={"name": "Test", "email": "test@example.com"}): with app.test_request_context("/ai/admin/users", method="POST", json={"name": "Test", "email": "test@example.com"}):
mock_insert_request.return_value = ({"id": "123"}, 201, {}) with patch("filter_insert.make_insert_request") as mock_insert:
result = main() mock_insert.return_value = ({"id": "123"}, 201, {})
result = main()
mock_insert_request.assert_called_once() mock_insert.assert_called_once()
assert result == ({"id": "123"}, 201, {}) assert result == ({"id": "123"}, 201, {})
def test_main_method_not_allowed(self): def test_main_method_not_allowed(self):
"""Test main() with unsupported HTTP method returns 405""" """Test main() with unsupported HTTP method returns 405"""
@@ -52,29 +51,26 @@ class TestMain:
from filter_insert import main from filter_insert import main
app = Flask(__name__) app = Flask(__name__)
with app.test_request_context("/ai/admin/users", method="GET"):
with patch("filter_insert.make_filter_request") as mock_filter: with patch("filter_insert.make_filter_request") as mock_filter:
mock_filter.side_effect = Exception("Database connection failed") mock_filter.side_effect = Exception("Database connection failed")
with app.test_request_context("/ai/admin/users", method="GET"):
result = main() result = main()
assert result[1] == 500 assert result[1] == 500
assert "error" in result[0] assert "error" in result[0]
class TestMakeInsertRequest: class TestMakeInsertRequest:
"""Test cases for make_insert_request() function""" """Test cases for make_insert_request() function"""
@patch("filter_insert.init_db_connection") def test_make_insert_request_success(self):
@patch("filter_insert.request")
@patch("filter_insert.db_row_to_dict")
def test_make_insert_request_success(self, mock_db_row, mock_request, mock_init_db):
"""Test successful user insertion""" """Test successful user insertion"""
from flask import Flask from flask import Flask
from filter_insert import make_insert_request, CORS_HEADERS from filter_insert import make_insert_request, CORS_HEADERS
app = Flask(__name__) app = Flask(__name__)
mock_request = MagicMock()
mock_request.get_json.return_value = { mock_request.get_json.return_value = {
"name": "John Doe", "name": "John Doe",
"email": "john@example.com", "email": "john@example.com",
@@ -98,39 +94,37 @@ class TestMakeInsertRequest:
mock_conn.__exit__ = MagicMock(return_value=False) mock_conn.__exit__ = MagicMock(return_value=False)
mock_conn.cursor.return_value.__enter__ = MagicMock(return_value=mock_cursor) mock_conn.cursor.return_value.__enter__ = MagicMock(return_value=mock_cursor)
mock_conn.cursor.return_value.__exit__ = MagicMock(return_value=False) mock_conn.cursor.return_value.__exit__ = MagicMock(return_value=False)
mock_init_db.return_value = mock_conn
mock_db_row.return_value = {"id": "uuid-123", "name": "John Doe"}
with app.test_request_context("/ai/admin/users", method="POST", json=mock_request.get_json.return_value): with app.test_request_context("/ai/admin/users", method="POST", json=mock_request.get_json.return_value):
result = make_insert_request() with patch("filter_insert.init_db_connection", return_value=mock_conn):
with patch("filter_insert.db_row_to_dict", return_value={"id": "uuid-123", "name": "John Doe"}):
result = make_insert_request()
assert result[1] == 201 assert result[1] == 201
assert result[2] == CORS_HEADERS assert result[2] == CORS_HEADERS
@patch("filter_insert.request") def test_make_insert_request_validation_error(self):
def test_make_insert_request_validation_error(self, mock_request):
"""Test make_insert_request() with invalid data returns 400""" """Test make_insert_request() with invalid data returns 400"""
from flask import Flask from flask import Flask
from filter_insert import make_insert_request, CORS_HEADERS from filter_insert import make_insert_request, CORS_HEADERS
app = Flask(__name__) app = Flask(__name__)
# Invalid email format # Invalid email format - pydantic will validate and reject
mock_request.get_json.return_value = { request_data = {
"name": "John Doe", "name": "John Doe",
"email": "invalid-email" "email": "invalid-email"
} }
with app.test_request_context("/ai/admin/users", method="POST", json=mock_request.get_json.return_value): with app.test_request_context("/ai/admin/users", method="POST", json=request_data):
result = make_insert_request() result = make_insert_request()
assert result[1] == 400 assert result[1] == 400
assert "errorCode" in result[0].json
assert result[0].json["errorCode"] == "VALIDATION_ERROR" assert result[0].json["errorCode"] == "VALIDATION_ERROR"
assert result[2] == CORS_HEADERS assert result[2] == CORS_HEADERS
@patch("filter_insert.init_db_connection") def test_make_insert_request_duplicate_error(self):
@patch("filter_insert.request")
def test_make_insert_request_duplicate_error(self, mock_request, mock_init_db):
"""Test make_insert_request() with duplicate email returns 409""" """Test make_insert_request() with duplicate email returns 409"""
from flask import Flask from flask import Flask
from filter_insert import make_insert_request, CORS_HEADERS from filter_insert import make_insert_request, CORS_HEADERS
@@ -138,7 +132,7 @@ class TestMakeInsertRequest:
app = Flask(__name__) app = Flask(__name__)
mock_request.get_json.return_value = { request_data = {
"name": "John Doe", "name": "John Doe",
"email": "john@example.com" "email": "john@example.com"
} }
@@ -149,13 +143,12 @@ class TestMakeInsertRequest:
mock_conn.__exit__ = MagicMock(return_value=False) mock_conn.__exit__ = MagicMock(return_value=False)
mock_conn.cursor.return_value.__enter__ = MagicMock(return_value=mock_cursor) mock_conn.cursor.return_value.__enter__ = MagicMock(return_value=mock_cursor)
mock_conn.cursor.return_value.__exit__ = MagicMock(return_value=False) mock_conn.cursor.return_value.__exit__ = MagicMock(return_value=False)
mock_init_db.return_value = mock_conn
# Simulate IntegrityError with app.test_request_context("/ai/admin/users", method="POST", json=request_data):
mock_cursor.execute.side_effect = IntegrityError("duplicate key value violates unique constraint") with patch("filter_insert.init_db_connection", return_value=mock_conn):
# Simulate IntegrityError
with app.test_request_context("/ai/admin/users", method="POST", json=mock_request.get_json.return_value): mock_cursor.execute.side_effect = IntegrityError("duplicate key value violates unique constraint")
result = make_insert_request() result = make_insert_request()
assert result[1] == 409 assert result[1] == 409
assert result[0].json["errorCode"] == "DUPLICATE_TAG" assert result[0].json["errorCode"] == "DUPLICATE_TAG"
@@ -165,116 +158,107 @@ class TestMakeInsertRequest:
class TestMakeFilterRequest: class TestMakeFilterRequest:
"""Test cases for make_filter_request() function""" """Test cases for make_filter_request() function"""
@patch("filter_insert.init_db_connection") def test_make_filter_request_success(self):
@patch("filter_insert.request")
@patch("filter_insert.UserPage")
@patch("filter_insert.db_rows_to_array")
def test_make_filter_request_success(self, mock_db_rows, mock_page_class, mock_request, mock_init_db):
"""Test successful filter request""" """Test successful filter request"""
from flask import Flask from flask import Flask
from filter_insert import make_filter_request from filter_insert import make_filter_request
app = Flask(__name__) app = Flask(__name__)
mock_paging = MagicMock()
mock_paging.size = 8
mock_paging.page = 0
mock_paging.filter = MagicMock()
mock_paging.filter.ids = None
mock_paging.filter.keyword = None
mock_paging.filter.name = None
mock_paging.filter.email = None
mock_paging.filter.created_from = None
mock_paging.filter.created_to = None
mock_paging.filter.modified_from = None
mock_paging.filter.modified_to = None
mock_paging.filter.dob_from = None
mock_paging.filter.dob_to = None
mock_paging.sortby = None
mock_paging.asc = None
mock_page_class.from_request_queries.return_value = mock_paging
mock_request.args.get.return_value = None
mock_conn = MagicMock()
mock_cursor = MagicMock()
mock_cursor.fetchall.return_value = []
mock_conn.cursor.return_value = mock_cursor
mock_init_db.return_value = mock_conn
mock_db_rows.return_value = []
with app.test_request_context("/ai/admin/users?page=0&size=8"): with app.test_request_context("/ai/admin/users?page=0&size=8"):
result = make_filter_request() with patch("filter_insert.init_db_connection") as mock_init_db:
mock_conn = MagicMock()
mock_cursor = MagicMock()
mock_cursor.fetchall.return_value = []
mock_conn.cursor.return_value = mock_cursor
mock_init_db.return_value = mock_conn
assert result[1] == 200 with patch("filter_insert.db_rows_to_array", return_value=[]):
mock_db_rows.assert_called_once() result = make_filter_request()
# make_filter_request returns Flask Response object (jsonify)
assert result.status_code == 200
class TestUserFilter: class TestUserFilter:
"""Test cases for UserFilter.from_request_queries()""" """Test cases for UserFilter.from_request_queries()"""
@patch("filter_insert.request") def test_user_filter_from_queries(self):
def test_user_filter_from_queries(self, mock_request):
"""Test UserFilter parses query parameters correctly""" """Test UserFilter parses query parameters correctly"""
from flask import Flask
from filter_insert import UserFilter from filter_insert import UserFilter
mock_request.args.get.side_effect = lambda key, default=None: { app = Flask(__name__)
"filter[ids]": None,
"filter[keyword]": "test",
"filter[name]": "John",
"filter[email]": "john@example.com",
"filter[gender]": "male",
"filter[created_from]": "2024-01-01",
"filter[created_to]": "2024-12-31",
"filter[modified_from]": None,
"filter[modified_to]": None,
"filter[dob_from]": None,
"filter[dob_to]": None,
}.get(key, default)
mock_request.args.getlist.return_value = [] def mock_get(key, default=None):
values = {
"filter[ids]": None,
"filter[keyword]": "test",
"filter[name]": "John",
"filter[email]": "john@example.com",
"filter[gender]": "male",
"filter[created_from]": "2024-01-01",
"filter[created_to]": "2024-12-31",
"filter[modified_from]": None,
"filter[modified_to]": None,
"filter[dob_from]": None,
"filter[dob_to]": None,
}
return values.get(key, default)
result = UserFilter.from_request_queries() with app.test_request_context():
with patch("filter_insert.request") as mock_request:
mock_request.args.get = mock_get
mock_request.args.getlist.return_value = []
assert result.keyword == "test" result = UserFilter.from_request_queries()
assert result.name == "John"
assert result.email == "john@example.com" assert result.keyword == "test"
assert result.gender == "male" assert result.name == "John"
assert result.created_from == "2024-01-01" assert result.email == "john@example.com"
assert result.created_to == "2024-12-31" assert result.gender == "male"
assert result.created_from == "2024-01-01"
assert result.created_to == "2024-12-31"
class TestPage: class TestPage:
"""Test cases for Page.from_request_queries()""" """Test cases for Page.from_request_queries()"""
@patch("filter_insert.request") def test_page_default_values(self):
def test_page_default_values(self, mock_request):
"""Test Page uses default values when params not provided""" """Test Page uses default values when params not provided"""
from flask import Flask
from filter_insert import Page from filter_insert import Page
mock_request.args.get.side_effect = lambda key, default=None, type=None: { app = Flask(__name__)
"page": 0,
"size": 8,
"asc": "false",
}.get(key, default)
result = Page.from_request_queries() def mock_get(key, default=None, type=None):
values = {
"page": 0,
"size": 8,
"asc": "false",
}
return values.get(key, default)
assert result.page == 0 with app.test_request_context():
assert result.size == 8 with patch("filter_insert.request") as mock_request:
assert result.asc is False mock_request.args.get = mock_get
result = Page.from_request_queries()
assert result.page == 0
assert result.size == 8
assert result.asc == False or result.asc == "false"
class TestUserPage: class TestUserPage:
"""Test cases for UserPage.from_request_queries()""" """Test cases for UserPage.from_request_queries()"""
@patch("filter_insert.request") def test_user_page_with_sortby(self):
def test_user_page_with_sortby(self, mock_request):
"""Test UserPage parses sortby parameter correctly""" """Test UserPage parses sortby parameter correctly"""
from flask import Flask
from filter_insert import UserPage, UserSortField from filter_insert import UserPage, UserSortField
# Simulate request.args.get behavior app = Flask(__name__)
def mock_get(key, default=None, type=None): def mock_get(key, default=None, type=None):
values = { values = {
"page": 0, "page": 0,
@@ -284,19 +268,23 @@ class TestUserPage:
} }
return values.get(key, default) return values.get(key, default)
mock_request.args.get = mock_get with app.test_request_context():
mock_request.args.getlist.return_value = [] with patch("filter_insert.request") as mock_request:
mock_request.args.get = mock_get
mock_request.args.getlist.return_value = []
result = UserPage.from_request_queries() result = UserPage.from_request_queries()
assert result.sortby == UserSortField.CREATED assert result.sortby == UserSortField.CREATED
assert result.asc is True assert result.asc == True or result.asc == "true"
@patch("filter_insert.request") def test_user_page_invalid_sortby(self):
def test_user_page_invalid_sortby(self, mock_request):
"""Test UserPage handles invalid sortby gracefully""" """Test UserPage handles invalid sortby gracefully"""
from flask import Flask
from filter_insert import UserPage from filter_insert import UserPage
app = Flask(__name__)
def mock_get(key, default=None, type=None): def mock_get(key, default=None, type=None):
values = { values = {
"page": 0, "page": 0,
@@ -306,12 +294,14 @@ class TestUserPage:
} }
return values.get(key, default) return values.get(key, default)
mock_request.args.get = mock_get with app.test_request_context():
mock_request.args.getlist.return_value = [] with patch("filter_insert.request") as mock_request:
mock_request.args.get = mock_get
mock_request.args.getlist.return_value = []
result = UserPage.from_request_queries() result = UserPage.from_request_queries()
assert result.sortby is None assert result.sortby is None
class TestUserSortField: class TestUserSortField: