diff --git a/huntflow_api_client/entities/applicants.py b/huntflow_api_client/entities/applicants.py index 02f1c23..bc1a1ac 100644 --- a/huntflow_api_client/entities/applicants.py +++ b/huntflow_api_client/entities/applicants.py @@ -12,10 +12,12 @@ ApplicantUpdateRequest, ) from huntflow_api_client.models.response.applicants import ( + ApplicantCreateAgreementLinkResponse, ApplicantCreateResponse, ApplicantItem, ApplicantListResponse, ApplicantSearchByCursorResponse, + ApplicantSendAgreementResponse, ) @@ -186,3 +188,41 @@ async def search_by_cursor( response = await self._api.request("GET", path, params=params) return ApplicantSearchByCursorResponse.model_validate(response.json()) + + async def create_agreement_link( + self, + account_id: int, + applicant_id: int, + ) -> ApplicantCreateAgreementLinkResponse: + """ + API method reference: + https://api.huntflow.ai/v2/docs#post-/accounts/-account_id-/applicants/-applicant_id-/agreement_link + + :param account_id: Organization ID + :param applicant_id: Applicant ID + :return: Link to interact with agreement + """ + response = await self._api.request( + "POST", + f"/accounts/{account_id}/applicants/{applicant_id}/agreement_link", + ) + return ApplicantCreateAgreementLinkResponse.model_validate(response.json()) + + async def send_agreement_via_email( + self, + account_id: int, + applicant_id: int, + ) -> ApplicantSendAgreementResponse: + """ + API method reference: + https://api.huntflow.ai/v2/docs#post-/accounts/-account_id-/applicants/-applicant_id-/agreement_email + + :param account_id: Organization ID + :param applicant_id: Applicant ID + :return: Job_id and recipient email of agreement + """ + response = await self._api.request( + "POST", + f"/accounts/{account_id}/applicants/{applicant_id}/agreement_email", + ) + return ApplicantSendAgreementResponse.model_validate(response.json()) diff --git a/huntflow_api_client/models/response/applicants.py b/huntflow_api_client/models/response/applicants.py index 9da3f1a..6c0ea4b 100644 --- a/huntflow_api_client/models/response/applicants.py +++ b/huntflow_api_client/models/response/applicants.py @@ -133,3 +133,12 @@ class ApplicantSearchItem(BaseModel): class ApplicantSearchByCursorResponse(BaseModel): items: List[ApplicantSearchItem] = Field(..., description="List of applicants") next_page_cursor: Optional[str] = Field(None, description="Next page cursor") + + +class ApplicantCreateAgreementLinkResponse(BaseModel): + link: str = Field(..., description="Link to agreement") + + +class ApplicantSendAgreementResponse(BaseModel): + sent_to: str = Field(..., description="Email recipient") + job_id: str = Field(..., description="Job ID") diff --git a/pyproject.toml b/pyproject.toml index 371e3b5..880de13 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "huntflow-api-client" -version = "2.8.0" +version = "2.9.0" description = "Huntflow API Client for Python" authors = [ {name = "Developers huntflow", email = "developer@huntflow.ru"}, diff --git a/tests/test_entities/test_applicants.py b/tests/test_entities/test_applicants.py index 1e46cb7..2498c76 100644 --- a/tests/test_entities/test_applicants.py +++ b/tests/test_entities/test_applicants.py @@ -9,10 +9,12 @@ ApplicantUpdateRequest, ) from huntflow_api_client.models.response.applicants import ( + ApplicantCreateAgreementLinkResponse, ApplicantCreateResponse, ApplicantItem, ApplicantListResponse, ApplicantSearchByCursorResponse, + ApplicantSendAgreementResponse, ) from huntflow_api_client.tokens.proxy import HuntflowTokenProxy from tests.api import BASE_URL, VERSIONED_BASE_URL @@ -269,6 +271,12 @@ "next_page_cursor": "3VudCI6IjoXIjogW10IiwgMy4wXX0=", } +APPLICANT_CREATE_AGREEMENT_RESPONSE: Dict[str, Any] = {"link": "https://agreement.example/1"} +APPLICANT_SEND_AGREEMENT_RESPONSE: Dict[str, Any] = { + "sent_to": "user@example.com", + "job_id": "job-id-1111", +} + async def test_list_applicant( httpx_mock: HTTPXMock, @@ -385,3 +393,35 @@ async def test_applicant_search_by_cursor( assert response == ApplicantSearchByCursorResponse.model_validate( APPLICANT_SEARCH_BY_CURSOR_RESPONSE, ) + + +async def test_create_agreement_link( + httpx_mock: HTTPXMock, + token_proxy: HuntflowTokenProxy, +) -> None: + httpx_mock.add_response( + url=f"{VERSIONED_BASE_URL}/accounts/{ACCOUNT_ID}/applicants/{APPLICANT_ID}/agreement_link", + json=APPLICANT_CREATE_AGREEMENT_RESPONSE, + ) + api_client = HuntflowAPI(BASE_URL, token_proxy=token_proxy) + + applicants = Applicant(api_client) + + response = await applicants.create_agreement_link(ACCOUNT_ID, APPLICANT_ID) + assert response == ApplicantCreateAgreementLinkResponse(**APPLICANT_CREATE_AGREEMENT_RESPONSE) + + +async def test_send_agreement_via_email( + httpx_mock: HTTPXMock, + token_proxy: HuntflowTokenProxy, +) -> None: + httpx_mock.add_response( + url=f"{VERSIONED_BASE_URL}/accounts/{ACCOUNT_ID}/applicants/{APPLICANT_ID}/agreement_email", + json=APPLICANT_SEND_AGREEMENT_RESPONSE, + ) + api_client = HuntflowAPI(BASE_URL, token_proxy=token_proxy) + + applicants = Applicant(api_client) + + response = await applicants.send_agreement_via_email(ACCOUNT_ID, APPLICANT_ID) + assert response == ApplicantSendAgreementResponse(**APPLICANT_SEND_AGREEMENT_RESPONSE)