"""Tests for the Catalogue class, which interacts with the library catalogue.""" from unittest.mock import MagicMock import pytest import requests from pytest_mock import MockerFixture from bibapi.catalogue import Catalogue class TestCatalogue: """Tests for the Catalogue class.""" def test_catalogue_initialization(self, mocker: MockerFixture): """Test Catalogue initialization.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) catalogue = Catalogue() assert catalogue.timeout == 15 def test_catalogue_custom_timeout(self, mocker: MockerFixture): """Test Catalogue initialization with custom timeout.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) catalogue = Catalogue(timeout=30) assert catalogue.timeout == 30 def test_check_book_exists(self, mocker: MockerFixture): """Test the check_book_exists method of the Catalogue class.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) catalogue = Catalogue() # Mock the get_book_links method to control its output mocker.patch.object( catalogue, "get_book_links", return_value=["link1", "link2"], ) # Test with a known existing book existing_book_searchterm = "1693321114" assert catalogue.check_book_exists(existing_book_searchterm) is True # Change the mock to return an empty list for non-existing book mocker.patch.object( catalogue, "get_book_links", return_value=[], ) # Test with a known non-existing book non_existing_book_searchterm = "00000000009" assert catalogue.check_book_exists(non_existing_book_searchterm) is False def test_no_connection_raises_error(self, mocker: MockerFixture): """Test that a ConnectionError is raised with no internet connection.""" # Mock the check_connection method to simulate no internet connection mocker.patch.object( Catalogue, "check_connection", return_value=False, ) with pytest.raises(ConnectionError, match="No internet connection available."): Catalogue() def test_check_connection_success(self, mocker: MockerFixture): """Test check_connection returns True on success.""" mock_response = MagicMock() mock_response.status_code = 200 mocker.patch("requests.get", return_value=mock_response) catalogue = Catalogue.__new__(Catalogue) catalogue.timeout = 15 assert catalogue.check_connection() is True def test_check_connection_failure(self, mocker: MockerFixture): """Test check_connection handles request exception.""" mocker.patch( "requests.get", side_effect=requests.exceptions.RequestException("Network error"), ) catalogue = Catalogue.__new__(Catalogue) catalogue.timeout = 15 result = catalogue.check_connection() assert result is None # Returns None on exception def test_search_book(self, mocker: MockerFixture): """Test search_book method.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) mock_response = MagicMock() mock_response.text = "search results" mocker.patch("requests.get", return_value=mock_response) catalogue = Catalogue() result = catalogue.search_book("test search") assert result == "search results" def test_search(self, mocker: MockerFixture): """Test search method.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) mock_response = MagicMock() mock_response.text = "detail page" mocker.patch("requests.get", return_value=mock_response) catalogue = Catalogue() result = catalogue.search("https://example.com/book/123") assert result == "detail page" def test_get_book_links(self, mocker: MockerFixture, mock_catalogue_html): """Test get_book_links method.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) mocker.patch.object( Catalogue, "search_book", return_value=mock_catalogue_html, ) catalogue = Catalogue() links = catalogue.get_book_links("test search") assert len(links) == 1 assert "https://rds.ibs-bw.de/opac/record/123" in links[0] def test_in_library_with_ppn(self, mocker: MockerFixture): """Test in_library method with valid PPN.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) mocker.patch.object( Catalogue, "get_book_links", return_value=["link1"], ) catalogue = Catalogue() assert catalogue.in_library("123456789") is True def test_in_library_without_ppn(self, mocker: MockerFixture): """Test in_library method with None PPN.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) catalogue = Catalogue() assert catalogue.in_library(None) is False def test_in_library_not_found(self, mocker: MockerFixture): """Test in_library method when book not found.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) mocker.patch.object( Catalogue, "get_book_links", return_value=[], ) catalogue = Catalogue() assert catalogue.in_library("nonexistent") is False def test_get_location_none_ppn(self, mocker: MockerFixture): """Test get_location method with None PPN.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) catalogue = Catalogue() assert catalogue.get_location(None) is None def test_get_location_not_found(self, mocker: MockerFixture): """Test get_location when book not found.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) mocker.patch.object(Catalogue, "get_book", return_value=None) catalogue = Catalogue() assert catalogue.get_location("123") is None def test_get_ppn(self, mocker: MockerFixture): """Test get_ppn method with valid PPN format.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) mocker.patch.object( Catalogue, "get_book_links", return_value=["https://example.com/opac/record/1234567890"], ) mocker.patch.object(Catalogue, "search", return_value="") catalogue = Catalogue() ppn = catalogue.get_ppn("test") assert ppn == "1234567890" def test_get_ppn_with_x(self, mocker: MockerFixture): """Test get_ppn method with PPN ending in X.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) mocker.patch.object( Catalogue, "get_book_links", return_value=["https://example.com/opac/record/123456789X"], ) mocker.patch.object(Catalogue, "search", return_value="") catalogue = Catalogue() ppn = catalogue.get_ppn("test") assert ppn == "123456789X" def test_get_semesterapparat_number(self, mocker: MockerFixture): """Test get_semesterapparat_number method.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) mocker.patch.object( Catalogue, "get_book_links", return_value=["https://example.com/book"], ) html = """
Semesterapparat-42
""" mocker.patch.object(Catalogue, "search", return_value=html) catalogue = Catalogue() result = catalogue.get_semesterapparat_number("test") assert result == 42 def test_get_semesterapparat_number_handbibliothek(self, mocker: MockerFixture): """Test get_semesterapparat_number with Handbibliothek location.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) mocker.patch.object( Catalogue, "get_book_links", return_value=["https://example.com/book"], ) html = """
Floor 1 Handbibliothek-Reference
""" mocker.patch.object(Catalogue, "search", return_value=html) catalogue = Catalogue() result = catalogue.get_semesterapparat_number("test") assert "Reference" in str(result) or "Handbibliothek" in str(result) def test_get_semesterapparat_number_not_found(self, mocker: MockerFixture): """Test get_semesterapparat_number when not found.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) mocker.patch.object(Catalogue, "get_book_links", return_value=[]) catalogue = Catalogue() result = catalogue.get_semesterapparat_number("test") assert result == 0 def test_get_author(self, mocker: MockerFixture): """Test get_author method.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) mocker.patch.object( Catalogue, "get_book_links", return_value=["https://example.com/book"], ) html = """
Author One Author Two
""" mocker.patch.object(Catalogue, "search", return_value=html) catalogue = Catalogue() author = catalogue.get_author("kid:123") assert "Author One" in author assert "Author Two" in author assert "; " in author # Separator def test_get_signature(self, mocker: MockerFixture): """Test get_signature method.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) mocker.patch.object( Catalogue, "get_book_links", return_value=["https://example.com/book"], ) html = """
ABC 123
Available
Semesterapparat-1
""" mocker.patch.object(Catalogue, "search", return_value=html) catalogue = Catalogue() signature = catalogue.get_signature("9783123456789") assert signature == "ABC 123" def test_get_signature_not_found(self, mocker: MockerFixture): """Test get_signature when not found.""" mocker.patch.object(Catalogue, "check_connection", return_value=True) mocker.patch.object(Catalogue, "get_book_links", return_value=[]) catalogue = Catalogue() signature = catalogue.get_signature("nonexistent") assert signature is None