#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
###############################################################################
# #
# Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/ #
# Contact: beat.support@idiap.ch #
# #
# This file is part of the beat.web module of the BEAT platform. #
# #
# Commercial License Usage #
# Licensees holding valid commercial BEAT licenses may use this file in #
# accordance with the terms contained in a written agreement between you #
# and Idiap. For further information contact tto@idiap.ch #
# #
# Alternatively, this file may be used under the terms of the GNU Affero #
# Public License version 3 as published by the Free Software and appearing #
# in the file LICENSE.AGPL included in the packaging of this file. #
# The BEAT platform is distributed in the hope that it will be useful, but #
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY #
# or FITNESS FOR A PARTICULAR PURPOSE. #
# #
# You should have received a copy of the GNU Affero Public License along #
# with the BEAT platform. If not, see http://www.gnu.org/licenses/. #
# #
###############################################################################
import json
import os
import shutil
from django.conf import settings
from django.contrib.auth.models import User
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APITestCase
from ..common.testutils import tearDownModule # noqa test runner will call it
from ..dataformats.models import DataFormat
from .models import Team
from .serializers import SimpleTeamSerializer
# ----------------------------------------------------------
[docs]class TeamTestCase(APITestCase):
[docs] def setUp(self):
self.password = "1234"
self.johndoe = User.objects.create_user(
"johndoe", "johndoe@test.org", self.password
)
self.teamdoe = Team.objects.create(
name="teamdoe", owner=self.johndoe, privacy_level=Team.PUBLIC
)
self.teamdoe_members = Team.objects.create(
name="teamdoe_members", owner=self.johndoe, privacy_level=Team.MEMBERS
)
self.teamdoe_private = Team.objects.create(
name="teamdoe_private", owner=self.johndoe, privacy_level=Team.PRIVATE
)
self.jackdoe = User.objects.create_user(
"jackdoe", "jackdoe@test.org", self.password
)
self.williamdoe = User.objects.create_user(
"williamdoe", "williamdoe@test.org", self.password
)
self.invalid_username = "janedoe"
# object to test sharing/deletion
if os.path.exists(settings.DATAFORMATS_ROOT):
shutil.rmtree(settings.DATAFORMATS_ROOT)
(dataformat, errors) = DataFormat.objects.create_dataformat(
author=self.johndoe, name="data_format_shared_with_private_team"
)
self.assertIsNotNone(dataformat, errors)
dataformat.share(teams=[self.teamdoe_private])
self.dataformat = dataformat
# ----------------------------------------------------------
[docs]class TeamListTestCase(TeamTestCase):
[docs] def setUp(self):
super(TeamListTestCase, self).setUp()
self.url = reverse("api_teams:teamlist")
[docs] def test_anonymous_user(self):
response = self.client.get(self.url, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
[docs] def test_logged_in_user(self):
self.client.login(username=self.johndoe.username, password=self.password)
serializer = SimpleTeamSerializer(
Team.objects.filter(owner__username=self.johndoe.username),
many=True,
context={"user": self.johndoe},
)
expected_answer = serializer.data
response = self.client.get(self.url, format="json")
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(json.loads(response.content), expected_answer)
# ----------------------------------------------------------
[docs]class TeamPrivacyTestCase(TeamTestCase):
[docs] def setUp(self):
super(TeamPrivacyTestCase, self).setUp()
self.public_url = reverse(
"api_teams:team_info",
kwargs={
"owner_name": self.johndoe.username,
"team_name": self.teamdoe.name,
},
)
self.member_url = reverse(
"api_teams:team_info",
kwargs={
"owner_name": self.johndoe.username,
"team_name": self.teamdoe_members.name,
},
)
self.private_url = reverse(
"api_teams:team_info",
kwargs={
"owner_name": self.johndoe.username,
"team_name": self.teamdoe_private.name,
},
)
self.teamdoe_members.members.add(self.jackdoe)
self.teamdoe_private.members.add(self.jackdoe)
[docs] def test_public_privacy_level_anoymous_user(self):
response = self.client.get(self.public_url, format="json")
self.assertEqual(response.status_code, status.HTTP_200_OK)
[docs] def test_public_privacy_level_loggedin_user_in_team(self):
self.client.login(username=self.jackdoe, password=self.password)
response = self.client.get(self.public_url, format="json")
self.assertEqual(response.status_code, status.HTTP_200_OK)
[docs] def test_public_privacy_level_loggedin_user_not_in_team(self):
self.client.login(username=self.williamdoe, password=self.password)
response = self.client.get(self.public_url, format="json")
self.assertEqual(response.status_code, status.HTTP_200_OK)
[docs] def test_members_privacy_level(self):
response = self.client.get(self.member_url, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
[docs] def test_member_privacy_level_loggedin_user_in_team(self):
self.client.login(username=self.jackdoe, password=self.password)
response = self.client.get(self.member_url, format="json")
self.assertEqual(response.status_code, status.HTTP_200_OK)
[docs] def test_member_privacy_level_loggedin_user_not_in_team(self):
self.client.login(username=self.williamdoe, password=self.password)
response = self.client.get(self.member_url, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
[docs] def test_private_privacy_level(self):
response = self.client.get(self.private_url, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
[docs] def test_private_privacy_level_loggedin_user_in_team(self):
self.client.login(username=self.jackdoe, password=self.password)
response = self.client.get(self.private_url, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
# ----------------------------------------------------------
[docs]class TeamCreationTestCase(TeamTestCase):
[docs] def setUp(self):
super(TeamCreationTestCase, self).setUp()
self.url = reverse(
"api_teams:user_teamlist", kwargs={"owner_name": self.johndoe.username}
)
self.data = {
"name": "teamdoe2",
"short_description": "blah",
"accessibility": "private",
"members": ["{}".format(self.johndoe)],
}
[docs] def test_anyonymous_user(self):
response = self.client.post(self.url, self.data, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
[docs] def test_logged_in_user(self):
expected_answer = {
"name": "{}/teamdoe2".format(self.johndoe),
"short_description": u"blah",
"accessibility": "private",
"members": ["{}".format(self.johndoe)],
"object_view": reverse("teams:view", args=["johndoe", "teamdoe2"]),
}
self.client.login(username=self.johndoe.username, password=self.password)
response = self.client.post(self.url, self.data, format="json")
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(json.loads(response.content), expected_answer)
response = self.client.post(self.url, self.data, format="json")
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
# ----------------------------------------------------------
[docs]class TeamAddMemberTestCase(TeamTestCase):
[docs] def setUp(self):
super(TeamAddMemberTestCase, self).setUp()
self.url = reverse(
"api_teams:team_info",
kwargs={"owner_name": self.johndoe.username, "team_name": "teamdoe"},
)
self.data = {"members": [self.johndoe.username, self.jackdoe.username]}
[docs] def test_anonymous_user(self):
response = self.client.put(self.url, self.data, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
[docs] def test_logged_in_user(self):
expected_answer = {
"name": "{}/teamdoe".format(self.johndoe.username),
"short_description": u"",
"is_owner": True,
"accessibility": "public",
"members": set([self.johndoe.username, self.jackdoe.username]),
}
self.client.login(username=self.johndoe.username, password=self.password)
response = self.client.put(self.url, self.data, format="json")
self.assertEqual(response.status_code, status.HTTP_200_OK)
response = self.client.get(self.url, format="json")
r = json.loads(response.content)
r["members"] = set(r["members"]) # fix order
self.assertEqual(r, expected_answer)
[docs] def test_logged_in_user_not_owner(self):
self.client.login(username=self.jackdoe, password=self.password)
response = self.client.put(self.url, self.data, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
[docs] def test_logged_in_user_invalid_team(self):
self.client.login(username=self.johndoe.username, password=self.password)
url = reverse(
"api_teams:team_info",
kwargs={"owner_name": self.johndoe.username, "team_name": "teaminvalid"},
)
response = self.client.put(url, self.data, format="json")
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
# ----------------------------------------------------------
[docs]class TeamRemoveMemberTestCase(TeamTestCase):
[docs] def setUp(self):
super(TeamRemoveMemberTestCase, self).setUp()
self.teamdoe_members.members.add(self.johndoe)
self.teamdoe_members.members.add(self.jackdoe)
self.url = reverse(
"api_teams:team_info",
kwargs={"owner_name": self.johndoe.username, "team_name": "teamdoe"},
)
self.data = {"members": [self.johndoe.username]}
[docs] def test_anonymous_user(self):
response = self.client.put(self.url, self.data, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
[docs] def test_logged_in_user(self):
expected_answer = {
"name": "{}/teamdoe".format(self.johndoe.username),
"short_description": u"",
"is_owner": True,
"accessibility": "public",
"members": [self.johndoe.username],
}
self.client.login(username=self.johndoe.username, password=self.password)
response = self.client.put(self.url, self.data, format="json")
self.assertEqual(response.status_code, status.HTTP_200_OK)
response = self.client.get(self.url, format="json")
self.assertEqual(json.loads(response.content), expected_answer)
[docs] def test_logged_in_user_not_owner(self):
self.client.login(username=self.jackdoe, password=self.password)
response = self.client.put(self.url, self.data, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
[docs] def test_logged_in_user_invalid_team(self):
self.client.login(username=self.johndoe.username, password=self.password)
url = url = reverse(
"api_teams:team_info",
kwargs={"owner_name": self.johndoe.username, "team_name": "teaminvalid"},
)
response = self.client.put(url, self.data, format="json")
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
# ----------------------------------------------------------
[docs]class TeamInfoTestCase(TeamTestCase):
[docs] def setUp(self):
super(TeamInfoTestCase, self).setUp()
self.url = reverse(
"api_teams:team_info",
kwargs={"owner_name": self.johndoe.username, "team_name": "teamdoe"},
)
[docs] def test_anonymous_user(self):
expected_answer = {
"name": "{}/teamdoe".format(self.johndoe.username),
"short_description": u"",
"is_owner": False,
"accessibility": "public",
"members": [],
}
response = self.client.get(self.url, format="json")
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(json.loads(response.content), expected_answer)
[docs] def test_logged_in_user(self):
expected_answer = {
"name": "{}/teamdoe".format(self.johndoe.username),
"short_description": u"",
"is_owner": True,
"accessibility": "public",
"members": [],
}
self.client.login(username=self.johndoe.username, password=self.password)
response = self.client.get(self.url, format="json")
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(json.loads(response.content), expected_answer)
[docs] def test_logged_in_user_invalid_team(self):
self.client.login(username=self.johndoe.username, password=self.password)
url = reverse(
"api_teams:team_info",
kwargs={"owner_name": self.johndoe.username, "team_name": "teaminvalid"},
)
response = self.client.get(url, format="json")
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
# ----------------------------------------------------------
[docs]class TeamDeletionTestCase(TeamTestCase):
[docs] def setUp(self):
super(TeamDeletionTestCase, self).setUp()
self.options = {"owner_name": self.johndoe.username, "team_name": "teamdoe"}
[docs] def get_url(self, options):
return reverse("api_teams:team_info", kwargs=options)
[docs] def test_anonymous_user(self):
response = self.client.put(self.get_url(self.options), format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
[docs] def test_logged_in_user_own_team(self):
self.client.login(username=self.johndoe.username, password=self.password)
options = self.options
options["owner_name"] = self.johndoe.username
url = self.get_url(options)
self.assertEqual(self.teamdoe.total_shares(), 0)
response = self.client.delete(url, format="json")
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
[docs] def test_logged_in_user_own_team_shared(self):
self.client.login(username=self.johndoe.username, password=self.password)
options = self.options
options["owner_name"] = self.johndoe.username
options["team_name"] = "teamdoe_private"
url = self.get_url(options)
self.assertEqual(self.teamdoe_private.total_shares(), 1)
response = self.client.delete(url, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
[docs] def test_logged_in_user_team_from_other(self):
self.client.login(username=self.jackdoe, password=self.password)
url = self.get_url(self.options)
self.assertEqual(self.teamdoe.total_shares(), 0)
response = self.client.delete(url, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
[docs] def test_logged_in_user_invalid_owner(self):
self.client.login(username=self.johndoe.username, password=self.password)
options = self.options
options["owner_name"] = self.invalid_username
url = self.get_url(options)
self.assertEqual(self.teamdoe.total_shares(), 0)
response = self.client.delete(url, format="json")
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
[docs] def test_logged_in_user_invalid_team(self):
self.client.login(username=self.johndoe.username, password=self.password)
options = self.options
options["team_name"] = "teaminvalid"
url = self.get_url(options)
response = self.client.delete(url, format="json")
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)