Fix HTML entities in GWR advance ticket dates
This commit is contained in:
parent
e75acc3364
commit
69992bebb7
2 changed files with 25 additions and 5 deletions
|
|
@ -3,6 +3,7 @@
|
|||
import os
|
||||
import re
|
||||
from datetime import date, datetime
|
||||
from html import unescape
|
||||
from time import time
|
||||
|
||||
import httpx
|
||||
|
|
@ -12,6 +13,7 @@ url = "https://www.gwr.com/your-tickets/choosing-your-ticket/advance-tickets"
|
|||
|
||||
def parse_date_string(date_str: str) -> date:
|
||||
"""Parse date string from HTML."""
|
||||
date_str = " ".join(unescape(date_str).split())
|
||||
if not date_str[-1].isdigit(): # If the year is missing, use the current year
|
||||
date_str += f" {date.today().year}"
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
import os
|
||||
import tempfile
|
||||
import typing
|
||||
from datetime import date
|
||||
from typing import Any
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
|
|
@ -20,6 +20,16 @@ from agenda.gwr import (
|
|||
class TestParseDateString:
|
||||
"""Tests for parse_date_string function."""
|
||||
|
||||
@pytest.mark.parametrize("space", [" ", " ", " ", "\u00a0"])
|
||||
@pytest.mark.parametrize("include_year", [True, False])
|
||||
def test_parse_html_whitespace(self, space: str, include_year: bool) -> None:
|
||||
"""Decode HTML spaces before parsing dates or inferring the year."""
|
||||
date_str = f"Thursday 25{space}March"
|
||||
if include_year:
|
||||
date_str += " 2027"
|
||||
result = parse_date_string(f" {space}{date_str}{space} ")
|
||||
assert result == date(2027 if include_year else date.today().year, 3, 25)
|
||||
|
||||
def test_parse_date_with_year(self) -> None:
|
||||
"""Test parsing date string with year included."""
|
||||
result = parse_date_string("Monday 25 December 2023")
|
||||
|
|
@ -152,7 +162,7 @@ class TestAdvanceTicketsPageHtml:
|
|||
|
||||
@pytest.mark.asyncio
|
||||
@patch("httpx.AsyncClient")
|
||||
async def test_fetch_from_web(self, mock_client: Any) -> None:
|
||||
async def test_fetch_from_web(self, mock_client: typing.Any) -> None:
|
||||
"""Test fetching from web when cache is stale."""
|
||||
mock_response = AsyncMock()
|
||||
mock_response.text = "<html>fresh content</html>"
|
||||
|
|
@ -176,7 +186,7 @@ class TestAdvanceTicketDate:
|
|||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agenda.gwr.advance_tickets_page_html")
|
||||
async def test_advance_ticket_date_success(self, mock_html: Any) -> None:
|
||||
async def test_advance_ticket_date_success(self, mock_html: typing.Any) -> None:
|
||||
"""Test successfully extracting advance ticket date."""
|
||||
mock_html.return_value = """
|
||||
<tr><td>Weekdays</td><td>Monday 25 December 2023</td></tr>
|
||||
|
|
@ -188,7 +198,7 @@ class TestAdvanceTicketDate:
|
|||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agenda.gwr.advance_tickets_page_html")
|
||||
async def test_advance_ticket_date_no_match(self, mock_html: Any) -> None:
|
||||
async def test_advance_ticket_date_no_match(self, mock_html: typing.Any) -> None:
|
||||
"""Test when no weekday date can be extracted."""
|
||||
mock_html.return_value = "<p>No relevant data</p>"
|
||||
|
||||
|
|
@ -197,7 +207,7 @@ class TestAdvanceTicketDate:
|
|||
|
||||
@pytest.mark.asyncio
|
||||
@patch("agenda.gwr.advance_tickets_page_html")
|
||||
async def test_advance_ticket_date_force_cache(self, mock_html: Any) -> None:
|
||||
async def test_advance_ticket_date_force_cache(self, mock_html: typing.Any) -> None:
|
||||
"""Test advance_ticket_date with force_cache parameter."""
|
||||
mock_html.return_value = """
|
||||
<tr><td>Weekdays</td><td>Tuesday 26 December 2023</td></tr>
|
||||
|
|
@ -206,3 +216,11 @@ class TestAdvanceTicketDate:
|
|||
result = await advance_ticket_date("/fake/dir", force_cache=True)
|
||||
assert result == date(2023, 12, 26)
|
||||
mock_html.assert_called_once_with("/fake/dir", force_cache=True)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("suffix", ["", "**"])
|
||||
def test_extract_html_entity_date(suffix: str) -> None:
|
||||
"""Both extraction paths accept the date that caused the update crash."""
|
||||
html = f"<tr><td>Weekdays</td><td>Thursday 25 March 2027{suffix}</td></tr>"
|
||||
assert extract_dates(html) == {"Weekdays": date(2027, 3, 25)}
|
||||
assert extract_weekday_date(html) == date(2027, 3, 25)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue