diff --git a/seahub/dtable/api.py b/seahub/dtable/api.py index 5503116890..763ba28070 100644 --- a/seahub/dtable/api.py +++ b/seahub/dtable/api.py @@ -8,7 +8,7 @@ from rest_framework.permissions import IsAuthenticated from rest_framework import status from rest_framework.response import Response from django.utils.translation import ugettext as _ -from seaserv import seafile_api, ccnet_api +from seaserv import seafile_api from seahub.base.accounts import User from seahub.api2.authentication import TokenAuthentication @@ -18,12 +18,12 @@ from seahub.dtable.models import Workspaces, DTables, ShareDTable from seahub.base.templatetags.seahub_tags import email2nickname from seahub.utils import is_valid_username, is_org_context from seahub.api2.endpoints.utils import is_org_user -from seahub.utils import normalize_dir_path, normalize_file_path +from seahub.utils import normalize_file_path from seahub.constants import PERMISSION_ADMIN, PERMISSION_PREVIEW, PERMISSION_PREVIEW_EDIT, \ PERMISSION_READ, PERMISSION_READ_WRITE from seahub.api2.endpoints.dtable import FILE_TYPE -from seahub.group.utils import group_id_to_name, is_group_member -from seahub.utils.timeutils import timestamp_to_isoformat_timestr, datetime_to_isoformat_timestr +from seahub.group.utils import group_id_to_name +from seahub.utils.timeutils import datetime_to_isoformat_timestr logger = logging.getLogger(__name__) permission_tuple = (PERMISSION_ADMIN, PERMISSION_PREVIEW, PERMISSION_PREVIEW_EDIT, @@ -84,6 +84,7 @@ class ShareDTablesView(APIView): dtable_info['updated_at'] = datetime_to_isoformat_timestr(dtable.updated_at) dtable_info['permission'] = permission dtable_info['from_user'] = from_user + dtable_info['from_user_name'] = email2nickname(from_user) workspace_info['table_list'].append(dtable_info) diff --git a/tests/seahub/dtable/test_api.py b/tests/seahub/dtable/test_api.py new file mode 100644 index 0000000000..06910d3e90 --- /dev/null +++ b/tests/seahub/dtable/test_api.py @@ -0,0 +1,266 @@ +import json + +from django.core.urlresolvers import reverse +from seahub.dtable.models import Workspaces, ShareDTable, DTables +from seaserv import seafile_api + +from seahub.test_utils import BaseTestCase +from seahub.base.templatetags.seahub_tags import email2nickname + + +class ShareDTablesViewTest(BaseTestCase): + def setUp(self): + # create workspace + self.workspace = Workspaces.objects.create_workspace( + self.user.username, self.repo.id) + assert len(Workspaces.objects.all()) == 1 + # create dtable + seafile_api.post_empty_file( + self.repo.id, '/', 'dtable1.dtable', self.user.username) + self.dtable = DTables.objects.create_dtable( + self.user.username, self.workspace, 'dtable1') + assert len(DTables.objects.all()) == 1 + # share dtable to admin + ShareDTable.objects.add( + self.dtable, self.user.username, self.admin.username, 'rw') + assert len(ShareDTable.objects.all()) == 1 + + self.url = reverse('api-v2.1-dtables-share') + + def tearDown(self): + workspace = Workspaces.objects.get_workspace_by_owner(self.user.username) + workspace_id = workspace.id + Workspaces.objects.delete_workspace(workspace_id) + + self.remove_repo() + + def test_can_list(self): + self.login_as(self.admin) + + resp = self.client.get(self.url) + self.assertEqual(200, resp.status_code) + json_resp = json.loads(resp.content) + assert json_resp["share_list"] + assert json_resp["share_list"][0] + assert json_resp["share_list"][0]['owner_type'] == 'Personal' + assert json_resp["share_list"][0]['repo_id'] == self.repo.id + assert json_resp["share_list"][0]['id'] == self.workspace.id + assert json_resp["share_list"][0]['owner_name'] == email2nickname(self.user.username) + assert json_resp["share_list"][0]['table_list'] + assert json_resp["share_list"][0]['table_list'][0]['workspace_id'] == self.workspace.id + assert json_resp["share_list"][0]['table_list'][0]['uuid'] + assert json_resp["share_list"][0]['table_list'][0]['creator'] == email2nickname(self.user.username) + assert json_resp["share_list"][0]['table_list'][0]['created_at'] + assert json_resp["share_list"][0]['table_list'][0]['permission'] == 'rw' + assert json_resp["share_list"][0]['table_list'][0]['updated_at'] + assert json_resp["share_list"][0]['table_list'][0]['from_user'] == self.user.username + assert json_resp["share_list"][0]['table_list'][0]['from_user_name'] == email2nickname(self.user.username) + assert json_resp["share_list"][0]['table_list'][0]['modifier'] == email2nickname(self.user.username) + assert json_resp["share_list"][0]['table_list'][0]['id'] + assert json_resp["share_list"][0]['table_list'][0]['name'] == 'dtable1' + + +class ShareDTableViewTest(BaseTestCase): + def setUp(self): + # create workspace + self.workspace = Workspaces.objects.create_workspace( + self.user.username, self.repo.id) + assert len(Workspaces.objects.all()) == 1 + # create dtable + seafile_api.post_empty_file( + self.repo.id, '/', 'dtable1.dtable', self.user.username) + self.dtable = DTables.objects.create_dtable( + self.user.username, self.workspace, 'dtable1') + assert len(DTables.objects.all()) == 1 + # share dtable to admin + ShareDTable.objects.add( + self.dtable, self.user.username, self.admin.username, 'rw') + assert len(ShareDTable.objects.all()) == 1 + + self.url = reverse('api-v2.1-dtable-share', args=[self.workspace.id, self.dtable.name]) + + def tearDown(self): + workspace = Workspaces.objects.get_workspace_by_owner(self.user.username) + workspace_id = workspace.id + Workspaces.objects.delete_workspace(workspace_id) + + self.remove_repo() + + def test_can_post(self): + assert len(ShareDTable.objects.all()) == 1 + ShareDTable.objects.all().delete() + assert len(ShareDTable.objects.all()) == 0 + + self.login_as(self.user) + + data = { + 'email': self.admin.username, + 'permission': 'rw', + } + resp = self.client.post(self.url, data) + self.assertEqual(201, resp.status_code) + assert len(ShareDTable.objects.all()) == 1 + + def test_can_not_post_with_already_share(self): + assert len(ShareDTable.objects.all()) == 1 + + self.login_as(self.user) + + data = { + 'email': self.admin.username, + 'permission': 'rw', + } + resp = self.client.post(self.url, data) + self.assertEqual(409, resp.status_code) + + def test_can_not_post_with_not_owner(self): + assert len(ShareDTable.objects.all()) == 1 + ShareDTable.objects.all().delete() + assert len(ShareDTable.objects.all()) == 0 + + self.login_as(self.admin) + + data = { + 'email': self.admin.username, + 'permission': 'rw', + } + resp = self.client.post(self.url, data) + self.assertEqual(403, resp.status_code) + + def test_can_not_post_with_share_to_owner(self): + assert len(ShareDTable.objects.all()) == 1 + ShareDTable.objects.all().delete() + assert len(ShareDTable.objects.all()) == 0 + + self.login_as(self.user) + + data = { + 'email': self.user.username, + 'permission': 'rw', + } + resp = self.client.post(self.url, data) + self.assertEqual(400, resp.status_code) + + def test_can_not_post_with_share_to_org_user(self): + assert len(ShareDTable.objects.all()) == 1 + ShareDTable.objects.all().delete() + assert len(ShareDTable.objects.all()) == 0 + + self.login_as(self.user) + + data = { + 'email': self.org_user.username, + 'permission': 'rw', + } + resp = self.client.post(self.url, data) + self.assertEqual(400, resp.status_code) + + def test_can_get(self): + self.login_as(self.user) + + resp = self.client.get(self.url) + self.assertEqual(200, resp.status_code) + json_resp = json.loads(resp.content) + assert json_resp["user_list"] + assert json_resp["user_list"][0] + assert json_resp["user_list"][0] + assert json_resp["user_list"][0]['permission'] == 'rw' + assert json_resp["user_list"][0]['avatar_url'] + assert json_resp["user_list"][0]['contact_email'] == self.admin.username + assert json_resp["user_list"][0]['email'] == self.admin.username + assert json_resp["user_list"][0]['name'] == email2nickname(self.admin.username) + + def test_can_not_get_with_not_owner(self): + self.login_as(self.admin) + + resp = self.client.get(self.url) + self.assertEqual(403, resp.status_code) + + def test_can_put(self): + self.login_as(self.user) + + data = { + 'email': self.admin.username, + 'permission': 'r', + } + resp = self.client.put(self.url, json.dumps(data), 'application/json') + self.assertEqual(200, resp.status_code) + + assert ShareDTable.objects.get_by_dtable_and_to_user( + self.dtable, self.admin.username).permission == 'r' + + def test_can_not_put_with_not_shared(self): + assert len(ShareDTable.objects.all()) == 1 + ShareDTable.objects.all().delete() + assert len(ShareDTable.objects.all()) == 0 + + self.login_as(self.user) + + data = { + 'email': self.admin.username, + 'permission': 'r', + } + resp = self.client.put(self.url, json.dumps(data), 'application/json') + self.assertEqual(404, resp.status_code) + + def test_can_not_put_with_same_permission(self): + self.login_as(self.user) + + data = { + 'email': self.admin.username, + 'permission': 'rw', + } + resp = self.client.put(self.url, json.dumps(data), 'application/json') + self.assertEqual(400, resp.status_code) + + def test_can_not_put_with_share_to_owner(self): + self.login_as(self.user) + + data = { + 'email': self.user.username, + 'permission': 'rw', + } + resp = self.client.put(self.url, json.dumps(data), 'application/json') + self.assertEqual(400, resp.status_code) + + def test_can_delete(self): + self.login_as(self.user) + + data = { + 'email': self.admin.username, + } + resp = self.client.delete(self.url, json.dumps(data), 'application/json') + self.assertEqual(200, resp.status_code) + assert len(ShareDTable.objects.all()) == 0 + + def test_can_delete_with_share_user(self): + self.login_as(self.admin) + + data = { + 'email': self.admin.username, + } + resp = self.client.delete(self.url, json.dumps(data), 'application/json') + self.assertEqual(200, resp.status_code) + assert len(ShareDTable.objects.all()) == 0 + + def test_can_not_delete_with_not_shared(self): + assert len(ShareDTable.objects.all()) == 1 + ShareDTable.objects.all().delete() + assert len(ShareDTable.objects.all()) == 0 + + self.login_as(self.user) + + data = { + 'email': self.admin.username, + } + resp = self.client.delete(self.url, json.dumps(data), 'application/json') + self.assertEqual(404, resp.status_code) + + def test_can_not_delete_with_not_shared_user(self): + self.login_as(self.org_user) + + data = { + 'email': self.admin.username, + } + resp = self.client.delete(self.url, json.dumps(data), 'application/json') + self.assertEqual(403, resp.status_code)