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.
- {linkedapi-1.3.5 → linkedapi-1.3.7}/PKG-INFO +1 -1
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/__init__.py +1 -1
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/core/operation.py +1 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/errors.py +4 -0
- linkedapi-1.3.7/linkedapi/operations/nv_sync_conversation.py +15 -0
- linkedapi-1.3.7/linkedapi/operations/sync_conversation.py +15 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/__init__.py +6 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/message.py +11 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/workflow.py +5 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/pyproject.toml +1 -1
- {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/test_errors.py +2 -0
- linkedapi-1.3.7/tests/test_working_hours_contract.py +108 -0
- linkedapi-1.3.5/linkedapi/operations/nv_sync_conversation.py +0 -12
- linkedapi-1.3.5/linkedapi/operations/sync_conversation.py +0 -12
- {linkedapi-1.3.5 → linkedapi-1.3.7}/.github/workflows/publish.yaml +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/.gitignore +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/LICENSE +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/README.md +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/admin/__init__.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/admin/accounts.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/admin/admin.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/admin/http_client.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/admin/limits.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/admin/subscription.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/admin/webhooks.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/client.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/config.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/core/__init__.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/core/polling.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/http/__init__.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/http/base.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/http/linked_api_http_client.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/mappers/__init__.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/mappers/array.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/mappers/base.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/mappers/send_message.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/mappers/simple.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/mappers/then.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/mappers/void.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/__init__.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/accept_invitation.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/check_connection_status.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/comment_on_post.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/create_post.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/custom_workflow.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/fetch_company.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/fetch_job.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/fetch_person.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/fetch_post.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/ignore_invitation.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/manage_conversation.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/nv_fetch_company.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/nv_fetch_person.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/nv_manage_conversation.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/nv_search_companies.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/nv_search_people.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/nv_send_message.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/nv_sync_inbox.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/react_to_comment.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/react_to_post.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/remove_connection.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/reply_to_comment.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/retrieve_connections.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/retrieve_feed.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/retrieve_invitations.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/retrieve_pending_requests.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/retrieve_performance.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/retrieve_ssi.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/search_companies.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/search_jobs.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/search_people.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/send_connection_request.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/send_message.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/sync_inbox.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/sync_network.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/operations/withdraw_connection_request.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/py.typed +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/account.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/admin/__init__.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/admin/accounts.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/admin/config.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/admin/limits.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/admin/subscription.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/base.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/company.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/connection.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/feed.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/jobs.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/network.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/params.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/person.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/post.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/responses.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/search_companies.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/search_people.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/statistics.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/types/webhooks.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/webhooks/__init__.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/linkedapi/webhooks/parse.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/conftest.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/test_admin.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/test_direct_methods.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/test_http_client.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/test_mappers.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/test_models.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/test_operations.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/test_polling.py +0 -0
- {linkedapi-1.3.5 → linkedapi-1.3.7}/tests/test_webhooks.py +0 -0
|
@@ -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
|
|
|
@@ -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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|