Beispiel #1
0
def test_non_existing_individual_task_retrieval(
        calendar_data: CalendarData) -> None:
    with pytest.raises(ValueError):
        calendar_data.task_from_calendar(calendar_id="sample_data_file",
                                         year=2017,
                                         month=11,
                                         day=6,
                                         task_id=0)
Beispiel #2
0
def test_tasks_can_be_filtered_after_retrieval(
        calendar_data: CalendarData, past_normal_tasks_data: Dict) -> None:
    year = 2001

    tasks = calendar_data.tasks_from_calendar(year, 1, past_normal_tasks_data)
    assert len(tasks["1"]) > 0
    # if we switch to next month, month 1 should become empty
    calendar_data.hide_past_tasks(year, 2, tasks)
    assert len(tasks["1"]) == 0
Beispiel #3
0
def edit_task_action(calendar_id: str, year: int, month: int, day: int,
                     task_id: int) -> Response:
    month_names = GregorianCalendar.MONTH_NAMES
    calendar_data = CalendarData(current_app.config["DATA_FOLDER"],
                                 current_app.config["WEEK_STARTING_DAY"])

    repeats = request.args.get("repeats") == "1"
    try:
        if repeats:
            task = calendar_data.repetitive_task_from_calendar(
                calendar_id=calendar_id,
                year=year,
                month=month,
                task_id=int(task_id))
        else:
            task = calendar_data.task_from_calendar(
                calendar_id=calendar_id,
                year=year,
                month=month,
                day=day,
                task_id=int(task_id),
            )
    except (FileNotFoundError, IndexError):
        abort(404)

    if task["details"] == " ":
        task["details"] = ""

    emojis_enabled = current_app.config.get("EMOJIS_ENABLED", False)

    return cast(
        Response,
        render_template(
            "task.html",
            calendar_id=calendar_id,
            year=year,
            month=month,
            day=day,
            min_year=current_app.config["MIN_YEAR"],
            max_year=current_app.config["MAX_YEAR"],
            month_names=month_names,
            task=task,
            base_url=current_app.config["BASE_URL"],
            editing=True,
            emojis_enabled=emojis_enabled,
            button_default_color_value=current_app.
            config["BUTTON_CUSTOM_COLOR_VALUE"],
            buttons_colors=current_app.config["BUTTONS_COLORS_LIST"],
            buttons_emojis=current_app.config["BUTTONS_EMOJIS_LIST"]
            if emojis_enabled else tuple(),
        ),
    )
Beispiel #4
0
def delete_task_action(calendar_id: str, year: str, month: str, day: str,
                       task_id: str) -> Response:
    calendar_data = CalendarData(current_app.config["DATA_FOLDER"],
                                 current_app.config["WEEK_STARTING_DAY"])
    calendar_data.delete_task(
        calendar_id=calendar_id,
        year_str=year,
        month_str=month,
        day_str=day,
        task_id=int(task_id),
    )

    return cast(Response, jsonify({}))
Beispiel #5
0
def hide_repetition_task_instance_action(calendar_id: str, year: str,
                                         month: str, day: str,
                                         task_id: str) -> Response:
    calendar_data = CalendarData(current_app.config["DATA_FOLDER"],
                                 current_app.config["WEEK_STARTING_DAY"])
    calendar_data.hide_repetition_task_instance(
        calendar_id=calendar_id,
        year_str=year,
        month_str=month,
        day_str=day,
        task_id_str=task_id,
    )

    return cast(Response, jsonify({}))
Beispiel #6
0
def save_task_action(calendar_id: str) -> Response:
    title = request.form["title"].strip()
    date = request.form.get("date", "")
    if len(date) > 0:
        date_fragments = re.split("-", date)
        year = int(date_fragments[0])  # type: Optional[int]
        month = int(date_fragments[1])  # type: Optional[int]
        day = int(date_fragments[2])  # type: Optional[int]
    else:
        year = month = day = None
    is_all_day = request.form.get("is_all_day", "0") == "1"
    start_time = request.form["start_time"]
    end_time = request.form.get("end_time", None)
    details = request.form["details"].replace("\r", "").replace("\n", "<br>")
    color = request.form["color"]
    has_repetition = request.form.get("repeats", "0") == "1"
    repetition_type = request.form.get("repetition_type")
    repetition_subtype = request.form.get("repetition_subtype")
    repetition_value = int(request.form["repetition_value"])

    calendar_data = CalendarData(current_app.config["DATA_FOLDER"],
                                 current_app.config["WEEK_STARTING_DAY"])
    calendar_data.create_task(
        calendar_id=calendar_id,
        year=year,
        month=month,
        day=day,
        title=title,
        is_all_day=is_all_day,
        start_time=start_time,
        end_time=end_time,
        details=details,
        color=color,
        has_repetition=has_repetition,
        repetition_type=repetition_type,
        repetition_subtype=repetition_subtype,
        repetition_value=repetition_value,
    )

    if year is None:
        return redirect("{}/{}/".format(current_app.config["BASE_URL"],
                                        calendar_id),
                        code=302)
    else:
        return redirect(
            "{}/{}/?y={}&m={}".format(current_app.config["BASE_URL"],
                                      calendar_id, year, month),
            code=302,
        )
Beispiel #7
0
def update_task_day_action(calendar_id: str, year: str, month: str, day: str,
                           task_id: str) -> Response:
    new_day = request.data.decode("utf-8")

    calendar_data = CalendarData(current_app.config["DATA_FOLDER"],
                                 current_app.config["WEEK_STARTING_DAY"])
    calendar_data.update_task_day(
        calendar_id=calendar_id,
        year_str=year,
        month_str=month,
        day_str=day,
        task_id=int(task_id),
        new_day_str=new_day,
    )

    return cast(Response, jsonify({}))
Beispiel #8
0
def test_hidden_montly_weekday_repetitions_dont_appear(
    calendar_data: CalendarData, ) -> None:
    year = 2017
    month = 12
    data = calendar_data.load_calendar(
        "repetitive_monthly_weekday_hidden_task_data_file")

    tasks = calendar_data.tasks_from_calendar(year=year,
                                              month=month,
                                              data=data)
    tasks = calendar_data.add_repetitive_tasks_from_calendar(year=year,
                                                             month=month,
                                                             data=data,
                                                             tasks=tasks)

    assert str(month) not in tasks
Beispiel #9
0
def test_existing_repetitive_task_retrieval(
        calendar_data: CalendarData) -> None:
    task_id = 2
    task = calendar_data.repetitive_task_from_calendar(
        calendar_id="sample_data_file", year=2017, month=11, task_id=task_id)
    assert task is not None
    assert task["id"] == task_id
    assert task["is_all_day"] is True
Beispiel #10
0
def main_calendar_action(calendar_id: str) -> Response:
    GregorianCalendar.setfirstweekday(current_app.config["WEEK_STARTING_DAY"])

    current_day, current_month, current_year = GregorianCalendar.current_date()
    year = int(request.args.get("y", current_year))
    year = max(min(year, current_app.config["MAX_YEAR"]),
               current_app.config["MIN_YEAR"])
    month = int(request.args.get("m", current_month))
    month = max(min(month, 12), 1)
    month_name = GregorianCalendar.MONTH_NAMES[month - 1]

    if current_app.config["HIDE_PAST_TASKS"]:
        view_past_tasks = False
    else:
        view_past_tasks = request.cookies.get("ViewPastTasks", "1") == "1"

    calendar_data = CalendarData(current_app.config["DATA_FOLDER"],
                                 current_app.config["WEEK_STARTING_DAY"])
    try:
        data = calendar_data.load_calendar(calendar_id)
    except FileNotFoundError:
        abort(404)

    tasks = calendar_data.tasks_from_calendar(year, month, data)
    tasks = calendar_data.add_repetitive_tasks_from_calendar(
        year, month, data, tasks)

    if not view_past_tasks:
        calendar_data.hide_past_tasks(year, month, tasks)

    if current_app.config[
            "WEEK_STARTING_DAY"] == constants.WEEK_START_DAY_MONDAY:
        weekdays_headers = ["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"]
    else:
        weekdays_headers = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"]

    return cast(
        Response,
        render_template(
            "calendar.html",
            calendar_id=calendar_id,
            year=year,
            month=month,
            month_name=month_name,
            current_year=current_year,
            current_month=current_month,
            current_day=current_day,
            month_days=GregorianCalendar.month_days(year, month),
            previous_month_link=previous_month_link(year, month),
            next_month_link=next_month_link(year, month),
            base_url=current_app.config["BASE_URL"],
            tasks=tasks,
            display_view_past_button=current_app.
            config["SHOW_VIEW_PAST_BUTTON"],
            weekdays_headers=weekdays_headers,
        ),
    )
Beispiel #11
0
 def wrapper(*args: Any, **kwargs: Any) -> Any:
     username = get_session_username(str(request.cookies.get(SESSION_ID)))
     authorization = Authorization(calendar_data=CalendarData(
         data_folder=current_app.config["DATA_FOLDER"]))
     if "calendar_id" not in kwargs:
         raise ValueError("calendar_id")
     calendar_id = str(kwargs["calendar_id"])
     if not authorization.can_access(username=username,
                                     calendar_id=calendar_id):
         abort(403)
     return decorated_function(*args, **kwargs)
Beispiel #12
0
def test_existing_individual_task_retrieval(
        calendar_data: CalendarData) -> None:
    task_id = 4

    task = calendar_data.task_from_calendar(calendar_id="sample_data_file",
                                            year=2017,
                                            month=11,
                                            day=6,
                                            task_id=task_id)
    assert task is not None
    assert task["id"] == task_id
    assert task["is_all_day"] is True
Beispiel #13
0
def test_creates_task_with_start_and_end_dates(
        save_calendar_mock: MagicMock, calendar_data: CalendarData) -> None:
    year = 2017
    month = 12
    day = 10
    title = "an irrelevant title"
    is_all_day = False
    start_time = "12:00"
    end_time = "13:00"
    details = ""
    color = "an_irrelevant_color"
    has_repetition = False
    repetition_type = ""
    repetition_subtype = ""
    repetition_value = 0
    calendar_id = "sample_empty_data_file"

    result = calendar_data.create_task(
        calendar_id=calendar_id,
        year=year,
        month=month,
        day=day,
        title=title,
        is_all_day=is_all_day,
        start_time=start_time,
        end_time=end_time,
        details=details,
        color=color,
        has_repetition=has_repetition,
        repetition_type=repetition_type,
        repetition_subtype=repetition_subtype,
        repetition_value=repetition_value,
    )
    assert result is True

    save_calendar_mock.assert_called_once_with(ANY, filename=calendar_id)
    call_args, _ = save_calendar_mock.call_args
    data = call_args[0]
    assert "tasks" in data
    assert "normal" in data["tasks"]
    assert str(year) in data["tasks"]["normal"]
    assert str(month) in data["tasks"]["normal"][str(year)]
    assert str(day) in data["tasks"]["normal"][str(year)][str(month)]
    assert len(data["tasks"]["normal"][str(year)][str(month)][str(day)]) == 1

    task_data = data["tasks"]["normal"][str(year)][str(month)][str(day)][0]

    assert "title" in task_data
    assert task_data["title"] == title
    assert task_data["is_all_day"] is False
    assert task_data["start_time"] == start_time
    assert task_data["end_time"] == end_time
Beispiel #14
0
def test_loads_normal_tasks_from_calendar_given_data(
        calendar_data: CalendarData, sample_data_file_data: Dict) -> None:
    year = 2017
    month = 12
    month_str = str(month)

    tasks = calendar_data.tasks_from_calendar(year, month,
                                              sample_data_file_data)
    assert len(tasks[month_str]) == 1
    assert len(tasks[month_str]["25"]) == 2
    assert tasks[month_str]["25"][0]["id"] in [0, 1]
    assert tasks[month_str]["25"][1]["id"] in [0, 1]
    assert tasks[month_str]["25"][0]["id"] != tasks[month_str]["25"][1]["id"]
Beispiel #15
0
def test_joins_repetitive_tasks_with_normal_ones(
        calendar_data: CalendarData, sample_data_file_data: Dict) -> None:
    year = 2017
    month = 11
    month_str = str(month)

    tasks = calendar_data.tasks_from_calendar(year, month,
                                              sample_data_file_data)
    assert len(tasks[month_str]) == 1

    tasks = calendar_data.add_repetitive_tasks_from_calendar(
        year, month, sample_data_file_data, tasks)
    assert len(tasks[month_str]) > 0
    # month has 4 mondays
    repetitive_weekly_weekday_task_ocurrences = 4
    # month has 5 thursdays
    repetitive_weekly_weekday_3_task_ocurrences = 5
    repetitive_monthly_weekday_task_ocurrences = 1
    repetitive_monthly_monthday_task_ocurrences = 1

    # We're counting the number of days with tasks, not the exact number of tasks (day 6 has 2 tasks)
    assert len(
        tasks[month_str]) == (repetitive_weekly_weekday_task_ocurrences +
                              repetitive_monthly_weekday_task_ocurrences +
                              repetitive_monthly_monthday_task_ocurrences +
                              repetitive_weekly_weekday_3_task_ocurrences)
    assert len(tasks[month_str]["6"]) == 2

    # Normal task should be first (as repetitive ones are appended afterwards)
    assert tasks[month_str]["6"][0]["id"] == 4
    assert "repetition_value" not in tasks[month_str]["6"][0]
    assert "repetition_value" in tasks[month_str]["6"][1]
    assert tasks[month_str]["6"][1]["repetition_value"] == 0
    assert tasks[month_str]["6"][1][
        "repetition_subtype"] == CalendarData.REPETITION_SUBTYPE_WEEK_DAY
    assert tasks[month_str]["6"][1][
        "repetition_type"] == CalendarData.REPETITION_TYPE_WEEKLY
Beispiel #16
0
def new_task_action(calendar_id: str, year: int, month: int) -> Response:
    GregorianCalendar.setfirstweekday(current_app.config["WEEK_STARTING_DAY"])

    current_day, current_month, current_year = GregorianCalendar.current_date()
    year = max(min(int(year), current_app.config["MAX_YEAR"]),
               current_app.config["MIN_YEAR"])
    month = max(min(int(month), 12), 1)
    month_names = GregorianCalendar.MONTH_NAMES

    if current_month == month and current_year == year:
        day = current_day
    else:
        day = 1
    day = int(request.args.get("day", day))

    task = {
        "date": CalendarData.date_for_frontend(year, month, day),
        "is_all_day": True,
        "repeats": False,
        "details": "",
    }

    emojis_enabled = current_app.config.get("EMOJIS_ENABLED", False)

    return cast(
        Response,
        render_template(
            "task.html",
            calendar_id=calendar_id,
            year=year,
            month=month,
            min_year=current_app.config["MIN_YEAR"],
            max_year=current_app.config["MAX_YEAR"],
            month_names=month_names,
            task=task,
            base_url=current_app.config["BASE_URL"],
            editing=False,
            emojis_enabled=emojis_enabled,
            button_default_color_value=current_app.
            config["BUTTON_CUSTOM_COLOR_VALUE"],
            buttons_colors=current_app.config["BUTTONS_COLORS_LIST"],
            buttons_emojis=current_app.config["BUTTONS_EMOJIS_LIST"]
            if emojis_enabled else tuple(),
        ),
    )
Beispiel #17
0
def calendar_data() -> CalendarData:
    return CalendarData("test/fixtures")
Beispiel #18
0
def test_non_existing_repetitive_task_retrieval(
        calendar_data: CalendarData) -> None:
    with pytest.raises(IndexError):
        calendar_data.repetitive_task_from_calendar(
            calendar_id="sample_data_file", year=2017, month=11, task_id=111)
Beispiel #19
0
def test_error_retrieving_tasks_from_calendar(
        year: int, month: int, data: Dict,
        calendar_data: CalendarData) -> None:
    with pytest.raises(ValueError):
        calendar_data.tasks_from_calendar(year, month, data)
Beispiel #20
0
def past_normal_tasks_data(calendar_data: CalendarData) -> Dict:
    return calendar_data.load_calendar(filename="past_normal_tasks")
Beispiel #21
0
def update_task_action(calendar_id: str, year: str, month: str, day: str,
                       task_id: str) -> Response:
    # Logic is same as save + delete, could refactor but can wait until need to change any save/delete logic

    calendar_data = CalendarData(current_app.config["DATA_FOLDER"],
                                 current_app.config["WEEK_STARTING_DAY"])

    # For creation of "updated" task use only form data
    title = request.form["title"].strip()
    date = request.form.get("date", "")
    if len(date) > 0:
        fragments = re.split("-", date)
        updated_year = int(fragments[0])  # type: Optional[int]
        updated_month = int(fragments[1])  # type: Optional[int]
        updated_day = int(fragments[2])  # type: Optional[int]
    else:
        updated_year = updated_month = updated_day = None
    is_all_day = request.form.get("is_all_day", "0") == "1"
    start_time = request.form["start_time"]
    end_time = request.form.get("end_time", None)
    details = request.form["details"].replace("\r", "").replace("\n", "<br>")
    color = request.form["color"]
    has_repetition = request.form.get("repeats", "0") == "1"
    repetition_type = request.form.get("repetition_type", "")
    repetition_subtype = request.form.get("repetition_subtype", "")
    repetition_value = int(request.form["repetition_value"])  # type: int

    calendar_data.create_task(
        calendar_id=calendar_id,
        year=updated_year,
        month=updated_month,
        day=updated_day,
        title=title,
        is_all_day=is_all_day,
        start_time=start_time,
        end_time=end_time,
        details=details,
        color=color,
        has_repetition=has_repetition,
        repetition_type=repetition_type,
        repetition_subtype=repetition_subtype,
        repetition_value=repetition_value,
    )
    # For deletion of old task data use only url data
    calendar_data.delete_task(
        calendar_id=calendar_id,
        year_str=year,
        month_str=month,
        day_str=day,
        task_id=int(task_id),
    )

    if updated_year is None:
        return redirect("{}/{}/".format(current_app.config["BASE_URL"],
                                        calendar_id),
                        code=302)
    else:
        return redirect(
            "{}/{}/?y={}&m={}".format(current_app.config["BASE_URL"],
                                      calendar_id, updated_year,
                                      updated_month),
            code=302,
        )
def authorization() -> Authorization:
    return Authorization(calendar_data=CalendarData("test/fixtures"))
Beispiel #23
0
def sample_data_file_data(calendar_data: CalendarData) -> Dict:
    return calendar_data.load_calendar(filename="sample_data_file")