# apps/api/tests/integration
dir: apps/api/tests/integration

index: apps/api/tests/integration/.pi-map.index.md

## role
Integration and unit test suite for the API backend, covering authentication, CRUD APIs, workspace operations, git integration, notifications, and database model validation against real PostgreSQL and mocked dependencies.
## files
- __init__.py | Empty file with no functionality
- test_auth_api.py | Integration tests for authentication API endpoints using a real PostgreSQL database | exp: func:_postgres_available() → bool, call:asyncpg.connect, call:conn.close, call:asyncio.run, call:_check, func:_check() → bool, call:asyncpg.connect, call:conn.close, func:_prepare_auth_test_db() → None, call:create_async_engine, call:build_database_url, call:engine.begin, call:connection.run_sync, call:connection.execute, call:text, call:engine.dispose, call:asyncio.run, call:_run, func:_run() → None, call:create_async_engine, call:build_database_url, call:engine.begin, call:connection.run_sync, call:connection.execute, call:text, call:engine.dispose, func:_load_app(), call:importlib.reload, func:_insert_test_user(user_id: str) → None, call:create_async_engine, call:build_database_url, call:engine.begin, call:connection.run_sync, call:async_sessionmaker, call:session_factory, call:User, call:uuid.UUID, call:session.merge, call:session.commit, call:engine.dispose, call:asyncio.run, call:_run, func:_run() → None, call:create_async_engine, call:build_database_url, call:engine.begin, call:connection.run_sync, call:async_sessionmaker, call:session_factory, call:User, call:uuid.UUID, call:session.merge, call:session.commit, call:engine.dispose, func:test_login_redirects_to_authentik_authorize_endpoint() → None, call:_prepare_auth_test_db, call:_load_app, call:TestClient, call:client.get, func:test_me_returns_401_without_session_cookie() → None, call:_prepare_auth_test_db, call:_load_app, call:TestClient, call:client.get, func:test_me_returns_user_with_valid_session() → None, call:_prepare_auth_test_db, call:_insert_test_user, call:_load_app, call:Settings, call:create_session_cookie, call:TestClient, call:client.get, call:response.json, func:test_logout_clears_session_cookie() → None, call:_prepare_auth_test_db, call:_load_app, call:TestClient, call:client.post, call:response.headers.get | dep: uuid, asyncio, importlib, fastapi.testclient, pytest, sqlalchemy, sqlalchemy.ext.asyncio, src.auth.session, src.config, src.models, src.models.user.user, asyncpg, fastapi
- test_auth_services.py | Integration tests for authentication services including cookie options, OIDC login URLs, and session cookie creation/decoding with security validations. | exp: func:test_cookie_options_follow_environment_defaults(monkeypatch) → None, call:monkeypatch.setenv, call:Settings, call:build_cookie_options, func:test_login_redirect_url_contains_required_oidc_params() → None, call:Settings, call:build_login_redirect_url, func:test_create_and_decode_session_cookie_round_trip() → None, call:Settings, call:create_session_cookie, call:decode_session_cookie, func:test_decode_session_rejects_invalid_signature() → None, call:Settings, call:create_session_cookie, call:pytest.raises, call:decode_session_cookie, func:test_decode_session_rejects_expired_cookie(monkeypatch) → None, call:Settings, call:create_session_cookie, call:pytest.raises, call:decode_session_cookie | dep: pytest, src.auth.cookies, src.auth.oidc, src.auth.session, src.config
- test_config_profiles_api.py | Integration tests for a FastAPI config profiles REST API covering CRUD operations, profile inheritance, default resolution, git mounts, and validation. | exp: class:TestConfigProfilesAPI, method:test_list_config_profiles_requires_authentication(self, test_client: TestClient) → None, call:test_client.get, method:test_list_config_profiles_returns_user_profiles(self, authenticated_client: TestClient) → None, call:authenticated_client.get, call:response.json, call:isinstance, method:test_create_config_profile_successfully(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:response.json, method:test_create_config_profile_duplicate_name(self, authenticated_client: TestClient) → None, call:authenticated_client.post, method:test_create_config_profile_exceeds_size_limit(self, authenticated_client: TestClient) → None, call:authenticated_client.post, method:test_create_config_profile_invalid_file_path(self, authenticated_client: TestClient) → None, call:authenticated_client.post, method:test_create_config_profile_invalid_mount_target(self, authenticated_client: TestClient) → None, call:authenticated_client.post, method:test_get_config_profile_by_id(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:create_response.json, call:authenticated_client.get, call:response.json, method:test_get_config_profile_not_found(self, authenticated_client: TestClient) → None, call:authenticated_client.get, call:uuid.uuid4, method:test_update_config_profile_successfully(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:create_response.json, call:authenticated_client.put, call:response.json, method:test_delete_config_profile_successfully(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:create_response.json, call:authenticated_client.delete, call:authenticated_client.get, method:test_update_profile_includes_successfully(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:base_response.json, call:child_response.json, call:authenticated_client.put, call:response.json, call:print, call:data.get, call:len, method:test_update_profile_includes_cycle_detection(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:a_response.json, call:b_response.json, call:authenticated_client.put, method:test_preview_config_profile_successfully(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:base_response.json, call:child_response.json, call:authenticated_client.put, call:authenticated_client.get, call:response.json, call:len, method:test_resolve_default_profile(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:str, call:uuid.uuid4, call:authenticated_client.get, call:response.json, method:test_resolve_default_profile_no_match(self, authenticated_client: TestClient) → None, call:str, call:uuid.uuid4, call:authenticated_client.get, call:response.json, method:test_create_config_profile_with_git_mounts(self, authenticated_client: TestClient, test_project_and_repo) → None, call:authenticated_client.post, call:response.json, call:len, method:test_update_config_profile_git_mounts(self, authenticated_client: TestClient, test_project_and_repo) → None, call:authenticated_client.post, call:create_response.json, call:authenticated_client.put, call:response.json, call:len, method:test_create_config_profile_invalid_git_mount_source_path(self, authenticated_client: TestClient, test_project_and_repo) → None, call:authenticated_client.post, method:test_create_config_profile_invalid_git_mount_target_path_traversal(self, authenticated_client: TestClient, test_project_and_repo) → None, call:authenticated_client.post, method:test_preview_config_profile_with_git_mounts(self, authenticated_client: TestClient, test_project_and_repo) → None, call:authenticated_client.post, call:create_response.json, call:authenticated_client.get, call:response.json, call:len | dep: uuid, pytest, fastapi.testclient, fastapi.testclient.TestClient
- test_events.py | Integration tests for SSE endpoint authentication, connection limits, event bus pub/sub, and lifecycle event persistence to database | exp: func:event_bus() → Generator[InstanceEventBus, None, None], call:InstanceEventBus, call:bus._reset_for_testing, func:sample_payload() → InstanceEventPayload, call:str, call:uuid.uuid4, func:_get_user_id_from_client(client: TestClient) → uuid.UUID | None, call:Settings, call:client.cookies.get, call:decode_session_cookie, call:uuid.UUID, func:test_sse_requires_auth(test_client: TestClient) → None, call:test_client.get, func:test_sse_enforces_connection_limit(authenticated_client: TestClient) → None, call:_get_user_id_from_client, call:authenticated_client.get, call:events_module._connection_counts.pop, func:test_sse_event_generator_format() → None, call:getattr, call:any, call:str, func:test_lifecycle_hook_publishes_event_and_persists(authenticated_client: TestClient, db_session: AsyncSession, event_bus: InstanceEventBus) → None, call:_get_user_id_from_client, call:Project, call:uuid.uuid4, call:GitRepository, call:ToolType, call:db_session.add_all, call:db_session.commit, call:ToolInstance, call:db_session.add, call:received.append, call:event_bus.subscribe, call:publish_lifecycle_event, call:len, call:db_session.execute, call:select(InstanceEvent).where, call:result.scalars().all, func:subscriber(payload: InstanceEventPayload) → None, call:received.append, func:test_lifecycle_event_persists_audit_row(authenticated_client: TestClient, db_session: AsyncSession, event_bus: InstanceEventBus) → None, call:_get_user_id_from_client, call:Project, call:uuid.uuid4, call:GitRepository, call:ToolType, call:db_session.add_all, call:db_session.commit, call:ToolInstance, call:db_session.add, call:publish_lifecycle_event, call:db_session.execute, call:select(InstanceEvent).where, call:result.scalars().all, call:len, func:test_event_bus_pubsub(event_bus: InstanceEventBus) → None, call:received.append, call:event_bus.subscribe, call:str, call:uuid.uuid4, call:asyncio.run, call:event_bus.publish, call:len, func:handler(payload: InstanceEventPayload) → None, call:received.append | dep: asyncio, uuid, collections.abc, typing, pytest, fastapi.testclient, sqlalchemy, sqlalchemy.ext.asyncio, src.api.system, src.auth.session, src.config, src.models.project.git_repository, src.models.system.instance_event, src.models.project.project, src.models.tool.tool_instance, src.models.tool.tool_type, src.services.instance.event_bus, src.api.system.events, src.services.instance.lifecycle_hooks, fastapi
- test_git_control.py | Unit tests for git utility functions including repository status, branch operations, and commit handling | exp: class:TestGitStatus, method:test_clean_repo(self, temp_repo), call:get_status, call:isinstance, call:len, method:test_modified_file(self, temp_repo), call:open, call:os.path.join, call:f.write, call:get_status, method:test_untracked_file(self, temp_repo), call:open, call:os.path.join, call:f.write, call:get_status, class:TestBranchOperations, method:test_create_branch(self, temp_repo), call:get_current_branch, call:create_branch, call:get_status, method:test_checkout_branch(self, temp_repo), call:get_current_branch, call:create_branch, call:checkout_branch, method:test_delete_branch(self, temp_repo), call:get_current_branch, call:create_branch, call:delete_branch, method:test_get_current_branch(self, temp_repo), call:get_current_branch, class:TestCommit, method:test_commit_changes(self, temp_repo), call:open, call:os.path.join, call:f.write, call:commit_changes, call:get_status, method:test_commit_all_changes(self, temp_repo), call:open, call:os.path.join, call:f.write, call:commit_changes, call:get_status, call:len, func:temp_repo(), call:tempfile.TemporaryDirectory, call:os.system, call:open, call:os.path.join, call:f.write, func:test_get_current_branch_handles_unborn_main() → None, call:tempfile.TemporaryDirectory, call:os.system, call:get_current_branch, func:test_create_branch_on_bare_repo_with_no_commits() → None, call:tempfile.TemporaryDirectory, call:os.system, call:create_branch, call:get_current_branch, func:test_checkout_branch_on_bare_repo_with_no_commits() → None, call:tempfile.TemporaryDirectory, call:os.system, call:checkout_branch, call:get_current_branch | dep: os, tempfile, pytest, src.utils.git_control
- test_models.py | Integration tests verifying SQLAlchemy model definitions, table registration, column constraints, relationships, and async database operations. | exp: func:test_base_metadata_collects_declared_tables() → None, call:isinstance, func:test_shared_mixins_define_expected_columns() → None, func:test_expected_tables_are_registered() → None, call:set, func:test_user_table_has_required_columns() → None, call:set, call:columns.keys, func:test_project_relationships_point_to_owner_and_default_ssh_key() → None, call:next, call:iter, func:test_repository_and_user_config_relationships_are_registered() → None, call:next, call:iter, func:test_async_session_can_insert_and_load_user(db_session: AsyncSession) → None, call:User, call:db_session.add, call:db_session.commit, call:db_session.refresh, call:db_session.get | dep: pytest, sqlalchemy.ext.asyncio, src.models, src.models.base, src.models.project.git_repository, src.models.project.project, src.models.user.ssh_key, src.models.user.user, src.models.user.user_config, src.models (Base, mixins, User, Project, GitRepository, SSHKey, UserConfig)
- test_notifications_api.py | Integration tests for a notifications REST API covering authentication, CRUD operations, pagination, and user isolation. | exp: func:notification_service() → NotificationService, call:NotificationService, func:user_a(db_session: AsyncSession) → User, call:User, call:uuid.uuid4, call:db_session.add, call:db_session.commit, func:user_b(db_session: AsyncSession) → User, call:User, call:uuid.uuid4, call:db_session.add, call:db_session.commit, func:_mint_cookie_for_user(test_client: TestClient, user_id: uuid.UUID) → None, call:Settings, call:create_session_cookie, call:str, call:test_client.cookies.set, func:test_list_requires_auth(test_client: TestClient) → None, call:test_client.get, func:test_list_returns_only_own_notifications(authenticated_client: TestClient, db_session: AsyncSession, notification_service: NotificationService, user_a: User, user_b: User) → None, call:notification_service.create_notification, call:asyncio.run, call:create_notifications, call:_mint_cookie_for_user, call:authenticated_client.get, call:response.json, call:len, func:create_notifications() → None, call:notification_service.create_notification, func:test_list_pagination(authenticated_client: TestClient, db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:range, call:notification_service.create_notification, call:datetime.now, call:timedelta, call:db_session.commit, call:db_session.refresh, call:asyncio.run, call:create_many, call:_mint_cookie_for_user, call:authenticated_client.get, call:response.json, call:len, func:create_many() → None, call:range, call:notification_service.create_notification, call:datetime.now, call:timedelta, call:db_session.commit, call:db_session.refresh, func:test_unread_count_endpoint(authenticated_client: TestClient, db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:range, call:notification_service.create_notification, call:asyncio.run, call:create_unread, call:_mint_cookie_for_user, call:authenticated_client.get, call:response.json, func:create_unread() → None, call:range, call:notification_service.create_notification, func:test_mark_read_endpoint(authenticated_client: TestClient, db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:notification_service.create_notification, call:asyncio.run, call:create_and_get, call:_mint_cookie_for_user, call:authenticated_client.patch, call:response.json, func:create_and_get() → uuid.UUID, call:notification_service.create_notification, func:test_mark_read_404_for_other_user(authenticated_client: TestClient, db_session: AsyncSession, notification_service: NotificationService, user_a: User, user_b: User) → None, call:notification_service.create_notification, call:asyncio.run, call:create_and_get, call:_mint_cookie_for_user, call:authenticated_client.patch, func:create_and_get() → uuid.UUID, call:notification_service.create_notification, func:test_mark_all_read_endpoint(authenticated_client: TestClient, db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:range, call:notification_service.create_notification, call:asyncio.run, call:create_unread, call:_mint_cookie_for_user, call:authenticated_client.post, call:response.json, func:create_unread() → None, call:range, call:notification_service.create_notification, func:test_dismiss_endpoint(authenticated_client: TestClient, db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:notification_service.create_notification, call:asyncio.run, call:create_and_get, call:_mint_cookie_for_user, call:authenticated_client.delete, call:authenticated_client.get, call:response.json, call:len, func:create_and_get() → uuid.UUID, call:notification_service.create_notification, func:test_dismiss_404_for_other_user(authenticated_client: TestClient, db_session: AsyncSession, notification_service: NotificationService, user_a: User, user_b: User) → None, call:notification_service.create_notification, call:asyncio.run, call:create_and_get, call:_mint_cookie_for_user, call:authenticated_client.delete, func:create_and_get() → uuid.UUID, call:notification_service.create_notification, func:test_mute_categories_filter_in_list(authenticated_client: TestClient, db_session: AsyncSession, notification_service: NotificationService, user_a: User) → None, call:UserConfig, call:db_session.add, call:db_session.commit, call:notification_service.create_notification, call:asyncio.run, call:setup, call:_mint_cookie_for_user, call:authenticated_client.get, call:response.json, call:len, func:setup() → None, call:UserConfig, call:db_session.add, call:db_session.commit, call:notification_service.create_notification | dep: uuid, datetime, pytest, fastapi.testclient, sqlalchemy.ext.asyncio, src.models.user.user, src.models.user.user_config, src.services.shared.notification_service, src.auth.session, src.config, asyncio, fastapi, sqlalchemy
- test_notifications_lifecycle.py | Integration tests verifying that instance lifecycle events and health monitor state changes correctly create (or skip) notifications with proper ownership, severity, and error handling. | exp: func:event_bus() → Generator[InstanceEventBus, None, None], call:InstanceEventBus, call:bus._reset_for_testing, func:test_instance(db_session: AsyncSession) → ToolInstance, call:User, call:uuid.uuid4, call:db_session.add, call:db_session.commit, call:Project, call:GitRepository, call:ToolType, call:db_session.add_all, call:ToolInstance, func:test_lifecycle_started_intermediate_skips_notification(db_session: AsyncSession, event_bus: InstanceEventBus, test_instance: ToolInstance) → None, call:received.append, call:event_bus.subscribe, call:publish_lifecycle_event, call:len, call:db_session.execute, call:select(Notification).where, call:list, call:result.scalars().all, func:subscriber(payload: InstanceEventPayload) → None, call:received.append, func:test_lifecycle_running_creates_notification(db_session: AsyncSession, event_bus: InstanceEventBus, test_instance: ToolInstance) → None, call:publish_lifecycle_event, call:db_session.execute, call:select(Notification).where, call:list, call:result.scalars().all, call:len, func:test_health_monitor_error_creates_notification(db_session: AsyncSession, event_bus: InstanceEventBus, test_instance: ToolInstance) → None, call:HealthMonitor, call:HealthSnapshot, call:received.append, call:event_bus.subscribe, call:patch, call:monitor._check_instance, call:len, call:db_session.execute, call:select(Notification).where, call:list, call:result.scalars().all, func:subscriber(payload: InstanceEventPayload) → None, call:received.append, func:test_notification_failure_does_not_block_event_pipeline(db_session: AsyncSession, event_bus: InstanceEventBus, test_instance: ToolInstance) → None, call:received.append, call:event_bus.subscribe, call:patch, call:RuntimeError, call:publish_lifecycle_event, call:len, call:db_session.execute, call:select(Notification).where, call:result.scalar_one_or_none, func:subscriber(payload: InstanceEventPayload) → None, call:received.append, func:test_notification_ownership_matches_instance_owner(db_session: AsyncSession, event_bus: InstanceEventBus) → None, call:User, call:uuid.uuid4, call:db_session.add, call:db_session.commit, call:Project, call:GitRepository, call:ToolType, call:db_session.add_all, call:ToolInstance, call:publish_lifecycle_event, call:db_session.execute, call:select(Notification).where, call:result.scalar_one, func:test_lifecycle_error_creates_error_notification(db_session: AsyncSession, event_bus: InstanceEventBus, test_instance: ToolInstance) → None, call:publish_lifecycle_event, call:db_session.execute, call:select(Notification).where, call:result.scalar_one, func:test_health_monitor_unhealthy_creates_warning_notification(db_session: AsyncSession, event_bus: InstanceEventBus, test_instance: ToolInstance) → None, call:HealthMonitor, call:HealthSnapshot, call:patch, call:monitor._check_instance, call:db_session.execute, call:select(Notification).where, call:result.scalar_one | dep: uuid, collections.abc, unittest.mock, pytest, pytest_asyncio, sqlalchemy, sqlalchemy.ext.asyncio, src.models.project.git_repository, src.models.system.notification, src.models.project.project, src.models.tool.tool_instance, src.models.tool.tool_type, src.models.user.user, src.services.instance.event_bus, src.services.instance.health_monitor, src.services.instance.lifecycle_hooks
- test_projects_api.py | Integration tests for a FastAPI projects API endpoint, verifying authentication, CRUD operations, and ownership-based authorization against a real PostgreSQL database. | exp: func:_postgres_available() → bool, call:asyncpg.connect, call:conn.close, call:asyncio.run, call:_check, func:_check() → bool, call:asyncpg.connect, call:conn.close, func:_prepare_test_db() → None, call:create_async_engine, call:build_database_url, call:engine.begin, call:connection.run_sync, call:connection.execute, call:text, call:engine.dispose, call:asyncio.run, call:_run, func:_run() → None, call:create_async_engine, call:build_database_url, call:engine.begin, call:connection.run_sync, call:connection.execute, call:text, call:engine.dispose, func:_load_app(), call:hasattr, call:asyncio.run, call:database_module.engine.dispose, call:importlib.reload, func:_mint_token(user_id: str) → str, call:Settings, call:create_session_cookie, func:_insert_user(user_id: str, email) → None, call:create_async_engine, call:build_database_url, call:engine.begin, call:connection.run_sync, call:async_sessionmaker, call:session_factory, call:User, call:uuid.UUID, call:session.merge, call:session.commit, call:engine.dispose, call:asyncio.run, call:_run, func:_run() → None, call:create_async_engine, call:build_database_url, call:engine.begin, call:connection.run_sync, call:async_sessionmaker, call:session_factory, call:User, call:uuid.UUID, call:session.merge, call:session.commit, call:engine.dispose, func:_insert_project(project_id: str, owner_id: str, name) → None, call:create_async_engine, call:build_database_url, call:async_sessionmaker, call:session_factory, call:Project, call:uuid.UUID, call:session.merge, call:session.commit, call:engine.dispose, call:asyncio.run, call:_run, func:_run() → None, call:create_async_engine, call:build_database_url, call:async_sessionmaker, call:session_factory, call:Project, call:uuid.UUID, call:session.merge, call:session.commit, call:engine.dispose, func:test_create_project_requires_authentication() → None, call:_prepare_test_db, call:_load_app, call:TestClient, call:client.post, func:test_create_project_successfully() → None, call:_prepare_test_db, call:_insert_user, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.post, call:response.json, func:test_list_projects_returns_only_owned_projects() → None, call:_prepare_test_db, call:_insert_user, call:_insert_project, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.get, call:response.json, call:len, func:test_update_project_requires_ownership() → None, call:_prepare_test_db, call:_insert_user, call:_insert_project, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.patch, func:test_update_project_successfully() → None, call:_prepare_test_db, call:_insert_user, call:_insert_project, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.patch, call:response.json, func:test_delete_project_requires_ownership() → None, call:_prepare_test_db, call:_insert_user, call:_insert_project, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.delete, func:test_delete_project_successfully() → None, call:_prepare_test_db, call:_insert_user, call:_insert_project, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.delete, func:test_set_default_ssh_key_requires_ownership() → None, call:_prepare_test_db, call:_insert_user, call:_insert_project, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.patch | dep: uuid, datetime, asyncio, pytest, fastapi.testclient, sqlalchemy, sqlalchemy.ext.asyncio, src.auth.session, src.config, src.models, src.models.project.project, src.models.user.user, asyncpg, importlib, fastapi, src.database, src.api.user.auth, src.api.project.projects, src.main
- test_seed.py | Tests deterministic seed user generation and database seeding functionality for development environments. | exp: func:test_build_seed_user_returns_deterministic_payload() → None, call:build_seed_user, func:test_seed_database_creates_development_user(db_session: AsyncSession) → None, call:seed_database, call:db_session.scalar, call:select(User).where | dep: pytest, sqlalchemy, sqlalchemy.ext.asyncio, src.models.user, src.scripts.seed
- test_ssh_keys_api.py | Integration tests verifying SSH key API endpoints require authentication | exp: func:test_create_ssh_key_requires_authentication(test_client: TestClient) → None, call:test_client.post, func:test_list_ssh_keys_requires_authentication(test_client: TestClient) → None, call:test_client.get | dep: pytest, fastapi.testclient
- test_tool_instance_lifecycle.py | Integration test placeholder for verifying Docker availability and container home directory lifecycle behavior | exp: func:_docker_available() → bool, call:subprocess.run, func:test_docker_available_placeholder() → None, call:_docker_available | dep: subprocess, pytest
- test_tool_types_api.py | Integration tests for a FastAPI tool types REST API endpoint using a real PostgreSQL database. | exp: func:_postgres_available() → bool, call:asyncpg.connect, call:conn.close, call:asyncio.run, call:_check, func:_check() → bool, call:asyncpg.connect, call:conn.close, func:_prepare_test_db() → None, call:create_async_engine, call:build_database_url, call:engine.begin, call:connection.run_sync, call:connection.execute, call:text, call:engine.dispose, call:asyncio.run, call:_run, func:_run() → None, call:create_async_engine, call:build_database_url, call:engine.begin, call:connection.run_sync, call:connection.execute, call:text, call:engine.dispose, func:_load_app(), call:hasattr, call:asyncio.run, call:database_module.engine.dispose, call:importlib.reload, func:_mint_token(user_id: str) → str, call:Settings, call:create_session_cookie, call:datetime.now, call:timedelta, func:_insert_user(user_id: str, email) → None, call:create_async_engine, call:build_database_url, call:engine.begin, call:connection.run_sync, call:async_sessionmaker, call:session_factory, call:User, call:uuid.UUID, call:session.merge, call:session.commit, call:engine.dispose, call:asyncio.run, call:_run, func:_run() → None, call:create_async_engine, call:build_database_url, call:engine.begin, call:connection.run_sync, call:async_sessionmaker, call:session_factory, call:User, call:uuid.UUID, call:session.merge, call:session.commit, call:engine.dispose, func:_insert_tool_type(tool_type_id: str, name: str, display_name: str, compose_template: str, created_by_id) → None, call:create_async_engine, call:build_database_url, call:async_sessionmaker, call:session_factory, call:ToolType, call:uuid.UUID, call:session.merge, call:session.commit, call:engine.dispose, call:asyncio.run, call:_run, func:_run() → None, call:create_async_engine, call:build_database_url, call:async_sessionmaker, call:session_factory, call:ToolType, call:uuid.UUID, call:session.merge, call:session.commit, call:engine.dispose, func:test_list_tool_types_requires_authentication() → None, call:_prepare_test_db, call:_load_app, call:TestClient, call:client.get, func:test_list_tool_types_returns_all_types() → None, call:_prepare_test_db, call:_insert_user, call:_insert_tool_type, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.get, call:response.json, call:len, call:next, func:test_get_tool_type_by_id() → None, call:_prepare_test_db, call:_insert_user, call:_insert_tool_type, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.get, call:response.json, func:test_get_tool_type_not_found() → None, call:_prepare_test_db, call:_insert_user, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.get, func:test_create_tool_type_successfully() → None, call:_prepare_test_db, call:_insert_user, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.post, call:response.json, func:test_create_tool_type_duplicate_name() → None, call:_prepare_test_db, call:_insert_user, call:_insert_tool_type, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.post, func:test_create_tool_type_invalid_yaml() → None, call:_prepare_test_db, call:_insert_user, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.post, func:test_create_tool_type_missing_services() → None, call:_prepare_test_db, call:_insert_user, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.post, func:test_create_tool_type_missing_required_variable() → None, call:_prepare_test_db, call:_insert_user, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.post, func:test_update_tool_type_successfully() → None, call:_prepare_test_db, call:_insert_user, call:_insert_tool_type, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.put, call:response.json, func:test_update_tool_type_not_found() → None, call:_prepare_test_db, call:_insert_user, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.put, func:test_delete_tool_type_successfully() → None, call:_prepare_test_db, call:_insert_user, call:_insert_tool_type, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.delete, call:client.get, func:test_delete_tool_type_not_found() → None, call:_prepare_test_db, call:_insert_user, call:_load_app, call:TestClient, call:client.cookies.set, call:_mint_token, call:client.delete | dep: uuid, datetime, asyncio, pytest, fastapi.testclient, sqlalchemy, sqlalchemy.ext.asyncio, src.auth.session, src.config, src.models, src.models.tool.tool_type, src.models.user.user, asyncpg, importlib, fastapi
- test_tool_types_api_extended.py | Integration tests for a FastAPI tool types API endpoint covering CRUD operations with extended fields like dockerfile templates, readiness probes, startup commands, and validation. | exp: class:TestToolTypesAPIExtended, method:test_create_tool_type_with_dockerfile(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:response.json, method:test_create_tool_type_with_readiness_probe(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:response.json, method:test_create_tool_type_invalid_definition_type(self, authenticated_client: TestClient) → None, call:authenticated_client.post, method:test_create_tool_type_dockerfile_without_template(self, authenticated_client: TestClient) → None, call:authenticated_client.post, method:test_update_tool_type_with_new_fields(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:create_response.json, call:authenticated_client.put, call:response.json, method:test_validate_tool_type_compose(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:response.json, method:test_validate_tool_type_invalid_compose(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:response.json, method:test_validate_tool_type_dockerfile(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:response.json, method:test_get_tool_type_returns_new_fields(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:create_response.json, call:authenticated_client.get, call:response.json, method:test_create_tool_type_without_port_fails(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:response.json, call:str, method:test_create_tool_type_with_port_mismatch_fails(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:response.json, method:test_create_tool_type_with_startup_command(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:response.json, method:test_update_tool_type_startup_command(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:create_response.json, call:authenticated_client.put, call:response.json, method:test_get_tool_type_returns_startup_command(self, authenticated_client: TestClient) → None, call:authenticated_client.post, call:create_response.json, call:authenticated_client.get, call:response.json | dep: pytest, fastapi.testclient, fastapi.testclient.TestClient
- test_users_api.py | Integration tests for user profile API endpoints using a real PostgreSQL database | exp: func:_postgres_available() → bool, call:asyncpg.connect, call:conn.close, call:asyncio.run, call:_check, func:_check() → bool, call:asyncpg.connect, call:conn.close, func:_prepare_users_test_db() → None, call:create_async_engine, call:build_database_url, call:engine.begin, call:connection.run_sync, call:connection.execute, call:text, call:engine.dispose, call:asyncio.run, call:_run, func:_run() → None, call:create_async_engine, call:build_database_url, call:engine.begin, call:connection.run_sync, call:connection.execute, call:text, call:engine.dispose, func:_load_app(), call:importlib.reload, func:_insert_test_user(user_id: str) → None, call:create_async_engine, call:build_database_url, call:engine.begin, call:connection.run_sync, call:async_sessionmaker, call:session_factory, call:User, call:uuid.UUID, call:session.merge, call:session.commit, call:engine.dispose, call:asyncio.run, call:_run, func:_run() → None, call:create_async_engine, call:build_database_url, call:engine.begin, call:connection.run_sync, call:async_sessionmaker, call:session_factory, call:User, call:uuid.UUID, call:session.merge, call:session.commit, call:engine.dispose, func:_create_auth_cookie(user_id: str) → str, call:Settings, call:create_session_cookie, func:test_get_profile_returns_401_without_cookie() → None, call:_prepare_users_test_db, call:_load_app, call:TestClient, call:client.get, func:test_get_profile_returns_user_data() → None, call:_prepare_users_test_db, call:_insert_test_user, call:_load_app, call:TestClient, call:client.cookies.set, call:_create_auth_cookie, call:client.get, call:response.json, func:test_update_profile_changes_name_and_email() → None, call:_prepare_users_test_db, call:_insert_test_user, call:_load_app, call:TestClient, call:client.cookies.set, call:_create_auth_cookie, call:client.put, call:response.json, func:test_update_profile_rejects_empty_name() → None, call:_prepare_users_test_db, call:_insert_test_user, call:_load_app, call:TestClient, call:client.cookies.set, call:_create_auth_cookie, call:client.put, func:test_update_profile_rejects_invalid_email() → None, call:_prepare_users_test_db, call:_insert_test_user, call:_load_app, call:TestClient, call:client.cookies.set, call:_create_auth_cookie, call:client.put, func:test_upload_avatar_updates_avatar_url() → None, call:_prepare_users_test_db, call:_insert_test_user, call:_load_app, call:TestClient, call:client.cookies.set, call:_create_auth_cookie, call:client.post, call:io.BytesIO, call:response.json, call:data["avatar_url"].startswith, func:test_upload_avatar_rejects_invalid_file_type() → None, call:_prepare_users_test_db, call:_insert_test_user, call:_load_app, call:TestClient, call:client.cookies.set, call:_create_auth_cookie, call:client.post, call:io.BytesIO, func:test_upload_avatar_rejects_oversized_file() → None, call:_prepare_users_test_db, call:_insert_test_user, call:_load_app, call:TestClient, call:client.cookies.set, call:_create_auth_cookie, call:client.post, call:io.BytesIO | dep: uuid, datetime, asyncio, io, fastapi.testclient, pytest, sqlalchemy, sqlalchemy.ext.asyncio, src.auth.session, src.config, src.models, src.models.user.user, asyncpg, importlib, fastapi, src.database, src.api.user.users, src.main
- test_workspace_files.py | Integration tests for FastAPI endpoints that manage workspace file operations (list, read, write) | exp: class:TestListWorkspaceFiles, method:test_list_files(self, authenticated_client: TestClient, test_repo_with_workspace: Workspace), call:os.makedirs, call:os.path.join, call:open, call:f.write, call:authenticated_client.get, call:response.json, method:test_list_files_path_escapes_workspace(self, authenticated_client: TestClient, test_repo_with_workspace: Workspace), call:authenticated_client.get, class:TestGetFileContent, method:test_get_content(self, authenticated_client: TestClient, test_repo_with_workspace: Workspace), call:open, call:os.path.join, call:f.write, call:authenticated_client.get, call:response.json, method:test_get_missing_file(self, authenticated_client: TestClient, test_repo_with_workspace: Workspace), call:authenticated_client.get, class:TestWriteFileContent, method:test_write_file(self, authenticated_client: TestClient, test_repo_with_workspace: Workspace), call:authenticated_client.post, call:os.path.exists, call:os.path.join, method:test_write_file_missing_path(self, authenticated_client: TestClient, test_repo_with_workspace: Workspace), call:authenticated_client.post, func:_get_user_id(client: TestClient) → uuid.UUID, call:Settings, call:client.cookies.get, call:decode_session_cookie, call:uuid.UUID, raise:RuntimeError, func:test_repo_with_workspace(db_session: AsyncSession, authenticated_client: TestClient), call:_get_user_id, call:Project, call:db_session.add, call:db_session.flush, call:GitRepository, call:tempfile.mkdtemp, call:Workspace, call:db_session.commit, call:db_session.refresh, call:asyncio.run, call:_create, func:_create(), call:Project, call:db_session.add, call:db_session.flush, call:GitRepository, call:tempfile.mkdtemp, call:Workspace, call:db_session.commit, call:db_session.refresh | dep: asyncio, os, tempfile, uuid, unittest.mock, pytest, fastapi.testclient, sqlalchemy.ext.asyncio, src.models, src.services.shared.workspace_manager, src.auth.session, src.config, fastapi, sqlalchemy
- test_workspace_git.py | Integration tests for FastAPI workspace git endpoints (status, commit, history, checkout) using real git repositories. | exp: class:TestGitStatus, method:test_status_clean(self, authenticated_client: TestClient, test_repo_with_git_workspace: Workspace), call:authenticated_client.get, call:response.json, method:test_status_modified(self, authenticated_client: TestClient, test_repo_with_git_workspace: Workspace), call:open, call:os.path.join, call:f.write, call:authenticated_client.get, call:response.json, class:TestGitCommit, method:test_commit(self, authenticated_client: TestClient, test_repo_with_git_workspace: Workspace), call:open, call:os.path.join, call:f.write, call:authenticated_client.post, call:response.json, method:test_commit_missing_message(self, authenticated_client: TestClient, test_repo_with_git_workspace: Workspace), call:authenticated_client.post, class:TestGitHistory, method:test_history(self, authenticated_client: TestClient, test_repo_with_git_workspace: Workspace), call:authenticated_client.get, call:response.json, call:len, class:TestGitCheckout, method:test_checkout(self, authenticated_client: TestClient, test_repo_with_git_workspace: Workspace), call:_run_git, call:authenticated_client.post, call:response.json, func:_run_git(*args: str, cwd: str) → None, call:subprocess.run, func:_get_user_id(client: TestClient) → uuid.UUID, call:Settings, call:client.cookies.get, call:decode_session_cookie, call:uuid.UUID, raise:RuntimeError, func:test_repo_with_git_workspace(db_session: AsyncSession, authenticated_client: TestClient), call:_get_user_id, call:Project, call:db_session.add, call:db_session.flush, call:GitRepository, call:tempfile.mkdtemp, call:_run_git, call:open, call:os.path.join, call:f.write, call:Workspace, call:db_session.commit, call:db_session.refresh, call:asyncio.run, call:_create, func:_create(), call:Project, call:db_session.add, call:db_session.flush, call:GitRepository, call:tempfile.mkdtemp, call:_run_git, call:open, call:os.path.join, call:f.write, call:Workspace, call:db_session.commit, call:db_session.refresh | dep: asyncio, os, subprocess, tempfile, uuid, pytest, fastapi.testclient, sqlalchemy.ext.asyncio, src.models, src.auth.session, src.config, fastapi, sqlalchemy
- test_workspace_instances.py | Integration tests for FastAPI workspace instance endpoints (list and create) using an authenticated test client and mocked database fixtures. | exp: class:TestListWorkspaceInstances, method:test_list_empty(self, authenticated_client: TestClient, test_workspace_with_tool_type), call:authenticated_client.get, call:response.json, method:test_list_instances(self, authenticated_client: TestClient, db_session: AsyncSession, test_workspace_with_tool_type), call:ToolInstance, call:db_session.add, call:db_session.commit, call:asyncio.run, call:_create_instance, call:authenticated_client.get, call:response.json, call:len, class:TestCreateWorkspaceInstance, method:test_create_instance(self, authenticated_client: TestClient, test_workspace_with_tool_type), call:ToolInstance, call:uuid.uuid4, call:datetime.now, call:patch, call:authenticated_client.post, call:str, call:response.json, func:_get_user_id(client: TestClient) → uuid.UUID, call:Settings, call:client.cookies.get, call:decode_session_cookie, call:uuid.UUID, raise:RuntimeError, func:test_workspace_with_tool_type(db_session: AsyncSession, authenticated_client: TestClient), call:_get_user_id, call:Project, call:db_session.add, call:db_session.flush, call:GitRepository, call:tempfile.mkdtemp, call:Workspace, call:ToolType, call:db_session.commit, call:db_session.refresh, call:asyncio.run, call:_create, func:_create(), call:Project, call:db_session.add, call:db_session.flush, call:GitRepository, call:tempfile.mkdtemp, call:Workspace, call:ToolType, call:db_session.commit, call:db_session.refresh | dep: asyncio, tempfile, uuid, datetime, unittest.mock, pytest, fastapi.testclient, sqlalchemy.ext.asyncio, src.models, src.auth.session, src.config, src.api.workspace.workspace_instances
- test_workspaces_api.py | Integration tests for workspace API endpoints including list, create, delete, and sync operations with repository/project scoping | exp: class:TestListWorkspaces, method:test_list_empty(self, authenticated_client: TestClient, test_repo: GitRepository), call:authenticated_client.get, call:response.json, method:test_list_with_workspaces(self, authenticated_client: TestClient, db_session: AsyncSession, test_repo: GitRepository), call:Workspace, call:db_session.add, call:db_session.commit, call:asyncio.run, call:_commit, call:authenticated_client.get, call:response.json, call:len, class:TestCreateWorkspace, method:test_create_success(self, authenticated_client: TestClient, test_repo: GitRepository), call:Workspace, call:uuid.uuid4, call:patch.object, call:authenticated_client.post, call:response.json, call:mock_create.assert_called_once, method:test_create_missing_name(self, authenticated_client: TestClient, test_repo: GitRepository), call:authenticated_client.post, call:response.json, method:test_create_duplicate_name(self, authenticated_client: TestClient, db_session: AsyncSession, test_repo: GitRepository), call:Workspace, call:db_session.add, call:db_session.commit, call:asyncio.run, call:_commit, call:patch.object, call:Exception, call:authenticated_client.post, class:TestDeleteWorkspace, method:test_delete_without_instances(self, authenticated_client: TestClient, db_session: AsyncSession, test_repo: GitRepository), call:Workspace, call:db_session.add, call:db_session.commit, call:db_session.refresh, call:asyncio.run, call:_commit_refresh, call:patch.object, call:authenticated_client.delete, call:response.json, method:test_delete_with_instances_force(self, authenticated_client: TestClient, db_session: AsyncSession, test_repo: GitRepository), call:Workspace, call:db_session.add, call:db_session.commit, call:db_session.refresh, call:asyncio.run, call:_commit_refresh, call:patch.object, call:authenticated_client.delete, class:TestSyncWorkspace, method:test_sync_success(self, authenticated_client: TestClient, db_session: AsyncSession, test_repo: GitRepository), call:Workspace, call:db_session.add, call:db_session.commit, call:db_session.refresh, call:asyncio.run, call:_commit_refresh, call:patch.object, call:MagicMock, call:authenticated_client.post, call:response.json, method:test_sync_branch_deleted(self, authenticated_client: TestClient, db_session: AsyncSession, test_repo: GitRepository), call:Workspace, call:db_session.add, call:db_session.commit, call:db_session.refresh, call:asyncio.run, call:_commit_refresh, call:patch.object, call:MagicMock, call:authenticated_client.post, call:response.json, func:_get_user_id_from_client(client: TestClient) → uuid.UUID, call:Settings, call:client.cookies.get, call:decode_session_cookie, call:uuid.UUID, raise:RuntimeError, func:test_repo(db_session: AsyncSession, authenticated_client: TestClient), call:_get_user_id_from_client, call:Project, call:db_session.add, call:db_session.flush, call:GitRepository, call:db_session.commit, call:db_session.refresh, call:asyncio.run, call:_create, func:_create(), call:Project, call:db_session.add, call:db_session.flush, call:GitRepository, call:db_session.commit, call:db_session.refresh | dep: asyncio, uuid, unittest.mock, pytest, fastapi.testclient, sqlalchemy.ext.asyncio, src.models, src.services.shared.workspace_manager, src.auth.session, src.config, fastapi, sqlalchemy
## arch
Pytest-based integration testing with FastAPI TestClient, SQLAlchemy async sessions, real PostgreSQL database fixtures, and selective mocking; follows pattern of endpoint-per-test-file with authenticated client fixtures and seeded database state.
## tags
test, call:, call:db, call:authenticated, user, create, call:response.json, call:create
## symbols
- TestConfigProfilesAPI
- TestGitStatus
- TestBranchOperations
- TestCommit
- TestToolTypesAPIExtended
- TestListWorkspaceFiles
- TestGetFileContent
- TestWriteFileContent
## workflows
- change integration behavior
  read: __init__.py, test_auth_api.py, test_auth_services.py
- change integration config
  read: test_config_profiles_api.py
## dirty
-
