add /files/ and /item_files/ API endpoints
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
3afeed81b3
commit
d00d637dca
11 changed files with 430 additions and 33 deletions
|
|
@ -3,28 +3,28 @@ from toolshed.models import Category, Tag, Property, InventoryItem, ItemProperty
|
|||
|
||||
class CategoryTestMixin:
|
||||
def prepare_categories(self):
|
||||
self.f['cat1'] = Category.objects.create(name='cat1')
|
||||
self.f['cat2'] = Category.objects.create(name='cat2')
|
||||
self.f['cat3'] = Category.objects.create(name='cat3')
|
||||
self.f['subcat1'] = Category.objects.create(name='subcat1', parent=self.f['cat1'])
|
||||
self.f['subcat2'] = Category.objects.create(name='subcat2', parent=self.f['cat1'])
|
||||
self.f['subcat3'] = Category.objects.create(name='subcat3', parent=self.f['subcat1'])
|
||||
self.f['cat1'] = Category.objects.create(name='cat1', origin='test')
|
||||
self.f['cat2'] = Category.objects.create(name='cat2', origin='test')
|
||||
self.f['cat3'] = Category.objects.create(name='cat3', origin='test')
|
||||
self.f['subcat1'] = Category.objects.create(name='subcat1', parent=self.f['cat1'], origin='test')
|
||||
self.f['subcat2'] = Category.objects.create(name='subcat2', parent=self.f['cat1'], origin='test')
|
||||
self.f['subcat3'] = Category.objects.create(name='subcat3', parent=self.f['subcat1'], origin='test')
|
||||
|
||||
|
||||
class TagTestMixin:
|
||||
def prepare_tags(self):
|
||||
self.f['tag1'] = Tag.objects.create(name='tag1', description='tag1 description', category=self.f['cat1'])
|
||||
self.f['tag2'] = Tag.objects.create(name='tag2', description='tag2 description', category=self.f['cat1'])
|
||||
self.f['tag3'] = Tag.objects.create(name='tag3')
|
||||
self.f['tag1'] = Tag.objects.create(name='tag1', description='tag1 description', category=self.f['cat1'], origin='test')
|
||||
self.f['tag2'] = Tag.objects.create(name='tag2', description='tag2 description', category=self.f['cat1'], origin='test')
|
||||
self.f['tag3'] = Tag.objects.create(name='tag3', origin='test')
|
||||
|
||||
|
||||
class PropertyTestMixin:
|
||||
def prepare_properties(self):
|
||||
self.f['prop1'] = Property.objects.create(name='prop1')
|
||||
self.f['prop1'] = Property.objects.create(name='prop1', origin='test')
|
||||
self.f['prop2'] = Property.objects.create(
|
||||
name='prop2', description='prop2 description', category=self.f['cat1'])
|
||||
name='prop2', description='prop2 description', category=self.f['cat1'], origin='test')
|
||||
self.f['prop3'] = Property.objects.create(
|
||||
name='prop3', description='prop3 description', category=self.f['cat1'])
|
||||
name='prop3', description='prop3 description', category=self.f['cat1'], origin='test')
|
||||
|
||||
|
||||
class InventoryTestMixin(CategoryTestMixin, TagTestMixin, PropertyTestMixin):
|
||||
|
|
|
|||
140
backend/toolshed/tests/test_files.py
Normal file
140
backend/toolshed/tests/test_files.py
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
from django.test import Client
|
||||
from authentication.tests import SignatureAuthClient, UserTestMixin, ToolshedTestCase
|
||||
from files.tests import FilesTestMixin
|
||||
from toolshed.models import File
|
||||
|
||||
from toolshed.tests import InventoryTestMixin
|
||||
|
||||
anonymous_client = Client()
|
||||
client = SignatureAuthClient()
|
||||
|
||||
|
||||
class FileApiTestCase(UserTestMixin, FilesTestMixin, InventoryTestMixin, ToolshedTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.prepare_users()
|
||||
self.prepare_files()
|
||||
self.prepare_categories()
|
||||
self.prepare_tags()
|
||||
self.prepare_properties()
|
||||
self.prepare_inventory()
|
||||
self.f['item1'].files.add(self.f['test_file1'])
|
||||
self.f['item1'].files.add(self.f['test_file2'])
|
||||
self.f['item2'].files.add(self.f['test_file1'])
|
||||
|
||||
def test_files_anonymous(self):
|
||||
response = anonymous_client.get(f"/api/item_files/{self.f['item1'].id}/")
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_list_all_files(self):
|
||||
response = client.get(f"/api/files/", self.f['local_user1'])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(response.json()), 2)
|
||||
self.assertEqual(response.json()[0]['mime_type'], 'text/plain')
|
||||
self.assertEqual(response.json()[0]['name'],
|
||||
f"/media/{self.f['hash1'][:2]}/{self.f['hash1'][2:4]}/{self.f['hash1'][4:6]}/{self.f['hash1'][6:]}")
|
||||
self.assertEqual(response.json()[1]['mime_type'], 'text/plain')
|
||||
self.assertEqual(response.json()[1]['name'],
|
||||
f"/media/{self.f['hash2'][:2]}/{self.f['hash2'][2:4]}/{self.f['hash2'][4:6]}/{self.f['hash2'][6:]}")
|
||||
|
||||
def test_files(self):
|
||||
response = client.get(f"/api/item_files/{self.f['item1'].id}/", self.f['local_user1'])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(response.json()), 2)
|
||||
self.assertEqual(response.json()[0]['mime_type'], 'text/plain')
|
||||
self.assertEqual(response.json()[0]['name'],
|
||||
f"/media/{self.f['hash1'][:2]}/{self.f['hash1'][2:4]}/{self.f['hash1'][4:6]}/{self.f['hash1'][6:]}")
|
||||
self.assertEqual(response.json()[1]['mime_type'], 'text/plain')
|
||||
self.assertEqual(response.json()[1]['name'],
|
||||
f"/media/{self.f['hash2'][:2]}/{self.f['hash2'][2:4]}/{self.f['hash2'][4:6]}/{self.f['hash2'][6:]}")
|
||||
|
||||
def test_files_not_found(self):
|
||||
response = client.get(f"/api/item_files/99999/", self.f['local_user1'])
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_post_file(self):
|
||||
response = client.post(f"/api/item_files/{self.f['item1'].id}/", self.f['local_user1'],
|
||||
{'data': self.f['encoded_content4'], 'mime_type': 'text/plain'})
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertEqual(File.objects.count(), 4)
|
||||
self.assertEqual(File.objects.last().mime_type, 'text/plain')
|
||||
self.assertEqual(File.objects.last().file.read(), self.f['test_content4'])
|
||||
self.assertEqual(File.objects.last().file.size, len(self.f['test_content4']))
|
||||
self.assertEqual(File.objects.last().file.name,
|
||||
f"{self.f['hash4'][:2]}/{self.f['hash4'][2:4]}/{self.f['hash4'][4:6]}/{self.f['hash4'][6:]}")
|
||||
|
||||
def test_post_file_duplicate(self):
|
||||
self.assertEqual(File.objects.count(), 3)
|
||||
self.assertEqual(self.f['item1'].files.count(), 2)
|
||||
response = client.post(f"/api/item_files/{self.f['item1'].id}/", self.f['local_user1'],
|
||||
{'data': self.f['encoded_content3'], 'mime_type': 'text/plain'})
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertEqual(File.objects.count(), 3)
|
||||
self.assertEqual(self.f['item1'].files.count(), 3)
|
||||
self.assertEqual(self.f['item1'].files.last().file.read(), self.f['test_content3'])
|
||||
self.assertEqual(self.f['item1'].files.last().file.size, len(self.f['test_content3']))
|
||||
self.assertEqual(self.f['item1'].files.last().file.name,
|
||||
f"{self.f['hash3'][:2]}/{self.f['hash3'][2:4]}/{self.f['hash3'][4:6]}/{self.f['hash3'][6:]}")
|
||||
|
||||
def test_post_file_invalid(self):
|
||||
response = client.post(f"/api/item_files/{self.f['item1'].id}/", self.f['local_user1'],
|
||||
{'data': self.f['encoded_content4']})
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_post_file_not_found_item(self):
|
||||
response = client.post(f"/api/item_files/99999/", self.f['local_user1'],
|
||||
{'data': self.f['encoded_content3'], 'mime_type': 'text/plain'})
|
||||
self.assertEqual(response.status_code, 404)
|
||||
self.assertEqual(File.objects.count(), 3)
|
||||
|
||||
def test_post_file_not_authenticated(self):
|
||||
response = anonymous_client.post(f"/api/item_files/{self.f['item1'].id}/",
|
||||
{'data': self.f['encoded_content3'], 'mime_type': 'text/plain'})
|
||||
self.assertEqual(response.status_code, 403)
|
||||
self.assertEqual(File.objects.count(), 3)
|
||||
|
||||
def test_post_file_not_authorized(self):
|
||||
response = client.post(f"/api/item_files/{self.f['item1'].id}/", self.f['local_user2'],
|
||||
{'data': self.f['encoded_content3'], 'mime_type': 'text/plain'})
|
||||
self.assertEqual(response.status_code, 404)
|
||||
self.assertEqual(File.objects.count(), 3)
|
||||
|
||||
def test_delete_file(self):
|
||||
response = client.delete(f"/api/item_files/{self.f['item1'].id}/{self.f['test_file1'].id}/",
|
||||
self.f['local_user1'])
|
||||
self.assertEqual(response.status_code, 204)
|
||||
self.assertEqual(File.objects.count(), 3)
|
||||
self.assertEqual(self.f['item1'].files.count(), 1)
|
||||
|
||||
def test_delete_file_last_use(self):
|
||||
response = client.delete(f"/api/item_files/{self.f['item1'].id}/{self.f['test_file2'].id}/",
|
||||
self.f['local_user1'])
|
||||
self.assertEqual(response.status_code, 204)
|
||||
self.assertEqual(File.objects.count(), 2)
|
||||
self.assertEqual(self.f['item1'].files.count(), 1)
|
||||
|
||||
def test_delete_file_not_found(self):
|
||||
response = client.delete(f"/api/item_files/{self.f['item1'].id}/99999/", self.f['local_user1'])
|
||||
self.assertEqual(response.status_code, 404)
|
||||
self.assertEqual(File.objects.count(), 3)
|
||||
self.assertEqual(self.f['item1'].files.count(), 2)
|
||||
|
||||
def test_delete_file_not_found_item(self):
|
||||
response = client.delete(f"/api/item_files/99999/{self.f['test_file1'].id}/", self.f['local_user1'])
|
||||
self.assertEqual(response.status_code, 404)
|
||||
self.assertEqual(File.objects.count(), 3)
|
||||
self.assertEqual(self.f['item1'].files.count(), 2)
|
||||
|
||||
def test_delete_file_not_owner(self):
|
||||
response = client.delete(f"/api/item_files/{self.f['item1'].id}/{self.f['test_file1'].id}/",
|
||||
self.f['local_user2'])
|
||||
self.assertEqual(response.status_code, 404)
|
||||
self.assertEqual(File.objects.count(), 3)
|
||||
self.assertEqual(self.f['item1'].files.count(), 2)
|
||||
|
||||
def test_delete_file_anonymous(self):
|
||||
response = anonymous_client.delete(f"/api/item_files/{self.f['item1'].id}/{self.f['test_file1'].id}/")
|
||||
self.assertEqual(response.status_code, 403)
|
||||
self.assertEqual(File.objects.count(), 3)
|
||||
self.assertEqual(self.f['item1'].files.count(), 2)
|
||||
|
|
@ -1,11 +1,12 @@
|
|||
from authentication.tests import SignatureAuthClient, UserTestMixin, ToolshedTestCase
|
||||
from files.tests import FilesTestMixin
|
||||
from toolshed.models import InventoryItem, Category
|
||||
from toolshed.tests import InventoryTestMixin, CategoryTestMixin, TagTestMixin, PropertyTestMixin
|
||||
|
||||
client = SignatureAuthClient()
|
||||
|
||||
|
||||
class InventoryTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
||||
class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
|
@ -77,6 +78,15 @@ class InventoryTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
|||
self.assertEqual([t for t in item.tags.all()], [])
|
||||
self.assertEqual([p for p in item.properties.all()], [])
|
||||
|
||||
def test_post_new_item_empty(self):
|
||||
reply = client.post('/api/inventory_items/', self.f['local_user1'], {
|
||||
'availability_policy': 'friends',
|
||||
'owned_quantity': 1,
|
||||
'image': '',
|
||||
})
|
||||
self.assertEqual(reply.status_code, 400)
|
||||
self.assertEqual(InventoryItem.objects.count(), 2)
|
||||
|
||||
def test_post_new_item3(self):
|
||||
reply = client.post('/api/inventory_items/', self.f['local_user1'], {
|
||||
'availability_policy': 'friends',
|
||||
|
|
@ -202,3 +212,84 @@ class InventoryTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
|||
reply = client.get('/api/search/?query=test', self.f['ext_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 0)
|
||||
|
||||
|
||||
class TestInventoryItemWithFileApiTestCase(UserTestMixin, FilesTestMixin, InventoryTestMixin, ToolshedTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.prepare_users()
|
||||
self.prepare_categories()
|
||||
self.prepare_tags()
|
||||
self.prepare_properties()
|
||||
self.prepare_files()
|
||||
self.prepare_inventory()
|
||||
|
||||
def test_post_item_with_file_id(self):
|
||||
reply = client.post('/api/inventory_items/', self.f['local_user1'], {
|
||||
'name': 'test4',
|
||||
'description': 'test',
|
||||
'category': 'cat1',
|
||||
'owned_quantity': 1,
|
||||
'tags': ['tag1', 'tag2'],
|
||||
'properties': [{'name': 'prop1', 'value': 'value1'}, {'name': 'prop2', 'value': 'value2'}],
|
||||
'files': [self.f['test_file1'].id]
|
||||
})
|
||||
self.assertEqual(reply.status_code, 201)
|
||||
self.assertEqual(InventoryItem.objects.count(), 3)
|
||||
item = InventoryItem.objects.get(id=3)
|
||||
self.assertEqual(item.availability_policy, 'private')
|
||||
self.assertEqual(item.category, Category.objects.get(name='cat1'))
|
||||
self.assertEqual(item.name, 'test4')
|
||||
self.assertEqual(item.description, 'test')
|
||||
self.assertEqual(item.owned_quantity, 1)
|
||||
self.assertEqual([t for t in item.tags.all()], [self.f['tag1'], self.f['tag2']])
|
||||
self.assertEqual([p for p in item.properties.all()], [self.f['prop1'], self.f['prop2']])
|
||||
self.assertEqual([p.value for p in item.itemproperty_set.all()], ['value1', 'value2'])
|
||||
self.assertEqual([f for f in item.files.all()], [self.f['test_file1']])
|
||||
|
||||
def test_post_item_with_encoded_file(self):
|
||||
reply = client.post('/api/inventory_items/', self.f['local_user1'], {
|
||||
'name': 'test4',
|
||||
'description': 'test',
|
||||
'category': 'cat1',
|
||||
'owned_quantity': 1,
|
||||
'tags': ['tag1', 'tag2'],
|
||||
'properties': [{'name': 'prop1', 'value': 'value1'}, {'name': 'prop2', 'value': 'value2'}],
|
||||
'files': [{'data': self.f['encoded_content3'], 'mime_type': 'text/plain'}]
|
||||
})
|
||||
self.assertEqual(reply.status_code, 201)
|
||||
self.assertEqual(InventoryItem.objects.count(), 3)
|
||||
item = InventoryItem.objects.get(id=3)
|
||||
self.assertEqual(item.availability_policy, 'private')
|
||||
self.assertEqual(item.category, Category.objects.get(name='cat1'))
|
||||
self.assertEqual(item.name, 'test4')
|
||||
self.assertEqual(item.description, 'test')
|
||||
self.assertEqual(item.owned_quantity, 1)
|
||||
self.assertEqual([t for t in item.tags.all()], [self.f['tag1'], self.f['tag2']])
|
||||
self.assertEqual([p for p in item.properties.all()], [self.f['prop1'], self.f['prop2']])
|
||||
self.assertEqual([p.value for p in item.itemproperty_set.all()], ['value1', 'value2'])
|
||||
self.assertEqual([f for f in item.files.all()], [self.f['test_file3']])
|
||||
|
||||
def test_post_item_with_file_id_fail(self):
|
||||
reply = client.post('/api/inventory_items/', self.f['local_user1'], {
|
||||
'name': 'test4',
|
||||
'description': 'test',
|
||||
'category': 'cat1',
|
||||
'owned_quantity': 1,
|
||||
'tags': ['tag1', 'tag2'],
|
||||
'properties': [{'name': 'prop1', 'value': 'value1'}, {'name': 'prop2', 'value': 'value2'}],
|
||||
'files': [99999]
|
||||
})
|
||||
self.assertEqual(reply.status_code, 400)
|
||||
|
||||
def test_post_item_with_encoded_file_fail(self):
|
||||
reply = client.post('/api/inventory_items/', self.f['local_user1'], {
|
||||
'name': 'test4',
|
||||
'description': 'test',
|
||||
'category': 'cat1',
|
||||
'owned_quantity': 1,
|
||||
'tags': ['tag1', 'tag2'],
|
||||
'properties': [{'name': 'prop1', 'value': 'value1'}, {'name': 'prop2', 'value': 'value2'}],
|
||||
'files': [{'data': self.f['encoded_content3']}]
|
||||
})
|
||||
self.assertEqual(reply.status_code, 400)
|
||||
Loading…
Add table
Add a link
Reference in a new issue