-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
🎉 New Source: Zenloop #7380
🎉 New Source: Zenloop #7380
Conversation
Hey @AlexanderBatoulis thanks for the contribution. We will review this soon |
Hey @AlexanderBatoulis , could you please fill the checklist at the bottom of the PR's description so that we can check if it's ready for review? Thanks! 🙏 |
# expect_records: | ||
# path: "integration_tests/expected_records.txt" | ||
# extra_fields: no | ||
# exact_order: no | ||
# extra_records: yes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you remove this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @AlexanderBatoulis small comment also can you run ./gradlew format
?
done |
done |
Hello @AlexanderBatoulis ! Sorry to not finished your contribution before the date stipulated in the contest. All contributions made before 15-November are eligible to receive the award. We're trying to review your contribution as soon as possible. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much @AlexanderBatoulis for this contribution, I have some minor questions and suggestions that you'll find in my review comments.
In addition, we configured a sandbox account for Zenloop and I'm afraid that the integration tests are not passing when we fill the public_hash_id
field. The https://app.zenloop.com/settings/api
page provides list of hash ids for surveys, but this value is reused to build requests to survey_groups
endpoint in the AnswersSurveyGroup
stream (survey_groups/{self.public_hash_id}/answers
). It looks like the API expects a survey group id that is different from the public hash id provided in the config (which is expected to be a survey id and not a survey group id) and it leads to 404 error.
TLDR: integration tests did not pass when setting public_hash_id
to a valid value in our config.
Could you also fix conflicts with master please? 🙏
airbyte-integrations/connectors/source-zenloop/source_zenloop/source.py
Outdated
Show resolved
Hide resolved
|
||
class IncrementalZenloopStream(ZenloopStream, ABC): | ||
# checkpoint stream reads after 100 records. | ||
state_checkpoint_interval = 100 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using state_checkpoint_interval
combined with a stream_slice
implementation leads to checkpointing at every 100 records of each slice, is it your original intent?
airbyte-config/init/src/main/resources/seed/source_definitions.yaml
Outdated
Show resolved
Hide resolved
"cursor_field": expected_cursor_field, | ||
"stream_state": {expected_cursor_field: "2021-10-20T03:30:30Z"}, | ||
} | ||
expected_stream_slice = [None] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you're not testing the behavior of stream_slices
if public_hash_id
is None
def test_request_headers(patch_base_class, config): | ||
stream = ZenloopStream(config["api_token"], config["date_from"], config["public_hash_id"]) | ||
inputs = {"stream_slice": None, "stream_state": None, "next_page_token": None} | ||
expected_headers = {} | ||
assert stream.request_headers(**inputs) == expected_headers | ||
|
||
|
||
def test_http_method(patch_base_class, config): | ||
stream = ZenloopStream(config["api_token"], config["date_from"], config["public_hash_id"]) | ||
expected_method = "GET" | ||
assert stream.http_method == expected_method | ||
|
||
|
||
@pytest.mark.parametrize( | ||
("http_status", "should_retry"), | ||
[ | ||
(HTTPStatus.OK, False), | ||
(HTTPStatus.BAD_REQUEST, False), | ||
(HTTPStatus.TOO_MANY_REQUESTS, True), | ||
(HTTPStatus.INTERNAL_SERVER_ERROR, True), | ||
], | ||
) | ||
def test_should_retry(patch_base_class, config, http_status, should_retry): | ||
response_mock = MagicMock() | ||
response_mock.status_code = http_status | ||
stream = ZenloopStream(config["api_token"], config["date_from"], config["public_hash_id"]) | ||
assert stream.should_retry(response_mock) == should_retry | ||
|
||
|
||
def test_backoff_time(patch_base_class, config): | ||
response_mock = MagicMock() | ||
stream = ZenloopStream(config["api_token"], config["date_from"], config["public_hash_id"]) | ||
expected_backoff_time = None | ||
assert stream.backoff_time(response_mock) == expected_backoff_time |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These test might be redundant because you're not overriding these methods from the parent HttpStream class
expected_parsed_object = {"answers": [{"id": 123, "name": "John Doe"}]} | ||
assert next(stream.parse_response(**inputs)) == expected_parsed_object | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could add tests for SurveyGroups
and Surveys
to increase coverage.
def test_check_connection(mocker, config): | ||
source = SourceZenloop() | ||
logger_mock = MagicMock() | ||
assert source.check_connection(logger_mock, config) == (True, None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is not passing, you might miss some mock because the real zenloop backend seems to be called... and moreover please test the behavior in case of error.
Hi @alafanechere, Kind regards, |
HI @AlexanderBatoulis , thanks for your modifications, I'll go for another review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @AlexanderBatoulis , I tried to run the acceptance tests but they are failing. Could you please make sure the following command runs flawlessly?
./gradlew :airbyte-integrations:connectors:source-zenloop:integrationTest
Hi @alafanechere, this should run fine now - missed to update setup.py |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, I'm happy with the change you've made and successfully ran the acceptance tests!
Ready to merge 👏
What
How
Added four streams for this source
Recommended reading order
Pre-merge Checklist
Expand the relevant checklist and delete the others.
Test Runs
unit test
integration test
New Connector
Community member or Airbyter
airbyte_secret
./gradlew :airbyte-integrations:connectors:<name>:integrationTest
.README.md
bootstrap.md
. See description and examplesdocs/SUMMARY.md
docs/integrations/<source or destination>/<name>.md
including changelog. See changelog exampledocs/integrations/README.md
airbyte-integrations/builds.md
Airbyter
If this is a community PR, the Airbyte engineer reviewing this PR is responsible for the below items.
/test connector=connectors/<name>
command is passing./publish
command described here