|
32 | 32 | ConcurrentDeclarativeSource, |
33 | 33 | ) |
34 | 34 | from airbyte_cdk.sources.declarative.declarative_stream import DeclarativeStream |
| 35 | +from airbyte_cdk.sources.declarative.extractors.record_filter import ( |
| 36 | + ClientSideIncrementalRecordFilterDecorator, |
| 37 | +) |
35 | 38 | from airbyte_cdk.sources.declarative.partition_routers import AsyncJobPartitionRouter |
36 | 39 | from airbyte_cdk.sources.declarative.stream_slicers.declarative_partition_generator import ( |
37 | 40 | StreamSlicerPartitionGenerator, |
@@ -1647,6 +1650,44 @@ def test_async_incremental_stream_uses_concurrent_cursor_with_state(): |
1647 | 1650 | assert async_job_partition_router.stream_slicer._concurrent_state == expected_state |
1648 | 1651 |
|
1649 | 1652 |
|
| 1653 | +def test_stream_using_is_client_side_incremental_has_cursor_state(): |
| 1654 | + expected_cursor_value = "2024-07-01" |
| 1655 | + state = [ |
| 1656 | + AirbyteStateMessage( |
| 1657 | + type=AirbyteStateType.STREAM, |
| 1658 | + stream=AirbyteStreamState( |
| 1659 | + stream_descriptor=StreamDescriptor(name="locations", namespace=None), |
| 1660 | + stream_state=AirbyteStateBlob(updated_at=expected_cursor_value), |
| 1661 | + ), |
| 1662 | + ) |
| 1663 | + ] |
| 1664 | + |
| 1665 | + manifest_with_stream_state_interpolation = copy.deepcopy(_MANIFEST) |
| 1666 | + |
| 1667 | + # Enable semi-incremental on the locations stream |
| 1668 | + manifest_with_stream_state_interpolation["definitions"]["locations_stream"]["incremental_sync"][ |
| 1669 | + "is_client_side_incremental" |
| 1670 | + ] = True |
| 1671 | + |
| 1672 | + source = ConcurrentDeclarativeSource( |
| 1673 | + source_config=manifest_with_stream_state_interpolation, |
| 1674 | + config=_CONFIG, |
| 1675 | + catalog=_CATALOG, |
| 1676 | + state=state, |
| 1677 | + ) |
| 1678 | + concurrent_streams, synchronous_streams = source._group_streams(config=_CONFIG) |
| 1679 | + |
| 1680 | + locations_stream = concurrent_streams[2] |
| 1681 | + assert isinstance(locations_stream, DefaultStream) |
| 1682 | + |
| 1683 | + simple_retriever = locations_stream._stream_partition_generator._partition_factory._retriever |
| 1684 | + record_filter = simple_retriever.record_selector.record_filter |
| 1685 | + assert isinstance(record_filter, ClientSideIncrementalRecordFilterDecorator) |
| 1686 | + client_side_incremental_cursor_state = record_filter._cursor._cursor |
| 1687 | + |
| 1688 | + assert client_side_incremental_cursor_state == expected_cursor_value |
| 1689 | + |
| 1690 | + |
1650 | 1691 | def create_wrapped_stream(stream: DeclarativeStream) -> Stream: |
1651 | 1692 | slice_to_records_mapping = get_mocked_read_records_output(stream_name=stream.name) |
1652 | 1693 |
|
|
0 commit comments