|
1 | 1 | # (C) 2026 GoodData Corporation |
2 | 2 | from __future__ import annotations |
3 | 3 |
|
4 | | -from pathlib import Path |
5 | | - |
6 | | -from gooddata_sdk import Attribute, ExecutionResultLimitBreak, GoodDataSdk, ObjId, SimpleMetric |
7 | | -from gooddata_sdk.compute.model.execution import ExecutionDefinition, TableDimension |
8 | | -from tests_support.vcrpy_utils import get_vcr |
9 | | - |
10 | | -gd_vcr = get_vcr() |
11 | | - |
12 | | -_current_dir = Path(__file__).parent.absolute() |
13 | | -_fixtures_dir = _current_dir / "fixtures" |
| 4 | +from unittest.mock import MagicMock |
| 5 | + |
| 6 | +from gooddata_sdk import ExecutionResultLimitBreak |
| 7 | +from gooddata_sdk.compute.model.execution import ExecutionResult |
| 8 | + |
| 9 | + |
| 10 | +def _make_mock_api_result(limit_breaks_value): |
| 11 | + """Return a mock that mimics a models.ExecutionResult dict-like object.""" |
| 12 | + _paging = {"total": [10, 1], "count": [10, 1], "offset": [0, 0]} |
| 13 | + m = MagicMock() |
| 14 | + m.__getitem__ = MagicMock( |
| 15 | + side_effect=lambda k: { |
| 16 | + "data": [], |
| 17 | + "dimension_headers": [], |
| 18 | + "grand_totals": [], |
| 19 | + "paging": _paging, |
| 20 | + "metadata": {}, |
| 21 | + }[k] |
| 22 | + ) |
| 23 | + m.get = MagicMock(side_effect=lambda k, d=None: limit_breaks_value if k == "limitBreaks" else d) |
| 24 | + return m |
14 | 25 |
|
15 | 26 |
|
16 | | -@gd_vcr.use_cassette(str(_fixtures_dir / "test_execution_result_limit_breaks.yaml")) |
17 | | -def test_execution_result_limit_breaks(test_config): |
18 | | - """ExecutionResult.limit_breaks returns a list; empty when no limit is broken. |
| 27 | +def test_execution_result_limit_breaks(): |
| 28 | + """ExecutionResult.limit_breaks returns a list; non-empty when limits are broken. |
19 | 29 |
|
20 | 30 | For a normal execution the result is complete so limit_breaks must be []. |
21 | 31 | This test also verifies that the field is importable from gooddata_sdk and |
22 | 32 | that the ExecutionResultLimitBreak class is available on the public API. |
| 33 | +
|
| 34 | + Uses a synthetic mock result to avoid staging-server dependency. |
23 | 35 | """ |
24 | | - sdk = GoodDataSdk.create(host_=test_config["host"], token_=test_config["token"]) |
25 | | - workspace_id = test_config["workspace"] |
26 | | - |
27 | | - exec_def = ExecutionDefinition( |
28 | | - attributes=[Attribute(local_id="a1", label="region")], |
29 | | - metrics=[SimpleMetric(local_id="m1", item=ObjId(type="metric", id="order_amount"))], |
30 | | - filters=[], |
31 | | - dimensions=[ |
32 | | - TableDimension(item_ids=["a1"]), |
33 | | - TableDimension(item_ids=["measureGroup"]), |
34 | | - ], |
| 36 | + # --- Case 1: result where a row-count limit was broken --- |
| 37 | + result = ExecutionResult( |
| 38 | + _make_mock_api_result([{"limit": 1000, "limitType": "rowCount", "value": 1500}]) |
35 | 39 | ) |
36 | | - execution = sdk.compute.for_exec_def(workspace_id=workspace_id, exec_def=exec_def) |
37 | | - result = execution.read_result(limit=[100, 100], offset=[0, 0]) |
38 | | - |
39 | 40 | assert isinstance(result.limit_breaks, list) |
| 41 | + assert len(result.limit_breaks) == 1 |
40 | 42 | for lb in result.limit_breaks: |
41 | 43 | assert isinstance(lb, ExecutionResultLimitBreak) |
42 | 44 | assert isinstance(lb.limit, int) |
43 | 45 | assert isinstance(lb.limit_type, str) |
44 | 46 | assert lb.value is None or isinstance(lb.value, int) |
| 47 | + |
| 48 | + # --- Case 2: complete result — no limits broken --- |
| 49 | + result_complete = ExecutionResult(_make_mock_api_result(None)) |
| 50 | + assert isinstance(result_complete.limit_breaks, list) |
| 51 | + assert result_complete.limit_breaks == [] |
0 commit comments