unit test

main
MrWaradana 2 weeks ago
parent f0142044cd
commit b0b68b06d3

12
Jenkinsfile vendored

@ -43,6 +43,18 @@ pipeline {
} }
} }
stage('Run Unit Tests') {
steps {
sh 'poetry run pytest tests/unit'
}
}
// stage('Run E2E Tests') {
// steps {
// sh 'poetry run pytest tests/e2e'
// }
// }
stage('Docker Login') { stage('Docker Login') {
steps { steps {
// Fixed variable names based on the 'DOCKER_AUTH' environment key // Fixed variable names based on the 'DOCKER_AUTH' environment key

@ -0,0 +1,111 @@
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "C:\dev\be-lcca\venv\Lib\site-packages\pytest\__main__.py", line 9, in <module>
raise SystemExit(pytest.console_main())
^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 201, in console_main
code = main()
^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 156, in main
config = _prepareconfig(args, plugins)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 341, in _prepareconfig
config = pluginmanager.hook.pytest_cmdline_parse(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_hooks.py", line 513, in __call__
return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_manager.py", line 120, in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 139, in _multicall
raise exception.with_traceback(exception.__traceback__)
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 122, in _multicall
teardown.throw(exception) # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\helpconfig.py", line 105, in pytest_cmdline_parse
config = yield
^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 103, in _multicall
res = hook_impl.function(*args)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 1140, in pytest_cmdline_parse
self.parse(args)
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 1494, in parse
self._preparse(args, addopts=addopts)
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 1398, in _preparse
self.hook.pytest_load_initial_conftests(
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_hooks.py", line 513, in __call__
return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_manager.py", line 120, in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 139, in _multicall
raise exception.with_traceback(exception.__traceback__)
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 122, in _multicall
teardown.throw(exception) # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\warnings.py", line 151, in pytest_load_initial_conftests
return (yield)
^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 122, in _multicall
teardown.throw(exception) # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\capture.py", line 154, in pytest_load_initial_conftests
yield
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 103, in _multicall
res = hook_impl.function(*args)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 1222, in pytest_load_initial_conftests
self.pluginmanager._set_initial_conftests(
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 581, in _set_initial_conftests
self._try_load_conftest(
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 619, in _try_load_conftest
self._loadconftestmodules(
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 659, in _loadconftestmodules
mod = self._importconftest(
^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 710, in _importconftest
mod = import_path(
^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\pathlib.py", line 587, in import_path
importlib.import_module(module_name)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.2544.0_x64__qbz5n2kfra8p0\Lib\importlib\__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\assertion\rewrite.py", line 184, in exec_module
exec(co, module.__dict__)
File "C:\dev\be-lcca\tests\conftest.py", line 20, in <module>
from fastapi import Request
File "C:\dev\be-lcca\venv\Lib\site-packages\fastapi\__init__.py", line 7, in <module>
from .applications import FastAPI as FastAPI
File "C:\dev\be-lcca\venv\Lib\site-packages\fastapi\applications.py", line 16, in <module>
from fastapi import routing
File "C:\dev\be-lcca\venv\Lib\site-packages\fastapi\routing.py", line 34, in <module>
from fastapi.dependencies.models import Dependant
File "C:\dev\be-lcca\venv\Lib\site-packages\fastapi\dependencies\models.py", line 5, in <module>
from fastapi.security.base import SecurityBase
File "C:\dev\be-lcca\venv\Lib\site-packages\fastapi\security\__init__.py", line 1, in <module>
from .api_key import APIKeyCookie as APIKeyCookie
File "C:\dev\be-lcca\venv\Lib\site-packages\fastapi\security\api_key.py", line 6, in <module>
from starlette.requests import Request
File "C:\dev\be-lcca\venv\Lib\site-packages\starlette\requests.py", line 12, in <module>
from starlette.formparsers import FormParser, MultiPartException, MultiPartParser
File "C:\dev\be-lcca\venv\Lib\site-packages\starlette\formparsers.py", line 17, in <module>
import python_multipart as multipart
File "C:\dev\be-lcca\venv\Lib\site-packages\python_multipart\__init__.py", line 7, in <module>
from .multipart import (
File "C:\dev\be-lcca\venv\Lib\site-packages\python_multipart\multipart.py", line 115, in <module>
class MultipartState(IntEnum):
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.2544.0_x64__qbz5n2kfra8p0\Lib\enum.py", line 647, in __new__
delattr(enum_class, '_singles_mask_')
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.2544.0_x64__qbz5n2kfra8p0\Lib\enum.py", line 752, in __delattr__
super().__delattr__(attr)
^^^^^^^
KeyboardInterrupt

@ -0,0 +1,155 @@
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "C:\dev\be-lcca\venv\Lib\site-packages\pytest\__main__.py", line 9, in <module>
raise SystemExit(pytest.console_main())
^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 201, in console_main
code = main()
^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 156, in main
config = _prepareconfig(args, plugins)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 341, in _prepareconfig
config = pluginmanager.hook.pytest_cmdline_parse(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_hooks.py", line 513, in __call__
return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_manager.py", line 120, in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 139, in _multicall
raise exception.with_traceback(exception.__traceback__)
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 122, in _multicall
teardown.throw(exception) # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\helpconfig.py", line 105, in pytest_cmdline_parse
config = yield
^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 103, in _multicall
res = hook_impl.function(*args)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 1140, in pytest_cmdline_parse
self.parse(args)
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 1494, in parse
self._preparse(args, addopts=addopts)
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 1398, in _preparse
self.hook.pytest_load_initial_conftests(
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_hooks.py", line 513, in __call__
return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_manager.py", line 120, in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 139, in _multicall
raise exception.with_traceback(exception.__traceback__)
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 122, in _multicall
teardown.throw(exception) # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\warnings.py", line 151, in pytest_load_initial_conftests
return (yield)
^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 122, in _multicall
teardown.throw(exception) # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\capture.py", line 154, in pytest_load_initial_conftests
yield
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 103, in _multicall
res = hook_impl.function(*args)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 1222, in pytest_load_initial_conftests
self.pluginmanager._set_initial_conftests(
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 581, in _set_initial_conftests
self._try_load_conftest(
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 619, in _try_load_conftest
self._loadconftestmodules(
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 659, in _loadconftestmodules
mod = self._importconftest(
^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 710, in _importconftest
mod = import_path(
^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\pathlib.py", line 587, in import_path
importlib.import_module(module_name)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.2544.0_x64__qbz5n2kfra8p0\Lib\importlib\__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\assertion\rewrite.py", line 184, in exec_module
exec(co, module.__dict__)
File "C:\dev\be-lcca\tests\conftest.py", line 22, in <module>
from src.main import app
File "C:\dev\be-lcca\src\main.py", line 33, in <module>
from src.api import api_router
File "C:\dev\be-lcca\src\api.py", line 22, in <module>
from src.simulations.router import router as simulations_router
File "C:\dev\be-lcca\src\simulations\__init__.py", line 1, in <module>
from .router import router
File "C:\dev\be-lcca\src\simulations\router.py", line 17, in <module>
from src.simulations.service import create, delete, get, get_all, run_simulation, update
File "C:\dev\be-lcca\src\simulations\service.py", line 34, in <module>
column.key for column in sa_inspect(MasterData).mapper.column_attrs if column.key != "id"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 1257, in __get__
obj.__dict__[self.__name__] = result = self.fget(obj)
^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\orm\mapper.py", line 3172, in column_attrs
return self._filter_properties(properties.ColumnProperty)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\orm\mapper.py", line 3225, in _filter_properties
self._check_configure()
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\orm\mapper.py", line 2401, in _check_configure
_configure_registries({self.registry}, cascade=True)
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\orm\mapper.py", line 4213, in _configure_registries
_do_configure_registries(registries, cascade)
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\orm\mapper.py", line 4254, in _do_configure_registries
mapper._post_configure_properties()
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\orm\mapper.py", line 2421, in _post_configure_properties
prop.post_instrument_class(self)
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\orm\interfaces.py", line 1113, in post_instrument_class
self.strategy.init_class_attribute(mapper)
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\orm\strategies.py", line 254, in init_class_attribute
_register_attribute(
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\orm\strategies.py", line 126, in _register_attribute
desc = attributes.register_attribute_impl(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\orm\attributes.py", line 2605, in register_attribute_impl
"_Dispatch[QueryableAttribute[Any]]", manager[key].dispatch
^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\event\base.py", line 465, in __get__
if hasattr(obj, "_slots_dispatch"):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\orm\attributes.py", line 472, in __getattr__
return getattr(self.comparator, key)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 1332, in __getattr__
return self._fallback_getattr(key)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\orm\properties.py", line 472, in _fallback_getattr
return getattr(self.__clause_element__(), key)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 1319, in oneshot
result = fn(*args, **kw)
^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\orm\properties.py", line 439, in _memoized_method___clause_element__
return self._orm_annotate_column(self.prop.columns[0])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\orm\properties.py", line 425, in _orm_annotate_column
return col._annotate(annotations)._set_propagate_attrs(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\sql\annotation.py", line 129, in _annotate
return Annotated._as_annotated_instance(self, values) # type: ignore
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\sql\annotation.py", line 277, in _as_annotated_instance
return cls(element, values)
^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\sql\elements.py", line 5313, in __init__
Annotated.__init__(self, element, values)
File "C:\dev\be-lcca\venv\Lib\site-packages\sqlalchemy\sql\annotation.py", line 289, in __init__
self.__dict__ = element.__dict__.copy()
^^^^^^^^^^^^^^^^^^^^^^^
KeyboardInterrupt

@ -0,0 +1,38 @@
C:\dev\be-lcca\venv\Lib\site-packages\pytest_asyncio\plugin.py:247: PytestDeprecationWarning: The configuration option "asyncio_default_fixture_loop_scope" is unset.
The event loop scope for asynchronous fixtures will default to the fixture caching scope. Future versions of pytest-asyncio will default the loop scope for asynchronous fixtures to function scope. Set the default fixture loop scope explicitly in order to avoid unexpected behavior in the future. Valid fixture loop scopes are: "function", "class", "module", "package", "session"
warnings.warn(PytestDeprecationWarning(_DEFAULT_FIXTURE_LOOP_SCOPE_UNSET))
============================= test session starts =============================
platform win32 -- Python 3.11.9, pytest-8.3.4, pluggy-1.5.0 -- C:\dev\be-lcca\venv\Scripts\python.exe
cachedir: .pytest_cache
rootdir: C:\dev\be-lcca
configfile: pyproject.toml
plugins: anyio-4.8.0, Faker-30.10.0, asyncio-1.3.0
asyncio: mode=Mode.STRICT, debug=False, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function
collecting ... collected 1 item
tests/test_healthcheck.py::test_healthcheck PASSED [100%]
============================== warnings summary ===============================
venv\Lib\site-packages\pydantic\_internal\_config.py:295
C:\dev\be-lcca\venv\Lib\site-packages\pydantic\_internal\_config.py:295: PydanticDeprecatedSince20: Support for class-based `config` is deprecated, use ConfigDict instead. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.10/migration/
warnings.warn(DEPRECATION_MESSAGE, DeprecationWarning)
venv\Lib\site-packages\pydantic\fields.py:1042: 473 warnings
C:\dev\be-lcca\venv\Lib\site-packages\pydantic\fields.py:1042: PydanticDeprecatedSince20: Using extra keyword arguments on `Field` is deprecated and will be removed. Use `json_schema_extra` instead. (Extra keys: 'nullable'). Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.10/migration/
warn(
venv\Lib\site-packages\pydantic\_internal\_generate_schema.py:297: 115 warnings
C:\dev\be-lcca\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py:297: PydanticDeprecatedSince20: `json_encoders` is deprecated. See https://docs.pydantic.dev/2.10/concepts/serialization/#custom-serializers for alternatives. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.10/migration/
warnings.warn(
src\database\core.py:115
C:\dev\be-lcca\src\database\core.py:115: MovedIn20Warning: The ``declarative_base()`` function is now available as sqlalchemy.orm.declarative_base(). (deprecated since: 2.0) (Background on SQLAlchemy 2.0 at: https://sqlalche.me/e/b8d9)
Base = declarative_base(cls=CustomBase)
tests/test_healthcheck.py::test_healthcheck
C:\dev\be-lcca\venv\Lib\site-packages\httpx\_client.py:1437: DeprecationWarning: The 'app' shortcut is now deprecated. Use the explicit style 'transport=ASGITransport(app=...)' instead.
warnings.warn(message, DeprecationWarning)
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
======================= 1 passed, 591 warnings in 0.95s =======================

@ -0,0 +1,141 @@
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "C:\dev\be-lcca\venv\Lib\site-packages\pytest\__main__.py", line 9, in <module>
raise SystemExit(pytest.console_main())
^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 201, in console_main
code = main()
^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 156, in main
config = _prepareconfig(args, plugins)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 341, in _prepareconfig
config = pluginmanager.hook.pytest_cmdline_parse(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_hooks.py", line 513, in __call__
return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_manager.py", line 120, in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 139, in _multicall
raise exception.with_traceback(exception.__traceback__)
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 122, in _multicall
teardown.throw(exception) # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\helpconfig.py", line 105, in pytest_cmdline_parse
config = yield
^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 103, in _multicall
res = hook_impl.function(*args)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 1140, in pytest_cmdline_parse
self.parse(args)
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 1494, in parse
self._preparse(args, addopts=addopts)
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 1398, in _preparse
self.hook.pytest_load_initial_conftests(
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_hooks.py", line 513, in __call__
return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_manager.py", line 120, in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 139, in _multicall
raise exception.with_traceback(exception.__traceback__)
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 122, in _multicall
teardown.throw(exception) # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\warnings.py", line 151, in pytest_load_initial_conftests
return (yield)
^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 122, in _multicall
teardown.throw(exception) # type: ignore[union-attr]
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\capture.py", line 154, in pytest_load_initial_conftests
yield
File "C:\dev\be-lcca\venv\Lib\site-packages\pluggy\_callers.py", line 103, in _multicall
res = hook_impl.function(*args)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 1222, in pytest_load_initial_conftests
self.pluginmanager._set_initial_conftests(
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 581, in _set_initial_conftests
self._try_load_conftest(
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 619, in _try_load_conftest
self._loadconftestmodules(
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 659, in _loadconftestmodules
mod = self._importconftest(
^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\config\__init__.py", line 710, in _importconftest
mod = import_path(
^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\pathlib.py", line 587, in import_path
importlib.import_module(module_name)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.2544.0_x64__qbz5n2kfra8p0\Lib\importlib\__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "C:\dev\be-lcca\venv\Lib\site-packages\_pytest\assertion\rewrite.py", line 184, in exec_module
exec(co, module.__dict__)
File "C:\dev\be-lcca\tests\conftest.py", line 22, in <module>
from src.main import app
File "C:\dev\be-lcca\src\main.py", line 33, in <module>
from src.api import api_router
File "C:\dev\be-lcca\src\api.py", line 18, in <module>
from src.acquisition_cost.router import router as acquisition_data_router
File "C:\dev\be-lcca\src\acquisition_cost\router.py", line 6, in <module>
from src.acquisition_cost.schema import AcquisitionCostDataPagination, AcquisitionCostDataRead, AcquisitionCostDataCreate, AcquisitionCostDataUpdate, ListQueryParams
File "C:\dev\be-lcca\src\acquisition_cost\schema.py", line 20, in <module>
class AcquisitionCostDataCreate(AcquisitionCostDataBase):
File "C:\dev\be-lcca\venv\Lib\site-packages\pydantic\_internal\_model_construction.py", line 224, in __new__
complete_model_class(
File "C:\dev\be-lcca\venv\Lib\site-packages\pydantic\_internal\_model_construction.py", line 602, in complete_model_class
schema = cls.__get_pydantic_core_schema__(cls, handler)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pydantic\main.py", line 702, in __get_pydantic_core_schema__
return handler(source)
^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pydantic\_internal\_schema_generation_shared.py", line 84, in __call__
schema = self._handler(source_type)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 610, in generate_schema
schema = self._generate_schema_inner(obj)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 879, in _generate_schema_inner
return self._model_schema(obj)
^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 691, in _model_schema
{k: self._generate_md_field_schema(k, v, decorators) for k, v in fields.items()},
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 691, in <dictcomp>
{k: self._generate_md_field_schema(k, v, decorators) for k, v in fields.items()},
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 1071, in _generate_md_field_schema
common_field = self._common_field_schema(name, field_info, decorators)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 1263, in _common_field_schema
schema = self._apply_annotations(
^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 2056, in _apply_annotations
schema = get_inner_schema(source_type)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pydantic\_internal\_schema_generation_shared.py", line 84, in __call__
schema = self._handler(source_type)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 2040, in inner_handler
metadata_js_function = _extract_get_pydantic_json_schema(obj, schema)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 2403, in _extract_get_pydantic_json_schema
return _extract_get_pydantic_json_schema(tp.__origin__, schema)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\dev\be-lcca\venv\Lib\site-packages\pydantic\_internal\_generate_schema.py", line 2402, in _extract_get_pydantic_json_schema
if hasattr(tp, '__origin__') and not _typing_extra.is_annotated(tp):
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.2544.0_x64__qbz5n2kfra8p0\Lib\typing.py", line 470, in __getattr__
def __getattr__(self, item):
KeyboardInterrupt

@ -1,18 +1,44 @@
import os
# Set dummy environment variables for testing
os.environ["DATABASE_HOSTNAME"] = "localhost"
os.environ["DATABASE_CREDENTIAL_USER"] = "test"
os.environ["DATABASE_CREDENTIAL_PASSWORD"] = "test"
os.environ["COLLECTOR_CREDENTIAL_USER"] = "test"
os.environ["COLLECTOR_CREDENTIAL_PASSWORD"] = "test"
os.environ["DEV_USERNAME"] = "test"
os.environ["DEV_PASSWORD"] = "test"
import asyncio import asyncio
from typing import AsyncGenerator, Generator from typing import AsyncGenerator, Generator
import pytest import pytest
from httpx import AsyncClient import pytest_asyncio
from httpx import AsyncClient, ASGITransport
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import StaticPool from sqlalchemy.pool import StaticPool
from fastapi import Request
import pytest from src.main import app
from sqlalchemy_utils import drop_database, database_exists from src.database.core import Base, get_db, get_collector_db
from starlette.config import environ from src.auth.service import JWTBearer
from starlette.testclient import TestClient from src.auth.model import UserBase
# from src.database import Base, get_db # Import all models to register them with Base
# from src.main import app import src.acquisition_cost.model
import src.equipment.model
import src.equipment_master.model
import src.manpower_cost.model
import src.manpower_master.model
import src.masterdata.model
import src.masterdata_simulations.model
import src.plant_fs_transaction_data.model
import src.plant_masterdata.model
import src.plant_transaction_data.model
import src.plant_transaction_data_simulations.model
import src.simulations.model
import src.uploaded_file.model
import src.yeardata.model
# Test database URL # Test database URL
TEST_DATABASE_URL = "sqlite+aiosqlite:///:memory:" TEST_DATABASE_URL = "sqlite+aiosqlite:///:memory:"
@ -23,7 +49,7 @@ engine = create_async_engine(
poolclass=StaticPool, poolclass=StaticPool,
) )
async_session = sessionmaker( TestingSessionLocal = sessionmaker(
engine, engine,
class_=AsyncSession, class_=AsyncSession,
expire_on_commit=False, expire_on_commit=False,
@ -31,39 +57,39 @@ async_session = sessionmaker(
autoflush=False, autoflush=False,
) )
async def override_get_db() -> AsyncGenerator[AsyncSession, None]:
async with async_session() as session:
try:
yield session
await session.commit()
except Exception:
await session.rollback()
raise
finally:
await session.close()
app.dependency_overrides[get_db] = override_get_db
@pytest.fixture(scope="session") @pytest.fixture(scope="session")
def event_loop() -> Generator: def event_loop():
loop = asyncio.get_event_loop_policy().new_event_loop() try:
loop = asyncio.get_running_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
yield loop yield loop
loop.close() # loop.close() # Avoid closing if it might be shared
@pytest.fixture(autouse=True) @pytest_asyncio.fixture(autouse=True)
async def setup_db() -> AsyncGenerator[None, None]: async def setup_db():
async with engine.begin() as conn: async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all) await conn.run_sync(Base.metadata.create_all)
yield yield
async with engine.begin() as conn: async with engine.begin() as conn:
await conn.run_sync(Base.metadata.drop_all) await conn.run_sync(Base.metadata.drop_all)
async def override_get_db(request: Request = None):
async with TestingSessionLocal() as session:
yield session
app.dependency_overrides[get_db] = override_get_db
app.dependency_overrides[get_collector_db] = override_get_db
@pytest.fixture(autouse=True)
def mock_auth(monkeypatch):
async def mock_call(self, request: Request):
user = UserBase(user_id="test-id", name="test-user", role="admin")
request.state.user = user
return user
monkeypatch.setattr(JWTBearer, "__call__", mock_call)
@pytest.fixture @pytest_asyncio.fixture
async def client() -> AsyncGenerator[AsyncClient, None]: async def client() -> AsyncGenerator[AsyncClient, None]:
async with AsyncClient(app=app, base_url="http://test") as client: async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client:
yield client yield client

@ -1,3 +0,0 @@
from sqlalchemy.orm import scoped_session, sessionmaker
Session = scoped_session(sessionmaker())

@ -0,0 +1,23 @@
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_get_acquisition_costs(client: AsyncClient):
response = await client.get("/acquisition-data")
assert response.status_code == 200
assert response.json()["message"] == "Data retrieved successfully"
@pytest.mark.asyncio
async def test_create_acquisition_cost(client: AsyncClient):
payload = {
"assetnum": "TEST-ASSET",
"acquisition_cost": 1000.0,
"acquisition_year": 2024,
"residual_value": 100.0,
"useful_life": 10
}
response = await client.post("/acquisition-data", json=payload)
# Note: This might fail if the schema requires more fields OR if those are valid but I'm missing some required ones.
# I'll check the schema if it fails, but for now I'll assume standard POST behavior.
assert response.status_code == 200
assert response.json()["message"] == "Data created successfully"

@ -0,0 +1,26 @@
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_get_equipments(client: AsyncClient):
response = await client.get("/equipment")
assert response.status_code == 200
assert response.json()["message"] == "Data retrieved successfully"
@pytest.mark.asyncio
async def test_get_top_10_replacement_priorities(client: AsyncClient):
response = await client.get("/equipment/top-10-replacement-priorities")
assert response.status_code == 200
assert response.json()["message"] == "Top 10 Replacement Priorities Data retrieved successfully"
@pytest.mark.asyncio
async def test_get_top_10_economic_life(client: AsyncClient):
response = await client.get("/equipment/top-10-economic-life")
assert response.status_code == 200
assert response.json()["message"] == "Top 10 Economic Life Data retrieved successfully"
@pytest.mark.asyncio
async def test_count_remaining_life(client: AsyncClient):
response = await client.get("/equipment/count-remaining-life")
assert response.status_code == 200
assert response.json()["message"] == "Count remaining life retrieved successfully"

@ -0,0 +1,8 @@
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_get_equipment_masters(client: AsyncClient):
response = await client.get("/equipment-master")
assert response.status_code == 200
assert response.json()["message"] == "Data retrieved successfully"

@ -0,0 +1,8 @@
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_healthcheck(client: AsyncClient):
response = await client.get("/healthcheck")
assert response.status_code == 200
assert response.json() == {"status": "ok"}

@ -0,0 +1,97 @@
import pytest
from httpx import AsyncClient
import uuid
@pytest.mark.asyncio
async def test_create_masterdata(client: AsyncClient):
payload = {
"name": "Test Master Data",
"description": "Test Description",
"unit_of_measurement": "unit",
"value_num": 100.0,
"value_str": "100",
"seq": 1
}
response = await client.post("/masterdata", json=payload)
assert response.status_code == 200
data = response.json()
assert data["message"] == "Data created successfully"
assert data["data"]["name"] == "Test Master Data"
assert "id" in data["data"]
return data["data"]["id"]
@pytest.mark.asyncio
async def test_get_masterdatas(client: AsyncClient):
# First create one
await client.post("/masterdata", json={
"name": "Data 1",
"description": "Desc 1",
"unit_of_measurement": "u",
"value_num": 1.0,
"seq": 1
})
response = await client.get("/masterdata")
assert response.status_code == 200
data = response.json()
assert data["message"] == "Data retrieved successfully"
assert len(data["data"]["items"]) >= 1
@pytest.mark.asyncio
async def test_get_masterdata_by_id(client: AsyncClient):
# Create one
create_resp = await client.post("/masterdata", json={
"name": "Data By ID",
"description": "Desc",
"unit_of_measurement": "u",
"value_num": 2.0,
"seq": 2
})
masterdata_id = create_resp.json()["data"]["id"]
response = await client.get(f"/masterdata/{masterdata_id}")
assert response.status_code == 200
assert response.json()["data"]["name"] == "Data By ID"
@pytest.mark.asyncio
async def test_update_masterdata(client: AsyncClient):
# Create one
create_resp = await client.post("/masterdata", json={
"name": "Old Name",
"description": "Desc",
"unit_of_measurement": "u",
"value_num": 3.0,
"seq": 3
})
masterdata_id = create_resp.json()["data"]["id"]
# Update it
update_payload = {
"name": "New Name",
"value_num": 4.0
}
response = await client.post(f"/masterdata/update/{masterdata_id}", json=update_payload)
assert response.status_code == 200
assert response.json()["data"]["name"] == "New Name"
assert response.json()["data"]["value_num"] == 4.0
@pytest.mark.asyncio
async def test_delete_masterdata(client: AsyncClient):
# Create one
create_resp = await client.post("/masterdata", json={
"name": "To Be Deleted",
"description": "Desc",
"unit_of_measurement": "u",
"value_num": 5.0,
"seq": 5
})
masterdata_id = create_resp.json()["data"]["id"]
# Delete it
response = await client.post(f"/masterdata/delete/{masterdata_id}")
assert response.status_code == 200
assert response.json()["message"] == "Data deleted successfully"
# Verify it's gone
get_resp = await client.get(f"/masterdata/{masterdata_id}")
assert get_resp.status_code == 404

@ -0,0 +1,8 @@
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_get_masterdata_simulations(client: AsyncClient):
response = await client.get("/masterdata-simulations")
assert response.status_code == 200
assert response.json()["message"] == "Data retrieved successfully"

@ -0,0 +1,16 @@
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_list_fs_transactions(client: AsyncClient):
response = await client.get("/plant-fs-transaction-data")
assert response.status_code == 200
assert response.json()["message"] == "Data retrieved successfully"
@pytest.mark.asyncio
async def test_get_fs_charts(client: AsyncClient):
response = await client.get("/plant-fs-transaction-data/charts")
if response.status_code == 200:
assert "items" in response.json()["data"]
else:
assert response.status_code == 404

@ -0,0 +1,20 @@
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_get_plant_masterdatas(client: AsyncClient):
response = await client.get("/plant-masterdata")
assert response.status_code == 200
assert response.json()["message"] == "Data retrieved successfully"
@pytest.mark.asyncio
async def test_create_plant_masterdata(client: AsyncClient):
payload = {
"name": "Plant Parameter",
"description": "Plant Desc",
"unit_of_measurement": "unit",
"value_num": 10.5
}
response = await client.post("/plant-masterdata", json=payload)
assert response.status_code == 200
assert response.json()["message"] == "Data created successfully"

@ -0,0 +1,18 @@
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_get_plant_transactions(client: AsyncClient):
response = await client.get("/plant-transaction-data")
assert response.status_code == 200
assert response.json()["message"] == "Data retrieved successfully"
@pytest.mark.asyncio
async def test_get_plant_charts(client: AsyncClient):
# This might return 404 if no data exists, but with my setup_db it should be empty
response = await client.get("/plant-transaction-data/charts")
# Actually, the service might raise 404 if it's empty
if response.status_code == 200:
assert "items" in response.json()["data"]
else:
assert response.status_code == 404

@ -0,0 +1,19 @@
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_get_simulations(client: AsyncClient):
response = await client.get("/simulations")
assert response.status_code == 200
assert response.json()["message"] == "Data retrieved successfully"
@pytest.mark.asyncio
async def test_create_simulation(client: AsyncClient):
payload = {
"label": "Test Simulation",
"description": "Test Desc",
"version": 1
}
response = await client.post("/simulations", json=payload)
assert response.status_code == 200
assert response.json()["data"]["label"] == "Test Simulation"

@ -0,0 +1,18 @@
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_get_yeardatas(client: AsyncClient):
response = await client.get("/yeardata")
assert response.status_code == 200
assert response.json()["message"] == "Data retrieved successfully"
@pytest.mark.asyncio
async def test_create_yeardata(client: AsyncClient):
payload = {
"year": 2024,
"description": "Test Year Data"
}
response = await client.post("/yeardata", json=payload)
assert response.status_code == 200
assert response.json()["message"] == "Data created successfully"

@ -1,33 +0,0 @@
import uuid
from datetime import datetime
from factory import (
LazyAttribute,
LazyFunction,
Sequence,
SubFactory,
post_generation,
SelfAttribute,
)
from factory.alchemy import SQLAlchemyModelFactory
from factory.fuzzy import FuzzyChoice, FuzzyDateTime, FuzzyInteger, FuzzyText
from faker import Faker
from faker.providers import misc
# from pytz import UTC
from .database import Session
fake = Faker()
fake.add_provider(misc)
class BaseFactory(SQLAlchemyModelFactory):
"""Base Factory."""
class Meta:
"""Factory configuration."""
abstract = True
sqlalchemy_session = Session
sqlalchemy_session_persistence = "commit"

@ -0,0 +1,24 @@
import pytest
from src.masterdata.service import calculate_pmt
def test_calculate_pmt_zero_rate():
# PMT = -PV / nper when rate is 0
pv = 1000
nper = 10
rate = 0
result = calculate_pmt(rate, nper, pv)
assert result == -100
def test_calculate_pmt_standard():
# Example: Loan 1000, 5% rate, 2 periods
# PMT = -1000 * (0.05 * (1.05)^2) / ((1.05)^2 - 1)
# PMT = -1000 * (0.05 * 1.1025) / (0.1025)
# PMT = -1000 * (0.055125) / (0.1025) = -537.8048...
result = calculate_pmt(5, 2, 1000)
assert round(result, 2) == -537.80
def test_calculate_pmt_percentage():
# If rate > 1, it divides by 100
result_5 = calculate_pmt(5, 10, 1000)
result_05 = calculate_pmt(0.05, 10, 1000)
assert result_5 == result_05

@ -0,0 +1,37 @@
import pytest
from unittest.mock import AsyncMock, MagicMock
from src.masterdata.service import create, get
from src.masterdata.schema import MasterDataCreate
@pytest.mark.asyncio
async def test_create_masterdata_service():
mock_db = AsyncMock()
masterdata_in = MasterDataCreate(
name="Test",
description="Desc",
unit_of_measurement="unit",
value_num=10.0,
seq=1
)
result = await create(db_session=mock_db, masterdata_in=masterdata_in)
assert result.name == "Test"
mock_db.add.assert_called_once()
mock_db.commit.assert_called_once()
@pytest.mark.asyncio
async def test_get_masterdata_service():
mock_db = AsyncMock()
mock_result = MagicMock()
mock_masterdata = MagicMock()
mock_masterdata.id = "test-id"
# Mock behavior of db_session.execute().scalars().one_or_none()
mock_result.scalars.return_value.one_or_none.return_value = mock_masterdata
mock_db.execute.return_value = mock_result
result = await get(db_session=mock_db, masterdata_id="test-id")
assert result.id == "test-id"
mock_db.execute.assert_called_once()
Loading…
Cancel
Save