本次提交修复了多个测试文件中的问题: 1. 将 ChannelType 枚举调用改为字符串实例化方式 2. 修正了日志断言、异步mock使用、配置参数等多处测试细节 3. 新增了会话聚合根、跨渠道关联策略等单元测试用例 4. 修复了路由测试中的路径方法错误与断言逻辑 5. 调整了依赖导入与测试夹具的兼容性 6. 统一了重试回退调度的列表/元组使用规范
99 lines
88 KiB
XML
99 lines
88 KiB
XML
<?xml version="1.0" encoding="utf-8"?><testsuites name="pytest tests"><testsuite name="pytest" errors="0" failures="25" skipped="0" tests="340" time="20.138" timestamp="2026-07-03T22:50:08.974491+08:00" hostname="78e9018dc77e"><testcase classname="test.integration.api.channels.test_account_router" name="test_list_accounts_requires_auth" time="1.358" /><testcase classname="test.integration.api.channels.test_account_router" name="test_list_accounts_forbids_standard_user" time="0.207" /><testcase classname="test.integration.api.channels.test_account_router" name="test_admin_can_list_accounts" time="0.044"><failure message="AssertionError: assert 'items' in {'accounts': []}">test/integration/api/channels/test_account_router.py:55: in test_admin_can_list_accounts
|
|
assert "items" in payload["data"]
|
|
E AssertionError: assert 'items' in {'accounts': []}</failure></testcase><testcase classname="test.integration.api.channels.test_account_router" name="test_list_accounts_rejects_limit_zero" time="0.016" /><testcase classname="test.integration.api.channels.test_account_router" name="test_list_accounts_rejects_limit_over_max" time="0.014" /><testcase classname="test.integration.api.channels.test_account_router" name="test_batch_enable_accounts_requires_auth" time="0.015" /><testcase classname="test.integration.api.channels.test_account_router" name="test_batch_enable_accounts_forbids_standard_user" time="0.170" /><testcase classname="test.integration.api.channels.test_account_router" name="test_batch_enable_accounts_rejects_empty_body" time="0.036" /><testcase classname="test.integration.api.channels.test_account_router" name="test_batch_disable_accounts_rejects_empty_body" time="0.018" /><testcase classname="test.integration.api.channels.test_account_router" name="test_create_account_requires_auth" time="0.016" /><testcase classname="test.integration.api.channels.test_account_router" name="test_create_account_forbids_standard_user" time="0.153" /><testcase classname="test.integration.api.channels.test_account_router" name="test_create_account_invalid_channel_type_returns_422" time="0.025" /><testcase classname="test.integration.api.channels.test_account_router" name="test_create_account_with_invalid_body_returns_not_4xx" time="0.014" /><testcase classname="test.integration.api.channels.test_account_router" name="test_get_account_non_existent_returns_404" time="0.030" /><testcase classname="test.integration.api.channels.test_account_router" name="test_update_account_non_existent_returns_404" time="0.033" /><testcase classname="test.integration.api.channels.test_account_router" name="test_update_account_rejects_empty_body" time="0.019" /><testcase classname="test.integration.api.channels.test_account_router" name="test_delete_account_non_existent_returns_404" time="0.032" /><testcase classname="test.integration.api.channels.test_account_router" name="test_enable_account_non_existent_returns_404" time="0.028" /><testcase classname="test.integration.api.channels.test_account_router" name="test_disable_account_non_existent_returns_404" time="0.033" /><testcase classname="test.integration.api.channels.test_account_router" name="test_recover_account_non_existent_returns_404" time="0.030" /><testcase classname="test.integration.api.channels.test_account_router" name="test_get_runtime_status_non_existent_returns_404" time="0.031" /><testcase classname="test.integration.api.channels.test_account_router" name="test_rotate_credentials_non_existent_returns_404" time="0.031" /><testcase classname="test.integration.api.channels.test_account_router" name="test_test_connection_non_existent_returns_404" time="0.030" /><testcase classname="test.integration.api.channels.test_account_router" name="test_export_account_non_existent_returns_404" time="0.032" /><testcase classname="test.integration.api.channels.test_account_router" name="test_export_account_with_secrets_non_existent_returns_404" time="0.027" /><testcase classname="test.integration.api.channels.test_account_router" name="test_clone_account_non_existent_returns_404" time="0.034" /><testcase classname="test.integration.api.channels.test_account_router" name="test_clone_account_rejects_invalid_body" time="0.015" /><testcase classname="test.integration.api.channels.test_allowlist_router" name="test_list_whitelist_requires_auth" time="0.025" /><testcase classname="test.integration.api.channels.test_allowlist_router" name="test_list_whitelist_requires_admin" time="0.162" /><testcase classname="test.integration.api.channels.test_allowlist_router" name="test_admin_list_whitelist_returns_404_for_non_existent_account" time="0.099" /><testcase classname="test.integration.api.channels.test_allowlist_router" name="test_list_whitelist_rejects_invalid_policy_type" time="0.019" /><testcase classname="test.integration.api.channels.test_allowlist_router" name="test_add_whitelist_rejects_invalid_expires_at" time="0.017" /><testcase classname="test.integration.api.channels.test_allowlist_router" name="test_batch_add_whitelist_rejects_empty_items" time="0.019" /><testcase classname="test.integration.api.channels.test_allowlist_router" name="test_batch_add_whitelist_rejects_too_many_items" time="0.019" /><testcase classname="test.integration.api.channels.test_allowlist_router" name="test_export_whitelist_rejects_invalid_format" time="0.019" /><testcase classname="test.integration.api.channels.test_allowlist_router" name="test_batch_delete_whitelist_rejects_empty_peer_ids" time="0.018" /><testcase classname="test.integration.api.channels.test_allowlist_router" name="test_clean_expired_whitelist_rejects_zero_max_count" time="0.018" /><testcase classname="test.integration.api.channels.test_allowlist_router" name="test_clean_expired_whitelist_rejects_max_count_over_limit" time="0.014" /><testcase classname="test.integration.api.channels.test_allowlist_router" name="test_update_whitelist_returns_404_for_non_existent_peer" time="0.027" /><testcase classname="test.integration.api.channels.test_allowlist_router" name="test_delete_whitelist_returns_404_for_non_existent_peer" time="0.031" /><testcase classname="test.integration.api.channels.test_allowlist_router" name="test_batch_static_path_not_captured_as_policy_type" time="0.027" /><testcase classname="test.integration.api.channels.test_analytics_router" name="test_analyze_messages_requires_auth" time="0.026" /><testcase classname="test.integration.api.channels.test_analytics_router" name="test_analyze_messages_requires_admin" time="0.157" /><testcase classname="test.integration.api.channels.test_analytics_router" name="test_admin_can_analyze_messages" time="0.055" /><testcase classname="test.integration.api.channels.test_analytics_router" name="test_analyze_messages_rejects_missing_start_time" time="0.014" /><testcase classname="test.integration.api.channels.test_analytics_router" name="test_analyze_messages_rejects_missing_end_time" time="0.013" /><testcase classname="test.integration.api.channels.test_analytics_router" name="test_admin_can_get_message_distribution" time="0.029" /><testcase classname="test.integration.api.channels.test_analytics_router" name="test_admin_can_analyze_sessions" time="0.051" /><testcase classname="test.integration.api.channels.test_analytics_router" name="test_admin_can_analyze_delivery" time="0.042" /><testcase classname="test.integration.api.channels.test_analytics_router" name="test_admin_can_get_delivery_latency" time="0.034" /><testcase classname="test.integration.api.channels.test_analytics_router" name="test_admin_can_get_delivery_funnel" time="0.030" /><testcase classname="test.integration.api.channels.test_analytics_router" name="test_admin_can_analyze_accounts" time="0.040" /><testcase classname="test.integration.api.channels.test_analytics_router" name="test_admin_can_analyze_peers" time="0.032" /><testcase classname="test.integration.api.channels.test_analytics_router" name="test_admin_can_analyze_content_review" time="0.043"><failure message="AssertionError: {"success":false,"error":{"code":"DEPENDENCY","message":"Dependency content_review_repository failed","trace_id":"5d6327ac537b4b18a27697a1ccd92042","details":{"cause":{"error_code":"ERROR","message":"(sqlalchemy.dialects.postgresql.asyncpg.ProgrammingError) <class 'asyncpg.exceptions.UndefinedFunctionError'>: function json_array_elements_text(jsonb) does not exist\nHINT: No function matches the given name and argument types. You might need to add explicit type casts.\n[SQL: SELECT json_array_elements_text(channel_content_review_records.categories) AS category, count(channel_content_review_records.id) AS count \nFROM channel_content_review_records \nWHERE channel_content_review_records.reviewed_at >= $1::TIMESTAMP WITHOUT TIME ZONE AND channel_content_review_records.reviewed_at < $2::TIMESTAMP WITHOUT TIME ZONE AND channel_content_review_records.is_deleted = $3::INTEGER GROUP BY json_array_elements_text(channel_content_review_records.categories)]\n[parameters: (datetime.datetime(2026, 1, 1, 0, 0), datetime.datetime(2026, 7, 1, 0, 0), 0)]\n(Background on this error at: https://sqlalche.me/e/20/f405)","trace_id":""},"dep":"content_review_repository"}}} assert 502 == 200 + where 502 = <Response [502 Bad Gateway]>.status_code">test/integration/api/channels/test_analytics_router.py:213: in test_admin_can_analyze_content_review
|
|
assert response.status_code == 200, response.text
|
|
E AssertionError: {"success":false,"error":{"code":"DEPENDENCY","message":"Dependency content_review_repository failed","trace_id":"5d6327ac537b4b18a27697a1ccd92042","details":{"cause":{"error_code":"ERROR","message":"(sqlalchemy.dialects.postgresql.asyncpg.ProgrammingError) <class 'asyncpg.exceptions.UndefinedFunctionError'>: function json_array_elements_text(jsonb) does not exist\nHINT: No function matches the given name and argument types. You might need to add explicit type casts.\n[SQL: SELECT json_array_elements_text(channel_content_review_records.categories) AS category, count(channel_content_review_records.id) AS count \nFROM channel_content_review_records \nWHERE channel_content_review_records.reviewed_at >= $1::TIMESTAMP WITHOUT TIME ZONE AND channel_content_review_records.reviewed_at < $2::TIMESTAMP WITHOUT TIME ZONE AND channel_content_review_records.is_deleted = $3::INTEGER GROUP BY json_array_elements_text(channel_content_review_records.categories)]\n[parameters: (datetime.datetime(2026, 1, 1, 0, 0), datetime.datetime(2026, 7, 1, 0, 0), 0)]\n(Background on this error at: https://sqlalche.me/e/20/f405)","trace_id":""},"dep":"content_review_repository"}}}
|
|
E assert 502 == 200
|
|
E + where 502 = <Response [502 Bad Gateway]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_analytics_router" name="test_admin_can_analyze_messages_with_channel_type" time="0.031" /><testcase classname="test.integration.api.channels.test_analytics_router" name="test_analyze_peers_rejects_limit_zero" time="0.015" /><testcase classname="test.integration.api.channels.test_analytics_router" name="test_analyze_peers_rejects_limit_over_max" time="0.014" /><testcase classname="test.integration.api.channels.test_audit_router" name="test_query_audit_logs_requires_auth" time="0.028" /><testcase classname="test.integration.api.channels.test_audit_router" name="test_query_audit_logs_requires_admin" time="0.153" /><testcase classname="test.integration.api.channels.test_audit_router" name="test_admin_can_query_audit_logs" time="0.022"><failure message="AssertionError: {"success":false,"error":{"code":"DEPENDENCY","message":"Dependency audit_log failed","trace_id":"31e4478671814002893457c6b2aea5bb","details":{"cause":{"error_code":"ERROR","message":"invalid enum value for AuditOperationType: 'whitelist_batch_added'","trace_id":""},"dep":"audit_log"}}} assert 502 == 200 + where 502 = <Response [502 Bad Gateway]>.status_code">test/integration/api/channels/test_audit_router.py:44: in test_admin_can_query_audit_logs
|
|
assert response.status_code == 200, response.text
|
|
E AssertionError: {"success":false,"error":{"code":"DEPENDENCY","message":"Dependency audit_log failed","trace_id":"31e4478671814002893457c6b2aea5bb","details":{"cause":{"error_code":"ERROR","message":"invalid enum value for AuditOperationType: 'whitelist_batch_added'","trace_id":""},"dep":"audit_log"}}}
|
|
E assert 502 == 200
|
|
E + where 502 = <Response [502 Bad Gateway]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_audit_router" name="test_query_audit_logs_rejects_limit_zero" time="0.014" /><testcase classname="test.integration.api.channels.test_audit_router" name="test_query_audit_logs_rejects_limit_over_max" time="0.014" /><testcase classname="test.integration.api.channels.test_audit_router" name="test_query_audit_logs_rejects_negative_offset" time="0.014" /><testcase classname="test.integration.api.channels.test_audit_router" name="test_admin_can_get_audit_log_stats" time="0.035" /><testcase classname="test.integration.api.channels.test_audit_router" name="test_admin_can_list_audit_operations" time="0.030" /><testcase classname="test.integration.api.channels.test_audit_router" name="test_admin_can_export_audit_logs" time="0.058"><failure message="AssertionError: {"success":false,"error":{"code":"DEPENDENCY","message":"Dependency audit_log failed","trace_id":"b2d12135439842b3a1830e7ebd4e58d3","details":{"cause":{"error_code":"ERROR","message":"invalid enum value for AuditOperationType: 'whitelist_batch_added'","trace_id":""},"dep":"audit_log"}}} assert 502 == 200 + where 502 = <Response [502 Bad Gateway]>.status_code">test/integration/api/channels/test_audit_router.py:128: in test_admin_can_export_audit_logs
|
|
assert response.status_code == 200, response.text
|
|
E AssertionError: {"success":false,"error":{"code":"DEPENDENCY","message":"Dependency audit_log failed","trace_id":"b2d12135439842b3a1830e7ebd4e58d3","details":{"cause":{"error_code":"ERROR","message":"invalid enum value for AuditOperationType: 'whitelist_batch_added'","trace_id":""},"dep":"audit_log"}}}
|
|
E assert 502 == 200
|
|
E + where 502 = <Response [502 Bad Gateway]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_audit_router" name="test_admin_can_get_retention_policy" time="0.031" /><testcase classname="test.integration.api.channels.test_audit_router" name="test_update_retention_policy_requires_auth" time="0.017" /><testcase classname="test.integration.api.channels.test_audit_router" name="test_update_retention_policy_rejects_standard_user" time="0.146" /><testcase classname="test.integration.api.channels.test_audit_router" name="test_superadmin_can_update_retention_policy" time="0.030"><failure message="AssertionError: {"success":false,"error":{"code":"INTERNAL","message":"control execution failed: This transaction is closed","trace_id":"5ea315ff6ce445a3ab4e9ec1b3e294c8","details":{"cause":{"type":"ResourceClosedError","message":"This transaction is closed"}}}} assert 500 == 200 + where 500 = <Response [500 Internal Server Error]>.status_code">test/integration/api/channels/test_audit_router.py:195: in test_superadmin_can_update_retention_policy
|
|
assert response.status_code == 200, response.text
|
|
E AssertionError: {"success":false,"error":{"code":"INTERNAL","message":"control execution failed: This transaction is closed","trace_id":"5ea315ff6ce445a3ab4e9ec1b3e294c8","details":{"cause":{"type":"ResourceClosedError","message":"This transaction is closed"}}}}
|
|
E assert 500 == 200
|
|
E + where 500 = <Response [500 Internal Server Error]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_audit_router" name="test_update_retention_policy_rejects_archive_before_ge_retention" time="0.015" /><testcase classname="test.integration.api.channels.test_audit_router" name="test_get_audit_log_returns_404_for_nonexistent" time="0.033" /><testcase classname="test.integration.api.channels.test_capability_router" name="test_list_capabilities_requires_auth" time="0.022" /><testcase classname="test.integration.api.channels.test_capability_router" name="test_list_capabilities_requires_admin" time="0.151" /><testcase classname="test.integration.api.channels.test_capability_router" name="test_admin_can_list_capabilities" time="0.024" /><testcase classname="test.integration.api.channels.test_capability_router" name="test_admin_can_get_capability_for_channel_type" time="0.026" /><testcase classname="test.integration.api.channels.test_capability_router" name="test_get_capability_unregistered_channel_type" time="0.024" /><testcase classname="test.integration.api.channels.test_config_router" name="test_get_config_schema_requires_auth" time="0.032" /><testcase classname="test.integration.api.channels.test_config_router" name="test_get_config_schema_requires_admin" time="0.145" /><testcase classname="test.integration.api.channels.test_config_router" name="test_admin_can_get_config_schema" time="0.026" /><testcase classname="test.integration.api.channels.test_config_router" name="test_export_config_requires_auth" time="0.016" /><testcase classname="test.integration.api.channels.test_config_router" name="test_export_config_requires_superadmin_for_standard_user" time="0.146" /><testcase classname="test.integration.api.channels.test_config_router" name="test_superadmin_can_export_config" time="0.036" /><testcase classname="test.integration.api.channels.test_config_router" name="test_import_config_requires_auth" time="0.016" /><testcase classname="test.integration.api.channels.test_config_router" name="test_import_config_rejects_standard_user" time="0.148" /><testcase classname="test.integration.api.channels.test_config_router" name="test_superadmin_can_import_config_dry_run" time="0.027"><failure message="AssertionError: {"success":false,"error":{"code":"INTERNAL","message":"control execution failed: This transaction is closed","trace_id":"d41a318f32a24e70a2c36a7cd8a185ae","details":{"cause":{"type":"ResourceClosedError","message":"This transaction is closed"}}}} assert 500 == 200 + where 500 = <Response [500 Internal Server Error]>.status_code">test/integration/api/channels/test_config_router.py:125: in test_superadmin_can_import_config_dry_run
|
|
assert response.status_code == 200, response.text
|
|
E AssertionError: {"success":false,"error":{"code":"INTERNAL","message":"control execution failed: This transaction is closed","trace_id":"d41a318f32a24e70a2c36a7cd8a185ae","details":{"cause":{"type":"ResourceClosedError","message":"This transaction is closed"}}}}
|
|
E assert 500 == 200
|
|
E + where 500 = <Response [500 Internal Server Error]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_config_router" name="test_batch_update_config_requires_auth" time="0.015" /><testcase classname="test.integration.api.channels.test_config_router" name="test_batch_update_config_requires_admin" time="0.145" /><testcase classname="test.integration.api.channels.test_config_router" name="test_batch_update_config_rejects_empty_updates" time="0.016" /><testcase classname="test.integration.api.channels.test_config_router" name="test_batch_update_config_rejects_too_many_updates" time="0.015" /><testcase classname="test.integration.api.channels.test_config_router" name="test_get_config_returns_404_for_non_existent_key" time="0.029"><failure message="AssertionError: {"success":true,"data":{"key":"nonexistent_config_key_0000","value":"new_value","version":3,"scope":"global"}} assert 200 == 404 + where 200 = <Response [200 OK]>.status_code">test/integration/api/channels/test_config_router.py:194: in test_get_config_returns_404_for_non_existent_key
|
|
assert response.status_code == 404, response.text
|
|
E AssertionError: {"success":true,"data":{"key":"nonexistent_config_key_0000","value":"new_value","version":3,"scope":"global"}}
|
|
E assert 200 == 404
|
|
E + where 200 = <Response [200 OK]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_config_router" name="test_update_config_returns_404_for_non_existent_key" time="0.031"><failure message="AssertionError: {"success":false,"error":{"code":"INTERNAL","message":"control execution failed: This transaction is closed","trace_id":"11abde4d53354420bcb61e3edbea7059","details":{"cause":{"type":"ResourceClosedError","message":"This transaction is closed"}}}} assert 500 == 404 + where 500 = <Response [500 Internal Server Error]>.status_code">test/integration/api/channels/test_config_router.py:212: in test_update_config_returns_404_for_non_existent_key
|
|
assert response.status_code == 404, response.text
|
|
E AssertionError: {"success":false,"error":{"code":"INTERNAL","message":"control execution failed: This transaction is closed","trace_id":"11abde4d53354420bcb61e3edbea7059","details":{"cause":{"type":"ResourceClosedError","message":"This transaction is closed"}}}}
|
|
E assert 500 == 404
|
|
E + where 500 = <Response [500 Internal Server Error]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_config_router" name="test_rollback_config_returns_404_for_non_existent_key" time="0.032"><failure message="AssertionError: {"success":false,"error":{"code":"INTERNAL","message":"control execution failed: This transaction is closed","trace_id":"dec0d28af30046f8bd501429aae361f9","details":{"cause":{"type":"ResourceClosedError","message":"This transaction is closed"}}}} assert 500 == 404 + where 500 = <Response [500 Internal Server Error]>.status_code">test/integration/api/channels/test_config_router.py:230: in test_rollback_config_returns_404_for_non_existent_key
|
|
assert response.status_code == 404, response.text
|
|
E AssertionError: {"success":false,"error":{"code":"INTERNAL","message":"control execution failed: This transaction is closed","trace_id":"dec0d28af30046f8bd501429aae361f9","details":{"cause":{"type":"ResourceClosedError","message":"This transaction is closed"}}}}
|
|
E assert 500 == 404
|
|
E + where 500 = <Response [500 Internal Server Error]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_config_router" name="test_rollback_config_rejects_zero_target_version" time="0.014" /><testcase classname="test.integration.api.channels.test_config_router" name="test_get_config_history_returns_404_for_non_existent_key" time="0.032"><failure message="AssertionError: {"success":true,"data":{"key":"nonexistent_config_key_0000","history":[{"version":4,"value":"new_value","updated_at":"2026-07-03T14:50:17.571806"},{"version":3,"value":"new_value","updated_at":"2026-07-03T14:25:40.143051"},{"version":2,"value":"new_value","updated_at":"2026-07-03T14:25:40.068399"},{"version":1,"value":"new_value","updated_at":"2026-07-03T13:10:24.965318"}]}} assert 200 == 404 + where 200 = <Response [200 OK]>.status_code">test/integration/api/channels/test_config_router.py:259: in test_get_config_history_returns_404_for_non_existent_key
|
|
assert response.status_code == 404, response.text
|
|
E AssertionError: {"success":true,"data":{"key":"nonexistent_config_key_0000","history":[{"version":4,"value":"new_value","updated_at":"2026-07-03T14:50:17.571806"},{"version":3,"value":"new_value","updated_at":"2026-07-03T14:25:40.143051"},{"version":2,"value":"new_value","updated_at":"2026-07-03T14:25:40.068399"},{"version":1,"value":"new_value","updated_at":"2026-07-03T13:10:24.965318"}]}}
|
|
E assert 200 == 404
|
|
E + where 200 = <Response [200 OK]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_config_router" name="test_schema_static_path_not_captured_as_key" time="0.024" /><testcase classname="test.integration.api.channels.test_content_review_router" name="test_preview_requires_auth" time="0.028" /><testcase classname="test.integration.api.channels.test_content_review_router" name="test_preview_requires_admin" time="0.153" /><testcase classname="test.integration.api.channels.test_content_review_router" name="test_admin_preview_returns_404_or_400_for_non_existent_account" time="0.022"><failure message="AssertionError: {"success":false,"error":{"code":"DEPENDENCY","message":"Dependency content_review_repository failed","trace_id":"0f5e5301e1064b6889d0e41f61e45831","details":{"cause":{"error_code":"ERROR","message":"(sqlalchemy.dialects.postgresql.asyncpg.Error) <class 'asyncpg.exceptions.InFailedSQLTransactionError'>: current transaction is aborted, commands ignored until end of transaction block\n[SQL: INSERT INTO channel_content_review_records (review_id, channel_type, account_id, resource_type, content_preview, verdict, confidence, categories, detail, reviewed_at, reviewer, source, trace_id, created_by, updated_by, created_at, updated_at, is_deleted, deleted_at) VALUES ($1::VARCHAR, $2::VARCHAR, $3::VARCHAR, $4::VARCHAR, $5::VARCHAR, $6::VARCHAR, $7::FLOAT, $8::JSONB, $9::JSONB, $10::TIMESTAMP WITHOUT TIME ZONE, $11::VARCHAR, $12::VARCHAR, $13::VARCHAR, $14::VARCHAR, $15::VARCHAR, $16::TIMESTAMP WITHOUT TIME ZONE, $17::TIMESTAMP WITHOUT TIME ZONE, $18::INTEGER, $19::TIMESTAMP WITHOUT TIME ZONE) RETURNING channel_content_review_records.id]\n[parameters: ('rev_20260703145018028377_c9d62a81', 'feishu', 'nonexistent_account_00000000', 'message_text', 'pytest content for review', 'pass', 0.95, '[]', '[]', datetime.datetime(2026, 7, 3, 14, 50, 18, 28421, tzinfo=datetime.timezone.utc), 'Kris', 'manual_preview', '0f5e5301e1064b6889d0e41f61e45831', None, None, datetime.datetime(2026, 7, 3, 14, 50, 18, 29714), datetime.datetime(2026, 7, 3, 14, 50, 18, 29718), 0, None)]\n(Background on this error at: https://sqlalche.me/e/20/dbapi)","trace_id":""},"dep":"content_review_repository"}}} assert 502 in (400, 404, 501) + where 502 = <Response [502 Bad Gateway]>.status_code">test/integration/api/channels/test_content_review_router.py:72: in test_admin_preview_returns_404_or_400_for_non_existent_account
|
|
assert response.status_code in (400, 404, 501), response.text
|
|
E AssertionError: {"success":false,"error":{"code":"DEPENDENCY","message":"Dependency content_review_repository failed","trace_id":"0f5e5301e1064b6889d0e41f61e45831","details":{"cause":{"error_code":"ERROR","message":"(sqlalchemy.dialects.postgresql.asyncpg.Error) <class 'asyncpg.exceptions.InFailedSQLTransactionError'>: current transaction is aborted, commands ignored until end of transaction block\n[SQL: INSERT INTO channel_content_review_records (review_id, channel_type, account_id, resource_type, content_preview, verdict, confidence, categories, detail, reviewed_at, reviewer, source, trace_id, created_by, updated_by, created_at, updated_at, is_deleted, deleted_at) VALUES ($1::VARCHAR, $2::VARCHAR, $3::VARCHAR, $4::VARCHAR, $5::VARCHAR, $6::VARCHAR, $7::FLOAT, $8::JSONB, $9::JSONB, $10::TIMESTAMP WITHOUT TIME ZONE, $11::VARCHAR, $12::VARCHAR, $13::VARCHAR, $14::VARCHAR, $15::VARCHAR, $16::TIMESTAMP WITHOUT TIME ZONE, $17::TIMESTAMP WITHOUT TIME ZONE, $18::INTEGER, $19::TIMESTAMP WITHOUT TIME ZONE) RETURNING channel_content_review_records.id]\n[parameters: ('rev_20260703145018028377_c9d62a81', 'feishu', 'nonexistent_account_00000000', 'message_text', 'pytest content for review', 'pass', 0.95, '[]', '[]', datetime.datetime(2026, 7, 3, 14, 50, 18, 28421, tzinfo=datetime.timezone.utc), 'Kris', 'manual_preview', '0f5e5301e1064b6889d0e41f61e45831', None, None, datetime.datetime(2026, 7, 3, 14, 50, 18, 29714), datetime.datetime(2026, 7, 3, 14, 50, 18, 29718), 0, None)]\n(Background on this error at: https://sqlalche.me/e/20/dbapi)","trace_id":""},"dep":"content_review_repository"}}}
|
|
E assert 502 in (400, 404, 501)
|
|
E + where 502 = <Response [502 Bad Gateway]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_content_review_router" name="test_preview_rejects_oversized_content" time="0.015" /><testcase classname="test.integration.api.channels.test_content_review_router" name="test_preview_rejects_empty_content" time="0.016" /><testcase classname="test.integration.api.channels.test_content_review_router" name="test_admin_can_list_review_history" time="0.021"><failure message="AssertionError: {"success":false,"error":{"code":"DEPENDENCY","message":"Dependency content_review_repository failed","trace_id":"abd5da7e9a3a4264b9bf1aee8d9fd19e","details":{"cause":{"error_code":"ERROR","message":"This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (sqlalchemy.dialects.postgresql.asyncpg.Error) <class 'asyncpg.exceptions.InFailedSQLTransactionError'>: current transaction is aborted, commands ignored until end of transaction block\n[SQL: INSERT INTO channel_content_review_records (review_id, channel_type, account_id, resource_type, content_preview, verdict, confidence, categories, detail, reviewed_at, reviewer, source, trace_id, created_by, updated_by, created_at, updated_at, is_deleted, deleted_at) VALUES ($1::VARCHAR, $2::VARCHAR, $3::VARCHAR, $4::VARCHAR, $5::VARCHAR, $6::VARCHAR, $7::FLOAT, $8::JSONB, $9::JSONB, $10::TIMESTAMP WITHOUT TIME ZONE, $11::VARCHAR, $12::VARCHAR, $13::VARCHAR, $14::VARCHAR, $15::VARCHAR, $16::TIMESTAMP WITHOUT TIME ZONE, $17::TIMESTAMP WITHOUT TIME ZONE, $18::INTEGER, $19::TIMESTAMP WITHOUT TIME ZONE) RETURNING channel_content_review_records.id]\n[parameters: ('rev_20260703145018028377_c9d62a81', 'feishu', 'nonexistent_account_00000000', 'message_text', 'pytest content for review', 'pass', 0.95, '[]', '[]', datetime.datetime(2026, 7, 3, 14, 50, 18, 28421, tzinfo=datetime.timezone.utc), 'Kris', 'manual_preview', '0f5e5301e1064b6889d0e41f61e45831', None, None, datetime.datetime(2026, 7, 3, 14, 50, 18, 29714), datetime.datetime(2026, 7, 3, 14, 50, 18, 29718), 0, None)]\n(Background on this error at: https://sqlalche.me/e/20/dbapi) (Background on this error at: https://sqlalche.me/e/20/7s2a)","trace_id":""},"dep":"content_review_repository"}}} assert 502 == 200 + where 502 = <Response [502 Bad Gateway]>.status_code">test/integration/api/channels/test_content_review_router.py:130: in test_admin_can_list_review_history
|
|
assert response.status_code == 200, response.text
|
|
E AssertionError: {"success":false,"error":{"code":"DEPENDENCY","message":"Dependency content_review_repository failed","trace_id":"abd5da7e9a3a4264b9bf1aee8d9fd19e","details":{"cause":{"error_code":"ERROR","message":"This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (sqlalchemy.dialects.postgresql.asyncpg.Error) <class 'asyncpg.exceptions.InFailedSQLTransactionError'>: current transaction is aborted, commands ignored until end of transaction block\n[SQL: INSERT INTO channel_content_review_records (review_id, channel_type, account_id, resource_type, content_preview, verdict, confidence, categories, detail, reviewed_at, reviewer, source, trace_id, created_by, updated_by, created_at, updated_at, is_deleted, deleted_at) VALUES ($1::VARCHAR, $2::VARCHAR, $3::VARCHAR, $4::VARCHAR, $5::VARCHAR, $6::VARCHAR, $7::FLOAT, $8::JSONB, $9::JSONB, $10::TIMESTAMP WITHOUT TIME ZONE, $11::VARCHAR, $12::VARCHAR, $13::VARCHAR, $14::VARCHAR, $15::VARCHAR, $16::TIMESTAMP WITHOUT TIME ZONE, $17::TIMESTAMP WITHOUT TIME ZONE, $18::INTEGER, $19::TIMESTAMP WITHOUT TIME ZONE) RETURNING channel_content_review_records.id]\n[parameters: ('rev_20260703145018028377_c9d62a81', 'feishu', 'nonexistent_account_00000000', 'message_text', 'pytest content for review', 'pass', 0.95, '[]', '[]', datetime.datetime(2026, 7, 3, 14, 50, 18, 28421, tzinfo=datetime.timezone.utc), 'Kris', 'manual_preview', '0f5e5301e1064b6889d0e41f61e45831', None, None, datetime.datetime(2026, 7, 3, 14, 50, 18, 29714), datetime.datetime(2026, 7, 3, 14, 50, 18, 29718), 0, None)]\n(Background on this error at: https://sqlalche.me/e/20/dbapi) (Background on this error at: https://sqlalche.me/e/20/7s2a)","trace_id":""},"dep":"content_review_repository"}}}
|
|
E assert 502 == 200
|
|
E + where 502 = <Response [502 Bad Gateway]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_content_review_router" name="test_review_history_rejects_invalid_verdict" time="0.014" /><testcase classname="test.integration.api.channels.test_content_review_router" name="test_review_history_rejects_limit_zero" time="0.015" /><testcase classname="test.integration.api.channels.test_content_review_router" name="test_review_history_rejects_limit_over_max" time="0.014" /><testcase classname="test.integration.api.channels.test_content_review_router" name="test_admin_can_get_review_stats" time="0.020"><failure message="AssertionError: {"success":false,"error":{"code":"DEPENDENCY","message":"Dependency content_review_repository failed","trace_id":"f15a099f337c41689d788ea1cae3371e","details":{"cause":{"error_code":"ERROR","message":"This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (sqlalchemy.dialects.postgresql.asyncpg.Error) <class 'asyncpg.exceptions.InFailedSQLTransactionError'>: current transaction is aborted, commands ignored until end of transaction block\n[SQL: INSERT INTO channel_content_review_records (review_id, channel_type, account_id, resource_type, content_preview, verdict, confidence, categories, detail, reviewed_at, reviewer, source, trace_id, created_by, updated_by, created_at, updated_at, is_deleted, deleted_at) VALUES ($1::VARCHAR, $2::VARCHAR, $3::VARCHAR, $4::VARCHAR, $5::VARCHAR, $6::VARCHAR, $7::FLOAT, $8::JSONB, $9::JSONB, $10::TIMESTAMP WITHOUT TIME ZONE, $11::VARCHAR, $12::VARCHAR, $13::VARCHAR, $14::VARCHAR, $15::VARCHAR, $16::TIMESTAMP WITHOUT TIME ZONE, $17::TIMESTAMP WITHOUT TIME ZONE, $18::INTEGER, $19::TIMESTAMP WITHOUT TIME ZONE) RETURNING channel_content_review_records.id]\n[parameters: ('rev_20260703145018028377_c9d62a81', 'feishu', 'nonexistent_account_00000000', 'message_text', 'pytest content for review', 'pass', 0.95, '[]', '[]', datetime.datetime(2026, 7, 3, 14, 50, 18, 28421, tzinfo=datetime.timezone.utc), 'Kris', 'manual_preview', '0f5e5301e1064b6889d0e41f61e45831', None, None, datetime.datetime(2026, 7, 3, 14, 50, 18, 29714), datetime.datetime(2026, 7, 3, 14, 50, 18, 29718), 0, None)]\n(Background on this error at: https://sqlalche.me/e/20/dbapi) (Background on this error at: https://sqlalche.me/e/20/7s2a)","trace_id":""},"dep":"content_review_repository"}}} assert 502 == 200 + where 502 = <Response [502 Bad Gateway]>.status_code">test/integration/api/channels/test_content_review_router.py:192: in test_admin_can_get_review_stats
|
|
assert response.status_code == 200, response.text
|
|
E AssertionError: {"success":false,"error":{"code":"DEPENDENCY","message":"Dependency content_review_repository failed","trace_id":"f15a099f337c41689d788ea1cae3371e","details":{"cause":{"error_code":"ERROR","message":"This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (sqlalchemy.dialects.postgresql.asyncpg.Error) <class 'asyncpg.exceptions.InFailedSQLTransactionError'>: current transaction is aborted, commands ignored until end of transaction block\n[SQL: INSERT INTO channel_content_review_records (review_id, channel_type, account_id, resource_type, content_preview, verdict, confidence, categories, detail, reviewed_at, reviewer, source, trace_id, created_by, updated_by, created_at, updated_at, is_deleted, deleted_at) VALUES ($1::VARCHAR, $2::VARCHAR, $3::VARCHAR, $4::VARCHAR, $5::VARCHAR, $6::VARCHAR, $7::FLOAT, $8::JSONB, $9::JSONB, $10::TIMESTAMP WITHOUT TIME ZONE, $11::VARCHAR, $12::VARCHAR, $13::VARCHAR, $14::VARCHAR, $15::VARCHAR, $16::TIMESTAMP WITHOUT TIME ZONE, $17::TIMESTAMP WITHOUT TIME ZONE, $18::INTEGER, $19::TIMESTAMP WITHOUT TIME ZONE) RETURNING channel_content_review_records.id]\n[parameters: ('rev_20260703145018028377_c9d62a81', 'feishu', 'nonexistent_account_00000000', 'message_text', 'pytest content for review', 'pass', 0.95, '[]', '[]', datetime.datetime(2026, 7, 3, 14, 50, 18, 28421, tzinfo=datetime.timezone.utc), 'Kris', 'manual_preview', '0f5e5301e1064b6889d0e41f61e45831', None, None, datetime.datetime(2026, 7, 3, 14, 50, 18, 29714), datetime.datetime(2026, 7, 3, 14, 50, 18, 29718), 0, None)]\n(Background on this error at: https://sqlalche.me/e/20/dbapi) (Background on this error at: https://sqlalche.me/e/20/7s2a)","trace_id":""},"dep":"content_review_repository"}}}
|
|
E assert 502 == 200
|
|
E + where 502 = <Response [502 Bad Gateway]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_content_review_router" name="test_batch_decision_rejects_empty_decisions" time="0.018" /><testcase classname="test.integration.api.channels.test_content_review_router" name="test_batch_decision_rejects_too_many_decisions" time="0.016" /><testcase classname="test.integration.api.channels.test_content_review_router" name="test_batch_decision_with_non_existent_review_returns_200_or_404" time="0.034" /><testcase classname="test.integration.api.channels.test_content_review_router" name="test_get_review_returns_404_for_non_existent" time="0.019"><failure message="AssertionError: {"success":false,"error":{"code":"DEPENDENCY","message":"Dependency content_review_repository failed","trace_id":"b600a7c10709451a91efdf1eb960353d","details":{"cause":{"error_code":"ERROR","message":"This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (sqlalchemy.dialects.postgresql.asyncpg.Error) <class 'asyncpg.exceptions.InFailedSQLTransactionError'>: current transaction is aborted, commands ignored until end of transaction block\n[SQL: INSERT INTO channel_content_review_records (review_id, channel_type, account_id, resource_type, content_preview, verdict, confidence, categories, detail, reviewed_at, reviewer, source, trace_id, created_by, updated_by, created_at, updated_at, is_deleted, deleted_at) VALUES ($1::VARCHAR, $2::VARCHAR, $3::VARCHAR, $4::VARCHAR, $5::VARCHAR, $6::VARCHAR, $7::FLOAT, $8::JSONB, $9::JSONB, $10::TIMESTAMP WITHOUT TIME ZONE, $11::VARCHAR, $12::VARCHAR, $13::VARCHAR, $14::VARCHAR, $15::VARCHAR, $16::TIMESTAMP WITHOUT TIME ZONE, $17::TIMESTAMP WITHOUT TIME ZONE, $18::INTEGER, $19::TIMESTAMP WITHOUT TIME ZONE) RETURNING channel_content_review_records.id]\n[parameters: ('rev_20260703145018028377_c9d62a81', 'feishu', 'nonexistent_account_00000000', 'message_text', 'pytest content for review', 'pass', 0.95, '[]', '[]', datetime.datetime(2026, 7, 3, 14, 50, 18, 28421, tzinfo=datetime.timezone.utc), 'Kris', 'manual_preview', '0f5e5301e1064b6889d0e41f61e45831', None, None, datetime.datetime(2026, 7, 3, 14, 50, 18, 29714), datetime.datetime(2026, 7, 3, 14, 50, 18, 29718), 0, None)]\n(Background on this error at: https://sqlalche.me/e/20/dbapi) (Background on this error at: https://sqlalche.me/e/20/7s2a)","trace_id":""},"dep":"content_review_repository"}}} assert 502 == 404 + where 502 = <Response [502 Bad Gateway]>.status_code">test/integration/api/channels/test_content_review_router.py:277: in test_get_review_returns_404_for_non_existent
|
|
assert response.status_code == 404, response.text
|
|
E AssertionError: {"success":false,"error":{"code":"DEPENDENCY","message":"Dependency content_review_repository failed","trace_id":"b600a7c10709451a91efdf1eb960353d","details":{"cause":{"error_code":"ERROR","message":"This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (sqlalchemy.dialects.postgresql.asyncpg.Error) <class 'asyncpg.exceptions.InFailedSQLTransactionError'>: current transaction is aborted, commands ignored until end of transaction block\n[SQL: INSERT INTO channel_content_review_records (review_id, channel_type, account_id, resource_type, content_preview, verdict, confidence, categories, detail, reviewed_at, reviewer, source, trace_id, created_by, updated_by, created_at, updated_at, is_deleted, deleted_at) VALUES ($1::VARCHAR, $2::VARCHAR, $3::VARCHAR, $4::VARCHAR, $5::VARCHAR, $6::VARCHAR, $7::FLOAT, $8::JSONB, $9::JSONB, $10::TIMESTAMP WITHOUT TIME ZONE, $11::VARCHAR, $12::VARCHAR, $13::VARCHAR, $14::VARCHAR, $15::VARCHAR, $16::TIMESTAMP WITHOUT TIME ZONE, $17::TIMESTAMP WITHOUT TIME ZONE, $18::INTEGER, $19::TIMESTAMP WITHOUT TIME ZONE) RETURNING channel_content_review_records.id]\n[parameters: ('rev_20260703145018028377_c9d62a81', 'feishu', 'nonexistent_account_00000000', 'message_text', 'pytest content for review', 'pass', 0.95, '[]', '[]', datetime.datetime(2026, 7, 3, 14, 50, 18, 28421, tzinfo=datetime.timezone.utc), 'Kris', 'manual_preview', '0f5e5301e1064b6889d0e41f61e45831', None, None, datetime.datetime(2026, 7, 3, 14, 50, 18, 29714), datetime.datetime(2026, 7, 3, 14, 50, 18, 29718), 0, None)]\n(Background on this error at: https://sqlalche.me/e/20/dbapi) (Background on this error at: https://sqlalche.me/e/20/7s2a)","trace_id":""},"dep":"content_review_repository"}}}
|
|
E assert 502 == 404
|
|
E + where 502 = <Response [502 Bad Gateway]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_content_review_router" name="test_stats_path_not_captured_by_review_id" time="0.017"><failure message="AssertionError: {"success":false,"error":{"code":"DEPENDENCY","message":"Dependency content_review_repository failed","trace_id":"45a169b8b00148bdb658e137ce4d38c0","details":{"cause":{"error_code":"ERROR","message":"This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (sqlalchemy.dialects.postgresql.asyncpg.Error) <class 'asyncpg.exceptions.InFailedSQLTransactionError'>: current transaction is aborted, commands ignored until end of transaction block\n[SQL: INSERT INTO channel_content_review_records (review_id, channel_type, account_id, resource_type, content_preview, verdict, confidence, categories, detail, reviewed_at, reviewer, source, trace_id, created_by, updated_by, created_at, updated_at, is_deleted, deleted_at) VALUES ($1::VARCHAR, $2::VARCHAR, $3::VARCHAR, $4::VARCHAR, $5::VARCHAR, $6::VARCHAR, $7::FLOAT, $8::JSONB, $9::JSONB, $10::TIMESTAMP WITHOUT TIME ZONE, $11::VARCHAR, $12::VARCHAR, $13::VARCHAR, $14::VARCHAR, $15::VARCHAR, $16::TIMESTAMP WITHOUT TIME ZONE, $17::TIMESTAMP WITHOUT TIME ZONE, $18::INTEGER, $19::TIMESTAMP WITHOUT TIME ZONE) RETURNING channel_content_review_records.id]\n[parameters: ('rev_20260703145018028377_c9d62a81', 'feishu', 'nonexistent_account_00000000', 'message_text', 'pytest content for review', 'pass', 0.95, '[]', '[]', datetime.datetime(2026, 7, 3, 14, 50, 18, 28421, tzinfo=datetime.timezone.utc), 'Kris', 'manual_preview', '0f5e5301e1064b6889d0e41f61e45831', None, None, datetime.datetime(2026, 7, 3, 14, 50, 18, 29714), datetime.datetime(2026, 7, 3, 14, 50, 18, 29718), 0, None)]\n(Background on this error at: https://sqlalche.me/e/20/dbapi) (Background on this error at: https://sqlalche.me/e/20/7s2a)","trace_id":""},"dep":"content_review_repository"}}} assert 502 == 200 + where 502 = <Response [502 Bad Gateway]>.status_code">test/integration/api/channels/test_content_review_router.py:295: in test_stats_path_not_captured_by_review_id
|
|
assert response.status_code == 200, response.text
|
|
E AssertionError: {"success":false,"error":{"code":"DEPENDENCY","message":"Dependency content_review_repository failed","trace_id":"45a169b8b00148bdb658e137ce4d38c0","details":{"cause":{"error_code":"ERROR","message":"This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (sqlalchemy.dialects.postgresql.asyncpg.Error) <class 'asyncpg.exceptions.InFailedSQLTransactionError'>: current transaction is aborted, commands ignored until end of transaction block\n[SQL: INSERT INTO channel_content_review_records (review_id, channel_type, account_id, resource_type, content_preview, verdict, confidence, categories, detail, reviewed_at, reviewer, source, trace_id, created_by, updated_by, created_at, updated_at, is_deleted, deleted_at) VALUES ($1::VARCHAR, $2::VARCHAR, $3::VARCHAR, $4::VARCHAR, $5::VARCHAR, $6::VARCHAR, $7::FLOAT, $8::JSONB, $9::JSONB, $10::TIMESTAMP WITHOUT TIME ZONE, $11::VARCHAR, $12::VARCHAR, $13::VARCHAR, $14::VARCHAR, $15::VARCHAR, $16::TIMESTAMP WITHOUT TIME ZONE, $17::TIMESTAMP WITHOUT TIME ZONE, $18::INTEGER, $19::TIMESTAMP WITHOUT TIME ZONE) RETURNING channel_content_review_records.id]\n[parameters: ('rev_20260703145018028377_c9d62a81', 'feishu', 'nonexistent_account_00000000', 'message_text', 'pytest content for review', 'pass', 0.95, '[]', '[]', datetime.datetime(2026, 7, 3, 14, 50, 18, 28421, tzinfo=datetime.timezone.utc), 'Kris', 'manual_preview', '0f5e5301e1064b6889d0e41f61e45831', None, None, datetime.datetime(2026, 7, 3, 14, 50, 18, 29714), datetime.datetime(2026, 7, 3, 14, 50, 18, 29718), 0, None)]\n(Background on this error at: https://sqlalche.me/e/20/dbapi) (Background on this error at: https://sqlalche.me/e/20/7s2a)","trace_id":""},"dep":"content_review_repository"}}}
|
|
E assert 502 == 200
|
|
E + where 502 = <Response [502 Bad Gateway]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_content_review_router" name="test_batch_decision_path_not_captured_by_review_id" time="0.027" /><testcase classname="test.integration.api.channels.test_dashboard_router" name="test_get_dashboard_overview_requires_auth" time="0.019" /><testcase classname="test.integration.api.channels.test_dashboard_router" name="test_get_dashboard_overview_requires_admin" time="0.153" /><testcase classname="test.integration.api.channels.test_dashboard_router" name="test_admin_can_get_dashboard_overview" time="0.030" /><testcase classname="test.integration.api.channels.test_dashboard_router" name="test_admin_can_get_dashboard_accounts" time="0.028" /><testcase classname="test.integration.api.channels.test_dashboard_router" name="test_admin_can_get_dashboard_messages" time="0.030" /><testcase classname="test.integration.api.channels.test_dashboard_router" name="test_admin_can_get_dashboard_sessions" time="0.033" /><testcase classname="test.integration.api.channels.test_dashboard_router" name="test_admin_can_get_dashboard_delivery" time="0.036" /><testcase classname="test.integration.api.channels.test_dashboard_router" name="test_admin_can_get_dashboard_realtime" time="0.030" /><testcase classname="test.integration.api.channels.test_dashboard_router" name="test_dashboard_realtime_rejects_window_below_min" time="0.013" /><testcase classname="test.integration.api.channels.test_dashboard_router" name="test_dashboard_realtime_rejects_window_above_max" time="0.015" /><testcase classname="test.integration.api.channels.test_dashboard_router" name="test_dashboard_delivery_rejects_invalid_start_time_format" time="0.024" /><testcase classname="test.integration.api.channels.test_directory_router" name="test_search_directory_users_requires_auth" time="0.028" /><testcase classname="test.integration.api.channels.test_directory_router" name="test_search_directory_users_requires_admin" time="0.157" /><testcase classname="test.integration.api.channels.test_directory_router" name="test_admin_search_directory_users_returns_404_or_501" time="0.027" /><testcase classname="test.integration.api.channels.test_directory_router" name="test_search_directory_users_rejects_limit_zero" time="0.017" /><testcase classname="test.integration.api.channels.test_directory_router" name="test_search_directory_users_rejects_limit_over_max" time="0.014" /><testcase classname="test.integration.api.channels.test_directory_router" name="test_search_directory_groups_returns_404_or_501" time="0.033" /><testcase classname="test.integration.api.channels.test_directory_router" name="test_get_directory_user_profile_returns_404_or_501" time="0.031" /><testcase classname="test.integration.api.channels.test_directory_router" name="test_get_directory_group_detail_returns_404_or_501" time="0.029" /><testcase classname="test.integration.api.channels.test_directory_router" name="test_get_directory_group_members_returns_404_or_501" time="0.037" /><testcase classname="test.integration.api.channels.test_directory_router" name="test_clear_directory_cache_returns_404_or_200_or_501" time="0.030" /><testcase classname="test.integration.api.channels.test_directory_router" name="test_clear_directory_cache_does_not_reject_path_for_invalid_scope" time="0.016" /><testcase classname="test.integration.api.channels.test_directory_router" name="test_clear_directory_cache_requires_auth" time="0.011" /><testcase classname="test.integration.api.channels.test_doctor_router" name="test_list_doctor_checks_requires_auth" time="0.029" /><testcase classname="test.integration.api.channels.test_doctor_router" name="test_list_doctor_checks_requires_admin" time="0.152" /><testcase classname="test.integration.api.channels.test_doctor_router" name="test_admin_list_doctor_checks_nonexistent_account" time="0.030" /><testcase classname="test.integration.api.channels.test_doctor_router" name="test_run_all_doctor_checks_nonexistent_account" time="0.030" /><testcase classname="test.integration.api.channels.test_doctor_router" name="test_get_doctor_check_nonexistent_check" time="0.030" /><testcase classname="test.integration.api.channels.test_doctor_router" name="test_run_doctor_check_nonexistent_check" time="0.029" /><testcase classname="test.integration.api.channels.test_doctor_router" name="test_preview_doctor_repair_nonexistent_check" time="0.032" /><testcase classname="test.integration.api.channels.test_doctor_router" name="test_execute_doctor_repair_nonexistent_check" time="0.031" /><testcase classname="test.integration.api.channels.test_doctor_router" name="test_run_doctor_check_rejects_invalid_check_id_format" time="0.026" /><testcase classname="test.integration.api.channels.test_health_router" name="test_get_health_does_not_require_auth" time="0.032" /><testcase classname="test.integration.api.channels.test_health_router" name="test_get_health_works_with_standard_user" time="0.156" /><testcase classname="test.integration.api.channels.test_health_router" name="test_get_health_not_captured_by_channel_type_path" time="0.014" /><testcase classname="test.integration.api.channels.test_health_router" name="test_get_health_detail_requires_auth" time="0.014" /><testcase classname="test.integration.api.channels.test_health_router" name="test_get_health_detail_requires_admin" time="0.148" /><testcase classname="test.integration.api.channels.test_health_router" name="test_admin_can_get_health_detail" time="0.018" /><testcase classname="test.integration.api.channels.test_health_router" name="test_export_diagnostics_requires_auth" time="0.016" /><testcase classname="test.integration.api.channels.test_health_router" name="test_export_diagnostics_requires_admin" time="0.156" /><testcase classname="test.integration.api.channels.test_health_router" name="test_admin_can_export_diagnostics_with_empty_body" time="0.019"><failure message="AssertionError: {"success":false,"error":{"code":"INTERNAL","message":"diagnostics export failed: [DEPENDENCY] Dependency channel_audit_log failed","trace_id":"cba79be9bfb5486e92ee57950344db6a","details":{"cause":{"error_code":"ERROR","message":"[DEPENDENCY] Dependency channel_audit_log failed","trace_id":""}}}} assert 500 == 200 + where 500 = <Response [500 Internal Server Error]>.status_code">test/integration/api/channels/test_health_router.py:142: in test_admin_can_export_diagnostics_with_empty_body
|
|
assert response.status_code == 200, response.text
|
|
E AssertionError: {"success":false,"error":{"code":"INTERNAL","message":"diagnostics export failed: [DEPENDENCY] Dependency channel_audit_log failed","trace_id":"cba79be9bfb5486e92ee57950344db6a","details":{"cause":{"error_code":"ERROR","message":"[DEPENDENCY] Dependency channel_audit_log failed","trace_id":""}}}}
|
|
E assert 500 == 200
|
|
E + where 500 = <Response [500 Internal Server Error]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_health_router" name="test_export_diagnostics_rejects_audit_log_count_zero" time="0.014" /><testcase classname="test.integration.api.channels.test_health_router" name="test_export_diagnostics_rejects_audit_log_count_over_max" time="0.015" /><testcase classname="test.integration.api.channels.test_health_router" name="test_get_single_health_nonexistent_account" time="0.033" /><testcase classname="test.integration.api.channels.test_health_router" name="test_probe_channel_nonexistent_account" time="0.031" /><testcase classname="test.integration.api.channels.test_health_router" name="test_probe_rejects_timeout_below_min" time="0.017" /><testcase classname="test.integration.api.channels.test_health_router" name="test_probe_rejects_timeout_above_max" time="0.015" /><testcase classname="test.integration.api.channels.test_login_router" name="test_get_login_status_requires_auth" time="0.028" /><testcase classname="test.integration.api.channels.test_login_router" name="test_get_login_status_forbids_standard_user" time="0.154" /><testcase classname="test.integration.api.channels.test_login_router" name="test_get_login_status_non_existent_returns_404" time="0.029" /><testcase classname="test.integration.api.channels.test_login_router" name="test_qr_start_requires_auth" time="0.015" /><testcase classname="test.integration.api.channels.test_login_router" name="test_qr_start_forbids_standard_user" time="0.150" /><testcase classname="test.integration.api.channels.test_login_router" name="test_qr_start_non_existent_account_returns_404" time="0.018"><failure message="AssertionError: {"success":false,"error":{"code":"DEPENDENCY","message":"Dependency feishu_api failed","trace_id":"9e60d09deb6f42bc8bd197003673f55b","details":{"cause":{"error_code":"NOT_FOUND","message":"config not found: app_id","trace_id":"","resource":"config","id":"app_id"},"dep":"feishu_api"}}} assert 502 == 404 + where 502 = <Response [502 Bad Gateway]>.status_code">test/integration/api/channels/test_login_router.py:83: in test_qr_start_non_existent_account_returns_404
|
|
assert response.status_code == 404, response.text
|
|
E AssertionError: {"success":false,"error":{"code":"DEPENDENCY","message":"Dependency feishu_api failed","trace_id":"9e60d09deb6f42bc8bd197003673f55b","details":{"cause":{"error_code":"NOT_FOUND","message":"config not found: app_id","trace_id":"","resource":"config","id":"app_id"},"dep":"feishu_api"}}}
|
|
E assert 502 == 404
|
|
E + where 502 = <Response [502 Bad Gateway]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_login_router" name="test_qr_wait_requires_session_id" time="0.018" /><testcase classname="test.integration.api.channels.test_login_router" name="test_qr_wait_non_existent_account_returns_404_or_422" time="0.025" /><testcase classname="test.integration.api.channels.test_login_router" name="test_qr_wait_rejects_timeout_out_of_range" time="0.014" /><testcase classname="test.integration.api.channels.test_login_router" name="test_qr_wait_rejects_timeout_over_max" time="0.015" /><testcase classname="test.integration.api.channels.test_login_router" name="test_qr_cancel_requires_session_id" time="0.019" /><testcase classname="test.integration.api.channels.test_login_router" name="test_qr_cancel_non_existent_account_returns_404_or_422" time="0.026" /><testcase classname="test.integration.api.channels.test_login_router" name="test_qr_refresh_requires_session_id" time="0.017" /><testcase classname="test.integration.api.channels.test_login_router" name="test_qr_refresh_non_existent_account_returns_404_or_422" time="0.025" /><testcase classname="test.integration.api.channels.test_login_router" name="test_logout_requires_auth" time="0.015" /><testcase classname="test.integration.api.channels.test_login_router" name="test_logout_forbids_standard_user" time="0.174" /><testcase classname="test.integration.api.channels.test_login_router" name="test_logout_non_existent_account_returns_404" time="0.029" /><testcase classname="test.integration.api.channels.test_login_router" name="test_force_logout_requires_auth" time="0.020" /><testcase classname="test.integration.api.channels.test_login_router" name="test_force_logout_forbids_standard_user" time="0.163" /><testcase classname="test.integration.api.channels.test_login_router" name="test_force_logout_requires_reason" time="0.017" /><testcase classname="test.integration.api.channels.test_login_router" name="test_force_logout_non_existent_account_returns_404" time="0.029" /><testcase classname="test.integration.api.channels.test_message_router" name="test_list_messages_requires_auth" time="0.026" /><testcase classname="test.integration.api.channels.test_message_router" name="test_list_messages_requires_admin" time="0.151" /><testcase classname="test.integration.api.channels.test_message_router" name="test_admin_can_list_messages" time="0.032" /><testcase classname="test.integration.api.channels.test_message_router" name="test_list_messages_rejects_limit_zero" time="0.015" /><testcase classname="test.integration.api.channels.test_message_router" name="test_list_messages_rejects_limit_over_max" time="0.014" /><testcase classname="test.integration.api.channels.test_message_router" name="test_admin_can_list_messages_with_time_range" time="0.030" /><testcase classname="test.integration.api.channels.test_message_router" name="test_search_messages_requires_keyword" time="0.015" /><testcase classname="test.integration.api.channels.test_message_router" name="test_search_messages_rejects_short_keyword" time="0.018" /><testcase classname="test.integration.api.channels.test_message_router" name="test_admin_can_search_messages" time="0.027" /><testcase classname="test.integration.api.channels.test_message_router" name="test_batch_recall_rejects_empty_message_ids" time="0.016" /><testcase classname="test.integration.api.channels.test_message_router" name="test_batch_recall_rejects_too_many_message_ids" time="0.015" /><testcase classname="test.integration.api.channels.test_message_router" name="test_batch_recall_with_non_existent_ids_returns_partial_success" time="0.026" /><testcase classname="test.integration.api.channels.test_message_router" name="test_get_message_returns_404_for_non_existent" time="0.030" /><testcase classname="test.integration.api.channels.test_message_router" name="test_get_message_status_returns_404_for_non_existent" time="0.031" /><testcase classname="test.integration.api.channels.test_message_router" name="test_search_path_not_captured_by_message_id" time="0.028" /><testcase classname="test.integration.api.channels.test_message_router" name="test_batch_recall_path_not_captured_by_message_id" time="0.026" /><testcase classname="test.integration.api.channels.test_message_router" name="test_send_admin_message_requires_idempotency_key" time="0.018" /><testcase classname="test.integration.api.channels.test_message_router" name="test_send_admin_message_with_non_existent_account_returns_404_or_400" time="0.034"><failure message="AssertionError: {"success":false,"data":{"message_ids":[],"failures":[{"target":"nonexistent_target","error_code":"VALIDATION_ERROR","message":"invalid channel_type in target: nonexistent_target","retryable":false,"details":null}],"skipped":[]}} assert 200 in (400, 404) + where 200 = <Response [200 OK]>.status_code">test/integration/api/channels/test_message_router.py:293: in test_send_admin_message_with_non_existent_account_returns_404_or_400
|
|
assert response.status_code in (400, 404), response.text
|
|
E AssertionError: {"success":false,"data":{"message_ids":[],"failures":[{"target":"nonexistent_target","error_code":"VALIDATION_ERROR","message":"invalid channel_type in target: nonexistent_target","retryable":false,"details":null}],"skipped":[]}}
|
|
E assert 200 in (400, 404)
|
|
E + where 200 = <Response [200 OK]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_message_router" name="test_upload_attachment_requires_file" time="0.020" /><testcase classname="test.integration.api.channels.test_message_router" name="test_recall_message_returns_404_for_non_existent" time="0.029" /><testcase classname="test.integration.api.channels.test_message_router" name="test_resend_message_returns_404_for_non_existent" time="0.031" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_list_outbox_messages_requires_auth" time="0.033" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_list_outbox_messages_requires_admin" time="0.156" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_admin_can_list_outbox_messages" time="0.028" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_list_outbox_messages_rejects_limit_zero" time="0.014" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_list_outbox_messages_rejects_limit_over_max" time="0.016" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_admin_can_get_outbox_stats" time="0.030" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_outbox_trend_requires_start_time" time="0.021" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_outbox_trend_requires_end_time" time="0.014" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_admin_can_get_outbox_trend" time="0.026" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_admin_can_list_dead_letter" time="0.031" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_admin_can_get_retry_policy" time="0.028" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_admin_can_batch_retry_dead_letter" time="0.035"><failure message="AssertionError: {"success":false,"error":{"code":"INTERNAL","message":"control execution failed: This transaction is closed","trace_id":"6dba06f439d64b69969467f6df9e565b","details":{"cause":{"type":"ResourceClosedError","message":"This transaction is closed"}}}} assert 500 == 200 + where 500 = <Response [500 Internal Server Error]>.status_code">test/integration/api/channels/test_outbox_router.py:191: in test_admin_can_batch_retry_dead_letter
|
|
assert response.status_code == 200, response.text
|
|
E AssertionError: {"success":false,"error":{"code":"INTERNAL","message":"control execution failed: This transaction is closed","trace_id":"6dba06f439d64b69969467f6df9e565b","details":{"cause":{"type":"ResourceClosedError","message":"This transaction is closed"}}}}
|
|
E assert 500 == 200
|
|
E + where 500 = <Response [500 Internal Server Error]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_outbox_router" name="test_admin_can_batch_delete_dead_letter" time="0.031" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_admin_can_export_dead_letter" time="0.029" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_admin_can_update_retry_policy" time="0.029" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_update_retry_policy_rejects_max_retry_zero" time="0.015" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_update_retry_policy_rejects_max_retry_over_max" time="0.019" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_update_retry_policy_rejects_ttl_too_small" time="0.015" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_update_retry_policy_rejects_ttl_too_large" time="0.015" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_get_outbox_message_returns_404_for_non_existent" time="0.032" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_delete_dead_letter_returns_404_for_non_existent" time="0.032" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_retry_outbox_message_returns_404_for_non_existent" time="0.033" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_stats_path_not_captured_by_outbox_id" time="0.026" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_trend_path_not_captured_by_outbox_id" time="0.027" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_dead_letter_path_not_captured_by_outbox_id" time="0.032" /><testcase classname="test.integration.api.channels.test_outbox_router" name="test_retry_policy_path_not_captured_by_outbox_id" time="0.024" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_list_pairings_requires_auth" time="0.034" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_list_pairings_forbids_standard_user" time="0.159" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_admin_can_list_pairings" time="0.042" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_list_pairings_rejects_limit_zero" time="0.015" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_list_pairings_rejects_limit_over_max" time="0.018" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_list_pairings_rejects_invalid_status" time="0.014" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_create_pairing_requires_auth" time="0.015" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_create_pairing_forbids_standard_user" time="0.151" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_create_pairing_non_existent_account_returns_404" time="0.033" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_create_pairing_rejects_expires_zero" time="0.016" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_create_pairing_rejects_expires_over_max" time="0.015" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_batch_approve_pairings_rejects_empty_ids" time="0.019" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_batch_approve_pairings_rejects_too_many_ids" time="0.015" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_batch_reject_pairings_rejects_empty_ids" time="0.021" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_clean_expired_pairings_rejects_max_count_zero" time="0.018" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_clean_expired_pairings_rejects_max_count_over_max" time="0.015" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_get_pairings_stats_returns_200" time="0.034" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_get_pairing_non_existent_returns_404" time="0.031" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_approve_pairing_non_existent_returns_404" time="0.034" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_reject_pairing_non_existent_returns_404" time="0.031" /><testcase classname="test.integration.api.channels.test_pairing_router" name="test_revoke_pairing_non_existent_returns_404" time="0.032" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_list_plugins_requires_auth" time="0.025" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_list_plugins_requires_admin" time="0.159" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_admin_can_list_plugins" time="0.030" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_list_plugin_catalog_requires_auth" time="0.016" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_install_plugin_requires_auth" time="0.015" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_install_plugin_rejects_standard_user" time="0.159" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_superadmin_install_nonexistent_source_fails" time="0.026" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_uninstall_plugin_rejects_standard_user" time="0.160" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_superadmin_uninstall_nonexistent_plugin_returns_404" time="0.030" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_get_plugin_returns_404_for_non_existent" time="0.032" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_get_plugin_config_returns_404_for_non_existent" time="0.034" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_update_plugin_config_returns_404_for_non_existent" time="0.031" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_load_plugin_returns_404_for_non_existent" time="0.028" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_start_plugin_returns_404_for_non_existent" time="0.033" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_pause_plugin_returns_404_for_non_existent" time="0.030" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_resume_plugin_returns_404_for_non_existent" time="0.030" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_stop_plugin_returns_404_for_non_existent" time="0.028" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_unload_plugin_returns_404_for_non_existent" time="0.028" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_reload_plugin_returns_404_for_non_existent" time="0.034" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_batch_start_plugins_with_empty_plugin_ids" time="0.018" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_batch_start_plugins_with_empty_body" time="0.015" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_batch_stop_plugins_requires_auth" time="0.018" /><testcase classname="test.integration.api.channels.test_plugin_router" name="test_install_static_path_not_captured_as_plugin_id" time="0.026" /><testcase classname="test.integration.api.channels.test_reports_router" name="test_list_oneoff_reports_requires_auth" time="0.032" /><testcase classname="test.integration.api.channels.test_reports_router" name="test_list_oneoff_reports_requires_admin" time="0.149" /><testcase classname="test.integration.api.channels.test_reports_router" name="test_admin_can_list_oneoff_reports" time="0.039" /><testcase classname="test.integration.api.channels.test_reports_router" name="test_admin_can_create_oneoff_report" time="0.060"><failure message="AssertionError: {"success":false,"error":{"code":"INTERNAL","message":"control execution failed: This transaction is closed","trace_id":"dfa5be90a4a047159d77f20c1c610a45","details":{"cause":{"type":"ResourceClosedError","message":"This transaction is closed"}}}} assert 500 == 200 + where 500 = <Response [500 Internal Server Error]>.status_code">test/integration/api/channels/test_reports_router.py:64: in test_admin_can_create_oneoff_report
|
|
assert response.status_code == 200, response.text
|
|
E AssertionError: {"success":false,"error":{"code":"INTERNAL","message":"control execution failed: This transaction is closed","trace_id":"dfa5be90a4a047159d77f20c1c610a45","details":{"cause":{"type":"ResourceClosedError","message":"This transaction is closed"}}}}
|
|
E assert 500 == 200
|
|
E + where 500 = <Response [500 Internal Server Error]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_reports_router" name="test_create_oneoff_report_rejects_invalid_report_type" time="0.014" /><testcase classname="test.integration.api.channels.test_reports_router" name="test_list_oneoff_reports_rejects_limit_zero" time="0.014" /><testcase classname="test.integration.api.channels.test_reports_router" name="test_list_oneoff_reports_rejects_limit_over_max" time="0.014" /><testcase classname="test.integration.api.channels.test_reports_router" name="test_download_oneoff_report_returns_404_or_409_for_nonexistent" time="0.033" /><testcase classname="test.integration.api.channels.test_reports_router" name="test_retry_oneoff_report_returns_404_for_nonexistent" time="0.031" /><testcase classname="test.integration.api.channels.test_reports_router" name="test_get_report_returns_404_for_nonexistent" time="0.030" /><testcase classname="test.integration.api.channels.test_reports_router" name="test_static_oneoff_path_not_captured_as_report_id" time="0.027" /><testcase classname="test.integration.api.channels.test_session_router" name="test_list_sessions_requires_auth" time="0.025" /><testcase classname="test.integration.api.channels.test_session_router" name="test_list_sessions_forbids_standard_user" time="0.150" /><testcase classname="test.integration.api.channels.test_session_router" name="test_admin_can_list_sessions" time="0.030" /><testcase classname="test.integration.api.channels.test_session_router" name="test_list_sessions_rejects_limit_zero" time="0.014" /><testcase classname="test.integration.api.channels.test_session_router" name="test_list_sessions_rejects_limit_over_max" time="0.014" /><testcase classname="test.integration.api.channels.test_session_router" name="test_batch_close_sessions_requires_auth" time="0.014" /><testcase classname="test.integration.api.channels.test_session_router" name="test_batch_close_sessions_forbids_standard_user" time="0.155" /><testcase classname="test.integration.api.channels.test_session_router" name="test_batch_close_sessions_rejects_empty_body" time="0.015" /><testcase classname="test.integration.api.channels.test_session_router" name="test_batch_close_sessions_with_non_existent_ids_returns_success" time="0.029" /><testcase classname="test.integration.api.channels.test_session_router" name="test_get_session_requires_auth" time="0.016" /><testcase classname="test.integration.api.channels.test_session_router" name="test_get_session_forbids_standard_user" time="0.155" /><testcase classname="test.integration.api.channels.test_session_router" name="test_get_session_non_existent_returns_404" time="0.027" /><testcase classname="test.integration.api.channels.test_session_router" name="test_merge_session_requires_auth" time="0.015" /><testcase classname="test.integration.api.channels.test_session_router" name="test_merge_session_forbids_standard_user" time="0.150" /><testcase classname="test.integration.api.channels.test_session_router" name="test_merge_session_non_existent_returns_404" time="0.028" /><testcase classname="test.integration.api.channels.test_session_router" name="test_transfer_session_requires_auth" time="0.015" /><testcase classname="test.integration.api.channels.test_session_router" name="test_transfer_session_forbids_standard_user" time="0.151" /><testcase classname="test.integration.api.channels.test_session_router" name="test_transfer_session_non_existent_returns_404" time="0.026" /><testcase classname="test.integration.api.channels.test_session_router" name="test_close_session_requires_auth" time="0.015" /><testcase classname="test.integration.api.channels.test_session_router" name="test_close_session_forbids_standard_user" time="0.148" /><testcase classname="test.integration.api.channels.test_session_router" name="test_close_session_non_existent_returns_404" time="0.029" /><testcase classname="test.integration.api.channels.test_session_router" name="test_list_session_messages_requires_auth" time="0.015" /><testcase classname="test.integration.api.channels.test_session_router" name="test_list_session_messages_forbids_standard_user" time="0.155" /><testcase classname="test.integration.api.channels.test_session_router" name="test_list_session_messages_non_existent_returns_404" time="0.029" /><testcase classname="test.integration.api.channels.test_session_router" name="test_list_session_messages_rejects_invalid_limit" time="0.015" /><testcase classname="test.integration.api.channels.test_session_router" name="test_get_session_stats_requires_auth" time="0.015" /><testcase classname="test.integration.api.channels.test_session_router" name="test_get_session_stats_forbids_standard_user" time="0.154" /><testcase classname="test.integration.api.channels.test_session_router" name="test_get_session_stats_non_existent_returns_404" time="0.027" /><testcase classname="test.integration.api.channels.test_session_router" name="test_bind_session_user_non_existent_returns_404" time="0.021" /><testcase classname="test.integration.api.channels.test_session_router" name="test_unbind_session_user_non_existent_returns_404" time="0.020" /><testcase classname="test.integration.api.channels.test_session_router" name="test_get_session_identity_non_existent_returns_404" time="0.022" /><testcase classname="test.integration.api.channels.test_webhook_router" name="test_webhook_does_not_require_auth" time="0.030"><failure message="AssertionError: {"success":false,"error":{"code":"NOT_FOUND","message":"channel_account not found: feishu:<webhook>","trace_id":"e595066ec3884a8cab1bde4f0228f8cd","details":{"resource":"channel_account","id":"feishu:<webhook>"}}} assert 404 in (200, 500, 501) + where 404 = <Response [404 Not Found]>.status_code">test/integration/api/channels/test_webhook_router.py:29: in test_webhook_does_not_require_auth
|
|
assert response.status_code in (200, 500, 501), response.text
|
|
E AssertionError: {"success":false,"error":{"code":"NOT_FOUND","message":"channel_account not found: feishu:<webhook>","trace_id":"e595066ec3884a8cab1bde4f0228f8cd","details":{"resource":"channel_account","id":"feishu:<webhook>"}}}
|
|
E assert 404 in (200, 500, 501)
|
|
E + where 404 = <Response [404 Not Found]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_webhook_router" name="test_webhook_accepts_empty_body_without_auth_error" time="0.015" /><testcase classname="test.integration.api.channels.test_webhook_router" name="test_webhook_rejects_oversized_body" time="0.016" /><testcase classname="test.integration.api.channels.test_webhook_router" name="test_verify_signature_does_not_require_auth" time="0.019"><failure message="AssertionError: {"success":false,"error":{"code":"NOT_FOUND","message":"config not found: encrypt_key","trace_id":"1d60b3be44404678bca3adb5248ef019","details":{"resource":"config","id":"encrypt_key"}}} assert 404 in (200, 501) + where 404 = <Response [404 Not Found]>.status_code">test/integration/api/channels/test_webhook_router.py:76: in test_verify_signature_does_not_require_auth
|
|
assert response.status_code in (200, 501), response.text
|
|
E AssertionError: {"success":false,"error":{"code":"NOT_FOUND","message":"config not found: encrypt_key","trace_id":"1d60b3be44404678bca3adb5248ef019","details":{"resource":"config","id":"encrypt_key"}}}
|
|
E assert 404 in (200, 501)
|
|
E + where 404 = <Response [404 Not Found]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_webhook_router" name="test_verify_signature_with_valid_body_returns_200_or_501" time="0.013"><failure message="AssertionError: {"success":false,"error":{"code":"NOT_FOUND","message":"config not found: encrypt_key","trace_id":"1bf8262d0d55470cba16de5b62e2ea6c","details":{"resource":"config","id":"encrypt_key"}}} assert 404 in (200, 501) + where 404 = <Response [404 Not Found]>.status_code">test/integration/api/channels/test_webhook_router.py:93: in test_verify_signature_with_valid_body_returns_200_or_501
|
|
assert response.status_code in (200, 501), response.text
|
|
E AssertionError: {"success":false,"error":{"code":"NOT_FOUND","message":"config not found: encrypt_key","trace_id":"1bf8262d0d55470cba16de5b62e2ea6c","details":{"resource":"config","id":"encrypt_key"}}}
|
|
E assert 404 in (200, 501)
|
|
E + where 404 = <Response [404 Not Found]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_webhook_router" name="test_verify_signature_rejects_empty_raw_event" time="0.013" /><testcase classname="test.integration.api.channels.test_webhook_router" name="test_webhook_test_requires_auth" time="0.016" /><testcase classname="test.integration.api.channels.test_webhook_router" name="test_webhook_test_requires_admin" time="0.149" /><testcase classname="test.integration.api.channels.test_webhook_router" name="test_admin_can_test_webhook_returns_200_or_501" time="0.028" /><testcase classname="test.integration.api.channels.test_webhook_router" name="test_webhook_test_with_valid_body_returns_200_or_501" time="0.027" /><testcase classname="test.integration.api.channels.test_webhook_router" name="test_webhook_unregistered_channel_type" time="0.012" /><testcase classname="test.integration.api.channels.test_wizard_router" name="test_list_wizard_steps_requires_auth" time="0.024" /><testcase classname="test.integration.api.channels.test_wizard_router" name="test_list_wizard_steps_requires_admin" time="0.158" /><testcase classname="test.integration.api.channels.test_wizard_router" name="test_admin_can_list_wizard_steps_returns_200_or_404_or_501" time="0.030" /><testcase classname="test.integration.api.channels.test_wizard_router" name="test_wizard_validate_returns_200_or_404_or_501" time="0.032" /><testcase classname="test.integration.api.channels.test_wizard_router" name="test_wizard_validate_rejects_empty_step_id" time="0.011" /><testcase classname="test.integration.api.channels.test_wizard_router" name="test_wizard_apply_returns_200_or_404_or_501" time="0.031" /><testcase classname="test.integration.api.channels.test_wizard_router" name="test_wizard_finalize_returns_200_or_404_or_501" time="0.032" /><testcase classname="test.integration.api.channels.test_wizard_router" name="test_wizard_finalize_rejects_empty_patches" time="0.014" /><testcase classname="test.integration.api.channels.test_wizard_router" name="test_oauth_initiate_rejects_invalid_redirect_uri_scheme" time="0.072"><failure message="AssertionError: {"success":false,"error":{"code":"INTERNAL","message":"Internal server error","trace_id":null,"details":{}}} assert 500 == 422 + where 500 = <Response [500 Internal Server Error]>.status_code">test/integration/api/channels/test_wizard_router.py:178: in test_oauth_initiate_rejects_invalid_redirect_uri_scheme
|
|
assert response.status_code == 422, response.text
|
|
E AssertionError: {"success":false,"error":{"code":"INTERNAL","message":"Internal server error","trace_id":null,"details":{}}}
|
|
E assert 500 == 422
|
|
E + where 500 = <Response [500 Internal Server Error]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_wizard_router" name="test_oauth_initiate_with_valid_params_returns_404_or_501_or_400" time="0.025" /><testcase classname="test.integration.api.channels.test_wizard_router" name="test_oauth_callback_requires_code" time="0.018" /><testcase classname="test.integration.api.channels.test_wizard_router" name="test_oauth_callback_requires_state" time="0.014" /><testcase classname="test.integration.api.channels.test_wizard_router" name="test_oauth_callback_requires_redirect_uri" time="0.014" /><testcase classname="test.integration.api.channels.test_wizard_router" name="test_oauth_callback_rejects_invalid_redirect_uri_scheme" time="0.047"><failure message="AssertionError: {"success":false,"error":{"code":"INTERNAL","message":"Internal server error","trace_id":null,"details":{}}} assert 500 == 422 + where 500 = <Response [500 Internal Server Error]>.status_code">test/integration/api/channels/test_wizard_router.py:258: in test_oauth_callback_rejects_invalid_redirect_uri_scheme
|
|
assert response.status_code == 422, response.text
|
|
E AssertionError: {"success":false,"error":{"code":"INTERNAL","message":"Internal server error","trace_id":null,"details":{}}}
|
|
E assert 500 == 422
|
|
E + where 500 = <Response [500 Internal Server Error]>.status_code</failure></testcase><testcase classname="test.integration.api.channels.test_wizard_router" name="test_oauth_callback_with_all_params_returns_404_or_501_or_400" time="0.029" /><testcase classname="test.integration.api.channels.test_wizard_router" name="test_wizard_unregistered_channel_type" time="0.063" /></testsuite></testsuites> |