Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions src/mock_vws/_requests_mock_server/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from collections.abc import Callable, Mapping
from contextlib import ContextDecorator
from typing import Any, Literal, Self
from urllib.parse import urljoin, urlparse
from urllib.parse import urlparse

import requests
from beartype import BeartypeConf, beartype
Expand Down Expand Up @@ -222,10 +222,7 @@ def __enter__(self) -> Self:
(self._mock_vwq_api, self._base_vwq_url),
):
for route in api.routes:
url_pattern = urljoin(
base=base_url,
url=f"{route.path_pattern}$",
)
url_pattern = base_url.rstrip("/") + route.path_pattern + "$"
compiled_url_pattern = re.compile(pattern=url_pattern)

for http_method in route.http_methods:
Expand Down
9 changes: 3 additions & 6 deletions src/mock_vws/_respx_mock_server/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from collections.abc import Callable, Mapping
from contextlib import ContextDecorator
from typing import Literal, Self
from urllib.parse import urljoin, urlparse
from urllib.parse import urlparse

import httpx
import respx
Expand Down Expand Up @@ -48,7 +48,7 @@ def _to_request_data(request: httpx.Request) -> RequestData:
return RequestData(
method=request.method,
path=request.url.raw_path.decode(encoding="ascii"),
headers=request.headers,
headers={k.title(): v for k, v in request.headers.items()},
body=request.content,
)

Expand Down Expand Up @@ -238,10 +238,7 @@ def __enter__(self) -> Self:
(self._mock_vwq_api, self._base_vwq_url),
):
for route in api.routes:
url_pattern = urljoin(
base=base_url,
url=f"{route.path_pattern}$",
)
url_pattern = base_url.rstrip("/") + route.path_pattern + "$"
compiled_url_pattern = re.compile(pattern=url_pattern)

for http_method in route.http_methods:
Expand Down
44 changes: 44 additions & 0 deletions tests/mock_vws/test_requests_mock_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,50 @@ def test_custom_base_vwq_url() -> None:
timeout=30,
)

@staticmethod
def test_custom_base_vws_url_with_path_prefix() -> None:
"""A custom base VWS URL with a path prefix intercepts at the
prefix.
"""
with MockVWS(
base_vws_url="https://vuforia.vws.example.com/prefix",
real_http=False,
):
with pytest.raises(
expected_exception=requests.exceptions.ConnectionError
):
requests.get(
url="https://vuforia.vws.example.com/summary",
timeout=30,
)

requests.get(
url="https://vuforia.vws.example.com/prefix/summary",
timeout=30,
)

@staticmethod
def test_custom_base_vwq_url_with_path_prefix() -> None:
"""A custom base VWQ URL with a path prefix intercepts at the
prefix.
"""
with MockVWS(
base_vwq_url="https://vuforia.vwq.example.com/prefix",
real_http=False,
):
with pytest.raises(
expected_exception=requests.exceptions.ConnectionError
):
requests.post(
url="https://vuforia.vwq.example.com/v1/query",
timeout=30,
)

requests.post(
url="https://vuforia.vwq.example.com/prefix/v1/query",
timeout=30,
)

@staticmethod
def test_no_scheme() -> None:
"""An error if raised if a URL is given with no scheme."""
Expand Down
83 changes: 82 additions & 1 deletion tests/mock_vws/test_respx_mock_usage.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
"""Tests for the usage of the mock for ``httpx`` via ``respx``."""

import json
import socket
import uuid
from http import HTTPMethod, HTTPStatus

import httpx
import pytest
from vws_auth_tools import rfc_1123_date
from vws_auth_tools import authorization_header, rfc_1123_date

from mock_vws import MissingSchemeError, MockVWSForHttpx
from mock_vws.database import CloudDatabase, VuMarkDatabase
from mock_vws.target import VuMarkTarget


def _request_unmocked_address() -> None:
Expand Down Expand Up @@ -208,6 +212,46 @@ def test_custom_base_vwq_url() -> None:
timeout=30,
)

@staticmethod
def test_custom_base_vws_url_with_path_prefix() -> None:
"""A custom base VWS URL with a path prefix intercepts at the
prefix.
"""
with MockVWSForHttpx(
base_vws_url="https://vuforia.vws.example.com/prefix",
real_http=False,
):
with pytest.raises(expected_exception=httpx.ConnectError):
httpx.get(
url="https://vuforia.vws.example.com/summary",
timeout=30,
)

httpx.get(
url="https://vuforia.vws.example.com/prefix/summary",
timeout=30,
)

@staticmethod
def test_custom_base_vwq_url_with_path_prefix() -> None:
"""A custom base VWQ URL with a path prefix intercepts at the
prefix.
"""
with MockVWSForHttpx(
base_vwq_url="https://vuforia.vwq.example.com/prefix",
real_http=False,
):
with pytest.raises(expected_exception=httpx.ConnectError):
httpx.post(
url="https://vuforia.vwq.example.com/v1/query",
timeout=30,
)

httpx.post(
url="https://vuforia.vwq.example.com/prefix/v1/query",
timeout=30,
)

@staticmethod
def test_no_scheme() -> None:
"""An error is raised if a URL is given with no scheme."""
Expand Down Expand Up @@ -348,3 +392,40 @@ def test_database_summary() -> None:
)
# We just verify we get a response (auth will fail but endpoint works)
assert response.status_code is not None

@staticmethod
def test_vumark_bytes_response() -> None:
"""The VuMark endpoint returns bytes content via httpx."""
vumark_target = VuMarkTarget(name="test-target")
database = VuMarkDatabase(vumark_targets={vumark_target})
target_id = vumark_target.target_id
request_path = f"/targets/{target_id}/instances"
content_type = "application/json"
content = json.dumps(obj={"instance_id": uuid.uuid4().hex}).encode(
encoding="utf-8"
)
date = rfc_1123_date()
auth = authorization_header(
access_key=database.server_access_key,
secret_key=database.server_secret_key,
method=HTTPMethod.POST,
content=content,
content_type=content_type,
date=date,
request_path=request_path,
)
with MockVWSForHttpx() as mock:
mock.add_vumark_database(vumark_database=database)
response = httpx.post(
url="https://vws.vuforia.com" + request_path,
headers={
"Accept": "image/png",
"Authorization": auth,
"Content-Length": str(object=len(content)),
"Content-Type": content_type,
"Date": date,
},
content=content,
timeout=30,
)
assert response.status_code == HTTPStatus.OK