1
+ """Tests for label functionality in thread responses."""
2
+
3
+ import pytest
4
+ from django .urls import reverse
5
+ from rest_framework import status
6
+
7
+ from core import enums , factories , models
8
+
9
+ pytestmark = pytest .mark .django_db
10
+
11
+
12
+ @pytest .fixture
13
+ def user ():
14
+ """Create a test user."""
15
+ return factories .UserFactory ()
16
+
17
+
18
+ @pytest .fixture
19
+ def mailbox (user ):
20
+ """Create a mailbox with user access."""
21
+ mailbox = factories .MailboxFactory ()
22
+ factories .MailboxAccessFactory (
23
+ mailbox = mailbox ,
24
+ user = user ,
25
+ role = enums .MailboxRoleChoices .EDITOR ,
26
+ )
27
+ return mailbox
28
+
29
+
30
+ @pytest .fixture
31
+ def thread (mailbox ):
32
+ """Create a thread with mailbox access and a message."""
33
+ thread = factories .ThreadFactory ()
34
+ factories .ThreadAccessFactory (
35
+ mailbox = mailbox ,
36
+ thread = thread ,
37
+ role = enums .ThreadAccessRoleChoices .EDITOR ,
38
+ )
39
+ # Add a message to the thread
40
+ factories .MessageFactory (thread = thread )
41
+ thread .update_stats ()
42
+ return thread
43
+
44
+
45
+ @pytest .fixture
46
+ def label (mailbox ):
47
+ """Create a label in the mailbox."""
48
+ return factories .LabelFactory (mailbox = mailbox )
49
+
50
+
51
+ def test_thread_includes_labels (api_client , user , thread , label ):
52
+ """Test that thread responses include labels."""
53
+ # Add the label to the thread
54
+ thread .labels .add (label )
55
+
56
+ api_client .force_authenticate (user = user )
57
+ response = api_client .get (reverse ("threads-list" ))
58
+
59
+ assert response .status_code == status .HTTP_200_OK
60
+ assert response .data ["count" ] == 1 # We should have exactly one thread
61
+ thread_data = response .data ["results" ][0 ] # Get the first (and only) thread
62
+ assert "labels" in thread_data
63
+ assert len (thread_data ["labels" ]) == 1
64
+ label_data = thread_data ["labels" ][0 ]
65
+ assert label_data ["id" ] == str (label .id )
66
+ assert label_data ["name" ] == label .name
67
+ assert label_data ["slug" ] == label .slug
68
+ assert label_data ["color" ] == label .color
69
+ assert label_data ["mailbox" ] == label .mailbox .id
70
+
71
+
72
+ def test_thread_labels_filtered_by_access (api_client , user , thread , mailbox ):
73
+ """Test that thread responses only include labels from mailboxes the user has access to."""
74
+ # Create a label in a mailbox the user has access to
75
+ accessible_label = factories .LabelFactory (mailbox = mailbox )
76
+
77
+ # Create a label in a mailbox the user doesn't have access to
78
+ other_mailbox = factories .MailboxFactory ()
79
+ inaccessible_label = factories .LabelFactory (mailbox = other_mailbox )
80
+
81
+ # Add both labels to the thread
82
+ thread .labels .add (accessible_label , inaccessible_label )
83
+
84
+ api_client .force_authenticate (user = user )
85
+ response = api_client .get (reverse ("threads-list" ))
86
+
87
+ assert response .status_code == status .HTTP_200_OK
88
+ assert response .data ["count" ] == 1 # We should have exactly one thread
89
+ thread_data = response .data ["results" ][0 ] # Get the first (and only) thread
90
+ assert "labels" in thread_data
91
+ assert len (thread_data ["labels" ]) == 1
92
+ assert thread_data ["labels" ][0 ]["id" ] == str (accessible_label .id )
93
+
94
+
95
+ def test_thread_labels_empty_when_no_labels (api_client , user , thread ):
96
+ """Test that thread responses include an empty labels list when the thread has no labels."""
97
+ api_client .force_authenticate (user = user )
98
+ response = api_client .get (reverse ("threads-list" ))
99
+
100
+ assert response .status_code == status .HTTP_200_OK
101
+ assert response .data ["count" ] == 1 # We should have exactly one thread
102
+ thread_data = response .data ["results" ][0 ] # Get the first (and only) thread
103
+ assert "labels" in thread_data
104
+ assert thread_data ["labels" ] == []
105
+
106
+
107
+ def test_thread_labels_updated_after_label_changes (api_client , user , thread , label ):
108
+ """Test that thread responses reflect label changes."""
109
+ # Add the label to the thread
110
+ thread .labels .add (label )
111
+
112
+ api_client .force_authenticate (user = user )
113
+
114
+ # Check initial state
115
+ response = api_client .get (reverse ("threads-list" ))
116
+ assert response .status_code == status .HTTP_200_OK
117
+ assert response .data ["count" ] == 1 # We should have exactly one thread
118
+ thread_data = response .data ["results" ][0 ] # Get the first (and only) thread
119
+ assert len (thread_data ["labels" ]) == 1
120
+
121
+ # Remove the label
122
+ thread .labels .remove (label )
123
+
124
+ # Check updated state
125
+ response = api_client .get (reverse ("threads-list" ))
126
+ assert response .status_code == status .HTTP_200_OK
127
+ assert response .data ["count" ] == 1 # We should have exactly one thread
128
+ thread_data = response .data ["results" ][0 ] # Get the first (and only) thread
129
+ assert thread_data ["labels" ] == []
130
+
131
+
132
+ def test_thread_labels_in_detail_view (api_client , user , thread , label ):
133
+ """Test that labels are included in thread detail view."""
134
+ # Add the label to the thread
135
+ thread .labels .add (label )
136
+
137
+ api_client .force_authenticate (user = user )
138
+ response = api_client .get (reverse ("threads-detail" , args = [thread .id ]))
139
+
140
+ assert response .status_code == status .HTTP_200_OK
141
+ assert "labels" in response .data
142
+ assert len (response .data ["labels" ]) == 1
143
+ label_data = response .data ["labels" ][0 ]
144
+ assert label_data ["id" ] == str (label .id )
145
+ assert label_data ["name" ] == label .name
146
+ assert label_data ["slug" ] == label .slug
147
+ assert label_data ["color" ] == label .color
148
+ assert label_data ["mailbox" ] == label .mailbox .id
0 commit comments