diff --git a/base/accounts.py b/base/accounts.py index a8a7fa1470..582dbe2d0f 100644 --- a/base/accounts.py +++ b/base/accounts.py @@ -13,6 +13,7 @@ from registration import signals #from registration.forms import RegistrationForm from seaserv import ccnet_threaded_rpc, unset_repo_passwd, is_passwd_set +from profile.models import Profile from seahub.utils import get_user_repos class UserManager(object): @@ -110,8 +111,8 @@ class User(object): """ # TODO: what about repo and org? ccnet_threaded_rpc.remove_emailuser(self.username) - ccnet_threaded_rpc.remove_binding(self.username) ccnet_threaded_rpc.remove_group_user(self.username) + Profile.objects.filter(user=self.username).delete() def get_and_delete_messages(self): messages = [] diff --git a/fts/__init__.py b/fts/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/fts/models.py b/fts/models.py new file mode 100644 index 0000000000..71a8362390 --- /dev/null +++ b/fts/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/fts/tests.py b/fts/tests.py new file mode 100644 index 0000000000..3276ad7069 --- /dev/null +++ b/fts/tests.py @@ -0,0 +1,246 @@ +# encoding: utf-8 +import os + +from django.test import TestCase, Client +from django_liveserver.testcases import LiveServerTestCase +from selenium import webdriver +from selenium.webdriver.firefox.webdriver import WebDriver +from selenium.webdriver.common.action_chains import ActionChains +from selenium.webdriver.common.keys import Keys + +from seahub.base.accounts import User +from seaserv import list_personal_repos_by_owner, remove_repo + +class BaseTest(LiveServerTestCase): + + def setUp(self): + self.site_url = 'localhost:8000' + + self.username = 'foo@foo.com' + self.passwd = 'foo' + self.browser = webdriver.Firefox() + self.browser.implicitly_wait(3) + + def tearDown(self): + self.browser.quit() + + def _setup_new_user(self, username, passwd): + User.objects.create_user(username, passwd, False, True) + + def _teardown_new_user(self, username): + # First delete all repos created by user + for e in list_personal_repos_by_owner(username): + remove_repo(e.id) + # Then remove user + User.objects.get(email=username).delete() + + def _login_user(self, username=None, passwd=None): + if not (username and passwd): + username = self.username + passwd = self.passwd + + self._setup_new_user(username, passwd) + # A user goes to the login page, and inputs username and password + self.browser.get(self.site_url+ '/accounts/login/') + username_field = self.browser.find_element_by_name('username') + username_field.send_keys(username) + password_field = self.browser.find_element_by_name('password') + password_field.send_keys(passwd) + password_field.send_keys(Keys.RETURN) + + # He is returned to myhome page + body = self.browser.find_element_by_tag_name('body') + self.assertIn(u'Libraries', body.text) + + def _logout_user(self, username=None, remove_user=True): + if not username: + username = self.username + self.browser.find_elements_by_link_text(u'Log out')[0].click() + if remove_user: + self._teardown_new_user(username) + + def test_can_login_and_logout(self): + self._setup_new_user(self.username, self.passwd) + # A user goes to the login page, and inputs username and password + self.browser.get(self.site_url+ '/accounts/login/') + + # He sees the login heading + body = self.browser.find_element_by_tag_name('body') + self.assertIn(u'Log In', body.text) + + # He types username and password + username_field = self.browser.find_element_by_name('username') + username_field.send_keys(self.username) + password_field = self.browser.find_element_by_name('password') + password_field.send_keys(self.passwd) + password_field.send_keys(Keys.RETURN) + + # He is returned to myhome page + body = self.browser.find_element_by_tag_name('body') + self.assertIn(u'Libraries', body.text) + + # He logout + self.browser.find_elements_by_link_text(u'Log out')[0].click() + body = self.browser.find_element_by_tag_name('body') + self.assertIn(u'Log In', body.text) + + self._teardown_new_user(self.username) + + def test_can_modify_personal_infos(self): + self._login_user() + + self.browser.find_element_by_css_selector('.home-profile .avatar').click() + body = self.browser.find_element_by_tag_name('body') + self.assertIn(u'Profile Setting', body.text) + + nickname_field = self.browser.find_element_by_name('nickname') + nickname_field.send_keys(u'test_nickname2012') + + intro_field = self.browser.find_element_by_name('intro') + intro_field.send_keys('Hi, My name is test.') + + self.browser.find_element_by_css_selector('.submit').click() + + body = self.browser.find_element_by_tag_name('body') + self.assertIn(u'Successfully', body.text) + + self._logout_user() + + def _create_new_library(self, name, desc, read_only=False, encrypt=False, + passwd=None): + # He sees a button to 'add' a new repo, so he clicks it + new_repo_btn = self.browser.find_element_by_css_selector("#repo-create") + new_repo_btn.click() + + # He sees some input fields for "Name" and "description", etc + body = self.browser.find_element_by_tag_name('body') + self.assertIn(u'Name', body.text) + self.assertIn(u'Description', body.text) + + # He types in an test repo + reponame_field = self.browser.find_element_by_name('repo_name') + reponame_field.send_keys(name) + repodesc_field = self.browser.find_element_by_name('repo_desc') + repodesc_field.send_keys(desc) + if encrypt: + self.assertNotEquals(passwd, None) + self.browser.find_element_by_name('encryption').click() + self.browser.find_element_by_name('passwd').send_keys(passwd) + self.browser.find_element_by_name('passwd_again').send_keys(passwd) + if read_only: + self.browser.find_element_by_css_selector('option ~ option').click() + + # He clicks the submit button + sub_btn = self.browser.find_element_by_css_selector("#repo-create-submit") + sub_btn.click() + + # He is returned to the myhome page, where he can see his new repo, + # listed as a clickable link + new_repo_links = self.browser.find_elements_by_link_text(name) + self.assertNotEquals(len(new_repo_links), 0) + + def test_can_create_new_library(self): + self._login_user() + + '''Create a unencrypt repo''' + self._create_new_library('test_repo', 'test repo desc') + self.browser.find_elements_by_link_text('test_repo')[0].click() + # He is returned to the repo page, where he can view/add files or directories + body = self.browser.find_element_by_tag_name('body') + self.assertIn('Upload', body.text) + # He backs to Myhome page + self.browser.find_elements_by_link_text('My Home')[0].click() + + '''Create an encrypte repo''' + passwd = '123' + self._create_new_library('test_enc_repo', 'test repo desc', encrypt=True, + passwd=passwd) + self.browser.find_elements_by_link_text('test_enc_repo')[0].click() + # He is returned to the repo decryption page, where he can input passwords + self.assertIn('Password', self.browser.find_element_by_tag_name('body').text) + # He inputs the password + passwd_input = self.browser.find_element_by_name('password') + passwd_input.send_keys(passwd) + passwd_input.send_keys(Keys.RETURN) + # He is returned to the repo page, where he can view/add files or directories + body = self.browser.find_element_by_tag_name('body') + self.assertIn('Upload', body.text) + # He backs to Myhome page + self.browser.find_elements_by_link_text('My Home')[0].click() + + self._logout_user() + + def test_can_view_readonly_library(self): + self._login_user() + + '''Create read-only repo in Public Library''' + self.browser.find_elements_by_link_text('Public Library')[0].click() + body = self.browser.find_element_by_tag_name('body') + self.assertIn('Public Libraries', body.text) + self._create_new_library('test_readonly_repo', 'test read only repo', + read_only=True) + # He clicks the readonly library name + self.browser.find_elements_by_link_text('test_readonly_repo')[0].click() + # He is returned to the repo page, where he can view/add files or directories + body = self.browser.find_element_by_tag_name('body') + self.assertIn('Upload', body.text) + self._logout_user(remove_user=False) + + # Another user login and click this readonly repo + self._login_user('bar@bar.com', 'bar') + self.browser.find_elements_by_link_text('Public Library')[0].click() + self.browser.find_elements_by_link_text('test_readonly_repo')[0].click() + # He can only view repo contents, but not upload or new files + body = self.browser.find_element_by_tag_name('body') + self.assertNotIn('Upload', body.text) + self._logout_user(username='bar@bar.com') + + # Clean first user's libraries + self._login_user() + self._logout_user() + + + def _create_new_folder(self, folder_name): + # He clicks the New Directory button + self.browser.find_element_by_css_selector('#add-new-dir').click() + new_dir_input = self.browser.find_element_by_name('new_dir_name') + new_dir_input.send_keys(folder_name) + new_dir_input.send_keys(Keys.RETURN) + + def test_folder_operations(self): + self._login_user() + + # He create a new repo, clicked the repo name, and returned to the + # repo page + self._create_new_library('test_repo', 'test desc') + self.browser.find_elements_by_link_text('test_repo')[0].click() + + # He creates two folders + self._create_new_folder('dir1') + self.assertNotEquals(self.browser.find_elements_by_link_text('dir1'), None) + self._create_new_folder('dir2') + self.assertNotEquals(self.browser.find_elements_by_link_text('dir2'), None) + + '''Moving folder from one to another''' + # He clicks more op icon + ele_to_hover_over = self.browser.find_elements_by_link_text('dir1')[0] + hover = ActionChains(self.browser).move_to_element(ele_to_hover_over) + hover.perform() + + # He chooses move operation + more_op = self.browser.find_element_by_css_selector('.repo-file-list .more-op-icon') + more_op.click() + self.browser.find_elements_by_link_text('Move')[0].click() + + # He selects dir2 to move in, and click submit button + self.browser.find_element_by_css_selector('.jstree-default .jstree-closed ins').click() + self.browser.find_element_by_css_selector('.jstree-leaf a').click() + self.browser.find_element_by_css_selector('#mv-form .submit').click() + + # He sees seccessfull message + body = self.browser.find_element_by_tag_name('body') + self.assertIn('Successfully moving', body.text) + + self._logout_user() + + diff --git a/fts/views.py b/fts/views.py new file mode 100644 index 0000000000..60f00ef0ef --- /dev/null +++ b/fts/views.py @@ -0,0 +1 @@ +# Create your views here. diff --git a/run-fts.sh b/run-fts.sh new file mode 100755 index 0000000000..6b9e804539 --- /dev/null +++ b/run-fts.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +. setenv.sh + +python manage.py test fts + diff --git a/thirdpart/seaserv/__init__.py b/thirdpart/seaserv/__init__.py index faf05d2c61..87b29500fe 100644 --- a/thirdpart/seaserv/__init__.py +++ b/thirdpart/seaserv/__init__.py @@ -10,7 +10,7 @@ from service import get_org_groups, get_personal_groups_by_user, \ get_group_members, get_shared_groups_by_repo, is_group_user, \ get_org_group_repos, get_group_repos, get_org_groups_by_user, is_org_group,\ del_org_group_repo, get_org_groups_by_repo -from service import get_repos, get_repo, get_commits, get_branches, \ +from service import get_repos, get_repo, get_commits, get_branches, remove_repo, \ get_org_repos, is_repo_owner, create_org_repo, is_inner_pub_repo, \ list_org_inner_pub_repos, get_org_id_by_repo_id, list_org_shared_repos, \ list_personal_shared_repos, is_personal_repo, list_inner_pub_repos, \ diff --git a/thirdpart/seaserv/service.py b/thirdpart/seaserv/service.py index c61d12fa61..064ce226a1 100644 --- a/thirdpart/seaserv/service.py +++ b/thirdpart/seaserv/service.py @@ -296,6 +296,9 @@ def get_repos(): def get_repo(repo_id): return seafserv_threaded_rpc.get_repo(repo_id) +def remove_repo(repo_id): + seafserv_threaded_rpc.remove_repo(repo_id) + def list_personal_repos_by_owner(owner): """ List users owned repos in personal context. diff --git a/views.py b/views.py index 00d20f1886..11dd5d775a 100644 --- a/views.py +++ b/views.py @@ -38,7 +38,7 @@ from seaserv import ccnet_rpc, ccnet_threaded_rpc, get_repos, get_emailusers, \ get_repo, get_commits, get_branches, is_valid_filename, remove_group_user,\ seafserv_threaded_rpc, seafserv_rpc, get_binding_peerids, is_repo_owner, \ check_group_staff, get_personal_groups_by_user, is_inner_pub_repo, \ - del_org_group_repo, get_personal_groups, web_get_access_token, \ + del_org_group_repo, get_personal_groups, web_get_access_token, remove_repo, \ get_group, get_shared_groups_by_repo, is_group_user, check_permission, \ list_personal_shared_repos, is_org_group, get_org_id_by_group, is_org_repo,\ list_inner_pub_repos, get_org_groups_by_repo, is_org_repo_owner, \ @@ -795,7 +795,7 @@ def remove_repo(request, repo_id): is_org_repo_owner(org.org_id, repo_id, user): # Must get related useres before remove the repo usernames = get_related_users_by_org_repo(org.org_id, repo_id) - seafserv_threaded_rpc.remove_repo(repo_id) + remove_repo(repo_id) repo_deleted.send(sender=None, org_id=org.org_id, usernames=usernames, @@ -811,7 +811,7 @@ def remove_repo(request, repo_id): # perform this operation. if validate_owner(request, repo_id) or request.user.is_staff: usernames = get_related_users_by_repo(repo_id) - seafserv_threaded_rpc.remove_repo(repo_id) + remove_repo(repo_id) repo_deleted.send(sender=None, org_id=-1, usernames=usernames,