diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..c0768f8 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,42 @@ +version: 2 + +updates: +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily + time: "04:24" + target-branch: main + labels: + - CI/CD + - skip-changelog + groups: + actions: + applies-to: "version-updates" + patterns: + - "*" + actions-security: + applies-to: "security-updates" + patterns: + - "*" + +- package-ecosystem: pip + directories: + - "/" + - "/.github/utils" + schedule: + interval: weekly + time: "04:16" + target-branch: main + labels: + - dependencies + - skip-changelog + groups: + python: + applies-to: "version-updates" + patterns: + - "*" + python-security: + applies-to: "security-updates" + patterns: + - "*" diff --git a/.github/utils/requirements_ci.txt b/.github/utils/requirements_ci.txt new file mode 100644 index 0000000..b3f6f9f --- /dev/null +++ b/.github/utils/requirements_ci.txt @@ -0,0 +1,2 @@ +pip-tools~=7.5 +pre-commit~=4.6 diff --git a/.github/workflows/cd_release.yml b/.github/workflows/cd_release.yml new file mode 100644 index 0000000..398e7b1 --- /dev/null +++ b/.github/workflows/cd_release.yml @@ -0,0 +1,68 @@ +name: CD - Release + +on: + release: + types: [published] + +jobs: + build: + name: External + uses: SINTEF/ci-cd/.github/workflows/cd_release.yml@v2.10.0 + if: github.repository == 'SemanticMatter/httpx2_auth' && startsWith(github.ref, 'refs/tags/v') + + permissions: + contents: write + + with: + # General + git_username: ${{ vars.CI_CD_GIT_USER }} + git_email: ${{ vars.CI_CD_GIT_EMAIL }} + release_branch: main + + # Python package + python_package: true + package_dirs: httpx2_auth + install_extras: "[dev]" + pip_index_url: "${{ vars.EXTERNAL_PYPI_INDEX_URL }}" + python_version_build: "3.10" + build_libs: build + build_cmd: "python -m build" + build_dir: "dist" + changelog_exclude_labels: skip-changelog,duplicate,question,invalid,wontfix + publish_on_pypi: false + upload_distribution: true + version_update_changes_separator: "," + version_update_changes: | + {package_dir}/__init__.py,__version__ *= *(?:'|\").*(?:'|\"),__version__ = \"{version}\" + .github/workflows/ci_tests.yml,dist/httpx2_auth-2\.[0-9]+\.[0-9]+\.[0-9]+,dist/httpx2_auth-{version} + + # Documentation + update_docs: false + + secrets: + PAT: ${{ secrets.BOT_PAT }} + + publish: + name: Publish to SINTEF GitLab + needs: build + runs-on: ubuntu-latest + + environment: + name: GitLab + url: ${{ vars.GITLAB_PACKAGE_URL }} + + steps: + - name: Download distribution + uses: actions/download-artifact@v8 + with: + name: dist # The artifact will always be called 'dist' + path: dist + + - name: Publish to SemanticMatter @ SINTEF GitLab + uses: pypa/gh-action-pypi-publish@release/v1 + with: + # The path to the distribution to upload + packages-dir: dist + repository-url: ${{ vars.GITLAB_PACKAGE_REGISTRY_URL }} + user: ${{ secrets.DEPLOY_TOKEN_USERNAME }} + password: ${{ secrets.DEPLOY_TOKEN_PASSWORD }} diff --git a/.github/workflows/ci_automerge.yml b/.github/workflows/ci_automerge.yml new file mode 100644 index 0000000..c8c9c22 --- /dev/null +++ b/.github/workflows/ci_automerge.yml @@ -0,0 +1,13 @@ +name: CI - Activate auto-merging + +on: + pull_request_target: + branches: [main] + +jobs: + update-dependabot-branch: + name: External + uses: SINTEF/ci-cd/.github/workflows/ci_automerge_prs.yml@v2.10.0 + if: github.repository_owner == 'SemanticMatter' && ( ( startsWith(github.event.pull_request.head.ref, 'dependabot/') && github.actor == 'dependabot[bot]' ) || ( github.event.pull_request.head.ref == 'pre-commit-ci-update-config' && github.actor == 'pre-commit-ci[bot]' ) ) + secrets: + PAT: ${{ secrets.BOT_PAT }} diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml new file mode 100644 index 0000000..8bb72ef --- /dev/null +++ b/.github/workflows/ci_tests.yml @@ -0,0 +1,120 @@ +name: CI - Tests + +on: + pull_request: + push: + branches: + - master + - 'push-action/**' # Allow pushing to protected branches (using CasperWA/push-protected) + +env: + PIP_INDEX_URL: "${{ vars.EXTERNAL_PYPI_INDEX_URL }}" + +jobs: + pre-commit_audit: + runs-on: ubuntu-latest + steps: + - name: Checkout ${{ github.repository }} + uses: actions/checkout@v6 + + - name: Set up Python 3.10 + uses: actions/setup-python@v6 + with: + python-version: '3.10' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U setuptools wheel + pip install -U -r .github/utils/requirements_ci.txt + + - name: Run pre-commit + # Ensure pip-audit is also run - if pre-commit fails, pip-audit will still run + # If pre-commit fails (but pip-audit does not), the job will fail from the last step + continue-on-error: true + id: pre_commit + run: pre-commit run --all-files + + - name: Create requirements.txt file for pip-audit + run: pip-compile --index-url="${{ env.PIP_INDEX_URL }}" --output-file="${{ runner.temp }}/requirements.txt" --all-extras --verbose --color "${{ github.workspace }}/pyproject.toml" + + - name: Run pip-audit + uses: pypa/gh-action-pip-audit@v1.1.0 + with: + extra-index-urls: ${{ env.PIP_INDEX_URL }} + no-deps: true + inputs: ${{ runner.temp }}/requirements.txt + + - name: Fail if pre-commit failed + if: steps.pre_commit.outcome == 'failure' + run: | + echo "❌ pre-commit run failed (see step 'Run pre-commit' above for details)" + exit 1 + + pytest: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ['3.10', '3.11', '3.12', '3.13'] + + steps: + - name: Checkout ${{ github.repository }} + uses: actions/checkout@v6 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U setuptools wheel + pip install -U -e .[testing] + + - name: Run pytest + run: pytest -vv --color=yes --doctest-modules --cov-report=xml ./tests + + - name: Upload coverage + if: github.repository_owner == 'SemanticMatter' + uses: codecov/codecov-action@v6 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true + env_vars: PYTHON + flags: local + env: + PYTHON: ${{ matrix.python-version }} + + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout ${{ github.repository }} + uses: actions/checkout@v6 + + - name: Set up Python 3.10 + uses: actions/setup-python@v6 + with: + python-version: '3.10' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U setuptools wheel + pip install -U build + + - name: Build package + run: | + python -m build . + rm -Rf httpx2_auth + + - name: Install wheel + run: | + python -m pip install dist/httpx2_auth-2.0.1.0-py3-none-any.whl --force-reinstall + python -c 'import httpx2_auth' + + - name: Install source distribution + run: | + python -m pip install dist/httpx2_auth-2.0.1.0.tar.gz --force-reinstall + python -c 'import httpx2_auth' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 5338b25..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Release - -on: - push: - branches: - - master - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.13' - - name: Create packages - run: | - python -m pip install build - python -m build . - - name: Publish packages - run: | - python -m pip install twine - python -m twine upload dist/* --skip-existing --username __token__ --password ${{ secrets.pypi_password }} \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 0c58bf0..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Test - -on: [push, pull_request] - -jobs: - build: - - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] - - steps: - - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python -m pip install .[testing] - - name: Test with pytest - run: | - pytest --doctest-modules --cov=httpx_auth --cov-fail-under=100 --cov-report=term-missing - - name: Create packages - run: | - python -m pip install build - python -m build . - rm -Rf httpx_auth - - name: Install wheel - run: | - python -m pip install dist/httpx_auth-0.23.1-py3-none-any.whl --force-reinstall - python -c 'import httpx_auth' - - name: Install source distribution - run: | - python -m pip install dist/httpx_auth-0.23.1.tar.gz --force-reinstall - python -c 'import httpx_auth' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8856f1b..e96c32e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,83 @@ +# pre-commit.ci +ci: + autofix_commit_msg: | + [pre-commit.ci] auto fixes from pre-commit hooks + + For more information, see https://pre-commit.ci + autofix_prs: false + autoupdate_branch: 'main' + autoupdate_commit_msg: '[pre-commit.ci] pre-commit autoupdate' + autoupdate_schedule: 'weekly' + skip: [] + submodules: false + +# hooks repos: - - repo: https://github.com/psf/black - rev: 24.8.0 + # General-purpose hygiene hooks. + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 hooks: - - id: black \ No newline at end of file + - id: check-json + - id: check-toml + - id: check-yaml + - id: debug-statements + - id: end-of-file-fixer + - id: mixed-line-ending + - id: name-tests-test + args: ["--pytest-test-first"] + - id: trailing-whitespace + args: ["--markdown-linebreak-ext=md"] + - id: check-added-large-files + - id: check-merge-conflict + + # pyupgrade — modernize syntax to the project's minimum Python. + - repo: https://github.com/asottile/pyupgrade + rev: v3.21.2 + hooks: + - id: pyupgrade + args: ["--py310-plus", "--keep-runtime-typing"] + + # black — code formatter (config in [tool.black]). + - repo: https://github.com/psf/black-pre-commit-mirror + rev: 26.5.1 + hooks: + - id: black + + # blacken-docs — format Python code blocks inside docs. + - repo: https://github.com/adamchainz/blacken-docs + rev: 1.20.0 + hooks: + - id: blacken-docs + additional_dependencies: [black] + + # ruff — linter only (config in [tool.ruff]; black does the formatting). + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.15.15 + hooks: + - id: ruff-check + name: ruff + args: + - "--fix" + - "--exit-non-zero-on-fix" + - "--show-fixes" + - "--no-unsafe-fixes" + + # bandit — security linter (config in [tool.bandit]; needs the toml extra). + - repo: https://github.com/PyCQA/bandit + rev: 1.9.4 + hooks: + - id: bandit + args: ["-c", "pyproject.toml", "-r"] + # testing.py is a test-support module (browser/HTTP-server mocks); exempt like tests/. + exclude: ^(tests/.*|httpx2_auth/testing\.py)$ + additional_dependencies: ["bandit[toml]"] + + # mypy — static type checking (strict; config in [tool.mypy]). Runs in its own + # isolated env with the project's runtime deps pinned for type resolution. + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v2.1.0 + hooks: + - id: mypy + exclude: ^tests/.*$ + additional_dependencies: + - "httpx2~=2.3" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 01ab6ec..0d91436 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,9 +22,9 @@ Before creating an issue please make sure that it was not already reported. 1) Go to the *Issues* tab and click on the *New issue* button. 2) Title should be a small sentence describing the request. 3) The comment should contain as much information as possible - * Actual behavior (including the version you used) - * Expected behavior - * Steps to reproduce + - Actual behavior (including the version you used) + - Expected behavior + - Steps to reproduce ## Submitting a pull request @@ -40,16 +40,16 @@ Before creating an issue please make sure that it was not already reported. 1) Create a new branch based on `develop` branch. 2) Fetch all dev dependencies. - * Install required python modules using `pip`: **python -m pip install .[testing]** + - Install required python modules using `pip`: **python -m pip install .[testing]** 3) Ensure tests are ok by running them using [`pytest`](http://doc.pytest.org/en/latest/index.html). 4) Add your changes. 5) Follow [Black](https://black.readthedocs.io/en/stable/) code formatting. - * Install [pre-commit](https://pre-commit.com) python module using `pip`: **python -m pip install pre-commit** - * To add the [pre-commit](https://pre-commit.com) hook, after the installation run: **pre-commit install** + - Install [pre-commit](https://pre-commit.com) python module using `pip`: **python -m pip install pre-commit** + - To add the [pre-commit](https://pre-commit.com) hook, after the installation run: **pre-commit install** 6) Add at least one [`pytest`](http://doc.pytest.org/en/latest/index.html) test case. - * Unless it is an internal refactoring request or a documentation update. + - Unless it is an internal refactoring request or a documentation update. 7) Add related [changelog entry](https://keepachangelog.com/en/1.0.0/) in the `Unreleased` section. - * Unless it is a documentation update. + - Unless it is a documentation update. #### Enter pull request @@ -57,6 +57,6 @@ Before creating an issue please make sure that it was not already reported. 2) *base* should always be set to `develop` and it should be compared to your branch. 3) Title should be a small sentence describing the request. 4) The comment should contain as much information as possible - * Actual behavior (before the new code) - * Expected behavior (with the new code) - * Steps to reproduce (with and without the new code to see the difference) + - Actual behavior (before the new code) + - Expected behavior (with the new code) + - Steps to reproduce (with and without the new code to see the difference) diff --git a/LICENSE b/LICENSE index cab2d30..00ff532 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 Colin Bounouar +Copyright (c) 2024-2026 Colin Bounouar Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 06c1ddd..ce610d7 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,21 @@ -

Authentication for HTTPX

+

Authentication for HTTPX2

+ +> [!NOTE] +> This is a fork of [Colin-b/httpx_auth](https://github.com/Colin-b/httpx_auth) with support for [HTTPX2](https://httpx2.pydantic.dev). +> +> There is not associated docuemntation, and everything below this NOTE is the same as in the original repository. +> With the exception of code snippets and links to create new issues. +> These have been directed to this repository instead of the original one. +> +> For more information about this project, please refer to the original repository.

-pypi version -Build status -Coverage +pypi version +Build status +Coverage Code style: black -Number of tests -Number of downloads +Number of tests +Number of downloads

> [!NOTE] @@ -53,25 +62,31 @@ Provides authentication classes to be used with [`httpx`][1] [authentication par Most of [OAuth2](https://oauth.net/2/) flows are supported. -If the one you are looking for is not yet supported, feel free to [ask for its implementation](https://github.com/Colin-b/httpx_auth/issues/new). +If the one you are looking for is not yet supported, feel free to [ask for its implementation](https://github.com/SemanticMatter/httpx2_auth/issues/new). ### Authorization Code flow Authorization Code Grant is implemented following [rfc6749](https://tools.ietf.org/html/rfc6749#section-4.1). -Use `httpx_auth.OAuth2AuthorizationCode` to configure this kind of authentication. +Use `httpx2_auth.OAuth2AuthorizationCode` to configure this kind of authentication. ```python -import httpx -from httpx_auth import OAuth2AuthorizationCode - -with httpx.Client() as client: - client.get('https://www.example.com', auth=OAuth2AuthorizationCode('https://www.authorization.url', 'https://www.token.url')) +import httpx2 +from httpx2_auth import OAuth2AuthorizationCode + +with httpx2.Client() as client: + client.get( + "https://www.example.com", + auth=OAuth2AuthorizationCode( + "https://www.authorization.url", "https://www.token.url" + ), + ) ``` Note: -* You can persist tokens thanks to [the token cache](#managing-token-cache). -* You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). + +- You can persist tokens thanks to [the token cache](#managing-token-cache). +- You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). #### Parameters @@ -91,12 +106,12 @@ Note: | `code_field_name` | Field name containing the code. | Optional | code | | `username` | User name in case basic authentication should be used to retrieve token. | Optional | | | `password` | User password in case basic authentication should be used to retrieve token. | Optional | | -| `client` | `httpx.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | | +| `client` | `httpx2.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | | -Any other parameter will be put as query parameter in the authorization URL and as body parameters in the token URL. +Any other parameter will be put as query parameter in the authorization URL and as body parameters in the token URL. Usual extra parameters are: - + | Name | Description | |:----------------|:---------------------------------------------------------------------| | `client_id` | Corresponding to your Application ID (in Microsoft Azure app portal) | @@ -107,27 +122,30 @@ Usual extra parameters are: Most of [OAuth2](https://oauth.net/2/) Authorization Code Grant providers are supported. -If the one you are looking for is not yet supported, feel free to [ask for its implementation](https://github.com/Colin-b/httpx_auth/issues/new). +If the one you are looking for is not yet supported, feel free to [ask for its implementation](https://github.com/SemanticMatter/httpx2_auth/issues/new). ##### Okta (OAuth2 Authorization Code) [Okta Authorization Code Grant](https://developer.okta.com/docs/guides/implement-auth-code/overview/) providing access tokens is supported. -Use `httpx_auth.OktaAuthorizationCode` to configure this kind of authentication. +Use `httpx2_auth.OktaAuthorizationCode` to configure this kind of authentication. ```python -import httpx -from httpx_auth import OktaAuthorizationCode - - -okta = OktaAuthorizationCode(instance='testserver.okta-emea.com', client_id='54239d18-c68c-4c47-8bdd-ce71ea1d50cd') -with httpx.Client() as client: - client.get('https://www.example.com', auth=okta) +import httpx2 +from httpx2_auth import OktaAuthorizationCode + +okta = OktaAuthorizationCode( + instance="testserver.okta-emea.com", + client_id="54239d18-c68c-4c47-8bdd-ce71ea1d50cd", +) +with httpx2.Client() as client: + client.get("https://www.example.com", auth=okta) ``` Note: -* You can persist tokens thanks to [the token cache](#managing-token-cache). -* You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). + +- You can persist tokens thanks to [the token cache](#managing-token-cache). +- You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). ###### Parameters @@ -147,12 +165,12 @@ Note: | `timeout` | Maximum amount of seconds to wait for a token to be received once requested. | Optional | 60 | | `header_name` | Name of the header field used to send token. | Optional | Authorization | | `header_value` | Format used to send the token value. "{token}" must be present as it will be replaced by the actual token. | Optional | Bearer {token} | -| `client` | `httpx.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | | +| `client` | `httpx2.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | | -Any other parameter will be put as query parameter in the authorization URL. +Any other parameter will be put as query parameter in the authorization URL. Usual extra parameters are: - + | Name | Description | |:----------------|:---------------------------------------------------------------------| | `prompt` | none to avoid prompting the user if a session is already opened. | @@ -161,21 +179,23 @@ Usual extra parameters are: [WakaTime Authorization Code Grant](https://wakatime.com/developers#authentication) providing access tokens is supported. -Use `httpx_auth.WakaTimeAuthorizationCode` to configure this kind of authentication. +Use `httpx2_auth.WakaTimeAuthorizationCode` to configure this kind of authentication. ```python -import httpx -from httpx_auth import WakaTimeAuthorizationCode - - -waka_time = WakaTimeAuthorizationCode(client_id="aPJQV0op6Pu3b66MWDi9b1wB", client_secret="waka_sec_0c5MB", scope="email") -with httpx.Client() as client: - client.get('https://wakatime.com/api/v1/users/current', auth=waka_time) +import httpx2 +from httpx2_auth import WakaTimeAuthorizationCode + +waka_time = WakaTimeAuthorizationCode( + client_id="aPJQV0op6Pu3b66MWDi9b1wB", client_secret="waka_sec_0c5MB", scope="email" +) +with httpx2.Client() as client: + client.get("https://wakatime.com/api/v1/users/current", auth=waka_time) ``` Note: -* You can persist tokens thanks to [the token cache](#managing-token-cache). -* You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). + +- You can persist tokens thanks to [the token cache](#managing-token-cache). +- You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). ###### Parameters @@ -194,7 +214,7 @@ Note: | `timeout` | Maximum amount of seconds to wait for a token to be received once requested. | Optional | 60 | | `header_name` | Name of the header field used to send token. | Optional | Authorization | | `header_value` | Format used to send the token value. "{token}" must be present as it will be replaced by the actual token. | Optional | Bearer {token} | -| `client` | `httpx.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | | +| `client` | `httpx2.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | | Any other parameter will be put as query parameter in the authorization URL. @@ -202,21 +222,27 @@ Any other parameter will be put as query parameter in the authorization URL. Proof Key for Code Exchange is implemented following [rfc7636](https://tools.ietf.org/html/rfc7636). -Use `httpx_auth.OAuth2AuthorizationCodePKCE` to configure this kind of authentication. +Use `httpx2_auth.OAuth2AuthorizationCodePKCE` to configure this kind of authentication. ```python -import httpx -from httpx_auth import OAuth2AuthorizationCodePKCE - -with httpx.Client() as client: - client.get('https://www.example.com', auth=OAuth2AuthorizationCodePKCE('https://www.authorization.url', 'https://www.token.url')) +import httpx2 +from httpx2_auth import OAuth2AuthorizationCodePKCE + +with httpx2.Client() as client: + client.get( + "https://www.example.com", + auth=OAuth2AuthorizationCodePKCE( + "https://www.authorization.url", "https://www.token.url" + ), + ) ``` Note: -* You can persist tokens thanks to [the token cache](#managing-token-cache). -* You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). -#### Parameters +- You can persist tokens thanks to [the token cache](#managing-token-cache). +- You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). + +#### Parameters | Name | Description | Mandatory | Default value | |:------------------------|:---------------------------|:----------|:--------------| @@ -232,12 +258,12 @@ Note: | `token_field_name` | Field name containing the token. | Optional | access_token | | `early_expiry` | Number of seconds before actual token expiry where token will be considered as expired. Used to ensure token will not expire between the time of retrieval and the time the request reaches the actual server. Set it to 0 to deactivate this feature and use the same token until actual expiry. | Optional | 30.0 | | `code_field_name` | Field name containing the code. | Optional | code | -| `client` | `httpx.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | | +| `client` | `httpx2.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | | -Any other parameter will be put as query parameter in the authorization URL and as body parameters in the token URL. +Any other parameter will be put as query parameter in the authorization URL and as body parameters in the token URL. Usual extra parameters are: - + | Name | Description | |:----------------|:---------------------------------------------------------------------| | `client_id` | Corresponding to your Application ID (in Microsoft Azure app portal) | @@ -248,27 +274,30 @@ Usual extra parameters are: Most of [OAuth2](https://oauth.net/2/) Proof Key for Code Exchange providers are supported. -If the one you are looking for is not yet supported, feel free to [ask for its implementation](https://github.com/Colin-b/httpx_auth/issues/new). +If the one you are looking for is not yet supported, feel free to [ask for its implementation](https://github.com/SemanticMatter/httpx2_auth/issues/new). ##### Okta (OAuth2 Proof Key for Code Exchange) [Okta Proof Key for Code Exchange](https://developer.okta.com/docs/guides/implement-auth-code-pkce/overview/) providing access tokens is supported. -Use `httpx_auth.OktaAuthorizationCodePKCE` to configure this kind of authentication. +Use `httpx2_auth.OktaAuthorizationCodePKCE` to configure this kind of authentication. ```python -import httpx -from httpx_auth import OktaAuthorizationCodePKCE - - -okta = OktaAuthorizationCodePKCE(instance='testserver.okta-emea.com', client_id='54239d18-c68c-4c47-8bdd-ce71ea1d50cd') -with httpx.Client() as client: - client.get('https://www.example.com', auth=okta) +import httpx2 +from httpx2_auth import OktaAuthorizationCodePKCE + +okta = OktaAuthorizationCodePKCE( + instance="testserver.okta-emea.com", + client_id="54239d18-c68c-4c47-8bdd-ce71ea1d50cd", +) +with httpx2.Client() as client: + client.get("https://www.example.com", auth=okta) ``` Note: -* You can persist tokens thanks to [the token cache](#managing-token-cache). -* You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). + +- You can persist tokens thanks to [the token cache](#managing-token-cache). +- You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). ###### Parameters @@ -289,12 +318,12 @@ Note: | `timeout` | Maximum amount of seconds to wait for a token to be received once requested. | Optional | 60 | | `header_name` | Name of the header field used to send token. | Optional | Authorization | | `header_value` | Format used to send the token value. "{token}" must be present as it will be replaced by the actual token. | Optional | Bearer {token} | -| `client` | `httpx.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | | +| `client` | `httpx2.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | | -Any other parameter will be put as query parameter in the authorization URL and as body parameters in the token URL. +Any other parameter will be put as query parameter in the authorization URL and as body parameters in the token URL. Usual extra parameters are: - + | Name | Description | |:----------------|:---------------------------------------------------------------------| | `client_secret` | If client is not authenticated with the authorization server | @@ -304,18 +333,24 @@ Usual extra parameters are: Resource Owner Password Credentials Grant is implemented following [rfc6749](https://tools.ietf.org/html/rfc6749#section-4.3). -Use `httpx_auth.OAuth2ResourceOwnerPasswordCredentials` to configure this kind of authentication. +Use `httpx2_auth.OAuth2ResourceOwnerPasswordCredentials` to configure this kind of authentication. ```python -import httpx -from httpx_auth import OAuth2ResourceOwnerPasswordCredentials - -with httpx.Client() as client: - client.get('https://www.example.com', auth=OAuth2ResourceOwnerPasswordCredentials('https://www.token.url', 'user name', 'user password')) +import httpx2 +from httpx2_auth import OAuth2ResourceOwnerPasswordCredentials + +with httpx2.Client() as client: + client.get( + "https://www.example.com", + auth=OAuth2ResourceOwnerPasswordCredentials( + "https://www.token.url", "user name", "user password" + ), + ) ``` Note: -* You can persist tokens thanks to [the token cache](#managing-token-cache). + +- You can persist tokens thanks to [the token cache](#managing-token-cache). #### Parameters @@ -324,14 +359,14 @@ Note: | `token_url` | OAuth 2 token URL. | Mandatory | | | `username` | Resource owner user name. | Mandatory | | | `password` | Resource owner password. | Mandatory | | -| `client_auth` | Client authentication if the client type is confidential or the client was issued client credentials (or assigned other authentication requirements). Can be a tuple or any httpx authentication class instance. | Optional | | +| `client_auth` | Client authentication if the client type is confidential or the client was issued client credentials (or assigned other authentication requirements). Can be a tuple or any httpx2 authentication class instance. | Optional | | | `timeout` | Maximum amount of seconds to wait for a token to be received once requested. | Optional | 60 | | `header_name` | Name of the header field used to send token. | Optional | Authorization | | `header_value` | Format used to send the token value. "{token}" must be present as it will be replaced by the actual token. | Optional | Bearer {token} | | `scope` | Scope parameter sent to token URL as body. Can also be a list of scopes. | Optional | | | `token_field_name` | Field name containing the token. | Optional | access_token | | `early_expiry` | Number of seconds before actual token expiry where token will be considered as expired. Used to ensure token will not expire between the time of retrieval and the time the request reaches the actual server. Set it to 0 to deactivate this feature and use the same token until actual expiry. | Optional | 30.0 | -| `client` | `httpx.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | | +| `client` | `httpx2.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | | Any other parameter will be put as body parameter in the token URL. @@ -339,26 +374,32 @@ Any other parameter will be put as body parameter in the token URL. Most of [OAuth2](https://oauth.net/2/) Resource Owner Password Credentials providers are supported. -If the one you are looking for is not yet supported, feel free to [ask for its implementation](https://github.com/Colin-b/httpx_auth/issues/new). +If the one you are looking for is not yet supported, feel free to [ask for its implementation](https://github.com/SemanticMatter/httpx2_auth/issues/new). ##### Okta (OAuth2 Resource Owner Password Credentials) [Okta Resource Owner Password Credentials](https://developer.okta.com/docs/guides/implement-grant-type/ropassword/main/) providing access tokens is supported. -Use `httpx_auth.OktaResourceOwnerPasswordCredentials` to configure this kind of authentication. +Use `httpx2_auth.OktaResourceOwnerPasswordCredentials` to configure this kind of authentication. ```python -import httpx -from httpx_auth import OktaResourceOwnerPasswordCredentials - - -okta = OktaResourceOwnerPasswordCredentials(instance='testserver.okta-emea.com', username='user name', password='user password', client_id='54239d18-c68c-4c47-8bdd-ce71ea1d50cd', client_secret="0c5MB") -with httpx.Client() as client: - client.get('https://www.example.com', auth=okta) +import httpx2 +from httpx2_auth import OktaResourceOwnerPasswordCredentials + +okta = OktaResourceOwnerPasswordCredentials( + instance="testserver.okta-emea.com", + username="user name", + password="user password", + client_id="54239d18-c68c-4c47-8bdd-ce71ea1d50cd", + client_secret="0c5MB", +) +with httpx2.Client() as client: + client.get("https://www.example.com", auth=okta) ``` Note: -* You can persist tokens thanks to [the token cache](#managing-token-cache). + +- You can persist tokens thanks to [the token cache](#managing-token-cache). ###### Parameters @@ -375,27 +416,32 @@ Note: | `scope` | Scope parameter sent in query. Can also be a list of scopes. | Optional | openid | | `token_field_name` | Field name containing the token. | Optional | access_token | | `early_expiry` | Number of seconds before actual token expiry where token will be considered as expired. Used to ensure token will not expire between the time of retrieval and the time the request reaches the actual server. Set it to 0 to deactivate this feature and use the same token until actual expiry. | Optional | 30.0 | -| `client` | `httpx.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | | +| `client` | `httpx2.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | | Any other parameter will be put as body parameters in the token URL. - ### Client Credentials flow Client Credentials Grant is implemented following [rfc6749](https://tools.ietf.org/html/rfc6749#section-4.4). -Use `httpx_auth.OAuth2ClientCredentials` to configure this kind of authentication. +Use `httpx2_auth.OAuth2ClientCredentials` to configure this kind of authentication. ```python -import httpx -from httpx_auth import OAuth2ClientCredentials - -with httpx.Client() as client: - client.get('https://www.example.com', auth=OAuth2ClientCredentials('https://www.token.url', client_id='id', client_secret='secret')) +import httpx2 +from httpx2_auth import OAuth2ClientCredentials + +with httpx2.Client() as client: + client.get( + "https://www.example.com", + auth=OAuth2ClientCredentials( + "https://www.token.url", client_id="id", client_secret="secret" + ), + ) ``` Note: -* You can persist tokens thanks to [the token cache](#managing-token-cache). + +- You can persist tokens thanks to [the token cache](#managing-token-cache). #### Parameters @@ -410,7 +456,7 @@ Note: | `scope` | Scope parameter sent to token URL as body. Can also be a list of scopes. | Optional | | | `token_field_name` | Field name containing the token. | Optional | access_token | | `early_expiry` | Number of seconds before actual token expiry where token will be considered as expired. Used to ensure token will not expire between the time of retrieval and the time the request reaches the actual server. Set it to 0 to deactivate this feature and use the same token until actual expiry. | Optional | 30.0 | -| `client` | `httpx.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | | +| `client` | `httpx2.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | | Any other parameter will be put as body parameter in the token URL. @@ -418,26 +464,31 @@ Any other parameter will be put as body parameter in the token URL. Most of [OAuth2](https://oauth.net/2/) Client Credentials Grant providers are supported. -If the one you are looking for is not yet supported, feel free to [ask for its implementation](https://github.com/Colin-b/httpx_auth/issues/new). +If the one you are looking for is not yet supported, feel free to [ask for its implementation](https://github.com/SemanticMatter/httpx2_auth/issues/new). ##### Okta (OAuth2 Client Credentials) [Okta Client Credentials Grant](https://developer.okta.com/docs/guides/implement-grant-type/clientcreds/main/) providing access tokens is supported. -Use `httpx_auth.OktaClientCredentials` to configure this kind of authentication. +Use `httpx2_auth.OktaClientCredentials` to configure this kind of authentication. ```python -import httpx -from httpx_auth import OktaClientCredentials - - -okta = OktaClientCredentials(instance='testserver.okta-emea.com', client_id='54239d18-c68c-4c47-8bdd-ce71ea1d50cd', client_secret="secret", scope=["scope1", "scope2"]) -with httpx.Client() as client: - client.get('https://www.example.com', auth=okta) +import httpx2 +from httpx2_auth import OktaClientCredentials + +okta = OktaClientCredentials( + instance="testserver.okta-emea.com", + client_id="54239d18-c68c-4c47-8bdd-ce71ea1d50cd", + client_secret="secret", + scope=["scope1", "scope2"], +) +with httpx2.Client() as client: + client.get("https://www.example.com", auth=okta) ``` Note: -* You can persist tokens thanks to [the token cache](#managing-token-cache). + +- You can persist tokens thanks to [the token cache](#managing-token-cache). ###### Parameters @@ -453,27 +504,30 @@ Note: | `header_value` | Format used to send the token value. "{token}" must be present as it will be replaced by the actual token. | Optional | Bearer {token} | | `token_field_name` | Field name containing the token. | Optional | access_token | | `early_expiry` | Number of seconds before actual token expiry where token will be considered as expired. Used to ensure token will not expire between the time of retrieval and the time the request reaches the actual server. Set it to 0 to deactivate this feature and use the same token until actual expiry. | Optional | 30.0 | -| `client` | `httpx.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | | +| `client` | `httpx2.Client` instance that will be used to request the token. Use it to provide a custom proxying rule for instance. | Optional | | -Any other parameter will be put as query parameter in the token URL. +Any other parameter will be put as query parameter in the token URL. ### Implicit flow Implicit Grant is implemented following [rfc6749](https://tools.ietf.org/html/rfc6749#section-4.2). -Use `httpx_auth.OAuth2Implicit` to configure this kind of authentication. +Use `httpx2_auth.OAuth2Implicit` to configure this kind of authentication. ```python -import httpx -from httpx_auth import OAuth2Implicit +import httpx2 +from httpx2_auth import OAuth2Implicit -with httpx.Client() as client: - client.get('https://www.example.com', auth=OAuth2Implicit('https://www.authorization.url')) +with httpx2.Client() as client: + client.get( + "https://www.example.com", auth=OAuth2Implicit("https://www.authorization.url") + ) ``` Note: -* You can persist tokens thanks to [the token cache](#managing-token-cache). -* You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). + +- You can persist tokens thanks to [the token cache](#managing-token-cache). +- You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). #### Parameters @@ -490,10 +544,10 @@ Note: | `header_name` | Name of the header field used to send token. | Optional | Authorization | | `header_value` | Format used to send the token value. "{token}" must be present as it will be replaced by the actual token. | Optional | Bearer {token} | -Any other parameter will be put as query parameter in the authorization URL. +Any other parameter will be put as query parameter in the authorization URL. Usual extra parameters are: - + | Name | Description | |:----------------|:---------------------------------------------------------------------| | `client_id` | Corresponding to your Application ID (in Microsoft Azure app portal) | @@ -504,27 +558,30 @@ Usual extra parameters are: Most of [OAuth2](https://oauth.net/2/) Implicit Grant providers are supported. -If the one you are looking for is not yet supported, feel free to [ask for its implementation](https://github.com/Colin-b/httpx_auth/issues/new). +If the one you are looking for is not yet supported, feel free to [ask for its implementation](https://github.com/SemanticMatter/httpx2_auth/issues/new). ##### Microsoft - Azure Active Directory (OAuth2 Access Token) [Microsoft identity platform access tokens](https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens) are supported. -Use `httpx_auth.AzureActiveDirectoryImplicit` to configure this kind of authentication. +Use `httpx2_auth.AzureActiveDirectoryImplicit` to configure this kind of authentication. ```python -import httpx -from httpx_auth import AzureActiveDirectoryImplicit - - -aad = AzureActiveDirectoryImplicit(tenant_id='45239d18-c68c-4c47-8bdd-ce71ea1d50cd', client_id='54239d18-c68c-4c47-8bdd-ce71ea1d50cd') -with httpx.Client() as client: - client.get('https://www.example.com', auth=aad) +import httpx2 +from httpx2_auth import AzureActiveDirectoryImplicit + +aad = AzureActiveDirectoryImplicit( + tenant_id="45239d18-c68c-4c47-8bdd-ce71ea1d50cd", + client_id="54239d18-c68c-4c47-8bdd-ce71ea1d50cd", +) +with httpx2.Client() as client: + client.get("https://www.example.com", auth=aad) ``` Note: -* You can persist tokens thanks to [the token cache](#managing-token-cache). -* You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). + +- You can persist tokens thanks to [the token cache](#managing-token-cache). +- You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). You can retrieve Microsoft Azure Active Directory application information thanks to the [application list on Azure portal](https://portal.azure.com/#blade/Microsoft_AAD_IAM/StartboardApplicationsMenuBlade/AllApps/menuId/). @@ -545,10 +602,10 @@ You can retrieve Microsoft Azure Active Directory application information thanks | `header_name` | Name of the header field used to send token. | Optional | Authorization | | `header_value` | Format used to send the token value. "{token}" must be present as it will be replaced by the actual token. | Optional | Bearer {token} | -Any other parameter will be put as query parameter in the authorization URL. +Any other parameter will be put as query parameter in the authorization URL. Usual extra parameters are: - + | Name | Description | |:----------------|:---------------------------------------------------------------------| | `prompt` | none to avoid prompting the user if a session is already opened. | @@ -557,21 +614,24 @@ Usual extra parameters are: [Microsoft identity platform ID tokens](https://docs.microsoft.com/en-us/azure/active-directory/develop/id-tokens) are supported. -Use `httpx_auth.AzureActiveDirectoryImplicitIdToken` to configure this kind of authentication. +Use `httpx2_auth.AzureActiveDirectoryImplicitIdToken` to configure this kind of authentication. ```python -import httpx -from httpx_auth import AzureActiveDirectoryImplicitIdToken - - -aad = AzureActiveDirectoryImplicitIdToken(tenant_id='45239d18-c68c-4c47-8bdd-ce71ea1d50cd', client_id='54239d18-c68c-4c47-8bdd-ce71ea1d50cd') -with httpx.Client() as client: - client.get('https://www.example.com', auth=aad) +import httpx2 +from httpx2_auth import AzureActiveDirectoryImplicitIdToken + +aad = AzureActiveDirectoryImplicitIdToken( + tenant_id="45239d18-c68c-4c47-8bdd-ce71ea1d50cd", + client_id="54239d18-c68c-4c47-8bdd-ce71ea1d50cd", +) +with httpx2.Client() as client: + client.get("https://www.example.com", auth=aad) ``` Note: -* You can persist tokens thanks to [the token cache](#managing-token-cache). -* You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). + +- You can persist tokens thanks to [the token cache](#managing-token-cache). +- You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). You can retrieve Microsoft Azure Active Directory application information thanks to the [application list on Azure portal](https://portal.azure.com/#blade/Microsoft_AAD_IAM/StartboardApplicationsMenuBlade/AllApps/menuId/). @@ -592,10 +652,10 @@ You can retrieve Microsoft Azure Active Directory application information thanks | `header_name` | Name of the header field used to send token. | Optional | Authorization | | `header_value` | Format used to send the token value. "{token}" must be present as it will be replaced by the actual token. | Optional | Bearer {token} | -Any other parameter will be put as query parameter in the authorization URL. +Any other parameter will be put as query parameter in the authorization URL. Usual extra parameters are: - + | Name | Description | |:----------------|:---------------------------------------------------------------------| | `prompt` | none to avoid prompting the user if a session is already opened. | @@ -604,21 +664,24 @@ Usual extra parameters are: [Okta Implicit Grant](https://developer.okta.com/docs/guides/implement-implicit/overview/) providing access tokens is supported. -Use `httpx_auth.OktaImplicit` to configure this kind of authentication. +Use `httpx2_auth.OktaImplicit` to configure this kind of authentication. ```python -import httpx -from httpx_auth import OktaImplicit - - -okta = OktaImplicit(instance='testserver.okta-emea.com', client_id='54239d18-c68c-4c47-8bdd-ce71ea1d50cd') -with httpx.Client() as client: - client.get('https://www.example.com', auth=okta) +import httpx2 +from httpx2_auth import OktaImplicit + +okta = OktaImplicit( + instance="testserver.okta-emea.com", + client_id="54239d18-c68c-4c47-8bdd-ce71ea1d50cd", +) +with httpx2.Client() as client: + client.get("https://www.example.com", auth=okta) ``` Note: -* You can persist tokens thanks to [the token cache](#managing-token-cache). -* You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). + +- You can persist tokens thanks to [the token cache](#managing-token-cache). +- You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). ###### Parameters @@ -639,10 +702,10 @@ Note: | `header_name` | Name of the header field used to send token. | Optional | Authorization | | `header_value` | Format used to send the token value. "{token}" must be present as it will be replaced by the actual token. | Optional | Bearer {token} | -Any other parameter will be put as query parameter in the authorization URL. +Any other parameter will be put as query parameter in the authorization URL. Usual extra parameters are: - + | Name | Description | |:----------------|:---------------------------------------------------------------------| | `prompt` | none to avoid prompting the user if a session is already opened. | @@ -651,21 +714,24 @@ Usual extra parameters are: [Okta Implicit Grant](https://developer.okta.com/docs/guides/implement-implicit/overview/) providing ID tokens is supported. -Use `httpx_auth.OktaImplicitIdToken` to configure this kind of authentication. +Use `httpx2_auth.OktaImplicitIdToken` to configure this kind of authentication. ```python -import httpx -from httpx_auth import OktaImplicitIdToken - - -okta = OktaImplicitIdToken(instance='testserver.okta-emea.com', client_id='54239d18-c68c-4c47-8bdd-ce71ea1d50cd') -with httpx.Client() as client: - client.get('https://www.example.com', auth=okta) +import httpx2 +from httpx2_auth import OktaImplicitIdToken + +okta = OktaImplicitIdToken( + instance="testserver.okta-emea.com", + client_id="54239d18-c68c-4c47-8bdd-ce71ea1d50cd", +) +with httpx2.Client() as client: + client.get("https://www.example.com", auth=okta) ``` Note: -* You can persist tokens thanks to [the token cache](#managing-token-cache). -* You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). + +- You can persist tokens thanks to [the token cache](#managing-token-cache). +- You can tweak web browser interaction thanks to [the display settings](#managing-the-web-browser). ###### Parameters @@ -686,10 +752,10 @@ Note: | `header_name` | Name of the header field used to send token. | Optional | Authorization | | `header_value` | Format used to send the token value. "{token}" must be present as it will be replaced by the actual token. | Optional | Bearer {token} | -Any other parameter will be put as query parameter in the authorization URL. +Any other parameter will be put as query parameter in the authorization URL. Usual extra parameters are: - + | Name | Description | |:----------------|:---------------------------------------------------------------------| | `prompt` | none to avoid prompting the user if a session is already opened. | @@ -705,18 +771,19 @@ You need to provide the location of your token cache file. It can be a full or r If the file already exists it will be used, if the file do not exist it will be created. ```python -from httpx_auth import OAuth2, JsonTokenFileCache +from httpx2_auth import OAuth2, JsonTokenFileCache -OAuth2.token_cache = JsonTokenFileCache('path/to/my_token_cache.json') +OAuth2.token_cache = JsonTokenFileCache("path/to/my_token_cache.json") ``` ### Managing the web browser #### Authentication response pages -You can configure the browser display settings thanks to `httpx_auth.OAuth2.display` as in the following: +You can configure the browser display settings thanks to `httpx2_auth.OAuth2.display` as in the following: + ```python -from httpx_auth import OAuth2, DisplaySettings +from httpx2_auth import OAuth2, DisplaySettings OAuth2.display = DisplaySettings() ``` @@ -732,7 +799,7 @@ The following parameters can be provided to `DisplaySettings`: #### Text-mode web browser -This project uses [`webbrowser.open()`][4] to open a web browser to support authentication flows like OAuth's Authorization Code grant. When running graphically, `webbrowser.open()` does not block. But when run in text mode, `webbrowser.open()` blocks until the opened browser is closed, which leads to a deadlock when httpx-auth cannot serve the auth response pages to the webbrowser. To work around this, you can specify a `BROWSER` environment variable that contains a `%s` and ends with a `&`, and the `webbrowser` module will open the text-mode browser in a subprocess and allow httpx-auth to serve the auth response pages to the browser without deadlocking. +This project uses [`webbrowser.open()`][4] to open a web browser to support authentication flows like OAuth's Authorization Code grant. When running graphically, `webbrowser.open()` does not block. But when run in text mode, `webbrowser.open()` blocks until the opened browser is closed, which leads to a deadlock when httpx2-auth cannot serve the auth response pages to the webbrowser. To work around this, you can specify a `BROWSER` environment variable that contains a `%s` and ends with a `&`, and the `webbrowser` module will open the text-mode browser in a subprocess and allow httpx2-auth to serve the auth response pages to the browser without deadlocking. ```bash BROWSER="/usr/bin/links %s &" @@ -744,31 +811,37 @@ For more information, please see the implementation of [`webbrowser.get()`][5]. Amazon Web Service Signature version 4 is implemented following [Amazon S3 documentation](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html) and [request-aws4auth 1.2.3](https://github.com/sam-washington/requests-aws4auth) (with some changes, see below). -Use `httpx_auth.AWS4Auth` to configure this kind of authentication. +Use `httpx2_auth.AWS4Auth` to configure this kind of authentication. ```python -import httpx -from httpx_auth import AWS4Auth - -aws = AWS4Auth(access_id="my-access-id", secret_key="my-secret-key", region="eu-west-1", service="s3") -with httpx.Client() as client: - client.get('http://s3-eu-west-1.amazonaws.com', auth=aws) +import httpx2 +from httpx2_auth import AWS4Auth + +aws = AWS4Auth( + access_id="my-access-id", + secret_key="my-secret-key", + region="eu-west-1", + service="s3", +) +with httpx2.Client() as client: + client.get("http://s3-eu-west-1.amazonaws.com", auth=aws) ``` Note that the following changes were made compared to `requests-aws4auth`: - - Each request now has its own signing key and `x-amz-date`. Meaning **you can use the same auth instance for more than one request**. - - `session_token` was renamed into `security_token` for consistency with the underlying name at Amazon. - - `include_hdrs` parameter was renamed into `include_headers`. When using this parameter: - - Provided values will not be stripped, [WYSIWYG](https://en.wikipedia.org/wiki/WYSIWYG). - - If multiple values are provided for a same header, the computation will be based on the value order you provided and value separated by `, `. Instead of ordered values separated by comma for `requests-aws4auth`. - - `amz_date` attribute has been removed. - - It is not possible to provide a `date`. It will default to now. - - It is not possible to provide an `AWSSigningKey` instance, use explicit parameters instead. - - It is not possible to provide `raise_invalid_date` parameter anymore as the date will always be valid. - - `host` is not considered as a specific Amazon service anymore (no test specific code). - - Canonical query string computation is entirely based on AWS documentation (and consider undocumented fragment (`#` and following characters) as part of the query string). - - Canonical uri computation is entirely based on AWS documentation. - - Canonical headers computation is entirely based on AWS documentation. + +- Each request now has its own signing key and `x-amz-date`. Meaning **you can use the same auth instance for more than one request**. +- `session_token` was renamed into `security_token` for consistency with the underlying name at Amazon. +- `include_hdrs` parameter was renamed into `include_headers`. When using this parameter: + - Provided values will not be stripped, [WYSIWYG](https://en.wikipedia.org/wiki/WYSIWYG). + - If multiple values are provided for a same header, the computation will be based on the value order you provided and value separated by `,`. Instead of ordered values separated by comma for `requests-aws4auth`. +- `amz_date` attribute has been removed. +- It is not possible to provide a `date`. It will default to now. +- It is not possible to provide an `AWSSigningKey` instance, use explicit parameters instead. +- It is not possible to provide `raise_invalid_date` parameter anymore as the date will always be valid. +- `host` is not considered as a specific Amazon service anymore (no test specific code). +- Canonical query string computation is entirely based on AWS documentation (and consider undocumented fragment (`#` and following characters) as part of the query string). +- Canonical uri computation is entirely based on AWS documentation. +- Canonical headers computation is entirely based on AWS documentation. ### Parameters @@ -783,17 +856,25 @@ Note that the following changes were made compared to `requests-aws4auth`: ### Dynamically retrieving credentials using boto3 -While `httpx-auth` does not want to include support for `botocore`, the following authentication class should allow you to automatically retrieve up-to-date credentials. +While `httpx2-auth` does not want to include support for `botocore`, the following authentication class should allow you to automatically retrieve up-to-date credentials. ```python -import httpx +import httpx2 from botocore.session import Session -from httpx_auth import AWS4Auth +from httpx2_auth import AWS4Auth + class AWS4BotoAuth(AWS4Auth): def __init__(self, region: str, service: str = "s3", **kwargs): self.refreshable_credentials = Session().get_credentials() - AWS4Auth.__init__(self, access_id=kwargs.pop("access_id", "_"), secret_key=kwargs.pop("secret_key", "_"), region=region, service=service, **kwargs) + AWS4Auth.__init__( + self, + access_id=kwargs.pop("access_id", "_"), + secret_key=kwargs.pop("secret_key", "_"), + region=region, + service=service, + **kwargs + ) def auth_flow(self, request): self.refresh_credentials() @@ -807,20 +888,20 @@ class AWS4BotoAuth(AWS4Auth): aws = AWS4BotoAuth(region="eu-west-1") -with httpx.Client() as client: - client.get('http://s3-eu-west-1.amazonaws.com', auth=aws) +with httpx2.Client() as client: + client.get("http://s3-eu-west-1.amazonaws.com", auth=aws) ``` ## API key in header -You can send an API key inside the header of your request using `httpx_auth.HeaderApiKey`. +You can send an API key inside the header of your request using `httpx2_auth.HeaderApiKey`. ```python -import httpx -from httpx_auth import HeaderApiKey +import httpx2 +from httpx2_auth import HeaderApiKey -with httpx.Client() as client: - client.get('https://www.example.com', auth=HeaderApiKey('my_api_key')) +with httpx2.Client() as client: + client.get("https://www.example.com", auth=HeaderApiKey("my_api_key")) ``` ### Parameters @@ -832,14 +913,14 @@ with httpx.Client() as client: ## API key in query -You can send an API key inside the query parameters of your request using `httpx_auth.QueryApiKey`. +You can send an API key inside the query parameters of your request using `httpx2_auth.QueryApiKey`. ```python -import httpx -from httpx_auth import QueryApiKey +import httpx2 +from httpx2_auth import QueryApiKey -with httpx.Client() as client: - client.get('https://www.example.com', auth=QueryApiKey('my_api_key')) +with httpx2.Client() as client: + client.get("https://www.example.com", auth=QueryApiKey("my_api_key")) ``` ### Parameters @@ -851,16 +932,16 @@ with httpx.Client() as client: ## Basic -You can use basic authentication using `httpx_auth.Basic`. +You can use basic authentication using `httpx2_auth.Basic`. -The only advantage of using this class instead of `httpx` native support of basic authentication, is to be able to use it in [multiple authentication](#multiple-authentication-at-once). +The only advantage of using this class instead of `httpx2` native support of basic authentication, is to be able to use it in [multiple authentication](#multiple-authentication-at-once). ```python -import httpx -from httpx_auth import Basic +import httpx2 +from httpx2_auth import Basic -with httpx.Client() as client: - client.get('https://www.example.com', auth=Basic('username', 'password')) +with httpx2.Client() as client: + client.get("https://www.example.com", auth=Basic("username", "password")) ``` ### Parameters @@ -875,35 +956,37 @@ with httpx.Client() as client: You can also use a combination of authentication using `+`or `&` as in the following sample: ```python -import httpx -from httpx_auth import HeaderApiKey, OAuth2Implicit +import httpx2 +from httpx2_auth import HeaderApiKey, OAuth2Implicit -api_key = HeaderApiKey('my_api_key') -oauth2 = OAuth2Implicit('https://www.example.com') -with httpx.Client() as client: - client.get('https://www.example.com', auth=api_key + oauth2) +api_key = HeaderApiKey("my_api_key") +oauth2 = OAuth2Implicit("https://www.example.com") +with httpx2.Client() as client: + client.get("https://www.example.com", auth=api_key + oauth2) ``` -This is supported on every authentication class exposed by `httpx_auth`, but you can also enable it on your own authentication classes by using `httpx_auth.SupportMultiAuth` as in the following sample: +This is supported on every authentication class exposed by `httpx2_auth`, but you can also enable it on your own authentication classes by using `httpx2_auth.SupportMultiAuth` as in the following sample: ```python -from httpx_auth import SupportMultiAuth +from httpx2_auth import SupportMultiAuth + # TODO Import your own auth here from my_package import MyAuth + class MyMultiAuth(MyAuth, SupportMultiAuth): pass ``` - ## Available pytest fixtures -Testing the code using `httpx_auth` authentication classes can be achieved using provided [`pytest`][6] fixtures. +Testing the code using `httpx2_auth` authentication classes can be achieved using provided [`pytest`][6] fixtures. ### token_cache_mock ```python -from httpx_auth.testing import token_cache_mock, token_mock +from httpx2_auth.testing import token_cache_mock, token_mock + def test_something(token_cache_mock): # perform code using authentication @@ -911,20 +994,21 @@ def test_something(token_cache_mock): ``` Use this fixture to mock authentication success for any of the following classes: - * `OAuth2AuthorizationCodePKCE` - * `OktaAuthorizationCodePKCE` - * `OAuth2Implicit` - * `OktaImplicit` - * `OktaImplicitIdToken` - * `AzureActiveDirectoryImplicit` - * `AzureActiveDirectoryImplicitIdToken` - * `OAuth2AuthorizationCode` - * `OktaAuthorizationCode` - * `WakaTimeAuthorizationCode` - * `OAuth2ClientCredentials` - * `OktaClientCredentials` - * `OAuth2ResourceOwnerPasswordCredentials` - * `OktaResourceOwnerPasswordCredentials` + +- `OAuth2AuthorizationCodePKCE` +- `OktaAuthorizationCodePKCE` +- `OAuth2Implicit` +- `OktaImplicit` +- `OktaImplicitIdToken` +- `AzureActiveDirectoryImplicit` +- `AzureActiveDirectoryImplicitIdToken` +- `OAuth2AuthorizationCode` +- `OktaAuthorizationCode` +- `WakaTimeAuthorizationCode` +- `OAuth2ClientCredentials` +- `OktaClientCredentials` +- `OAuth2ResourceOwnerPasswordCredentials` +- `OktaResourceOwnerPasswordCredentials` By default, an access token with value `2YotnFZFEjr1zCsicMWpAA` is generated. @@ -933,7 +1017,7 @@ You can however return your custom token by providing your own `token_mock` fixt ```python import pytest -from httpx_auth.testing import token_cache_mock +from httpx2_auth.testing import token_cache_mock @pytest.fixture @@ -952,7 +1036,7 @@ Note that [`pyjwt`](https://pypi.org/project/PyJWT/) is a required dependency in ```python import pytest -from httpx_auth.testing import token_cache_mock, create_token +from httpx2_auth.testing import token_cache_mock, create_token @pytest.fixture @@ -973,7 +1057,8 @@ def test_something(token_cache_mock): This [`pytest`][6] fixture will return the token cache and ensure it is reset at the end of the test case. ```python -from httpx_auth.testing import token_cache +from httpx2_auth.testing import token_cache + def test_something(token_cache): # perform code using authentication @@ -991,10 +1076,13 @@ With this [`pytest`][6] fixture you will be allowed to fine tune your authentica ```python import datetime -from httpx_auth.testing import browser_mock, BrowserMock, create_token +from httpx2_auth.testing import browser_mock, BrowserMock, create_token + def test_something(browser_mock: BrowserMock): - token_expiry = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) + token_expiry = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta( + hours=1 + ) token = create_token(token_expiry) tab = browser_mock.add_response( opened_url="http://url_opened_by_browser?state=1234", diff --git a/_config.yml b/_config.yml deleted file mode 100644 index c419263..0000000 --- a/_config.yml +++ /dev/null @@ -1 +0,0 @@ -theme: jekyll-theme-cayman \ No newline at end of file diff --git a/httpx_auth/__init__.py b/httpx2_auth/__init__.py similarity index 59% rename from httpx_auth/__init__.py rename to httpx2_auth/__init__.py index b948ba1..8af5b38 100644 --- a/httpx_auth/__init__.py +++ b/httpx2_auth/__init__.py @@ -1,80 +1,88 @@ -from httpx_auth._authentication import ( +from httpx2_auth._authentication import ( Basic, HeaderApiKey, QueryApiKey, SupportMultiAuth, ) -from httpx_auth._oauth2.browser import DisplaySettings -from httpx_auth._oauth2.common import OAuth2 -from httpx_auth._oauth2.authorization_code import ( +from httpx2_auth._aws import AWS4Auth +from httpx2_auth._errors import ( + AuthenticationFailed, + GrantNotProvided, + HttpxAuthException, + InvalidGrantRequest, + InvalidToken, + StateNotProvided, + TimeoutOccurred, + TokenExpiryNotProvided, +) +from httpx2_auth._oauth2.authorization_code import ( OAuth2AuthorizationCode, OktaAuthorizationCode, WakaTimeAuthorizationCode, ) -from httpx_auth._oauth2.authorization_code_pkce import ( +from httpx2_auth._oauth2.authorization_code_pkce import ( OAuth2AuthorizationCodePKCE, OktaAuthorizationCodePKCE, ) -from httpx_auth._oauth2.client_credentials import ( +from httpx2_auth._oauth2.browser import DisplaySettings +from httpx2_auth._oauth2.client_credentials import ( OAuth2ClientCredentials, OktaClientCredentials, ) -from httpx_auth._oauth2.implicit import ( +from httpx2_auth._oauth2.common import OAuth2 +from httpx2_auth._oauth2.implicit import ( + AzureActiveDirectoryImplicit, + AzureActiveDirectoryImplicitIdToken, OAuth2Implicit, OktaImplicit, OktaImplicitIdToken, - AzureActiveDirectoryImplicit, - AzureActiveDirectoryImplicitIdToken, ) -from httpx_auth._oauth2.resource_owner_password import ( +from httpx2_auth._oauth2.resource_owner_password import ( OAuth2ResourceOwnerPasswordCredentials, OktaResourceOwnerPasswordCredentials, ) -from httpx_auth._oauth2.tokens import JsonTokenFileCache, TokenMemoryCache -from httpx_auth._aws import AWS4Auth -from httpx_auth._errors import ( - GrantNotProvided, - TimeoutOccurred, - AuthenticationFailed, - StateNotProvided, - InvalidToken, - TokenExpiryNotProvided, - InvalidGrantRequest, - HttpxAuthException, -) -from httpx_auth.version import __version__ +from httpx2_auth._oauth2.tokens import JsonTokenFileCache, TokenMemoryCache __all__ = [ + "AWS4Auth", + "AuthenticationFailed", + "AzureActiveDirectoryImplicit", + "AzureActiveDirectoryImplicitIdToken", "Basic", + "DisplaySettings", + "GrantNotProvided", "HeaderApiKey", - "QueryApiKey", + "HttpxAuthException", + "InvalidGrantRequest", + "InvalidToken", + "JsonTokenFileCache", "OAuth2", - "DisplaySettings", + "OAuth2AuthorizationCode", "OAuth2AuthorizationCodePKCE", - "OktaAuthorizationCodePKCE", + "OAuth2ClientCredentials", "OAuth2Implicit", - "OktaImplicit", - "OktaImplicitIdToken", - "AzureActiveDirectoryImplicit", - "AzureActiveDirectoryImplicitIdToken", - "OAuth2AuthorizationCode", + "OAuth2ResourceOwnerPasswordCredentials", "OktaAuthorizationCode", - "OAuth2ClientCredentials", + "OktaAuthorizationCodePKCE", "OktaClientCredentials", - "OAuth2ResourceOwnerPasswordCredentials", + "OktaImplicit", + "OktaImplicitIdToken", "OktaResourceOwnerPasswordCredentials", - "WakaTimeAuthorizationCode", + "QueryApiKey", + "StateNotProvided", "SupportMultiAuth", - "JsonTokenFileCache", - "TokenMemoryCache", - "AWS4Auth", - "HttpxAuthException", - "GrantNotProvided", "TimeoutOccurred", - "AuthenticationFailed", - "StateNotProvided", - "InvalidToken", "TokenExpiryNotProvided", - "InvalidGrantRequest", + "TokenMemoryCache", + "WakaTimeAuthorizationCode", "__version__", ] + +# Version number as Major.Minor.Patch +# The version modification must respect the following rules: +# Major should be incremented in case there is a breaking change. (eg: 2.5.8 -> 3.0.0) +# Minor should be incremented in case there is an enhancement. (eg: 2.5.8 -> 2.6.0) +# Patch should be incremented in case there is a bug fix. (eg: 2.5.8 -> 2.5.9) + +# Started epoch 2 to be able to use distinct version numbers for the first release of httpx2_auth, which is compatible with httpx2. +__version__ = "2.0.1.0" diff --git a/httpx_auth/_authentication.py b/httpx2_auth/_authentication.py similarity index 72% rename from httpx_auth/_authentication.py rename to httpx2_auth/_authentication.py index f251bff..7b0c15a 100644 --- a/httpx_auth/_authentication.py +++ b/httpx2_auth/_authentication.py @@ -1,17 +1,17 @@ -from typing import Generator +from collections.abc import Generator -import httpx +import httpx2 -class _MultiAuth(httpx.Auth): +class _MultiAuth(httpx2.Auth): """Authentication using multiple authentication methods.""" def __init__(self, *authentication_modes): self.authentication_modes = authentication_modes def auth_flow( - self, request: httpx.Request - ) -> Generator[httpx.Request, httpx.Response, None]: + self, request: httpx2.Request + ) -> Generator[httpx2.Request, httpx2.Response, None]: for authentication_mode in self.authentication_modes: next(authentication_mode.auth_flow(request)) yield request @@ -28,7 +28,7 @@ def __and__(self, other) -> "_MultiAuth": class SupportMultiAuth: - """Inherit from this class to be able to use your class with httpx_auth provided authentication classes.""" + """Inherit from this class to be able to use your class with httpx2_auth provided authentication classes.""" def __add__(self, other) -> _MultiAuth: if isinstance(other, _MultiAuth): @@ -41,10 +41,10 @@ def __and__(self, other) -> _MultiAuth: return _MultiAuth(self, other) -class HeaderApiKey(httpx.Auth, SupportMultiAuth): +class HeaderApiKey(httpx2.Auth, SupportMultiAuth): """Describes an API Key requests authentication.""" - def __init__(self, api_key: str, header_name: str = None): + def __init__(self, api_key: str, header_name: str | None = None): """ :param api_key: The API key that will be sent. :param header_name: Name of the header field. "X-API-Key" by default. @@ -55,16 +55,16 @@ def __init__(self, api_key: str, header_name: str = None): self.header_name = header_name or "X-API-Key" def auth_flow( - self, request: httpx.Request - ) -> Generator[httpx.Request, httpx.Response, None]: + self, request: httpx2.Request + ) -> Generator[httpx2.Request, httpx2.Response, None]: request.headers[self.header_name] = self.api_key yield request -class QueryApiKey(httpx.Auth, SupportMultiAuth): +class QueryApiKey(httpx2.Auth, SupportMultiAuth): """Describes an API Key requests authentication.""" - def __init__(self, api_key: str, query_parameter_name: str = None): + def __init__(self, api_key: str, query_parameter_name: str | None = None): """ :param api_key: The API key that will be sent. :param query_parameter_name: Name of the query parameter. "api_key" by default. @@ -75,16 +75,14 @@ def __init__(self, api_key: str, query_parameter_name: str = None): self.query_parameter_name = query_parameter_name or "api_key" def auth_flow( - self, request: httpx.Request - ) -> Generator[httpx.Request, httpx.Response, None]: - request.url = request.url.copy_merge_params( - {self.query_parameter_name: self.api_key} - ) + self, request: httpx2.Request + ) -> Generator[httpx2.Request, httpx2.Response, None]: + request.url = request.url.copy_merge_params({self.query_parameter_name: self.api_key}) yield request -class Basic(httpx.BasicAuth, SupportMultiAuth): +class Basic(httpx2.BasicAuth, SupportMultiAuth): """Describes a basic requests authentication.""" def __init__(self, username: str, password: str): - httpx.BasicAuth.__init__(self, username, password) + httpx2.BasicAuth.__init__(self, username, password) diff --git a/httpx_auth/_aws.py b/httpx2_auth/_aws.py similarity index 83% rename from httpx_auth/_aws.py rename to httpx2_auth/_aws.py index 826937a..5d2e669 100644 --- a/httpx_auth/_aws.py +++ b/httpx2_auth/_aws.py @@ -1,29 +1,29 @@ """ Provides code for AWSAuth initially ported to httpx from Sam Washington's requests-aws4auth https://github.com/sam-washington/requests-aws4auth + +Updated to use httpx2 and to be compatible with httpx2_auth multi-authentication system. """ import datetime import hashlib import hmac from collections import defaultdict +from collections.abc import Generator from posixpath import normpath -from typing import Generator from urllib.parse import quote -import httpx +import httpx2 -class AWS4Auth(httpx.Auth): +class AWS4Auth(httpx2.Auth): """ https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html """ requires_request_body = True - def __init__( - self, access_id: str, secret_key: str, region: str, service: str, **kwargs - ): + def __init__(self, access_id: str, secret_key: str, region: str, service: str, **kwargs): """ :param access_id: AWS access ID @@ -51,13 +51,11 @@ def __init__( self.security_token = kwargs.get("security_token") - self.include_headers = { - header.lower() for header in kwargs.get("include_headers", []) - } + self.include_headers = {header.lower() for header in kwargs.get("include_headers", [])} def auth_flow( - self, request: httpx.Request - ) -> Generator[httpx.Request, httpx.Response, None]: + self, request: httpx2.Request + ) -> Generator[httpx2.Request, httpx2.Response, None]: date = datetime.datetime.now(datetime.timezone.utc) # https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html @@ -69,9 +67,7 @@ def auth_flow( # The x-amz-content-sha256 header is required for all AWS Signature Version 4 requests. # It provides a hash of the request payload. # If there is no payload, you must provide the hash of an empty string. - request.headers["x-amz-content-sha256"] = hashlib.sha256( - request.read() - ).hexdigest() + request.headers["x-amz-content-sha256"] = hashlib.sha256(request.read()).hexdigest() # https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html # if you are using temporary security credentials, you need to include x-amz-security-token in your request. @@ -82,9 +78,7 @@ def auth_flow( canonical_headers, signed_headers = canonical_and_signed_headers( request.headers, self.include_headers ) - canonical_request = self._canonical_request( - request, canonical_headers, signed_headers - ) + canonical_request = self._canonical_request(request, canonical_headers, signed_headers) scope = f"{date.strftime('%Y%m%d')}/{self.region}/{self.service}/aws4_request" string_to_sign = _string_to_sign(request, canonical_request, scope) signing_key = _signing_key( @@ -102,7 +96,7 @@ def auth_flow( yield request def _canonical_request( - self, request: httpx.Request, canonical_headers: str, signed_headers: str + self, request: httpx2.Request, canonical_headers: str, signed_headers: str ) -> str: return "\n".join( [ @@ -118,7 +112,7 @@ def _canonical_request( def canonical_and_signed_headers( - headers: httpx.Headers, include_headers: set[str] + headers: httpx2.Headers, include_headers: set[str] ) -> tuple[str, str]: r""" See https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html for more details. @@ -133,7 +127,7 @@ def canonical_and_signed_headers( ... Lowercase()+":"+Trim()+"\n" - >>> canonical_and_signed_headers(httpx.Headers({"X-AMZ-Whatever": " value with spaces "}), include_headers=set()) + >>> canonical_and_signed_headers(httpx2.Headers({"X-AMZ-Whatever": " value with spaces "}), include_headers=set()) ('x-amz-whatever:value with spaces\n', 'x-amz-whatever') The Lowercase() and Trim() functions used in this example are described in the preceding section. @@ -167,7 +161,7 @@ def canonical_and_signed_headers( For example, for the previous example, the value of SignedHeaders would be as follows: host;x-amz-content-sha256;x-amz-date - >>> canonical_and_signed_headers(httpx.Headers({"Host": "s3.amazonaws.com", "x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "x-amz-date": "20130708T220855Z"}), include_headers={"host"}) + >>> canonical_and_signed_headers(httpx2.Headers({"Host": "s3.amazonaws.com", "x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "x-amz-date": "20130708T220855Z"}), include_headers={"host"}) ('host:s3.amazonaws.com\nx-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\nx-amz-date:20130708T220855Z\n', 'host;x-amz-content-sha256;x-amz-date') """ include_headers.add("host") @@ -177,7 +171,7 @@ def canonical_and_signed_headers( if (header or "*") in include_headers or ( header.startswith("x-amz-") # x-amz-client-context break mobile analytics auth if included - and not header == "x-amz-client-context" + and header != "x-amz-client-context" ): included_headers[header] = header_value.strip() @@ -190,14 +184,12 @@ def canonical_and_signed_headers( return canonical_headers, ";".join(signed_headers) -def _string_to_sign(request: httpx.Request, canonical_request: str, scope: str) -> str: +def _string_to_sign(request: httpx2.Request, canonical_request: str, scope: str) -> str: hsh = hashlib.sha256(canonical_request.encode()) - return "\n".join( - ["AWS4-HMAC-SHA256", request.headers["x-amz-date"], scope, hsh.hexdigest()] - ) + return "\n".join(["AWS4-HMAC-SHA256", request.headers["x-amz-date"], scope, hsh.hexdigest()]) -def canonical_uri(url: httpx.URL, is_s3: bool) -> str: +def canonical_uri(url: httpx2.URL, is_s3: bool) -> str: """ See https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html for more details. @@ -209,7 +201,7 @@ def canonical_uri(url: httpx.URL, is_s3: bool) -> str: The URI in the following example, /examplebucket/myphoto.jpg, is the absolute path, and you don't encode the "/" in the absolute path: http://s3.amazonaws.com/examplebucket/myphoto.jpg - >>> canonical_uri(httpx.URL("http://s3.amazonaws.com/examplebucket/myphoto.jpg"), is_s3=False) + >>> canonical_uri(httpx2.URL("http://s3.amazonaws.com/examplebucket/myphoto.jpg"), is_s3=False) '/examplebucket/myphoto.jpg' Note @@ -217,18 +209,18 @@ def canonical_uri(url: httpx.URL, is_s3: bool) -> str: For example, you may have a bucket with an object named "my-object//example//photo.user". Normalizing the path changes the object name in the request to "my-object/example/photo.user". This is an incorrect path for that object. - >>> canonical_uri(httpx.URL("http://s3.amazonaws.com/my-object//example//photo.user"), is_s3=False) + >>> canonical_uri(httpx2.URL("http://s3.amazonaws.com/my-object//example//photo.user"), is_s3=False) '/my-object/example/photo.user' - >>> canonical_uri(httpx.URL("http://s3.amazonaws.com/my-object//example//photo.user"), is_s3=True) + >>> canonical_uri(httpx2.URL("http://s3.amazonaws.com/my-object//example//photo.user"), is_s3=True) '/my-object//example//photo.user' Some limitation that should be covered but not documented by AWS: - Trailing / should be kept - >>> canonical_uri(httpx.URL("http://s3.amazonaws.com/resource/"), is_s3=False) + >>> canonical_uri(httpx2.URL("http://s3.amazonaws.com/resource/"), is_s3=False) '/resource/' - Starting with // should be normalized - >>> canonical_uri(httpx.URL("http://s3.amazonaws.com//resource/"), is_s3=False) + >>> canonical_uri(httpx2.URL("http://s3.amazonaws.com//resource/"), is_s3=False) '/resource/' """ resource = url.path @@ -244,7 +236,7 @@ def canonical_uri(url: httpx.URL, is_s3: bool) -> str: return uri_encode(resource, is_key=True) -def canonical_query_string(url: httpx.URL) -> str: +def canonical_query_string(url: httpx2.URL) -> str: """ See https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html for more details. @@ -261,7 +253,7 @@ def canonical_query_string(url: httpx.URL) -> str: UriEncode("marker")+"="+UriEncode("someMarker")+"&"+ UriEncode("max-keys")+"="+UriEncode("20") + "&" + UriEncode("prefix")+"="+UriEncode("somePrefix") - >>> canonical_query_string(httpx.URL("http://s3.amazonaws.com/examplebucket?prefix=somePrefix&marker=someMarker&max-keys=20")) + >>> canonical_query_string(httpx2.URL("http://s3.amazonaws.com/examplebucket?prefix=somePrefix&marker=someMarker&max-keys=20")) 'marker=someMarker&max-keys=20&prefix=somePrefix' When a request targets a subresource, the corresponding query parameter value will be an empty string (""). @@ -272,11 +264,11 @@ def canonical_query_string(url: httpx.URL) -> str: The CanonicalQueryString in this case is as follows: UriEncode("acl") + "=" + "" - >>> canonical_query_string(httpx.URL("http://s3.amazonaws.com/examplebucket?acl")) + >>> canonical_query_string(httpx2.URL("http://s3.amazonaws.com/examplebucket?acl")) 'acl=' If the URI does not include a '?', there is no query string in the request, and you set the canonical query string to an empty string (""). - >>> canonical_query_string(httpx.URL("http://s3.amazonaws.com/examplebucket")) + >>> canonical_query_string(httpx2.URL("http://s3.amazonaws.com/examplebucket")) '' You will still need to include the "\n". @@ -284,18 +276,18 @@ def canonical_query_string(url: httpx.URL) -> str: Undocumented: As URL fragment are not mentionned in AWS documentation, it is assumed they don't treat it as what it is and part of the query string instead - >>> canonical_query_string(httpx.URL("http://s3.amazonaws.com/examplebucket?#this_will_be_a_parameter=and_its_value")) + >>> canonical_query_string(httpx2.URL("http://s3.amazonaws.com/examplebucket?#this_will_be_a_parameter=and_its_value")) '%23this_will_be_a_parameter=and_its_value' - >>> canonical_query_string(httpx.URL("http://s3.amazonaws.com/examplebucket?#first=1#invalue")) + >>> canonical_query_string(httpx2.URL("http://s3.amazonaws.com/examplebucket?#first=1#invalue")) '%23first=1%23invalue' - >>> canonical_query_string(httpx.URL("http://s3.amazonaws.com/examplebucket?first#=1&#second=invalue&#")) + >>> canonical_query_string(httpx2.URL("http://s3.amazonaws.com/examplebucket?first#=1&#second=invalue&#")) '%23second=invalue&first%23=1' """ if fragment := url.fragment: url_without_fragment = url.copy_with(fragment=None) - return canonical_query_string(httpx.URL(f"{url_without_fragment}%23{fragment}")) + return canonical_query_string(httpx2.URL(f"{url_without_fragment}%23{fragment}")) encoded_params = defaultdict(list) for name, value in url.params.multi_items(): @@ -310,7 +302,7 @@ def canonical_query_string(url: httpx.URL) -> str: def _signing_key(secret_key: str, region: str, service: str, date: str) -> bytes: - init_key = f"AWS4{secret_key}".encode("utf-8") + init_key = f"AWS4{secret_key}".encode() date_key = sign_sha256(init_key, date) region_key = sign_sha256(date_key, region) service_key = sign_sha256(region_key, service) @@ -322,7 +314,7 @@ def sign_sha256(signing_key: bytes, message: str) -> bytes: def uri_encode(value: str, is_key: bool = False) -> str: - """ + r""" See https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html for more details. URI encode every byte. UriEncode() must enforce the following rules: diff --git a/httpx_auth/_errors.py b/httpx2_auth/_errors.py similarity index 92% rename from httpx_auth/_errors.py rename to httpx2_auth/_errors.py index 078fe41..724ec60 100644 --- a/httpx_auth/_errors.py +++ b/httpx2_auth/_errors.py @@ -1,10 +1,10 @@ from json import JSONDecodeError -from typing import Union +from typing import ClassVar -import httpx +import httpx2 -class HttpxAuthException(httpx.HTTPError): ... +class HttpxAuthException(httpx2.HTTPError): ... class AuthenticationFailed(HttpxAuthException): @@ -45,7 +45,7 @@ class InvalidGrantRequest(HttpxAuthException): """ # https://tools.ietf.org/html/rfc6749#section-5.2 - request_errors = { + request_errors: ClassVar[dict[str, str]] = { "invalid_request": "The request is missing a required parameter, includes an unsupported parameter value (other than grant type), repeats a parameter, includes multiple credentials, utilizes more than one mechanism for authenticating the client, or is otherwise malformed.", "invalid_client": 'Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). The authorization server MAY return an HTTP 401 (Unauthorized) status code to indicate which HTTP authentication schemes are supported. If the client attempted to authenticate via the "Authorization" request header field, the authorization server MUST respond with an HTTP 401 (Unauthorized) status code and include the "WWW-Authenticate" response header field matching the authentication scheme used by the client.', "invalid_grant": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.", @@ -56,7 +56,7 @@ class InvalidGrantRequest(HttpxAuthException): # https://tools.ietf.org/html/rfc6749#section-4.2.2.1 # https://tools.ietf.org/html/rfc6749#section-4.1.2.1 - browser_errors = { + browser_errors: ClassVar[dict[str, str]] = { "invalid_request": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.", "unauthorized_client": "The client is not authorized to request an authorization code or an access token using this method.", "access_denied": "The resource owner or authorization server denied the request.", @@ -66,11 +66,11 @@ class InvalidGrantRequest(HttpxAuthException): "temporarily_unavailable": "The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server. (This error code is needed because a 503 Service Unavailable HTTP status code cannot be returned to the client via an HTTP redirect.)", } - def __init__(self, response: Union[httpx.Response, dict]): + def __init__(self, response: httpx2.Response | dict): HttpxAuthException.__init__(self, InvalidGrantRequest.to_message(response)) @staticmethod - def to_message(response: Union[httpx.Response, dict]) -> str: + def to_message(response: httpx2.Response | dict) -> str: """ Handle response as described in: * https://tools.ietf.org/html/rfc6749#section-5.2 @@ -121,15 +121,11 @@ class StateNotProvided(HttpxAuthException): """State was not provided.""" def __init__(self, dictionary_without_state: dict): - HttpxAuthException.__init__( - self, f"state not provided within {dictionary_without_state}." - ) + HttpxAuthException.__init__(self, f"state not provided within {dictionary_without_state}.") class TokenExpiryNotProvided(HttpxAuthException): """Token expiry was not provided.""" def __init__(self, token_body: dict): - HttpxAuthException.__init__( - self, f"Expiry (exp) is not provided in {token_body}." - ) + HttpxAuthException.__init__(self, f"Expiry (exp) is not provided in {token_body}.") diff --git a/httpx_auth/_oauth2/__init__.py b/httpx2_auth/_oauth2/__init__.py similarity index 100% rename from httpx_auth/_oauth2/__init__.py rename to httpx2_auth/_oauth2/__init__.py diff --git a/httpx_auth/_oauth2/authentication_responses_server.py b/httpx2_auth/_oauth2/authentication_responses_server.py similarity index 82% rename from httpx_auth/_oauth2/authentication_responses_server.py rename to httpx2_auth/_oauth2/authentication_responses_server.py index fef2c80..2e87fa9 100644 --- a/httpx_auth/_oauth2/authentication_responses_server.py +++ b/httpx2_auth/_oauth2/authentication_responses_server.py @@ -1,37 +1,35 @@ -import webbrowser import logging -from http.server import HTTPServer, BaseHTTPRequestHandler +import webbrowser +from http.server import BaseHTTPRequestHandler, HTTPServer from urllib.parse import parse_qs, urlparse -from socket import socket -import httpx +import httpx2 -from httpx_auth._errors import ( - InvalidGrantRequest, +from httpx2_auth._errors import ( GrantNotProvided, + InvalidGrantRequest, StateNotProvided, TimeoutOccurred, ) -from httpx_auth._oauth2.common import OAuth2 +from httpx2_auth._oauth2.common import OAuth2 logger = logging.getLogger(__name__) class OAuth2ResponseHandler(BaseHTTPRequestHandler): + # The server is always a FixedHttpServer (set when the server instantiates the handler). + server: "FixedHttpServer" + def do_GET(self) -> None: # Do not consider a favicon request as an error if self.path == "/favicon.ico": - logger.debug( - "Favicon request received on OAuth2 authentication response server." - ) + logger.debug("Favicon request received on OAuth2 authentication response server.") return self.send_html("Favicon is not provided.") - logger.debug(f"GET received on {self.path}") + logger.debug("GET received on %s", self.path) try: args = self._get_params() - if self.server.grant_details.name in args or args.pop( - "httpx_auth_redirect", None - ): + if self.server.grant_details.name in args or args.pop("httpx2_auth_redirect", None): self._parse_grant(args) else: logger.debug("Send anchor grant as query parameter.") @@ -47,7 +45,7 @@ def do_GET(self) -> None: ) def do_POST(self) -> None: - logger.debug(f"POST received on {self.path}") + logger.debug("POST received on %s", self.path) try: form_dict = self._get_form() self._parse_grant(form_dict) @@ -72,19 +70,17 @@ def _parse_grant(self, arguments: dict) -> None: if "error" in arguments: raise InvalidGrantRequest(arguments) raise GrantNotProvided(self.server.grant_details.name, arguments) - logger.debug(f"Received grants: {grants}") + logger.debug("Received grants: %s", grants) grant = grants[0] states = arguments.get("state") if not states or len(states) > 1: raise StateNotProvided(arguments) - logger.debug(f"Received states: {states}") + logger.debug("Received states: %s", states) state = states[0] self.server.grant = state, grant self.send_html( - OAuth2.display.success_html.format( - display_time=OAuth2.display.success_display_time - ) + OAuth2.display.success_html.format(display_time=OAuth2.display.success_display_time) ) def _get_form(self) -> dict: @@ -114,9 +110,9 @@ def fragment_redirect_page(self) -> str: return """""" @@ -142,16 +138,14 @@ def __init__( class FixedHttpServer(HTTPServer): def __init__(self, grant_details: GrantDetails): - HTTPServer.__init__( - self, ("", grant_details.redirect_uri_port), OAuth2ResponseHandler - ) + HTTPServer.__init__(self, ("", grant_details.redirect_uri_port), OAuth2ResponseHandler) self.timeout = grant_details.reception_timeout - logger.debug(f"Timeout is set to {self.timeout} seconds.") + logger.debug("Timeout is set to %s seconds.", self.timeout) self.grant_details = grant_details - self.request_error = None - self.grant = False + self.request_error: Exception | None = None + self.grant: tuple[str, str] | None = None - def finish_request(self, request: socket, client_address) -> None: + def finish_request(self, request, client_address) -> None: """Make sure that timeout is used by the request (seems like a bug in HTTPServer).""" request.settimeout(self.timeout) HTTPServer.finish_request(self, request, client_address) @@ -163,7 +157,7 @@ def ensure_no_error_occurred(self) -> bool: return not self.grant def handle_timeout(self) -> None: - raise TimeoutOccurred(self.timeout) + raise TimeoutOccurred(self.grant_details.reception_timeout) def request_new_grant(grant_details: GrantDetails) -> tuple[str, str]: @@ -175,7 +169,7 @@ def request_new_grant(grant_details: GrantDetails) -> tuple[str, str]: :raises GrantNotProvided: If grant is not provided in response (but no error occurred). :raises StateNotProvided: If state is not provided in addition to the grant. """ - logger.debug(f"Requesting new {grant_details.name}...") + logger.debug("Requesting new %s...", grant_details.name) with FixedHttpServer(grant_details) as server: _open_url(grant_details.url) @@ -192,16 +186,16 @@ def _open_url(url: str) -> None: if hasattr(webbrowser, "iexplore") else webbrowser.get() ) - logger.debug(f"Opening browser on {url}") + logger.debug("Opening browser on %s", url) if not browser.open(url, new=1): logger.warning("Unable to open URL, try with a GET request.") - httpx.get(url) + httpx2.get(url) except webbrowser.Error: logger.exception("Unable to open URL, try with a GET request.") - httpx.get(url) + httpx2.get(url) -def _wait_for_grant(server: FixedHttpServer) -> (str, str): +def _wait_for_grant(server: FixedHttpServer) -> tuple[str, str]: """ :return: A tuple (state, grant) :raises InvalidGrantRequest: If the request was invalid. @@ -210,7 +204,7 @@ def _wait_for_grant(server: FixedHttpServer) -> (str, str): :raises StateNotProvided: If state is not provided in addition to the grant. """ logger.debug("Waiting for user authentication...") - while not server.grant: + while server.grant is None: server.handle_request() server.ensure_no_error_occurred() return server.grant diff --git a/httpx_auth/_oauth2/authorization_code.py b/httpx2_auth/_oauth2/authorization_code.py similarity index 89% rename from httpx_auth/_oauth2/authorization_code.py rename to httpx2_auth/_oauth2/authorization_code.py index 334a44c..831d48e 100644 --- a/httpx_auth/_oauth2/authorization_code.py +++ b/httpx2_auth/_oauth2/authorization_code.py @@ -1,17 +1,17 @@ +from collections.abc import Iterable from hashlib import sha512 -from typing import Iterable, Union -import httpx +import httpx2 -from httpx_auth._authentication import SupportMultiAuth -from httpx_auth._oauth2 import authentication_responses_server -from httpx_auth._oauth2.browser import BrowserAuth -from httpx_auth._oauth2.common import ( - request_new_grant_with_post, +from httpx2_auth._authentication import SupportMultiAuth +from httpx2_auth._oauth2 import authentication_responses_server +from httpx2_auth._oauth2.browser import BrowserAuth +from httpx2_auth._oauth2.common import ( OAuth2BaseAuth, _add_parameters, - _pop_parameter, _get_query_parameter, + _pop_parameter, + request_new_grant_with_post, ) @@ -52,7 +52,7 @@ def __init__(self, authorization_url: str, token_url: str, **kwargs): :param code_field_name: Field name containing the code. code by default. :param username: Username in case basic authentication should be used to retrieve token. :param password: User password in case basic authentication should be used to retrieve token. - :param client: httpx.Client instance that will be used to request the token. + :param client: httpx2.Client instance that will be used to request the token. Use it to provide a custom proxying rule for instance. :param kwargs: all additional authorization parameters that should be put as query parameter in the authorization URL and as body parameters in the token URL. @@ -91,24 +91,18 @@ def __init__(self, authorization_url: str, token_url: str, **kwargs): # As described in https://tools.ietf.org/html/rfc6749#section-4.1.1 kwargs.setdefault("response_type", "code") - authorization_url_without_nonce = _add_parameters( - self.authorization_url, kwargs - ) + authorization_url_without_nonce = _add_parameters(self.authorization_url, kwargs) authorization_url_without_nonce, nonce = _pop_parameter( authorization_url_without_nonce, "nonce" ) - state = sha512( - authorization_url_without_nonce.encode("unicode_escape") - ).hexdigest() - custom_code_parameters = { + state = sha512(authorization_url_without_nonce.encode("unicode_escape")).hexdigest() + custom_code_parameters: dict[str, str | list[str]] = { "state": state, "redirect_uri": self.redirect_uri, } if nonce: custom_code_parameters["nonce"] = nonce - code_grant_url = _add_parameters( - authorization_url_without_nonce, custom_code_parameters - ) + code_grant_url = _add_parameters(authorization_url_without_nonce, custom_code_parameters) self.code_grant_details = authentication_responses_server.GrantDetails( code_grant_url, code_field_name, @@ -138,14 +132,12 @@ def __init__(self, authorization_url: str, token_url: str, **kwargs): def request_new_token(self) -> tuple: # Request code - state, code = authentication_responses_server.request_new_grant( - self.code_grant_details - ) + _state, code = authentication_responses_server.request_new_grant(self.code_grant_details) # As described in https://tools.ietf.org/html/rfc6749#section-4.1.3 self.token_data["code"] = code - client = self.client or httpx.Client() + client = self.client or httpx2.Client() self._configure_client(client) try: # As described in https://tools.ietf.org/html/rfc6749#section-4.1.4 @@ -157,14 +149,10 @@ def request_new_token(self) -> tuple: if self.client is None: client.close() # Handle both Access and Bearer tokens - return ( - (self.state, token, expires_in, refresh_token) - if expires_in - else (self.state, token) - ) + return (self.state, token, expires_in, refresh_token) if expires_in else (self.state, token) def refresh_token(self, refresh_token: str) -> tuple: - client = self.client or httpx.Client() + client = self.client or httpx2.Client() self._configure_client(client) try: # As described in https://tools.ietf.org/html/rfc6749#section-6 @@ -181,8 +169,10 @@ def refresh_token(self, refresh_token: str) -> tuple: client.close() return self.state, token, expires_in, refresh_token - def _configure_client(self, client: httpx.Client): - client.auth = self.auth + def _configure_client(self, client: httpx2.Client) -> None: + # self.auth may be None (no client credentials); httpx2 accepts None at + # runtime even though its setter is typed as AuthTypes only. + client.auth = self.auth # type: ignore[assignment] client.timeout = self.timeout @@ -220,7 +210,7 @@ def __init__(self, instance: str, client_id: str, **kwargs): :param header_value: Format used to send the token value. "{token}" must be present as it will be replaced by the actual token. Token will be sent as "Bearer {token}" by default. - :param client: httpx.Client instance that will be used to request the token. + :param client: httpx2.Client instance that will be used to request the token. Use it to provide a custom proxying rule for instance. :param kwargs: all additional authorization parameters that should be put as query parameter in the authorization URL. @@ -248,7 +238,7 @@ def __init__( self, client_id: str, client_secret: str, - scope: Union[str, Iterable[str]], + scope: str | Iterable[str], **kwargs, ): """ @@ -276,7 +266,7 @@ def __init__( :param header_value: Format used to send the token value. "{token}" must be present as it will be replaced by the actual token. Token will be sent as "Bearer {token}" by default. - :param client: httpx.Client instance that will be used to request the token. + :param client: httpx2.Client instance that will be used to request the token. Use it to provide a custom proxying rule for instance. :param kwargs: all additional authorization parameters that should be put as query parameter in the authorization URL. diff --git a/httpx_auth/_oauth2/authorization_code_pkce.py b/httpx2_auth/_oauth2/authorization_code_pkce.py similarity index 91% rename from httpx_auth/_oauth2/authorization_code_pkce.py rename to httpx2_auth/_oauth2/authorization_code_pkce.py index 314f736..d6f7baf 100644 --- a/httpx_auth/_oauth2/authorization_code_pkce.py +++ b/httpx2_auth/_oauth2/authorization_code_pkce.py @@ -2,16 +2,16 @@ import os from hashlib import sha256, sha512 -import httpx +import httpx2 -from httpx_auth._authentication import SupportMultiAuth -from httpx_auth._oauth2 import authentication_responses_server -from httpx_auth._oauth2.browser import BrowserAuth -from httpx_auth._oauth2.common import ( - request_new_grant_with_post, +from httpx2_auth._authentication import SupportMultiAuth +from httpx2_auth._oauth2 import authentication_responses_server +from httpx2_auth._oauth2.browser import BrowserAuth +from httpx2_auth._oauth2.common import ( OAuth2BaseAuth, _add_parameters, _pop_parameter, + request_new_grant_with_post, ) @@ -50,7 +50,7 @@ def __init__(self, authorization_url: str, token_url: str, **kwargs): Default to 30 seconds to ensure token will not expire between the time of retrieval and the time the request reaches the actual server. Set it to 0 to deactivate this feature and use the same token until actual expiry. :param code_field_name: Field name containing the code. code by default. - :param client: httpx.Client instance that will be used to request the token. + :param client: httpx2.Client instance that will be used to request the token. Use it to provide a custom proxying rule for instance. :param kwargs: all additional authorization parameters that should be put as query parameter in the authorization URL and as body parameters in the token URL. @@ -95,10 +95,8 @@ def __init__(self, authorization_url: str, token_url: str, **kwargs): authorization_url_without_nonce, nonce = _pop_parameter( authorization_url_without_nonce, "nonce" ) - state = sha512( - authorization_url_without_nonce.encode("unicode_escape") - ).hexdigest() - custom_code_parameters = { + state = sha512(authorization_url_without_nonce.encode("unicode_escape")).hexdigest() + custom_code_parameters: dict[str, str | list[str]] = { "state": state, "redirect_uri": self.redirect_uri, } @@ -110,12 +108,10 @@ def __init__(self, authorization_url: str, token_url: str, **kwargs): code_challenge = self.generate_code_challenge(code_verifier) # add code challenge parameters to the authorization_url request - custom_code_parameters["code_challenge"] = code_challenge + custom_code_parameters["code_challenge"] = code_challenge.decode("ascii") custom_code_parameters["code_challenge_method"] = "S256" - code_grant_url = _add_parameters( - authorization_url_without_nonce, custom_code_parameters - ) + code_grant_url = _add_parameters(authorization_url_without_nonce, custom_code_parameters) self.code_grant_details = authentication_responses_server.GrantDetails( code_grant_url, code_field_name, @@ -142,14 +138,12 @@ def __init__(self, authorization_url: str, token_url: str, **kwargs): def request_new_token(self) -> tuple: # Request code - state, code = authentication_responses_server.request_new_grant( - self.code_grant_details - ) + _state, code = authentication_responses_server.request_new_grant(self.code_grant_details) # As described in https://tools.ietf.org/html/rfc6749#section-4.1.3 self.token_data["code"] = code - client = self.client or httpx.Client() + client = self.client or httpx2.Client() self._configure_client(client) try: # As described in https://tools.ietf.org/html/rfc6749#section-4.1.4 @@ -161,14 +155,10 @@ def request_new_token(self) -> tuple: if self.client is None: client.close() # Handle both Access and Bearer tokens - return ( - (self.state, token, expires_in, refresh_token) - if expires_in - else (self.state, token) - ) + return (self.state, token, expires_in, refresh_token) if expires_in else (self.state, token) def refresh_token(self, refresh_token: str) -> tuple: - client = self.client or httpx.Client() + client = self.client or httpx2.Client() self._configure_client(client) try: # As described in https://tools.ietf.org/html/rfc6749#section-6 @@ -185,7 +175,7 @@ def refresh_token(self, refresh_token: str) -> tuple: client.close() return self.state, token, expires_in, refresh_token - def _configure_client(self, client: httpx.Client): + def _configure_client(self, client: httpx2.Client): client.timeout = self.timeout @staticmethod @@ -256,7 +246,7 @@ def __init__(self, instance: str, client_id: str, **kwargs): :param header_value: Format used to send the token value. "{token}" must be present as it will be replaced by the actual token. Token will be sent as "Bearer {token}" by default. - :param client: httpx.Client instance that will be used to request the token. + :param client: httpx2.Client instance that will be used to request the token. Use it to provide a custom proxying rule for instance. :param kwargs: all additional authorization parameters that should be put as query parameter in the authorization URL and as body parameters in the token URL. diff --git a/httpx_auth/_oauth2/browser.py b/httpx2_auth/_oauth2/browser.py similarity index 88% rename from httpx_auth/_oauth2/browser.py rename to httpx2_auth/_oauth2/browser.py index 4c244a6..3dded8e 100644 --- a/httpx_auth/_oauth2/browser.py +++ b/httpx2_auth/_oauth2/browser.py @@ -12,7 +12,9 @@ def __init__(self, kwargs): redirect_uri_domain = kwargs.pop("redirect_uri_domain", None) or "localhost" redirect_uri_endpoint = kwargs.pop("redirect_uri_endpoint", None) or "" self.redirect_uri_port = int(kwargs.pop("redirect_uri_port", None) or 5000) - self.redirect_uri = f"http://{redirect_uri_domain}:{self.redirect_uri_port}/{redirect_uri_endpoint}" + self.redirect_uri = ( + f"http://{redirect_uri_domain}:{self.redirect_uri_port}/{redirect_uri_endpoint}" + ) # Time is expressed in seconds self.timeout = float(kwargs.pop("timeout", None) or 60) @@ -92,8 +94,8 @@ class DisplaySettings:

{information}

""" @@ -113,9 +115,9 @@ def __init__( self, *, success_display_time: int = 1, - success_html: str = None, + success_html: str | None = None, failure_display_time: int = 10_000, - failure_html: str = None, + failure_html: str | None = None, ): """ :param success_display_time: In case a code/token is successfully received, diff --git a/httpx_auth/_oauth2/client_credentials.py b/httpx2_auth/_oauth2/client_credentials.py similarity index 91% rename from httpx_auth/_oauth2/client_credentials.py rename to httpx2_auth/_oauth2/client_credentials.py index ea46520..9730080 100644 --- a/httpx_auth/_oauth2/client_credentials.py +++ b/httpx2_auth/_oauth2/client_credentials.py @@ -1,13 +1,14 @@ import copy +from collections.abc import Iterable from hashlib import sha512 -from typing import Union, Iterable -import httpx -from httpx_auth._authentication import SupportMultiAuth -from httpx_auth._oauth2.common import ( +import httpx2 + +from httpx2_auth._authentication import SupportMultiAuth +from httpx2_auth._oauth2.common import ( OAuth2BaseAuth, - request_new_grant_with_post, _add_parameters, + request_new_grant_with_post, ) @@ -36,7 +37,7 @@ def __init__(self, token_url: str, client_id: str, client_secret: str, **kwargs) :param early_expiry: Number of seconds before actual token expiry where token will be considered as expired. Default to 30 seconds to ensure token will not expire between the time of retrieval and the time the request reaches the actual server. Set it to 0 to deactivate this feature and use the same token until actual expiry. - :param client: httpx.Client instance that will be used to request the token. + :param client: httpx2.Client instance that will be used to request the token. Use it to provide a custom proxying rule for instance. :param kwargs: all additional authorization parameters that should be put as query parameter in the token URL. """ @@ -69,8 +70,8 @@ def __init__(self, token_url: str, client_id: str, client_secret: str, **kwargs) self.data.update(kwargs) cache_data = copy.deepcopy(self.data) - cache_data["_httpx_auth_client_id"] = self.client_id - cache_data["_httpx_auth_client_secret"] = self.client_secret + cache_data["_httpx2_auth_client_id"] = self.client_id + cache_data["_httpx2_auth_client_secret"] = self.client_secret all_parameters_in_url = _add_parameters(self.token_url, cache_data) state = sha512(all_parameters_in_url.encode("unicode_escape")).hexdigest() @@ -82,7 +83,7 @@ def __init__(self, token_url: str, client_id: str, client_secret: str, **kwargs) ) def request_new_token(self) -> tuple: - client = self.client or httpx.Client() + client = self.client or httpx2.Client() self._configure_client(client) try: # As described in https://tools.ietf.org/html/rfc6749#section-4.4.3 @@ -96,7 +97,7 @@ def request_new_token(self) -> tuple: # Handle both Access and Bearer tokens return (self.state, token, expires_in) if expires_in else (self.state, token) - def _configure_client(self, client: httpx.Client): + def _configure_client(self, client: httpx2.Client): client.auth = (self.client_id, self.client_secret) client.timeout = self.timeout @@ -114,7 +115,7 @@ def __init__( client_id: str, client_secret: str, *, - scope: Union[str, Iterable[str]], + scope: str | Iterable[str], **kwargs, ): """ @@ -135,7 +136,7 @@ def __init__( :param early_expiry: Number of seconds before actual token expiry where token will be considered as expired. Default to 30 seconds to ensure token will not expire between the time of retrieval and the time the request reaches the actual server. Set it to 0 to deactivate this feature and use the same token until actual expiry. - :param client: httpx.Client instance that will be used to request the token. + :param client: httpx2.Client instance that will be used to request the token. Use it to provide a custom proxying rule for instance. :param kwargs: all additional authorization parameters that should be put as query parameter in the token URL. """ diff --git a/httpx_auth/_oauth2/common.py b/httpx2_auth/_oauth2/common.py similarity index 72% rename from httpx_auth/_oauth2/common.py rename to httpx2_auth/_oauth2/common.py index 7670c1f..a6e4a32 100644 --- a/httpx_auth/_oauth2/common.py +++ b/httpx2_auth/_oauth2/common.py @@ -1,12 +1,12 @@ import abc -from typing import Callable, Generator, Optional, Union -from urllib.parse import parse_qs, urlsplit, urlunsplit, urlencode +from collections.abc import Callable, Generator +from urllib.parse import parse_qs, urlencode, urlsplit, urlunsplit -import httpx +import httpx2 -from httpx_auth._errors import GrantNotProvided, InvalidGrantRequest -from httpx_auth._oauth2.browser import DisplaySettings -from httpx_auth._oauth2.tokens import TokenMemoryCache +from httpx2_auth._errors import GrantNotProvided, InvalidGrantRequest +from httpx2_auth._oauth2.browser import DisplaySettings +from httpx2_auth._oauth2.tokens import TokenMemoryCache def _add_parameters(initial_url: str, extra_parameters: dict) -> str: @@ -31,7 +31,7 @@ def _add_parameters(initial_url: str, extra_parameters: dict) -> str: return urlunsplit((scheme, netloc, path, new_query_string, fragment)) -def _pop_parameter(url: str, query_parameter_name: str) -> (str, Optional[str]): +def _pop_parameter(url: str, query_parameter_name: str) -> tuple[str, list[str] | None]: """ Remove and return parameter of an URL. @@ -50,14 +50,13 @@ def _pop_parameter(url: str, query_parameter_name: str) -> (str, Optional[str]): ) -def _get_query_parameter(url: str, param_name: str) -> Optional[str]: - scheme, netloc, path, query_string, fragment = urlsplit(url) - query_params = parse_qs(query_string) +def _get_query_parameter(url: str, param_name: str) -> str | None: + query_params = parse_qs(urlsplit(url).query) all_values = query_params.get(param_name) return all_values[0] if all_values else None -def _content_from_response(response: httpx.Response) -> dict: +def _content_from_response(response: httpx2.Response) -> dict: content_type = response.headers.get("content-type") if content_type == "text/html; charset=utf-8": return { @@ -69,8 +68,8 @@ def _content_from_response(response: httpx.Response) -> dict: def request_new_grant_with_post( - url: str, data, grant_name: str, client: httpx.Client -) -> (str, int, str): + url: str, data, grant_name: str, client: httpx2.Client +) -> tuple[str, int, str]: response = client.post(url, data=data) if response.is_error: @@ -81,7 +80,9 @@ def request_new_grant_with_post( token = content.get(grant_name) if not token: raise GrantNotProvided(grant_name, content) - return token, content.get("expires_in"), content.get("refresh_token") + # Values are decoded from an untyped JSON/form response; the OAuth2 token + # endpoint guarantees the (token, expires_in, refresh_token) shape here. + return token, content.get("expires_in"), content.get("refresh_token") # type: ignore[return-value] class OAuth2: @@ -89,14 +90,14 @@ class OAuth2: display = DisplaySettings() -class OAuth2BaseAuth(abc.ABC, httpx.Auth): +class OAuth2BaseAuth(abc.ABC, httpx2.Auth): def __init__( self, state: str, early_expiry: float, header_name: str, header_value: str, - refresh_token: Optional[Callable] = None, + refresh_token: Callable | None = None, ) -> None: if "{token}" not in header_value: raise Exception("header_value parameter must contains {token}.") @@ -108,8 +109,8 @@ def __init__( self.refresh_token = refresh_token def auth_flow( - self, request: httpx.Request - ) -> Generator[httpx.Request, httpx.Response, None]: + self, request: httpx2.Request + ) -> Generator[httpx2.Request, httpx2.Response, None]: token = OAuth2.token_cache.get_token( self.state, early_expiry=self.early_expiry, @@ -120,8 +121,8 @@ def auth_flow( yield request @abc.abstractmethod - def request_new_token(self) -> Union[tuple[str, str], tuple[str, str, int]]: + def request_new_token(self) -> tuple[str, str] | tuple[str, str, int]: pass # pragma: no cover - def _update_user_request(self, request: httpx.Request, token: str) -> None: + def _update_user_request(self, request: httpx2.Request, token: str) -> None: request.headers[self.header_name] = self.header_value.format(token=token) diff --git a/httpx_auth/_oauth2/implicit.py b/httpx2_auth/_oauth2/implicit.py similarity index 96% rename from httpx_auth/_oauth2/implicit.py rename to httpx2_auth/_oauth2/implicit.py index 3ebc986..37dad82 100644 --- a/httpx_auth/_oauth2/implicit.py +++ b/httpx2_auth/_oauth2/implicit.py @@ -1,16 +1,14 @@ import uuid from hashlib import sha512 -import httpx - -from httpx_auth._authentication import SupportMultiAuth -from httpx_auth._oauth2 import authentication_responses_server -from httpx_auth._oauth2.browser import BrowserAuth -from httpx_auth._oauth2.common import ( +from httpx2_auth._authentication import SupportMultiAuth +from httpx2_auth._oauth2 import authentication_responses_server +from httpx2_auth._oauth2.browser import BrowserAuth +from httpx2_auth._oauth2.common import ( OAuth2BaseAuth, _add_parameters, - _pop_parameter, _get_query_parameter, + _pop_parameter, ) @@ -75,22 +73,19 @@ def __init__(self, authorization_url: str, **kwargs): # As described in https://tools.ietf.org/html/rfc6749#section-4.2.2 token_field_name = kwargs.pop("token_field_name", None) if not token_field_name: - token_field_name = ( - "id_token" if "id_token" == response_type else "access_token" - ) + token_field_name = "id_token" if response_type == "id_token" else "access_token" early_expiry = float(kwargs.pop("early_expiry", None) or 30.0) - authorization_url_without_nonce = _add_parameters( - self.authorization_url, kwargs - ) + authorization_url_without_nonce = _add_parameters(self.authorization_url, kwargs) authorization_url_without_nonce, nonce = _pop_parameter( authorization_url_without_nonce, "nonce" ) - state = sha512( - authorization_url_without_nonce.encode("unicode_escape") - ).hexdigest() - custom_parameters = {"state": state, "redirect_uri": self.redirect_uri} + state = sha512(authorization_url_without_nonce.encode("unicode_escape")).hexdigest() + custom_parameters: dict[str, str | list[str]] = { + "state": state, + "redirect_uri": self.redirect_uri, + } if nonce: custom_parameters["nonce"] = nonce grant_url = _add_parameters(authorization_url_without_nonce, custom_parameters) diff --git a/httpx_auth/_oauth2/resource_owner_password.py b/httpx2_auth/_oauth2/resource_owner_password.py similarity index 92% rename from httpx_auth/_oauth2/resource_owner_password.py rename to httpx2_auth/_oauth2/resource_owner_password.py index 2be25bf..bc5c0dd 100644 --- a/httpx_auth/_oauth2/resource_owner_password.py +++ b/httpx2_auth/_oauth2/resource_owner_password.py @@ -1,11 +1,12 @@ from hashlib import sha512 -import httpx -from httpx_auth._authentication import SupportMultiAuth -from httpx_auth._oauth2.common import ( +import httpx2 + +from httpx2_auth._authentication import SupportMultiAuth +from httpx2_auth._oauth2.common import ( OAuth2BaseAuth, - request_new_grant_with_post, _add_parameters, + request_new_grant_with_post, ) @@ -24,7 +25,7 @@ def __init__(self, token_url: str, username: str, password: str, **kwargs): :param password: Resource owner password. :param client_auth: Client authentication if the client type is confidential or the client was issued client credentials (or assigned other authentication requirements). - Can be a tuple or any httpx authentication class instance. + Can be a tuple or any httpx2 authentication class instance. :param timeout: Maximum amount of seconds to wait for a token to be received once requested. Wait for 1 minute by default. :param header_name: Name of the header field used to send token. @@ -37,7 +38,7 @@ def __init__(self, token_url: str, username: str, password: str, **kwargs): :param early_expiry: Number of seconds before actual token expiry where token will be considered as expired. Default to 30 seconds to ensure token will not expire between the time of retrieval and the time the request reaches the actual server. Set it to 0 to deactivate this feature and use the same token until actual expiry. - :param client: httpx.Client instance that will be used to request the token. + :param client: httpx2.Client instance that will be used to request the token. Use it to provide a custom proxying rule for instance. :param kwargs: all additional authorization parameters that should be put as body parameters in the token URL. """ @@ -93,7 +94,7 @@ def __init__(self, token_url: str, username: str, password: str, **kwargs): ) def request_new_token(self) -> tuple: - client = self.client or httpx.Client() + client = self.client or httpx2.Client() self._configure_client(client) try: # As described in https://tools.ietf.org/html/rfc6749#section-4.3.3 @@ -105,14 +106,10 @@ def request_new_token(self) -> tuple: if self.client is None: client.close() # Handle both Access and Bearer tokens - return ( - (self.state, token, expires_in, refresh_token) - if expires_in - else (self.state, token) - ) + return (self.state, token, expires_in, refresh_token) if expires_in else (self.state, token) def refresh_token(self, refresh_token: str) -> tuple: - client = self.client or httpx.Client() + client = self.client or httpx2.Client() self._configure_client(client) try: # As described in https://tools.ietf.org/html/rfc6749#section-6 @@ -129,7 +126,7 @@ def refresh_token(self, refresh_token: str) -> tuple: client.close() return self.state, token, expires_in, refresh_token - def _configure_client(self, client: httpx.Client): + def _configure_client(self, client: httpx2.Client): if self.client_auth: client.auth = self.client_auth client.timeout = self.timeout @@ -170,7 +167,7 @@ def __init__( :param early_expiry: Number of seconds before actual token expiry where token will be considered as expired. Default to 30 seconds to ensure token will not expire between the time of retrieval and the time the request reaches the actual server. Set it to 0 to deactivate this feature and use the same token until actual expiry. - :param client: httpx.Client instance that will be used to request the token. + :param client: httpx2.Client instance that will be used to request the token. Use it to provide a custom proxying rule for instance. :param kwargs: all additional authorization parameters that should be put as body parameters in the token URL. """ diff --git a/httpx_auth/_oauth2/tokens.py b/httpx2_auth/_oauth2/tokens.py similarity index 82% rename from httpx_auth/_oauth2/tokens.py rename to httpx2_auth/_oauth2/tokens.py index ca65c08..74068b1 100644 --- a/httpx_auth/_oauth2/tokens.py +++ b/httpx2_auth/_oauth2/tokens.py @@ -1,18 +1,16 @@ import base64 -import json -import os import datetime -import threading +import json import logging +import threading from pathlib import Path -from typing import Union, Optional -from httpx_auth._errors import ( - InvalidToken, - TokenExpiryNotProvided, +from httpx2_auth._errors import ( AuthenticationFailed, - InvalidGrantRequest, GrantNotProvided, + InvalidGrantRequest, + InvalidToken, + TokenExpiryNotProvided, ) logger = logging.getLogger(__name__) @@ -37,7 +35,7 @@ def is_expired(expiry: float, early_expiry: float) -> bool: ) < datetime.datetime.now(datetime.timezone.utc) -def to_expiry(expires_in: Union[int, str]) -> float: +def to_expiry(expires_in: int | str) -> float: expiry = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta( seconds=int(expires_in) ) @@ -65,7 +63,7 @@ def _add_bearer_token(self, key: str, token: str) -> None: if not token: raise InvalidToken(token) - header, body, other = token.split(".") + _header, body, _other = token.split(".") body = json.loads(decode_base64(body)) expiry = body.get("exp") if not expiry: @@ -77,8 +75,8 @@ def _add_access_token( self, key: str, token: str, - expires_in: Union[int, str], - refresh_token: Optional[str] = None, + expires_in: int | str, + refresh_token: str | None = None, ) -> None: """ Set the bearer token and save it @@ -90,7 +88,7 @@ def _add_access_token( self._add_token(key, token, to_expiry(expires_in), refresh_token) def _add_token( - self, key: str, token: str, expiry: float, refresh_token: Optional[str] = None + self, key: str, token: str, expiry: float, refresh_token: str | None = None ) -> None: """ Set the bearer token and save it @@ -103,8 +101,9 @@ def _add_token( self.tokens[key] = token, expiry, refresh_token self._save_tokens() logger.debug( - "Inserting token expiring on" - f' {datetime.datetime.fromtimestamp(expiry, datetime.timezone.utc)} with "{key}" key.' + 'Inserting token expiring on %s with "%s" key.', + datetime.datetime.fromtimestamp(expiry, datetime.timezone.utc), + key, ) def get_token( @@ -128,7 +127,7 @@ def get_token( :return: the token :raise AuthenticationFailed: in case token cannot be retrieved. """ - logger.debug(f'Retrieving token with "{key}" key.') + logger.debug('Retrieving token with "%s" key.', key) refresh_token = None with self._forbid_concurrent_cache_access: self._load_tokens() @@ -139,28 +138,27 @@ def get_token( else: bearer, expiry, refresh_token = token if is_expired(expiry, early_expiry): - logger.debug(f'Authentication token with "{key}" key is expired.') + logger.debug('Authentication token with "%s" key is expired.', key) del self.tokens[key] else: logger.debug( - "Using already received authentication, will expire on" - f" {datetime.datetime.fromtimestamp(expiry, datetime.timezone.utc)}." + "Using already received authentication, will expire on %s.", + datetime.datetime.fromtimestamp(expiry, datetime.timezone.utc), ) return bearer if refresh_token is not None and on_expired_token is not None: try: with self._forbid_concurrent_missing_token_function_call: - state, token, expires_in, refresh_token = on_expired_token( - refresh_token - ) + state, token, expires_in, refresh_token = on_expired_token(refresh_token) self._add_access_token(state, token, expires_in, refresh_token) - logger.debug(f"Refreshed token with key {key}.") + logger.debug("Refreshed token with key %s.", key) with self._forbid_concurrent_cache_access: if state in self.tokens: bearer, expiry, refresh_token = self.tokens[state] logger.debug( - f"Using newly refreshed token, expiring on {datetime.datetime.fromtimestamp(expiry, datetime.timezone.utc)}." + "Using newly refreshed token, expiring on %s.", + datetime.datetime.fromtimestamp(expiry, datetime.timezone.utc), ) return bearer except (InvalidGrantRequest, GrantNotProvided): @@ -181,19 +179,23 @@ def get_token( self._add_access_token(state, token, expires_in, refresh_token) if key != state: logger.warning( - f"Using a token received on another key than expected. Expecting {key} but was {state}." + "Using a token received on another key than expected. Expecting %s but was %s.", + key, + state, ) with self._forbid_concurrent_cache_access: if state in self.tokens: bearer, expiry, refresh_token = self.tokens[state] logger.debug( - "Using newly received authentication, expiring on" - f" {datetime.datetime.fromtimestamp(expiry, datetime.timezone.utc)}." + "Using newly received authentication, expiring on %s.", + datetime.datetime.fromtimestamp(expiry, datetime.timezone.utc), ) return bearer logger.debug( - f"User was not authenticated: key {key} cannot be found in {list(self.tokens)}." + "User was not authenticated: key %s cannot be found in %s.", + key, + list(self.tokens), ) raise AuthenticationFailed() @@ -219,25 +221,25 @@ class JsonTokenFileCache(TokenMemoryCache): Class to manage tokens using a cache file. """ - def __init__(self, tokens_path: Union[str, Path]): + def __init__(self, tokens_path: str | Path): TokenMemoryCache.__init__(self) self._tokens_path = Path(tokens_path) - self._last_save_time = 0 + self._last_save_time = 0.0 self._load_tokens() def _clear(self) -> None: - self._last_save_time = 0 + self._last_save_time = 0.0 try: self._tokens_path.unlink(missing_ok=True) - except: + except Exception: logger.debug("Cannot remove tokens file.") def _save_tokens(self) -> None: try: with self._tokens_path.open(mode="w") as tokens_cache_file: json.dump(self.tokens, tokens_cache_file) - self._last_save_time = os.path.getmtime(self._tokens_path) - except: + self._last_save_time = self._tokens_path.stat().st_mtime + except Exception: logger.exception("Cannot save tokens.") def _load_tokens(self) -> None: @@ -245,10 +247,10 @@ def _load_tokens(self) -> None: logger.debug("No token loaded. Token cache does not exists.") return try: - last_modification_time = os.path.getmtime(self._tokens_path) + last_modification_time = self._tokens_path.stat().st_mtime if last_modification_time > self._last_save_time: self._last_save_time = last_modification_time with self._tokens_path.open(mode="r") as tokens_cache_file: self.tokens = json.load(tokens_cache_file) - except: + except Exception: logger.exception("Cannot load tokens.") diff --git a/httpx_auth/py.typed b/httpx2_auth/py.typed similarity index 100% rename from httpx_auth/py.typed rename to httpx2_auth/py.typed diff --git a/httpx_auth/testing.py b/httpx2_auth/testing.py similarity index 69% rename from httpx_auth/testing.py rename to httpx2_auth/testing.py index c7fb000..d274855 100644 --- a/httpx_auth/testing.py +++ b/httpx2_auth/testing.py @@ -1,25 +1,25 @@ -import urllib.request +import datetime import threading -from typing import Optional +import urllib.request +from collections.abc import Generator from urllib.parse import urlsplit -import datetime import pytest -import httpx_auth -import httpx_auth._oauth2.authentication_responses_server +import httpx2_auth +import httpx2_auth._oauth2.authentication_responses_server -def create_token(expiry: Optional[datetime.datetime]) -> str: +def create_token(expiry: datetime.datetime | None) -> str: import jwt # Consider jwt an optional dependency for testing return jwt.encode({"exp": expiry}, "secret") if expiry else jwt.encode({}, "secret") @pytest.fixture -def token_cache() -> httpx_auth.TokenMemoryCache: - yield httpx_auth.OAuth2.token_cache - httpx_auth.OAuth2.token_cache.clear() +def token_cache() -> Generator[httpx2_auth.TokenMemoryCache, None, None]: + yield httpx2_auth.OAuth2.token_cache + httpx2_auth.OAuth2.token_cache.clear() class Tab(threading.Thread): @@ -33,16 +33,14 @@ class Tab(threading.Thread): def __init__( self, - reply_url: str, - data: str, - displayed_html: Optional[str] = None, + reply_url: str | None, + data: str | None, + displayed_html: str | None = None, ): self.reply_url = reply_url self.data = data.encode() if data is not None else None self.checked = False - self.success_html = ( - displayed_html - or """ + self.success_html = displayed_html or """ Authentication success @@ -115,15 +113,12 @@ def __init__(

You can close this tab

""" - ) - self.failure_html = ( - displayed_html - or """ + self.failure_html = displayed_html or """ Authentication failed @@ -196,46 +191,44 @@ def __init__(

{information}

""" - ) super().__init__() def run(self) -> None: - if not self.reply_url: + reply_url = self.reply_url + if not reply_url: self.checked = True return # Simulate a browser tab by first requesting a favicon - self._request_favicon() + self._request_favicon(reply_url) # Simulate a browser tab token redirect to the reply URL - self.content = self._simulate_redirect().decode() + self.content = self._simulate_redirect(reply_url).decode() - def _request_favicon(self): - scheme, netloc, *_ = urlsplit(self.reply_url) + def _request_favicon(self, reply_url: str) -> None: + scheme, netloc, *_ = urlsplit(reply_url) favicon_response = urllib.request.urlopen(f"{scheme}://{netloc}/favicon.ico") assert favicon_response.read() == b"Favicon is not provided." - def _simulate_redirect(self) -> bytes: - content = urllib.request.urlopen(self.reply_url, data=self.data).read() + def _simulate_redirect(self, reply_url: str) -> bytes: + content = urllib.request.urlopen(reply_url, data=self.data).read() # Simulate Javascript execution by the browser if ( content - == b'' + == b'' ): - content = self._simulate_httpx_auth_redirect() + content = self._simulate_httpx2_auth_redirect(reply_url) return content - def _simulate_httpx_auth_redirect(self) -> bytes: + def _simulate_httpx2_auth_redirect(self, reply_url: str) -> bytes: # Replace fragment by query parameter as requested by Javascript - reply_url = self.reply_url.replace("#", "?") + reply_url = reply_url.replace("#", "?") # Add requests_auth_redirect query parameter as requested by Javascript - reply_url += ( - "&httpx_auth_redirect=1" if "?" in reply_url else "?httpx_auth_redirect=1" - ) + reply_url += "&httpx2_auth_redirect=1" if "?" in reply_url else "?httpx2_auth_redirect=1" return urllib.request.urlopen(reply_url, data=self.data).read() def assert_success(self, timeout: int = 1): @@ -265,12 +258,12 @@ def open(self, url: str, new: int) -> bool: def add_response( self, opened_url: str, - reply_url: Optional[str], - data: Optional[str] = None, - displayed_html: Optional[str] = None, + reply_url: str | None, + data: str | None = None, + displayed_html: str | None = None, ) -> Tab: """ - :param opened_url: URL opened by httpx_auth + :param opened_url: URL opened by httpx2_auth :param reply_url: The URL to send a response to, None to simulate the fact that there is no redirect. :param data: Body of the POST response to be sent. None to send a GET request. :param displayed_html: Expected success/failure page. @@ -286,15 +279,15 @@ def assert_checked(self): @pytest.fixture -def browser_mock(monkeypatch) -> BrowserMock: +def browser_mock(monkeypatch) -> Generator[BrowserMock, None, None]: mock = BrowserMock() monkeypatch.setattr( - httpx_auth._oauth2.authentication_responses_server.webbrowser, + httpx2_auth._oauth2.authentication_responses_server.webbrowser, "get", - lambda *args: mock, + lambda *_args: mock, ) - monkeypatch.setattr(httpx_auth.OAuth2, "display", httpx_auth.DisplaySettings()) + monkeypatch.setattr(httpx2_auth.OAuth2, "display", httpx2_auth.DisplaySettings()) yield mock @@ -309,7 +302,7 @@ def token_mock() -> str: @pytest.fixture def token_cache_mock(monkeypatch, token_mock: str): class TokenCacheMock: - def get_token(self, *args, **kwargs) -> str: + def get_token(self, *_args, **_kwargs) -> str: return token_mock - monkeypatch.setattr(httpx_auth.OAuth2, "token_cache", TokenCacheMock()) + monkeypatch.setattr(httpx2_auth.OAuth2, "token_cache", TokenCacheMock()) diff --git a/httpx_auth/version.py b/httpx_auth/version.py deleted file mode 100644 index 3e3aba8..0000000 --- a/httpx_auth/version.py +++ /dev/null @@ -1,6 +0,0 @@ -# Version number as Major.Minor.Patch -# The version modification must respect the following rules: -# Major should be incremented in case there is a breaking change. (eg: 2.5.8 -> 3.0.0) -# Minor should be incremented in case there is an enhancement. (eg: 2.5.8 -> 2.6.0) -# Patch should be incremented in case there is a bug fix. (eg: 2.5.8 -> 2.5.9) -__version__ = "0.23.1" diff --git a/pyproject.toml b/pyproject.toml index 9f68ced..ddcdbca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,16 +3,17 @@ requires = ["setuptools", "setuptools_scm"] build-backend = "setuptools.build_meta" [project] -name = "httpx_auth" -description = "Authentication for HTTPX" +name = "httpx2_auth" +description = "Authentication for HTTPX2" readme = "README.md" -requires-python = ">=3.9" +requires-python = "~=3.10" license = {file = "LICENSE"} authors = [ + {name = "Casper Welzel Andersen", email = "casper.w.andersen@sintef.no" }, {name = "Colin Bounouar", email = "colin.bounouar.dev@gmail.com" } ] maintainers = [ - {name = "Colin Bounouar", email = "colin.bounouar.dev@gmail.com" } + {name = "Casper Welzel Andersen", email = "casper.w.andersen@sintef.no" } ] keywords = ["authentication", "oauth2", "aws", "okta", "aad", "entra"] classifiers=[ @@ -23,7 +24,6 @@ classifiers=[ "Typing :: Typed", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -31,36 +31,131 @@ classifiers=[ "Topic :: Software Development :: Build Tools", ] dependencies = [ - "httpx==0.28.*", + "httpx2~=2.3", ] dynamic = ["version"] [project.urls] -documentation = "https://colin-b.github.io/httpx_auth/" -repository = "https://github.com/Colin-b/httpx_auth" -changelog = "https://github.com/Colin-b/httpx_auth/blob/master/CHANGELOG.md" -issues = "https://github.com/Colin-b/httpx_auth/issues" +repository = "https://github.com/SemanticMatter/httpx2_auth" +changelog = "https://github.com/SemanticMatter/httpx2_auth/blob/master/CHANGELOG.md" +issues = "https://github.com/SemanticMatter/httpx2_auth/issues" + +# Expose the testing fixtures (token_cache, browser_mock, ...) as a pytest plugin +# so they are auto-registered both for this project's tests and for downstream users. +[project.entry-points.pytest11] +httpx2_auth = "httpx2_auth.testing" [project.optional-dependencies] testing = [ + # Used to mock httpx2 + "httpx2-pytest~=1.0", # Used to generate test tokens - "pyjwt==2.*", - # Used to mock httpx - "pytest_httpx==0.35.*", - # Used to mock date and time - "time-machine==2.*", - # Used to check coverage - "pytest-cov==6.*", + "pyjwt~=2.13", + "pytest~=9.0", # Used to run async tests - "pytest-asyncio==0.25.*", + "pytest-asyncio~=1.4", + # Used to check coverage + "pytest-cov~=7.1", + # Used to mock date and time + "time-machine~=3.2", +] +dev = [ + "httpx2_auth[testing]", + "pre-commit~=4.6", ] [tool.setuptools.dynamic] -version = {attr = "httpx_auth.version.__version__"} +version = {attr = "httpx2_auth.__version__"} [tool.pytest.ini_options] +minversion = "9" +addopts = "-rs --cov=httpx2_auth --cov-report=term-missing:skip-covered --no-cov-on-fail" filterwarnings = [ "error", + # Test tokens are signed with short HMAC keys on purpose; the key length is + # irrelevant to what these tests verify. + "ignore::jwt.warnings.InsecureKeyLengthWarning", ] -# Silence deprecation warnings about option "asyncio_default_fixture_loop_scope" +log_level = "WARNING" +asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" + + +# --- Formatting ------------------------------------------------------------- +# black handles formatting (via the black pre-commit hook); ruff is lint-only. +[tool.black] +line-length = 100 +target-version = ["py310", "py311", "py312"] + +# --- Linting (ruff, lint-only) ---------------------------------------------- +# Rule selection adapted from the stack repo's .ruff.toml. Kept in pyproject so +# editors/ruff auto-discover it; the pre-commit hook passes no --config. +[tool.ruff] +line-length = 100 +indent-width = 4 +target-version = "py310" + +[tool.ruff.lint] +extend-select = [ + "B", # flake8-bugbear + "I", # isort + "ARG", # flake8-unused-arguments + "C4", # flake8-comprehensions + "ICN", # flake8-import-conventions + "G", # flake8-logging-format + "PGH", # pygrep-hooks + "PIE", # flake8-pie + "PL", # pylint + "PT", # flake8-pytest-style + "PTH", # flake8-use-pathlib + "RET", # flake8-return + "RUF", # Ruff-specific + "SIM", # flake8-simplify + "T20", # flake8-print + "YTT", # flake8-2020 + "EXE", # flake8-executable + "PYI", # flake8-pyi +] +ignore = [ + "PLC", # pylint convention codes + "PLR", # pylint refactor codes +] + +[tool.ruff.lint.extend-per-file-ignores] +# Tests rely on patterns the linter flags but that are idiomatic for pytest. +"tests/**" = [ + "ARG001", # Fixtures are injected by name and not always referenced in the body. + "ARG002", # Mock/stub methods mirror the real signatures they replace. + "ARG005", # Mock lambdas mirror the real callables they replace. + "PT006", # parametrize names are given as a single comma-separated string. + "PT007", # parametrize rows are given as lists rather than tuples. + "PT011", # pytest.raises(Exception) is paired with an explicit message assertion. + "RUF043", # raises match= values are literal strings, not regular expressions. + "SIM117", # Nested `with` (client + pytest.raises) reads clearly in tests. +] + +# --- Type checking (mypy) --------------------------------------------------- +# Strict (deploy-pet's own baseline) plus the pydantic plugin from the stack's +# .mypy.ini. Auto-discovered from pyproject; the pre-commit hook passes no +# --config-file. mypy runs in pre-commit's isolated env, never the project venv. +[tool.mypy] +python_version = "3.10" +ignore_missing_imports = true +scripts_are_modules = true +warn_unused_configs = true +show_error_codes = true +allow_redefinition = true +warn_unreachable = true +# plugins = ["pydantic.mypy"] +mypy_path = "." +explicit_package_bases = true +check_untyped_defs = true + +# --- Security linting (bandit) ---------------------------------------------- +# Read via `bandit -c pyproject.toml`. B404/B603 are skipped project-wide: all +# subprocess use is funnelled through the single shell=False, fixed-argv +# chokepoint in commands.py (see that module). Anything more specific (e.g. the +# parameterized SQL IN-clause) is suppressed inline with `# nosec`. +[tool.bandit] +exclude_dirs = ["tests"] +skips = ["B404", "B603"] diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/api_key/__init__.py b/tests/api_key/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/api_key/test_api_key.py b/tests/api_key/test_api_key.py index b7534ef..ec75691 100644 --- a/tests/api_key/test_api_key.py +++ b/tests/api_key/test_api_key.py @@ -1,15 +1,15 @@ import pytest -import httpx_auth +import httpx2_auth def test_header_api_key_requires_an_api_key(): with pytest.raises(Exception) as exception_info: - httpx_auth.HeaderApiKey(None) + httpx2_auth.HeaderApiKey(None) assert str(exception_info.value) == "API Key is mandatory." def test_query_api_key_requires_an_api_key(): with pytest.raises(Exception) as exception_info: - httpx_auth.QueryApiKey(None) + httpx2_auth.QueryApiKey(None) assert str(exception_info.value) == "API Key is mandatory." diff --git a/tests/api_key/test_api_key_async.py b/tests/api_key/test_api_key_async.py index 3064937..0e8d86f 100644 --- a/tests/api_key/test_api_key_async.py +++ b/tests/api_key/test_api_key_async.py @@ -1,14 +1,13 @@ +import httpx2 import pytest -from pytest_httpx import HTTPXMock -import httpx +from pytest_httpx2 import HTTPXMock - -import httpx_auth +import httpx2_auth @pytest.mark.asyncio async def test_header_api_key_is_sent_in_x_api_key_by_default(httpx_mock: HTTPXMock): - auth = httpx_auth.HeaderApiKey("my_provided_api_key") + auth = httpx2_auth.HeaderApiKey("my_provided_api_key") httpx_mock.add_response( url="https://authorized_only", @@ -16,25 +15,23 @@ async def test_header_api_key_is_sent_in_x_api_key_by_default(httpx_mock: HTTPXM match_headers={"X-API-Key": "my_provided_api_key"}, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio async def test_query_api_key_is_sent_in_api_key_by_default(httpx_mock: HTTPXMock): - auth = httpx_auth.QueryApiKey("my_provided_api_key") + auth = httpx2_auth.QueryApiKey("my_provided_api_key") - httpx_mock.add_response( - url="https://authorized_only?api_key=my_provided_api_key", method="GET" - ) + httpx_mock.add_response(url="https://authorized_only?api_key=my_provided_api_key", method="GET") - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio async def test_header_api_key_can_be_sent_in_a_custom_field_name(httpx_mock: HTTPXMock): - auth = httpx_auth.HeaderApiKey("my_provided_api_key", "X-API-HEADER-KEY") + auth = httpx2_auth.HeaderApiKey("my_provided_api_key", "X-API-HEADER-KEY") httpx_mock.add_response( url="https://authorized_only", @@ -42,17 +39,17 @@ async def test_header_api_key_can_be_sent_in_a_custom_field_name(httpx_mock: HTT match_headers={"X-API-HEADER-KEY": "my_provided_api_key"}, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio async def test_query_api_key_can_be_sent_in_a_custom_field_name(httpx_mock: HTTPXMock): - auth = httpx_auth.QueryApiKey("my_provided_api_key", "X-API-QUERY-KEY") + auth = httpx2_auth.QueryApiKey("my_provided_api_key", "X-API-QUERY-KEY") httpx_mock.add_response( url="https://authorized_only?X-API-QUERY-KEY=my_provided_api_key", method="GET" ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) diff --git a/tests/api_key/test_api_key_sync.py b/tests/api_key/test_api_key_sync.py index 2c371c5..1b71c59 100644 --- a/tests/api_key/test_api_key_sync.py +++ b/tests/api_key/test_api_key_sync.py @@ -1,12 +1,11 @@ -from pytest_httpx import HTTPXMock -import httpx +import httpx2 +from pytest_httpx2 import HTTPXMock - -import httpx_auth +import httpx2_auth def test_header_api_key_is_sent_in_x_api_key_by_default(httpx_mock: HTTPXMock): - auth = httpx_auth.HeaderApiKey("my_provided_api_key") + auth = httpx2_auth.HeaderApiKey("my_provided_api_key") httpx_mock.add_response( url="https://authorized_only", @@ -14,23 +13,21 @@ def test_header_api_key_is_sent_in_x_api_key_by_default(httpx_mock: HTTPXMock): match_headers={"X-API-Key": "my_provided_api_key"}, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_query_api_key_is_sent_in_api_key_by_default(httpx_mock: HTTPXMock): - auth = httpx_auth.QueryApiKey("my_provided_api_key") + auth = httpx2_auth.QueryApiKey("my_provided_api_key") - httpx_mock.add_response( - url="https://authorized_only?api_key=my_provided_api_key", method="GET" - ) + httpx_mock.add_response(url="https://authorized_only?api_key=my_provided_api_key", method="GET") - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_header_api_key_can_be_sent_in_a_custom_field_name(httpx_mock: HTTPXMock): - auth = httpx_auth.HeaderApiKey("my_provided_api_key", "X-API-HEADER-KEY") + auth = httpx2_auth.HeaderApiKey("my_provided_api_key", "X-API-HEADER-KEY") httpx_mock.add_response( url="https://authorized_only", @@ -38,16 +35,16 @@ def test_header_api_key_can_be_sent_in_a_custom_field_name(httpx_mock: HTTPXMock match_headers={"X-API-HEADER-KEY": "my_provided_api_key"}, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_query_api_key_can_be_sent_in_a_custom_field_name(httpx_mock: HTTPXMock): - auth = httpx_auth.QueryApiKey("my_provided_api_key", "X-API-QUERY-KEY") + auth = httpx2_auth.QueryApiKey("my_provided_api_key", "X-API-QUERY-KEY") httpx_mock.add_response( url="https://authorized_only?X-API-QUERY-KEY=my_provided_api_key", method="GET" ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) diff --git a/tests/aws_signature_v4/__init__.py b/tests/aws_signature_v4/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/aws_signature_v4/test_aws4auth.py b/tests/aws_signature_v4/test_aws4auth.py index 4273819..8eeef29 100644 --- a/tests/aws_signature_v4/test_aws4auth.py +++ b/tests/aws_signature_v4/test_aws4auth.py @@ -1,11 +1,11 @@ import pytest -import httpx_auth +import httpx2_auth def test_aws_auth_with_empty_secret_key(): with pytest.raises(Exception) as exception_info: - httpx_auth.AWS4Auth( + httpx2_auth.AWS4Auth( access_id="access_id", secret_key="", region="us-east-1", service="iam" ) assert str(exception_info.value) == "Secret key is mandatory." diff --git a/tests/aws_signature_v4/test_aws4auth_async.py b/tests/aws_signature_v4/test_aws4auth_async.py index 99eb9bb..82a5433 100644 --- a/tests/aws_signature_v4/test_aws4auth_async.py +++ b/tests/aws_signature_v4/test_aws4auth_async.py @@ -1,17 +1,17 @@ import time +import httpx2 import pytest import time_machine -from pytest_httpx import HTTPXMock -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth +import httpx2_auth @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) @pytest.mark.asyncio async def test_aws_auth_without_content_in_request(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -28,14 +28,14 @@ async def test_aws_auth_without_content_in_request(httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post("https://authorized_only", auth=auth) @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) @pytest.mark.asyncio async def test_aws_auth_with_content_in_request(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -53,7 +53,7 @@ async def test_aws_auth_with_content_in_request(httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post("https://authorized_only", json=[{"key": "value"}], auth=auth) @@ -62,7 +62,7 @@ async def test_aws_auth_with_content_in_request(httpx_mock: HTTPXMock): async def test_aws_auth_with_security_token_and_without_content_in_request( httpx_mock: HTTPXMock, ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -81,7 +81,7 @@ async def test_aws_auth_with_security_token_and_without_content_in_request( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post("https://authorized_only", auth=auth) @@ -90,14 +90,14 @@ async def test_aws_auth_with_security_token_and_without_content_in_request( async def test_aws_auth_share_security_tokens_between_instances( httpx_mock: HTTPXMock, ): - httpx_auth.AWS4Auth( + httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", service="iam", security_token="security_token1", ) - auth2 = httpx_auth.AWS4Auth( + auth2 = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -117,7 +117,7 @@ async def test_aws_auth_share_security_tokens_between_instances( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post("https://authorized_only", auth=auth2) @@ -126,7 +126,7 @@ async def test_aws_auth_share_security_tokens_between_instances( async def test_aws_auth_includes_custom_x_amz_headers( httpx_mock: HTTPXMock, ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -146,10 +146,8 @@ async def test_aws_auth_includes_custom_x_amz_headers( }, ) - async with httpx.AsyncClient() as client: - await client.post( - "https://authorized_only", headers={"X-AmZ-CustoM": "Custom"}, auth=auth - ) + async with httpx2.AsyncClient() as client: + await client.post("https://authorized_only", headers={"X-AmZ-CustoM": "Custom"}, auth=auth) @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) @@ -157,7 +155,7 @@ async def test_aws_auth_includes_custom_x_amz_headers( async def test_aws_auth_excludes_x_amz_client_context_header( httpx_mock: HTTPXMock, ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -175,7 +173,7 @@ async def test_aws_auth_excludes_x_amz_client_context_header( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post( "https://authorized_only", headers={"x-amz-Client-Context": "Custom"}, @@ -188,7 +186,7 @@ async def test_aws_auth_excludes_x_amz_client_context_header( async def test_aws_auth_allows_to_include_custom_and_default_forbidden_header( httpx_mock: HTTPXMock, ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -211,7 +209,7 @@ async def test_aws_auth_allows_to_include_custom_and_default_forbidden_header( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post( "https://authorized_only", headers={"Custom": "Custom", "x-amz-Client-Context": "Context"}, @@ -224,7 +222,7 @@ async def test_aws_auth_allows_to_include_custom_and_default_forbidden_header( async def test_aws_auth_does_not_strips_header_names( httpx_mock: HTTPXMock, ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -245,7 +243,7 @@ async def test_aws_auth_does_not_strips_header_names( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post( "https://authorized_only", headers={" Custom ": "Custom"}, @@ -258,7 +256,7 @@ async def test_aws_auth_does_not_strips_header_names( async def test_aws_auth_header_with_multiple_values( httpx_mock: HTTPXMock, ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -280,10 +278,10 @@ async def test_aws_auth_header_with_multiple_values( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post( "https://authorized_only", - headers=httpx.Headers( + headers=httpx2.Headers( [("Custom", "value2"), ("Custom", "value1"), ("custoM", "value3")] ), auth=auth, @@ -295,7 +293,7 @@ async def test_aws_auth_header_with_multiple_values( async def test_aws_auth_header_performances_with_spaces_in_value( httpx_mock: HTTPXMock, ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -318,7 +316,7 @@ async def test_aws_auth_header_performances_with_spaces_in_value( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: start = time.perf_counter_ns() await client.get( "https://authorized_only", @@ -335,7 +333,7 @@ async def test_aws_auth_header_performances_with_spaces_in_value( async def test_aws_auth_header_performances_without_spaces_in_value( httpx_mock: HTTPXMock, ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -358,7 +356,7 @@ async def test_aws_auth_header_performances_without_spaces_in_value( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: start = time.perf_counter_ns() await client.get( "https://authorized_only", @@ -394,7 +392,7 @@ async def test_aws_auth_header_performances_without_spaces_in_value( async def test_aws_auth_headers_encoded_values( httpx_mock: HTTPXMock, decoded_value: str, signature: str ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -416,7 +414,7 @@ async def test_aws_auth_headers_encoded_values( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post( "https://authorized_only", headers={"My-Header1": decoded_value}, @@ -428,7 +426,7 @@ async def test_aws_auth_headers_encoded_values( @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) @pytest.mark.asyncio async def test_aws_auth_host_header_with_port(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -445,7 +443,7 @@ async def test_aws_auth_host_header_with_port(httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get( "https://authorized_only:8443", auth=auth, @@ -457,7 +455,7 @@ async def test_aws_auth_host_header_with_port(httpx_mock: HTTPXMock): async def test_aws_auth_with_security_token_and_content_in_request( httpx_mock: HTTPXMock, ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -477,14 +475,14 @@ async def test_aws_auth_with_security_token_and_content_in_request( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post("https://authorized_only", json=[{"key": "value"}], auth=auth) @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) @pytest.mark.asyncio async def test_aws_auth_override_x_amz_date_header(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -501,7 +499,7 @@ async def test_aws_auth_override_x_amz_date_header(httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post( "https://authorized_only", headers={"x-amz-date": "20201011T150505Z"}, @@ -512,7 +510,7 @@ async def test_aws_auth_override_x_amz_date_header(httpx_mock: HTTPXMock): @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) @pytest.mark.asyncio async def test_aws_auth_root_path(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -529,14 +527,14 @@ async def test_aws_auth_root_path(httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post("https://authorized_only/", auth=auth) @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) @pytest.mark.asyncio async def test_aws_auth_query_parameters(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -553,7 +551,7 @@ async def test_aws_auth_query_parameters(httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post( "https://authorized_only?id-type=third&id=second*&id=first&id_type=fourth", auth=auth, @@ -563,7 +561,7 @@ async def test_aws_auth_query_parameters(httpx_mock: HTTPXMock): @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) @pytest.mark.asyncio async def test_aws_auth_query_parameters_with_multiple_values(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -580,7 +578,7 @@ async def test_aws_auth_query_parameters_with_multiple_values(httpx_mock: HTTPXM }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post("https://authorized_only?foo=1&bar=2&bar=3&bar=1", auth=auth) @@ -619,7 +617,7 @@ async def test_aws_auth_query_parameters_with_multiple_values(httpx_mock: HTTPXM async def test_aws_auth_query_parameters_encoded_values( httpx_mock: HTTPXMock, decoded_value: str, encoded_value: str, signature: str ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -636,7 +634,7 @@ async def test_aws_auth_query_parameters_encoded_values( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post( "https://authorized_only", params={"foo": decoded_value, "bar": 1}, @@ -647,7 +645,7 @@ async def test_aws_auth_query_parameters_encoded_values( @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) @pytest.mark.asyncio async def test_aws_auth_query_reserved(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -664,7 +662,7 @@ async def test_aws_auth_query_reserved(httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post( r'https://authorized_only/?@$%^&+=/,?><`";:\|][{} =@$%^&+=/,?><`";:\|][{}', auth=auth, @@ -674,7 +672,7 @@ async def test_aws_auth_query_reserved(httpx_mock: HTTPXMock): @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) @pytest.mark.asyncio async def test_aws_auth_query_reserved_with_fragment(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -691,7 +689,7 @@ async def test_aws_auth_query_reserved_with_fragment(httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post( r'https://authorized_only/?@#$%^&+=/,?><`";:\|][{} =@#$%^&+=/,?><`";:\|][{}', auth=auth, @@ -701,7 +699,7 @@ async def test_aws_auth_query_reserved_with_fragment(httpx_mock: HTTPXMock): @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) @pytest.mark.asyncio async def test_aws_auth_query_parameters_with_semicolon(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -718,7 +716,7 @@ async def test_aws_auth_query_parameters_with_semicolon(httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get( "https://authorized_only?foo=value;bar=1", auth=auth, @@ -728,7 +726,7 @@ async def test_aws_auth_query_parameters_with_semicolon(httpx_mock: HTTPXMock): @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) @pytest.mark.asyncio async def test_aws_auth_path_normalize(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -745,14 +743,14 @@ async def test_aws_auth_path_normalize(httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post("https://authorized_only/./test/../stuff//more/", auth=auth) @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) @pytest.mark.asyncio async def test_aws_auth_path_quoting(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -769,14 +767,14 @@ async def test_aws_auth_path_quoting(httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post("https://authorized_only/test/hello-*.&^~+{}!$£_ ", auth=auth) @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) @pytest.mark.asyncio async def test_aws_auth_path_percent_encode_non_s3(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -793,14 +791,14 @@ async def test_aws_auth_path_percent_encode_non_s3(httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post("https://authorized_only/test/%2a%2b%25/~-_^& %%", auth=auth) @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) @pytest.mark.asyncio async def test_aws_auth_path_percent_encode_s3(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -817,14 +815,14 @@ async def test_aws_auth_path_percent_encode_s3(httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.post("https://authorized_only/test/%2a%2b%25/~-_^& %%", auth=auth) @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) @pytest.mark.asyncio async def test_aws_auth_without_path(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -841,5 +839,5 @@ async def test_aws_auth_without_path(httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) diff --git a/tests/aws_signature_v4/test_aws4auth_sync.py b/tests/aws_signature_v4/test_aws4auth_sync.py index e3e5e7c..dd7de1b 100644 --- a/tests/aws_signature_v4/test_aws4auth_sync.py +++ b/tests/aws_signature_v4/test_aws4auth_sync.py @@ -1,16 +1,16 @@ import time +import httpx2 import pytest import time_machine -from pytest_httpx import HTTPXMock -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth +import httpx2_auth @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) def test_aws_auth_without_content_in_request(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -27,13 +27,13 @@ def test_aws_auth_without_content_in_request(httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post("https://authorized_only", auth=auth) @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) def test_aws_auth_with_content_in_request(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -51,7 +51,7 @@ def test_aws_auth_with_content_in_request(httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post("https://authorized_only", json=[{"key": "value"}], auth=auth) @@ -59,7 +59,7 @@ def test_aws_auth_with_content_in_request(httpx_mock: HTTPXMock): def test_aws_auth_with_security_token_and_without_content_in_request( httpx_mock: HTTPXMock, ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -78,7 +78,7 @@ def test_aws_auth_with_security_token_and_without_content_in_request( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post("https://authorized_only", auth=auth) @@ -86,14 +86,14 @@ def test_aws_auth_with_security_token_and_without_content_in_request( def test_aws_auth_share_security_tokens_between_instances( httpx_mock: HTTPXMock, ): - httpx_auth.AWS4Auth( + httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", service="iam", security_token="security_token1", ) - auth2 = httpx_auth.AWS4Auth( + auth2 = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -113,7 +113,7 @@ def test_aws_auth_share_security_tokens_between_instances( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post("https://authorized_only", auth=auth2) @@ -121,7 +121,7 @@ def test_aws_auth_share_security_tokens_between_instances( def test_aws_auth_includes_custom_x_amz_headers( httpx_mock: HTTPXMock, ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -141,17 +141,15 @@ def test_aws_auth_includes_custom_x_amz_headers( }, ) - with httpx.Client() as client: - client.post( - "https://authorized_only", headers={"X-AmZ-CustoM": "Custom"}, auth=auth - ) + with httpx2.Client() as client: + client.post("https://authorized_only", headers={"X-AmZ-CustoM": "Custom"}, auth=auth) @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) def test_aws_auth_excludes_x_amz_client_context_header( httpx_mock: HTTPXMock, ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -169,7 +167,7 @@ def test_aws_auth_excludes_x_amz_client_context_header( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post( "https://authorized_only", headers={"x-amz-Client-Context": "Custom"}, @@ -181,7 +179,7 @@ def test_aws_auth_excludes_x_amz_client_context_header( def test_aws_auth_allows_to_include_custom_and_default_forbidden_header( httpx_mock: HTTPXMock, ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -204,7 +202,7 @@ def test_aws_auth_allows_to_include_custom_and_default_forbidden_header( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post( "https://authorized_only", headers={"Custom": "Custom", "x-amz-Client-Context": "Context"}, @@ -216,7 +214,7 @@ def test_aws_auth_allows_to_include_custom_and_default_forbidden_header( def test_aws_auth_does_not_strips_header_names( httpx_mock: HTTPXMock, ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -237,7 +235,7 @@ def test_aws_auth_does_not_strips_header_names( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post( "https://authorized_only", headers={" Custom ": "Custom"}, @@ -249,7 +247,7 @@ def test_aws_auth_does_not_strips_header_names( def test_aws_auth_header_with_multiple_values( httpx_mock: HTTPXMock, ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -271,10 +269,10 @@ def test_aws_auth_header_with_multiple_values( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post( "https://authorized_only", - headers=httpx.Headers( + headers=httpx2.Headers( [("Custom", "value2"), ("Custom", "value1"), ("custoM", "value3")] ), auth=auth, @@ -285,7 +283,7 @@ def test_aws_auth_header_with_multiple_values( def test_aws_auth_header_performances_with_spaces_in_value( httpx_mock: HTTPXMock, ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -308,7 +306,7 @@ def test_aws_auth_header_performances_with_spaces_in_value( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: start = time.perf_counter_ns() client.get( "https://authorized_only", @@ -324,7 +322,7 @@ def test_aws_auth_header_performances_with_spaces_in_value( def test_aws_auth_header_performances_without_spaces_in_value( httpx_mock: HTTPXMock, ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -347,7 +345,7 @@ def test_aws_auth_header_performances_without_spaces_in_value( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: start = time.perf_counter_ns() client.get( "https://authorized_only", @@ -379,10 +377,8 @@ def test_aws_auth_header_performances_without_spaces_in_value( ], ) @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) -def test_aws_auth_headers_encoded_values( - httpx_mock: HTTPXMock, decoded_value: str, signature: str -): - auth = httpx_auth.AWS4Auth( +def test_aws_auth_headers_encoded_values(httpx_mock: HTTPXMock, decoded_value: str, signature: str): + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -404,7 +400,7 @@ def test_aws_auth_headers_encoded_values( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post( "https://authorized_only", headers={"My-Header1": decoded_value}, @@ -415,7 +411,7 @@ def test_aws_auth_headers_encoded_values( @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) def test_aws_auth_host_header_with_port(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -432,7 +428,7 @@ def test_aws_auth_host_header_with_port(httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get( "https://authorized_only:8443", auth=auth, @@ -441,7 +437,7 @@ def test_aws_auth_host_header_with_port(httpx_mock: HTTPXMock): @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) def test_aws_auth_with_security_token_and_content_in_request(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -461,13 +457,13 @@ def test_aws_auth_with_security_token_and_content_in_request(httpx_mock: HTTPXMo }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post("https://authorized_only", json=[{"key": "value"}], auth=auth) @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) def test_aws_auth_override_x_amz_date_header(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -484,7 +480,7 @@ def test_aws_auth_override_x_amz_date_header(httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post( "https://authorized_only", headers={"x-amz-date": "20201011T150505Z"}, @@ -494,7 +490,7 @@ def test_aws_auth_override_x_amz_date_header(httpx_mock: HTTPXMock): @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) def test_aws_auth_root_path(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -511,13 +507,13 @@ def test_aws_auth_root_path(httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post("https://authorized_only/", auth=auth) @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) def test_aws_auth_query_parameters(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -534,7 +530,7 @@ def test_aws_auth_query_parameters(httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post( "https://authorized_only?id-type=third&id=second*&id=first&id_type=fourth", auth=auth, @@ -543,7 +539,7 @@ def test_aws_auth_query_parameters(httpx_mock: HTTPXMock): @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) def test_aws_auth_query_parameters_with_multiple_values(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -560,7 +556,7 @@ def test_aws_auth_query_parameters_with_multiple_values(httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post("https://authorized_only?foo=1&bar=2&bar=3&bar=1", auth=auth) @@ -598,7 +594,7 @@ def test_aws_auth_query_parameters_with_multiple_values(httpx_mock: HTTPXMock): def test_aws_auth_query_parameters_encoded_values( httpx_mock: HTTPXMock, decoded_value: str, encoded_value: str, signature: str ): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -615,7 +611,7 @@ def test_aws_auth_query_parameters_encoded_values( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post( "https://authorized_only", params={"foo": decoded_value, "bar": 1}, @@ -625,7 +621,7 @@ def test_aws_auth_query_parameters_encoded_values( @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) def test_aws_auth_query_reserved(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -642,7 +638,7 @@ def test_aws_auth_query_reserved(httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post( r'https://authorized_only/?@$%^&+=/,?><`";:\|][{} =@$%^&+=/,?><`";:\|][{}', auth=auth, @@ -651,7 +647,7 @@ def test_aws_auth_query_reserved(httpx_mock: HTTPXMock): @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) def test_aws_auth_query_reserved_with_fragment(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -668,7 +664,7 @@ def test_aws_auth_query_reserved_with_fragment(httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post( r'https://authorized_only/?@#$%^&+=/,?><`";:\|][{} =@#$%^&+=/,?><`";:\|][{}', auth=auth, @@ -677,7 +673,7 @@ def test_aws_auth_query_reserved_with_fragment(httpx_mock: HTTPXMock): @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) def test_aws_auth_query_parameters_with_semicolon(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -694,7 +690,7 @@ def test_aws_auth_query_parameters_with_semicolon(httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get( "https://authorized_only?foo=value;bar=1", auth=auth, @@ -703,7 +699,7 @@ def test_aws_auth_query_parameters_with_semicolon(httpx_mock: HTTPXMock): @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) def test_aws_auth_path_normalize(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -720,13 +716,13 @@ def test_aws_auth_path_normalize(httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post("https://authorized_only/./test/../stuff//more/", auth=auth) @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) def test_aws_auth_path_quoting(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -743,13 +739,13 @@ def test_aws_auth_path_quoting(httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post("https://authorized_only/test/hello-*.&^~+{}!$£_ ", auth=auth) @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) def test_aws_auth_path_percent_encode_non_s3(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -766,13 +762,13 @@ def test_aws_auth_path_percent_encode_non_s3(httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post("https://authorized_only/test/%2a%2b%25/~-_^& %%", auth=auth) @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) def test_aws_auth_path_percent_encode_s3(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -789,13 +785,13 @@ def test_aws_auth_path_percent_encode_s3(httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.post("https://authorized_only/test/%2a%2b%25/~-_^& %%", auth=auth) @time_machine.travel("2018-10-11T15:05:05.663979+00:00", tick=False) def test_aws_auth_without_path(httpx_mock: HTTPXMock): - auth = httpx_auth.AWS4Auth( + auth = httpx2_auth.AWS4Auth( access_id="access_id", secret_key="wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", region="us-east-1", @@ -812,5 +808,5 @@ def test_aws_auth_without_path(httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) diff --git a/tests/basic_auth/__init__.py b/tests/basic_auth/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/basic_auth/test_basic_async.py b/tests/basic_auth/test_basic_async.py index 9756d20..7b5502d 100644 --- a/tests/basic_auth/test_basic_async.py +++ b/tests/basic_auth/test_basic_async.py @@ -1,13 +1,13 @@ -import httpx +import httpx2 import pytest -from pytest_httpx import HTTPXMock +from pytest_httpx2 import HTTPXMock -import httpx_auth +import httpx2_auth @pytest.mark.asyncio async def test_basic_authentication_send_authorization_header(httpx_mock: HTTPXMock): - auth = httpx_auth.Basic("test_user", "test_pwd") + auth = httpx2_auth.Basic("test_user", "test_pwd") httpx_mock.add_response( url="https://authorized_only", @@ -17,5 +17,5 @@ async def test_basic_authentication_send_authorization_header(httpx_mock: HTTPXM }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) diff --git a/tests/basic_auth/test_basic_sync.py b/tests/basic_auth/test_basic_sync.py index 361c251..ce3abe2 100644 --- a/tests/basic_auth/test_basic_sync.py +++ b/tests/basic_auth/test_basic_sync.py @@ -1,11 +1,11 @@ -import httpx -from pytest_httpx import HTTPXMock +import httpx2 +from pytest_httpx2 import HTTPXMock -import httpx_auth +import httpx2_auth def test_basic_authentication_send_authorization_header(httpx_mock: HTTPXMock): - auth = httpx_auth.Basic("test_user", "test_pwd") + auth = httpx2_auth.Basic("test_user", "test_pwd") httpx_mock.add_response( url="https://authorized_only", @@ -15,5 +15,5 @@ def test_basic_authentication_send_authorization_header(httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) diff --git a/tests/features/__init__.py b/tests/features/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/features/multi_auth/__init__.py b/tests/features/multi_auth/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/features/multi_auth/test_add_operator_async.py b/tests/features/multi_auth/test_add_operator_async.py index 396cf9a..784276a 100644 --- a/tests/features/multi_auth/test_add_operator_async.py +++ b/tests/features/multi_auth/test_add_operator_async.py @@ -1,18 +1,18 @@ import datetime +import httpx2 import pytest -from pytest_httpx import HTTPXMock -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import BrowserMock, create_token, token_cache, browser_mock -import httpx_auth._oauth2.authorization_code_pkce +import httpx2_auth +import httpx2_auth._oauth2.authorization_code_pkce +from httpx2_auth.testing import BrowserMock, create_token @pytest.mark.asyncio async def test_basic_and_api_key_authentication_can_be_combined(httpx_mock: HTTPXMock): - basic_auth = httpx_auth.Basic("test_user", "test_pwd") - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + basic_auth = httpx2_auth.Basic("test_user", "test_pwd") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = basic_auth + api_key_auth httpx_mock.add_response( @@ -24,7 +24,7 @@ async def test_basic_and_api_key_authentication_can_be_combined(httpx_mock: HTTP }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -32,13 +32,9 @@ async def test_basic_and_api_key_authentication_can_be_combined(httpx_mock: HTTP async def test_header_api_key_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") auth = api_key_auth + (api_key_auth2 + api_key_auth3) httpx_mock.add_response( @@ -51,21 +47,15 @@ async def test_header_api_key_and_multiple_authentication_can_be_combined( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio -async def test_multiple_auth_and_header_api_key_can_be_combined( - token_cache, httpx_mock: HTTPXMock -): - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) +async def test_multiple_auth_and_header_api_key_can_be_combined(token_cache, httpx_mock: HTTPXMock): + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") auth = (api_key_auth + api_key_auth2) + api_key_auth3 httpx_mock.add_response( @@ -78,24 +68,16 @@ async def test_multiple_auth_and_header_api_key_can_be_combined( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio -async def test_multiple_auth_and_multiple_auth_can_be_combined( - token_cache, httpx_mock: HTTPXMock -): - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) - api_key_auth4 = httpx_auth.HeaderApiKey( - "my_provided_api_key4", header_name="X-Api-Key4" - ) +async def test_multiple_auth_and_multiple_auth_can_be_combined(token_cache, httpx_mock: HTTPXMock): + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") + api_key_auth4 = httpx2_auth.HeaderApiKey("my_provided_api_key4", header_name="X-Api-Key4") auth = (api_key_auth + api_key_auth2) + (api_key_auth3 + api_key_auth4) httpx_mock.add_response( @@ -109,7 +91,7 @@ async def test_multiple_auth_and_multiple_auth_can_be_combined( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -117,13 +99,9 @@ async def test_multiple_auth_and_multiple_auth_can_be_combined( async def test_basic_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - basic_auth = httpx_auth.Basic("test_user", "test_pwd") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) + basic_auth = httpx2_auth.Basic("test_user", "test_pwd") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") auth = basic_auth + (api_key_auth2 + api_key_auth3) httpx_mock.add_response( @@ -136,7 +114,7 @@ async def test_basic_and_multiple_authentication_can_be_combined( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -144,13 +122,9 @@ async def test_basic_and_multiple_authentication_can_be_combined( async def test_query_api_key_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - api_key_auth = httpx_auth.QueryApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.QueryApiKey( - "my_provided_api_key2", query_parameter_name="api_key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) + api_key_auth = httpx2_auth.QueryApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.QueryApiKey("my_provided_api_key2", query_parameter_name="api_key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") auth = api_key_auth + (api_key_auth2 + api_key_auth3) httpx_mock.add_response( @@ -161,7 +135,7 @@ async def test_query_api_key_and_multiple_authentication_can_be_combined( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -169,10 +143,10 @@ async def test_query_api_key_and_multiple_authentication_can_be_combined( async def test_oauth2_resource_owner_password_and_api_key_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - resource_owner_password_auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + resource_owner_password_auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = resource_owner_password_auth + api_key_auth httpx_mock.add_response( @@ -196,7 +170,7 @@ async def test_oauth2_resource_owner_password_and_api_key_authentication_can_be_ }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -204,13 +178,11 @@ async def test_oauth2_resource_owner_password_and_api_key_authentication_can_be_ async def test_oauth2_resource_owner_password_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - resource_owner_password_auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + resource_owner_password_auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = resource_owner_password_auth + (api_key_auth + api_key_auth2) httpx_mock.add_response( @@ -235,7 +207,7 @@ async def test_oauth2_resource_owner_password_and_multiple_authentication_can_be }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -243,10 +215,10 @@ async def test_oauth2_resource_owner_password_and_multiple_authentication_can_be async def test_oauth2_client_credential_and_api_key_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - resource_owner_password_auth = httpx_auth.OAuth2ClientCredentials( + resource_owner_password_auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = resource_owner_password_auth + api_key_auth httpx_mock.add_response( @@ -270,7 +242,7 @@ async def test_oauth2_client_credential_and_api_key_authentication_can_be_combin }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -278,13 +250,11 @@ async def test_oauth2_client_credential_and_api_key_authentication_can_be_combin async def test_oauth2_client_credential_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - resource_owner_password_auth = httpx_auth.OAuth2ClientCredentials( + resource_owner_password_auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = resource_owner_password_auth + (api_key_auth + api_key_auth2) httpx_mock.add_response( @@ -309,7 +279,7 @@ async def test_oauth2_client_credential_and_multiple_authentication_can_be_combi }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -317,12 +287,12 @@ async def test_oauth2_client_credential_and_multiple_authentication_can_be_combi async def test_oauth2_authorization_code_and_api_key_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - authorization_code_auth = httpx_auth.OAuth2AuthorizationCode( + authorization_code_auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = authorization_code_auth + api_key_auth tab = browser_mock.add_response( @@ -351,7 +321,7 @@ async def test_oauth2_authorization_code_and_api_key_authentication_can_be_combi }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -361,15 +331,13 @@ async def test_oauth2_authorization_code_and_api_key_authentication_can_be_combi async def test_oauth2_authorization_code_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - authorization_code_auth = httpx_auth.OAuth2AuthorizationCode( + authorization_code_auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = authorization_code_auth + (api_key_auth + api_key_auth2) tab = browser_mock.add_response( @@ -399,7 +367,7 @@ async def test_oauth2_authorization_code_and_multiple_authentication_can_be_comb }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -414,14 +382,14 @@ async def test_oauth2_pkce_and_api_key_authentication_can_be_combined( unused_tcp_port: int, ): monkeypatch.setattr( - httpx_auth._oauth2.authorization_code_pkce.os, "urandom", lambda x: b"1" * 63 + httpx2_auth._oauth2.authorization_code_pkce.os, "urandom", lambda x: b"1" * 63 ) - pkce_auth = httpx_auth.OAuth2AuthorizationCodePKCE( + pkce_auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = pkce_auth + api_key_auth tab = browser_mock.add_response( @@ -450,7 +418,7 @@ async def test_oauth2_pkce_and_api_key_authentication_can_be_combined( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -465,17 +433,15 @@ async def test_oauth2_pkce_and_multiple_authentication_can_be_combined( unused_tcp_port: int, ): monkeypatch.setattr( - httpx_auth._oauth2.authorization_code_pkce.os, "urandom", lambda x: b"1" * 63 + httpx2_auth._oauth2.authorization_code_pkce.os, "urandom", lambda x: b"1" * 63 ) - pkce_auth = httpx_auth.OAuth2AuthorizationCodePKCE( + pkce_auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = pkce_auth + (api_key_auth + api_key_auth2) tab = browser_mock.add_response( @@ -505,7 +471,7 @@ async def test_oauth2_pkce_and_multiple_authentication_can_be_combined( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -515,15 +481,13 @@ async def test_oauth2_pkce_and_multiple_authentication_can_be_combined( async def test_oauth2_implicit_and_api_key_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - implicit_auth = httpx_auth.OAuth2Implicit( + implicit_auth = httpx2_auth.OAuth2Implicit( "https://provide_token", redirect_uri_port=unused_tcp_port ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = implicit_auth + api_key_auth - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -540,7 +504,7 @@ async def test_oauth2_implicit_and_api_key_authentication_can_be_combined( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -550,18 +514,14 @@ async def test_oauth2_implicit_and_api_key_authentication_can_be_combined( async def test_oauth2_implicit_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - implicit_auth = httpx_auth.OAuth2Implicit( + implicit_auth = httpx2_auth.OAuth2Implicit( "https://provide_token", redirect_uri_port=unused_tcp_port ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = implicit_auth + (api_key_auth + api_key_auth2) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -579,7 +539,7 @@ async def test_oauth2_implicit_and_multiple_authentication_can_be_combined( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() diff --git a/tests/features/multi_auth/test_add_operator_sync.py b/tests/features/multi_auth/test_add_operator_sync.py index fc176f5..f124a73 100644 --- a/tests/features/multi_auth/test_add_operator_sync.py +++ b/tests/features/multi_auth/test_add_operator_sync.py @@ -1,16 +1,16 @@ import datetime -from pytest_httpx import HTTPXMock -import httpx +import httpx2 +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import BrowserMock, create_token, token_cache, browser_mock -import httpx_auth._oauth2.authorization_code_pkce +import httpx2_auth +import httpx2_auth._oauth2.authorization_code_pkce +from httpx2_auth.testing import BrowserMock, create_token def test_basic_and_api_key_authentication_can_be_combined(httpx_mock: HTTPXMock): - basic_auth = httpx_auth.Basic("test_user", "test_pwd") - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + basic_auth = httpx2_auth.Basic("test_user", "test_pwd") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = basic_auth + api_key_auth httpx_mock.add_response( @@ -22,20 +22,16 @@ def test_basic_and_api_key_authentication_can_be_combined(httpx_mock: HTTPXMock) }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_header_api_key_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") auth = api_key_auth + (api_key_auth2 + api_key_auth3) httpx_mock.add_response( @@ -48,20 +44,14 @@ def test_header_api_key_and_multiple_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) -def test_multiple_auth_and_header_api_key_can_be_combined( - token_cache, httpx_mock: HTTPXMock -): - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) +def test_multiple_auth_and_header_api_key_can_be_combined(token_cache, httpx_mock: HTTPXMock): + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") auth = (api_key_auth + api_key_auth2) + api_key_auth3 httpx_mock.add_response( @@ -74,23 +64,15 @@ def test_multiple_auth_and_header_api_key_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) -def test_multiple_auth_and_multiple_auth_can_be_combined( - token_cache, httpx_mock: HTTPXMock -): - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) - api_key_auth4 = httpx_auth.HeaderApiKey( - "my_provided_api_key4", header_name="X-Api-Key4" - ) +def test_multiple_auth_and_multiple_auth_can_be_combined(token_cache, httpx_mock: HTTPXMock): + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") + api_key_auth4 = httpx2_auth.HeaderApiKey("my_provided_api_key4", header_name="X-Api-Key4") auth = (api_key_auth + api_key_auth2) + (api_key_auth3 + api_key_auth4) httpx_mock.add_response( @@ -104,20 +86,14 @@ def test_multiple_auth_and_multiple_auth_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) -def test_basic_and_multiple_authentication_can_be_combined( - token_cache, httpx_mock: HTTPXMock -): - basic_auth = httpx_auth.Basic("test_user", "test_pwd") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) +def test_basic_and_multiple_authentication_can_be_combined(token_cache, httpx_mock: HTTPXMock): + basic_auth = httpx2_auth.Basic("test_user", "test_pwd") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") auth = basic_auth + (api_key_auth2 + api_key_auth3) httpx_mock.add_response( @@ -130,20 +106,16 @@ def test_basic_and_multiple_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_query_api_key_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - api_key_auth = httpx_auth.QueryApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.QueryApiKey( - "my_provided_api_key2", query_parameter_name="api_key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) + api_key_auth = httpx2_auth.QueryApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.QueryApiKey("my_provided_api_key2", query_parameter_name="api_key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") auth = api_key_auth + (api_key_auth2 + api_key_auth3) httpx_mock.add_response( @@ -154,17 +126,17 @@ def test_query_api_key_and_multiple_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_resource_owner_password_and_api_key_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - resource_owner_password_auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + resource_owner_password_auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = resource_owner_password_auth + api_key_auth httpx_mock.add_response( @@ -188,20 +160,18 @@ def test_oauth2_resource_owner_password_and_api_key_authentication_can_be_combin }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_resource_owner_password_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - resource_owner_password_auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + resource_owner_password_auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = resource_owner_password_auth + (api_key_auth + api_key_auth2) httpx_mock.add_response( @@ -226,17 +196,17 @@ def test_oauth2_resource_owner_password_and_multiple_authentication_can_be_combi }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_client_credential_and_api_key_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - resource_owner_password_auth = httpx_auth.OAuth2ClientCredentials( + resource_owner_password_auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = resource_owner_password_auth + api_key_auth httpx_mock.add_response( @@ -260,20 +230,18 @@ def test_oauth2_client_credential_and_api_key_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_client_credential_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - resource_owner_password_auth = httpx_auth.OAuth2ClientCredentials( + resource_owner_password_auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = resource_owner_password_auth + (api_key_auth + api_key_auth2) httpx_mock.add_response( @@ -298,19 +266,19 @@ def test_oauth2_client_credential_and_multiple_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_authorization_code_and_api_key_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - authorization_code_auth = httpx_auth.OAuth2AuthorizationCode( + authorization_code_auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = authorization_code_auth + api_key_auth tab = browser_mock.add_response( @@ -339,7 +307,7 @@ def test_oauth2_authorization_code_and_api_key_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -348,15 +316,13 @@ def test_oauth2_authorization_code_and_api_key_authentication_can_be_combined( def test_oauth2_authorization_code_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - authorization_code_auth = httpx_auth.OAuth2AuthorizationCode( + authorization_code_auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = authorization_code_auth + (api_key_auth + api_key_auth2) tab = browser_mock.add_response( @@ -386,7 +352,7 @@ def test_oauth2_authorization_code_and_multiple_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -400,14 +366,14 @@ def test_oauth2_pkce_and_api_key_authentication_can_be_combined( unused_tcp_port: int, ): monkeypatch.setattr( - httpx_auth._oauth2.authorization_code_pkce.os, "urandom", lambda x: b"1" * 63 + httpx2_auth._oauth2.authorization_code_pkce.os, "urandom", lambda x: b"1" * 63 ) - pkce_auth = httpx_auth.OAuth2AuthorizationCodePKCE( + pkce_auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = pkce_auth + api_key_auth tab = browser_mock.add_response( @@ -436,7 +402,7 @@ def test_oauth2_pkce_and_api_key_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -450,17 +416,15 @@ def test_oauth2_pkce_and_multiple_authentication_can_be_combined( unused_tcp_port: int, ): monkeypatch.setattr( - httpx_auth._oauth2.authorization_code_pkce.os, "urandom", lambda x: b"1" * 63 + httpx2_auth._oauth2.authorization_code_pkce.os, "urandom", lambda x: b"1" * 63 ) - pkce_auth = httpx_auth.OAuth2AuthorizationCodePKCE( + pkce_auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = pkce_auth + (api_key_auth + api_key_auth2) tab = browser_mock.add_response( @@ -490,7 +454,7 @@ def test_oauth2_pkce_and_multiple_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -499,16 +463,14 @@ def test_oauth2_pkce_and_multiple_authentication_can_be_combined( def test_oauth2_implicit_and_api_key_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - implicit_auth = httpx_auth.OAuth2Implicit( + implicit_auth = httpx2_auth.OAuth2Implicit( "https://provide_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = implicit_auth + api_key_auth - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -525,7 +487,7 @@ def test_oauth2_implicit_and_api_key_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -534,19 +496,15 @@ def test_oauth2_implicit_and_api_key_authentication_can_be_combined( def test_oauth2_implicit_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - implicit_auth = httpx_auth.OAuth2Implicit( + implicit_auth = httpx2_auth.OAuth2Implicit( "https://provide_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = implicit_auth + (api_key_auth + api_key_auth2) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -564,7 +522,7 @@ def test_oauth2_implicit_and_multiple_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() diff --git a/tests/features/multi_auth/test_and_operator_async.py b/tests/features/multi_auth/test_and_operator_async.py index a77f25e..186f856 100644 --- a/tests/features/multi_auth/test_and_operator_async.py +++ b/tests/features/multi_auth/test_and_operator_async.py @@ -1,18 +1,18 @@ import datetime +import httpx2 import pytest -from pytest_httpx import HTTPXMock -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import BrowserMock, create_token, token_cache, browser_mock -import httpx_auth._oauth2.authorization_code_pkce +import httpx2_auth +import httpx2_auth._oauth2.authorization_code_pkce +from httpx2_auth.testing import BrowserMock, create_token @pytest.mark.asyncio async def test_basic_and_api_key_authentication_can_be_combined(httpx_mock: HTTPXMock): - basic_auth = httpx_auth.Basic("test_user", "test_pwd") - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + basic_auth = httpx2_auth.Basic("test_user", "test_pwd") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = basic_auth & api_key_auth httpx_mock.add_response( @@ -24,7 +24,7 @@ async def test_basic_and_api_key_authentication_can_be_combined(httpx_mock: HTTP }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -32,13 +32,9 @@ async def test_basic_and_api_key_authentication_can_be_combined(httpx_mock: HTTP async def test_header_api_key_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") auth = api_key_auth & (api_key_auth2 & api_key_auth3) httpx_mock.add_response( @@ -51,21 +47,15 @@ async def test_header_api_key_and_multiple_authentication_can_be_combined( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio -async def test_multiple_auth_and_header_api_key_can_be_combined( - token_cache, httpx_mock: HTTPXMock -): - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) +async def test_multiple_auth_and_header_api_key_can_be_combined(token_cache, httpx_mock: HTTPXMock): + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") auth = (api_key_auth & api_key_auth2) & api_key_auth3 httpx_mock.add_response( @@ -78,24 +68,16 @@ async def test_multiple_auth_and_header_api_key_can_be_combined( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio -async def test_multiple_auth_and_multiple_auth_can_be_combined( - token_cache, httpx_mock: HTTPXMock -): - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) - api_key_auth4 = httpx_auth.HeaderApiKey( - "my_provided_api_key4", header_name="X-Api-Key4" - ) +async def test_multiple_auth_and_multiple_auth_can_be_combined(token_cache, httpx_mock: HTTPXMock): + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") + api_key_auth4 = httpx2_auth.HeaderApiKey("my_provided_api_key4", header_name="X-Api-Key4") auth = (api_key_auth & api_key_auth2) & (api_key_auth3 & api_key_auth4) httpx_mock.add_response( @@ -109,7 +91,7 @@ async def test_multiple_auth_and_multiple_auth_can_be_combined( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -117,13 +99,9 @@ async def test_multiple_auth_and_multiple_auth_can_be_combined( async def test_basic_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - basic_auth = httpx_auth.Basic("test_user", "test_pwd") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) + basic_auth = httpx2_auth.Basic("test_user", "test_pwd") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") auth = basic_auth & (api_key_auth2 & api_key_auth3) httpx_mock.add_response( @@ -136,7 +114,7 @@ async def test_basic_and_multiple_authentication_can_be_combined( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -144,13 +122,9 @@ async def test_basic_and_multiple_authentication_can_be_combined( async def test_query_api_key_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - api_key_auth = httpx_auth.QueryApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.QueryApiKey( - "my_provided_api_key2", query_parameter_name="api_key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) + api_key_auth = httpx2_auth.QueryApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.QueryApiKey("my_provided_api_key2", query_parameter_name="api_key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") auth = api_key_auth & (api_key_auth2 & api_key_auth3) httpx_mock.add_response( @@ -161,7 +135,7 @@ async def test_query_api_key_and_multiple_authentication_can_be_combined( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -169,10 +143,10 @@ async def test_query_api_key_and_multiple_authentication_can_be_combined( async def test_oauth2_resource_owner_password_and_api_key_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - resource_owner_password_auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + resource_owner_password_auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = resource_owner_password_auth & api_key_auth httpx_mock.add_response( @@ -196,7 +170,7 @@ async def test_oauth2_resource_owner_password_and_api_key_authentication_can_be_ }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -204,13 +178,11 @@ async def test_oauth2_resource_owner_password_and_api_key_authentication_can_be_ async def test_oauth2_resource_owner_password_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - resource_owner_password_auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + resource_owner_password_auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = resource_owner_password_auth & (api_key_auth & api_key_auth2) httpx_mock.add_response( @@ -235,7 +207,7 @@ async def test_oauth2_resource_owner_password_and_multiple_authentication_can_be }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -243,10 +215,10 @@ async def test_oauth2_resource_owner_password_and_multiple_authentication_can_be async def test_oauth2_client_credential_and_api_key_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - resource_owner_password_auth = httpx_auth.OAuth2ClientCredentials( + resource_owner_password_auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = resource_owner_password_auth & api_key_auth httpx_mock.add_response( @@ -270,7 +242,7 @@ async def test_oauth2_client_credential_and_api_key_authentication_can_be_combin }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -278,13 +250,11 @@ async def test_oauth2_client_credential_and_api_key_authentication_can_be_combin async def test_oauth2_client_credential_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - resource_owner_password_auth = httpx_auth.OAuth2ClientCredentials( + resource_owner_password_auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = resource_owner_password_auth & (api_key_auth & api_key_auth2) httpx_mock.add_response( @@ -309,7 +279,7 @@ async def test_oauth2_client_credential_and_multiple_authentication_can_be_combi }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -317,12 +287,12 @@ async def test_oauth2_client_credential_and_multiple_authentication_can_be_combi async def test_oauth2_authorization_code_and_api_key_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - authorization_code_auth = httpx_auth.OAuth2AuthorizationCode( + authorization_code_auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = authorization_code_auth & api_key_auth tab = browser_mock.add_response( @@ -351,7 +321,7 @@ async def test_oauth2_authorization_code_and_api_key_authentication_can_be_combi }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -361,15 +331,13 @@ async def test_oauth2_authorization_code_and_api_key_authentication_can_be_combi async def test_oauth2_authorization_code_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - authorization_code_auth = httpx_auth.OAuth2AuthorizationCode( + authorization_code_auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = authorization_code_auth & (api_key_auth & api_key_auth2) tab = browser_mock.add_response( @@ -399,7 +367,7 @@ async def test_oauth2_authorization_code_and_multiple_authentication_can_be_comb }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -414,14 +382,14 @@ async def test_oauth2_pkce_and_api_key_authentication_can_be_combined( unused_tcp_port: int, ): monkeypatch.setattr( - httpx_auth._oauth2.authorization_code_pkce.os, "urandom", lambda x: b"1" * 63 + httpx2_auth._oauth2.authorization_code_pkce.os, "urandom", lambda x: b"1" * 63 ) - pkce_auth = httpx_auth.OAuth2AuthorizationCodePKCE( + pkce_auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = pkce_auth & api_key_auth tab = browser_mock.add_response( @@ -450,7 +418,7 @@ async def test_oauth2_pkce_and_api_key_authentication_can_be_combined( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -465,17 +433,15 @@ async def test_oauth2_pkce_and_multiple_authentication_can_be_combined( unused_tcp_port: int, ): monkeypatch.setattr( - httpx_auth._oauth2.authorization_code_pkce.os, "urandom", lambda x: b"1" * 63 + httpx2_auth._oauth2.authorization_code_pkce.os, "urandom", lambda x: b"1" * 63 ) - pkce_auth = httpx_auth.OAuth2AuthorizationCodePKCE( + pkce_auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = pkce_auth & (api_key_auth & api_key_auth2) tab = browser_mock.add_response( @@ -505,7 +471,7 @@ async def test_oauth2_pkce_and_multiple_authentication_can_be_combined( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -515,16 +481,14 @@ async def test_oauth2_pkce_and_multiple_authentication_can_be_combined( async def test_oauth2_implicit_and_api_key_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - implicit_auth = httpx_auth.OAuth2Implicit( + implicit_auth = httpx2_auth.OAuth2Implicit( "https://provide_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = implicit_auth & api_key_auth - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -541,7 +505,7 @@ async def test_oauth2_implicit_and_api_key_authentication_can_be_combined( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -551,19 +515,15 @@ async def test_oauth2_implicit_and_api_key_authentication_can_be_combined( async def test_oauth2_implicit_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - implicit_auth = httpx_auth.OAuth2Implicit( + implicit_auth = httpx2_auth.OAuth2Implicit( "https://provide_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = implicit_auth & (api_key_auth & api_key_auth2) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -581,7 +541,7 @@ async def test_oauth2_implicit_and_multiple_authentication_can_be_combined( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() diff --git a/tests/features/multi_auth/test_and_operator_sync.py b/tests/features/multi_auth/test_and_operator_sync.py index a06a30d..9374fc3 100644 --- a/tests/features/multi_auth/test_and_operator_sync.py +++ b/tests/features/multi_auth/test_and_operator_sync.py @@ -1,16 +1,16 @@ import datetime -from pytest_httpx import HTTPXMock -import httpx +import httpx2 +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import BrowserMock, create_token, token_cache, browser_mock -import httpx_auth._oauth2.authorization_code_pkce +import httpx2_auth +import httpx2_auth._oauth2.authorization_code_pkce +from httpx2_auth.testing import BrowserMock, create_token def test_basic_and_api_key_authentication_can_be_combined(httpx_mock: HTTPXMock): - basic_auth = httpx_auth.Basic("test_user", "test_pwd") - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + basic_auth = httpx2_auth.Basic("test_user", "test_pwd") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = basic_auth & api_key_auth httpx_mock.add_response( @@ -22,20 +22,16 @@ def test_basic_and_api_key_authentication_can_be_combined(httpx_mock: HTTPXMock) }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_header_api_key_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") auth = api_key_auth & (api_key_auth2 & api_key_auth3) httpx_mock.add_response( @@ -48,20 +44,14 @@ def test_header_api_key_and_multiple_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) -def test_multiple_auth_and_header_api_key_can_be_combined( - token_cache, httpx_mock: HTTPXMock -): - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) +def test_multiple_auth_and_header_api_key_can_be_combined(token_cache, httpx_mock: HTTPXMock): + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") auth = (api_key_auth & api_key_auth2) & api_key_auth3 httpx_mock.add_response( @@ -74,23 +64,15 @@ def test_multiple_auth_and_header_api_key_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) -def test_multiple_auth_and_multiple_auth_can_be_combined( - token_cache, httpx_mock: HTTPXMock -): - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) - api_key_auth4 = httpx_auth.HeaderApiKey( - "my_provided_api_key4", header_name="X-Api-Key4" - ) +def test_multiple_auth_and_multiple_auth_can_be_combined(token_cache, httpx_mock: HTTPXMock): + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") + api_key_auth4 = httpx2_auth.HeaderApiKey("my_provided_api_key4", header_name="X-Api-Key4") auth = (api_key_auth & api_key_auth2) & (api_key_auth3 & api_key_auth4) httpx_mock.add_response( @@ -104,20 +86,14 @@ def test_multiple_auth_and_multiple_auth_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) -def test_basic_and_multiple_authentication_can_be_combined( - token_cache, httpx_mock: HTTPXMock -): - basic_auth = httpx_auth.Basic("test_user", "test_pwd") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) +def test_basic_and_multiple_authentication_can_be_combined(token_cache, httpx_mock: HTTPXMock): + basic_auth = httpx2_auth.Basic("test_user", "test_pwd") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") auth = basic_auth & (api_key_auth2 & api_key_auth3) httpx_mock.add_response( @@ -130,20 +106,16 @@ def test_basic_and_multiple_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_query_api_key_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - api_key_auth = httpx_auth.QueryApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.QueryApiKey( - "my_provided_api_key2", query_parameter_name="api_key2" - ) - api_key_auth3 = httpx_auth.HeaderApiKey( - "my_provided_api_key3", header_name="X-Api-Key3" - ) + api_key_auth = httpx2_auth.QueryApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.QueryApiKey("my_provided_api_key2", query_parameter_name="api_key2") + api_key_auth3 = httpx2_auth.HeaderApiKey("my_provided_api_key3", header_name="X-Api-Key3") auth = api_key_auth & (api_key_auth2 & api_key_auth3) httpx_mock.add_response( @@ -154,17 +126,17 @@ def test_query_api_key_and_multiple_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_resource_owner_password_and_api_key_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - resource_owner_password_auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + resource_owner_password_auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = resource_owner_password_auth & api_key_auth httpx_mock.add_response( @@ -188,20 +160,18 @@ def test_oauth2_resource_owner_password_and_api_key_authentication_can_be_combin }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_resource_owner_password_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - resource_owner_password_auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + resource_owner_password_auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = resource_owner_password_auth & (api_key_auth & api_key_auth2) httpx_mock.add_response( @@ -226,17 +196,17 @@ def test_oauth2_resource_owner_password_and_multiple_authentication_can_be_combi }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_client_credential_and_api_key_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - resource_owner_password_auth = httpx_auth.OAuth2ClientCredentials( + resource_owner_password_auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = resource_owner_password_auth & api_key_auth httpx_mock.add_response( @@ -260,20 +230,18 @@ def test_oauth2_client_credential_and_api_key_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_client_credential_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock ): - resource_owner_password_auth = httpx_auth.OAuth2ClientCredentials( + resource_owner_password_auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = resource_owner_password_auth & (api_key_auth & api_key_auth2) httpx_mock.add_response( @@ -298,19 +266,19 @@ def test_oauth2_client_credential_and_multiple_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_authorization_code_and_api_key_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - authorization_code_auth = httpx_auth.OAuth2AuthorizationCode( + authorization_code_auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = authorization_code_auth & api_key_auth tab = browser_mock.add_response( @@ -339,7 +307,7 @@ def test_oauth2_authorization_code_and_api_key_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -348,15 +316,13 @@ def test_oauth2_authorization_code_and_api_key_authentication_can_be_combined( def test_oauth2_authorization_code_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - authorization_code_auth = httpx_auth.OAuth2AuthorizationCode( + authorization_code_auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = authorization_code_auth & (api_key_auth & api_key_auth2) tab = browser_mock.add_response( @@ -386,7 +352,7 @@ def test_oauth2_authorization_code_and_multiple_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -400,14 +366,14 @@ def test_oauth2_pkce_and_api_key_authentication_can_be_combined( unused_tcp_port: int, ): monkeypatch.setattr( - httpx_auth._oauth2.authorization_code_pkce.os, "urandom", lambda x: b"1" * 63 + httpx2_auth._oauth2.authorization_code_pkce.os, "urandom", lambda x: b"1" * 63 ) - pkce_auth = httpx_auth.OAuth2AuthorizationCodePKCE( + pkce_auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = pkce_auth & api_key_auth tab = browser_mock.add_response( @@ -436,7 +402,7 @@ def test_oauth2_pkce_and_api_key_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -450,17 +416,15 @@ def test_oauth2_pkce_and_multiple_authentication_can_be_combined( unused_tcp_port: int, ): monkeypatch.setattr( - httpx_auth._oauth2.authorization_code_pkce.os, "urandom", lambda x: b"1" * 63 + httpx2_auth._oauth2.authorization_code_pkce.os, "urandom", lambda x: b"1" * 63 ) - pkce_auth = httpx_auth.OAuth2AuthorizationCodePKCE( + pkce_auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = pkce_auth & (api_key_auth & api_key_auth2) tab = browser_mock.add_response( @@ -490,7 +454,7 @@ def test_oauth2_pkce_and_multiple_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -499,16 +463,14 @@ def test_oauth2_pkce_and_multiple_authentication_can_be_combined( def test_oauth2_implicit_and_api_key_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - implicit_auth = httpx_auth.OAuth2Implicit( + implicit_auth = httpx2_auth.OAuth2Implicit( "https://provide_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") auth = implicit_auth & api_key_auth - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -525,7 +487,7 @@ def test_oauth2_implicit_and_api_key_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -534,19 +496,15 @@ def test_oauth2_implicit_and_api_key_authentication_can_be_combined( def test_oauth2_implicit_and_multiple_authentication_can_be_combined( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - implicit_auth = httpx_auth.OAuth2Implicit( + implicit_auth = httpx2_auth.OAuth2Implicit( "https://provide_token", redirect_uri_port=unused_tcp_port, ) - api_key_auth = httpx_auth.HeaderApiKey("my_provided_api_key") - api_key_auth2 = httpx_auth.HeaderApiKey( - "my_provided_api_key2", header_name="X-Api-Key2" - ) + api_key_auth = httpx2_auth.HeaderApiKey("my_provided_api_key") + api_key_auth2 = httpx2_auth.HeaderApiKey("my_provided_api_key2", header_name="X-Api-Key2") auth = implicit_auth & (api_key_auth & api_key_auth2) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -564,7 +522,7 @@ def test_oauth2_implicit_and_multiple_authentication_can_be_combined( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() diff --git a/tests/features/pytest_fixture/__init__.py b/tests/features/pytest_fixture/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/features/pytest_fixture/test_testing_token_mock_async.py b/tests/features/pytest_fixture/test_testing_token_mock_async.py index d026d15..c3f14ba 100644 --- a/tests/features/pytest_fixture/test_testing_token_mock_async.py +++ b/tests/features/pytest_fixture/test_testing_token_mock_async.py @@ -1,14 +1,13 @@ -import httpx +import httpx2 import pytest -from pytest_httpx import HTTPXMock +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import token_cache_mock, token_mock +import httpx2_auth @pytest.mark.asyncio async def test_token_mock(token_cache_mock, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2Implicit("https://provide_token") + auth = httpx2_auth.OAuth2Implicit("https://provide_token") httpx_mock.add_response( url="https://authorized_only", @@ -18,5 +17,5 @@ async def test_token_mock(token_cache_mock, httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) diff --git a/tests/features/pytest_fixture/test_testing_token_mock_sync.py b/tests/features/pytest_fixture/test_testing_token_mock_sync.py index 81dce41..4eb7505 100644 --- a/tests/features/pytest_fixture/test_testing_token_mock_sync.py +++ b/tests/features/pytest_fixture/test_testing_token_mock_sync.py @@ -1,12 +1,11 @@ -import httpx -from pytest_httpx import HTTPXMock +import httpx2 +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import token_cache_mock, token_mock +import httpx2_auth def test_token_mock(token_cache_mock, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2Implicit("https://provide_token") + auth = httpx2_auth.OAuth2Implicit("https://provide_token") httpx_mock.add_response( url="https://authorized_only", @@ -16,5 +15,5 @@ def test_token_mock(token_cache_mock, httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) diff --git a/tests/features/token_cache/__init__.py b/tests/features/token_cache/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/features/token_cache/authorization_code/__init__.py b/tests/features/token_cache/authorization_code/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/features/token_cache/authorization_code/test_testing_oauth2_authorization_code_async.py b/tests/features/token_cache/authorization_code/test_testing_oauth2_authorization_code_async.py index b4205df..5ba32b2 100644 --- a/tests/features/token_cache/authorization_code/test_testing_oauth2_authorization_code_async.py +++ b/tests/features/token_cache/authorization_code/test_testing_oauth2_authorization_code_async.py @@ -1,9 +1,8 @@ -import httpx +import httpx2 import pytest -from pytest_httpx import HTTPXMock +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import token_cache_mock +import httpx2_auth @pytest.fixture @@ -13,7 +12,7 @@ def token_mock() -> str: @pytest.mark.asyncio async def test_oauth2_authorization_code_flow(token_cache_mock, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token" ) @@ -24,13 +23,13 @@ async def test_oauth2_authorization_code_flow(token_cache_mock, httpx_mock: HTTP "Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA", }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio async def test_okta_authorization_code_flow(token_cache_mock, httpx_mock: HTTPXMock): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) @@ -42,15 +41,13 @@ async def test_okta_authorization_code_flow(token_cache_mock, httpx_mock: HTTPXM }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio -async def test_oauth2_authorization_code_pkce_flow( - token_cache_mock, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( +async def test_oauth2_authorization_code_pkce_flow(token_cache_mock, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token" ) @@ -62,15 +59,13 @@ async def test_oauth2_authorization_code_pkce_flow( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio -async def test_okta_authorization_code_pkce_flow( - token_cache_mock, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaAuthorizationCodePKCE( +async def test_okta_authorization_code_pkce_flow(token_cache_mock, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) @@ -82,5 +77,5 @@ async def test_okta_authorization_code_pkce_flow( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) diff --git a/tests/features/token_cache/authorization_code/test_testing_oauth2_authorization_code_sync.py b/tests/features/token_cache/authorization_code/test_testing_oauth2_authorization_code_sync.py index d6644a3..07dfef5 100644 --- a/tests/features/token_cache/authorization_code/test_testing_oauth2_authorization_code_sync.py +++ b/tests/features/token_cache/authorization_code/test_testing_oauth2_authorization_code_sync.py @@ -1,9 +1,8 @@ -import httpx +import httpx2 import pytest -from pytest_httpx import HTTPXMock +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import token_cache_mock +import httpx2_auth @pytest.fixture @@ -12,7 +11,7 @@ def token_mock() -> str: def test_oauth2_authorization_code_flow(token_cache_mock, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token" ) @@ -24,12 +23,12 @@ def test_oauth2_authorization_code_flow(token_cache_mock, httpx_mock: HTTPXMock) }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_okta_authorization_code_flow(token_cache_mock, httpx_mock: HTTPXMock): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) @@ -41,12 +40,12 @@ def test_okta_authorization_code_flow(token_cache_mock, httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_authorization_code_pkce_flow(token_cache_mock, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token" ) @@ -58,12 +57,12 @@ def test_oauth2_authorization_code_pkce_flow(token_cache_mock, httpx_mock: HTTPX }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_okta_authorization_code_pkce_flow(token_cache_mock, httpx_mock: HTTPXMock): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) @@ -75,5 +74,5 @@ def test_okta_authorization_code_pkce_flow(token_cache_mock, httpx_mock: HTTPXMo }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) diff --git a/tests/features/token_cache/implicit/__init__.py b/tests/features/token_cache/implicit/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/features/token_cache/implicit/test_testing_oauth2_implicit_async.py b/tests/features/token_cache/implicit/test_testing_oauth2_implicit_async.py index 18400c4..e2d1e57 100644 --- a/tests/features/token_cache/implicit/test_testing_oauth2_implicit_async.py +++ b/tests/features/token_cache/implicit/test_testing_oauth2_implicit_async.py @@ -1,9 +1,8 @@ -import httpx +import httpx2 import pytest -from pytest_httpx import HTTPXMock +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import token_cache_mock +import httpx2_auth @pytest.fixture @@ -13,7 +12,7 @@ def token_mock() -> str: @pytest.mark.asyncio async def test_oauth2_implicit_flow(token_cache_mock, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2Implicit("https://provide_token") + auth = httpx2_auth.OAuth2Implicit("https://provide_token") httpx_mock.add_response( url="https://authorized_only", @@ -23,13 +22,13 @@ async def test_oauth2_implicit_flow(token_cache_mock, httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio async def test_okta_implicit_flow(token_cache_mock, httpx_mock: HTTPXMock): - auth = httpx_auth.OktaImplicit( + auth = httpx2_auth.OktaImplicit( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) @@ -41,13 +40,13 @@ async def test_okta_implicit_flow(token_cache_mock, httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio async def test_aad_implicit_flow(token_cache_mock, httpx_mock: HTTPXMock): - auth = httpx_auth.AzureActiveDirectoryImplicit( + auth = httpx2_auth.AzureActiveDirectoryImplicit( "45239d18-c68c-4c47-8bdd-ce71ea1d50cd", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) @@ -59,13 +58,13 @@ async def test_aad_implicit_flow(token_cache_mock, httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio async def test_okta_implicit_id_token_flow(token_cache_mock, httpx_mock: HTTPXMock): - auth = httpx_auth.OktaImplicitIdToken( + auth = httpx2_auth.OktaImplicitIdToken( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) @@ -77,13 +76,13 @@ async def test_okta_implicit_id_token_flow(token_cache_mock, httpx_mock: HTTPXMo }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio async def test_aad_implicit_id_token_flow(token_cache_mock, httpx_mock: HTTPXMock): - auth = httpx_auth.AzureActiveDirectoryImplicitIdToken( + auth = httpx2_auth.AzureActiveDirectoryImplicitIdToken( "45239d18-c68c-4c47-8bdd-ce71ea1d50cd", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) @@ -95,5 +94,5 @@ async def test_aad_implicit_id_token_flow(token_cache_mock, httpx_mock: HTTPXMoc }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) diff --git a/tests/features/token_cache/implicit/test_testing_oauth2_implicit_sync.py b/tests/features/token_cache/implicit/test_testing_oauth2_implicit_sync.py index bf531c6..5c0cce3 100644 --- a/tests/features/token_cache/implicit/test_testing_oauth2_implicit_sync.py +++ b/tests/features/token_cache/implicit/test_testing_oauth2_implicit_sync.py @@ -1,9 +1,8 @@ -import httpx +import httpx2 import pytest -from pytest_httpx import HTTPXMock +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import token_cache_mock +import httpx2_auth @pytest.fixture @@ -12,7 +11,7 @@ def token_mock() -> str: def test_oauth2_implicit_flow(token_cache_mock, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2Implicit("https://provide_token") + auth = httpx2_auth.OAuth2Implicit("https://provide_token") httpx_mock.add_response( url="https://authorized_only", @@ -22,12 +21,12 @@ def test_oauth2_implicit_flow(token_cache_mock, httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_okta_implicit_flow(token_cache_mock, httpx_mock: HTTPXMock): - auth = httpx_auth.OktaImplicit( + auth = httpx2_auth.OktaImplicit( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) @@ -39,12 +38,12 @@ def test_okta_implicit_flow(token_cache_mock, httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_aad_implicit_flow(token_cache_mock, httpx_mock: HTTPXMock): - auth = httpx_auth.AzureActiveDirectoryImplicit( + auth = httpx2_auth.AzureActiveDirectoryImplicit( "45239d18-c68c-4c47-8bdd-ce71ea1d50cd", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) @@ -56,12 +55,12 @@ def test_aad_implicit_flow(token_cache_mock, httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_okta_implicit_id_token_flow(token_cache_mock, httpx_mock: HTTPXMock): - auth = httpx_auth.OktaImplicitIdToken( + auth = httpx2_auth.OktaImplicitIdToken( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) @@ -73,12 +72,12 @@ def test_okta_implicit_id_token_flow(token_cache_mock, httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_aad_implicit_id_token_flow(token_cache_mock, httpx_mock: HTTPXMock): - auth = httpx_auth.AzureActiveDirectoryImplicitIdToken( + auth = httpx2_auth.AzureActiveDirectoryImplicitIdToken( "45239d18-c68c-4c47-8bdd-ce71ea1d50cd", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) @@ -90,5 +89,5 @@ def test_aad_implicit_id_token_flow(token_cache_mock, httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) diff --git a/tests/features/token_cache/test_json_token_file_cache.py b/tests/features/token_cache/test_json_token_file_cache.py index 511f253..90cd94c 100644 --- a/tests/features/token_cache/test_json_token_file_cache.py +++ b/tests/features/token_cache/test_json_token_file_cache.py @@ -2,31 +2,27 @@ import logging import pathlib -import httpx -import pytest +import httpx2 import jwt +import pytest -import httpx_auth -import httpx_auth._oauth2.tokens +import httpx2_auth +import httpx2_auth._oauth2.tokens @pytest.fixture def token_cache(tmp_path): - _token_cache = httpx_auth.JsonTokenFileCache(tmp_path / "my_tokens.cache") + _token_cache = httpx2_auth.JsonTokenFileCache(tmp_path / "my_tokens.cache") yield _token_cache _token_cache.clear() def test_add_bearer_tokens(token_cache): - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token1 = jwt.encode({"exp": expiry_in_1_hour}, "secret") token_cache._add_bearer_token("key1", token1) - expiry_in_2_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=2) + expiry_in_2_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=2) token2 = jwt.encode({"exp": expiry_in_2_hour}, "secret") token_cache._add_bearer_token("key2", token2) @@ -40,34 +36,26 @@ def test_add_bearer_tokens(token_cache): def test_save_bearer_tokens(token_cache, tmp_path): - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token1 = jwt.encode({"exp": expiry_in_1_hour}, "secret") token_cache._add_bearer_token("key1", token1) - expiry_in_2_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=2) + expiry_in_2_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=2) token2 = jwt.encode({"exp": expiry_in_2_hour}, "secret") token_cache._add_bearer_token("key2", token2) - same_cache = httpx_auth.JsonTokenFileCache(tmp_path / "my_tokens.cache") + same_cache = httpx2_auth.JsonTokenFileCache(tmp_path / "my_tokens.cache") assert same_cache.get_token("key1") == token1 assert same_cache.get_token("key2") == token2 -def test_save_bearer_token_exception_handling( - token_cache, tmp_path, monkeypatch, caplog -): +def test_save_bearer_token_exception_handling(token_cache, tmp_path, monkeypatch, caplog): def failing_dump(*args): raise Exception("Failure") - monkeypatch.setattr(httpx_auth._oauth2.tokens.json, "dump", failing_dump) + monkeypatch.setattr(httpx2_auth._oauth2.tokens.json, "dump", failing_dump) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token1 = jwt.encode({"exp": expiry_in_1_hour}, "secret") caplog.set_level(logging.DEBUG) @@ -75,12 +63,12 @@ def failing_dump(*args): # Assert that the exception is not thrown token_cache._add_bearer_token("key1", token1) - same_cache = httpx_auth.JsonTokenFileCache(tmp_path / "my_tokens.cache") - with pytest.raises(httpx_auth.AuthenticationFailed) as exception_info: + same_cache = httpx2_auth.JsonTokenFileCache(tmp_path / "my_tokens.cache") + with pytest.raises(httpx2_auth.AuthenticationFailed) as exception_info: same_cache.get_token("key1") assert str(exception_info.value) == "User was not authenticated." - assert isinstance(exception_info.value, httpx_auth.HttpxAuthException) - assert isinstance(exception_info.value, httpx.HTTPError) + assert isinstance(exception_info.value, httpx2_auth.HttpxAuthException) + assert isinstance(exception_info.value, httpx2.HTTPError) assert caplog.messages == [ "Cannot save tokens.", @@ -94,7 +82,7 @@ def failing_dump(*args): def test_missing_token_on_empty_cache(token_cache, caplog): caplog.set_level(logging.DEBUG) - with pytest.raises(httpx_auth.AuthenticationFailed): + with pytest.raises(httpx2_auth.AuthenticationFailed): token_cache.get_token("key1") assert caplog.messages == [ 'Retrieving token with "key1" key.', @@ -105,14 +93,12 @@ def test_missing_token_on_empty_cache(token_cache, caplog): def test_missing_token_on_non_empty_cache(token_cache, caplog): - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token1 = jwt.encode({"exp": expiry_in_1_hour}, "secret") token_cache._add_bearer_token("key0", token1) caplog.set_level(logging.DEBUG) - with pytest.raises(httpx_auth.AuthenticationFailed): + with pytest.raises(httpx2_auth.AuthenticationFailed): token_cache.get_token("key1") assert caplog.messages == [ 'Retrieving token with "key1" key.', @@ -122,20 +108,14 @@ def test_missing_token_on_non_empty_cache(token_cache, caplog): def test_missing_token_function(token_cache): - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = jwt.encode({"exp": expiry_in_1_hour}, "secret") - retrieved_token = token_cache.get_token( - "key1", on_missing_token=lambda: ("key1", token) - ) + retrieved_token = token_cache.get_token("key1", on_missing_token=lambda: ("key1", token)) assert retrieved_token == token def test_token_without_refresh_token(token_cache): - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) # add token without refresh token token = jwt.encode({"exp": expiry_in_1_hour}, "secret") token_cache.tokens["key1"] = ( diff --git a/tests/oauth2/__init__.py b/tests/oauth2/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/oauth2/authorization_code/__init__.py b/tests/oauth2/authorization_code/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/oauth2/authorization_code/okta/__init__.py b/tests/oauth2/authorization_code/okta/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/oauth2/authorization_code/okta/test_oauth2_authorization_code_okta.py b/tests/oauth2/authorization_code/okta/test_oauth2_authorization_code_okta.py index a4fa824..b140d0c 100644 --- a/tests/oauth2/authorization_code/okta/test_oauth2_authorization_code_okta.py +++ b/tests/oauth2/authorization_code/okta/test_oauth2_authorization_code_okta.py @@ -1,11 +1,11 @@ import pytest -import httpx_auth +import httpx2_auth def test_header_value_must_contains_token(): with pytest.raises(Exception) as exception_info: - httpx_auth.OktaAuthorizationCode( + httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", header_value="Bearer token", diff --git a/tests/oauth2/authorization_code/okta/test_oauth2_authorization_code_okta_async.py b/tests/oauth2/authorization_code/okta/test_oauth2_authorization_code_okta_async.py index e91250e..7a5c0dc 100644 --- a/tests/oauth2/authorization_code/okta/test_oauth2_authorization_code_okta_async.py +++ b/tests/oauth2/authorization_code/okta/test_oauth2_authorization_code_okta_async.py @@ -1,19 +1,18 @@ -from pytest_asyncio.plugin import unused_tcp_port -from pytest_httpx import HTTPXMock +import httpx2 import pytest -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import BrowserMock, browser_mock, token_cache -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry +from httpx2_auth.testing import BrowserMock @pytest.mark.asyncio async def test_oauth2_authorization_code_flow_uses_provided_client( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OktaAuthorizationCode( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", client=client, @@ -44,7 +43,7 @@ async def test_oauth2_authorization_code_flow_uses_provided_client( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -54,7 +53,7 @@ async def test_oauth2_authorization_code_flow_uses_provided_client( async def test_oauth2_authorization_code_flow_uses_redirect_uri_domain( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_domain="localhost.mycompany.com", @@ -84,7 +83,7 @@ async def test_oauth2_authorization_code_flow_uses_redirect_uri_domain( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -94,14 +93,12 @@ async def test_oauth2_authorization_code_flow_uses_redirect_uri_domain( async def test_oauth2_authorization_code_flow_uses_custom_success( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.success_html = ( - "
SUCCESS: {display_time}
" - ) + httpx2_auth.OAuth2.display.success_html = "
SUCCESS: {display_time}
" tab = browser_mock.add_response( opened_url=f"https://testserver.okta-emea.com/oauth2/default/v1/authorize?client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#code=SplxlOBeZQQYbYS6WxSbIA&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b", @@ -127,7 +124,7 @@ async def test_oauth2_authorization_code_flow_uses_custom_success( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -137,20 +134,20 @@ async def test_oauth2_authorization_code_flow_uses_custom_success( async def test_oauth2_authorization_code_flow_uses_custom_failure( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" + httpx2_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" tab = browser_mock.add_response( opened_url=f"https://testserver.okta-emea.com/oauth2/default/v1/authorize?client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", displayed_html="FAILURE: {display_time}\n{information}", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest): await client.get("https://authorized_only", auth=auth) tab.assert_failure( @@ -162,7 +159,7 @@ async def test_oauth2_authorization_code_flow_uses_custom_failure( async def test_oauth2_authorization_code_flow_get_code_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -191,7 +188,7 @@ async def test_oauth2_authorization_code_flow_get_code_is_sent_in_authorization_ }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -201,7 +198,7 @@ async def test_oauth2_authorization_code_flow_get_code_is_sent_in_authorization_ async def test_oauth2_authorization_code_flow_get_code_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -237,7 +234,7 @@ async def test_oauth2_authorization_code_flow_get_code_is_expired_after_30_secon }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -247,7 +244,7 @@ async def test_oauth2_authorization_code_flow_get_code_is_expired_after_30_secon async def test_oauth2_authorization_code_flow_get_code_custom_expiry( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", early_expiry=28, @@ -267,7 +264,7 @@ async def test_oauth2_authorization_code_flow_get_code_custom_expiry( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -275,7 +272,7 @@ async def test_oauth2_authorization_code_flow_get_code_custom_expiry( async def test_oauth2_authorization_code_flow_refresh_token( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -304,7 +301,7 @@ async def test_oauth2_authorization_code_flow_refresh_token( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -330,7 +327,7 @@ async def test_oauth2_authorization_code_flow_refresh_token( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -338,7 +335,7 @@ async def test_oauth2_authorization_code_flow_refresh_token( async def test_oauth2_authorization_code_flow_refresh_token_invalid( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -367,7 +364,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -407,7 +404,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -417,7 +414,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid( async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -446,7 +443,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -459,7 +456,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp }, ) # expect Bearer token to remain the same - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -467,7 +464,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp async def test_empty_token_is_invalid( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -488,8 +485,8 @@ async def test_empty_token_is_invalid( }, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.GrantNotProvided) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.GrantNotProvided) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -503,7 +500,7 @@ async def test_empty_token_is_invalid( async def test_with_invalid_grant_request_no_json( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -519,8 +516,8 @@ async def test_with_invalid_grant_request_no_json( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest, match="failure"): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="failure"): await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -530,7 +527,7 @@ async def test_with_invalid_grant_request_no_json( async def test_with_invalid_grant_request_invalid_request_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -546,8 +543,8 @@ async def test_with_invalid_grant_request_invalid_request_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -564,7 +561,7 @@ async def test_with_invalid_grant_request_invalid_request_error( async def test_with_invalid_grant_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -580,8 +577,8 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc of the error" @@ -592,7 +589,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri async def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -612,13 +609,13 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url" + == "invalid_request: desc of the error\nMore information can be found on https://test_url" ) tab.assert_success() @@ -627,7 +624,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri async def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -648,8 +645,8 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -663,7 +660,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri async def test_with_invalid_grant_request_without_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -679,10 +676,8 @@ async def test_with_invalid_grant_request_without_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises( - httpx_auth.InvalidGrantRequest, match="{'other': 'other info'}" - ): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="{'other': 'other info'}"): await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -692,7 +687,7 @@ async def test_with_invalid_grant_request_without_error( async def test_with_invalid_grant_request_invalid_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -708,8 +703,8 @@ async def test_with_invalid_grant_request_invalid_client_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -730,7 +725,7 @@ async def test_with_invalid_grant_request_invalid_client_error( async def test_with_invalid_grant_request_invalid_grant_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -746,8 +741,8 @@ async def test_with_invalid_grant_request_invalid_grant_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -764,7 +759,7 @@ async def test_with_invalid_grant_request_invalid_grant_error( async def test_with_invalid_grant_request_unauthorized_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -780,8 +775,8 @@ async def test_with_invalid_grant_request_unauthorized_client_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -796,7 +791,7 @@ async def test_with_invalid_grant_request_unauthorized_client_error( async def test_with_invalid_grant_request_unsupported_grant_type_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -812,8 +807,8 @@ async def test_with_invalid_grant_request_unsupported_grant_type_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -828,7 +823,7 @@ async def test_with_invalid_grant_request_unsupported_grant_type_error( async def test_with_invalid_grant_request_invalid_scope_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -844,8 +839,8 @@ async def test_with_invalid_grant_request_invalid_scope_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -860,7 +855,7 @@ async def test_with_invalid_grant_request_invalid_scope_error( async def test_with_invalid_token_request_invalid_request_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -870,8 +865,8 @@ async def test_with_invalid_token_request_invalid_request_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -887,7 +882,7 @@ async def test_with_invalid_token_request_invalid_request_error( async def test_with_invalid_token_request_invalid_request_error_and_error_description( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -897,10 +892,8 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc", ) - async with httpx.AsyncClient() as client: - with pytest.raises( - httpx_auth.InvalidGrantRequest, match="invalid_request: desc" - ): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="invalid_request: desc"): await client.get("https://authorized_only", auth=auth) tab.assert_failure("invalid_request: desc") @@ -910,7 +903,7 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri async def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -920,24 +913,22 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_request: desc\nMore information can be found on https://test_url" ) - tab.assert_failure( - "invalid_request: desc
More information can be found on https://test_url" - ) + tab.assert_failure("invalid_request: desc
More information can be found on https://test_url") @pytest.mark.asyncio async def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -947,8 +938,8 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url&other=test", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -964,7 +955,7 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri async def test_with_invalid_token_request_unauthorized_client_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -974,8 +965,8 @@ async def test_with_invalid_token_request_unauthorized_client_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unauthorized_client", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -991,7 +982,7 @@ async def test_with_invalid_token_request_unauthorized_client_error( async def test_with_invalid_token_request_access_denied_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -1001,8 +992,8 @@ async def test_with_invalid_token_request_access_denied_error( reply_url=f"http://localhost:{unused_tcp_port}#error=access_denied", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1018,7 +1009,7 @@ async def test_with_invalid_token_request_access_denied_error( async def test_with_invalid_token_request_unsupported_response_type_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -1028,8 +1019,8 @@ async def test_with_invalid_token_request_unsupported_response_type_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unsupported_response_type", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1045,7 +1036,7 @@ async def test_with_invalid_token_request_unsupported_response_type_error( async def test_with_invalid_token_request_invalid_scope_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -1055,24 +1046,22 @@ async def test_with_invalid_token_request_invalid_scope_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_scope", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_scope: The requested scope is invalid, unknown, or malformed." ) - tab.assert_failure( - "invalid_scope: The requested scope is invalid, unknown, or malformed." - ) + tab.assert_failure("invalid_scope: The requested scope is invalid, unknown, or malformed.") @pytest.mark.asyncio async def test_with_invalid_token_request_server_error_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -1082,8 +1071,8 @@ async def test_with_invalid_token_request_server_error_error( reply_url=f"http://localhost:{unused_tcp_port}#error=server_error", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1099,7 +1088,7 @@ async def test_with_invalid_token_request_server_error_error( async def test_with_invalid_token_request_temporarily_unavailable_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -1109,8 +1098,8 @@ async def test_with_invalid_token_request_temporarily_unavailable_error( reply_url=f"http://localhost:{unused_tcp_port}#error=temporarily_unavailable", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( diff --git a/tests/oauth2/authorization_code/okta/test_oauth2_authorization_code_okta_sync.py b/tests/oauth2/authorization_code/okta/test_oauth2_authorization_code_okta_sync.py index 4207abd..9c18fcc 100644 --- a/tests/oauth2/authorization_code/okta/test_oauth2_authorization_code_okta_sync.py +++ b/tests/oauth2/authorization_code/okta/test_oauth2_authorization_code_okta_sync.py @@ -1,17 +1,17 @@ -from pytest_httpx import HTTPXMock +import httpx2 import pytest -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import BrowserMock, browser_mock, token_cache -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry +from httpx2_auth.testing import BrowserMock def test_oauth2_authorization_code_flow_uses_provided_client( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OktaAuthorizationCode( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", client=client, @@ -42,7 +42,7 @@ def test_oauth2_authorization_code_flow_uses_provided_client( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -51,7 +51,7 @@ def test_oauth2_authorization_code_flow_uses_provided_client( def test_oauth2_authorization_code_flow_uses_redirect_uri_domain( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_domain="localhost.mycompany.com", @@ -81,7 +81,7 @@ def test_oauth2_authorization_code_flow_uses_redirect_uri_domain( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -90,14 +90,12 @@ def test_oauth2_authorization_code_flow_uses_redirect_uri_domain( def test_oauth2_authorization_code_flow_uses_custom_success( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.success_html = ( - "
SUCCESS: {display_time}
" - ) + httpx2_auth.OAuth2.display.success_html = "
SUCCESS: {display_time}
" tab = browser_mock.add_response( opened_url=f"https://testserver.okta-emea.com/oauth2/default/v1/authorize?client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#code=SplxlOBeZQQYbYS6WxSbIA&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b", @@ -123,7 +121,7 @@ def test_oauth2_authorization_code_flow_uses_custom_success( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -132,21 +130,20 @@ def test_oauth2_authorization_code_flow_uses_custom_success( def test_oauth2_authorization_code_flow_uses_custom_failure( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" + httpx2_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" tab = browser_mock.add_response( opened_url=f"https://testserver.okta-emea.com/oauth2/default/v1/authorize?client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", displayed_html="FAILURE: {display_time}\n{information}", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest): - client.get("https://authorized_only", auth=auth) + with httpx2.Client() as client, pytest.raises(httpx2_auth.InvalidGrantRequest): + client.get("https://authorized_only", auth=auth) tab.assert_failure( "invalid_request: The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed." @@ -156,7 +153,7 @@ def test_oauth2_authorization_code_flow_uses_custom_failure( def test_oauth2_authorization_code_flow_get_code_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -185,7 +182,7 @@ def test_oauth2_authorization_code_flow_get_code_is_sent_in_authorization_header }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -194,7 +191,7 @@ def test_oauth2_authorization_code_flow_get_code_is_sent_in_authorization_header def test_oauth2_authorization_code_flow_get_code_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -230,7 +227,7 @@ def test_oauth2_authorization_code_flow_get_code_is_expired_after_30_seconds_by_ }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -239,7 +236,7 @@ def test_oauth2_authorization_code_flow_get_code_is_expired_after_30_seconds_by_ def test_oauth2_authorization_code_flow_get_code_custom_expiry( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", early_expiry=28, @@ -259,14 +256,14 @@ def test_oauth2_authorization_code_flow_get_code_custom_expiry( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_authorization_code_flow_refresh_token( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -295,7 +292,7 @@ def test_oauth2_authorization_code_flow_refresh_token( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -321,14 +318,14 @@ def test_oauth2_authorization_code_flow_refresh_token( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_authorization_code_flow_refresh_token_invalid( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -357,7 +354,7 @@ def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -397,7 +394,7 @@ def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -406,7 +403,7 @@ def test_oauth2_authorization_code_flow_refresh_token_invalid( def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -435,7 +432,7 @@ def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -448,14 +445,14 @@ def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( }, ) # expect Bearer token to remain the same - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_empty_token_is_invalid( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -476,8 +473,8 @@ def test_empty_token_is_invalid( }, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.GrantNotProvided) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.GrantNotProvided) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -490,7 +487,7 @@ def test_empty_token_is_invalid( def test_with_invalid_grant_request_no_json( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -506,8 +503,8 @@ def test_with_invalid_grant_request_no_json( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest, match="failure"): + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="failure"): client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -516,7 +513,7 @@ def test_with_invalid_grant_request_no_json( def test_with_invalid_grant_request_invalid_request_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -532,8 +529,8 @@ def test_with_invalid_grant_request_invalid_request_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -549,7 +546,7 @@ def test_with_invalid_grant_request_invalid_request_error( def test_with_invalid_grant_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -565,8 +562,8 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc of the error" @@ -576,7 +573,7 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description( def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -596,13 +593,13 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url" + == "invalid_request: desc of the error\nMore information can be found on https://test_url" ) tab.assert_success() @@ -610,7 +607,7 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -631,8 +628,8 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -645,7 +642,7 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ def test_with_invalid_grant_request_without_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -661,10 +658,8 @@ def test_with_invalid_grant_request_without_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises( - httpx_auth.InvalidGrantRequest, match="{'other': 'other info'}" - ): + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="{'other': 'other info'}"): client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -673,7 +668,7 @@ def test_with_invalid_grant_request_without_error( def test_with_invalid_grant_request_invalid_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -689,8 +684,8 @@ def test_with_invalid_grant_request_invalid_client_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -710,7 +705,7 @@ def test_with_invalid_grant_request_invalid_client_error( def test_with_invalid_grant_request_invalid_grant_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -726,8 +721,8 @@ def test_with_invalid_grant_request_invalid_grant_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -743,7 +738,7 @@ def test_with_invalid_grant_request_invalid_grant_error( def test_with_invalid_grant_request_unauthorized_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -759,8 +754,8 @@ def test_with_invalid_grant_request_unauthorized_client_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -774,7 +769,7 @@ def test_with_invalid_grant_request_unauthorized_client_error( def test_with_invalid_grant_request_unsupported_grant_type_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -790,8 +785,8 @@ def test_with_invalid_grant_request_unsupported_grant_type_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -805,7 +800,7 @@ def test_with_invalid_grant_request_unsupported_grant_type_error( def test_with_invalid_grant_request_invalid_scope_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -821,8 +816,8 @@ def test_with_invalid_grant_request_invalid_scope_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -836,7 +831,7 @@ def test_with_invalid_grant_request_invalid_scope_error( def test_with_invalid_token_request_invalid_request_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -846,8 +841,8 @@ def test_with_invalid_token_request_invalid_request_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -862,7 +857,7 @@ def test_with_invalid_token_request_invalid_request_error( def test_with_invalid_token_request_invalid_request_error_and_error_description( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -872,10 +867,8 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc", ) - with httpx.Client() as client: - with pytest.raises( - httpx_auth.InvalidGrantRequest, match="invalid_request: desc" - ): + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="invalid_request: desc"): client.get("https://authorized_only", auth=auth) tab.assert_failure("invalid_request: desc") @@ -884,7 +877,7 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description( def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -894,23 +887,21 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description_ reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_request: desc\nMore information can be found on https://test_url" ) - tab.assert_failure( - "invalid_request: desc
More information can be found on https://test_url" - ) + tab.assert_failure("invalid_request: desc
More information can be found on https://test_url") def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -920,8 +911,8 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description_ reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url&other=test", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -936,7 +927,7 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description_ def test_with_invalid_token_request_unauthorized_client_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -946,8 +937,8 @@ def test_with_invalid_token_request_unauthorized_client_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unauthorized_client", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -962,7 +953,7 @@ def test_with_invalid_token_request_unauthorized_client_error( def test_with_invalid_token_request_access_denied_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -972,8 +963,8 @@ def test_with_invalid_token_request_access_denied_error( reply_url=f"http://localhost:{unused_tcp_port}#error=access_denied", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -988,7 +979,7 @@ def test_with_invalid_token_request_access_denied_error( def test_with_invalid_token_request_unsupported_response_type_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -998,8 +989,8 @@ def test_with_invalid_token_request_unsupported_response_type_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unsupported_response_type", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1014,7 +1005,7 @@ def test_with_invalid_token_request_unsupported_response_type_error( def test_with_invalid_token_request_invalid_scope_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -1024,23 +1015,21 @@ def test_with_invalid_token_request_invalid_scope_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_scope", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_scope: The requested scope is invalid, unknown, or malformed." ) - tab.assert_failure( - "invalid_scope: The requested scope is invalid, unknown, or malformed." - ) + tab.assert_failure("invalid_scope: The requested scope is invalid, unknown, or malformed.") def test_with_invalid_token_request_server_error_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -1050,8 +1039,8 @@ def test_with_invalid_token_request_server_error_error( reply_url=f"http://localhost:{unused_tcp_port}#error=server_error", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1066,7 +1055,7 @@ def test_with_invalid_token_request_server_error_error( def test_with_invalid_token_request_temporarily_unavailable_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCode( + auth = httpx2_auth.OktaAuthorizationCode( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -1076,8 +1065,8 @@ def test_with_invalid_token_request_temporarily_unavailable_error( reply_url=f"http://localhost:{unused_tcp_port}#error=temporarily_unavailable", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( diff --git a/tests/oauth2/authorization_code/test_oauth2_authorization_code.py b/tests/oauth2/authorization_code/test_oauth2_authorization_code.py index ba19899..46a4206 100644 --- a/tests/oauth2/authorization_code/test_oauth2_authorization_code.py +++ b/tests/oauth2/authorization_code/test_oauth2_authorization_code.py @@ -1,23 +1,23 @@ import pytest -import httpx_auth +import httpx2_auth def test_authorization_url_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OAuth2AuthorizationCode("", "https://test_url") + httpx2_auth.OAuth2AuthorizationCode("", "https://test_url") assert str(exception_info.value) == "Authorization URL is mandatory." def test_token_url_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OAuth2AuthorizationCode("https://test_url", "") + httpx2_auth.OAuth2AuthorizationCode("https://test_url", "") assert str(exception_info.value) == "Token URL is mandatory." def test_header_value_must_contains_token(): with pytest.raises(Exception) as exception_info: - httpx_auth.OAuth2AuthorizationCode( + httpx2_auth.OAuth2AuthorizationCode( "https://test_url", "https://test_url", header_value="Bearer token" ) assert str(exception_info.value) == "header_value parameter must contains {token}." diff --git a/tests/oauth2/authorization_code/test_oauth2_authorization_code_async.py b/tests/oauth2/authorization_code/test_oauth2_authorization_code_async.py index cd26380..7684e78 100644 --- a/tests/oauth2/authorization_code/test_oauth2_authorization_code_async.py +++ b/tests/oauth2/authorization_code/test_oauth2_authorization_code_async.py @@ -1,20 +1,20 @@ import time -from pytest_httpx import HTTPXMock +import httpx2 import pytest -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import BrowserMock, browser_mock, token_cache -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry +from httpx2_auth.testing import BrowserMock @pytest.mark.asyncio async def test_oauth2_authorization_code_flow_uses_provided_client( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2AuthorizationCode( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", client=client, @@ -45,7 +45,7 @@ async def test_oauth2_authorization_code_flow_uses_provided_client( "Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA", }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -55,7 +55,7 @@ async def test_oauth2_authorization_code_flow_uses_provided_client( async def test_oauth2_authorization_code_flow_uses_redirect_uri_domain( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_domain="localhost.mycompany.com", @@ -85,7 +85,7 @@ async def test_oauth2_authorization_code_flow_uses_redirect_uri_domain( "Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA", }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -99,14 +99,12 @@ async def test_oauth2_authorization_code_flow_uses_custom_success( monkeypatch, unused_tcp_port: int, ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.success_html = ( - "
SUCCESS: {display_time}
" - ) + httpx2_auth.OAuth2.display.success_html = "
SUCCESS: {display_time}
" tab = browser_mock.add_response( opened_url=f"https://provide_code?response_type=code&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#code=SplxlOBeZQQYbYS6WxSbIA&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5", @@ -132,7 +130,7 @@ async def test_oauth2_authorization_code_flow_uses_custom_success( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -142,20 +140,20 @@ async def test_oauth2_authorization_code_flow_uses_custom_success( async def test_with_invalid_request_error_uses_custom_failure( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" + httpx2_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" tab = browser_mock.add_response( opened_url=f"https://provide_code?response_type=code&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", displayed_html="FAILURE: {display_time}\n{information}", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest): await client.get("https://authorized_only", auth=auth) tab.assert_failure( @@ -167,8 +165,8 @@ async def test_with_invalid_request_error_uses_custom_failure( async def test_oauth2_authorization_code_flow_is_able_to_reuse_client( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2AuthorizationCode( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", client=client, @@ -198,7 +196,7 @@ async def test_oauth2_authorization_code_flow_is_able_to_reuse_client( "Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA", }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -229,7 +227,7 @@ async def test_oauth2_authorization_code_flow_is_able_to_reuse_client( "Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA", }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -239,8 +237,8 @@ async def test_oauth2_authorization_code_flow_is_able_to_reuse_client( async def test_oauth2_authorization_code_flow_is_able_to_reuse_client_with_token_refresh( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2AuthorizationCode( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", client=client, @@ -271,7 +269,7 @@ async def test_oauth2_authorization_code_flow_is_able_to_reuse_client_with_token "Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA", }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -300,7 +298,7 @@ async def test_oauth2_authorization_code_flow_is_able_to_reuse_client_with_token }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -308,7 +306,7 @@ async def test_oauth2_authorization_code_flow_is_able_to_reuse_client_with_token async def test_oauth2_authorization_code_flow_get_code_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -337,7 +335,7 @@ async def test_oauth2_authorization_code_flow_get_code_is_sent_in_authorization_ "Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA", }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -347,7 +345,7 @@ async def test_oauth2_authorization_code_flow_get_code_is_sent_in_authorization_ async def test_oauth2_authorization_code_flow_token_as_html( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -370,7 +368,7 @@ async def test_oauth2_authorization_code_flow_token_as_html( "Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA", }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -380,7 +378,7 @@ async def test_oauth2_authorization_code_flow_token_as_html( async def test_oauth2_authorization_code_flow_get_code_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -416,7 +414,7 @@ async def test_oauth2_authorization_code_flow_get_code_is_expired_after_30_secon "Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA", }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -426,7 +424,7 @@ async def test_oauth2_authorization_code_flow_get_code_is_expired_after_30_secon async def test_oauth2_authorization_code_flow_get_code_custom_expiry( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", early_expiry=28, @@ -446,7 +444,7 @@ async def test_oauth2_authorization_code_flow_get_code_custom_expiry( "Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA", }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -454,7 +452,7 @@ async def test_oauth2_authorization_code_flow_get_code_custom_expiry( async def test_oauth2_authorization_code_flow_refresh_token( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -484,7 +482,7 @@ async def test_oauth2_authorization_code_flow_refresh_token( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -510,7 +508,7 @@ async def test_oauth2_authorization_code_flow_refresh_token( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -518,7 +516,7 @@ async def test_oauth2_authorization_code_flow_refresh_token( async def test_oauth2_authorization_code_flow_refresh_token_invalid( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -548,7 +546,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -588,7 +586,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -598,7 +596,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid( async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -628,7 +626,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -641,7 +639,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp }, ) # expect Bearer token to remain the same - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -649,7 +647,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp async def test_empty_token_is_invalid( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -670,8 +668,8 @@ async def test_empty_token_is_invalid( }, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.GrantNotProvided) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.GrantNotProvided) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -685,7 +683,7 @@ async def test_empty_token_is_invalid( async def test_with_invalid_grant_request_no_json( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -701,8 +699,8 @@ async def test_with_invalid_grant_request_no_json( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest, match="failure"): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="failure"): await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -712,7 +710,7 @@ async def test_with_invalid_grant_request_no_json( async def test_with_invalid_grant_request_invalid_request_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -728,8 +726,8 @@ async def test_with_invalid_grant_request_invalid_request_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -746,7 +744,7 @@ async def test_with_invalid_grant_request_invalid_request_error( async def test_with_invalid_grant_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -762,8 +760,8 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc of the error" @@ -774,7 +772,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri async def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -794,13 +792,13 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url" + == "invalid_request: desc of the error\nMore information can be found on https://test_url" ) tab.assert_success() @@ -809,7 +807,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri async def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -830,8 +828,8 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -845,7 +843,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri async def test_with_invalid_grant_request_without_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -861,10 +859,8 @@ async def test_with_invalid_grant_request_without_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises( - httpx_auth.InvalidGrantRequest, match="{'other': 'other info'}" - ): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="{'other': 'other info'}"): await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -874,7 +870,7 @@ async def test_with_invalid_grant_request_without_error( async def test_with_invalid_grant_request_invalid_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -890,8 +886,8 @@ async def test_with_invalid_grant_request_invalid_client_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -912,7 +908,7 @@ async def test_with_invalid_grant_request_invalid_client_error( async def test_with_invalid_grant_request_invalid_grant_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -928,8 +924,8 @@ async def test_with_invalid_grant_request_invalid_grant_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -946,7 +942,7 @@ async def test_with_invalid_grant_request_invalid_grant_error( async def test_with_invalid_grant_request_unauthorized_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -962,8 +958,8 @@ async def test_with_invalid_grant_request_unauthorized_client_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -978,7 +974,7 @@ async def test_with_invalid_grant_request_unauthorized_client_error( async def test_with_invalid_grant_request_unsupported_grant_type_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -994,8 +990,8 @@ async def test_with_invalid_grant_request_unsupported_grant_type_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1010,7 +1006,7 @@ async def test_with_invalid_grant_request_unsupported_grant_type_error( async def test_with_invalid_grant_request_invalid_scope_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1026,8 +1022,8 @@ async def test_with_invalid_grant_request_invalid_scope_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1042,7 +1038,7 @@ async def test_with_invalid_grant_request_invalid_scope_error( async def test_with_invalid_token_request_invalid_request_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1052,8 +1048,8 @@ async def test_with_invalid_token_request_invalid_request_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1069,7 +1065,7 @@ async def test_with_invalid_token_request_invalid_request_error( async def test_with_invalid_token_request_invalid_request_error_and_error_description( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1079,10 +1075,8 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc", ) - async with httpx.AsyncClient() as client: - with pytest.raises( - httpx_auth.InvalidGrantRequest, match="invalid_request: desc" - ): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="invalid_request: desc"): await client.get("https://authorized_only", auth=auth) tab.assert_failure("invalid_request: desc") @@ -1092,7 +1086,7 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri async def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1102,24 +1096,22 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_request: desc\nMore information can be found on https://test_url" ) - tab.assert_failure( - "invalid_request: desc
More information can be found on https://test_url" - ) + tab.assert_failure("invalid_request: desc
More information can be found on https://test_url") @pytest.mark.asyncio async def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1129,8 +1121,8 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url&other=test", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1146,7 +1138,7 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri async def test_with_invalid_token_request_unauthorized_client_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1156,8 +1148,8 @@ async def test_with_invalid_token_request_unauthorized_client_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unauthorized_client", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1173,7 +1165,7 @@ async def test_with_invalid_token_request_unauthorized_client_error( async def test_with_invalid_token_request_access_denied_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1183,8 +1175,8 @@ async def test_with_invalid_token_request_access_denied_error( reply_url=f"http://localhost:{unused_tcp_port}#error=access_denied", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1200,7 +1192,7 @@ async def test_with_invalid_token_request_access_denied_error( async def test_with_invalid_token_request_unsupported_response_type_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1210,8 +1202,8 @@ async def test_with_invalid_token_request_unsupported_response_type_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unsupported_response_type", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1227,7 +1219,7 @@ async def test_with_invalid_token_request_unsupported_response_type_error( async def test_with_invalid_token_request_invalid_scope_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1237,24 +1229,22 @@ async def test_with_invalid_token_request_invalid_scope_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_scope", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_scope: The requested scope is invalid, unknown, or malformed." ) - tab.assert_failure( - "invalid_scope: The requested scope is invalid, unknown, or malformed." - ) + tab.assert_failure("invalid_scope: The requested scope is invalid, unknown, or malformed.") @pytest.mark.asyncio async def test_with_invalid_token_request_server_error_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1264,8 +1254,8 @@ async def test_with_invalid_token_request_server_error_error( reply_url=f"http://localhost:{unused_tcp_port}#error=server_error", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1281,7 +1271,7 @@ async def test_with_invalid_token_request_server_error_error( async def test_with_invalid_token_request_temporarily_unavailable_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1291,8 +1281,8 @@ async def test_with_invalid_token_request_temporarily_unavailable_error( reply_url=f"http://localhost:{unused_tcp_port}#error=temporarily_unavailable", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1308,7 +1298,7 @@ async def test_with_invalid_token_request_temporarily_unavailable_error( async def test_nonce_is_sent_if_provided_in_authorization_url( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1337,7 +1327,7 @@ async def test_nonce_is_sent_if_provided_in_authorization_url( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -1347,7 +1337,7 @@ async def test_nonce_is_sent_if_provided_in_authorization_url( async def test_response_type_can_be_provided_in_url( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code?response_type=my_code", "https://provide_access_token", response_type="not_used", @@ -1377,7 +1367,7 @@ async def test_response_type_can_be_provided_in_url( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() diff --git a/tests/oauth2/authorization_code/test_oauth2_authorization_code_sync.py b/tests/oauth2/authorization_code/test_oauth2_authorization_code_sync.py index 5e25221..48b6a1f 100644 --- a/tests/oauth2/authorization_code/test_oauth2_authorization_code_sync.py +++ b/tests/oauth2/authorization_code/test_oauth2_authorization_code_sync.py @@ -1,19 +1,19 @@ import time -from pytest_httpx import HTTPXMock +import httpx2 import pytest -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import BrowserMock, browser_mock, token_cache -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry +from httpx2_auth.testing import BrowserMock def test_oauth2_authorization_code_flow_uses_provided_client( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2AuthorizationCode( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", client=client, @@ -44,7 +44,7 @@ def test_oauth2_authorization_code_flow_uses_provided_client( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -53,7 +53,7 @@ def test_oauth2_authorization_code_flow_uses_provided_client( def test_oauth2_authorization_code_flow_uses_redirect_uri_domain( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_domain="localhost.mycompany.com", @@ -83,7 +83,7 @@ def test_oauth2_authorization_code_flow_uses_redirect_uri_domain( "Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA", }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -96,14 +96,12 @@ def test_oauth2_authorization_code_flow_uses_custom_success( monkeypatch, unused_tcp_port: int, ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.success_html = ( - "
SUCCESS: {display_time}
" - ) + httpx2_auth.OAuth2.display.success_html = "
SUCCESS: {display_time}
" tab = browser_mock.add_response( opened_url=f"https://provide_code?response_type=code&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#code=SplxlOBeZQQYbYS6WxSbIA&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5", @@ -129,7 +127,7 @@ def test_oauth2_authorization_code_flow_uses_custom_success( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -138,24 +136,24 @@ def test_oauth2_authorization_code_flow_uses_custom_success( def test_with_invalid_request_error_uses_custom_failure( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" + httpx2_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" tab = browser_mock.add_response( opened_url=f"https://provide_code?response_type=code&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", displayed_html="FAILURE: {display_time}\n{information}", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) - assert isinstance(exception_info.value, httpx_auth.HttpxAuthException) - assert isinstance(exception_info.value, httpx.HTTPError) + assert isinstance(exception_info.value, httpx2_auth.HttpxAuthException) + assert isinstance(exception_info.value, httpx2.HTTPError) tab.assert_failure( "invalid_request: The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed." @@ -165,8 +163,8 @@ def test_with_invalid_request_error_uses_custom_failure( def test_oauth2_authorization_code_flow_is_able_to_reuse_client( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2AuthorizationCode( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", client=client, @@ -196,7 +194,7 @@ def test_oauth2_authorization_code_flow_is_able_to_reuse_client( "Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA", }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -227,7 +225,7 @@ def test_oauth2_authorization_code_flow_is_able_to_reuse_client( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -236,8 +234,8 @@ def test_oauth2_authorization_code_flow_is_able_to_reuse_client( def test_oauth2_authorization_code_flow_is_able_to_reuse_client_with_token_refresh( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2AuthorizationCode( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", client=client, @@ -268,7 +266,7 @@ def test_oauth2_authorization_code_flow_is_able_to_reuse_client_with_token_refre "Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA", }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -297,14 +295,14 @@ def test_oauth2_authorization_code_flow_is_able_to_reuse_client_with_token_refre }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_authorization_code_flow_get_code_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -333,7 +331,7 @@ def test_oauth2_authorization_code_flow_get_code_is_sent_in_authorization_header }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -342,7 +340,7 @@ def test_oauth2_authorization_code_flow_get_code_is_sent_in_authorization_header def test_oauth2_authorization_code_flow_token_as_html( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -365,7 +363,7 @@ def test_oauth2_authorization_code_flow_token_as_html( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -374,7 +372,7 @@ def test_oauth2_authorization_code_flow_token_as_html( def test_oauth2_authorization_code_flow_get_code_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -410,7 +408,7 @@ def test_oauth2_authorization_code_flow_get_code_is_expired_after_30_seconds_by_ }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -419,7 +417,7 @@ def test_oauth2_authorization_code_flow_get_code_is_expired_after_30_seconds_by_ def test_oauth2_authorization_code_flow_get_code_custom_expiry( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", early_expiry=28 ) # Add a token that expires in 29 seconds, so should be considered as not expired when issuing the request @@ -436,14 +434,14 @@ def test_oauth2_authorization_code_flow_get_code_custom_expiry( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_authorization_code_flow_refresh_token( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -473,7 +471,7 @@ def test_oauth2_authorization_code_flow_refresh_token( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -499,14 +497,14 @@ def test_oauth2_authorization_code_flow_refresh_token( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_authorization_code_flow_refresh_token_invalid( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -536,7 +534,7 @@ def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -576,7 +574,7 @@ def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -585,7 +583,7 @@ def test_oauth2_authorization_code_flow_refresh_token_invalid( def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -615,7 +613,7 @@ def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -628,14 +626,14 @@ def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( }, ) # expect Bearer token to remain the same - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_empty_token_is_invalid( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -656,23 +654,23 @@ def test_empty_token_is_invalid( }, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.GrantNotProvided) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.GrantNotProvided) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "access_token not provided within {'access_token': '', 'token_type': 'example', 'expires_in': 3600, 'refresh_token': 'tGzv3JOkF0XG5Qx2TlKWIA', 'example_parameter': 'example_value'}." ) - assert isinstance(exception_info.value, httpx_auth.HttpxAuthException) - assert isinstance(exception_info.value, httpx.HTTPError) + assert isinstance(exception_info.value, httpx2_auth.HttpxAuthException) + assert isinstance(exception_info.value, httpx2.HTTPError) tab.assert_success() def test_with_invalid_grant_request_no_json( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -688,8 +686,8 @@ def test_with_invalid_grant_request_no_json( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest, match="failure"): + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="failure"): client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -698,7 +696,7 @@ def test_with_invalid_grant_request_no_json( def test_with_invalid_grant_request_invalid_request_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -714,8 +712,8 @@ def test_with_invalid_grant_request_invalid_request_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -731,7 +729,7 @@ def test_with_invalid_grant_request_invalid_request_error( def test_with_invalid_grant_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -747,8 +745,8 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc of the error" @@ -758,7 +756,7 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description( def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -778,13 +776,13 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url" + == "invalid_request: desc of the error\nMore information can be found on https://test_url" ) tab.assert_success() @@ -792,7 +790,7 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -813,8 +811,8 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -827,7 +825,7 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ def test_with_invalid_grant_request_without_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -843,10 +841,8 @@ def test_with_invalid_grant_request_without_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises( - httpx_auth.InvalidGrantRequest, match="{'other': 'other info'}" - ): + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="{'other': 'other info'}"): client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -855,7 +851,7 @@ def test_with_invalid_grant_request_without_error( def test_with_invalid_grant_request_invalid_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -871,8 +867,8 @@ def test_with_invalid_grant_request_invalid_client_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -892,7 +888,7 @@ def test_with_invalid_grant_request_invalid_client_error( def test_with_invalid_grant_request_invalid_grant_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -908,8 +904,8 @@ def test_with_invalid_grant_request_invalid_grant_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -925,7 +921,7 @@ def test_with_invalid_grant_request_invalid_grant_error( def test_with_invalid_grant_request_unauthorized_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -941,8 +937,8 @@ def test_with_invalid_grant_request_unauthorized_client_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -956,7 +952,7 @@ def test_with_invalid_grant_request_unauthorized_client_error( def test_with_invalid_grant_request_unsupported_grant_type_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -972,8 +968,8 @@ def test_with_invalid_grant_request_unsupported_grant_type_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -987,7 +983,7 @@ def test_with_invalid_grant_request_unsupported_grant_type_error( def test_with_invalid_grant_request_invalid_scope_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1003,8 +999,8 @@ def test_with_invalid_grant_request_invalid_scope_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1018,7 +1014,7 @@ def test_with_invalid_grant_request_invalid_scope_error( def test_with_invalid_token_request_invalid_request_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1028,8 +1024,8 @@ def test_with_invalid_token_request_invalid_request_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1044,7 +1040,7 @@ def test_with_invalid_token_request_invalid_request_error( def test_with_invalid_token_request_invalid_request_error_and_error_description( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1054,10 +1050,8 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc", ) - with httpx.Client() as client: - with pytest.raises( - httpx_auth.InvalidGrantRequest, match="invalid_request: desc" - ): + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="invalid_request: desc"): client.get("https://authorized_only", auth=auth) tab.assert_failure("invalid_request: desc") @@ -1066,7 +1060,7 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description( def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1076,23 +1070,21 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description_ reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_request: desc\nMore information can be found on https://test_url" ) - tab.assert_failure( - "invalid_request: desc
More information can be found on https://test_url" - ) + tab.assert_failure("invalid_request: desc
More information can be found on https://test_url") def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1102,8 +1094,8 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description_ reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url&other=test", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1118,7 +1110,7 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description_ def test_with_invalid_token_request_unauthorized_client_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1128,8 +1120,8 @@ def test_with_invalid_token_request_unauthorized_client_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unauthorized_client", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1144,7 +1136,7 @@ def test_with_invalid_token_request_unauthorized_client_error( def test_with_invalid_token_request_access_denied_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1154,8 +1146,8 @@ def test_with_invalid_token_request_access_denied_error( reply_url=f"http://localhost:{unused_tcp_port}#error=access_denied", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1170,7 +1162,7 @@ def test_with_invalid_token_request_access_denied_error( def test_with_invalid_token_request_unsupported_response_type_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1180,8 +1172,8 @@ def test_with_invalid_token_request_unsupported_response_type_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unsupported_response_type", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1196,7 +1188,7 @@ def test_with_invalid_token_request_unsupported_response_type_error( def test_with_invalid_token_request_invalid_scope_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1206,23 +1198,21 @@ def test_with_invalid_token_request_invalid_scope_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_scope", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_scope: The requested scope is invalid, unknown, or malformed." ) - tab.assert_failure( - "invalid_scope: The requested scope is invalid, unknown, or malformed." - ) + tab.assert_failure("invalid_scope: The requested scope is invalid, unknown, or malformed.") def test_with_invalid_token_request_server_error_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1232,8 +1222,8 @@ def test_with_invalid_token_request_server_error_error( reply_url=f"http://localhost:{unused_tcp_port}#error=server_error", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1248,7 +1238,7 @@ def test_with_invalid_token_request_server_error_error( def test_with_invalid_token_request_temporarily_unavailable_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1258,8 +1248,8 @@ def test_with_invalid_token_request_temporarily_unavailable_error( reply_url=f"http://localhost:{unused_tcp_port}#error=temporarily_unavailable", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1274,7 +1264,7 @@ def test_with_invalid_token_request_temporarily_unavailable_error( def test_nonce_is_sent_if_provided_in_authorization_url( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1303,7 +1293,7 @@ def test_nonce_is_sent_if_provided_in_authorization_url( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -1312,7 +1302,7 @@ def test_nonce_is_sent_if_provided_in_authorization_url( def test_response_type_can_be_provided_in_url( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCode( + auth = httpx2_auth.OAuth2AuthorizationCode( "https://provide_code?response_type=my_code", "https://provide_access_token", response_type="not_used", @@ -1342,7 +1332,7 @@ def test_response_type_can_be_provided_in_url( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() diff --git a/tests/oauth2/authorization_code/wakatime/__init__.py b/tests/oauth2/authorization_code/wakatime/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/oauth2/authorization_code/wakatime/test_oauth2_authorization_code_wakatime.py b/tests/oauth2/authorization_code/wakatime/test_oauth2_authorization_code_wakatime.py index 22e0534..954ddac 100644 --- a/tests/oauth2/authorization_code/wakatime/test_oauth2_authorization_code_wakatime.py +++ b/tests/oauth2/authorization_code/wakatime/test_oauth2_authorization_code_wakatime.py @@ -1,11 +1,11 @@ import pytest -import httpx_auth +import httpx2_auth def test_header_value_must_contains_token(): with pytest.raises(Exception) as exception_info: - httpx_auth.WakaTimeAuthorizationCode( + httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -16,7 +16,7 @@ def test_header_value_must_contains_token(): def test_empty_scope_is_invalid(): with pytest.raises(Exception) as exception_info: - httpx_auth.WakaTimeAuthorizationCode( + httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="", @@ -26,7 +26,7 @@ def test_empty_scope_is_invalid(): def test_scope_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.WakaTimeAuthorizationCode( + httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope=None, diff --git a/tests/oauth2/authorization_code/wakatime/test_oauth2_authorization_code_wakatime_async.py b/tests/oauth2/authorization_code/wakatime/test_oauth2_authorization_code_wakatime_async.py index 25e1d78..1b42c59 100644 --- a/tests/oauth2/authorization_code/wakatime/test_oauth2_authorization_code_wakatime_async.py +++ b/tests/oauth2/authorization_code/wakatime/test_oauth2_authorization_code_wakatime_async.py @@ -1,18 +1,18 @@ -from pytest_httpx import HTTPXMock +import httpx2 import pytest -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import BrowserMock, browser_mock, token_cache -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry +from httpx2_auth.testing import BrowserMock @pytest.mark.asyncio async def test_oauth2_authorization_code_flow_uses_provided_client( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.WakaTimeAuthorizationCode( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -38,7 +38,7 @@ async def test_oauth2_authorization_code_flow_uses_provided_client( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -49,7 +49,7 @@ async def test_oauth2_authorization_code_flow_uses_redirect_uri_domain( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -74,7 +74,7 @@ async def test_oauth2_authorization_code_flow_uses_redirect_uri_domain( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -85,15 +85,13 @@ async def test_oauth2_authorization_code_flow_uses_custom_success( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.success_html = ( - "
SUCCESS: {display_time}
" - ) + httpx2_auth.OAuth2.display.success_html = "
SUCCESS: {display_time}
" tab = browser_mock.add_response( opened_url=f"https://wakatime.com/oauth/authorize?client_id=jPJQV0op6Pu3b66MWDi8b1wD&client_secret=waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU&scope=email&response_type=code&state=5d0adb208bdbecaf5cfb6de0bf4ba0aea52986f3fc5ea7bc30c4b2db449c17e5c9d15f9a3926476cdaf1c72e9f73c7cfdc624dde0187c38d8c6b04532770df2a&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#code=SplxlOBeZQQYbYS6WxSbIA&state=5d0adb208bdbecaf5cfb6de0bf4ba0aea52986f3fc5ea7bc30c4b2db449c17e5c9d15f9a3926476cdaf1c72e9f73c7cfdc624dde0187c38d8c6b04532770df2a", @@ -113,7 +111,7 @@ async def test_oauth2_authorization_code_flow_uses_custom_success( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -124,21 +122,21 @@ async def test_oauth2_authorization_code_flow_uses_custom_failure( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" + httpx2_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" tab = browser_mock.add_response( opened_url=f"https://wakatime.com/oauth/authorize?client_id=jPJQV0op6Pu3b66MWDi8b1wD&client_secret=waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU&scope=email&response_type=code&state=5d0adb208bdbecaf5cfb6de0bf4ba0aea52986f3fc5ea7bc30c4b2db449c17e5c9d15f9a3926476cdaf1c72e9f73c7cfdc624dde0187c38d8c6b04532770df2a&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", displayed_html="FAILURE: {display_time}\n{information}", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest): await client.get("https://authorized_only", auth=auth) tab.assert_failure( @@ -151,7 +149,7 @@ async def test_multiple_scopes_are_comma_separated( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope=["email", "read_stats"], @@ -175,7 +173,7 @@ async def test_multiple_scopes_are_comma_separated( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -186,7 +184,7 @@ async def test_oauth2_authorization_code_flow_get_code_is_sent_in_authorization_ token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -211,7 +209,7 @@ async def test_oauth2_authorization_code_flow_get_code_is_sent_in_authorization_ }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -222,7 +220,7 @@ async def test_json_response_is_handled_even_if_unused( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -254,7 +252,7 @@ async def test_json_response_is_handled_even_if_unused( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -265,7 +263,7 @@ async def test_oauth2_authorization_code_flow_get_code_is_expired_after_30_secon token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -297,7 +295,7 @@ async def test_oauth2_authorization_code_flow_get_code_is_expired_after_30_secon }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -308,7 +306,7 @@ async def test_oauth2_authorization_code_flow_get_code_custom_expiry( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -328,7 +326,7 @@ async def test_oauth2_authorization_code_flow_get_code_custom_expiry( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -337,7 +335,7 @@ async def test_oauth2_authorization_code_flow_refresh_token( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -362,7 +360,7 @@ async def test_oauth2_authorization_code_flow_refresh_token( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -382,7 +380,7 @@ async def test_oauth2_authorization_code_flow_refresh_token( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -391,7 +389,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -416,7 +414,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -450,7 +448,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -461,7 +459,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -486,7 +484,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -499,7 +497,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp }, ) # expect Bearer token to remain the same - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -508,7 +506,7 @@ async def test_empty_token_is_invalid( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -526,8 +524,8 @@ async def test_empty_token_is_invalid( match_content=f"grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F&client_id=jPJQV0op6Pu3b66MWDi8b1wD&client_secret=waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU&scope=email&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA".encode(), ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.GrantNotProvided) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.GrantNotProvided) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -542,7 +540,7 @@ async def test_with_invalid_grant_request_no_json( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -560,8 +558,8 @@ async def test_with_invalid_grant_request_no_json( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest, match="failure"): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="failure"): await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -572,7 +570,7 @@ async def test_with_invalid_grant_request_invalid_request_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -590,8 +588,8 @@ async def test_with_invalid_grant_request_invalid_request_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -609,7 +607,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -627,8 +625,8 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc of the error" @@ -640,7 +638,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -662,13 +660,13 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url" + == "invalid_request: desc of the error\nMore information can be found on https://test_url" ) tab.assert_success() @@ -678,7 +676,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -701,8 +699,8 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -717,7 +715,7 @@ async def test_with_invalid_grant_request_without_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -735,10 +733,8 @@ async def test_with_invalid_grant_request_without_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises( - httpx_auth.InvalidGrantRequest, match="{'other': 'other info'}" - ): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="{'other': 'other info'}"): await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -749,7 +745,7 @@ async def test_with_invalid_grant_request_invalid_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -767,8 +763,8 @@ async def test_with_invalid_grant_request_invalid_client_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -790,7 +786,7 @@ async def test_with_invalid_grant_request_invalid_grant_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -808,8 +804,8 @@ async def test_with_invalid_grant_request_invalid_grant_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -827,7 +823,7 @@ async def test_with_invalid_grant_request_unauthorized_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -845,8 +841,8 @@ async def test_with_invalid_grant_request_unauthorized_client_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -862,7 +858,7 @@ async def test_with_invalid_grant_request_unsupported_grant_type_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -880,8 +876,8 @@ async def test_with_invalid_grant_request_unsupported_grant_type_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -897,7 +893,7 @@ async def test_with_invalid_grant_request_invalid_scope_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -915,8 +911,8 @@ async def test_with_invalid_grant_request_invalid_scope_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -932,7 +928,7 @@ async def test_with_invalid_token_request_invalid_request_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -944,8 +940,8 @@ async def test_with_invalid_token_request_invalid_request_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -962,7 +958,7 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -974,10 +970,8 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc", ) - async with httpx.AsyncClient() as client: - with pytest.raises( - httpx_auth.InvalidGrantRequest, match="invalid_request: desc" - ): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="invalid_request: desc"): await client.get("https://authorized_only", auth=auth) tab.assert_failure("invalid_request: desc") @@ -988,7 +982,7 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -1000,17 +994,15 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_request: desc\nMore information can be found on https://test_url" ) - tab.assert_failure( - "invalid_request: desc
More information can be found on https://test_url" - ) + tab.assert_failure("invalid_request: desc
More information can be found on https://test_url") @pytest.mark.asyncio @@ -1018,7 +1010,7 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -1030,8 +1022,8 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url&other=test", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1048,7 +1040,7 @@ async def test_with_invalid_token_request_unauthorized_client_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -1060,8 +1052,8 @@ async def test_with_invalid_token_request_unauthorized_client_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unauthorized_client", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1078,7 +1070,7 @@ async def test_with_invalid_token_request_access_denied_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -1090,8 +1082,8 @@ async def test_with_invalid_token_request_access_denied_error( reply_url=f"http://localhost:{unused_tcp_port}#error=access_denied", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1108,7 +1100,7 @@ async def test_with_invalid_token_request_unsupported_response_type_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -1120,8 +1112,8 @@ async def test_with_invalid_token_request_unsupported_response_type_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unsupported_response_type", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1138,7 +1130,7 @@ async def test_with_invalid_token_request_invalid_scope_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -1150,17 +1142,15 @@ async def test_with_invalid_token_request_invalid_scope_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_scope", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_scope: The requested scope is invalid, unknown, or malformed." ) - tab.assert_failure( - "invalid_scope: The requested scope is invalid, unknown, or malformed." - ) + tab.assert_failure("invalid_scope: The requested scope is invalid, unknown, or malformed.") @pytest.mark.asyncio @@ -1168,7 +1158,7 @@ async def test_with_invalid_token_request_server_error_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -1180,8 +1170,8 @@ async def test_with_invalid_token_request_server_error_error( reply_url=f"http://localhost:{unused_tcp_port}#error=server_error", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1198,7 +1188,7 @@ async def test_with_invalid_token_request_temporarily_unavailable_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -1210,8 +1200,8 @@ async def test_with_invalid_token_request_temporarily_unavailable_error( reply_url=f"http://localhost:{unused_tcp_port}#error=temporarily_unavailable", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( diff --git a/tests/oauth2/authorization_code/wakatime/test_oauth2_authorization_code_wakatime_sync.py b/tests/oauth2/authorization_code/wakatime/test_oauth2_authorization_code_wakatime_sync.py index 2be543f..b91700e 100644 --- a/tests/oauth2/authorization_code/wakatime/test_oauth2_authorization_code_wakatime_sync.py +++ b/tests/oauth2/authorization_code/wakatime/test_oauth2_authorization_code_wakatime_sync.py @@ -1,17 +1,17 @@ -from pytest_httpx import HTTPXMock +import httpx2 import pytest -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import BrowserMock, browser_mock, token_cache -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry +from httpx2_auth.testing import BrowserMock def test_oauth2_authorization_code_flow_uses_provided_client( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.WakaTimeAuthorizationCode( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -37,7 +37,7 @@ def test_oauth2_authorization_code_flow_uses_provided_client( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -46,7 +46,7 @@ def test_oauth2_authorization_code_flow_uses_provided_client( def test_oauth2_authorization_code_flow_uses_redirect_uri_domain( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -71,7 +71,7 @@ def test_oauth2_authorization_code_flow_uses_redirect_uri_domain( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -80,15 +80,13 @@ def test_oauth2_authorization_code_flow_uses_redirect_uri_domain( def test_oauth2_authorization_code_flow_uses_custom_success( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.success_html = ( - "
SUCCESS: {display_time}
" - ) + httpx2_auth.OAuth2.display.success_html = "
SUCCESS: {display_time}
" tab = browser_mock.add_response( opened_url=f"https://wakatime.com/oauth/authorize?client_id=jPJQV0op6Pu3b66MWDi8b1wD&client_secret=waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU&scope=email&response_type=code&state=5d0adb208bdbecaf5cfb6de0bf4ba0aea52986f3fc5ea7bc30c4b2db449c17e5c9d15f9a3926476cdaf1c72e9f73c7cfdc624dde0187c38d8c6b04532770df2a&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#code=SplxlOBeZQQYbYS6WxSbIA&state=5d0adb208bdbecaf5cfb6de0bf4ba0aea52986f3fc5ea7bc30c4b2db449c17e5c9d15f9a3926476cdaf1c72e9f73c7cfdc624dde0187c38d8c6b04532770df2a", @@ -108,7 +106,7 @@ def test_oauth2_authorization_code_flow_uses_custom_success( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -117,22 +115,21 @@ def test_oauth2_authorization_code_flow_uses_custom_success( def test_oauth2_authorization_code_flow_uses_custom_failure( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" + httpx2_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" tab = browser_mock.add_response( opened_url=f"https://wakatime.com/oauth/authorize?client_id=jPJQV0op6Pu3b66MWDi8b1wD&client_secret=waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU&scope=email&response_type=code&state=5d0adb208bdbecaf5cfb6de0bf4ba0aea52986f3fc5ea7bc30c4b2db449c17e5c9d15f9a3926476cdaf1c72e9f73c7cfdc624dde0187c38d8c6b04532770df2a&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", displayed_html="FAILURE: {display_time}\n{information}", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest): - client.get("https://authorized_only", auth=auth) + with httpx2.Client() as client, pytest.raises(httpx2_auth.InvalidGrantRequest): + client.get("https://authorized_only", auth=auth) tab.assert_failure( "invalid_request: The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed." @@ -142,7 +139,7 @@ def test_oauth2_authorization_code_flow_uses_custom_failure( def test_multiple_scopes_are_comma_separated( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope=["email", "read_stats"], @@ -166,7 +163,7 @@ def test_multiple_scopes_are_comma_separated( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -175,7 +172,7 @@ def test_multiple_scopes_are_comma_separated( def test_oauth2_authorization_code_flow_get_code_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -199,7 +196,7 @@ def test_oauth2_authorization_code_flow_get_code_is_sent_in_authorization_header }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -208,7 +205,7 @@ def test_oauth2_authorization_code_flow_get_code_is_sent_in_authorization_header def test_json_response_is_handled_even_if_unused( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -239,7 +236,7 @@ def test_json_response_is_handled_even_if_unused( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -248,7 +245,7 @@ def test_json_response_is_handled_even_if_unused( def test_oauth2_authorization_code_flow_get_code_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -279,7 +276,7 @@ def test_oauth2_authorization_code_flow_get_code_is_expired_after_30_seconds_by_ }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -288,7 +285,7 @@ def test_oauth2_authorization_code_flow_get_code_is_expired_after_30_seconds_by_ def test_oauth2_authorization_code_flow_get_code_custom_expiry( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -308,14 +305,14 @@ def test_oauth2_authorization_code_flow_get_code_custom_expiry( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_authorization_code_flow_refresh_token( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -339,7 +336,7 @@ def test_oauth2_authorization_code_flow_refresh_token( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -359,14 +356,14 @@ def test_oauth2_authorization_code_flow_refresh_token( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_authorization_code_flow_refresh_token_invalid( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -390,7 +387,7 @@ def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -424,7 +421,7 @@ def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -433,7 +430,7 @@ def test_oauth2_authorization_code_flow_refresh_token_invalid( def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -457,7 +454,7 @@ def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -470,14 +467,14 @@ def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( }, ) # expect Bearer token to remain the same - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_empty_token_is_invalid( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -494,8 +491,8 @@ def test_empty_token_is_invalid( match_content=f"grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F&client_id=jPJQV0op6Pu3b66MWDi8b1wD&client_secret=waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU&scope=email&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA".encode(), ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.GrantNotProvided) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.GrantNotProvided) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -508,7 +505,7 @@ def test_empty_token_is_invalid( def test_with_invalid_grant_request_no_json( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -525,8 +522,8 @@ def test_with_invalid_grant_request_no_json( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest, match="failure"): + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="failure"): client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -535,7 +532,7 @@ def test_with_invalid_grant_request_no_json( def test_with_invalid_grant_request_invalid_request_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -552,8 +549,8 @@ def test_with_invalid_grant_request_invalid_request_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -569,7 +566,7 @@ def test_with_invalid_grant_request_invalid_request_error( def test_with_invalid_grant_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -586,8 +583,8 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc of the error" @@ -597,7 +594,7 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description( def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -618,13 +615,13 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url" + == "invalid_request: desc of the error\nMore information can be found on https://test_url" ) tab.assert_success() @@ -632,7 +629,7 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -654,8 +651,8 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -668,7 +665,7 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ def test_with_invalid_grant_request_without_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -685,10 +682,8 @@ def test_with_invalid_grant_request_without_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises( - httpx_auth.InvalidGrantRequest, match="{'other': 'other info'}" - ): + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="{'other': 'other info'}"): client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -697,7 +692,7 @@ def test_with_invalid_grant_request_without_error( def test_with_invalid_grant_request_invalid_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -714,8 +709,8 @@ def test_with_invalid_grant_request_invalid_client_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -735,7 +730,7 @@ def test_with_invalid_grant_request_invalid_client_error( def test_with_invalid_grant_request_invalid_grant_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -752,8 +747,8 @@ def test_with_invalid_grant_request_invalid_grant_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -769,7 +764,7 @@ def test_with_invalid_grant_request_invalid_grant_error( def test_with_invalid_grant_request_unauthorized_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -786,8 +781,8 @@ def test_with_invalid_grant_request_unauthorized_client_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -801,7 +796,7 @@ def test_with_invalid_grant_request_unauthorized_client_error( def test_with_invalid_grant_request_unsupported_grant_type_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -818,8 +813,8 @@ def test_with_invalid_grant_request_unsupported_grant_type_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -833,7 +828,7 @@ def test_with_invalid_grant_request_unsupported_grant_type_error( def test_with_invalid_grant_request_invalid_scope_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -850,8 +845,8 @@ def test_with_invalid_grant_request_invalid_scope_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -865,7 +860,7 @@ def test_with_invalid_grant_request_invalid_scope_error( def test_with_invalid_token_request_invalid_request_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -876,8 +871,8 @@ def test_with_invalid_token_request_invalid_request_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -892,7 +887,7 @@ def test_with_invalid_token_request_invalid_request_error( def test_with_invalid_token_request_invalid_request_error_and_error_description( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -903,10 +898,8 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc", ) - with httpx.Client() as client: - with pytest.raises( - httpx_auth.InvalidGrantRequest, match="invalid_request: desc" - ): + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="invalid_request: desc"): client.get("https://authorized_only", auth=auth) tab.assert_failure("invalid_request: desc") @@ -915,7 +908,7 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description( def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -926,23 +919,21 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description_ reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_request: desc\nMore information can be found on https://test_url" ) - tab.assert_failure( - "invalid_request: desc
More information can be found on https://test_url" - ) + tab.assert_failure("invalid_request: desc
More information can be found on https://test_url") def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -953,8 +944,8 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description_ reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url&other=test", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -969,7 +960,7 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description_ def test_with_invalid_token_request_unauthorized_client_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -980,8 +971,8 @@ def test_with_invalid_token_request_unauthorized_client_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unauthorized_client", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -996,7 +987,7 @@ def test_with_invalid_token_request_unauthorized_client_error( def test_with_invalid_token_request_access_denied_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -1007,8 +998,8 @@ def test_with_invalid_token_request_access_denied_error( reply_url=f"http://localhost:{unused_tcp_port}#error=access_denied", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1023,7 +1014,7 @@ def test_with_invalid_token_request_access_denied_error( def test_with_invalid_token_request_unsupported_response_type_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -1034,8 +1025,8 @@ def test_with_invalid_token_request_unsupported_response_type_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unsupported_response_type", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1050,7 +1041,7 @@ def test_with_invalid_token_request_unsupported_response_type_error( def test_with_invalid_token_request_invalid_scope_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -1061,23 +1052,21 @@ def test_with_invalid_token_request_invalid_scope_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_scope", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_scope: The requested scope is invalid, unknown, or malformed." ) - tab.assert_failure( - "invalid_scope: The requested scope is invalid, unknown, or malformed." - ) + tab.assert_failure("invalid_scope: The requested scope is invalid, unknown, or malformed.") def test_with_invalid_token_request_server_error_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -1088,8 +1077,8 @@ def test_with_invalid_token_request_server_error_error( reply_url=f"http://localhost:{unused_tcp_port}#error=server_error", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1104,7 +1093,7 @@ def test_with_invalid_token_request_server_error_error( def test_with_invalid_token_request_temporarily_unavailable_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.WakaTimeAuthorizationCode( + auth = httpx2_auth.WakaTimeAuthorizationCode( "jPJQV0op6Pu3b66MWDi8b1wD", "waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU", scope="email", @@ -1115,8 +1104,8 @@ def test_with_invalid_token_request_temporarily_unavailable_error( reply_url=f"http://localhost:{unused_tcp_port}#error=temporarily_unavailable", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( diff --git a/tests/oauth2/authorization_code_pkce/__init__.py b/tests/oauth2/authorization_code_pkce/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/oauth2/authorization_code_pkce/conftest.py b/tests/oauth2/authorization_code_pkce/conftest.py index ab292b4..89466b7 100644 --- a/tests/oauth2/authorization_code_pkce/conftest.py +++ b/tests/oauth2/authorization_code_pkce/conftest.py @@ -1,10 +1,10 @@ import pytest -import httpx_auth._oauth2.authorization_code_pkce +import httpx2_auth._oauth2.authorization_code_pkce @pytest.fixture(autouse=True) def urandom_patch(monkeypatch): monkeypatch.setattr( - httpx_auth._oauth2.authorization_code_pkce.os, "urandom", lambda x: b"1" * 63 + httpx2_auth._oauth2.authorization_code_pkce.os, "urandom", lambda x: b"1" * 63 ) diff --git a/tests/oauth2/authorization_code_pkce/okta/__init__.py b/tests/oauth2/authorization_code_pkce/okta/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/oauth2/authorization_code_pkce/okta/test_oauth2_authorization_code_pkce_okta.py b/tests/oauth2/authorization_code_pkce/okta/test_oauth2_authorization_code_pkce_okta.py index 251ee4f..894cb27 100644 --- a/tests/oauth2/authorization_code_pkce/okta/test_oauth2_authorization_code_pkce_okta.py +++ b/tests/oauth2/authorization_code_pkce/okta/test_oauth2_authorization_code_pkce_okta.py @@ -1,11 +1,11 @@ import pytest -import httpx_auth +import httpx2_auth def test_header_value_must_contains_token(): with pytest.raises(Exception) as exception_info: - httpx_auth.OktaAuthorizationCodePKCE( + httpx2_auth.OktaAuthorizationCodePKCE( "test_url", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", header_value="Bearer token", diff --git a/tests/oauth2/authorization_code_pkce/okta/test_oauth2_authorization_code_pkce_okta_async.py b/tests/oauth2/authorization_code_pkce/okta/test_oauth2_authorization_code_pkce_okta_async.py index 5b1b31a..9d21f8d 100644 --- a/tests/oauth2/authorization_code_pkce/okta/test_oauth2_authorization_code_pkce_okta_async.py +++ b/tests/oauth2/authorization_code_pkce/okta/test_oauth2_authorization_code_pkce_okta_async.py @@ -1,18 +1,18 @@ -from pytest_httpx import HTTPXMock +import httpx2 import pytest -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import BrowserMock, browser_mock, token_cache -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry +from httpx2_auth.testing import BrowserMock @pytest.mark.asyncio async def test_oauth2_pkce_flow_uses_provided_client( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OktaAuthorizationCodePKCE( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", client=client, @@ -43,7 +43,7 @@ async def test_oauth2_pkce_flow_uses_provided_client( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -53,7 +53,7 @@ async def test_oauth2_pkce_flow_uses_provided_client( async def test_oauth2_pkce_flow_uses_redirect_uri_domain( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_domain="localhost.mycompany.com", @@ -83,7 +83,7 @@ async def test_oauth2_pkce_flow_uses_redirect_uri_domain( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -93,14 +93,12 @@ async def test_oauth2_pkce_flow_uses_redirect_uri_domain( async def test_oauth2_pkce_flow_uses_custom_success( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.success_html = ( - "
SUCCESS: {display_time}
" - ) + httpx2_auth.OAuth2.display.success_html = "
SUCCESS: {display_time}
" tab = browser_mock.add_response( opened_url=f"https://testserver.okta-emea.com/oauth2/default/v1/authorize?client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc&code_challenge_method=S256", reply_url=f"http://localhost:{unused_tcp_port}#code=SplxlOBeZQQYbYS6WxSbIA&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b", @@ -126,7 +124,7 @@ async def test_oauth2_pkce_flow_uses_custom_success( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -136,20 +134,20 @@ async def test_oauth2_pkce_flow_uses_custom_success( async def test_oauth2_pkce_flow_uses_custom_failure( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" + httpx2_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" tab = browser_mock.add_response( opened_url=f"https://testserver.okta-emea.com/oauth2/default/v1/authorize?client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc&code_challenge_method=S256", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", displayed_html="FAILURE: {display_time}\n{information}", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest): await client.get("https://authorized_only", auth=auth) tab.assert_failure( @@ -161,7 +159,7 @@ async def test_oauth2_pkce_flow_uses_custom_failure( async def test_oauth2_pkce_flow_get_code_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -190,7 +188,7 @@ async def test_oauth2_pkce_flow_get_code_is_sent_in_authorization_header_by_defa }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -200,7 +198,7 @@ async def test_oauth2_pkce_flow_get_code_is_sent_in_authorization_header_by_defa async def test_oauth2_pkce_flow_get_code_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -236,7 +234,7 @@ async def test_oauth2_pkce_flow_get_code_is_expired_after_30_seconds_by_default( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -246,7 +244,7 @@ async def test_oauth2_pkce_flow_get_code_is_expired_after_30_seconds_by_default( async def test_oauth2_pkce_flow_get_code_custom_expiry( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", early_expiry=28, @@ -265,7 +263,7 @@ async def test_oauth2_pkce_flow_get_code_custom_expiry( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -273,7 +271,7 @@ async def test_oauth2_pkce_flow_get_code_custom_expiry( async def test_oauth2_authorization_code_flow_refresh_token( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -302,7 +300,7 @@ async def test_oauth2_authorization_code_flow_refresh_token( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -328,7 +326,7 @@ async def test_oauth2_authorization_code_flow_refresh_token( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -336,7 +334,7 @@ async def test_oauth2_authorization_code_flow_refresh_token( async def test_oauth2_authorization_code_flow_refresh_token_invalid( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -365,7 +363,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -405,7 +403,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -415,7 +413,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid( async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -444,7 +442,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -457,7 +455,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp }, ) # expect Bearer token to remain the same - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -465,7 +463,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp async def test_expires_in_sent_as_str( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -494,7 +492,7 @@ async def test_expires_in_sent_as_str( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -504,7 +502,7 @@ async def test_expires_in_sent_as_str( async def test_with_invalid_grant_request_no_json( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -520,8 +518,8 @@ async def test_with_invalid_grant_request_no_json( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest, match="failure"): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="failure"): await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -531,7 +529,7 @@ async def test_with_invalid_grant_request_no_json( async def test_with_invalid_grant_request_invalid_request_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -547,8 +545,8 @@ async def test_with_invalid_grant_request_invalid_request_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -565,7 +563,7 @@ async def test_with_invalid_grant_request_invalid_request_error( async def test_with_invalid_grant_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -581,8 +579,8 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc of the error" @@ -593,7 +591,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri async def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -613,13 +611,13 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url" + == "invalid_request: desc of the error\nMore information can be found on https://test_url" ) tab.assert_success() @@ -628,7 +626,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri async def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -649,13 +647,13 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {{'other': 'other info'}}" + == "invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {'other': 'other info'}" ) tab.assert_success() @@ -664,7 +662,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri async def test_with_invalid_grant_request_without_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -680,10 +678,8 @@ async def test_with_invalid_grant_request_without_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises( - httpx_auth.InvalidGrantRequest, match="{'other': 'other info'}" - ): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="{'other': 'other info'}"): await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -693,7 +689,7 @@ async def test_with_invalid_grant_request_without_error( async def test_with_invalid_grant_request_invalid_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -709,8 +705,8 @@ async def test_with_invalid_grant_request_invalid_client_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -731,7 +727,7 @@ async def test_with_invalid_grant_request_invalid_client_error( async def test_with_invalid_grant_request_invalid_grant_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -747,8 +743,8 @@ async def test_with_invalid_grant_request_invalid_grant_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -765,7 +761,7 @@ async def test_with_invalid_grant_request_invalid_grant_error( async def test_with_invalid_grant_request_unauthorized_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -781,8 +777,8 @@ async def test_with_invalid_grant_request_unauthorized_client_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -797,7 +793,7 @@ async def test_with_invalid_grant_request_unauthorized_client_error( async def test_with_invalid_grant_request_unsupported_grant_type_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -813,8 +809,8 @@ async def test_with_invalid_grant_request_unsupported_grant_type_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -829,7 +825,7 @@ async def test_with_invalid_grant_request_unsupported_grant_type_error( async def test_with_invalid_grant_request_invalid_scope_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -845,8 +841,8 @@ async def test_with_invalid_grant_request_invalid_scope_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -861,7 +857,7 @@ async def test_with_invalid_grant_request_invalid_scope_error( async def test_with_invalid_token_request_invalid_request_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -871,8 +867,8 @@ async def test_with_invalid_token_request_invalid_request_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -888,7 +884,7 @@ async def test_with_invalid_token_request_invalid_request_error( async def test_with_invalid_token_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -898,8 +894,8 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc" @@ -910,7 +906,7 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri async def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -920,24 +916,22 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_request: desc\nMore information can be found on https://test_url" ) - tab.assert_failure( - "invalid_request: desc
More information can be found on https://test_url" - ) + tab.assert_failure("invalid_request: desc
More information can be found on https://test_url") @pytest.mark.asyncio async def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -947,8 +941,8 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url&other=test", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -964,7 +958,7 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri async def test_with_invalid_token_request_unauthorized_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -974,8 +968,8 @@ async def test_with_invalid_token_request_unauthorized_client_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unauthorized_client", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -991,7 +985,7 @@ async def test_with_invalid_token_request_unauthorized_client_error( async def test_with_invalid_token_request_access_denied_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -1001,8 +995,8 @@ async def test_with_invalid_token_request_access_denied_error( reply_url=f"http://localhost:{unused_tcp_port}#error=access_denied", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1018,7 +1012,7 @@ async def test_with_invalid_token_request_access_denied_error( async def test_with_invalid_token_request_unsupported_response_type_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -1028,8 +1022,8 @@ async def test_with_invalid_token_request_unsupported_response_type_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unsupported_response_type", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1045,7 +1039,7 @@ async def test_with_invalid_token_request_unsupported_response_type_error( async def test_with_invalid_token_request_invalid_scope_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -1055,24 +1049,22 @@ async def test_with_invalid_token_request_invalid_scope_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_scope", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_scope: The requested scope is invalid, unknown, or malformed." ) - tab.assert_failure( - "invalid_scope: The requested scope is invalid, unknown, or malformed." - ) + tab.assert_failure("invalid_scope: The requested scope is invalid, unknown, or malformed.") @pytest.mark.asyncio async def test_with_invalid_token_request_server_error_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -1082,8 +1074,8 @@ async def test_with_invalid_token_request_server_error_error( reply_url=f"http://localhost:{unused_tcp_port}#error=server_error", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1099,7 +1091,7 @@ async def test_with_invalid_token_request_server_error_error( async def test_with_invalid_token_request_temporarily_unavailable_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -1109,8 +1101,8 @@ async def test_with_invalid_token_request_temporarily_unavailable_error( reply_url=f"http://localhost:{unused_tcp_port}#error=temporarily_unavailable", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( diff --git a/tests/oauth2/authorization_code_pkce/okta/test_oauth2_authorization_code_pkce_okta_sync.py b/tests/oauth2/authorization_code_pkce/okta/test_oauth2_authorization_code_pkce_okta_sync.py index 70b4061..5502075 100644 --- a/tests/oauth2/authorization_code_pkce/okta/test_oauth2_authorization_code_pkce_okta_sync.py +++ b/tests/oauth2/authorization_code_pkce/okta/test_oauth2_authorization_code_pkce_okta_sync.py @@ -1,17 +1,17 @@ -from pytest_httpx import HTTPXMock +import httpx2 import pytest -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import BrowserMock, browser_mock, token_cache -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry +from httpx2_auth.testing import BrowserMock def test_oauth2_pkce_flow_uses_provided_client( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OktaAuthorizationCodePKCE( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", client=client, @@ -42,7 +42,7 @@ def test_oauth2_pkce_flow_uses_provided_client( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -51,7 +51,7 @@ def test_oauth2_pkce_flow_uses_provided_client( def test_oauth2_pkce_flow_uses_redirect_uri_domain( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_domain="localhost.mycompany.com", @@ -81,7 +81,7 @@ def test_oauth2_pkce_flow_uses_redirect_uri_domain( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -90,14 +90,12 @@ def test_oauth2_pkce_flow_uses_redirect_uri_domain( def test_oauth2_pkce_flow_uses_custom_success( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.success_html = ( - "
SUCCESS: {display_time}
" - ) + httpx2_auth.OAuth2.display.success_html = "
SUCCESS: {display_time}
" tab = browser_mock.add_response( opened_url=f"https://testserver.okta-emea.com/oauth2/default/v1/authorize?client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc&code_challenge_method=S256", reply_url=f"http://localhost:{unused_tcp_port}#code=SplxlOBeZQQYbYS6WxSbIA&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b", @@ -123,7 +121,7 @@ def test_oauth2_pkce_flow_uses_custom_success( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -132,21 +130,20 @@ def test_oauth2_pkce_flow_uses_custom_success( def test_oauth2_pkce_flow_uses_custom_failure( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" + httpx2_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" tab = browser_mock.add_response( opened_url=f"https://testserver.okta-emea.com/oauth2/default/v1/authorize?client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc&code_challenge_method=S256", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", displayed_html="FAILURE: {display_time}\n{information}", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest): - client.get("https://authorized_only", auth=auth) + with httpx2.Client() as client, pytest.raises(httpx2_auth.InvalidGrantRequest): + client.get("https://authorized_only", auth=auth) tab.assert_failure( "invalid_request: The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed." @@ -156,7 +153,7 @@ def test_oauth2_pkce_flow_uses_custom_failure( def test_oauth2_pkce_flow_get_code_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -185,7 +182,7 @@ def test_oauth2_pkce_flow_get_code_is_sent_in_authorization_header_by_default( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -194,7 +191,7 @@ def test_oauth2_pkce_flow_get_code_is_sent_in_authorization_header_by_default( def test_oauth2_pkce_flow_get_code_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -230,7 +227,7 @@ def test_oauth2_pkce_flow_get_code_is_expired_after_30_seconds_by_default( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -239,7 +236,7 @@ def test_oauth2_pkce_flow_get_code_is_expired_after_30_seconds_by_default( def test_oauth2_pkce_flow_get_code_custom_expiry( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", early_expiry=28, @@ -258,14 +255,14 @@ def test_oauth2_pkce_flow_get_code_custom_expiry( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_authorization_code_flow_refresh_token( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -294,7 +291,7 @@ def test_oauth2_authorization_code_flow_refresh_token( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -320,14 +317,14 @@ def test_oauth2_authorization_code_flow_refresh_token( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_authorization_code_flow_refresh_token_invalid( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -356,7 +353,7 @@ def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -396,7 +393,7 @@ def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -405,7 +402,7 @@ def test_oauth2_authorization_code_flow_refresh_token_invalid( def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -434,7 +431,7 @@ def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -447,14 +444,14 @@ def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( }, ) # expect Bearer token to remain the same - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_expires_in_sent_as_str( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -483,7 +480,7 @@ def test_expires_in_sent_as_str( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -492,7 +489,7 @@ def test_expires_in_sent_as_str( def test_with_invalid_grant_request_no_json( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -508,8 +505,8 @@ def test_with_invalid_grant_request_no_json( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest, match="failure"): + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="failure"): client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -518,7 +515,7 @@ def test_with_invalid_grant_request_no_json( def test_with_invalid_grant_request_invalid_request_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -534,8 +531,8 @@ def test_with_invalid_grant_request_invalid_request_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -551,7 +548,7 @@ def test_with_invalid_grant_request_invalid_request_error( def test_with_invalid_grant_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -567,8 +564,8 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc of the error" @@ -578,7 +575,7 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description( def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -598,13 +595,13 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url" + == "invalid_request: desc of the error\nMore information can be found on https://test_url" ) tab.assert_success() @@ -612,7 +609,7 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -633,13 +630,13 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {{'other': 'other info'}}" + == "invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {'other': 'other info'}" ) tab.assert_success() @@ -647,7 +644,7 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ def test_with_invalid_grant_request_without_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -663,10 +660,8 @@ def test_with_invalid_grant_request_without_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises( - httpx_auth.InvalidGrantRequest, match="{'other': 'other info'}" - ): + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="{'other': 'other info'}"): client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -675,7 +670,7 @@ def test_with_invalid_grant_request_without_error( def test_with_invalid_grant_request_invalid_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -691,8 +686,8 @@ def test_with_invalid_grant_request_invalid_client_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -712,7 +707,7 @@ def test_with_invalid_grant_request_invalid_client_error( def test_with_invalid_grant_request_invalid_grant_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -728,8 +723,8 @@ def test_with_invalid_grant_request_invalid_grant_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -745,7 +740,7 @@ def test_with_invalid_grant_request_invalid_grant_error( def test_with_invalid_grant_request_unauthorized_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -761,8 +756,8 @@ def test_with_invalid_grant_request_unauthorized_client_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -776,7 +771,7 @@ def test_with_invalid_grant_request_unauthorized_client_error( def test_with_invalid_grant_request_unsupported_grant_type_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -792,8 +787,8 @@ def test_with_invalid_grant_request_unsupported_grant_type_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -807,7 +802,7 @@ def test_with_invalid_grant_request_unsupported_grant_type_error( def test_with_invalid_grant_request_invalid_scope_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -823,8 +818,8 @@ def test_with_invalid_grant_request_invalid_scope_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -838,7 +833,7 @@ def test_with_invalid_grant_request_invalid_scope_error( def test_with_invalid_token_request_invalid_request_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -848,8 +843,8 @@ def test_with_invalid_token_request_invalid_request_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -864,7 +859,7 @@ def test_with_invalid_token_request_invalid_request_error( def test_with_invalid_token_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -874,8 +869,8 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc" @@ -885,7 +880,7 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description( def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -895,23 +890,21 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description_ reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_request: desc\nMore information can be found on https://test_url" ) - tab.assert_failure( - "invalid_request: desc
More information can be found on https://test_url" - ) + tab.assert_failure("invalid_request: desc
More information can be found on https://test_url") def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -921,8 +914,8 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description_ reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url&other=test", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -937,7 +930,7 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description_ def test_with_invalid_token_request_unauthorized_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -947,8 +940,8 @@ def test_with_invalid_token_request_unauthorized_client_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unauthorized_client", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -963,7 +956,7 @@ def test_with_invalid_token_request_unauthorized_client_error( def test_with_invalid_token_request_access_denied_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -973,8 +966,8 @@ def test_with_invalid_token_request_access_denied_error( reply_url=f"http://localhost:{unused_tcp_port}#error=access_denied", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -989,7 +982,7 @@ def test_with_invalid_token_request_access_denied_error( def test_with_invalid_token_request_unsupported_response_type_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -999,8 +992,8 @@ def test_with_invalid_token_request_unsupported_response_type_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unsupported_response_type", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1015,7 +1008,7 @@ def test_with_invalid_token_request_unsupported_response_type_error( def test_with_invalid_token_request_invalid_scope_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -1025,23 +1018,21 @@ def test_with_invalid_token_request_invalid_scope_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_scope", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_scope: The requested scope is invalid, unknown, or malformed." ) - tab.assert_failure( - "invalid_scope: The requested scope is invalid, unknown, or malformed." - ) + tab.assert_failure("invalid_scope: The requested scope is invalid, unknown, or malformed.") def test_with_invalid_token_request_server_error_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -1051,8 +1042,8 @@ def test_with_invalid_token_request_server_error_error( reply_url=f"http://localhost:{unused_tcp_port}#error=server_error", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1067,7 +1058,7 @@ def test_with_invalid_token_request_server_error_error( def test_with_invalid_token_request_temporarily_unavailable_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OktaAuthorizationCodePKCE( + auth = httpx2_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd", redirect_uri_port=unused_tcp_port, @@ -1077,8 +1068,8 @@ def test_with_invalid_token_request_temporarily_unavailable_error( reply_url=f"http://localhost:{unused_tcp_port}#error=temporarily_unavailable", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( diff --git a/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce.py b/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce.py index a80015c..f545ba0 100644 --- a/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce.py +++ b/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce.py @@ -1,23 +1,23 @@ import pytest -import httpx_auth +import httpx2_auth def test_authorization_url_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OAuth2AuthorizationCodePKCE("", "https://test_url") + httpx2_auth.OAuth2AuthorizationCodePKCE("", "https://test_url") assert str(exception_info.value) == "Authorization URL is mandatory." def test_token_url_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OAuth2AuthorizationCodePKCE("https://test_url", "") + httpx2_auth.OAuth2AuthorizationCodePKCE("https://test_url", "") assert str(exception_info.value) == "Token URL is mandatory." def test_header_value_must_contains_token(): with pytest.raises(Exception) as exception_info: - httpx_auth.OAuth2AuthorizationCodePKCE( + httpx2_auth.OAuth2AuthorizationCodePKCE( "https://test_url", "https://test_url", header_value="Bearer token" ) assert str(exception_info.value) == "header_value parameter must contains {token}." diff --git a/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce_async.py b/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce_async.py index f334587..0d97a24 100644 --- a/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce_async.py +++ b/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce_async.py @@ -1,20 +1,20 @@ import time -from pytest_httpx import HTTPXMock +import httpx2 import pytest -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import BrowserMock, browser_mock, token_cache -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry +from httpx2_auth.testing import BrowserMock @pytest.mark.asyncio async def test_oauth2_pkce_flow_uses_provided_client( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", client=client, @@ -45,7 +45,7 @@ async def test_oauth2_pkce_flow_uses_provided_client( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -55,7 +55,7 @@ async def test_oauth2_pkce_flow_uses_provided_client( async def test_oauth2_pkce_flow_uses_redirect_uri_domain( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_domain="localhost.mycompany.com", @@ -85,7 +85,7 @@ async def test_oauth2_pkce_flow_uses_redirect_uri_domain( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -95,14 +95,12 @@ async def test_oauth2_pkce_flow_uses_redirect_uri_domain( async def test_oauth2_pkce_flow_uses_custom_success( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.success_html = ( - "
SUCCESS: {display_time}
" - ) + httpx2_auth.OAuth2.display.success_html = "
SUCCESS: {display_time}
" tab = browser_mock.add_response( opened_url=f"https://provide_code?response_type=code&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc&code_challenge_method=S256", reply_url=f"http://localhost:{unused_tcp_port}#code=SplxlOBeZQQYbYS6WxSbIA&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5", @@ -128,7 +126,7 @@ async def test_oauth2_pkce_flow_uses_custom_success( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -138,20 +136,20 @@ async def test_oauth2_pkce_flow_uses_custom_success( async def test_oauth2_pkce_flow_uses_custom_failure( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" + httpx2_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" tab = browser_mock.add_response( opened_url=f"https://provide_code?response_type=code&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc&code_challenge_method=S256", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", displayed_html="FAILURE: {display_time}\n{information}", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest): await client.get("https://authorized_only", auth=auth) tab.assert_failure( @@ -163,8 +161,8 @@ async def test_oauth2_pkce_flow_uses_custom_failure( async def test_oauth2_pkce_flow_is_able_to_reuse_client( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", client=client, @@ -194,7 +192,7 @@ async def test_oauth2_pkce_flow_is_able_to_reuse_client( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -223,7 +221,7 @@ async def test_oauth2_pkce_flow_is_able_to_reuse_client( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -233,8 +231,8 @@ async def test_oauth2_pkce_flow_is_able_to_reuse_client( async def test_oauth2_pkce_flow_is_able_to_reuse_client_with_token_refresh( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", client=client, @@ -265,7 +263,7 @@ async def test_oauth2_pkce_flow_is_able_to_reuse_client_with_token_refresh( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -292,7 +290,7 @@ async def test_oauth2_pkce_flow_is_able_to_reuse_client_with_token_refresh( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -300,7 +298,7 @@ async def test_oauth2_pkce_flow_is_able_to_reuse_client_with_token_refresh( async def test_oauth2_pkce_flow_get_code_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -329,7 +327,7 @@ async def test_oauth2_pkce_flow_get_code_is_sent_in_authorization_header_by_defa }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -339,7 +337,7 @@ async def test_oauth2_pkce_flow_get_code_is_sent_in_authorization_header_by_defa async def test_oauth2_pkce_flow_get_code_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -375,7 +373,7 @@ async def test_oauth2_pkce_flow_get_code_is_expired_after_30_seconds_by_default( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -385,7 +383,7 @@ async def test_oauth2_pkce_flow_get_code_is_expired_after_30_seconds_by_default( async def test_oauth2_pkce_flow_get_code_custom_expiry( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", early_expiry=28 ) # Add a token that expires in 29 seconds, so should be considered as not expired when issuing the request @@ -402,7 +400,7 @@ async def test_oauth2_pkce_flow_get_code_custom_expiry( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -410,7 +408,7 @@ async def test_oauth2_pkce_flow_get_code_custom_expiry( async def test_oauth2_authorization_code_flow_refresh_token( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -440,7 +438,7 @@ async def test_oauth2_authorization_code_flow_refresh_token( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -466,7 +464,7 @@ async def test_oauth2_authorization_code_flow_refresh_token( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -474,7 +472,7 @@ async def test_oauth2_authorization_code_flow_refresh_token( async def test_oauth2_authorization_code_flow_refresh_token_invalid( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -504,7 +502,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -544,7 +542,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -554,7 +552,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid( async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -584,7 +582,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -597,7 +595,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp }, ) # expect Bearer token to remain the same - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -605,7 +603,7 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp async def test_expires_in_sent_as_str( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -634,7 +632,7 @@ async def test_expires_in_sent_as_str( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -644,7 +642,7 @@ async def test_expires_in_sent_as_str( async def test_nonce_is_sent_if_provided_in_authorization_url( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -673,7 +671,7 @@ async def test_nonce_is_sent_if_provided_in_authorization_url( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -683,7 +681,7 @@ async def test_nonce_is_sent_if_provided_in_authorization_url( async def test_with_invalid_grant_request_no_json( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -699,8 +697,8 @@ async def test_with_invalid_grant_request_no_json( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest, match="failure"): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="failure"): await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -710,7 +708,7 @@ async def test_with_invalid_grant_request_no_json( async def test_with_invalid_grant_request_invalid_request_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -726,8 +724,8 @@ async def test_with_invalid_grant_request_invalid_request_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -744,7 +742,7 @@ async def test_with_invalid_grant_request_invalid_request_error( async def test_with_invalid_grant_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -760,8 +758,8 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc of the error" @@ -772,7 +770,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri async def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -792,13 +790,13 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url" + == "invalid_request: desc of the error\nMore information can be found on https://test_url" ) tab.assert_success() @@ -807,7 +805,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri async def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -828,13 +826,13 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {{'other': 'other info'}}" + == "invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {'other': 'other info'}" ) tab.assert_success() @@ -843,7 +841,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri async def test_with_invalid_grant_request_without_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -859,8 +857,8 @@ async def test_with_invalid_grant_request_without_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "{'other': 'other info'}" @@ -871,7 +869,7 @@ async def test_with_invalid_grant_request_without_error( async def test_with_invalid_grant_request_invalid_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -887,8 +885,8 @@ async def test_with_invalid_grant_request_invalid_client_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -909,7 +907,7 @@ async def test_with_invalid_grant_request_invalid_client_error( async def test_with_invalid_grant_request_invalid_grant_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -925,8 +923,8 @@ async def test_with_invalid_grant_request_invalid_grant_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -943,7 +941,7 @@ async def test_with_invalid_grant_request_invalid_grant_error( async def test_with_invalid_grant_request_unauthorized_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -959,8 +957,8 @@ async def test_with_invalid_grant_request_unauthorized_client_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -975,7 +973,7 @@ async def test_with_invalid_grant_request_unauthorized_client_error( async def test_with_invalid_grant_request_unsupported_grant_type_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -991,8 +989,8 @@ async def test_with_invalid_grant_request_unsupported_grant_type_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1007,7 +1005,7 @@ async def test_with_invalid_grant_request_unsupported_grant_type_error( async def test_with_invalid_grant_request_invalid_scope_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1023,8 +1021,8 @@ async def test_with_invalid_grant_request_invalid_scope_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1039,7 +1037,7 @@ async def test_with_invalid_grant_request_invalid_scope_error( async def test_with_invalid_token_request_invalid_request_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1049,8 +1047,8 @@ async def test_with_invalid_token_request_invalid_request_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1066,7 +1064,7 @@ async def test_with_invalid_token_request_invalid_request_error( async def test_with_invalid_token_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1076,8 +1074,8 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc" @@ -1088,7 +1086,7 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri async def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1098,24 +1096,22 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_request: desc\nMore information can be found on https://test_url" ) - tab.assert_failure( - "invalid_request: desc
More information can be found on https://test_url" - ) + tab.assert_failure("invalid_request: desc
More information can be found on https://test_url") @pytest.mark.asyncio async def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1125,8 +1121,8 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url&other=test", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1142,7 +1138,7 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri async def test_with_invalid_token_request_unauthorized_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1152,8 +1148,8 @@ async def test_with_invalid_token_request_unauthorized_client_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unauthorized_client", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1169,7 +1165,7 @@ async def test_with_invalid_token_request_unauthorized_client_error( async def test_with_invalid_token_request_access_denied_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1179,8 +1175,8 @@ async def test_with_invalid_token_request_access_denied_error( reply_url=f"http://localhost:{unused_tcp_port}#error=access_denied", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1196,7 +1192,7 @@ async def test_with_invalid_token_request_access_denied_error( async def test_with_invalid_token_request_unsupported_response_type_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1206,8 +1202,8 @@ async def test_with_invalid_token_request_unsupported_response_type_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unsupported_response_type", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1223,7 +1219,7 @@ async def test_with_invalid_token_request_unsupported_response_type_error( async def test_with_invalid_token_request_invalid_scope_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1233,24 +1229,22 @@ async def test_with_invalid_token_request_invalid_scope_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_scope", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_scope: The requested scope is invalid, unknown, or malformed." ) - tab.assert_failure( - "invalid_scope: The requested scope is invalid, unknown, or malformed." - ) + tab.assert_failure("invalid_scope: The requested scope is invalid, unknown, or malformed.") @pytest.mark.asyncio async def test_with_invalid_token_request_server_error_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1260,8 +1254,8 @@ async def test_with_invalid_token_request_server_error_error( reply_url=f"http://localhost:{unused_tcp_port}#error=server_error", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1277,7 +1271,7 @@ async def test_with_invalid_token_request_server_error_error( async def test_with_invalid_token_request_temporarily_unavailable_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1287,8 +1281,8 @@ async def test_with_invalid_token_request_temporarily_unavailable_error( reply_url=f"http://localhost:{unused_tcp_port}#error=temporarily_unavailable", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1304,7 +1298,7 @@ async def test_with_invalid_token_request_temporarily_unavailable_error( async def test_response_type_can_be_provided_in_url( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?response_type=my_code", "https://provide_access_token", response_type="not_used", @@ -1334,7 +1328,7 @@ async def test_response_type_can_be_provided_in_url( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() diff --git a/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce_sync.py b/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce_sync.py index c60942d..2efefb9 100644 --- a/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce_sync.py +++ b/tests/oauth2/authorization_code_pkce/test_oauth2_authorization_code_pkce_sync.py @@ -1,19 +1,19 @@ import time -from pytest_httpx import HTTPXMock +import httpx2 import pytest -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import BrowserMock, browser_mock, token_cache -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry +from httpx2_auth.testing import BrowserMock def test_oauth2_pkce_flow_uses_provided_client( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", client=client, @@ -44,7 +44,7 @@ def test_oauth2_pkce_flow_uses_provided_client( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -53,7 +53,7 @@ def test_oauth2_pkce_flow_uses_provided_client( def test_oauth2_pkce_flow_uses_redirect_uri_domain( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_domain="localhost.mycompany.com", @@ -83,7 +83,7 @@ def test_oauth2_pkce_flow_uses_redirect_uri_domain( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -92,14 +92,12 @@ def test_oauth2_pkce_flow_uses_redirect_uri_domain( def test_oauth2_pkce_flow_uses_custom_success( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.success_html = ( - "
SUCCESS: {display_time}
" - ) + httpx2_auth.OAuth2.display.success_html = "
SUCCESS: {display_time}
" tab = browser_mock.add_response( opened_url=f"https://provide_code?response_type=code&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc&code_challenge_method=S256", reply_url=f"http://localhost:{unused_tcp_port}#code=SplxlOBeZQQYbYS6WxSbIA&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5", @@ -125,7 +123,7 @@ def test_oauth2_pkce_flow_uses_custom_success( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -134,21 +132,20 @@ def test_oauth2_pkce_flow_uses_custom_success( def test_oauth2_pkce_flow_uses_custom_failure( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" + httpx2_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" tab = browser_mock.add_response( opened_url=f"https://provide_code?response_type=code&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc&code_challenge_method=S256", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", displayed_html="FAILURE: {display_time}\n{information}", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest): - client.get("https://authorized_only", auth=auth) + with httpx2.Client() as client, pytest.raises(httpx2_auth.InvalidGrantRequest): + client.get("https://authorized_only", auth=auth) tab.assert_failure( "invalid_request: The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed." @@ -158,8 +155,8 @@ def test_oauth2_pkce_flow_uses_custom_failure( def test_oauth2_pkce_flow_is_able_to_reuse_client( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", client=client, @@ -189,7 +186,7 @@ def test_oauth2_pkce_flow_is_able_to_reuse_client( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -218,7 +215,7 @@ def test_oauth2_pkce_flow_is_able_to_reuse_client( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -227,8 +224,8 @@ def test_oauth2_pkce_flow_is_able_to_reuse_client( def test_oauth2_pkce_flow_is_able_to_reuse_client_with_token_refresh( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", client=client, @@ -260,7 +257,7 @@ def test_oauth2_pkce_flow_is_able_to_reuse_client_with_token_refresh( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -287,14 +284,14 @@ def test_oauth2_pkce_flow_is_able_to_reuse_client_with_token_refresh( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_pkce_flow_get_code_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -323,7 +320,7 @@ def test_oauth2_pkce_flow_get_code_is_sent_in_authorization_header_by_default( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -332,7 +329,7 @@ def test_oauth2_pkce_flow_get_code_is_sent_in_authorization_header_by_default( def test_oauth2_pkce_flow_get_code_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -368,7 +365,7 @@ def test_oauth2_pkce_flow_get_code_is_expired_after_30_seconds_by_default( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -377,7 +374,7 @@ def test_oauth2_pkce_flow_get_code_is_expired_after_30_seconds_by_default( def test_oauth2_pkce_flow_get_code_custom_expiry( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", early_expiry=28 ) # Add a token that expires in 29 seconds, so should be considered as not expired when issuing the request @@ -394,14 +391,14 @@ def test_oauth2_pkce_flow_get_code_custom_expiry( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_authorization_code_flow_refresh_token( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -431,7 +428,7 @@ def test_oauth2_authorization_code_flow_refresh_token( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -457,14 +454,14 @@ def test_oauth2_authorization_code_flow_refresh_token( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_authorization_code_flow_refresh_token_invalid( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -494,7 +491,7 @@ def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -534,7 +531,7 @@ def test_oauth2_authorization_code_flow_refresh_token_invalid( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -543,7 +540,7 @@ def test_oauth2_authorization_code_flow_refresh_token_invalid( def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -573,7 +570,7 @@ def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -586,14 +583,14 @@ def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired( }, ) # expect Bearer token to remain the same - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_expires_in_sent_as_str( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -622,7 +619,7 @@ def test_expires_in_sent_as_str( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -631,7 +628,7 @@ def test_expires_in_sent_as_str( def test_nonce_is_sent_if_provided_in_authorization_url( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -660,7 +657,7 @@ def test_nonce_is_sent_if_provided_in_authorization_url( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -669,7 +666,7 @@ def test_nonce_is_sent_if_provided_in_authorization_url( def test_with_invalid_grant_request_no_json( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -685,8 +682,8 @@ def test_with_invalid_grant_request_no_json( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest, match="failure"): + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="failure"): client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -695,7 +692,7 @@ def test_with_invalid_grant_request_no_json( def test_with_invalid_grant_request_invalid_request_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -711,8 +708,8 @@ def test_with_invalid_grant_request_invalid_request_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -728,7 +725,7 @@ def test_with_invalid_grant_request_invalid_request_error( def test_with_invalid_grant_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -744,8 +741,8 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc of the error" @@ -755,7 +752,7 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description( def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -775,13 +772,13 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url" + == "invalid_request: desc of the error\nMore information can be found on https://test_url" ) tab.assert_success() @@ -789,7 +786,7 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -810,13 +807,13 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {{'other': 'other info'}}" + == "invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {'other': 'other info'}" ) tab.assert_success() @@ -824,7 +821,7 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ def test_with_invalid_grant_request_without_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -840,8 +837,8 @@ def test_with_invalid_grant_request_without_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "{'other': 'other info'}" @@ -851,7 +848,7 @@ def test_with_invalid_grant_request_without_error( def test_with_invalid_grant_request_invalid_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -867,8 +864,8 @@ def test_with_invalid_grant_request_invalid_client_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -888,7 +885,7 @@ def test_with_invalid_grant_request_invalid_client_error( def test_with_invalid_grant_request_invalid_grant_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -904,8 +901,8 @@ def test_with_invalid_grant_request_invalid_grant_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -921,7 +918,7 @@ def test_with_invalid_grant_request_invalid_grant_error( def test_with_invalid_grant_request_unauthorized_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -937,8 +934,8 @@ def test_with_invalid_grant_request_unauthorized_client_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -952,7 +949,7 @@ def test_with_invalid_grant_request_unauthorized_client_error( def test_with_invalid_grant_request_unsupported_grant_type_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -968,8 +965,8 @@ def test_with_invalid_grant_request_unsupported_grant_type_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -983,7 +980,7 @@ def test_with_invalid_grant_request_unsupported_grant_type_error( def test_with_invalid_grant_request_invalid_scope_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?nonce=123456", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -999,8 +996,8 @@ def test_with_invalid_grant_request_invalid_scope_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1014,7 +1011,7 @@ def test_with_invalid_grant_request_invalid_scope_error( def test_with_invalid_token_request_invalid_request_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1024,8 +1021,8 @@ def test_with_invalid_token_request_invalid_request_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1040,7 +1037,7 @@ def test_with_invalid_token_request_invalid_request_error( def test_with_invalid_token_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1050,8 +1047,8 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc" @@ -1061,7 +1058,7 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description( def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1071,23 +1068,21 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description_ reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_request: desc\nMore information can be found on https://test_url" ) - tab.assert_failure( - "invalid_request: desc
More information can be found on https://test_url" - ) + tab.assert_failure("invalid_request: desc
More information can be found on https://test_url") def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1097,8 +1092,8 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description_ reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url&other=test", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1113,7 +1108,7 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description_ def test_with_invalid_token_request_unauthorized_client_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1123,8 +1118,8 @@ def test_with_invalid_token_request_unauthorized_client_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unauthorized_client", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1139,7 +1134,7 @@ def test_with_invalid_token_request_unauthorized_client_error( def test_with_invalid_token_request_access_denied_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1149,8 +1144,8 @@ def test_with_invalid_token_request_access_denied_error( reply_url=f"http://localhost:{unused_tcp_port}#error=access_denied", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1165,7 +1160,7 @@ def test_with_invalid_token_request_access_denied_error( def test_with_invalid_token_request_unsupported_response_type_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1175,8 +1170,8 @@ def test_with_invalid_token_request_unsupported_response_type_error( reply_url=f"http://localhost:{unused_tcp_port}#error=unsupported_response_type", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1191,7 +1186,7 @@ def test_with_invalid_token_request_unsupported_response_type_error( def test_with_invalid_token_request_invalid_scope_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1201,23 +1196,21 @@ def test_with_invalid_token_request_invalid_scope_error( reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_scope", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_scope: The requested scope is invalid, unknown, or malformed." ) - tab.assert_failure( - "invalid_scope: The requested scope is invalid, unknown, or malformed." - ) + tab.assert_failure("invalid_scope: The requested scope is invalid, unknown, or malformed.") def test_with_invalid_token_request_server_error_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1227,8 +1220,8 @@ def test_with_invalid_token_request_server_error_error( reply_url=f"http://localhost:{unused_tcp_port}#error=server_error", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1243,7 +1236,7 @@ def test_with_invalid_token_request_server_error_error( def test_with_invalid_token_request_temporarily_unavailable_error( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code", "https://provide_access_token", redirect_uri_port=unused_tcp_port, @@ -1253,8 +1246,8 @@ def test_with_invalid_token_request_temporarily_unavailable_error( reply_url=f"http://localhost:{unused_tcp_port}#error=temporarily_unavailable", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1269,7 +1262,7 @@ def test_with_invalid_token_request_temporarily_unavailable_error( def test_response_type_can_be_provided_in_url( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2AuthorizationCodePKCE( + auth = httpx2_auth.OAuth2AuthorizationCodePKCE( "https://provide_code?response_type=my_code", "https://provide_access_token", response_type="not_used", @@ -1300,7 +1293,7 @@ def test_response_type_can_be_provided_in_url( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() diff --git a/tests/oauth2/client_credential/__init__.py b/tests/oauth2/client_credential/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/oauth2/client_credential/okta/__init__.py b/tests/oauth2/client_credential/okta/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/oauth2/client_credential/okta/test_oauth2_client_credential_okta.py b/tests/oauth2/client_credential/okta/test_oauth2_client_credential_okta.py index b9b2083..da3845b 100644 --- a/tests/oauth2/client_credential/okta/test_oauth2_client_credential_okta.py +++ b/tests/oauth2/client_credential/okta/test_oauth2_client_credential_okta.py @@ -1,35 +1,35 @@ import pytest -import httpx_auth +import httpx2_auth def test_scope_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OktaClientCredentials("test_url", "test_user", "test_pwd", scope="") + httpx2_auth.OktaClientCredentials("test_url", "test_user", "test_pwd", scope="") assert str(exception_info.value) == "scope is mandatory." def test_instance_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OktaClientCredentials("", "test_user", "test_pwd", scope="dummy") + httpx2_auth.OktaClientCredentials("", "test_user", "test_pwd", scope="dummy") assert str(exception_info.value) == "Okta instance is mandatory." def test_client_id_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OktaClientCredentials("test_url", "", "test_pwd", scope="dummy") + httpx2_auth.OktaClientCredentials("test_url", "", "test_pwd", scope="dummy") assert str(exception_info.value) == "client_id is mandatory." def test_client_secret_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OktaClientCredentials("test_url", "test_user", "", scope="dummy") + httpx2_auth.OktaClientCredentials("test_url", "test_user", "", scope="dummy") assert str(exception_info.value) == "client_secret is mandatory." def test_header_value_must_contains_token(): with pytest.raises(Exception) as exception_info: - httpx_auth.OktaClientCredentials( + httpx2_auth.OktaClientCredentials( "test_url", "test_user", "test_pwd", diff --git a/tests/oauth2/client_credential/okta/test_oauth2_client_credential_okta_async.py b/tests/oauth2/client_credential/okta/test_oauth2_client_credential_okta_async.py index a2feed2..24f9538 100644 --- a/tests/oauth2/client_credential/okta/test_oauth2_client_credential_okta_async.py +++ b/tests/oauth2/client_credential/okta/test_oauth2_client_credential_okta_async.py @@ -1,10 +1,9 @@ +import httpx2 import pytest -from pytest_httpx import HTTPXMock -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import token_cache -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry @pytest.mark.asyncio @@ -12,8 +11,8 @@ async def test_okta_client_credentials_flow_uses_provided_client( token_cache, httpx_mock: HTTPXMock ): # TODO Add support for AsyncClient - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OktaClientCredentials( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OktaClientCredentials( "test_okta", client_id="test_user", client_secret="test_pwd", @@ -41,7 +40,7 @@ async def test_okta_client_credentials_flow_uses_provided_client( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -49,7 +48,7 @@ async def test_okta_client_credentials_flow_uses_provided_client( async def test_okta_client_credentials_flow_token_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaClientCredentials( + auth = httpx2_auth.OktaClientCredentials( "test_okta", client_id="test_user", client_secret="test_pwd", scope="dummy" ) httpx_mock.add_response( @@ -72,7 +71,7 @@ async def test_okta_client_credentials_flow_token_is_sent_in_authorization_heade }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -80,12 +79,12 @@ async def test_okta_client_credentials_flow_token_is_sent_in_authorization_heade async def test_okta_client_credentials_flow_token_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaClientCredentials( + auth = httpx2_auth.OktaClientCredentials( "test_okta", client_id="test_user", client_secret="test_pwd", scope="dummy" ) # Add a token that expires in 29 seconds, so should be considered as expired when issuing the request token_cache._add_token( - key="73cb07a6e48774ad335f5bae75e036d1df813a3c44ae186895eb6f956b9993ed83590871dddefbc2310b863cda3f414161bc7fcd4c4e5fefa582cba4f7de7ace", + key="18889021f8cfa6b3874b3add7c3961b09d78d9afd2eb4c33343959c786a5cad375928fbcbe2f048935a697e2c2cbf3636d4f476b531bf1ec6f239809caaf892c", token="2YotnFZFEjr1zCsicMWpAA", expiry=to_expiry(expires_in=29), ) @@ -110,15 +109,13 @@ async def test_okta_client_credentials_flow_token_is_expired_after_30_seconds_by }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio -async def test_okta_client_credentials_flow_token_custom_expiry( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaClientCredentials( +async def test_okta_client_credentials_flow_token_custom_expiry(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaClientCredentials( "test_okta", client_id="test_user", client_secret="test_pwd", @@ -127,7 +124,7 @@ async def test_okta_client_credentials_flow_token_custom_expiry( ) # Add a token that expires in 29 seconds, so should be considered as not expired when issuing the request token_cache._add_token( - key="73cb07a6e48774ad335f5bae75e036d1df813a3c44ae186895eb6f956b9993ed83590871dddefbc2310b863cda3f414161bc7fcd4c4e5fefa582cba4f7de7ace", + key="18889021f8cfa6b3874b3add7c3961b09d78d9afd2eb4c33343959c786a5cad375928fbcbe2f048935a697e2c2cbf3636d4f476b531bf1ec6f239809caaf892c", token="2YotnFZFEjr1zCsicMWpAA", expiry=to_expiry(expires_in=29), ) @@ -139,13 +136,13 @@ async def test_okta_client_credentials_flow_token_custom_expiry( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio async def test_expires_in_sent_as_str(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OktaClientCredentials( + auth = httpx2_auth.OktaClientCredentials( "test_okta", client_id="test_user", client_secret="test_pwd", scope="dummy" ) httpx_mock.add_response( @@ -168,7 +165,7 @@ async def test_expires_in_sent_as_str(token_cache, httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -190,10 +187,10 @@ async def test_handle_credentials_as_part_of_cache_key( client_id2, client_secret2, ): - auth1 = httpx_auth.OktaClientCredentials( + auth1 = httpx2_auth.OktaClientCredentials( "test_okta", client_id=client_id1, client_secret=client_secret1, scope="dummy" ) - auth2 = httpx_auth.OktaClientCredentials( + auth2 = httpx2_auth.OktaClientCredentials( "test_okta", client_id=client_id2, client_secret=client_secret2, scope="dummy" ) httpx_mock.add_response( @@ -216,7 +213,7 @@ async def test_handle_credentials_as_part_of_cache_key( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth1) httpx_mock.add_response( @@ -240,7 +237,7 @@ async def test_handle_credentials_as_part_of_cache_key( ) # This should request a new token (different credentials) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth2) httpx_mock.add_response( @@ -258,6 +255,6 @@ async def test_handle_credentials_as_part_of_cache_key( }, ) # Ensure the proper token is fetched - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth1) await client.get("https://authorized_only", auth=auth2) diff --git a/tests/oauth2/client_credential/okta/test_oauth2_client_credential_okta_sync.py b/tests/oauth2/client_credential/okta/test_oauth2_client_credential_okta_sync.py index eed2ee5..04b1b99 100644 --- a/tests/oauth2/client_credential/okta/test_oauth2_client_credential_okta_sync.py +++ b/tests/oauth2/client_credential/okta/test_oauth2_client_credential_okta_sync.py @@ -1,17 +1,14 @@ +import httpx2 import pytest -from pytest_httpx import HTTPXMock -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import token_cache -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry -def test_okta_client_credentials_flow_uses_provided_client( - token_cache, httpx_mock: HTTPXMock -): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OktaClientCredentials( +def test_okta_client_credentials_flow_uses_provided_client(token_cache, httpx_mock: HTTPXMock): + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OktaClientCredentials( "test_okta", client_id="test_user", client_secret="test_pwd", @@ -39,14 +36,14 @@ def test_okta_client_credentials_flow_uses_provided_client( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_okta_client_credentials_flow_token_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaClientCredentials( + auth = httpx2_auth.OktaClientCredentials( "test_okta", client_id="test_user", client_secret="test_pwd", scope="dummy" ) httpx_mock.add_response( @@ -69,19 +66,19 @@ def test_okta_client_credentials_flow_token_is_sent_in_authorization_header_by_d }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_okta_client_credentials_flow_token_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaClientCredentials( + auth = httpx2_auth.OktaClientCredentials( "test_okta", client_id="test_user", client_secret="test_pwd", scope="dummy" ) # Add a token that expires in 29 seconds, so should be considered as expired when issuing the request token_cache._add_token( - key="73cb07a6e48774ad335f5bae75e036d1df813a3c44ae186895eb6f956b9993ed83590871dddefbc2310b863cda3f414161bc7fcd4c4e5fefa582cba4f7de7ace", + key="18889021f8cfa6b3874b3add7c3961b09d78d9afd2eb4c33343959c786a5cad375928fbcbe2f048935a697e2c2cbf3636d4f476b531bf1ec6f239809caaf892c", token="2YotnFZFEjr1zCsicMWpAA", expiry=to_expiry(expires_in=29), ) @@ -106,14 +103,12 @@ def test_okta_client_credentials_flow_token_is_expired_after_30_seconds_by_defau }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) -def test_okta_client_credentials_flow_token_custom_expiry( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaClientCredentials( +def test_okta_client_credentials_flow_token_custom_expiry(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaClientCredentials( "test_okta", client_id="test_user", client_secret="test_pwd", @@ -122,7 +117,7 @@ def test_okta_client_credentials_flow_token_custom_expiry( ) # Add a token that expires in 29 seconds, so should be considered as not expired when issuing the request token_cache._add_token( - key="73cb07a6e48774ad335f5bae75e036d1df813a3c44ae186895eb6f956b9993ed83590871dddefbc2310b863cda3f414161bc7fcd4c4e5fefa582cba4f7de7ace", + key="18889021f8cfa6b3874b3add7c3961b09d78d9afd2eb4c33343959c786a5cad375928fbcbe2f048935a697e2c2cbf3636d4f476b531bf1ec6f239809caaf892c", token="2YotnFZFEjr1zCsicMWpAA", expiry=to_expiry(expires_in=29), ) @@ -134,12 +129,12 @@ def test_okta_client_credentials_flow_token_custom_expiry( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_expires_in_sent_as_str(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OktaClientCredentials( + auth = httpx2_auth.OktaClientCredentials( "test_okta", client_id="test_user", client_secret="test_pwd", scope="dummy" ) httpx_mock.add_response( @@ -162,7 +157,7 @@ def test_expires_in_sent_as_str(token_cache, httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) @@ -183,10 +178,10 @@ def test_handle_credentials_as_part_of_cache_key( client_id2, client_secret2, ): - auth1 = httpx_auth.OktaClientCredentials( + auth1 = httpx2_auth.OktaClientCredentials( "test_okta", client_id=client_id1, client_secret=client_secret1, scope="dummy" ) - auth2 = httpx_auth.OktaClientCredentials( + auth2 = httpx2_auth.OktaClientCredentials( "test_okta", client_id=client_id2, client_secret=client_secret2, scope="dummy" ) httpx_mock.add_response( @@ -209,7 +204,7 @@ def test_handle_credentials_as_part_of_cache_key( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth1) httpx_mock.add_response( @@ -233,7 +228,7 @@ def test_handle_credentials_as_part_of_cache_key( ) # This should request a new token (different credentials) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth2) httpx_mock.add_response( @@ -251,6 +246,6 @@ def test_handle_credentials_as_part_of_cache_key( }, ) # Ensure the proper token is fetched - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth1) client.get("https://authorized_only", auth=auth2) diff --git a/tests/oauth2/client_credential/test_oauth2_client_credential.py b/tests/oauth2/client_credential/test_oauth2_client_credential.py index d84ea0a..6edbea2 100644 --- a/tests/oauth2/client_credential/test_oauth2_client_credential.py +++ b/tests/oauth2/client_credential/test_oauth2_client_credential.py @@ -1,29 +1,29 @@ import pytest -import httpx_auth +import httpx2_auth def test_token_url_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OAuth2ClientCredentials("", "test_user", "test_pwd") + httpx2_auth.OAuth2ClientCredentials("", "test_user", "test_pwd") assert str(exception_info.value) == "Token URL is mandatory." def test_client_id_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OAuth2ClientCredentials("https://test_url", "", "test_pwd") + httpx2_auth.OAuth2ClientCredentials("https://test_url", "", "test_pwd") assert str(exception_info.value) == "client_id is mandatory." def test_client_secret_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OAuth2ClientCredentials("https://test_url", "test_user", "") + httpx2_auth.OAuth2ClientCredentials("https://test_url", "test_user", "") assert str(exception_info.value) == "client_secret is mandatory." def test_header_value_must_contains_token(): with pytest.raises(Exception) as exception_info: - httpx_auth.OAuth2ClientCredentials( + httpx2_auth.OAuth2ClientCredentials( "https://test_url", "test_user", "test_pwd", header_value="Bearer token" ) assert str(exception_info.value) == "header_value parameter must contains {token}." diff --git a/tests/oauth2/client_credential/test_oauth2_client_credential_async.py b/tests/oauth2/client_credential/test_oauth2_client_credential_async.py index 29c2519..83ae942 100644 --- a/tests/oauth2/client_credential/test_oauth2_client_credential_async.py +++ b/tests/oauth2/client_credential/test_oauth2_client_credential_async.py @@ -1,12 +1,11 @@ import time -from pytest_httpx import HTTPXMock +import httpx2 import pytest -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import token_cache -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry @pytest.mark.asyncio @@ -14,8 +13,8 @@ async def test_oauth2_client_credentials_flow_uses_provided_client( token_cache, httpx_mock: HTTPXMock ): # TODO Add support for AsyncClient - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2ClientCredentials( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd", @@ -42,7 +41,7 @@ async def test_oauth2_client_credentials_flow_uses_provided_client( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -51,8 +50,8 @@ async def test_oauth2_client_credentials_flow_is_able_to_reuse_client( token_cache, httpx_mock: HTTPXMock ): # TODO Add support for AsyncClient - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2ClientCredentials( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd", @@ -79,7 +78,7 @@ async def test_oauth2_client_credentials_flow_is_able_to_reuse_client( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) time.sleep(2) @@ -104,7 +103,7 @@ async def test_oauth2_client_credentials_flow_is_able_to_reuse_client( "Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA", }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -112,7 +111,7 @@ async def test_oauth2_client_credentials_flow_is_able_to_reuse_client( async def test_oauth2_client_credentials_flow_token_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -135,7 +134,7 @@ async def test_oauth2_client_credentials_flow_token_is_sent_in_authorization_hea }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -143,12 +142,12 @@ async def test_oauth2_client_credentials_flow_token_is_sent_in_authorization_hea async def test_oauth2_client_credentials_flow_token_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) # Add a token that expires in 29 seconds, so should be considered as expired when issuing the request token_cache._add_token( - key="fcd9be12271843a292d3c87c6051ea3dd54ee66d4938d15ebda9c7492d51fe555064fa9f787d0fb207a76558ae33e57ac11cb7aee668d665db9c6c1d60c5c314", + key="e0862ac4c79bf9398d4317129bbfd069bbb7408e5cb92cfa0f80b4219fd259ee259179d28862a9c7fa24d1d5cd18abeca31b580e6d37d9102b98d314b480c0d3", token="2YotnFZFEjr1zCsicMWpAA", expiry=to_expiry(expires_in=29), ) @@ -173,7 +172,7 @@ async def test_oauth2_client_credentials_flow_token_is_expired_after_30_seconds_ }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -181,7 +180,7 @@ async def test_oauth2_client_credentials_flow_token_is_expired_after_30_seconds_ async def test_oauth2_client_credentials_flow_token_custom_expiry( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd", @@ -189,7 +188,7 @@ async def test_oauth2_client_credentials_flow_token_custom_expiry( ) # Add a token that expires in 29 seconds, so should be considered as not expired when issuing the request token_cache._add_token( - key="fcd9be12271843a292d3c87c6051ea3dd54ee66d4938d15ebda9c7492d51fe555064fa9f787d0fb207a76558ae33e57ac11cb7aee668d665db9c6c1d60c5c314", + key="e0862ac4c79bf9398d4317129bbfd069bbb7408e5cb92cfa0f80b4219fd259ee259179d28862a9c7fa24d1d5cd18abeca31b580e6d37d9102b98d314b480c0d3", token="2YotnFZFEjr1zCsicMWpAA", expiry=to_expiry(expires_in=29), ) @@ -201,13 +200,13 @@ async def test_oauth2_client_credentials_flow_token_custom_expiry( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio async def test_expires_in_sent_as_str(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -230,13 +229,13 @@ async def test_expires_in_sent_as_str(token_cache, httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio async def test_with_invalid_grant_request_no_json(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -246,16 +245,14 @@ async def test_with_invalid_grant_request_no_json(token_cache, httpx_mock: HTTPX status_code=400, match_content=b"grant_type=client_credentials", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest, match="failure"): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="failure"): await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio -async def test_with_invalid_grant_request_invalid_request_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ClientCredentials( +async def test_with_invalid_grant_request_invalid_request_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -266,8 +263,8 @@ async def test_with_invalid_grant_request_invalid_request_error( match_content=b"grant_type=client_credentials", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -283,7 +280,7 @@ async def test_with_invalid_grant_request_invalid_request_error( async def test_with_invalid_grant_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -294,8 +291,8 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri match_content=b"grant_type=client_credentials", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc of the error" @@ -305,7 +302,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri async def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -320,13 +317,13 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri match_content=b"grant_type=client_credentials", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url" + == "invalid_request: desc of the error\nMore information can be found on https://test_url" ) @@ -334,7 +331,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri async def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -350,21 +347,19 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri match_content=b"grant_type=client_credentials", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {{'other': 'other info'}}" + == "invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {'other': 'other info'}" ) @pytest.mark.asyncio -async def test_with_invalid_grant_request_without_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ClientCredentials( +async def test_with_invalid_grant_request_without_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -375,18 +370,16 @@ async def test_with_invalid_grant_request_without_error( match_content=b"grant_type=client_credentials", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "{'other': 'other info'}" @pytest.mark.asyncio -async def test_with_invalid_grant_request_invalid_client_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ClientCredentials( +async def test_with_invalid_grant_request_invalid_client_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -397,8 +390,8 @@ async def test_with_invalid_grant_request_invalid_client_error( match_content=b"grant_type=client_credentials", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -415,10 +408,8 @@ async def test_with_invalid_grant_request_invalid_client_error( @pytest.mark.asyncio -async def test_with_invalid_grant_request_invalid_grant_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ClientCredentials( +async def test_with_invalid_grant_request_invalid_grant_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -429,8 +420,8 @@ async def test_with_invalid_grant_request_invalid_grant_error( match_content=b"grant_type=client_credentials", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -446,7 +437,7 @@ async def test_with_invalid_grant_request_invalid_grant_error( async def test_with_invalid_grant_request_unauthorized_client_error( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -457,8 +448,8 @@ async def test_with_invalid_grant_request_unauthorized_client_error( match_content=b"grant_type=client_credentials", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -472,7 +463,7 @@ async def test_with_invalid_grant_request_unauthorized_client_error( async def test_with_invalid_grant_request_unsupported_grant_type_error( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -483,8 +474,8 @@ async def test_with_invalid_grant_request_unsupported_grant_type_error( match_content=b"grant_type=client_credentials", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -495,10 +486,8 @@ async def test_with_invalid_grant_request_unsupported_grant_type_error( @pytest.mark.asyncio -async def test_with_invalid_grant_request_invalid_scope_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ClientCredentials( +async def test_with_invalid_grant_request_invalid_scope_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -509,8 +498,8 @@ async def test_with_invalid_grant_request_invalid_scope_error( match_content=b"grant_type=client_credentials", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -538,12 +527,12 @@ async def test_oauth2_client_credentials_flow_handle_credentials_as_part_of_cach client_id2, client_secret2, ): - auth1 = httpx_auth.OAuth2ClientCredentials( + auth1 = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id=client_id1, client_secret=client_secret1, ) - auth2 = httpx_auth.OAuth2ClientCredentials( + auth2 = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id=client_id2, client_secret=client_secret2, @@ -568,7 +557,7 @@ async def test_oauth2_client_credentials_flow_handle_credentials_as_part_of_cach }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth1) httpx_mock.add_response( @@ -592,7 +581,7 @@ async def test_oauth2_client_credentials_flow_handle_credentials_as_part_of_cach ) # This should request a new token (different credentials) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth2) httpx_mock.add_response( @@ -610,6 +599,6 @@ async def test_oauth2_client_credentials_flow_handle_credentials_as_part_of_cach }, ) # Ensure the proper token is fetched - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth1) await client.get("https://authorized_only", auth=auth2) diff --git a/tests/oauth2/client_credential/test_oauth2_client_credential_sync.py b/tests/oauth2/client_credential/test_oauth2_client_credential_sync.py index 805b486..342cb5e 100644 --- a/tests/oauth2/client_credential/test_oauth2_client_credential_sync.py +++ b/tests/oauth2/client_credential/test_oauth2_client_credential_sync.py @@ -1,19 +1,16 @@ import time -from pytest_httpx import HTTPXMock +import httpx2 import pytest -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import token_cache -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry -def test_oauth2_client_credentials_flow_uses_provided_client( - token_cache, httpx_mock: HTTPXMock -): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2ClientCredentials( +def test_oauth2_client_credentials_flow_uses_provided_client(token_cache, httpx_mock: HTTPXMock): + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd", @@ -40,15 +37,13 @@ def test_oauth2_client_credentials_flow_uses_provided_client( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) -def test_oauth2_client_credentials_flow_is_able_to_reuse_client( - token_cache, httpx_mock: HTTPXMock -): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2ClientCredentials( +def test_oauth2_client_credentials_flow_is_able_to_reuse_client(token_cache, httpx_mock: HTTPXMock): + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd", @@ -75,7 +70,7 @@ def test_oauth2_client_credentials_flow_is_able_to_reuse_client( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) time.sleep(2) @@ -100,14 +95,14 @@ def test_oauth2_client_credentials_flow_is_able_to_reuse_client( "Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA", }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_client_credentials_flow_token_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -130,19 +125,19 @@ def test_oauth2_client_credentials_flow_token_is_sent_in_authorization_header_by }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_client_credentials_flow_token_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) # Add a token that expires in 29 seconds, so should be considered as expired when issuing the request token_cache._add_token( - key="fcd9be12271843a292d3c87c6051ea3dd54ee66d4938d15ebda9c7492d51fe555064fa9f787d0fb207a76558ae33e57ac11cb7aee668d665db9c6c1d60c5c314", + key="e0862ac4c79bf9398d4317129bbfd069bbb7408e5cb92cfa0f80b4219fd259ee259179d28862a9c7fa24d1d5cd18abeca31b580e6d37d9102b98d314b480c0d3", token="2YotnFZFEjr1zCsicMWpAA", expiry=to_expiry(expires_in=29), ) @@ -167,14 +162,12 @@ def test_oauth2_client_credentials_flow_token_is_expired_after_30_seconds_by_def }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) -def test_oauth2_client_credentials_flow_token_custom_expiry( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ClientCredentials( +def test_oauth2_client_credentials_flow_token_custom_expiry(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd", @@ -182,7 +175,7 @@ def test_oauth2_client_credentials_flow_token_custom_expiry( ) # Add a token that expires in 29 seconds, so should be considered as not expired when issuing the request token_cache._add_token( - key="fcd9be12271843a292d3c87c6051ea3dd54ee66d4938d15ebda9c7492d51fe555064fa9f787d0fb207a76558ae33e57ac11cb7aee668d665db9c6c1d60c5c314", + key="e0862ac4c79bf9398d4317129bbfd069bbb7408e5cb92cfa0f80b4219fd259ee259179d28862a9c7fa24d1d5cd18abeca31b580e6d37d9102b98d314b480c0d3", token="2YotnFZFEjr1zCsicMWpAA", expiry=to_expiry(expires_in=29), ) @@ -194,12 +187,12 @@ def test_oauth2_client_credentials_flow_token_custom_expiry( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_expires_in_sent_as_str(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -222,12 +215,12 @@ def test_expires_in_sent_as_str(token_cache, httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_with_invalid_grant_request_no_json(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -237,15 +230,13 @@ def test_with_invalid_grant_request_no_json(token_cache, httpx_mock: HTTPXMock): status_code=400, match_content=b"grant_type=client_credentials", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest, match="failure"): + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="failure"): client.get("https://authorized_only", auth=auth) -def test_with_invalid_grant_request_invalid_request_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ClientCredentials( +def test_with_invalid_grant_request_invalid_request_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -256,8 +247,8 @@ def test_with_invalid_grant_request_invalid_request_error( match_content=b"grant_type=client_credentials", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -272,7 +263,7 @@ def test_with_invalid_grant_request_invalid_request_error( def test_with_invalid_grant_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -283,8 +274,8 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description( match_content=b"grant_type=client_credentials", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc of the error" @@ -293,7 +284,7 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description( def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -308,20 +299,20 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ match_content=b"grant_type=client_credentials", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url" + == "invalid_request: desc of the error\nMore information can be found on https://test_url" ) def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -337,18 +328,18 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ match_content=b"grant_type=client_credentials", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {{'other': 'other info'}}" + == "invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {'other': 'other info'}" ) def test_with_invalid_grant_request_without_error(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -359,17 +350,15 @@ def test_with_invalid_grant_request_without_error(token_cache, httpx_mock: HTTPX match_content=b"grant_type=client_credentials", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "{'other': 'other info'}" -def test_with_invalid_grant_request_invalid_client_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ClientCredentials( +def test_with_invalid_grant_request_invalid_client_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -380,8 +369,8 @@ def test_with_invalid_grant_request_invalid_client_error( match_content=b"grant_type=client_credentials", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -397,10 +386,8 @@ def test_with_invalid_grant_request_invalid_client_error( ) -def test_with_invalid_grant_request_invalid_grant_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ClientCredentials( +def test_with_invalid_grant_request_invalid_grant_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -411,8 +398,8 @@ def test_with_invalid_grant_request_invalid_grant_error( match_content=b"grant_type=client_credentials", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -424,10 +411,8 @@ def test_with_invalid_grant_request_invalid_grant_error( ) -def test_with_invalid_grant_request_unauthorized_client_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ClientCredentials( +def test_with_invalid_grant_request_unauthorized_client_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -438,8 +423,8 @@ def test_with_invalid_grant_request_unauthorized_client_error( match_content=b"grant_type=client_credentials", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -452,7 +437,7 @@ def test_with_invalid_grant_request_unauthorized_client_error( def test_with_invalid_grant_request_unsupported_grant_type_error( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ClientCredentials( + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -463,8 +448,8 @@ def test_with_invalid_grant_request_unsupported_grant_type_error( match_content=b"grant_type=client_credentials", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -474,10 +459,8 @@ def test_with_invalid_grant_request_unsupported_grant_type_error( ) -def test_with_invalid_grant_request_invalid_scope_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ClientCredentials( +def test_with_invalid_grant_request_invalid_scope_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id="test_user", client_secret="test_pwd" ) httpx_mock.add_response( @@ -488,8 +471,8 @@ def test_with_invalid_grant_request_invalid_scope_error( match_content=b"grant_type=client_credentials", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -516,12 +499,12 @@ def test_oauth2_client_credentials_flow_handle_credentials_as_part_of_cache_key( client_id2, client_secret2, ): - auth1 = httpx_auth.OAuth2ClientCredentials( + auth1 = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id=client_id1, client_secret=client_secret1, ) - auth2 = httpx_auth.OAuth2ClientCredentials( + auth2 = httpx2_auth.OAuth2ClientCredentials( "https://provide_access_token", client_id=client_id2, client_secret=client_secret2, @@ -546,7 +529,7 @@ def test_oauth2_client_credentials_flow_handle_credentials_as_part_of_cache_key( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth1) httpx_mock.add_response( @@ -570,7 +553,7 @@ def test_oauth2_client_credentials_flow_handle_credentials_as_part_of_cache_key( ) # This should request a new token (different credentials) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth2) httpx_mock.add_response( @@ -588,6 +571,6 @@ def test_oauth2_client_credentials_flow_handle_credentials_as_part_of_cache_key( }, ) # Ensure the proper token is fetched - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth1) client.get("https://authorized_only", auth=auth2) diff --git a/tests/oauth2/implicit/__init__.py b/tests/oauth2/implicit/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/oauth2/implicit/azure_ad/__init__.py b/tests/oauth2/implicit/azure_ad/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/oauth2/implicit/azure_ad/test_oauth2_implicit_azure_active_directory.py b/tests/oauth2/implicit/azure_ad/test_oauth2_implicit_azure_active_directory.py index 53b41fd..c3b936b 100644 --- a/tests/oauth2/implicit/azure_ad/test_oauth2_implicit_azure_active_directory.py +++ b/tests/oauth2/implicit/azure_ad/test_oauth2_implicit_azure_active_directory.py @@ -1,14 +1,14 @@ -import httpx_auth -import httpx_auth._oauth2.implicit +import httpx2_auth +import httpx2_auth._oauth2.implicit def test_corresponding_oauth2_implicit_flow_instance(monkeypatch): monkeypatch.setattr( - httpx_auth._oauth2.implicit.uuid, + httpx2_auth._oauth2.implicit.uuid, "uuid4", lambda *args: "27ddfeed4e-854b-4361-8e7a-eab371c9bc91", ) - aad = httpx_auth.AzureActiveDirectoryImplicit( + aad = httpx2_auth.AzureActiveDirectoryImplicit( "45239d18-c68c-4c47-8bdd-ce71ea1d50cd", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) assert ( diff --git a/tests/oauth2/implicit/azure_ad/test_oauth2_implicit_id_token_azure_active_directory.py b/tests/oauth2/implicit/azure_ad/test_oauth2_implicit_id_token_azure_active_directory.py index 992e858..b2afc9f 100644 --- a/tests/oauth2/implicit/azure_ad/test_oauth2_implicit_id_token_azure_active_directory.py +++ b/tests/oauth2/implicit/azure_ad/test_oauth2_implicit_id_token_azure_active_directory.py @@ -1,14 +1,14 @@ -import httpx_auth -import httpx_auth._oauth2.implicit +import httpx2_auth +import httpx2_auth._oauth2.implicit def test_corresponding_oauth2_implicit_flow_id_token_instance(monkeypatch): monkeypatch.setattr( - httpx_auth._oauth2.implicit.uuid, + httpx2_auth._oauth2.implicit.uuid, "uuid4", lambda *args: "27ddfeed4e-854b-4361-8e7a-eab371c9bc91", ) - aad = httpx_auth.AzureActiveDirectoryImplicitIdToken( + aad = httpx2_auth.AzureActiveDirectoryImplicitIdToken( "45239d18-c68c-4c47-8bdd-ce71ea1d50cd", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) assert ( diff --git a/tests/oauth2/implicit/okta/__init__.py b/tests/oauth2/implicit/okta/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/oauth2/implicit/okta/test_oauth2_implicit_id_token_okta.py b/tests/oauth2/implicit/okta/test_oauth2_implicit_id_token_okta.py index 3969977..8bcde04 100644 --- a/tests/oauth2/implicit/okta/test_oauth2_implicit_id_token_okta.py +++ b/tests/oauth2/implicit/okta/test_oauth2_implicit_id_token_okta.py @@ -1,19 +1,18 @@ -import httpx_auth -import httpx_auth._oauth2.implicit +import httpx2_auth +import httpx2_auth._oauth2.implicit def test_corresponding_oauth2_implicit_flow_id_token_instance(monkeypatch): monkeypatch.setattr( - httpx_auth._oauth2.implicit.uuid, + httpx2_auth._oauth2.implicit.uuid, "uuid4", lambda *args: "27ddfeed4e-854b-4361-8e7a-eab371c9bc91", ) - okta = httpx_auth.OktaImplicitIdToken( + okta = httpx2_auth.OktaImplicitIdToken( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) assert ( - okta.grant_details.url - == "https://testserver.okta-emea.com/oauth2/default/v1/authorize?" + okta.grant_details.url == "https://testserver.okta-emea.com/oauth2/default/v1/authorize?" "client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd" "&response_type=id_token" "&scope=openid+profile+email" @@ -21,8 +20,5 @@ def test_corresponding_oauth2_implicit_flow_id_token_instance(monkeypatch): "&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F" "&nonce=%5B%2727ddfeed4e-854b-4361-8e7a-eab371c9bc91%27%5D" ) - assert ( - okta.authorization_url - == "https://testserver.okta-emea.com/oauth2/default/v1/authorize" - ) + assert okta.authorization_url == "https://testserver.okta-emea.com/oauth2/default/v1/authorize" assert okta.grant_details.name == "id_token" diff --git a/tests/oauth2/implicit/okta/test_oauth2_implicit_okta.py b/tests/oauth2/implicit/okta/test_oauth2_implicit_okta.py index 10ea287..808eed1 100644 --- a/tests/oauth2/implicit/okta/test_oauth2_implicit_okta.py +++ b/tests/oauth2/implicit/okta/test_oauth2_implicit_okta.py @@ -1,19 +1,18 @@ -import httpx_auth -import httpx_auth._oauth2.implicit +import httpx2_auth +import httpx2_auth._oauth2.implicit def test_corresponding_oauth2_implicit_flow_instance(monkeypatch): monkeypatch.setattr( - httpx_auth._oauth2.implicit.uuid, + httpx2_auth._oauth2.implicit.uuid, "uuid4", lambda *args: "27ddfeed4e-854b-4361-8e7a-eab371c9bc91", ) - okta = httpx_auth.OktaImplicit( + okta = httpx2_auth.OktaImplicit( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd" ) assert ( - okta.grant_details.url - == "https://testserver.okta-emea.com/oauth2/default/v1/authorize?" + okta.grant_details.url == "https://testserver.okta-emea.com/oauth2/default/v1/authorize?" "client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd" "&scope=openid+profile+email" "&response_type=token" @@ -21,8 +20,5 @@ def test_corresponding_oauth2_implicit_flow_instance(monkeypatch): "&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F" "&nonce=%5B%2727ddfeed4e-854b-4361-8e7a-eab371c9bc91%27%5D" ) - assert ( - okta.authorization_url - == "https://testserver.okta-emea.com/oauth2/default/v1/authorize" - ) + assert okta.authorization_url == "https://testserver.okta-emea.com/oauth2/default/v1/authorize" assert okta.grant_details.name == "access_token" diff --git a/tests/oauth2/implicit/test_oauth2_implicit.py b/tests/oauth2/implicit/test_oauth2_implicit.py index 03710be..ef1c7c2 100644 --- a/tests/oauth2/implicit/test_oauth2_implicit.py +++ b/tests/oauth2/implicit/test_oauth2_implicit.py @@ -1,15 +1,15 @@ import pytest -import httpx_auth +import httpx2_auth def test_oauth2_implicit_flow_url_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OAuth2Implicit(None) + httpx2_auth.OAuth2Implicit(None) assert str(exception_info.value) == "Authorization URL is mandatory." def test_header_value_must_contains_token(): with pytest.raises(Exception) as exception_info: - httpx_auth.OAuth2Implicit("https://test_url", header_value="Bearer token") + httpx2_auth.OAuth2Implicit("https://test_url", header_value="Bearer token") assert str(exception_info.value) == "header_value parameter must contains {token}." diff --git a/tests/oauth2/implicit/test_oauth2_implicit_async.py b/tests/oauth2/implicit/test_oauth2_implicit_async.py index 8473fcd..2bb16da 100644 --- a/tests/oauth2/implicit/test_oauth2_implicit_async.py +++ b/tests/oauth2/implicit/test_oauth2_implicit_async.py @@ -1,17 +1,16 @@ +import datetime import json import time -import datetime import typing -import httpx +import httpx2 import jwt import pytest -from pytest_asyncio.plugin import unused_tcp_port -from pytest_httpx import HTTPXMock +from pytest_httpx2 import HTTPXMock -from httpx_auth.testing import BrowserMock, create_token, token_cache, browser_mock -import httpx_auth -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry +from httpx2_auth.testing import BrowserMock, create_token @pytest.mark.asyncio @@ -21,14 +20,12 @@ async def test_oauth2_implicit_flow_token_is_not_reused_if_a_url_parameter_is_ch browser_mock: BrowserMock, unused_tcp_port_factory: typing.Callable[[], int], ): - auth1 = httpx_auth.OAuth2Implicit( + auth1 = httpx2_auth.OAuth2Implicit( "https://provide_token?response_type=custom_token&fake_param=1", token_field_name="custom_token", redirect_uri_port=unused_tcp_port_factory(), ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) first_token = create_token(expiry_in_1_hour) tab1 = browser_mock.add_response( opened_url=f"https://provide_token?response_type=custom_token&fake_param=1&state=fc65632abc93fbf8fede279fb6405912f18e05e5e7042b9d92e711f341b8a71efede90865c5fb38f0f11735e9923c0dccdf173be81acf61955f873d4a6e28fdb&redirect_uri=http%3A%2F%2Flocalhost%3A{auth1.redirect_uri_port}%2F", @@ -43,15 +40,15 @@ async def test_oauth2_implicit_flow_token_is_not_reused_if_a_url_parameter_is_ch }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth1) # Ensure that the new token is different than previous one - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1, seconds=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta( + hours=1, seconds=1 + ) - auth2 = httpx_auth.OAuth2Implicit( + auth2 = httpx2_auth.OAuth2Implicit( "https://provide_token?response_type=custom_token&fake_param=2", token_field_name="custom_token", redirect_uri_port=unused_tcp_port_factory(), @@ -70,7 +67,7 @@ async def test_oauth2_implicit_flow_token_is_not_reused_if_a_url_parameter_is_ch }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth2) tab1.assert_success() @@ -81,14 +78,12 @@ async def test_oauth2_implicit_flow_token_is_not_reused_if_a_url_parameter_is_ch async def test_oauth2_implicit_flow_uses_redirect_uri_domain( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( + auth = httpx2_auth.OAuth2Implicit( "https://provide_token", redirect_uri_domain="localhost.mycompany.com", redirect_uri_port=unused_tcp_port, ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost.mycompany.com%3A{unused_tcp_port}%2F", @@ -103,7 +98,7 @@ async def test_oauth2_implicit_flow_uses_redirect_uri_domain( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -113,16 +108,12 @@ async def test_oauth2_implicit_flow_uses_redirect_uri_domain( async def test_oauth2_implicit_flow_uses_custom_success( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( + auth = httpx2_auth.OAuth2Implicit( "https://provide_token", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.success_html = ( - "
SUCCESS: {display_time}
" - ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + httpx2_auth.OAuth2.display.success_html = "
SUCCESS: {display_time}
" + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -138,7 +129,7 @@ async def test_oauth2_implicit_flow_uses_custom_success( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -148,19 +139,19 @@ async def test_oauth2_implicit_flow_uses_custom_success( async def test_oauth2_implicit_flow_uses_custom_failure( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( + auth = httpx2_auth.OAuth2Implicit( "https://provide_token", redirect_uri_port=unused_tcp_port, ) - httpx_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" + httpx2_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", displayed_html="FAILURE: {display_time}\n{information}", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest): await client.get("https://authorized_only", auth=auth) tab.assert_failure( @@ -172,14 +163,12 @@ async def test_oauth2_implicit_flow_uses_custom_failure( async def test_oauth2_implicit_flow_token_is_reused_if_only_nonce_differs( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth1 = httpx_auth.OAuth2Implicit( + auth1 = httpx2_auth.OAuth2Implicit( "https://provide_token?response_type=custom_token&nonce=1", token_field_name="custom_token", redirect_uri_port=unused_tcp_port, ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=custom_token&state=da5ed86c8443102b3d318731e35c51a9d7d3fc8ab5ccfc138531399803c4d8f72268347e85db8b8953c8d5c97039af70f924fd0cb075e0c5876f7502d4e8ff79&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F&nonce=%5B%271%27%5D", @@ -194,10 +183,10 @@ async def test_oauth2_implicit_flow_token_is_reused_if_only_nonce_differs( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth1) - auth2 = httpx_auth.OAuth2Implicit( + auth2 = httpx2_auth.OAuth2Implicit( "https://provide_token?response_type=custom_token&nonce=2", token_field_name="custom_token", ) @@ -209,7 +198,7 @@ async def test_oauth2_implicit_flow_token_is_reused_if_only_nonce_differs( "Authorization": f"Bearer {token}", }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth2) tab.assert_success() @@ -219,12 +208,8 @@ async def test_oauth2_implicit_flow_token_is_reused_if_only_nonce_differs( async def test_oauth2_implicit_flow_token_can_be_requested_on_a_custom_server_port( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -239,7 +224,7 @@ async def test_oauth2_implicit_flow_token_can_be_requested_on_a_custom_server_po }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -249,12 +234,8 @@ async def test_oauth2_implicit_flow_token_can_be_requested_on_a_custom_server_po async def test_oauth2_implicit_flow_post_token_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = jwt.encode( { "exp": expiry_in_1_hour, @@ -275,7 +256,7 @@ async def test_oauth2_implicit_flow_post_token_is_sent_in_authorization_header_b }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -285,22 +266,18 @@ async def test_oauth2_implicit_flow_post_token_is_sent_in_authorization_header_b async def test_oauth2_implicit_flow_post_token_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) # Add a token that expires in 29 seconds, so should be considered as expired when issuing the request - expiry_in_29_seconds = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(seconds=29) + expiry_in_29_seconds = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta( + seconds=29 + ) token_cache._add_token( key="bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c", token=create_token(expiry_in_29_seconds), expiry=to_expiry(expires_in=29), ) # Meaning a new one will be requested - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -315,7 +292,7 @@ async def test_oauth2_implicit_flow_post_token_is_expired_after_30_seconds_by_de }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -325,11 +302,11 @@ async def test_oauth2_implicit_flow_post_token_is_expired_after_30_seconds_by_de async def test_oauth2_implicit_flow_post_token_custom_expiry( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit("https://provide_token", early_expiry=28) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", early_expiry=28) # Add a token that expires in 29 seconds, so should be considered as not expired when issuing the request - expiry_in_29_seconds = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(seconds=29) + expiry_in_29_seconds = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta( + seconds=29 + ) token = create_token(expiry_in_29_seconds) token_cache._add_token( key="bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c", @@ -344,7 +321,7 @@ async def test_oauth2_implicit_flow_post_token_custom_expiry( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -352,9 +329,9 @@ async def test_oauth2_implicit_flow_post_token_custom_expiry( async def test_browser_opening_failure( token_cache, httpx_mock: HTTPXMock, monkeypatch, unused_tcp_port: int ): - import httpx_auth._oauth2.authentication_responses_server + import httpx2_auth._oauth2.authentication_responses_server - auth = httpx_auth.OAuth2Implicit( + auth = httpx2_auth.OAuth2Implicit( "https://provide_token", timeout=0.1, redirect_uri_port=unused_tcp_port ) @@ -363,7 +340,7 @@ def open(self, url, new): return False monkeypatch.setattr( - httpx_auth._oauth2.authentication_responses_server.webbrowser, + httpx2_auth._oauth2.authentication_responses_server.webbrowser, "get", lambda *args: FakeBrowser(), ) @@ -373,23 +350,18 @@ def open(self, url, new): url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.TimeoutOccurred) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.TimeoutOccurred) as exception_info: await client.get("https://authorized_only", auth=auth) - assert ( - str(exception_info.value) - == "User authentication was not received within 0.1 seconds." - ) + assert str(exception_info.value) == "User authentication was not received within 0.1 seconds." @pytest.mark.asyncio -async def test_browser_error( - token_cache, httpx_mock: HTTPXMock, monkeypatch, unused_tcp_port: int -): - import httpx_auth._oauth2.authentication_responses_server +async def test_browser_error(token_cache, httpx_mock: HTTPXMock, monkeypatch, unused_tcp_port: int): + import httpx2_auth._oauth2.authentication_responses_server - auth = httpx_auth.OAuth2Implicit( + auth = httpx2_auth.OAuth2Implicit( "https://provide_token", timeout=0.1, redirect_uri_port=unused_tcp_port ) @@ -400,7 +372,7 @@ def open(self, url, new): raise webbrowser.Error("Failure") monkeypatch.setattr( - httpx_auth._oauth2.authentication_responses_server.webbrowser, + httpx2_auth._oauth2.authentication_responses_server.webbrowser, "get", lambda *args: FakeBrowser(), ) @@ -409,26 +381,19 @@ def open(self, url, new): method="GET", url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.TimeoutOccurred) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.TimeoutOccurred) as exception_info: await client.get("https://authorized_only", auth=auth) - assert ( - str(exception_info.value) - == "User authentication was not received within 0.1 seconds." - ) + assert str(exception_info.value) == "User authentication was not received within 0.1 seconds." @pytest.mark.asyncio async def test_state_change( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -443,27 +408,23 @@ async def test_state_change( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @pytest.mark.asyncio -async def test_empty_token_is_invalid( - token_cache, browser_mock: BrowserMock, unused_tcp_port: int -): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) +async def test_empty_token_is_invalid(token_cache, browser_mock: BrowserMock, unused_tcp_port: int): + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}", - data=f"access_token=&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c", + data="access_token=&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidToken, match=" is invalid."): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidToken, match=" is invalid."): await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -473,17 +434,15 @@ async def test_empty_token_is_invalid( async def test_token_without_expiry_is_invalid( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}", data=f"access_token={create_token(None)}&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.TokenExpiryNotProvided) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.TokenExpiryNotProvided) as exception_info: await client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "Expiry (exp) is not provided in None." @@ -494,12 +453,8 @@ async def test_token_without_expiry_is_invalid( async def test_oauth2_implicit_flow_get_token_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -513,7 +468,7 @@ async def test_oauth2_implicit_flow_get_token_is_sent_in_authorization_header_by }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -523,15 +478,13 @@ async def test_oauth2_implicit_flow_get_token_is_sent_in_authorization_header_by async def test_oauth2_implicit_flow_token_is_sent_in_requested_field( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( + auth = httpx2_auth.OAuth2Implicit( "https://provide_token", header_name="Bearer", header_value="{token}", redirect_uri_port=unused_tcp_port, ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -546,7 +499,7 @@ async def test_oauth2_implicit_flow_token_is_sent_in_requested_field( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -556,15 +509,13 @@ async def test_oauth2_implicit_flow_token_is_sent_in_requested_field( async def test_oauth2_implicit_flow_can_send_a_custom_response_type_and_expects_token_to_be_received_with_this_name( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( + auth = httpx2_auth.OAuth2Implicit( "https://provide_token", response_type="custom_token", token_field_name="custom_token", redirect_uri_port=unused_tcp_port, ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=custom_token&state=da5ed86c8443102b3d318731e35c51a9d7d3fc8ab5ccfc138531399803c4d8f72268347e85db8b8953c8d5c97039af70f924fd0cb075e0c5876f7502d4e8ff79&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -579,7 +530,7 @@ async def test_oauth2_implicit_flow_can_send_a_custom_response_type_and_expects_ }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -589,14 +540,12 @@ async def test_oauth2_implicit_flow_can_send_a_custom_response_type_and_expects_ async def test_oauth2_implicit_flow_expects_token_in_id_token_if_response_type_is_id_token( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( + auth = httpx2_auth.OAuth2Implicit( "https://provide_token", response_type="id_token", redirect_uri_port=unused_tcp_port, ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=id_token&state=4b7a43e14ff4940a513dba46a736b62890e0a568f3342412cecfa968af823feae7b3c56cd2ecf07d533df3990cdc7436b3c090f27e6fde42813a3c6510e077d9&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -611,7 +560,7 @@ async def test_oauth2_implicit_flow_expects_token_in_id_token_if_response_type_i }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -621,13 +570,11 @@ async def test_oauth2_implicit_flow_expects_token_in_id_token_if_response_type_i async def test_oauth2_implicit_flow_expects_token_in_id_token_if_response_type_in_url_is_id_token( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( + auth = httpx2_auth.OAuth2Implicit( "https://provide_token?response_type=id_token", redirect_uri_port=unused_tcp_port, ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=id_token&state=4b7a43e14ff4940a513dba46a736b62890e0a568f3342412cecfa968af823feae7b3c56cd2ecf07d533df3990cdc7436b3c090f27e6fde42813a3c6510e077d9&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -642,7 +589,7 @@ async def test_oauth2_implicit_flow_expects_token_in_id_token_if_response_type_i }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -652,12 +599,8 @@ async def test_oauth2_implicit_flow_expects_token_in_id_token_if_response_type_i async def test_oauth2_implicit_flow_expects_token_to_be_stored_in_access_token_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -672,7 +615,7 @@ async def test_oauth2_implicit_flow_expects_token_to_be_stored_in_access_token_b }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -682,12 +625,8 @@ async def test_oauth2_implicit_flow_expects_token_to_be_stored_in_access_token_b async def test_oauth2_implicit_flow_token_is_reused_if_not_expired( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth1 = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + auth1 = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -702,12 +641,10 @@ async def test_oauth2_implicit_flow_token_is_reused_if_not_expired( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth1) - auth2 = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth2 = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) httpx_mock.add_response( url="https://authorized_only", @@ -716,7 +653,7 @@ async def test_oauth2_implicit_flow_token_is_reused_if_not_expired( "Authorization": f"Bearer {token}", }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth2) tab.assert_success() @@ -726,16 +663,14 @@ async def test_oauth2_implicit_flow_token_is_reused_if_not_expired( async def test_oauth2_implicit_flow_post_failure_if_token_is_not_provided( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}", data="", ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: with pytest.raises(Exception) as exception_info: await client.get("https://authorized_only", auth=auth) @@ -747,15 +682,13 @@ async def test_oauth2_implicit_flow_post_failure_if_token_is_not_provided( async def test_oauth2_implicit_flow_get_failure_if_token_is_not_provided( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}", ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: with pytest.raises(Exception) as exception_info: await client.get("https://authorized_only", auth=auth) @@ -767,12 +700,8 @@ async def test_oauth2_implicit_flow_get_failure_if_token_is_not_provided( async def test_oauth2_implicit_flow_post_failure_if_state_is_not_provided( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -780,13 +709,12 @@ async def test_oauth2_implicit_flow_post_failure_if_state_is_not_provided( data=f"access_token={token}", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.StateNotProvided) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.StateNotProvided) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( - str(exception_info.value) - == f"state not provided within {{'access_token': ['{token}']}}." + str(exception_info.value) == f"state not provided within {{'access_token': ['{token}']}}." ) tab.assert_failure(f"state not provided within {{'access_token': ['{token}']}}.") @@ -795,28 +723,24 @@ async def test_oauth2_implicit_flow_post_failure_if_state_is_not_provided( async def test_oauth2_implicit_flow_get_failure_if_state_is_not_provided( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#access_token={token}", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.StateNotProvided) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.StateNotProvided) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"state not provided within {{'access_token': ['{token}'], 'httpx_auth_redirect': ['1']}}." + == f"state not provided within {{'access_token': ['{token}'], 'httpx2_auth_redirect': ['1']}}." ) tab.assert_failure( - f"state not provided within {{'access_token': ['{token}'], 'httpx_auth_redirect': ['1']}}." + f"state not provided within {{'access_token': ['{token}'], 'httpx2_auth_redirect': ['1']}}." ) @@ -824,16 +748,14 @@ async def test_oauth2_implicit_flow_get_failure_if_state_is_not_provided( async def test_with_invalid_token_request_invalid_request_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -849,16 +771,14 @@ async def test_with_invalid_token_request_invalid_request_error( async def test_with_invalid_token_request_invalid_request_error_and_error_description( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc" @@ -869,41 +789,35 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri async def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_request: desc\nMore information can be found on https://test_url" ) - tab.assert_failure( - "invalid_request: desc
More information can be found on https://test_url" - ) + tab.assert_failure("invalid_request: desc
More information can be found on https://test_url") @pytest.mark.asyncio async def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url&other=test", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -919,16 +833,14 @@ async def test_with_invalid_token_request_invalid_request_error_and_error_descri async def test_with_invalid_token_request_unauthorized_client_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=unauthorized_client", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -944,16 +856,14 @@ async def test_with_invalid_token_request_unauthorized_client_error( async def test_with_invalid_token_request_access_denied_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=access_denied", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -969,16 +879,14 @@ async def test_with_invalid_token_request_access_denied_error( async def test_with_invalid_token_request_unsupported_response_type_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=unsupported_response_type", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -994,41 +902,35 @@ async def test_with_invalid_token_request_unsupported_response_type_error( async def test_with_invalid_token_request_invalid_scope_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_scope", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_scope: The requested scope is invalid, unknown, or malformed." ) - tab.assert_failure( - "invalid_scope: The requested scope is invalid, unknown, or malformed." - ) + tab.assert_failure("invalid_scope: The requested scope is invalid, unknown, or malformed.") @pytest.mark.asyncio async def test_with_invalid_token_request_server_error_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=server_error", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1044,16 +946,14 @@ async def test_with_invalid_token_request_server_error_error( async def test_with_invalid_token_request_temporarily_unavailable_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=temporarily_unavailable", ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -1069,7 +969,7 @@ async def test_with_invalid_token_request_temporarily_unavailable_error( async def test_oauth2_implicit_flow_failure_if_token_is_not_received_within_the_timeout_interval( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( + auth = httpx2_auth.OAuth2Implicit( "https://provide_token", timeout=0.1, redirect_uri_port=unused_tcp_port ) browser_mock.add_response( @@ -1078,27 +978,22 @@ async def test_oauth2_implicit_flow_failure_if_token_is_not_received_within_the_ reply_url=None, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.TimeoutOccurred) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.TimeoutOccurred) as exception_info: await client.get("https://authorized_only", auth=auth) - assert ( - str(exception_info.value) - == "User authentication was not received within 0.1 seconds." - ) + assert str(exception_info.value) == "User authentication was not received within 0.1 seconds." @pytest.mark.asyncio async def test_oauth2_implicit_flow_token_is_requested_again_if_expired( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) # This token will expires in 100 milliseconds - expiry_in_1_second = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(milliseconds=100) + expiry_in_1_second = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta( + milliseconds=100 + ) first_token = create_token(expiry_in_1_second) tab1 = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -1113,16 +1008,14 @@ async def test_oauth2_implicit_flow_token_is_requested_again_if_expired( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) # Wait to ensure that the token will be considered as expired time.sleep(0.2) # Token should now be expired, a new one should be requested - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) second_token = create_token(expiry_in_1_hour) tab2 = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -1137,7 +1030,7 @@ async def test_oauth2_implicit_flow_token_is_requested_again_if_expired( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) tab1.assert_success() diff --git a/tests/oauth2/implicit/test_oauth2_implicit_sync.py b/tests/oauth2/implicit/test_oauth2_implicit_sync.py index 0e2f975..e5c6350 100644 --- a/tests/oauth2/implicit/test_oauth2_implicit_sync.py +++ b/tests/oauth2/implicit/test_oauth2_implicit_sync.py @@ -1,28 +1,26 @@ +import datetime import json import time -import datetime -import httpx +import httpx2 import jwt import pytest -from pytest_httpx import HTTPXMock +from pytest_httpx2 import HTTPXMock -from httpx_auth.testing import BrowserMock, create_token, token_cache, browser_mock -import httpx_auth -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry +from httpx2_auth.testing import BrowserMock, create_token def test_oauth2_implicit_flow_token_is_not_reused_if_a_url_parameter_is_changing( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth1 = httpx_auth.OAuth2Implicit( + auth1 = httpx2_auth.OAuth2Implicit( "https://provide_token?response_type=custom_token&fake_param=1", token_field_name="custom_token", redirect_uri_port=unused_tcp_port, ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) first_token = create_token(expiry_in_1_hour) tab1 = browser_mock.add_response( opened_url=f"https://provide_token?response_type=custom_token&fake_param=1&state=fc65632abc93fbf8fede279fb6405912f18e05e5e7042b9d92e711f341b8a71efede90865c5fb38f0f11735e9923c0dccdf173be81acf61955f873d4a6e28fdb&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -37,15 +35,15 @@ def test_oauth2_implicit_flow_token_is_not_reused_if_a_url_parameter_is_changing }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth1) # Ensure that the new token is different than previous one - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1, seconds=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta( + hours=1, seconds=1 + ) - auth2 = httpx_auth.OAuth2Implicit( + auth2 = httpx2_auth.OAuth2Implicit( "https://provide_token?response_type=custom_token&fake_param=2", token_field_name="custom_token", redirect_uri_port=unused_tcp_port, @@ -64,7 +62,7 @@ def test_oauth2_implicit_flow_token_is_not_reused_if_a_url_parameter_is_changing }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth2) tab1.assert_success() @@ -74,14 +72,12 @@ def test_oauth2_implicit_flow_token_is_not_reused_if_a_url_parameter_is_changing def test_oauth2_implicit_flow_uses_redirect_uri_domain( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( + auth = httpx2_auth.OAuth2Implicit( "https://provide_token", redirect_uri_domain="localhost.mycompany.com", redirect_uri_port=unused_tcp_port, ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost.mycompany.com%3A{unused_tcp_port}%2F", @@ -96,7 +92,7 @@ def test_oauth2_implicit_flow_uses_redirect_uri_domain( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -105,15 +101,9 @@ def test_oauth2_implicit_flow_uses_redirect_uri_domain( def test_oauth2_implicit_flow_uses_custom_success( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) - httpx_auth.OAuth2.display.success_html = ( - "
SUCCESS: {display_time}
" - ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) + httpx2_auth.OAuth2.display.success_html = "
SUCCESS: {display_time}
" + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -129,7 +119,7 @@ def test_oauth2_implicit_flow_uses_custom_success( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -138,19 +128,16 @@ def test_oauth2_implicit_flow_uses_custom_success( def test_oauth2_implicit_flow_uses_custom_failure( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) - httpx_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) + httpx2_auth.OAuth2.display.failure_html = "FAILURE: {display_time}\n{information}" tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", displayed_html="FAILURE: {display_time}\n{information}", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest): - client.get("https://authorized_only", auth=auth) + with httpx2.Client() as client, pytest.raises(httpx2_auth.InvalidGrantRequest): + client.get("https://authorized_only", auth=auth) tab.assert_failure( "invalid_request: The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed." @@ -160,14 +147,12 @@ def test_oauth2_implicit_flow_uses_custom_failure( def test_oauth2_implicit_flow_token_is_reused_if_only_nonce_differs( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth1 = httpx_auth.OAuth2Implicit( + auth1 = httpx2_auth.OAuth2Implicit( "https://provide_token?response_type=custom_token&nonce=1", token_field_name="custom_token", redirect_uri_port=unused_tcp_port, ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=custom_token&state=da5ed86c8443102b3d318731e35c51a9d7d3fc8ab5ccfc138531399803c4d8f72268347e85db8b8953c8d5c97039af70f924fd0cb075e0c5876f7502d4e8ff79&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F&nonce=%5B%271%27%5D", @@ -182,10 +167,10 @@ def test_oauth2_implicit_flow_token_is_reused_if_only_nonce_differs( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth1) - auth2 = httpx_auth.OAuth2Implicit( + auth2 = httpx2_auth.OAuth2Implicit( "https://provide_token?response_type=custom_token&nonce=2", token_field_name="custom_token", ) @@ -197,7 +182,7 @@ def test_oauth2_implicit_flow_token_is_reused_if_only_nonce_differs( "Authorization": f"Bearer {token}", }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth2) tab.assert_success() @@ -208,12 +193,8 @@ def test_oauth2_implicit_flow_token_can_be_requested_on_a_custom_server_port( ): # TODO Should use a method to retrieve a free port instead available_port = 5002 - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=available_port - ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=available_port) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url="https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A5002%2F", @@ -228,7 +209,7 @@ def test_oauth2_implicit_flow_token_can_be_requested_on_a_custom_server_port( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -237,12 +218,8 @@ def test_oauth2_implicit_flow_token_can_be_requested_on_a_custom_server_port( def test_oauth2_implicit_flow_post_token_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = jwt.encode( { "exp": expiry_in_1_hour, @@ -263,7 +240,7 @@ def test_oauth2_implicit_flow_post_token_is_sent_in_authorization_header_by_defa }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -272,22 +249,18 @@ def test_oauth2_implicit_flow_post_token_is_sent_in_authorization_header_by_defa def test_oauth2_implicit_flow_post_token_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) # Add a token that expires in 29 seconds, so should be considered as expired when issuing the request - expiry_in_29_seconds = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(seconds=29) + expiry_in_29_seconds = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta( + seconds=29 + ) token_cache._add_token( key="bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c", token=create_token(expiry_in_29_seconds), expiry=to_expiry(expires_in=29), ) # Meaning a new one will be requested - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -302,7 +275,7 @@ def test_oauth2_implicit_flow_post_token_is_expired_after_30_seconds_by_default( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -311,11 +284,11 @@ def test_oauth2_implicit_flow_post_token_is_expired_after_30_seconds_by_default( def test_oauth2_implicit_flow_post_token_custom_expiry( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit("https://provide_token", early_expiry=28) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", early_expiry=28) # Add a token that expires in 29 seconds, so should be considered as not expired when issuing the request - expiry_in_29_seconds = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(seconds=29) + expiry_in_29_seconds = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta( + seconds=29 + ) token = create_token(expiry_in_29_seconds) token_cache._add_token( key="bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c", @@ -330,16 +303,16 @@ def test_oauth2_implicit_flow_post_token_custom_expiry( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_browser_opening_failure( token_cache, httpx_mock: HTTPXMock, monkeypatch, unused_tcp_port: int ): - import httpx_auth._oauth2.authentication_responses_server + import httpx2_auth._oauth2.authentication_responses_server - auth = httpx_auth.OAuth2Implicit( + auth = httpx2_auth.OAuth2Implicit( "https://provide_token", timeout=0.1, redirect_uri_port=unused_tcp_port, @@ -350,7 +323,7 @@ def open(self, url, new): return False monkeypatch.setattr( - httpx_auth._oauth2.authentication_responses_server.webbrowser, + httpx2_auth._oauth2.authentication_responses_server.webbrowser, "get", lambda *args: FakeBrowser(), ) @@ -360,24 +333,18 @@ def open(self, url, new): url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.TimeoutOccurred) as exception_info: - client.get("https://authorized_only", auth=auth) + with httpx2.Client() as client, pytest.raises(httpx2_auth.TimeoutOccurred) as exception_info: + client.get("https://authorized_only", auth=auth) - assert ( - str(exception_info.value) - == "User authentication was not received within 0.1 seconds." - ) - assert isinstance(exception_info.value, httpx_auth.HttpxAuthException) - assert isinstance(exception_info.value, httpx.HTTPError) + assert str(exception_info.value) == "User authentication was not received within 0.1 seconds." + assert isinstance(exception_info.value, httpx2_auth.HttpxAuthException) + assert isinstance(exception_info.value, httpx2.HTTPError) -def test_browser_error( - token_cache, httpx_mock: HTTPXMock, monkeypatch, unused_tcp_port: int -): - import httpx_auth._oauth2.authentication_responses_server +def test_browser_error(token_cache, httpx_mock: HTTPXMock, monkeypatch, unused_tcp_port: int): + import httpx2_auth._oauth2.authentication_responses_server - auth = httpx_auth.OAuth2Implicit( + auth = httpx2_auth.OAuth2Implicit( "https://provide_token", timeout=0.1, redirect_uri_port=unused_tcp_port, @@ -390,7 +357,7 @@ def open(self, url, new): raise webbrowser.Error("Failure") monkeypatch.setattr( - httpx_auth._oauth2.authentication_responses_server.webbrowser, + httpx2_auth._oauth2.authentication_responses_server.webbrowser, "get", lambda *args: FakeBrowser(), ) @@ -399,27 +366,19 @@ def open(self, url, new): method="GET", url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.TimeoutOccurred) as exception_info: - client.get("https://authorized_only", auth=auth) + with httpx2.Client() as client, pytest.raises(httpx2_auth.TimeoutOccurred) as exception_info: + client.get("https://authorized_only", auth=auth) - assert ( - str(exception_info.value) - == "User authentication was not received within 0.1 seconds." - ) - assert isinstance(exception_info.value, httpx_auth.HttpxAuthException) - assert isinstance(exception_info.value, httpx.HTTPError) + assert str(exception_info.value) == "User authentication was not received within 0.1 seconds." + assert isinstance(exception_info.value, httpx2_auth.HttpxAuthException) + assert isinstance(exception_info.value, httpx2.HTTPError) def test_state_change( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -434,66 +393,54 @@ def test_state_change( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() -def test_empty_token_is_invalid( - token_cache, browser_mock: BrowserMock, unused_tcp_port: int -): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) +def test_empty_token_is_invalid(token_cache, browser_mock: BrowserMock, unused_tcp_port: int): + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}", - data=f"access_token=&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c", + data="access_token=&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c", ) - with httpx.Client() as client: - with pytest.raises( - httpx_auth.InvalidToken, match=" is invalid." - ) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidToken, match=" is invalid.") as exception_info: client.get("https://authorized_only", auth=auth) - assert isinstance(exception_info.value, httpx_auth.HttpxAuthException) - assert isinstance(exception_info.value, httpx.HTTPError) + assert isinstance(exception_info.value, httpx2_auth.HttpxAuthException) + assert isinstance(exception_info.value, httpx2.HTTPError) tab.assert_success() def test_token_without_expiry_is_invalid( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}", data=f"access_token={create_token(None)}&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.TokenExpiryNotProvided) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.TokenExpiryNotProvided) as exception_info: client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "Expiry (exp) is not provided in None." - assert isinstance(exception_info.value, httpx_auth.HttpxAuthException) - assert isinstance(exception_info.value, httpx.HTTPError) + assert isinstance(exception_info.value, httpx2_auth.HttpxAuthException) + assert isinstance(exception_info.value, httpx2.HTTPError) tab.assert_success() def test_oauth2_implicit_flow_get_token_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -507,7 +454,7 @@ def test_oauth2_implicit_flow_get_token_is_sent_in_authorization_header_by_defau }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -516,15 +463,13 @@ def test_oauth2_implicit_flow_get_token_is_sent_in_authorization_header_by_defau def test_oauth2_implicit_flow_token_is_sent_in_requested_field( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( + auth = httpx2_auth.OAuth2Implicit( "https://provide_token", header_name="Bearer", header_value="{token}", redirect_uri_port=unused_tcp_port, ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -539,7 +484,7 @@ def test_oauth2_implicit_flow_token_is_sent_in_requested_field( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -548,15 +493,13 @@ def test_oauth2_implicit_flow_token_is_sent_in_requested_field( def test_oauth2_implicit_flow_can_send_a_custom_response_type_and_expects_token_to_be_received_with_this_name( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( + auth = httpx2_auth.OAuth2Implicit( "https://provide_token", response_type="custom_token", token_field_name="custom_token", redirect_uri_port=unused_tcp_port, ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=custom_token&state=da5ed86c8443102b3d318731e35c51a9d7d3fc8ab5ccfc138531399803c4d8f72268347e85db8b8953c8d5c97039af70f924fd0cb075e0c5876f7502d4e8ff79&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -571,7 +514,7 @@ def test_oauth2_implicit_flow_can_send_a_custom_response_type_and_expects_token_ }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -580,14 +523,12 @@ def test_oauth2_implicit_flow_can_send_a_custom_response_type_and_expects_token_ def test_oauth2_implicit_flow_expects_token_in_id_token_if_response_type_is_id_token( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( + auth = httpx2_auth.OAuth2Implicit( "https://provide_token", response_type="id_token", redirect_uri_port=unused_tcp_port, ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=id_token&state=4b7a43e14ff4940a513dba46a736b62890e0a568f3342412cecfa968af823feae7b3c56cd2ecf07d533df3990cdc7436b3c090f27e6fde42813a3c6510e077d9&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -602,7 +543,7 @@ def test_oauth2_implicit_flow_expects_token_in_id_token_if_response_type_is_id_t }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -611,13 +552,11 @@ def test_oauth2_implicit_flow_expects_token_in_id_token_if_response_type_is_id_t def test_oauth2_implicit_flow_expects_token_in_id_token_if_response_type_in_url_is_id_token( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( + auth = httpx2_auth.OAuth2Implicit( "https://provide_token?response_type=id_token", redirect_uri_port=unused_tcp_port, ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=id_token&state=4b7a43e14ff4940a513dba46a736b62890e0a568f3342412cecfa968af823feae7b3c56cd2ecf07d533df3990cdc7436b3c090f27e6fde42813a3c6510e077d9&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -632,7 +571,7 @@ def test_oauth2_implicit_flow_expects_token_in_id_token_if_response_type_in_url_ }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -641,12 +580,8 @@ def test_oauth2_implicit_flow_expects_token_in_id_token_if_response_type_in_url_ def test_oauth2_implicit_flow_expects_token_to_be_stored_in_access_token_by_default( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -661,7 +596,7 @@ def test_oauth2_implicit_flow_expects_token_to_be_stored_in_access_token_by_defa }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab.assert_success() @@ -670,12 +605,8 @@ def test_oauth2_implicit_flow_expects_token_to_be_stored_in_access_token_by_defa def test_oauth2_implicit_flow_token_is_reused_if_not_expired( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth1 = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + auth1 = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -690,12 +621,10 @@ def test_oauth2_implicit_flow_token_is_reused_if_not_expired( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth1) - auth2 = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth2 = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) httpx_mock.add_response( url="https://authorized_only", @@ -704,7 +633,7 @@ def test_oauth2_implicit_flow_token_is_reused_if_not_expired( "Authorization": f"Bearer {token}", }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth2) tab.assert_success() @@ -713,18 +642,15 @@ def test_oauth2_implicit_flow_token_is_reused_if_not_expired( def test_oauth2_implicit_flow_post_failure_if_token_is_not_provided( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}", data="", ) - with httpx.Client() as client: - with pytest.raises(Exception) as exception_info: - client.get("https://authorized_only", auth=auth) + with httpx2.Client() as client, pytest.raises(Exception) as exception_info: + client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "access_token not provided within {}." tab.assert_failure("access_token not provided within {}.") @@ -733,17 +659,14 @@ def test_oauth2_implicit_flow_post_failure_if_token_is_not_provided( def test_oauth2_implicit_flow_get_failure_if_token_is_not_provided( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}", ) - with httpx.Client() as client: - with pytest.raises(Exception) as exception_info: - client.get("https://authorized_only", auth=auth) + with httpx2.Client() as client, pytest.raises(Exception) as exception_info: + client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "access_token not provided within {}." tab.assert_failure("access_token not provided within {}.") @@ -752,12 +675,8 @@ def test_oauth2_implicit_flow_get_failure_if_token_is_not_provided( def test_oauth2_implicit_flow_post_failure_if_state_is_not_provided( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -765,60 +684,53 @@ def test_oauth2_implicit_flow_post_failure_if_state_is_not_provided( data=f"access_token={token}", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.StateNotProvided) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.StateNotProvided) as exception_info: client.get("https://authorized_only", auth=auth) assert ( - str(exception_info.value) - == f"state not provided within {{'access_token': ['{token}']}}." + str(exception_info.value) == f"state not provided within {{'access_token': ['{token}']}}." ) - assert isinstance(exception_info.value, httpx_auth.HttpxAuthException) - assert isinstance(exception_info.value, httpx.HTTPError) + assert isinstance(exception_info.value, httpx2_auth.HttpxAuthException) + assert isinstance(exception_info.value, httpx2.HTTPError) tab.assert_failure(f"state not provided within {{'access_token': ['{token}']}}.") def test_oauth2_implicit_flow_get_failure_if_state_is_not_provided( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) token = create_token(expiry_in_1_hour) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#access_token={token}", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.StateNotProvided) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.StateNotProvided) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"state not provided within {{'access_token': ['{token}'], 'httpx_auth_redirect': ['1']}}." + == f"state not provided within {{'access_token': ['{token}'], 'httpx2_auth_redirect': ['1']}}." ) tab.assert_failure( - f"state not provided within {{'access_token': ['{token}'], 'httpx_auth_redirect': ['1']}}." + f"state not provided within {{'access_token': ['{token}'], 'httpx2_auth_redirect': ['1']}}." ) def test_with_invalid_token_request_invalid_request_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -833,16 +745,14 @@ def test_with_invalid_token_request_invalid_request_error( def test_with_invalid_token_request_invalid_request_error_and_error_description( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc" @@ -852,40 +762,34 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description( def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_request: desc\nMore information can be found on https://test_url" ) - tab.assert_failure( - "invalid_request: desc
More information can be found on https://test_url" - ) + tab.assert_failure("invalid_request: desc
More information can be found on https://test_url") def test_with_invalid_token_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_request&error_description=desc&error_uri=https://test_url&other=test", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -900,16 +804,14 @@ def test_with_invalid_token_request_invalid_request_error_and_error_description_ def test_with_invalid_token_request_unauthorized_client_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=unauthorized_client", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -924,16 +826,14 @@ def test_with_invalid_token_request_unauthorized_client_error( def test_with_invalid_token_request_access_denied_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=access_denied", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -948,16 +848,14 @@ def test_with_invalid_token_request_access_denied_error( def test_with_invalid_token_request_unsupported_response_type_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=unsupported_response_type", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -972,40 +870,34 @@ def test_with_invalid_token_request_unsupported_response_type_error( def test_with_invalid_token_request_invalid_scope_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=invalid_scope", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_scope: The requested scope is invalid, unknown, or malformed." ) - tab.assert_failure( - "invalid_scope: The requested scope is invalid, unknown, or malformed." - ) + tab.assert_failure("invalid_scope: The requested scope is invalid, unknown, or malformed.") def test_with_invalid_token_request_server_error_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=server_error", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1020,16 +912,14 @@ def test_with_invalid_token_request_server_error_error( def test_with_invalid_token_request_temporarily_unavailable_error( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) tab = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", reply_url=f"http://localhost:{unused_tcp_port}#error=temporarily_unavailable", ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -1044,7 +934,7 @@ def test_with_invalid_token_request_temporarily_unavailable_error( def test_oauth2_implicit_flow_failure_if_token_is_not_received_within_the_timeout_interval( token_cache, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( + auth = httpx2_auth.OAuth2Implicit( "https://provide_token", timeout=0.1, redirect_uri_port=unused_tcp_port, @@ -1055,26 +945,20 @@ def test_oauth2_implicit_flow_failure_if_token_is_not_received_within_the_timeou reply_url=None, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.TimeoutOccurred) as exception_info: - client.get("https://authorized_only", auth=auth) + with httpx2.Client() as client, pytest.raises(httpx2_auth.TimeoutOccurred) as exception_info: + client.get("https://authorized_only", auth=auth) - assert ( - str(exception_info.value) - == "User authentication was not received within 0.1 seconds." - ) + assert str(exception_info.value) == "User authentication was not received within 0.1 seconds." def test_oauth2_implicit_flow_token_is_requested_again_if_expired( token_cache, httpx_mock: HTTPXMock, browser_mock: BrowserMock, unused_tcp_port: int ): - auth = httpx_auth.OAuth2Implicit( - "https://provide_token", redirect_uri_port=unused_tcp_port - ) + auth = httpx2_auth.OAuth2Implicit("https://provide_token", redirect_uri_port=unused_tcp_port) # This token will expires in 100 milliseconds - expiry_in_1_second = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(milliseconds=100) + expiry_in_1_second = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta( + milliseconds=100 + ) first_token = create_token(expiry_in_1_second) tab1 = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -1089,16 +973,14 @@ def test_oauth2_implicit_flow_token_is_requested_again_if_expired( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) # Wait to ensure that the token will be considered as expired time.sleep(0.2) # Token should now be expired, a new one should be requested - expiry_in_1_hour = datetime.datetime.now( - datetime.timezone.utc - ) + datetime.timedelta(hours=1) + expiry_in_1_hour = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=1) second_token = create_token(expiry_in_1_hour) tab2 = browser_mock.add_response( opened_url=f"https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A{unused_tcp_port}%2F", @@ -1113,7 +995,7 @@ def test_oauth2_implicit_flow_token_is_requested_again_if_expired( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) tab1.assert_success() diff --git a/tests/oauth2/resource_owner_password/__init__.py b/tests/oauth2/resource_owner_password/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/oauth2/resource_owner_password/okta/__init__.py b/tests/oauth2/resource_owner_password/okta/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta.py b/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta.py index 3485050..6fac627 100644 --- a/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta.py +++ b/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta.py @@ -1,11 +1,11 @@ import pytest -import httpx_auth +import httpx2_auth def test_instance_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OktaResourceOwnerPasswordCredentials( + httpx2_auth.OktaResourceOwnerPasswordCredentials( "", "test_user", "test_pwd", @@ -17,7 +17,7 @@ def test_instance_is_mandatory(): def test_user_name_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OktaResourceOwnerPasswordCredentials( + httpx2_auth.OktaResourceOwnerPasswordCredentials( "https://test_url", "", "test_pwd", @@ -29,7 +29,7 @@ def test_user_name_is_mandatory(): def test_password_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OktaResourceOwnerPasswordCredentials( + httpx2_auth.OktaResourceOwnerPasswordCredentials( "https://test_url", "test_user", "", @@ -41,7 +41,7 @@ def test_password_is_mandatory(): def test_client_id_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OktaResourceOwnerPasswordCredentials( + httpx2_auth.OktaResourceOwnerPasswordCredentials( "https://test_url", "test_user", "test_pwd", @@ -53,7 +53,7 @@ def test_client_id_is_mandatory(): def test_client_secret_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OktaResourceOwnerPasswordCredentials( + httpx2_auth.OktaResourceOwnerPasswordCredentials( "https://test_url", "test_user", "test_pwd", @@ -65,7 +65,7 @@ def test_client_secret_is_mandatory(): def test_header_value_must_contains_token(): with pytest.raises(Exception) as exception_info: - httpx_auth.OktaResourceOwnerPasswordCredentials( + httpx2_auth.OktaResourceOwnerPasswordCredentials( "https://test_url", "test_user", "test_pwd", diff --git a/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta_async.py b/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta_async.py index cc008d5..0e5a05a 100644 --- a/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta_async.py +++ b/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta_async.py @@ -1,12 +1,11 @@ import time -from pytest_httpx import HTTPXMock +import httpx2 import pytest -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import token_cache -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry @pytest.mark.asyncio @@ -14,8 +13,8 @@ async def test_oauth2_password_credentials_flow_uses_provided_client( token_cache, httpx_mock: HTTPXMock ): # TODO Add support for AsyncClient - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -47,7 +46,7 @@ async def test_oauth2_password_credentials_flow_uses_provided_client( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -56,8 +55,8 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client( token_cache, httpx_mock: HTTPXMock ): # TODO Add support for AsyncClient - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -88,7 +87,7 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) time.sleep(2) @@ -115,7 +114,7 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client( "Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA", }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -124,8 +123,8 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_tok token_cache, httpx_mock: HTTPXMock ): # TODO Add support for AsyncClient - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -157,7 +156,7 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_tok }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) time.sleep(2) @@ -186,7 +185,7 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_tok }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -194,7 +193,7 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_tok async def test_oauth2_password_credentials_flow_token_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -222,7 +221,7 @@ async def test_oauth2_password_credentials_flow_token_is_sent_in_authorization_h }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -230,7 +229,7 @@ async def test_oauth2_password_credentials_flow_token_is_sent_in_authorization_h async def test_oauth2_password_credentials_flow_token_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -265,7 +264,7 @@ async def test_oauth2_password_credentials_flow_token_is_expired_after_30_second }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -273,7 +272,7 @@ async def test_oauth2_password_credentials_flow_token_is_expired_after_30_second async def test_oauth2_password_credentials_flow_token_custom_expiry( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -295,15 +294,13 @@ async def test_oauth2_password_credentials_flow_token_custom_expiry( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio -async def test_oauth2_password_credentials_flow_refresh_token( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( +async def test_oauth2_password_credentials_flow_refresh_token(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -333,7 +330,7 @@ async def test_oauth2_password_credentials_flow_refresh_token( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) # response for refresh token grant @@ -360,7 +357,7 @@ async def test_oauth2_password_credentials_flow_refresh_token( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -368,7 +365,7 @@ async def test_oauth2_password_credentials_flow_refresh_token( async def test_oauth2_password_credentials_flow_refresh_token_invalid( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -398,7 +395,7 @@ async def test_oauth2_password_credentials_flow_refresh_token_invalid( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) # response for refresh token grant @@ -436,7 +433,7 @@ async def test_oauth2_password_credentials_flow_refresh_token_invalid( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -444,7 +441,7 @@ async def test_oauth2_password_credentials_flow_refresh_token_invalid( async def test_oauth2_password_credentials_flow_refresh_token_access_token_not_expired( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -474,7 +471,7 @@ async def test_oauth2_password_credentials_flow_refresh_token_access_token_not_e }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) httpx_mock.add_response( @@ -485,13 +482,13 @@ async def test_oauth2_password_credentials_flow_refresh_token_access_token_not_e }, ) # expect Bearer token to remain the same - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio async def test_expires_in_sent_as_str(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -519,15 +516,13 @@ async def test_expires_in_sent_as_str(token_cache, httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio -async def test_scope_is_sent_as_is_when_provided_as_str( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( +async def test_scope_is_sent_as_is_when_provided_as_str(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -556,15 +551,13 @@ async def test_scope_is_sent_as_is_when_provided_as_str( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio -async def test_scope_is_sent_as_str_when_provided_as_list( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( +async def test_scope_is_sent_as_str_when_provided_as_list(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -593,13 +586,13 @@ async def test_scope_is_sent_as_str_when_provided_as_list( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio async def test_with_invalid_grant_request_no_json(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -613,16 +606,14 @@ async def test_with_invalid_grant_request_no_json(token_cache, httpx_mock: HTTPX status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest, match="failure"): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="failure"): await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio -async def test_with_invalid_grant_request_invalid_request_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( +async def test_with_invalid_grant_request_invalid_request_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -636,8 +627,8 @@ async def test_with_invalid_grant_request_invalid_request_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -653,7 +644,7 @@ async def test_with_invalid_grant_request_invalid_request_error( async def test_with_invalid_grant_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -667,8 +658,8 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc of the error" @@ -678,7 +669,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri async def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -696,13 +687,13 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url" + == "invalid_request: desc of the error\nMore information can be found on https://test_url" ) @@ -710,7 +701,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri async def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -729,21 +720,19 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {{'other': 'other info'}}" + == "invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {'other': 'other info'}" ) @pytest.mark.asyncio -async def test_with_invalid_grant_request_without_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( +async def test_with_invalid_grant_request_without_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -757,18 +746,16 @@ async def test_with_invalid_grant_request_without_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "{'other': 'other info'}" @pytest.mark.asyncio -async def test_with_invalid_grant_request_invalid_client_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( +async def test_with_invalid_grant_request_invalid_client_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -782,8 +769,8 @@ async def test_with_invalid_grant_request_invalid_client_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -800,10 +787,8 @@ async def test_with_invalid_grant_request_invalid_client_error( @pytest.mark.asyncio -async def test_with_invalid_grant_request_invalid_grant_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( +async def test_with_invalid_grant_request_invalid_grant_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -817,8 +802,8 @@ async def test_with_invalid_grant_request_invalid_grant_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -834,7 +819,7 @@ async def test_with_invalid_grant_request_invalid_grant_error( async def test_with_invalid_grant_request_unauthorized_client_error( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -848,8 +833,8 @@ async def test_with_invalid_grant_request_unauthorized_client_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -863,7 +848,7 @@ async def test_with_invalid_grant_request_unauthorized_client_error( async def test_with_invalid_grant_request_unsupported_grant_type_error( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -877,8 +862,8 @@ async def test_with_invalid_grant_request_unsupported_grant_type_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -889,10 +874,8 @@ async def test_with_invalid_grant_request_unsupported_grant_type_error( @pytest.mark.asyncio -async def test_with_invalid_grant_request_invalid_scope_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( +async def test_with_invalid_grant_request_invalid_scope_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -906,8 +889,8 @@ async def test_with_invalid_grant_request_invalid_scope_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -919,7 +902,7 @@ async def test_with_invalid_grant_request_invalid_scope_error( @pytest.mark.asyncio async def test_without_expected_token(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -939,8 +922,8 @@ async def test_without_expected_token(token_cache, httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.GrantNotProvided) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.GrantNotProvided) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( diff --git a/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta_sync.py b/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta_sync.py index e285f5f..b81c33b 100644 --- a/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta_sync.py +++ b/tests/oauth2/resource_owner_password/okta/test_oauth2_resource_owner_password_okta_sync.py @@ -1,19 +1,16 @@ import time -from pytest_httpx import HTTPXMock +import httpx2 import pytest -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import token_cache -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry -def test_oauth2_password_credentials_flow_uses_provided_client( - token_cache, httpx_mock: HTTPXMock -): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( +def test_oauth2_password_credentials_flow_uses_provided_client(token_cache, httpx_mock: HTTPXMock): + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -45,15 +42,15 @@ def test_oauth2_password_credentials_flow_uses_provided_client( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_password_credentials_flow_is_able_to_reuse_client( token_cache, httpx_mock: HTTPXMock ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -84,7 +81,7 @@ def test_oauth2_password_credentials_flow_is_able_to_reuse_client( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) time.sleep(2) @@ -112,15 +109,15 @@ def test_oauth2_password_credentials_flow_is_able_to_reuse_client( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_token_refresh( token_cache, httpx_mock: HTTPXMock ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -152,7 +149,7 @@ def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_token_ref }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) time.sleep(2) @@ -181,14 +178,14 @@ def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_token_ref }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_password_credentials_flow_token_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -216,14 +213,14 @@ def test_oauth2_password_credentials_flow_token_is_sent_in_authorization_header_ }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_password_credentials_flow_token_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -258,14 +255,12 @@ def test_oauth2_password_credentials_flow_token_is_expired_after_30_seconds_by_d }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) -def test_oauth2_password_credentials_flow_token_custom_expiry( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( +def test_oauth2_password_credentials_flow_token_custom_expiry(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -287,14 +282,12 @@ def test_oauth2_password_credentials_flow_token_custom_expiry( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) -def test_oauth2_password_credentials_flow_refresh_token( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( +def test_oauth2_password_credentials_flow_refresh_token(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -324,7 +317,7 @@ def test_oauth2_password_credentials_flow_refresh_token( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) # response for refresh token grant @@ -351,14 +344,12 @@ def test_oauth2_password_credentials_flow_refresh_token( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) -def test_oauth2_password_credentials_flow_refresh_token_invalid( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( +def test_oauth2_password_credentials_flow_refresh_token_invalid(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -388,7 +379,7 @@ def test_oauth2_password_credentials_flow_refresh_token_invalid( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) # response for refresh token grant @@ -426,14 +417,14 @@ def test_oauth2_password_credentials_flow_refresh_token_invalid( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_password_credentials_flow_refresh_token_access_token_not_expired( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -463,7 +454,7 @@ def test_oauth2_password_credentials_flow_refresh_token_access_token_not_expired }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) httpx_mock.add_response( @@ -474,12 +465,12 @@ def test_oauth2_password_credentials_flow_refresh_token_access_token_not_expired }, ) # expect Bearer token to remain the same - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_expires_in_sent_as_str(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -507,12 +498,12 @@ def test_expires_in_sent_as_str(token_cache, httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_scope_is_sent_as_is_when_provided_as_str(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -541,12 +532,12 @@ def test_scope_is_sent_as_is_when_provided_as_str(token_cache, httpx_mock: HTTPX }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_scope_is_sent_as_str_when_provided_as_list(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -575,12 +566,12 @@ def test_scope_is_sent_as_str_when_provided_as_list(token_cache, httpx_mock: HTT }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_with_invalid_grant_request_no_json(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -594,15 +585,13 @@ def test_with_invalid_grant_request_no_json(token_cache, httpx_mock: HTTPXMock): status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest, match="failure"): + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="failure"): client.get("https://authorized_only", auth=auth) -def test_with_invalid_grant_request_invalid_request_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( +def test_with_invalid_grant_request_invalid_request_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -616,8 +605,8 @@ def test_with_invalid_grant_request_invalid_request_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -632,7 +621,7 @@ def test_with_invalid_grant_request_invalid_request_error( def test_with_invalid_grant_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -646,8 +635,8 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc of the error" @@ -656,7 +645,7 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description( def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -674,20 +663,20 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url" + == "invalid_request: desc of the error\nMore information can be found on https://test_url" ) def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -706,18 +695,18 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {{'other': 'other info'}}" + == "invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {'other': 'other info'}" ) def test_with_invalid_grant_request_without_error(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -731,17 +720,15 @@ def test_with_invalid_grant_request_without_error(token_cache, httpx_mock: HTTPX status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "{'other': 'other info'}" -def test_with_invalid_grant_request_invalid_client_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( +def test_with_invalid_grant_request_invalid_client_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -755,8 +742,8 @@ def test_with_invalid_grant_request_invalid_client_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -772,10 +759,8 @@ def test_with_invalid_grant_request_invalid_client_error( ) -def test_with_invalid_grant_request_invalid_grant_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( +def test_with_invalid_grant_request_invalid_grant_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -789,8 +774,8 @@ def test_with_invalid_grant_request_invalid_grant_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -802,10 +787,8 @@ def test_with_invalid_grant_request_invalid_grant_error( ) -def test_with_invalid_grant_request_unauthorized_client_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( +def test_with_invalid_grant_request_unauthorized_client_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -819,8 +802,8 @@ def test_with_invalid_grant_request_unauthorized_client_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -833,7 +816,7 @@ def test_with_invalid_grant_request_unauthorized_client_error( def test_with_invalid_grant_request_unsupported_grant_type_error( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -847,8 +830,8 @@ def test_with_invalid_grant_request_unsupported_grant_type_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -858,10 +841,8 @@ def test_with_invalid_grant_request_unsupported_grant_type_error( ) -def test_with_invalid_grant_request_invalid_scope_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( +def test_with_invalid_grant_request_invalid_scope_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -875,8 +856,8 @@ def test_with_invalid_grant_request_invalid_scope_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -887,7 +868,7 @@ def test_with_invalid_grant_request_invalid_scope_error( def test_without_expected_token(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OktaResourceOwnerPasswordCredentials( + auth = httpx2_auth.OktaResourceOwnerPasswordCredentials( "testserver.okta-emea.com", username="test_user", password="test_pwd", @@ -907,8 +888,8 @@ def test_without_expected_token(token_cache, httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.GrantNotProvided) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.GrantNotProvided) as exception_info: client.get("https://authorized_only", auth=auth) assert ( diff --git a/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password.py b/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password.py index 7c70c4b..3ad651f 100644 --- a/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password.py +++ b/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password.py @@ -1,33 +1,29 @@ import pytest -import httpx_auth +import httpx2_auth def test_token_url_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OAuth2ResourceOwnerPasswordCredentials("", "test_user", "test_pwd") + httpx2_auth.OAuth2ResourceOwnerPasswordCredentials("", "test_user", "test_pwd") assert str(exception_info.value) == "Token URL is mandatory." def test_user_name_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OAuth2ResourceOwnerPasswordCredentials( - "https://test_url", "", "test_pwd" - ) + httpx2_auth.OAuth2ResourceOwnerPasswordCredentials("https://test_url", "", "test_pwd") assert str(exception_info.value) == "User name is mandatory." def test_password_is_mandatory(): with pytest.raises(Exception) as exception_info: - httpx_auth.OAuth2ResourceOwnerPasswordCredentials( - "https://test_url", "test_user", "" - ) + httpx2_auth.OAuth2ResourceOwnerPasswordCredentials("https://test_url", "test_user", "") assert str(exception_info.value) == "Password is mandatory." def test_header_value_must_contains_token(): with pytest.raises(Exception) as exception_info: - httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://test_url", "test_user", "test_pwd", header_value="Bearer token" ) assert str(exception_info.value) == "header_value parameter must contains {token}." diff --git a/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password_async.py b/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password_async.py index b070d87..0f1f1c1 100644 --- a/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password_async.py +++ b/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password_async.py @@ -1,12 +1,11 @@ import time -from pytest_httpx import HTTPXMock +import httpx2 import pytest -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import token_cache -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry @pytest.mark.asyncio @@ -14,8 +13,8 @@ async def test_oauth2_password_credentials_flow_uses_provided_client( token_cache, httpx_mock: HTTPXMock ): # TODO Add support for AsyncClient - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd", @@ -42,7 +41,7 @@ async def test_oauth2_password_credentials_flow_uses_provided_client( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -51,8 +50,8 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client( token_cache, httpx_mock: HTTPXMock ): # TODO Add support for AsyncClient - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd", @@ -78,7 +77,7 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) time.sleep(2) @@ -102,7 +101,7 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client( "Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA", }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -111,8 +110,8 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_tok token_cache, httpx_mock: HTTPXMock ): # TODO Add support for AsyncClient - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd", @@ -139,7 +138,7 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_tok }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) time.sleep(2) @@ -165,7 +164,7 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_tok }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -173,7 +172,7 @@ async def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_tok async def test_oauth2_password_credentials_flow_token_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -196,7 +195,7 @@ async def test_oauth2_password_credentials_flow_token_is_sent_in_authorization_h }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -204,7 +203,7 @@ async def test_oauth2_password_credentials_flow_token_is_sent_in_authorization_h async def test_oauth2_password_credentials_flow_does_not_authenticate_by_default( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -227,20 +226,15 @@ async def test_oauth2_password_credentials_flow_does_not_authenticate_by_default }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) - assert ( - "Authorization" - not in httpx_mock.get_request(url="https://provide_access_token").headers - ) + assert "Authorization" not in httpx_mock.get_request(url="https://provide_access_token").headers @pytest.mark.asyncio -async def test_oauth2_password_credentials_flow_authentication( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +async def test_oauth2_password_credentials_flow_authentication(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd", @@ -267,7 +261,7 @@ async def test_oauth2_password_credentials_flow_authentication( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -275,7 +269,7 @@ async def test_oauth2_password_credentials_flow_authentication( async def test_oauth2_password_credentials_flow_token_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) # Add a token that expires in 29 seconds, so should be considered as expired when issuing the request @@ -305,7 +299,7 @@ async def test_oauth2_password_credentials_flow_token_is_expired_after_30_second }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -313,7 +307,7 @@ async def test_oauth2_password_credentials_flow_token_is_expired_after_30_second async def test_oauth2_password_credentials_flow_token_custom_expiry( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd", @@ -333,15 +327,13 @@ async def test_oauth2_password_credentials_flow_token_custom_expiry( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio -async def test_oauth2_password_credentials_flow_refresh_token( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +async def test_oauth2_password_credentials_flow_refresh_token(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -364,7 +356,7 @@ async def test_oauth2_password_credentials_flow_refresh_token( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) # response for refresh token grant @@ -388,7 +380,7 @@ async def test_oauth2_password_credentials_flow_refresh_token( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -396,7 +388,7 @@ async def test_oauth2_password_credentials_flow_refresh_token( async def test_oauth2_password_credentials_flow_refresh_token_invalid( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -419,7 +411,7 @@ async def test_oauth2_password_credentials_flow_refresh_token_invalid( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) # response for refresh token grant @@ -451,7 +443,7 @@ async def test_oauth2_password_credentials_flow_refresh_token_invalid( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @@ -459,7 +451,7 @@ async def test_oauth2_password_credentials_flow_refresh_token_invalid( async def test_oauth2_password_credentials_flow_refresh_token_access_token_not_expired( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -482,7 +474,7 @@ async def test_oauth2_password_credentials_flow_refresh_token_access_token_not_e }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) httpx_mock.add_response( @@ -493,13 +485,13 @@ async def test_oauth2_password_credentials_flow_refresh_token_access_token_not_e }, ) # expect Bearer token to remain the same - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio async def test_expires_in_sent_as_str(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -522,15 +514,13 @@ async def test_expires_in_sent_as_str(token_cache, httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio -async def test_scope_is_sent_as_is_when_provided_as_str( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +async def test_scope_is_sent_as_is_when_provided_as_str(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd", @@ -556,15 +546,13 @@ async def test_scope_is_sent_as_is_when_provided_as_str( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio -async def test_scope_is_sent_as_str_when_provided_as_list( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +async def test_scope_is_sent_as_str_when_provided_as_list(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd", @@ -590,13 +578,13 @@ async def test_scope_is_sent_as_str_when_provided_as_list( }, ) - async with httpx.AsyncClient() as client: + async with httpx2.AsyncClient() as client: await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio async def test_with_invalid_grant_request_no_json(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -606,16 +594,14 @@ async def test_with_invalid_grant_request_no_json(token_cache, httpx_mock: HTTPX status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest, match="failure"): + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="failure"): await client.get("https://authorized_only", auth=auth) @pytest.mark.asyncio -async def test_with_invalid_grant_request_invalid_request_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +async def test_with_invalid_grant_request_invalid_request_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -625,8 +611,8 @@ async def test_with_invalid_grant_request_invalid_request_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -642,7 +628,7 @@ async def test_with_invalid_grant_request_invalid_request_error( async def test_with_invalid_grant_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -652,8 +638,8 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc of the error" @@ -663,7 +649,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri async def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -677,13 +663,13 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url" + == "invalid_request: desc of the error\nMore information can be found on https://test_url" ) @@ -691,7 +677,7 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri async def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -706,21 +692,19 @@ async def test_with_invalid_grant_request_invalid_request_error_and_error_descri status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {{'other': 'other info'}}" + == "invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {'other': 'other info'}" ) @pytest.mark.asyncio -async def test_with_invalid_grant_request_without_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +async def test_with_invalid_grant_request_without_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -730,18 +714,16 @@ async def test_with_invalid_grant_request_without_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "{'other': 'other info'}" @pytest.mark.asyncio -async def test_with_invalid_grant_request_invalid_client_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +async def test_with_invalid_grant_request_invalid_client_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -751,8 +733,8 @@ async def test_with_invalid_grant_request_invalid_client_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -769,10 +751,8 @@ async def test_with_invalid_grant_request_invalid_client_error( @pytest.mark.asyncio -async def test_with_invalid_grant_request_invalid_grant_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +async def test_with_invalid_grant_request_invalid_grant_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -782,8 +762,8 @@ async def test_with_invalid_grant_request_invalid_grant_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -799,7 +779,7 @@ async def test_with_invalid_grant_request_invalid_grant_error( async def test_with_invalid_grant_request_unauthorized_client_error( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -809,8 +789,8 @@ async def test_with_invalid_grant_request_unauthorized_client_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -824,7 +804,7 @@ async def test_with_invalid_grant_request_unauthorized_client_error( async def test_with_invalid_grant_request_unsupported_grant_type_error( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -834,8 +814,8 @@ async def test_with_invalid_grant_request_unsupported_grant_type_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -846,10 +826,8 @@ async def test_with_invalid_grant_request_unsupported_grant_type_error( @pytest.mark.asyncio -async def test_with_invalid_grant_request_invalid_scope_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +async def test_with_invalid_grant_request_invalid_scope_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -859,8 +837,8 @@ async def test_with_invalid_grant_request_invalid_scope_error( status_code=400, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( @@ -872,7 +850,7 @@ async def test_with_invalid_grant_request_invalid_scope_error( @pytest.mark.asyncio async def test_without_expected_token(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd", @@ -890,8 +868,8 @@ async def test_without_expected_token(token_cache, httpx_mock: HTTPXMock): }, ) - async with httpx.AsyncClient() as client: - with pytest.raises(httpx_auth.GrantNotProvided) as exception_info: + async with httpx2.AsyncClient() as client: + with pytest.raises(httpx2_auth.GrantNotProvided) as exception_info: await client.get("https://authorized_only", auth=auth) assert ( diff --git a/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password_sync.py b/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password_sync.py index 3988419..91865de 100644 --- a/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password_sync.py +++ b/tests/oauth2/resource_owner_password/test_oauth2_resource_owner_password_sync.py @@ -1,19 +1,16 @@ import time -from pytest_httpx import HTTPXMock +import httpx2 import pytest -import httpx +from pytest_httpx2 import HTTPXMock -import httpx_auth -from httpx_auth.testing import token_cache -from httpx_auth._oauth2.tokens import to_expiry +import httpx2_auth +from httpx2_auth._oauth2.tokens import to_expiry -def test_oauth2_password_credentials_flow_uses_provided_client( - token_cache, httpx_mock: HTTPXMock -): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +def test_oauth2_password_credentials_flow_uses_provided_client(token_cache, httpx_mock: HTTPXMock): + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd", @@ -40,15 +37,15 @@ def test_oauth2_password_credentials_flow_uses_provided_client( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_password_credentials_flow_is_able_to_reuse_client( token_cache, httpx_mock: HTTPXMock ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd", @@ -74,7 +71,7 @@ def test_oauth2_password_credentials_flow_is_able_to_reuse_client( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) time.sleep(2) @@ -98,15 +95,15 @@ def test_oauth2_password_credentials_flow_is_able_to_reuse_client( "Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA", }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_token_refresh( token_cache, httpx_mock: HTTPXMock ): - client = httpx.Client(headers={"x-test": "Test value"}) - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + client = httpx2.Client(headers={"x-test": "Test value"}) + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd", @@ -133,7 +130,7 @@ def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_token_ref }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) time.sleep(2) @@ -159,14 +156,14 @@ def test_oauth2_password_credentials_flow_is_able_to_reuse_client_with_token_ref }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_password_credentials_flow_token_is_sent_in_authorization_header_by_default( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -189,14 +186,14 @@ def test_oauth2_password_credentials_flow_token_is_sent_in_authorization_header_ }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_password_credentials_flow_does_not_authenticate_by_default( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -219,19 +216,14 @@ def test_oauth2_password_credentials_flow_does_not_authenticate_by_default( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) - assert ( - "Authorization" - not in httpx_mock.get_request(url="https://provide_access_token").headers - ) + assert "Authorization" not in httpx_mock.get_request(url="https://provide_access_token").headers -def test_oauth2_password_credentials_flow_authentication( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +def test_oauth2_password_credentials_flow_authentication(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd", @@ -258,14 +250,14 @@ def test_oauth2_password_credentials_flow_authentication( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_password_credentials_flow_token_is_expired_after_30_seconds_by_default( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) # Add a token that expires in 29 seconds, so should be considered as expired when issuing the request @@ -295,14 +287,12 @@ def test_oauth2_password_credentials_flow_token_is_expired_after_30_seconds_by_d }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) -def test_oauth2_password_credentials_flow_token_custom_expiry( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +def test_oauth2_password_credentials_flow_token_custom_expiry(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd", @@ -322,14 +312,12 @@ def test_oauth2_password_credentials_flow_token_custom_expiry( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) -def test_oauth2_password_credentials_flow_refresh_token( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +def test_oauth2_password_credentials_flow_refresh_token(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -352,7 +340,7 @@ def test_oauth2_password_credentials_flow_refresh_token( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) # response for refresh token grant @@ -376,14 +364,12 @@ def test_oauth2_password_credentials_flow_refresh_token( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) -def test_oauth2_password_credentials_flow_refresh_token_invalid( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +def test_oauth2_password_credentials_flow_refresh_token_invalid(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -406,7 +392,7 @@ def test_oauth2_password_credentials_flow_refresh_token_invalid( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) # response for refresh token grant @@ -438,14 +424,14 @@ def test_oauth2_password_credentials_flow_refresh_token_invalid( }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_oauth2_password_credentials_flow_refresh_token_access_token_not_expired( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -468,7 +454,7 @@ def test_oauth2_password_credentials_flow_refresh_token_access_token_not_expired }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) httpx_mock.add_response( @@ -479,12 +465,12 @@ def test_oauth2_password_credentials_flow_refresh_token_access_token_not_expired }, ) # expect Bearer token to remain the same - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_expires_in_sent_as_str(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -507,12 +493,12 @@ def test_expires_in_sent_as_str(token_cache, httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_scope_is_sent_as_is_when_provided_as_str(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd", @@ -538,12 +524,12 @@ def test_scope_is_sent_as_is_when_provided_as_str(token_cache, httpx_mock: HTTPX }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_scope_is_sent_as_str_when_provided_as_list(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd", @@ -569,12 +555,12 @@ def test_scope_is_sent_as_str_when_provided_as_list(token_cache, httpx_mock: HTT }, ) - with httpx.Client() as client: + with httpx2.Client() as client: client.get("https://authorized_only", auth=auth) def test_with_invalid_grant_request_no_json(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -584,15 +570,13 @@ def test_with_invalid_grant_request_no_json(token_cache, httpx_mock: HTTPXMock): status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest, match="failure"): + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest, match="failure"): client.get("https://authorized_only", auth=auth) -def test_with_invalid_grant_request_invalid_request_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +def test_with_invalid_grant_request_invalid_request_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -602,8 +586,8 @@ def test_with_invalid_grant_request_invalid_request_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -618,7 +602,7 @@ def test_with_invalid_grant_request_invalid_request_error( def test_with_invalid_grant_request_invalid_request_error_and_error_description( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -628,8 +612,8 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "invalid_request: desc of the error" @@ -638,7 +622,7 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description( def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -652,20 +636,20 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url" + == "invalid_request: desc of the error\nMore information can be found on https://test_url" ) def test_with_invalid_grant_request_invalid_request_error_and_error_description_and_uri_and_other_fields( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -680,18 +664,18 @@ def test_with_invalid_grant_request_invalid_request_error_and_error_description_ status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( str(exception_info.value) - == f"invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {{'other': 'other info'}}" + == "invalid_request: desc of the error\nMore information can be found on https://test_url\nAdditional information: {'other': 'other info'}" ) def test_with_invalid_grant_request_without_error(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -701,17 +685,15 @@ def test_with_invalid_grant_request_without_error(token_cache, httpx_mock: HTTPX status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert str(exception_info.value) == "{'other': 'other info'}" -def test_with_invalid_grant_request_invalid_client_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +def test_with_invalid_grant_request_invalid_client_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -721,8 +703,8 @@ def test_with_invalid_grant_request_invalid_client_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -738,10 +720,8 @@ def test_with_invalid_grant_request_invalid_client_error( ) -def test_with_invalid_grant_request_invalid_grant_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +def test_with_invalid_grant_request_invalid_grant_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -751,8 +731,8 @@ def test_with_invalid_grant_request_invalid_grant_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -764,10 +744,8 @@ def test_with_invalid_grant_request_invalid_grant_error( ) -def test_with_invalid_grant_request_unauthorized_client_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +def test_with_invalid_grant_request_unauthorized_client_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -777,8 +755,8 @@ def test_with_invalid_grant_request_unauthorized_client_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -791,7 +769,7 @@ def test_with_invalid_grant_request_unauthorized_client_error( def test_with_invalid_grant_request_unsupported_grant_type_error( token_cache, httpx_mock: HTTPXMock ): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -801,8 +779,8 @@ def test_with_invalid_grant_request_unsupported_grant_type_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -812,10 +790,8 @@ def test_with_invalid_grant_request_unsupported_grant_type_error( ) -def test_with_invalid_grant_request_invalid_scope_error( - token_cache, httpx_mock: HTTPXMock -): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( +def test_with_invalid_grant_request_invalid_scope_error(token_cache, httpx_mock: HTTPXMock): + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd" ) httpx_mock.add_response( @@ -825,8 +801,8 @@ def test_with_invalid_grant_request_invalid_scope_error( status_code=400, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.InvalidGrantRequest) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.InvalidGrantRequest) as exception_info: client.get("https://authorized_only", auth=auth) assert ( @@ -837,7 +813,7 @@ def test_with_invalid_grant_request_invalid_scope_error( def test_without_expected_token(token_cache, httpx_mock: HTTPXMock): - auth = httpx_auth.OAuth2ResourceOwnerPasswordCredentials( + auth = httpx2_auth.OAuth2ResourceOwnerPasswordCredentials( "https://provide_access_token", username="test_user", password="test_pwd", @@ -855,8 +831,8 @@ def test_without_expected_token(token_cache, httpx_mock: HTTPXMock): }, ) - with httpx.Client() as client: - with pytest.raises(httpx_auth.GrantNotProvided) as exception_info: + with httpx2.Client() as client: + with pytest.raises(httpx2_auth.GrantNotProvided) as exception_info: client.get("https://authorized_only", auth=auth) assert (