def test_jwt() -> None: """Test for Credential class.""" jwt_token = get_jwt() credential = JWTCredential(jwt_token) assert credential.value == jwt_token assert not credential.has_expired() expired_time = time.time() + 3600 with mock.patch("time.time", mock.MagicMock(return_value=expired_time)): assert credential.has_expired()
def test_jwt_credential() -> None: """Test get/set with jwt credential.""" credential_store = CredentialStore() test_key = "test" # Try to get value from empty store assert test_key not in credential_store assert not credential_store.get(test_key) with pytest.raises(KeyError): credential_store[test_key] # Set value test_value = JWTCredential(get_jwt()) credential_store[test_key] = test_value # Try to get values from filled store assert test_key in credential_store assert credential_store.get(test_key) == test_value assert credential_store.get_value(test_key) == test_value.value assert credential_store[test_key] == test_value # Try again with expired expired_time = time.time() + 3600 with mock.patch("time.time", mock.MagicMock(return_value=expired_time)): assert test_key not in credential_store assert credential_store.get_value(test_key) is None assert not credential_store.get(test_key) with pytest.raises(KeyError): credential_store[test_key]
def test_file_store() -> None: """Test file credential store.""" with tempfile.TemporaryDirectory() as tmpdirname: # Prepare initial store old_filename = f"{tmpdirname}/.credentials/renault-api.json" old_credential_store = FileCredentialStore(old_filename) test_key = "key" test_value = Credential("value") test_jwt_key = "gigya_jwt" test_jwt_value = JWTCredential(get_jwt()) old_credential_store[test_key] = test_value old_credential_store[test_jwt_key] = test_jwt_value assert test_key in old_credential_store assert old_credential_store.get(test_key) == test_value assert old_credential_store[test_key] == test_value assert test_jwt_key in old_credential_store assert old_credential_store.get(test_jwt_key) == test_jwt_value assert old_credential_store[test_jwt_key] == test_jwt_value # Copy the data into new file new_filename = f"{tmpdirname}/.credentials/renault-api-copy.json" copyfile(old_filename, new_filename) new_credential_store = FileCredentialStore(new_filename) # Check that the data is in the new store assert test_key in new_credential_store assert new_credential_store.get(test_key) == test_value assert new_credential_store[test_key] == test_value assert test_jwt_key in new_credential_store assert new_credential_store.get(test_jwt_key) == test_jwt_value assert new_credential_store[test_jwt_key] == test_jwt_value
def get_logged_in_credential_store() -> CredentialStore: """Get credential store initialised with Gigya credentials.""" credential_store = CredentialStore() credential_store[GIGYA_LOGIN_TOKEN] = Credential(TEST_LOGIN_TOKEN) credential_store[GIGYA_PERSON_ID] = Credential(TEST_PERSON_ID) credential_store[GIGYA_JWT] = JWTCredential(get_jwt()) return credential_store
def test_http_get(mocked_responses: aioresponses, cli_runner: CliRunner) -> None: """It exits with a status code of zero.""" credential_store = FileCredentialStore(os.path.expanduser(CREDENTIAL_PATH)) credential_store[CONF_LOCALE] = Credential(TEST_LOCALE) credential_store[CONF_ACCOUNT_ID] = Credential(TEST_ACCOUNT_ID) credential_store[CONF_VIN] = Credential(TEST_VIN) credential_store[GIGYA_LOGIN_TOKEN] = Credential(TEST_LOGIN_TOKEN) credential_store[GIGYA_PERSON_ID] = Credential(TEST_PERSON_ID) credential_store[GIGYA_JWT] = JWTCredential(fixtures.get_jwt()) fixtures.inject_get_charging_settings(mocked_responses, "single") endpoint = ("/commerce/v1/accounts/{account_id}" "/kamereon/kca/car-adapter" "/v1/cars/{vin}/charging-settings") result = cli_runner.invoke( __main__.main, f"http get {endpoint}", ) assert result.exit_code == 0, result.exception expected_output = ( "{'data': {'type': 'Car', 'id': 'VF1AAAAA555777999', 'attributes': {" "'mode': 'scheduled', 'schedules': [" "{'id': 1, 'activated': True, " "'monday': {'startTime': 'T12:00Z', 'duration': 15}, " "'tuesday': {'startTime': 'T04:30Z', 'duration': 420}, " "'wednesday': {'startTime': 'T22:30Z', 'duration': 420}, " "'thursday': {'startTime': 'T22:00Z', 'duration': 420}, " "'friday': {'startTime': 'T12:15Z', 'duration': 15}, " "'saturday': {'startTime': 'T12:30Z', 'duration': 30}, " "'sunday': {'startTime': 'T12:45Z', 'duration': 45}}" "]}}}\n") assert expected_output == result.output
def test_http_post_file(tmpdir: Any, mocked_responses: aioresponses, cli_runner: CliRunner) -> None: """It exits with a status code of zero.""" credential_store = FileCredentialStore(os.path.expanduser(CREDENTIAL_PATH)) credential_store[CONF_LOCALE] = Credential(TEST_LOCALE) credential_store[CONF_ACCOUNT_ID] = Credential(TEST_ACCOUNT_ID) credential_store[CONF_VIN] = Credential(TEST_VIN) credential_store[GIGYA_LOGIN_TOKEN] = Credential(TEST_LOGIN_TOKEN) credential_store[GIGYA_PERSON_ID] = Credential(TEST_PERSON_ID) credential_store[GIGYA_JWT] = JWTCredential(fixtures.get_jwt()) url = fixtures.inject_set_charge_schedule(mocked_responses, "schedules") endpoint = ("/commerce/v1/accounts/{account_id}" "/kamereon/kca/car-adapter" "/v2/cars/{vin}/actions/charge-schedule") body = { "data": { "type": "ChargeSchedule", "attributes": { "schedules": [] } } } json_file = tmpdir.mkdir("json").join("sample.json") json_file.write(json.dumps(body)) result = cli_runner.invoke( __main__.main, f"http post-file {endpoint} '{json_file}'", ) assert result.exit_code == 0, result.exception expected_output = ( "{'data': {'type': 'ChargeSchedule', 'id': 'guid', " "'attributes': {'schedules': [" "{'id': 1, 'activated': True, " "'tuesday': {'startTime': 'T04:30Z', 'duration': 420}, " "'wednesday': {'startTime': 'T22:30Z', 'duration': 420}, " "'thursday': {'startTime': 'T22:00Z', 'duration': 420}, " "'friday': {'startTime': 'T23:30Z', 'duration': 480}, " "'saturday': {'startTime': 'T18:30Z', 'duration': 120}, " "'sunday': {'startTime': 'T12:45Z', 'duration': 45}}]}}}\n") assert expected_output == result.output expected_json = { "data": { "type": "ChargeSchedule", "attributes": { "schedules": [] } } } request: RequestCall = mocked_responses.requests[("POST", URL(url))][0] assert expected_json == request.kwargs["json"]
def initialise_credential_store( include_account_id: Optional[bool] = None, include_vin: Optional[bool] = None, ) -> None: """Initialise CLI credential store.""" credential_store = FileCredentialStore(os.path.expanduser(CREDENTIAL_PATH)) credential_store[CONF_LOCALE] = Credential(TEST_LOCALE) credential_store[GIGYA_LOGIN_TOKEN] = Credential(TEST_LOGIN_TOKEN) credential_store[GIGYA_PERSON_ID] = Credential(TEST_PERSON_ID) credential_store[GIGYA_JWT] = JWTCredential(get_jwt()) if include_account_id: credential_store[CONF_ACCOUNT_ID] = Credential(TEST_ACCOUNT_ID) if include_vin: credential_store[CONF_VIN] = Credential(TEST_VIN)
def _read(self) -> None: """Read data from store location.""" if not os.path.exists(self._store_location): return with open(self._store_location) as json_file: data = json.load(json_file) for key, value in data.items(): if key == "gigya_jwt": try: self[key] = JWTCredential(value) except jwt.ExpiredSignatureError: # pragma: no cover pass else: self[key] = Credential(value)
def test_vehicle_status_no_prompt(mocked_responses: aioresponses, cli_runner: CliRunner) -> None: """It exits with a status code of zero.""" credential_store = FileCredentialStore(os.path.expanduser(CREDENTIAL_PATH)) credential_store[CONF_LOCALE] = Credential(TEST_LOCALE) credential_store[GIGYA_LOGIN_TOKEN] = Credential(TEST_LOGIN_TOKEN) credential_store[GIGYA_PERSON_ID] = Credential(TEST_PERSON_ID) credential_store[GIGYA_JWT] = JWTCredential(fixtures.get_jwt()) fixtures.inject_vehicle_status(mocked_responses) result = cli_runner.invoke( __main__.main, f"--account {TEST_ACCOUNT_ID} --vin {TEST_VIN} status") assert result.exit_code == 0, result.exception assert EXPECTED_BATTERY_STATUS == result.output
def test_list_vehicles_no_prompt(mocked_responses: aioresponses, cli_runner: CliRunner) -> None: """It exits with a status code of zero.""" credential_store = FileCredentialStore(os.path.expanduser(CREDENTIAL_PATH)) credential_store[CONF_LOCALE] = Credential(TEST_LOCALE) credential_store[GIGYA_LOGIN_TOKEN] = Credential(TEST_LOGIN_TOKEN) credential_store[GIGYA_PERSON_ID] = Credential(TEST_PERSON_ID) credential_store[GIGYA_JWT] = JWTCredential(fixtures.get_jwt()) fixtures.inject_get_vehicles(mocked_responses, "zoe_40.1.json") result = cli_runner.invoke(__main__.main, f"--account {TEST_ACCOUNT_ID} vehicles") assert result.exit_code == 0, result.exception expected_output = ("Registration Brand Model VIN\n" "-------------- ------- ------- -----------------\n" "REG-NUMBER RENAULT ZOE VF1AAAAA555777999\n") assert expected_output == result.output
def test_vehicle_status(mocked_responses: aioresponses, cli_runner: CliRunner, filename: str) -> None: """It exits with a status code of zero.""" filename = os.path.basename(filename) credential_store = FileCredentialStore(os.path.expanduser(CREDENTIAL_PATH)) credential_store[CONF_LOCALE] = Credential(TEST_LOCALE) credential_store[CONF_ACCOUNT_ID] = Credential(TEST_ACCOUNT_ID) credential_store[CONF_VIN] = Credential(TEST_VIN) credential_store[GIGYA_LOGIN_TOKEN] = Credential(TEST_LOGIN_TOKEN) credential_store[GIGYA_PERSON_ID] = Credential(TEST_PERSON_ID) credential_store[GIGYA_JWT] = JWTCredential(fixtures.get_jwt()) fixtures.inject_get_vehicle_details(mocked_responses, filename) fixtures.inject_get_vehicle_contracts(mocked_responses, "fr_FR.2.json") fixtures.inject_vehicle_status(mocked_responses) result = cli_runner.invoke(__main__.main, "status") assert result.exit_code == 0, result.exception assert EXPECTED_STATUS[filename] == result.output
def test_vehicle_contracts(mocked_responses: aioresponses, cli_runner: CliRunner) -> None: """It exits with a status code of zero.""" credential_store = FileCredentialStore(os.path.expanduser(CREDENTIAL_PATH)) credential_store[CONF_LOCALE] = Credential(TEST_LOCALE) credential_store[CONF_ACCOUNT_ID] = Credential(TEST_ACCOUNT_ID) credential_store[CONF_VIN] = Credential(TEST_VIN) credential_store[GIGYA_LOGIN_TOKEN] = Credential(TEST_LOGIN_TOKEN) credential_store[GIGYA_PERSON_ID] = Credential(TEST_PERSON_ID) credential_store[GIGYA_JWT] = JWTCredential(fixtures.get_jwt()) fixtures.inject_get_vehicle_contracts(mocked_responses, "fr_FR.1.json") result = cli_runner.invoke(__main__.main, "contracts") assert result.exit_code == 0, result.exception expected_output = ( "Type Code " "Description Start End Status\n" "------------------------------ -------------------- " "-------------------------------- ---------- ---------- " "------------------\n" "WARRANTY_MAINTENANCE_CONTRACTS 40 " "CONTRAT LOSANGE 2018-04-04 2022-04-03 Actif\n" "CONNECTED_SERVICES ZECONNECTP " "My Z.E. Connect en série 36 mois 2018-08-23 2021-08-23 Actif\n" "CONNECTED_SERVICES GBA " "Battery Services 2018-03-23 " "Echec d’activation\n" "WARRANTY ManufacturerWarranty " "Garantie fabricant 2020-04-03 Expiré\n" "WARRANTY PaintingWarranty " "Garantie peinture 2021-04-03 Actif\n" "WARRANTY CorrosionWarranty " "Garantie corrosion 2030-04-03 Actif\n" "WARRANTY GMPeWarranty " "Garantie GMPe 2020-04-03 Expiré\n" "WARRANTY AssistanceWarranty " "Garantie assistance 2020-04-03 Expiré\n") assert expected_output == result.output
def test_list_accounts_no_prompt( mocked_responses: aioresponses, cli_runner: CliRunner ) -> None: """It exits with a status code of zero.""" credential_store = FileCredentialStore(os.path.expanduser(CREDENTIAL_PATH)) credential_store[CONF_LOCALE] = Credential(TEST_LOCALE) credential_store[GIGYA_LOGIN_TOKEN] = Credential(TEST_LOGIN_TOKEN) credential_store[GIGYA_PERSON_ID] = Credential(TEST_PERSON_ID) credential_store[GIGYA_JWT] = JWTCredential(fixtures.get_jwt()) fixtures.inject_get_person(mocked_responses) result = cli_runner.invoke(__main__.main, "accounts") assert result.exit_code == 0, result.exception expected_output = ( "Type ID\n" "--------- ------------\n" "MYRENAULT account-id-1\n" "SFDC account-id-2\n" ) assert expected_output == result.output