Added arbitrary files and links to boxes

This commit is contained in:
2026-01-01 14:50:07 +01:00
parent acde0cb2f8
commit a4f9274da4
8 changed files with 673 additions and 15 deletions

View File

@@ -6,7 +6,7 @@ from django.test import Client, TestCase
from django.urls import reverse
from .admin import BoxAdmin, BoxTypeAdmin, ThingAdmin, ThingTypeAdmin
from .models import Box, BoxType, Thing, ThingType
from .models import Box, BoxType, Thing, ThingFile, ThingLink, ThingType
class AuthTestCase(TestCase):
@@ -1310,3 +1310,303 @@ class ThingPictureUploadTests(AuthTestCase):
self.assertRedirects(response, f'/thing/{self.thing.id}/')
self.thing.refresh_from_db()
self.assertFalse(self.thing.picture.name)
class ThingFileModelTests(AuthTestCase):
"""Tests for the ThingFile model."""
def setUp(self):
"""Set up test fixtures."""
super().setUp()
self.box_type = BoxType.objects.create(
name='Standard Box',
width=200,
height=100,
length=300
)
self.box = Box.objects.create(
id='BOX001',
box_type=self.box_type
)
self.thing_type = ThingType.objects.create(name='Electronics')
self.thing = Thing.objects.create(
name='Arduino Uno',
thing_type=self.thing_type,
box=self.box
)
def test_thing_file_creation(self):
"""ThingFile should be created with correct attributes."""
thing_file = ThingFile.objects.create(
thing=self.thing,
title='Datasheet',
file='datasheets/test.pdf'
)
self.assertEqual(thing_file.thing, self.thing)
self.assertEqual(thing_file.title, 'Datasheet')
self.assertEqual(thing_file.file.name, 'datasheets/test.pdf')
def test_thing_file_str(self):
"""ThingFile __str__ should return thing name and title."""
thing_file = ThingFile.objects.create(
thing=self.thing,
title='Manual',
file='manuals/test.pdf'
)
expected = f'{self.thing.name} - Manual'
self.assertEqual(str(thing_file), expected)
def test_thing_file_ordering(self):
"""ThingFiles should be ordered by uploaded_at descending."""
file1 = ThingFile.objects.create(
thing=self.thing,
title='First File',
file='test1.pdf'
)
file2 = ThingFile.objects.create(
thing=self.thing,
title='Second File',
file='test2.pdf'
)
files = list(ThingFile.objects.all())
self.assertEqual(files[0], file2)
self.assertEqual(files[1], file1)
def test_thing_file_deletion_on_thing_delete(self):
"""Deleting a Thing should delete its files."""
thing_file = ThingFile.objects.create(
thing=self.thing,
title='Test File',
file='test.pdf'
)
file_id = thing_file.id
self.thing.delete()
self.assertFalse(ThingFile.objects.filter(id=file_id).exists())
class ThingLinkModelTests(AuthTestCase):
"""Tests for the ThingLink model."""
def setUp(self):
"""Set up test fixtures."""
super().setUp()
self.box_type = BoxType.objects.create(
name='Standard Box',
width=200,
height=100,
length=300
)
self.box = Box.objects.create(
id='BOX001',
box_type=self.box_type
)
self.thing_type = ThingType.objects.create(name='Electronics')
self.thing = Thing.objects.create(
name='Arduino Uno',
thing_type=self.thing_type,
box=self.box
)
def test_thing_link_creation(self):
"""ThingLink should be created with correct attributes."""
thing_link = ThingLink.objects.create(
thing=self.thing,
title='Manufacturer Website',
url='https://www.arduino.cc'
)
self.assertEqual(thing_link.thing, self.thing)
self.assertEqual(thing_link.title, 'Manufacturer Website')
self.assertEqual(thing_link.url, 'https://www.arduino.cc')
def test_thing_link_str(self):
"""ThingLink __str__ should return thing name and title."""
thing_link = ThingLink.objects.create(
thing=self.thing,
title='Documentation',
url='https://docs.arduino.cc'
)
expected = f'{self.thing.name} - Documentation'
self.assertEqual(str(thing_link), expected)
def test_thing_link_ordering(self):
"""ThingLinks should be ordered by uploaded_at descending."""
link1 = ThingLink.objects.create(
thing=self.thing,
title='First Link',
url='https://example1.com'
)
link2 = ThingLink.objects.create(
thing=self.thing,
title='Second Link',
url='https://example2.com'
)
links = list(ThingLink.objects.all())
self.assertEqual(links[0], link2)
self.assertEqual(links[1], link1)
def test_thing_link_deletion_on_thing_delete(self):
"""Deleting a Thing should delete its links."""
thing_link = ThingLink.objects.create(
thing=self.thing,
title='Test Link',
url='https://example.com'
)
link_id = thing_link.id
self.thing.delete()
self.assertFalse(ThingLink.objects.filter(id=link_id).exists())
class ThingFileAndLinkCRUDTests(AuthTestCase):
"""Tests for Thing file and link CRUD operations."""
def setUp(self):
"""Set up test fixtures."""
super().setUp()
self.box_type = BoxType.objects.create(
name='Standard Box',
width=200,
height=100,
length=300
)
self.box = Box.objects.create(
id='BOX001',
box_type=self.box_type
)
self.thing_type = ThingType.objects.create(name='Electronics')
self.thing = Thing.objects.create(
name='Arduino Uno',
thing_type=self.thing_type,
box=self.box
)
def test_add_file_to_thing(self):
"""Adding a file should create ThingFile."""
file_content = b'Sample PDF content'
uploaded_file = SimpleUploadedFile(
name='datasheet.pdf',
content=file_content,
content_type='application/pdf'
)
response = self.client.post(
f'/thing/{self.thing.id}/',
{'action': 'add_file', 'title': 'Datasheet', 'file': uploaded_file}
)
self.assertRedirects(response, f'/thing/{self.thing.id}/')
self.assertEqual(self.thing.files.count(), 1)
self.assertEqual(self.thing.files.first().title, 'Datasheet')
def test_add_link_to_thing(self):
"""Adding a link should create ThingLink."""
response = self.client.post(
f'/thing/{self.thing.id}/',
{
'action': 'add_link',
'title': 'Manufacturer',
'url': 'https://www.arduino.cc'
}
)
self.assertRedirects(response, f'/thing/{self.thing.id}/')
self.assertEqual(self.thing.links.count(), 1)
self.assertEqual(self.thing.links.first().title, 'Manufacturer')
self.assertEqual(self.thing.links.first().url, 'https://www.arduino.cc')
def test_delete_file_from_thing(self):
"""Deleting a file should remove it from database."""
thing_file = ThingFile.objects.create(
thing=self.thing,
title='Test File',
file='test.pdf'
)
file_id = thing_file.id
response = self.client.post(
f'/thing/{self.thing.id}/',
{'action': 'delete_file', 'file_id': str(file_id)}
)
self.assertRedirects(response, f'/thing/{self.thing.id}/')
self.assertFalse(ThingFile.objects.filter(id=file_id).exists())
def test_delete_link_from_thing(self):
"""Deleting a link should remove it from database."""
thing_link = ThingLink.objects.create(
thing=self.thing,
title='Test Link',
url='https://example.com'
)
link_id = thing_link.id
response = self.client.post(
f'/thing/{self.thing.id}/',
{'action': 'delete_link', 'link_id': str(link_id)}
)
self.assertRedirects(response, f'/thing/{self.thing.id}/')
self.assertFalse(ThingLink.objects.filter(id=link_id).exists())
def test_cannot_delete_file_from_other_thing(self):
"""Cannot delete file from another thing."""
other_thing = Thing.objects.create(
name='Other Item',
thing_type=self.thing_type,
box=self.box
)
thing_file = ThingFile.objects.create(
thing=other_thing,
title='Other File',
file='other.pdf'
)
file_id = thing_file.id
response = self.client.post(
f'/thing/{self.thing.id}/',
{'action': 'delete_file', 'file_id': str(file_id)}
)
self.assertRedirects(response, f'/thing/{self.thing.id}/')
self.assertTrue(ThingFile.objects.filter(id=file_id).exists())
def test_cannot_delete_link_from_other_thing(self):
"""Cannot delete link from another thing."""
other_thing = Thing.objects.create(
name='Other Item',
thing_type=self.thing_type,
box=self.box
)
thing_link = ThingLink.objects.create(
thing=other_thing,
title='Other Link',
url='https://other.com'
)
link_id = thing_link.id
response = self.client.post(
f'/thing/{self.thing.id}/',
{'action': 'delete_link', 'link_id': str(link_id)}
)
self.assertRedirects(response, f'/thing/{self.thing.id}/')
self.assertTrue(ThingLink.objects.filter(id=link_id).exists())
def test_thing_detail_shows_files_section(self):
"""Thing detail page should show files when they exist."""
ThingFile.objects.create(
thing=self.thing,
title='Datasheet',
file='test.pdf'
)
response = self.client.get(f'/thing/{self.thing.id}/')
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Files')
self.assertContains(response, 'Datasheet')
def test_thing_detail_shows_links_section(self):
"""Thing detail page should show links when they exist."""
ThingLink.objects.create(
thing=self.thing,
title='Documentation',
url='https://docs.example.com'
)
response = self.client.get(f'/thing/{self.thing.id}/')
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Links')
self.assertContains(response, 'Documentation')
def test_thing_detail_shows_upload_forms(self):
"""Thing detail page should show upload forms."""
response = self.client.get(f'/thing/{self.thing.id}/')
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Upload File')
self.assertContains(response, 'Add Link')