|
| 1 | +# |
| 2 | +# Copyright (c) 2021 Airbyte, Inc., all rights reserved. |
| 3 | +# |
| 4 | + |
| 5 | +import random |
| 6 | +import pytest |
| 7 | +from typing import Any, MutableMapping |
| 8 | + |
| 9 | +from source_freshdesk.streams import Agents, Companies, Contacts, Conversations, Groups, Roles, SatisfactionRatings, Skills, Tickets, TimeEntries |
| 10 | +from airbyte_cdk.models import SyncMode |
| 11 | +from airbyte_cdk.sources.streams import Stream |
| 12 | + |
| 13 | + |
| 14 | +def _read_full_refresh(stream_instance: Stream): |
| 15 | + records = [] |
| 16 | + slices = stream_instance.stream_slices(sync_mode=SyncMode.full_refresh) |
| 17 | + for slice in slices: |
| 18 | + records.extend(list(stream_instance.read_records(stream_slice=slice, sync_mode=SyncMode.full_refresh))) |
| 19 | + return records |
| 20 | + |
| 21 | + |
| 22 | +def _read_incremental(stream_instance: Stream, stream_state: MutableMapping[str, Any]): |
| 23 | + res = [] |
| 24 | + slices = stream_instance.stream_slices(sync_mode=SyncMode.incremental, stream_state=stream_state) |
| 25 | + for slice in slices: |
| 26 | + records = stream_instance.read_records(sync_mode=SyncMode.incremental, stream_slice=slice, stream_state=stream_state) |
| 27 | + for record in records: |
| 28 | + stream_state = stream_instance.get_updated_state(stream_state, record) |
| 29 | + res.append(record) |
| 30 | + return res, stream_state |
| 31 | + |
| 32 | + |
| 33 | +@pytest.mark.parametrize( |
| 34 | + "stream, resource", |
| 35 | + [ |
| 36 | + (Agents, "agents"), |
| 37 | + (Companies, "companies"), |
| 38 | + (Contacts, "contacts"), |
| 39 | + (Groups, "groups"), |
| 40 | + (Roles, "roles"), |
| 41 | + (Skills, "skills"), |
| 42 | + (TimeEntries, "time_entries"), |
| 43 | + (SatisfactionRatings, "surveys/satisfaction_ratings"), |
| 44 | + ], |
| 45 | +) |
| 46 | +def test_full_refresh(stream, resource, authenticator, config, requests_mock): |
| 47 | + requests_mock.register_uri("GET", f"/api/{resource}", json=[{"id": x} for x in range(25)]) |
| 48 | + |
| 49 | + stream = stream(authenticator=authenticator, config=config) |
| 50 | + records = _read_full_refresh(stream) |
| 51 | + |
| 52 | + assert len(records) == 25 |
| 53 | + |
| 54 | + |
| 55 | +def test_full_refresh_conversations(authenticator, config, requests_mock): |
| 56 | + requests_mock.register_uri("GET", f"/api/tickets", json=[{"id": x} for x in range(5)]) |
| 57 | + for i in range(5): |
| 58 | + requests_mock.register_uri("GET", f"/api/tickets/{i}/conversations", json=[{"id": x} for x in range(10)]) |
| 59 | + |
| 60 | + stream = Conversations(authenticator=authenticator, config=config) |
| 61 | + records = _read_full_refresh(stream) |
| 62 | + |
| 63 | + assert len(records) == 50 |
| 64 | + |
| 65 | + |
| 66 | +@pytest.mark.parametrize( |
| 67 | + "stream, resource", |
| 68 | + [ |
| 69 | + (Contacts, "contacts"), |
| 70 | + (Tickets, "tickets"), |
| 71 | + (SatisfactionRatings, "surveys/satisfaction_ratings"), |
| 72 | + ], |
| 73 | +) |
| 74 | +def test_incremental(stream, resource, authenticator, config, requests_mock): |
| 75 | + highest_updated_at = "2022-04-25T22:00:00Z" |
| 76 | + other_updated_at = "2022-04-01T00:00:00Z" |
| 77 | + highest_index = random.randint(0, 25) |
| 78 | + requests_mock.register_uri( |
| 79 | + "GET", |
| 80 | + f"/api/{resource}", |
| 81 | + json=[{"id": x, "updated_at": highest_updated_at if x == highest_index else other_updated_at} for x in range(25)] |
| 82 | + ) |
| 83 | + |
| 84 | + stream = stream(authenticator=authenticator, config=config) |
| 85 | + records, state = _read_incremental(stream, {}) |
| 86 | + |
| 87 | + assert len(records) == 25 |
| 88 | + assert "updated_at" in state |
| 89 | + assert state["updated_at"] == highest_updated_at |
0 commit comments