From 4f194ab01cdbecf1cdb5cadc4e426071d0317989 Mon Sep 17 00:00:00 2001 From: Simone Robutti Date: Wed, 5 May 2021 14:29:13 +0200 Subject: [PATCH] added tests for strategy --- mobilizon_bots/event/event.py | 2 ++ mobilizon_bots/models/event.py | 2 +- mobilizon_bots/storage/db.py | 1 + poetry.lock | 46 +------------------------ pyproject.toml | 1 - tests/__init__.py | 33 ------------------ tests/configtest.py | 14 -------- tests/conftest.py | 50 +++++++++++++++++++++++++++ tests/event/event_selector.py | 13 +++---- tests/event/test_event.py | 26 -------------- tests/event/test_strategies.py | 63 +++++++++++++++++++++++++++++----- 11 files changed, 117 insertions(+), 134 deletions(-) delete mode 100644 tests/configtest.py create mode 100644 tests/conftest.py diff --git a/mobilizon_bots/event/event.py b/mobilizon_bots/event/event.py index fedd368..89875fa 100644 --- a/mobilizon_bots/event/event.py +++ b/mobilizon_bots/event/event.py @@ -1,8 +1,10 @@ from __future__ import annotations + from dataclasses import dataclass, asdict from datetime import datetime from enum import Enum from typing import Optional + from jinja2 import Template diff --git a/mobilizon_bots/models/event.py b/mobilizon_bots/models/event.py index c6dde35..038d9c1 100644 --- a/mobilizon_bots/models/event.py +++ b/mobilizon_bots/models/event.py @@ -1,5 +1,5 @@ -from tortoise.models import Model from tortoise import fields +from tortoise.models import Model class Event(Model): diff --git a/mobilizon_bots/storage/db.py b/mobilizon_bots/storage/db.py index f287209..2b556a4 100644 --- a/mobilizon_bots/storage/db.py +++ b/mobilizon_bots/storage/db.py @@ -1,4 +1,5 @@ from pathlib import Path + from tortoise import Tortoise diff --git a/poetry.lock b/poetry.lock index 028610e..d148a88 100644 --- a/poetry.lock +++ b/poetry.lock @@ -56,34 +56,6 @@ toml = ["toml"] vault = ["hvac"] yaml = ["ruamel.yaml"] -[[package]] -name = "hypothesis" -version = "6.10.1" -description = "A library for property-based testing" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -attrs = ">=19.2.0" -sortedcontainers = ">=2.1.0,<3.0.0" - -[package.extras] -all = ["black (>=19.10b0)", "click (>=7.0)", "django (>=2.2)", "dpcontracts (>=0.4)", "lark-parser (>=0.6.5)", "libcst (>=0.3.16)", "numpy (>=1.9.0)", "pandas (>=0.25)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "importlib-resources (>=3.3.0)", "importlib-metadata (>=3.6)", "backports.zoneinfo (>=0.2.1)", "tzdata (>=2020.4)"] -cli = ["click (>=7.0)", "black (>=19.10b0)", "rich (>=9.0.0)"] -codemods = ["libcst (>=0.3.16)"] -dateutil = ["python-dateutil (>=1.4)"] -django = ["pytz (>=2014.1)", "django (>=2.2)"] -dpcontracts = ["dpcontracts (>=0.4)"] -ghostwriter = ["black (>=19.10b0)"] -lark = ["lark-parser (>=0.6.5)"] -numpy = ["numpy (>=1.9.0)"] -pandas = ["pandas (>=0.25)"] -pytest = ["pytest (>=4.6)"] -pytz = ["pytz (>=2014.1)"] -redis = ["redis (>=3.0.0)"] -zoneinfo = ["importlib-resources (>=3.3.0)", "backports.zoneinfo (>=0.2.1)", "tzdata (>=2020.4)"] - [[package]] name = "iso8601" version = "0.1.14" @@ -198,14 +170,6 @@ category = "main" optional = false python-versions = "*" -[[package]] -name = "sortedcontainers" -version = "2.3.0" -description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" -category = "dev" -optional = false -python-versions = "*" - [[package]] name = "tortoise-orm" version = "0.17.2" @@ -246,7 +210,7 @@ python-versions = "*" [metadata] lock-version = "1.1" python-versions = "^3.9" -content-hash = "f78f8e295d8c94dfe0e4e0f29ce5056f5cea948037cc62b9903b6bc8263a0db6" +content-hash = "2a9d2f27ed4c4197d4dd022c2e1f8968ef7fff2ab73145a4bd74712f35d88855" [metadata.files] aiosqlite = [ @@ -269,10 +233,6 @@ dynaconf = [ {file = "dynaconf-3.1.4-py2.py3-none-any.whl", hash = "sha256:e6f383b84150b70fc439c8b2757581a38a58d07962aa14517292dcce1a77e160"}, {file = "dynaconf-3.1.4.tar.gz", hash = "sha256:b2f472d83052f809c5925565b8a2ba76a103d5dc1dbb9748b693ed67212781b9"}, ] -hypothesis = [ - {file = "hypothesis-6.10.1-py3-none-any.whl", hash = "sha256:1d65f58d82d1cbd35b6441bda3bb11cb1adc879d6b2af191aea388fa412171b1"}, - {file = "hypothesis-6.10.1.tar.gz", hash = "sha256:586b6c46e90878c2546743afbed348bca51e1f30e3461fa701fad58c2c47c650"}, -] iso8601 = [ {file = "iso8601-0.1.14-py2.py3-none-any.whl", hash = "sha256:e7e1122f064d626e17d47cd5106bed2c620cb38fe464999e0ddae2b6d2de6004"}, {file = "iso8601-0.1.14.tar.gz", hash = "sha256:8aafd56fa0290496c5edbb13c311f78fa3a241f0853540da09d9363eae3ebd79"}, @@ -343,10 +303,6 @@ pytz = [ {file = "pytz-2020.5-py2.py3-none-any.whl", hash = "sha256:16962c5fb8db4a8f63a26646d8886e9d769b6c511543557bc84e9569fb9a9cb4"}, {file = "pytz-2020.5.tar.gz", hash = "sha256:180befebb1927b16f6b57101720075a984c019ac16b1b7575673bea42c6c3da5"}, ] -sortedcontainers = [ - {file = "sortedcontainers-2.3.0-py2.py3-none-any.whl", hash = "sha256:37257a32add0a3ee490bb170b599e93095eed89a55da91fa9f48753ea12fd73f"}, - {file = "sortedcontainers-2.3.0.tar.gz", hash = "sha256:59cc937650cf60d677c16775597c89a960658a09cf7c1a668f86e1e4464b10a1"}, -] tortoise-orm = [ {file = "tortoise-orm-0.17.2.tar.gz", hash = "sha256:1a742b2f15a31d47a8dea7706b478cc9a7ce9af268b61d77d0fa22cfbaea271a"}, {file = "tortoise_orm-0.17.2-py3-none-any.whl", hash = "sha256:b0c02be3800398053058377ddca91fa051eb98eebb704d2db2a3ab1c6a58e347"}, diff --git a/pyproject.toml b/pyproject.toml index 8d67d2b..c243b95 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,6 @@ Jinja2 = "^2.11.3" [tool.poetry.dev-dependencies] pytest = "^5.2" -hypothesis = "^6.10.1" [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/tests/__init__.py b/tests/__init__.py index af165a0..e69de29 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,33 +0,0 @@ -import hypothesis -from hypothesis import assume -from hypothesis.provisional import urls -from hypothesis.strategies import characters, datetimes, text, sampled_from - -from mobilizon_bots.event.event import MobilizonEvent, PublicationStatus - - -@hypothesis.strategies.composite -def events(draw, published: bool = False): - begin_datetime = draw(datetimes()) - end_datetime = draw(datetimes()) - assume(begin_datetime < end_datetime) - - return MobilizonEvent( - name=draw(characters()), - description=draw(text()), - begin_datetime=begin_datetime, - end_datetime=end_datetime, - last_accessed=draw(datetimes()), - mobilizon_link=draw(urls()), - mobilizon_id=draw(characters()), - thumbnail_link=draw(urls()), - location=draw(text()), - publication_time=draw(datetimes()) if published else None, - publication_status=draw( - sampled_from( - [PublicationStatus.COMPLETED, PublicationStatus.PARTIAL] - if published - else [PublicationStatus.WAITING, PublicationStatus.FAILED] - ) - ), - ) diff --git a/tests/configtest.py b/tests/configtest.py deleted file mode 100644 index 524d8ad..0000000 --- a/tests/configtest.py +++ /dev/null @@ -1,14 +0,0 @@ -import pytest -from dynaconf import settings -from tortoise.contrib.test import finalizer, initializer - - -@pytest.fixture(scope="session", autouse=True) -def initialize_tests(request): - settings.configure(FORCE_ENV_FOR_DYNACONF="testing") - initializer( - ["tests.test_models"], - db_url=f"sqlite:///{settings.DB_PATH}", - app_label="models", - ) - request.addfinalizer(finalizer) diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..7e360de --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,50 @@ +from datetime import datetime, timedelta + +import pytest + +from mobilizon_bots.event.event import MobilizonEvent, PublicationStatus + + +def generate_publication_status(published): + return PublicationStatus.COMPLETED if published else PublicationStatus.WAITING + + +@pytest.fixture +def event_generator(): + def _event_generator( + begin_date=datetime(year=2021, month=1, day=1, hour=11, minute=30), + published=False, + publication_time=None, + ): + + return MobilizonEvent( + name="test event", + description="description of the event", + begin_datetime=begin_date, + end_datetime=begin_date + timedelta(hours=2), + last_accessed=datetime.now(), + mobilizon_link="http://some_link.com/123", + mobilizon_id="12345", + thumbnail_link="http://some_link.com/123.jpg", + location="location", + publication_status=generate_publication_status(published), + publication_time=publication_time + or (begin_date - timedelta(days=1) if published else None), + ) + + return _event_generator + + +@pytest.fixture() +def event() -> MobilizonEvent: + return MobilizonEvent( + name="test event", + description="description of the event", + begin_datetime=datetime(year=2021, month=1, day=1, hour=11, minute=30), + end_datetime=datetime(year=2021, month=1, day=1, hour=12, minute=30), + last_accessed=datetime.now(), + mobilizon_link="http://some_link.com/123", + mobilizon_id="12345", + thumbnail_link="http://some_link.com/123.jpg", + location="location", + ) diff --git a/tests/event/event_selector.py b/tests/event/event_selector.py index 0fd15a6..49de8f6 100644 --- a/tests/event/event_selector.py +++ b/tests/event/event_selector.py @@ -1,10 +1,9 @@ +from abc import ABC, abstractmethod from datetime import timedelta, datetime from typing import List, Optional from mobilizon_bots.event.event import MobilizonEvent -from abc import ABC, abstractmethod - class EventSelectionStrategy(ABC): @abstractmethod @@ -28,13 +27,15 @@ class SelectNextEventStrategy(EventSelectionStrategy): last_published_event = published_events[-1] first_unpublished_event = unpublished_events[0] - assert ( - last_published_event.publication_time < datetime.now() - ), "Last published event has been published in the future" + assert last_published_event.publication_time < datetime.now(), ( + f"Last published event has been published in the future\n" + f"{last_published_event.publication_time}\n" + f"{datetime.now()}" + ) if ( last_published_event.publication_time + self.minimum_break_between_events - > first_unpublished_event.begin_datetime + > datetime.now() ): return None diff --git a/tests/event/test_event.py b/tests/event/test_event.py index 0ada83d..8ef7f1f 100644 --- a/tests/event/test_event.py +++ b/tests/event/test_event.py @@ -1,27 +1,6 @@ -from datetime import datetime - import pytest -from hypothesis import given from jinja2 import Template -from mobilizon_bots.event.event import MobilizonEvent -from tests import events - - -@pytest.fixture() -def event() -> MobilizonEvent: - return MobilizonEvent( - name="test event", - description="description of the event", - begin_datetime=datetime(year=2021, month=1, day=1, hour=11, minute=30), - end_datetime=datetime(year=2021, month=1, day=1, hour=12, minute=30), - last_accessed=datetime.now(), - mobilizon_link="http://some_link.com/123", - mobilizon_id="12345", - thumbnail_link="http://some_link.com/123.jpg", - location="location", - ) - @pytest.fixture() def simple_template(): @@ -42,8 +21,3 @@ def test_format(event, simple_template): event.format(simple_template) == "test event|description of the event|location|2021-01-01, 11:30" ) - - -@given(events()) -def test_event_properties(event): - assert event.end_datetime > event.begin_datetime diff --git a/tests/event/test_strategies.py b/tests/event/test_strategies.py index d3d8668..21f4bde 100644 --- a/tests/event/test_strategies.py +++ b/tests/event/test_strategies.py @@ -1,12 +1,59 @@ -from hypothesis import given -from hypothesis.strategies import lists +from datetime import datetime, timedelta -from tests import events +import pytest + +from tests.event.event_selector import SelectNextEventStrategy -@given( - unpublished_events=lists(events(published=True), max_size=5), - published_events=lists(events(published=False), max_size=3), +@pytest.mark.parametrize( + "desired_break_window,days_passed_from_publication", [[2, 1], [3, 2]] ) -def test_select_next_event_properties(unpublished_events, published_events): - pass +def test_window_simple_no_event( + event_generator, desired_break_window, days_passed_from_publication +): + "Testing that the break between events is respected" + unpublished_events = [ + event_generator( + published=False, + begin_date=datetime(year=2021, month=1, day=5, hour=11, minute=30), + ) + ] + published_events = [ + event_generator( + published=True, + publication_time=datetime.now() + - timedelta(days=days_passed_from_publication), + ) + ] + + selected_event = SelectNextEventStrategy( + minimum_break_between_events=timedelta(days=desired_break_window) + ).select(published_events, unpublished_events) + assert selected_event is None + + +@pytest.mark.parametrize( + "desired_break_window,days_passed_from_publication", [[1, 2], [2, 10], [4, 4]] +) +def test_window_simple_event_found( + event_generator, desired_break_window, days_passed_from_publication +): + "Testing that the break between events is respected" + unpublished_events = [ + event_generator( + published=False, + begin_date=datetime(year=2021, month=1, day=5, hour=11, minute=30), + ) + ] + published_events = [ + event_generator( + published=True, + publication_time=datetime.now() + - timedelta(days=days_passed_from_publication), + ) + ] + + selected_event = SelectNextEventStrategy( + minimum_break_between_events=timedelta(days=desired_break_window) + ).select(published_events, unpublished_events) + assert selected_event is unpublished_events[0]