stash
This commit is contained in:
parent
8cba1f52e8
commit
ebd0db4b43
27 changed files with 326 additions and 329 deletions
|
|
@ -412,26 +412,26 @@ class FriendApiTestCase(UserTestMixin, ToolshedTestCase):
|
|||
self.client = SignatureAuthClient()
|
||||
|
||||
def test_friend_local(self):
|
||||
reply = self.client.get('/api/friends/', self.f['local_user1'])
|
||||
reply = self.client.get('/api/v1/friends/', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
|
||||
def test_friend_external(self):
|
||||
reply = self.client.get('/api/friends/', self.f['ext_user1'])
|
||||
reply = self.client.get('/api/v1/friends/', self.f['ext_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
|
||||
def test_friend_fail(self):
|
||||
reply = self.anonymous_client.get('/api/friends/')
|
||||
reply = self.anonymous_client.get('/api/v1/friends/')
|
||||
self.assertEqual(reply.status_code, 403)
|
||||
|
||||
def test_friend_fail2(self):
|
||||
target = "/api/friends/"
|
||||
target = "/api/v1/friends/"
|
||||
signature = self.f['local_user1'].sign("http://testserver2" + target)
|
||||
header = {'HTTP_AUTHORIZATION': 'Signature ' + str(self.f['local_user1']) + ':' + signature}
|
||||
reply = self.anonymous_client.get(target, **header)
|
||||
self.assertEqual(reply.status_code, 403)
|
||||
|
||||
def test_friend_fail3(self):
|
||||
target = "/api/friends/"
|
||||
target = "/api/v1/friends/"
|
||||
unknown_user = DummyExternalUser('extuser3', 'external.org', False)
|
||||
signature = unknown_user.sign("http://testserver" + target)
|
||||
header = {'HTTP_AUTHORIZATION': 'Signature ' + str(unknown_user) + ':' + signature}
|
||||
|
|
@ -439,7 +439,7 @@ class FriendApiTestCase(UserTestMixin, ToolshedTestCase):
|
|||
self.assertEqual(reply.status_code, 403)
|
||||
|
||||
def test_friend_fail4(self):
|
||||
target = "/api/friends/"
|
||||
target = "/api/v1/friends/"
|
||||
signature = self.f['local_user1'].sign("http://testserver" + target)
|
||||
header = {'HTTP_AUTHORIZATION': 'Auth ' + str(self.f['local_user1']) + ':' + signature}
|
||||
reply = self.anonymous_client.get(target, **header)
|
||||
|
|
|
|||
|
|
@ -19,13 +19,14 @@ urlpatterns = [
|
|||
path('djangoadmin/', admin.site.urls),
|
||||
path('auth/', include('authentication.api')),
|
||||
path('admin/', include('hostadmin.api')),
|
||||
path('api/', include('toolshed.api.friend')),
|
||||
path('api/', include('toolshed.api.group')),
|
||||
path('api/', include('toolshed.api.idmap')),
|
||||
path('api/', include('toolshed.api.inventory')),
|
||||
path('api/', include('toolshed.api.info')),
|
||||
path('api/', include('toolshed.api.files')),
|
||||
path('api/', include('toolshed.api.offlinedata')),
|
||||
path('api/version/', include('toolshed.api.version')),
|
||||
path('api/v1/', include('toolshed.api.info')),
|
||||
path('api/v1/', include('toolshed.api.friend')),
|
||||
path('api/v1/', include('toolshed.api.group')),
|
||||
path('api/v1/', include('toolshed.api.idmap')),
|
||||
path('api/v1/', include('toolshed.api.inventory')),
|
||||
path('api/v1/', include('toolshed.api.files')),
|
||||
path('api/v1/', include('toolshed.api.offlinedata')),
|
||||
path('media/', include('files.media_urls')),
|
||||
path('docs/', schema_view.with_ui('swagger', cache_timeout=0), name='api-docs'),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class DomainApiTestCase(UserTestMixin, ToolshedTestCase):
|
|||
self.prepare_users()
|
||||
|
||||
def test_get_domains(self):
|
||||
response = client.get('/api/domains/', self.f['local_user1'])
|
||||
response = client.get('/api/v1/domains/', self.f['local_user1'])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.json(), ['example.com'])
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ class CategoryApiTestCase(UserTestMixin, CategoryTestMixin, ToolshedTestCase):
|
|||
self.prepare_categories()
|
||||
|
||||
def test_get_categories(self):
|
||||
response = client.get('/api/categories/', self.f['local_user1'])
|
||||
response = client.get('/api/v1/categories/', self.f['local_user1'])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.json(),
|
||||
["cat1", "cat2", "cat3", "cat1/subcat1",
|
||||
|
|
@ -215,7 +215,7 @@ class TagApiTestCase(UserTestMixin, CategoryTestMixin, TagTestMixin, ToolshedTes
|
|||
self.prepare_tags()
|
||||
|
||||
def test_get_tags(self):
|
||||
response = client.get('/api/tags/', self.f['local_user1'])
|
||||
response = client.get('/api/v1/tags/', self.f['local_user1'])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.json(), ["tag1", "tag2", "tag3"])
|
||||
|
||||
|
|
@ -275,7 +275,7 @@ class PropertyApiTestCase(UserTestMixin, CategoryTestMixin, PropertyTestMixin, T
|
|||
self.prepare_properties()
|
||||
|
||||
def test_get_properties(self):
|
||||
response = client.get('/api/properties/', self.f['local_user1'])
|
||||
response = client.get('/api/v1/properties/', self.f['local_user1'])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(response.json()), 3)
|
||||
self.assertEqual(response.json()[0]['name'], 'prop1')
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ def _get_authorized_item(identity, item_id):
|
|||
@api_view(['GET'])
|
||||
@permission_classes([IsAuthenticated])
|
||||
@authentication_classes([SignatureAuthenticationLocal])
|
||||
def list_all_files(request, format=None): # /files/
|
||||
def list_all_files(request, format=None):
|
||||
# request.user is a ToolshedUser here; reach group membership via public_identity.
|
||||
files = File.objects.select_related().filter(
|
||||
Q(connected_items__owner=request.user) |
|
||||
|
|
@ -94,7 +94,7 @@ def post_staged_file(request, workflow_id):
|
|||
@api_view(['POST', 'GET'])
|
||||
@permission_classes([IsAuthenticated])
|
||||
@authentication_classes([SignatureAuthentication])
|
||||
def item_files(request, item_id, format=None): # /item_files/
|
||||
def item_files(request, item_id, format=None):
|
||||
if request.method == 'GET':
|
||||
return get_item_files(request, item_id)
|
||||
elif request.method == 'POST':
|
||||
|
|
@ -104,7 +104,7 @@ def item_files(request, item_id, format=None): # /item_files/
|
|||
@api_view(['DELETE'])
|
||||
@permission_classes([IsAuthenticated])
|
||||
@authentication_classes([SignatureAuthentication])
|
||||
def delete_item_file(request, item_id, file_id, format=None): # /item_files/
|
||||
def delete_item_file(request, item_id, file_id, format=None):
|
||||
item = _get_authorized_item(request.user, item_id)
|
||||
if item is None:
|
||||
return Response(status=status.HTTP_404_NOT_FOUND)
|
||||
|
|
@ -123,7 +123,7 @@ def delete_item_file(request, item_id, file_id, format=None): # /item_files/
|
|||
@api_view(['POST', 'GET'])
|
||||
@permission_classes([IsAuthenticated])
|
||||
@authentication_classes([SignatureAuthenticationLocal])
|
||||
def staged_files(request, workflow_id, format=None): # /staged_files/
|
||||
def staged_files(request, workflow_id, format=None):
|
||||
if request.method == 'GET':
|
||||
return get_staged_files(request, workflow_id)
|
||||
elif request.method == 'POST':
|
||||
|
|
@ -133,7 +133,7 @@ def staged_files(request, workflow_id, format=None): # /staged_files/
|
|||
@api_view(['DELETE'])
|
||||
@permission_classes([IsAuthenticated])
|
||||
@authentication_classes([SignatureAuthenticationLocal])
|
||||
def delete_staged_file(request, workflow_id, file_hash, format=None): # /staged_files/
|
||||
def delete_staged_file(request, workflow_id, file_hash, format=None):
|
||||
try:
|
||||
workflow = WorkflowInstance.objects.get(id=workflow_id, owner=request.user)
|
||||
file = workflow.staged_files.get(hash=file_hash)
|
||||
|
|
|
|||
|
|
@ -19,13 +19,13 @@ class Friends(APIView, ViewSetMixin):
|
|||
authentication_classes = [SignatureAuthentication]
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, format=None): # /api/friends/ #
|
||||
def get(self, request, format=None):
|
||||
user = request.user
|
||||
friends = user.friends.all()
|
||||
serializer = FriendSerializer(friends, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
def post(self, request, format=None): # /api/friends/
|
||||
def post(self, request, format=None):
|
||||
# only for local users
|
||||
try:
|
||||
user = request.user
|
||||
|
|
@ -47,7 +47,7 @@ class Friends(APIView, ViewSetMixin):
|
|||
|
||||
|
||||
class FriendsRequests(APIView, ViewSetMixin):
|
||||
def get(self, request, format=None): # /api/friendrequests/
|
||||
def get(self, request, format=None):
|
||||
raw_request = request.body.decode('utf-8')
|
||||
if user := authenticate_request_against_local_users(request, raw_request):
|
||||
friends_requests = user.friend_requests_incoming.all()
|
||||
|
|
@ -56,7 +56,7 @@ class FriendsRequests(APIView, ViewSetMixin):
|
|||
else:
|
||||
return Response(status=status.HTTP_401_UNAUTHORIZED, data={'status': 'unauthorized'})
|
||||
|
||||
def post(self, request, format=None): # /api/friendrequests/
|
||||
def post(self, request, format=None):
|
||||
raw_request = request.body.decode('utf-8')
|
||||
if 'befriender' not in request.data or 'befriendee' not in request.data:
|
||||
return Response(status=status.HTTP_400_BAD_REQUEST, data={'status': 'missing parameters'})
|
||||
|
|
@ -131,7 +131,7 @@ class FriendsRequests(APIView, ViewSetMixin):
|
|||
@api_view(['DELETE'])
|
||||
@authentication_classes([SignatureAuthenticationLocal])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def dropFriend(request, pk, format=None): # /api/friends/<id>/
|
||||
def dropFriend(request, pk, format=None):
|
||||
user = request.user
|
||||
friend = get_object_or_404(user.friends, pk=pk)
|
||||
user.friends.remove(friend)
|
||||
|
|
@ -142,7 +142,7 @@ def dropFriend(request, pk, format=None): # /api/friends/<id>/
|
|||
@api_view(['DELETE'])
|
||||
@authentication_classes([SignatureAuthenticationLocal])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def deleteFriendRequest(request, pk, format=None): # /api/friendrequests/<id>/
|
||||
def deleteFriendRequest(request, pk, format=None):
|
||||
user = request.user
|
||||
get_object_or_404(user.friend_requests_incoming, pk=pk).delete()
|
||||
user.save()
|
||||
|
|
|
|||
|
|
@ -21,11 +21,11 @@ class Groups(APIView, ViewSetMixin):
|
|||
authentication_classes = [SignatureAuthentication]
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, format=None): # /api/groups/
|
||||
def get(self, request, format=None):
|
||||
groups = request.user.member_of_groups.all()
|
||||
return Response(GroupSerializer(groups, many=True).data)
|
||||
|
||||
def post(self, request, format=None): # /api/groups/
|
||||
def post(self, request, format=None):
|
||||
name = request.data.get('name')
|
||||
if not name:
|
||||
return Response(status=status.HTTP_400_BAD_REQUEST, data={'status': 'name is required'})
|
||||
|
|
@ -40,7 +40,7 @@ class GroupDetail(APIView, ViewSetMixin):
|
|||
authentication_classes = [SignatureAuthentication]
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, handle, format=None): # /api/groups/<name@domain>/
|
||||
def get(self, request, handle, format=None):
|
||||
try:
|
||||
name, domain = split_userhandle_or_throw(handle)
|
||||
except ValueError:
|
||||
|
|
@ -54,7 +54,7 @@ class GroupDetail(APIView, ViewSetMixin):
|
|||
@api_view(['DELETE'])
|
||||
@authentication_classes([SignatureAuthentication])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def removeGroupMember(request, handle, identity_id, format=None): # /api/groups/<name@domain>/members/<identity_id>/
|
||||
def removeGroupMember(request, handle, identity_id, format=None):
|
||||
try:
|
||||
name, domain = split_userhandle_or_throw(handle)
|
||||
except ValueError:
|
||||
|
|
@ -73,7 +73,7 @@ def removeGroupMember(request, handle, identity_id, format=None): # /api/groups
|
|||
@api_view(['POST'])
|
||||
@authentication_classes([SignatureAuthentication])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def createGroupInvite(request, handle, format=None): # /api/groups/<name@domain>/invites/
|
||||
def createGroupInvite(request, handle, format=None):
|
||||
try:
|
||||
name, domain = split_userhandle_or_throw(handle)
|
||||
except ValueError:
|
||||
|
|
@ -97,18 +97,14 @@ def createGroupInvite(request, handle, format=None): # /api/groups/<name@domain
|
|||
|
||||
|
||||
class GroupInvitesIncoming(APIView, ViewSetMixin):
|
||||
"""/api/groupinvites/ - the invitee's own view of their pending invites, and the delivery
|
||||
endpoint an inviter's client posts to directly on the invitee's own home backend (see
|
||||
docs/design-in-progress/groups-mvp.md's invite/accept dance)."""
|
||||
|
||||
def get(self, request, format=None): # /api/groupinvites/ - only ever a local user checking their own invites
|
||||
def get(self, request, format=None):
|
||||
raw_request = request.body.decode('utf-8')
|
||||
if not (user := authenticate_request_against_local_users(request, raw_request)):
|
||||
return Response(status=status.HTTP_401_UNAUTHORIZED, data={'status': 'unauthorized'})
|
||||
invites = user.group_invites_incoming.all()
|
||||
return Response(GroupInviteIncomingSerializer(invites, many=True).data)
|
||||
|
||||
def post(self, request, format=None): # /api/groupinvites/ - delivery, self-certified, caller isn't known here
|
||||
def post(self, request, format=None):
|
||||
raw_request = request.body.decode('utf-8')
|
||||
for field in ('group', 'inviter', 'inviter_key', 'invitee', 'secret'):
|
||||
if field not in request.data:
|
||||
|
|
@ -135,7 +131,7 @@ class GroupInvitesIncoming(APIView, ViewSetMixin):
|
|||
@api_view(['DELETE'])
|
||||
@authentication_classes([SignatureAuthenticationLocal])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def declineGroupInvite(request, pk, format=None): # /api/groupinvites/<pk>/
|
||||
def declineGroupInvite(request, pk, format=None):
|
||||
get_object_or_404(request.user.group_invites_incoming, pk=pk).delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
|
@ -143,12 +139,7 @@ def declineGroupInvite(request, pk, format=None): # /api/groupinvites/<pk>/
|
|||
@api_view(['POST'])
|
||||
@authentication_classes([SignatureAuthenticationLocal])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def recordGroupMembership(request, pk, format=None): # /api/groupinvites/<pk>/accept/
|
||||
"""Local bookkeeping call on the invitee's own home backend, made by the client once its
|
||||
accept request against the group's home backend (acceptGroupInvite) has succeeded. Turns the
|
||||
now-obsolete GroupInviteIncoming into a durable GroupMembership pointer, so this backend
|
||||
remembers which foreign groups its own user belongs to -- the same way FriendRequestIncoming
|
||||
ends up recorded as a friend on both sides, not just the group's authoritative backend."""
|
||||
def recordGroupMembership(request, pk, format=None):
|
||||
invite = get_object_or_404(request.user.group_invites_incoming, pk=pk)
|
||||
membership, _ = GroupMembership.objects.get_or_create(
|
||||
user=request.user, group_name=invite.group_name, group_domain=invite.group_domain)
|
||||
|
|
@ -157,19 +148,16 @@ def recordGroupMembership(request, pk, format=None): # /api/groupinvites/<pk>/a
|
|||
|
||||
|
||||
class GroupMemberships(APIView, ViewSetMixin):
|
||||
"""/api/groupmemberships/ - the personal index of every group (local or remote) this backend
|
||||
has recorded the caller as belonging to, kept independently of the group's own membership
|
||||
roster (see GroupMembership and recordGroupMembership)."""
|
||||
authentication_classes = [SignatureAuthenticationLocal]
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, format=None): # /api/groupmemberships/
|
||||
def get(self, request, format=None):
|
||||
memberships = request.user.group_memberships.all()
|
||||
return Response(GroupMembershipSerializer(memberships, many=True).data)
|
||||
|
||||
|
||||
@api_view(['POST'])
|
||||
def acceptGroupInvite(request, format=None): # /api/group_invites/accept/ - lands on the group's home backend
|
||||
def acceptGroupInvite(request, format=None):
|
||||
raw_request = request.body.decode('utf-8')
|
||||
for field in ('group', 'invitee', 'invitee_key', 'secret'):
|
||||
if field not in request.data:
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class IdMap(APIView, ViewSetMixin):
|
|||
authentication_classes = [SignatureAuthentication]
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get(self, request, format=None): # /api/idmap/
|
||||
def get(self, request, format=None):
|
||||
identity = request.user
|
||||
identities = identity.friends.all() | KnownIdentity.objects.filter(pk=identity.pk)
|
||||
groups = identity.member_of_groups.all()
|
||||
|
|
|
|||
|
|
@ -7,20 +7,12 @@ from hostadmin.models import Domain
|
|||
from authentication.signature_auth import SignatureAuthentication
|
||||
from toolshed.models import Tag, Property, Category, InventoryItem
|
||||
from toolshed.serializers import CategorySerializer, PropertySerializer
|
||||
from backend.settings import TOOLSHED_VERSION, GIT_COMMIT
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
@permission_classes([])
|
||||
@authentication_classes([])
|
||||
def get_version(request, format=None): # /version/
|
||||
return Response({'version': TOOLSHED_VERSION, 'commit': GIT_COMMIT})
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
@permission_classes([])
|
||||
@authentication_classes([])
|
||||
def list_domains(request, format=None): # /domains/
|
||||
def list_domains(request, format=None):
|
||||
domains = [domain.name for domain in Domain.objects.filter(open_registration=True)]
|
||||
return Response(domains)
|
||||
|
||||
|
|
@ -28,7 +20,7 @@ def list_domains(request, format=None): # /domains/
|
|||
@api_view(['GET'])
|
||||
@permission_classes([IsAuthenticated])
|
||||
@authentication_classes([SignatureAuthentication])
|
||||
def list_tags(format=None): # /tags/
|
||||
def list_tags(format=None):
|
||||
tags = [tag.name for tag in Tag.objects.all()]
|
||||
return Response(tags)
|
||||
|
||||
|
|
@ -36,28 +28,28 @@ def list_tags(format=None): # /tags/
|
|||
@api_view(['GET'])
|
||||
@permission_classes([IsAuthenticated])
|
||||
@authentication_classes([SignatureAuthentication])
|
||||
def list_properties(request, format=None): # /properties/
|
||||
def list_properties(request, format=None):
|
||||
return Response(PropertySerializer(Property.objects.all(), many=True).data)
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
@permission_classes([IsAuthenticated])
|
||||
@authentication_classes([SignatureAuthentication])
|
||||
def list_categories(request, format=None): # /categories/
|
||||
def list_categories(request, format=None):
|
||||
return Response(CategorySerializer(Category.objects.all(), many=True).data)
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
@permission_classes([IsAuthenticated])
|
||||
@authentication_classes([SignatureAuthentication])
|
||||
def list_availability_policies(request, format=None): # /availability_policies/
|
||||
def list_availability_policies(request, format=None):
|
||||
return Response(InventoryItem.AVAILABILITY_POLICY_CHOICES)
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
@permission_classes([IsAuthenticated])
|
||||
@authentication_classes([SignatureAuthentication])
|
||||
def combined_info(request, format=None): # /info/
|
||||
def combined_info(request, format=None):
|
||||
tags = [tag.name for tag in Tag.objects.all()]
|
||||
properties = PropertySerializer(Property.objects.all(), many=True).data
|
||||
categories = [str(category) for category in Category.objects.all()]
|
||||
|
|
@ -69,7 +61,7 @@ def combined_info(request, format=None): # /info/
|
|||
|
||||
|
||||
urlpatterns = [
|
||||
path('version/', get_version, name='version'),
|
||||
|
||||
path('availability_policies/', list_availability_policies, name='availability_policies'),
|
||||
path('properties/', list_properties, name='propertylist'),
|
||||
path('categories/', list_categories, name='categorylist'),
|
||||
|
|
|
|||
17
backend/toolshed/api/version.py
Normal file
17
backend/toolshed/api/version.py
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
from django.urls import path
|
||||
from rest_framework.decorators import api_view, permission_classes, authentication_classes
|
||||
from rest_framework.response import Response
|
||||
|
||||
from backend.settings import TOOLSHED_VERSION, GIT_COMMIT
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
@permission_classes([])
|
||||
@authentication_classes([])
|
||||
def get_api_version(request, format=None):
|
||||
return Response({'version': TOOLSHED_VERSION, 'commit': GIT_COMMIT})
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path('', get_api_version, name='version'),
|
||||
]
|
||||
|
|
@ -27,31 +27,31 @@ class CombinedApiTestCase(UserTestMixin, CategoryTestMixin, TagTestMixin, Proper
|
|||
self.assertEqual(response.json(), {'version': settings.TOOLSHED_VERSION, 'commit': settings.GIT_COMMIT})
|
||||
|
||||
def test_domains_anonymous(self):
|
||||
response = anonymous_client.get('/api/domains/')
|
||||
response = anonymous_client.get('/api/v1/domains/')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.json(), ['example.com'])
|
||||
|
||||
def test_domains_authenticated(self):
|
||||
response = client.get('/api/domains/', self.f['local_user1'])
|
||||
response = client.get('/api/v1/domains/', self.f['local_user1'])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.json(), ['example.com'])
|
||||
|
||||
def test_policy_api_anonymous(self):
|
||||
response = anonymous_client.get('/api/availability_policies/')
|
||||
response = anonymous_client.get('/api/v1/availability_policies/')
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_policy_api(self):
|
||||
response = client.get('/api/availability_policies/', self.f['local_user1'])
|
||||
response = client.get('/api/v1/availability_policies/', self.f['local_user1'])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.json(), [['sell', 'Sell'], ['rent', 'Rent'], ['lend', 'Lend'], ['share', 'Share'],
|
||||
['private', 'Private']])
|
||||
|
||||
def test_combined_api_anonymous(self):
|
||||
response = anonymous_client.get('/api/info/')
|
||||
response = anonymous_client.get('/api/v1/info/')
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_combined_api(self):
|
||||
response = client.get('/api/info/', self.f['local_user1'])
|
||||
response = client.get('/api/v1/info/', self.f['local_user1'])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.json()['availability_policies'], [['sell', 'Sell'], ['rent', 'Rent'], ['lend', 'Lend'],
|
||||
['share', 'Share'], ['private', 'Private']])
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class CategoryApiTestCase(CategoryTestMixin, UserTestMixin, ToolshedTestCase):
|
|||
self.prepare_categories()
|
||||
|
||||
def test_get_categories(self):
|
||||
reply = client.get('/api/categories/', self.f['local_user1'])
|
||||
reply = client.get('/api/v1/categories/', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 7)
|
||||
self.assertEqual(reply.json()[0], 'cat1')
|
||||
|
|
|
|||
|
|
@ -25,11 +25,11 @@ class FileApiTestCase(UserTestMixin, FilesTestMixin, InventoryTestMixin, Toolshe
|
|||
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}/")
|
||||
response = anonymous_client.get(f"/api/v1/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'])
|
||||
response = client.get(f"/api/v1/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')
|
||||
|
|
@ -40,7 +40,7 @@ class FileApiTestCase(UserTestMixin, FilesTestMixin, InventoryTestMixin, Toolshe
|
|||
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'])
|
||||
response = client.get(f"/api/v1/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')
|
||||
|
|
@ -51,11 +51,11 @@ class FileApiTestCase(UserTestMixin, FilesTestMixin, InventoryTestMixin, Toolshe
|
|||
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'])
|
||||
response = client.get(f"/api/v1/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'],
|
||||
response = client.post(f"/api/v1/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)
|
||||
|
|
@ -68,7 +68,7 @@ class FileApiTestCase(UserTestMixin, FilesTestMixin, InventoryTestMixin, Toolshe
|
|||
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'],
|
||||
response = client.post(f"/api/v1/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)
|
||||
|
|
@ -79,69 +79,69 @@ class FileApiTestCase(UserTestMixin, FilesTestMixin, InventoryTestMixin, Toolshe
|
|||
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'],
|
||||
response = client.post(f"/api/v1/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'],
|
||||
response = client.post(f"/api/v1/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}/",
|
||||
response = anonymous_client.post(f"/api/v1/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'],
|
||||
response = client.post(f"/api/v1/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}/",
|
||||
response = client.delete(f"/api/v1/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}/",
|
||||
response = client.delete(f"/api/v1/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'])
|
||||
response = client.delete(f"/api/v1/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'])
|
||||
response = client.delete(f"/api/v1/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}/",
|
||||
response = client.delete(f"/api/v1/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}/")
|
||||
response = anonymous_client.delete(f"/api/v1/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)
|
||||
|
||||
def test_get_inventory(self):
|
||||
reply = client.get('/api/inventory_items/{}/'.format(self.f['local_user1']), self.f['local_user1'])
|
||||
reply = client.get('/api/v1/inventory_items/{}/'.format(self.f['local_user1']), self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 2)
|
||||
self.assertEqual(reply.json()[0]['name'], 'test1')
|
||||
|
|
@ -171,46 +171,46 @@ class GroupOwnedFileApiTestCase(UserTestMixin, GroupTestMixin, FilesTestMixin, T
|
|||
self.f['group_item'].files.add(self.f['test_file1'])
|
||||
|
||||
def test_get_group_item_files(self):
|
||||
response = client.get(f"/api/item_files/{self.f['group_item'].id}/", self.f['local_user1'])
|
||||
response = client.get(f"/api/v1/item_files/{self.f['group_item'].id}/", self.f['local_user1'])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(response.json()), 1)
|
||||
|
||||
def test_other_member_can_post_file(self):
|
||||
response = client.post(f"/api/item_files/{self.f['group_item'].id}/", self.f['local_user2'],
|
||||
response = client.post(f"/api/v1/item_files/{self.f['group_item'].id}/", self.f['local_user2'],
|
||||
{'data': self.f['encoded_content4'], 'mime_type': 'text/plain'})
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertEqual(self.f['group_item'].files.count(), 2)
|
||||
|
||||
def test_remote_member_without_local_account_can_post_file(self):
|
||||
self.f['group1'].members.add(self.f['ext_user1'].public_identity)
|
||||
response = client.post(f"/api/item_files/{self.f['group_item'].id}/", self.f['ext_user1'],
|
||||
response = client.post(f"/api/v1/item_files/{self.f['group_item'].id}/", self.f['ext_user1'],
|
||||
{'data': self.f['encoded_content4'], 'mime_type': 'text/plain'})
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertEqual(self.f['group_item'].files.count(), 2)
|
||||
|
||||
def test_remote_member_without_local_account_can_get_files(self):
|
||||
self.f['group1'].members.add(self.f['ext_user1'].public_identity)
|
||||
response = client.get(f"/api/item_files/{self.f['group_item'].id}/", self.f['ext_user1'])
|
||||
response = client.get(f"/api/v1/item_files/{self.f['group_item'].id}/", self.f['ext_user1'])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_non_member_cannot_post_file(self):
|
||||
response = client.post(f"/api/item_files/{self.f['group_item'].id}/", self.f['ext_user1'],
|
||||
response = client.post(f"/api/v1/item_files/{self.f['group_item'].id}/", self.f['ext_user1'],
|
||||
{'data': self.f['encoded_content4'], 'mime_type': 'text/plain'})
|
||||
self.assertEqual(response.status_code, 404)
|
||||
self.assertEqual(self.f['group_item'].files.count(), 1)
|
||||
|
||||
def test_non_member_cannot_get_files(self):
|
||||
response = client.get(f"/api/item_files/{self.f['group_item'].id}/", self.f['ext_user1'])
|
||||
response = client.get(f"/api/v1/item_files/{self.f['group_item'].id}/", self.f['ext_user1'])
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_other_member_can_delete_file(self):
|
||||
response = client.delete(f"/api/item_files/{self.f['group_item'].id}/{self.f['test_file1'].id}/",
|
||||
response = client.delete(f"/api/v1/item_files/{self.f['group_item'].id}/{self.f['test_file1'].id}/",
|
||||
self.f['local_user2'])
|
||||
self.assertEqual(response.status_code, 204)
|
||||
self.assertEqual(self.f['group_item'].files.count(), 0)
|
||||
|
||||
def test_non_member_cannot_delete_file(self):
|
||||
response = client.delete(f"/api/item_files/{self.f['group_item'].id}/{self.f['test_file1'].id}/",
|
||||
response = client.delete(f"/api/v1/item_files/{self.f['group_item'].id}/{self.f['test_file1'].id}/",
|
||||
self.f['ext_user1'])
|
||||
self.assertEqual(response.status_code, 404)
|
||||
self.assertEqual(self.f['group_item'].files.count(), 1)
|
||||
|
|
@ -222,12 +222,12 @@ class GroupOwnedFileApiTestCase(UserTestMixin, GroupTestMixin, FilesTestMixin, T
|
|||
owner_group=group2, owned_quantity=1, name='group2-drill', availability_policy='private')
|
||||
self.assertEqual(self.f['group_item'].id, group2_item.id)
|
||||
|
||||
response = client.get(f"/api/item_files/{self.f['group_item'].id}/", self.f['local_user2'])
|
||||
response = client.get(f"/api/v1/item_files/{self.f['group_item'].id}/", self.f['local_user2'])
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_group_item_files_listed_in_all_files(self):
|
||||
response = client.get('/api/files/', self.f['local_user2'])
|
||||
response = client.get('/api/v1/files/', self.f['local_user2'])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(response.json()), 1)
|
||||
self.assertEqual(response.json()[0]['id'], self.f['test_file1'].id)
|
||||
|
|
|
|||
|
|
@ -60,26 +60,26 @@ class FriendApiTestCase(UserTestMixin, ToolshedTestCase):
|
|||
self.f['ext_user1'].friends.add(self.f['local_user1'].public_identity)
|
||||
|
||||
def test_friend_list_internal1(self):
|
||||
reply = client.get('/api/friends/', self.f['local_user1'])
|
||||
reply = client.get('/api/v1/friends/', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 2)
|
||||
self.assertEqual(reply.json()[0]['handle'], str(self.f['local_user2']))
|
||||
self.assertEqual(reply.json()[1]['handle'], str(self.f['ext_user1']))
|
||||
|
||||
def test_friend_list_internal2(self):
|
||||
reply = client.get('/api/friends/', self.f['local_user2'])
|
||||
reply = client.get('/api/v1/friends/', self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 1)
|
||||
self.assertEqual(reply.json()[0]['handle'], str(self.f['local_user1']))
|
||||
|
||||
def test_friend_list_external(self):
|
||||
reply = client.get('/api/friends/', self.f['ext_user1'])
|
||||
reply = client.get('/api/v1/friends/', self.f['ext_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 1)
|
||||
self.assertEqual(reply.json()[0]['handle'], str(self.f['local_user1']))
|
||||
|
||||
def test_friend_delete(self):
|
||||
reply = client.delete('/api/friends/{}/'.format(self.f['local_user2'].public_identity.id),
|
||||
reply = client.delete('/api/v1/friends/{}/'.format(self.f['local_user2'].public_identity.id),
|
||||
self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 204)
|
||||
self.assertEqual(self.f['local_user1'].friends.count(), 1)
|
||||
|
|
@ -101,29 +101,29 @@ class FriendRequestListTestCase(UserTestMixin, ToolshedTestCase):
|
|||
self.friendrequest1.save()
|
||||
|
||||
def test_friend_request_withouth_auth(self):
|
||||
reply = Client().get('/api/friendrequests/')
|
||||
reply = Client().get('/api/v1/friendrequests/')
|
||||
self.assertEqual(reply.status_code, 401)
|
||||
|
||||
def test_friend_request_empty(self):
|
||||
reply = client.get('/api/friendrequests/', self.f['local_user2'])
|
||||
reply = client.get('/api/v1/friendrequests/', self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(reply.json(), [])
|
||||
|
||||
def test_friend_request_list(self):
|
||||
reply = client.get('/api/friendrequests/', self.f['local_user1'])
|
||||
reply = client.get('/api/v1/friendrequests/', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 1)
|
||||
self.assertEqual(reply.json()[0]['befriender'], str(self.f['ext_user2']))
|
||||
self.assertEqual(reply.json()[0]['befriender_public_key'], self.f['ext_user2'].public_key())
|
||||
|
||||
def test_delete_friend_request(self):
|
||||
reply = client.delete('/api/friendrequests/{}/'.format(self.friendrequest1.id),
|
||||
reply = client.delete('/api/v1/friendrequests/{}/'.format(self.friendrequest1.id),
|
||||
self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 204)
|
||||
self.assertEqual(FriendRequestIncoming.objects.count(), 0)
|
||||
|
||||
def test_delete_friend_request_not_found(self):
|
||||
reply = client.delete('/api/friendrequests/999/', self.f['local_user1'])
|
||||
reply = client.delete('/api/v1/friendrequests/999/', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 404)
|
||||
self.assertEqual(FriendRequestIncoming.objects.count(), 1)
|
||||
|
||||
|
|
@ -140,7 +140,7 @@ class FriendRequestIncomingTestCase(UserTestMixin, ToolshedTestCase):
|
|||
def test_post_request(self):
|
||||
befriender = self.f['ext_user1']
|
||||
befriendee = self.f['local_user1']
|
||||
reply = client.post('/api/friendrequests/', befriender, {
|
||||
reply = client.post('/api/v1/friendrequests/', befriender, {
|
||||
'befriender': str(befriender),
|
||||
'befriender_key': befriender.public_key(),
|
||||
'befriendee': str(befriendee),
|
||||
|
|
@ -158,7 +158,7 @@ class FriendRequestIncomingTestCase(UserTestMixin, ToolshedTestCase):
|
|||
def test_post_request_local(self):
|
||||
befriender = self.f['local_user2']
|
||||
befriendee = self.f['local_user1']
|
||||
reply = client.post('/api/friendrequests/', befriender, {
|
||||
reply = client.post('/api/v1/friendrequests/', befriender, {
|
||||
'befriender': str(befriender),
|
||||
'befriendee': str(befriendee),
|
||||
# 'secret': 'secret2'
|
||||
|
|
@ -173,14 +173,14 @@ class FriendRequestIncomingTestCase(UserTestMixin, ToolshedTestCase):
|
|||
# self.assertEqual(incoming.secret, 'secret2')
|
||||
|
||||
def test_post_request_withouth_auth(self):
|
||||
reply = Client().post('/api/friendrequests/')
|
||||
reply = Client().post('/api/v1/friendrequests/')
|
||||
self.assertEqual(reply.status_code, 400)
|
||||
|
||||
def test_post_request_broken_header(self):
|
||||
befriender = self.f['ext_user1']
|
||||
befriendee = self.f['local_user1']
|
||||
broken_client = SignatureAuthClient(header_prefix='broken ')
|
||||
reply = broken_client.post('/api/friendrequests/', befriender, {
|
||||
reply = broken_client.post('/api/v1/friendrequests/', befriender, {
|
||||
'befriender': str(befriender),
|
||||
'befriender_key': befriender.public_key(),
|
||||
'befriendee': str(befriendee),
|
||||
|
|
@ -191,7 +191,7 @@ class FriendRequestIncomingTestCase(UserTestMixin, ToolshedTestCase):
|
|||
def test_post_request_missing_key(self):
|
||||
befriender = self.f['ext_user1']
|
||||
befriendee = self.f['local_user1']
|
||||
reply = client.post('/api/friendrequests/', befriender, {
|
||||
reply = client.post('/api/v1/friendrequests/', befriender, {
|
||||
'befriender': str(befriender),
|
||||
'befriendee': str(befriendee),
|
||||
'secret': 'secret2'
|
||||
|
|
@ -201,7 +201,7 @@ class FriendRequestIncomingTestCase(UserTestMixin, ToolshedTestCase):
|
|||
def test_post_request_missing_key_none(self):
|
||||
befriender = self.f['ext_user1']
|
||||
befriendee = self.f['local_user1']
|
||||
reply = client.post('/api/friendrequests/', befriender, {
|
||||
reply = client.post('/api/v1/friendrequests/', befriender, {
|
||||
'befriender': str(befriender),
|
||||
'befriendee': str(befriendee),
|
||||
'befriender_key': None,
|
||||
|
|
@ -212,7 +212,7 @@ class FriendRequestIncomingTestCase(UserTestMixin, ToolshedTestCase):
|
|||
def test_post_request_breaking_key(self):
|
||||
befriender = self.f['ext_user1']
|
||||
befriendee = self.f['local_user1']
|
||||
reply = client.post('/api/friendrequests/', befriender, {
|
||||
reply = client.post('/api/v1/friendrequests/', befriender, {
|
||||
'befriender': str(befriender),
|
||||
'befriendee': str(befriendee),
|
||||
'secret': 'secret2',
|
||||
|
|
@ -223,7 +223,7 @@ class FriendRequestIncomingTestCase(UserTestMixin, ToolshedTestCase):
|
|||
def test_post_request_wrong_befriender(self):
|
||||
befriender = self.f['ext_user1']
|
||||
befriendee = self.f['local_user1']
|
||||
reply = client.post('/api/friendrequests/', befriender, {
|
||||
reply = client.post('/api/v1/friendrequests/', befriender, {
|
||||
'befriender': str(self.f['local_user2']),
|
||||
'befriender_key': befriender.public_key(),
|
||||
'befriendee': str(befriendee),
|
||||
|
|
@ -235,7 +235,7 @@ class FriendRequestIncomingTestCase(UserTestMixin, ToolshedTestCase):
|
|||
befriender = self.f['ext_user1']
|
||||
befriendee = self.f['local_user1']
|
||||
bad_signature = SignatureAuthClient(bad_signature=True)
|
||||
reply = bad_signature.post('/api/friendrequests/', befriender, {
|
||||
reply = bad_signature.post('/api/v1/friendrequests/', befriender, {
|
||||
'befriender': str(befriender),
|
||||
'befriender_key': befriender.public_key(),
|
||||
'befriendee': str(befriendee),
|
||||
|
|
@ -246,7 +246,7 @@ class FriendRequestIncomingTestCase(UserTestMixin, ToolshedTestCase):
|
|||
def test_post_request_self(self):
|
||||
befriender = self.f['local_user1']
|
||||
befriendee = self.f['local_user1']
|
||||
reply = client.post('/api/friendrequests/', befriender, {
|
||||
reply = client.post('/api/v1/friendrequests/', befriender, {
|
||||
'befriender': str(befriender),
|
||||
'befriender_key': befriender.public_key(),
|
||||
'befriendee': str(befriendee),
|
||||
|
|
@ -257,7 +257,7 @@ class FriendRequestIncomingTestCase(UserTestMixin, ToolshedTestCase):
|
|||
def test_post_request_befreindee_not_found(self):
|
||||
befriender = self.f['ext_user1']
|
||||
befriendee = self.f['local_user1']
|
||||
reply = client.post('/api/friendrequests/', befriender, {
|
||||
reply = client.post('/api/v1/friendrequests/', befriender, {
|
||||
'befriender': str(befriender),
|
||||
'befriender_key': befriender.public_key(),
|
||||
'befriendee': 'nonexistent@' + befriendee.domain,
|
||||
|
|
@ -268,7 +268,7 @@ class FriendRequestIncomingTestCase(UserTestMixin, ToolshedTestCase):
|
|||
def test_post_request_missing_secret(self):
|
||||
befriender = self.f['ext_user1']
|
||||
befriendee = self.f['local_user1']
|
||||
reply = client.post('/api/friendrequests/', befriender, {
|
||||
reply = client.post('/api/v1/friendrequests/', befriender, {
|
||||
'befriender': str(befriender),
|
||||
'befriender_key': befriender.public_key(),
|
||||
'befriendee': str(befriendee)
|
||||
|
|
@ -281,7 +281,7 @@ class FriendRequestIncomingTestCase(UserTestMixin, ToolshedTestCase):
|
|||
request = FriendRequestIncoming.objects.filter(befriender_username=befriender.username,
|
||||
befriender_domain=befriender.domain,
|
||||
befriendee_user=befriendee).first()
|
||||
reply = client.post('/api/friends/', befriendee, {
|
||||
reply = client.post('/api/v1/friends/', befriendee, {
|
||||
'friend_request_id': request.id,
|
||||
'secret': request.secret
|
||||
})
|
||||
|
|
@ -294,7 +294,7 @@ class FriendRequestIncomingTestCase(UserTestMixin, ToolshedTestCase):
|
|||
request = FriendRequestIncoming.objects.filter(befriender_username=befriender.username,
|
||||
befriender_domain=befriender.domain,
|
||||
befriendee_user=befriendee).first()
|
||||
reply = client.post('/api/friends/', befriendee, {
|
||||
reply = client.post('/api/v1/friends/', befriendee, {
|
||||
'friend_request_id': request.id,
|
||||
'secret': request.secret
|
||||
})
|
||||
|
|
@ -304,7 +304,7 @@ class FriendRequestIncomingTestCase(UserTestMixin, ToolshedTestCase):
|
|||
def test_accept_request_not_found(self):
|
||||
befriender = self.f['ext_user2']
|
||||
befriendee = self.f['local_user1']
|
||||
reply = client.post('/api/friends/', befriendee, {
|
||||
reply = client.post('/api/v1/friends/', befriendee, {
|
||||
'friend_request_id': 999,
|
||||
'secret': 'secret1'
|
||||
})
|
||||
|
|
@ -326,7 +326,7 @@ class FriendRequestOutgoingTestCase(UserTestMixin, ToolshedTestCase):
|
|||
def test_post_outgoing_friend_request(self):
|
||||
befriender = self.f['local_user1']
|
||||
befriendee = self.f['ext_user1']
|
||||
reply = client.post('/api/friendrequests/', befriender, {
|
||||
reply = client.post('/api/v1/friendrequests/', befriender, {
|
||||
'befriender': str(befriender),
|
||||
'befriendee': str(befriendee),
|
||||
})
|
||||
|
|
@ -343,7 +343,7 @@ class FriendRequestOutgoingTestCase(UserTestMixin, ToolshedTestCase):
|
|||
def test_accept_request(self):
|
||||
befriender = self.f['ext_user1']
|
||||
befriendee = self.f['local_user2']
|
||||
reply = client.post('/api/friendrequests/', befriender, {
|
||||
reply = client.post('/api/v1/friendrequests/', befriender, {
|
||||
'befriender': str(befriender),
|
||||
'befriender_key': befriender.public_key(),
|
||||
'befriendee': str(befriendee),
|
||||
|
|
@ -367,12 +367,12 @@ class FriendRequestCombinedTestCase(UserTestMixin, ToolshedTestCase):
|
|||
def test_friend_request_combined(self):
|
||||
befriender = self.f['local_user1']
|
||||
befriendee = self.f['local_user2']
|
||||
reply1 = client.post('/api/friendrequests/', befriender, {
|
||||
reply1 = client.post('/api/v1/friendrequests/', befriender, {
|
||||
'befriender': str(befriender),
|
||||
'befriendee': str(befriendee),
|
||||
})
|
||||
secret = reply1.json()['secret']
|
||||
reply2 = client.post('/api/friendrequests/', befriender, {
|
||||
reply2 = client.post('/api/v1/friendrequests/', befriender, {
|
||||
'befriender': str(befriender),
|
||||
'befriender_key': befriender.public_key(),
|
||||
'befriendee': str(befriendee),
|
||||
|
|
@ -389,7 +389,7 @@ class FriendRequestCombinedTestCase(UserTestMixin, ToolshedTestCase):
|
|||
befriender = self.f['local_user1']
|
||||
befriendee = self.f['local_user2']
|
||||
befriender.friends.add(befriendee.public_identity)
|
||||
reply1 = client.post('/api/friendrequests/', befriender, {
|
||||
reply1 = client.post('/api/v1/friendrequests/', befriender, {
|
||||
'befriender': str(befriender),
|
||||
'befriendee': str(befriendee),
|
||||
})
|
||||
|
|
|
|||
|
|
@ -27,34 +27,34 @@ class GroupApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase):
|
|||
self.prepare_users()
|
||||
|
||||
def test_create_group(self):
|
||||
reply = client.post('/api/groups/', self.f['local_user1'], {'name': 'workshop'})
|
||||
reply = client.post('/api/v1/groups/', self.f['local_user1'], {'name': 'workshop'})
|
||||
self.assertEqual(reply.status_code, 201)
|
||||
group = Group.objects.get(name='workshop')
|
||||
self.assertEqual(group.domain, self.f['local_user1'].domain)
|
||||
self.assertTrue(group.is_member(self.f['local_user1'].public_identity))
|
||||
|
||||
def test_create_group_duplicate_name(self):
|
||||
client.post('/api/groups/', self.f['local_user1'], {'name': 'workshop'})
|
||||
reply = client.post('/api/groups/', self.f['local_user1'], {'name': 'workshop'})
|
||||
client.post('/api/v1/groups/', self.f['local_user1'], {'name': 'workshop'})
|
||||
reply = client.post('/api/v1/groups/', self.f['local_user1'], {'name': 'workshop'})
|
||||
self.assertEqual(reply.status_code, 409)
|
||||
|
||||
def test_create_group_missing_name(self):
|
||||
reply = client.post('/api/groups/', self.f['local_user1'], {})
|
||||
reply = client.post('/api/v1/groups/', self.f['local_user1'], {})
|
||||
self.assertEqual(reply.status_code, 400)
|
||||
|
||||
def test_list_groups(self):
|
||||
self.prepare_groups()
|
||||
reply = client.get('/api/groups/', self.f['local_user1'])
|
||||
reply = client.get('/api/v1/groups/', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 1)
|
||||
reply2 = client.get('/api/groups/', self.f['local_user2'])
|
||||
reply2 = client.get('/api/v1/groups/', self.f['local_user2'])
|
||||
self.assertEqual(reply2.status_code, 200)
|
||||
self.assertEqual(len(reply2.json()), 0)
|
||||
|
||||
def test_group_detail_member(self):
|
||||
self.prepare_groups()
|
||||
group = self.f['group1']
|
||||
reply = client.get('/api/groups/{}@{}/'.format(group.name, group.domain), self.f['local_user1'])
|
||||
reply = client.get('/api/v1/groups/{}@{}/'.format(group.name, group.domain), self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(reply.json()['handle'], str(group))
|
||||
self.assertEqual(len(reply.json()['members']), 1)
|
||||
|
|
@ -62,18 +62,18 @@ class GroupApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase):
|
|||
def test_group_detail_non_member(self):
|
||||
self.prepare_groups()
|
||||
group = self.f['group1']
|
||||
reply = client.get('/api/groups/{}@{}/'.format(group.name, group.domain), self.f['local_user2'])
|
||||
reply = client.get('/api/v1/groups/{}@{}/'.format(group.name, group.domain), self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 404)
|
||||
|
||||
def test_group_detail_no_such_group(self):
|
||||
reply = client.get('/api/groups/nonexistent@example.com/', self.f['local_user1'])
|
||||
reply = client.get('/api/v1/groups/nonexistent@example.com/', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 404)
|
||||
|
||||
def test_remove_member(self):
|
||||
self.prepare_groups()
|
||||
group = self.f['group1']
|
||||
group.members.add(self.f['local_user2'].public_identity)
|
||||
reply = client.delete('/api/groups/{}@{}/members/{}/'.format(
|
||||
reply = client.delete('/api/v1/groups/{}@{}/members/{}/'.format(
|
||||
group.name, group.domain, self.f['local_user2'].public_identity.id), self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 204)
|
||||
self.assertEqual(group.members.count(), 1)
|
||||
|
|
@ -81,7 +81,7 @@ class GroupApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase):
|
|||
def test_remove_last_member_blocked(self):
|
||||
self.prepare_groups()
|
||||
group = self.f['group1']
|
||||
reply = client.delete('/api/groups/{}@{}/members/{}/'.format(
|
||||
reply = client.delete('/api/v1/groups/{}@{}/members/{}/'.format(
|
||||
group.name, group.domain, self.f['local_user1'].public_identity.id), self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 400)
|
||||
self.assertEqual(group.members.count(), 1)
|
||||
|
|
@ -90,7 +90,7 @@ class GroupApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase):
|
|||
self.prepare_groups()
|
||||
group = self.f['group1']
|
||||
group.members.add(self.f['local_user2'].public_identity)
|
||||
reply = client.delete('/api/groups/{}@{}/members/{}/'.format(
|
||||
reply = client.delete('/api/v1/groups/{}@{}/members/{}/'.format(
|
||||
group.name, group.domain, self.f['local_user1'].public_identity.id), self.f['ext_user1'])
|
||||
self.assertEqual(reply.status_code, 404)
|
||||
self.assertEqual(group.members.count(), 2)
|
||||
|
|
@ -107,13 +107,13 @@ class GroupInviteApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase):
|
|||
inviter = self.f['local_user1']
|
||||
invitee = self.f['local_user2']
|
||||
|
||||
reply1 = client.post('/api/groups/{}@{}/invites/'.format(group.name, group.domain), inviter,
|
||||
reply1 = client.post('/api/v1/groups/{}@{}/invites/'.format(group.name, group.domain), inviter,
|
||||
{'invitee': str(invitee)})
|
||||
self.assertEqual(reply1.status_code, 201)
|
||||
secret = reply1.json()['secret']
|
||||
self.assertEqual(GroupInvite.objects.count(), 1)
|
||||
|
||||
reply2 = client.post('/api/groupinvites/', inviter, {
|
||||
reply2 = client.post('/api/v1/groupinvites/', inviter, {
|
||||
'group': str(group), 'inviter': str(inviter), 'inviter_key': inviter.public_key(),
|
||||
'invitee': str(invitee), 'secret': secret
|
||||
})
|
||||
|
|
@ -121,20 +121,20 @@ class GroupInviteApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase):
|
|||
incoming = GroupInviteIncoming.objects.get()
|
||||
self.assertEqual(incoming.invitee_user, invitee)
|
||||
|
||||
reply3 = client.get('/api/groupinvites/', invitee)
|
||||
reply3 = client.get('/api/v1/groupinvites/', invitee)
|
||||
self.assertEqual(reply3.status_code, 200)
|
||||
self.assertEqual(len(reply3.json()), 1)
|
||||
self.assertEqual(reply3.json()[0]['group'], str(group))
|
||||
self.assertEqual(reply3.json()[0]['inviter'], str(inviter))
|
||||
|
||||
reply4 = client.post('/api/group_invites/accept/', invitee, {
|
||||
reply4 = client.post('/api/v1/group_invites/accept/', invitee, {
|
||||
'group': str(group), 'invitee': str(invitee), 'invitee_key': invitee.public_key(), 'secret': secret
|
||||
})
|
||||
self.assertEqual(reply4.status_code, 201)
|
||||
self.assertTrue(group.is_member(invitee.public_identity))
|
||||
self.assertEqual(GroupInvite.objects.count(), 0)
|
||||
|
||||
reply5 = client.post('/api/groupinvites/{}/accept/'.format(incoming.id), invitee)
|
||||
reply5 = client.post('/api/v1/groupinvites/{}/accept/'.format(incoming.id), invitee)
|
||||
self.assertEqual(reply5.status_code, 201)
|
||||
self.assertEqual(reply5.json()['handle'], str(group))
|
||||
self.assertEqual(GroupInviteIncoming.objects.count(), 0)
|
||||
|
|
@ -144,7 +144,7 @@ class GroupInviteApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase):
|
|||
|
||||
def test_invite_non_member_denied(self):
|
||||
group = self.f['group1']
|
||||
reply = client.post('/api/groups/{}@{}/invites/'.format(group.name, group.domain), self.f['local_user2'],
|
||||
reply = client.post('/api/v1/groups/{}@{}/invites/'.format(group.name, group.domain), self.f['local_user2'],
|
||||
{'invitee': str(self.f['ext_user1'])})
|
||||
self.assertEqual(reply.status_code, 404)
|
||||
self.assertEqual(GroupInvite.objects.count(), 0)
|
||||
|
|
@ -152,7 +152,7 @@ class GroupInviteApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase):
|
|||
def test_invite_already_member(self):
|
||||
group = self.f['group1']
|
||||
group.members.add(self.f['local_user2'].public_identity)
|
||||
reply = client.post('/api/groups/{}@{}/invites/'.format(group.name, group.domain), self.f['local_user1'],
|
||||
reply = client.post('/api/v1/groups/{}@{}/invites/'.format(group.name, group.domain), self.f['local_user1'],
|
||||
{'invitee': str(self.f['local_user2'])})
|
||||
self.assertEqual(reply.status_code, 208)
|
||||
|
||||
|
|
@ -161,7 +161,7 @@ class GroupInviteApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase):
|
|||
group_name=self.f['group1'].name, group_domain=self.f['group1'].domain,
|
||||
inviter_username=self.f['local_user1'].username, inviter_domain=self.f['local_user1'].domain,
|
||||
invitee_user=self.f['local_user2'], secret='some-secret')
|
||||
reply = client.delete('/api/groupinvites/{}/'.format(invite.id), self.f['local_user2'])
|
||||
reply = client.delete('/api/v1/groupinvites/{}/'.format(invite.id), self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 204)
|
||||
self.assertEqual(GroupInviteIncoming.objects.count(), 0)
|
||||
|
||||
|
|
@ -169,8 +169,8 @@ class GroupInviteApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase):
|
|||
group = self.f['group1']
|
||||
inviter = self.f['local_user1']
|
||||
invitee = self.f['local_user2']
|
||||
client.post('/api/groups/{}@{}/invites/'.format(group.name, group.domain), inviter, {'invitee': str(invitee)})
|
||||
reply = client.post('/api/group_invites/accept/', invitee, {
|
||||
client.post('/api/v1/groups/{}@{}/invites/'.format(group.name, group.domain), inviter, {'invitee': str(invitee)})
|
||||
reply = client.post('/api/v1/group_invites/accept/', invitee, {
|
||||
'group': str(group), 'invitee': str(invitee), 'invitee_key': invitee.public_key(),
|
||||
'secret': 'not-the-right-secret'
|
||||
})
|
||||
|
|
@ -181,11 +181,11 @@ class GroupInviteApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase):
|
|||
group = self.f['group1']
|
||||
inviter = self.f['local_user1']
|
||||
invitee = DummyExternalUser('newmember', 'remote.example', known=False)
|
||||
reply1 = client.post('/api/groups/{}@{}/invites/'.format(group.name, group.domain), inviter,
|
||||
reply1 = client.post('/api/v1/groups/{}@{}/invites/'.format(group.name, group.domain), inviter,
|
||||
{'invitee': str(invitee)})
|
||||
secret = reply1.json()['secret']
|
||||
|
||||
reply = client.post('/api/group_invites/accept/', invitee, {
|
||||
reply = client.post('/api/v1/group_invites/accept/', invitee, {
|
||||
'group': str(group), 'invitee': str(invitee), 'invitee_key': invitee.public_key(), 'secret': secret
|
||||
})
|
||||
self.assertEqual(reply.status_code, 201)
|
||||
|
|
@ -199,11 +199,11 @@ class GroupInviteApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase):
|
|||
group = self.f['group1']
|
||||
inviter = self.f['local_user1']
|
||||
invitee = self.f['local_user2']
|
||||
reply1 = client.post('/api/groups/{}@{}/invites/'.format(group.name, group.domain), inviter,
|
||||
reply1 = client.post('/api/v1/groups/{}@{}/invites/'.format(group.name, group.domain), inviter,
|
||||
{'invitee': str(invitee)})
|
||||
secret = reply1.json()['secret']
|
||||
bad_signature_client = SignatureAuthClient(bad_signature=True)
|
||||
reply = bad_signature_client.post('/api/group_invites/accept/', invitee, {
|
||||
reply = bad_signature_client.post('/api/v1/group_invites/accept/', invitee, {
|
||||
'group': str(group), 'invitee': str(invitee), 'invitee_key': invitee.public_key(), 'secret': secret
|
||||
})
|
||||
self.assertEqual(reply.status_code, 401)
|
||||
|
|
@ -230,7 +230,7 @@ class GroupMembershipApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase
|
|||
inviter_username='someone', inviter_domain='other.example',
|
||||
invitee_user=invitee, secret='some-secret')
|
||||
|
||||
reply = client.post('/api/groupinvites/{}/accept/'.format(incoming.id), invitee)
|
||||
reply = client.post('/api/v1/groupinvites/{}/accept/'.format(incoming.id), invitee)
|
||||
|
||||
self.assertEqual(reply.status_code, 201)
|
||||
self.assertEqual(reply.json()['handle'], '#remoteworkshop@other.example')
|
||||
|
|
@ -245,7 +245,7 @@ class GroupMembershipApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase
|
|||
inviter_username='someone', inviter_domain='other.example',
|
||||
invitee_user=self.f['local_user2'], secret='some-secret')
|
||||
|
||||
reply = client.post('/api/groupinvites/{}/accept/'.format(incoming.id), self.f['local_user1'])
|
||||
reply = client.post('/api/v1/groupinvites/{}/accept/'.format(incoming.id), self.f['local_user1'])
|
||||
|
||||
self.assertEqual(reply.status_code, 404)
|
||||
self.assertEqual(GroupMembership.objects.count(), 0)
|
||||
|
|
@ -257,7 +257,7 @@ class GroupMembershipApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase
|
|||
inviter_username='someone', inviter_domain='other.example',
|
||||
invitee_user=self.f['local_user2'], secret='some-secret')
|
||||
|
||||
reply = client.delete('/api/groupinvites/{}/'.format(incoming.id), self.f['local_user2'])
|
||||
reply = client.delete('/api/v1/groupinvites/{}/'.format(incoming.id), self.f['local_user2'])
|
||||
|
||||
self.assertEqual(reply.status_code, 204)
|
||||
self.assertEqual(GroupMembership.objects.count(), 0)
|
||||
|
|
@ -273,7 +273,7 @@ class GroupMembershipApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase
|
|||
inviter_username='someone', inviter_domain='other.example',
|
||||
invitee_user=invitee, secret='some-secret')
|
||||
|
||||
reply = client.post('/api/groupinvites/{}/accept/'.format(incoming.id), invitee)
|
||||
reply = client.post('/api/v1/groupinvites/{}/accept/'.format(incoming.id), invitee)
|
||||
|
||||
self.assertEqual(reply.status_code, 201)
|
||||
self.assertEqual(GroupMembership.objects.filter(user=invitee).count(), 1)
|
||||
|
|
@ -283,12 +283,12 @@ class GroupMembershipApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase
|
|||
GroupMembership.objects.create(
|
||||
user=self.f['local_user1'], group_name='remoteworkshop', group_domain='other.example')
|
||||
|
||||
reply = client.get('/api/groupmemberships/', self.f['local_user1'])
|
||||
reply = client.get('/api/v1/groupmemberships/', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 1)
|
||||
self.assertEqual(reply.json()[0]['handle'], '#remoteworkshop@other.example')
|
||||
|
||||
reply2 = client.get('/api/groupmemberships/', self.f['local_user2'])
|
||||
reply2 = client.get('/api/v1/groupmemberships/', self.f['local_user2'])
|
||||
self.assertEqual(reply2.status_code, 200)
|
||||
self.assertEqual(len(reply2.json()), 0)
|
||||
|
||||
|
|
@ -296,7 +296,7 @@ class GroupMembershipApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase
|
|||
GroupMembership.objects.create(
|
||||
user=self.f['local_user1'], group_name='remoteworkshop', group_domain='other.example')
|
||||
|
||||
reply = client.get('/api/groupmemberships/', self.f['ext_user1'])
|
||||
reply = client.get('/api/v1/groupmemberships/', self.f['ext_user1'])
|
||||
|
||||
# authenticate() returns bare None (not raise) for a caller with no local ToolshedUser, so
|
||||
# DRF falls through to IsAuthenticated denying an anonymous request -- 403, not 401 (same
|
||||
|
|
|
|||
|
|
@ -13,40 +13,40 @@ class IdMapTestCase(UserTestMixin, GroupTestMixin, ToolshedTestCase):
|
|||
self.prepare_users()
|
||||
|
||||
def test_idmap_includes_self(self):
|
||||
reply = client.get('/api/idmap/', self.f['local_user1'])
|
||||
reply = client.get('/api/v1/idmap/', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
identities = reply.json()['identities']
|
||||
self.assertIn(str(self.f['local_user1']), [i['handle'] for i in identities])
|
||||
|
||||
def test_idmap_includes_friends(self):
|
||||
self.f['local_user1'].friends.add(self.f['local_user2'].public_identity)
|
||||
reply = client.get('/api/idmap/', self.f['local_user1'])
|
||||
reply = client.get('/api/v1/idmap/', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
identities = reply.json()['identities']
|
||||
self.assertIn(str(self.f['local_user2']), [i['handle'] for i in identities])
|
||||
|
||||
def test_idmap_excludes_non_friends(self):
|
||||
reply = client.get('/api/idmap/', self.f['local_user1'])
|
||||
reply = client.get('/api/v1/idmap/', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
identities = reply.json()['identities']
|
||||
self.assertNotIn(str(self.f['local_user2']), [i['handle'] for i in identities])
|
||||
|
||||
def test_idmap_includes_member_groups(self):
|
||||
self.prepare_groups()
|
||||
reply = client.get('/api/idmap/', self.f['local_user1'])
|
||||
reply = client.get('/api/v1/idmap/', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
groups = reply.json()['groups']
|
||||
self.assertIn(str(self.f['group1']), [g['handle'] for g in groups])
|
||||
|
||||
def test_idmap_excludes_non_member_groups(self):
|
||||
self.prepare_groups()
|
||||
reply = client.get('/api/idmap/', self.f['local_user2'])
|
||||
reply = client.get('/api/v1/idmap/', self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
groups = reply.json()['groups']
|
||||
self.assertNotIn(str(self.f['group1']), [g['handle'] for g in groups])
|
||||
|
||||
def test_idmap_unauthenticated(self):
|
||||
reply = Client().get('/api/idmap/')
|
||||
reply = Client().get('/api/v1/idmap/')
|
||||
self.assertEqual(reply.status_code, 403)
|
||||
|
||||
|
||||
|
|
@ -64,60 +64,60 @@ class ResolveShortIdApiTestCase(UserTestMixin, InventoryTestMixin, GroupTestMixi
|
|||
self.owner_id = self.f['local_user1'].public_identity.pk
|
||||
|
||||
def test_resolve_item_as_owner(self):
|
||||
reply = client.get(f'/api/resolve_short_id/item/{self.owner_id}/{self.f["item1"].id}/',
|
||||
reply = client.get(f'/api/v1/resolve_short_id/item/{self.owner_id}/{self.f["item1"].id}/',
|
||||
self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(reply.json(), {'handle': 'testuser1@example.com', 'id': self.f['item1'].id})
|
||||
|
||||
def test_resolve_item_as_friend(self):
|
||||
reply = client.get(f'/api/resolve_short_id/item/{self.owner_id}/{self.f["item1"].id}/',
|
||||
reply = client.get(f'/api/v1/resolve_short_id/item/{self.owner_id}/{self.f["item1"].id}/',
|
||||
self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
|
||||
def test_resolve_item_not_friend(self):
|
||||
reply = client.get(f'/api/resolve_short_id/item/{self.owner_id}/{self.f["item1"].id}/',
|
||||
reply = client.get(f'/api/v1/resolve_short_id/item/{self.owner_id}/{self.f["item1"].id}/',
|
||||
self.f['ext_user1'])
|
||||
self.assertEqual(reply.status_code, 403)
|
||||
|
||||
def test_resolve_item_private_not_owner(self):
|
||||
private_item = InventoryItem.create_for_owner(
|
||||
owner=self.f['local_user1'], owned_quantity=1, name='secret', availability_policy='private')
|
||||
reply = client.get(f'/api/resolve_short_id/item/{self.owner_id}/{private_item.id}/',
|
||||
reply = client.get(f'/api/v1/resolve_short_id/item/{self.owner_id}/{private_item.id}/',
|
||||
self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 403)
|
||||
reply = client.get(f'/api/resolve_short_id/item/{self.owner_id}/{private_item.id}/',
|
||||
reply = client.get(f'/api/v1/resolve_short_id/item/{self.owner_id}/{private_item.id}/',
|
||||
self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
|
||||
def test_resolve_item_unknown_owner(self):
|
||||
reply = client.get('/api/resolve_short_id/item/999999/1/', self.f['local_user2'])
|
||||
reply = client.get('/api/v1/resolve_short_id/item/999999/1/', self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 404)
|
||||
|
||||
def test_resolve_item_unknown_local_id(self):
|
||||
reply = client.get(f'/api/resolve_short_id/item/{self.owner_id}/999999/', self.f['local_user2'])
|
||||
reply = client.get(f'/api/v1/resolve_short_id/item/{self.owner_id}/999999/', self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 404)
|
||||
|
||||
def test_resolve_unsupported_kind(self):
|
||||
# workflow/category/file/group aren't wired up yet - see
|
||||
# docs/handles-and-shortids.md#domain-qualified-short-id's note on the remaining gap.
|
||||
reply = client.get(f'/api/resolve_short_id/workflow/{self.owner_id}/1/', self.f['local_user2'])
|
||||
reply = client.get(f'/api/v1/resolve_short_id/workflow/{self.owner_id}/1/', self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 400)
|
||||
|
||||
def test_resolve_storage_location_as_owner(self):
|
||||
reply = client.get(f'/api/resolve_short_id/storage_location/{self.owner_id}/{self.f["loc1"].id}/',
|
||||
reply = client.get(f'/api/v1/resolve_short_id/storage_location/{self.owner_id}/{self.f["loc1"].id}/',
|
||||
self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(reply.json(), {'handle': 'testuser1@example.com', 'id': self.f['loc1'].id})
|
||||
|
||||
def test_resolve_storage_location_unknown_local_id(self):
|
||||
reply = client.get(f'/api/resolve_short_id/storage_location/{self.owner_id}/999999/',
|
||||
reply = client.get(f'/api/v1/resolve_short_id/storage_location/{self.owner_id}/999999/',
|
||||
self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 404)
|
||||
|
||||
def test_resolve_group_item_as_member(self):
|
||||
item = InventoryItem.create_for_owner(
|
||||
owner_group=self.f['group1'], owned_quantity=1, name='drill', availability_policy='private')
|
||||
reply = client.get(f'/api/resolve_short_id/group_item/{self.f["group1"].pk}/{item.id}/',
|
||||
reply = client.get(f'/api/v1/resolve_short_id/group_item/{self.f["group1"].pk}/{item.id}/',
|
||||
self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(reply.json(), {'handle': str(self.f['group1']), 'id': item.id})
|
||||
|
|
@ -125,18 +125,18 @@ class ResolveShortIdApiTestCase(UserTestMixin, InventoryTestMixin, GroupTestMixi
|
|||
def test_resolve_group_item_non_member_denied(self):
|
||||
item = InventoryItem.create_for_owner(
|
||||
owner_group=self.f['group1'], owned_quantity=1, name='drill', availability_policy='private')
|
||||
reply = client.get(f'/api/resolve_short_id/group_item/{self.f["group1"].pk}/{item.id}/',
|
||||
reply = client.get(f'/api/v1/resolve_short_id/group_item/{self.f["group1"].pk}/{item.id}/',
|
||||
self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 403)
|
||||
|
||||
def test_resolve_group_storage_location_as_member(self):
|
||||
location = StorageLocation.create_for_owner(owner_group=self.f['group1'], name='shelf')
|
||||
reply = client.get(
|
||||
f'/api/resolve_short_id/group_storage_location/{self.f["group1"].pk}/{location.id}/',
|
||||
f'/api/v1/resolve_short_id/group_storage_location/{self.f["group1"].pk}/{location.id}/',
|
||||
self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(reply.json(), {'handle': str(self.f['group1']), 'id': location.id})
|
||||
|
||||
def test_resolve_unknown_group(self):
|
||||
reply = client.get('/api/resolve_short_id/group_item/999999/1/', self.f['local_user1'])
|
||||
reply = client.get('/api/v1/resolve_short_id/group_item/999999/1/', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 404)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
|||
self.own_handle = str(self.f['local_user1'])
|
||||
|
||||
def test_get_inventory(self):
|
||||
reply = client.get('/api/inventory_items/{}/'.format(self.own_handle), self.f['local_user1'])
|
||||
reply = client.get('/api/v1/inventory_items/{}/'.format(self.own_handle), self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 2)
|
||||
self.assertEqual(reply.json()[0]['name'], 'test1')
|
||||
|
|
@ -39,7 +39,7 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
|||
self.assertEqual(reply.json()[1]['availability_policy'], 'friends')
|
||||
|
||||
def test_post_new_item(self):
|
||||
reply = client.post('/api/inventory_items/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
reply = client.post('/api/v1/inventory_items/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
'availability_policy': 'rent',
|
||||
'category': 'cat2',
|
||||
'name': 'test3',
|
||||
|
|
@ -62,7 +62,7 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
|||
self.assertEqual([p.value for p in item.itemproperty_set.all()], ['value3', 'value4'])
|
||||
|
||||
def test_post_new_item2(self):
|
||||
reply = client.post('/api/inventory_items/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
reply = client.post('/api/v1/inventory_items/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
'availability_policy': 'share',
|
||||
'name': 'test3',
|
||||
'description': 'test',
|
||||
|
|
@ -81,7 +81,7 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
|||
self.assertEqual([p for p in item.properties.all()], [])
|
||||
|
||||
def test_post_new_item_empty(self):
|
||||
reply = client.post('/api/inventory_items/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
reply = client.post('/api/v1/inventory_items/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
'availability_policy': 'rent',
|
||||
'owned_quantity': 1,
|
||||
'image': '',
|
||||
|
|
@ -90,7 +90,7 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
|||
self.assertEqual(InventoryItem.objects.count(), 2)
|
||||
|
||||
def test_post_new_item3(self):
|
||||
reply = client.post('/api/inventory_items/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
reply = client.post('/api/v1/inventory_items/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
'availability_policy': 'private',
|
||||
'name': 'test3',
|
||||
'description': 'test',
|
||||
|
|
@ -110,7 +110,7 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
|||
self.assertEqual([p for p in item.properties.all()], [])
|
||||
|
||||
def test_put_item(self):
|
||||
reply = client.put('/api/inventory_items/{}/1/'.format(self.own_handle), self.f['local_user1'], {
|
||||
reply = client.put('/api/v1/inventory_items/{}/1/'.format(self.own_handle), self.f['local_user1'], {
|
||||
'availability_policy': 'sell',
|
||||
'name': 'test4',
|
||||
'description': 'new description',
|
||||
|
|
@ -133,7 +133,7 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
|||
self.assertEqual([p.value for p in item.itemproperty_set.all()], ['value5', 'value6', 'value7'])
|
||||
|
||||
def test_patch_item(self):
|
||||
reply = client.patch('/api/inventory_items/{}/1/'.format(self.own_handle), self.f['local_user1'], {
|
||||
reply = client.patch('/api/v1/inventory_items/{}/1/'.format(self.own_handle), self.f['local_user1'], {
|
||||
'description': 'new description2',
|
||||
'category': 'cat1',
|
||||
'owned_quantity': 100,
|
||||
|
|
@ -153,7 +153,7 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
|||
self.assertEqual([p.value for p in item.itemproperty_set.all()], ['value8'])
|
||||
|
||||
def test_patch_item2(self):
|
||||
reply = client.patch('/api/inventory_items/{}/1/'.format(self.own_handle), self.f['local_user1'], {
|
||||
reply = client.patch('/api/v1/inventory_items/{}/1/'.format(self.own_handle), self.f['local_user1'], {
|
||||
'description': 'new description2',
|
||||
'category': None,
|
||||
'owned_quantity': 100,
|
||||
|
|
@ -172,14 +172,14 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
|||
self.assertEqual([p for p in item.properties.all()], [])
|
||||
|
||||
def test_delete_item(self):
|
||||
reply = client.delete('/api/inventory_items/{}/1/'.format(self.own_handle), self.f['local_user1'])
|
||||
reply = client.delete('/api/v1/inventory_items/{}/1/'.format(self.own_handle), self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 204)
|
||||
self.assertEqual(InventoryItem.objects.count(), 1)
|
||||
self.assertEqual(InventoryItem.objects.get(id=2).name, 'test2')
|
||||
self.assertEqual(InventoryItem.objects.filter(name='test1').count(), 0)
|
||||
|
||||
def test_search_items(self):
|
||||
reply = client.get('/api/search/?query=test', self.f['local_user1'])
|
||||
reply = client.get('/api/v1/search/?query=test', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 2)
|
||||
self.assertEqual(reply.json()[0]['name'], 'test1')
|
||||
|
|
@ -199,31 +199,31 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
|||
self.assertEqual(reply.json()[1]['availability_policy'], 'friends')
|
||||
|
||||
def test_search_items2(self):
|
||||
reply = client.get('/api/search/?query=test', self.f['local_user2'])
|
||||
reply = client.get('/api/v1/search/?query=test', self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 2)
|
||||
self.assertEqual(reply.json()[0]['name'], 'test1')
|
||||
self.assertEqual(reply.json()[1]['name'], 'test2')
|
||||
|
||||
def test_search_items_fail(self):
|
||||
reply = client.get('/api/search/', self.f['local_user1'])
|
||||
reply = client.get('/api/v1/search/', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 400)
|
||||
self.assertEqual(reply.json()['error'], 'No query provided.')
|
||||
|
||||
def test_search_items_fail2(self):
|
||||
reply = client.get('/api/search/?query=test', self.f['ext_user1'])
|
||||
reply = client.get('/api/v1/search/?query=test', self.f['ext_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 0)
|
||||
|
||||
def test_get_shared_item_as_friend(self):
|
||||
reply = client.get('/api/inventory_items/testuser1@example.com/' + str(self.f['item1'].id) + '/',
|
||||
reply = client.get('/api/v1/inventory_items/testuser1@example.com/' + str(self.f['item1'].id) + '/',
|
||||
self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(reply.json()['name'], 'test1')
|
||||
self.assertEqual(reply.json()['owner'], 'testuser1@example.com')
|
||||
|
||||
def test_get_shared_item_as_owner(self):
|
||||
reply = client.get('/api/inventory_items/testuser1@example.com/' + str(self.f['item1'].id) + '/',
|
||||
reply = client.get('/api/v1/inventory_items/testuser1@example.com/' + str(self.f['item1'].id) + '/',
|
||||
self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(reply.json()['name'], 'test1')
|
||||
|
|
@ -232,31 +232,31 @@ class InventoryApiTestCase(UserTestMixin, InventoryTestMixin, ToolshedTestCase):
|
|||
# Non-visible resolves the same way a non-member's group access does now (see
|
||||
# GroupOwnedInventoryApiTestCase.test_non_member_cannot_see_or_edit) - 404, not a
|
||||
# separate 403 special case for "not a friend".
|
||||
reply = client.get('/api/inventory_items/testuser1@example.com/' + str(self.f['item1'].id) + '/',
|
||||
reply = client.get('/api/v1/inventory_items/testuser1@example.com/' + str(self.f['item1'].id) + '/',
|
||||
self.f['ext_user1'])
|
||||
self.assertEqual(reply.status_code, 404)
|
||||
|
||||
def test_get_shared_item_private(self):
|
||||
private_item = InventoryItem.create_for_owner(
|
||||
owner=self.f['local_user1'], owned_quantity=1, name='secret', availability_policy='private')
|
||||
reply = client.get('/api/inventory_items/testuser1@example.com/' + str(private_item.id) + '/',
|
||||
reply = client.get('/api/v1/inventory_items/testuser1@example.com/' + str(private_item.id) + '/',
|
||||
self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 404)
|
||||
reply = client.get('/api/inventory_items/testuser1@example.com/' + str(private_item.id) + '/',
|
||||
reply = client.get('/api/v1/inventory_items/testuser1@example.com/' + str(private_item.id) + '/',
|
||||
self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
|
||||
def test_get_shared_item_unknown_handle(self):
|
||||
reply = client.get('/api/inventory_items/nobody@example.com/' + str(self.f['item1'].id) + '/',
|
||||
reply = client.get('/api/v1/inventory_items/nobody@example.com/' + str(self.f['item1'].id) + '/',
|
||||
self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 404)
|
||||
|
||||
def test_get_shared_item_unknown_id(self):
|
||||
reply = client.get('/api/inventory_items/testuser1@example.com/99999/', self.f['local_user2'])
|
||||
reply = client.get('/api/v1/inventory_items/testuser1@example.com/99999/', self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 404)
|
||||
|
||||
def test_get_shared_item_bad_handle(self):
|
||||
reply = client.get('/api/inventory_items/testuser1/' + str(self.f['item1'].id) + '/', self.f['local_user2'])
|
||||
reply = client.get('/api/v1/inventory_items/testuser1/' + str(self.f['item1'].id) + '/', self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 400)
|
||||
|
||||
|
||||
|
|
@ -272,7 +272,7 @@ class TestInventoryItemWithFileApiTestCase(UserTestMixin, FilesTestMixin, Invent
|
|||
self.own_handle = str(self.f['local_user1'])
|
||||
|
||||
def test_post_item_with_file_id(self):
|
||||
reply = client.post('/api/inventory_items/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
reply = client.post('/api/v1/inventory_items/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
'name': 'test4',
|
||||
'description': 'test',
|
||||
'category': 'cat1',
|
||||
|
|
@ -295,7 +295,7 @@ class TestInventoryItemWithFileApiTestCase(UserTestMixin, FilesTestMixin, Invent
|
|||
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/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
reply = client.post('/api/v1/inventory_items/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
'name': 'test4',
|
||||
'description': 'test',
|
||||
'category': 'cat1',
|
||||
|
|
@ -318,7 +318,7 @@ class TestInventoryItemWithFileApiTestCase(UserTestMixin, FilesTestMixin, Invent
|
|||
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/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
reply = client.post('/api/v1/inventory_items/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
'name': 'test4',
|
||||
'description': 'test',
|
||||
'category': 'cat1',
|
||||
|
|
@ -330,7 +330,7 @@ class TestInventoryItemWithFileApiTestCase(UserTestMixin, FilesTestMixin, Invent
|
|||
self.assertEqual(reply.status_code, 400)
|
||||
|
||||
def test_post_item_with_encoded_file_fail(self):
|
||||
reply = client.post('/api/inventory_items/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
reply = client.post('/api/v1/inventory_items/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
'name': 'test4',
|
||||
'description': 'test',
|
||||
'category': 'cat1',
|
||||
|
|
@ -357,7 +357,7 @@ class GroupOwnedInventoryApiTestCase(UserTestMixin, GroupTestMixin, CategoryTest
|
|||
self.group_handle = '+' + str(self.f['group1'])[1:]
|
||||
|
||||
def create_group_item(self, name='drill'):
|
||||
return client.post('/api/inventory_items/{}/'.format(self.group_handle), self.f['local_user1'], {
|
||||
return client.post('/api/v1/inventory_items/{}/'.format(self.group_handle), self.f['local_user1'], {
|
||||
'name': name, 'owned_quantity': 1, 'availability_policy': 'private',
|
||||
})
|
||||
|
||||
|
|
@ -371,7 +371,7 @@ class GroupOwnedInventoryApiTestCase(UserTestMixin, GroupTestMixin, CategoryTest
|
|||
self.assertIsNone(reply.json()['owner'])
|
||||
|
||||
def test_create_group_owned_item_non_member_denied(self):
|
||||
reply = client.post('/api/inventory_items/{}/'.format(self.group_handle), self.f['ext_user1'], {
|
||||
reply = client.post('/api/v1/inventory_items/{}/'.format(self.group_handle), self.f['ext_user1'], {
|
||||
'name': 'drill', 'owned_quantity': 1, 'availability_policy': 'private',
|
||||
})
|
||||
self.assertEqual(reply.status_code, 403)
|
||||
|
|
@ -379,7 +379,7 @@ class GroupOwnedInventoryApiTestCase(UserTestMixin, GroupTestMixin, CategoryTest
|
|||
|
||||
def test_other_member_can_edit(self):
|
||||
item_id = self.create_group_item().json()['id']
|
||||
reply = client.patch('/api/inventory_items/{}/{}/'.format(self.group_handle, item_id), self.f['local_user2'], {
|
||||
reply = client.patch('/api/v1/inventory_items/{}/{}/'.format(self.group_handle, item_id), self.f['local_user2'], {
|
||||
'name': 'drill-renamed'
|
||||
})
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
|
|
@ -387,20 +387,20 @@ class GroupOwnedInventoryApiTestCase(UserTestMixin, GroupTestMixin, CategoryTest
|
|||
|
||||
def test_other_member_can_delete(self):
|
||||
item_id = self.create_group_item().json()['id']
|
||||
reply = client.delete('/api/inventory_items/{}/{}/'.format(self.group_handle, item_id), self.f['local_user2'])
|
||||
reply = client.delete('/api/v1/inventory_items/{}/{}/'.format(self.group_handle, item_id), self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 204)
|
||||
self.assertEqual(InventoryItem.objects.filter(id=item_id).count(), 0)
|
||||
|
||||
def test_delete_group_item_when_id_collides_with_own_personal_item(self):
|
||||
own_handle = str(self.f['local_user2'])
|
||||
personal_reply = client.post('/api/inventory_items/{}/'.format(own_handle), self.f['local_user2'], {
|
||||
personal_reply = client.post('/api/v1/inventory_items/{}/'.format(own_handle), self.f['local_user2'], {
|
||||
'name': 'personal-drill', 'owned_quantity': 1, 'availability_policy': 'private',
|
||||
})
|
||||
self.assertEqual(personal_reply.json()['id'], 1)
|
||||
item_id = self.create_group_item().json()['id']
|
||||
self.assertEqual(item_id, 1)
|
||||
|
||||
reply = client.delete('/api/inventory_items/{}/{}/'.format(self.group_handle, item_id), self.f['local_user2'])
|
||||
reply = client.delete('/api/v1/inventory_items/{}/{}/'.format(self.group_handle, item_id), self.f['local_user2'])
|
||||
|
||||
self.assertEqual(reply.status_code, 204)
|
||||
self.assertEqual(InventoryItem.objects.filter(name='drill').count(), 0)
|
||||
|
|
@ -411,9 +411,9 @@ class GroupOwnedInventoryApiTestCase(UserTestMixin, GroupTestMixin, CategoryTest
|
|||
# items - not unauthorized just because .user.exists() is False.
|
||||
self.f['group1'].members.add(self.f['ext_user1'].public_identity)
|
||||
item_id = self.create_group_item().json()['id']
|
||||
reply = client.get('/api/inventory_items/{}/{}/'.format(self.group_handle, item_id), self.f['ext_user1'])
|
||||
reply = client.get('/api/v1/inventory_items/{}/{}/'.format(self.group_handle, item_id), self.f['ext_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
reply = client.patch('/api/inventory_items/{}/{}/'.format(self.group_handle, item_id), self.f['ext_user1'], {
|
||||
reply = client.patch('/api/v1/inventory_items/{}/{}/'.format(self.group_handle, item_id), self.f['ext_user1'], {
|
||||
'name': 'drill-renamed-by-remote-member'
|
||||
})
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
|
|
@ -421,32 +421,32 @@ class GroupOwnedInventoryApiTestCase(UserTestMixin, GroupTestMixin, CategoryTest
|
|||
|
||||
def test_non_member_cannot_see_or_edit(self):
|
||||
item_id = self.create_group_item().json()['id']
|
||||
reply = client.get('/api/inventory_items/{}/{}/'.format(self.group_handle, item_id), self.f['ext_user1'])
|
||||
reply = client.get('/api/v1/inventory_items/{}/{}/'.format(self.group_handle, item_id), self.f['ext_user1'])
|
||||
self.assertEqual(reply.status_code, 404)
|
||||
|
||||
def test_group_items_excluded_from_personal_list(self):
|
||||
self.create_group_item()
|
||||
reply = client.get('/api/inventory_items/{}/'.format(str(self.f['local_user1'])), self.f['local_user1'])
|
||||
reply = client.get('/api/v1/inventory_items/{}/'.format(str(self.f['local_user1'])), self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 0)
|
||||
|
||||
def test_group_items_listed_by_owner_handle(self):
|
||||
self.create_group_item()
|
||||
reply = client.get('/api/inventory_items/{}/'.format(self.group_handle), self.f['local_user2'])
|
||||
reply = client.get('/api/v1/inventory_items/{}/'.format(self.group_handle), self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 1)
|
||||
self.assertEqual(reply.json()[0]['name'], 'drill')
|
||||
|
||||
def test_group_items_not_listed_for_non_member(self):
|
||||
self.create_group_item()
|
||||
reply = client.get('/api/inventory_items/{}/'.format(self.group_handle), self.f['ext_user1'])
|
||||
reply = client.get('/api/v1/inventory_items/{}/'.format(self.group_handle), self.f['ext_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 0)
|
||||
|
||||
def test_create_group_owned_item_with_full_fields(self):
|
||||
# Parity with InventoryApiTestCase.test_post_new_item: tags/properties/category attach
|
||||
# to a group-owned item the same way as a personal one.
|
||||
reply = client.post('/api/inventory_items/{}/'.format(self.group_handle), self.f['local_user1'], {
|
||||
reply = client.post('/api/v1/inventory_items/{}/'.format(self.group_handle), self.f['local_user1'], {
|
||||
'availability_policy': 'rent',
|
||||
'category': 'cat2',
|
||||
'name': 'drill',
|
||||
|
|
@ -468,21 +468,21 @@ class GroupOwnedInventoryApiTestCase(UserTestMixin, GroupTestMixin, CategoryTest
|
|||
|
||||
def test_create_group_owned_item_empty_fails(self):
|
||||
# Parity with InventoryApiTestCase.test_post_new_item_empty: clean()'s name-or-files validation still applies.
|
||||
reply = client.post('/api/inventory_items/{}/'.format(self.group_handle), self.f['local_user1'], {
|
||||
reply = client.post('/api/v1/inventory_items/{}/'.format(self.group_handle), self.f['local_user1'], {
|
||||
'availability_policy': 'private', 'owned_quantity': 1,
|
||||
})
|
||||
self.assertEqual(reply.status_code, 400)
|
||||
self.assertEqual(InventoryItem.objects.count(), 0)
|
||||
|
||||
def test_create_group_owned_item_nonexistent_group(self):
|
||||
reply = client.post('/api/inventory_items/+nonexistent@example.com/', self.f['local_user1'], {
|
||||
reply = client.post('/api/v1/inventory_items/+nonexistent@example.com/', self.f['local_user1'], {
|
||||
'name': 'drill', 'owned_quantity': 1, 'availability_policy': 'private',
|
||||
})
|
||||
self.assertEqual(reply.status_code, 404)
|
||||
self.assertEqual(InventoryItem.objects.count(), 0)
|
||||
|
||||
def test_group_items_listed_for_nonexistent_group(self):
|
||||
reply = client.get('/api/inventory_items/+nonexistent@example.com/', self.f['local_user1'])
|
||||
reply = client.get('/api/v1/inventory_items/+nonexistent@example.com/', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 0)
|
||||
|
||||
|
|
@ -490,7 +490,7 @@ class GroupOwnedInventoryApiTestCase(UserTestMixin, GroupTestMixin, CategoryTest
|
|||
# Parity with InventoryApiTestCase.test_put_item, but as a PUT by a different member than
|
||||
# the creator, to exercise the _is_authorized branch in perform_update for PUT too.
|
||||
item_id = self.create_group_item().json()['id']
|
||||
reply = client.put('/api/inventory_items/{}/{}/'.format(self.group_handle, item_id), self.f['local_user2'], {
|
||||
reply = client.put('/api/v1/inventory_items/{}/{}/'.format(self.group_handle, item_id), self.f['local_user2'], {
|
||||
'availability_policy': 'sell',
|
||||
'name': 'drill-4000',
|
||||
'description': 'new description',
|
||||
|
|
@ -510,12 +510,12 @@ class GroupOwnedInventoryApiTestCase(UserTestMixin, GroupTestMixin, CategoryTest
|
|||
|
||||
def test_patch_group_item_clears_fields(self):
|
||||
# Parity with InventoryApiTestCase.test_patch_item2 - clearing category/tags/properties.
|
||||
reply = client.post('/api/inventory_items/{}/'.format(self.group_handle), self.f['local_user1'], {
|
||||
reply = client.post('/api/v1/inventory_items/{}/'.format(self.group_handle), self.f['local_user1'], {
|
||||
'name': 'drill', 'owned_quantity': 1, 'availability_policy': 'private',
|
||||
'category': 'cat1', 'tags': ['tag1'],
|
||||
})
|
||||
item_id = reply.json()['id']
|
||||
reply = client.patch('/api/inventory_items/{}/{}/'.format(self.group_handle, item_id), self.f['local_user2'], {
|
||||
reply = client.patch('/api/v1/inventory_items/{}/{}/'.format(self.group_handle, item_id), self.f['local_user2'], {
|
||||
'category': None, 'tags': [], 'properties': []
|
||||
})
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
|
|
@ -524,7 +524,7 @@ class GroupOwnedInventoryApiTestCase(UserTestMixin, GroupTestMixin, CategoryTest
|
|||
self.assertEqual([t for t in item.tags.all()], [])
|
||||
|
||||
def test_group_item_storage_location(self):
|
||||
reply = client.post('/api/inventory_items/{}/'.format(self.group_handle), self.f['local_user1'], {
|
||||
reply = client.post('/api/v1/inventory_items/{}/'.format(self.group_handle), self.f['local_user1'], {
|
||||
'name': 'drill', 'owned_quantity': 1, 'availability_policy': 'private',
|
||||
'storage_location': self.f['loc1'].id,
|
||||
})
|
||||
|
|
@ -534,7 +534,7 @@ class GroupOwnedInventoryApiTestCase(UserTestMixin, GroupTestMixin, CategoryTest
|
|||
|
||||
def test_post_group_item_with_file_id(self):
|
||||
# Parity with TestInventoryItemWithFileApiTestCase.test_post_item_with_file_id.
|
||||
reply = client.post('/api/inventory_items/{}/'.format(self.group_handle), self.f['local_user1'], {
|
||||
reply = client.post('/api/v1/inventory_items/{}/'.format(self.group_handle), self.f['local_user1'], {
|
||||
'name': 'drill', 'owned_quantity': 1, 'availability_policy': 'private',
|
||||
'files': [self.f['test_file1'].id],
|
||||
})
|
||||
|
|
@ -543,7 +543,7 @@ class GroupOwnedInventoryApiTestCase(UserTestMixin, GroupTestMixin, CategoryTest
|
|||
self.assertEqual([f for f in item.files.all()], [self.f['test_file1']])
|
||||
|
||||
def test_post_group_item_with_encoded_file(self):
|
||||
reply = client.post('/api/inventory_items/{}/'.format(self.group_handle), self.f['local_user1'], {
|
||||
reply = client.post('/api/v1/inventory_items/{}/'.format(self.group_handle), self.f['local_user1'], {
|
||||
'name': 'drill', 'owned_quantity': 1, 'availability_policy': 'private',
|
||||
'files': [{'data': self.f['encoded_content3'], 'mime_type': 'text/plain'}],
|
||||
})
|
||||
|
|
@ -556,7 +556,7 @@ class GroupOwnedInventoryApiTestCase(UserTestMixin, GroupTestMixin, CategoryTest
|
|||
# docs/design-in-progress/groups-mvp.md) - search must not surface them either.
|
||||
self.create_group_item(name='searchable-drill')
|
||||
InventoryItem.create_for_owner(owner=self.f['local_user1'], owned_quantity=1, name='searchable-personal')
|
||||
reply = client.get('/api/search/?query=searchable', self.f['local_user1'])
|
||||
reply = client.get('/api/v1/search/?query=searchable', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
names = [item['name'] for item in reply.json()]
|
||||
self.assertEqual(names, ['searchable-personal'])
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class LocationApiTestCase(UserTestMixin, InventoryTestMixin, LocationTestMixin,
|
|||
self.assertEqual(self.f['loc1'], self.f['loc4'].parent)
|
||||
|
||||
def test_get_inventory(self):
|
||||
reply = client.get('/api/inventory_items/{}/'.format(self.own_handle), self.f['local_user1'])
|
||||
reply = client.get('/api/v1/inventory_items/{}/'.format(self.own_handle), self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 2)
|
||||
self.assertEqual(reply.json()[0]['name'], 'test1')
|
||||
|
|
@ -51,7 +51,7 @@ class LocationApiTestCase(UserTestMixin, InventoryTestMixin, LocationTestMixin,
|
|||
self.assertEqual(reply.json()[1]['availability_policy'], 'friends')
|
||||
|
||||
def test_get_inventory_item(self):
|
||||
reply = client.get('/api/storage_locations/{}/'.format(self.own_handle), self.f['local_user1'])
|
||||
reply = client.get('/api/v1/storage_locations/{}/'.format(self.own_handle), self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 4)
|
||||
self.assertEqual(reply.json()[0]['name'], 'loc1')
|
||||
|
|
@ -72,7 +72,7 @@ class LocationApiTestCase(UserTestMixin, InventoryTestMixin, LocationTestMixin,
|
|||
self.assertEqual(reply.json()[3]['path'], 'loc1/loc4')
|
||||
|
||||
def test_post_new_location(self):
|
||||
reply = client.post('/api/storage_locations/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
reply = client.post('/api/v1/storage_locations/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
'name': 'loc5',
|
||||
'description': 'a new location',
|
||||
})
|
||||
|
|
@ -85,7 +85,7 @@ class LocationApiTestCase(UserTestMixin, InventoryTestMixin, LocationTestMixin,
|
|||
self.assertEqual(reply.json()['path'], 'loc5')
|
||||
|
||||
def test_post_new_nested_location(self):
|
||||
reply = client.post('/api/storage_locations/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
reply = client.post('/api/v1/storage_locations/{}/'.format(self.own_handle), self.f['local_user1'], {
|
||||
'name': 'loc5',
|
||||
'parent': self.f['loc3'].id,
|
||||
})
|
||||
|
|
@ -96,7 +96,7 @@ class LocationApiTestCase(UserTestMixin, InventoryTestMixin, LocationTestMixin,
|
|||
|
||||
def test_patch_location(self):
|
||||
reply = client.patch(
|
||||
'/api/storage_locations/{}/{}/'.format(self.own_handle, self.f['loc2'].id), self.f['local_user1'], {
|
||||
'/api/v1/storage_locations/{}/{}/'.format(self.own_handle, self.f['loc2'].id), self.f['local_user1'], {
|
||||
'name': 'loc2-renamed',
|
||||
'parent': self.f['loc1'].id,
|
||||
})
|
||||
|
|
@ -108,7 +108,7 @@ class LocationApiTestCase(UserTestMixin, InventoryTestMixin, LocationTestMixin,
|
|||
|
||||
def test_delete_location(self):
|
||||
reply = client.delete(
|
||||
'/api/storage_locations/{}/{}/'.format(self.own_handle, self.f['loc4'].id), self.f['local_user1'])
|
||||
'/api/v1/storage_locations/{}/{}/'.format(self.own_handle, self.f['loc4'].id), self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 204)
|
||||
self.assertEqual(StorageLocation.objects.count(), 3)
|
||||
self.assertEqual(StorageLocation.objects.filter(id=self.f['loc4'].id).count(), 0)
|
||||
|
|
@ -117,14 +117,14 @@ class LocationApiTestCase(UserTestMixin, InventoryTestMixin, LocationTestMixin,
|
|||
item = InventoryItem.create_for_owner(
|
||||
owner=self.f['local_user1'], name='located_item', storage_location=self.f['loc3'])
|
||||
reply = client.delete(
|
||||
'/api/storage_locations/{}/{}/'.format(self.own_handle, self.f['loc3'].id), self.f['local_user1'])
|
||||
'/api/v1/storage_locations/{}/{}/'.format(self.own_handle, self.f['loc3'].id), self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 204)
|
||||
item.refresh_from_db()
|
||||
self.assertIsNone(item.storage_location)
|
||||
self.assertEqual(InventoryItem.objects.filter(id=item.id).count(), 1)
|
||||
|
||||
def test_locations_are_owner_scoped(self):
|
||||
reply = client.get('/api/storage_locations/{}/'.format(str(self.f['local_user2'])), self.f['local_user2'])
|
||||
reply = client.get('/api/v1/storage_locations/{}/'.format(str(self.f['local_user2'])), self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 0)
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ class LocationApiTestCase(UserTestMixin, InventoryTestMixin, LocationTestMixin,
|
|||
# handle resolves and the location is visible - friends can read but never write, so this
|
||||
# is a 403 (found, not authorized), not a 404.
|
||||
reply = client.delete(
|
||||
'/api/storage_locations/{}/{}/'.format(self.own_handle, self.f['loc1'].id), self.f['local_user2'])
|
||||
'/api/v1/storage_locations/{}/{}/'.format(self.own_handle, self.f['loc1'].id), self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 403)
|
||||
self.assertEqual(StorageLocation.objects.filter(id=self.f['loc1'].id).count(), 1)
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ class GroupOwnedLocationApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestC
|
|||
self.group_handle = '+' + str(self.f['group1'])[1:]
|
||||
|
||||
def create_group_location(self, name='shelf'):
|
||||
return client.post('/api/storage_locations/{}/'.format(self.group_handle), self.f['local_user1'], {
|
||||
return client.post('/api/v1/storage_locations/{}/'.format(self.group_handle), self.f['local_user1'], {
|
||||
'name': name,
|
||||
})
|
||||
|
||||
|
|
@ -163,7 +163,7 @@ class GroupOwnedLocationApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestC
|
|||
self.assertIsNone(reply.json()['owner'])
|
||||
|
||||
def test_create_group_owned_location_non_member_denied(self):
|
||||
reply = client.post('/api/storage_locations/{}/'.format(self.group_handle), self.f['ext_user1'], {
|
||||
reply = client.post('/api/v1/storage_locations/{}/'.format(self.group_handle), self.f['ext_user1'], {
|
||||
'name': 'shelf',
|
||||
})
|
||||
self.assertEqual(reply.status_code, 403)
|
||||
|
|
@ -172,7 +172,7 @@ class GroupOwnedLocationApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestC
|
|||
def test_other_member_can_edit(self):
|
||||
location_id = self.create_group_location().json()['id']
|
||||
reply = client.patch(
|
||||
'/api/storage_locations/{}/{}/'.format(self.group_handle, location_id), self.f['local_user2'], {
|
||||
'/api/v1/storage_locations/{}/{}/'.format(self.group_handle, location_id), self.f['local_user2'], {
|
||||
'name': 'shelf-renamed'
|
||||
})
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
|
|
@ -181,7 +181,7 @@ class GroupOwnedLocationApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestC
|
|||
def test_other_member_can_delete(self):
|
||||
location_id = self.create_group_location().json()['id']
|
||||
reply = client.delete(
|
||||
'/api/storage_locations/{}/{}/'.format(self.group_handle, location_id), self.f['local_user2'])
|
||||
'/api/v1/storage_locations/{}/{}/'.format(self.group_handle, location_id), self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 204)
|
||||
self.assertEqual(StorageLocation.objects.filter(id=location_id).count(), 0)
|
||||
|
||||
|
|
@ -191,14 +191,14 @@ class GroupOwnedLocationApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestC
|
|||
# land on the same id. Every route being scoped by an explicit owner_handle - never a
|
||||
# bare, unscoped id - means this can no longer raise MultipleObjectsReturned.
|
||||
own_handle = str(self.f['local_user2'])
|
||||
personal_reply = client.post('/api/storage_locations/{}/'.format(own_handle), self.f['local_user2'],
|
||||
personal_reply = client.post('/api/v1/storage_locations/{}/'.format(own_handle), self.f['local_user2'],
|
||||
{'name': 'personal-shelf'})
|
||||
self.assertEqual(personal_reply.json()['id'], 1)
|
||||
location_id = self.create_group_location().json()['id']
|
||||
self.assertEqual(location_id, 1)
|
||||
|
||||
reply = client.delete(
|
||||
'/api/storage_locations/{}/{}/'.format(self.group_handle, location_id), self.f['local_user2'])
|
||||
'/api/v1/storage_locations/{}/{}/'.format(self.group_handle, location_id), self.f['local_user2'])
|
||||
|
||||
self.assertEqual(reply.status_code, 204)
|
||||
self.assertEqual(StorageLocation.objects.filter(name='shelf').count(), 0)
|
||||
|
|
@ -210,10 +210,10 @@ class GroupOwnedLocationApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestC
|
|||
self.f['group1'].members.add(self.f['ext_user1'].public_identity)
|
||||
location_id = self.create_group_location().json()['id']
|
||||
reply = client.get(
|
||||
'/api/storage_locations/{}/{}/'.format(self.group_handle, location_id), self.f['ext_user1'])
|
||||
'/api/v1/storage_locations/{}/{}/'.format(self.group_handle, location_id), self.f['ext_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
reply = client.patch(
|
||||
'/api/storage_locations/{}/{}/'.format(self.group_handle, location_id), self.f['ext_user1'], {
|
||||
'/api/v1/storage_locations/{}/{}/'.format(self.group_handle, location_id), self.f['ext_user1'], {
|
||||
'name': 'shelf-renamed-by-remote-member'
|
||||
})
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
|
|
@ -222,31 +222,31 @@ class GroupOwnedLocationApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestC
|
|||
def test_non_member_cannot_see_or_edit(self):
|
||||
location_id = self.create_group_location().json()['id']
|
||||
reply = client.get(
|
||||
'/api/storage_locations/{}/{}/'.format(self.group_handle, location_id), self.f['ext_user1'])
|
||||
'/api/v1/storage_locations/{}/{}/'.format(self.group_handle, location_id), self.f['ext_user1'])
|
||||
self.assertEqual(reply.status_code, 404)
|
||||
|
||||
def test_group_locations_excluded_from_personal_list(self):
|
||||
self.create_group_location()
|
||||
reply = client.get('/api/storage_locations/{}/'.format(str(self.f['local_user1'])), self.f['local_user1'])
|
||||
reply = client.get('/api/v1/storage_locations/{}/'.format(str(self.f['local_user1'])), self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 0)
|
||||
|
||||
def test_group_locations_listed_by_owner_handle(self):
|
||||
self.create_group_location()
|
||||
reply = client.get('/api/storage_locations/{}/'.format(self.group_handle), self.f['local_user2'])
|
||||
reply = client.get('/api/v1/storage_locations/{}/'.format(self.group_handle), self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 1)
|
||||
self.assertEqual(reply.json()[0]['name'], 'shelf')
|
||||
|
||||
def test_group_locations_not_listed_for_non_member(self):
|
||||
self.create_group_location()
|
||||
reply = client.get('/api/storage_locations/{}/'.format(self.group_handle), self.f['ext_user1'])
|
||||
reply = client.get('/api/v1/storage_locations/{}/'.format(self.group_handle), self.f['ext_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 0)
|
||||
|
||||
def test_group_location_can_be_parent_for_group_member(self):
|
||||
parent_id = self.create_group_location('shelf').json()['id']
|
||||
reply = client.post('/api/storage_locations/{}/'.format(self.group_handle), self.f['local_user2'], {
|
||||
reply = client.post('/api/v1/storage_locations/{}/'.format(self.group_handle), self.f['local_user2'], {
|
||||
'name': 'bin', 'parent': parent_id,
|
||||
})
|
||||
self.assertEqual(reply.status_code, 201)
|
||||
|
|
@ -259,7 +259,7 @@ class GroupOwnedLocationApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestC
|
|||
# InventoryItem.storage_location already had before group ownership existed here; not
|
||||
# something this feature narrows.
|
||||
personal = StorageLocation.create_for_owner(name='mine', owner=self.f['local_user1'])
|
||||
reply = client.post('/api/storage_locations/{}/'.format(self.group_handle), self.f['local_user1'], {
|
||||
reply = client.post('/api/v1/storage_locations/{}/'.format(self.group_handle), self.f['local_user1'], {
|
||||
'name': 'bin', 'parent': personal.id,
|
||||
})
|
||||
self.assertEqual(reply.status_code, 201)
|
||||
|
|
@ -267,7 +267,7 @@ class GroupOwnedLocationApiTestCase(UserTestMixin, GroupTestMixin, ToolshedTestC
|
|||
def test_group_location_not_valid_parent_for_non_member(self):
|
||||
parent_id = self.create_group_location('shelf').json()['id']
|
||||
reply = client.post(
|
||||
'/api/storage_locations/{}/'.format(str(self.f['ext_user1'])), self.f['ext_user1'], {
|
||||
'/api/v1/storage_locations/{}/'.format(str(self.f['ext_user1'])), self.f['ext_user1'], {
|
||||
'name': 'bin', 'parent': parent_id,
|
||||
})
|
||||
self.assertEqual(reply.status_code, 400)
|
||||
|
|
|
|||
|
|
@ -47,11 +47,11 @@ class _DeleteTestDataMixin(UserTestMixin, CategoryTestMixin, LocationTestMixin):
|
|||
class DeleteDataTestCase(_DeleteTestDataMixin, ToolshedTestCase):
|
||||
|
||||
def test_delete_data_anonymous(self):
|
||||
response = anonymous_client.delete('/api/account_data/')
|
||||
response = anonymous_client.delete('/api/v1/account_data/')
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_delete_data_removes_all_owned_data_but_keeps_account(self):
|
||||
response = client.delete('/api/account_data/', self.f['local_user1'])
|
||||
response = client.delete('/api/v1/account_data/', self.f['local_user1'])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
summary = response.json()
|
||||
|
|
@ -83,14 +83,14 @@ class DeleteDataTestCase(_DeleteTestDataMixin, ToolshedTestCase):
|
|||
class DeleteAccountTestCase(_DeleteTestDataMixin, ToolshedTestCase):
|
||||
|
||||
def test_delete_account_anonymous(self):
|
||||
response = anonymous_client.delete('/api/account/')
|
||||
response = anonymous_client.delete('/api/v1/account/')
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
def test_delete_account_removes_data_and_closes_account(self):
|
||||
user1_id = self.f['local_user1'].id
|
||||
identity_id = self.f['local_user1'].public_identity_id
|
||||
|
||||
response = client.delete('/api/account/', self.f['local_user1'])
|
||||
response = client.delete('/api/v1/account/', self.f['local_user1'])
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
summary = response.json()
|
||||
|
|
@ -219,7 +219,7 @@ class ImportInventoryPropertiesTestCase(UserTestMixin, CategoryTestMixin, TagTes
|
|||
|
||||
class ExportImportApiRoundTripTestCase(UserTestMixin, CategoryTestMixin, TagTestMixin, PropertyTestMixin,
|
||||
ToolshedTestCase):
|
||||
"""End-to-end coverage of the /api/export/ + /api/import/ endpoints (as actually used by clients), rather than calling the internal helper functions directly - this is what a real export/import round trip between two accounts looks like."""
|
||||
"""End-to-end coverage of the /api/v1/export/ + /api/v1/import/ endpoints (as actually used by clients), rather than calling the internal helper functions directly - this is what a real export/import round trip between two accounts looks like."""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
|
@ -238,11 +238,11 @@ class ExportImportApiRoundTripTestCase(UserTestMixin, CategoryTestMixin, TagTest
|
|||
ItemProperty.objects.create(inventory_item=item, property=self.f['prop1'], value='10cm, 20cm')
|
||||
ItemProperty.objects.create(inventory_item=item, property=self.f['prop2'], value='a=b')
|
||||
|
||||
export_reply = client.get('/api/export/', self.f['local_user1'])
|
||||
export_reply = client.get('/api/v1/export/', self.f['local_user1'])
|
||||
self.assertEqual(export_reply.status_code, 200)
|
||||
zip_bytes = export_reply.content
|
||||
|
||||
import_reply = client.post('/api/import/', self.f['local_user2'],
|
||||
import_reply = client.post('/api/v1/import/', self.f['local_user2'],
|
||||
{'zip': base64.b64encode(zip_bytes).decode('ascii')})
|
||||
self.assertEqual(import_reply.status_code, 200)
|
||||
summary = import_reply.json()
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class PropertyApiTestCase(PropertyTestMixin, CategoryTestMixin, UserTestMixin, T
|
|||
self.prepare_properties()
|
||||
|
||||
def test_get_properties(self):
|
||||
reply = client.get('/api/properties/', self.f['local_user1'])
|
||||
reply = client.get('/api/v1/properties/', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 3)
|
||||
self.assertEqual(reply.json()[0]['name'], 'prop1')
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class TagApiTestCase(TagTestMixin, CategoryTestMixin, UserTestMixin, ToolshedTes
|
|||
self.prepare_tags()
|
||||
|
||||
def test_get_tags(self):
|
||||
reply = client.get('/api/tags/', self.f['local_user1'])
|
||||
reply = client.get('/api/v1/tags/', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(len(reply.json()), 3)
|
||||
self.assertEqual(reply.json()[0], 'tag1')
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class WorkflowInstanceApiTestCase(UserTestMixin, WorkflowTestMixin, ToolshedTest
|
|||
|
||||
|
||||
def test_get_workflow_instances(self):
|
||||
reply = client.get('/api/workflows/', self.f['local_user1'])
|
||||
reply = client.get('/api/v1/workflows/', self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(len(reply.data), 3)
|
||||
self.assertEqual(reply.data[0]['name'], 'workflow1')
|
||||
|
|
@ -39,7 +39,7 @@ class WorkflowInstanceApiTestCase(UserTestMixin, WorkflowTestMixin, ToolshedTest
|
|||
|
||||
|
||||
def test_get_workflow_instances_user2(self):
|
||||
reply = client.get('/api/workflows/', self.f['local_user2'])
|
||||
reply = client.get('/api/v1/workflows/', self.f['local_user2'])
|
||||
self.assertEqual(reply.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(len(reply.data), 1)
|
||||
self.assertEqual(reply.data[0]['name'], 'workflow2')
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ from nacl.signing import SigningKey
|
|||
from json import dumps, loads
|
||||
|
||||
COMMANDS = {
|
||||
'getinventory': {'path': '/api/inventory_items/{handle}/', 'method': 'get'},
|
||||
'additem': {'path': '/api/inventory_items/{handle}/', 'method': 'post'},
|
||||
'delitem': {'path': '/api/inventory_items/{handle}/{internal_id}/', 'method': 'delete'},
|
||||
'getinventory': {'path': '/api/v1/inventory_items/{handle}/', 'method': 'get'},
|
||||
'additem': {'path': '/api/v1/inventory_items/{handle}/', 'method': 'post'},
|
||||
'delitem': {'path': '/api/v1/inventory_items/{handle}/{internal_id}/', 'method': 'delete'},
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ class ToolshedApi:
|
|||
|
||||
def get_raw(self, target):
|
||||
"""Like get(), but returns the raw response body instead of parsing it as JSON - for
|
||||
endpoints like /api/export/ that hand back a zip file, not a JSON document."""
|
||||
endpoints like /api/v1/export/ that hand back a zip file, not a JSON document."""
|
||||
response = self._send('GET', target)
|
||||
if not response.ok:
|
||||
raise ApiError("{} {} from {}: {}".format(
|
||||
|
|
@ -199,7 +199,7 @@ def build_request(api, spec, command, cmd_args, json_input):
|
|||
def run_command(api, cmd, cmd_args, json_input):
|
||||
if cmd == 'export':
|
||||
path = cmd_args[0] if cmd_args else 'toolshed-export.zip'
|
||||
data = api.get_raw("/api/export/")
|
||||
data = api.get_raw("/api/v1/export/")
|
||||
with open(path, 'wb') as f:
|
||||
f.write(data)
|
||||
return {'exported_to': path, 'bytes': len(data)}
|
||||
|
|
@ -209,7 +209,7 @@ def run_command(api, cmd, cmd_args, json_input):
|
|||
path = cmd_args[0]
|
||||
with open(path, 'rb') as f:
|
||||
data = f.read()
|
||||
return api.post("/api/import/", {"zip": base64.b64encode(data).decode('ascii')})
|
||||
return api.post("/api/v1/import/", {"zip": base64.b64encode(data).decode('ascii')})
|
||||
|
||||
command = COMMANDS.get(cmd)
|
||||
if command is None:
|
||||
|
|
|
|||
|
|
@ -579,7 +579,6 @@ export default {
|
|||
this.importError = null;
|
||||
const created_item_ids = [];
|
||||
const errors = [];
|
||||
// Each row is created via the same generic POST /api/inventory_items/ endpoint any client would use.
|
||||
for (const [index, row] of this.items.entries()) {
|
||||
if (!row.name) {
|
||||
errors.push(`Row ${index + 1}: missing required "name" field, skipped.`);
|
||||
|
|
|
|||
|
|
@ -395,7 +395,7 @@ export default createStore({
|
|||
},
|
||||
async fetchInventoryItems({state, commit, dispatch, getters}) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const items = await servers.get(getters.signAuth, '/api/inventory_items/' + state.user + '/')
|
||||
const items = await servers.get(getters.signAuth, '/api/v1/inventory_items/' + state.user + '/')
|
||||
items.map(item => item.files.map(file => file.owner = item.owner))
|
||||
commit('setInventoryItems', {url: '/', items})
|
||||
return items
|
||||
|
|
@ -407,7 +407,7 @@ export default createStore({
|
|||
const owner = item.owner_group ? encodeHandleForUrl(item.owner_group) : state.user
|
||||
const data = {availability_policy: 'private', ...item}
|
||||
delete data.owner_group
|
||||
const reply = await servers.post(getters.signAuth, '/api/inventory_items/' + owner + '/', data)
|
||||
const reply = await servers.post(getters.signAuth, '/api/v1/inventory_items/' + owner + '/', data)
|
||||
state.last_load.files = 0
|
||||
return reply
|
||||
},
|
||||
|
|
@ -418,28 +418,28 @@ export default createStore({
|
|||
const data = {availability_policy: 'friends', ...item}
|
||||
data.files = data.files.map(file => file.id)
|
||||
// Path is scoped by the owner's handle, not the item's own id domain - see docs/implementation.md#owner-handle-scoped-routes.
|
||||
const path = '/api/inventory_items/' + encodeHandleForUrl(item.owner_group || item.owner) + '/' + item.id + '/'
|
||||
const path = '/api/v1/inventory_items/' + encodeHandleForUrl(item.owner_group || item.owner) + '/' + item.id + '/'
|
||||
return await servers.patch(getters.signAuth, path, data)
|
||||
},
|
||||
async deleteInventoryItem({state, dispatch, getters}, item) {
|
||||
const servers = item.owner_group
|
||||
? await dispatch('getFriendServers', {username: 'x@' + splitGroupHandle(item.owner_group).domain})
|
||||
: await dispatch('getHomeServers')
|
||||
const path = '/api/inventory_items/' + encodeHandleForUrl(item.owner_group || item.owner) + '/' + item.id + '/'
|
||||
const path = '/api/v1/inventory_items/' + encodeHandleForUrl(item.owner_group || item.owner) + '/' + item.id + '/'
|
||||
const ret = await servers.delete(getters.signAuth, path)
|
||||
dispatch('fetchInventoryItems')
|
||||
return ret
|
||||
},
|
||||
async fetchSearchResults({state, commit, dispatch, getters}, {query}) {
|
||||
const servers = await dispatch('getAllKnownServers')
|
||||
const items = await servers.get(getters.signAuth, '/api/search/?query=' + query)
|
||||
const items = await servers.get(getters.signAuth, '/api/v1/search/?query=' + query)
|
||||
items.map(item => item.files.map(file => file.owner = item.owner))
|
||||
commit('setInventoryItems', {url: '/search/' + query, items})
|
||||
return items
|
||||
},
|
||||
async fetchFriends({commit, dispatch, getters, state}) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const data = await servers.get(getters.signAuth, '/api/friends/')
|
||||
const data = await servers.get(getters.signAuth, '/api/v1/friends/')
|
||||
commit('setFriends', data)
|
||||
return data
|
||||
},
|
||||
|
|
@ -461,7 +461,7 @@ export default createStore({
|
|||
try {
|
||||
const servers = await dispatch('getFriendServers', {username: owner});
|
||||
// owner is a full handle, looked up by owner not requester. See docs/implementation.md#owner-handle-scoped-routes.
|
||||
const item = await servers.get(getters.signAuth, '/api/inventory_items/' + owner + '/' + id + '/');
|
||||
const item = await servers.get(getters.signAuth, '/api/v1/inventory_items/' + owner + '/' + id + '/');
|
||||
if (item && item.files) {
|
||||
item.files.forEach(file => file.owner = item.owner)
|
||||
}
|
||||
|
|
@ -485,14 +485,14 @@ export default createStore({
|
|||
},
|
||||
async fetchFriendRequests({state, dispatch, getters}) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
return await servers.get(getters.signAuth, '/api/friendrequests/')
|
||||
return await servers.get(getters.signAuth, '/api/v1/friendrequests/')
|
||||
},
|
||||
async requestFriend({state, dispatch, getters}, {username}) {
|
||||
if (username in state.friends) {
|
||||
return true;
|
||||
}
|
||||
const home_servers = await dispatch('getHomeServers')
|
||||
const home_reply = await home_servers.post(getters.signAuth, '/api/friendrequests/', {
|
||||
const home_reply = await home_servers.post(getters.signAuth, '/api/v1/friendrequests/', {
|
||||
befriender: state.user,
|
||||
befriendee: username
|
||||
})
|
||||
|
|
@ -500,7 +500,7 @@ export default createStore({
|
|||
return false;
|
||||
|
||||
const befriendee_servers = await dispatch('getFriendServers', {username})
|
||||
const ext_reply = await befriendee_servers.post(getters.signAuth, '/api/friendrequests/', {
|
||||
const ext_reply = await befriendee_servers.post(getters.signAuth, '/api/v1/friendrequests/', {
|
||||
befriender: state.user,
|
||||
befriendee: username,
|
||||
befriender_key: nacl.to_hex(state.keypair.signPk),
|
||||
|
|
@ -510,11 +510,11 @@ export default createStore({
|
|||
},
|
||||
async acceptFriend({state, dispatch, getters}, {id, secret, befriender}) {
|
||||
const home_servers = await dispatch('getHomeServers')
|
||||
const home_reply = await home_servers.post(getters.signAuth, '/api/friends/', {
|
||||
const home_reply = await home_servers.post(getters.signAuth, '/api/v1/friends/', {
|
||||
friend_request_id: id, secret: secret
|
||||
})
|
||||
const ext_servers = await dispatch('getFriendServers', {username: befriender})
|
||||
const ext_reply = await ext_servers.post(getters.signAuth, '/api/friendrequests/', {
|
||||
const ext_reply = await ext_servers.post(getters.signAuth, '/api/v1/friendrequests/', {
|
||||
befriender: state.user,
|
||||
befriendee: befriender,
|
||||
befriender_key: nacl.to_hex(state.keypair.signPk),
|
||||
|
|
@ -524,21 +524,21 @@ export default createStore({
|
|||
},
|
||||
async declineFriend({state, dispatch, getters}, {id}) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
return await servers.delete(getters.signAuth, '/api/friendrequests/' + id + '/')
|
||||
return await servers.delete(getters.signAuth, '/api/v1/friendrequests/' + id + '/')
|
||||
},
|
||||
async dropFriend({state, dispatch, getters}, {id}) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
return await servers.delete(getters.signAuth, '/api/friends/' + id + '/')
|
||||
return await servers.delete(getters.signAuth, '/api/v1/friends/' + id + '/')
|
||||
},
|
||||
async fetchGroups({commit, dispatch, getters}) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const data = await servers.get(getters.signAuth, '/api/groups/')
|
||||
const data = await servers.get(getters.signAuth, '/api/v1/groups/')
|
||||
commit('setGroups', data)
|
||||
return data
|
||||
},
|
||||
async fetchIdMap({commit, dispatch, getters}) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const idmap = await servers.get(getters.signAuth, '/api/idmap/')
|
||||
const idmap = await servers.get(getters.signAuth, '/api/v1/idmap/')
|
||||
commit('setIdMap', idmap)
|
||||
return idmap
|
||||
},
|
||||
|
|
@ -546,7 +546,7 @@ export default createStore({
|
|||
async resolveShortId({dispatch, getters}, {domain, kind, ownerId, localId}) {
|
||||
try {
|
||||
const servers = await dispatch('getFriendServers', {username: 'x@' + domain})
|
||||
return await servers.get(getters.signAuth, `/api/resolve_short_id/${kind}/${ownerId}/${localId}/`)
|
||||
return await servers.get(getters.signAuth, `/api/v1/resolve_short_id/${kind}/${ownerId}/${localId}/`)
|
||||
} catch (error) {
|
||||
console.error(`Failed to resolve short id (${kind}, ${ownerId}, ${localId}) on ${domain}:`, error);
|
||||
return null;
|
||||
|
|
@ -556,27 +556,27 @@ export default createStore({
|
|||
async fetchGroup({dispatch, getters}, {handle}) {
|
||||
const {domain} = splitGroupHandle(handle)
|
||||
const servers = await dispatch('getFriendServers', {username: 'x@' + domain})
|
||||
return await servers.get(getters.signAuth, `/api/groups/${handle.slice(1)}/`)
|
||||
return await servers.get(getters.signAuth, `/api/v1/groups/${handle.slice(1)}/`)
|
||||
},
|
||||
async createGroup({dispatch, getters}, {name}) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
return await servers.post(getters.signAuth, '/api/groups/', {name})
|
||||
return await servers.post(getters.signAuth, '/api/v1/groups/', {name})
|
||||
},
|
||||
async removeGroupMember({dispatch, getters}, {groupHandle, identityId}) {
|
||||
const {domain} = splitGroupHandle(groupHandle)
|
||||
const servers = await dispatch('getFriendServers', {username: 'x@' + domain})
|
||||
return await servers.delete(
|
||||
getters.signAuth, '/api/groups/' + groupHandle.slice(1) + '/members/' + identityId + '/')
|
||||
getters.signAuth, '/api/v1/groups/' + groupHandle.slice(1) + '/members/' + identityId + '/')
|
||||
},
|
||||
async fetchGroupInvites({commit, dispatch, getters}) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const data = await servers.get(getters.signAuth, '/api/groupinvites/')
|
||||
const data = await servers.get(getters.signAuth, '/api/v1/groupinvites/')
|
||||
commit('setGroupInvites', data)
|
||||
return data
|
||||
},
|
||||
async fetchGroupMemberships({commit, dispatch, getters}) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const data = await servers.get(getters.signAuth, '/api/groupmemberships/')
|
||||
const data = await servers.get(getters.signAuth, '/api/v1/groupmemberships/')
|
||||
commit('setGroupMemberships', data)
|
||||
return data
|
||||
},
|
||||
|
|
@ -584,12 +584,12 @@ export default createStore({
|
|||
const {domain} = splitGroupHandle(groupHandle)
|
||||
const group_servers = await dispatch('getFriendServers', {username: 'x@' + domain})
|
||||
const group_reply = await group_servers.post(
|
||||
getters.signAuth, '/api/groups/' + groupHandle.slice(1) + '/invites/', {invitee})
|
||||
getters.signAuth, '/api/v1/groups/' + groupHandle.slice(1) + '/invites/', {invitee})
|
||||
if (!group_reply.secret) {
|
||||
return false
|
||||
}
|
||||
const invitee_servers = await dispatch('getFriendServers', {username: invitee})
|
||||
await invitee_servers.post(getters.signAuth, '/api/groupinvites/', {
|
||||
await invitee_servers.post(getters.signAuth, '/api/v1/groupinvites/', {
|
||||
group: groupHandle,
|
||||
inviter: state.user,
|
||||
inviter_key: nacl.to_hex(state.keypair.signPk),
|
||||
|
|
@ -601,24 +601,24 @@ export default createStore({
|
|||
async acceptGroupInvite({state, dispatch, getters}, invite) {
|
||||
const group_domain = invite.group.split('@')[1]
|
||||
const group_servers = await dispatch('getFriendServers', {username: 'x@' + group_domain})
|
||||
await group_servers.post(getters.signAuth, '/api/group_invites/accept/', {
|
||||
await group_servers.post(getters.signAuth, '/api/v1/group_invites/accept/', {
|
||||
group: invite.group,
|
||||
invitee: state.user,
|
||||
invitee_key: nacl.to_hex(state.keypair.signPk),
|
||||
secret: invite.secret
|
||||
})
|
||||
const home_servers = await dispatch('getHomeServers')
|
||||
await home_servers.post(getters.signAuth, '/api/groupinvites/' + invite.id + '/accept/', {})
|
||||
await home_servers.post(getters.signAuth, '/api/v1/groupinvites/' + invite.id + '/accept/', {})
|
||||
return true
|
||||
},
|
||||
async declineGroupInvite({dispatch, getters}, invite) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
return await servers.delete(getters.signAuth, '/api/groupinvites/' + invite.id + '/')
|
||||
return await servers.delete(getters.signAuth, '/api/v1/groupinvites/' + invite.id + '/')
|
||||
},
|
||||
async fetchGroupInventoryItems({commit, dispatch, getters}, {groupHandle}) {
|
||||
const {domain} = splitGroupHandle(groupHandle)
|
||||
const servers = await dispatch('getFriendServers', {username: 'x@' + domain})
|
||||
const items = await servers.get(getters.signAuth, '/api/inventory_items/' + encodeHandleForUrl(groupHandle) + '/')
|
||||
const items = await servers.get(getters.signAuth, '/api/v1/inventory_items/' + encodeHandleForUrl(groupHandle) + '/')
|
||||
// Keyed by the full handle, not a bare id: a group pk is only unique within its own
|
||||
// backend's database, so two different domains could otherwise collide on the same
|
||||
// item_map key - the handle already carries the domain, so no separate namespacing is needed.
|
||||
|
|
@ -630,7 +630,7 @@ export default createStore({
|
|||
return state.files
|
||||
}
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const data = await servers.get(getters.signAuth, '/api/files/')
|
||||
const data = await servers.get(getters.signAuth, '/api/v1/files/')
|
||||
data.map(file => file.owner = state.user)
|
||||
commit('setFiles', data)
|
||||
state.last_load.files = Date.now()
|
||||
|
|
@ -638,11 +638,11 @@ export default createStore({
|
|||
},
|
||||
async fetchFilesByItem({state, commit, dispatch, getters}, {id}) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
return await servers.get(getters.signAuth, '/api/item_files/' + id + '/')
|
||||
return await servers.get(getters.signAuth, '/api/v1/item_files/' + id + '/')
|
||||
},
|
||||
async pushFile({state, dispatch, getters}, {item_id, file}) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const data = await servers.post(getters.signAuth, '/api/item_files/' + item_id + '/', file)
|
||||
const data = await servers.post(getters.signAuth, '/api/v1/item_files/' + item_id + '/', file)
|
||||
if (data.name) {
|
||||
data.owner = state.user
|
||||
state.files.push(data)
|
||||
|
|
@ -651,28 +651,28 @@ export default createStore({
|
|||
},
|
||||
async deleteFile({state, dispatch, getters}, {id}) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
await servers.delete(getters.signAuth, '/api/files/' + id + '/')
|
||||
await servers.delete(getters.signAuth, '/api/v1/files/' + id + '/')
|
||||
state.files = state.files.filter(file => file.id !== id)
|
||||
},
|
||||
async deleteItemFile({state, dispatch, getters}, {item_id, file_id}) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
await servers.delete(getters.signAuth, '/api/item_files/' + item_id + '/' + file_id + '/')
|
||||
await servers.delete(getters.signAuth, '/api/v1/item_files/' + item_id + '/' + file_id + '/')
|
||||
state.files = state.files.filter(file => file.id !== file_id)
|
||||
},
|
||||
async stageFile({state, dispatch, getters}, {lifetime_id, file}) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const data = await servers.post(getters.signAuth, '/api/staged_files/' + lifetime_id + '/', file)
|
||||
const data = await servers.post(getters.signAuth, '/api/v1/staged_files/' + lifetime_id + '/', file)
|
||||
if (data.hash) {
|
||||
return data.hash
|
||||
}
|
||||
},
|
||||
async unstageFile({state, dispatch, getters}, {lifetime_id, file_hash}) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
await servers.delete(getters.signAuth, '/api/staged_files/' + lifetime_id + '/' + file_hash + '/')
|
||||
await servers.delete(getters.signAuth, '/api/v1/staged_files/' + lifetime_id + '/' + file_hash + '/')
|
||||
},
|
||||
async commitStagedFile({state, dispatch, getters}, {item_id, file_hash}) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const data = await servers.post(getters.signAuth, '/api/item_files/' + item_id + '/', {file_hash})
|
||||
const data = await servers.post(getters.signAuth, '/api/v1/item_files/' + item_id + '/', {file_hash})
|
||||
if (data.name) {
|
||||
data.owner = state.user
|
||||
state.files.push(data)
|
||||
|
|
@ -684,7 +684,7 @@ export default createStore({
|
|||
return state.tags
|
||||
}
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const data = await servers.get(getters.signAuth, '/api/tags/')
|
||||
const data = await servers.get(getters.signAuth, '/api/v1/tags/')
|
||||
commit('setTags', data)
|
||||
state.last_load.tags = Date.now()
|
||||
return data
|
||||
|
|
@ -694,7 +694,7 @@ export default createStore({
|
|||
return state.properties
|
||||
}
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const data = await servers.get(getters.signAuth, '/api/properties/')
|
||||
const data = await servers.get(getters.signAuth, '/api/v1/properties/')
|
||||
commit('setProperties', data)
|
||||
state.last_load.properties = Date.now()
|
||||
return data
|
||||
|
|
@ -704,7 +704,7 @@ export default createStore({
|
|||
return state.categories
|
||||
}
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const data = await servers.get(getters.signAuth, '/api/categories/')
|
||||
const data = await servers.get(getters.signAuth, '/api/v1/categories/')
|
||||
commit('setCategories', data)
|
||||
state.last_load.categories = Date.now()
|
||||
return data
|
||||
|
|
@ -714,7 +714,7 @@ export default createStore({
|
|||
return state.availability_policies
|
||||
}
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const data = await servers.get(getters.signAuth, '/api/availability_policies/')
|
||||
const data = await servers.get(getters.signAuth, '/api/v1/availability_policies/')
|
||||
commit('setAvailabilityPolicies', data.map(policy => ({slug: policy[0], text: policy[1]})))
|
||||
state.last_load.availability_policies = Date.now()
|
||||
return data
|
||||
|
|
@ -724,7 +724,7 @@ export default createStore({
|
|||
return state.storage_locations
|
||||
}
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const data = await servers.get(getters.signAuth, '/api/storage_locations/' + state.user + '/')
|
||||
const data = await servers.get(getters.signAuth, '/api/v1/storage_locations/' + state.user + '/')
|
||||
commit('setStorageLocations', data)
|
||||
state.last_load.storage_locations = Date.now()
|
||||
return data
|
||||
|
|
@ -733,7 +733,7 @@ export default createStore({
|
|||
const {domain} = splitGroupHandle(groupHandle)
|
||||
const servers = await dispatch('getFriendServers', {username: 'x@' + domain})
|
||||
const locations = await servers.get(
|
||||
getters.signAuth, '/api/storage_locations/' + encodeHandleForUrl(groupHandle) + '/')
|
||||
getters.signAuth, '/api/v1/storage_locations/' + encodeHandleForUrl(groupHandle) + '/')
|
||||
commit('setLocationsForKey', {url: '/' + groupHandle, locations})
|
||||
return locations
|
||||
},
|
||||
|
|
@ -755,7 +755,7 @@ export default createStore({
|
|||
? await dispatch('getFriendServers', {username: 'x@' + splitGroupHandle(location.owner_group).domain})
|
||||
: await dispatch('getHomeServers')
|
||||
// Path is scoped by the owner's handle, not the location's own id domain - see docs/implementation.md#owner-handle-scoped-routes.
|
||||
const path = '/api/storage_locations/' + encodeHandleForUrl(location.owner_group || location.owner) + '/' + location.id + '/'
|
||||
const path = '/api/v1/storage_locations/' + encodeHandleForUrl(location.owner_group || location.owner) + '/' + location.id + '/'
|
||||
const ret = await servers.delete(getters.signAuth, path)
|
||||
state.last_load.storage_locations = 0
|
||||
dispatch('fetchStorageLocations')
|
||||
|
|
@ -771,7 +771,7 @@ export default createStore({
|
|||
const data = {...location}
|
||||
delete data.owner_group
|
||||
if (data.parent === '') data.parent = null
|
||||
const reply = await servers.post(getters.signAuth, '/api/storage_locations/' + owner + '/', data)
|
||||
const reply = await servers.post(getters.signAuth, '/api/v1/storage_locations/' + owner + '/', data)
|
||||
state.last_load.storage_locations = 0
|
||||
return reply
|
||||
},
|
||||
|
|
@ -781,7 +781,7 @@ export default createStore({
|
|||
: await dispatch('getHomeServers')
|
||||
const data = {...location}
|
||||
if (data.parent === '') data.parent = null
|
||||
const path = '/api/storage_locations/' + encodeHandleForUrl(location.owner_group || location.owner) + '/' + location.id + '/'
|
||||
const path = '/api/v1/storage_locations/' + encodeHandleForUrl(location.owner_group || location.owner) + '/' + location.id + '/'
|
||||
const reply = await servers.patch(getters.signAuth, path, data)
|
||||
state.last_load.storage_locations = 0
|
||||
dispatch('fetchStorageLocations')
|
||||
|
|
@ -797,7 +797,7 @@ export default createStore({
|
|||
return state.info
|
||||
}
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const data = await servers.get(getters.signAuth, '/api/info/')
|
||||
const data = await servers.get(getters.signAuth, '/api/v1/info/')
|
||||
commit('setTags', data.tags)
|
||||
commit('setProperties', data.properties)
|
||||
commit('setCategories', data.categories)
|
||||
|
|
@ -820,7 +820,7 @@ export default createStore({
|
|||
return state.active_workflows
|
||||
}
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const data = await servers.get(getters.signAuth, '/api/workflows/')
|
||||
const data = await servers.get(getters.signAuth, '/api/v1/workflows/')
|
||||
const workflows = data.map(deserializeWorkflowPayload)
|
||||
commit('setActiveWorkflows', workflows)
|
||||
state.last_load.active_workflows = Date.now()
|
||||
|
|
@ -830,19 +830,19 @@ export default createStore({
|
|||
const servers = await dispatch('getHomeServers')
|
||||
// The backend stores payload as an opaque string; the frontend (de)serializes it.
|
||||
// See docs/implementation.md#workflow-payload-is-an-opaque-string.
|
||||
const data = await servers.post(getters.signAuth, '/api/workflows/', serializeWorkflowPayload(workflowData))
|
||||
const data = await servers.post(getters.signAuth, '/api/v1/workflows/', serializeWorkflowPayload(workflowData))
|
||||
state.last_load.active_workflows = 0 // Invalidate cache
|
||||
return deserializeWorkflowPayload(data)
|
||||
},
|
||||
async updateWorkflow({state, commit, dispatch, getters}, workflow) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const data = await servers.patch(getters.signAuth, '/api/workflows/' + workflow.id + '/', serializeWorkflowPayload(workflow))
|
||||
const data = await servers.patch(getters.signAuth, '/api/v1/workflows/' + workflow.id + '/', serializeWorkflowPayload(workflow))
|
||||
state.last_load.active_workflows = 0 // Invalidate cache
|
||||
return deserializeWorkflowPayload(data)
|
||||
},
|
||||
async updateWorkflowStep({state, commit, dispatch, getters}, {workflowId, currentStep, payload}) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
const data = await servers.post(getters.signAuth, '/api/workflows/' + workflowId + '/update_step/', {
|
||||
const data = await servers.post(getters.signAuth, '/api/v1/workflows/' + workflowId + '/update_step/', {
|
||||
current_step: currentStep,
|
||||
payload: JSON.stringify(payload)
|
||||
})
|
||||
|
|
@ -851,7 +851,7 @@ export default createStore({
|
|||
},
|
||||
async deleteWorkflow({state, commit, dispatch, getters}, workflowId) {
|
||||
const servers = await dispatch('getHomeServers')
|
||||
await servers.delete(getters.signAuth, '/api/workflows/' + workflowId + '/')
|
||||
await servers.delete(getters.signAuth, '/api/v1/workflows/' + workflowId + '/')
|
||||
state.last_load.active_workflows = 0 // Invalidate cache
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ export default {
|
|||
const unreachable = new NeighborsCache();
|
||||
const servers = await this.lookupServer({username: this.username}).then(servers => new ServerSet(servers, unreachable))
|
||||
const auth = createSignAuth(this.username, this.keypair.signSk);
|
||||
const reply = await servers.getRaw(auth, '/api/friends/');
|
||||
const reply = await servers.getRaw(auth, '/api/v1/friends/');
|
||||
if (reply.status === 200) {
|
||||
this.setUserFromIdentityRecord({username: this.username, keypair: this.keypair});
|
||||
router.push({path: '/'});
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ export default {
|
|||
}
|
||||
try {
|
||||
const servers = await this.getHomeServers();
|
||||
const response = await servers.delete(this.signAuth, '/api/account/');
|
||||
const response = await servers.delete(this.signAuth, '/api/v1/account/');
|
||||
if (!response || !response.ok) {
|
||||
const errorBody = response ? await response.json().catch(() => ({})) : {};
|
||||
alert('Account deletion failed: ' + (errorBody.detail || response?.statusText || 'unknown error'));
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ export default {
|
|||
}
|
||||
try {
|
||||
const servers = await this.getHomeServers();
|
||||
const response = await servers.delete(this.signAuth, '/api/account_data/');
|
||||
const response = await servers.delete(this.signAuth, '/api/v1/account_data/');
|
||||
if (!response || !response.ok) {
|
||||
const errorBody = response ? await response.json().catch(() => ({})) : {};
|
||||
alert('Data deletion failed: ' + (errorBody.detail || response?.statusText || 'unknown error'));
|
||||
|
|
@ -148,7 +148,7 @@ export default {
|
|||
try {
|
||||
const base64 = await this.fileToBase64(this.selectedFile);
|
||||
const servers = await this.getHomeServers();
|
||||
const summary = await servers.post(this.signAuth, '/api/import/', {zip: base64});
|
||||
const summary = await servers.post(this.signAuth, '/api/v1/import/', {zip: base64});
|
||||
if (summary && summary.detail) {
|
||||
alert('Data import failed: ' + summary.detail);
|
||||
return;
|
||||
|
|
@ -172,7 +172,7 @@ export default {
|
|||
},
|
||||
async exportData() {
|
||||
const servers = await this.getHomeServers();
|
||||
const data = await servers.getRaw(this.signAuth, '/api/export/');
|
||||
const data = await servers.getRaw(this.signAuth, '/api/v1/export/');
|
||||
const blob = new Blob([await data.blob()], {type: 'application/zip'});
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue