port-ocean 0.17.5__py3-none-any.whl → 0.17.6__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.

@@ -147,6 +147,7 @@ class SyncRawMixin(HandlerMixin, EventsMixin):
147
147
  return CalculationResult(
148
148
  objects_diff[0].entity_selector_diff._replace(passed=modified_objects),
149
149
  errors=objects_diff[0].errors,
150
+ misonfigured_entity_keys=objects_diff[0].misonfigured_entity_keys,
150
151
  )
151
152
 
152
153
  async def _unregister_resource_raw(
@@ -162,7 +163,7 @@ class SyncRawMixin(HandlerMixin, EventsMixin):
162
163
  return [], []
163
164
 
164
165
  objects_diff = await self._calculate_raw([(resource, results)])
165
- entities_selector_diff, errors = objects_diff[0]
166
+ entities_selector_diff, errors, _ = objects_diff[0]
166
167
 
167
168
  await self.entities_state_applier.delete(
168
169
  entities_selector_diff.passed, user_agent_type
@@ -245,7 +246,7 @@ class SyncRawMixin(HandlerMixin, EventsMixin):
245
246
  if not resource_mappings:
246
247
  return []
247
248
 
248
- diffs, errors = zip(
249
+ diffs, errors, misconfigured_entity_keys = zip(
249
250
  *await asyncio.gather(
250
251
  *(
251
252
  self._register_resource_raw(
@@ -258,6 +259,8 @@ class SyncRawMixin(HandlerMixin, EventsMixin):
258
259
 
259
260
  diffs = list(diffs)
260
261
  errors = sum(errors, [])
262
+ misconfigured_entity_keys = list(misconfigured_entity_keys)
263
+
261
264
 
262
265
  if errors:
263
266
  message = f"Failed to register {len(errors)} entities. Skipping delete phase due to incomplete state"
@@ -164,6 +164,14 @@ def mock_sync_raw_mixin(
164
164
  return sync_raw_mixin
165
165
 
166
166
 
167
+ @pytest.fixture
168
+ def mock_sync_raw_mixin_with_jq_processor(
169
+ mock_sync_raw_mixin: SyncRawMixin,
170
+ ) -> SyncRawMixin:
171
+ mock_sync_raw_mixin._entity_processor = JQEntityProcessor(mock_context) # type: ignore
172
+ return mock_sync_raw_mixin
173
+
174
+
167
175
  @asynccontextmanager
168
176
  async def no_op_event_context(
169
177
  existing_event: EventContext,
@@ -398,3 +406,147 @@ async def test_sync_raw_mixin_dependency(
398
406
  "entity_3-entity_1-entity_4-entity_2-entity_5",
399
407
  "entity_3-entity_1-entity_4-entity_5-entity_2",
400
408
  )
409
+
410
+
411
+ @pytest.mark.asyncio
412
+ async def test_register_raw(
413
+ mock_sync_raw_mixin_with_jq_processor: SyncRawMixin, mock_ocean: Ocean
414
+ ) -> None:
415
+ kind = "service"
416
+ user_agent_type = UserAgentType.exporter
417
+ raw_entity = [
418
+ {"id": "entity_1", "name": "entity_1", "web_url": "https://example.com"},
419
+ ]
420
+ expected_result = [
421
+ {
422
+ "identifier": "entity_1",
423
+ "blueprint": "service",
424
+ "name": "entity_1",
425
+ "properties": {"url": "https://example.com"},
426
+ },
427
+ ]
428
+
429
+ async with event_context(EventType.HTTP_REQUEST, trigger_type="machine") as event:
430
+ # Use patch to mock the method instead of direct assignment
431
+ with patch.object(
432
+ mock_sync_raw_mixin_with_jq_processor.port_app_config_handler,
433
+ "get_port_app_config",
434
+ return_value=PortAppConfig(
435
+ enable_merge_entity=True,
436
+ delete_dependent_entities=True,
437
+ create_missing_related_entities=False,
438
+ resources=[
439
+ ResourceConfig(
440
+ kind=kind,
441
+ selector=Selector(query="true"),
442
+ port=PortResourceConfig(
443
+ entity=MappingsConfig(
444
+ mappings=EntityMapping(
445
+ identifier=".id | tostring",
446
+ title=".name",
447
+ blueprint='"service"',
448
+ properties={"url": ".web_url"},
449
+ relations={},
450
+ )
451
+ )
452
+ ),
453
+ )
454
+ ],
455
+ ),
456
+ ):
457
+ # Ensure the event.port_app_config is set correctly
458
+ event.port_app_config = await mock_sync_raw_mixin_with_jq_processor.port_app_config_handler.get_port_app_config(
459
+ use_cache=False
460
+ )
461
+
462
+ def upsert_side_effect(
463
+ entities: list[Entity], user_agent_type: UserAgentType
464
+ ) -> list[Entity]:
465
+ # Simulate returning the passed entities
466
+ return entities
467
+
468
+ # Patch the upsert method with the side effect
469
+ with patch.object(
470
+ mock_sync_raw_mixin_with_jq_processor.entities_state_applier,
471
+ "upsert",
472
+ side_effect=upsert_side_effect,
473
+ ):
474
+ # Call the register_raw method
475
+ registered_entities = (
476
+ await mock_sync_raw_mixin_with_jq_processor.register_raw(
477
+ kind, raw_entity, user_agent_type
478
+ )
479
+ )
480
+
481
+ # Assert that the registered entities match the expected results
482
+ assert len(registered_entities) == len(expected_result)
483
+ for entity, result in zip(registered_entities, expected_result):
484
+ assert entity.identifier == result["identifier"]
485
+ assert entity.blueprint == result["blueprint"]
486
+ assert entity.properties == result["properties"]
487
+
488
+
489
+ @pytest.mark.asyncio
490
+ async def test_unregister_raw(
491
+ mock_sync_raw_mixin_with_jq_processor: SyncRawMixin, mock_ocean: Ocean
492
+ ) -> None:
493
+ kind = "service"
494
+ user_agent_type = UserAgentType.exporter
495
+ raw_entity = [
496
+ {"id": "entity_1", "name": "entity_1", "web_url": "https://example.com"},
497
+ ]
498
+ expected_result = [
499
+ {
500
+ "identifier": "entity_1",
501
+ "blueprint": "service",
502
+ "name": "entity_1",
503
+ "properties": {"url": "https://example.com"},
504
+ },
505
+ ]
506
+
507
+ async with event_context(EventType.HTTP_REQUEST, trigger_type="machine") as event:
508
+ # Use patch to mock the method instead of direct assignment
509
+ with patch.object(
510
+ mock_sync_raw_mixin_with_jq_processor.port_app_config_handler,
511
+ "get_port_app_config",
512
+ return_value=PortAppConfig(
513
+ enable_merge_entity=True,
514
+ delete_dependent_entities=True,
515
+ create_missing_related_entities=False,
516
+ resources=[
517
+ ResourceConfig(
518
+ kind=kind,
519
+ selector=Selector(query="true"),
520
+ port=PortResourceConfig(
521
+ entity=MappingsConfig(
522
+ mappings=EntityMapping(
523
+ identifier=".id | tostring",
524
+ title=".name",
525
+ blueprint='"service"',
526
+ properties={"url": ".web_url"},
527
+ relations={},
528
+ )
529
+ )
530
+ ),
531
+ )
532
+ ],
533
+ ),
534
+ ):
535
+ # Ensure the event.port_app_config is set correctly
536
+ event.port_app_config = await mock_sync_raw_mixin_with_jq_processor.port_app_config_handler.get_port_app_config(
537
+ use_cache=False
538
+ )
539
+
540
+ # Call the unregister_raw method
541
+ unregistered_entities = (
542
+ await mock_sync_raw_mixin_with_jq_processor.unregister_raw(
543
+ kind, raw_entity, user_agent_type
544
+ )
545
+ )
546
+
547
+ # Assert that the unregistered entities match the expected results
548
+ assert len(unregistered_entities) == len(expected_result)
549
+ for entity, result in zip(unregistered_entities, expected_result):
550
+ assert entity.identifier == result["identifier"]
551
+ assert entity.blueprint == result["blueprint"]
552
+ assert entity.properties == result["properties"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: port-ocean
3
- Version: 0.17.5
3
+ Version: 0.17.6
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
@@ -101,7 +101,7 @@ port_ocean/core/integrations/mixins/__init__.py,sha256=FA1FEKMM6P-L2_m7Q4L20mFa4
101
101
  port_ocean/core/integrations/mixins/events.py,sha256=0jKRsBw6lU8Mqs7MaQK4n-t_H6Z4NEkXZ5VWzqTrKEc,2396
102
102
  port_ocean/core/integrations/mixins/handler.py,sha256=mZ7-0UlG3LcrwJttFbMe-R4xcOU2H_g33tZar7PwTv8,3771
103
103
  port_ocean/core/integrations/mixins/sync.py,sha256=B9fEs8faaYLLikH9GBjE_E61vo0bQDjIGQsQ1SRXOlA,3931
104
- port_ocean/core/integrations/mixins/sync_raw.py,sha256=Wir4aTSCkIvG6Ny9Eo0Xf55OkSbh_6wHfNSaCffAKJQ,20279
104
+ port_ocean/core/integrations/mixins/sync_raw.py,sha256=a23humX9HRS6xPWQhetbBcSQv3o29q2a72c9y3Do_1U,20457
105
105
  port_ocean/core/integrations/mixins/utils.py,sha256=oN4Okz6xlaefpid1_Pud8HPSw9BwwjRohyNsknq-Myg,2309
106
106
  port_ocean/core/models.py,sha256=O8nOKc4ORZz9tS5s6y5YgGLEBroXpvSPDqKuz48uKvs,1965
107
107
  port_ocean/core/ocean_types.py,sha256=j_-or1VxDy22whLLxwxgzIsE4wAhFLH19Xff9l4oJA8,1124
@@ -133,7 +133,7 @@ port_ocean/tests/clients/port/mixins/test_entities.py,sha256=A9myrnkLhKSQrnOLv1Z
133
133
  port_ocean/tests/conftest.py,sha256=JXASSS0IY0nnR6bxBflhzxS25kf4iNaABmThyZ0mZt8,101
134
134
  port_ocean/tests/core/defaults/test_common.py,sha256=sR7RqB3ZYV6Xn6NIg-c8k5K6JcGsYZ2SCe_PYX5vLYM,5560
135
135
  port_ocean/tests/core/handlers/entity_processor/test_jq_entity_processor.py,sha256=FnEnaDjuoAbKvKyv6xJ46n3j0ZcaT70Sg2zc7oy7HAA,13596
136
- port_ocean/tests/core/handlers/mixins/test_sync_raw.py,sha256=RPrbw4Zs6bmhL9zMQviq7-qMfgP5_4nJDkfZiAukK-g,15782
136
+ port_ocean/tests/core/handlers/mixins/test_sync_raw.py,sha256=qpIrcF5A9B5WA0XW0PXplcSHdM7sjHAsqNccrY7TMk0,21887
137
137
  port_ocean/tests/core/test_utils.py,sha256=Z3kdhb5V7Svhcyy3EansdTpgHL36TL6erNtU-OPwAcI,2647
138
138
  port_ocean/tests/core/utils/test_entity_topological_sorter.py,sha256=zuq5WSPy_88PemG3mOUIHTxWMR_js1R7tOzUYlgBd68,3447
139
139
  port_ocean/tests/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -157,8 +157,8 @@ port_ocean/utils/repeat.py,sha256=0EFWM9d8lLXAhZmAyczY20LAnijw6UbIECf5lpGbOas,32
157
157
  port_ocean/utils/signal.py,sha256=K-6kKFQTltcmKDhtyZAcn0IMa3sUpOHGOAUdWKgx0_E,1369
158
158
  port_ocean/utils/time.py,sha256=pufAOH5ZQI7gXvOvJoQXZXZJV-Dqktoj9Qp9eiRwmJ4,1939
159
159
  port_ocean/version.py,sha256=UsuJdvdQlazzKGD3Hd5-U7N69STh8Dq9ggJzQFnu9fU,177
160
- port_ocean-0.17.5.dist-info/LICENSE.md,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
161
- port_ocean-0.17.5.dist-info/METADATA,sha256=MLLVprYgIbrMB7-PJAhNDxR3k18AXhgen-D-rh-5A7w,6673
162
- port_ocean-0.17.5.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
163
- port_ocean-0.17.5.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
164
- port_ocean-0.17.5.dist-info/RECORD,,
160
+ port_ocean-0.17.6.dist-info/LICENSE.md,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
161
+ port_ocean-0.17.6.dist-info/METADATA,sha256=TKcBAHIAELisX7FYMubFZq5aXplH-eCuMbH6q0r2kU4,6673
162
+ port_ocean-0.17.6.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
163
+ port_ocean-0.17.6.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
164
+ port_ocean-0.17.6.dist-info/RECORD,,