From adeb5a52f75226a37f0c4a36aecf6e9eebafb81a Mon Sep 17 00:00:00 2001 From: Oscar MARIE--TAILLEFER Date: Thu, 21 Dec 2023 17:55:11 +0100 Subject: [PATCH] feat: add user-agent headers on each APIs --- .pre-commit-config.yaml | 1 + novu/api/base.py | 8 +++- poetry.lock | 23 ++++++------ pyproject.toml | 1 + tests/api/test_base.py | 33 +++++++++++++--- tests/api/test_blueprint.py | 8 +++- tests/api/test_change.py | 14 ++++--- tests/api/test_environment.py | 16 +++++--- tests/api/test_event.py | 50 +++++++++++++------------ tests/api/test_execution_detail.py | 6 ++- tests/api/test_feed.py | 10 +++-- tests/api/test_inbound_parse.py | 6 ++- tests/api/test_integration.py | 31 ++++++++------- tests/api/test_layout.py | 18 +++++---- tests/api/test_message.py | 14 ++++--- tests/api/test_notification.py | 14 ++++--- tests/api/test_notification_group.py | 15 +++++--- tests/api/test_notification_template.py | 20 ++++++---- tests/api/test_subscriber.py | 40 +++++++++++--------- tests/api/test_tenant.py | 20 ++++++---- tests/api/test_topic.py | 24 +++++++----- 21 files changed, 232 insertions(+), 140 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5cf0bbcf..f09dd220 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -91,3 +91,4 @@ repos: pass_filenames: false additional_dependencies: - types-requests + - types-setuptools diff --git a/novu/api/base.py b/novu/api/base.py index 491f01be..2553599c 100644 --- a/novu/api/base.py +++ b/novu/api/base.py @@ -5,6 +5,7 @@ from json.decoder import JSONDecodeError from typing import Generic, List, Optional, Type, TypeVar, Union +import pkg_resources import requests from novu.config import NovuConfig @@ -13,7 +14,7 @@ LOGGER = logging.getLogger(__name__) - +__version__ = pkg_resources.get_distribution("novu").version _C_co = TypeVar("_C_co", bound=CamelCaseDto, covariant=True) @@ -101,7 +102,10 @@ def __init__( api_key = api_key or config.api_key self._url = url - self._headers = {"Authorization": f"ApiKey {api_key}"} + self._headers = { + "Authorization": f"ApiKey {api_key}", + "User-Agent": f"novu/python@{__version__}", + } self.requests_timeout = requests_timeout or int(os.getenv("NOVU_PYTHON_REQUESTS_TIMEOUT", "5")) self.session = session diff --git a/poetry.lock b/poetry.lock index dbd6fd85..4ba62fd5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -584,16 +584,6 @@ files = [ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, @@ -1393,6 +1383,17 @@ files = [ [package.dependencies] urllib3 = ">=2" +[[package]] +name = "types-setuptools" +version = "69.0.0.0" +description = "Typing stubs for setuptools" +optional = false +python-versions = ">=3.7" +files = [ + {file = "types-setuptools-69.0.0.0.tar.gz", hash = "sha256:b0a06219f628c6527b2f8ce770a4f47550e00d3e8c3ad83e2dc31bc6e6eda95d"}, + {file = "types_setuptools-69.0.0.0-py3-none-any.whl", hash = "sha256:8c86195bae2ad81e6dea900a570fe9d64a59dbce2b11cc63c046b03246ea77bf"}, +] + [[package]] name = "typing-extensions" version = "4.8.0" @@ -1459,4 +1460,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "f3af05ed4d833043944b304d69d039ef65b08e90ade0e4a5461d297574d32101" +content-hash = "76966a130d36ebf7474e2e5936dc3668b7e5a6536b24246a05e259372e88eca6" diff --git a/pyproject.toml b/pyproject.toml index 4d3bb8cb..d93ab94e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,6 +52,7 @@ pytest = "^7.2.0" sentry-sdk = "^1.14.0" toml = "^0.10.2" types-requests = "^2.28.11.12" +types-setuptools = "^69.0.0.0" [tool.poetry.group.docs.dependencies] Sphinx = "^7.0.0" diff --git a/tests/api/test_base.py b/tests/api/test_base.py index 0fd42a71..11adaff4 100644 --- a/tests/api/test_base.py +++ b/tests/api/test_base.py @@ -1,11 +1,14 @@ from unittest import TestCase, mock +import pkg_resources from requests.exceptions import HTTPError from novu.api.base import Api from novu.config import NovuConfig from tests.factories import MockResponse +__version__ = pkg_resources.get_distribution("novu").version + class ApiTests(TestCase): @classmethod @@ -23,7 +26,11 @@ def test_handle_request_with_header_override(self, mock_request: mock.MagicMock) mock_request.assert_called_once_with( method="GET", url="sample.novu.com", - headers={"Authorization": "ApiKey api-key", "MyHeader": "value"}, + headers={ + "Authorization": "ApiKey api-key", + "User-Agent": f"novu/python@{__version__}", + "MyHeader": "value", + }, json=None, params=None, timeout=5, @@ -40,7 +47,11 @@ def test_handle_request_raise_with_details(self, mock_request: mock.MagicMock) - mock_request.assert_called_once_with( method="GET", url="sample.novu.com", - headers={"Authorization": "ApiKey api-key", "MyHeader": "value"}, + headers={ + "Authorization": "ApiKey api-key", + "User-Agent": f"novu/python@{__version__}", + "MyHeader": "value", + }, json=None, params=None, timeout=5, @@ -57,7 +68,11 @@ def test_handle_request_raise_without_details(self, mock_request: mock.MagicMock mock_request.assert_called_once_with( method="GET", url="sample.novu.com", - headers={"Authorization": "ApiKey api-key", "MyHeader": "value"}, + headers={ + "Authorization": "ApiKey api-key", + "User-Agent": f"novu/python@{__version__}", + "MyHeader": "value", + }, json=None, params=None, timeout=5, @@ -74,7 +89,11 @@ def test_override_requests_timeout(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com", - headers={"Authorization": "ApiKey api-key", "MyHeader": "value"}, + headers={ + "Authorization": "ApiKey api-key", + "User-Agent": f"novu/python@{__version__}", + "MyHeader": "value", + }, json=None, params=None, timeout=60, @@ -93,7 +112,11 @@ def test_use_requests_session(self, mock_request: mock.MagicMock) -> None: session_mock.request.assert_called_once_with( method="GET", url="sample.novu.com", - headers={"Authorization": "ApiKey api-key", "MyHeader": "value"}, + headers={ + "Authorization": "ApiKey api-key", + "User-Agent": f"novu/python@{__version__}", + "MyHeader": "value", + }, json=None, params=None, timeout=5, diff --git a/tests/api/test_blueprint.py b/tests/api/test_blueprint.py index d9f794d0..36828e97 100644 --- a/tests/api/test_blueprint.py +++ b/tests/api/test_blueprint.py @@ -1,10 +1,14 @@ from unittest import TestCase, mock +import pkg_resources + from novu.api import BlueprintApi from novu.config import NovuConfig from novu.dto import BlueprintDto, GroupedBlueprintDto from tests.factories import MockResponse +__version__ = pkg_resources.get_distribution("novu").version + class BlueprintApiTests(TestCase): api: BlueprintApi @@ -69,7 +73,7 @@ def test_get_blueprint_by_id(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/blueprints/63dafeda7779f59258e38450", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -86,7 +90,7 @@ def test_get_grouped_blueprints(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/blueprints/group-by-category", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, diff --git a/tests/api/test_change.py b/tests/api/test_change.py index 13e37900..2734960f 100644 --- a/tests/api/test_change.py +++ b/tests/api/test_change.py @@ -1,11 +1,15 @@ import types from unittest import TestCase, mock +import pkg_resources + from novu.api import ChangeApi from novu.config import NovuConfig from novu.dto.change import ChangeDetailDto, ChangeDto, PaginatedChangeDto from tests.factories import MockResponse +__version__ = pkg_resources.get_distribution("novu").version + class ChangeApiTests(TestCase): @classmethod @@ -592,7 +596,7 @@ def test_list(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/changes", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={"promoted": "false"}, timeout=5, @@ -609,7 +613,7 @@ def test_list_with_pagination(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/changes", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={"page": 1, "limit": 10, "promoted": "false"}, timeout=5, @@ -625,7 +629,7 @@ def test_count(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/changes/count", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -642,7 +646,7 @@ def test_apply(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/changes/63e59af2105a61b054458218/apply", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -783,7 +787,7 @@ def test_bulk_apply(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/changes/bulk/apply", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"changeIds": ["63e59af2105a61b054458218", "63e003995fd0df473199a46c"]}, params=None, timeout=5, diff --git a/tests/api/test_environment.py b/tests/api/test_environment.py index fc1a3403..02f61399 100644 --- a/tests/api/test_environment.py +++ b/tests/api/test_environment.py @@ -1,11 +1,15 @@ import types from unittest import TestCase, mock +import pkg_resources + from novu.api import EnvironmentApi from novu.config import NovuConfig from novu.dto import EnvironmentApiKeyDto, EnvironmentDto, EnvironmentWidgetDto from tests.factories import MockResponse +__version__ = pkg_resources.get_distribution("novu").version + class EnvironmentApiTests(TestCase): @classmethod @@ -56,7 +60,7 @@ def test_list_environments(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/environments", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -73,7 +77,7 @@ def test_create_environment(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/environments", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"name": "test"}, params=None, timeout=5, @@ -90,7 +94,7 @@ def test_create_environment_with_parent_id(self, mock_request: mock.MagicMock) - mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/environments", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"name": "test", "parentId": "parent_id"}, params=None, timeout=5, @@ -107,7 +111,7 @@ def test_get_current_environment(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/environments/me", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -124,7 +128,7 @@ def test_list_environment_api_keys(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/environments/api-keys", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -141,7 +145,7 @@ def test_regenerate_api_key(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/environments/api-keys/regenerate", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, diff --git a/tests/api/test_event.py b/tests/api/test_event.py index e6d8e3a6..4355245c 100644 --- a/tests/api/test_event.py +++ b/tests/api/test_event.py @@ -1,5 +1,7 @@ from unittest import TestCase, mock +import pkg_resources + from novu.api import EventApi from novu.config import NovuConfig from novu.dto.event import EventDto, InputEventDto @@ -7,6 +9,8 @@ from novu.enums import EventStatus from tests.factories import MockResponse +__version__ = pkg_resources.get_distribution("novu").version + class EventApiTests(TestCase): api: EventApi @@ -31,7 +35,7 @@ def test_trigger_with_single_recipient(self, mock_request: mock.MagicMock) -> No mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"name": "test-template", "to": "sample-recipient", "payload": {}}, params=None, timeout=5, @@ -52,7 +56,7 @@ def test_trigger_with_multiple_recipients(self, mock_request: mock.MagicMock) -> mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"name": "test-template", "to": ["sample-recipient-1", "sample-recipient-2"], "payload": {}}, params=None, timeout=5, @@ -73,7 +77,7 @@ def test_trigger_with_overrides(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"name": "test-template", "to": "sample-recipient", "payload": {}, "overrides": {"an": "override"}}, params=None, timeout=5, @@ -94,7 +98,7 @@ def test_trigger_with_actor(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"name": "test-template", "to": "sample-recipient", "payload": {}, "actor": "actor-id"}, params=None, timeout=5, @@ -115,7 +119,7 @@ def test_trigger_with_transaction_id(self, mock_request: mock.MagicMock) -> None mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"name": "test-template", "to": "sample-recipient", "payload": {}, "transactionId": "sample-test"}, params=None, timeout=5, @@ -136,7 +140,7 @@ def test_trigger_with_tenant(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"name": "test-template", "to": "sample-recipient", "payload": {}, "tenant": "tenant-id"}, params=None, timeout=5, @@ -158,7 +162,7 @@ def test_trigger_topic_with_single_topic(self, mock_request: mock.MagicMock) -> mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"name": "test-template", "to": [{"topicKey": "topic-key", "type": "type"}], "payload": {}}, params=None, timeout=5, @@ -181,7 +185,7 @@ def test_trigger_topic_with_multiple_topics(self, mock_request: mock.MagicMock) mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "name": "test-template", "to": [{"topicKey": "topic-key-1", "type": "type"}, {"topicKey": "topic-key-2", "type": "type"}], @@ -207,7 +211,7 @@ def test_trigger_topic_with_overrides(self, mock_request: mock.MagicMock) -> Non mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "name": "test-template", "to": [{"topicKey": "topic-key", "type": "type"}], @@ -234,7 +238,7 @@ def test_trigger_topic_with_actor(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "name": "test-template", "to": [{"topicKey": "topic-key", "type": "type"}], @@ -261,7 +265,7 @@ def test_trigger_topic_with_transaction_id(self, mock_request: mock.MagicMock) - mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "name": "test-template", "to": [{"topicKey": "topic-key", "type": "type"}], @@ -288,7 +292,7 @@ def test_trigger_topic_with_tenant(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "name": "test-template", "to": [{"topicKey": "topic-key", "type": "type"}], @@ -326,7 +330,7 @@ def test_trigger_bulk_with_one_event(self, mock_request: mock.MagicMock) -> None mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger/bulk", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "events": [ {"name": "test-template", "to": "recipient_1", "payload": {}}, @@ -368,7 +372,7 @@ def test_trigger_bulk_with_with_multiple(self, mock_request: mock.MagicMock) -> mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger/bulk", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "events": [ {"name": "test-template", "to": "recipient_1", "payload": {}}, @@ -411,7 +415,7 @@ def test_trigger_bulk_with_multiple_events_and_overrides(self, mock_request: moc mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger/bulk", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "events": [ {"name": "test-template", "to": "recipient_1", "payload": {}, "overrides": {"an": "override"}}, @@ -454,7 +458,7 @@ def test_trigger_bulk_with_multiple_events_and_actor(self, mock_request: mock.Ma mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger/bulk", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "events": [ {"name": "test-template", "to": "recipient_1", "payload": {}, "actor": "actor-id"}, @@ -499,7 +503,7 @@ def test_trigger_bulk_with_multiple_events_and_transaction_id(self, mock_request mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger/bulk", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "events": [ {"name": "test-template", "to": "recipient_1", "payload": {}, "transactionId": transaction_ids[0]}, @@ -542,7 +546,7 @@ def test_trigger_bulk_with_multiple_events_and_tenant(self, mock_request: mock.M mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger/bulk", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "events": [ {"name": "test-template", "to": "recipient_1", "payload": {}, "tenant": "tenant-id"}, @@ -568,7 +572,7 @@ def test_broadcast_with_overrides(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger/broadcast", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "name": "test-template", "payload": {}, @@ -593,7 +597,7 @@ def test_broadcast_with_actor(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger/broadcast", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "name": "test-template", "payload": {}, @@ -618,7 +622,7 @@ def test_broadcast_with_transaction_id(self, mock_request: mock.MagicMock) -> No mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger/broadcast", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "name": "test-template", "payload": {}, @@ -643,7 +647,7 @@ def test_broadcast_with_tenant(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/events/trigger/broadcast", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "name": "test-template", "payload": {}, @@ -662,7 +666,7 @@ def test_delete(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="DELETE", url="sample.novu.com/v1/events/trigger/sample-test", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, diff --git a/tests/api/test_execution_detail.py b/tests/api/test_execution_detail.py index 6dcac293..e923063a 100644 --- a/tests/api/test_execution_detail.py +++ b/tests/api/test_execution_detail.py @@ -1,11 +1,15 @@ import types from unittest import TestCase, mock +import pkg_resources + from novu.api import ExecutionDetailApi from novu.config import NovuConfig from novu.dto import ExecutionDetailDto from tests.factories import MockResponse +__version__ = pkg_resources.get_distribution("novu").version + class ExecutionDetailApiTests(TestCase): @classmethod @@ -66,7 +70,7 @@ def test_list_execution_details(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/execution-details", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={"notificationId": "63eaba6ed1a5554c97dca098", "subscriberId": "63dafedbc037e013fd82d37a"}, timeout=5, diff --git a/tests/api/test_feed.py b/tests/api/test_feed.py index 77b1c520..9b8ccd6c 100644 --- a/tests/api/test_feed.py +++ b/tests/api/test_feed.py @@ -1,11 +1,15 @@ import types from unittest import TestCase, mock +import pkg_resources + from novu.api import FeedApi from novu.config import NovuConfig from novu.dto.feed import FeedDto from tests.factories import MockResponse +__version__ = pkg_resources.get_distribution("novu").version + class FeedApiTests(TestCase): api: FeedApi @@ -49,7 +53,7 @@ def test_list_feeds(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/feeds", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -66,7 +70,7 @@ def test_create_feed(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/feeds", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"name": "test"}, params=None, timeout=5, @@ -81,7 +85,7 @@ def test_delete_feed(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="DELETE", url="sample.novu.com/v1/feeds/63e969fcb6729e21337e2360", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, diff --git a/tests/api/test_inbound_parse.py b/tests/api/test_inbound_parse.py index a6cab827..82de4f2f 100644 --- a/tests/api/test_inbound_parse.py +++ b/tests/api/test_inbound_parse.py @@ -1,9 +1,13 @@ from unittest import TestCase, mock +import pkg_resources + from novu.api import InboundParseApi from novu.config import NovuConfig from tests.factories import MockResponse +__version__ = pkg_resources.get_distribution("novu").version + class InboundParseApiTests(TestCase): @classmethod @@ -20,7 +24,7 @@ def test_validate_mx_record_setup(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/inbound-parse/mx/status", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, diff --git a/tests/api/test_integration.py b/tests/api/test_integration.py index 27158b88..2ec2bdb9 100644 --- a/tests/api/test_integration.py +++ b/tests/api/test_integration.py @@ -1,6 +1,7 @@ import types from unittest import TestCase, mock +import pkg_resources from requests.exceptions import HTTPError from novu.api import IntegrationApi @@ -9,6 +10,8 @@ from novu.enums import Channel, ChatProviderIdEnum, EmailProviderIdEnum from tests.factories import MockResponse +__version__ = pkg_resources.get_distribution("novu").version + class IntegrationApiTests(TestCase): @classmethod @@ -71,7 +74,7 @@ def test_list_no_result(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/integrations", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -88,7 +91,7 @@ def test_list_with_results(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/integrations", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -105,7 +108,7 @@ def test_list_only_active_no_result(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/integrations/active", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -122,7 +125,7 @@ def test_list_with_results(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/integrations/active", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -152,7 +155,7 @@ def test_create_with_check_by_default(self, mock_request: mock.MagicMock) -> Non mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/integrations", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "providerId": EmailProviderIdEnum.CUSTOM_SMTP, "channel": Channel.EMAIL, @@ -196,7 +199,7 @@ def test_create_without_check(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/integrations", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "providerId": EmailProviderIdEnum.CUSTOM_SMTP, "channel": Channel.EMAIL, @@ -265,7 +268,7 @@ def test_create_channel_without_credentials(self, mock_request: mock.MagicMock) mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/integrations", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "providerId": ChatProviderIdEnum.MS_TEAMS, "channel": Channel.CHAT, @@ -287,7 +290,7 @@ def test_get_provider_status(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/integrations/webhooks/provider/something/status", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -318,7 +321,7 @@ def test_update_with_check_by_default(self, mock_request: mock.MagicMock) -> Non mock_request.assert_called_once_with( method="PUT", url="sample.novu.com/v1/integrations/identifier", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "providerId": EmailProviderIdEnum.CUSTOM_SMTP, "channel": Channel.EMAIL, @@ -363,7 +366,7 @@ def test_update_without_check(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="PUT", url="sample.novu.com/v1/integrations/identifier", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "providerId": EmailProviderIdEnum.CUSTOM_SMTP, "channel": Channel.EMAIL, @@ -391,7 +394,7 @@ def test_delete(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="DELETE", url="sample.novu.com/v1/integrations/identifier", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -409,7 +412,7 @@ def test_limit(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/integrations/email/limit", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -424,7 +427,7 @@ def test_set_primary_with_valid_integration_id(self, mock_request: mock.MagicMoc mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/integrations/63dfe50ecac5cff328ca5d24/set-primary", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -440,7 +443,7 @@ def test_set_primary_with_invalid_integration_id(self, mock_request: mock.MagicM mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/integrations/63dfe50ecac5cff328ca5d23/set-primary", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, diff --git a/tests/api/test_layout.py b/tests/api/test_layout.py index 155ca55a..190528a9 100644 --- a/tests/api/test_layout.py +++ b/tests/api/test_layout.py @@ -1,10 +1,14 @@ from unittest import TestCase, mock +import pkg_resources + from novu.api import LayoutApi from novu.config import NovuConfig from novu.dto import LayoutDto, LayoutVariableDto, PaginatedLayoutDto from tests.factories import MockResponse +__version__ = pkg_resources.get_distribution("novu").version + class LayoutApiTests(TestCase): @classmethod @@ -123,7 +127,7 @@ def test_list_layout(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/layouts", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={"page": 0, "pageSize": 100}, timeout=5, @@ -140,7 +144,7 @@ def test_list_layout_with_filters(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/layouts", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={"page": 1, "pageSize": 20}, timeout=5, @@ -157,7 +161,7 @@ def test_create_layout(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/layouts", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "name": "Default Layout", "description": "The default layout created by Novu", @@ -216,7 +220,7 @@ def test_get_layout(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/layouts/63dafeda7779f59258e38450", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -233,7 +237,7 @@ def test_patch_layout(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="PATCH", url="sample.novu.com/v1/layouts/63dafeda7779f59258e38450", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "name": "Default Layout", "description": "The default layout created by Novu", @@ -291,7 +295,7 @@ def test_delete_layout(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="DELETE", url="sample.novu.com/v1/layouts/63dafeda7779f59258e38450", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -307,7 +311,7 @@ def test_set_default_layout(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/layouts/63dafeda7779f59258e38450/default", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, diff --git a/tests/api/test_message.py b/tests/api/test_message.py index 01bfcefd..822cb045 100644 --- a/tests/api/test_message.py +++ b/tests/api/test_message.py @@ -1,5 +1,7 @@ from unittest import TestCase, mock +import pkg_resources + from novu.api import MessageApi from novu.api.base import PaginationIterator from novu.config import NovuConfig @@ -7,6 +9,8 @@ from novu.enums import Channel from tests.factories import MockResponse +__version__ = pkg_resources.get_distribution("novu").version + class MessageApiTests(TestCase): @classmethod @@ -80,7 +84,7 @@ def test_list_messages(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/messages", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={"limit": 10, "page": 0}, timeout=5, @@ -99,7 +103,7 @@ def test_list_messages_with_filters(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/messages", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={ "limit": 10, @@ -122,7 +126,7 @@ def test_stream_messages(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/messages", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={"limit": 10, "page": 0}, timeout=5, @@ -139,7 +143,7 @@ def test_stream_messages_with_filters(self, mock_request: mock.MagicMock) -> Non mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/messages", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={"limit": 10, "page": 0, "channel": "in_app", "subscriberId": "63dafedbc037e013fd82d37a"}, timeout=5, @@ -156,7 +160,7 @@ def test_delete_message(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="DELETE", url="sample.novu.com/v1/messages/63e969fcb6729e21337e2360", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, diff --git a/tests/api/test_notification.py b/tests/api/test_notification.py index 7506d232..44d53bcb 100644 --- a/tests/api/test_notification.py +++ b/tests/api/test_notification.py @@ -1,5 +1,7 @@ from unittest import TestCase, mock +import pkg_resources + from novu.api.base import PaginationIterator from novu.api.notification import NotificationApi from novu.config import NovuConfig @@ -16,6 +18,8 @@ ) from tests.factories import MockResponse +__version__ = pkg_resources.get_distribution("novu").version + class NotificationApiTests(TestCase): @classmethod @@ -158,7 +162,7 @@ def test_list(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/notifications", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={ "channels": channels, @@ -190,7 +194,7 @@ def test_stream(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/notifications", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={ "channels": channels, @@ -216,7 +220,7 @@ def test_stats(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/notifications/stats", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -251,7 +255,7 @@ def test_graph_stats(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/notifications/graph/stats", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={ "id": "123", @@ -277,7 +281,7 @@ def test_get(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url=f"sample.novu.com/v1/notifications/{notification_id}", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, diff --git a/tests/api/test_notification_group.py b/tests/api/test_notification_group.py index b80c0f61..a165b2c6 100644 --- a/tests/api/test_notification_group.py +++ b/tests/api/test_notification_group.py @@ -1,6 +1,7 @@ -from collections.abc import Generator from unittest import TestCase, mock +import pkg_resources + from novu.api import NotificationGroupApi from novu.config import NovuConfig from novu.dto.notification_group import ( @@ -9,6 +10,8 @@ ) from tests.factories import MockResponse +__version__ = pkg_resources.get_distribution("novu").version + class NotificationGroupApiTests(TestCase): @classmethod @@ -47,7 +50,7 @@ def test_list_notification_group(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/notification-groups", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -64,7 +67,7 @@ def test_create_notification_group(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/notification-groups", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"name": "something"}, params=None, timeout=5, @@ -81,7 +84,7 @@ def test_get_notification_group(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/notification-groups/63dafed97779f59258e38449", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -98,7 +101,7 @@ def test_patch_notification_group(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="PATCH", url="sample.novu.com/v1/notification-groups/63dafed97779f59258e38449", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"name": "Something"}, params=None, timeout=5, @@ -113,7 +116,7 @@ def test_delete_notification_group(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="DELETE", url="sample.novu.com/v1/notification-groups/63dafed97779f59258e38449", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, diff --git a/tests/api/test_notification_template.py b/tests/api/test_notification_template.py index e205539e..b5307ae1 100644 --- a/tests/api/test_notification_template.py +++ b/tests/api/test_notification_template.py @@ -1,5 +1,7 @@ from unittest import TestCase, mock +import pkg_resources + from novu.api import NotificationTemplateApi from novu.api.base import PaginationIterator from novu.config import NovuConfig @@ -16,6 +18,8 @@ ) from tests.factories import MockResponse +__version__ = pkg_resources.get_distribution("novu").version + class NotificationTemplateApiTests(TestCase): @classmethod @@ -154,7 +158,7 @@ def test_list_notification_template(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/notification-templates", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={}, timeout=5, @@ -171,7 +175,7 @@ def test_list_notification_template_with_pagination(self, mock_request: mock.Mag mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/notification-templates", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={"page": 1, "limit": 10}, timeout=5, @@ -188,7 +192,7 @@ def test_stream_notification_template(self, mock_request: mock.MagicMock) -> Non mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/notification-templates", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={"page": 0, "limit": 10}, timeout=5, @@ -242,7 +246,7 @@ def test_create_notification_template(self, mock_request: mock.MagicMock) -> Non mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/notification-templates", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "name": "Absences", "notificationGroupId": "63dafed97779f59258e38449", @@ -292,7 +296,7 @@ def test_get_notification_template(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/notification-templates/63daff36c037e013fd82d9fc", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -347,7 +351,7 @@ def test_update_notification_template(self, mock_request: mock.MagicMock) -> Non mock_request.assert_called_once_with( method="PUT", url="sample.novu.com/v1/notification-templates/63daff36c037e013fd82d9fc", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "name": "Absences", "notificationGroupId": "63dafed97779f59258e38449", @@ -396,7 +400,7 @@ def test_delete_notification_template(self, mock_request: mock.MagicMock) -> Non mock_request.assert_called_once_with( method="DELETE", url="sample.novu.com/v1/notification-templates/63daff36c037e013fd82d9fc", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -413,7 +417,7 @@ def test_update_status_notification_template(self, mock_request: mock.MagicMock) mock_request.assert_called_once_with( method="PUT", url="sample.novu.com/v1/notification-templates/63daff36c037e013fd82d9fc/status", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"active": True}, params=None, timeout=5, diff --git a/tests/api/test_subscriber.py b/tests/api/test_subscriber.py index 1368315c..8cac1612 100644 --- a/tests/api/test_subscriber.py +++ b/tests/api/test_subscriber.py @@ -1,6 +1,8 @@ from collections.abc import Generator from unittest import TestCase, mock +import pkg_resources + from novu.api import SubscriberApi from novu.api.base import PaginationIterator from novu.config import NovuConfig @@ -18,6 +20,8 @@ from novu.enums import Channel, ChatProviderIdEnum from tests.factories import MockResponse +__version__ = pkg_resources.get_distribution("novu").version + class SubscriberApiTests(TestCase): @classmethod @@ -73,7 +77,7 @@ def test_list_subscriber(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/subscribers", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={}, timeout=5, @@ -90,7 +94,7 @@ def test_list_subscriber_using_pagination(self, mock_request: mock.MagicMock) -> mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/subscribers", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={"page": 1}, timeout=5, @@ -107,7 +111,7 @@ def test_stream_subscriber(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/subscribers", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={"page": 0, "limit": 10}, timeout=5, @@ -147,7 +151,7 @@ def test_create_subscriber(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/subscribers", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "subscriberId": "subscriber-id", "email": "subscriber@sample.com", @@ -241,7 +245,7 @@ def test_bulk_create_subscribers(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/subscribers/bulk", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "subscribers": [ { @@ -281,7 +285,7 @@ def test_get_subscriber(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/subscribers/subscriber-id", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -370,7 +374,7 @@ def test_get_subscriber_with_credentials_info(self, mock_request: mock.MagicMock mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/subscribers/subscriber-id", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -388,7 +392,7 @@ def test_update_subscriber(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="PUT", url="sample.novu.com/v1/subscribers/subscriber-id", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={ "subscriberId": "subscriber-id", "email": "subscriber@sample.com", @@ -412,7 +416,7 @@ def test_delete(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="DELETE", url="sample.novu.com/v1/subscribers/subscriber-id", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -429,7 +433,7 @@ def test_credentials_update_webhook_url(self, mock_request: mock.MagicMock) -> N mock_request.assert_called_once_with( method="PUT", url="sample.novu.com/v1/subscribers/subscriber-id/credentials", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"providerId": "slack", "credentials": {"webhookUrl": "TEST"}}, params=None, timeout=5, @@ -446,7 +450,7 @@ def test_credentials_update_device_tokens(self, mock_request: mock.MagicMock) -> mock_request.assert_called_once_with( method="PUT", url="sample.novu.com/v1/subscribers/subscriber-id/credentials", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"providerId": "slack", "credentials": {"deviceTokens": ["TEST"]}}, params=None, timeout=5, @@ -463,7 +467,7 @@ def test_online_status(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="PATCH", url="sample.novu.com/v1/subscribers/subscriber-id/online-status", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"isOnline": True}, params=None, timeout=5, @@ -510,7 +514,7 @@ def test_preferences(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/subscribers/subscriber-id/preferences", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -552,7 +556,7 @@ def test_change_channel_preference(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="PATCH", url="sample.novu.com/v1/subscribers/subscriber-id/preferences/63daff36c037e013fd82da05", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"channel": {"type": "in_app", "enabled": True}}, params=None, timeout=5, @@ -594,7 +598,7 @@ def test_change_channel_preference_using_enum_in_params(self, mock_request: mock mock_request.assert_called_once_with( method="PATCH", url="sample.novu.com/v1/subscribers/subscriber-id/preferences/63daff36c037e013fd82da05", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"channel": {"type": "in_app", "enabled": True}}, params=None, timeout=5, @@ -636,7 +640,7 @@ def test_change_preference_state(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="PATCH", url="sample.novu.com/v1/subscribers/subscriber-id/preferences/63daff36c037e013fd82da05", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"enabled": False}, params=None, timeout=5, @@ -652,7 +656,7 @@ def test_unseen_notifications(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/subscribers/subscriber-id/notifications/unseen", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -667,7 +671,7 @@ def test_delete_credentials(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="DELETE", url="sample.novu.com/v1/subscribers/subscriber-id/credentials/slack", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, diff --git a/tests/api/test_tenant.py b/tests/api/test_tenant.py index 0f196e22..72d2bf88 100644 --- a/tests/api/test_tenant.py +++ b/tests/api/test_tenant.py @@ -1,12 +1,16 @@ import copy from unittest import TestCase, mock +import pkg_resources + from novu.api import TenantApi from novu.api.base import PaginationIterator from novu.config import NovuConfig from novu.dto.tenant import PaginatedTenantDto, TenantDto from tests.factories import MockResponse +__version__ = pkg_resources.get_distribution("novu").version + class TenantApiTests(TestCase): api: TenantApi @@ -44,7 +48,7 @@ def test_list_tenant(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/tenants", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={}, timeout=5, @@ -61,7 +65,7 @@ def test_list_tenant_using_pagination(self, mock_request: mock.MagicMock) -> Non mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/tenants", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={"page": 1, "limit": 10}, timeout=5, @@ -78,7 +82,7 @@ def test_stream_tenant(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/tenants", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={"page": 0, "limit": 10}, timeout=5, @@ -100,7 +104,7 @@ def test_stream_with_multiple_pages_tenant(self, mock_request: mock.MagicMock) - mock_request.assert_any_call( method="GET", url="sample.novu.com/v1/tenants", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={"page": 1, "limit": 10}, timeout=5, @@ -120,7 +124,7 @@ def test_create_tenant(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/tenants", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"identifier": "my-tenant", "name": "My Tenant", "data": {}}, params=None, timeout=5, @@ -139,7 +143,7 @@ def test_get_tenant(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/tenants/my-tenant", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -160,7 +164,7 @@ def test_patch_tenant(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="PATCH", url="sample.novu.com/v1/tenants/my-tenant", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"identifier": "new-tenant-ref"}, params=None, timeout=5, @@ -175,7 +179,7 @@ def test_delete_tenant(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="DELETE", url="sample.novu.com/v1/tenants/my-tenant", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, diff --git a/tests/api/test_topic.py b/tests/api/test_topic.py index 1b47b21d..8a5b3f44 100644 --- a/tests/api/test_topic.py +++ b/tests/api/test_topic.py @@ -1,10 +1,14 @@ from unittest import TestCase, mock +import pkg_resources + from novu.api import TopicApi from novu.config import NovuConfig from novu.dto.topic import PaginatedTopicDto, TopicDto from tests.factories import MockResponse +__version__ = pkg_resources.get_distribution("novu").version + class TopicApiTests(TestCase): @classmethod @@ -41,7 +45,7 @@ def test_list_topic(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/topics", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={}, timeout=5, @@ -58,7 +62,7 @@ def test_list_topic_using_pagination(self, mock_request: mock.MagicMock) -> None mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/topics", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params={"page": 1, "limit": 10, "key": "my-topic"}, timeout=5, @@ -77,7 +81,7 @@ def test_create_topic(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/topics", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"key": "my-topic", "name": "My Topic"}, params=None, timeout=5, @@ -96,7 +100,7 @@ def test_get_topic(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="GET", url="sample.novu.com/v1/topics/my-topic", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5, @@ -113,7 +117,7 @@ def test_subscribe_ok(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/topics/my-topic/subscribers", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"subscribers": ["63dafed4117f8c850991ec4a"]}, params=None, timeout=5, @@ -132,7 +136,7 @@ def test_subscribe_with_ok_and_failed(self, mock_request: mock.MagicMock) -> Non mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/topics/my-topic/subscribers", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"subscribers": ["63dafed4117f8c850991ec4a", "not-defined"]}, params=None, timeout=5, @@ -147,7 +151,7 @@ def test_unsubscribe_single_subscriber(self, mock_request: mock.MagicMock) -> No mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/topics/my-topic/subscribers/removal", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"subscribers": ["not-defined"]}, params=None, timeout=5, @@ -162,7 +166,7 @@ def test_unsubscribe_multiple_subscribers(self, mock_request: mock.MagicMock) -> mock_request.assert_called_once_with( method="POST", url="sample.novu.com/v1/topics/my-topic/subscribers/removal", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"subscribers": ["63dafed4117f8c850991ec4a", "not-defined"]}, params=None, timeout=5, @@ -180,7 +184,7 @@ def test_rename_200(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="PATCH", url="sample.novu.com/v1/topics/my-topic", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json={"name": "My Topic"}, params=None, timeout=5, @@ -195,7 +199,7 @@ def test_delete(self, mock_request: mock.MagicMock) -> None: mock_request.assert_called_once_with( method="DELETE", url="sample.novu.com/v1/topics/my-topic", - headers={"Authorization": "ApiKey api-key"}, + headers={"Authorization": "ApiKey api-key", "User-Agent": f"novu/python@{__version__}"}, json=None, params=None, timeout=5,