Repository: privacera/paig (language: python)

Issue:
[ENH]: Fix warning while running pytest
### Contact Details

siddheshwar.kamble@privacera.com

### Feature Description

Below warnings are harmless, however its better to evaluate and fix these.

```
./venv/lib/python3.10/site-packages/_pytest/fixtures.py:1306
  /Users/siddheshwarkamble/paig_fork/paig/backend/venv/lib/python3.10/site-packages/_pytest/fixtures.py:1306: PytestRemovedIn9Warning: Marks applied to fixtures have no effect
  See docs: https://docs.pytest.org/en/stable/deprecations.html#applying-a-mark-to-a-fixture-function
    return fixture_marker(fixture_function)

../venv/lib/python3.10/site-packages/pydantic/_internal/_config.py:291: 14 warnings
  /Users/siddheshwarkamble/paig_fork/paig/backend/venv/lib/python3.10/site-packages/pydantic/_internal/_config.py:291: 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.8/migration/
    warnings.warn(DEPRECATION_MESSAGE, DeprecationWarning)

../venv/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py:273: 20 warnings
  /Users/siddheshwarkamble/paig_fork/paig/backend/venv/lib/python3.10/site-packages/pydantic/_internal/_generate_schema.py:273: PydanticDeprecatedSince20: `json_encoders` is deprecated. See https://docs.pydantic.dev/2.8/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.8/migration/
    warnings.warn(

../venv/lib/python3.10/site-packages/profanity_check/profanity_check.py:2
  /Users/siddheshwarkamble/paig_fork/paig/backend/venv/lib/python3.10/site-packages/profanity_check/profanity_check.py:2: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
    import pkg_resources

backend/paig/tests/api/authz/authorizer/backend/test_rds_based_paig_authorizer.py::test_get_user_groups
  /Users/siddheshwarkamble/paig_fork/paig/backend/venv/lib/python3.10/site-packages/pytest_asyncio/plugin.py:757: DeprecationWarning: The event_loop fixture provided by pytest-asyncio has been redefined in
  /Users/siddheshwarkamble/paig_fork/paig/backend/paig/tests/conftest.py:26
  Replacing the event_loop fixture with a custom implementation is deprecated
  and will lead to errors in the future.
  If you want to request an asyncio event loop with a scope other than function
  scope, use the "scope" argument to the asyncio mark when marking the tests.
  If you want to return different types of event loops, use the event_loop_policy
  fixture.
  
    warnings.warn(

backend/paig/tests/api/encryption/routes/test_encryption_key_router.py::test_list_encryption_keys_success
backend/paig/tests/api/encryption/routes/test_encryption_key_router.py::test_list_encryption_keys_success
backend/paig/tests/api/encryption/routes/test_encryption_key_router.py::test_list_encryption_keys_success
backend/paig/tests/api/encryption/routes/test_encryption_key_router.py::test_list_encryption_keys_success
backend/paig/tests/api/encryption/routes/test_encryption_key_router.py::test_list_encryption_keys_success
backend/paig/tests/api/encryption/routes/test_encryption_key_router.py::test_list_encryption_keys_success
backend/paig/tests/api/encryption/routes/test_encryption_key_router.py::test_list_encryption_keys_success
  /Users/siddheshwarkamble/paig_fork/paig/backend/venv/lib/python3.10/site-packages/pydantic/main.py:1132: PydanticDeprecatedSince20: The `parse_obj` method is deprecated; use `model_validate` instead. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.8/migration/
    warnings.warn(

backend/paig/tests/api/encryption/routes/test_encryption_key_router.py::test_list_encryption_keys_success
backend/paig/tests/api/router/audit/test_data_service_routers.py::TestDataServiceRouters::test_get_access_audits
  /Users/siddheshwarkamble/paig_fork/paig/backend/paig/core/middlewares/usage.py:58: DeprecationWarning: 
          on_event is deprecated, use lifespan event handlers instead.
  
          Read more about it in the
          [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/).
          
    @app.on_event("startup")

backend/paig/tests/api/encryption/routes/test_encryption_key_router.py::test_list_encryption_keys_success
backend/paig/tests/api/encryption/routes/test_encryption_key_router.py::test_list_encryption_keys_success
backend/paig/tests/api/router/audit/test_data_service_routers.py::TestDataServiceRouters::test_get_access_audits
backend/paig/tests/api/router/audit/test_data_service_routers.py::TestDataServiceRouters::test_get_access_audits
  /Users/siddheshwarkamble/paig_fork/paig/backend/venv/lib/python3.10/site-packages/fastapi/applications.py:4495: DeprecationWarning: 
          on_event is deprecated, use lifespan event handlers instead.
  
          Read more about it in the
          [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/).
          
    return self.router.on_event(event_type)

backend/paig/tests/api/encryption/routes/test_encryption_key_router.py::test_list_encryption_keys_success
backend/paig/tests/api/router/audit/test_data_service_routers.py::TestDataServiceRouters::test_get_access_audits
  /Users/siddheshwarkamble/paig_fork/paig/backend/paig/core/middlewares/usage.py:71: DeprecationWarning: 
          on_event is deprecated, use lifespan event handlers instead.
  
          Read more about it in the
          [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/).
          
    @app.on_event("shutdown")

backend/paig/tests/api/encryption/services/test_encryption_key_service.py::test_create_encryption_key
  /Users/siddheshwarkamble/paig_fork/paig/backend/venv/lib/python3.10/site-packages/pydantic/main.py:364: UserWarning: Pydantic serializer warnings:
    Expected `str` but got `MagicMock` - serialized value may not be as expected
    Expected `str` but got `MagicMock` - serialized value may not be as expected
    return self.__pydantic_serializer__.to_python(

backend/paig/tests/api/encryption/services/test_encryption_key_service.py: 2 warnings
backend/paig/tests/api/router/audit/test_data_service_routers.py: 5 warnings
backend/paig/tests/api/router/governance/test_ai_app_policy_routers.py: 12 warnings
backend/paig/tests/api/router/governance/test_ai_app_routers.py: 2 warnings
backend/paig/tests/api/router/governance/test_metadata_routers.py: 2 warnings
backend/paig/tests/api/router/governance/test_metadata_value_routers.py: 4 warnings
backend/paig/tests/api/router/governance/test_tag_routers.py: 2 warnings
backend/paig/tests/api/router/governance/test_vector_db_policy_routers.py: 2 warnings
backend/paig/tests/api/router/governance/test_vector_db_routers.py: 2 warnings
backend/paig/tests/api/router/user/test_group_routers.py: 3 warnings
backend/paig/tests/api/router/user/test_user_routers.py: 3 warnings
  /Users/siddheshwarkamble/paig_fork/paig/backend/venv/lib/python3.10/site-packages/pydantic/main.py:1228: PydanticDeprecatedSince20: The `from_orm` method is deprecated; set `model_config['from_attributes']=True` and use `model_validate` instead. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.8/migration/
    warnings.warn(

backend/paig/tests/api/encryption/services/test_encryption_key_service.py::test_delete_disabled_encryption_key
backend/paig/tests/api/encryption/services/test_encryption_key_service.py::test_disable_passive_encryption_key
  /Users/siddheshwarkamble/paig_fork/paig/backend/paig/core/controllers/base_controller.py:99: RuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was never awaited
    model.set_attribute(updated_data)
  Enable tracemalloc to get traceback where the object was allocated.
  See https://docs.pytest.org/en/stable/how-to/capture-warnings.html#resource-warnings for more info.

backend/paig/tests/api/governance/database/db_operations/test_ai_app_repository.py::test_get_ai_application_by_application_key_not_found
  /opt/homebrew/Cellar/python@3.10/3.10.14/Frameworks/Python.framework/Versions/3.10/lib/python3.10/unittest/mock.py:2181: RuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was never awaited
    self.name = name
  Enable tracemalloc to get traceback where the object was allocated.
  See https://docs.pytest.org/en/stable/how-to/capture-warnings.html#resource-warnings for more info.

backend/paig/tests/api/governance/database/db_operations/test_vector_db_policy_repository.py::test_list_policies_for_authorization_no_policies
  /opt/homebrew/Cellar/python@3.10/3.10.14/Frameworks/Python.framework/Versions/3.10/lib/python3.10/inspect.py:3134: RuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was never awaited
    for param in itertools.chain(parameters_ex, parameters):
  Enable tracemalloc to get traceback where the object was allocated.
  See https://docs.pytest.org/en/stable/how-to/capture-warnings.html#resource-warnings for more info.

backend/paig/tests/api/router/audit/test_data_service_routers.py::TestDataServiceRouters::test_get_access_audits
  /Users/siddheshwarkamble/paig_fork/paig/backend/venv/lib/python3.10/site-packages/pydantic/_internal/_core_utils.py:568: RuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was never awaited
    return _validate_core_schema(schema)
  Enable tracemalloc to get traceback where the object was allocated.
  See https://docs.pytest.org/en/stable/how-to/capture-warnings.html#resource-warnings for more info.

backend/paig/tests/api/router/audit/test_data_service_routers.py: 4 warnings
backend/paig/tests/api/router/governance/test_ai_app_config_routers.py: 2 warnings
backend/paig/tests/api/router/governance/test_ai_app_policy_routers.py: 2 warnings
backend/paig/tests/api/router/governance/test_ai_app_routers.py: 2 warnings
backend/paig/tests/api/router/governance/test_metadata_routers.py: 2 warnings
backend/paig/tests/api/router/governance/test_metadata_value_routers.py: 2 warnings
backend/paig/tests/api/router/governance/test_tag_routers.py: 2 warnings
backend/paig/tests/api/router/governance/test_vector_db_policy_routers.py: 2 warnings
backend/paig/tests/api/router/governance/test_vector_db_routers.py: 2 warnings
backend/paig/tests/api/router/user/test_account_service.py: 2 warnings
backend/paig/tests/api/router/user/test_group_routers.py: 4 warnings
backend/paig/tests/api/router/user/test_user_routers.py: 4 warnings
  /Users/siddheshwarkamble/paig_fork/paig/backend/venv/lib/python3.10/site-packages/httpx/_client.py:1426: DeprecationWarning: The 'app' shortcut is now deprecated. Use the explicit style 'transport=ASGITransport(app=...)' instead.
    warnings.warn(message, DeprecationWarning)

backend/paig/tests/api/router/audit/test_data_service_routers.py: 28 warnings
backend/paig/tests/api/router/governance/test_ai_app_config_routers.py: 28 warnings
backend/paig/tests/api/router/governance/test_ai_app_policy_routers.py: 44 warnings
backend/paig/tests/api/router/governance/test_ai_app_routers.py: 37 warnings
backend/paig/tests/api/router/governance/test_metadata_routers.py: 8 warnings
backend/paig/tests/api/router/governance/test_metadata_value_routers.py: 12 warnings
backend/paig/tests/api/router/governance/test_tag_routers.py: 10 warnings
backend/paig/tests/api/router/governance/test_vector_db_policy_routers.py: 30 warnings
backend/paig/tests/api/router/governance/test_vector_db_routers.py: 21 warnings
backend/paig/tests/api/router/user/test_account_service.py: 19 warnings
backend/paig/tests/api/router/user/test_group_routers.py: 60 warnings
backend/paig/tests/api/router/user/test_user_routers.py: 57 warnings
backend/paig/tests/api/shield/test_log_message_in_data_service.py: 1 warning
backend/paig/tests/api/user/test_group_controller.py: 5 warnings
backend/paig/tests/api/user/test_user_controller.py: 3 warnings
  /Users/siddheshwarkamble/paig_fork/paig/backend/venv/lib/python3.10/site-packages/pydantic/main.py:1087: PydanticDeprecatedSince20: The `dict` method is deprecated; use `model_dump` instead. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.8/migration/
    warnings.warn('The `dict` method is deprecated; use `model_dump` instead.', category=PydanticDeprecatedSince20)

backend/paig/tests/api/router/audit/test_data_service_routers.py: 12 warnings
  /Users/siddheshwarkamble/paig_fork/paig/backend/venv/lib/python3.10/site-packages/pydantic/_internal/_model_construction.py:268: PydanticDeprecatedSince20: The `__fields__` attribute is deprecated, use `model_fields` instead. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.8/migration/
    warnings.warn(

backend/paig/tests/api/router/governance/test_ai_app_config_download_routers.py::test_ai_application_config_download_operation
  /Users/siddheshwarkamble/paig_fork/paig/backend/venv/lib/python3.10/site-packages/_pytest/python.py:151: PytestUnhandledCoroutineWarning: async def functions are not natively supported and have been skipped.
  You need to install a suitable plugin for your async framework, for example:
    - anyio
    - pytest-asyncio
    - pytest-tornasync
    - pytest-trio
    - pytest-twisted
    warnings.warn(PytestUnhandledCoroutineWarning(msg.format(nodeid)))

backend/paig/tests/api/router/governance/test_ai_app_config_routers.py: 8 warnings
backend/paig/tests/api/router/governance/test_ai_app_policy_routers.py: 23 warnings
backend/paig/tests/api/router/governance/test_ai_app_routers.py: 10 warnings
backend/paig/tests/api/router/governance/test_metadata_routers.py: 7 warnings
backend/paig/tests/api/router/governance/test_metadata_value_routers.py: 8 warnings
backend/paig/tests/api/router/governance/test_tag_routers.py: 8 warnings
backend/paig/tests/api/router/governance/test_vector_db_policy_routers.py: 21 warnings
backend/paig/tests/api/router/governance/test_vector_db_routers.py: 10 warnings
backend/paig/tests/api/router/user/test_account_service.py: 14 warnings
backend/paig/tests/api/router/user/test_group_routers.py: 19 warnings
backend/paig/tests/api/router/user/test_user_routers.py: 19 warnings
  /Users/siddheshwarkamble/paig_fork/paig/backend/venv/lib/python3.10/site-packages/httpx/_content.py:202: DeprecationWarning: Use 'content=<...>' to upload raw bytes/text content.
    warnings.warn(message, DeprecationWarning)

backend/paig/tests/api/router/governance/test_ai_app_policy_routers.py: 2 warnings
backend/paig/tests/api/router/governance/test_tag_routers.py: 1 warning
backend/paig/tests/api/router/user/test_account_service.py: 1 warning
backend/paig/tests/api/router/user/test_group_routers.py: 4 warnings
backend/paig/tests/api/router/user/test_user_routers.py: 3 warnings
backend/paig/tests/api/user/test_group_controller.py: 1 warning
backend/paig/tests/api/user/test_user_controller.py: 1 warning
  sys:1: SAWarning: TypeDecorator CommaSeparatedList(length=1024) will not produce a cache key because the ``cache_ok`` attribute is not set to True.  This can have significant performance implications including some performance degradations in comparison to prior SQLAlchemy versions.  Set this attribute to True if this type object's state is safe to use in a cache key, or False to disable this warning. (Background on this warning at: https://sqlalche.me/e/20/cprf)

backend/paig/tests/api/router/governance/test_vector_db_routers.py: 2 warnings
backend/paig/tests/api/router/user/test_account_service.py: 1 warning
backend/paig/tests/api/router/user/test_group_routers.py: 4 warnings
backend/paig/tests/api/router/user/test_user_routers.py: 3 warnings
backend/paig/tests/api/user/test_group_controller.py: 1 warning
backend/paig/tests/api/user/test_user_controller.py: 1 warning
  sys:1: SAWarning: TypeDecorator CommaSeparatedList(length=255) will not produce a cache key because the ``cache_ok`` attribute is not set to True.  This can have significant performance implications including some performance degradations in comparison to prior SQLAlchemy versions.  Set this attribute to True if this type object's state is safe to use in a cache key, or False to disable this warning. (Background on this warning at: https://sqlalche.me/e/20/cprf)

backend/paig/tests/api/shield/test_log_message_in_data_service.py::test_log_message_in_data_service
  /Users/siddheshwarkamble/paig_fork/paig/backend/venv/lib/python3.10/site-packages/pydantic/main.py:364: UserWarning: Pydantic serializer warnings:
    Expected `dict[any, any]` but got `str` - serialized value may not be as expected
    Expected `int` but got `str` - serialized value may not be as expected
    Expected `dict[any, any]` but got `str` - serialized value may not be as expected
    Expected `list[dict[any, any]]` but got `str` - serialized value may not be as expected
    Expected `list[int]` but got `str` - serialized value may not be as expected
    Expected `list[str]` but got `str` - serialized value may not be as expected
    Expected `int` but got `str` - serialized value may not be as expected
    return self.__pydantic_serializer__.to_python(

backend/paig/tests/api/user/test_user_controller.py::TestUserController::test_create_user_exceptions_with_empty_username
  /Users/siddheshwarkamble/paig_fork/paig/backend/paig/core/factory/database_initiator.py:397: SADeprecationWarning: Invoking or_() without arguments is deprecated, and will be disallowed in a future release.   For an empty or_() construct, use 'or_(false(), *args)' or 'or_(False, *args)'.
    query = query.filter(or_(*self._get_filter(filters)))
```


### Code of Conduct

- [X] I agree to follow this project's Code of Conduct


Discussion / hints:

Fix patch:
diff --git a/paig-server/backend/paig/api/user/services/user_service.py b/paig-server/backend/paig/api/user/services/user_service.py
index 7ce2cf50..a39da888 100644
--- a/paig-server/backend/paig/api/user/services/user_service.py
+++ b/paig-server/backend/paig/api/user/services/user_service.py
@@ -105,7 +105,7 @@ async def update_user(self, id: int, user: dict, user_params: dict):
         if email:
             email = email.strip()
             user = await self.user_repository.get_user_by_field(field="email", value=email)
-            if user:
+            if user and user.id != id:
                 raise ConflictException(f"User with email {email} already exists")
 
         user_params['password'] = _format_password(roles=user_params['roles'], secret=user_params['password'])


Test patch:
diff --git a/paig-server/backend/paig/tests/api/router/user/test_account_service.py b/paig-server/backend/paig/tests/api/router/user/test_account_service.py
index 80be7ce3..1fce5d36 100644
--- a/paig-server/backend/paig/tests/api/router/user/test_account_service.py
+++ b/paig-server/backend/paig/tests/api/router/user/test_account_service.py
@@ -132,6 +132,7 @@ async def test_users_crud_operations(self, client: AsyncClient, app: FastAPI):
             "firstName": "first_user_updated",
             "lastName": "user_1_updated",
             "roles": ["USER"],
+            "email": "user1@test.com",
             "groups": []
         }
         response = await client.put(
@@ -141,6 +142,62 @@ async def test_users_crud_operations(self, client: AsyncClient, app: FastAPI):
         assert response.json()['firstName'] == 'first_user_updated'
         assert response.json()['lastName'] == 'user_1_updated'
 
+        # Create Test user2
+        test_user2_dict = {
+            "username": "test_user2",
+            "status": 1,
+            "firstName": "User2_fistName",
+            "lastName": "User2_LastName",
+            "password": "TestUser@2",
+            "roles": ["OWNER"],
+            "email": "user2@test.com",
+            "groups": []
+        }
+
+        response = await client.post(
+            f"{user_services_base_route}/users", content=json.dumps(test_user2_dict)
+        )
+        assert response.status_code == 201
+        assert response.json()["username"] == 'test_user2'
+
+        # Test update user email
+        test_user2_dict['email'] = 'test_user2@test.com'
+        response = await client.put(
+            f"{user_services_base_route}/users/3", content=json.dumps(test_user2_dict)
+        )
+        assert response.status_code == 200
+        assert response.json()["username"] == 'test_user2'
+        assert response.json()["email"] == 'test_user2@test.com'
+
+        # Test conflict to update user email with existing other user email
+        update_req = {
+            "status": 1,
+            "firstName": "User2_firstName_updated",
+            "lastName": "User2_lastName_updated",
+            "roles": ["OWNER"],
+            "email": "user1@test.com"
+        }
+        response = await client.put(
+            f"{user_services_base_route}/users/3", content=json.dumps(update_req)
+        )
+        assert response.status_code == 409
+
+        # Test conflict to create user with existing username
+        response = await client.post(
+            f"{user_services_base_route}/users", content=json.dumps(test_user2_dict)
+        )
+
+        assert response.status_code == 409
+
+        # Test conflict to create user with existing email
+        test_user2_dict['username'] = 'test_user3'
+        response = await client.post(
+            f"{user_services_base_route}/users", content=json.dumps(test_user2_dict)
+        )
+
+        assert response.status_code == 409
+
+
         # Delete user
         response = await client.delete(
             f"{user_services_base_route}/users/2"