aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_scheduling.py
blob: af89afa8eebfd6ac6f9f8d3398e0b5572386c990 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
"""
Scheduling tests.

These tests rely on a fixed time to work.
In order to achieve this the fixture for `now` sets the expected time.
"""

import datetime

import dateutil.parser
import dateutil.tz
import pytest

from nikola.plugins.command.new_post import get_date

freezegun = pytest.importorskip("freezegun")
freeze_time = freezegun.freeze_time

UTC = dateutil.tz.tzutc()
RULE_THURSDAYS = "RRULE:FREQ=WEEKLY;BYDAY=TH"
RULE_FRIDAYS = "RRULE:FREQ=WEEKLY;BYDAY=FR"


def test_current_time_not_matching_rule(today):
    """`today` does not match rule."""
    # No last date
    expected = today.replace(day=23)
    assert expected == get_date(True, RULE_FRIDAYS, tz=UTC)[1]
    assert expected == get_date(True, RULE_FRIDAYS, tz=UTC)[1]

    # Last date in the past; doesn't match rule
    date = today.replace(hour=7)
    expected = today.replace(day=23, hour=7)
    assert expected == get_date(True, RULE_FRIDAYS, date, tz=UTC)[1]

    # Last date in the future; doesn't match rule
    date = today.replace(day=24, hour=7)
    expected = today.replace(day=30, hour=7)
    assert expected == get_date(True, RULE_FRIDAYS, date, tz=UTC)[1]


def test_current_time_matching_rule(today):
    # Last date in the past; matches rule
    date = today.replace(day=16, hour=8)
    expected = today.replace(day=23, hour=8)
    assert expected == get_date(True, RULE_FRIDAYS, date, tz=UTC)[1]

    # Last date in the future; matches rule
    date = today.replace(day=23, hour=18)
    expected = today.replace(day=30, hour=18)
    assert expected == get_date(True, RULE_FRIDAYS, date, tz=UTC)[1]


@pytest.mark.parametrize("scheduling", [True, False])
def test_current_time_matching_rule_no_given_date(now, scheduling):
    """
    No last date given means we should always get the current time.

    `now` matches the rule.
    """
    assert now == get_date(scheduling, RULE_THURSDAYS, tz=UTC)[1]


def test_last_date_in_the_past_not_matching_rule(today):
    """Last date in the past; doesn't match rule."""
    # Corresponding time has already passed, today
    date = today.replace(day=21, hour=7)
    expected = today.replace(day=29, hour=7)
    assert expected == get_date(True, RULE_THURSDAYS, date, tz=UTC)[1]

    # Corresponding time has not passed today
    date = today.replace(day=21, hour=18)
    expected = today.replace(day=22, hour=18)
    assert expected == get_date(True, RULE_THURSDAYS, date, tz=UTC)[1]


def test_last_date_in_the_future_not_matching_rule(today):
    """Last date in the future; doesn't match rule."""
    # Corresponding time has already passed, today
    date = today.replace(day=24, hour=7)
    expected = today.replace(day=29, hour=7)
    assert expected == get_date(True, RULE_THURSDAYS, date, tz=UTC)[1]

    # Corresponding time has not passed today
    date = today.replace(day=24, hour=18)
    expected = today.replace(day=29, hour=18)
    assert expected == get_date(True, RULE_THURSDAYS, date, tz=UTC)[1]


def test_last_date_in_the_past_matching_rule(today):
    """Last date in the past; matches rule."""
    # Corresponding time has already passed, today
    date = today.replace(day=15, hour=7)
    expected = today.replace(day=29, hour=7)
    assert expected == get_date(True, RULE_THURSDAYS, date, tz=UTC)[1]

    # Corresponding time has already passed, today; rule specifies HOUR
    date = today.replace(day=15, hour=7)
    expected = today.replace(day=29, hour=9)
    assert expected == get_date(True, RULE_THURSDAYS + ";BYHOUR=9", date, tz=UTC)[1]

    # Corresponding time has not passed today
    date = today.replace(day=15, hour=18)
    expected = today.replace(day=22, hour=18)
    assert expected == get_date(True, RULE_THURSDAYS, date, tz=UTC)[1]


def test_last_date_in_the_future_matching_rule(today):
    """Last date in the future; matches rule."""
    # Corresponding time has already passed, today
    date = today.replace(day=29, hour=7)
    expected = today.replace(day=5, month=9, hour=7)
    assert expected == get_date(True, RULE_THURSDAYS, date, tz=UTC)[1]

    # Corresponding time has not passed today
    date = today.replace(day=22, hour=18)
    expected = today.replace(day=29, hour=18)
    assert expected == get_date(True, RULE_THURSDAYS, date, tz=UTC)[1]


@pytest.fixture
def today(now):
    current_time = now.strftime("%Y-%m-%d %H:%M:%S %Z")
    yield dateutil.parser.parse(current_time)


@pytest.fixture
def now() -> datetime:
    """
    Get the current time.

    datetime is frozen to this point in time.
    """
    _NOW = datetime.datetime(2013, 8, 22, 10, 0, 0, tzinfo=UTC)  # Thursday

    with freeze_time(_NOW):
        yield _NOW