All user comments on one page implemented, including tests

This commit is contained in:
2025-12-03 13:23:11 +01:00
parent 2c39db104e
commit a78f53f58e
4 changed files with 201 additions and 12 deletions

View File

@@ -2182,3 +2182,164 @@ class DeleteVorgabeCommentViewTest(TestCase):
self.assertIn('Content-Security-Policy', response) self.assertIn('Content-Security-Policy', response)
self.assertIn('X-Content-Type-Options', response) self.assertIn('X-Content-Type-Options', response)
self.assertEqual(response['X-Content-Type-Options'], 'nosniff') self.assertEqual(response['X-Content-Type-Options'], 'nosniff')
class UserCommentsViewTest(TestCase):
"""Test the user comments view that displays all comments grouped by document"""
def setUp(self):
"""Set up test data"""
# Create users
self.user1 = User.objects.create_user(username='user1', password='pass123')
self.user2 = User.objects.create_user(username='user2', password='pass123')
# Create documents
self.doc_type = Dokumententyp.objects.create(name='Test Type', verantwortliche_ve='test')
self.doc1 = Dokument.objects.create(nummer='DOC-001', name='Document 1', dokumententyp=self.doc_type, aktiv=True)
self.doc2 = Dokument.objects.create(nummer='DOC-002', name='Document 2', dokumententyp=self.doc_type, aktiv=True)
# Create themes
self.theme1 = Thema.objects.create(name='Theme 1')
self.theme2 = Thema.objects.create(name='Theme 2')
# Create vorgaben
from datetime import date
self.vorgabe1 = Vorgabe.objects.create(
nummer=1,
order=1,
dokument=self.doc1,
thema=self.theme1,
titel='Vorgabe 1',
gueltigkeit_von=date.today()
)
self.vorgabe2 = Vorgabe.objects.create(
nummer=2,
order=2,
dokument=self.doc1,
thema=self.theme1,
titel='Vorgabe 2',
gueltigkeit_von=date.today()
)
self.vorgabe3 = Vorgabe.objects.create(
nummer=1,
order=1,
dokument=self.doc2,
thema=self.theme2,
titel='Vorgabe 3',
gueltigkeit_von=date.today()
)
# Create comments for user1
self.comment1 = VorgabeComment.objects.create(
vorgabe=self.vorgabe1,
user=self.user1,
text='User1 comment on vorgabe1'
)
self.comment2 = VorgabeComment.objects.create(
vorgabe=self.vorgabe2,
user=self.user1,
text='User1 comment on vorgabe2'
)
self.comment3 = VorgabeComment.objects.create(
vorgabe=self.vorgabe3,
user=self.user1,
text='User1 comment on vorgabe3'
)
# Create comment for user2
self.comment4 = VorgabeComment.objects.create(
vorgabe=self.vorgabe1,
user=self.user2,
text='User2 comment on vorgabe1'
)
def test_user_comments_requires_login(self):
"""Test that user comments view requires authentication"""
response = self.client.get(reverse('user_comments'))
self.assertEqual(response.status_code, 302)
self.assertIn('/login/', response.url)
def test_user_comments_shows_only_own_comments(self):
"""Test that user only sees their own comments"""
self.client.login(username='user1', password='pass123')
response = self.client.get(reverse('user_comments'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'User1 comment on vorgabe1')
self.assertContains(response, 'User1 comment on vorgabe2')
self.assertContains(response, 'User1 comment on vorgabe3')
self.assertNotContains(response, 'User2 comment on vorgabe1')
def test_user_comments_grouped_by_document(self):
"""Test that comments are properly grouped by document"""
self.client.login(username='user1', password='pass123')
response = self.client.get(reverse('user_comments'))
self.assertEqual(response.status_code, 200)
# Check that document titles appear
self.assertContains(response, 'DOC-001 Document 1')
self.assertContains(response, 'DOC-002 Document 2')
# Check context
self.assertIn('comments_by_document', response.context)
self.assertEqual(len(response.context['comments_by_document']), 2)
def test_user_comments_count_display(self):
"""Test that total comment count is displayed"""
self.client.login(username='user1', password='pass123')
response = self.client.get(reverse('user_comments'))
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['total_comments'], 3)
self.assertContains(response, '3 Kommentare')
def test_user_comments_empty_view(self):
"""Test the view when user has no comments"""
# Create a new user with no comments
user3 = User.objects.create_user(username='user3', password='pass123')
self.client.login(username='user3', password='pass123')
response = self.client.get(reverse('user_comments'))
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['total_comments'], 0)
self.assertContains(response, 'Sie haben noch keine Kommentare')
def test_user_comments_comment_text_preserved(self):
"""Test that comment text is correctly displayed"""
self.client.login(username='user1', password='pass123')
response = self.client.get(reverse('user_comments'))
self.assertEqual(response.status_code, 200)
# Check that comment text appears in response
self.assertContains(response, 'User1 comment on vorgabe1')
def test_user_comments_vorgabe_number_link(self):
"""Test that vorgabe numbers are linked correctly"""
self.client.login(username='user1', password='pass123')
response = self.client.get(reverse('user_comments'))
self.assertEqual(response.status_code, 200)
# Check that vorgabe numbers appear (format is DOC-001.T.1)
self.assertContains(response, 'DOC-001.T.1')
self.assertContains(response, 'DOC-001.T.2')
self.assertContains(response, 'DOC-002.T.1')
def test_user_comments_ordered_by_creation_date(self):
"""Test that comments are ordered by creation date (newest first)"""
self.client.login(username='user1', password='pass123')
response = self.client.get(reverse('user_comments'))
self.assertEqual(response.status_code, 200)
# The queryset orders by vorgabe document, then by -created_at
# Check that all three comments are in the response
self.assertContains(response, 'User1 comment on vorgabe1')
self.assertContains(response, 'User1 comment on vorgabe2')
self.assertContains(response, 'User1 comment on vorgabe3')
def test_user_comments_template_used(self):
"""Test that correct template is used"""
self.client.login(username='user1', password='pass123')
response = self.client.get(reverse('user_comments'))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'standards/user_comments.html')

View File

@@ -4,6 +4,7 @@ from . import views
urlpatterns = [ urlpatterns = [
path('', views.standard_list, name='standard_list'), path('', views.standard_list, name='standard_list'),
path('unvollstaendig/', views.incomplete_vorgaben, name='incomplete_vorgaben'), path('unvollstaendig/', views.incomplete_vorgaben, name='incomplete_vorgaben'),
path('meine-kommentare/', views.user_comments, name='user_comments'),
path('<str:nummer>/', views.standard_detail, name='standard_detail'), path('<str:nummer>/', views.standard_detail, name='standard_detail'),
path('<str:nummer>/history/<str:check_date>/', views.standard_detail), path('<str:nummer>/history/<str:check_date>/', views.standard_detail),
path('<str:nummer>/history/', views.standard_detail, {"check_date":"today"}, name='standard_history'), path('<str:nummer>/history/', views.standard_detail, {"check_date":"today"}, name='standard_history'),

View File

@@ -366,3 +366,29 @@ def delete_vorgabe_comment(request, comment_id):
response['Content-Security-Policy'] = "default-src 'self'" response['Content-Security-Policy'] = "default-src 'self'"
response['X-Content-Type-Options'] = 'nosniff' response['X-Content-Type-Options'] = 'nosniff'
return response return response
@login_required
def user_comments(request):
"""
Display all comments made by the logged-in user, grouped by document.
"""
# Get all comments by the current user
user_comments = VorgabeComment.objects.filter(
user=request.user
).select_related('vorgabe', 'vorgabe__dokument').order_by(
'vorgabe__dokument__nummer', '-created_at'
)
# Group comments by document
comments_by_document = {}
for comment in user_comments:
dokument = comment.vorgabe.dokument
if dokument not in comments_by_document:
comments_by_document[dokument] = []
comments_by_document[dokument].append(comment)
return render(request, 'standards/user_comments.html', {
'comments_by_document': comments_by_document,
'total_comments': user_comments.count(),
})

View File

@@ -51,18 +51,19 @@
<span class="hidden-xs" style="margin-left: 0;">{{ user.first_name }} {{ user.last_name }}</span> <span class="hidden-xs" style="margin-left: 0;">{{ user.first_name }} {{ user.last_name }}</span>
<span class="caret" style="margin-left: 8px;"></span> <span class="caret" style="margin-left: 8px;"></span>
</a> </a>
<ul class="dropdown-menu dropdown-menu-right" role="menu"> <ul class="dropdown-menu dropdown-menu-right" role="menu">
<li><a href="{% url 'password_change' %}">Passwort ändern</a></li> <li><a href="{% url 'user_comments' %}">Meine Kommentare</a></li>
<li class="divider"></li> <li><a href="{% url 'password_change' %}">Passwort ändern</a></li>
<li> <li class="divider"></li>
<form method="post" action="{% url 'logout' %}" style="display: inline;"> <li>
{% csrf_token %} <form method="post" action="{% url 'logout' %}" style="display: inline;">
<button type="submit" style="background: none; border: none; color: inherit; padding: 3px 20px; width: 100%; text-align: left; cursor: pointer;"> {% csrf_token %}
Abmelden <button type="submit" style="background: none; border: none; color: inherit; padding: 3px 20px; width: 100%; text-align: left; cursor: pointer;">
</button> Abmelden
</form> </button>
</li> </form>
</ul> </li>
</ul>
</div> </div>
</div> </div>
{% else %} {% else %}