Skip to content

Commit

Permalink
fix: single select parameter not being passed as expected (#104)
Browse files Browse the repository at this point in the history
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 <[email protected]>
Co-authored-by: Nathan Bryant <[email protected]>
  • Loading branch information
3 people authored Jan 11, 2022
1 parent e43c3a2 commit 3bf067d
Show file tree
Hide file tree
Showing 9 changed files with 31 additions and 38 deletions.
10 changes: 8 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ services:

addons:
firefox: latest
apt:
packages: firefox-geckodriver

language: python

Expand All @@ -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]'

Expand Down
6 changes: 3 additions & 3 deletions smartcar/auth_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"])
Expand Down
8 changes: 4 additions & 4 deletions tests/auth_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}']")
)
Expand All @@ -79,15 +79,15 @@ 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)
driver.find_element_by_id("password").send_keys("password")
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()
Expand Down
10 changes: 5 additions & 5 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -138,20 +138,20 @@ 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
a different brand. This time, get the first vehicle acquired for 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)
4 changes: 2 additions & 2 deletions tests/e2e/test_auth_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ 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}}
test_url_ss_disabled = client.get_auth_url(
["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):
Expand Down
8 changes: 4 additions & 4 deletions tests/e2e/test_exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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:
Expand Down
13 changes: 0 additions & 13 deletions tests/e2e/test_smartcar.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
8 changes: 4 additions & 4 deletions tests/e2e/test_vehicle.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/test_auth_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down

0 comments on commit 3bf067d

Please sign in to comment.