        binary: bool | None = None,
    ) -> Self:
        """
        Execute a query or command to the database.
        """
        try:
            with self._conn.lock:
                self._conn.wait(
                    self._execute_gen(query, params, prepare=prepare, binary=binary)
                )
        except e._NO_TRACEBACK as ex:
>           raise ex.with_traceback(None)
E           psycopg.errors.ForeignKeyViolation: insert or update on table "recipient_lists" violates foreign key constraint "recipient_lists_user_id_fkey"
E           DETAIL:  Key (user_id)=(331) is not present in table "users".

/usr/local/lib/python3.11/site-packages/psycopg/cursor.py:97: ForeignKeyViolation

The above exception was the direct cause of the following exception:

self = <tests.test_sse_dashboard.TestSSEStreamTerminalStates object at 0x7fd6c1206010>
api = <starlette.testclient.TestClient object at 0x7fd6ba2c5790>
db = <sqlalchemy.orm.session.Session object at 0x7fd6b9faa3d0>
second_user = <starlette.testclient.TestClient object at 0x7fd6bad33a90>

    def test_stream_requires_ownership(self, api, db, second_user):
>       f = _seed_campaign_fixture(db, user_id_of(api))

tests/test_sse_dashboard.py:351: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/test_sse_dashboard.py:76: in _seed_campaign_fixture
    db.flush()
/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/session.py:4352: in flush
    self._flush(objects)
/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/session.py:4487: in _flush
    with util.safe_reraise():
/usr/local/lib/python3.11/site-packages/sqlalchemy/util/langhelpers.py:146: in __exit__
    raise exc_value.with_traceback(exc_tb)
/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/session.py:4448: in _flush
    flush_context.execute()
/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/unitofwork.py:466: in execute
    rec.execute(self)
/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/unitofwork.py:642: in execute
    util.preloaded.orm_persistence.save_obj(
/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/persistence.py:93: in save_obj
    _emit_insert_statements(
/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/persistence.py:1233: in _emit_insert_statements
    result = connection.execute(
/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py:1418: in execute
    return meth(
/usr/local/lib/python3.11/site-packages/sqlalchemy/sql/elements.py:515: in _execute_on_connection
    return connection._execute_clauseelement(
/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py:1640: in _execute_clauseelement
    ret = self._execute_context(
/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py:1846: in _execute_context
    return self._exec_single_context(
/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py:1986: in _exec_single_context
    self._handle_dbapi_exception(
/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py:2355: in _handle_dbapi_exception
    raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/base.py:1967: in _exec_single_context
    self.dialect.do_execute(
/usr/local/lib/python3.11/site-packages/sqlalchemy/engine/default.py:941: in do_execute
    cursor.execute(statement, parameters)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <psycopg.Cursor [closed] [IDLE] (host=localhost user=mailer database=bulkmailer_test_709a3a2f) at 0x7fd6ba969220>
query = 'INSERT INTO recipient_lists (user_id, name, description, source, row_count, created_at, updated_at) VALUES (%(user_id...EGER, %(created_at)s::TIMESTAMP WITH TIME ZONE, %(updated_at)s::TIMESTAMP WITH TIME ZONE) RETURNING recipient_lists.id'
params = {'created_at': datetime.datetime(2026, 9, 11, 17, 42, 12, 902106, tzinfo=datetime.timezone.utc), 'description': '', 'name': 'dash-list-f5620a', 'row_count': 0, ...}

    def execute(
        self,
        query: Query,
        params: Params | None = None,
        *,
        prepare: bool | None = None,
        binary: bool | None = None,
    ) -> Self:
        """
        Execute a query or command to the database.
        """
        try:
            with self._conn.lock:
                self._conn.wait(
                    self._execute_gen(query, params, prepare=prepare, binary=binary)
                )
        except e._NO_TRACEBACK as ex:
>           raise ex.with_traceback(None)
E           sqlalchemy.exc.IntegrityError: (psycopg.errors.ForeignKeyViolation) insert or update on table "recipient_lists" violates foreign key constraint "recipient_lists_user_id_fkey"
E           DETAIL:  Key (user_id)=(331) is not present in table "users".
E           [SQL: INSERT INTO recipient_lists (user_id, name, description, source, row_count, created_at, updated_at) VALUES (%(user_id)s::INTEGER, %(name)s::VARCHAR, %(description)s::VARCHAR, %(source)s::VARCHAR, %(row_count)s::INTEGER, %(created_at)s::TIMESTAMP WITH TIME ZONE, %(updated_at)s::TIMESTAMP WITH TIME ZONE) RETURNING recipient_lists.id]
E           [parameters: {'user_id': 331, 'name': 'dash-list-f5620a', 'description': '', 'source': 'manual', 'row_count': 0, 'created_at': datetime.datetime(2026, 9, 11, 17, 42, 12, 902106, tzinfo=datetime.timezone.utc), 'updated_at': datetime.datetime(2026, 9, 11, 17, 42, 12, 902112, tzinfo=datetime.timezone.utc)}]
E           (Background on this error at: https://sqlalche.me/e/20/gkpj)

/usr/local/lib/python3.11/site-packages/psycopg/cursor.py:97: IntegrityError
=============================== warnings summary ===============================
app/api/routers/test_send.py:27
  /workspace/bulkmailer/app/api/routers/test_send.py:27: PytestCollectionWarning: cannot collect test class 'TestSendIn' because it has a __init__ constructor (from: app/api/routers/test_send.py)
    class TestSendIn(BaseModel):

app/api/routers/test_send.py::test_accounts
app/api/routers/test_send.py::test_templates
  /usr/local/lib/python3.11/site-packages/_pytest/python.py:148: PytestUnhandledCoroutineWarning: async def functions are not natively supported and have been skipped.
  You need to install a suitable plugin for your async framework, for example:
    - anyio
    - pytest-asyncio
    - pytest-tornasync
    - pytest-trio
    - pytest-twisted
    warnings.warn(PytestUnhandledCoroutineWarning(msg.format(nodeid)))

tests/test_api_attachments_phones_suppression_settings_logs.py: 3 warnings
tests/test_api_recipients_subjects_templates.py: 1 warning
tests/test_message_builder.py: 9 warnings
tests/test_send_one_task.py: 15 warnings
  /usr/local/lib/python3.11/site-packages/bs4/builder/_lxml.py:124: DeprecationWarning: The 'strip_cdata' option of HTMLParser() has never done anything and will eventually be removed.
    parser = parser(

tests/test_api_attachments_phones_suppression_settings_logs.py: 2 warnings
tests/test_api_recipients_subjects_templates.py: 2 warnings
tests/test_message_builder.py: 8 warnings
tests/test_send_one_task.py: 2 warnings
  /usr/local/lib/python3.11/site-packages/pydyf/__init__.py:404: DeprecationWarning: transform is deprecated, use set_matrix instead.
    warn(Stream.transform.__doc__, DeprecationWarning)

tests/test_api_attachments_phones_suppression_settings_logs.py: 1 warning
tests/test_api_recipients_subjects_templates.py: 2 warnings
tests/test_message_builder.py: 5 warnings
tests/test_send_one_task.py: 3 warnings
  /usr/local/lib/python3.11/site-packages/pydyf/__init__.py:399: DeprecationWarning: text_matrix is deprecated, use set_text_matrix instead.
    warn(Stream.text_matrix.__doc__, DeprecationWarning)

tests/test_api_recipients_subjects_templates.py::TestTemplatesApi::test_create_list_preview_duplicate_delete
tests/test_message_builder.py::TestSanitization::test_script_neutralized
tests/test_message_builder.py::TestSanitization::test_script_content_cannot_reexecute
tests/test_message_builder.py::TestSanitization::test_style_and_links_kept
tests/test_message_builder.py::TestSanitization::test_email_variant_matches_preview
tests/test_message_builder.py::TestSanitization::test_table_markup_kept_for_invoice_layouts
  /usr/local/lib/python3.11/site-packages/bleach/sanitizer.py:166: NoCssSanitizerWarning: 'style' attribute specified, but css_sanitizer not set.
    warnings.warn(

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestAccountsApi::test_seeded_account_shape
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestAccountsApi::test_patch_updates_limits_and_method
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestAccountsApi::test_reauthorize_without_config_400
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestAccountsApi::test_revoke_and_delete_account
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestAccountsApi::test_revoke_deletes_token_row_and_sets_flags
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestAccountsApi::test_clear_all
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestAccountsApi::test_account_isolation
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestTestSendApi::test_account_listing_authorized_only
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestTestSendApi::test_templates_listing
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestTestSendApi::test_send_without_oauth_token_honest_failure
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestTestSendApi::test_send_expired_account_409
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestTestSendApi::test_send_requires_body_or_template
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestTestSendApi::test_send_substitutes_variables_before_send
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestTestSendApi::test_send_csrf_and_auth
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestUnsubscribeApi::test_landing_page_shows_email_and_form
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestUnsubscribeApi::test_confirm_adds_suppression_and_event
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestUnsubscribeApi::test_confirm_without_campaign_context_still_suppresses
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestUnsubscribeApi::test_confirm_idempotent_no_duplicate_suppression
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestUnsubscribeApi::test_landing_already_unsubscribed_message
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestUnsubscribeApi::test_status_json
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestUnsubscribeApi::test_public_flow_needs_no_auth
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_wizard_options_lists_everything
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_create_and_get
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_create_validation_errors_are_specific
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_create_rejects_weights_without_weighted_strategy
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_patch_campaign
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_patch_rejected_while_running
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_delete_and_clear_all
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_list_filters
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_preview_renders_real_messages
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_preview_requires_list_with_valid_recipients
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_start_materializes_and_queues
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_pause_resume_cancel_flow
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_pause_non_running_409
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_resume_requires_pending
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_progress_after_start
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_recipients_monitor_table
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_export_csv
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_sse_stream_first_events
FAILED tests/test_api_accounts_campaigns_testsend_unsubscribe.py::TestCampaignsApi::test_campaign_isolation
FAILED tests/test_api_attachments_phones_suppression_settings_logs.py::TestSettingsApi::test_reset_and_reset_all
FAILED tests/test_api_attachments_phones_suppression_settings_logs.py::TestLogsApi::test_list_shape_and_filters
FAILED tests/test_api_attachments_phones_suppression_settings_logs.py::TestLogsApi::test_events_endpoint
FAILED tests/test_api_attachments_phones_suppression_settings_logs.py::TestLogsApi::test_export_csv
FAILED tests/test_api_attachments_phones_suppression_settings_logs.py::TestLogsApi::test_recipient_history_seeded
FAILED tests/test_sse_dashboard.py::TestProgressEndpoint::test_progress_shape_draft_campaign
FAILED tests/test_sse_dashboard.py::TestProgressEndpoint::test_progress_requires_ownership
FAILED tests/test_sse_dashboard.py::TestProgressEndpoint::test_progress_reflects_manual_status_transitions
FAILED tests/test_sse_dashboard.py::TestRecipientsMonitor::test_status_filter_matches_only_that_status
FAILED tests/test_sse_dashboard.py::TestRecipientsMonitor::test_search_matches_email_substring_case_insensitive
FAILED tests/test_sse_dashboard.py::TestRecipientsMonitor::test_recipients_requires_ownership
FAILED tests/test_sse_dashboard.py::TestRecipientsMonitor::test_recipients_empty_before_start
FAILED tests/test_sse_dashboard.py::TestSSEStreamTerminalStates::test_stream_terminates_on_cancelled
FAILED tests/test_sse_dashboard.py::TestSSEStreamTerminalStates::test_stream_terminates_on_failed
FAILED tests/test_sse_dashboard.py::TestSSEStreamTerminalStates::test_stream_does_not_emit_done_while_running
FAILED tests/test_sse_dashboard.py::TestSSEStreamTerminalStates::test_stream_progress_payload_matches_progress_endpoint_shape
FAILED tests/test_sse_dashboard.py::TestSSEStreamTerminalStates::test_stream_requires_ownership
57 failed, 309 passed, 11 skipped, 62 warnings in 155.47s (0:02:35)
