Refactor create_pages.py and write tests
This commit is contained in:
192
tests/test_create_pages.py
Normal file
192
tests/test_create_pages.py
Normal file
@ -0,0 +1,192 @@
|
||||
import re
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import dateparser
|
||||
import interactions
|
||||
import pytz
|
||||
from apscheduler.job import Job
|
||||
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
|
||||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||
from interactions.ext.paginator import Page
|
||||
|
||||
from discord_reminder_bot.create_pages import (
|
||||
_get_pages,
|
||||
_get_pause_or_unpause_button,
|
||||
_get_row_of_buttons,
|
||||
_get_trigger_text,
|
||||
_make_button,
|
||||
_pause_job,
|
||||
_unpause_job,
|
||||
)
|
||||
from discord_reminder_bot.main import send_to_discord
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Generator
|
||||
|
||||
|
||||
def _test_pause_unpause_button(job: Job, button_label: str) -> None:
|
||||
button2: interactions.Button | None = _get_pause_or_unpause_button(job)
|
||||
assert button2
|
||||
assert button2.label == button_label
|
||||
assert button2.style == interactions.ButtonStyle.PRIMARY
|
||||
assert button2.type == interactions.ComponentType.BUTTON
|
||||
assert button2.emoji is None
|
||||
assert button2.custom_id == button_label.lower()
|
||||
assert button2.url is None
|
||||
assert button2.disabled is None
|
||||
|
||||
|
||||
class TestCountdown:
|
||||
jobstores: dict[str, SQLAlchemyJobStore] = {"default": SQLAlchemyJobStore(url="sqlite:///:memory")}
|
||||
job_defaults: dict[str, bool] = {"coalesce": True}
|
||||
scheduler = AsyncIOScheduler(
|
||||
jobstores=jobstores,
|
||||
timezone=pytz.timezone("Europe/Stockholm"),
|
||||
job_defaults=job_defaults,
|
||||
)
|
||||
|
||||
parsed_date: datetime | None = dateparser.parse(
|
||||
"18 January 2040",
|
||||
settings={
|
||||
"PREFER_DATES_FROM": "future",
|
||||
"TO_TIMEZONE": "Europe/Stockholm",
|
||||
},
|
||||
)
|
||||
assert parsed_date
|
||||
|
||||
run_date: str = parsed_date.strftime("%Y-%m-%d %H:%M:%S")
|
||||
normal_job: Job = scheduler.add_job(
|
||||
send_to_discord,
|
||||
run_date=run_date,
|
||||
kwargs={
|
||||
"channel_id": 865712621109772329,
|
||||
"message": "Running PyTest",
|
||||
"author_id": 126462229892694018,
|
||||
},
|
||||
)
|
||||
|
||||
cron_job: Job = scheduler.add_job(
|
||||
send_to_discord,
|
||||
"cron",
|
||||
minute="0",
|
||||
kwargs={
|
||||
"channel_id": 865712621109772329,
|
||||
"message": "Running PyTest",
|
||||
"author_id": 126462229892694018,
|
||||
},
|
||||
)
|
||||
|
||||
interval_job: Job = scheduler.add_job(
|
||||
send_to_discord,
|
||||
"interval",
|
||||
minutes=1,
|
||||
kwargs={
|
||||
"channel_id": 865712621109772329,
|
||||
"message": "Running PyTest",
|
||||
"author_id": 126462229892694018,
|
||||
},
|
||||
)
|
||||
|
||||
def test_get_trigger_text(self) -> None: # noqa: ANN101
|
||||
# FIXME: This try except train should be replaced with a better solution lol
|
||||
trigger_text: str = _get_trigger_text(self.normal_job)
|
||||
try:
|
||||
regex: str = r"2040-01-18 00:00 \(in \d+ days, \d+ hours, \d+ minutes\)"
|
||||
assert re.match(regex, trigger_text)
|
||||
except AssertionError:
|
||||
try:
|
||||
regex2: str = r"2040-01-18 00:00 \(in \d+ days, \d+ minutes\)"
|
||||
assert re.match(regex2, trigger_text)
|
||||
except AssertionError:
|
||||
regex3: str = r"2040-01-18 00:00 \(in \d+ days\, \d+ minutes\)"
|
||||
assert re.match(regex3, trigger_text)
|
||||
|
||||
def test_make_button(self) -> None: # noqa: ANN101
|
||||
button_name: str = "Test"
|
||||
|
||||
button: interactions.Button = _make_button(label=button_name, style=interactions.ButtonStyle.PRIMARY)
|
||||
assert button.label == button_name
|
||||
assert button.style == interactions.ButtonStyle.PRIMARY
|
||||
assert button.custom_id == button_name.lower()
|
||||
assert button.disabled is None
|
||||
assert button.emoji is None
|
||||
|
||||
def test_get_pause_or_unpause_button(self) -> None: # noqa: ANN101
|
||||
button: interactions.Button | None = _get_pause_or_unpause_button(self.normal_job)
|
||||
assert button is None
|
||||
|
||||
_test_pause_unpause_button(self.cron_job, "Pause")
|
||||
self.cron_job.pause()
|
||||
|
||||
_test_pause_unpause_button(self.cron_job, "Unpause")
|
||||
self.cron_job.resume()
|
||||
|
||||
_test_pause_unpause_button(self.interval_job, "Pause")
|
||||
self.interval_job.pause()
|
||||
|
||||
_test_pause_unpause_button(self.interval_job, "Unpause")
|
||||
self.interval_job.resume()
|
||||
|
||||
def test_get_row_of_buttons(self) -> None: # noqa: ANN101
|
||||
row: interactions.ActionRow = _get_row_of_buttons(self.normal_job)
|
||||
assert row
|
||||
assert row.components
|
||||
|
||||
# A normal job should have 2 buttons, edit and delete
|
||||
assert len(row.components) == 2 # noqa: PLR2004
|
||||
|
||||
row2: interactions.ActionRow = _get_row_of_buttons(self.cron_job)
|
||||
assert row2
|
||||
assert row2.components
|
||||
|
||||
# A cron job should have 3 buttons, edit, delete and pause/unpause
|
||||
assert len(row2.components) == 3 # noqa: PLR2004
|
||||
|
||||
# A cron job should have 3 buttons, edit, delete and pause/unpause
|
||||
assert len(row2.components) == 3 # noqa: PLR2004
|
||||
|
||||
def test_get_pages(self) -> None: # noqa: ANN101
|
||||
ctx = None # TODO: We should check ctx as well and not only channel id
|
||||
channel: interactions.Channel = interactions.Channel(id=interactions.Snowflake(865712621109772329))
|
||||
|
||||
pages: Generator[Page, None, None] = _get_pages(job=self.normal_job, channel=channel, ctx=ctx) # type: ignore # noqa: PGH003, E501
|
||||
assert pages
|
||||
|
||||
for page in pages:
|
||||
assert page
|
||||
assert page.title == "Running PyTest"
|
||||
assert page.components
|
||||
assert page.embeds
|
||||
assert page.embeds.fields is not None # type: ignore # noqa: PGH003
|
||||
assert page.embeds.fields[0].name == "**Channel:**" # type: ignore # noqa: PGH003
|
||||
assert page.embeds.fields[0].value == "#" # type: ignore # noqa: PGH003
|
||||
assert page.embeds.fields[1].name == "**Message:**" # type: ignore # noqa: PGH003
|
||||
assert page.embeds.fields[1].value == "Running PyTest" # type: ignore # noqa: PGH003
|
||||
assert page.embeds.fields[2].name == "**Trigger:**" # type: ignore # noqa: PGH003
|
||||
trigger_text: str = page.embeds.fields[2].value # type: ignore # noqa: PGH003
|
||||
|
||||
# FIXME: This try except train should be replaced with a better solution lol
|
||||
try:
|
||||
regex: str = r"2040-01-18 00:00 \(in \d+ days, \d+ hours, \d+ minutes\)"
|
||||
assert re.match(regex, trigger_text)
|
||||
except AssertionError:
|
||||
try:
|
||||
regex2: str = r"2040-01-18 00:00 \(in \d+ days, \d+ minutes\)"
|
||||
assert re.match(regex2, trigger_text)
|
||||
except AssertionError:
|
||||
regex3: str = r"2040-01-18 00:00 \(in \d+ days\, \d+ minutes\)"
|
||||
assert re.match(regex3, trigger_text)
|
||||
|
||||
# Check if type is Page
|
||||
assert isinstance(page, Page)
|
||||
|
||||
def test_pause_job(self) -> None: # noqa: ANN101
|
||||
assert _pause_job(self.interval_job, self.scheduler) == f"Job {self.interval_job.id} paused."
|
||||
assert _pause_job(self.cron_job, self.scheduler) == f"Job {self.cron_job.id} paused."
|
||||
assert _pause_job(self.normal_job, self.scheduler) == f"Job {self.normal_job.id} paused."
|
||||
|
||||
def test_unpause_job(self) -> None: # noqa: ANN101
|
||||
assert _unpause_job(self.interval_job, self.scheduler) == f"Job {self.interval_job.id} unpaused."
|
||||
assert _unpause_job(self.cron_job, self.scheduler) == f"Job {self.cron_job.id} unpaused."
|
||||
assert _unpause_job(self.normal_job, self.scheduler) == f"Job {self.normal_job.id} unpaused."
|
68
tests/test_parse.py
Normal file
68
tests/test_parse.py
Normal file
@ -0,0 +1,68 @@
|
||||
from datetime import datetime
|
||||
|
||||
import tzlocal
|
||||
|
||||
from discord_reminder_bot.parse import ParsedTime, parse_time
|
||||
|
||||
|
||||
def test_parse_time() -> None:
|
||||
"""Test the parse_time function."""
|
||||
parsed_time: ParsedTime = parse_time("18 January 2040")
|
||||
assert parsed_time.err is False
|
||||
assert not parsed_time.err_msg
|
||||
assert parsed_time.date_to_parse == "18 January 2040"
|
||||
assert parsed_time.parsed_time
|
||||
assert parsed_time.parsed_time.strftime("%Y-%m-%d %H:%M:%S") == "2040-01-18 00:00:00"
|
||||
|
||||
parsed_time: ParsedTime = parse_time("18 January 2040 12:00")
|
||||
assert parsed_time.err is False
|
||||
assert not parsed_time.err_msg
|
||||
assert parsed_time.date_to_parse == "18 January 2040 12:00"
|
||||
assert parsed_time.parsed_time
|
||||
assert parsed_time.parsed_time.strftime("%Y-%m-%d %H:%M:%S") == "2040-01-18 12:00:00"
|
||||
|
||||
parsed_time: ParsedTime = parse_time("18 January 2040 12:00:00")
|
||||
assert parsed_time.err is False
|
||||
assert not parsed_time.err_msg
|
||||
assert parsed_time.date_to_parse == "18 January 2040 12:00:00"
|
||||
assert parsed_time.parsed_time
|
||||
assert parsed_time.parsed_time.strftime("%Y-%m-%d %H:%M:%S") == "2040-01-18 12:00:00"
|
||||
|
||||
parsed_time: ParsedTime = parse_time("18 January 2040 12:00:00 UTC")
|
||||
assert parsed_time.err is False
|
||||
assert not parsed_time.err_msg
|
||||
assert parsed_time.date_to_parse == "18 January 2040 12:00:00 UTC"
|
||||
assert parsed_time.parsed_time
|
||||
assert parsed_time.parsed_time.strftime("%Y-%m-%d %H:%M:%S") == "2040-01-18 13:00:00"
|
||||
|
||||
parsed_time: ParsedTime = parse_time("18 January 2040 12:00:00 Europe/Stockholm")
|
||||
assert parsed_time.err is True
|
||||
assert parsed_time.err_msg == "Could not parse the date."
|
||||
assert parsed_time.date_to_parse == "18 January 2040 12:00:00 Europe/Stockholm"
|
||||
assert parsed_time.parsed_time is None
|
||||
|
||||
|
||||
def test_ParsedTime() -> None: # noqa: N802
|
||||
"""Test the ParsedTime class."""
|
||||
parsed_time: ParsedTime = ParsedTime(
|
||||
err=False,
|
||||
err_msg="",
|
||||
date_to_parse="18 January 2040",
|
||||
parsed_time=datetime(2040, 1, 18, 0, 0, 0, tzinfo=tzlocal.get_localzone()),
|
||||
)
|
||||
assert parsed_time.err is False
|
||||
assert not parsed_time.err_msg
|
||||
assert parsed_time.date_to_parse == "18 January 2040"
|
||||
assert parsed_time.parsed_time
|
||||
assert parsed_time.parsed_time.strftime("%Y-%m-%d %H:%M:%S") == "2040-01-18 00:00:00"
|
||||
|
||||
parsed_time: ParsedTime = ParsedTime(
|
||||
err=True,
|
||||
err_msg="Could not parse the date.",
|
||||
date_to_parse="18 January 2040 12:00:00 Europe/Stockholm",
|
||||
parsed_time=None,
|
||||
)
|
||||
assert parsed_time.err is True
|
||||
assert parsed_time.err_msg == "Could not parse the date."
|
||||
assert parsed_time.date_to_parse == "18 January 2040 12:00:00 Europe/Stockholm"
|
||||
assert parsed_time.parsed_time is None
|
Reference in New Issue
Block a user