Search now also includes Files and URLs
All checks were successful
Build containers when image tags change / build-if-image-changed (., web, containers, main container, git.baumann.gr/adebaumann/labhelper) (push) Successful in 2m53s
Build containers when image tags change / build-if-image-changed (data-loader, loader, initContainers, init-container, git.baumann.gr/adebaumann/labhelper-data-loader) (push) Successful in 5s
All checks were successful
Build containers when image tags change / build-if-image-changed (., web, containers, main container, git.baumann.gr/adebaumann/labhelper) (push) Successful in 2m53s
Build containers when image tags change / build-if-image-changed (data-loader, loader, initContainers, init-container, git.baumann.gr/adebaumann/labhelper-data-loader) (push) Successful in 5s
This commit is contained in:
@@ -27,7 +27,7 @@ spec:
|
|||||||
mountPath: /data
|
mountPath: /data
|
||||||
containers:
|
containers:
|
||||||
- name: web
|
- name: web
|
||||||
image: git.baumann.gr/adebaumann/labhelper:0.044
|
image: git.baumann.gr/adebaumann/labhelper:0.045
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8000
|
- containerPort: 8000
|
||||||
|
|||||||
@@ -1610,3 +1610,93 @@ class ThingFileAndLinkCRUDTests(AuthTestCase):
|
|||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertContains(response, 'Upload File')
|
self.assertContains(response, 'Upload File')
|
||||||
self.assertContains(response, 'Add Link')
|
self.assertContains(response, 'Add Link')
|
||||||
|
|
||||||
|
def test_search_api_includes_files(self):
|
||||||
|
"""Search API results should include files."""
|
||||||
|
ThingFile.objects.create(
|
||||||
|
thing=self.thing,
|
||||||
|
title='Datasheet',
|
||||||
|
file='datasheets/test.pdf'
|
||||||
|
)
|
||||||
|
response = self.client.get('/search/api/?q=ard')
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
results = response.json()['results']
|
||||||
|
self.assertEqual(len(results), 1)
|
||||||
|
self.assertEqual(len(results[0]['files']), 1)
|
||||||
|
self.assertEqual(results[0]['files'][0]['title'], 'Datasheet')
|
||||||
|
self.assertIn('filename', results[0]['files'][0])
|
||||||
|
|
||||||
|
def test_search_api_includes_links(self):
|
||||||
|
"""Search API results should include links."""
|
||||||
|
ThingLink.objects.create(
|
||||||
|
thing=self.thing,
|
||||||
|
title='Documentation',
|
||||||
|
url='https://docs.example.com'
|
||||||
|
)
|
||||||
|
response = self.client.get('/search/api/?q=ard')
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
results = response.json()['results']
|
||||||
|
self.assertEqual(len(results), 1)
|
||||||
|
self.assertEqual(len(results[0]['links']), 1)
|
||||||
|
self.assertEqual(results[0]['links'][0]['title'], 'Documentation')
|
||||||
|
self.assertEqual(results[0]['links'][0]['url'], 'https://docs.example.com')
|
||||||
|
|
||||||
|
def test_search_api_shows_empty_files_and_links(self):
|
||||||
|
"""Search API should show empty arrays for things without files/links."""
|
||||||
|
response = self.client.get('/search/api/?q=ard')
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
results = response.json()['results']
|
||||||
|
self.assertEqual(len(results), 1)
|
||||||
|
self.assertEqual(results[0]['files'], [])
|
||||||
|
self.assertEqual(results[0]['links'], [])
|
||||||
|
|
||||||
|
def test_search_api_searches_by_file_title(self):
|
||||||
|
"""Search API should find things by file title."""
|
||||||
|
ThingFile.objects.create(
|
||||||
|
thing=self.thing,
|
||||||
|
title='Datasheet PDF',
|
||||||
|
file='datasheets/test.pdf'
|
||||||
|
)
|
||||||
|
response = self.client.get('/search/api/?q=Datasheet')
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
results = response.json()['results']
|
||||||
|
self.assertEqual(len(results), 1)
|
||||||
|
self.assertEqual(results[0]['name'], self.thing.name)
|
||||||
|
|
||||||
|
def test_search_api_searches_by_filename(self):
|
||||||
|
"""Search API should find things by filename."""
|
||||||
|
ThingFile.objects.create(
|
||||||
|
thing=self.thing,
|
||||||
|
title='Test File',
|
||||||
|
file='models/part123.stl'
|
||||||
|
)
|
||||||
|
response = self.client.get('/search/api/?q=stl')
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
results = response.json()['results']
|
||||||
|
self.assertEqual(len(results), 1)
|
||||||
|
self.assertEqual(results[0]['name'], self.thing.name)
|
||||||
|
|
||||||
|
def test_search_api_searches_by_link_title(self):
|
||||||
|
"""Search API should find things by link title."""
|
||||||
|
ThingLink.objects.create(
|
||||||
|
thing=self.thing,
|
||||||
|
title='Documentation Link',
|
||||||
|
url='https://docs.example.com/manual.pdf'
|
||||||
|
)
|
||||||
|
response = self.client.get('/search/api/?q=Documentation')
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
results = response.json()['results']
|
||||||
|
self.assertEqual(len(results), 1)
|
||||||
|
self.assertEqual(results[0]['name'], self.thing.name)
|
||||||
|
|
||||||
|
def test_search_api_searches_by_link_url(self):
|
||||||
|
"""Search API should find things by link URL."""
|
||||||
|
ThingLink.objects.create(
|
||||||
|
thing=self.thing,
|
||||||
|
title='Manual',
|
||||||
|
url='https://arduino.cc/products/uno'
|
||||||
|
)
|
||||||
|
response = self.client.get('/search/api/?q=arduino')
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
results = response.json()['results']
|
||||||
|
self.assertGreater(len(results), 0)
|
||||||
|
|||||||
@@ -143,8 +143,12 @@ def search_api(request):
|
|||||||
things = Thing.objects.filter(
|
things = Thing.objects.filter(
|
||||||
Q(name__icontains=query) |
|
Q(name__icontains=query) |
|
||||||
Q(description__icontains=query) |
|
Q(description__icontains=query) |
|
||||||
Q(thing_type__name__icontains=query)
|
Q(thing_type__name__icontains=query) |
|
||||||
).select_related('thing_type', 'box')[:50]
|
Q(files__title__icontains=query) |
|
||||||
|
Q(files__file__icontains=query) |
|
||||||
|
Q(links__title__icontains=query) |
|
||||||
|
Q(links__url__icontains=query)
|
||||||
|
).prefetch_related('files', 'links').select_related('thing_type', 'box').distinct()[:50]
|
||||||
|
|
||||||
results = [
|
results = [
|
||||||
{
|
{
|
||||||
@@ -153,6 +157,20 @@ def search_api(request):
|
|||||||
'type': thing.thing_type.name,
|
'type': thing.thing_type.name,
|
||||||
'box': thing.box.id,
|
'box': thing.box.id,
|
||||||
'description': thing.description[:100] if thing.description else '',
|
'description': thing.description[:100] if thing.description else '',
|
||||||
|
'files': [
|
||||||
|
{
|
||||||
|
'title': f.title,
|
||||||
|
'filename': f.filename(),
|
||||||
|
}
|
||||||
|
for f in thing.files.all()
|
||||||
|
],
|
||||||
|
'links': [
|
||||||
|
{
|
||||||
|
'title': l.title,
|
||||||
|
'url': l.url,
|
||||||
|
}
|
||||||
|
for l in thing.links.all()
|
||||||
|
],
|
||||||
}
|
}
|
||||||
for thing in things
|
for thing in things
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user