Skip to content

Commit db68c51

Browse files
committed
tests refactored
1 parent 2e29f0f commit db68c51

File tree

5 files changed

+198
-103
lines changed

5 files changed

+198
-103
lines changed

tests/conftest.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import pytest
2+
from django.contrib.auth import get_user_model
3+
from django.test import Client
4+
from task_manager.statuses.models import Status
5+
from task_manager.labels.models import Label
6+
from task_manager.tasks.models import Task
7+
8+
User = get_user_model()
9+
10+
@pytest.fixture
11+
def password():
12+
return "P@ssw0rd12345"
13+
14+
@pytest.fixture
15+
def user(db, password):
16+
return User.objects.create_user(username="alice", password=password, first_name="Alice", last_name="A")
17+
18+
@pytest.fixture
19+
def other_user(db, password):
20+
return User.objects.create_user(username="bob", password=password, first_name="Bob", last_name="B")
21+
22+
@pytest.fixture
23+
def auth_client(db, user, password):
24+
c = Client()
25+
c.login(username=user.username, password=password)
26+
return c
27+
28+
@pytest.fixture
29+
def status_new(db):
30+
return Status.objects.create(name="новый")
31+
32+
@pytest.fixture
33+
def label_bug(db):
34+
return Label.objects.create(name="bug")
35+
36+
@pytest.fixture
37+
def make_task(db, status_new, user):
38+
def _make_task(**kwargs):
39+
defaults = {
40+
"name": "Test task",
41+
"description": "",
42+
"status": status_new,
43+
"author": user,
44+
"executor": None,
45+
}
46+
defaults.update(kwargs)
47+
return Task.objects.create(**defaults)
48+
return _make_task

tests/test_labels_crud.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
from task_manager.labels.models import Label
55
from task_manager.tasks.models import Task, Status
6+
pytestmark = pytest.mark.django_db
7+
68

79

810
@pytest.mark.django_db
@@ -69,4 +71,4 @@ def test_label_delete_when_unused_ok(client, django_user_model):
6971
url = reverse("labels:delete", args=[label.pk])
7072
resp = client.post(url)
7173
assert resp.status_code == 302
72-
assert not Label.objects.filter(pk=label.pk).exists()
74+
assert not Label.objects.filter(pk=label.pk).exists()

tests/test_statuses_crud.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
from task_manager.tasks.models import Task
66
import pytest
77
from django.contrib.auth import get_user_model
8+
from django.urls import reverse
9+
pytestmark = pytest.mark.django_db
10+
811
User = get_user_model()
912

1013

@@ -22,8 +25,8 @@ def auth_client(user):
2225

2326
@pytest.mark.django_db
2427
def test_login_required(client):
25-
r1 = client.get("/statuses/")
26-
r2 = client.get("/statuses/create/")
28+
r1 = client.get(reverse("statuses:index"))
29+
r2 = client.get(reverse("statuses:create"))
2730
assert r1.status_code in (302, 301)
2831
assert r2.status_code in (302, 301)
2932
assert "login" in r1.url
@@ -34,7 +37,7 @@ def test_login_required(client):
3437
def test_list(auth_client):
3538
Status.objects.create(name="новый")
3639
Status.objects.create(name="в работе")
37-
resp = auth_client.get("/statuses/")
40+
resp = auth_client.get(reverse("statuses:index"))
3841
assert resp.status_code == 200
3942
html = resp.content.decode()
4043
assert "новый" in html
@@ -43,7 +46,7 @@ def test_list(auth_client):
4346

4447
@pytest.mark.django_db
4548
def test_create(auth_client):
46-
resp = auth_client.post("/statuses/create/",
49+
resp = auth_client.post(reverse("statuses:create"),
4750
data={"name": "на тестировании"})
4851
assert resp.status_code in (302, 301)
4952
assert Status.objects.filter(name="на тестировании").exists()
@@ -52,7 +55,7 @@ def test_create(auth_client):
5255
@pytest.mark.django_db
5356
def test_update(auth_client):
5457
st = Status.objects.create(name="черновик")
55-
resp = auth_client.post(f"/statuses/{st.pk}/update/",
58+
resp = auth_client.post(reverse("statuses:update", args=[st.pk]),
5659
data={"name": "завершён"})
5760
assert resp.status_code in (302, 301)
5861
st.refresh_from_db()
@@ -62,9 +65,9 @@ def test_update(auth_client):
6265
@pytest.mark.django_db
6366
def test_delete(auth_client):
6467
st = Status.objects.create(name="временный")
65-
get_resp = auth_client.get(f"/statuses/{st.pk}/delete/")
68+
get_resp = auth_client.get(reverse("statuses:delete", args=[st.pk]))
6669
assert get_resp.status_code == 200
67-
post_resp = auth_client.post(f"/statuses/{st.pk}/delete/")
70+
post_resp = auth_client.post(reverse("statuses:delete", args=[st.pk]))
6871
assert post_resp.status_code in (302, 301)
6972
assert not Status.objects.filter(pk=st.pk).exists()
7073

@@ -82,4 +85,4 @@ def test_cannot_delete_status_in_use(django_user_model):
8285
)
8386

8487
with pytest.raises(ProtectedError):
85-
status.delete()
88+
status.delete()

tests/test_tasks_crud.py

Lines changed: 116 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,164 @@
1-
from task_manager.statuses.models import Status
2-
from task_manager.tasks.models import Task
31
import pytest
42
from django.contrib.auth import get_user_model
3+
from django.test import Client
4+
from django.urls import reverse
5+
from task_manager.tasks.models import Task
6+
from task_manager.statuses.models import Status
7+
58
User = get_user_model()
69

710

11+
@pytest.fixture
12+
def status_new(db):
13+
return Status.objects.create(name="новый")
14+
15+
816
@pytest.fixture
917
def users(db):
10-
pwd = "p12345678"
11-
u1 = User.objects.create_user(username="user1", password=pwd)
12-
u2 = User.objects.create_user(username="user2", password=pwd)
13-
return {"u1": u1, "u2": u2, "pwd": pwd}
18+
password = "P@ssw0rd12345"
19+
u1 = User.objects.create_user(
20+
username="alice", password=password, first_name="Alice", last_name="A"
21+
)
22+
u2 = User.objects.create_user(
23+
username="bob", password=password, first_name="Bob", last_name="B"
24+
)
25+
return {"alice": u1, "bob": u2, "password": password}
1426

1527

1628
@pytest.fixture
1729
def auth_client(users):
18-
from django.test import Client
1930
c = Client()
20-
c.login(username="user1", password=users["pwd"])
31+
c.login(username="alice", password=users["password"])
2132
return c
2233

2334

24-
@pytest.fixture
25-
def status_new(db):
26-
return Status.objects.create(name="новый")
35+
@pytest.mark.django_db
36+
def test_users_list_is_public(client, users):
37+
resp = client.get(reverse("list", current_app="users"))
38+
assert resp.status_code == 200
39+
html = resp.content.decode()
40+
assert "alice" in html
41+
assert "bob" in html
2742

2843

2944
@pytest.mark.django_db
30-
def test_login_required(client):
31-
r = client.get("/tasks/")
45+
def test_registration_get(client):
46+
r = client.get(reverse("create", current_app="users"))
47+
assert r.status_code == 200
48+
html = r.content.decode()
49+
assert 'name="username"' in html
50+
assert 'name="password1"' in html
51+
assert 'name="password2"' in html
52+
53+
54+
@pytest.mark.django_db
55+
def test_registration_post_creates_user(client):
56+
data = {
57+
"username": "charlie",
58+
"first_name": "Charlie",
59+
"last_name": "C",
60+
"password1": "XyZ12345!xyZ",
61+
"password2": "XyZ12345!xyZ",
62+
}
63+
r = client.post(reverse("create", current_app="users"), data=data)
3264
assert r.status_code in (302, 301)
65+
assert User.objects.filter(username="charlie").exists()
3366

3467

3568
@pytest.mark.django_db
36-
def test_list(auth_client, users, status_new):
37-
Task.objects.create(name="Тестовая задача", description="Описание",
38-
status=status_new, author=users["u1"])
39-
Task.objects.create(name="Вторая", description="Ещё одна",
40-
status=status_new, author=users["u1"])
41-
r = auth_client.get("/tasks/")
42-
assert r.status_code == 200
43-
html = r.content.decode()
44-
assert "Тестовая задача" in html
45-
assert "Вторая" in html
69+
def test_update_requires_auth_redirects(client, users):
70+
url = reverse("update", args=[users["alice"].pk], current_app="users")
71+
r = client.get(url)
72+
assert r.status_code in (302, 301)
73+
assert reverse("login") in r.url
74+
assert f"next={url}" in r.url
4675

4776

4877
@pytest.mark.django_db
49-
def test_create(auth_client, users, status_new):
50-
resp = auth_client.post("/tasks/create/", data={
51-
"name": "Новая задача",
52-
"description": "Что-то сделать",
53-
"status": status_new.pk,
54-
"executor": users["u2"].pk,
55-
})
56-
assert resp.status_code in (302, 301)
57-
assert Task.objects.filter(name="Новая задача",
58-
status=status_new,
59-
author=users["u1"]).exists()
78+
def test_user_can_update_self(auth_client, users):
79+
url = reverse("update", args=[users["alice"].pk], current_app="users")
80+
r_get = auth_client.get(url)
81+
assert r_get.status_code == 200
82+
83+
r_post = auth_client.post(
84+
url,
85+
data={"username": "alice_new", "first_name": "Al", "last_name": "A"},
86+
)
87+
assert r_post.status_code in (302, 301)
88+
89+
users["alice"].refresh_from_db()
90+
assert users["alice"].username == "alice_new"
91+
assert users["alice"].first_name == "Al"
6092

6193

6294
@pytest.mark.django_db
63-
def test_update(auth_client, users, status_new):
64-
t = Task.objects.create(name="Черновик", description="Описание",
65-
status=status_new, author=users["u1"])
66-
resp = auth_client.post(f"/tasks/{t.pk}/update/", data={
67-
"name": "Изменено",
68-
"description": "Новое описание",
69-
"status": status_new.pk,
70-
"executor": users["u2"].pk,
71-
})
72-
assert resp.status_code in (302, 301)
73-
t.refresh_from_db()
74-
assert t.name == "Изменено"
75-
assert t.description == "Новое описание"
76-
assert t.executor == users["u2"]
95+
def test_user_cannot_update_other(auth_client, users):
96+
url = reverse("update", args=[users["bob"].pk], current_app="users")
97+
r = auth_client.post(url, data={"username": "bob_hacked"})
98+
assert r.status_code in (302, 403, 404)
99+
users["bob"].refresh_from_db()
100+
assert users["bob"].username == "bob"
77101

78102

79103
@pytest.mark.django_db
80-
def test_view(auth_client, users, status_new):
81-
t = Task.objects.create(name="Посмотреть", description="Детали",
82-
status=status_new, author=users["u1"])
83-
r = auth_client.get(f"/tasks/{t.pk}/")
84-
assert r.status_code == 200
85-
html = r.content.decode()
86-
assert "Посмотреть" in html
87-
assert "Детали" in html
104+
def test_delete_requires_auth_redirects(client, users):
105+
url = reverse("delete", args=[users["alice"].pk], current_app="users")
106+
r = client.get(url)
107+
assert r.status_code in (302, 301)
108+
assert reverse("login") in r.url
88109

89110

90111
@pytest.mark.django_db
91-
def test_delete(auth_client, users, status_new):
92-
t = Task.objects.create(name="Удалить", description="Ненужная",
93-
status=status_new, author=users["u1"])
94-
r_get = auth_client.get(f"/tasks/{t.pk}/delete/")
112+
def test_user_can_delete_self(users):
113+
c = Client()
114+
c.login(username="bob", password=users["password"])
115+
url = reverse("delete", args=[users["bob"].pk], current_app="users")
116+
r_get = c.get(url)
95117
assert r_get.status_code == 200
96-
r_post = auth_client.post(f"/tasks/{t.pk}/delete/")
118+
r_post = c.post(url)
97119
assert r_post.status_code in (302, 301)
98-
assert not Task.objects.filter(pk=t.pk).exists()
120+
assert not User.objects.filter(pk=users["bob"].pk).exists()
121+
122+
123+
@pytest.mark.django_db
124+
def test_user_cannot_delete_other(auth_client, users):
125+
url = reverse("delete", args=[users["bob"].pk], current_app="users")
126+
r = auth_client.post(url)
127+
assert r.status_code in (302, 403, 404)
128+
assert User.objects.filter(pk=users["bob"].pk).exists()
99129

100130

101131
@pytest.mark.django_db
102132
def test_only_author_can_delete(auth_client, users, status_new):
103133
t = Task.objects.create(
104-
name="Чужая задача", description="...",
105-
status=status_new, author=users["u2"]
134+
name="Чужая задача",
135+
description="...",
136+
status=status_new,
137+
author=users["bob"],
106138
)
107-
r = auth_client.post(f"/tasks/{t.pk}/delete/")
139+
r = auth_client.post(reverse("tasks:delete", args=[t.pk]))
108140
assert r.status_code in (302, 301)
109141
assert Task.objects.filter(pk=t.pk).exists()
110142

111-
from django.test import Client
112143
c = Client()
113-
c.login(username="user2", password=users["pwd"])
114-
r2 = c.post(f"/tasks/{t.pk}/delete/")
144+
c.login(username="bob", password=users["password"])
145+
r2 = c.post(reverse("tasks:delete", args=[t.pk]))
115146
assert r2.status_code in (302, 301)
116147
assert not Task.objects.filter(pk=t.pk).exists()
148+
149+
150+
@pytest.mark.django_db
151+
def test_user_with_tasks_cannot_be_deleted(users, status_new):
152+
Task.objects.create(
153+
name="Тестовая",
154+
description="Проверка",
155+
status=status_new,
156+
author=users["bob"],
157+
)
158+
159+
c = Client()
160+
c.login(username="bob", password=users["password"])
161+
url = reverse("delete", args=[users["bob"].pk], current_app="users")
162+
r = c.post(url)
163+
assert r.status_code in (302, 301)
164+
assert User.objects.filter(pk=users["bob"].pk).exists()

0 commit comments

Comments
 (0)