forked from airbytehq/airbyte
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🐛 300-page-gate issue for Tickets Stream in Freshdesk source connector (
airbytehq#4002) airbytehq#4002 - 300-page-gate issue for Tickets Stream in Freshdesk source connector Co-authored-by: Oleksandr Bazarnov <[email protected]>
- Loading branch information
Showing
9 changed files
with
186 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ __pycache__ | |
.venv | ||
.mypy_cache | ||
.ipynb_checkpoints | ||
.pytest_ | ||
|
||
# dbt | ||
profiles.yml | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 4 additions & 0 deletions
4
airbyte-integrations/connectors/source-freshdesk/CHANGELOG.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,8 @@ | ||
# Changelog | ||
|
||
## 0.2.4 | ||
Fix the issue when server doesn't allow the client to fetch more than 300 pages from Tickets Stream: | ||
`Validation failed: [{'field': 'page', 'message': 'You cannot access tickets beyond the 300th page. Please provide a smaller page number.', 'code': 'invalid_value'}]` | ||
|
||
## 0.2.3 | ||
Fix discovery and set default cursor field as "updated_at" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
airbyte-integrations/connectors/source-freshdesk/unit_tests/test_300_page.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
# | ||
# MIT License | ||
# | ||
# Copyright (c) 2020 Airbyte | ||
# | ||
# Permission is hereby granted, free of charge, to any person obtaining a copy | ||
# of this software and associated documentation files (the "Software"), to deal | ||
# in the Software without restriction, including without limitation the rights | ||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
# copies of the Software, and to permit persons to whom the Software is | ||
# furnished to do so, subject to the following conditions: | ||
# | ||
# The above copyright notice and this permission notice shall be included in all | ||
# copies or substantial portions of the Software. | ||
# | ||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
# SOFTWARE. | ||
# | ||
|
||
import pendulum | ||
from source_freshdesk.api import TicketsAPI | ||
|
||
|
||
class Test300PageLimit: | ||
|
||
tickets_input = [ | ||
{"id": 1, "updated_at": "2018-01-02T00:00:00Z"}, | ||
{"id": 2, "updated_at": "2018-02-02T00:00:00Z"}, | ||
{"id": 3, "updated_at": "2018-03-02T00:00:00Z"}, | ||
{"id": 4, "updated_at": "2019-01-03T00:00:00Z"}, | ||
{"id": 5, "updated_at": "2019-02-03T00:00:00Z"}, | ||
{"id": 6, "updated_at": "2019-03-03T00:00:00Z"}, | ||
] | ||
|
||
expected_output = [ | ||
{"id": 1, "updated_at": "2018-01-02T00:00:00Z"}, | ||
{"id": 2, "updated_at": "2018-02-02T00:00:00Z"}, | ||
{"id": 2, "updated_at": "2018-02-02T00:00:00Z"}, # duplicate | ||
{"id": 3, "updated_at": "2018-03-02T00:00:00Z"}, | ||
{"id": 3, "updated_at": "2018-03-02T00:00:00Z"}, # duplicate | ||
{"id": 4, "updated_at": "2019-01-03T00:00:00Z"}, | ||
{"id": 4, "updated_at": "2019-01-03T00:00:00Z"}, # duplicate | ||
{"id": 5, "updated_at": "2019-02-03T00:00:00Z"}, | ||
{"id": 5, "updated_at": "2019-02-03T00:00:00Z"}, # duplicate | ||
{"id": 6, "updated_at": "2019-03-03T00:00:00Z"}, | ||
{"id": 6, "updated_at": "2019-03-03T00:00:00Z"}, # duplicate | ||
] | ||
|
||
# Mocking the getter: Callable to produce the server output | ||
def _getter(self, params, **args): | ||
|
||
tickets_stream = self.tickets_input | ||
updated_since = params.get("updated_since", None) | ||
|
||
if updated_since: | ||
tickets_stream = filter(lambda ticket: pendulum.parse(ticket["updated_at"]) >= updated_since, self.tickets_input) | ||
|
||
start_from = (params["page"] - 1) * params["per_page"] | ||
output = list(tickets_stream)[start_from : start_from + params["per_page"]] | ||
|
||
return output | ||
|
||
def test_not_all_records(self): | ||
""" | ||
TEST 1 - not all records are retrieved | ||
During test1 the tickets_stream changes the state of parameters on page: 2, | ||
by updating the params: | ||
`params["order_by"] = "updated_at"` | ||
`params["updated_since"] = last_record` | ||
continues to fetch records from the source, using new cycle, and so on. | ||
NOTE: | ||
After switch of the state on ticket_paginate_limit = 2, is this example, we will experience the | ||
records duplication, because of the last_record state, starting at the point | ||
where we stoped causes the duplication of the output. The solution for this is to add at least 1 second to the | ||
last_record state. The DBT normalization should handle this for the end user, so the duplication issue is not a | ||
blocker in such cases. | ||
Main pricipal here is: airbyte is at-least-once delivery, but skipping records is data loss. | ||
""" | ||
|
||
# INT value of page number where the switch state should be triggered. | ||
# in this test case values from: 1 - 4, assuming we want to switch state on this page. | ||
ticket_paginate_limit = 2 | ||
# This parameter mocks the "per_page" parameter in the API Call | ||
result_return_limit = 1 | ||
# Calling the TicketsAPI.get_tickets method directly from the module | ||
test1 = list( | ||
TicketsAPI.get_tickets( | ||
result_return_limit=result_return_limit, getter=self._getter, ticket_paginate_limit=ticket_paginate_limit | ||
) | ||
) | ||
# We're expecting 6 records to return from the tickets_stream | ||
assert self.expected_output == test1 |