Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
87 changes: 87 additions & 0 deletions tests/tests_unit/test_api/test_integrations/test_actions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
from __future__ import annotations

import re

from pytest_httpx import HTTPXMock

from cognite.client import AsyncCogniteClient, CogniteClient
from cognite.client.data_classes.integrations import Action, ActionList, ActionWrite
from tests.utils import get_url, jsgz_load

ACTION_RESPONSE = {
"externalId": "my-action",
"actionName": "restart",
"status": "pending",
"createdTime": 0,
"lastUpdatedTime": 0,
}


class TestIntegrationActions:
def test_create_single(
self, cognite_client: CogniteClient, async_client: AsyncCogniteClient, httpx_mock: HTTPXMock
) -> None:
httpx_mock.add_response(
method="POST",
url=re.compile(re.escape(get_url(async_client.integrations.actions, "/integrations/actions")) + r"\?.*"),
json={"items": [ACTION_RESPONSE]},
status_code=201,
)

res = cognite_client.integrations.actions.create(
"my-integration", ActionWrite(external_id="my-action", action_name="restart")
)

assert isinstance(res, Action)
assert res.status == "pending"

request = httpx_mock.get_requests()[0]
assert "externalId=my-integration" in str(request.url)
body = jsgz_load(request.content)
assert body == {"items": [{"externalId": "my-action", "actionName": "restart"}]}

def test_list(self, cognite_client: CogniteClient, async_client: AsyncCogniteClient, httpx_mock: HTTPXMock) -> None:
url_pattern = re.compile(
re.escape(get_url(async_client.integrations.actions, "/integrations/actions")) + r"(?:\?.*)?$"
)
httpx_mock.add_response(method="GET", url=url_pattern, json={"items": [ACTION_RESPONSE]})

res = cognite_client.integrations.actions.list(external_id="my-integration", include_completed=False)

assert isinstance(res, ActionList)
assert len(res) == 1

request = httpx_mock.get_requests()[0]
assert "includeCompleted=false" in str(request.url)

def test_retrieve(
self, cognite_client: CogniteClient, async_client: AsyncCogniteClient, httpx_mock: HTTPXMock
) -> None:
httpx_mock.add_response(
method="POST",
url=get_url(async_client.integrations.actions, "/integrations/actions/byids"),
json={"items": [ACTION_RESPONSE]},
)

res = cognite_client.integrations.actions.retrieve("my-action")

assert isinstance(res, Action)
assert res.external_id == "my-action"

def test_cancel(
self, cognite_client: CogniteClient, async_client: AsyncCogniteClient, httpx_mock: HTTPXMock
) -> None:
cancelled_response = {**ACTION_RESPONSE, "status": "cancel_pending"}
httpx_mock.add_response(
method="POST",
url=get_url(async_client.integrations.actions, "/integrations/actions/cancel"),
json={"items": [cancelled_response]},
)

res = cognite_client.integrations.actions.cancel("my-action")

assert isinstance(res, ActionList)
assert res[0].status == "cancel_pending"

body = jsgz_load(httpx_mock.get_requests()[0].content)
assert body == {"items": [{"externalId": "my-action"}]}
78 changes: 78 additions & 0 deletions tests/tests_unit/test_api/test_integrations/test_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
from __future__ import annotations

import re

from pytest_httpx import HTTPXMock

from cognite.client import AsyncCogniteClient, CogniteClient
from cognite.client.data_classes.integrations import ConfigRevision, ConfigRevisionMetadataList, ConfigRevisionWrite
from tests.utils import get_url, jsgz_load

CONFIG_REVISION_RESPONSE = {
"externalId": "my-integration",
"revision": 1,
"config": "my config contents",
"createdTime": 0,
"lastUpdatedTime": 0,
}
CONFIG_REVISION_METADATA_RESPONSE = {
"externalId": "my-integration",
"revision": 1,
"createdTime": 0,
"lastUpdatedTime": 0,
}


class TestIntegrationConfig:
def test_create(
self, cognite_client: CogniteClient, async_client: AsyncCogniteClient, httpx_mock: HTTPXMock
) -> None:
httpx_mock.add_response(
method="POST",
url=get_url(async_client.integrations.config, "/integrations/config"),
json=CONFIG_REVISION_RESPONSE,
)

res = cognite_client.integrations.config.create(
ConfigRevisionWrite(external_id="my-integration", config="my config contents")
)

assert isinstance(res, ConfigRevision)
assert res.revision == 1
assert res.config == "my config contents"

body = jsgz_load(httpx_mock.get_requests()[0].content)
assert body == {"externalId": "my-integration", "config": "my config contents"}

def test_retrieve(
self, cognite_client: CogniteClient, async_client: AsyncCogniteClient, httpx_mock: HTTPXMock
) -> None:
url_pattern = re.compile(
re.escape(get_url(async_client.integrations.config, "/integrations/config")) + r"(?:\?.*)?$"
)
httpx_mock.add_response(method="GET", url=url_pattern, json=CONFIG_REVISION_RESPONSE)

res = cognite_client.integrations.config.retrieve("my-integration", revision=1)

assert isinstance(res, ConfigRevision)
assert res.revision == 1

request = httpx_mock.get_requests()[0]
assert "externalId=my-integration" in str(request.url)
assert "revision=1" in str(request.url)

def test_list(self, cognite_client: CogniteClient, async_client: AsyncCogniteClient, httpx_mock: HTTPXMock) -> None:
url_pattern = re.compile(
re.escape(get_url(async_client.integrations.config, "/integrations/config/revisions")) + r"(?:\?.*)?$"
)
httpx_mock.add_response(method="GET", url=url_pattern, json={"items": [CONFIG_REVISION_METADATA_RESPONSE]})

res = cognite_client.integrations.config.list(external_id="my-integration")

assert isinstance(res, ConfigRevisionMetadataList)
assert len(res) == 1
assert res[0].revision == 1

request = httpx_mock.get_requests()[0]
assert "externalId=my-integration" in str(request.url)
assert "limit=25" in str(request.url)
41 changes: 41 additions & 0 deletions tests/tests_unit/test_api/test_integrations/test_errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from __future__ import annotations

import re

import pytest
from pytest_httpx import HTTPXMock

from cognite.client import AsyncCogniteClient, CogniteClient
from cognite.client.data_classes.integrations.errors import IntegrationErrorList
from tests.utils import get_url

ERROR_RESPONSE = {
"externalId": "my-integration",
"level": "error",
"description": "Something went wrong",
"startTime": 100,
"task": "poll",
}


class TestIntegrationErrors:
def test_list(self, cognite_client: CogniteClient, async_client: AsyncCogniteClient, httpx_mock: HTTPXMock) -> None:
url_pattern = re.compile(
re.escape(get_url(async_client.integrations.errors, "/integrations/errors")) + r"(?:\?.*)?$"
)
httpx_mock.add_response(method="GET", url=url_pattern, json={"items": [ERROR_RESPONSE]})

res = cognite_client.integrations.errors.list(external_id="my-integration", task="poll")

assert isinstance(res, IntegrationErrorList)
assert len(res) == 1
assert res[0].level == "error"
assert res[0].description == "Something went wrong"

request = httpx_mock.get_requests()[0]
assert "externalId=my-integration" in str(request.url)
assert "task=poll" in str(request.url)

def test_list_task_without_external_id_raises(self, cognite_client: CogniteClient) -> None:
with pytest.raises(ValueError, match="'task' requires 'external_id'"):
cognite_client.integrations.errors.list(task="poll")
118 changes: 118 additions & 0 deletions tests/tests_unit/test_api/test_integrations/test_integrations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
from __future__ import annotations

import re

from pytest_httpx import HTTPXMock

from cognite.client import AsyncCogniteClient, CogniteClient
from cognite.client.data_classes.integrations import (
Extractor,
Integration,
IntegrationList,
IntegrationUpdate,
IntegrationWrite,
)
from tests.utils import get_url, jsgz_load

INTEGRATION_RESPONSE = {
"externalId": "my-integration",
"extractor": {"externalId": "cognite-simple-influxdb-extractor", "version": "1.0.0"},
"name": "My integration",
"createdTime": 0,
"lastUpdatedTime": 0,
"tasks": [{"type": "continuous", "name": "poll", "action": False}],
}


class TestIntegrations:
def test_list(self, cognite_client: CogniteClient, async_client: AsyncCogniteClient, httpx_mock: HTTPXMock) -> None:
url_pattern = re.compile(re.escape(get_url(async_client.integrations, "/integrations")) + r"(?:\?.*)?$")
httpx_mock.add_response(method="GET", url=url_pattern, json={"items": [INTEGRATION_RESPONSE]})

res = cognite_client.integrations.list(limit=10)

assert isinstance(res, IntegrationList)
assert len(res) == 1
assert res[0].external_id == "my-integration"
assert res[0].tasks[0].name == "poll"

request = httpx_mock.get_requests()[0]
assert request.method == "GET"
assert request.headers["cdf-version"] == async_client.integrations._beta_version_header()["cdf-version"]

def test_create(
self, cognite_client: CogniteClient, async_client: AsyncCogniteClient, httpx_mock: HTTPXMock
) -> None:
httpx_mock.add_response(
method="POST",
url=get_url(async_client.integrations, "/integrations"),
json={"items": [INTEGRATION_RESPONSE]},
)
integration = IntegrationWrite(
external_id="my-integration",
extractor=Extractor(external_id="cognite-simple-influxdb-extractor", version="1.0.0"),
name="My integration",
)

res = cognite_client.integrations.create(integration)

assert isinstance(res, Integration)
assert res.external_id == "my-integration"

body = jsgz_load(httpx_mock.get_requests()[0].content)
assert body == {
"items": [
{
"externalId": "my-integration",
"name": "My integration",
"extractor": {"externalId": "cognite-simple-influxdb-extractor", "version": "1.0.0"},
}
]
}

def test_retrieve(
self, cognite_client: CogniteClient, async_client: AsyncCogniteClient, httpx_mock: HTTPXMock
) -> None:
httpx_mock.add_response(
method="POST",
url=get_url(async_client.integrations, "/integrations/byids"),
json={"items": [INTEGRATION_RESPONSE]},
)

res = cognite_client.integrations.retrieve("my-integration")

assert isinstance(res, Integration)
assert res.external_id == "my-integration"

body = jsgz_load(httpx_mock.get_requests()[0].content)
assert body == {"items": [{"externalId": "my-integration"}], "ignoreUnknownIds": False}

def test_update(
self, cognite_client: CogniteClient, async_client: AsyncCogniteClient, httpx_mock: HTTPXMock
) -> None:
httpx_mock.add_response(
method="POST",
url=get_url(async_client.integrations, "/integrations/update"),
json={"items": [INTEGRATION_RESPONSE]},
)
update = IntegrationUpdate(external_id="my-integration")
update.description.set("My new description")

res = cognite_client.integrations.update(update)

assert isinstance(res, Integration)

body = jsgz_load(httpx_mock.get_requests()[0].content)
assert body == {
"items": [{"externalId": "my-integration", "update": {"description": {"set": "My new description"}}}]
}

def test_delete(
self, cognite_client: CogniteClient, async_client: AsyncCogniteClient, httpx_mock: HTTPXMock
) -> None:
httpx_mock.add_response(method="POST", url=get_url(async_client.integrations, "/integrations/delete"), json={})

cognite_client.integrations.delete("my-integration")

body = jsgz_load(httpx_mock.get_requests()[0].content)
assert body == {"items": [{"externalId": "my-integration"}], "ignoreUnknownIds": False}
65 changes: 65 additions & 0 deletions tests/tests_unit/test_api/test_integrations/test_tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from __future__ import annotations

import re

import pytest
from pytest_httpx import HTTPXMock

from cognite.client import AsyncCogniteClient, CogniteClient
from cognite.client.data_classes.integrations.tasks import SyncResult, TaskHistoryList
from tests.utils import get_url

TASK_HISTORY_RESPONSE = {
"externalId": "my-integration",
"taskName": "poll",
"startTime": 100,
"endTime": 200,
"errorCount": 0,
}


class TestIntegrationTasks:
def test_list_history(
self, cognite_client: CogniteClient, async_client: AsyncCogniteClient, httpx_mock: HTTPXMock
) -> None:
url_pattern = re.compile(
re.escape(get_url(async_client.integrations.tasks, "/integrations/history")) + r"(?:\?.*)?$"
)
httpx_mock.add_response(method="GET", url=url_pattern, json={"items": [TASK_HISTORY_RESPONSE]})

res = cognite_client.integrations.tasks.list_history(external_id="my-integration", task_name="poll")

assert isinstance(res, TaskHistoryList)
assert len(res) == 1
assert res[0].task_name == "poll"

request = httpx_mock.get_requests()[0]
assert "externalId=my-integration" in str(request.url)
assert "taskName=poll" in str(request.url)

def test_list_history_task_name_without_external_id_raises(self, cognite_client: CogniteClient) -> None:
with pytest.raises(ValueError, match="'task_name' requires 'external_id'"):
cognite_client.integrations.tasks.list_history(task_name="poll")

def test_sync(self, cognite_client: CogniteClient, async_client: AsyncCogniteClient, httpx_mock: HTTPXMock) -> None:
url_pattern = re.compile(
re.escape(get_url(async_client.integrations.tasks, "/integrations/sync")) + r"(?:\?.*)?$"
)
httpx_mock.add_response(
method="GET",
url=url_pattern,
json={"nextCursor": "abc", "moreData": False, "history": [TASK_HISTORY_RESPONSE]},
)

res = cognite_client.integrations.tasks.sync(external_id="my-integration", include_task_updates=True)

assert isinstance(res, SyncResult)
assert res.next_cursor == "abc"
assert res.more_data is False
assert res.history is not None
assert res.history[0].task_name == "poll"
assert res.errors is None

def test_sync_requires_include_errors_or_include_task_updates(self, cognite_client: CogniteClient) -> None:
with pytest.raises(ValueError, match="'include_errors' or 'include_task_updates'"):
cognite_client.integrations.tasks.sync(external_id="my-integration")
Loading
Loading