Skip to content

Commit

Permalink
add more stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
ogajduse committed Jul 16, 2023
1 parent 57be0dc commit 3a02068
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 71 deletions.
39 changes: 0 additions & 39 deletions .github/workflows/pull_request.yaml

This file was deleted.

6 changes: 6 additions & 0 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ jobs:
- name: Pre Commit Checks
uses: pre-commit/action@v3.0.0

- name: Collect Tests
run: pytest --collect-only tests

- name: Run Tests
run: pytest -sv tests/

- name: Analysis (git diff)
if: failure()
run: git diff
6 changes: 6 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ repos:
rev: "v1.4.1"
hooks:
- id: mypy
name: mypy feedparser
args: ["--ignore-missing-imports", "--scripts-are-modules", "custom_components/feedparser"]
additional_dependencies: [homeassistant-stubs, voluptuous-stubs, types-python-dateutil]
- id: mypy
name: mypy tests
args: ["--ignore-missing-imports", "--scripts-are-modules", "tests"]
additional_dependencies: [homeassistant-stubs, voluptuous-stubs, types-python-dateutil]
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
Expand Down
31 changes: 18 additions & 13 deletions custom_components/feedparser/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from __future__ import annotations

import logging
import re
from datetime import datetime, timedelta
from typing import TYPE_CHECKING

Expand All @@ -14,6 +13,7 @@
from homeassistant.util import dt

import feedparser
from feedparser import FeedParserDict

if TYPE_CHECKING:
from homeassistant.core import HomeAssistant
Expand All @@ -34,6 +34,7 @@
CONF_SHOW_TOPN = "show_topn"

DEFAULT_SCAN_INTERVAL = timedelta(hours=1)
DEFAULT_THUMBNAIL = "https://www.home-assistant.io/images/favicon-192x192-full.png"

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
Expand Down Expand Up @@ -84,9 +85,9 @@ def __init__(
name: str,
date_format: str,
show_topn: int,
exclusions: str,
inclusions: str,
scan_interval: int,
exclusions: list[str | None],
inclusions: list[str | None],
scan_interval: timedelta,
local_time: bool,
) -> None:
self._feed = feed
Expand All @@ -103,7 +104,7 @@ def __init__(

def update(self: FeedParserSensor) -> None:
"""Parse the feed and update the state of the sensor."""
parsed_feed = feedparser.parse(self._feed) # type: ignore [attr-defined]
parsed_feed: FeedParserDict = feedparser.parse(self._feed)

if not parsed_feed:
self._attr_native_value = None
Expand Down Expand Up @@ -135,18 +136,22 @@ def update(self: FeedParserSensor) -> None:
entry_value[key] = value

if "image" in self._inclusions and "image" not in entry_value.keys():
images = []
if "summary" in entry:
images = re.findall(
r"<img.+?src=\"(.+?)\".+?>",
entry["summary"],
)
if "enclosures" in entry:
images: list[FeedParserDict] = [
enc
for enc in entry["enclosures"]
if enc.type.startswith("image/")
]
else:
images = []
if images:
entry_value["image"] = images[0]
entry_value["image"] = images[0][
"href"
] # pick the first image found
else:
entry_value[
"image"
] = "https://www.home-assistant.io/images/favicon-192x192-full.png"
] = DEFAULT_THUMBNAIL # use default image if no image found

self._entries.append(entry_value)

Expand Down
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,7 @@ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

# Assume Python 3.11.
target-version = "py311"

[[tool.mypy.overrides]]
module = "feedparser.*"
ignore_missing_imports = true
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tests for the feedparser component."""
31 changes: 31 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""Pytest configuration."""
from pathlib import Path

import pytest
from pytest import FixtureRequest


def get_feeds() -> dict[str, str]:
"""Return dict of feed names and paths."""
fixtures_path = Path(__file__).parent / "fixtures"
feed_files = [f.name for f in fixtures_path.glob("*.xml")]
feeds = {}
for feed_file in feed_files:
feed_name = feed_file.split("-")[0]
feeds[feed_name] = f"file://{fixtures_path / feed_file}"
return feeds


def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
"""Generate tests and fixtures."""
if "feed_file" in metafunc.fixturenames:
feeds = get_feeds()
metafunc.parametrize(
"feed_file", feeds.values(), ids=feeds.keys(), indirect=True
)


@pytest.fixture
def feed_file(request: FixtureRequest) -> Path:
"""Return feed file."""
return Path(request.param)
22 changes: 12 additions & 10 deletions tests/fixtures/download.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
"""Download RSS feeds for testing."""
import asyncio
from datetime import date
from pathlib import Path

import aiohttp


base_date = date(2023, 7, 4)

feeds = [
{'name': 'CTK', 'url': 'https://www.ceskenoviny.cz/sluzby/rss/cr.php'},
{'name': 'nu-nl', 'url': 'https://www.nu.nl/rss'},
{'name': 'ct24', 'url': 'https://ct24.ceskatelevize.cz/rss/hlavni-zpravy'},
{'name': 'cd', 'url': 'https://www.cd.cz/rss/cdaktuality.rss'},
{'name': 'cez', 'url': 'https://www.cez.cz/rss/cs/tiskove_zpravy.xml'},
{'name': 'zive', 'url': 'https://www.zive.cz/rss/sc-47/'},
{"name": "CTK", "url": "https://www.ceskenoviny.cz/sluzby/rss/cr.php"},
{"name": "nu-nl", "url": "https://www.nu.nl/rss"},
{"name": "ct24", "url": "https://ct24.ceskatelevize.cz/rss/hlavni-zpravy"},
{"name": "cd", "url": "https://www.cd.cz/rss/cdaktuality.rss"},
{"name": "cez", "url": "https://www.cez.cz/rss/cs/tiskove_zpravy.xml"},
{"name": "zive", "url": "https://www.zive.cz/rss/sc-47/"},
]


async def run_feed(feed: dict):
async def run_feed(feed: dict) -> None:
"""Download feed."""
async with aiohttp.ClientSession() as session:
async with session.get(feed['url']) as response:
async with session.get(feed["url"]) as response:
text = await response.text()
file = Path(__file__).parent / f'{feed["name"]}-{base_date.isoformat()}.xml'
file.write_text(text)


async def run_all(feeds: list):
async def run_all(feeds: list) -> None:
"""Gather all feeds."""
await asyncio.gather(*[run_feed(feed) for feed in feeds])


Expand Down
18 changes: 9 additions & 9 deletions tests/test_sensors.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
""""Tests the feedparser sensor."""

from pathlib import Path

from custom_components.feedparser.sensor import DEFAULT_SCAN_INTERVAL
from custom_components.feedparser.sensor import FeedParserSensor
from custom_components.feedparser.sensor import DEFAULT_SCAN_INTERVAL, FeedParserSensor


def test_update_sensor():
def test_update_sensor(feed_file: Path) -> None:
"""Test instantiate sensor."""
fixtures_path = Path(__file__).parent / 'fixtures'
feed_file = next(fixtures_path.glob('nu*'))
feed_sensor = FeedParserSensor(
feed=f'file://{feed_file}',
name="Nu.nl",
date_format='%a, %d %b %Y %H:%M:%S %Z',
feed=f"file://{feed_file}",
name=feed_file.name.split("-")[0],
date_format="%a, %d %b %Y %H:%M:%S %Z",
local_time=False,
show_topn=9999,
inclusions=['image'],
inclusions=["image", "title", "link", "published"],
exclusions=[],
scan_interval=DEFAULT_SCAN_INTERVAL,
)
feed_sensor.update()
assert feed_sensor._entries
# assert that all entries have non-default image

0 comments on commit 3a02068

Please sign in to comment.