def test_parse_ordoclic_slots(): # Test availability_data vide request = ScraperRequest("", "2021-04-05") assert parse_ordoclic_slots(request, {}) == None # Test pas de slots disponibles empty_slots_file = Path("tests/fixtures/ordoclic/empty_slots.json") empty_slots = json.loads(empty_slots_file.read_text()) request = ScraperRequest("", "2021-04-05") assert parse_ordoclic_slots(request, empty_slots) == None # Test nextAvailableSlotDate nextavailable_slots_file = Path( "tests/fixtures/ordoclic/nextavailable_slots.json") nextavailable_slots = json.loads(nextavailable_slots_file.read_text()) request = ScraperRequest("", "2021-04-05") assert parse_ordoclic_slots(request, nextavailable_slots) == isoparse( "2021-06-12T11:30:00Z") # timezone CET # Test slots disponibles full_slots_file = Path("tests/fixtures/ordoclic/full_slots.json") full_slots = json.loads(full_slots_file.read_text()) request = ScraperRequest("", "2021-04-05") first_availability = parse_ordoclic_slots(request, full_slots) assert first_availability == isoparse( "2021-04-19T16:15:00Z") # timezone CET assert request.appointment_count == 42
def test_fetch_slots(): def app(request: httpx.Request) -> httpx.Response: try: with open(Path("tests", "fixtures", "mapharma", "slots.json"), encoding="utf8") as f: return httpx.Response(200, content=f.read()) except IOError: return httpx.Response(404, content="") client = httpx.Client(transport=httpx.MockTransport(app)) request = ScraperRequest("https://mapharma.net/97200?c=60&l=1", "2021-04-14") first_availability = fetch_slots(request, client, opendata_file=TEST_OPEN_DATA_FILE) assert first_availability == "2021-04-19T17:15:00" # test campagne["total_libres"]: 0 request = ScraperRequest("https://mapharma.net/88400?c=92&l=1", "2021-04-14") first_availability = fetch_slots(request, client, opendata_file=TEST_OPEN_DATA_FILE) assert first_availability == None
def test_get_appointments(): """get_appointments should return first available appointment date""" center_data = dict() center_data = json.load(io.open(TEST_CENTRE_INFO, "r", encoding="utf-8-sig")) center_info = CenterInfo.from_csv_data(center_data) # This center has availabilities and should return a date, non null appointment_count and vaccines request = ScraperRequest( "https://server.bimedoc.com/vmd/pharmacy-with-slots/9cf46288-0080-4a8d-8856-8e9998ced9f7?start_date=2021-08-10&end_date=2021-08-17", "2021-08-10", center_info, "Bimedoc9cf46288-0080-4a8d-8856-8e9998ced9f", ) center_with_availability = bimedoc.BimedocSlots() slots = json.load(io.open(Path("tests", "fixtures", "bimedoc", "slots_available.json"), "r", encoding="utf-8-sig")) assert center_with_availability.get_appointments(request, slots_api=slots) == "2021-08-11T08:15:00Z" assert request.appointment_count == 133 assert request.vaccine_type == [Vaccine.PFIZER] # This one should return no date, neither appointment_count nor vaccine. request = ScraperRequest( "https://server.bimedoc.com/vmd/pharmacy-with-slots/9cf46288-0080-4a8d-8856-8e9998ced9f7?start_date=2021-08-10&end_date=2021-08-17", "2021-08-10", center_info, ) center_without_availability = bimedoc.BimedocSlots() slots = json.load( io.open(Path("tests", "fixtures", "bimedoc", "slots_unavailable.json"), "r", encoding="utf-8-sig") ) assert center_without_availability.get_appointments(request, slots_api=slots) == None assert request.appointment_count == 0 assert request.vaccine_type == None
def test_get_slots(): request = ScraperRequest("https://app.ordoclic.fr/app/pharmacie/pharmacie-de-la-mairie-meru-meru", "2021-05-08") data = {"id": 1} assert not parse_ordoclic_slots(request, data) request = ScraperRequest("https://app.ordoclic.fr/app/pharmacie/pharmacie-de-la-mairie-meru-meru", "2021-05-08") data = {"slots": [{"timeEnd": "2021-05-09"}]} assert not parse_ordoclic_slots(request, data)
def test_get_slots(): request = ScraperRequest( "https://app.ordoclic.fr/app/pharmacie/pharmacie-de-la-mairie-meru-meru", "2021-05-08") data = {'id': 1} assert not parse_ordoclic_slots(request, data) request = ScraperRequest( "https://app.ordoclic.fr/app/pharmacie/pharmacie-de-la-mairie-meru-meru", "2021-05-08") data = {'slots': [{'timeEnd': '2021-05-09'}]} assert not parse_ordoclic_slots(request, data)
def test_fetch_slots(): # Oops I forgot centerid request = ScraperRequest( 'https://www.maiia.com/centre-de-vaccination/42400-saint-chamond/centre-de-vaccination-covid---hopital-du-gier-', '2021-04-16') first_availability = fetch_slots(request, client=client) assert first_availability == None request = ScraperRequest( 'https://www.maiia.com/centre-de-vaccination/42400-saint-chamond/centre-de-vaccination-covid---hopital-du-gier-?centerid=5ffc744c68dedf073a5b87a2', '2021-04-16') first_availability = fetch_slots(request, client=client) assert first_availability == "2021-05-13T13:40:00+00:00"
def test_fetch_slots(): def app(request: httpx.Request) -> httpx.Response: try: with open(Path("tests", "fixtures", "mapharma", "slots.json"), encoding="utf8") as f: return httpx.Response(200, content=f.read()) except IOError: return httpx.Response(404, content="") client = httpx.Client(transport=httpx.MockTransport(app)) center_info = CenterInfo( departement="49", nom="Pharmacie Grand Maine", url="https://mapharma.net/49100-3?c=257&l=0", location=CenterLocation(longitude=-0.595416, latitude=47.468377, city="ANGERS", cp="49100"), metadata={ "address": "CENTRE CIAL GRAND MAINE RUE DU GRAND LAUNAY, 49100 ANGERS", "business_hours": { "lundi": "09:30 – 20:00", "mardi": "09:30 – 20:00", "mercredi": "09:30 – 20:00", "jeudi": "09:30 – 20:00", "vendredi": "09:30 – 20:00", "samedi": "09:30 – 20:00", "dimanche": "Fermé", }, }, ) request = ScraperRequest(url="https://mapharma.net/97200?c=60&l=1", start_date="2021-04-14", center_info=center_info) first_availability = fetch_slots(request, creneau_q=DummyQueue(), client=client, opendata_file=TEST_OPEN_DATA_FILE) assert first_availability == "2021-04-19T17:15:00" # test campagne["total_libres"]: 0 request = ScraperRequest("https://mapharma.net/88400?c=92&l=1", "2021-04-14", center_info=center_info) first_availability = fetch_slots(request, client=client, opendata_file=TEST_OPEN_DATA_FILE) assert first_availability == None
def test_get_slots(): ordoclic = OrdoclicSlots() request = ScraperRequest("https://app.ordoclic.fr/app/pharmacie/pharmacie-de-la-mairie-meru-meru", "2021-05-08") data = {"id": 1} vaccine = Vaccine.MODERNA dose = [1] assert not ordoclic.parse_ordoclic_slots(request, data, vaccine, dose) request = ScraperRequest("https://app.ordoclic.fr/app/pharmacie/pharmacie-de-la-mairie-meru-meru", "2021-05-08") data = {"slots": [{"timeEnd": "2021-05-09"}]} vaccine = Vaccine.MODERNA dose = [2] assert not ordoclic.parse_ordoclic_slots(request, data, vaccine, dose)
def test_keldoc_timeout(): center1_url = "https://vaccination-covid.keldoc.com/centre-hospitalier-regional/foo/bar?specialty=no" def app(request: httpx.Request) -> httpx.Response: if request.url.path == "/centre-hospitalier-regional/foo/bar": raise TimeoutError if request.url.path == "/api/patients/v2/searches/resource": raise TimeoutError if request.url.path == "/api/patients/v2/clinics/1/specialties/1/cabinets": raise TimeoutError return httpx.Response(200, json={}) client = httpx.Client(transport=httpx.MockTransport(app)) request = ScraperRequest(center1_url, "2020-04-04") test_center_1 = KeldocCenter(request, client=client) # Test center info TA with pytest.raises(TimeoutError): test_center_1.parse_resource() with pytest.raises(TimeoutError): test_center_1.fetch_center_data() # Test cabinet TA test_center_1.id = 1 test_center_1.vaccine_specialties = [1] with pytest.raises(TimeoutError): test_center_1.fetch_vaccine_cabinets() assert not test_center_1.vaccine_cabinets
def test_doctolib(): # Cas de base. start_date = "2021-04-03" base_url = "https://partners.doctolib.fr/centre-de-vaccinations-internationales/ville1/centre1?pid=practice-165752&enable_cookies_consent=1" # noqa scrap_request = ScraperRequest(base_url, start_date) def app(request: httpx.Request) -> httpx.Response: assert "User-Agent" in request.headers if request.url.path == "/booking/centre1.json": path = Path("tests", "fixtures", "doctolib", "basic-booking.json") return httpx.Response(200, json=json.loads(path.read_text())) assert request.url.path == "/availabilities.json" params = dict(httpx.QueryParams(request.url.query)) path = Path("tests", "fixtures", "doctolib", "basic-availabilities.json") return httpx.Response(200, json=json.loads(path.read_text())) client = httpx.Client(transport=httpx.MockTransport(app)) slots = DoctolibSlots(client=client, cooldown_interval=0) next_date = slots.fetch(scrap_request) assert next_date == '2021-04-10'
def online_keldoc_test(): request = ScraperRequest( "https://www.keldoc.com/cabinet-medical/grenoble-38000/centre-de-vaccination-universite-inter-age-du-dauphine-uiad", "2021-04-13", ) slots = fetch_slots(request)
def test_fetch(): def app(requested: httpx.Request) -> httpx.Response: assert "User-Agent" in requested.headers return httpx.Response(responsecode, json=slots) bimedoc.PLATFORM_ENABLED = True center_data = dict() center_data = json.load(io.open(TEST_CENTRE_INFO, "r", encoding="utf-8-sig")) center_info = CenterInfo.from_csv_data(center_data) # This center has availabilities and should return a date, non null appointment_count and vaccines request = ScraperRequest( "https://server.bimedoc.com/vmd/pharmacy-with-slots/9cf46288-0080-4a8d-8856-8e9998ced9f7?start_date=2021-08-10&end_date=2021-08-17", "2021-08-10", center_info, ) slots = json.load(io.open(Path("tests", "fixtures", "bimedoc", "slots_available.json"), "r", encoding="utf-8-sig")) # Response 200 responsecode = 200 client = httpx.Client(transport=httpx.MockTransport(app)) center_with_availability = bimedoc.BimedocSlots(client=client) response = center_with_availability.fetch(request) assert response == "2021-08-11T08:15:00Z" # Response 403 responsecode = 403 client = httpx.Client(transport=httpx.MockTransport(app)) center_with_availability = bimedoc.BimedocSlots(client=client) with pytest.raises(Exception): response = center_with_availability.fetch(request) assert response == None
def test_keldoc_scrape_nodate(): center1_url = ( "https://www.keldoc.com/centre-hospitalier-regional/lorient-56100/groupe-hospitalier" "-bretagne-sud-lorient-hopital-du-scorff?specialty=144 " ) keldoc.KELDOC_ENABLED = True def app_center2(request: httpx.Request) -> httpx.Response: if "timetables/" in request.url.path: return httpx.Response(200, json={}) if ( request.url.path == "/centre-hospitalier-regional/lorient-56100/groupe-hospitalier-bretagne-sud-lorient-hopital-du-scorff" ): return httpx.Response( 302, headers={ "Location": "https://vaccination-covid.keldoc.com/redirect/?dom=centre-hospitalier-regional&inst=lorient-56100&user=groupe-hospitalier-bretagne-sud-lorient-hopital-du-scorff&specialty=144 " }, ) for path in CENTER1_KELDOC: if request.url.path == path: return httpx.Response(200, json=get_test_data(CENTER1_KELDOC[path])) return httpx.Response(200, json={}) request = ScraperRequest(center1_url, "2099-12-12") keldoc.session = httpx.Client(transport=httpx.MockTransport(app_center2)) date = fetch_slots(request) assert not date
def test_get_slots_from(self): # Testing the None return if rdv_form doesn't have a correct shape # RdvForm = make_dataclass("RdvForm", # [("contents", list, field(default_factory=list))]) # rdv_form = RdvForm() # rdv_form.contents = ['{}'] # assert get_slots_from(rdv_form, "", "") is None # Testing with correct data rdv_form with open("tests/fixtures/maiia/maiia_script_response.html", "r") as html_file: soup = BeautifulSoup(html_file, "html.parser") with open("tests/fixtures/maiia/availability.json", "r") as json_file: availibility = json.load(json_file) def mock_get_availibility(*args): return availibility scraper.maiia.maiia.get_any_availibility_from = mock_get_availibility scrap_request = ScraperRequest("", "") assert get_slots_from(soup.script, scrap_request) == "2021-05-04T14:00:00.000000Z" del availibility["firstPhysicalStartDateTime"] assert get_slots_from(soup.script, scrap_request) == "2021-05-04T14:00:00.000000Z" del availibility["closestPhysicalAvailability"] assert get_slots_from(soup.script, scrap_request) is None
def test_fetch(): def app(requested: httpx.Request) -> httpx.Response: assert "User-Agent" in requested.headers return httpx.Response(responsecode, json=slots) valwin.PLATFORM_ENABLED = True center_data = dict() center_data = json.load(io.open(TEST_CENTRE_INFO, "r", encoding="utf-8-sig")) center_info = CenterInfo.from_csv_data(center_data) # This center has availabilities and should return a date, non null appointment_count and vaccines request = ScraperRequest( "https://pharma-api.epharmacie.pro/global/api/meetings/v2/pharmabest75-plateau-lyon/slots", "2021-08-10", center_info, ) slots = json.load(io.open(Path("tests", "fixtures", "valwin", "slots_available.json"), "r", encoding="utf-8-sig")) # Response 200 responsecode = 200 client = httpx.Client(transport=httpx.MockTransport(app)) center_with_availability = valwin.Slots(client=client) response = center_with_availability.fetch(request) assert response == "2021-09-17T10:00:00" # Response 403 responsecode = 403 client = httpx.Client(transport=httpx.MockTransport(app)) center_with_availability = valwin.Slots(client=client) with pytest.raises(Exception): response = center_with_availability.fetch(request) assert response == None
def test_fetch(): mesoigner.PLATFORM_ENABLED = True center_data = dict() center_data = json.load( io.open(TEST_CENTRE_INFO, "r", encoding="utf-8-sig")) center_info = CenterInfo.from_csv_data(center_data) # This center has availabilities and should return a date, non null appointment_count and vaccines request = ScraperRequest( "https://pharmacie-des-pyrenees.pharmaxv.fr/rendez-vous/vaccination/269-vaccination-covid-19/pre-inscription", "2021-06-16", center_info, ) slots = json.load( io.open(Path("tests", "fixtures", "mesoigner", "slots_available.json"), "r", encoding="utf-8-sig")) def app(requested: httpx.Request) -> httpx.Response: assert "User-Agent" in requested.headers return httpx.Response(200, json=slots) client = httpx.Client(transport=httpx.MockTransport(app)) center_with_availability = mesoigner.MesoignerSlots(client=client) response = center_with_availability.fetch(request) assert response == "2021-06-16T14:50:00+02:00"
def test_blocked_by_doctolib_par_availabilities(): # Cas de base. start_date = "2021-04-03" base_url = "https://partners.doctolib.fr/centre-de-vaccinations-internationales/ville1/centre1?pid=practice-165752&enable_cookies_consent=1" # noqa center_info = CenterInfo(departement="07", nom="Mon Super Centre", url=base_url) scrap_request = ScraperRequest(base_url, start_date, center_info) def app(request: httpx.Request) -> httpx.Response: assert "User-Agent" in request.headers if request.url.path == "/booking/centre1.json": path = Path("tests", "fixtures", "doctolib", "basic-booking.json") return httpx.Response(200, json=json.loads( path.read_text(encoding="utf-8"))) return httpx.Response(403, text="Anti dDos") client = httpx.Client(transport=httpx.MockTransport(app)) slots = DoctolibSlots(client=client, cooldown_interval=0) with pytest.raises(Blocked403): slots.fetch(scrap_request)
def test_doctolib_next_slot(): # Cas de repli : c'est surprenant, mais parfois la liste des dispos # est vide, mais il y a un champ 'next_slot' qui contient la date de # la prochaine visite, que l'on utilise dans ce cas. start_date = "2021-04-03" base_url = "https://partners.doctolib.fr/centre-de-vaccinations-internationales/ville1/centre1?pid=practice-165752&enable_cookies_consent=1" # noqa scrap_request = ScraperRequest(base_url, start_date) def app(request: httpx.Request) -> httpx.Response: assert "User-Agent" in request.headers if request.url.path == "/booking/centre1.json": path = Path("tests", "fixtures", "doctolib", "next-slot-booking.json") return httpx.Response(200, json=json.loads(path.read_text())) assert request.url.path == "/availabilities.json" path = Path("tests", "fixtures", "doctolib", "next-slot-availabilities.json") return httpx.Response(200, json=json.loads(path.read_text())) client = httpx.Client(transport=httpx.MockTransport(app)) slots = DoctolibSlots(client=client, cooldown_interval=0) next_date = slots.fetch(scrap_request) # Next slot should not be used assert next_date is None
def test_no_center_data(): path_centerinfo = Path("tests", "fixtures", "keldoc", "cabinet-16913-centerinfo.json") centerinfo_1 = json.loads(path_centerinfo.read_text(encoding="utf-8")) center_info = CenterInfo.from_csv_data(centerinfo_1) center1_url = "https://www.keldoc.com/centre-hospitalier-regional/lorient-56100/groupe-hospitalier-bretagne-sud-lorient-hopital-du-scorff?specialty=144" request = ScraperRequest(center1_url, "2020-04-04", center_info=center_info) def app(request: httpx.Request) -> httpx.Response: if (request.url.path == "/centre-hospitalier-regional/lorient-56100/groupe-hospitalier-bretagne-sud-lorient-hopital-du-scorff" ): return httpx.Response( 302, headers={ "Location": "https://vaccination-covid.keldoc.com/redirect/?dom=centre-hospitalier-regional&inst=lorient-56100&user=groupe-hospitalier-bretagne-sud-lorient-hopital-du-scorff&specialty=144 " }, ) if request.url.path == "/redirect/": return httpx.Response(200, json={}) return httpx.Response(403, json={}) keldoc.session = httpx.Client(transport=httpx.MockTransport(app)) date = fetch_slots(request) assert not date
def test_doctolib_motive_categories(): # Certains centres opèrent une distinction de motifs pour les professionnels de santé / # non professionnels de santé. # On doit gérer ces cas-là. start_date = "2021-04-03" base_url = "https://partners.doctolib.fr/centre-de-vaccinations-internationales/ville1/centre1?pid=practice-165752&enable_cookies_consent=1" # noqa scrap_request = ScraperRequest(base_url, start_date) def app(request: httpx.Request) -> httpx.Response: assert "User-Agent" in request.headers if request.url.path == "/booking/centre1.json": path = Path("tests", "fixtures", "doctolib", "category-booking.json") return httpx.Response(200, json=json.loads(path.read_text())) assert request.url.path == "/availabilities.json" path = Path("tests", "fixtures", "doctolib", "category-availabilities.json") return httpx.Response(200, json=json.loads(path.read_text())) client = httpx.Client(transport=httpx.MockTransport(app)) slots = DoctolibSlots(client=client, cooldown_interval=0) next_date = slots.fetch(scrap_request) assert next_date == '2021-04-10'
def test_keldoc_parse_center(): center1_url = "https://vaccination-covid.keldoc.com/centre-hospitalier-regional/lorient-56100/groupe-hospitalier-bretagne-sud-lorient-hopital-du-scorff?cabinet=16913&specialty=144" path = Path("tests", "fixtures", "keldoc", "center1-cabinet-16913.json") input_data = json.loads(path.read_text(encoding="utf-8")) request = ScraperRequest(center1_url, "2020-04-04", input_data=input_data) client = httpx.Client(transport=httpx.MockTransport(app_center1)) test_center_1 = KeldocCenter(request, client=client) # Fetch vaccine cabinets cabinets = filter_vaccine_motives(test_center_1.appointment_motives) agendas = [] for match in cabinets: agendas.extend(match.get("agendas")) agendas = list(set(agendas)) assert agendas == [51414, 49335] # Fetch motives motives = filter_vaccine_motives(test_center_1.appointment_motives) assert motives == json.loads( Path("tests", "fixtures", "keldoc", "center1-motives.json").read_text()) # Find first availability date fake_now = dt.datetime(2020, 4, 4, 8, 15) with mock_datetime_now(fake_now): date, count = test_center_1.find_first_availability("2020-04-04") assert not date test_center_1.vaccine_motives = motives with mock_datetime_now(fake_now): date, count = test_center_1.find_first_availability("2020-04-04") tz = datetime.timezone(datetime.timedelta(seconds=7200)) assert date == datetime.datetime(2021, 4, 20, 16, 55, tzinfo=tz)
def test_keldoc_parse_complex(): center1_url = "https://vaccination-covid.keldoc.com/centre-hospitalier-regional/lorient-56100/groupe-hospitalier-bretagne-sud-lorient-hopital-du-scorff?cabinet=16913&specialty=144" path = Path("tests", "fixtures", "keldoc", "center1-cabinet-16913.json") input_data = json.loads(path.read_text(encoding="utf-8")) request = ScraperRequest(center1_url, "2020-04-04", input_data=input_data) client = httpx.Client(transport=httpx.MockTransport(app_center1)) test_center_1 = KeldocCenter(request, client=client) # Fetch vaccine cabinets cabinets = filter_vaccine_motives(test_center_1.appointment_motives) appointments = [] data = { "availabilities": { "2021-04-20": [ { "start_time": "2021-04-20T16:53:00.000000+0200" }, { "start_time": "2021-04-20T16:50:00.000000+0200" }, { "start_time": "2021-04-20T18:59:59.000000+0200" }, ], "2021-04-21": [{ "start_time": "2021-04-21T08:12:12.000000+0200" }], } } availability, new_count = parse_keldoc_availability( test_center_1, data, appointments) assert availability.isoformat() == "2021-04-20T16:50:00+02:00"
def test_keldoc_motives_connect_error(): center1_url = ( "https://vaccination-covid.keldoc.com/centre-hospitalier-regional/lorient-56100/groupe-hospitalier" "-bretagne-sud-lorient-hopital-du-scorff?specialty=144 ") center1_data = json.loads( Path("tests", "fixtures", "keldoc", "center1-info.json").read_text()) request = ScraperRequest(center1_url, "2020-04-04") def mock_client(request: httpx.Request) -> httpx.Response: if request.url.path == "/api/patients/v2/searches/resource": raise httpx.ConnectError("Unable to connect", request=request) if (request.url.path == "/centre-hospitalier-regional/lorient-56100/groupe-hospitalier-bretagne-sud-lorient-hopital-du-scorff" ): return httpx.Response( 302, headers={ "Location": "https://vaccination-covid.keldoc.com/redirect/?dom=centre-hospitalier-regional&inst=lorient-56100&user=groupe-hospitalier-bretagne-sud-lorient-hopital-du-scorff&specialty=144 " }, ) for path in CENTER1_KELDOC: if request.url.path == path: return httpx.Response(200, json=get_test_data(CENTER1_KELDOC[path])) return httpx.Response(200, json={}) client = httpx.Client(transport=httpx.MockTransport(mock_client)) test_center_1 = KeldocCenter(request, client=client) assert not test_center_1.vaccine_motives
def test_blocked_by_doctolib_par_centre(): # Cas de base. start_date = "2021-04-03" base_url = "https://partners.doctolib.fr/centre-de-vaccinations-internationales/ville1/centre1?pid=practice-165752&enable_cookies_consent=1" # noqa scrap_request = ScraperRequest(base_url, start_date) def app(request: httpx.Request) -> httpx.Response: assert "User-Agent" in request.headers if request.url.path == "/booking/centre1.json": path = Path("tests", "fixtures", "doctolib", "basic-booking.json") return httpx.Response(403, text="Anti dDos") assert request.url.path == "/availabilities.json" params = dict(httpx.QueryParams(request.url.query)) assert params == { "start_date": start_date, "visit_motive_ids": "2", "agenda_ids": "3", "insurance_sector": "public", "practice_ids": "4", "destroy_temporary": "true", "limit": str(DOCTOLIB_CONF.pagination["pages"]), } path = Path("tests", "fixtures", "doctolib", "basic-availabilities.json") return httpx.Response(200, json=json.loads(path.read_text(encoding="utf-8"))) client = httpx.Client(transport=httpx.MockTransport(app)) slots = DoctolibSlots(client=client, cooldown_interval=0) with pytest.raises(BlockedByDoctolibError): slots.fetch(scrap_request)
def test_blocked_by_doctolib_par_availabilities(): # Cas de base. start_date = "2021-04-03" base_url = "https://partners.doctolib.fr/centre-de-vaccinations-internationales/ville1/centre1?pid=practice-165752&enable_cookies_consent=1" # noqa scrap_request = ScraperRequest(base_url, start_date) def app(request: httpx.Request) -> httpx.Response: assert "User-Agent" in request.headers if request.url.path == "/booking/centre1.json": path = Path("tests", "fixtures", "doctolib", "basic-booking.json") return httpx.Response(200, json=json.loads(path.read_text())) return httpx.Response(403, text="Anti dDos") client = httpx.Client(transport=httpx.MockTransport(app)) slots = DoctolibSlots(client=client, cooldown_interval=0) error = None try: next_date = slots.fetch(scrap_request) except Exception as e: error = e assert True is isinstance(error, BlockedByDoctolibError)
def test_get_profile(): # Timeout test (profile) def app4(request: httpx.Request) -> httpx.Response: raise httpx.TimeoutException(message="Timeout", request=request) client = httpx.Client(transport=httpx.MockTransport(app4)) request = ScraperRequest("https://app.ordoclic.fr/app/pharmacie/pharmacie-de-la-mairie-meru-meru", "2021-05-08") res = get_profile(request, client) assert not res # HTTP error test (profile) def app5(request: httpx.Request) -> httpx.Response: return httpx.Response(403, json={}) client = httpx.Client(transport=httpx.MockTransport(app5)) request = ScraperRequest("https://app.ordoclic.fr/app/pharmacie/pharmacie-de-la-mairie-meru-meru", "2021-05-08") res = get_profile(request, client) assert not res
def fetch_centre_slots(rdv_site_web, start_date, fetch_map: dict = None): if fetch_map is None: # Map platform to implementation. # May be overridden for unit testing purposes. fetch_map = { 'Doctolib': { 'urls': ['https://partners.doctolib.fr', 'https://www.doctolib.fr'], 'scraper_ptr': doctolib_fetch_slots }, 'Keldoc': { 'urls': ['https://vaccination-covid.keldoc.com', 'https://keldoc.com'], 'scraper_ptr': keldoc_fetch_slots }, 'Maiia': { 'urls': ['https://www.maiia.com'], 'scraper_ptr': maiia_fetch_slots }, 'Mapharma': { 'urls': [ 'https://mapharma.net/', ], 'scraper_ptr': mapharma_fetch_slots }, 'Ordoclic': { 'urls': [ 'https://app.ordoclic.fr/', ], 'scraper_ptr': ordoclic_fetch_slots } } rdv_site_web = fix_scrap_urls(rdv_site_web) request = ScraperRequest(rdv_site_web, start_date) # Determine platform based on visit URL platform = None for scraper_name in fetch_map: scraper = fetch_map[scraper_name] scrap = sum([ 1 if rdv_site_web.startswith(url) else 0 for url in scraper.get('urls', []) ]) if scrap == 0: continue platform = scraper_name if not platform: return ScraperResult(request, 'Autre', None) # Dispatch to appropriate implementation. fetch_impl = fetch_map[platform]['scraper_ptr'] result = ScraperResult(request, platform, None) result.next_availability = fetch_impl(request) return result
def async_ordoclic_scrape(centre): vaccine_center = centre["nom"] website = centre["rdv_site_web"] #print("Vaccine Center {0}: looking for an appointment".format(vaccine_center)) request = ScraperRequest(website, today) date = ordoclic_fetch_slots(request) if not date: print(f"Vaccine Center {vaccine_center}: no appointment found") return print(f"Vaccine Center {vaccine_center}: next appointment found: {date}")
def test_pop_practice_id(): base_url = "https://partners.doctolib.fr/centre-de-vaccinations-internationales/ville1/centre1?pid=practice-165752&enable_cookies_consent=1" expected_result = ( "https://partners.doctolib.fr/centre-de-vaccinations-internationales/ville1/centre1?enable_cookies_consent=1" ) start_date = "2021-04-03" scraper_request = ScraperRequest(base_url, start_date) doctolib_slots = DoctolibSlots() doctolib_slots.pop_practice_id(scraper_request) assert scraper_request.url == expected_result
def test_mapharma_fetch_slots(): def app(request: httpx.Request) -> httpx.Response: try: with open(Path("tests", "fixtures", "mapharma", "slots.json"), encoding="utf8") as f: return httpx.Response(200, content=f.read()) except IOError: return httpx.Response(404, content="") client = httpx.Client(transport=httpx.MockTransport(app)) request = ScraperRequest("https://mapharma.net/97200?c=60&l=1", "2021-04-14")