vws-python-mock 2026.2.22__tar.gz → 2026.2.22.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/CHANGELOG.rst +4 -0
  2. {vws_python_mock-2026.2.22/src/vws_python_mock.egg-info → vws_python_mock-2026.2.22.1}/PKG-INFO +1 -1
  3. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_requests_mock_server/decorators.py +2 -5
  4. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_respx_mock_server/decorators.py +3 -6
  5. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1/src/vws_python_mock.egg-info}/PKG-INFO +1 -1
  6. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_requests_mock_usage.py +44 -0
  7. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_respx_mock_usage.py +82 -1
  8. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/.git_archival.txt +0 -0
  9. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/.gitattributes +0 -0
  10. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/.github/dependabot.yml +0 -0
  11. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/.github/workflows/dependabot-merge.yml +0 -0
  12. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/.github/workflows/docker-build.yml +0 -0
  13. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/.github/workflows/lint.yml +0 -0
  14. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/.github/workflows/publish-site.yml +0 -0
  15. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/.github/workflows/release.yml +0 -0
  16. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/.github/workflows/test.yml +0 -0
  17. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/.gitignore +0 -0
  18. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/.pre-commit-config.yaml +0 -0
  19. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/.prettierrc +0 -0
  20. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/.vscode/extensions.json +0 -0
  21. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/.vscode/settings.json +0 -0
  22. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/CODE_OF_CONDUCT.rst +0 -0
  23. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/LICENSE +0 -0
  24. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/MANIFEST.in +0 -0
  25. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/README.rst +0 -0
  26. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/admin/__init__.py +0 -0
  27. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/admin/create_secrets_files.py +0 -0
  28. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/admin/vumark_template.svg +0 -0
  29. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/ci/__init__.py +0 -0
  30. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/ci/decrypt_secret.sh +0 -0
  31. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/ci/test_custom_linters.py +0 -0
  32. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/conftest.py +0 -0
  33. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/docker-bake.hcl +0 -0
  34. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/docs/source/__init__.py +0 -0
  35. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/docs/source/basic-example.rst +0 -0
  36. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/docs/source/changelog.rst +0 -0
  37. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/docs/source/ci-setup.rst +0 -0
  38. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/docs/source/conf.py +0 -0
  39. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/docs/source/contributing.rst +0 -0
  40. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/docs/source/differences-to-vws.rst +0 -0
  41. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/docs/source/docker.rst +0 -0
  42. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/docs/source/getting-started.rst +0 -0
  43. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/docs/source/httpx-example.rst +0 -0
  44. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/docs/source/index.rst +0 -0
  45. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/docs/source/installation.rst +0 -0
  46. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/docs/source/mock-api-reference.rst +0 -0
  47. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/docs/source/release-process.rst +0 -0
  48. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/docs/source/versioning-and-api-stability.rst +0 -0
  49. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/pyproject.toml +0 -0
  50. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/secrets.tar.gpg +0 -0
  51. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/setup.cfg +0 -0
  52. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/spelling_private_dict.txt +0 -0
  53. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/__init__.py +0 -0
  54. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_base64_decoding.py +0 -0
  55. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_constants.py +0 -0
  56. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_database_matchers.py +0 -0
  57. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_flask_server/Dockerfile +0 -0
  58. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_flask_server/__init__.py +0 -0
  59. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_flask_server/healthcheck.py +0 -0
  60. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_flask_server/target_manager.py +0 -0
  61. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_flask_server/vwq.py +0 -0
  62. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_flask_server/vws.py +0 -0
  63. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_mock_common.py +0 -0
  64. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_query_tools.py +0 -0
  65. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_query_validators/__init__.py +0 -0
  66. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_query_validators/accept_header_validators.py +0 -0
  67. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_query_validators/auth_validators.py +0 -0
  68. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_query_validators/content_length_validators.py +0 -0
  69. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_query_validators/content_type_validators.py +0 -0
  70. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_query_validators/date_validators.py +0 -0
  71. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_query_validators/exceptions.py +0 -0
  72. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_query_validators/fields_validators.py +0 -0
  73. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_query_validators/image_validators.py +0 -0
  74. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_query_validators/include_target_data_validators.py +0 -0
  75. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_query_validators/num_results_validators.py +0 -0
  76. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_query_validators/project_state_validators.py +0 -0
  77. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_requests_mock_server/__init__.py +0 -0
  78. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_requests_mock_server/mock_web_query_api.py +0 -0
  79. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_requests_mock_server/mock_web_services_api.py +0 -0
  80. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_respx_mock_server/__init__.py +0 -0
  81. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_services_validators/__init__.py +0 -0
  82. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_services_validators/active_flag_validators.py +0 -0
  83. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_services_validators/auth_validators.py +0 -0
  84. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_services_validators/content_length_validators.py +0 -0
  85. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_services_validators/content_type_validators.py +0 -0
  86. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_services_validators/date_validators.py +0 -0
  87. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_services_validators/exceptions.py +0 -0
  88. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_services_validators/image_validators.py +0 -0
  89. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_services_validators/json_validators.py +0 -0
  90. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_services_validators/key_validators.py +0 -0
  91. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_services_validators/metadata_validators.py +0 -0
  92. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_services_validators/name_validators.py +0 -0
  93. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_services_validators/project_state_validators.py +0 -0
  94. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_services_validators/target_validators.py +0 -0
  95. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/_services_validators/width_validators.py +0 -0
  96. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/database.py +0 -0
  97. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/database_type.py +0 -0
  98. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/image_matchers.py +0 -0
  99. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/py.typed +0 -0
  100. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/states.py +0 -0
  101. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/target.py +0 -0
  102. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/target_manager.py +0 -0
  103. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/mock_vws/target_raters.py +0 -0
  104. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/vws_python_mock.egg-info/SOURCES.txt +0 -0
  105. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/vws_python_mock.egg-info/dependency_links.txt +0 -0
  106. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/vws_python_mock.egg-info/not-zip-safe +0 -0
  107. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/vws_python_mock.egg-info/requires.txt +0 -0
  108. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/src/vws_python_mock.egg-info/top_level.txt +0 -0
  109. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/__init__.py +0 -0
  110. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/conftest.py +0 -0
  111. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/__init__.py +0 -0
  112. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/fixtures/__init__.py +0 -0
  113. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/fixtures/credentials.py +0 -0
  114. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/fixtures/prepared_requests.py +0 -0
  115. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/fixtures/vuforia_backends.py +0 -0
  116. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_add_target.py +0 -0
  117. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_authorization_header.py +0 -0
  118. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_content_length.py +0 -0
  119. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_database_summary.py +0 -0
  120. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_date_header.py +0 -0
  121. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_delete_target.py +0 -0
  122. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_docker.py +0 -0
  123. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_flask_app_usage.py +0 -0
  124. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_get_duplicates.py +0 -0
  125. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_get_target.py +0 -0
  126. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_invalid_given_id.py +0 -0
  127. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_invalid_json.py +0 -0
  128. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_query.py +0 -0
  129. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_target_list.py +0 -0
  130. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_target_raters.py +0 -0
  131. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_target_summary.py +0 -0
  132. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_target_validators.py +0 -0
  133. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_unexpected_json.py +0 -0
  134. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_update_target.py +0 -0
  135. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/test_vumark_generation_api.py +0 -0
  136. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/utils/__init__.py +0 -0
  137. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/utils/assertions.py +0 -0
  138. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/utils/retries.py +0 -0
  139. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/utils/too_many_requests.py +0 -0
  140. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/tests/mock_vws/utils/usage_test_helpers.py +0 -0
  141. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/vuforia_secrets.env.example +0 -0
  142. {vws_python_mock-2026.2.22 → vws_python_mock-2026.2.22.1}/zizmor.yml +0 -0
@@ -4,6 +4,10 @@ Changelog
4
4
  Next
5
5
  ----
6
6
 
7
+ 2026.02.22.1
8
+ ------------
9
+
10
+
7
11
  2026.02.22
8
12
  ----------
9
13
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vws-python-mock
3
- Version: 2026.2.22
3
+ Version: 2026.2.22.1
4
4
  Summary: A mock for the Vuforia Web Services (VWS) API.
5
5
  Author-email: Adam Dangoor <adamdangoor@gmail.com>
6
6
  License-Expression: MIT
@@ -5,7 +5,7 @@ import time
5
5
  from collections.abc import Callable, Mapping
6
6
  from contextlib import ContextDecorator
7
7
  from typing import Any, Literal, Self
8
- from urllib.parse import urljoin, urlparse
8
+ from urllib.parse import urlparse
9
9
 
10
10
  import requests
11
11
  from beartype import BeartypeConf, beartype
@@ -222,10 +222,7 @@ class MockVWS(ContextDecorator):
222
222
  (self._mock_vwq_api, self._base_vwq_url),
223
223
  ):
224
224
  for route in api.routes:
225
- url_pattern = urljoin(
226
- base=base_url,
227
- url=f"{route.path_pattern}$",
228
- )
225
+ url_pattern = base_url.rstrip("/") + route.path_pattern + "$"
229
226
  compiled_url_pattern = re.compile(pattern=url_pattern)
230
227
 
231
228
  for http_method in route.http_methods:
@@ -5,7 +5,7 @@ import time
5
5
  from collections.abc import Callable, Mapping
6
6
  from contextlib import ContextDecorator
7
7
  from typing import Literal, Self
8
- from urllib.parse import urljoin, urlparse
8
+ from urllib.parse import urlparse
9
9
 
10
10
  import httpx
11
11
  import respx
@@ -48,7 +48,7 @@ def _to_request_data(request: httpx.Request) -> RequestData:
48
48
  return RequestData(
49
49
  method=request.method,
50
50
  path=request.url.raw_path.decode(encoding="ascii"),
51
- headers=request.headers,
51
+ headers={k.title(): v for k, v in request.headers.items()},
52
52
  body=request.content,
53
53
  )
54
54
 
@@ -238,10 +238,7 @@ class MockVWSForHttpx(ContextDecorator):
238
238
  (self._mock_vwq_api, self._base_vwq_url),
239
239
  ):
240
240
  for route in api.routes:
241
- url_pattern = urljoin(
242
- base=base_url,
243
- url=f"{route.path_pattern}$",
244
- )
241
+ url_pattern = base_url.rstrip("/") + route.path_pattern + "$"
245
242
  compiled_url_pattern = re.compile(pattern=url_pattern)
246
243
 
247
244
  for http_method in route.http_methods:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vws-python-mock
3
- Version: 2026.2.22
3
+ Version: 2026.2.22.1
4
4
  Summary: A mock for the Vuforia Web Services (VWS) API.
5
5
  Author-email: Adam Dangoor <adamdangoor@gmail.com>
6
6
  License-Expression: MIT
@@ -347,6 +347,50 @@ class TestCustomBaseURLs:
347
347
  timeout=30,
348
348
  )
349
349
 
350
+ @staticmethod
351
+ def test_custom_base_vws_url_with_path_prefix() -> None:
352
+ """A custom base VWS URL with a path prefix intercepts at the
353
+ prefix.
354
+ """
355
+ with MockVWS(
356
+ base_vws_url="https://vuforia.vws.example.com/prefix",
357
+ real_http=False,
358
+ ):
359
+ with pytest.raises(
360
+ expected_exception=requests.exceptions.ConnectionError
361
+ ):
362
+ requests.get(
363
+ url="https://vuforia.vws.example.com/summary",
364
+ timeout=30,
365
+ )
366
+
367
+ requests.get(
368
+ url="https://vuforia.vws.example.com/prefix/summary",
369
+ timeout=30,
370
+ )
371
+
372
+ @staticmethod
373
+ def test_custom_base_vwq_url_with_path_prefix() -> None:
374
+ """A custom base VWQ URL with a path prefix intercepts at the
375
+ prefix.
376
+ """
377
+ with MockVWS(
378
+ base_vwq_url="https://vuforia.vwq.example.com/prefix",
379
+ real_http=False,
380
+ ):
381
+ with pytest.raises(
382
+ expected_exception=requests.exceptions.ConnectionError
383
+ ):
384
+ requests.post(
385
+ url="https://vuforia.vwq.example.com/v1/query",
386
+ timeout=30,
387
+ )
388
+
389
+ requests.post(
390
+ url="https://vuforia.vwq.example.com/prefix/v1/query",
391
+ timeout=30,
392
+ )
393
+
350
394
  @staticmethod
351
395
  def test_no_scheme() -> None:
352
396
  """An error if raised if a URL is given with no scheme."""
@@ -1,13 +1,17 @@
1
1
  """Tests for the usage of the mock for ``httpx`` via ``respx``."""
2
2
 
3
+ import json
3
4
  import socket
5
+ import uuid
6
+ from http import HTTPMethod, HTTPStatus
4
7
 
5
8
  import httpx
6
9
  import pytest
7
- from vws_auth_tools import rfc_1123_date
10
+ from vws_auth_tools import authorization_header, rfc_1123_date
8
11
 
9
12
  from mock_vws import MissingSchemeError, MockVWSForHttpx
10
13
  from mock_vws.database import CloudDatabase, VuMarkDatabase
14
+ from mock_vws.target import VuMarkTarget
11
15
 
12
16
 
13
17
  def _request_unmocked_address() -> None:
@@ -208,6 +212,46 @@ class TestCustomBaseURLs:
208
212
  timeout=30,
209
213
  )
210
214
 
215
+ @staticmethod
216
+ def test_custom_base_vws_url_with_path_prefix() -> None:
217
+ """A custom base VWS URL with a path prefix intercepts at the
218
+ prefix.
219
+ """
220
+ with MockVWSForHttpx(
221
+ base_vws_url="https://vuforia.vws.example.com/prefix",
222
+ real_http=False,
223
+ ):
224
+ with pytest.raises(expected_exception=httpx.ConnectError):
225
+ httpx.get(
226
+ url="https://vuforia.vws.example.com/summary",
227
+ timeout=30,
228
+ )
229
+
230
+ httpx.get(
231
+ url="https://vuforia.vws.example.com/prefix/summary",
232
+ timeout=30,
233
+ )
234
+
235
+ @staticmethod
236
+ def test_custom_base_vwq_url_with_path_prefix() -> None:
237
+ """A custom base VWQ URL with a path prefix intercepts at the
238
+ prefix.
239
+ """
240
+ with MockVWSForHttpx(
241
+ base_vwq_url="https://vuforia.vwq.example.com/prefix",
242
+ real_http=False,
243
+ ):
244
+ with pytest.raises(expected_exception=httpx.ConnectError):
245
+ httpx.post(
246
+ url="https://vuforia.vwq.example.com/v1/query",
247
+ timeout=30,
248
+ )
249
+
250
+ httpx.post(
251
+ url="https://vuforia.vwq.example.com/prefix/v1/query",
252
+ timeout=30,
253
+ )
254
+
211
255
  @staticmethod
212
256
  def test_no_scheme() -> None:
213
257
  """An error is raised if a URL is given with no scheme."""
@@ -348,3 +392,40 @@ class TestVWSEndpoints:
348
392
  )
349
393
  # We just verify we get a response (auth will fail but endpoint works)
350
394
  assert response.status_code is not None
395
+
396
+ @staticmethod
397
+ def test_vumark_bytes_response() -> None:
398
+ """The VuMark endpoint returns bytes content via httpx."""
399
+ vumark_target = VuMarkTarget(name="test-target")
400
+ database = VuMarkDatabase(vumark_targets={vumark_target})
401
+ target_id = vumark_target.target_id
402
+ request_path = f"/targets/{target_id}/instances"
403
+ content_type = "application/json"
404
+ content = json.dumps(obj={"instance_id": uuid.uuid4().hex}).encode(
405
+ encoding="utf-8"
406
+ )
407
+ date = rfc_1123_date()
408
+ auth = authorization_header(
409
+ access_key=database.server_access_key,
410
+ secret_key=database.server_secret_key,
411
+ method=HTTPMethod.POST,
412
+ content=content,
413
+ content_type=content_type,
414
+ date=date,
415
+ request_path=request_path,
416
+ )
417
+ with MockVWSForHttpx() as mock:
418
+ mock.add_vumark_database(vumark_database=database)
419
+ response = httpx.post(
420
+ url="https://vws.vuforia.com" + request_path,
421
+ headers={
422
+ "Accept": "image/png",
423
+ "Authorization": auth,
424
+ "Content-Length": str(object=len(content)),
425
+ "Content-Type": content_type,
426
+ "Date": date,
427
+ },
428
+ content=content,
429
+ timeout=30,
430
+ )
431
+ assert response.status_code == HTTPStatus.OK