From a7c0994ffd511fecbc9217c47170fd88f6a0e1da Mon Sep 17 00:00:00 2001 From: a2-imeri <Alfret2.imeri@live.uwe.ac.uk> Date: Wed, 10 Jul 2024 08:00:58 +0100 Subject: [PATCH] Add Tests for Rules --- MisplaceAI/process_misplaced_manager/views.py | 5 +- MisplaceAI/pytest.ini | 3 +- MisplaceAI/results_viewer/utils.py | 2 +- .../rules/__pycache__/views.cpython-310.pyc | Bin 5003 -> 5272 bytes MisplaceAI/rules/tests/test_permissions.py | 145 +++++++++++++++ MisplaceAI/rules/tests/test_views.py | 172 +++++++++++++++++- MisplaceAI/rules/views.py | 18 +- frontend/src/services/locationApi.js | 1 + 8 files changed, 325 insertions(+), 21 deletions(-) create mode 100644 MisplaceAI/rules/tests/test_permissions.py diff --git a/MisplaceAI/process_misplaced_manager/views.py b/MisplaceAI/process_misplaced_manager/views.py index 0ade349..9fbceb2 100644 --- a/MisplaceAI/process_misplaced_manager/views.py +++ b/MisplaceAI/process_misplaced_manager/views.py @@ -41,14 +41,11 @@ class UploadedImageViewSet(viewsets.ModelViewSet): serializer_class = UploadedImageSerializer # Serializer class for uploaded images permission_classes = [IsAuthenticated] # Only authenticated users can access -# API view for normal detection on uploaded images +# API view for normal detection on uploaded imagesm to detect misplaced items @api_view(['POST']) @permission_classes([IsAuthenticated]) def normal_detection(request): """Handle image upload, run object detection, and check for misplaced objects.""" - print("Received request for normal detection") - print("Request data:", request.data) - print("Request FILES:", request.FILES) try: if 'capturedImageData' in request.data: # Process base64 encoded image data diff --git a/MisplaceAI/pytest.ini b/MisplaceAI/pytest.ini index 981b79b..78635f9 100644 --- a/MisplaceAI/pytest.ini +++ b/MisplaceAI/pytest.ini @@ -3,4 +3,5 @@ DJANGO_SETTINGS_MODULE = MisplaceAI.settings addopts = -v --ignore=MisplaceAI/models testpaths = rules/tests - +filterwarnings = + ignore::django.utils.deprecation.RemovedInDjango41Warning diff --git a/MisplaceAI/results_viewer/utils.py b/MisplaceAI/results_viewer/utils.py index a9388e2..520b696 100644 --- a/MisplaceAI/results_viewer/utils.py +++ b/MisplaceAI/results_viewer/utils.py @@ -98,7 +98,7 @@ def visualize_pil_misplaced_objects(image_pil, detected_objects, misplaced_objec misplaced_names = [obj["class_name"] for obj in misplaced_objects] # Load a font using absolute path to the static directory - font_size = 40 # Set the font size (increase if needed) + font_size = 25 # Set the font size (increase if needed) font_path = os.path.join(settings.BASE_DIR, 'core/static/core/fonts/Arial.ttf') # Path to the font file try: font = ImageFont.truetype(font_path, font_size) diff --git a/MisplaceAI/rules/__pycache__/views.cpython-310.pyc b/MisplaceAI/rules/__pycache__/views.cpython-310.pyc index 640e602c37df9e18fdb78e344c73f3e2edbd9abe..1b6771d072a0121af1c0f8569ec94a78e46e978f 100644 GIT binary patch delta 2672 zcmeBHpP|W@&&$ijz`(!|Z_t;frZ$mJhVjHiZNvIpjwlXBh7^Vr)*Q}Ut|%@>h7`6G z_8jh9o+zGN-YDK&z9>Gh7)K6&u0WJPu3(g4u27Uvu5gqvSRZGONUms<D45NaBbF;3 zCC<p;&XB^L!qdW#!jsC_%p4`*&XB^J!q>u(!UyI{x-+EkrwFt#q{s?@1*F^=QUp_k zS{PD<z<lWx;a~<$k%=$V<(Y2rdloyEmSm*nm1HI-mZYZK;`S_dOv%m63oTA9nykp! zAg0N9OQ;~VC^xgXI5R&lJ~=0`xHz?V@<PV<A{-1147b?xld@8iONwtXC+6f72~1wX z6w0VD`4^KcqxfVA=Fs{gAqED9A|()^fJ!KWxWWt!3?LQ7Aj3EqSQy!uc^Hd8qRF5T zMaIkw3=9qo3=G8)3=9mZ3{i|J3{gxej8V*~EUB#NjLnQGOexGQ49$#DY^f}%>|hZV zofKBE5C>d{ErlH{!U-4QNZ|yFa7|`q*;y|Fauy2%1A``K5jTh}1|q~ke&xt7N=Yq> zPpT~91BrngR3rgnv4RLmkRG-oDG*y4M96>$S&&B7%#zgH;v#vF03sB?0RRdaRgkaP z7#J7?n0Y4KvepQJ4TZV^Y?Z|1)2sm&Sd7MI<}H?j{NfTlkfESt$-_K3m~BeEKFD&g zncPK!AU4=@5Ys_i0}x>dBEbHFd#T76BxVBg96Q2ux7a~miqA|bLimyeB!tyL%mt;w zCDtGZ@h~tj@G$c+aWHW(2~4(Sm7F|@-BrjEWChr5Y*4pNe#x#|kMJ)@FT$oG8<2Xm zfCMECFOU_WfaGE3VB%q_k^-k?-^9Gc^i<E1)ZDPl)N;L))ST3kR6kAbB4v;<Dj)(B z14U{e7AP?mfs80p3Ig%jL4+BIumuqyTZ#}igIVBsRA*pd05OU|=?9dMIheT^IXJi& zIe54jIr#V(i$E$SFJzRQe2&?UQGD_TZt=;YoW=E^C@O-du_A4dExaHC91Y-<0FMhz z?8%EWCqFr{Br`t`cM^+)g^U0b50d~>l{745CP#A%Ob%m}NiWg`Sqe%unw&*o2Y~Iy zmMn}wD&fhZ$P~l{hXj}ag+dW1#1cVvg1pBAiEfa+GLt`WOH5wGC0B0_(q#ckR?zea zQc1vKP!_|H9=Ty*fSM*bV8ZC>QV#4)P@Lw1oC!{sOwe@6B)~K|klQ@R4&+38kQ1TF z66{295&%aII9?nf@`$wR3epA76-90!E;wMo1lU@T5!DO~44**>4HP;&Oq1VnD`u|b z!kQ*Qs*uW2P}mlMTwVk+2Wx6{W?*0l2Kft=zd@;yjhTaqgM)*Ihpz}E2TF&WMNS~6 zbKer4%qS#0xqxSBy%hrkLr4)Q1s8#HBUce9T)?UG7F$|oPDyG}5h#yAQYk;kXW)PU zrxb8#fMN(oDrGGy%}K?bLc16kCQsqL%MH%kE+C^VC)e;f)PwB<32F*K3R_T#32_CY z7z0NPI1_n;%3HS7ip=7Y;v%r)!0rN-Ul7lLi#U+^x0s7lONzjr03~Qm9z^MeRMfbE z{RS$3Zt=j<Qha7gF~kKRcNKvRV*&XNJ&}PU8x&oWCO7iGs|Ocza4ki?AW!;%2!9X( z4sjt!`3DYmu+3oKf{SWYKNbam^q_eVVRj%$7VK592f@)2hUCLr>>&4|<dq^&f`J4v z$h$@0;tydWw#o~X2scf35e!Yn$SPnTfYT?!jTl)a1msFYRslNzoJ+t2IP^e9oChg$ zpZrHq(bfaR1j`}_usTl$28I?aDPDm`wg@EWrzsOPIZ7yxsfc~@Q6U9OP<!JRTW)?z zYEE$xIB3Cv4084@?&8#<%*33`s??%lNQnf>Mv$Z;Fj-DmtP+&+q9lt_i%a6uiV|~E z%kzt}^-@xk^NSKo@{5WgnHAKE0hjvVEC+T4w#<5q!zMRBr8FnijuGU3P(i}O#>2?N WD8R_WD8eYg2xc=2@Cz7;7y<xN!MkPv delta 2353 zcmbQC*{#l(&&$ijz`(%pLaQUqUUed$4C9W8+J^Ov3@HpLtT`OHoKc*N3@L0W>^WSy z+)>=QJW)KkyivShF^(L*T>dEjT!AQoT)`;8T%jl-us+Tl;arg@5k>}gh7_(8?iPj= z?o`HR<|t8jh7_I@-WG-wUNB$GogsxUg};R%g&)ipcV|cuND&0d3xWkCQiOsTG=(Sr zP#0pn#qU|{SXz>inpcvUoLG{YGTDx?VX`8x<m9)E*F@ME7#MD`=O<;QCYKc7VouD- zDdL}eohg)2Zn7@3ETh<DZ|2a+2N*>Rixe0b7>eXj33(7#kb!|gfPsObn1g|VfrEjC zk&T&$sYr0L9Iwn|H%`0BK`fi<g+K~f7#J8dIg3ESRwM!v5CvJzkzbUOS`?pDS;Pwx zV+IjoAc7S{h=cU76-j{Dk|06~L`Z`)vSyZ~<`x&pf&>um0y_!hRuu*YhR<vuw=wZd z-p?*Mc@Ar`5ZGX-JHXb7O%`Meu)tzGHgj*W6yz6|=zt6cd4h*&@=UfV^#&jZfX(DC z0)+#_gAmg}QidSH2t<JW2KQEx2}sNo<Uw|X2XC>1ycM6BQiSj+3rGm7gP03Sc}grm z4&q^8VBlezyn{Ve$QooW*g<Si2Tj)J(6vE$(iWruZhVm)h>I42&I}9;ZXk0(A;`lt zc?O4K+Dfh>MUYY@5TOhrKw(@2Qc<J|;(~&`$Q;D72N57Mu%;Mw1_lO@eV_T@DTafI zgM)*Ihp$L|vK+50vl;`#<Oa_EdQOlz@U&8-4dQ})S_BSCaBRZEQxkhK;mpZTPAtjH z&%>QmLO{mqGB7YyNjs+GX6E@O<|U@5`s621*5~G$JdaB@N)Mz$9~4!bMPU2ER%44< zV~|RC%odq}xFEkm0s@>mK_L_a5(h=xWO;6jdP@+`3S>Mq34#5M-y%@Xz>$QwVO~Z} zMjS9<^rR#Lb`~hkGC&S-0Efh6MQ+K-{5&!ljvz57kmI1q3G6s<<bq=X904v6c|;oX z0_j4eF>eqTEgV2bl!3%uK^DqQR^*m2NJ-5}ElKq&0;N4jkfCYvU|?YI18H&x5gwq_ z!l*XchIfCx4Fdy1ND-o>;VR+=DFLOPTWo2WIVGt@MZO>ra4G^NJrYt8Yf))VD()22 z!oV=OitjErI4gOAEU})P#P3iKwhttzDO3bbGT<x%7DW^l;P3=Fvk2s|TWqNnnZ+f= z5XXT77gR<-JOeI9K<3|KE>0~e0(%0K;xu^>B?zM6C~^ba3CixbcwmtqpP5n&2?vn7 ziok}kfP9CZD!_>XlvaBtrwhER2bU^vEkyw!PX>aBAP@mAZiFDk4LI1rHiLZ&Dk_Um z{a6$X(t}7nU=Je92IohxSHT_xrF6|OBp=>l2e}s|aTkSwOaxmB@@`Qmh>I{0TO|QX z?`tM&35C{Uq;RkgK*<v+5-?JDILHb_3I{s?EwO@(I0;e)PT^8Wg-cLrPHI?YYPnuY zYK}7g6z{{pz)&|?QCOS<#PZXWyfxWDIB)W1VcB|c?ah{(pOTtW3<+XzV1t~0i@P|r zC^Io9vnsWy7*b||t0ZuU@-r|nL<yv1CFZ5)>lJ6@7nLNJmJ~x`4^*8OflBBiP*y7f t*@-P9-r}&yRnJc;%}KRm1Xcc^oX^9?!w7*Qj1r7Ii~>vod;$g{1^{8@i!A^E diff --git a/MisplaceAI/rules/tests/test_permissions.py b/MisplaceAI/rules/tests/test_permissions.py new file mode 100644 index 0000000..8286aee --- /dev/null +++ b/MisplaceAI/rules/tests/test_permissions.py @@ -0,0 +1,145 @@ +from rest_framework.test import APITestCase +from rest_framework import status +from django.urls import reverse +from django.contrib.auth.models import User +from rules.models import Item, Location + +class PermissionsTest(APITestCase): + """ + Test suite for permissions to ensure only authenticated users can access item and location endpoints. + """ + + def setUp(self): + # Create a normal user and an admin user + self.normal_user = User.objects.create_user(username='normaluser', password='testpassword') + self.admin_user = User.objects.create_superuser(username='adminuser', password='adminpassword') + + # Create an item and a location + self.item = Item.objects.create(name='Test Item') + self.location = Location.objects.create(name='Test Location') + + def test_normal_user_cannot_access_items(self): + """ + Ensure a normal user cannot access the item management endpoints. + """ + self.client.force_authenticate(user=self.normal_user) + + # Attempt to access item list + url = reverse('rules:admin_manage_item') + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + # Attempt to create an item + data = {'name': 'New Item'} + response = self.client.post(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + # Attempt to update an item + url = reverse('rules:admin_manage_item_detail', args=[self.item.id]) + data = {'name': 'Updated Item'} + response = self.client.put(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + # Attempt to delete an item + response = self.client.delete(url) + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + def test_normal_user_cannot_access_locations(self): + """ + Ensure a normal user cannot access the location management endpoints. + """ + self.client.force_authenticate(user=self.normal_user) + + # Attempt to access location list + url = reverse('rules:admin_manage_location') + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + # Attempt to create a location + data = {'name': 'New Location'} + response = self.client.post(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + # Attempt to update a location + url = reverse('rules:admin_manage_location_detail', args=[self.location.id]) + data = {'name': 'Updated Location'} + response = self.client.put(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + # Attempt to delete a location + response = self.client.delete(url) + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + def test_admin_user_can_access_items_and_locations(self): + """ + Ensure an admin user can access the item and location management endpoints. + """ + self.client.force_authenticate(user=self.admin_user) + + # Access item list + url = reverse('rules:admin_manage_item') + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + # Create an item + data = {'name': 'New Item'} + response = self.client.post(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + # Update an item + url = reverse('rules:admin_manage_item_detail', args=[self.item.id]) + data = {'name': 'Updated Item'} + response = self.client.put(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + # Delete an item + response = self.client.delete(url) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + + # Access location list + url = reverse('rules:admin_manage_location') + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + # Create a location + data = {'name': 'New Location'} + response = self.client.post(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + # Update a location + url = reverse('rules:admin_manage_location_detail', args=[self.location.id]) + data = {'name': 'Updated Location'} + response = self.client.put(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + # Delete a location + response = self.client.delete(url) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + + def test_normal_user_can_access_rules(self): + """ + Ensure a normal user can access the rules management endpoints. + """ + self.client.force_authenticate(user=self.normal_user) + + # Access rule list + url = reverse('rules:admin_manage_rule') + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + # Create a rule + data = {'item': self.item.id, 'locations': [self.location.id]} + response = self.client.post(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + # Update a rule + url = reverse('rules:admin_manage_rule_detail', args=[self.item.id]) + new_item = Item.objects.create(name='New Item') + new_location = Location.objects.create(name='New Location') + data = {'item': new_item.id, 'locations': [new_location.id]} + response = self.client.put(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + # Delete a rule + response = self.client.delete(url) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) diff --git a/MisplaceAI/rules/tests/test_views.py b/MisplaceAI/rules/tests/test_views.py index 441e11b..e501fe6 100644 --- a/MisplaceAI/rules/tests/test_views.py +++ b/MisplaceAI/rules/tests/test_views.py @@ -1,18 +1,49 @@ -# misplaceAI/rules/tests/test_views.py - from rest_framework.test import APITestCase from rest_framework import status from django.urls import reverse from django.contrib.auth.models import User -from rules.models import Item +from rules.models import Location, Item, Rule -class AdminManageItemViewTest(APITestCase): +class UserListViewTest(APITestCase): + """ + Test suite for the UserListView. + """ def setUp(self): # Create a user self.user = User.objects.create_user(username='testuser', password='testpassword') self.client.force_authenticate(user=self.user) + def test_list_users(self): + """ + Ensure we can list all users. + """ + url = reverse('rules:user-list') + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data), 1) + self.assertEqual(response.data[0]['username'], 'testuser') + +class AdminManageItemViewTest(APITestCase): + """ + Test suite for the AdminManageItemView. + """ + + def setUp(self): + self.user = User.objects.create_user(username='testuser', password='testpassword') + self.client.force_authenticate(user=self.user) + self.item = Item.objects.create(name='Test Item') + + def test_get_items(self): + """ + Ensure we can retrieve the list of items. + """ + url = reverse('rules:admin_manage_item') + response = self.client.get(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_create_item(self): """ Ensure we can create a new item. @@ -20,9 +51,132 @@ class AdminManageItemViewTest(APITestCase): url = reverse('rules:admin_manage_item') data = {'name': 'New Item'} response = self.client.post(url, data, format='json') - - # Check if the response status is 201 Created self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # Check if the item was actually created - self.assertEqual(Item.objects.count(), 1) - self.assertEqual(Item.objects.get().name, 'New Item') + self.assertEqual(Item.objects.count(), 2) + self.assertEqual(Item.objects.get(id=response.data['id']).name, 'New Item') + + def test_update_item(self): + """ + Ensure we can update an existing item. + """ + url = reverse('rules:admin_manage_item_detail', args=[self.item.id]) + data = {'name': 'Updated Item'} + response = self.client.put(url, 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_delete_item(self): + """ + Ensure we can delete an existing item. + """ + url = reverse('rules:admin_manage_item_detail', args=[self.item.id]) + response = self.client.delete(url) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + self.assertEqual(Item.objects.count(), 0) + +class AdminManageLocationViewTest(APITestCase): + """ + Test suite for the AdminManageLocationView. + """ + + def setUp(self): + self.user = User.objects.create_user(username='testuser', password='testpassword') + self.client.force_authenticate(user=self.user) + self.location = Location.objects.create(name='Test Location') + + def test_get_locations(self): + """ + Ensure we can retrieve the list of locations. + """ + url = reverse('rules:admin_manage_location') + response = self.client.get(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_create_location(self): + """ + Ensure we can create a new location. + """ + url = reverse('rules:admin_manage_location') + data = {'name': 'New Location'} + response = self.client.post(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_update_location(self): + """ + Ensure we can update an existing location. + """ + url = reverse('rules:admin_manage_location_detail', args=[self.location.id]) + data = {'name': 'Updated Location'} + response = self.client.put(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(Location.objects.get(id=self.location.id).name, 'Updated Location') + + def test_delete_location(self): + """ + Ensure we can delete an existing location. + """ + url = reverse('rules:admin_manage_location_detail', args=[self.location.id]) + response = self.client.delete(url) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + self.assertEqual(Location.objects.count(), 0) + +class AdminManageRuleViewTest(APITestCase): + """ + Test suite for the AdminManageRuleView. + """ + + def setUp(self): + self.user = User.objects.create_user(username='testuser', password='testpassword') + self.client.force_authenticate(user=self.user) + self.item = Item.objects.create(name='Test Item') + self.location = Location.objects.create(name='Test Location') + self.rule = Rule.objects.create(user=self.user, item=self.item) + self.rule.locations.add(self.location) + + def test_get_rules(self): + """ + Ensure we can retrieve the list of rules. + """ + url = reverse('rules:admin_manage_rule') + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data), 1) + self.assertEqual(response.data[0]['item']['id'], self.item.id) + + def test_create_rule(self): + """ + Ensure we can create a new rule. + """ + url = reverse('rules:admin_manage_rule') + data = {'item': self.item.id, 'locations': [self.location.id]} + response = self.client.post(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertEqual(Rule.objects.count(), 2) + self.assertEqual(Rule.objects.get(id=response.data['id']).item.id, self.item.id) + + def test_update_rule(self): + """ + Ensure we can update an existing rule. + """ + url = reverse('rules:admin_manage_rule_detail', args=[self.rule.id]) + new_item = Item.objects.create(name='New Item') + new_location = Location.objects.create(name='New Location') + data = {'item': new_item.id, 'locations': [new_location.id]} + response = self.client.put(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + updated_rule = Rule.objects.get(id=self.rule.id) + self.assertEqual(updated_rule.item.id, new_item.id) + self.assertEqual(updated_rule.locations.first().id, new_location.id) + + def test_delete_rule(self): + """ + Ensure we can delete an existing rule. + """ + url = reverse('rules:admin_manage_rule_detail', args=[self.rule.id]) + response = self.client.delete(url) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + self.assertEqual(Rule.objects.count(), 0) \ No newline at end of file diff --git a/MisplaceAI/rules/views.py b/MisplaceAI/rules/views.py index 615067a..94223ea 100644 --- a/MisplaceAI/rules/views.py +++ b/MisplaceAI/rules/views.py @@ -7,18 +7,19 @@ from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status -from rest_framework.permissions import IsAuthenticated +from rest_framework.permissions import IsAuthenticated, IsAdminUser from django.contrib.auth.models import User from .models import Location, Item, Rule from .serializers import LocationSerializer, ItemSerializer, RuleSerializer, UserSerializer from django.shortcuts import get_object_or_404 +from rest_framework.decorators import permission_classes + class UserListView(APIView): """ View to list all users. Only accessible by authenticated users. """ permission_classes = [IsAuthenticated] - def get(self, request, *args, **kwargs): # Retrieve all user objects from the database users = User.objects.all() @@ -27,12 +28,13 @@ class UserListView(APIView): # 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. """ - permission_classes = [IsAuthenticated] - + @permission_classes([IsAuthenticated]) def get(self, request, *args, **kwargs): # Retrieve all item objects from the database, ordered by name items = Item.objects.all().order_by('name') @@ -40,7 +42,8 @@ class AdminManageItemView(APIView): serializer = ItemSerializer(items, many=True) # Return the serialized data with a 200 OK status return Response(serializer.data, status=status.HTTP_200_OK) - + + @permission_classes([IsAdminUser]) def post(self, request, *args, **kwargs): # Deserialize the incoming data into an ItemSerializer serializer = ItemSerializer(data=request.data) @@ -53,6 +56,7 @@ class AdminManageItemView(APIView): # Return validation errors with a 400 Bad Request status return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + @permission_classes([IsAdminUser]) def put(self, request, item_id, *args, **kwargs): # Retrieve the existing item object from the database item = get_object_or_404(Item, id=item_id) @@ -66,7 +70,8 @@ class AdminManageItemView(APIView): return Response(serializer.data, status=status.HTTP_200_OK) # Return validation errors with a 400 Bad Request status return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - + + @permission_classes([IsAdminUser]) def delete(self, request, item_id, *args, **kwargs): # Retrieve the existing item object from the database item = get_object_or_404(Item, id=item_id) @@ -123,6 +128,7 @@ class AdminManageLocationView(APIView): # Return a 204 No Content status to indicate successful deletion return Response(status=status.HTTP_204_NO_CONTENT) +# misplaceAI/rules/views.py class AdminManageRuleView(APIView): """ View to manage rules. Only accessible by authenticated users. diff --git a/frontend/src/services/locationApi.js b/frontend/src/services/locationApi.js index 58e95a7..e29fde8 100644 --- a/frontend/src/services/locationApi.js +++ b/frontend/src/services/locationApi.js @@ -1,3 +1,4 @@ +// src/services/locationApi.js import api, { getCsrfToken } from './api'; export const addLocation = async (locationData) => { -- GitLab