kopia lustrzana https://github.com/OpenDroneMap/WebODM
Add unit tests
rodzic
2850571f2c
commit
e706bfd17d
|
@ -86,8 +86,8 @@ class ProjectViewSet(viewsets.ModelViewSet):
|
|||
|
||||
try:
|
||||
with transaction.atomic():
|
||||
project.name = request.data.get('name')
|
||||
project.description = request.data.get('description')
|
||||
project.name = request.data.get('name', '')
|
||||
project.description = request.data.get('description', '')
|
||||
project.save()
|
||||
|
||||
form_perms = request.data.get('permissions')
|
||||
|
@ -127,5 +127,7 @@ class ProjectViewSet(viewsets.ModelViewSet):
|
|||
|
||||
except User.DoesNotExist as e:
|
||||
return Response({'error': _("Invalid user in permissions list")}, status=status.HTTP_400_BAD_REQUEST)
|
||||
except AttributeError as e:
|
||||
return Response({'error': _("Invalid permissions")}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
return Response({'success': True}, status=status.HTTP_200_OK)
|
|
@ -12,7 +12,7 @@ from rest_framework_jwt.views import obtain_jwt_token
|
|||
from .tiler import TileJson, Bounds, Metadata, Tiles, Export
|
||||
from .potree import Scene, CameraView
|
||||
from .workers import CheckTask, GetTaskResult
|
||||
from .users import UserViewSet
|
||||
from .users import UsersList
|
||||
from webodm import settings
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
|
@ -20,9 +20,6 @@ router.register(r'projects', ProjectViewSet)
|
|||
router.register(r'processingnodes', ProcessingNodeViewSet)
|
||||
router.register(r'presets', PresetViewSet, base_name='presets')
|
||||
|
||||
if settings.ENABLE_USERS_API:
|
||||
router.register(r'users', UserViewSet, base_name='users')
|
||||
|
||||
tasks_router = routers.NestedSimpleRouter(router, r'projects', lookup='project')
|
||||
tasks_router.register(r'tasks', TaskViewSet, base_name='projects-tasks')
|
||||
|
||||
|
@ -61,3 +58,7 @@ urlpatterns = [
|
|||
|
||||
url(r'^plugins/(?P<plugin_name>[^/.]+)/(.*)$', api_view_handler)
|
||||
]
|
||||
|
||||
if settings.ENABLE_USERS_API:
|
||||
urlpatterns.append(url(r'users', UsersList.as_view()))
|
||||
|
||||
|
|
|
@ -1,33 +1,24 @@
|
|||
from django.contrib.auth.models import User
|
||||
from rest_framework import serializers, viewsets, mixins, status, exceptions, permissions
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework import exceptions, permissions, parsers
|
||||
from rest_framework.response import Response
|
||||
|
||||
class UserSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['username', 'email']
|
||||
class UsersList(APIView):
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
parser_classes = (parsers.JSONParser, parsers.FormParser,)
|
||||
|
||||
class UserViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
|
||||
serializer_class = UserSerializer
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
|
||||
# Disable pagination when not requesting any page
|
||||
def paginate_queryset(self, queryset):
|
||||
if self.paginator and self.request.query_params.get(self.paginator.page_query_param, None) is None:
|
||||
return None
|
||||
return super().paginate_queryset(queryset)
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = User.objects.all()
|
||||
def get(self, request):
|
||||
qs = User.objects.all()
|
||||
|
||||
search = self.request.query_params.get('search', None)
|
||||
if search is not None:
|
||||
queryset = queryset.filter(username__istartswith=search) | queryset.filter(email__istartswith=search)
|
||||
|
||||
qs = qs.filter(username__istartswith=search) | qs.filter(email__istartswith=search)
|
||||
|
||||
limit = self.request.query_params.get('limit', None)
|
||||
if limit is not None:
|
||||
try:
|
||||
queryset = queryset[:abs(int(limit))]
|
||||
qs = qs[:abs(int(limit))]
|
||||
except ValueError:
|
||||
raise exceptions.ValidationError(detail="Invalid query parameters")
|
||||
|
||||
return queryset
|
||||
return Response([{'username': u.username, 'email': u.email} for u in qs])
|
|
@ -0,0 +1,107 @@
|
|||
import logging
|
||||
from django.contrib.auth.models import User
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APIClient
|
||||
from app.models import Project
|
||||
from .classes import BootTestCase
|
||||
from guardian.shortcuts import get_perms
|
||||
|
||||
from webodm import settings
|
||||
logger = logging.getLogger('app.logger')
|
||||
|
||||
|
||||
class TestApiProjects(BootTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
def tearDown(self):
|
||||
super().tearDown()
|
||||
|
||||
def test_project(self):
|
||||
client = APIClient()
|
||||
|
||||
user = User.objects.get(username="testuser")
|
||||
project = Project.objects.create(
|
||||
owner=user,
|
||||
name="test project"
|
||||
)
|
||||
|
||||
# Cannot edit project (anonymous)
|
||||
res = client.post("/api/projects/{}/edit/".format(project.id), {
|
||||
'name': 'edited'
|
||||
})
|
||||
self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)
|
||||
|
||||
client.login(username="testuser", password="test1234")
|
||||
|
||||
# Can edit project
|
||||
res = client.post("/api/projects/{}/edit/".format(project.id), {
|
||||
'name': 'edited'
|
||||
})
|
||||
self.assertEqual(res.status_code, status.HTTP_200_OK)
|
||||
project.refresh_from_db()
|
||||
|
||||
self.assertEqual(project.name, 'edited')
|
||||
self.assertEqual(project.description, '')
|
||||
|
||||
other_user = User.objects.get(username="testuser2")
|
||||
|
||||
other_client = APIClient()
|
||||
other_client.login(username="testuser2", password="test1234")
|
||||
|
||||
# Other user cannot edit project
|
||||
res = other_client.post("/api/projects/{}/edit/".format(project.id), {
|
||||
'name': 'edited2'
|
||||
})
|
||||
self.assertEqual(res.status_code, status.HTTP_404_NOT_FOUND)
|
||||
|
||||
# Other user cannot see project
|
||||
res = other_client.get("/api/projects/{}/".format(project.id))
|
||||
self.assertEqual(res.status_code, status.HTTP_404_NOT_FOUND)
|
||||
|
||||
# Change permissions via API
|
||||
res = client.post("/api/projects/{}/edit/".format(project.id), {
|
||||
'permissions': [{'username': 'testuser2', 'permissions': ['view']}]
|
||||
}, format="json")
|
||||
self.assertEqual(res.status_code, status.HTTP_200_OK)
|
||||
|
||||
# Other user can see project
|
||||
res = other_client.get("/api/projects/{}/".format(project.id))
|
||||
self.assertEqual(res.status_code, status.HTTP_200_OK)
|
||||
|
||||
# Other user still cannot edit project
|
||||
res = other_client.post("/api/projects/{}/edit/".format(project.id), {
|
||||
'name': 'edited2'
|
||||
})
|
||||
self.assertEqual(res.status_code, status.HTTP_404_NOT_FOUND)
|
||||
|
||||
# Change permissions again
|
||||
res = client.post("/api/projects/{}/edit/".format(project.id), {
|
||||
'permissions': [{'username': 'testuser2', 'permissions': ['view', 'add', 'change', 'delete']}]
|
||||
}, format="json")
|
||||
self.assertEqual(res.status_code, status.HTTP_200_OK)
|
||||
|
||||
# Other user can now edit
|
||||
res = other_client.post("/api/projects/{}/edit/".format(project.id), {
|
||||
'name': 'edited3'
|
||||
})
|
||||
self.assertEqual(res.status_code, status.HTTP_200_OK)
|
||||
project.refresh_from_db()
|
||||
self.assertEqual(project.name, 'edited3')
|
||||
|
||||
# Can remove permissions
|
||||
res = client.post("/api/projects/{}/edit/".format(project.id), {
|
||||
'permissions': []
|
||||
}, format="json")
|
||||
self.assertEqual(res.status_code, status.HTTP_200_OK)
|
||||
|
||||
# Other user cannot see project
|
||||
res = other_client.get("/api/projects/{}/".format(project.id))
|
||||
self.assertEqual(res.status_code, status.HTTP_404_NOT_FOUND)
|
||||
|
||||
# Current user (owner) still has permissions
|
||||
res = client.get("/api/projects/{}/".format(project.id))
|
||||
self.assertEqual(res.status_code, status.HTTP_200_OK)
|
||||
|
||||
perms = get_perms(user, project)
|
||||
self.assertEqual(len(perms), 4)
|
|
@ -0,0 +1,52 @@
|
|||
import logging
|
||||
from django.contrib.auth.models import User
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APIClient
|
||||
from app.models import Project
|
||||
from .classes import BootTestCase
|
||||
|
||||
from webodm import settings
|
||||
logger = logging.getLogger('app.logger')
|
||||
|
||||
|
||||
class TestApiUsers(BootTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
def tearDown(self):
|
||||
super().tearDown()
|
||||
|
||||
def test_users(self):
|
||||
client = APIClient()
|
||||
|
||||
user = User.objects.get(username="testuser")
|
||||
|
||||
# Cannot list users (anonymous)
|
||||
res = client.get("/api/users/?limit=30")
|
||||
self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)
|
||||
|
||||
client.login(username="testuser", password="test1234")
|
||||
|
||||
# Can list users (authenticated)
|
||||
res = client.get("/api/users/?limit=30")
|
||||
self.assertEqual(res.status_code, status.HTTP_200_OK)
|
||||
self.assertTrue([u for u in res.data if u['username'] == 'testuser'])
|
||||
self.assertTrue([u for u in res.data if u['username'] == 'testsuperuser'])
|
||||
|
||||
# Can search for users
|
||||
res = client.get("/api/users/?search=super")
|
||||
self.assertEqual(res.status_code, status.HTTP_200_OK)
|
||||
self.assertFalse([u for u in res.data if u['username'] == 'testuser'])
|
||||
self.assertTrue([u for u in res.data if u['username'] == 'testsuperuser'])
|
||||
|
||||
# Can search for users and limit
|
||||
res = client.get("/api/users/?search=super&limit=1")
|
||||
self.assertEqual(res.status_code, status.HTTP_200_OK)
|
||||
self.assertFalse([u for u in res.data if u['username'] == 'testuser'])
|
||||
self.assertTrue([u for u in res.data if u['username'] == 'testsuperuser'])
|
||||
|
||||
# Handle invalid limits
|
||||
res = client.get("/api/users/?search=super&limit=-1")
|
||||
self.assertEqual(res.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(len(res.data), 1)
|
||||
|
Ładowanie…
Reference in New Issue