linkedapi 1.3.5__tar.gz → 1.3.7__tar.gz

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.
Files changed (108) hide show
  1. {linkedapi-1.3.5 → linkedapi-1.3.7}/PKG-INFO +1 -1
  2. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/__init__.py +1 -1
  3. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/core/operation.py +1 -0
  4. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/errors.py +4 -0
  5. linkedapi-1.3.7/linkedapi/operations/nv_sync_conversation.py +15 -0
  6. linkedapi-1.3.7/linkedapi/operations/sync_conversation.py +15 -0
  7. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/__init__.py +6 -0
  8. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/message.py +11 -0
  9. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/workflow.py +5 -0
  10. {linkedapi-1.3.5 → linkedapi-1.3.7}/pyproject.toml +1 -1
  11. {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/test_errors.py +2 -0
  12. linkedapi-1.3.7/tests/test_working_hours_contract.py +108 -0
  13. linkedapi-1.3.5/linkedapi/operations/nv_sync_conversation.py +0 -12
  14. linkedapi-1.3.5/linkedapi/operations/sync_conversation.py +0 -12
  15. {linkedapi-1.3.5 → linkedapi-1.3.7}/.github/workflows/publish.yaml +0 -0
  16. {linkedapi-1.3.5 → linkedapi-1.3.7}/.gitignore +0 -0
  17. {linkedapi-1.3.5 → linkedapi-1.3.7}/LICENSE +0 -0
  18. {linkedapi-1.3.5 → linkedapi-1.3.7}/README.md +0 -0
  19. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/admin/__init__.py +0 -0
  20. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/admin/accounts.py +0 -0
  21. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/admin/admin.py +0 -0
  22. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/admin/http_client.py +0 -0
  23. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/admin/limits.py +0 -0
  24. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/admin/subscription.py +0 -0
  25. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/admin/webhooks.py +0 -0
  26. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/client.py +0 -0
  27. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/config.py +0 -0
  28. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/core/__init__.py +0 -0
  29. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/core/polling.py +0 -0
  30. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/http/__init__.py +0 -0
  31. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/http/base.py +0 -0
  32. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/http/linked_api_http_client.py +0 -0
  33. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/mappers/__init__.py +0 -0
  34. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/mappers/array.py +0 -0
  35. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/mappers/base.py +0 -0
  36. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/mappers/send_message.py +0 -0
  37. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/mappers/simple.py +0 -0
  38. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/mappers/then.py +0 -0
  39. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/mappers/void.py +0 -0
  40. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/__init__.py +0 -0
  41. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/accept_invitation.py +0 -0
  42. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/check_connection_status.py +0 -0
  43. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/comment_on_post.py +0 -0
  44. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/create_post.py +0 -0
  45. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/custom_workflow.py +0 -0
  46. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/fetch_company.py +0 -0
  47. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/fetch_job.py +0 -0
  48. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/fetch_person.py +0 -0
  49. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/fetch_post.py +0 -0
  50. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/ignore_invitation.py +0 -0
  51. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/manage_conversation.py +0 -0
  52. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/nv_fetch_company.py +0 -0
  53. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/nv_fetch_person.py +0 -0
  54. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/nv_manage_conversation.py +0 -0
  55. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/nv_search_companies.py +0 -0
  56. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/nv_search_people.py +0 -0
  57. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/nv_send_message.py +0 -0
  58. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/nv_sync_inbox.py +0 -0
  59. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/react_to_comment.py +0 -0
  60. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/react_to_post.py +0 -0
  61. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/remove_connection.py +0 -0
  62. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/reply_to_comment.py +0 -0
  63. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/retrieve_connections.py +0 -0
  64. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/retrieve_feed.py +0 -0
  65. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/retrieve_invitations.py +0 -0
  66. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/retrieve_pending_requests.py +0 -0
  67. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/retrieve_performance.py +0 -0
  68. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/retrieve_ssi.py +0 -0
  69. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/search_companies.py +0 -0
  70. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/search_jobs.py +0 -0
  71. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/search_people.py +0 -0
  72. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/send_connection_request.py +0 -0
  73. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/send_message.py +0 -0
  74. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/sync_inbox.py +0 -0
  75. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/sync_network.py +0 -0
  76. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/withdraw_connection_request.py +0 -0
  77. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/py.typed +0 -0
  78. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/account.py +0 -0
  79. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/admin/__init__.py +0 -0
  80. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/admin/accounts.py +0 -0
  81. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/admin/config.py +0 -0
  82. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/admin/limits.py +0 -0
  83. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/admin/subscription.py +0 -0
  84. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/base.py +0 -0
  85. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/company.py +0 -0
  86. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/connection.py +0 -0
  87. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/feed.py +0 -0
  88. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/jobs.py +0 -0
  89. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/network.py +0 -0
  90. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/params.py +0 -0
  91. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/person.py +0 -0
  92. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/post.py +0 -0
  93. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/responses.py +0 -0
  94. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/search_companies.py +0 -0
  95. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/search_people.py +0 -0
  96. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/statistics.py +0 -0
  97. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/webhooks.py +0 -0
  98. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/webhooks/__init__.py +0 -0
  99. {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/webhooks/parse.py +0 -0
  100. {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/conftest.py +0 -0
  101. {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/test_admin.py +0 -0
  102. {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/test_direct_methods.py +0 -0
  103. {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/test_http_client.py +0 -0
  104. {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/test_mappers.py +0 -0
  105. {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/test_models.py +0 -0
  106. {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/test_operations.py +0 -0
  107. {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/test_polling.py +0 -0
  108. {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/test_webhooks.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: linkedapi
3
- Version: 1.3.5
3
+ Version: 1.3.7
4
4
  Summary: Official synchronous Python SDK for Linked API.
5
5
  Project-URL: Homepage, https://linkedapi.io
6
6
  Project-URL: Repository, https://github.com/Linked-API/linkedapi-python
@@ -78,7 +78,7 @@ from linkedapi.types import * # noqa: F403
78
78
  from linkedapi.types import __all__ as _types_all
79
79
  from linkedapi.webhooks import parse_webhook_event
80
80
 
81
- __version__ = "1.3.5"
81
+ __version__ = "1.3.7"
82
82
  PredefinedOperation = Operation
83
83
 
84
84
  __all__ = [
@@ -60,6 +60,7 @@ class Operation(ABC, Generic[TParams, TResult]):
60
60
  workflow_id=workflow_id,
61
61
  workflow_status=workflow_result.workflow_status,
62
62
  message=workflow_result.message,
63
+ pending_reason=workflow_result.pending_reason,
63
64
  )
64
65
 
65
66
  completion = self._get_completion(workflow_result)
@@ -66,6 +66,8 @@ LinkedApiErrorType = Literal[
66
66
  "linkedinAccountSignedOut",
67
67
  "languageNotSupported",
68
68
  "workflowTimeout",
69
+ "outsideWorkingHours",
70
+ "workingHoursWaitExpired",
69
71
  "httpError",
70
72
  "tooManyRequests",
71
73
  "accountNotFound",
@@ -87,6 +89,8 @@ LINKED_API_ERROR_TYPES: tuple[str, ...] = (
87
89
  "linkedinAccountSignedOut",
88
90
  "languageNotSupported",
89
91
  "workflowTimeout",
92
+ "outsideWorkingHours",
93
+ "workingHoursWaitExpired",
90
94
  "httpError",
91
95
  "tooManyRequests",
92
96
  "accountNotFound",
@@ -0,0 +1,15 @@
1
+ from __future__ import annotations
2
+
3
+ from linkedapi.core import Operation
4
+ from linkedapi.mappers import SimpleWorkflowMapper
5
+ from linkedapi.types import NvSyncConversationParams, NvSyncConversationResult
6
+
7
+
8
+ class NvSyncConversation(Operation[NvSyncConversationParams, NvSyncConversationResult]):
9
+ """Sync a Sales Navigator conversation."""
10
+
11
+ operation_name = "nvSyncConversation"
12
+ mapper = SimpleWorkflowMapper[NvSyncConversationParams, NvSyncConversationResult](
13
+ "nv.syncConversation",
14
+ result_model=NvSyncConversationResult,
15
+ )
@@ -0,0 +1,15 @@
1
+ from __future__ import annotations
2
+
3
+ from linkedapi.core import Operation
4
+ from linkedapi.mappers import SimpleWorkflowMapper
5
+ from linkedapi.types import SyncConversationParams, SyncConversationResult
6
+
7
+
8
+ class SyncConversation(Operation[SyncConversationParams, SyncConversationResult]):
9
+ """Sync a standard LinkedIn conversation."""
10
+
11
+ operation_name = "syncConversation"
12
+ mapper = SimpleWorkflowMapper[SyncConversationParams, SyncConversationResult](
13
+ "st.syncConversation",
14
+ result_model=SyncConversationResult,
15
+ )
@@ -115,10 +115,12 @@ from linkedapi.types.message import (
115
115
  NvManageConversationParams,
116
116
  NvSendMessageParams,
117
117
  NvSyncConversationParams,
118
+ NvSyncConversationResult,
118
119
  NvSyncInboxParams,
119
120
  SendMessageManageConversation,
120
121
  SendMessageParams,
121
122
  SyncConversationParams,
123
+ SyncConversationResult,
122
124
  SyncInboxParams,
123
125
  )
124
126
  from linkedapi.types.network import (
@@ -235,6 +237,7 @@ from linkedapi.types.workflow import (
235
237
  WorkflowFailure,
236
238
  WorkflowInProgressResponse,
237
239
  WorkflowInProgressStatus,
240
+ WorkflowPendingReason,
238
241
  WorkflowResponse,
239
242
  WorkflowStartedResponse,
240
243
  WorkflowStatus,
@@ -360,6 +363,7 @@ __all__ = [
360
363
  "NvSearchPeopleResult",
361
364
  "NvSendMessageParams",
362
365
  "NvSyncConversationParams",
366
+ "NvSyncConversationResult",
363
367
  "NvSyncInboxParams",
364
368
  "PendingConnectionSession",
365
369
  "Person",
@@ -430,6 +434,7 @@ __all__ = [
430
434
  "SubscriptionStatus",
431
435
  "SubscriptionStatusValue",
432
436
  "SyncConversationParams",
437
+ "SyncConversationResult",
433
438
  "SyncInboxParams",
434
439
  "SyncNetworkParams",
435
440
  "WebhookDelivery",
@@ -448,6 +453,7 @@ __all__ = [
448
453
  "WorkflowFailure",
449
454
  "WorkflowInProgressResponse",
450
455
  "WorkflowInProgressStatus",
456
+ "WorkflowPendingReason",
451
457
  "WorkflowResponse",
452
458
  "WorkflowStartedResponse",
453
459
  "WorkflowStatus",
@@ -22,6 +22,11 @@ class SendMessageParams(BaseActionParams):
22
22
 
23
23
  class SyncConversationParams(BaseActionParams):
24
24
  person_url: str
25
+ days: int | None = None
26
+
27
+
28
+ class SyncConversationResult(LinkedApiModel):
29
+ sync_until: str
25
30
 
26
31
 
27
32
  class SyncInboxParams(BaseActionParams):
@@ -42,6 +47,11 @@ class NvSendMessageParams(BaseActionParams):
42
47
 
43
48
  class NvSyncConversationParams(BaseActionParams):
44
49
  person_url: str
50
+ days: int | None = None
51
+
52
+
53
+ class NvSyncConversationResult(LinkedApiModel):
54
+ sync_until: str
45
55
 
46
56
 
47
57
  class NvSyncInboxParams(BaseActionParams):
@@ -72,6 +82,7 @@ class ConversationPollResult(LinkedApiModel):
72
82
  type: ConversationType | None = None
73
83
  messages: list[Message] | None = None
74
84
  since: str | None = None
85
+ sync_until: str | None = None
75
86
 
76
87
 
77
88
  class InboxPollRequest(LinkedApiModel):
@@ -9,6 +9,7 @@ WorkflowPendingStatus = Literal["pending"]
9
9
  WorkflowRunningStatus = Literal["running"]
10
10
  WorkflowInProgressStatus = Literal["pending", "running"]
11
11
  WorkflowStatus = Literal["pending", "running", "completed", "failed"]
12
+ WorkflowPendingReason = Literal["queued", "outsideWorkingHours"]
12
13
  WorkflowDefinition = dict[str, Any] | list[dict[str, Any]]
13
14
  WorkflowCompletion = dict[str, Any] | list[dict[str, Any]]
14
15
 
@@ -22,12 +23,15 @@ class WorkflowStartedResponse(LinkedApiModel):
22
23
  workflow_id: str
23
24
  workflow_status: WorkflowInProgressStatus
24
25
  message: str | None = None
26
+ # Optional so an older API that does not send it still parses.
27
+ pending_reason: WorkflowPendingReason | None = None
25
28
 
26
29
 
27
30
  class WorkflowInProgressResponse(LinkedApiModel):
28
31
  workflow_id: str
29
32
  workflow_status: WorkflowInProgressStatus
30
33
  message: str | None = None
34
+ pending_reason: WorkflowPendingReason | None = None
31
35
 
32
36
 
33
37
  class WorkflowFailure(LinkedApiModel):
@@ -43,6 +47,7 @@ class WorkflowResponse(LinkedApiModel):
43
47
  workflow_id: str
44
48
  workflow_status: WorkflowStatus
45
49
  message: str | None = None
50
+ pending_reason: WorkflowPendingReason | None = None
46
51
  completion: WorkflowCompletion | None = None
47
52
  failure: WorkflowFailure | None = None
48
53
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "linkedapi"
7
- version = "1.3.5"
7
+ version = "1.3.7"
8
8
  description = "Official synchronous Python SDK for Linked API."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -21,6 +21,8 @@ def test_error_type_sets_match_node_contract() -> None:
21
21
  "linkedinAccountSignedOut",
22
22
  "languageNotSupported",
23
23
  "workflowTimeout",
24
+ "outsideWorkingHours",
25
+ "workingHoursWaitExpired",
24
26
  "httpError",
25
27
  "tooManyRequests",
26
28
  "accountNotFound",
@@ -0,0 +1,108 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+ from unittest.mock import Mock
5
+
6
+ import pytest
7
+
8
+ from linkedapi.core.operation import Operation
9
+ from linkedapi.errors import LINKED_API_ERROR_TYPES
10
+ from linkedapi.types import (
11
+ WorkflowInProgressResponse,
12
+ WorkflowResponse,
13
+ WorkflowStartedResponse,
14
+ )
15
+
16
+
17
+ class _StubMapper:
18
+ def map_request(self, params: Any) -> Any:
19
+ return params
20
+
21
+ def map_response(self, completion: Any) -> Any:
22
+ return completion
23
+
24
+
25
+ class _StubOperation(Operation): # type: ignore[type-arg]
26
+ operation_name = "fetchPerson"
27
+
28
+ def __init__(self, http_client: Any) -> None:
29
+ super().__init__(http_client)
30
+ self.mapper = _StubMapper() # type: ignore[assignment]
31
+
32
+
33
+ def _operation(workflow_result: dict[str, Any]) -> _StubOperation:
34
+ http_client = Mock()
35
+ http_client.get.return_value = Mock(
36
+ error=None,
37
+ result=WorkflowResponse.model_validate(workflow_result),
38
+ )
39
+ return _StubOperation(http_client)
40
+
41
+
42
+ class TestPendingReasonModels:
43
+ def test_in_progress_response_accepts_a_pending_reason(self) -> None:
44
+ response = WorkflowInProgressResponse(
45
+ workflowId="wf-1",
46
+ workflowStatus="pending",
47
+ pendingReason="outsideWorkingHours",
48
+ )
49
+
50
+ assert response.pending_reason == "outsideWorkingHours"
51
+
52
+ def test_started_response_accepts_a_pending_reason(self) -> None:
53
+ response = WorkflowStartedResponse(
54
+ workflowId="wf-1",
55
+ workflowStatus="pending",
56
+ pendingReason="queued",
57
+ )
58
+
59
+ assert response.pending_reason == "queued"
60
+
61
+ @pytest.mark.parametrize(
62
+ "model",
63
+ [WorkflowInProgressResponse, WorkflowStartedResponse, WorkflowResponse],
64
+ )
65
+ def test_field_is_optional_for_back_compat(self, model: Any) -> None:
66
+ response = model(workflowId="wf-1", workflowStatus="running")
67
+
68
+ assert response.pending_reason is None
69
+
70
+
71
+ class TestStatusCarriesPendingReason:
72
+ def test_carries_the_outside_working_hours_reason(self) -> None:
73
+ operation = _operation(
74
+ {
75
+ "workflowId": "wf-1",
76
+ "workflowStatus": "pending",
77
+ "pendingReason": "outsideWorkingHours",
78
+ }
79
+ )
80
+
81
+ result = operation.status("wf-1")
82
+
83
+ assert isinstance(result, WorkflowInProgressResponse)
84
+ assert result.pending_reason == "outsideWorkingHours"
85
+
86
+ def test_carries_the_queued_reason(self) -> None:
87
+ operation = _operation(
88
+ {"workflowId": "wf-1", "workflowStatus": "pending", "pendingReason": "queued"}
89
+ )
90
+
91
+ result = operation.status("wf-1")
92
+
93
+ assert isinstance(result, WorkflowInProgressResponse)
94
+ assert result.pending_reason == "queued"
95
+
96
+ def test_keeps_none_when_the_api_sends_nothing(self) -> None:
97
+ operation = _operation({"workflowId": "wf-1", "workflowStatus": "running"})
98
+
99
+ result = operation.status("wf-1")
100
+
101
+ assert isinstance(result, WorkflowInProgressResponse)
102
+ assert result.pending_reason is None
103
+
104
+
105
+ class TestWorkingHoursErrorTypes:
106
+ @pytest.mark.parametrize("error_type", ["outsideWorkingHours", "workingHoursWaitExpired"])
107
+ def test_error_type_is_known(self, error_type: str) -> None:
108
+ assert error_type in LINKED_API_ERROR_TYPES
@@ -1,12 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from linkedapi.core import Operation
4
- from linkedapi.mappers import VoidWorkflowMapper
5
- from linkedapi.types import NvSyncConversationParams
6
-
7
-
8
- class NvSyncConversation(Operation[NvSyncConversationParams, None]):
9
- """Sync a Sales Navigator conversation."""
10
-
11
- operation_name = "nvSyncConversation"
12
- mapper = VoidWorkflowMapper[NvSyncConversationParams]("nv.syncConversation")
@@ -1,12 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from linkedapi.core import Operation
4
- from linkedapi.mappers import VoidWorkflowMapper
5
- from linkedapi.types import SyncConversationParams
6
-
7
-
8
- class SyncConversation(Operation[SyncConversationParams, None]):
9
- """Sync a standard LinkedIn conversation."""
10
-
11
- operation_name = "syncConversation"
12
- mapper = VoidWorkflowMapper[SyncConversationParams]("st.syncConversation")
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes