From 3bf067d3fc9bb0e551b0ab6c7776278d3a93f0f2 Mon Sep 17 00:00:00 2001 From: Naomi Date: Mon, 10 Jan 2022 16:15:49 -0800 Subject: [PATCH] fix: single select parameter not being passed as expected (#104) fix: single select parameter not being passed as expected (#104) Modifies get_auth_url() so that when single_select parameter is set to true, the url query string is set to "true" instead of True. Also, removes test that tested functionality not available in production and modifies tests to use Ford vehicle instead of Tesla (Tesla requires captcha which causes timeout exception in selenium). * chore: remove get_compatibility with flags e2e test * Modify travis to use new geckodriver * replace tesla fixture with ford (#105) Co-authored-by: s-ashwinkumar Co-authored-by: Nathan Bryant <60950167+nbry@users.noreply.github.com> --- .travis.yml | 10 ++++++++-- smartcar/auth_client.py | 6 +++--- tests/auth_helpers.py | 8 ++++---- tests/conftest.py | 10 +++++----- tests/e2e/test_auth_client.py | 4 ++-- tests/e2e/test_exception.py | 8 ++++---- tests/e2e/test_smartcar.py | 13 ------------- tests/e2e/test_vehicle.py | 8 ++++---- tests/unit/test_auth_client.py | 2 +- 9 files changed, 31 insertions(+), 38 deletions(-) diff --git a/.travis.yml b/.travis.yml index dc47b1cd..f08dc3cc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,8 +5,6 @@ services: addons: firefox: latest - apt: - packages: firefox-geckodriver language: python @@ -18,6 +16,14 @@ python: if: tag IS blank # do not build tags +before_install: + - wget -N https://github.com/mozilla/geckodriver/releases/download/v0.30.0/geckodriver-v0.30.0-linux64.tar.gz -P ~/ + - tar -xzf ~/geckodriver-v0.30.0-linux64.tar.gz -C ~/ + - rm ~/geckodriver-v0.30.0-linux64.tar.gz + - sudo mv -f ~/geckodriver /usr/local/share + - sudo chmod +x /usr/local/share/geckodriver + - sudo ln -s /usr/local/share/geckodriver /usr/local/bin/geckodriver + install: - pip install -e '.[dev]' diff --git a/smartcar/auth_client.py b/smartcar/auth_client.py index 4009ccbe..deca7c80 100644 --- a/smartcar/auth_client.py +++ b/smartcar/auth_client.py @@ -125,11 +125,11 @@ def get_auth_url(self, scope: List[str], options: dict = None) -> str: if single_select.get("vin"): query["single_select_vin"] = single_select["vin"] - query["single_select"] = True + query["single_select"] = "true" elif single_select.get("enabled"): - query["single_select"] = True + query["single_select"] = "true" else: - query["single_select"] = False + query["single_select"] = "false" if options.get("flags"): flags_str = helpers.format_flag_query(options["flags"]) diff --git a/tests/auth_helpers.py b/tests/auth_helpers.py index f6b8bd05..38967919 100644 --- a/tests/auth_helpers.py +++ b/tests/auth_helpers.py @@ -64,13 +64,13 @@ def run_auth_flow(auth_url, brand="CHEVROLET"): driver.get(auth_url) # Preamble - preamble_button = WebDriverWait(driver, 10).until( + preamble_button = WebDriverWait(driver, 30).until( EC.presence_of_element_located((By.CSS_SELECTOR, "button#continue-button")) ) preamble_button.click() # Brand Selector - brand_button = WebDriverWait(driver, 10).until( + brand_button = WebDriverWait(driver, 30).until( EC.presence_of_element_located( (By.CSS_SELECTOR, f"button.brand-selector-button[data-make='{brand}']") ) @@ -79,7 +79,7 @@ def run_auth_flow(auth_url, brand="CHEVROLET"): # Logging in (with any random credentials to run through test-mode) username = str(uuid.uuid4()) + "@email.com" - sign_in_button = WebDriverWait(driver, 10).until( + sign_in_button = WebDriverWait(driver, 30).until( EC.presence_of_element_located((By.ID, "sign-in-button")) ) driver.find_element_by_id("username").send_keys(username) @@ -87,7 +87,7 @@ def run_auth_flow(auth_url, brand="CHEVROLET"): sign_in_button.click() # Permissions Approval - permissions_approval_button = WebDriverWait(driver, 10).until( + permissions_approval_button = WebDriverWait(driver, 30).until( EC.presence_of_element_located((By.ID, "approval-button")) ) permissions_approval_button.click() diff --git a/tests/conftest.py b/tests/conftest.py index 2d47a23a..329f6951 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -127,7 +127,7 @@ def chevy_volt_limited_scope(client): # # Tesla @pytest.fixture(scope="session") -def access_tesla(client): +def access_ford(client): """ Using the client fixture, go through Smartcar connect auth flow and acquire an access object. This object will have @@ -138,13 +138,13 @@ def access_tesla(client): access_tesla namedtuple """ client = sc.AuthClient(*ah.get_auth_client_params()) - code = ah.run_auth_flow(client.get_auth_url(["required:control_charge"]), "TESLA") + code = ah.run_auth_flow(client.get_auth_url(["required:control_charge"]), "FORD") access = client.exchange_code(code) yield access @pytest.fixture(scope="session") -def tesla_model_s(access_tesla): +def ford_car(access_ford): """ Using a separate instance of smartcar.AuthClient, run the Smartcar connect auth flow with different scope of permissions and @@ -152,6 +152,6 @@ def tesla_model_s(access_tesla): Yields: tesla(smartcar.Vehicle) """ - vehicle_ids = sc.get_vehicles(access_tesla.access_token) + vehicle_ids = sc.get_vehicles(access_ford.access_token) tesla_id = vehicle_ids.vehicles[0] - yield sc.Vehicle(tesla_id, access_tesla.access_token) + yield sc.Vehicle(tesla_id, access_ford.access_token) diff --git a/tests/e2e/test_auth_client.py b/tests/e2e/test_auth_client.py index bc522c5d..58715a3d 100644 --- a/tests/e2e/test_auth_client.py +++ b/tests/e2e/test_auth_client.py @@ -33,7 +33,7 @@ def test_get_auth_url_single_select(client): ["read_odometer", "read_vehicle_info"], options ) query_params = urlparse.parse_qs(test_url_ss_enabled) - assert query_params["single_select"][0] == "True" + assert query_params["single_select"][0] == "true" # Testing the explicit setting of single_select to false: options_2 = {"single_select": {"enabled": False}} @@ -41,7 +41,7 @@ def test_get_auth_url_single_select(client): ["read_odometer", "read_vehicle_info"], options_2 ) query_params_2 = urlparse.parse_qs(test_url_ss_disabled) - assert query_params_2["single_select"][0] == "False" + assert query_params_2["single_select"][0] == "false" def test_set_expiration(access): diff --git a/tests/e2e/test_exception.py b/tests/e2e/test_exception.py index 6c6f9b1e..c3ecc12a 100644 --- a/tests/e2e/test_exception.py +++ b/tests/e2e/test_exception.py @@ -62,12 +62,12 @@ def test_vehicle_state_error_v1(access): assert "resolution" not in e.__dict__ -def test_out_of_permission_scope(tesla_model_s): +def test_out_of_permission_scope(ford_car): """ status code: 403, no "error" code """ try: - tesla_model_s.odometer() + ford_car.odometer() except Exception as e: assert isinstance(e, SmartcarException) @@ -81,14 +81,14 @@ def test_out_of_permission_scope(tesla_model_s): assert "type" in e.resolution.keys() and "url" in e.resolution.keys() -def test_out_of_permission_scope_v1(access_tesla, tesla_model_s): +def test_out_of_permission_scope_v1(access_ford, ford_car): """ v1 permission error, code is None """ try: smartcar.set_api_version("1.0") tesla_for_v1_api = smartcar.Vehicle( - tesla_model_s.vehicle_id, access_tesla.access_token + ford_car.vehicle_id, access_ford.access_token ) tesla_for_v1_api.odometer() except Exception as e: diff --git a/tests/e2e/test_smartcar.py b/tests/e2e/test_smartcar.py index 82dc19f2..c5cdfbc7 100644 --- a/tests/e2e/test_smartcar.py +++ b/tests/e2e/test_smartcar.py @@ -41,19 +41,6 @@ def test_get_vehicles_with_paging(access): assert len(res.vehicles) == 0 -def test_get_compatibility_with_flags(chevy_volt): - res = get_compatibility( - vin=chevy_volt.vin().vin, - scope=["read_vehicle_info"], - options={ - "client_id": ah.CLIENT_ID, - "client_secret": ah.CLIENT_SECRET, - "flags": {"flag1": True}, - }, - ) - assert res.compatible is not None - - def test_get_compatibility_in_test_mode_but_no_level(): try: get_compatibility( diff --git a/tests/e2e/test_vehicle.py b/tests/e2e/test_vehicle.py index d34dfafe..c548fc34 100644 --- a/tests/e2e/test_vehicle.py +++ b/tests/e2e/test_vehicle.py @@ -96,15 +96,15 @@ def test_unlock(chevy_volt): assert response._fields == ("status", "message", "meta") -def test_start_charge(tesla_model_s): - response = tesla_model_s.start_charge() +def test_start_charge(ford_car): + response = ford_car.start_charge() assert response.status == "success" assert type(response) == types.Action assert response._fields == ("status", "message", "meta") -def test_stop_charge(tesla_model_s): - response = tesla_model_s.stop_charge() +def test_stop_charge(ford_car): + response = ford_car.stop_charge() assert response.status == "success" assert type(response) == types.Action assert response._fields == ("status", "message", "meta") diff --git a/tests/unit/test_auth_client.py b/tests/unit/test_auth_client.py index 22d653b1..f979be30 100644 --- a/tests/unit/test_auth_client.py +++ b/tests/unit/test_auth_client.py @@ -21,7 +21,7 @@ def test_get_auth_url_with_options(client): assert query_params["mode"][0] == "test" assert query_params["state"][0] == "WEEEEEEEEE" assert query_params["make"][0] == "Ford" - assert query_params["single_select"][0] == "True" + assert query_params["single_select"][0] == "true" assert query_params["single_select_vin"][0] == "abcdefghi12345678" assert query_params["flags"][0] == "flag_1:Yay flag_2:True flag_3:123"