Skip to content

Commit

Permalink
chore: added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
c0rydoras committed Aug 3, 2023
1 parent 710bf79 commit ef5ec4f
Show file tree
Hide file tree
Showing 11 changed files with 544 additions and 434 deletions.
14 changes: 14 additions & 0 deletions api/outdated/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from datetime import timedelta
from functools import partial

import pytest
from django.core.management import call_command
from pytest_factoryboy import register
from rest_framework.test import APIClient

Expand Down Expand Up @@ -59,6 +61,18 @@ def client(db, settings, get_claims):
return client


@pytest.fixture
def setup_notifications(transactional_db, settings):
settings.NOTIFICATIONS = [
("test-foo", timedelta(days=60)),
("test-bar", timedelta(days=10)),
("test-baz", timedelta(days=-20)),
]
call_command("update-notifications")
settings.TEMPLATES[0]["DIRS"] = ["outdated/notifications/tests/templates"]
settings.TEMPLATES[0]["APP_DIRS"] = False


@pytest.fixture(scope="module")
def vcr_config():
return {
Expand Down
Empty file.
4 changes: 4 additions & 0 deletions api/outdated/notifications/tests/templates/base.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{% block subject %}{% endblock %}
Project: {{project.name}}
Repo: {{project.repo}}
{% block content %}{% endblock %}
3 changes: 3 additions & 0 deletions api/outdated/notifications/tests/templates/test-bar.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{% extends 'base.txt' %}
{% block subject %}bar{% endblock %}
{% block content %}test-bar.txt contents{% endblock %}
3 changes: 3 additions & 0 deletions api/outdated/notifications/tests/templates/test-baz.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{% extends 'base.txt' %}
{% block subject %}baz{% endblock %}
{% block content %}test-baz.txt contents{% endblock %}
3 changes: 3 additions & 0 deletions api/outdated/notifications/tests/templates/test-foo.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{% extends 'base.txt' %}
{% block subject %}foo{% endblock %}
{% block content %}test-foo.txt contents{% endblock %}
47 changes: 47 additions & 0 deletions api/outdated/notifications/tests/test_build_notification_queue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from datetime import date, timedelta
from unittest.mock import MagicMock

import pytest
from pytest_mock import MockerFixture

from .. import models


@pytest.mark.parametrize(
"status,called",
(["UNDEFINED", False], ["OUTDATED", True], ["WARNING", True], ["UP-TO-DATE", True]),
)
def test_build_notification_queue_called(
transactional_db,
mocker: MockerFixture,
status,
called,
project_factory,
release_version_factory,
version_factory,
):
build_notification_queue_mock: MagicMock = mocker.patch.object(
models, "build_notification_queue"
)
release_version = release_version_factory(
undefined=status == "UNDEFINED",
outdated=status == "OUTDATED",
warning=status == "WARNING",
up_to_date=status == "UP-TO-DATE",
)
version = version_factory(release_version=release_version)
project = project_factory()
assert build_notification_queue_mock.call_count == 0
project.versioned_dependencies.add(version)

if called:
build_notification_queue_mock.assert_called_with(project)
other_project = project_factory(versioned_dependencies=[version])
build_notification_queue_mock.assert_called_with(other_project)

release_version.end_of_life = date.today() + timedelta(days=2000)
release_version.save()

assert build_notification_queue_mock.call_count == 4
else:
assert build_notification_queue_mock.call_count == 0
48 changes: 48 additions & 0 deletions api/outdated/notifications/tests/test_management_commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from unittest.mock import MagicMock

import pytest
from django.core.management import call_command
from pytest_mock import MockerFixture

from outdated.notifications.notifier import Notifier


def test_notify(db, project, maintainer_factory, mocker: MockerFixture):
notifier_init_mock: MagicMock = mocker.patch.object(
Notifier, "__init__", return_value=None
)
notify_mock: MagicMock = mocker.patch.object(Notifier, "notify")
with pytest.raises(
ValueError, match="Notify can't be used on projects without maintainers!"
):
call_command("notify", project.name)
notifier_init_mock.assert_not_called()
notify_mock.assert_not_called()
maintainer_factory(project=project)
call_command("notify", project.name)
notifier_init_mock.assert_called_once_with(project)
notify_mock.assert_called_once()


def test_notify_all(db, project_factory, maintainer_factory, mocker: MockerFixture):
notifier_init_mock: MagicMock = mocker.patch.object(
Notifier, "__init__", return_value=None
)
notify_mock: MagicMock = mocker.patch.object(Notifier, "notify")
project = project_factory(name="foo")
other_project = project_factory(name="bar")
project_factory(name="not-called")
call_command("notify-all")
notifier_init_mock.assert_not_called()
notify_mock.assert_not_called()

maintainer_factory(project=project)
maintainer_factory(project=other_project)
call_command("notify-all")
notifier_init_mock.assert_has_calls(
[
mocker.call(other_project),
mocker.call(project),
]
)
assert notify_mock.call_count == 2
58 changes: 58 additions & 0 deletions api/outdated/notifications/tests/test_notifier.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from datetime import date, timedelta
from typing import Optional

import pytest

from outdated.notifications.notifier import Notifier
from outdated.outdated.models import Maintainer


@pytest.mark.parametrize("nonprimary_maintainers", [False, True])
@pytest.mark.parametrize(
"days_until_outdated,template,sent",
[
(200, None, False),
(60, "test-foo", True),
(50, "test-foo", True),
(10, "test-bar", True),
(-20, "test-baz", True),
],
)
def test_send_notification(
setup_notifications,
days_until_outdated: int,
template: Optional[str],
sent: bool,
nonprimary_maintainers: bool,
maintainer,
maintainer_factory,
mailoutbox,
version_factory,
release_version_factory,
):
project = maintainer.project
release_version = release_version_factory(
end_of_life=date.today() + timedelta(days=days_until_outdated)
)
version = version_factory(release_version=release_version)
project.versioned_dependencies.add(version)
project.save()
if nonprimary_maintainers:
maintainer_factory(project=project)
maintainer_factory(project=project)
maintainer_factory(project=project)
nonprimary_maintainers = list(Maintainer.objects.filter(is_primary=False))
notification_queue = list(project.notification_queue.all())
Notifier(project).notify()
if sent:
mail = mailoutbox[0]
assert mail.subject == template.replace("test-", "")
assert (
mail.body
== f"Project: {project.name}\nRepo: {project.repo}\n{template}.txt contents\n"
)
assert mail.to[0] == maintainer.user.email
assert mail.cc == [m.user.email for m in nonprimary_maintainers]
assert notification_queue[1:] == list(project.notification_queue.all())
else:
assert not mailoutbox
Loading

0 comments on commit ef5ec4f

Please sign in to comment.