aboutsummaryrefslogtreecommitdiffstats
path: root/ctrack/users/tests/test_views.py
blob: e47d22be2dfbd63cd1dd69443a20074a447ad603 (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
import pytest
from django.contrib.auth.models import Permission
from django.test import RequestFactory, TestCase
from django.urls import reverse

from ctrack.core.views import home_page
from ctrack.register.models import SingleDateTimeEvent
from ctrack.users.models import User
from ctrack.users.views import UserDetailView, UserRedirectView, UserUpdateView

pytestmark = pytest.mark.django_db

test_case = TestCase("run")


class TestUserProfilePage:

    def test_their_full_name_in_h3(self, user: User, client):
        client.force_login(user)
        response = client.get(reverse("users:detail", args=[user.username]))
        assert response.status_code == 200
        html = response.content.decode("utf-8")
        test_string = f'<h1 class="display-4">{user.name}</h1>'
        assert test_string in html

    def test_view_has_all_events_related_to_user(self, user, client):
        SingleDateTimeEvent.objects.create(
            type_descriptor="PHONE_CALL",
            short_description="Important event",
            url="http://fake.url.com",
            requested_response_date="2021-01-24",
            response_received_date=None,
            date="2020-10-10T15:00",
            comments="Comments on important event",
            # location is optional
            user=user,
        )
        client.force_login(user)
        response = client.get(reverse("users:detail", args=[user.username]))
        assert response.status_code == 200
        html = response.content.decode("utf-8")
        test_case.assertInHTML("Comments on important event", html)


class TestUserUpdateView:
    """
    TODO:
        extracting view initialization code as class-scoped fixture
        would be great if only pytest-django supported non-function-scoped
        fixture db access -- this is a work-in-progress for now:
        https://github.com/pytest-dev/pytest-django/pull/258
    """

    def test_get_success_url(self, user: User, request_factory: RequestFactory):
        view = UserUpdateView()
        request = request_factory.get("/fake-url/")
        request.user = user

        view.request = request

        assert view.get_success_url() == f"/users/{user.username}/"

    def test_get_object(self, user: User, request_factory: RequestFactory):
        view = UserUpdateView()
        request = request_factory.get("/fake-url/")
        request.user = user

        view.request = request

        assert view.get_object() == user


class TestUserRedirectView:
    def test_get_redirect_url(self, user: User, request_factory: RequestFactory):
        view = UserRedirectView()
        request = request_factory.get("/fake-url")
        request.user = user

        view.request = request

        assert view.get_redirect_url() == "/"


def test_profile_view_contains_organisation_information(
    person, request_factory, stakeholder_user
):
    """
    This tests the context_data - not the rendered page... We'll do that in the
    next test.
    """
    org_name = person.organisation.name
    request = request_factory.get(f"/users/{stakeholder_user.username}")

    # we have to do the following to simulate logged-in user
    # Django Advanced Testing Topics
    request.user = stakeholder_user

    # We pass 'username' rather than 'slug' here because we are setting 'slug_url_kwarg' in our CBV.
    response = UserDetailView.as_view()(request, username=stakeholder_user.username)

    assert response.status_code == 200
    assert response.context_data["user"].username == stakeholder_user.username
    assert response.context_data["user"].is_stakeholder is True
    assert response.context_data["user"].stakeholder.person.first_name == "Toss"

    # Two ways of getting the organisaton name
    assert (
        response.context_data["user"].stakeholder.person.get_organisation_name()
        == org_name
    )
    assert response.context_data["user"].get_organisation_name() == org_name
    assert response.context_data["user"].stakeholder.person.first_name == "Toss"


def test_home_page_h1_tag_with_client(client, django_user_model):
    """
    Basic test of HTML from the home page.
    """
    django_user_model.objects.create_user(username="toss", password="knob")
    client.login(username="toss", password="knob")
    response = client.get("/")
    assert response.status_code == 200
    assert b"<title>ctrack - NIS Tracker</title>" in response.content
    assert b"</html>" in response.content


def test_regular_user_redirected_to_their_template_on_login(
    django_user_model, request_factory: RequestFactory
):
    """
    When a user logs in without a stakeholder mapping, they get sent to the site home
    page.
    """
    user = django_user_model.objects.create_user(username="toss", password="knob")
    request = request_factory.get("/")
    request.user = user
    response = home_page(request)
    assert response.status_code == 200
    assert b'<h1 class="display-3">ctrack</h1>' in response.content


def test_stakeholder_redirected_to_their_template_on_login(
    django_user_model, request_factory: RequestFactory, stakeholder_user
):
    """
    When a user logs in WITH a stakeholder mapping, they get sent to the stakehoder user
    template.
    """
    request = request_factory.get("/")
    request.user = stakeholder_user
    response = home_page(request)
    assert response.status_code == 200
    assert b"THIS IS A TEMPLATE FOR A STAKEHOLDER USER" in response.content


def test_stakeholder_returns_is_stakeholder(
    django_user_model, request_factory, stakeholder_user
):
    request = request_factory.get("/")
    request.user = stakeholder_user
    assert request.user.is_stakeholder is True


def test_stakeholder_user_is_not_staff(django_user_model, stakeholder_user):
    assert stakeholder_user.is_staff is False


def test_stakeholder_user_gets_301_when_trying_to_access_view_with_perm_set(
    django_user_model, client, stakeholder_user
):
    """
    No permissions are set when a regular user is created. This test knows that a suitable
    permission is set on the ctrack.organisations.view.OrganisationListView, and therefore we
    would expect a redirect/403 persmission denied response when trying to reach it with a
    regular user.
    """
    client.login(username="toss", password="knob")
    response = client.get(path="https://localhost:8000/organisations")
    assert (
        response.status_code == 301
    )  # This page redirects to 403.html, hence why its a 301 (I think)


@pytest.mark.skip("Explore why this does not pass - it passess in functional style")
def test_staff_user_gets_200_when_trying_to_access_view_with_perm_set(
    django_user_model, client, stakeholder_user
):
    org_list_permission = Permission.objects.get(name="Can view organisation")
    assert stakeholder_user.user_permissions.count() == 0
    stakeholder_user.user_permissions.add(org_list_permission)
    assert stakeholder_user.has_perm("organisations.view_organisation")
    stakeholder_user.save()
    logged_in = client.login(username="toss", password="knob")
    assert logged_in is True
    response = client.get("/organisations")
    assert response.status_code == 200