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
|
import datetime
from django.urls import reverse
from .base import AuthenticatedAPITestCase
from pydis_site.apps.api.models import OffensiveMessage
def create_offensive_message() -> OffensiveMessage:
"""Creates and returns an `OffensiveMessgage` record for tests."""
delete_at = datetime.datetime.now(tz=datetime.UTC) + datetime.timedelta(days=1)
return OffensiveMessage.objects.create(
id=602951077675139072,
channel_id=291284109232308226,
delete_date=delete_at,
)
class CreationTests(AuthenticatedAPITestCase):
def test_accept_valid_data(self):
url = reverse('api:bot:offensivemessage-list')
delete_at = datetime.datetime.now() + datetime.timedelta(days=1) # noqa: DTZ005
data = {
'id': '602951077675139072',
'channel_id': '291284109232308226',
'delete_date': delete_at.isoformat()[:-1]
}
aware_delete_at = delete_at.replace(tzinfo=datetime.UTC)
response = self.client.post(url, data=data)
self.assertEqual(response.status_code, 201)
offensive_message = OffensiveMessage.objects.get(id=response.json()['id'])
self.assertAlmostEqual(
aware_delete_at,
offensive_message.delete_date,
delta=datetime.timedelta(seconds=1)
)
self.assertEqual(data['id'], str(offensive_message.id))
self.assertEqual(data['channel_id'], str(offensive_message.channel_id))
def test_returns_400_on_non_future_date(self):
url = reverse('api:bot:offensivemessage-list')
delete_at = datetime.datetime.now() - datetime.timedelta(days=1) # noqa: DTZ005
data = {
'id': '602951077675139072',
'channel_id': '291284109232308226',
'delete_date': delete_at.isoformat()[:-1]
}
response = self.client.post(url, data=data)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json(), {
'delete_date': ['Date must be a future date']
})
def test_returns_400_on_negative_id_or_channel_id(self):
url = reverse('api:bot:offensivemessage-list')
delete_at = datetime.datetime.now() + datetime.timedelta(days=1) # noqa: DTZ005
data = {
'id': '602951077675139072',
'channel_id': '291284109232308226',
'delete_date': delete_at.isoformat()[:-1]
}
cases = (
('id', '-602951077675139072'),
('channel_id', '-291284109232308226')
)
for field, invalid_value in cases:
with self.subTest(field=field, invalid_value=invalid_value):
test_data = data.copy()
test_data.update({field: invalid_value})
response = self.client.post(url, test_data)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json(), {
field: ['Ensure this value is greater than or equal to 0.']
})
class ListTests(AuthenticatedAPITestCase):
@classmethod
def setUpTestData(cls):
delete_at = datetime.datetime.now() + datetime.timedelta(days=1) # noqa: DTZ005
aware_delete_at = delete_at.replace(tzinfo=datetime.UTC)
cls.messages = [
{
'id': 602951077675139072,
'channel_id': 91284109232308226,
},
{
'id': 645298201494159401,
'channel_id': 592000283102674944
}
]
cls.of1 = OffensiveMessage.objects.create(
**cls.messages[0],
delete_date=aware_delete_at.isoformat()
)
cls.of2 = OffensiveMessage.objects.create(
**cls.messages[1],
delete_date=aware_delete_at.isoformat()
)
# Expected API answer :
cls.messages[0]['delete_date'] = delete_at.isoformat() + 'Z'
cls.messages[1]['delete_date'] = delete_at.isoformat() + 'Z'
def test_get_data(self):
url = reverse('api:bot:offensivemessage-list')
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json(), self.messages)
class DeletionTests(AuthenticatedAPITestCase):
@classmethod
def setUpTestData(cls):
cls.valid_offensive_message = create_offensive_message()
def test_delete_data(self):
url = reverse(
'api:bot:offensivemessage-detail', args=(self.valid_offensive_message.id,)
)
response = self.client.delete(url)
self.assertEqual(response.status_code, 204)
self.assertFalse(
OffensiveMessage.objects.filter(id=self.valid_offensive_message.id).exists()
)
class UpdateOffensiveMessageTestCase(AuthenticatedAPITestCase):
@classmethod
def setUpTestData(cls):
cls.message = create_offensive_message()
cls.in_one_week = datetime.datetime.now(tz=datetime.UTC) + datetime.timedelta(days=7)
def test_updating_message(self):
url = reverse('api:bot:offensivemessage-detail', args=(self.message.id,))
data = {'delete_date': self.in_one_week.isoformat()}
update_response = self.client.patch(url, data=data)
self.assertEqual(update_response.status_code, 200)
self.message.refresh_from_db()
self.assertAlmostEqual(
self.message.delete_date,
self.in_one_week,
delta=datetime.timedelta(seconds=1),
)
def test_updating_write_once_fields(self):
"""Fields such as the channel ID may not be updated."""
url = reverse('api:bot:offensivemessage-detail', args=(self.message.id,))
data = {'channel_id': self.message.channel_id + 1}
response = self.client.patch(url, data=data)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.json(), {'channel_id': ["This field cannot be updated."]})
def test_updating_nonexistent_message(self):
url = reverse('api:bot:offensivemessage-detail', args=(self.message.id + 1,))
data = {'delete_date': self.in_one_week}
response = self.client.patch(url, data=data)
self.assertEqual(response.status_code, 404)
self.message.refresh_from_db()
self.assertNotAlmostEqual(
self.message.delete_date,
self.in_one_week,
delta=datetime.timedelta(seconds=1),
)
class NotAllowedMethodsTests(AuthenticatedAPITestCase):
@classmethod
def setUpTestData(cls):
cls.message = create_offensive_message()
def test_returns_405_for_get(self):
url = reverse('api:bot:offensivemessage-detail', args=(self.message.id,))
response = self.client.get(url)
self.assertEqual(response.status_code, 405)
|