modular parser framework
This commit is contained in:
@@ -5,7 +5,7 @@ import json
|
||||
import os
|
||||
import pytest
|
||||
|
||||
from stw_potsdam.config import read_canteen_config
|
||||
from openmensa_parsers.config import read_canteen_config
|
||||
|
||||
|
||||
def _resource_path(filename):
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
import pytest
|
||||
|
||||
from openmensa_parsers.config import Canteen
|
||||
from openmensa_parsers.parsers.base import BaseOpenMensaParser, FeedDefinition
|
||||
from openmensa_parsers.parsers.registry import create_parser, get_parser_class
|
||||
from openmensa_parsers.parsers.potsdam import PotsdamParser
|
||||
from openmensa_parsers.views import app
|
||||
from openmensa_parsers.xml_types.builder import Builder
|
||||
from openmensa_parsers.xml_types.canteen_xml import CanteenMeta, CanteenXML
|
||||
from openmensa_parsers.xml_types.times_xml import CanteenOpenTimespec, TimesXML
|
||||
|
||||
|
||||
def _configured_canteen():
|
||||
return Canteen(
|
||||
key="demo",
|
||||
name="Demo Canteen",
|
||||
street="Demo Street",
|
||||
city="Demo City",
|
||||
id="1",
|
||||
chash="demo",
|
||||
)
|
||||
|
||||
|
||||
def _canteen_xml():
|
||||
meta = CanteenMeta(
|
||||
name="Demo Canteen",
|
||||
address="Demo Street, 12345 Demo City",
|
||||
city="Demo City",
|
||||
phone="+49 331 123456",
|
||||
email="demo@example.test",
|
||||
availability="public",
|
||||
)
|
||||
times = TimesXML({
|
||||
day: CanteenOpenTimespec("geschlossen")
|
||||
for day in TimesXML.VALID_DAYS
|
||||
})
|
||||
return CanteenXML(meta, times)
|
||||
|
||||
|
||||
class DemoParser(BaseOpenMensaParser):
|
||||
id = "demo"
|
||||
feed = FeedDefinition(source="https://example.test")
|
||||
|
||||
def __init__(self):
|
||||
self.fetched = False
|
||||
self.parsed_raw_data = None
|
||||
|
||||
def fetch(self):
|
||||
self.fetched = True
|
||||
return {"source": "fixture"}
|
||||
|
||||
def parse(self, _config, raw_data):
|
||||
self.parsed_raw_data = raw_data
|
||||
return {"demo": _canteen_xml()}
|
||||
|
||||
|
||||
def test_builder_uses_supplied_parser():
|
||||
parser = DemoParser()
|
||||
|
||||
with app.test_request_context():
|
||||
builder = Builder({"demo": _configured_canteen()}, parser=parser)
|
||||
|
||||
assert parser.fetched
|
||||
assert parser.parsed_raw_data == {"source": "fixture"}
|
||||
assert b"https://example.test" in builder.get_xml("demo")
|
||||
|
||||
|
||||
def test_builder_accepts_source_data_fixture():
|
||||
parser = DemoParser()
|
||||
|
||||
with app.test_request_context():
|
||||
Builder(
|
||||
{"demo": _configured_canteen()},
|
||||
source_data={"source": "test-fixture"},
|
||||
parser=parser,
|
||||
)
|
||||
|
||||
assert not parser.fetched
|
||||
assert parser.parsed_raw_data == {"source": "test-fixture"}
|
||||
|
||||
|
||||
def test_parser_registry_loads_default_parser():
|
||||
assert get_parser_class("potsdam") is PotsdamParser
|
||||
assert isinstance(create_parser("potsdam"), PotsdamParser)
|
||||
|
||||
|
||||
def test_parser_registry_rejects_unknown_parser():
|
||||
with pytest.raises(KeyError, match="Unknown parser"):
|
||||
create_parser("unknown")
|
||||
@@ -4,8 +4,8 @@ import json
|
||||
import logging
|
||||
import os
|
||||
import pytest
|
||||
from stw_potsdam.config import read_canteen_config
|
||||
from stw_potsdam.views import canteen_xml_feed, app
|
||||
from openmensa_parsers.config import read_canteen_config
|
||||
from openmensa_parsers.views import canteen_xml_feed, app
|
||||
|
||||
# pragma pylint: disable=invalid-name,redefined-outer-name
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
from stw_potsdam.swp_webspeiseplan_api import SWPWebspeiseplanAPI
|
||||
|
||||
# pytest fixtures are linked via parameter names of test methods
|
||||
# pragma pylint: disable=unused-import,unused-argument,redefined-outer-name
|
||||
from tests.stub_api import api_offline
|
||||
|
||||
|
||||
def test_api_init_does_not_fetch(api_offline):
|
||||
"""Creating the API client does not perform network requests."""
|
||||
SWPWebspeiseplanAPI()
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
import pytest
|
||||
|
||||
from stw_potsdam import views
|
||||
from openmensa_parsers import views
|
||||
|
||||
# pytest fixtures are linked via parameter names of test methods
|
||||
# pragma pylint: disable=unused-import,redefined-outer-name,unused-argument
|
||||
@@ -21,7 +21,7 @@ def test_health_check(client):
|
||||
assert response.data == b"OK"
|
||||
|
||||
|
||||
def test_index(client):
|
||||
def test_index(client, api_online_one_shot):
|
||||
response = client.get("/").json
|
||||
canteen_url = response.get("griebnitzsee", None)
|
||||
assert canteen_url, "Known canteen in index response"
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
import httpretty
|
||||
import pytest
|
||||
|
||||
from openmensa_parsers.webspeiseplan_api import WebspeiseplanAPI
|
||||
|
||||
# pytest fixtures are linked via parameter names of test methods
|
||||
# pragma pylint: disable=unused-import,unused-argument,redefined-outer-name
|
||||
from tests.stub_api import api_offline
|
||||
|
||||
|
||||
def test_api_init_does_not_fetch(api_offline):
|
||||
"""Creating the API client does not perform network requests."""
|
||||
WebspeiseplanAPI("https://menus.example.test")
|
||||
|
||||
|
||||
def test_api_init_requires_valid_base_url():
|
||||
"""Creating the API client validates the base URL."""
|
||||
with pytest.raises(ValueError):
|
||||
WebspeiseplanAPI("menus.example.test")
|
||||
|
||||
|
||||
def test_parse_token_uses_configured_base_url():
|
||||
"""The API client uses the configured Webspeiseplan host."""
|
||||
httpretty.enable(allow_net_connect=False)
|
||||
try:
|
||||
httpretty.register_uri(
|
||||
httpretty.GET,
|
||||
"https://menus.example.test",
|
||||
body='<script src="/main.abc123.js"></script>',
|
||||
)
|
||||
httpretty.register_uri(
|
||||
httpretty.GET,
|
||||
"https://menus.example.test/main.abc123.js",
|
||||
body='PROXY_TOKEN: "0123456789abcdef"',
|
||||
)
|
||||
|
||||
token = WebspeiseplanAPI("https://menus.example.test/").parse_token()
|
||||
finally:
|
||||
httpretty.disable()
|
||||
httpretty.reset()
|
||||
|
||||
assert token == "0123456789abcdef"
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
from stw_potsdam.swp_webspeiseplan_parser import SWPWebspeiseplanParser
|
||||
from openmensa_parsers.webspeiseplan_parser import WebspeiseplanParser
|
||||
|
||||
|
||||
def _menu_item(name):
|
||||
@@ -25,7 +25,7 @@ def _menu_item(name):
|
||||
|
||||
|
||||
def _parse_meal(name):
|
||||
parser = SWPWebspeiseplanParser()
|
||||
parser = WebspeiseplanParser()
|
||||
meals = parser.parse_meals(_menu_item(name), {1: {"name": "Salattheke"}})
|
||||
return meals[0]["meal"]
|
||||
|
||||
Reference in New Issue
Block a user