Exemplo n.º 1
0
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]
Exemplo n.º 2
0
def test_file_store_expired_token() -> None:
    """Test loading expired token from credential store."""
    with tempfile.TemporaryDirectory() as tmpdirname:
        # Prepare initial store
        expired_token = get_jwt(timedelta(seconds=-900))

        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 = Credential(expired_token)  # bypass JWTCredential
        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

        # Except the JWT token which was rejected on load
        assert test_jwt_key not in new_credential_store
Exemplo n.º 3
0
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
Exemplo n.º 4
0
async def test_set_vehicle_action(websession: aiohttp.ClientSession,
                                  mocked_responses: aioresponses) -> None:
    """Test set_vehicle_action."""
    url = fixtures.inject_set_hvac_start(mocked_responses, "cancel")
    assert await kamereon.set_vehicle_action(
        websession=websession,
        root_url=TEST_KAMEREON_URL,
        api_key=TEST_KAMEREON_APIKEY,
        gigya_jwt=fixtures.get_jwt(),
        country=TEST_COUNTRY,
        account_id=TEST_ACCOUNT_ID,
        vin=TEST_VIN,
        endpoint="hvac-start",
        attributes={"action": "cancel"},
    )

    expected_json = {
        "data": {
            "type": "HvacStart",
            "attributes": {
                "action": "cancel"
            }
        }
    }

    request: RequestCall = mocked_responses.requests[("POST", URL(url))][0]
    assert expected_json == request.kwargs["json"]
Exemplo n.º 5
0
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
Exemplo n.º 6
0
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
Exemplo n.º 7
0
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"]
Exemplo n.º 8
0
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()
Exemplo n.º 9
0
async def test_get_account_vehicles(websession: aiohttp.ClientSession,
                                    mocked_responses: aioresponses) -> None:
    """Test get_account_vehicles."""
    fixtures.inject_get_vehicles(mocked_responses, "zoe_40.1")

    await kamereon.get_account_vehicles(
        websession=websession,
        root_url=TEST_KAMEREON_URL,
        api_key=TEST_KAMEREON_APIKEY,
        gigya_jwt=fixtures.get_jwt(),
        country=TEST_COUNTRY,
        account_id=TEST_ACCOUNT_ID,
    )
Exemplo n.º 10
0
async def test_get_person(websession: aiohttp.ClientSession,
                          mocked_responses: aioresponses) -> None:
    """Test get_person."""
    fixtures.inject_get_person(mocked_responses)

    person = await kamereon.get_person(
        websession=websession,
        root_url=TEST_KAMEREON_URL,
        api_key=TEST_KAMEREON_APIKEY,
        gigya_jwt=fixtures.get_jwt(),
        country=TEST_COUNTRY,
        person_id=TEST_PERSON_ID,
    )
    assert len(person.accounts) == 2
Exemplo n.º 11
0
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)
Exemplo n.º 12
0
async def test_get_vehicle_data(websession: aiohttp.ClientSession,
                                mocked_responses: aioresponses) -> None:
    """Test get_vehicle_data."""
    fixtures.inject_get_battery_status(mocked_responses)

    assert await kamereon.get_vehicle_data(
        websession=websession,
        root_url=TEST_KAMEREON_URL,
        api_key=TEST_KAMEREON_APIKEY,
        gigya_jwt=fixtures.get_jwt(),
        country=TEST_COUNTRY,
        account_id=TEST_ACCOUNT_ID,
        vin=TEST_VIN,
        endpoint="battery-status",
    )
Exemplo n.º 13
0
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
Exemplo n.º 14
0
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
Exemplo n.º 15
0
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
Exemplo n.º 16
0
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
Exemplo n.º 17
0
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