Files
mostovik-backend/tests/apps/parsers/test_vacancy_clients.py
Aleksandr Meshchriakov 0f17ff6773
All checks were successful
CI/CD Pipeline / Quality Gate (push) Successful in 26s
CI/CD Pipeline / Build and Push Images (push) Successful in 6s
CI/CD Pipeline / Internal Notify (push) Successful in 0s
CI/CD Pipeline / Deploy Dev in Dokploy (push) Successful in 1s
Add organizations v2 API and registry enrichment
2026-05-06 19:04:46 +02:00

256 lines
9.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from __future__ import annotations
from decimal import Decimal
from apps.parsers.clients.common.schemas import GenericParserItem
from apps.parsers.clients.trudvsem import TrudvsemClient
from apps.parsers.clients.vacancies import (
HHVacanciesClient,
SuperJobVacanciesClient,
VacanciesClient,
VacanciesClientError,
)
from apps.parsers.models import ParserLoadLog
from django.test import SimpleTestCase
from tests.utils import TestHTTPServer
class TrudvsemClientTest(SimpleTestCase):
def test_fetch_vacancies_by_company_inn_uses_company_endpoint(self):
with TestHTTPServer() as server:
server.add_json(
"/vacancies/company/inn/7701000001",
{
"results": {
"vacancies": [
{
"vacancy": {
"id": "trudvsem-1",
"company": {
"inn": "7701000001",
"ogrn": "1027700000001",
"name": "АО Реестр",
},
"job-name": "Инженер",
"salary": {"from": 100000},
}
}
]
}
},
)
client = TrudvsemClient(
base_url=server.base_url,
http_adapter=server.adapter,
)
records = client.fetch_vacancies(
company_inn="7701000001",
limit=100,
offset=0,
)
self.assertEqual(len(records), 1)
self.assertEqual(records[0].external_id, "trudvsem-1")
self.assertEqual(records[0].inn, "7701000001")
self.assertEqual(records[0].ogrn, "1027700000001")
class HHVacanciesClientTest(SimpleTestCase):
def test_fetch_vacancies_maps_hh_items_to_generic_records(self):
with TestHTTPServer() as server:
server.add_json(
"/vacancies",
{
"items": [
{
"id": "123",
"name": "Инженер",
"published_at": "2026-05-06T10:00:00+0300",
"salary": {"from": 120000, "to": 150000},
"employer": {"id": "77", "name": "АО Пример"},
"alternate_url": "https://hh.ru/vacancy/123",
"type": {"name": "Открытая"},
"archived": False,
}
]
},
)
client = HHVacanciesClient(
base_url=server.base_url,
http_adapter=server.adapter,
)
records = client.fetch_vacancies(limit=10, offset=0, text="Инженер")
self.assertEqual(len(records), 1)
record = records[0]
self.assertEqual(record.source, ParserLoadLog.Source.TRUDVSEM)
self.assertEqual(record.external_id, "hh:123")
self.assertEqual(record.title, "Инженер")
self.assertEqual(record.organisation_name, "АО Пример")
self.assertEqual(record.amount, Decimal("120000"))
self.assertEqual(record.url, "https://hh.ru/vacancy/123")
self.assertEqual(record.payload["vacancy_source"], "hh")
def test_fetch_vacancies_tolerates_unexpected_nested_shapes(self):
with TestHTTPServer() as server:
server.add_json(
"/vacancies",
{
"items": [
{
"id": "124",
"name": "Инженер",
"salary": "по договоренности",
"employer": "АО Пример",
"type": "open",
}
]
},
)
client = HHVacanciesClient(
base_url=server.base_url,
http_adapter=server.adapter,
)
records = client.fetch_vacancies(limit=10)
self.assertEqual(len(records), 1)
self.assertEqual(records[0].external_id, "hh:124")
self.assertEqual(records[0].organisation_name, "")
self.assertIsNone(records[0].amount)
class SuperJobVacanciesClientTest(SimpleTestCase):
def test_fetch_vacancies_maps_superjob_objects_to_generic_records(self):
with TestHTTPServer() as server:
server.add_json(
"/2.0/vacancies/",
{
"objects": [
{
"id": 456,
"id_client": 99,
"profession": "Технолог",
"firm_name": "ООО Пример",
"payment_from": 90000,
"payment_to": 130000,
"date_published": 1778064000,
"link": "https://www.superjob.ru/vakansii/456.html",
"is_archive": False,
}
],
"total": 1,
"more": False,
},
)
client = SuperJobVacanciesClient(
app_id="test-app-id",
base_url=server.base_url,
http_adapter=server.adapter,
)
records = client.fetch_vacancies(limit=10, offset=0, text="Технолог")
self.assertEqual(len(records), 1)
record = records[0]
self.assertEqual(record.source, ParserLoadLog.Source.TRUDVSEM)
self.assertEqual(record.external_id, "superjob:456")
self.assertEqual(record.title, "Технолог")
self.assertEqual(record.organisation_name, "ООО Пример")
self.assertEqual(record.amount, Decimal("90000"))
self.assertEqual(record.url, "https://www.superjob.ru/vakansii/456.html")
self.assertEqual(record.payload["vacancy_source"], "superjob")
class VacanciesClientTest(SimpleTestCase):
def test_fetch_vacancies_combines_enabled_sources(self):
class _Provider:
def __init__(self, source_name: str):
self.source_name = source_name
def fetch_vacancies(self, **kwargs):
return [
GenericParserItem(
source=ParserLoadLog.Source.TRUDVSEM,
external_id=f"{self.source_name}:1",
payload={"vacancy_source": self.source_name, "kwargs": kwargs},
)
]
client = VacanciesClient(
source_clients={
"trudvsem": _Provider("trudvsem"),
"hh": _Provider("hh"),
"superjob": _Provider("superjob"),
}
)
records = client.fetch_vacancies(limit=10, offset=5, text="инженер")
self.assertEqual(
[record.payload["vacancy_source"] for record in records],
["trudvsem", "hh", "superjob"],
)
def test_fetch_vacancies_skips_sources_without_company_inn_support(self):
class _Provider:
supports_company_inn = False
def fetch_vacancies(self, **kwargs):
return [
GenericParserItem(
source=ParserLoadLog.Source.TRUDVSEM,
external_id="unsupported:1",
)
]
class _InnProvider:
supports_company_inn = True
def fetch_vacancies(self, **kwargs):
return [
GenericParserItem(
source=ParserLoadLog.Source.TRUDVSEM,
external_id="trudvsem:1",
)
]
client = VacanciesClient(
source_clients={
"trudvsem": _InnProvider(),
"hh": _Provider(),
"superjob": _Provider(),
}
)
records = client.fetch_vacancies(company_inn="7700000000")
self.assertEqual([record.external_id for record in records], ["trudvsem:1"])
def test_fetch_vacancies_skips_unconfigured_optional_source_by_default(self):
class _Provider:
supports_company_inn = True
def fetch_vacancies(self, **kwargs):
return [
GenericParserItem(
source=ParserLoadLog.Source.TRUDVSEM,
external_id="trudvsem:1",
)
]
client = VacanciesClient(source_clients={"trudvsem": _Provider()})
records = client.fetch_vacancies()
self.assertEqual([record.external_id for record in records], ["trudvsem:1"])
def test_fetch_vacancies_requires_superjob_app_id_when_explicitly_selected(self):
client = VacanciesClient(sources=["superjob"], superjob_app_id="")
with self.assertRaises(VacanciesClientError):
client.fetch_vacancies()