Skip to content
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

🎉Source Intercom: increase unit test coverage at least 90% #11405

Merged
merged 12 commits into from
Mar 28, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from datetime import datetime
from enum import Enum
from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Tuple
from urllib.parse import parse_qsl, urlparse, urljoin
from urllib.parse import parse_qsl, urljoin, urlparse

import requests
from airbyte_cdk.logger import AirbyteLogger
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#
# Copyright (c) 2021 Airbyte, Inc., all rights reserved.
#

from pytest import fixture


@fixture(name="config")
def config_fixture():
config = {
"access_token": "TOKEN",
"start_date": "2022-03-20T00:00:00Z",
}

return config
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,27 @@

import pytest
import requests
from airbyte_cdk.logger import AirbyteLogger
from airbyte_cdk.models import SyncMode
from airbyte_cdk.sources.streams.http.auth import NoAuth
from source_intercom.source import Companies, Contacts, IntercomStream
from source_intercom.source import (
Admins,
Companies,
CompanyAttributes,
CompanySegments,
ContactAttributes,
Contacts,
ConversationParts,
Conversations,
IntercomStream,
Segments,
SourceIntercom,
Tags,
Teams,
)

logger = AirbyteLogger()


test_data = [
(
Expand Down Expand Up @@ -76,3 +94,101 @@ def test_switch_to_standard_endpoint_if_scroll_expired(requests_mock):
records += list(stream1.read_records(sync_mode=SyncMode, stream_slice=slice))

assert stream1._endpoint_type == Companies.EndpointType.standard


def test_check_connection_ok(config, requests_mock):
url = "https://api.intercom.io/tags"
requests_mock.get(url, json={})
ok, error_msg = SourceIntercom().check_connection(logger, config=config)

assert ok
assert not error_msg


def test_check_connection_empty_config(config):
config = {}

with pytest.raises(KeyError):
SourceIntercom().check_connection(logger, config=config)


def test_check_connection_invalid_config(config):
config.pop("start_date")
ok, error_msg = SourceIntercom().check_connection(logger, config=config)

assert not ok
assert error_msg


def test_check_connection_exception(config):
ok, error_msg = SourceIntercom().check_connection(logger, config=config)

assert not ok
assert error_msg


def test_streams(config):
streams = SourceIntercom().streams(config)

assert len(streams) == 11


@pytest.mark.parametrize(
"stream, endpoint, response, expected",
[
(Admins, "/admins", {"type": "admin.list", "admins": [{"type": "admin", "id": "id"}]}, [{"id": "id", "type": "admin"}]),
(
Companies,
"/companies/scroll",
{"type": "company.list", "data": [{"type": "company", "id": "id"}]},
[{"id": "id", "type": "company"}],
),
(
CompanySegments,
"/companies/id/segments",
{"type": "list", "data": [{"type": "segment", "id": "id"}]},
[{"id": "id", "type": "segment"}],
),
(Contacts, "/contacts", {"type": "list", "data": [{"type": "contact", "id": "id"}]}, [{"id": "id", "type": "contact"}]),
(
Conversations,
"/conversations",
{"type": "conversation.list", "conversations": [{"type": "conversation", "id": "id"}]},
[{"id": "id", "type": "conversation"}],
),
(
ConversationParts,
"/conversations/id",
{"id": "id", "conversation_parts": {"conversation_parts": [{"type": "conversation_part", "id": "id"}]}},
[{"id": "id", "type": "conversation_part"}],
),
(
CompanyAttributes,
"/data_attributes",
{"type": "list", "data": [{"type": "data_attribute", "id": "id"}]},
[{"id": "id", "type": "data_attribute"}],
),
(
ContactAttributes,
"/data_attributes",
{"type": "list", "data": [{"type": "data_attribute", "id": "id"}]},
[{"id": "id", "type": "data_attribute"}],
),
(Segments, "/segments", {"type": "segment.list", "segments": [{"type": "segment", "id": "id"}]}, [{"id": "id", "type": "segment"}]),
(Tags, "/tags", {"type": "list", "data": [{"type": "tag", "id": "id"}]}, [{"id": "id", "type": "tag"}]),
(Teams, "/teams", {"teams": [{"type": "team", "id": "id"}]}, [{"id": "id", "type": "team"}]),
],
)
def test_read(stream, endpoint, response, expected, config, requests_mock):
requests_mock.get("/conversations", json=response)
requests_mock.get("/companies/scroll", json=response)
requests_mock.get(endpoint, json=response)

stream = stream(authenticator=NoAuth())

records = []

for slice in stream.stream_slices(sync_mode=SyncMode.full_refresh):
records += list(stream.read_records(sync_mode=SyncMode, stream_slice=slice))

assert records == expected
9 changes: 6 additions & 3 deletions docs/integrations/sources/intercom.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ If there are more endpoints you'd like Airbyte to support, please [create an iss
| :--- | :--- |
| Full Refresh Sync | Yes |
| Incremental - Append Sync | Yes |
| Replicate Incremental Deletes | Coming soon |
| SSL connection | Yes |
| Namespaces | No |

Expand All @@ -43,9 +42,13 @@ The Intercom connector should not run into Intercom API limitations under normal

## Getting started
lazebnyi marked this conversation as resolved.
Show resolved Hide resolved

### Requirements
### Authentication Types

To access the Intercom API, you'll need an access token. How you get this token depends on if your app is for your own usage or for the public's usage.

* [Access Token](https://developers.intercom.com/building-apps/docs/authentication-types#section-access-tokens)
* [OAuth](https://developers.intercom.com/building-apps/docs/authentication-types#section-o-auth)

* Intercom Access Token

### Setup guide

Expand Down