feat(expenses): backfill historical claims into expense cases
This commit is contained in:
225
server/tests/test_maintenance_database_target.py
Normal file
225
server/tests/test_maintenance_database_target.py
Normal file
@@ -0,0 +1,225 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from app.db.maintenance_database_target import (
|
||||
MaintenanceDatabaseTargetError,
|
||||
is_disposable_maintenance_target,
|
||||
parse_maintenance_database_target,
|
||||
validate_maintenance_database_target,
|
||||
)
|
||||
|
||||
|
||||
def assert_target_error(code: str, callback) -> None:
|
||||
with pytest.raises(MaintenanceDatabaseTargetError) as exc_info:
|
||||
callback()
|
||||
assert exc_info.value.code == code
|
||||
|
||||
|
||||
def test_parse_target_supports_hostname_and_hides_password() -> None:
|
||||
target = parse_maintenance_database_target(
|
||||
"postgresql+psycopg://finance:super-secret@db.internal:5544/x_financial"
|
||||
"?application_name=backfill",
|
||||
expected_host="DB.INTERNAL.",
|
||||
expected_database="x_financial",
|
||||
)
|
||||
|
||||
assert target.host == "db.internal"
|
||||
assert target.port == 5544
|
||||
assert target.database == "x_financial"
|
||||
assert target.username == "finance"
|
||||
assert target.exact_target == "db.internal:5544/x_financial"
|
||||
assert "super-secret" not in target.sanitized_url
|
||||
assert "***" in target.sanitized_url
|
||||
assert "application_name=backfill" in target.sanitized_url
|
||||
assert target.is_disposable is False
|
||||
|
||||
|
||||
def test_parse_target_supports_ipv4_and_defaults_postgresql_port() -> None:
|
||||
target = parse_maintenance_database_target(
|
||||
"postgresql://finance:password@127.0.0.1/x_financial",
|
||||
expected_host="127.0.0.1",
|
||||
expected_database="x_financial",
|
||||
)
|
||||
|
||||
assert target.port == 5432
|
||||
assert target.exact_target == "127.0.0.1:5432/x_financial"
|
||||
assert "password" not in target.sanitized_url
|
||||
|
||||
|
||||
def test_parse_target_redacts_sensitive_query_values() -> None:
|
||||
target = parse_maintenance_database_target(
|
||||
"postgresql://finance:authority-secret@db.internal/x_financial"
|
||||
"?sslpassword=query-secret&application_name=safe-name",
|
||||
expected_host="db.internal",
|
||||
expected_database="x_financial",
|
||||
)
|
||||
|
||||
assert "authority-secret" not in target.sanitized_url
|
||||
assert "query-secret" not in target.sanitized_url
|
||||
assert "application_name=safe-name" in target.sanitized_url
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"routing_query",
|
||||
[
|
||||
"host=x-financial-local-postgres",
|
||||
"port=6432",
|
||||
"dbname=production",
|
||||
"user=other-user",
|
||||
"service=production-service",
|
||||
"options=-csearch_path%3Dother_schema",
|
||||
],
|
||||
)
|
||||
def test_parse_target_rejects_query_parameters_that_can_override_route(
|
||||
routing_query: str,
|
||||
) -> None:
|
||||
assert_target_error(
|
||||
"database_routing_query_forbidden",
|
||||
lambda: parse_maintenance_database_target(
|
||||
f"postgresql://finance:password@migration-probe/migration_probe?{routing_query}",
|
||||
expected_host="migration-probe",
|
||||
expected_database="migration_probe",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("database_url", "code"),
|
||||
[
|
||||
("", "database_url_required"),
|
||||
("not a database url", "invalid_database_url"),
|
||||
("sqlite:///tmp/test.db", "postgresql_required"),
|
||||
("postgresql:///x_financial", "database_host_required"),
|
||||
("postgresql://finance@db.internal", "database_name_required"),
|
||||
],
|
||||
)
|
||||
def test_parse_target_rejects_invalid_or_incomplete_urls(database_url: str, code: str) -> None:
|
||||
assert_target_error(
|
||||
code,
|
||||
lambda: parse_maintenance_database_target(
|
||||
database_url,
|
||||
expected_host="db.internal",
|
||||
expected_database="x_financial",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("expected_host", "expected_database", "code"),
|
||||
[
|
||||
("", "x_financial", "expected_host_required"),
|
||||
("other-db", "x_financial", "expected_host_mismatch"),
|
||||
("db.internal", "", "expected_database_required"),
|
||||
("db.internal", "other_database", "expected_database_mismatch"),
|
||||
],
|
||||
)
|
||||
def test_parse_target_rejects_expected_target_mismatches(
|
||||
expected_host: str,
|
||||
expected_database: str,
|
||||
code: str,
|
||||
) -> None:
|
||||
assert_target_error(
|
||||
code,
|
||||
lambda: parse_maintenance_database_target(
|
||||
"postgresql://finance:password@db.internal/x_financial",
|
||||
expected_host=expected_host,
|
||||
expected_database=expected_database,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("host", "database", "expected"),
|
||||
[
|
||||
("migration-probe", "migration_probe", True),
|
||||
("x-financial-migration-probe-123", "migration_probe_clone_123", True),
|
||||
("disposable-probe-7", "disposable_probe_7", True),
|
||||
("x-financial-local-postgres", "migration_probe", False),
|
||||
("migration-probe-7", "x_financial", False),
|
||||
],
|
||||
)
|
||||
def test_disposable_target_requires_markers_on_host_and_database(
|
||||
host: str,
|
||||
database: str,
|
||||
expected: bool,
|
||||
) -> None:
|
||||
assert is_disposable_maintenance_target(host=host, database=database) is expected
|
||||
|
||||
|
||||
def test_dry_run_allows_non_disposable_target_without_apply_override() -> None:
|
||||
target = validate_maintenance_database_target(
|
||||
"postgresql://finance:password@db.internal/x_financial",
|
||||
expected_host="db.internal",
|
||||
expected_database="x_financial",
|
||||
apply=False,
|
||||
)
|
||||
|
||||
assert target.is_disposable is False
|
||||
|
||||
|
||||
def test_apply_allows_disposable_target_without_non_disposable_override() -> None:
|
||||
target = validate_maintenance_database_target(
|
||||
"postgresql://finance:password@x-financial-migration-probe-1/migration_probe_1",
|
||||
expected_host="x-financial-migration-probe-1",
|
||||
expected_database="migration_probe_1",
|
||||
apply=True,
|
||||
)
|
||||
|
||||
assert target.is_disposable is True
|
||||
|
||||
|
||||
def test_apply_rejects_wrong_optional_confirmation_for_disposable_target() -> None:
|
||||
assert_target_error(
|
||||
"confirm_target_mismatch",
|
||||
lambda: validate_maintenance_database_target(
|
||||
"postgresql://finance:password@migration-probe/migration_probe",
|
||||
expected_host="migration-probe",
|
||||
expected_database="migration_probe",
|
||||
apply=True,
|
||||
confirm_target="other:5432/migration_probe",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_apply_rejects_non_disposable_target_without_explicit_override() -> None:
|
||||
assert_target_error(
|
||||
"non_disposable_apply_forbidden",
|
||||
lambda: validate_maintenance_database_target(
|
||||
"postgresql://finance:password@db.internal/x_financial",
|
||||
expected_host="db.internal",
|
||||
expected_database="x_financial",
|
||||
apply=True,
|
||||
confirm_target="db.internal:5432/x_financial",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("confirm_target", [None, "", "db.internal:5432/other_database"])
|
||||
def test_apply_rejects_non_disposable_target_without_exact_confirmation(
|
||||
confirm_target: str | None,
|
||||
) -> None:
|
||||
assert_target_error(
|
||||
"confirm_target_mismatch",
|
||||
lambda: validate_maintenance_database_target(
|
||||
"postgresql://finance:password@db.internal/x_financial",
|
||||
expected_host="db.internal",
|
||||
expected_database="x_financial",
|
||||
apply=True,
|
||||
allow_non_disposable=True,
|
||||
confirm_target=confirm_target,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def test_apply_allows_non_disposable_target_with_override_and_exact_confirmation() -> None:
|
||||
target = validate_maintenance_database_target(
|
||||
"postgresql://finance:password@db.internal/x_financial",
|
||||
expected_host="db.internal",
|
||||
expected_database="x_financial",
|
||||
apply=True,
|
||||
allow_non_disposable=True,
|
||||
confirm_target="db.internal:5432/x_financial",
|
||||
)
|
||||
|
||||
assert target.exact_target == "db.internal:5432/x_financial"
|
||||
Reference in New Issue
Block a user