Skip to content

Commit

Permalink
Merge pull request #97 from livechat/API-11719_billing_api
Browse files Browse the repository at this point in the history
Adding Billing API
  • Loading branch information
remleinpiotr authored Feb 2, 2023
2 parents 10b021c + 570564a commit f548949
Show file tree
Hide file tree
Showing 7 changed files with 500 additions and 0 deletions.
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file.
## [0.3.6] - TBA

### Added

- Added support for billing-api.
- New `highest_available` option for `customer_monitoring_level` in agent-api `login` method.

### Bugfixes
Expand Down
2 changes: 2 additions & 0 deletions livechat/billing/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# pylint: disable=C0114
from livechat.billing.base import BillingApi
2 changes: 2 additions & 0 deletions livechat/billing/api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# pylint: disable=C0114
from .v1 import BillingApiV1
351 changes: 351 additions & 0 deletions livechat/billing/api/v1.py

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions livechat/billing/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
''' Module with base class that allows retrieval of client for specific
Billing API version. '''

# pylint: disable=W0613,W0622,C0103,R0913,R0903

from __future__ import annotations

from livechat.config import CONFIG

from .api import BillingApiV1

billing_url = CONFIG.get('billing_url')
billing_version = CONFIG.get('billing_version')


class BillingApi:
''' Base class that allows retrieval of client for specific
Billing API version. '''
@staticmethod
def get_client(token: str,
version: str = billing_version,
base_url: str = billing_url,
http2: bool = False,
proxies: dict = None,
verify: bool = True) -> BillingApiV1:
''' Returns client for specific Billing API version.
Args:
token (str): Full token with type Bearer that will be
used as `Authorization` header in requests to API.
version (str): Billing API's version. Defaults to the v1 version of Billing.
base_url (str): API's base url. Defaults to API's production URL.
http2 (bool): A boolean indicating if HTTP/2 support should be
enabled. Defaults to `False`.
proxies (dict): A dictionary mapping proxy keys to proxy URLs.
verify (bool): SSL certificates (a.k.a CA bundle) used to
verify the identity of requested hosts. Either `True` (default CA bundle),
a path to an SSL certificate file, an `ssl.SSLContext`, or `False`
(which will disable verification). Defaults to `True`.
Returns:
BillingApi: API client object for specified version.
Raises:
ValueError: If the specified version does not exist.
'''
client = {
'1': BillingApiV1(token, base_url, http2, proxies, verify),
}.get(version)
if not client:
raise ValueError('Provided version does not exist.')
return client
2 changes: 2 additions & 0 deletions livechat/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

CONFIG = {
'url': 'api.livechatinc.com',
'billing_url': 'billing.livechatinc.com',
'stable': '3.5',
'dev': '3.6',
'billing_version': '1'
}
89 changes: 89 additions & 0 deletions livechat/tests/test_billing_api_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
''' Tests for Billing API client. '''

# pylint: disable=E1120,W0621

import pytest

from livechat.billing.base import BillingApi
from livechat.config import CONFIG

billing_url = CONFIG.get('billing_url')
billing_version = CONFIG.get('billing_version')


@pytest.fixture
def billing_api_client():
''' Fixture returning Billing API client. '''
return BillingApi.get_client(token='test')


def test_get_client_without_args():
''' Test if TypeError raised without args. '''
with pytest.raises(TypeError) as exception:
BillingApi.get_client()
assert str(
exception.value
) == "get_client() missing 1 required positional argument: 'token'"


def test_get_client_without_access_token():
''' Test if TypeError raised without access_token. '''
with pytest.raises(TypeError) as exception:
BillingApi.get_client(version='test')
assert str(
exception.value
) == "get_client() missing 1 required positional argument: 'token'"


def test_get_client_with_non_existing_version():
''' Test if ValueError raised for non-existing version. '''
with pytest.raises(ValueError) as exception:
BillingApi.get_client(token='test', version='test')
assert str(exception.value) == 'Provided version does not exist.'


def test_get_client_with_valid_args(billing_api_client):
''' Test if production API URL is used and token is added to headers for valid args. '''
assert billing_api_client.api_url == f'https://{billing_url}/v{billing_version}'
assert billing_api_client.session.headers.get('Authorization') == 'test'


def test_send_request(billing_api_client):
''' Test if it's possible to send a basic request via Billing API
client with arbitrary chosen method. '''
assert billing_api_client.create_direct_charge().json() == {
'error':
'invalid_request',
'error_description':
'The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.'
}


def test_modify_header(billing_api_client):
''' Test if Billing API object header can be updated with custom value. '''
assert 'test' not in billing_api_client.get_headers()
billing_api_client.modify_header({'test': '1234'})
assert 'test' in billing_api_client.get_headers()


def test_remove_header(billing_api_client):
''' Test if header can be removed from Billing API object. '''
billing_api_client.modify_header({'test2': '1234'})
assert 'test2' in billing_api_client.get_headers()
billing_api_client.remove_header('test2')
assert 'test2' not in billing_api_client.get_headers()


def test_custom_headers_within_the_request(billing_api_client):
''' Test if custom headers can be added to the session headers
only within the particular request. '''
headers = {'x-test': 'enabled'}
response = billing_api_client.create_direct_charge(headers=headers)
assert headers.items() <= response.request.headers.items()
assert 'x-test' not in billing_api_client.get_headers()


def test_client_supports_http_1():
''' Test if client supports HTTP/1.1 protocol. '''
client = BillingApi.get_client(token='test')
assert client.create_direct_charge().http_version == 'HTTP/1.1'

0 comments on commit f548949

Please sign in to comment.