diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bea34fee..74fb8422 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: os: ["macos-latest", "ubuntu-latest", "windows-latest"] - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12"] fail-fast: false steps: - name: "⤵️ Check out code from GitHub" diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index ca2d997b..3cd77654 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -13,7 +13,7 @@ jobs: - name: "🐍 Set up Python" uses: "actions/setup-python@v5" with: - python-version: 3.8 + python-version: 3.9 - name: "⚙️ Install Poetry" uses: "abatilo/actions-poetry@v3.0.0" with: diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 88e5f0f3..938a6b97 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -13,7 +13,7 @@ jobs: name: "Pytest" strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12"] runs-on: "ubuntu-latest" env: OS: "ubuntu-latest" diff --git a/mytoyota/controller.py b/mytoyota/controller.py index df084138..5c15b2ab 100644 --- a/mytoyota/controller.py +++ b/mytoyota/controller.py @@ -105,6 +105,7 @@ async def _authenticate(self): self._authenticate_url, json=data ) # , headers=standard_headers) _LOGGER.debug(format_httpx_response(resp)) + if resp.status_code != HTTPStatus.OK: raise ToyotaLoginError( f"Authentication Failed. {resp.status_code}, {resp.text}." @@ -123,6 +124,7 @@ async def _authenticate(self): headers={"cookie": f"iPlanetDirectoryPro={data['tokenId']}"}, ) _LOGGER.debug(format_httpx_response(resp)) + if resp.status_code != HTTPStatus.FOUND: raise ToyotaLoginError(f"Authorization failed. {resp.status_code}, {resp.text}.") authentication_code = parse.parse_qs( @@ -142,6 +144,7 @@ async def _authenticate(self): }, ) _LOGGER.debug(format_httpx_response(resp)) + if resp.status_code != HTTPStatus.OK: raise ToyotaLoginError(f"Token retrieval failed. {resp.status_code}, {resp.text}.") @@ -168,6 +171,7 @@ async def _refresh_tokens(self) -> None: }, ) _LOGGER.debug(format_httpx_response(resp)) + if resp.status_code != HTTPStatus.OK: raise ToyotaLoginError(f"Token refresh failed. {resp.status_code}, {resp.text}.") @@ -254,6 +258,7 @@ async def request_raw( # noqa: PLR0913 follow_redirects=True, ) _LOGGER.debug(format_httpx_response(response)) + if response.status_code in [ HTTPStatus.OK, HTTPStatus.ACCEPTED, diff --git a/mytoyota/utils/logging/log_utils.py b/mytoyota/utils/logging/log_utils.py index 80a3ebdb..8e5c132f 100644 --- a/mytoyota/utils/logging/log_utils.py +++ b/mytoyota/utils/logging/log_utils.py @@ -1,4 +1,5 @@ """Utilities for manipulating returns for log output tasks.""" +import json from typing import Any, Dict, Optional from httpx import Response @@ -54,6 +55,35 @@ def format_httpx_response(response: Response) -> str: ) +def format_httpx_response_json(response: Response) -> str: + """Format an HTTPX response into a json string representation. + + Args: + ---- + response (Response): The HTTPX response object to format. + + Returns: + ------- + str: The formatted representation of the HTTPX response. + + """ + return json.dumps( + { + "request": { + "method": response.request.method, + "url": str(response.request.url), + "headers": response.request.headers.multi_items(), + "content": response.request.content.decode("utf-8"), + }, + "response": { + "status": response.status_code, + "headers": response.headers.multi_items(), + "content": "" if len(response.content) == 0 else response.json(), + }, + } + ) + + def censor_all(dictionary: Dict[str, Any], to_censor: Optional[set] = None) -> Dict[str, Any]: r"""Censor sensitive values in a dictionary. diff --git a/poetry.lock b/poetry.lock index 95c969ca..d742ec7a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.0 and should not be changed by hand. [[package]] name = "anyio" @@ -353,13 +353,13 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co [[package]] name = "pluggy" -version = "1.3.0" +version = "1.4.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" files = [ - {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, - {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, + {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, + {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, ] [package.extras] @@ -368,13 +368,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pre-commit" -version = "3.5.0" +version = "3.6.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "pre_commit-3.5.0-py2.py3-none-any.whl", hash = "sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660"}, - {file = "pre_commit-3.5.0.tar.gz", hash = "sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32"}, + {file = "pre_commit-3.6.0-py2.py3-none-any.whl", hash = "sha256:c255039ef399049a5544b6ce13d135caba8f2c28c3b4033277a788f434308376"}, + {file = "pre_commit-3.6.0.tar.gz", hash = "sha256:d30bad9abf165f7785c15a21a1f46da7d0677cb00ee7ff4c579fd38922efe15d"}, ] [package.dependencies] @@ -523,6 +523,24 @@ pytest = ">=7.0.0" docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy (>=0.931)", "pytest-trio (>=0.7.0)"] +[[package]] +name = "pytest-httpx" +version = "0.28.0" +description = "Send responses to httpx." +optional = false +python-versions = ">=3.9" +files = [ + {file = "pytest_httpx-0.28.0-py3-none-any.whl", hash = "sha256:045774556a3633688742315a6981aab2806ce93bcbcc8444253ab87bca286800"}, + {file = "pytest_httpx-0.28.0.tar.gz", hash = "sha256:a82505fdf59f19eaaf2853db3f3832b3dee35d3bc58000232db2b65c5fca0614"}, +] + +[package.dependencies] +httpx = "==0.26.*" +pytest = "==7.*" + +[package.extras] +testing = ["pytest-asyncio (==0.23.*)", "pytest-cov (==4.*)"] + [[package]] name = "pytest-pretty" version = "1.2.0" @@ -577,7 +595,6 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -626,7 +643,6 @@ files = [ [package.dependencies] markdown-it-py = ">=2.2.0" pygments = ">=2.13.0,<3.0.0" -typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] @@ -785,13 +801,13 @@ files = [ [[package]] name = "types-python-dateutil" -version = "2.8.19.14" +version = "2.8.19.20240106" description = "Typing stubs for python-dateutil" optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "types-python-dateutil-2.8.19.14.tar.gz", hash = "sha256:1f4f10ac98bb8b16ade9dbee3518d9ace017821d94b057a425b069f834737f4b"}, - {file = "types_python_dateutil-2.8.19.14-py3-none-any.whl", hash = "sha256:f977b8de27787639986b4e28963263fd0e5158942b3ecef91b9335c130cb1ce9"}, + {file = "types-python-dateutil-2.8.19.20240106.tar.gz", hash = "sha256:1f8db221c3b98e6ca02ea83a58371b22c374f42ae5bbdf186db9c9a76581459f"}, + {file = "types_python_dateutil-2.8.19.20240106-py3-none-any.whl", hash = "sha256:efbbdc54590d0f16152fa103c9879c7d4a00e82078f6e2cf01769042165acaa2"}, ] [[package]] @@ -842,5 +858,5 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" -python-versions = "^3.8.1" -content-hash = "b87915f8ca6f2c4869e182d89fd995f20baa1dc93cccf0f82c11812a70cb3e6c" +python-versions = "^3.9" +content-hash = "7e0544ae018bba125c827d491f135271078de3b017ff4df63387af9066d751b2" diff --git a/pyproject.toml b/pyproject.toml index f41ef7dd..3cf78adc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,6 @@ packages = [ classifiers = [ "Development Status :: 4 - Beta", "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -30,7 +29,7 @@ repository = "https://github.com/DurgNomis-drol/mytoyota" "Release Notes" = "https://github.com/DurgNomis-drol/mytoyota/releases" [tool.poetry.dependencies] -python = "^3.8.1" +python = "^3.9" langcodes = "^3.1" httpx = ">=0.18.1" arrow = "^1.1" @@ -47,6 +46,7 @@ codespell = "^2.0.0" pytest = "^7.2.0" pytest-pretty = "^1.2.0" pytest-asyncio = "^0.21.1" +pytest-httpx = "^0.28.0" [tool.ruff] select = [ diff --git a/tests/conftest.py b/tests/conftest.py deleted file mode 100644 index 18e7e407..00000000 --- a/tests/conftest.py +++ /dev/null @@ -1 +0,0 @@ -"""Need for pytest or else it will cause an import error in pytest.""" diff --git a/tests/integration_tests/conftest.py b/tests/integration_tests/conftest.py new file mode 100644 index 00000000..c098a39e --- /dev/null +++ b/tests/integration_tests/conftest.py @@ -0,0 +1,20 @@ +"""Need for pytest or else it will cause an import error in pytest.""" + +from pathlib import Path + +import pytest + +from mytoyota.controller import CACHE_FILENAME + + +@pytest.fixture(scope="module") +def data_folder(request) -> str: + """Return the folder containing test files.""" + return str(Path(request.module.__file__).parent / "data") + + +@pytest.fixture(scope="function") +def remove_cache() -> None: + """Remove the credentials cache file if it exists.""" + # Remove cache file if exists + Path.unlink(CACHE_FILENAME, missing_ok=True) diff --git a/tests/integration_tests/data/authenticate_invalid_password.json b/tests/integration_tests/data/authenticate_invalid_password.json new file mode 100644 index 00000000..57aa731a --- /dev/null +++ b/tests/integration_tests/data/authenticate_invalid_password.json @@ -0,0 +1,231 @@ +[ + { + "request": { + "method": "POST", + "url": "https://b2c-login.toyota-europe.com/json/realms/root/realms/tme/authenticate?authIndexType=service&authIndexValue=oneapp", + "headers": [ + ["host", "b2c-login.toyota-europe.com"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["user-agent", "python-httpx/0.26.0"], + ["content-length", "2"], + ["content-type", "application/json"] + ], + "body": "{}" + }, + "response": { + "status": 200, + "headers": [ + ["content-type", "application/json"], + ["content-length", "2333"], + ["access-control-allow-credentials", "true"], + [ + "access-control-allow-headers", + "X-Username,x-username,Cookie,Host,Authorization,Access-Control-Allow-Headers,Content-Type,X-OpenIDM-OAuth-Login,X-OpenIDM-DataStoreToken,X-Requested-With,Cache-Control,Accept-Language,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,X-OpenAM-Username,X-OpenAM-Password,iPlanetDirectoryPro,Accept-API-Version" + ], + ["access-control-allow-methods", "GET, POST, OPTIONS, DELETE, PUT"], + [ + "access-control-allow-origin", + "https://b2c-login.toyota-europe.com,https://b2c-idm.toyota-europe.com,http://b2c-login.toyota-europe.com,http://b2c-idm.toyota-europe.com,https://tas600-huapps-acc-c.toyota-europe.com" + ], + [ + "access-control-expose-headers", + "x-username,X-Username,Access-Control-Allow-Headers,Access-Control-Allow-Origin,Access-Control-Allow-Credentials,Set-Cookie" + ], + ["content-api-version", "resource=2.1"], + ["pragma", "no-cache"], + ["server", "nginx/1.21.6"], + ["x-content-type-options", "nosniff"], + ["x-frame-options", "SAMEORIGIN"], + ["x-amz-cf-pop", "LHR61-P1"], + [ + "x-amz-cf-id", + "lTCtiIUdRjuzQt9AW38JCBlN9l1xnUmAasWesZdKIYEG5Ez4E-Xw4g==" + ], + ["cache-control", "private, max-age=0"], + ["expires", "Sat, 13 Jan 2024 15:11:26 GMT"], + ["date", "Sat, 13 Jan 2024 15:11:26 GMT"], + ["connection", "keep-alive"], + [ + "set-cookie", + "route=05d9245d324128421fd9615b40b7917b; expires=Mon, 15-Jan-24 15:11:26 GMT; max-age=172800; path=/" + ], + [ + "set-cookie", + "amlbcookie=01; Path=/; Secure; HttpOnly; SameSite=none" + ], + ["strict-transport-security", "max-age=86400"] + ], + "content": "{\"authId\":\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\",\"callbacks\":[{\"type\":\"NameCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"Market Locale\"}],\"input\":[{\"name\":\"IDToken1\",\"value\":\"\"}],\"_id\":0},{\"type\":\"NameCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"Internationalization\"}],\"input\":[{\"name\":\"IDToken2\",\"value\":\"\"}],\"_id\":1},{\"type\":\"NameCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"UI Locales\"}],\"input\":[{\"name\":\"IDToken3\",\"value\":\"\"}],\"_id\":2}]}" + } + }, + { + "request": { + "method": "POST", + "url": "https://b2c-login.toyota-europe.com/json/realms/root/realms/tme/authenticate?authIndexType=service&authIndexValue=oneapp", + "headers": [ + ["host", "b2c-login.toyota-europe.com"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["user-agent", "python-httpx/0.26.0"], + ["cookie", "amlbcookie=01; route=05d9245d324128421fd9615b40b7917b"], + ["content-length", "2377"], + ["content-type", "application/json"] + ], + "content": "{\"authId\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\", \"callbacks\": [{\"type\": \"NameCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"Market Locale\"}], \"input\": [{\"name\": \"IDToken1\", \"value\": \"\"}], \"_id\": 0}, {\"type\": \"NameCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"Internationalization\"}], \"input\": [{\"name\": \"IDToken2\", \"value\": \"\"}], \"_id\": 1}, {\"type\": \"NameCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"UI Locales\"}], \"input\": [{\"name\": \"IDToken3\", \"value\": \"\"}], \"_id\": 2}]}" + }, + "response": { + "status": 200, + "headers": [ + ["content-type", "application/json"], + ["content-length", "2597"], + ["access-control-allow-credentials", "true"], + [ + "access-control-allow-headers", + "X-Username,x-username,Cookie,Host,Authorization,Access-Control-Allow-Headers,Content-Type,X-OpenIDM-OAuth-Login,X-OpenIDM-DataStoreToken,X-Requested-With,Cache-Control,Accept-Language,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,X-OpenAM-Username,X-OpenAM-Password,iPlanetDirectoryPro,Accept-API-Version" + ], + ["access-control-allow-methods", "GET, POST, OPTIONS, DELETE, PUT"], + [ + "access-control-allow-origin", + "https://b2c-login.toyota-europe.com,https://b2c-idm.toyota-europe.com,http://b2c-login.toyota-europe.com,http://b2c-idm.toyota-europe.com,https://tas600-huapps-acc-c.toyota-europe.com" + ], + [ + "access-control-expose-headers", + "x-username,X-Username,Access-Control-Allow-Headers,Access-Control-Allow-Origin,Access-Control-Allow-Credentials,Set-Cookie" + ], + ["content-api-version", "resource=2.1"], + ["pragma", "no-cache"], + ["server", "nginx/1.21.6"], + ["x-content-type-options", "nosniff"], + ["x-frame-options", "SAMEORIGIN"], + ["x-amz-cf-pop", "LHR61-P1"], + [ + "x-amz-cf-id", + "ukxhuvVUgdDiaaVPzOcmzNMoQICSN3v8kgO5QK9vu42JavFl39CvaA==" + ], + ["cache-control", "private, max-age=0"], + ["expires", "Sat, 13 Jan 2024 15:11:26 GMT"], + ["date", "Sat, 13 Jan 2024 15:11:26 GMT"], + ["connection", "keep-alive"], + [ + "set-cookie", + "route=05d9245d324128421fd9615b40b7917b; expires=Mon, 15-Jan-24 15:11:26 GMT; max-age=172800; path=/" + ], + [ + "set-cookie", + "amlbcookie=01; Path=/; Secure; HttpOnly; SameSite=none" + ], + ["strict-transport-security", "max-age=86400"] + ], + "content": "{\"authId\":\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\",\"callbacks\":[{\"type\":\"NameCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"User Name\"}],\"input\":[{\"name\":\"IDToken1\",\"value\":\"\"}],\"_id\":3},{\"type\":\"ChoiceCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"Prompt\"},{\"name\":\"choices\",\"value\":[\"Local\",\"Google\",\"Facebook\",\"Apple\"]},{\"name\":\"defaultChoice\",\"value\":0}],\"input\":[{\"name\":\"IDToken2\",\"value\":0}],\"_id\":4}]}" + } + }, + { + "request": { + "method": "POST", + "url": "https://b2c-login.toyota-europe.com/json/realms/root/realms/tme/authenticate?authIndexType=service&authIndexValue=oneapp", + "headers": [ + ["host", "b2c-login.toyota-europe.com"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["user-agent", "python-httpx/0.26.0"], + ["cookie", "amlbcookie=01; route=05d9245d324128421fd9615b40b7917b"], + ["content-length", "2663"], + ["content-type", "application/json"] + ], + "content": "{\"authId\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\", \"callbacks\": [{\"type\": \"NameCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"User Name\"}], \"input\": [{\"name\": \"IDToken1\", \"value\": \"user@email.info\"}], \"_id\": 3}, {\"type\": \"ChoiceCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"Prompt\"}, {\"name\": \"choices\", \"value\": [\"Local\", \"Google\", \"Facebook\", \"Apple\"]}, {\"name\": \"defaultChoice\", \"value\": 0}], \"input\": [{\"name\": \"IDToken2\", \"value\": 0}], \"_id\": 4}]}" + }, + "response": { + "status": 200, + "headers": [ + ["content-type", "application/json"], + ["content-length", "3383"], + ["access-control-allow-credentials", "true"], + [ + "access-control-allow-headers", + "X-Username,x-username,Cookie,Host,Authorization,Access-Control-Allow-Headers,Content-Type,X-OpenIDM-OAuth-Login,X-OpenIDM-DataStoreToken,X-Requested-With,Cache-Control,Accept-Language,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,X-OpenAM-Username,X-OpenAM-Password,iPlanetDirectoryPro,Accept-API-Version" + ], + ["access-control-allow-methods", "GET, POST, OPTIONS, DELETE, PUT"], + [ + "access-control-allow-origin", + "https://b2c-login.toyota-europe.com,https://b2c-idm.toyota-europe.com,http://b2c-login.toyota-europe.com,http://b2c-idm.toyota-europe.com,https://tas600-huapps-acc-c.toyota-europe.com" + ], + [ + "access-control-expose-headers", + "x-username,X-Username,Access-Control-Allow-Headers,Access-Control-Allow-Origin,Access-Control-Allow-Credentials,Set-Cookie" + ], + ["content-api-version", "resource=2.1"], + ["pragma", "no-cache"], + ["server", "nginx/1.21.6"], + ["x-content-type-options", "nosniff"], + ["x-frame-options", "SAMEORIGIN"], + ["x-amz-cf-pop", "LHR61-P1"], + [ + "x-amz-cf-id", + "XTjuicx-XXxaAqzwbYW3MZH8_iqzV2YF3ALhPV_ecVIQ3aCuOAwXkg==" + ], + ["cache-control", "private, max-age=0"], + ["expires", "Sat, 13 Jan 2024 15:11:26 GMT"], + ["date", "Sat, 13 Jan 2024 15:11:26 GMT"], + ["connection", "keep-alive"], + [ + "set-cookie", + "route=05d9245d324128421fd9615b40b7917b; expires=Mon, 15-Jan-24 15:11:26 GMT; max-age=172800; path=/" + ], + [ + "set-cookie", + "amlbcookie=01; Path=/; Secure; HttpOnly; SameSite=none" + ], + ["strict-transport-security", "max-age=86400"] + ], + "content": "{\"authId\":\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\",\"callbacks\":[{\"type\":\"PasswordCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"Password\"}],\"input\":[{\"name\":\"IDToken1\",\"value\":\"\"}],\"_id\":5},{\"type\":\"ChoiceCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"Prompt\"},{\"name\":\"choices\",\"value\":[\"continue\",\"resetpass\"]},{\"name\":\"defaultChoice\",\"value\":0}],\"input\":[{\"name\":\"IDToken2\",\"value\":0}],\"_id\":6}]}" + } + }, + { + "request": { + "method": "POST", + "url": "https://b2c-login.toyota-europe.com/json/realms/root/realms/tme/authenticate?authIndexType=service&authIndexValue=oneapp", + "headers": [ + ["host", "b2c-login.toyota-europe.com"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["user-agent", "python-httpx/0.26.0"], + ["cookie", "amlbcookie=01; route=05d9245d324128421fd9615b40b7917b"], + ["content-length", "3427"], + ["content-type", "application/json"] + ], + "content": "{\"authId\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\", \"callbacks\": [{\"type\": \"PasswordCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"Password\"}], \"input\": [{\"name\": \"IDToken1\", \"value\": \"password\"}], \"_id\": 5}, {\"type\": \"ChoiceCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"Prompt\"}, {\"name\": \"choices\", \"value\": [\"continue\", \"resetpass\"]}, {\"name\": \"defaultChoice\", \"value\": 0}], \"input\": [{\"name\": \"IDToken2\", \"value\": 0}], \"_id\": 6}]}" + }, + "response": { + "status": 401, + "headers": [ + ["content-type", "application/json"], + ["content-length", "110"], + ["content-api-version", "resource=2.1"], + ["pragma", "no-cache"], + ["server", "nginx/1.21.6"], + ["x-content-type-options", "nosniff"], + ["x-frame-options", "SAMEORIGIN"], + ["x-amz-cf-pop", "LHR61-P1"], + [ + "x-amz-cf-id", + "SpcreIC5nJTLSuTT9xS0OR_jPo97lYE0xQ-cVEphbFgCCyYAdtIE1g==" + ], + ["cache-control", "private, max-age=0"], + ["expires", "Sat, 13 Jan 2024 15:11:26 GMT"], + ["date", "Sat, 13 Jan 2024 15:11:26 GMT"], + ["connection", "close"], + [ + "set-cookie", + "route=05d9245d324128421fd9615b40b7917b; expires=Mon, 15-Jan-24 15:11:26 GMT; max-age=172800; path=/" + ], + ["strict-transport-security", "max-age=86400"] + ], + "content": "{\"code\":401,\"reason\":\"Unauthorized\",\"message\":\"Login failure\",\"detail\":{\"failureUrl\":\"error://passworderror\"}}" + } + } +] diff --git a/tests/integration_tests/data/authenticate_invalid_username.json b/tests/integration_tests/data/authenticate_invalid_username.json new file mode 100644 index 00000000..a61e7f43 --- /dev/null +++ b/tests/integration_tests/data/authenticate_invalid_username.json @@ -0,0 +1,187 @@ +[ + { + "request": { + "method": "POST", + "url": "https://b2c-login.toyota-europe.com/json/realms/root/realms/tme/authenticate?authIndexType=service&authIndexValue=oneapp", + "headers": [ + ["host", "b2c-login.toyota-europe.com"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["user-agent", "python-httpx/0.26.0"], + ["content-length", "2"], + ["content-type", "application/json"] + ], + "body": "{}" + }, + "response": { + "status": 200, + "headers": [ + ["content-type", "application/json"], + ["content-length", "2333"], + ["access-control-allow-credentials", "true"], + [ + "access-control-allow-headers", + "X-Username,x-username,Cookie,Host,Authorization,Access-Control-Allow-Headers,Content-Type,X-OpenIDM-OAuth-Login,X-OpenIDM-DataStoreToken,X-Requested-With,Cache-Control,Accept-Language,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,X-OpenAM-Username,X-OpenAM-Password,iPlanetDirectoryPro,Accept-API-Version" + ], + ["access-control-allow-methods", "GET, POST, OPTIONS, DELETE, PUT"], + [ + "access-control-allow-origin", + "https://b2c-login.toyota-europe.com,https://b2c-idm.toyota-europe.com,http://b2c-login.toyota-europe.com,http://b2c-idm.toyota-europe.com,https://tas600-huapps-acc-c.toyota-europe.com" + ], + [ + "access-control-expose-headers", + "x-username,X-Username,Access-Control-Allow-Headers,Access-Control-Allow-Origin,Access-Control-Allow-Credentials,Set-Cookie" + ], + ["content-api-version", "resource=2.1"], + ["pragma", "no-cache"], + ["server", "nginx/1.21.6"], + ["x-content-type-options", "nosniff"], + ["x-frame-options", "SAMEORIGIN"], + ["x-amz-cf-pop", "LHR61-P1"], + [ + "x-amz-cf-id", + "xIN4ORjQX9QaWG9H26O_gUcRMbzfc74cLFuTYlNovjmhUjztq_Mh0A==" + ], + ["cache-control", "private, max-age=0"], + ["expires", "Sat, 13 Jan 2024 14:50:00 GMT"], + ["date", "Sat, 13 Jan 2024 14:50:00 GMT"], + ["connection", "keep-alive"], + [ + "set-cookie", + "route=1114d122a4f3e7d58cf0ae5ce740dc57; expires=Mon, 15-Jan-24 14:50:00 GMT; max-age=172800; path=/" + ], + [ + "set-cookie", + "amlbcookie=01; Path=/; Secure; HttpOnly; SameSite=none" + ], + ["strict-transport-security", "max-age=86400"] + ], + "content": "{\"authId\":\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\",\"callbacks\":[{\"type\":\"NameCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"Market Locale\"}],\"input\":[{\"name\":\"IDToken1\",\"value\":\"\"}],\"_id\":0},{\"type\":\"NameCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"Internationalization\"}],\"input\":[{\"name\":\"IDToken2\",\"value\":\"\"}],\"_id\":1},{\"type\":\"NameCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"UI Locales\"}],\"input\":[{\"name\":\"IDToken3\",\"value\":\"\"}],\"_id\":2}]}" + } + }, + { + "request": { + "method": "POST", + "url": "https://b2c-login.toyota-europe.com/json/realms/root/realms/tme/authenticate?authIndexType=service&authIndexValue=oneapp", + "headers": [ + ["host", "b2c-login.toyota-europe.com"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["user-agent", "python-httpx/0.26.0"], + ["cookie", "amlbcookie=01; route=1114d122a4f3e7d58cf0ae5ce740dc57"], + ["content-length", "2377"], + ["content-type", "application/json"] + ], + "body": "{\"authId\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\", \"callbacks\": [{\"type\": \"NameCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"Market Locale\"}], \"input\": [{\"name\": \"IDToken1\", \"value\": \"\"}], \"_id\": 0}, {\"type\": \"NameCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"Internationalization\"}], \"input\": [{\"name\": \"IDToken2\", \"value\": \"\"}], \"_id\": 1}, {\"type\": \"NameCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"UI Locales\"}], \"input\": [{\"name\": \"IDToken3\", \"value\": \"\"}], \"_id\": 2}]}" + }, + "response": { + "status": 200, + "headers": [ + ["content-type", "application/json"], + ["content-length", "2597"], + ["access-control-allow-credentials", "true"], + [ + "access-control-allow-headers", + "X-Username,x-username,Cookie,Host,Authorization,Access-Control-Allow-Headers,Content-Type,X-OpenIDM-OAuth-Login,X-OpenIDM-DataStoreToken,X-Requested-With,Cache-Control,Accept-Language,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,X-OpenAM-Username,X-OpenAM-Password,iPlanetDirectoryPro,Accept-API-Version" + ], + ["access-control-allow-methods", "GET, POST, OPTIONS, DELETE, PUT"], + [ + "access-control-allow-origin", + "https://b2c-login.toyota-europe.com,https://b2c-idm.toyota-europe.com,http://b2c-login.toyota-europe.com,http://b2c-idm.toyota-europe.com,https://tas600-huapps-acc-c.toyota-europe.com" + ], + [ + "access-control-expose-headers", + "x-username,X-Username,Access-Control-Allow-Headers,Access-Control-Allow-Origin,Access-Control-Allow-Credentials,Set-Cookie" + ], + ["content-api-version", "resource=2.1"], + ["pragma", "no-cache"], + ["server", "nginx/1.21.6"], + ["x-content-type-options", "nosniff"], + ["x-frame-options", "SAMEORIGIN"], + ["x-amz-cf-pop", "LHR61-P1"], + [ + "x-amz-cf-id", + "bNNgqVK6oBfyKQ3vdnjgUnhnigI126vATe3dsiVfpTINUp4Ztjb2Ww==" + ], + ["cache-control", "private, max-age=0"], + ["expires", "Sat, 13 Jan 2024 14:50:00 GMT"], + ["date", "Sat, 13 Jan 2024 14:50:00 GMT"], + ["connection", "keep-alive"], + [ + "set-cookie", + "route=1114d122a4f3e7d58cf0ae5ce740dc57; expires=Mon, 15-Jan-24 14:50:00 GMT; max-age=172800; path=/" + ], + [ + "set-cookie", + "amlbcookie=01; Path=/; Secure; HttpOnly; SameSite=none" + ], + ["strict-transport-security", "max-age=86400"] + ], + "content": "{\"authId\":\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\",\"callbacks\":[{\"type\":\"NameCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"User Name\"}],\"input\":[{\"name\":\"IDToken1\",\"value\":\"\"}],\"_id\":3},{\"type\":\"ChoiceCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"Prompt\"},{\"name\":\"choices\",\"value\":[\"Local\",\"Google\",\"Facebook\",\"Apple\"]},{\"name\":\"defaultChoice\",\"value\":0}],\"input\":[{\"name\":\"IDToken2\",\"value\":0}],\"_id\":4}]}" + } + }, + { + "request": { + "method": "POST", + "url": "https://b2c-login.toyota-europe.com/json/realms/root/realms/tme/authenticate?authIndexType=service&authIndexValue=oneapp", + "headers": [ + ["host", "b2c-login.toyota-europe.com"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["user-agent", "python-httpx/0.26.0"], + ["cookie", "amlbcookie=01; route=1114d122a4f3e7d58cf0ae5ce740dc57"], + ["content-length", "2661"], + ["content-type", "application/json"] + ], + "content": "{\"authId\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdXRoSW5kZXhWYWx1ZSI6Im9uZWFwcCIsIm90ayI6ImZ0cGlna2wzZThrM3VmdXRndW40MGVzaDVxIiwiYXV0aEluZGV4VHlwZSI6InNlcnZpY2UiLCJyZWFsbSI6Ii90bWUiLCJzZXNzaW9uSWQiOiIqQUFKVFNRQUNNRElBQkhSNWNHVUFDRXBYVkY5QlZWUklBQUpUTVFBQ01ERS4qZXlKMGVYQWlPaUpLVjFRaUxDSmpkSGtpT2lKS1YxUWlMQ0poYkdjaU9pSklVekkxTmlKOS5aWGxLTUdWWVFXbFBhVXBMVmpGUmFVeERTbXhpYlUxcFQybEtRazFVU1RSUk1FcEVURlZvVkUxcVZUSkphWGRwV1ZkNGJrbHFiMmxhUjJ4NVNXNHdMaTVoVGtKblFubHJkVzFaUkhST2IwUlBZVzAyZUc5QkxsUkxRMmRCVG5odVJqVnNRVFF5ZW1kaE16RmpiVEl6ZEhKRlMxWlZPVmg1Um5welJUUlJUM2gzTkVsVk5tSktSRzFIVld4RmRVbFJOVGh3TVVseVNtWndXVXB2UzBwUGVtbGhUVEIwU0RFd05rSXpjVzU1VW5sMFRsTkVNVGxDVG5jM1RrUlJUVXRSV0hoUVZVRllZV28wZGpJMWFHbHRYM0l3U2tSMU5IcFZPRFZHYzA4eFEzaHBjV3d6T1hsWFdrUm1iRzF6YzFKQ1kyb3pVMEZVU0VOMk9XUmlaSFIwWjFOclIyWk9MVUZJVlZGRFZGZEpPVTQ1ZWxJMWQwOXVjalJuTTNWcGFrNHpTVTE0VGtaZk1qSnBWVGt6WkRWWlZpMXdYM3B0VUZabU5XTklTRVp6VUZWamNuQm1jSE5rT1RVeGRHNXFWRlJFY0UxSVYwMTBSbUpqTWtsNVVXeExiMlIyVEVwdlIzRlJlbEUxVWxSS2JIUTJlVk5sTmxCRlJWRmlVSGwyTFROb1gyNTBaME5FZDB4cVJqTmFSVzU2UlVsd09VVm5ia0oxUldKVVRYSkNVMFJIVkhoVWNrWnhWbkZVTm1zNVNIWlRWMlEzVDA1SWRXZG1VV28zV2xWQ01GVmZMWEJ2WjA1WVlWUnROSEp0TjE5aGREQm9WRTkyVFMxQllsTlVWV00zVERGMVdsOVZja2RPWW1jeFdFWnJMVmg2VWpRMGFFdHpTbE5mV0ZScVdGVm5ZMDg1YlVkbFlXWlhNMFZCTURoNmR6RXlZVkJXWlVOV2JEZG5iak5TVkZwR00zaHlYMWhSUTIxVVpFcDNaM0J5ZW5wR05HbFdUVkJtVTBSbFExWnZXbXBvVUhWbFkwMUxkMHRZYmtsdFZXZzFlbXBJUTJNdE9WaFJaRnBmUm5CbFFtdHhOMWcyT1RONVJFbGtiRXg2VlhOdmRISlJVMUZIVm1abVgySlhiSGgzTjFSM2NFRjVkREZCZFVvMGFrUTFSSE5xU25NNFEzRTRRME5NUkZjMFREUkVkR0UyYW5kNVFVVmpMV1p4UmpWUExUUnRUVU16UnpReUxVSTJObmRSVUd0eE5HVjZUSHBrUkZScmRrMWZSeTA0WTNKd1UwYzJaRGRqU2pSTU0xQjJkMlJIT1d0a2QxVmxTMmxvYzNremNtcEZZalYwWmxkc1lUUk1UaTA0U0d4elRreHRaMmxWTWxocFVYZHpZUzFUWTJSU09WVTFUazFKZVRaeFNIbDZNRUUxYWs1RmFYVjBkRWhCU1RKME0zZHRPR05JYUU1c09FNDRWSEYzTkVwRVRVOUtjV1ZWVWtKZlQzUm5UV1pxVVdsQkxUUXRTR2haVTJKb2MxbEVaSEF3TVhKa1FrRlZSRlJoT1hGeVlWWk1lbmxUUmpGclpGZE9jRWRSYUhwSVYwMTNYM1o2WHkxRVUyTTVhVEU1TVVoU04yUlBUVEkyVldoUU1GVTVVRTFrTjBFd1NHODBTMlZyVldGU1UzUTFSVXBrVkdWU2JtSnlVR1F5WW1NemMzWnJMbGhuWkVwaGRWQjBTRTA1YmtZd1VqWnVTazVxVm1jLldnWkdGWmd3bXNNZFEtMDVsSlhJMC1LVW9sZnhjZnNvVk5vakt6b1ptZVEiLCJleHAiOjE3MDUxNTkyMDAsImlhdCI6MTcwNTE1NzQwMH0.gpWnTRI7g8sO-kzppieCiPkK6W_cbHhmrsKGvSHnwb0\", \"callbacks\": [{\"type\": \"NameCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"User Name\"}], \"input\": [{\"name\": \"IDToken1\", \"value\": \"user@email.info\"}], \"_id\": 3}, {\"type\": \"ChoiceCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"Prompt\"}, {\"name\": \"choices\", \"value\": [\"Local\", \"Google\", \"Facebook\", \"Apple\"]}, {\"name\": \"defaultChoice\", \"value\": 0}], \"input\": [{\"name\": \"IDToken2\", \"value\": 0}], \"_id\": 4}]}" + }, + "response": { + "status": 200, + "headers": [ + ["content-type", "application/json"], + ["content-length", "2640"], + ["access-control-allow-credentials", "true"], + [ + "access-control-allow-headers", + "X-Username,x-username,Cookie,Host,Authorization,Access-Control-Allow-Headers,Content-Type,X-OpenIDM-OAuth-Login,X-OpenIDM-DataStoreToken,X-Requested-With,Cache-Control,Accept-Language,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,X-OpenAM-Username,X-OpenAM-Password,iPlanetDirectoryPro,Accept-API-Version" + ], + ["access-control-allow-methods", "GET, POST, OPTIONS, DELETE, PUT"], + [ + "access-control-allow-origin", + "https://b2c-login.toyota-europe.com,https://b2c-idm.toyota-europe.com,http://b2c-login.toyota-europe.com,http://b2c-idm.toyota-europe.com,https://tas600-huapps-acc-c.toyota-europe.com" + ], + [ + "access-control-expose-headers", + "x-username,X-Username,Access-Control-Allow-Headers,Access-Control-Allow-Origin,Access-Control-Allow-Credentials,Set-Cookie" + ], + ["content-api-version", "resource=2.1"], + ["pragma", "no-cache"], + ["server", "nginx/1.21.6"], + ["x-content-type-options", "nosniff"], + ["x-frame-options", "SAMEORIGIN"], + ["x-amz-cf-pop", "LHR61-P1"], + [ + "x-amz-cf-id", + "T2EC5kQIbAaJIajxOeq6peRSlyaxANW4EiuWOpOSnp1KhHXAABAPuA==" + ], + ["cache-control", "private, max-age=0"], + ["expires", "Sat, 13 Jan 2024 14:50:01 GMT"], + ["date", "Sat, 13 Jan 2024 14:50:01 GMT"], + ["connection", "keep-alive"], + [ + "set-cookie", + "route=1114d122a4f3e7d58cf0ae5ce740dc57; expires=Mon, 15-Jan-24 14:50:01 GMT; max-age=172800; path=/" + ], + [ + "set-cookie", + "amlbcookie=01; Path=/; Secure; HttpOnly; SameSite=none" + ], + ["strict-transport-security", "max-age=86400"] + ], + "content": "{\"authId\":\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.\",\"callbacks\":[{\"type\":\"TextOutputCallback\",\"output\":[{\"name\":\"message\",\"value\":\"User Not Found\"},{\"name\":\"messageType\",\"value\":\"2\"}]}]}" + } + } +] diff --git a/tests/integration_tests/data/authenticate_refresh_token.json b/tests/integration_tests/data/authenticate_refresh_token.json new file mode 100644 index 00000000..6cb24cb5 --- /dev/null +++ b/tests/integration_tests/data/authenticate_refresh_token.json @@ -0,0 +1,59 @@ +[ + { + "request": { + "method": "POST", + "url": "https://b2c-login.toyota-europe.com/oauth2/realms/root/realms/tme/access_token", + "headers": [ + ["host", "b2c-login.toyota-europe.com"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["user-agent", "python-httpx/0.26.0"], + ["authorization", "basic b25lYXBwOm9uZWFwcA=="], + ["content-length", "1500"], + ["content-type", "application/x-www-form-urlencoded"] + ], + "content": "client_id=oneapp&redirect_uri=com.toyota.oneapp%3A%2Foauth2Callback&grant_type=refresh_token&code_verifier=plain&refresh_token=eyJ0eXAiOiJKV1QiLCJraWQiOiJZeVZ2SEU5d0xKNDBWVEpyc3pBNDJ6eTNyWjg9IiwiYWxnIjoiUlMyNTYifQ" + }, + "response": { + "status": 200, + "headers": [ + ["content-type", "application/json;charset=UTF-8"], + ["content-length", "4271"], + ["access-control-allow-credentials", "true"], + [ + "access-control-allow-headers", + "X-Username,x-username,Cookie,Host,Authorization,Access-Control-Allow-Headers,Content-Type,X-OpenIDM-OAuth-Login,X-OpenIDM-DataStoreToken,X-Requested-With,Cache-Control,Accept-Language,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,X-OpenAM-Username,X-OpenAM-Password,iPlanetDirectoryPro,Accept-API-Version" + ], + ["access-control-allow-methods", "GET, POST, OPTIONS, DELETE, PUT"], + [ + "access-control-allow-origin", + "https://b2c-login.toyota-europe.com,https://b2c-idm.toyota-europe.com,http://b2c-login.toyota-europe.com,http://b2c-idm.toyota-europe.com,https://tas600-huapps-acc-c.toyota-europe.com" + ], + [ + "access-control-expose-headers", + "x-username,X-Username,Access-Control-Allow-Headers,Access-Control-Allow-Origin,Access-Control-Allow-Credentials,Set-Cookie" + ], + ["pragma", "no-cache"], + ["server", "nginx/1.21.6"], + ["x-content-type-options", "nosniff"], + ["x-frame-options", "SAMEORIGIN"], + ["x-amz-cf-pop", "LHR61-P1"], + [ + "x-amz-cf-id", + "M6twOxfIlz6RC1mVOg6VSqtcWAIstJPnXQreE7f3umGRVVIgIoQjNA==" + ], + ["cache-control", "no-store"], + ["expires", "Sat, 13 Jan 2024 15:34:52 GMT"], + ["date", "Sat, 13 Jan 2024 15:34:52 GMT"], + ["connection", "keep-alive"], + [ + "set-cookie", + "route=00b47624ed45b7f29ea4e40234059589; expires=Mon, 15-Jan-24 15:34:52 GMT; max-age=172800; path=/" + ], + ["strict-transport-security", "max-age=86400"] + ], + "content": "{\"access_token\":\"eyJ0eXAiOiJKV1QiLCJraWQiOiJZeVZ2SEU5d0xKNDBWVEpyc3pBNDJ6eTNyWjg9IiwiYWxnIjoiUlMyNTYifQ\",\"refresh_token\":\"eyJ0eXAiOiJKV1QiLCJraWQiOiJZeVZ2SEU5d0xKNDBWVEpyc3pBNDJ6eTNyWjg9IiwiYWxnIjoiUlMyNTYifQ\",\"scope\":\"openid profile write\",\"id_token\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSm9obiBEb2UiLCJ1dWlkIjoiMTIzNDU2Nzg5In0.WRnmzTP3vOK0W_Xh2sw4OpxxqDksjeeBgx3_4y4UeZU\",\"token_type\":\"Bearer\",\"expires_in\":3599}" + } + } +] diff --git a/tests/integration_tests/data/authenticate_working.json b/tests/integration_tests/data/authenticate_working.json new file mode 100644 index 00000000..2be93868 --- /dev/null +++ b/tests/integration_tests/data/authenticate_working.json @@ -0,0 +1,376 @@ +[ + { + "request": { + "method": "POST", + "url": "https://b2c-login.toyota-europe.com/json/realms/root/realms/tme/authenticate?authIndexType=service&authIndexValue=oneapp", + "headers": [ + ["host", "b2c-login.toyota-europe.com"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["user-agent", "python-httpx/0.26.0"], + ["content-length", "2"], + ["content-type", "application/json"] + ], + "body": "{}" + }, + "response": { + "status": 200, + "headers": [ + ["content-type", "application/json"], + ["content-length", "2333"], + ["access-control-allow-credentials", "true"], + [ + "access-control-allow-headers", + "X-Username,x-username,Cookie,Host,Authorization,Access-Control-Allow-Headers,Content-Type,X-OpenIDM-OAuth-Login,X-OpenIDM-DataStoreToken,X-Requested-With,Cache-Control,Accept-Language,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,X-OpenAM-Username,X-OpenAM-Password,iPlanetDirectoryPro,Accept-API-Version" + ], + ["access-control-allow-methods", "GET, POST, OPTIONS, DELETE, PUT"], + [ + "access-control-allow-origin", + "https://b2c-login.toyota-europe.com,https://b2c-idm.toyota-europe.com,http://b2c-login.toyota-europe.com,http://b2c-idm.toyota-europe.com,https://tas600-huapps-acc-c.toyota-europe.com" + ], + [ + "access-control-expose-headers", + "x-username,X-Username,Access-Control-Allow-Headers,Access-Control-Allow-Origin,Access-Control-Allow-Credentials,Set-Cookie" + ], + ["content-api-version", "resource=2.1"], + ["pragma", "no-cache"], + ["server", "nginx/1.21.6"], + ["x-content-type-options", "nosniff"], + ["x-frame-options", "SAMEORIGIN"], + ["x-amz-cf-pop", "LHR5-P3"], + [ + "x-amz-cf-id", + "igrzeqATaK7NsWbuECKn4kbOwFePS5o1x7i4pDrvkMZix5XSfn_eyA==" + ], + ["cache-control", "private, max-age=0"], + ["expires", "Sun, 31 Dec 2023 14:42:04 GMT"], + ["date", "Sun, 31 Dec 2023 14:42:04 GMT"], + ["connection", "keep-alive"], + [ + "set-cookie", + "route=96df7747ca52fd82aa45abf2bfb78caf; expires=Tue, 02-Jan-24 14:42:04 GMT; max-age=172800; path=/" + ], + [ + "set-cookie", + "amlbcookie=01; Path=/; Secure; HttpOnly; SameSite=none" + ], + ["strict-transport-security", "max-age=86400"] + ], + "content": "{\"authId\":\"REMOVED\",\"callbacks\":[{\"type\":\"NameCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"Market Locale\"}],\"input\":[{\"name\":\"IDToken1\",\"value\":\"\"}],\"_id\":0},{\"type\":\"NameCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"Internationalization\"}],\"input\":[{\"name\":\"IDToken2\",\"value\":\"\"}],\"_id\":1},{\"type\":\"NameCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"UI Locales\"}],\"input\":[{\"name\":\"IDToken3\",\"value\":\"\"}],\"_id\":2}]}" + } + }, + { + "request": { + "method": "POST", + "url": "https://b2c-login.toyota-europe.com/json/realms/root/realms/tme/authenticate?authIndexType=service&authIndexValue=oneapp", + "headers": [ + ["host", "b2c-login.toyota-europe.com"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["user-agent", "python-httpx/0.26.0"], + ["cookie", "amlbcookie=01; route=96df7747ca52fd82aa45abf2bfb78caf"], + ["content-length", "2377"], + ["content-type", "application/json"] + ], + "body": "{\"authId\": \"REMOVED\", \"callbacks\": [{\"type\": \"NameCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"Market Locale\"}], \"input\": [{\"name\": \"IDToken1\", \"value\": \"\"}], \"_id\": 0}, {\"type\": \"NameCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"Internationalization\"}], \"input\": [{\"name\": \"IDToken2\", \"value\": \"\"}], \"_id\": 1}, {\"type\": \"NameCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"UI Locales\"}], \"input\": [{\"name\": \"IDToken3\", \"value\": \"\"}], \"_id\": 2}]}" + }, + "response": { + "status": 200, + "headers": [ + ["content-type", "application/json"], + ["content-length", "2597"], + ["access-control-allow-credentials", "true"], + [ + "access-control-allow-headers", + "X-Username,x-username,Cookie,Host,Authorization,Access-Control-Allow-Headers,Content-Type,X-OpenIDM-OAuth-Login,X-OpenIDM-DataStoreToken,X-Requested-With,Cache-Control,Accept-Language,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,X-OpenAM-Username,X-OpenAM-Password,iPlanetDirectoryPro,Accept-API-Version" + ], + ["access-control-allow-methods", "GET, POST, OPTIONS, DELETE, PUT"], + [ + "access-control-allow-origin", + "https://b2c-login.toyota-europe.com,https://b2c-idm.toyota-europe.com,http://b2c-login.toyota-europe.com,http://b2c-idm.toyota-europe.com,https://tas600-huapps-acc-c.toyota-europe.com" + ], + [ + "access-control-expose-headers", + "x-username,X-Username,Access-Control-Allow-Headers,Access-Control-Allow-Origin,Access-Control-Allow-Credentials,Set-Cookie" + ], + ["content-api-version", "resource=2.1"], + ["pragma", "no-cache"], + ["server", "nginx/1.21.6"], + ["x-content-type-options", "nosniff"], + ["x-frame-options", "SAMEORIGIN"], + ["x-amz-cf-pop", "LHR5-P3"], + [ + "x-amz-cf-id", + "EMV2goOZpW2iimCwHwC_BG84pcZlk9tl0oe2Tk2tQmq9Ro4d5yT9fA==" + ], + ["cache-control", "private, max-age=0"], + ["expires", "Sun, 31 Dec 2023 14:42:04 GMT"], + ["date", "Sun, 31 Dec 2023 14:42:04 GMT"], + ["connection", "keep-alive"], + [ + "set-cookie", + "route=96df7747ca52fd82aa45abf2bfb78caf; expires=Tue, 02-Jan-24 14:42:04 GMT; max-age=172800; path=/" + ], + [ + "set-cookie", + "amlbcookie=01; Path=/; Secure; HttpOnly; SameSite=none" + ], + ["strict-transport-security", "max-age=86400"] + ], + "content": "{\"authId\":\"REMOVED\",\"callbacks\":[{\"type\":\"NameCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"User Name\"}],\"input\":[{\"name\":\"IDToken1\",\"value\":\"\"}],\"_id\":3},{\"type\":\"ChoiceCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"Prompt\"},{\"name\":\"choices\",\"value\":[\"Local\",\"Google\",\"Facebook\",\"Apple\"]},{\"name\":\"defaultChoice\",\"value\":0}],\"input\":[{\"name\":\"IDToken2\",\"value\":0}],\"_id\":4}]}" + } + }, + { + "request": { + "method": "POST", + "url": "https://b2c-login.toyota-europe.com/json/realms/root/realms/tme/authenticate?authIndexType=service&authIndexValue=oneapp", + "headers": [ + ["host", "b2c-login.toyota-europe.com"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["user-agent", "python-httpx/0.26.0"], + ["cookie", "amlbcookie=01; route=96df7747ca52fd82aa45abf2bfb78caf"], + ["content-length", "2663"], + ["content-type", "application/json"] + ], + "body": "{\"authId\": \"REMOVED\", \"callbacks\": [{\"type\": \"NameCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"User Name\"}], \"input\": [{\"name\": \"IDToken1\", \"value\": \"user@email.co.uk\"}], \"_id\": 3}, {\"type\": \"ChoiceCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"Prompt\"}, {\"name\": \"choices\", \"value\": [\"Local\", \"Google\", \"Facebook\", \"Apple\"]}, {\"name\": \"defaultChoice\", \"value\": 0}], \"input\": [{\"name\": \"IDToken2\", \"value\": 0}], \"_id\": 4}]}" + }, + "response": { + "status": 200, + "headers": [ + ["content-type", "application/json"], + ["content-length", "3383"], + ["access-control-allow-credentials", "true"], + [ + "access-control-allow-headers", + "X-Username,x-username,Cookie,Host,Authorization,Access-Control-Allow-Headers,Content-Type,X-OpenIDM-OAuth-Login,X-OpenIDM-DataStoreToken,X-Requested-With,Cache-Control,Accept-Language,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,X-OpenAM-Username,X-OpenAM-Password,iPlanetDirectoryPro,Accept-API-Version" + ], + ["access-control-allow-methods", "GET, POST, OPTIONS, DELETE, PUT"], + [ + "access-control-allow-origin", + "https://b2c-login.toyota-europe.com,https://b2c-idm.toyota-europe.com,http://b2c-login.toyota-europe.com,http://b2c-idm.toyota-europe.com,https://tas600-huapps-acc-c.toyota-europe.com" + ], + [ + "access-control-expose-headers", + "x-username,X-Username,Access-Control-Allow-Headers,Access-Control-Allow-Origin,Access-Control-Allow-Credentials,Set-Cookie" + ], + ["content-api-version", "resource=2.1"], + ["pragma", "no-cache"], + ["server", "nginx/1.21.6"], + ["x-content-type-options", "nosniff"], + ["x-frame-options", "SAMEORIGIN"], + ["x-amz-cf-pop", "LHR5-P3"], + [ + "x-amz-cf-id", + "osCUwU5eMmzZEuXyxACrrhhxX1vNqCYOqh3AA8Gg3YfPEUgS5VLjUQ==" + ], + ["cache-control", "private, max-age=0"], + ["expires", "Sun, 31 Dec 2023 14:42:04 GMT"], + ["date", "Sun, 31 Dec 2023 14:42:04 GMT"], + ["connection", "keep-alive"], + [ + "set-cookie", + "route=96df7747ca52fd82aa45abf2bfb78caf; expires=Tue, 02-Jan-24 14:42:04 GMT; max-age=172800; path=/" + ], + [ + "set-cookie", + "amlbcookie=01; Path=/; Secure; HttpOnly; SameSite=none" + ], + ["strict-transport-security", "max-age=86400"] + ], + "content": "{\"authId\":\"REMOVED\",\"callbacks\":[{\"type\":\"PasswordCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"Password\"}],\"input\":[{\"name\":\"IDToken1\",\"value\":\"\"}],\"_id\":5},{\"type\":\"ChoiceCallback\",\"output\":[{\"name\":\"prompt\",\"value\":\"Prompt\"},{\"name\":\"choices\",\"value\":[\"continue\",\"resetpass\"]},{\"name\":\"defaultChoice\",\"value\":0}],\"input\":[{\"name\":\"IDToken2\",\"value\":0}],\"_id\":6}]}" + } + }, + { + "request": { + "method": "POST", + "url": "https://b2c-login.toyota-europe.com/json/realms/root/realms/tme/authenticate?authIndexType=service&authIndexValue=oneapp", + "headers": [ + ["host", "b2c-login.toyota-europe.com"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["user-agent", "python-httpx/0.26.0"], + ["cookie", "amlbcookie=01; route=96df7747ca52fd82aa45abf2bfb78caf"], + ["content-length", "3432"], + ["content-type", "application/json"] + ], + "body": "{\"authId\": \"REMOVED\", \"callbacks\": [{\"type\": \"PasswordCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"Password\"}], \"input\": [{\"name\": \"IDToken1\", \"value\": \"password\"}], \"_id\": 5}, {\"type\": \"ChoiceCallback\", \"output\": [{\"name\": \"prompt\", \"value\": \"Prompt\"}, {\"name\": \"choices\", \"value\": [\"continue\", \"resetpass\"]}, {\"name\": \"defaultChoice\", \"value\": 0}], \"input\": [{\"name\": \"IDToken2\", \"value\": 0}], \"_id\": 6}]}" + }, + "response": { + "status": 200, + "headers": [ + ["content-type", "application/json"], + ["content-length", "167"], + ["access-control-allow-credentials", "true"], + [ + "access-control-allow-headers", + "X-Username,x-username,Cookie,Host,Authorization,Access-Control-Allow-Headers,Content-Type,X-OpenIDM-OAuth-Login,X-OpenIDM-DataStoreToken,X-Requested-With,Cache-Control,Accept-Language,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,X-OpenAM-Username,X-OpenAM-Password,iPlanetDirectoryPro,Accept-API-Version" + ], + ["access-control-allow-methods", "GET, POST, OPTIONS, DELETE, PUT"], + [ + "access-control-allow-origin", + "https://b2c-login.toyota-europe.com,https://b2c-idm.toyota-europe.com,http://b2c-login.toyota-europe.com,http://b2c-idm.toyota-europe.com,https://tas600-huapps-acc-c.toyota-europe.com" + ], + [ + "access-control-expose-headers", + "x-username,X-Username,Access-Control-Allow-Headers,Access-Control-Allow-Origin,Access-Control-Allow-Credentials,Set-Cookie" + ], + ["content-api-version", "resource=2.1"], + ["pragma", "no-cache"], + ["server", "nginx/1.21.6"], + ["x-content-type-options", "nosniff"], + ["x-frame-options", "SAMEORIGIN"], + ["x-amz-cf-pop", "LHR5-P3"], + [ + "x-amz-cf-id", + "vJdFt4jMfY52b97UOk7T53kqUfgu1KfS3hvxMW0_disk5lz9gVGKrQ==" + ], + ["cache-control", "private, max-age=0"], + ["expires", "Sun, 31 Dec 2023 14:42:04 GMT"], + ["date", "Sun, 31 Dec 2023 14:42:04 GMT"], + ["connection", "keep-alive"], + [ + "set-cookie", + "route=96df7747ca52fd82aa45abf2bfb78caf; expires=Tue, 02-Jan-24 14:42:04 GMT; max-age=172800; path=/" + ], + [ + "set-cookie", + "iPlanetDirectoryPro=REMOVED; Path=/; Secure; HttpOnly; SameSite=none" + ], + [ + "set-cookie", + "amlbcookie=01; Path=/; Secure; HttpOnly; SameSite=none" + ], + ["strict-transport-security", "max-age=86400"] + ], + "content": "{\"tokenId\":\"REMOVED\",\"successUrl\":\"/console\",\"realm\":\"/tme\"}" + } + }, + { + "request": { + "method": "GET", + "url": "https://b2c-login.toyota-europe.com/oauth2/realms/root/realms/tme/authorize?client_id=oneapp&scope=openid+profile+write&response_type=code&redirect_uri=com.toyota.oneapp:/oauth2Callback&code_challenge=plain&code_challenge_method=plain", + "headers": [ + ["host", "b2c-login.toyota-europe.com"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["user-agent", "python-httpx/0.26.0"], + ["cookie", "iPlanetDirectoryPro=REMOVED"] + ], + "body": "" + }, + "response": { + "status": 302, + "headers": [ + ["content-length", "0"], + ["access-control-allow-credentials", "true"], + [ + "access-control-allow-headers", + "X-Username,x-username,Cookie,Host,Authorization,Access-Control-Allow-Headers,Content-Type,X-OpenIDM-OAuth-Login,X-OpenIDM-DataStoreToken,X-Requested-With,Cache-Control,Accept-Language,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,X-OpenAM-Username,X-OpenAM-Password,iPlanetDirectoryPro,Accept-API-Version" + ], + ["access-control-allow-methods", "GET, POST, OPTIONS, DELETE, PUT"], + [ + "access-control-allow-origin", + "https://b2c-login.toyota-europe.com,https://b2c-idm.toyota-europe.com,http://b2c-login.toyota-europe.com,http://b2c-idm.toyota-europe.com,https://tas600-huapps-acc-c.toyota-europe.com" + ], + [ + "access-control-expose-headers", + "x-username,X-Username,Access-Control-Allow-Headers,Access-Control-Allow-Origin,Access-Control-Allow-Credentials,Set-Cookie" + ], + [ + "location", + "com.toyota.oneapp:/oauth2Callback?code=F3W4WgKTYN7W-yZKdSMbYkTO0R0&iss=https%3A%2F%2Fb2c-login.toyota-europe.com%2Foauth2%2Frealms%2Froot%2Frealms%2Ftme&client_id=oneapp" + ], + ["pragma", "no-cache"], + ["server", "nginx/1.21.6"], + ["x-content-type-options", "nosniff"], + ["x-frame-options", "SAMEORIGIN"], + ["x-amz-cf-pop", "LHR5-P3"], + [ + "x-amz-cf-id", + "H6lfG3A9qKpe2DCGCrl44mP6owr9oMFh94kYoOxHo3kGKFGRh6hJlw==" + ], + ["cache-control", "no-store"], + ["expires", "Sun, 31 Dec 2023 14:42:04 GMT"], + ["date", "Sun, 31 Dec 2023 14:42:04 GMT"], + ["connection", "keep-alive"], + [ + "set-cookie", + "route=e8e8b55de08efd3c4b34265c0069d319; expires=Tue, 02-Jan-24 14:42:04 GMT; max-age=172800; path=/" + ], + [ + "set-cookie", + "OAUTH_REQUEST_ATTRIBUTES=DELETED; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=/; Secure; HttpOnly; SameSite=none" + ], + ["strict-transport-security", "max-age=86400"] + ], + "content": "" + } + }, + { + "request": { + "method": "POST", + "url": "https://b2c-login.toyota-europe.com/oauth2/realms/root/realms/tme/access_token", + "headers": [ + ["host", "b2c-login.toyota-europe.com"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["user-agent", "python-httpx/0.26.0"], + ["authorization", "basic b25lYXBwOm9uZWFwcA=="], + [ + "cookie", + "amlbcookie=01; iPlanetDirectoryPro=REMOVED; route=e8e8b55de08efd3c4b34265c0069d319" + ], + ["content-length", "150"], + ["content-type", "application/x-www-form-urlencoded"] + ], + "body": "client_id=oneapp&code=F3W4WgKTYN7W-yZKdSMbYkTO0R0&redirect_uri=com.toyota.oneapp%3A%2Foauth2Callback&grant_type=authorization_code&code_verifier=plain" + }, + "response": { + "status": 200, + "headers": [ + ["content-type", "application/json;charset=UTF-8"], + ["content-length", "4330"], + ["access-control-allow-credentials", "true"], + [ + "access-control-allow-headers", + "X-Username,x-username,Cookie,Host,Authorization,Access-Control-Allow-Headers,Content-Type,X-OpenIDM-OAuth-Login,X-OpenIDM-DataStoreToken,X-Requested-With,Cache-Control,Accept-Language,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,X-OpenAM-Username,X-OpenAM-Password,iPlanetDirectoryPro,Accept-API-Version" + ], + ["access-control-allow-methods", "GET, POST, OPTIONS, DELETE, PUT"], + [ + "access-control-allow-origin", + "https://b2c-login.toyota-europe.com,https://b2c-idm.toyota-europe.com,http://b2c-login.toyota-europe.com,http://b2c-idm.toyota-europe.com,https://tas600-huapps-acc-c.toyota-europe.com" + ], + [ + "access-control-expose-headers", + "x-username,X-Username,Access-Control-Allow-Headers,Access-Control-Allow-Origin,Access-Control-Allow-Credentials,Set-Cookie" + ], + ["pragma", "no-cache"], + ["server", "nginx/1.21.6"], + ["x-content-type-options", "nosniff"], + ["x-frame-options", "SAMEORIGIN"], + ["x-amz-cf-pop", "LHR5-P3"], + [ + "x-amz-cf-id", + "CHp4lcoobsfSMYEOtF1YADgajk3ob_ZCiL2AhFEMulwbp2-BOOfNrQ==" + ], + ["cache-control", "no-store"], + ["expires", "Sun, 31 Dec 2023 14:42:04 GMT"], + ["date", "Sun, 31 Dec 2023 14:42:04 GMT"], + ["connection", "keep-alive"], + [ + "set-cookie", + "route=e8e8b55de08efd3c4b34265c0069d319; expires=Tue, 02-Jan-24 14:42:04 GMT; max-age=172800; path=/" + ], + ["strict-transport-security", "max-age=86400"] + ], + "content": "{\"access_token\":\"REMOVED\",\"refresh_token\":\"REMOVED\",\"scope\":\"openid profile write\",\"id_token\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSm9obiBEb2UiLCJ1dWlkIjoiMTIzNDU2Nzg5In0.WRnmzTP3vOK0W_Xh2sw4OpxxqDksjeeBgx3_4y4UeZU\",\"token_type\":\"Bearer\",\"expires_in\":3599}" + } + } +] diff --git a/tests/integration_tests/data/cached_token.json b/tests/integration_tests/data/cached_token.json new file mode 100644 index 00000000..100694c1 --- /dev/null +++ b/tests/integration_tests/data/cached_token.json @@ -0,0 +1,7 @@ +{ + "access_token": "eyJ0eXAiOiJKV1QiLCJraWQiOiJZeVZ2SEU5d0xKNDBWVEpyc3pBNDJ6eTNyWjg9IiwiYWxnIjoiUlMyNTYifQ", + "refresh_token": "eyJ0eXAiOiJKV1QiLCJraWQiOiJZeVZ2SEU5d0xKNDBWVEpyc3pBNDJ6eTNyWjg9IiwiYWxnIjoiUlMyNTYifQ", + "uuid": "12345678-1234-1234-1234-123456789012", + "expiration": "2024-01-01 16:20:20.316881", + "username": "user@email.info" +} diff --git a/tests/integration_tests/data/get_static_data.json b/tests/integration_tests/data/get_static_data.json new file mode 100644 index 00000000..6e96c5b9 --- /dev/null +++ b/tests/integration_tests/data/get_static_data.json @@ -0,0 +1,912 @@ +[ + { + "request": { + "method": "GET", + "url": "https://ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io/v2/vehicle/guid", + "headers": [ + ["host", "ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["x-api-key", "tTZipv6liF74PwMfk9Ed68AQ0bISswwf3iHQdqcF"], + ["x-guid", "d95b0b58-3b3f-40e3-99ca-a3aa2a22a204"], + ["guid", "d95b0b58-3b3f-40e3-99ca-a3aa2a22a204"], + [ + "authorization", + "Bearer eyJ0eXAiOiJKV1QiLCJraWQiOiJZeVZ2SEU5d0xKNDBWVEpyc3pBNDJ6eTNyWjg9IiwiYWxnIjoiUlMyNTYifQ" + ], + ["x-channel", "ONEAPP"], + ["x-brand", "T"], + ["user-agent", "okhttp/4.10.0"] + ], + "content": "" + }, + "response": { + "status": 200, + "headers": [ + ["date", "Sat, 13 Jan 2024 16:30:26 GMT"], + ["content-type", "application/json"], + ["content-length", "9240"], + ["connection", "keep-alive"], + ["x-amzn-requestid", "3aab58b0-887a-4061-b916-67b5e5c956b5"], + ["access-control-allow-origin", "*"], + ["x-amz-apigw-id", "RfIZYG-FliAEL0w="], + [ + "x-amzn-trace-id", + "Root=1-65a2baa2-2195c0c85fa97d9523d98912;Sampled=0;lineage=aeb55e6e:0" + ] + ], + "content": { + "status": { + "messages": [ + { + "responseCode": "ONE-VL-10000", + "description": "Successfully retreived all vehicles", + "detailedDescription": "Successfully retreived all vehicles" + } + ] + }, + "payload": [ + { + "registrationNumber": null, + "vin": "12345678912345678", + "modelYear": "2020", + "modelName": "RAV4 Plug-in MY21", + "modelDescription": "RAV4 Plug-in MY21", + "modelCode": "RE", + "region": "EU", + "status": "ACTIVE", + "generation": "17CYPLUS", + "image": "https://dj3z27z47basa.cloudfront.net/17978304-7589-46b9-a630-64943bd91113", + "nickName": "RAV4", + "brand": "T", + "hwType": null, + "asiCode": "FB", + "subscriptionStatus": "SUBSCRIBED", + "primarySubscriber": true, + "remoteUser": true, + "evVehicle": true, + "remoteSubscriptionStatus": "ACTIVE", + "remoteUserGuid": "12345678-1234-1234-1234-123456789012", + "subscriberGuid": "12345678-1234-1234-1234-123456789012", + "remoteDisplay": "7", + "emergencyContact": null, + "remoteServiceCapabilities": { + "powerWindowCapable": false, + "ventilatorCapable": false, + "moonRoofCapable": false, + "steeringWheelHeaterCapable": false, + "allowHvacOverrideCapable": false, + "estartStopCapable": false, + "estartEnabled": false, + "hazardCapable": false, + "dlockUnlockCapable": false, + "estopEnabled": false, + "acsettingEnabled": false, + "guestDriverCapable": false, + "vehicleFinderCapable": false, + "headLightCapable": false, + "trunkCapable": false + }, + "nonCvtVehicle": false, + "remoteServicesExceptions": [], + "extendedCapabilities": { + "remoteEngineStartStop": false, + "remoteEConnectCapable": true, + "doorLockUnlockCapable": false, + "frontDriverDoorLockStatus": false, + "frontPassengerDoorLockStatus": false, + "rearDriverDoorLockStatus": false, + "rearPassengerDoorLockStatus": false, + "frontDriverDoorOpenStatus": false, + "frontPassengerDoorOpenStatus": false, + "rearDriverDoorOpenStatus": false, + "rearPassengerDoorOpenStatus": false, + "frontDriverDoorWindowStatus": false, + "frontPassengerDoorWindowStatus": false, + "rearDriverDoorWindowStatus": false, + "rearPassengerDoorWindowStatus": false, + "rearHatchRearWindow": true, + "moonroof": false, + "powerWindowsCapable": false, + "hazardCapable": false, + "hornCapable": false, + "lightsCapable": false, + "climateCapable": false, + "climateTemperatureControlFull": false, + "climateTemperatureControlLimited": false, + "frontDriverSeatHeater": false, + "frontPassengerSeatHeater": false, + "rearDriverSeatHeater": false, + "rearPassengerSeatHeater": false, + "frontDriverSeatVentilation": false, + "frontPassengerSeatVentilation": false, + "rearDriverSeatVentilation": false, + "rearPassengerSeatVentilation": false, + "steeringHeater": false, + "mirrorHeater": false, + "frontDefogger": true, + "rearDefogger": true, + "vehicleFinder": false, + "guestDriver": true, + "buzzerCapable": false, + "trunkLockUnlockCapable": false, + "evChargeStationsCapable": true, + "fcvStationsCapable": false, + "lastParkedCapable": true, + "acScheduling": true, + "chargeManagement": true, + "nextCharge": true, + "weeklyCharge": false, + "powerTailgateCapable": false, + "batteryStatus": false, + "evBattery": false, + "drivePulse": false, + "electricPulse": false, + "hydrogenPulse": false, + "hybridPulse": true, + "emergencyAssist": false, + "bumpCollisions": false, + "fuelLevelAvailable": true, + "fuelRangeAvailable": true, + "equippedWithAlarm": false, + "manualRearWindows": false, + "lightStatus": false, + "bonnetStatus": false, + "sunroof": false, + "smartKeyStatus": false, + "ecare": false, + "tryAndPlay": false, + "dashboardWarningLights": false, + "weHybridCapable": false, + "enhancedSecuritySystemCapable": false, + "vehicleStatus": false, + "stellantisVehicleStatusCapable": false, + "stellantisClimateCapable": false, + "vehicleDiagnosticCapable": true, + "telemetryCapable": true, + "econnectClimateCapable": true, + "econnectVehicleStatusCapable": true + }, + "electricalPlatformCode": "19", + "personalizedSettings": { + "name": null, + "link": null, + "imageUrl": null, + "body": null, + "buttonText": null + }, + "fuelType": "I", + "fleetInd": null, + "svlStatus": false, + "displayModelDescription": "2020 Toyota RAV4 Plug-in MY21", + "manufacturerCode": "TOY", + "suffixCode": null, + "imei": "123456789012345", + "color": "Dark Blue Metallic", + "vehicleDataConsents": null, + "dataConsent": { + "serviceConnect": "False", + "can300": "False", + "dealerContact": "False", + "ubi": "false" + }, + "vehicleCapabilities": [], + "capabilities": [ + { + "name": "EvRemoteService", + "description": null, + "value": true, + "translation": { + "english": null, + "french": null, + "spanish": null + }, + "display": true, + "displayName": null + }, + { + "name": "alexaSkillCapable", + "description": null, + "value": true, + "translation": { + "english": null, + "french": null, + "spanish": null + }, + "display": false, + "displayName": null + }, + { + "name": "alexaStandardCapable", + "description": null, + "value": true, + "translation": { + "english": null, + "french": null, + "spanish": null + }, + "display": true, + "displayName": null + }, + { + "name": "androidAutoCapable", + "description": null, + "value": true, + "translation": { + "english": null, + "french": null, + "spanish": null + }, + "display": true, + "displayName": null + }, + { + "name": "carplayStandardCapable", + "description": null, + "value": true, + "translation": { + "english": null, + "french": null, + "spanish": null + }, + "display": true, + "displayName": null + }, + { + "name": "googleAssistantCapable", + "description": null, + "value": true, + "translation": { + "english": null, + "french": null, + "spanish": null + }, + "display": false, + "displayName": null + } + ], + "subscriptions": [ + { + "subscriptionID": "12345678901234567-1234567890", + "productName": "REMOTE SERVICES", + "productDescription": "Standard Remote Services", + "displayProductName": "REMOTE SERVICES", + "subscriptionEndDate": "2027-01-01", + "subscriptionNextBillingDate": null, + "subscriptionStartDate": "2023-01-01", + "status": "ACTIVE", + "type": "Trial", + "subscriptionRemainingDays": 1111, + "subscriptionRemainingTerm": null, + "productCode": "PROD_REMOTESERVICE", + "productLine": "PROD_REMOTESERVICE", + "productType": null, + "term": 48, + "termUnit": "MTH", + "goodwillIssuedFor": null, + "renewable": false, + "displayTerm": "Expires On NOV 01, 2027", + "subscriptionTerm": "YRLY", + "autoRenew": false, + "futureCancel": false, + "consolidatedProductIds": [], + "consolidatedGoodwillIds": [], + "components": null, + "category": "STANDALONE" + }, + { + "subscriptionID": "12345678901234567-1234567890", + "productName": "STANDARD SERVICES", + "productDescription": "Standard Services", + "displayProductName": "STANDARD SERVICES", + "subscriptionEndDate": "2033-01-08", + "subscriptionNextBillingDate": null, + "subscriptionStartDate": "2023-01-08", + "status": "ACTIVE", + "type": "Trial", + "subscriptionRemainingDays": 1111, + "subscriptionRemainingTerm": null, + "productCode": "PROD_STANDARDSERVICES", + "productLine": "PROD_STANDARDSERVICES", + "productType": null, + "term": 120, + "termUnit": "MTH", + "goodwillIssuedFor": null, + "renewable": false, + "displayTerm": "Expires On NOV 01, 2033", + "subscriptionTerm": "YRLY", + "autoRenew": false, + "futureCancel": false, + "consolidatedProductIds": [], + "consolidatedGoodwillIds": [], + "components": null, + "category": "STANDALONE" + } + ], + "services": [], + "displaySubscriptions": [ + { + "productName": "REMOTE SERVICES", + "displayStatus": "Expires On JAN 01, 2027" + }, + { + "productName": "STANDARD SERVICES", + "displayStatus": "Expires On JAN 01, 2033" + } + ], + "alerts": [], + "features": { + "achPayment": 0, + "addServiceRecord": 0, + "autoDrive": 0, + "cerence": 0, + "chargingStation": 1, + "climateStartEngine": 0, + "collisionAssistance": 0, + "connectedCard": 0, + "connectedInsurance": 0, + "connectedSupport": 0, + "crashNotification": 0, + "criticalAlert": 0, + "dashboardLights": 0, + "dealerAppointment": 1, + "digitalKey": 0, + "doorLockCapable": 0, + "drivePulse": 0, + "driverCompanion": 0, + "driverScore": 0, + "dtcAccess": 0, + "dynamicNavi": 0, + "ecoHistory": 0, + "ecoRanking": 0, + "electricPulse": 0, + "emergencyAssist": 0, + "enhancedSecuritySystem": 0, + "evChargeStation": 1, + "evRemoteServices": 0, + "evVehicleStatus": 0, + "financialServices": 0, + "flexRental": 0, + "h2FuelStation": 0, + "homeCharge": 1, + "howToVideos": 0, + "hybridPulse": 1, + "hydrogenPulse": 0, + "importantMessage": 0, + "insurance": 0, + "lastParked": 1, + "lcfs": 0, + "linkedAccounts": 0, + "maintenanceTimeline": 0, + "marketingCard": 0, + "marketingConsent": 0, + "masterConsentEditable": 0, + "myDestination": 0, + "ownersManual": 0, + "paidProduct": 0, + "parkedVehicleLocator": 0, + "parking": 0, + "parkingNotes": 0, + "personalizedSettings": 0, + "privacy": 1, + "recentTrip": 0, + "remoteDtc": 0, + "remoteParking": 0, + "remoteService": 1, + "roadsideAssistance": 0, + "safetyRecall": 0, + "scheduleMaintenance": 0, + "serviceHistory": 1, + "shopGenuineParts": 0, + "smartCharging": 1, + "ssaDownload": 0, + "sxmRadio": 0, + "telemetry": 1, + "tff": 0, + "tirePressure": 0, + "v1g": 0, + "vaSetting": 0, + "vehicleDiagnostic": 1, + "vehicleHealthReport": 0, + "vehicleSpecifications": 0, + "vehicleStatus": 0, + "weHybrid": 0, + "wifi": 0, + "xcapp": 0 + }, + "subscriptionExpirationStatus": false, + "faqUrl": "http://toyota.com/FAQ", + "shopGenuinePartsUrl": "https://parts.toyota.com/accessories/Toyota_2020_RAV4.html?partner=ONEAPP2020RAV4", + "familySharing": false, + "ctsLinks": { + "name": "Connected Services Support", + "link": "https://qa.toyotaaudioandconnectedservicessupport.com/toyota/home?source=OneApp&vin=12345678912345678", + "imageUrl": null, + "body": null, + "buttonText": null + }, + "tffLinks": { + "name": null, + "link": null, + "imageUrl": null, + "body": null, + "buttonText": null + }, + "headUnit": { + "mobilePlatformCode": null, + "huDescription": null, + "huGeneration": null, + "huVersion": null, + "multimediaType": null + }, + "katashikiCode": "1234567-123456", + "oldImei": null, + "stockPicReference": "https://dj3z27z47basa.cloudfront.net/17978304-7589-46b9-a630-64943bd91113", + "transmissionType": "A", + "dateOfFirstUse": "2022-01-01", + "dcm": { + "dcmModelYear": "19", + "dcmDestination": "10", + "countryCode": "408", + "dcmSupplier": "65", + "dcmSupplierName": "Continental", + "dcmGrade": "1", + "euiccid": "12345678901234567890123456789012", + "hardwareType": null, + "vehicleUnitTerminalNumber": null + }, + "dcms": null, + "manufacturedDate": "2022-01-01", + "contractId": "T-1234567891234", + "carlineName": "RAV4 PHEV", + "externalSubscriptions": null, + "serviceConnectStatus": null, + "owner": true, + "remoteSubscriptionExists": true, + "dcmActive": false, + "commercialRental": false, + "preferred": 1 + } + ] + } + } + }, + { + "request": { + "method": "GET", + "url": "https://ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io/v2/notification/history", + "headers": [ + ["host", "ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["x-api-key", "tTZipv6liF74PwMfk9Ed68AQ0bISswwf3iHQdqcF"], + ["x-guid", "d95b0b58-3b3f-40e3-99ca-a3aa2a22a204"], + ["guid", "d95b0b58-3b3f-40e3-99ca-a3aa2a22a204"], + [ + "authorization", + "Bearer eyJ0eXAiOiJKV1QiLCJraWQiOiJZeVZ2SEU5d0xKNDBWVEpyc3pBNDJ6eTNyWjg9IiwiYWxnIjoiUlMyNTYifQ" + ], + ["x-channel", "ONEAPP"], + ["x-brand", "T"], + ["user-agent", "okhttp/4.10.0"], + ["vin", "12345678912345678"] + ], + "content": "" + }, + "response": { + "status": 200, + "headers": [ + ["date", "Sat, 13 Jan 2024 16:30:26 GMT"], + ["content-type", "application/json"], + ["content-length", "12916"], + ["connection", "keep-alive"], + ["x-amzn-requestid", "c813e157-ba0f-4fc9-a712-37f1c6c43cf4"], + ["access-control-allow-origin", "*"], + ["x-amz-apigw-id", "RfIZeECmliAEOfg="], + [ + "x-amzn-trace-id", + "Root=1-65a2baa2-04adbc98431eeb643eaa3e25;Sampled=0;lineage=aeb55e6e:0|412c0528:0" + ] + ], + "content": { + "guid": "12345678-1234-1234-1234-123456789123", + "statusCode": 200, + "headers": { + "Content-Type": "text/plain" + }, + "body": "Success", + "payload": [ + { + "vin": "12345678912345678", + "notifications": [ + { + "messageId": "65a0e1d516efe8e6ff4d1319", + "vin": "12345678912345678", + "notificationDate": "2024-01-12T06:53:09.105Z", + "isRead": false, + "iconUrl": "https://assets.preprod.ctdevops.com/assets/notification/icons/remoteconnect.png", + "message": "2020 RAV4 PHEV: Climate control was interrupted (Door open) [1]", + "status": "interrupted", + "type": "alert", + "category": "RemoteCommand", + "displayCategory": "Remote Commands" + }, + { + "messageId": "65a0df84f316a42fe79de05e", + "vin": "12345678912345678", + "notificationDate": "2024-01-12T06:43:16.843Z", + "isRead": false, + "iconUrl": "https://assets.preprod.ctdevops.com/assets/notification/icons/remoteconnect.png", + "message": "2020 RAV4 PHEV: Climate was started and will automatically shut off.", + "status": "completed", + "type": "alert", + "category": "RemoteCommand", + "displayCategory": "Remote Commands" + }, + { + "messageId": "659f3a0e96c8ef294705d558", + "vin": "12345678912345678", + "notificationDate": "2024-01-11T00:45:02.860Z", + "isRead": true, + "readTimestamp": "2024-01-12T06:42:22.199Z", + "iconUrl": "https://assets.preprod.ctdevops.com/assets/notification/icons/general.png", + "message": "2020 RAV4 PHEV: Charging Interrupted [4].", + "status": "completed", + "type": "alert", + "category": "ChargingAlert", + "displayCategory": "General" + } + ] + } + ] + } + } + }, + { + "request": { + "method": "GET", + "url": "https://ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io/v1/location", + "headers": [ + ["host", "ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["x-api-key", "tTZipv6liF74PwMfk9Ed68AQ0bISswwf3iHQdqcF"], + ["x-guid", "d95b0b58-3b3f-40e3-99ca-a3aa2a22a204"], + ["guid", "d95b0b58-3b3f-40e3-99ca-a3aa2a22a204"], + [ + "authorization", + "Bearer eyJ0eXAiOiJKV1QiLCJraWQiOiJZeVZ2SEU5d0xKNDBWVEpyc3pBNDJ6eTNyWjg9IiwiYWxnIjoiUlMyNTYifQ" + ], + ["x-channel", "ONEAPP"], + ["x-brand", "T"], + ["user-agent", "okhttp/4.10.0"], + ["vin", "12345678912345678"] + ], + "content": "" + }, + "response": { + "status": 200, + "headers": [ + ["date", "Sat, 13 Jan 2024 16:30:26 GMT"], + ["content-type", "application/json"], + ["content-length", "278"], + ["connection", "keep-alive"], + ["x-amzn-requestid", "e24d76a6-1835-4d6e-8789-c31175d4996a"], + ["access-control-allow-origin", "*"], + ["x-amz-apigw-id", "RfIZeFpWFiAEezg="], + [ + "x-amzn-trace-id", + "Root=1-65a2baa2-7d708a805c88aee22d4b3345;Sampled=0;lineage=aeb55e6e:0" + ] + ], + "content": { + "payload": { + "vin": "12345678912345678", + "lastTimestamp": "2024-01-13T15:02:28Z", + "vehicleLocation": { + "displayName": "Last Parked", + "latitude": 50.0, + "longitude": 0.0, + "locationAcquisitionDatetime": "2024-01-13T15:02:28Z" + } + }, + "status": "SUCCESS", + "code": 200, + "message": "Ok", + "errors": [] + } + } + }, + { + "request": { + "method": "GET", + "url": "https://ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io/v1/global/remote/electric/status", + "headers": [ + ["host", "ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["x-api-key", "tTZipv6liF74PwMfk9Ed68AQ0bISswwf3iHQdqcF"], + ["x-guid", "d95b0b58-3b3f-40e3-99ca-a3aa2a22a204"], + ["guid", "d95b0b58-3b3f-40e3-99ca-a3aa2a22a204"], + [ + "authorization", + "Bearer eyJ0eXAiOiJKV1QiLCJraWQiOiJZeVZ2SEU5d0xKNDBWVEpyc3pBNDJ6eTNyWjg9IiwiYWxnIjoiUlMyNTYifQ" + ], + ["x-channel", "ONEAPP"], + ["x-brand", "T"], + ["user-agent", "okhttp/4.10.0"], + ["vin", "12345678912345678"] + ], + "content": "" + }, + "response": { + "status": 200, + "headers": [ + ["date", "Sat, 13 Jan 2024 16:30:27 GMT"], + ["content-type", "application/json"], + ["content-length", "444"], + ["connection", "keep-alive"], + ["x-amzn-requestid", "f0cc029a-cd86-4ddc-a8a5-7d366d9d1b25"], + ["access-control-allow-origin", "*"], + ["x-amz-apigw-id", "RfIZeE75FiAEMvQ="], + [ + "x-amzn-trace-id", + "Root=1-65a2baa2-6881865f45dcadeb1f22a1de;Sampled=0;lineage=aeb55e6e:0" + ] + ], + "content": { + "status": { + "messages": [ + { + "responseCode": "ONE-GLOBAL-RS-10000", + "description": "Request Completed Successfully", + "detailedDescription": "Request Completed Successfully" + } + ] + }, + "payload": { + "fuelLevel": 11, + "batteryLevel": 22, + "chargingStatus": "none", + "evRange": { + "unit": "km", + "value": 33 + }, + "evRangeWithAc": { + "unit": "km", + "value": 30 + }, + "fuelRange": { + "unit": "mi", + "value": 70 + }, + "canSetNextChargingEvent": true, + "lastUpdateTimestamp": "2024-01-13T15:12:30Z" + } + } + } + }, + { + "request": { + "method": "GET", + "url": "https://ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io/v3/telemetry", + "headers": [ + ["host", "ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["x-api-key", "tTZipv6liF74PwMfk9Ed68AQ0bISswwf3iHQdqcF"], + ["x-guid", "d95b0b58-3b3f-40e3-99ca-a3aa2a22a204"], + ["guid", "d95b0b58-3b3f-40e3-99ca-a3aa2a22a204"], + [ + "authorization", + "Bearer eyJ0eXAiOiJKV1QiLCJraWQiOiJZeVZ2SEU5d0xKNDBWVEpyc3pBNDJ6eTNyWjg9IiwiYWxnIjoiUlMyNTYifQ" + ], + ["x-channel", "ONEAPP"], + ["x-brand", "T"], + ["user-agent", "okhttp/4.10.0"], + ["vin", "12345678912345678"] + ], + "content": "" + }, + "response": { + "status": 200, + "headers": [ + ["date", "Sat, 13 Jan 2024 16:30:27 GMT"], + ["content-type", "application/json"], + ["content-length", "260"], + ["connection", "keep-alive"], + ["x-amzn-requestid", "5e0e8953-cf98-4f1c-bbca-287bbc7d9583"], + ["access-control-allow-origin", "*"], + ["x-amz-apigw-id", "RfIZeGgNFiAEZhg="], + [ + "x-amzn-trace-id", + "Root=1-65a2baa2-540951cb0b3ac2dd1f06c5a7;Sampled=0;lineage=aeb55e6e:0" + ] + ], + "content": { + "payload": { + "fuelType": "I", + "odometer": { + "value": 6213.712, + "unit": "mi" + }, + "fuelLevel": 10, + "batteryLevel": 60, + "distanceToEmpty": { + "value": 100, + "unit": "km" + }, + "timestamp": "2024-01-13T15:12:30Z", + "chargingStatus": "none" + }, + "status": "SUCCESS", + "code": 200, + "message": "Ok", + "errors": [] + } + } + }, + { + "request": { + "method": "GET", + "url": "https://ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io/v1/vehiclehealth/status", + "headers": [ + ["host", "ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["x-api-key", "tTZipv6liF74PwMfk9Ed68AQ0bISswwf3iHQdqcF"], + ["x-guid", "d95b0b58-3b3f-40e3-99ca-a3aa2a22a204"], + ["guid", "d95b0b58-3b3f-40e3-99ca-a3aa2a22a204"], + [ + "authorization", + "Bearer eyJ0eXAiOiJKV1QiLCJraWQiOiJZeVZ2SEU5d0xKNDBWVEpyc3pBNDJ6eTNyWjg9IiwiYWxnIjoiUlMyNTYifQ" + ], + ["x-channel", "ONEAPP"], + ["x-brand", "T"], + ["user-agent", "okhttp/4.10.0"], + ["vin", "12345678912345678"] + ], + "content": "" + }, + "response": { + "status": 200, + "headers": [ + ["date", "Sat, 13 Jan 2024 16:30:27 GMT"], + ["content-type", "application/json"], + ["content-length", "164"], + ["connection", "keep-alive"], + ["x-amzn-requestid", "7013673d-c7ea-4236-9473-98f3114b64b7"], + ["access-control-allow-origin", "*"], + ["x-amz-apigw-id", "RfIZeHOYliAEGTg="], + [ + "x-amzn-trace-id", + "Root=1-65a2baa2-3bd3d8210283eeb1453102a5;Sampled=0;lineage=aeb55e6e:0" + ] + ], + "content": { + "status": "SUCCESS", + "code": 200, + "errors": [], + "payload": { + "quantityOfEngOilIcon": [], + "warning": [], + "vin": "12345678912345678", + "wnglastUpdTime": "2024-01-13T16:30:27.263Z" + } + } + } + }, + { + "request": { + "method": "GET", + "url": "https://ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io/v1/servicehistory/vehicle/summary", + "headers": [ + ["host", "ctpa-oneapi.tceu-ctp-prd.toyotaconnectedeurope.io"], + ["accept", "*/*"], + ["accept-encoding", "gzip, deflate"], + ["connection", "keep-alive"], + ["x-api-key", "tTZipv6liF74PwMfk9Ed68AQ0bISswwf3iHQdqcF"], + ["x-guid", "d95b0b58-3b3f-40e3-99ca-a3aa2a22a204"], + ["guid", "d95b0b58-3b3f-40e3-99ca-a3aa2a22a204"], + [ + "authorization", + "Bearer eyJ0eXAiOiJKV1QiLCJraWQiOiJZeVZ2SEU5d0xKNDBWVEpyc3pBNDJ6eTNyWjg9IiwiYWxnIjoiUlMyNTYifQ" + ], + ["x-channel", "ONEAPP"], + ["x-brand", "T"], + ["user-agent", "okhttp/4.10.0"], + ["vin", "12345678912345678"] + ], + "content": "" + }, + "response": { + "status": 200, + "headers": [ + ["date", "Sat, 13 Jan 2024 16:30:27 GMT"], + ["content-type", "application/json"], + ["content-length", "260"], + ["connection", "keep-alive"], + ["x-amzn-requestid", "5e0e8953-cf98-4f1c-bbca-287bbc7d9583"], + ["access-control-allow-origin", "*"], + ["x-amz-apigw-id", "RfIZeGgNFiAEZhg="], + [ + "x-amzn-trace-id", + "Root=1-65a2baa2-540951cb0b3ac2dd1f06c5a7;Sampled=0;lineage=aeb55e6e:0" + ] + ], + "content": { + "payload": { + "serviceHistories": [ + { + "customerCreatedRecord": false, + "mileage": "30087", + "notes": null, + "operationsPerformed": null, + "roNumber": null, + "serviceCategory": "HSC", + "serviceDate": "2023-11-16", + "serviceHistoryId": "12345678", + "serviceProvider": "Provider 1", + "servicingDealer": null, + "unit": "km" + }, + { + "customerCreatedRecord": false, + "mileage": "21738", + "notes": null, + "operationsPerformed": null, + "roNumber": null, + "serviceCategory": "HSC", + "serviceDate": "2022-12-20", + "serviceHistoryId": "1234567", + "serviceProvider": "Provider 2", + "servicingDealer": null, + "unit": "km" + }, + { + "customerCreatedRecord": false, + "mileage": null, + "notes": null, + "operationsPerformed": null, + "roNumber": null, + "serviceCategory": "VDE", + "serviceDate": "2020-11-19", + "serviceHistoryId": "123456", + "serviceProvider": "Provider 3", + "servicingDealer": null, + "unit": null + }, + { + "customerCreatedRecord": false, + "mileage": "10", + "notes": null, + "operationsPerformed": null, + "roNumber": null, + "serviceCategory": "RPR", + "serviceDate": "2020-11-19", + "serviceHistoryId": "12345", + "serviceProvider": "Provider 1", + "servicingDealer": null, + "unit": "km" + } + ] + }, + "status": { + "messages": [ + { + "description": "Request Processed successfully", + "detailedDescription": "Request Processed successfully", + "responseCode": "OSH-001" + } + ] + } + } + } + } +] diff --git a/tests/integration_tests/test_authentication.py b/tests/integration_tests/test_authentication.py new file mode 100644 index 00000000..a15f7578 --- /dev/null +++ b/tests/integration_tests/test_authentication.py @@ -0,0 +1,133 @@ +"""pytest tests for mytoyota using httpx mocking.""" +import json +from datetime import datetime, timedelta +from pathlib import Path +from shutil import copy2 +from typing import List + +import pytest +from pytest_httpx import HTTPXMock + +from mytoyota import MyT +from mytoyota.controller import CACHE_FILENAME +from mytoyota.exceptions import ToyotaInvalidUsernameError, ToyotaLoginError + + +def build_routes(httpx_mock: HTTPXMock, filenames: List[str]) -> None: # noqa: D103 + for filename in filenames: + # TODO: Move to fixture once I know how to use a fixture from a fixture + path: str = f"{Path(__file__).parent}/data/" + + with open( + f"{path}/{filename}", encoding="utf-8" + ) as f: # I cant see a problem for the tests + routes = json.load(f) + + for route in routes: + httpx_mock.add_response( + method=route["request"]["method"], + url=route["request"]["url"], + status_code=route["response"]["status"], + content=route["response"]["content"] + if isinstance(route["response"]["content"], str) + else json.dumps(route["response"]["content"]), + headers=route["response"]["headers"], + ) + + +@pytest.mark.asyncio +@pytest.mark.usefixtures("remove_cache") +async def test_authenticate(httpx_mock): # noqa: D103 + build_routes(httpx_mock, ["authenticate_working.json"]) + + client = MyT("user@email.com", "password") + # Nothing validates this is correct, just replays a "correct" authentication sequence + await client.login() + + +@pytest.mark.asyncio +@pytest.mark.usefixtures("remove_cache") +async def test_authenticate_invalid_username(httpx_mock: HTTPXMock): # noqa: D103 + build_routes(httpx_mock, ["authenticate_invalid_username.json"]) + + client = MyT("user@email.com", "password") + # Nothing validates this is correct, just replays an invalid username authentication sequence + with pytest.raises(ToyotaInvalidUsernameError): + await client.login() + + +@pytest.mark.asyncio +@pytest.mark.usefixtures("remove_cache") +async def test_authenticate_invalid_password(httpx_mock: HTTPXMock): # noqa: D103 + build_routes(httpx_mock, ["authenticate_invalid_password.json"]) + + client = MyT("user@email.com", "password") + # Nothing validates this is correct, just replays an invalid username authentication sequence + with pytest.raises(ToyotaLoginError): + await client.login() + + +@pytest.mark.asyncio +async def test_authenticate_refresh_token(data_folder, httpx_mock: HTTPXMock): # noqa: D103 + # Ensure expired cache file. + copy2(f"{data_folder}/cached_token.json", CACHE_FILENAME) + build_routes(httpx_mock, ["authenticate_refresh_token.json"]) + + client = MyT("user@email.info", "password") + # Nothing validates this is correct, just replays a refresh token sequence + await client.login() + + +@pytest.mark.asyncio +async def test_get_static_data(data_folder, httpx_mock: HTTPXMock): # noqa: D103 + # Create valid token => Means no authentication requests + with open(f"{data_folder}/cached_token.json", encoding="utf-8") as f: # noqa: ASYNC101. I dont see this as a problem in test code + valid_token = json.load(f) + valid_token["expiration"] = datetime.now() + timedelta(hours=4) + + with open(CACHE_FILENAME, "w", encoding="utf-8") as wf: # noqa: ASYNC101. I dont see this as a problem in test code + wf.write(json.dumps(valid_token, indent=4, default=str)) + + # Ensure expired cache file. + build_routes(httpx_mock, ["get_static_data.json"]) + + client = MyT("user@email.info", "password") + # Nothing validates this is correct, just replays a refresh token sequence + await client.login() + cars = await client.get_vehicles(metric=True) + car = cars[0] + await car.update() + + # Check VIN + assert car.vin == "12345678912345678" + + # Check alias + assert car.alias == "RAV4" + + # Check Dashboard + assert car.dashboard.odometer == 9999.975 + assert car.dashboard.fuel_level == 10 + assert car.dashboard.battery_level == 22 + assert car.dashboard.fuel_range == 112.654 + assert car.dashboard.battery_range == 33.0 + assert car.dashboard.battery_range_with_ac == 30 + assert car.dashboard.range == 100 + assert len(car.dashboard.warning_lights) == 0 + + # Check location + assert car.location.latitude == 50.0 + assert car.location.longitude == 0.0 + + # Check Notifications + assert len(car.notifications) == 3 + assert ( + car.notifications[0].message + == "2020 RAV4 PHEV: Climate control was interrupted (Door open) [1]" + ) + assert car.notifications[0].type == "alert" + assert car.notifications[0].category == "RemoteCommand" + assert ( + car.notifications[1].message + == "2020 RAV4 PHEV: Climate was started and will automatically shut off." + ) + assert car.notifications[2].message == "2020 RAV4 PHEV: Charging Interrupted [4]." diff --git a/tests/unit_tests/conftest.py b/tests/unit_tests/conftest.py new file mode 100644 index 00000000..0eda4ec4 --- /dev/null +++ b/tests/unit_tests/conftest.py @@ -0,0 +1,10 @@ +"""Need for pytest or else it will cause an import error in pytest.""" +from pathlib import Path + +import pytest + + +@pytest.fixture +def data_folder(request) -> str: + """Return the folder containing test files.""" + return f"{Path(request.module.__file__).parent}/data" diff --git a/tests/data/endpoints/v1_global_remote_electric_status.json b/tests/unit_tests/data/v1_global_remote_electric_status.json similarity index 100% rename from tests/data/endpoints/v1_global_remote_electric_status.json rename to tests/unit_tests/data/v1_global_remote_electric_status.json diff --git a/tests/data/endpoints/v1_global_remote_status.json b/tests/unit_tests/data/v1_global_remote_status.json similarity index 100% rename from tests/data/endpoints/v1_global_remote_status.json rename to tests/unit_tests/data/v1_global_remote_status.json diff --git a/tests/data/endpoints/v1_location_error.json b/tests/unit_tests/data/v1_location_error.json similarity index 100% rename from tests/data/endpoints/v1_location_error.json rename to tests/unit_tests/data/v1_location_error.json diff --git a/tests/data/endpoints/v1_location_ok.json b/tests/unit_tests/data/v1_location_ok.json similarity index 100% rename from tests/data/endpoints/v1_location_ok.json rename to tests/unit_tests/data/v1_location_ok.json diff --git a/tests/data/endpoints/v1_service_history.json b/tests/unit_tests/data/v1_service_history.json similarity index 100% rename from tests/data/endpoints/v1_service_history.json rename to tests/unit_tests/data/v1_service_history.json diff --git a/tests/data/endpoints/v1_trips.json b/tests/unit_tests/data/v1_trips.json similarity index 100% rename from tests/data/endpoints/v1_trips.json rename to tests/unit_tests/data/v1_trips.json diff --git a/tests/data/endpoints/v1_vehicle_health_error.json b/tests/unit_tests/data/v1_vehicle_health_error.json similarity index 100% rename from tests/data/endpoints/v1_vehicle_health_error.json rename to tests/unit_tests/data/v1_vehicle_health_error.json diff --git a/tests/data/endpoints/v1_vehicle_health_ok.json b/tests/unit_tests/data/v1_vehicle_health_ok.json similarity index 100% rename from tests/data/endpoints/v1_vehicle_health_ok.json rename to tests/unit_tests/data/v1_vehicle_health_ok.json diff --git a/tests/data/endpoints/v2_notification.json b/tests/unit_tests/data/v2_notification.json similarity index 100% rename from tests/data/endpoints/v2_notification.json rename to tests/unit_tests/data/v2_notification.json diff --git a/tests/data/endpoints/v2_vehicleguid.json b/tests/unit_tests/data/v2_vehicleguid.json similarity index 100% rename from tests/data/endpoints/v2_vehicleguid.json rename to tests/unit_tests/data/v2_vehicleguid.json diff --git a/tests/data/endpoints/v3_telemetry.json b/tests/unit_tests/data/v3_telemetry.json similarity index 100% rename from tests/data/endpoints/v3_telemetry.json rename to tests/unit_tests/data/v3_telemetry.json diff --git a/tests/data/endpoints/v4_accountmodel.json b/tests/unit_tests/data/v4_accountmodel.json similarity index 100% rename from tests/data/endpoints/v4_accountmodel.json rename to tests/unit_tests/data/v4_accountmodel.json diff --git a/tests/test_api.py b/tests/unit_tests/test_api.py similarity index 94% rename from tests/test_api.py rename to tests/unit_tests/test_api.py index dc2dbe35..062f2049 100644 --- a/tests/test_api.py +++ b/tests/unit_tests/test_api.py @@ -131,13 +131,14 @@ ), ], ) -async def test_api_request_and_parse_endpoints( - method, endpoint, model, response_data_json_path, test_id +async def test_api_request_and_parse_endpoints( # NOQA: PLR0913 + data_folder, method, endpoint, model, response_data_json_path, test_id ): """Test the API for various endpoints. Args: ---- + data_folder: Path to find data files method: The method with which the API endpoint is to be addressed. endpoint: The API endpoint to be tested. model: The pydantic model class to test. @@ -152,7 +153,7 @@ async def test_api_request_and_parse_endpoints( # Arrange with open( # noqa : ASYNC101 - f"tests/data/endpoints/{response_data_json_path}.json", "r", encoding="utf-8" + f"{data_folder}/{response_data_json_path}.json", "r", encoding="utf-8" ) as f: response_data = json.load(f) diff --git a/tests/test_client.py b/tests/unit_tests/test_client.py similarity index 100% rename from tests/test_client.py rename to tests/unit_tests/test_client.py diff --git a/tests/test_init.py b/tests/unit_tests/test_init.py similarity index 100% rename from tests/test_init.py rename to tests/unit_tests/test_init.py diff --git a/tests/test_models/test_lock_status.py b/tests/unit_tests/test_models/test_lock_status.py similarity index 100% rename from tests/test_models/test_lock_status.py rename to tests/unit_tests/test_models/test_lock_status.py diff --git a/tests/test_utils/test_conversions.py b/tests/unit_tests/test_utils/test_conversions.py similarity index 100% rename from tests/test_utils/test_conversions.py rename to tests/unit_tests/test_utils/test_conversions.py diff --git a/tests/test_utils/test_formatter.py b/tests/unit_tests/test_utils/test_formatter.py similarity index 100% rename from tests/test_utils/test_formatter.py rename to tests/unit_tests/test_utils/test_formatter.py diff --git a/tests/test_utils/test_helpers.py b/tests/unit_tests/test_utils/test_helpers.py similarity index 100% rename from tests/test_utils/test_helpers.py rename to tests/unit_tests/test_utils/test_helpers.py diff --git a/tests/test_utils/test_locale.py b/tests/unit_tests/test_utils/test_locale.py similarity index 100% rename from tests/test_utils/test_locale.py rename to tests/unit_tests/test_utils/test_locale.py diff --git a/tests/test_utils/test_logs.py b/tests/unit_tests/test_utils/test_logs.py similarity index 100% rename from tests/test_utils/test_logs.py rename to tests/unit_tests/test_utils/test_logs.py