|
1 | 1 | import socket |
2 | 2 |
|
3 | 3 | import pytest |
| 4 | +from clickhouse_driver import errors as clickhouse_errors |
4 | 5 | from django.urls import reverse |
5 | 6 | from pytest_django.fixtures import SettingsWrapper |
6 | 7 | from pytest_mock import MockerFixture |
@@ -1090,7 +1091,13 @@ def test_test_warehouse_connection__non_admin__returns_403( |
1090 | 1091 |
|
1091 | 1092 | @pytest.mark.parametrize( |
1092 | 1093 | "action", |
1093 | | - ["create", "update", "partial_update", "test_warehouse_connection"], |
| 1094 | + [ |
| 1095 | + "create", |
| 1096 | + "update", |
| 1097 | + "partial_update", |
| 1098 | + "test_warehouse_connection", |
| 1099 | + "test_warehouse_connection_config", |
| 1100 | + ], |
1094 | 1101 | ) |
1095 | 1102 | def test_get_throttles__write_actions__returns_scoped_throttle(action: str) -> None: |
1096 | 1103 | # Given |
@@ -1666,6 +1673,74 @@ def test_test_warehouse_connection__clickhouse__reverifies_and_returns_status( |
1666 | 1673 | assert clickhouse_connection.status == WarehouseConnectionStatus.CONNECTED |
1667 | 1674 |
|
1668 | 1675 |
|
| 1676 | +CLICKHOUSE_TEST_PAYLOAD = { |
| 1677 | + "warehouse_type": "clickhouse", |
| 1678 | + "config": {"host": "ch.example.com"}, |
| 1679 | + "credentials": {"password": "hunter2"}, |
| 1680 | +} |
| 1681 | + |
| 1682 | + |
| 1683 | +@pytest.mark.parametrize( |
| 1684 | + "data, client_side_effect, expected_status_code, expected_response", |
| 1685 | + [ |
| 1686 | + pytest.param( |
| 1687 | + CLICKHOUSE_TEST_PAYLOAD, |
| 1688 | + None, |
| 1689 | + status.HTTP_200_OK, |
| 1690 | + {"status": "connected", "status_detail": None}, |
| 1691 | + id="reachable", |
| 1692 | + ), |
| 1693 | + pytest.param( |
| 1694 | + CLICKHOUSE_TEST_PAYLOAD, |
| 1695 | + clickhouse_errors.NetworkError("boom"), |
| 1696 | + status.HTTP_200_OK, |
| 1697 | + {"status": "errored", "status_detail": "Could not connect to the host."}, |
| 1698 | + id="unreachable", |
| 1699 | + ), |
| 1700 | + pytest.param( |
| 1701 | + {"warehouse_type": "flagsmith"}, |
| 1702 | + None, |
| 1703 | + status.HTTP_400_BAD_REQUEST, |
| 1704 | + {"detail": "Connection testing is not supported for this warehouse type."}, |
| 1705 | + id="non_clickhouse_type", |
| 1706 | + ), |
| 1707 | + pytest.param( |
| 1708 | + {"warehouse_type": "clickhouse", "config": {"host": "ch.example.com"}}, |
| 1709 | + None, |
| 1710 | + status.HTTP_400_BAD_REQUEST, |
| 1711 | + {"credentials": {"password": "This field is required."}}, |
| 1712 | + id="invalid_payload", |
| 1713 | + ), |
| 1714 | + ], |
| 1715 | +) |
| 1716 | +def test_test_warehouse_connection_config__payload__returns_expected_response( |
| 1717 | + admin_client: APIClient, |
| 1718 | + client_side_effect: Exception | None, |
| 1719 | + data: dict[str, object], |
| 1720 | + enable_features: EnableFeaturesFixture, |
| 1721 | + environment: Environment, |
| 1722 | + expected_response: dict[str, object], |
| 1723 | + expected_status_code: int, |
| 1724 | + mocker: MockerFixture, |
| 1725 | +) -> None: |
| 1726 | + # Given |
| 1727 | + enable_features("experimentation_warehouse_connection") |
| 1728 | + mocker.patch("experimentation.services.Client", side_effect=client_side_effect) |
| 1729 | + url = reverse( |
| 1730 | + "api-v1:environments:experimentation:" |
| 1731 | + "warehouse-connections-test-warehouse-connection-config", |
| 1732 | + args=[environment.api_key], |
| 1733 | + ) |
| 1734 | + |
| 1735 | + # When |
| 1736 | + response = admin_client.post(url, data=data, format="json") |
| 1737 | + |
| 1738 | + # Then |
| 1739 | + assert response.status_code == expected_status_code |
| 1740 | + assert response.json() == expected_response |
| 1741 | + assert not WarehouseConnection.objects.filter(environment=environment).exists() |
| 1742 | + |
| 1743 | + |
1669 | 1744 | def test_patch__clickhouse_to_flagsmith__resets_connection_state( |
1670 | 1745 | admin_client: APIClient, |
1671 | 1746 | clickhouse_connection: WarehouseConnection, |
|
0 commit comments