2
0
mirror of https://github.com/inventree/InvenTree.git synced 2026-04-21 10:40:52 +00:00

!refactor(backend): remove API quirks (#11723)

* move action to post endpoint

* use default return code

* remove custom permissions on notifications endpoint

* add api bump

* update link

* fix assertation

* fix test to use post - this was refactored
This commit is contained in:
Matthias Mair
2026-04-13 02:31:08 +02:00
committed by GitHub
parent fc06aa354a
commit 27ce60dea3
6 changed files with 14 additions and 22 deletions

View File

@@ -1,11 +1,16 @@
"""InvenTree API version information.""" """InvenTree API version information."""
# InvenTree API version # InvenTree API version
INVENTREE_API_VERSION = 478 INVENTREE_API_VERSION = 479
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about.""" """Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
INVENTREE_API_TEXT = """ INVENTREE_API_TEXT = """
v479 -> 2026-04-11 : https://github.com/inventree/InvenTree/pull/11723
- POST /api//notifications/readall/ now requires a POST action
- POST /api/admin/email/test/ - now returns a 200 on. a successful test
- GET /api/notifications/ - now uses user-centric permissions, not a general read
v478 -> 2026-04-11 : https://github.com/inventree/InvenTree/pull/11073 v478 -> 2026-04-11 : https://github.com/inventree/InvenTree/pull/11073
- Add OptionalField class for cleaner handling of optional fields in serializers - Add OptionalField class for cleaner handling of optional fields in serializers

View File

@@ -395,21 +395,8 @@ class NotificationMessageViewSet(
queryset = queryset.filter(user=request.user) queryset = queryset.filter(user=request.user)
return queryset return queryset
def get_permissions(self):
"""Override permissions for list view."""
if self.action == 'list':
return [IsAuthenticatedOrReadScope()]
else:
return super().get_permissions()
def list(self, request, *args, **kwargs):
"""List view for all notifications of the current user."""
# TODO @matmair permissions for this are currently being overwritten in get_permissions - this should be moved to a dedicated endpoint
return super().list(request, *args, **kwargs)
# TODO @matmair this should really be a POST
@action( @action(
detail=False, methods=['get'], permission_classes=[IsAuthenticatedOrReadScope] detail=False, methods=['post'], permission_classes=[IsAuthenticatedOrReadScope]
) )
def readall(self, request, *args, **kwargs): def readall(self, request, *args, **kwargs):
"""Set all messages for the current user as read.""" """Set all messages for the current user as read."""
@@ -1248,7 +1235,6 @@ class EmailViewSet(BulkDeleteViewsetMixin, RetrieveDestroyModelViewSet):
'thread_id_key', 'thread_id_key',
] ]
@extend_schema(responses={201: common.serializers.TestEmailSerializer})
@action( @action(
detail=False, detail=False,
methods=['post'], methods=['post'],
@@ -1270,8 +1256,7 @@ class EmailViewSet(BulkDeleteViewsetMixin, RetrieveDestroyModelViewSet):
raise serializers.ValidationError( raise serializers.ValidationError(
detail=f'Failed to send test email: "{reason}"' detail=f'Failed to send test email: "{reason}"'
) # pragma: no cover ) # pragma: no cover
# TODO @matmair - breaking change: this should be a 200 return Response(serializer.data)
return Response(serializer.data, status=201)
admin_router.register('email', EmailViewSet, basename='api-email') admin_router.register('email', EmailViewSet, basename='api-email')

View File

@@ -103,7 +103,9 @@ class EmailTests(InvenTreeAPITestCase):
) )
def test_email_api(self): def test_email_api(self):
"""Test that the email api endpoints work.""" """Test that the email api endpoints work."""
self.post(reverse('api-email-test'), {'email': 'test@example.org'}) self.post(
reverse('api-email-test'), {'email': 'test@example.org'}, expected_code=200
)
response = self.get(reverse('api-email-list'), expected_code=200) response = self.get(reverse('api-email-list'), expected_code=200)
self.assertIn('subject', response.data[0]) self.assertIn('subject', response.data[0])

View File

@@ -1332,7 +1332,7 @@ class NotificationTest(InvenTreeAPITestCase):
self.assertEqual(len(self.get(url, expected_code=200).data), 1) self.assertEqual(len(self.get(url, expected_code=200).data), 1)
# Read with readall endpoint # Read with readall endpoint
self.get(reverse('api-notifications-readall'), {}, expected_code=200) self.post(reverse('api-notifications-readall'), {}, expected_code=200)
self.assertEqual(NotificationMessage.objects.filter(read=True).count(), 1) self.assertEqual(NotificationMessage.objects.filter(read=True).count(), 1)
self.assertEqual(len(self.get(url, expected_code=200).data), 1) self.assertEqual(len(self.get(url, expected_code=200).data), 1)

View File

@@ -137,7 +137,7 @@ export function NotificationDrawer({
const markAllAsRead = useCallback(() => { const markAllAsRead = useCallback(() => {
api api
.get(apiUrl(ApiEndpoints.notifications_readall), { .post(apiUrl(ApiEndpoints.notifications_readall), {
params: { params: {
read: false read: false
} }

View File

@@ -26,7 +26,7 @@ export default function NotificationsPage() {
const markAllAsRead = useCallback(() => { const markAllAsRead = useCallback(() => {
api api
.get(apiUrl(ApiEndpoints.notifications_readall), { .post(apiUrl(ApiEndpoints.notifications_readall), {
params: { params: {
read: false read: false
} }