Compare commits
3 commits
e447f389d8
...
f4894d3a8c
Author | SHA1 | Date | |
---|---|---|---|
f4894d3a8c | |||
93335b2776 | |||
0d394d531b |
12 changed files with 221 additions and 21 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -129,4 +129,5 @@ dmypy.json
|
||||||
.pyre/
|
.pyre/
|
||||||
|
|
||||||
staticfiles/
|
staticfiles/
|
||||||
|
userfiles/
|
||||||
testdata.py
|
testdata.py
|
|
@ -60,6 +60,8 @@ def verify_incoming_friend_request(request, raw_request_body):
|
||||||
befriender_key = request.data['befriender_key']
|
befriender_key = request.data['befriender_key']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return False
|
return False
|
||||||
|
if not befriender or not befriender_key:
|
||||||
|
return False
|
||||||
if username + "@" + domain != befriender:
|
if username + "@" + domain != befriender:
|
||||||
return False
|
return False
|
||||||
if len(befriender_key) != 64:
|
if len(befriender_key) != 64:
|
||||||
|
|
|
@ -72,7 +72,7 @@ class FriendsRequests(APIView, ViewSetMixin):
|
||||||
befriender_username=befriender_username,
|
befriender_username=befriender_username,
|
||||||
befriender_domain=befriender_domain,
|
befriender_domain=befriender_domain,
|
||||||
befriender_public_key=user.public_identity.public_key,
|
befriender_public_key=user.public_identity.public_key,
|
||||||
secret=secret, # request.data['secret'] # TODO ??
|
secret=secret,
|
||||||
befriendee_user=befriendee_user.get(),
|
befriendee_user=befriendee_user.get(),
|
||||||
)
|
)
|
||||||
return Response(status=status.HTTP_201_CREATED, data={'secret': secret, 'status': "pending"})
|
return Response(status=status.HTTP_201_CREATED, data={'secret': secret, 'status': "pending"})
|
||||||
|
@ -81,7 +81,7 @@ class FriendsRequests(APIView, ViewSetMixin):
|
||||||
befriender_user=user,
|
befriender_user=user,
|
||||||
befriendee_username=befriendee_username,
|
befriendee_username=befriendee_username,
|
||||||
befriendee_domain=befriendee_domain,
|
befriendee_domain=befriendee_domain,
|
||||||
secret=secret, # request.data['secret'] # TODO ??
|
secret=secret,
|
||||||
)
|
)
|
||||||
return Response(status=status.HTTP_201_CREATED, data={'secret': secret, 'status': "pending"})
|
return Response(status=status.HTTP_201_CREATED, data={'secret': secret, 'status': "pending"})
|
||||||
elif verify_incoming_friend_request(request, raw_request):
|
elif verify_incoming_friend_request(request, raw_request):
|
||||||
|
|
|
@ -7,8 +7,8 @@ from rest_framework.response import Response
|
||||||
|
|
||||||
from authentication.models import ToolshedUser, KnownIdentity
|
from authentication.models import ToolshedUser, KnownIdentity
|
||||||
from authentication.signature_auth import SignatureAuthentication
|
from authentication.signature_auth import SignatureAuthentication
|
||||||
from toolshed.models import InventoryItem
|
from toolshed.models import InventoryItem, StorageLocation
|
||||||
from toolshed.serializers import InventoryItemSerializer
|
from toolshed.serializers import InventoryItemSerializer, StorageLocationSerializer
|
||||||
|
|
||||||
router = routers.SimpleRouter()
|
router = routers.SimpleRouter()
|
||||||
|
|
||||||
|
@ -24,7 +24,8 @@ def inventory_items(identity):
|
||||||
for friend in identity.friends.all():
|
for friend in identity.friends.all():
|
||||||
if friend_user := friend.user.get():
|
if friend_user := friend.user.get():
|
||||||
for item in friend_user.inventory_items.all():
|
for item in friend_user.inventory_items.all():
|
||||||
yield item
|
if item.availability_policy != 'private':
|
||||||
|
yield item
|
||||||
|
|
||||||
|
|
||||||
class InventoryItemViewSet(viewsets.ModelViewSet):
|
class InventoryItemViewSet(viewsets.ModelViewSet):
|
||||||
|
@ -61,7 +62,19 @@ def search_inventory_items(request):
|
||||||
return Response({'error': 'No query provided.'}, status=400)
|
return Response({'error': 'No query provided.'}, status=400)
|
||||||
|
|
||||||
|
|
||||||
|
class StorageLocationViewSet(viewsets.ModelViewSet):
|
||||||
|
serializer_class = StorageLocationSerializer
|
||||||
|
authentication_classes = [SignatureAuthentication]
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
if type(self.request.user) == KnownIdentity and self.request.user.user.exists():
|
||||||
|
return StorageLocation.objects.filter(owner=self.request.user.user.get())
|
||||||
|
return StorageLocation.objects.none()
|
||||||
|
|
||||||
|
|
||||||
router.register(r'inventory_items', InventoryItemViewSet, basename='inventory_items')
|
router.register(r'inventory_items', InventoryItemViewSet, basename='inventory_items')
|
||||||
|
router.register(r'storage_locations', StorageLocationViewSet, basename='storage_locations')
|
||||||
|
|
||||||
urlpatterns = router.urls + [
|
urlpatterns = router.urls + [
|
||||||
path('search/', search_inventory_items, name='search_inventory_items'),
|
path('search/', search_inventory_items, name='search_inventory_items'),
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Generated by Django 4.2.2 on 2024-02-20 13:50
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('toolshed', '0003_inventoryitem_files_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='StorageLocation',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=255)),
|
||||||
|
('description', models.TextField(blank=True, null=True)),
|
||||||
|
('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='storage_locations', to='toolshed.category')),
|
||||||
|
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='storage_locations', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='toolshed.storagelocation')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='inventoryitem',
|
||||||
|
name='storage_location',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='inventory_items', to='toolshed.storagelocation'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 4.2.2 on 2024-02-20 15:15
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('toolshed', '0004_storagelocation_inventoryitem_storage_location'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='inventoryitem',
|
||||||
|
name='availability_policy',
|
||||||
|
field=models.CharField(choices=[('sell', 'Sell'), ('rent', 'Rent'), ('lend', 'Lend'), ('share', 'Share'), ('private', 'Private')], default='private', max_length=20),
|
||||||
|
),
|
||||||
|
]
|
|
@ -50,18 +50,28 @@ class Tag(models.Model):
|
||||||
|
|
||||||
|
|
||||||
class InventoryItem(SoftDeleteModel):
|
class InventoryItem(SoftDeleteModel):
|
||||||
|
AVAILABILITY_POLICY_CHOICES = (
|
||||||
|
('sell', 'Sell'),
|
||||||
|
('rent', 'Rent'),
|
||||||
|
('lend', 'Lend'),
|
||||||
|
('share', 'Share'),
|
||||||
|
('private', 'Private'),
|
||||||
|
)
|
||||||
|
|
||||||
published = models.BooleanField(default=False)
|
published = models.BooleanField(default=False)
|
||||||
name = models.CharField(max_length=255, null=True, blank=True)
|
name = models.CharField(max_length=255, null=True, blank=True)
|
||||||
description = models.TextField(null=True, blank=True)
|
description = models.TextField(null=True, blank=True)
|
||||||
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True,
|
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True,
|
||||||
related_name='inventory_items')
|
related_name='inventory_items')
|
||||||
availability_policy = models.CharField(max_length=255, default="private")
|
availability_policy = models.CharField(max_length=20, choices=AVAILABILITY_POLICY_CHOICES, default='private')
|
||||||
owned_quantity = models.IntegerField(default=1, validators=[MinValueValidator(0)])
|
owned_quantity = models.IntegerField(default=1, validators=[MinValueValidator(0)])
|
||||||
owner = models.ForeignKey(ToolshedUser, on_delete=models.CASCADE, related_name='inventory_items')
|
owner = models.ForeignKey(ToolshedUser, on_delete=models.CASCADE, related_name='inventory_items')
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
tags = models.ManyToManyField(Tag, through='ItemTag', related_name='inventory_items')
|
tags = models.ManyToManyField(Tag, through='ItemTag', related_name='inventory_items')
|
||||||
properties = models.ManyToManyField(Property, through='ItemProperty')
|
properties = models.ManyToManyField(Property, through='ItemProperty')
|
||||||
files = models.ManyToManyField(File, related_name='connected_items')
|
files = models.ManyToManyField(File, related_name='connected_items')
|
||||||
|
storage_location = models.ForeignKey('StorageLocation', on_delete=models.CASCADE, null=True, blank=True,
|
||||||
|
related_name='inventory_items')
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
if (self.name is None or self.name == "") and self.files.count() == 0:
|
if (self.name is None or self.name == "") and self.files.count() == 0:
|
||||||
|
@ -77,3 +87,16 @@ class ItemProperty(models.Model):
|
||||||
class ItemTag(models.Model):
|
class ItemTag(models.Model):
|
||||||
tag = models.ForeignKey(Tag, on_delete=models.CASCADE)
|
tag = models.ForeignKey(Tag, on_delete=models.CASCADE)
|
||||||
inventory_item = models.ForeignKey(InventoryItem, on_delete=models.CASCADE)
|
inventory_item = models.ForeignKey(InventoryItem, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
|
||||||
|
class StorageLocation(models.Model):
|
||||||
|
name = models.CharField(max_length=255)
|
||||||
|
description = models.TextField(null=True, blank=True)
|
||||||
|
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True,
|
||||||
|
related_name='storage_locations')
|
||||||
|
parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')
|
||||||
|
owner = models.ForeignKey(ToolshedUser, on_delete=models.CASCADE, related_name='storage_locations')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
parent = str(self.parent) + "/" if self.parent else ""
|
||||||
|
return parent + self.name
|
||||||
|
|
|
@ -3,7 +3,7 @@ from authentication.models import KnownIdentity, ToolshedUser, FriendRequestInco
|
||||||
from authentication.serializers import OwnerSerializer
|
from authentication.serializers import OwnerSerializer
|
||||||
from files.models import File
|
from files.models import File
|
||||||
from files.serializers import FileSerializer
|
from files.serializers import FileSerializer
|
||||||
from toolshed.models import Category, Property, ItemProperty, InventoryItem, Tag
|
from toolshed.models import Category, Property, ItemProperty, InventoryItem, Tag, StorageLocation
|
||||||
|
|
||||||
|
|
||||||
class FriendSerializer(serializers.ModelSerializer):
|
class FriendSerializer(serializers.ModelSerializer):
|
||||||
|
@ -11,7 +11,7 @@ class FriendSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = KnownIdentity
|
model = KnownIdentity
|
||||||
fields = ['username', 'public_key']
|
fields = ['id', 'username', 'public_key']
|
||||||
|
|
||||||
def get_username(self, obj):
|
def get_username(self, obj):
|
||||||
return obj.username + '@' + obj.domain
|
return obj.username + '@' + obj.domain
|
||||||
|
@ -48,6 +48,23 @@ class CategorySerializer(serializers.ModelSerializer):
|
||||||
return Category.objects.get(name=data.split("/")[-1])
|
return Category.objects.get(name=data.split("/")[-1])
|
||||||
|
|
||||||
|
|
||||||
|
class StorageLocationSerializer(serializers.ModelSerializer):
|
||||||
|
owner = OwnerSerializer(read_only=True)
|
||||||
|
category = CategorySerializer(required=False, allow_null=True)
|
||||||
|
path = serializers.SerializerMethodField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = StorageLocation
|
||||||
|
fields = ['id', 'name', 'description', 'path', 'category', 'owner']
|
||||||
|
read_only_fields = ['path']
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_path(obj):
|
||||||
|
if obj.parent:
|
||||||
|
return StorageLocationSerializer.get_path(obj.parent) + "/" + obj.name
|
||||||
|
return obj.name
|
||||||
|
|
||||||
|
|
||||||
class ItemPropertySerializer(serializers.ModelSerializer):
|
class ItemPropertySerializer(serializers.ModelSerializer):
|
||||||
property = PropertySerializer(read_only=True)
|
property = PropertySerializer(read_only=True)
|
||||||
|
|
||||||
|
@ -74,7 +91,7 @@ class InventoryItemSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = InventoryItem
|
model = InventoryItem
|
||||||
fields = ['id', 'name', 'description', 'owner', 'category', 'availability_policy', 'owned_quantity', 'owner',
|
fields = ['id', 'name', 'description', 'owner', 'category', 'availability_policy', 'owned_quantity', 'owner',
|
||||||
'tags', 'properties', 'files']
|
'tags', 'properties', 'files', 'storage_location']
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
files = data.pop('files', [])
|
files = data.pop('files', [])
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from toolshed.models import Category, Tag, Property, InventoryItem, ItemProperty
|
from toolshed.models import Category, Tag, Property, InventoryItem, ItemProperty, StorageLocation
|
||||||
|
|
||||||
|
|
||||||
class CategoryTestMixin:
|
class CategoryTestMixin:
|
||||||
|
@ -13,8 +13,10 @@ class CategoryTestMixin:
|
||||||
|
|
||||||
class TagTestMixin:
|
class TagTestMixin:
|
||||||
def prepare_tags(self):
|
def prepare_tags(self):
|
||||||
self.f['tag1'] = Tag.objects.create(name='tag1', description='tag1 description', category=self.f['cat1'], origin='test')
|
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'], origin='test')
|
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')
|
self.f['tag3'] = Tag.objects.create(name='tag3', origin='test')
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,3 +43,13 @@ class InventoryTestMixin(CategoryTestMixin, TagTestMixin, PropertyTestMixin):
|
||||||
self.f['item2'].tags.add(self.f['tag2'], through_defaults={})
|
self.f['item2'].tags.add(self.f['tag2'], through_defaults={})
|
||||||
ItemProperty.objects.create(inventory_item=self.f['item2'], property=self.f['prop1'], value='value1').save()
|
ItemProperty.objects.create(inventory_item=self.f['item2'], property=self.f['prop1'], value='value1').save()
|
||||||
ItemProperty.objects.create(inventory_item=self.f['item2'], property=self.f['prop2'], value='value2').save()
|
ItemProperty.objects.create(inventory_item=self.f['item2'], property=self.f['prop2'], value='value2').save()
|
||||||
|
|
||||||
|
|
||||||
|
class LocationTestMixin:
|
||||||
|
def prepare_locations(self):
|
||||||
|
self.f['loc1'] = StorageLocation.objects.create(name='loc1', owner=self.f['local_user1'])
|
||||||
|
self.f['loc2'] = StorageLocation.objects.create(name='loc2', owner=self.f['local_user1'],
|
||||||
|
category=self.f['cat1'])
|
||||||
|
self.f['loc3'] = StorageLocation.objects.create(name='loc3', owner=self.f['local_user1'], parent=self.f['loc1'])
|
||||||
|
self.f['loc4'] = StorageLocation.objects.create(name='loc4', owner=self.f['local_user1'], parent=self.f['loc1'],
|
||||||
|
category=self.f['cat1'])
|
||||||
|
|
|
@ -210,6 +210,17 @@ class FriendRequestIncomingTestCase(UserTestMixin, ToolshedTestCase):
|
||||||
})
|
})
|
||||||
self.assertEqual(reply.status_code, 400)
|
self.assertEqual(reply.status_code, 400)
|
||||||
|
|
||||||
|
def test_post_request_missing_key_none(self):
|
||||||
|
befriender = self.f['ext_user1']
|
||||||
|
befriendee = self.f['local_user1']
|
||||||
|
reply = client.post('/api/friendrequests/', befriender, {
|
||||||
|
'befriender': str(befriender),
|
||||||
|
'befriendee': str(befriendee),
|
||||||
|
'befriender_key': None,
|
||||||
|
'secret': 'secret2'
|
||||||
|
})
|
||||||
|
self.assertEqual(reply.status_code, 400)
|
||||||
|
|
||||||
def test_post_request_breaking_key(self):
|
def test_post_request_breaking_key(self):
|
||||||
befriender = self.f['ext_user1']
|
befriender = self.f['ext_user1']
|
||||||
befriendee = self.f['local_user1']
|
befriendee = self.f['local_user1']
|
||||||
|
|
|
@ -38,7 +38,7 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
||||||
|
|
||||||
def test_post_new_item(self):
|
def test_post_new_item(self):
|
||||||
reply = client.post('/api/inventory_items/', self.f['local_user1'], {
|
reply = client.post('/api/inventory_items/', self.f['local_user1'], {
|
||||||
'availability_policy': 'friends',
|
'availability_policy': 'rent',
|
||||||
'category': 'cat2',
|
'category': 'cat2',
|
||||||
'name': 'test3',
|
'name': 'test3',
|
||||||
'description': 'test',
|
'description': 'test',
|
||||||
|
@ -50,7 +50,7 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
||||||
self.assertEqual(reply.status_code, 201)
|
self.assertEqual(reply.status_code, 201)
|
||||||
self.assertEqual(InventoryItem.objects.count(), 3)
|
self.assertEqual(InventoryItem.objects.count(), 3)
|
||||||
item = InventoryItem.objects.get(name='test3')
|
item = InventoryItem.objects.get(name='test3')
|
||||||
self.assertEqual(item.availability_policy, 'friends')
|
self.assertEqual(item.availability_policy, 'rent')
|
||||||
self.assertEqual(item.category, Category.objects.get(name='cat2'))
|
self.assertEqual(item.category, Category.objects.get(name='cat2'))
|
||||||
self.assertEqual(item.name, 'test3')
|
self.assertEqual(item.name, 'test3')
|
||||||
self.assertEqual(item.description, 'test')
|
self.assertEqual(item.description, 'test')
|
||||||
|
@ -61,7 +61,7 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
||||||
|
|
||||||
def test_post_new_item2(self):
|
def test_post_new_item2(self):
|
||||||
reply = client.post('/api/inventory_items/', self.f['local_user1'], {
|
reply = client.post('/api/inventory_items/', self.f['local_user1'], {
|
||||||
'availability_policy': 'friends',
|
'availability_policy': 'share',
|
||||||
'name': 'test3',
|
'name': 'test3',
|
||||||
'description': 'test',
|
'description': 'test',
|
||||||
'owned_quantity': 1,
|
'owned_quantity': 1,
|
||||||
|
@ -70,7 +70,7 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
||||||
self.assertEqual(reply.status_code, 201)
|
self.assertEqual(reply.status_code, 201)
|
||||||
self.assertEqual(InventoryItem.objects.count(), 3)
|
self.assertEqual(InventoryItem.objects.count(), 3)
|
||||||
item = InventoryItem.objects.get(name='test3')
|
item = InventoryItem.objects.get(name='test3')
|
||||||
self.assertEqual(item.availability_policy, 'friends')
|
self.assertEqual(item.availability_policy, 'share')
|
||||||
self.assertEqual(item.category, None)
|
self.assertEqual(item.category, None)
|
||||||
self.assertEqual(item.name, 'test3')
|
self.assertEqual(item.name, 'test3')
|
||||||
self.assertEqual(item.description, 'test')
|
self.assertEqual(item.description, 'test')
|
||||||
|
@ -80,7 +80,7 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
||||||
|
|
||||||
def test_post_new_item_empty(self):
|
def test_post_new_item_empty(self):
|
||||||
reply = client.post('/api/inventory_items/', self.f['local_user1'], {
|
reply = client.post('/api/inventory_items/', self.f['local_user1'], {
|
||||||
'availability_policy': 'friends',
|
'availability_policy': 'rent',
|
||||||
'owned_quantity': 1,
|
'owned_quantity': 1,
|
||||||
'image': '',
|
'image': '',
|
||||||
})
|
})
|
||||||
|
@ -89,7 +89,7 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
||||||
|
|
||||||
def test_post_new_item3(self):
|
def test_post_new_item3(self):
|
||||||
reply = client.post('/api/inventory_items/', self.f['local_user1'], {
|
reply = client.post('/api/inventory_items/', self.f['local_user1'], {
|
||||||
'availability_policy': 'friends',
|
'availability_policy': 'private',
|
||||||
'name': 'test3',
|
'name': 'test3',
|
||||||
'description': 'test',
|
'description': 'test',
|
||||||
'owned_quantity': 1,
|
'owned_quantity': 1,
|
||||||
|
@ -99,7 +99,7 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
||||||
self.assertEqual(reply.status_code, 201)
|
self.assertEqual(reply.status_code, 201)
|
||||||
self.assertEqual(InventoryItem.objects.count(), 3)
|
self.assertEqual(InventoryItem.objects.count(), 3)
|
||||||
item = InventoryItem.objects.get(name='test3')
|
item = InventoryItem.objects.get(name='test3')
|
||||||
self.assertEqual(item.availability_policy, 'friends')
|
self.assertEqual(item.availability_policy, 'private')
|
||||||
self.assertEqual(item.category, None)
|
self.assertEqual(item.category, None)
|
||||||
self.assertEqual(item.name, 'test3')
|
self.assertEqual(item.name, 'test3')
|
||||||
self.assertEqual(item.description, 'test')
|
self.assertEqual(item.description, 'test')
|
||||||
|
@ -109,7 +109,7 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
||||||
|
|
||||||
def test_put_item(self):
|
def test_put_item(self):
|
||||||
reply = client.put('/api/inventory_items/1/', self.f['local_user1'], {
|
reply = client.put('/api/inventory_items/1/', self.f['local_user1'], {
|
||||||
'availability_policy': 'friends',
|
'availability_policy': 'sell',
|
||||||
'name': 'test4',
|
'name': 'test4',
|
||||||
'description': 'new description',
|
'description': 'new description',
|
||||||
'owned_quantity': 100,
|
'owned_quantity': 100,
|
||||||
|
@ -121,7 +121,7 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
||||||
self.assertEqual(reply.status_code, 200)
|
self.assertEqual(reply.status_code, 200)
|
||||||
self.assertEqual(InventoryItem.objects.count(), 2)
|
self.assertEqual(InventoryItem.objects.count(), 2)
|
||||||
item = InventoryItem.objects.get(id=1)
|
item = InventoryItem.objects.get(id=1)
|
||||||
self.assertEqual(item.availability_policy, 'friends')
|
self.assertEqual(item.availability_policy, 'sell')
|
||||||
self.assertEqual(item.category, None)
|
self.assertEqual(item.category, None)
|
||||||
self.assertEqual(item.name, 'test4')
|
self.assertEqual(item.name, 'test4')
|
||||||
self.assertEqual(item.description, 'new description')
|
self.assertEqual(item.description, 'new description')
|
||||||
|
|
71
backend/toolshed/tests/test_locations.py
Normal file
71
backend/toolshed/tests/test_locations.py
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
from authentication.tests import SignatureAuthClient, UserTestMixin, ToolshedTestCase
|
||||||
|
from files.tests import FilesTestMixin
|
||||||
|
from toolshed.models import InventoryItem, Category
|
||||||
|
from toolshed.tests import InventoryTestMixin, LocationTestMixin
|
||||||
|
|
||||||
|
client = SignatureAuthClient()
|
||||||
|
|
||||||
|
|
||||||
|
class LocationApiTestCase(UserTestMixin, InventoryTestMixin, LocationTestMixin, ToolshedTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
self.prepare_users()
|
||||||
|
self.prepare_categories()
|
||||||
|
self.prepare_tags()
|
||||||
|
self.prepare_properties()
|
||||||
|
self.prepare_locations()
|
||||||
|
self.prepare_inventory()
|
||||||
|
|
||||||
|
def test_locations(self):
|
||||||
|
self.assertEqual("loc1", str(self.f['loc1']))
|
||||||
|
self.assertEqual("loc1", self.f['loc1'].name)
|
||||||
|
self.assertEqual("loc2", str(self.f['loc2']))
|
||||||
|
self.assertEqual("loc2", self.f['loc2'].name)
|
||||||
|
self.assertEqual("loc1/loc3", str(self.f['loc3']))
|
||||||
|
self.assertEqual("loc3", self.f['loc3'].name)
|
||||||
|
self.assertEqual(self.f['loc1'], self.f['loc3'].parent)
|
||||||
|
self.assertEqual("loc1/loc4", str(self.f['loc4']))
|
||||||
|
self.assertEqual("loc4", self.f['loc4'].name)
|
||||||
|
self.assertEqual(self.f['loc1'], self.f['loc4'].parent)
|
||||||
|
|
||||||
|
def test_get_inventory(self):
|
||||||
|
reply = client.get('/api/inventory_items/', self.f['local_user1'])
|
||||||
|
self.assertEqual(reply.status_code, 200)
|
||||||
|
self.assertEqual(len(reply.json()), 2)
|
||||||
|
self.assertEqual(reply.json()[0]['name'], 'test1')
|
||||||
|
self.assertEqual(reply.json()[0]['description'], 'test')
|
||||||
|
self.assertEqual(reply.json()[0]['owned_quantity'], 1)
|
||||||
|
self.assertEqual(reply.json()[0]['tags'], [])
|
||||||
|
self.assertEqual(reply.json()[0]['properties'], [])
|
||||||
|
self.assertEqual(reply.json()[0]['category'], 'cat1')
|
||||||
|
self.assertEqual(reply.json()[0]['availability_policy'], 'friends')
|
||||||
|
self.assertEqual(reply.json()[1]['name'], 'test2')
|
||||||
|
self.assertEqual(reply.json()[1]['description'], 'test2')
|
||||||
|
self.assertEqual(reply.json()[1]['owned_quantity'], 1)
|
||||||
|
self.assertEqual(reply.json()[1]['tags'], ['tag1', 'tag2'])
|
||||||
|
self.assertEqual(reply.json()[1]['properties'],
|
||||||
|
[{'name': 'prop1', 'value': 'value1'}, {'name': 'prop2', 'value': 'value2'}])
|
||||||
|
self.assertEqual(reply.json()[1]['category'], 'cat1')
|
||||||
|
self.assertEqual(reply.json()[1]['availability_policy'], 'friends')
|
||||||
|
|
||||||
|
def test_get_inventory_item(self):
|
||||||
|
reply = client.get('/api/storage_locations/', self.f['local_user1'])
|
||||||
|
self.assertEqual(reply.status_code, 200)
|
||||||
|
self.assertEqual(len(reply.json()), 4)
|
||||||
|
self.assertEqual(reply.json()[0]['name'], 'loc1')
|
||||||
|
self.assertEqual(reply.json()[0]['description'], None)
|
||||||
|
self.assertEqual(reply.json()[0]['category'], None)
|
||||||
|
self.assertEqual(reply.json()[0]['path'], 'loc1')
|
||||||
|
self.assertEqual(reply.json()[1]['name'], 'loc2')
|
||||||
|
self.assertEqual(reply.json()[1]['description'], None)
|
||||||
|
self.assertEqual(reply.json()[1]['category'], 'cat1')
|
||||||
|
self.assertEqual(reply.json()[1]['path'], 'loc2')
|
||||||
|
self.assertEqual(reply.json()[2]['name'], 'loc3')
|
||||||
|
self.assertEqual(reply.json()[2]['description'], None)
|
||||||
|
self.assertEqual(reply.json()[2]['category'], None)
|
||||||
|
self.assertEqual(reply.json()[2]['path'], 'loc1/loc3')
|
||||||
|
self.assertEqual(reply.json()[3]['name'], 'loc4')
|
||||||
|
self.assertEqual(reply.json()[3]['description'], None)
|
||||||
|
self.assertEqual(reply.json()[3]['category'], 'cat1')
|
||||||
|
self.assertEqual(reply.json()[3]['path'], 'loc1/loc4')
|
Loading…
Reference in a new issue