diff --git a/posthog/tasks/exports/csv_exporter.py b/posthog/tasks/exports/csv_exporter.py index 90bcf28d8985e..870f3615c0505 100644 --- a/posthog/tasks/exports/csv_exporter.py +++ b/posthog/tasks/exports/csv_exporter.py @@ -84,13 +84,6 @@ def add_query_params(url: str, params: dict[str, str]) -> str: def _convert_response_to_csv_data(data: Any) -> Generator[Any, None, None]: if isinstance(data.get("results"), list): results = data.get("results") - elif isinstance(data.get("result"), list): - results = data.get("result") - else: - return None - - if isinstance(data.get("results"), list): - # query like if len(results) > 0 and (isinstance(results[0], list) or isinstance(results[0], tuple)) and data.get("types"): # e.g. {'columns': ['count()'], 'hasMore': False, 'results': [[1775]], 'types': ['UInt64']} # or {'columns': ['count()', 'event'], 'hasMore': False, 'results': [[551, '$feature_flag_called'], [265, '$autocapture']], 'types': ['UInt64', 'String']} @@ -112,6 +105,13 @@ def _convert_response_to_csv_data(data: Any) -> Generator[Any, None, None]: yield row_dict return + if isinstance(data.get("results"), list) or isinstance(data.get("results"), dict): + results = data.get("results") + elif isinstance(data.get("result"), list) or isinstance(data.get("result"), dict): + results = data.get("result") + else: + return None + if isinstance(results, list): first_result = next(iter(results), None) diff --git a/posthog/tasks/exports/test/test_csv_exporter.py b/posthog/tasks/exports/test/test_csv_exporter.py index 07af2c01cede6..bb6ec39715718 100644 --- a/posthog/tasks/exports/test/test_csv_exporter.py +++ b/posthog/tasks/exports/test/test_csv_exporter.py @@ -27,6 +27,7 @@ from posthog.tasks.exports.csv_exporter import ( UnexpectedEmptyJsonResponse, add_query_params, + _convert_response_to_csv_data, ) from posthog.hogql.constants import CSV_EXPORT_BREAKDOWN_LIMIT_INITIAL from posthog.test.base import APIBaseTest, _create_event, flush_persons_and_events, _create_person @@ -557,6 +558,47 @@ def test_csv_exporter_funnels_query(self, mocked_uuidt: Any, MAX_SELECT_RETURNED ], ) + def test_funnel_time_to_convert(self) -> None: + bins = [ + [1, 1], + [2, 3], + [3, 5], + [4, 17], + [5, 29], + [6, 44], + [7, 38], + [8, 24], + [9, 10], + [10, 7], + [11, 3], + [12, 1], + [13, 1], + [14, 1], + [15, 0], + [16, 0], + [17, 0], + [18, 0], + [19, 0], + [20, 0], + [21, 1], + [22, 0], + [23, 1], + [24, 0], + [25, 0], + [26, 0], + ] + data = { + "results": { + "average_conversion_time": 1.45, + "bins": bins, + } + } + csv_list = list(_convert_response_to_csv_data(data)) + assert len(bins) == len(csv_list) + for bin, csv in zip(bins, csv_list): + assert bin[0] == csv["bin"] + assert bin[1] == csv["value"] + @patch("posthog.models.exported_asset.UUIDT") def test_csv_exporter_empty_result(self, mocked_uuidt: Any) -> None: exported_asset = ExportedAsset(