|
1
|
import pytest |
|
2
|
|
|
3
|
from .models import Page |
|
4
|
|
|
5
|
|
|
6
|
@pytest.mark.django_db |
|
7
|
class TestPageModel: |
|
8
|
def test_create_page(self, org, admin_user): |
|
9
|
page = Page.objects.create(name="Test Page", content="# Hello", organization=org, created_by=admin_user) |
|
10
|
assert page.slug == "test-page" |
|
11
|
assert page.guid is not None |
|
12
|
assert page.is_published is True |
|
13
|
|
|
14
|
def test_soft_delete_page(self, sample_page, admin_user): |
|
15
|
sample_page.soft_delete(user=admin_user) |
|
16
|
assert Page.objects.filter(slug=sample_page.slug).count() == 0 |
|
17
|
assert Page.all_objects.filter(slug=sample_page.slug).count() == 1 |
|
18
|
|
|
19
|
|
|
20
|
@pytest.mark.django_db |
|
21
|
class TestPageViews: |
|
22
|
def test_page_list_renders(self, admin_client, sample_page): |
|
23
|
response = admin_client.get("/kb/") |
|
24
|
assert response.status_code == 200 |
|
25
|
assert sample_page.name in response.content.decode() |
|
26
|
|
|
27
|
def test_page_list_htmx(self, admin_client, sample_page): |
|
28
|
response = admin_client.get("/kb/", HTTP_HX_REQUEST="true") |
|
29
|
assert response.status_code == 200 |
|
30
|
assert b"page-table" in response.content |
|
31
|
|
|
32
|
def test_page_list_search(self, admin_client, sample_page): |
|
33
|
response = admin_client.get("/kb/?search=Getting") |
|
34
|
assert response.status_code == 200 |
|
35
|
|
|
36
|
def test_page_list_accessible_to_all(self, no_perm_client, sample_page): |
|
37
|
# Published pages are visible to everyone, including users without PAGE_VIEW perm |
|
38
|
response = no_perm_client.get("/kb/") |
|
39
|
assert response.status_code == 200 |
|
40
|
assert sample_page.name in response.content.decode() |
|
41
|
|
|
42
|
def test_page_create(self, admin_client, org): |
|
43
|
response = admin_client.post("/kb/create/", {"name": "New Page", "content": "# New", "is_published": True}) |
|
44
|
assert response.status_code == 302 |
|
45
|
assert Page.objects.filter(slug="new-page").exists() |
|
46
|
|
|
47
|
def test_page_create_denied(self, no_perm_client, org): |
|
48
|
response = no_perm_client.post("/kb/create/", {"name": "Hack"}) |
|
49
|
assert response.status_code == 403 |
|
50
|
|
|
51
|
def test_page_detail_renders_markdown(self, admin_client, sample_page): |
|
52
|
response = admin_client.get(f"/kb/{sample_page.slug}/") |
|
53
|
assert response.status_code == 200 |
|
54
|
content = response.content.decode() |
|
55
|
assert "<h1>" in content or "Getting Started" in content |
|
56
|
|
|
57
|
def test_page_detail_accessible_for_published(self, no_perm_client, sample_page): |
|
58
|
# Published pages are viewable by anyone, even without PAGE_VIEW permission |
|
59
|
response = no_perm_client.get(f"/kb/{sample_page.slug}/") |
|
60
|
assert response.status_code == 200 |
|
61
|
|
|
62
|
def test_page_detail_denied_for_draft(self, no_perm_client, org, admin_user): |
|
63
|
# Unpublished drafts require auth + edit permission |
|
64
|
draft = Page.objects.create(name="Draft Only", content="Secret", organization=org, is_published=False, created_by=admin_user) |
|
65
|
response = no_perm_client.get(f"/kb/{draft.slug}/") |
|
66
|
assert response.status_code == 403 |
|
67
|
|
|
68
|
def test_page_update(self, admin_client, sample_page): |
|
69
|
response = admin_client.post( |
|
70
|
f"/kb/{sample_page.slug}/edit/", |
|
71
|
{"name": "Updated Page", "content": "# Updated", "is_published": True}, |
|
72
|
) |
|
73
|
assert response.status_code == 302 |
|
74
|
sample_page.refresh_from_db() |
|
75
|
assert sample_page.name == "Updated Page" |
|
76
|
|
|
77
|
def test_page_update_denied(self, no_perm_client, sample_page): |
|
78
|
response = no_perm_client.post(f"/kb/{sample_page.slug}/edit/", {"name": "Hacked"}) |
|
79
|
assert response.status_code == 403 |
|
80
|
|
|
81
|
def test_page_delete(self, admin_client, sample_page): |
|
82
|
response = admin_client.post(f"/kb/{sample_page.slug}/delete/") |
|
83
|
assert response.status_code == 302 |
|
84
|
assert Page.objects.filter(slug=sample_page.slug).count() == 0 |
|
85
|
|
|
86
|
def test_page_delete_denied(self, no_perm_client, sample_page): |
|
87
|
response = no_perm_client.post(f"/kb/{sample_page.slug}/delete/") |
|
88
|
assert response.status_code == 403 |
|
89
|
|
|
90
|
def test_draft_page_visible_to_admin(self, admin_client, org, admin_user): |
|
91
|
Page.objects.create(name="Draft Doc", content="Secret", organization=org, is_published=False, created_by=admin_user) |
|
92
|
response = admin_client.get("/kb/") |
|
93
|
assert "Draft Doc" in response.content.decode() |
|
94
|
|
|
95
|
def test_draft_page_hidden_from_viewer(self, viewer_client, org, admin_user): |
|
96
|
Page.objects.create(name="Draft Doc", content="Secret", organization=org, is_published=False, created_by=admin_user) |
|
97
|
response = viewer_client.get("/kb/") |
|
98
|
assert "Draft Doc" not in response.content.decode() |
|
99
|
|