This commit is contained in:
j3d1 2024-07-17 20:22:40 +02:00
parent 6f98bf4942
commit 8cd66cc6e2
3 changed files with 96 additions and 5 deletions

View file

@ -6,7 +6,9 @@ from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from inventory.models import Event, Container, Item
from inventory.serializers import EventSerializer, ContainerSerializer, ItemSerializer
from inventory.serializers import EventSerializer, ContainerSerializer, ItemSerializer, SearchResultSerializer
from base64 import b64decode
class EventViewSet(viewsets.ModelViewSet):
@ -23,8 +25,13 @@ class ContainerViewSet(viewsets.ModelViewSet):
def filter_items(items, query):
query_tokens = query.split(' ')
for item in items:
if all(token in item.description for token in query_tokens):
yield item
value = 0
for token in query_tokens:
if token in item.description:
value += 1
if value > 0:
yield {'search_score': value, 'item': item}
@api_view(['GET'])
@permission_classes([])
@ -33,8 +40,8 @@ def filter_items(items, query):
def search_items(request, event_slug, query):
try:
event = Event.objects.get(slug=event_slug)
items = filter_items(Item.objects.filter(event=event), query)
return Response(ItemSerializer(items, many=True).data)
items = filter_items(Item.objects.filter(event=event), b64decode(query).decode('utf-8'))
return Response(SearchResultSerializer(items, many=True).data)
except Event.DoesNotExist:
return Response(status=404)

View file

@ -95,3 +95,14 @@ class ItemSerializer(serializers.ModelSerializer):
validated_data.pop('dataImage')
instance.files.add(file)
return super().update(instance, validated_data)
class SearchResultSerializer(serializers.Serializer):
search_score = serializers.IntegerField()
item = ItemSerializer()
def to_representation(self, instance):
return {**ItemSerializer(instance['item']).data, 'search_score': instance['search_score']}
class Meta:
model = Item

View file

@ -7,6 +7,8 @@ from authentication.models import ExtendedUser
from files.models import File
from inventory.models import Event, Container, Item
from base64 import b64encode
class ItemTestCase(TestCase):
@ -169,3 +171,74 @@ class ItemTestCase(TestCase):
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.json()), 1)
self.assertEqual(response.json()[0]['uid'], item1.uid)
class ItemSearchTestCase(TestCase):
def setUp(self):
super().setUp()
self.event = Event.objects.create(slug='EVENT', name='Event')
self.box = Container.objects.create(name='BOX')
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
self.user.user_permissions.add(*Permission.objects.all())
self.token = AuthToken.objects.create(user=self.user)
self.client = Client(headers={'Authorization': 'Token ' + self.token[1]})
self.item1 = Item.objects.create(container=self.box, event=self.event, description='abc def')
self.item2 = Item.objects.create(container=self.box, event=self.event, description='def ghi')
self.item3 = Item.objects.create(container=self.box, event=self.event, description='jkl mno pqr')
self.item4 = Item.objects.create(container=self.box, event=self.event, description='stu vwx')
def test_search(self):
search_query = b64encode(b'abc').decode('utf-8')
response = self.client.get(f'/api/2/{self.event.slug}/items/{search_query}/')
self.assertEqual(200, response.status_code)
self.assertEqual(1, len(response.json()))
self.assertEqual(self.item1.uid, response.json()[0]['uid'])
self.assertEqual('abc def', response.json()[0]['description'])
self.assertEqual('BOX', response.json()[0]['box'])
self.assertEqual(self.box.cid, response.json()[0]['cid'])
self.assertEqual(1, response.json()[0]['search_score'])
def test_search2(self):
search_query = b64encode(b'def').decode('utf-8')
response = self.client.get(f'/api/2/{self.event.slug}/items/{search_query}/')
self.assertEqual(200, response.status_code)
self.assertEqual(2, len(response.json()))
self.assertEqual(self.item1.uid, response.json()[0]['uid'])
self.assertEqual('abc def', response.json()[0]['description'])
self.assertEqual('BOX', response.json()[0]['box'])
self.assertEqual(self.box.cid, response.json()[0]['cid'])
self.assertEqual(1, response.json()[0]['search_score'])
self.assertEqual(self.item2.uid, response.json()[1]['uid'])
self.assertEqual('def ghi', response.json()[1]['description'])
self.assertEqual('BOX', response.json()[1]['box'])
self.assertEqual(self.box.cid, response.json()[1]['cid'])
self.assertEqual(1, response.json()[0]['search_score'])
def test_search3(self):
search_query = b64encode(b'jkl').decode('utf-8')
response = self.client.get(f'/api/2/{self.event.slug}/items/{search_query}/')
self.assertEqual(200, response.status_code)
self.assertEqual(1, len(response.json()))
self.assertEqual(self.item3.uid, response.json()[0]['uid'])
self.assertEqual('jkl mno pqr', response.json()[0]['description'])
self.assertEqual('BOX', response.json()[0]['box'])
self.assertEqual(self.box.cid, response.json()[0]['cid'])
self.assertEqual(1, response.json()[0]['search_score'])
def test_search4(self):
search_query = b64encode(b'abc def').decode('utf-8')
response = self.client.get(f'/api/2/{self.event.slug}/items/{search_query}/')
self.assertEqual(200, response.status_code)
self.assertEqual(2, len(response.json()))
self.assertEqual(self.item1.uid, response.json()[0]['uid'])
self.assertEqual('abc def', response.json()[0]['description'])
self.assertEqual('BOX', response.json()[0]['box'])
self.assertEqual(self.box.cid, response.json()[0]['cid'])
self.assertEqual(2, response.json()[0]['search_score'])
self.assertEqual(self.item2.uid, response.json()[1]['uid'])
self.assertEqual('def ghi', response.json()[1]['description'])
self.assertEqual('BOX', response.json()[1]['box'])
self.assertEqual(self.box.cid, response.json()[1]['cid'])
self.assertEqual(1, response.json()[1]['search_score'])