-
Notifications
You must be signed in to change notification settings - Fork 142
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
credits go to the respective contributors @RomainL972 - Allow search second/third dose only #60 @edwillys - Log with timestamp before looping over centers #67 @strombringer - add an option to exclude a list of centers from the search results #72 @gitolicious - add try_to_book happy path test with mock responses #73 @gitolicious - skip second shot motives #78 @namnhatpham1995 - Add AstraZeneca choice #79 @Dreiundzwanzig - Add options for AstraZeneca plus second and third shot #81 @gitolicious - Add option to include neighbor cities #85 @gitolicious - Add 2FA code argument for non-interactive environments #86 @gitolicious - Add option to include and exclude centers by regular expression #91 @laucia - Relax city name filtering for centers #94
- Loading branch information
1 parent
44af15d
commit 7813cc1
Showing
7 changed files
with
681 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,5 @@ | ||
__pycache__ | ||
*.pyc | ||
|
||
.vscode | ||
.devcontainer |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,49 @@ | ||
import pytest | ||
from requests.adapters import Response | ||
import responses | ||
from html import escape | ||
import json | ||
import datetime | ||
from woob.browser.browsers import Browser | ||
from woob.browser.exceptions import ServerError | ||
from doctoshotgun import DoctolibDE, DoctolibFR | ||
from doctoshotgun import DoctolibDE, DoctolibFR, CenterBookingPage | ||
|
||
# globals | ||
FIXTURES_FOLDER = "test_fixtures" | ||
|
||
|
||
@responses.activate | ||
def test_find_centers_fr_returns_503_should_continue(tmp_path): | ||
""" | ||
Check that find_centers doesn't raise a ServerError in case of 503 HTTP response | ||
""" | ||
docto = DoctolibFR("[email protected]", "1234", responses_dirname=tmp_path) | ||
docto = DoctolibFR("[email protected]", | ||
"1234", responses_dirname=tmp_path) | ||
docto.BASEURL = "https://127.0.0.1" | ||
|
||
responses.add( | ||
responses.GET, | ||
"https://127.0.0.1/vaccination-covid-19/Paris?ref_visit_motive_ids%5B%5D=6970&ref_visit_motive_ids%5B%5D=7005&ref_visit_motive_ids%5B%5D=7945", | ||
"https://127.0.0.1/vaccination-covid-19/Paris?ref_visit_motive_ids%5B%5D=6970&ref_visit_motive_ids%5B%5D=6971&ref_visit_motive_ids%5B%5D=8192&ref_visit_motive_ids%5B%5D=7005&ref_visit_motive_ids%5B%5D=7004&ref_visit_motive_ids%5B%5D=8193&ref_visit_motive_ids%5B%5D=7945&ref_visit_motive_ids%5B%5D=7107&ref_visit_motive_ids%5B%5D=7108", | ||
status=503 | ||
) | ||
|
||
# this should not raise an exception | ||
for _ in docto.find_centers(["Paris"]): | ||
pass | ||
|
||
|
||
@responses.activate | ||
def test_find_centers_de_returns_503_should_continue(tmp_path): | ||
""" | ||
Check that find_centers doesn't raise a ServerError in case of 503 HTTP response | ||
""" | ||
docto = DoctolibDE("[email protected]", "1234", responses_dirname=tmp_path) | ||
docto = DoctolibDE("[email protected]", | ||
"1234", responses_dirname=tmp_path) | ||
docto.BASEURL = "https://127.0.0.1" | ||
|
||
responses.add( | ||
responses.GET, | ||
"https://127.0.0.1/impfung-covid-19-corona/M%C3%BCnchen?ref_visit_motive_ids%5B%5D=6768&ref_visit_motive_ids%5B%5D=6936&ref_visit_motive_ids%5B%5D=7978", | ||
"https://127.0.0.1/impfung-covid-19-corona/M%C3%BCnchen?ref_visit_motive_ids%5B%5D=6768&ref_visit_motive_ids%5B%5D=6769&ref_visit_motive_ids%5B%5D=6936&ref_visit_motive_ids%5B%5D=6937&ref_visit_motive_ids%5B%5D=7978&ref_visit_motive_ids%5B%5D=7109&ref_visit_motive_ids%5B%5D=7110", | ||
status=503 | ||
) | ||
|
||
|
@@ -41,17 +52,38 @@ def test_find_centers_de_returns_503_should_continue(tmp_path): | |
pass | ||
|
||
|
||
@responses.activate | ||
def test_find_centers_de_returns_520_should_continue(tmp_path): | ||
""" | ||
Check that find_centers doesn't raise a ServerError in case of 503 HTTP response | ||
""" | ||
docto = DoctolibDE("[email protected]", | ||
"1234", responses_dirname=tmp_path) | ||
docto.BASEURL = "https://127.0.0.1" | ||
|
||
responses.add( | ||
responses.GET, | ||
"https://127.0.0.1/impfung-covid-19-corona/M%C3%BCnchen?ref_visit_motive_ids%5B%5D=6768&ref_visit_motive_ids%5B%5D=6769&ref_visit_motive_ids%5B%5D=6936&ref_visit_motive_ids%5B%5D=6937&ref_visit_motive_ids%5B%5D=7978&ref_visit_motive_ids%5B%5D=7109&ref_visit_motive_ids%5B%5D=7110", | ||
status=520 | ||
) | ||
|
||
# this should not raise an exception | ||
for _ in docto.find_centers(["München"]): | ||
pass | ||
|
||
|
||
@responses.activate | ||
def test_find_centers_fr_returns_502_should_fail(tmp_path): | ||
""" | ||
Check that find_centers raises an error in case of non-whitelisted status code | ||
""" | ||
docto = DoctolibFR("[email protected]", "1234", responses_dirname=tmp_path) | ||
docto = DoctolibFR("[email protected]", | ||
"1234", responses_dirname=tmp_path) | ||
docto.BASEURL = "https://127.0.0.1" | ||
|
||
responses.add( | ||
responses.GET, | ||
"https://127.0.0.1/vaccination-covid-19/Paris?ref_visit_motive_ids%5B%5D=6970&ref_visit_motive_ids%5B%5D=7005&ref_visit_motive_ids%5B%5D=7945", | ||
"https://127.0.0.1/vaccination-covid-19/Paris?ref_visit_motive_ids%5B%5D=6970&ref_visit_motive_ids%5B%5D=6971&ref_visit_motive_ids%5B%5D=8192&ref_visit_motive_ids%5B%5D=7005&ref_visit_motive_ids%5B%5D=7004&ref_visit_motive_ids%5B%5D=8193&ref_visit_motive_ids%5B%5D=7945&ref_visit_motive_ids%5B%5D=7107&ref_visit_motive_ids%5B%5D=7108", | ||
status=502 | ||
) | ||
|
||
|
@@ -60,21 +92,205 @@ def test_find_centers_fr_returns_502_should_fail(tmp_path): | |
for _ in docto.find_centers(["Paris"]): | ||
pass | ||
|
||
|
||
@responses.activate | ||
def test_find_centers_de_returns_502_should_fail(tmp_path): | ||
""" | ||
Check that find_centers raises an error in case of non-whitelisted status code | ||
""" | ||
docto = DoctolibDE("[email protected]", "1234", responses_dirname=tmp_path) | ||
docto = DoctolibDE("[email protected]", | ||
"1234", responses_dirname=tmp_path) | ||
docto.BASEURL = "https://127.0.0.1" | ||
|
||
responses.add( | ||
responses.GET, | ||
"https://127.0.0.1/impfung-covid-19-corona/M%C3%BCnchen?ref_visit_motive_ids%5B%5D=6768&ref_visit_motive_ids%5B%5D=6936&ref_visit_motive_ids%5B%5D=7978", | ||
"https://127.0.0.1/impfung-covid-19-corona/M%C3%BCnchen?ref_visit_motive_ids%5B%5D=6768&ref_visit_motive_ids%5B%5D=6769&ref_visit_motive_ids%5B%5D=6936&ref_visit_motive_ids%5B%5D=6937&ref_visit_motive_ids%5B%5D=7978&ref_visit_motive_ids%5B%5D=7109&ref_visit_motive_ids%5B%5D=7110", | ||
status=502 | ||
) | ||
|
||
# this should raise an exception | ||
with pytest.raises(ServerError): | ||
for _ in docto.find_centers(["München"]): | ||
pass | ||
|
||
|
||
@responses.activate | ||
def test_book_slots_should_succeed(tmp_path): | ||
""" | ||
Check that try_to_book calls all services successfully | ||
""" | ||
docto = DoctolibDE("[email protected]", | ||
"1234", responses_dirname=tmp_path) | ||
docto.BASEURL = "https://127.0.0.1" | ||
docto.patient = { | ||
"id": "patient-id", | ||
"first_name": "Roger", | ||
"last_name": "Phillibert" | ||
} | ||
|
||
mock_search_result_id = { | ||
"searchResultId": 1234567 | ||
} | ||
|
||
mock_search_result_id_escaped_json = escape( | ||
json.dumps(mock_search_result_id, separators=(',', ':'))) | ||
|
||
responses.add( | ||
responses.GET, | ||
"https://127.0.0.1/impfung-covid-19-corona/K%C3%B6ln?ref_visit_motive_ids%5B%5D=6768&ref_visit_motive_ids%5B%5D=6769&ref_visit_motive_ids%5B%5D=6936&ref_visit_motive_ids%5B%5D=6937&ref_visit_motive_ids%5B%5D=7978&ref_visit_motive_ids%5B%5D=7109&ref_visit_motive_ids%5B%5D=7110", | ||
status=200, | ||
body="<div class='js-dl-search-results-calendar' data-props='{dataProps}'></div>".format( | ||
dataProps=mock_search_result_id_escaped_json) | ||
) | ||
|
||
with open(FIXTURES_FOLDER + '/search_result.json') as json_file: | ||
mock_search_result = json.load(json_file) | ||
|
||
responses.add( | ||
responses.GET, | ||
"https://127.0.0.1/search_results/1234567.json?limit=4&ref_visit_motive_ids%5B%5D=6768&ref_visit_motive_ids%5B%5D=6769&ref_visit_motive_ids%5B%5D=6936&ref_visit_motive_ids%5B%5D=6937&ref_visit_motive_ids%5B%5D=7978&ref_visit_motive_ids%5B%5D=7109&ref_visit_motive_ids%5B%5D=7110&speciality_id=5494&search_result_format=json", | ||
status=200, | ||
body=json.dumps(mock_search_result) | ||
) | ||
|
||
with open(FIXTURES_FOLDER + '/doctor_response.json') as json_file: | ||
mock_doctor_response = json.load(json_file) | ||
|
||
responses.add( | ||
responses.GET, | ||
"https://127.0.0.1/allgemeinmedizin/koeln/dr-dre?insurance_sector=public", | ||
status=200, | ||
body=json.dumps(mock_doctor_response) | ||
) | ||
|
||
responses.add( | ||
responses.GET, | ||
"https://127.0.0.1/booking/dr-dre.json", | ||
status=200, | ||
body=json.dumps(mock_doctor_response) | ||
) | ||
|
||
with open(FIXTURES_FOLDER + '/availabilities.json') as json_file: | ||
mock_availabilities = json.load(json_file) | ||
|
||
responses.add( | ||
responses.GET, | ||
"https://127.0.0.1/availabilities.json?start_date=2021-06-01&visit_motive_ids=2920448&agenda_ids=&insurance_sector=public&practice_ids=234567&destroy_temporary=true&limit=3", | ||
status=200, | ||
body=json.dumps(mock_availabilities) | ||
) | ||
responses.add( | ||
responses.GET, | ||
"https://127.0.0.1/availabilities.json?start_date=2021-06-01&visit_motive_ids=2746983&agenda_ids=&insurance_sector=public&practice_ids=234567&destroy_temporary=true&limit=3", | ||
status=200, | ||
body=json.dumps(mock_availabilities) | ||
) | ||
|
||
mock_appointments = { | ||
"id": "appointment-id" | ||
} | ||
|
||
responses.add( | ||
responses.POST, | ||
"https://127.0.0.1/appointments.json", | ||
status=200, | ||
body=json.dumps(mock_appointments) | ||
) | ||
|
||
mock_appointments_edit = { | ||
"id": "appointment-edit-id", | ||
"appointment": { | ||
"custom_fields": {} | ||
} | ||
} | ||
|
||
responses.add( | ||
responses.GET, | ||
"https://127.0.0.1/appointments/appointment-id/edit.json", | ||
status=200, | ||
body=json.dumps(mock_appointments_edit) | ||
) | ||
|
||
responses.add( | ||
responses.GET, | ||
"https://127.0.0.1/second_shot_availabilities.json?start_date=2021-07-20&visit_motive_ids=2746983&agenda_ids=&first_slot=2021-06-10T08%3A40%3A00.000%2B02%3A00&insurance_sector=public&practice_ids=234567&limit=3", | ||
status=200, | ||
body=json.dumps(mock_availabilities) | ||
) | ||
|
||
mock_appointment_id_put = { | ||
} | ||
|
||
responses.add( | ||
responses.PUT, | ||
"https://127.0.0.1/appointments/appointment-id.json", | ||
status=200, | ||
body=json.dumps(mock_appointment_id_put) | ||
) | ||
|
||
mock_appointment_id = { | ||
"confirmed": True | ||
} | ||
|
||
responses.add( | ||
responses.GET, | ||
"https://127.0.0.1/appointments/appointment-id.json", | ||
status=200, | ||
body=json.dumps(mock_appointment_id) | ||
) | ||
|
||
result_handled = False | ||
for result in docto.find_centers(["Köln"]): | ||
result_handled = True | ||
|
||
center = result['search_result'] | ||
|
||
# single shot vaccination | ||
assert docto.try_to_book(center=center, | ||
vaccine_list=["Janssen"], | ||
start_date=datetime.date( | ||
year=2021, month=6, day=1), | ||
end_date=datetime.date( | ||
year=2021, month=6, day=14), | ||
only_second=False, | ||
only_third=False, | ||
dry_run=False) | ||
assert len(responses.calls) == 10 | ||
|
||
# two shot vaccination | ||
assert docto.try_to_book(center=center, | ||
vaccine_list=["Pfizer"], | ||
start_date=datetime.date( | ||
year=2021, month=6, day=1), | ||
end_date=datetime.date( | ||
year=2021, month=6, day=14), | ||
only_second=False, | ||
only_third=False, | ||
dry_run=False) | ||
assert len(responses.calls) == 20 | ||
pass | ||
|
||
assert result_handled | ||
|
||
|
||
@responses.activate | ||
def test_find_motive_should_ignore_second_shot(tmp_path): | ||
""" | ||
Check that find_motive ignores second shot motives | ||
""" | ||
|
||
with open(FIXTURES_FOLDER + '/doctor_response.json') as json_file: | ||
mock_doctor_response = json.load(json_file) | ||
|
||
response = Response() | ||
response._content = b'{}' | ||
|
||
booking_page = CenterBookingPage(browser=Browser(), response=response) | ||
booking_page.doc = mock_doctor_response | ||
visit_motive_id = CenterBookingPage.find_motive( | ||
booking_page, '.*(Pfizer)', False) | ||
assert visit_motive_id == mock_doctor_response['data']['visit_motives'][1]['id'] | ||
|
||
visit_motive_id = CenterBookingPage.find_motive( | ||
booking_page, '.*(Janssen)', True) | ||
assert visit_motive_id == mock_doctor_response['data']['visit_motives'][3]['id'] |
Oops, something went wrong.