port-ocean 0.10.10__py3-none-any.whl → 0.10.11__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of port-ocean might be problematic. Click here for more details.

@@ -0,0 +1,4 @@
1
+ # ruff: noqa
2
+ from port_ocean.tests.helpers.fixtures import (
3
+ port_client_for_fake_integration,
4
+ )
@@ -1,80 +0,0 @@
1
- import sys
2
- from inspect import getmembers
3
- from pathlib import Path
4
- from typing import Dict, List, Set, Tuple, Union
5
-
6
- from yaml import safe_load
7
-
8
- from port_ocean.bootstrap import create_default_app
9
- from port_ocean.core.handlers.port_app_config.models import ResourceConfig
10
- from port_ocean.core.ocean_types import RESYNC_RESULT
11
- from port_ocean.ocean import Ocean
12
- from port_ocean.utils.misc import get_spec_file, load_module
13
-
14
-
15
- def get_integration_ocean_app(integration_path: str) -> Ocean:
16
- spec_file = get_spec_file(Path(integration_path))
17
-
18
- config_factory = None if not spec_file else spec_file.get("configurations", [])
19
-
20
- default_app = create_default_app(
21
- integration_path,
22
- config_factory,
23
- {
24
- "port": {
25
- "client_id": "bla",
26
- "client_secret": "bla",
27
- },
28
- },
29
- )
30
- main_path = f"{integration_path}/main.py"
31
- sys.path.append(integration_path)
32
- app_module = load_module(main_path)
33
- app: Ocean = {name: item for name, item in getmembers(app_module)}.get(
34
- "app", default_app
35
- )
36
-
37
- return app
38
-
39
-
40
- def get_integation_resource_configs(integration_path: str) -> List[ResourceConfig]:
41
- with open(
42
- f"{integration_path}/.port/resources/port-app-config.yml"
43
- ) as port_app_config_file:
44
- resource_configs = safe_load(port_app_config_file)
45
-
46
- return [ResourceConfig(**item) for item in resource_configs["resources"]]
47
-
48
-
49
- def get_integation_resource_config_by_name(
50
- integration_path: str, kind: str
51
- ) -> Union[ResourceConfig, None]:
52
- resource_configs = get_integation_resource_configs(integration_path)
53
-
54
- relevant_configs = [x for x in resource_configs if x.kind == kind]
55
-
56
- return relevant_configs[0] if len(relevant_configs) else None
57
-
58
-
59
- async def get_raw_result_on_integration_sync_kinds(
60
- integration_path: str, override_kinds: Union[Set[str], None] = None
61
- ) -> Dict[str, List[Tuple[RESYNC_RESULT, List[Exception]]]]:
62
- app = get_integration_ocean_app(integration_path)
63
-
64
- resource_configs = get_integation_resource_configs(integration_path)
65
-
66
- if override_kinds:
67
- resource_configs = [x for x in resource_configs if x.kind in override_kinds]
68
-
69
- results: Dict[str, List[Tuple[RESYNC_RESULT, List[Exception]]]] = {}
70
-
71
- for resource_config in resource_configs:
72
- resource_result = await app.integration._get_resource_raw_results(
73
- resource_config
74
- )
75
-
76
- results[resource_config.kind] = results.get(resource_config.kind, []) + [
77
- resource_result
78
- ]
79
-
80
- return results
@@ -0,0 +1,110 @@
1
+ from os import environ, path
2
+ from typing import Any, AsyncGenerator, Callable, List, Tuple, Union
3
+
4
+ import pytest_asyncio
5
+ from pydantic import BaseModel
6
+
7
+ from port_ocean.clients.port.client import PortClient
8
+ from port_ocean.core.handlers.port_app_config.models import ResourceConfig
9
+ from port_ocean.ocean import Ocean
10
+ from port_ocean.tests.helpers.ocean_app import (
11
+ get_integation_resource_configs,
12
+ get_integration_ocean_app,
13
+ )
14
+
15
+
16
+ def get_port_client_for_integration(
17
+ client_id: str,
18
+ client_secret: str,
19
+ integration_identifier: str,
20
+ integration_type: str,
21
+ integration_version: str,
22
+ base_url: Union[str, None],
23
+ ) -> PortClient:
24
+ return PortClient(
25
+ base_url=base_url or "https://api.getport/io",
26
+ client_id=client_id,
27
+ client_secret=client_secret,
28
+ integration_identifier=integration_identifier,
29
+ integration_type=integration_type,
30
+ integration_version=integration_version,
31
+ )
32
+
33
+
34
+ async def cleanup_integration(client: PortClient, blueprints: List[str]) -> None:
35
+ for blueprint in blueprints:
36
+ bp = await client.get_blueprint(blueprint)
37
+ if bp is not None:
38
+ migration_id = await client.delete_blueprint(
39
+ identifier=blueprint, delete_entities=True
40
+ )
41
+ if migration_id:
42
+ await client.wait_for_migration_to_complete(migration_id=migration_id)
43
+ headers = await client.auth.headers()
44
+ await client.client.delete(f"{client.auth.api_url}/integrations", headers=headers)
45
+
46
+
47
+ class SmokeTestDetails(BaseModel):
48
+ integration_identifier: str
49
+ blueprint_department: str
50
+ blueprint_person: str
51
+
52
+
53
+ @pytest_asyncio.fixture()
54
+ async def port_client_for_fake_integration() -> (
55
+ AsyncGenerator[Tuple[SmokeTestDetails, PortClient], None]
56
+ ):
57
+ blueprint_department = "fake-department"
58
+ blueprint_person = "fake-person"
59
+ integration_identifier = "smoke-test-integration"
60
+ smoke_test_suffix = environ.get("SMOKE_TEST_SUFFIX")
61
+ client_id = environ.get("PORT_CLIENT_ID")
62
+ client_secret = environ.get("PORT_CLIENT_SECRET")
63
+
64
+ if not client_secret or not client_id:
65
+ assert False, "Missing port credentials"
66
+
67
+ base_url = environ.get("PORT_BASE_URL")
68
+ integration_version = "0.1.1-dev"
69
+ integration_type = "smoke-test"
70
+ if smoke_test_suffix is not None:
71
+ integration_identifier = f"{integration_identifier}-{smoke_test_suffix}"
72
+ blueprint_person = f"{blueprint_person}-{smoke_test_suffix}"
73
+ blueprint_department = f"{blueprint_department}-{smoke_test_suffix}"
74
+
75
+ client = get_port_client_for_integration(
76
+ client_id,
77
+ client_secret,
78
+ integration_identifier,
79
+ integration_type,
80
+ integration_version,
81
+ base_url,
82
+ )
83
+
84
+ smoke_test_details = SmokeTestDetails(
85
+ integration_identifier=integration_identifier,
86
+ blueprint_person=blueprint_person,
87
+ blueprint_department=blueprint_department,
88
+ )
89
+ yield smoke_test_details, client
90
+ await cleanup_integration(client, [blueprint_department, blueprint_person])
91
+
92
+
93
+ @pytest_asyncio.fixture
94
+ def get_mocked_ocean_app(request: Any) -> Callable[[], Ocean]:
95
+ test_dir = path.join(path.dirname(request.module.__file__), "..")
96
+
97
+ def get_ocean_app() -> Ocean:
98
+ return get_integration_ocean_app(test_dir)
99
+
100
+ return get_ocean_app
101
+
102
+
103
+ @pytest_asyncio.fixture
104
+ def get_mock_ocean_resource_configs(request: Any) -> Callable[[], List[ResourceConfig]]:
105
+ module_dir = path.join(path.dirname(request.module.__file__), "..")
106
+
107
+ def get_ocean_resource_configs() -> List[ResourceConfig]:
108
+ return get_integation_resource_configs(module_dir)
109
+
110
+ return get_ocean_resource_configs
@@ -0,0 +1,54 @@
1
+ import sys
2
+ from inspect import getmembers
3
+ from pathlib import Path
4
+ from typing import List, Tuple
5
+
6
+ from yaml import safe_load
7
+
8
+ from port_ocean.bootstrap import create_default_app
9
+ from port_ocean.core.handlers.port_app_config.models import ResourceConfig
10
+ from port_ocean.core.ocean_types import RESYNC_RESULT
11
+ from port_ocean.ocean import Ocean
12
+ from port_ocean.utils.misc import get_spec_file, load_module
13
+
14
+
15
+ def get_integration_ocean_app(integration_path: str) -> Ocean:
16
+ spec_file = get_spec_file(Path(integration_path))
17
+
18
+ config_factory = None if not spec_file else spec_file.get("configurations", [])
19
+
20
+ default_app = create_default_app(
21
+ integration_path,
22
+ config_factory,
23
+ {
24
+ "port": {
25
+ "client_id": "bla",
26
+ "client_secret": "bla",
27
+ },
28
+ },
29
+ )
30
+ main_path = f"{integration_path}/main.py"
31
+ sys.path.append(integration_path)
32
+ app_module = load_module(main_path)
33
+ app: Ocean = {name: item for name, item in getmembers(app_module)}.get(
34
+ "app", default_app
35
+ )
36
+
37
+ return app
38
+
39
+
40
+ def get_integation_resource_configs(integration_path: str) -> List[ResourceConfig]:
41
+ with open(
42
+ f"{integration_path}/.port/resources/port-app-config.yml"
43
+ ) as port_app_config_file:
44
+ resource_configs = safe_load(port_app_config_file)
45
+
46
+ return [ResourceConfig(**item) for item in resource_configs["resources"]]
47
+
48
+
49
+ async def get_raw_result_on_integration_sync_resource_config(
50
+ app: Ocean, resource_config: ResourceConfig
51
+ ) -> Tuple[RESYNC_RESULT, List[Exception]]:
52
+ resource_result = await app.integration._get_resource_raw_results(resource_config)
53
+
54
+ return resource_result
@@ -0,0 +1,71 @@
1
+ from os import environ
2
+ from typing import Tuple
3
+ import pytest
4
+
5
+ from port_ocean.clients.port.client import PortClient
6
+ from port_ocean.clients.port.types import UserAgentType
7
+ from port_ocean.tests.helpers.fixtures import SmokeTestDetails
8
+
9
+
10
+ @pytest.mark.skipif(
11
+ environ.get("SMOKE_TEST_SUFFIX", None) is None,
12
+ reason="You need to run the fake integration once",
13
+ )
14
+ async def test_valid_fake_integration(
15
+ port_client_for_fake_integration: Tuple[SmokeTestDetails, PortClient],
16
+ ) -> None:
17
+ _, port_client = port_client_for_fake_integration
18
+ current_integration = await port_client.get_current_integration()
19
+ assert current_integration is not None
20
+ assert current_integration.get("resyncState") is not None
21
+ assert current_integration.get("resyncState", {}).get("status") == "completed"
22
+
23
+
24
+ @pytest.mark.skipif(
25
+ environ.get("SMOKE_TEST_SUFFIX", None) is None,
26
+ reason="You need to run the fake integration once",
27
+ )
28
+ async def test_valid_fake_departments(
29
+ port_client_for_fake_integration: Tuple[SmokeTestDetails, PortClient],
30
+ ) -> None:
31
+ details, port_client = port_client_for_fake_integration
32
+ entities = await port_client.search_entities(user_agent_type=UserAgentType.exporter)
33
+ assert len(entities)
34
+ departments = [
35
+ x for x in entities if f"{x.blueprint}" == details.blueprint_department
36
+ ]
37
+ assert len(departments) == 5
38
+
39
+
40
+ @pytest.mark.skipif(
41
+ environ.get("SMOKE_TEST_SUFFIX", None) is None,
42
+ reason="You need to run the fake integration once",
43
+ )
44
+ async def test_valid_fake_persons(
45
+ port_client_for_fake_integration: Tuple[SmokeTestDetails, PortClient],
46
+ ) -> None:
47
+ details, port_client = port_client_for_fake_integration
48
+ headers = await port_client.auth.headers()
49
+ fake_person_entities_result = await port_client.client.get(
50
+ f"{port_client.auth.api_url}/blueprints/{details.blueprint_person}/entities",
51
+ headers=headers,
52
+ )
53
+
54
+ fake_person_entities = fake_person_entities_result.json()["entities"]
55
+ assert len(fake_person_entities)
56
+
57
+ fake_departments_result = await port_client.client.get(
58
+ f"{port_client.auth.api_url}/blueprints/{details.blueprint_department}/entities",
59
+ headers=headers,
60
+ )
61
+
62
+ departments = [x["identifier"] for x in fake_departments_result.json()["entities"]]
63
+
64
+ for department in departments:
65
+ assert len(
66
+ [
67
+ x
68
+ for x in fake_person_entities
69
+ if x["relations"]["department"] == department
70
+ ]
71
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: port-ocean
3
- Version: 0.10.10
3
+ Version: 0.10.11
4
4
  Summary: Port Ocean is a CLI tool for managing your Port projects.
5
5
  Home-page: https://app.getport.io
6
6
  Keywords: ocean,port-ocean,port
@@ -121,8 +121,12 @@ port_ocean/run.py,sha256=rTxBlrQd4yyrtgErCFJCHCEHs7d1OXrRiJehUYmIbN0,2212
121
121
  port_ocean/sonar-project.properties,sha256=X_wLzDOkEVmpGLRMb2fg9Rb0DxWwUFSvESId8qpvrPI,73
122
122
  port_ocean/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
123
123
  port_ocean/tests/clients/port/mixins/test_entities.py,sha256=A9myrnkLhKSQrnOLv1Zz2wiOVSxW65Q9RIUIRbn_V7w,1586
124
- port_ocean/tests/helpers/__init__.py,sha256=K-8wwjJz9N5F76P3NZZxe-g7nroMGjHl3semIjyuNog,2567
124
+ port_ocean/tests/conftest.py,sha256=JXASSS0IY0nnR6bxBflhzxS25kf4iNaABmThyZ0mZt8,101
125
+ port_ocean/tests/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
126
+ port_ocean/tests/helpers/fixtures.py,sha256=XGR8wjcAKBBYoIRKh_KzFg1PdqhlL9GqqR8z_q08nHA,3699
127
+ port_ocean/tests/helpers/ocean_app.py,sha256=Dp1bwEDhWsx_G-KVxOfJX1eVIS4168ajLu39wAY275g,1693
125
128
  port_ocean/tests/test_sample.py,sha256=Ew5LA_G1k6DC5a2ygU2FoyjZQa0fRmPy73N0bio0d14,46
129
+ port_ocean/tests/test_smoke.py,sha256=F-1MoEcdIT1smjWv3s1iaS7U5UxpKGf-AHc8mYHjOlw,2522
126
130
  port_ocean/utils/__init__.py,sha256=KMGnCPXZJbNwtgxtyMycapkDz8tpSyw23MSYT3iVeHs,91
127
131
  port_ocean/utils/async_http.py,sha256=arnH458TExn2Dju_Sy6pHas_vF5RMWnOp-jBz5WAAcE,1226
128
132
  port_ocean/utils/async_iterators.py,sha256=iw3cUHxfQm3zUSPdw2FmSXDU8E1Ppnys4TGhswNuQ8s,1569
@@ -133,8 +137,8 @@ port_ocean/utils/repeat.py,sha256=0EFWM9d8lLXAhZmAyczY20LAnijw6UbIECf5lpGbOas,32
133
137
  port_ocean/utils/signal.py,sha256=K-6kKFQTltcmKDhtyZAcn0IMa3sUpOHGOAUdWKgx0_E,1369
134
138
  port_ocean/utils/time.py,sha256=pufAOH5ZQI7gXvOvJoQXZXZJV-Dqktoj9Qp9eiRwmJ4,1939
135
139
  port_ocean/version.py,sha256=UsuJdvdQlazzKGD3Hd5-U7N69STh8Dq9ggJzQFnu9fU,177
136
- port_ocean-0.10.10.dist-info/LICENSE.md,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
137
- port_ocean-0.10.10.dist-info/METADATA,sha256=TYp3Vs2UhjxUckbdD-qPXrmJONsIn94f66BHbsSmtxI,6617
138
- port_ocean-0.10.10.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
139
- port_ocean-0.10.10.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
140
- port_ocean-0.10.10.dist-info/RECORD,,
140
+ port_ocean-0.10.11.dist-info/LICENSE.md,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
141
+ port_ocean-0.10.11.dist-info/METADATA,sha256=SffnArX7jyPJC_Tu_66jLqUtGwspuroiBDAycOH1RYY,6617
142
+ port_ocean-0.10.11.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
143
+ port_ocean-0.10.11.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
144
+ port_ocean-0.10.11.dist-info/RECORD,,