From 4fade5caaf564d717d5356873a2a54d887e302fc Mon Sep 17 00:00:00 2001 From: a2-imeri <Alfret2.imeri@live.uwe.ac.uk> Date: Wed, 10 Jul 2024 10:57:08 +0100 Subject: [PATCH] Added More Tests Items and Locations --- .../rules/__pycache__/views.cpython-310.pyc | Bin 5607 -> 6936 bytes MisplaceAI/rules/tests/test_items.py | 127 +++++++++++------- MisplaceAI/rules/tests/test_locations.py | 84 ++++++++---- MisplaceAI/rules/views.py | 87 +++++++++--- 4 files changed, 207 insertions(+), 91 deletions(-) diff --git a/MisplaceAI/rules/__pycache__/views.cpython-310.pyc b/MisplaceAI/rules/__pycache__/views.cpython-310.pyc index 42d382c54f46045ba5c3e96a83735586c16ecf95..22744b11f4ec44052d2c2cd9e304390e2ea764c1 100644 GIT binary patch delta 2166 zcmaE^J;RJIpO=@5fq{YHMPy%Ew82KcCCp64agz^ni}^F9Ft;#7v8A%7ax^ohu%xiI zFf=npaYFfQDePcA7nIMD!U^VcL-|}O++aRW3QsVDChslb$sbvSCkyk4v1FE{=1$h- z(Vu*lLz1z0vJs1cswQid8<zqU1f`Y~Wu}&;DkLi8WEPhw<fkcsv=mRCDX2O*m8F_n znSp_!n2mvfL4bAgYnE~iP39^UxNhg7)Wi~y-n`Uuus%Jw)Z|pwNuqin%^)B1uyHVP zFbOaTFjYxR{>UOSS%EEwMU$mUYjUNaj6BFjgwB<Wx0o_higXwl7>ZaK7#LPgUce^C zrVHZgO%CJ|<}v^=4Z$)u*=)J(K$h?@Ffj12O;%(#;A3ZCU;yd!XJBCX>@(S(O|m|P zxtF<?t%hv@%R+`Cxf-?wtP2?!8A{k{*s_>Q*t0lNSbCX)A$-mf_AD+4Uz4@U1n!@J z#G;bS#GIT;h0=l)u&47BQY$ixOEUA)(Y#({%D})7vXZGtf`NhI7JEUWBUmfgGezbg z$6J611vsGyQpZ}5SdyF(0CF_gGpquP9E=={0*nHTRg$1EV+SipW}bYWLws^9yQ+aE zbCnj{eJ-gvsi3I9<EqK+>>dJ^AX{ZXge-`#n%u}O%<sg&zz_opMo>iauuW#<P-5hr zEFz*I#RO6$1R{(<gf)n;2N6z_7mA8&6sa>XFn~-e2KkkPfrXKcg@cKWn~RZ+pNo-A zkc*Lxn~$+beey&O8K&X{P*M-%O<_)9X<>vXcGeU&aN>m}cJ>qwFdvrKIa9d6d{|=V zPT>Lbc~Y2y88rEBiBI0gB`#Ox4GxO1%+zv)l6-~S#Jt4xRE3=U<iwK9{JhD!JYMx~ z3=9l4OhvpU3?+;;Oeu`LOtq{fOf{^{jJ0fed?k!o%%JqKfHj3_A!99j2~!O_$fdnZ zwQS&&!d}9W#hJniN-3Ib__Gkq+G2(LB85bS;)2xV%(Sq~WVm|}sU4hHiZnnerbq-7 zu%M)?$yLMwVuKPw5kH6}1|q~kgeHh!0TG}eFJha#kXLka6_={XEl#+#MW|`3NQr@g zp%4_mAOl%gc$l~t1(<ml1sEsq;gXtM!zr7s&A`B*$y}uY4n$DdfReRg1|vBeo;@`= zAua^F29irbjsv?8l$?t6L0ovAEiwY7I7v`yst36UTspAAQ@YILeO!{0`M6{`Oh7JT zsnP?L5O!D`0Lo-Yg#<Txh#|QLRBC9#U9gh9NDAa6X%OKKB0vea2%H@}7#J8PJ8+6h zf)aWc$bFy?<6-54=f%l;xU^D`i<lxCkV9FkEZ{+hx2VA3laL}?kV`<3U*rX1d4qz9 zAC%Rmfw&F~3=CDWpuk}R6%*i6K%(9eWHoaYB3iJN0yr!LmqwawNTCKQ1d0&R<_t2M z4R26QZsryg1!-FZ3Mo)z^RRL-@-SA(P2R^P!JPswl2$VM6}dnP3s45k0x1Q>4WzK( zVq)XtVr1h26%-)M$5`YBDl9hd=dNQE2FEcdOf(s9v6L3478RLI4&e1>)SNtrH;8fD z=J&k*jBHk*@bR4N!f(WAI=P(RlF@4NMt&(q!^vm(^}#hzkte8pWiC!FDG~&!)t@XN zAkSzy*+4)XrrB3OmKBsF&uq>Y2w)U|+gk)R{Jdb8D5%DP@<FCVfC#<GRzk+Y;4(E5 z#D^${CL&f)BKkIYme74h)5%rBnrxt;DsrB@QrH;Glw+LyNLbgb$OjbCTt%RownznJ ziYkb31reZxR-^`EDS-%(6N^Bm7J-Xjwjy5!28IojQ$%bSqb4sD`N{?=j*HwT&k=QF K<rDA|aRUJ5M7$UP delta 1294 zcmbPX_FS7UpO=@5fq{YHe_&slmCi=KCCtH}y%-o6QW>HcQy8L{Qkl~kqgYZHQ<z#9 zqF7VeQrVjsQ<zg&S{Rxcqd1^^))Y1{pA*VwPvHRbxl%ZT88o?W2~Sq!5N1kdn#?C5 z&iHw9KZ^nLN>;zgoUGN{atsU%pV=4~7zCIm_p_EWuVnU{tj9KqTMZ-*av2Zv<kM_j zzAIV$Rx;jV%1kLTWME(@Vr5`p(Bv-S0I|721Rscy01-wY!WcxbfC!M;MUo(vDTpuw zX`FnP-Bt*s<TDQg0|O5;9}@=?2a~|$39OQnO*sT6OG@xej^k8iUCHcMWHWg)r-zXp zNUsctkOdL;AVL97D1uln3=9lTAXkHI<YAty%cYdZU8D?>QUMXFAc7r4fc#dZ1Y$9P z2q6$*0U{hg1jw8sgxO#g*a8g(1_mjR1t1L^3~WpsOl%xnjBGqyjBI>-j71ugFLKE! z6{&-K$aPEHF(o%M&o?nIF+J5MKRK}^Ge0jZGqoHN3ra<rAiK0cYB`HQp-?0S5)cOw zIv|37vN@|B7iSJsYw_fd>>`uvSy?&#L9%)b3=EScc+I2qK|BM9G5jDl&Nwgu$-?8H z$Q;B4dk##1eFzGKaFDnq$oMC`7A{sGo;ApLXk>$(ir*r%$Y!6sg~wp>H+Fu$B2f6I zfJ}4*ng4=M3l!7!MW9$Kat2w#21!w1OTh7fNJ6d<c~ArtNrTMr1`&uP;RE7=y#gk{ z{s9?L3=(%^U|^_{!yY3><$5WpIjJS7ensvewP5WC0&I{c0|NutJ`a!z&&e0LWH)~n zsAUwk0rA0^f$<hgX>n>%k?rJWA#X;V$>)WF7~3~13Hvj$fm5s3<Z=-sMw`j2L@Z@M z0-8ca;HUzpLxeZYCjS@FmjdODB2Y1Ki@7+pq(~5C3n>0Hc_s(2il{(zg7U;I9#{g2 z&rB&U@&hRZnO@{Ixj|Hx6%?U!H!l(mU=)D6v<NECBpxOT%8gJyNM{6yFrJ(%ZY%&Y zyeJaHhbrG7F2M?lzvGk7ir;6nnY>m)lMNKUMXr<YNEm~e?-?eGO6sy|GWuz9O%CAF t;09R_j`Sjz$rX|^jE$40O4=~qntVy}D;p>`6?slRE9J(@BVZ_E1^}+#@?HP{ diff --git a/MisplaceAI/rules/tests/test_items.py b/MisplaceAI/rules/tests/test_items.py index a16cab3..080f8b3 100644 --- a/MisplaceAI/rules/tests/test_items.py +++ b/MisplaceAI/rules/tests/test_items.py @@ -11,113 +11,146 @@ Test 7: test_update_item_as_normal_user - Test that a normal user cannot update Test 8: test_create_item_with_invalid_data - Test that creating an item with invalid data returns validation errors. Test 9: test_get_item_detail_as_admin - Test that an admin user can retrieve the details of a specific item. Test 10: test_get_item_detail_as_normal_user - Test that a normal user can retrieve the details of a specific item. +Test 11: test_create_duplicate_item_as_admin - Test that creating a duplicate item as admin returns an error. +Test 12: test_partial_update_item_as_admin - Test that an admin user can perform partial updates on an item. +Test 13: test_unauthenticated_access - Test that unauthenticated users cannot access any item endpoints. """ -from rest_framework.test import APITestCase + from rest_framework import status -from django.urls import reverse +from rest_framework.reverse import reverse +from rest_framework.test import APITestCase from django.contrib.auth.models import User from rules.models import Item class AdminManageItemViewTest(APITestCase): - """ - Test suite for the AdminManageItemView. - """ - def setUp(self): - self.admin_user = User.objects.create_superuser(username='adminuser', password='adminpassword') - self.normal_user = User.objects.create_user(username='testuser', password='testpassword') + """ + Set up test data for the test cases. + """ + self.admin_user = User.objects.create_superuser(username='admin', password='password') + self.normal_user = User.objects.create_user(username='user', password='password') + self.item = Item.objects.create(name='Test Item') + + self.url = reverse('rules:admin_manage_item') + self.detail_url = lambda item_id: reverse('rules:admin_manage_item_detail', args=[item_id]) def test_create_item_as_admin(self): """ - Ensure admin users can create a new item. + Test 1: test_create_item_as_admin - Test that an admin user can create a new item. """ self.client.force_authenticate(user=self.admin_user) - url = reverse('rules:admin_manage_item') data = {'name': 'New Item'} - response = self.client.post(url, data, format='json') + response = self.client.post(self.url, data, format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED) - self.assertEqual(Item.objects.count(), 2) - self.assertEqual(Item.objects.get(id=response.data['id']).name, 'New Item') def test_create_item_as_normal_user(self): """ - Ensure normal users cannot create a new item. + Test 2: test_create_item_as_normal_user - Test that a normal user cannot create a new item. """ self.client.force_authenticate(user=self.normal_user) - url = reverse('rules:admin_manage_item') data = {'name': 'New Item'} - response = self.client.post(url, data, format='json') + response = self.client.post(self.url, data, format='json') self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_delete_item_as_admin(self): """ - Ensure admin users can delete an existing item. + Test 3: test_delete_item_as_admin - Test that an admin user can delete an existing item. """ self.client.force_authenticate(user=self.admin_user) - url = reverse('rules:admin_manage_item_detail', args=[self.item.id]) - response = self.client.delete(url) + response = self.client.delete(self.detail_url(self.item.id)) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) - self.assertEqual(Item.objects.count(), 0) def test_delete_item_as_normal_user(self): """ - Ensure normal users cannot delete an existing item. + Test 4: test_delete_item_as_normal_user - Test that a normal user cannot delete an existing item. """ self.client.force_authenticate(user=self.normal_user) - url = reverse('rules:admin_manage_item_detail', args=[self.item.id]) - response = self.client.delete(url) + response = self.client.delete(self.detail_url(self.item.id)) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_get_items_as_normal_user(self): """ - Ensure normal users can retrieve the list of items. + Test 5: test_get_items_as_normal_user - Test that a normal user can retrieve the list of items. """ self.client.force_authenticate(user=self.normal_user) - url = reverse('rules:admin_manage_item') - response = self.client.get(url) + response = self.client.get(self.url) self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(len(response.data), 1) - self.assertEqual(response.data[0]['name'], 'Test Item') def test_update_item_as_admin(self): """ - Ensure admin users can update an existing item. + Test 6: test_update_item_as_admin - Test that an admin user can update an existing item. """ self.client.force_authenticate(user=self.admin_user) - url = reverse('rules:admin_manage_item_detail', args=[self.item.id]) data = {'name': 'Updated Item'} - response = self.client.put(url, data, format='json') + response = self.client.put(self.detail_url(self.item.id), data, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(Item.objects.get(id=self.item.id).name, 'Updated Item') def test_update_item_as_normal_user(self): """ - Ensure normal users cannot update an existing item. + Test 7: test_update_item_as_normal_user - Test that a normal user cannot update an existing item. """ self.client.force_authenticate(user=self.normal_user) - url = reverse('rules:admin_manage_item_detail', args=[self.item.id]) data = {'name': 'Updated Item'} - response = self.client.put(url, data, format='json') + response = self.client.put(self.detail_url(self.item.id), data, format='json') self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - + def test_create_item_with_invalid_data(self): + """ + Test 8: test_create_item_with_invalid_data - Test that creating an item with invalid data returns validation errors. + """ self.client.force_authenticate(user=self.admin_user) - url = reverse('rules:admin_manage_item') - data = {'invalid_field': 'invalid_data'} - response = self.client.post(url, data, format='json') - assert response.status_code == status.HTTP_400_BAD_REQUEST + data = {'name': ''} + response = self.client.post(self.url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) def test_get_item_detail_as_admin(self): + """ + Test 9: test_get_item_detail_as_admin - Test that an admin user can retrieve the details of a specific item. + """ self.client.force_authenticate(user=self.admin_user) - url = reverse('rules:admin_manage_item_detail', args=[self.item.id]) - response = self.client.get(url) - assert response.status_code == status.HTTP_200_OK + response = self.client.get(self.detail_url(self.item.id)) + self.assertEqual(response.status_code, status.HTTP_200_OK) def test_get_item_detail_as_normal_user(self): + """ + Test 10: test_get_item_detail_as_normal_user - Test that a normal user can retrieve the details of a specific item. + """ self.client.force_authenticate(user=self.normal_user) - url = reverse('rules:admin_manage_item_detail', args=[self.item.id]) - response = self.client.get(url) - assert response.status_code == status.HTTP_200_OK + response = self.client.get(self.detail_url(self.item.id)) + self.assertEqual(response.status_code, status.HTTP_200_OK) - + def test_create_duplicate_item_as_admin(self): + """ + Test 11: test_create_duplicate_item_as_admin - Test that creating a duplicate item as admin returns an error. + """ + self.client.force_authenticate(user=self.admin_user) + data = {'name': 'Test Item'} + response = self.client.post(self.url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + + def test_partial_update_item_as_admin(self): + """ + Test 12: test_partial_update_item_as_admin - Test that an admin user can perform partial updates on an item. + """ + self.client.force_authenticate(user=self.admin_user) + data = {'name': 'Partially Updated Item'} + response = self.client.patch(self.detail_url(self.item.id), data, format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + updated_item = Item.objects.get(id=self.item.id) + self.assertEqual(updated_item.name, 'Partially Updated Item') + + + def test_unauthenticated_access(self): + """ + Test 13: test_unauthenticated_access - Test that unauthenticated users cannot access any item endpoints. + """ + data = {'name': 'Unauthenticated Item'} + response = self.client.post(self.url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + response = self.client.get(self.url) + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + response = self.client.put(self.detail_url(self.item.id), data, format='json') + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + response = self.client.delete(self.detail_url(self.item.id)) + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) diff --git a/MisplaceAI/rules/tests/test_locations.py b/MisplaceAI/rules/tests/test_locations.py index 5c1ee11..32b210e 100644 --- a/MisplaceAI/rules/tests/test_locations.py +++ b/MisplaceAI/rules/tests/test_locations.py @@ -12,6 +12,8 @@ Test 7: test_update_location_as_normal_user - Test that a normal user cannot upd Test 8: test_create_location_with_invalid_data - Test that creating a location with invalid data returns validation errors. Test 9: test_get_location_detail_as_admin - Test that an admin user can retrieve the details of a specific location. Test 10: test_get_location_detail_as_normal_user - Test that a normal user can retrieve the details of a specific location. +Test 11: test_partial_update_location_as_admin - Test that an admin user can perform partial updates on a location. +Test 12: test_partial_update_location_as_normal_user - Test that a normal user cannot perform partial updates on a location. """ @@ -27,68 +29,70 @@ class AdminManageLocationViewTest(APITestCase): """ def setUp(self): + """ + Set up the test environment. + """ self.admin_user = User.objects.create_superuser(username='adminuser', password='adminpassword') self.normal_user = User.objects.create_user(username='testuser', password='testpassword') self.location = Location.objects.create(name='Test Location') + self.url = reverse('rules:admin_manage_location') + self.detail_url = lambda location_id: reverse('rules:admin_manage_location_detail', args=[location_id]) def test_create_location_as_admin(self): """ - Ensure admin users can create a new location. + Test 1: Ensure admin users can create a new location. """ self.client.force_authenticate(user=self.admin_user) - url = reverse('rules:admin_manage_location') data = {'name': 'New Location'} - response = self.client.post(url, data, format='json') + response = self.client.post(self.url, data, format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Location.objects.count(), 2) self.assertEqual(Location.objects.get(id=response.data['id']).name, 'New Location') def test_create_location_as_normal_user(self): """ - Ensure normal users cannot create a new location. + Test 2: Ensure normal users cannot create a new location. """ self.client.force_authenticate(user=self.normal_user) - url = reverse('rules:admin_manage_location') data = {'name': 'New Location'} - response = self.client.post(url, data, format='json') + response = self.client.post(self.url, data, format='json') self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_delete_location_as_admin(self): """ - Ensure admin users can delete an existing location. + Test 3: Ensure admin users can delete an existing location. """ self.client.force_authenticate(user=self.admin_user) - url = reverse('rules:admin_manage_location_detail', args=[self.location.id]) + url = self.detail_url(self.location.id) response = self.client.delete(url) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertEqual(Location.objects.count(), 0) def test_delete_location_as_normal_user(self): """ - Ensure normal users cannot delete an existing location. + Test 4: Ensure normal users cannot delete an existing location. """ self.client.force_authenticate(user=self.normal_user) - url = reverse('rules:admin_manage_location_detail', args=[self.location.id]) + url = self.detail_url(self.location.id) response = self.client.delete(url) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_get_locations_as_normal_user(self): """ - Ensure normal users can retrieve the list of locations. + Test 5: Ensure normal users can retrieve the list of locations. """ self.client.force_authenticate(user=self.normal_user) - url = reverse('rules:admin_manage_location') - response = self.client.get(url) + response = self.client.get(self.url) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 1) self.assertEqual(response.data[0]['name'], 'Test Location') def test_update_location_as_admin(self): """ - Ensure admin users can update an existing location. + Test 6: Ensure admin users can update an existing location. """ self.client.force_authenticate(user=self.admin_user) - url = reverse('rules:admin_manage_location_detail', args=[self.location.id]) + url = self.detail_url(self.location.id) data = {'name': 'Updated Location'} response = self.client.put(url, data, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -96,28 +100,60 @@ class AdminManageLocationViewTest(APITestCase): def test_update_location_as_normal_user(self): """ - Ensure normal users cannot update an existing location. + Test 7: Ensure normal users cannot update an existing location. """ self.client.force_authenticate(user=self.normal_user) - url = reverse('rules:admin_manage_location_detail', args=[self.location.id]) + url = self.detail_url(self.location.id) data = {'name': 'Updated Location'} response = self.client.put(url, data, format='json') self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + def test_create_location_with_invalid_data(self): + """ + Test 8: Ensure creating a location with invalid data returns validation errors. + """ self.client.force_authenticate(user=self.admin_user) - url = reverse('rules:admin_manage_location') data = {'invalid_field': 'invalid_data'} - response = self.client.post(url, data, format='json') - assert response.status_code == status.HTTP_400_BAD_REQUEST + response = self.client.post(self.url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) def test_get_location_detail_as_admin(self): + """ + Test 9: Ensure admin users can retrieve the details of a specific location. + """ self.client.force_authenticate(user=self.admin_user) - url = reverse('rules:admin_manage_location_detail', args=[self.location.id]) + url = self.detail_url(self.location.id) response = self.client.get(url) - assert response.status_code == status.HTTP_200_OK + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data['name'], 'Test Location') def test_get_location_detail_as_normal_user(self): + """ + Test 10: Ensure normal users can retrieve the details of a specific location. + """ self.client.force_authenticate(user=self.normal_user) - url = reverse('rules:admin_manage_location_detail', args=[self.location.id]) + url = self.detail_url(self.location.id) response = self.client.get(url) - assert response.status_code == status.HTTP_200_OK + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data['name'], 'Test Location') + + def test_partial_update_location_as_admin(self): + """ + Test 11: Ensure admin users can perform partial updates on a location. + """ + self.client.force_authenticate(user=self.admin_user) + url = self.detail_url(self.location.id) + data = {'name': 'Partially Updated Location'} + response = self.client.patch(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(Location.objects.get(id=self.location.id).name, 'Partially Updated Location') + + def test_partial_update_location_as_normal_user(self): + """ + Test 12: Ensure normal users cannot perform partial updates on a location. + """ + self.client.force_authenticate(user=self.normal_user) + url = self.detail_url(self.location.id) + data = {'name': 'Partially Updated Location'} + response = self.client.patch(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) diff --git a/MisplaceAI/rules/views.py b/MisplaceAI/rules/views.py index c7857ab..7a51421 100644 --- a/MisplaceAI/rules/views.py +++ b/MisplaceAI/rules/views.py @@ -22,12 +22,20 @@ class UserListView(APIView): serializer = UserSerializer(users, many=True) # Return the serialized data with a 200 OK status return Response(serializer.data, status=status.HTTP_200_OK) + + class AdminManageItemView(APIView): + """ + View to manage items. Only accessible by authenticated users. + """ # Only authenticated users can access this view permission_classes = [IsAuthenticated] def get(self, request, *args, **kwargs): + """ + Retrieve a list of items for the authenticated user. + """ # Retrieve all items from the database, ordered by name items = Item.objects.all().order_by('name') # Serialize the item objects @@ -37,6 +45,9 @@ class AdminManageItemView(APIView): @method_decorator(admin_required) def post(self, request, *args, **kwargs): + """ + Create a new item. + """ # Deserialize the request data into an ItemSerializer serializer = ItemSerializer(data=request.data) # Check if the data is valid @@ -50,6 +61,9 @@ class AdminManageItemView(APIView): @method_decorator(admin_required) def put(self, request, item_id, *args, **kwargs): + """ + Update an existing item. + """ # Retrieve the existing item or return 404 if not found item = get_object_or_404(Item, id=item_id) # Deserialize the request data into an ItemSerializer @@ -62,9 +76,24 @@ class AdminManageItemView(APIView): return Response(serializer.data, status=status.HTTP_200_OK) # Return the errors with a 400 Bad Request status return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + @method_decorator(admin_required) + def patch(self, request, item_id, *args, **kwargs): + """ + Partially update an existing item. + """ + item = get_object_or_404(Item, id=item_id) + serializer = ItemSerializer(item, data=request.data, partial=True) + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status=status.HTTP_200_OK) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @method_decorator(admin_required) def delete(self, request, item_id, *args, **kwargs): + """ + Delete an existing item. + """ # Retrieve the existing item or return 404 if not found item = get_object_or_404(Item, id=item_id) # Delete the item from the database @@ -72,53 +101,71 @@ class AdminManageItemView(APIView): # Return a 204 No Content status to indicate successful deletion return Response(status=status.HTTP_204_NO_CONTENT) + + class AdminManageLocationView(APIView): + """ + View to manage locations. Only accessible by authenticated users. + """ # Only authenticated users can access this view permission_classes = [IsAuthenticated] - def get(self, request, *args, **kwargs): - # Retrieve all locations from the database, ordered by name - locations = Location.objects.all().order_by('name') - # Serialize the location objects - serializer = LocationSerializer(locations, many=True) - # Return the serialized data with a 200 OK status + def get(self, request, location_id=None, *args, **kwargs): + """ + Retrieve a list of locations or a specific location. + """ + if location_id: + # Retrieve a specific location + location = get_object_or_404(Location, id=location_id) + serializer = LocationSerializer(location) + else: + # Retrieve all locations + locations = Location.objects.all().order_by('name') + serializer = LocationSerializer(locations, many=True) return Response(serializer.data, status=status.HTTP_200_OK) @method_decorator(admin_required) def post(self, request, *args, **kwargs): - # Deserialize the request data into a LocationSerializer + """ + Create a new location. + """ serializer = LocationSerializer(data=request.data) - # Check if the data is valid if serializer.is_valid(): - # Save the new location to the database serializer.save() - # Return the serialized data with a 201 Created status return Response(serializer.data, status=status.HTTP_201_CREATED) - # Return the errors with a 400 Bad Request status return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @method_decorator(admin_required) def put(self, request, location_id, *args, **kwargs): - # Retrieve the existing location or return 404 if not found + """ + Update an existing location. + """ location = get_object_or_404(Location, id=location_id) - # Deserialize the request data into a LocationSerializer serializer = LocationSerializer(location, data=request.data) - # Check if the data is valid if serializer.is_valid(): - # Save the updated location to the database serializer.save() - # Return the serialized data with a 200 OK status return Response(serializer.data, status=status.HTTP_200_OK) - # Return the errors with a 400 Bad Request status + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + @method_decorator(admin_required) + def patch(self, request, location_id, *args, **kwargs): + """ + Partially update an existing location. + """ + location = get_object_or_404(Location, id=location_id) + serializer = LocationSerializer(location, data=request.data, partial=True) + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @method_decorator(admin_required) def delete(self, request, location_id, *args, **kwargs): - # Retrieve the existing location or return 404 if not found + """ + Delete an existing location. + """ location = get_object_or_404(Location, id=location_id) - # Delete the location from the database location.delete() - # Return a 204 No Content status to indicate successful deletion return Response(status=status.HTTP_204_NO_CONTENT) -- GitLab