Skip to content

Commit

Permalink
Bug fixes (#113)
Browse files Browse the repository at this point in the history
* added ignore flake8 F401 for test_bookops_worldcat

* added types-pyyaml as dev dependency

* added type annotations removed unnecessary imports

* deleted test.mrc as it is now redundant

* fixed typo in import statement

* exported updated dev-requirements.txt

* added 3.13 to unit-tests.yaml

* fixed live_keys fixture for GITHUB_ACTIONS
  • Loading branch information
charlottekostelic authored Nov 7, 2024
1 parent 1bcfb7c commit 7403136
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 66 deletions.
3 changes: 2 additions & 1 deletion .flake8
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[flake8]
per-file-ignores =
tests/*:E501, W503
tests/*:E501, W503
tests/test_bookops_worldcat.py: F401
2 changes: 1 addition & 1 deletion .github/workflows/unit-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version}}
Expand Down
2 changes: 1 addition & 1 deletion bookops_worldcat/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from typing import Union, Tuple, TYPE_CHECKING
import sys

from requests.models import PreparedRequest
from requests import PreparedRequest
from requests.exceptions import ConnectionError, HTTPError, Timeout, RetryError
from .errors import WorldcatRequestError

Expand Down
3 changes: 3 additions & 0 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,9 @@ six==1.16.0 ; python_version >= "3.8" and python_version < "4.0" \
tomli==2.0.1 ; python_version >= "3.8" and python_full_version <= "3.11.0a6" \
--hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
--hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
types-pyyaml==6.0.12.20240917 ; python_version >= "3.8" and python_version < "4.0" \
--hash=sha256:392b267f1c0fe6022952462bf5d6523f31e37f6cea49b14cee7ad634b6301570 \
--hash=sha256:d1405a86f9576682234ef83bcb4e6fff7c9305c8b1fbad5e0bcd4f7dbdc9c587
types-requests==2.31.0.20240125 ; python_version >= "3.8" and python_version < "4.0" \
--hash=sha256:03a28ce1d7cd54199148e043b2079cdded22d6795d19a2c2a6791a4b2b5e2eb5 \
--hash=sha256:9592a9a4cb92d6d75d9b491a41477272b710e021011a2a3061157e2fb1f1a5d1
Expand Down
13 changes: 12 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ types-requests = "^2.31.0.20240125"
mkdocs-material = "^9.5.13"
mkdocstrings = "^0.24.1"
mkdocstrings-python = "^1.9.0"
types-pyyaml = "^6.0.12.20240917"

[tool.pytest.ini_options]
testpaths = ["tests"]
Expand Down
88 changes: 27 additions & 61 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@
import datetime
import json
import os

from typing import Dict, Generator, Union
import pytest
import requests

from requests import Response

from bookops_worldcat import WorldcatAccessToken, MetadataSession


@pytest.fixture
def live_keys():
if os.name == "nt":
if os.name == "nt" and not os.getenv("GITHUB_ACTIONS"):
fh = os.path.join(os.environ["USERPROFILE"], ".oclc/nyp_wc_test.json")
with open(fh, "r") as file:
data = json.load(file)
Expand All @@ -24,25 +22,20 @@ def live_keys():


@pytest.fixture
def stub_marc_xml():
def stub_marc_xml() -> str:
stub_marc_xml = "<record><leader>00000nam a2200000 a 4500</leader><controlfield tag='008'>120827s2012 nyua 000 0 eng d</controlfield><datafield tag='010' ind1=' ' ind2=' '><subfield code='a'> 63011276 </subfield></datafield><datafield tag='035' ind1=' ' ind2=' '><subfield code='a'>ocn850940548</subfield></datafield><datafield tag='040' ind1=' ' ind2=' '><subfield code='a'>OCWMS</subfield><subfield code='b'>eng</subfield><subfield code='c'>OCWMS</subfield></datafield><datafield tag='100' ind1='0' ind2=' '><subfield code='a'>OCLC Developer Network</subfield></datafield><datafield tag='245' ind1='1' ind2='0'><subfield code='a'>Test Record</subfield></datafield><datafield tag='500' ind1=' ' ind2=' '><subfield code='a'>FOR OCLC DEVELOPER NETWORK DOCUMENTATION</subfield></datafield></record>"
return stub_marc_xml


@pytest.fixture
def stub_holding_xml():
def stub_holding_xml() -> str:
stub_holding_xml = "<record><leader>00000nx a2200000zi 4500</leader><controlfield tag='004'>312010</controlfield><controlfield tag='007'>zu</controlfield><controlfield tag='008'>1103280p 0 4001uueng0210908</controlfield><datafield ind2=' ' ind1=' ' tag='852'><subfield code='a'>OCWMS</subfield><subfield code='b'>EAST</subfield><subfield code='c'>EAST-STACKS</subfield></datafield><datafield ind2=' ' ind1=' ' tag='876'><subfield code='p'>879456</subfield></datafield></record>"
return stub_holding_xml


@pytest.fixture
def stub_marc21():
fh = os.path.join(
os.environ["USERPROFILE"], "github/bookops-worldcat/tests/test.mrc"
)
with open(fh, "rb") as stub:
stub_marc21 = stub.read()
return stub_marc21
def stub_marc21() -> bytes:
return b"00266nam a2200097 a 4500008004100000010001700041040002200058100002700080245001600107500004500123\x1e120827s2012 nyua 000 0 eng d\x1e \x1fa 63011276 \x1e \x1faOCWMS\x1fbeng\x1fcOCWMS\x1e0 \x1faOCLC Developer Network\x1e10\x1faTest Record\x1e \x1faFOR OCLC DEVELOPER NETWORK DOCUMENTATION\x1e\x1d"


class FakeUtcNow(datetime.datetime):
Expand All @@ -59,10 +52,10 @@ def mock_now(monkeypatch):
class MockAuthServerResponseSuccess:
"""Simulates auth server response to successful token request"""

def __init__(self):
def __init__(self) -> None:
self.status_code = 200

def json(self):
def json(self) -> Dict[str, str]:
expires_at = datetime.datetime.strftime(
datetime.datetime.now() + datetime.timedelta(0, 1199),
"%Y-%m-%d %H:%M:%SZ",
Expand All @@ -84,11 +77,11 @@ def json(self):
class MockAuthServerResponseFailure:
"""Simulates auth server response to successful token request"""

def __init__(self):
def __init__(self) -> None:
self.status_code = 403
self.content = b""

def json(self):
def json(self) -> Dict[str, Union[str, int]]:
return {
"code": 403,
"message": "Invalid scope(s): invalid (invalid) [Invalid service specified, Not on key]",
Expand All @@ -98,38 +91,38 @@ def json(self):
class MockServiceErrorResponse:
"""Simulates web service error responses"""

def __init__(self, code, json_response, url):
def __init__(self, code, json_response, url) -> None:
self.status_code = code
self.msg = json_response
self.url = url
self.text = f"{json_response}"

def json(self):
def json(self) -> Dict[str, str]:
return self.msg


class MockUnexpectedException:
def __init__(self, *args, **kwargs):
def __init__(self, *args, **kwargs) -> None:
raise Exception


class MockTimeout:
def __init__(self, *args, **kwargs):
def __init__(self, *args, **kwargs) -> None:
raise requests.exceptions.Timeout


class MockConnectionError:
def __init__(self, *args, **kwargs):
def __init__(self, *args, **kwargs) -> None:
raise requests.exceptions.ConnectionError


class MockRetryError:
def __init__(self, *args, **kwargs):
def __init__(self, *args, **kwargs) -> None:
raise requests.exceptions.RetryError


class MockHTTPSessionResponse(Response):
def __init__(self, http_code):
class MockHTTPSessionResponse(requests.Response):
def __init__(self, http_code) -> None:
self.status_code = http_code
self.reason = "'foo'"
self.url = "https://foo.bar?query"
Expand All @@ -156,7 +149,7 @@ def mock_api_response(*args, http_code=http_code, **kwargs):


@pytest.fixture
def mock_credentials():
def mock_credentials() -> Dict[str, str]:
return {
"key": "my_WSkey",
"secret": "my_WSsecret",
Expand All @@ -165,7 +158,9 @@ def mock_credentials():


@pytest.fixture
def mock_oauth_server_response(mock_now, *args, **kwargs):
def mock_oauth_server_response(
mock_now, *args, **kwargs
) -> MockAuthServerResponseSuccess:
return MockAuthServerResponseSuccess()


Expand Down Expand Up @@ -214,18 +209,20 @@ def mock_retry_error(monkeypatch):


@pytest.fixture
def mock_token(mock_credentials, mock_successful_post_token_response):
def mock_token(
mock_credentials, mock_successful_post_token_response
) -> WorldcatAccessToken:
return WorldcatAccessToken(**mock_credentials)


@pytest.fixture
def stub_session(mock_token):
def stub_session(mock_token) -> Generator[MetadataSession, None, None]:
with MetadataSession(authorization=mock_token) as session:
yield session


@pytest.fixture
def stub_retry_session(mock_token):
def stub_retry_session(mock_token) -> Generator[MetadataSession, None, None]:
with MetadataSession(
authorization=mock_token,
totalRetries=3,
Expand All @@ -234,34 +231,3 @@ def stub_retry_session(mock_token):
allowedMethods=["GET", "POST", "PUT"],
) as session:
yield session


@pytest.fixture
def mock_400_response(monkeypatch):
def mock_api_response(*args, **kwargs):
msg = {
"type": "MISSING_QUERY_PARAMETER",
"title": "Validation Failure",
"detail": "details here",
}
url = "https://test.org/some_endpoint"
return MockServiceErrorResponse(code=400, json_response=msg, url=url)

monkeypatch.setattr(requests.Session, "get", mock_api_response)
monkeypatch.setattr(requests.Session, "post", mock_api_response)
monkeypatch.setattr(requests.Session, "delete", mock_api_response)


@pytest.fixture
def mock_409_response(monkeypatch):
def mock_api_response(*args, **kwargs):
msg = {
"code": {"value": "WS-409", "type": "application"},
"message": "Trying to set hold while holding already exists",
"detail": None,
}
url = "https://test.org/some_endpoint"
return MockServiceErrorResponse(code=409, json_response=msg, url=url)

monkeypatch.setattr(requests.Session, "post", mock_api_response)
monkeypatch.setattr(requests.Session, "delete", mock_api_response)
1 change: 0 additions & 1 deletion tests/test.mrc

This file was deleted.

0 comments on commit 7403136

Please sign in to comment.