summaryrefslogtreecommitdiff
path: root/service/test
diff options
context:
space:
mode:
Diffstat (limited to 'service/test')
-rw-r--r--service/test/functional/features/environment.py2
-rw-r--r--service/test/functional/features/steps/attachments.py10
-rw-r--r--service/test/functional/features/steps/common.py2
-rw-r--r--service/test/functional/features/steps/compose.py6
-rw-r--r--service/test/functional/features/steps/login.py6
-rw-r--r--service/test/functional/features/steps/tag_list.py21
-rw-r--r--service/test/integration/test_multi_user_login.py9
-rw-r--r--service/test/support/integration/app_test_client.py6
-rw-r--r--service/test/unit/resources/test_backup_account_resource.py (renamed from service/test/unit/resources/test_account_recovery_resource.py)8
-rw-r--r--service/test/unit/resources/test_helpers.py7
-rw-r--r--service/test/unit/resources/test_login_resource.py113
11 files changed, 130 insertions, 60 deletions
diff --git a/service/test/functional/features/environment.py b/service/test/functional/features/environment.py
index d49016b6..821a762b 100644
--- a/service/test/functional/features/environment.py
+++ b/service/test/functional/features/environment.py
@@ -63,7 +63,7 @@ def before_all(context):
def _setup_webdriver(context):
- browser = context.config.userdata.get('webdriver', 'phantomjs')
+ browser = context.config.userdata.get('webdriver', 'chrome')
supported_webdrivers = {
'phantomjs': webdriver.PhantomJS,
'firefox': webdriver.Firefox,
diff --git a/service/test/functional/features/steps/attachments.py b/service/test/functional/features/steps/attachments.py
index 8852b787..37fabb6a 100644
--- a/service/test/functional/features/steps/attachments.py
+++ b/service/test/functional/features/steps/attachments.py
@@ -13,6 +13,8 @@
#
# You should have received a copy of the GNU Affero General Public License
# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
+import os
+
from email.MIMEMultipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.mime.text import MIMEText
@@ -67,8 +69,10 @@ def find_icon(context):
def upload_big_file(context):
base_dir = "test/functional/features/files/"
fname = "over_5mb.data"
+ path = os.path.abspath(os.path.join(base_dir, fname))
+
context.browser.execute_script("$('#fileupload').removeAttr('hidden');")
- fill_by_css_selector(context, '#fileupload', base_dir + fname)
+ fill_by_css_selector(context, '#fileupload', path)
find_element_by_css_selector(context, '#upload-error-message')
@@ -97,7 +101,9 @@ def should_not_show_upload_error_message(context):
def upload_attachment(context):
base_dir = "test/functional/features/files/"
fname = "5mb.data"
- fill_by_css_selector(context, '#fileupload', base_dir + fname)
+ path = os.path.abspath(os.path.join(base_dir, fname))
+
+ fill_by_css_selector(context, '#fileupload', path)
attachment_list_item = find_element_by_css_selector(context, '#attachment-list-item li a')
assert attachment_list_item.text == "%s (5.00 Mb)" % fname
diff --git a/service/test/functional/features/steps/common.py b/service/test/functional/features/steps/common.py
index edfe2a50..3e1e995e 100644
--- a/service/test/functional/features/steps/common.py
+++ b/service/test/functional/features/steps/common.py
@@ -61,7 +61,7 @@ def _wait_until_elements_are_visible_by_locator(context, locator_tuple, timeout=
def _wait_until_element_is_visible_by_locator(context, locator_tuple, timeout=TIMEOUT_IN_S):
wait = WebDriverWait(context.browser, timeout)
- wait.until(EC.presence_of_element_located(locator_tuple))
+ wait.until(EC.visibility_of_element_located(locator_tuple))
return context.browser.find_element(locator_tuple[0], locator_tuple[1])
diff --git a/service/test/functional/features/steps/compose.py b/service/test/functional/features/steps/compose.py
index 1dab1b6d..1b90052e 100644
--- a/service/test/functional/features/steps/compose.py
+++ b/service/test/functional/features/steps/compose.py
@@ -19,7 +19,9 @@ from behave import when
from common import (
fill_by_css_selector,
- find_element_by_css_selector)
+ find_element_by_css_selector,
+ find_element_by_id
+)
@when('I compose a message with')
@@ -52,7 +54,7 @@ def send_impl(context):
@when(u'I toggle the cc and bcc fields')
def collapse_cc_bcc_fields(context):
- cc_and_bcc_chevron = find_element_by_css_selector(context, '#cc-bcc-collapse')
+ cc_and_bcc_chevron = find_element_by_id(context, 'cc-bcc-collapse')
cc_and_bcc_chevron.click()
diff --git a/service/test/functional/features/steps/login.py b/service/test/functional/features/steps/login.py
index 6ee521e9..9ce37370 100644
--- a/service/test/functional/features/steps/login.py
+++ b/service/test/functional/features/steps/login.py
@@ -29,13 +29,13 @@ def login_page(context):
@when(u'I enter {username} and {password} as credentials')
def enter_credentials(context, username, password):
- fill_by_css_selector(context, 'input#email', context.username)
- fill_by_css_selector(context, 'input#password', password)
+ fill_by_css_selector(context, 'input[name="username"]', context.username)
+ fill_by_css_selector(context, 'input[name="password"]', password)
@when(u'I click on the login button')
def click_login(context):
- find_element_by_css_selector(context, 'input[name="login"]').click()
+ find_element_by_css_selector(context, 'button[type="submit"]').click()
@then(u'I should see the fancy interstitial')
diff --git a/service/test/functional/features/steps/tag_list.py b/service/test/functional/features/steps/tag_list.py
index daea416d..e3382a61 100644
--- a/service/test/functional/features/steps/tag_list.py
+++ b/service/test/functional/features/steps/tag_list.py
@@ -14,11 +14,10 @@
# You should have received a copy of the GNU Affero General Public License
# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
from behave import when
-from selenium.common.exceptions import TimeoutException
+from selenium.common.exceptions import TimeoutException, StaleElementReferenceException
from common import (
find_element_by_class_name,
- find_element_by_id,
find_element_by_css_selector,
wait_for_user_alert_to_disapear)
@@ -37,12 +36,11 @@ def expand_side_nav(context):
if is_side_nav_expanded(context):
return
- toggle = find_element_by_class_name(context, 'side-nav-toggle')
- toggle.click()
+ find_element_by_css_selector(context, '.side-nav-toggle-icon i').click()
@when('I select the tag \'{tag}\'')
-def impl(context, tag):
+def select_tag(context, tag):
wait_for_user_alert_to_disapear(context)
expand_side_nav(context)
@@ -53,23 +51,14 @@ def impl(context, tag):
try:
find_element_by_css_selector(context, '#tag-%s' % tag)
- e = find_element_by_id(context, 'tag-%s' % tag)
+ e = find_element_by_css_selector(context, '#tag-%s .tag-label' % tag)
e.click()
find_element_by_css_selector(context, ".mail-list-entry__item[href*='%s']" % tag)
success = True
- except TimeoutException:
+ except (TimeoutException, StaleElementReferenceException):
pass
finally:
try_again -= 1
assert success
-
-
-@when('I am in \'{tag}\'')
-def impl(context, tag):
- expand_side_nav(context)
-
- find_element_by_css_selector(context, '#tag-%s' % tag)
- e = find_element_by_id(context, 'tag-%s' % tag)
- assert "selected" in e.get_attribute("class")
diff --git a/service/test/integration/test_multi_user_login.py b/service/test/integration/test_multi_user_login.py
index fe456583..04cceec3 100644
--- a/service/test/integration/test_multi_user_login.py
+++ b/service/test/integration/test_multi_user_login.py
@@ -13,7 +13,6 @@
#
# You should have received a copy of the GNU Affero General Public License
# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
-from mock import patch
from twisted.internet import defer
@@ -47,8 +46,8 @@ class MultiUserLoginTest(MultiUserSoledadTestBase):
self.assertEquals(val, response[key])
@defer.inlineCallbacks
- def test_wrong_credentials_cannot_access_resources(self):
+ def test_wrong_credentials_is_redirected_to_login(self):
response, login_request = self.app_test_client.login('username', 'wrong_password')
- response_str = yield response
- self.assertEqual(401, login_request.responseCode)
- self.assertIn('Invalid username or password', login_request.written)
+ yield response
+ self.assertEqual(302, login_request.responseCode)
+ self.assertIn('/login?auth-error', login_request.responseHeaders.getRawHeaders('location'))
diff --git a/service/test/support/integration/app_test_client.py b/service/test/support/integration/app_test_client.py
index d52c85c0..538cf633 100644
--- a/service/test/support/integration/app_test_client.py
+++ b/service/test/support/integration/app_test_client.py
@@ -429,8 +429,6 @@ def initialize_soledad(tempdir, uuid):
def __call__(self):
return self
- Soledad._shared_db = MockSharedDB()
-
_soledad = Soledad(
uuid,
passphrase,
@@ -438,8 +436,8 @@ def initialize_soledad(tempdir, uuid):
local_db_path,
server_url,
cert_file,
- defer_encryption=False,
- syncable=False)
+ shared_db=MockSharedDB()
+ )
yield SoledadMailAdaptor().initialize_store(_soledad)
diff --git a/service/test/unit/resources/test_account_recovery_resource.py b/service/test/unit/resources/test_backup_account_resource.py
index 01ffaed2..21ae5aab 100644
--- a/service/test/unit/resources/test_account_recovery_resource.py
+++ b/service/test/unit/resources/test_backup_account_resource.py
@@ -20,18 +20,18 @@ from mock import MagicMock, patch
from twisted.trial import unittest
from twisted.web.test.requesthelper import DummyRequest
-from pixelated.resources.account_recovery_resource import AccountRecoveryResource
+from pixelated.resources.backup_account_resource import BackupAccountResource
from test.unit.resources import DummySite
-class TestAccountRecoveryResource(unittest.TestCase):
+class TestBackupAccountResource(unittest.TestCase):
def setUp(self):
self.services_factory = MagicMock()
- self.resource = AccountRecoveryResource(self.services_factory)
+ self.resource = BackupAccountResource(self.services_factory)
self.web = DummySite(self.resource)
def test_get(self):
- request = DummyRequest(['/recovery'])
+ request = DummyRequest(['/backup-account'])
request.method = 'GET'
d = self.web.get(request)
diff --git a/service/test/unit/resources/test_helpers.py b/service/test/unit/resources/test_helpers.py
index e21c5373..6c456f51 100644
--- a/service/test/unit/resources/test_helpers.py
+++ b/service/test/unit/resources/test_helpers.py
@@ -18,6 +18,7 @@ from twisted.trial import unittest
import re
from pixelated.resources import respond_json, respond_json_deferred
+from pixelated.resources import get_public_static_folder, get_protected_static_folder
from test.unit.resources import DummySite
from twisted.web.test.requesthelper import DummyRequest
@@ -44,3 +45,9 @@ class TestHelpers(unittest.TestCase):
self.assertEqual(b"{\"test\": \"yep\"}", request.written[0])
self.assertEqual([b"application/json"],
request.responseHeaders.getRawHeaders("Content-Type"))
+
+ def test_getting_public_folder_returns_path(self):
+ self.assertIn('web-ui/dist/public', get_public_static_folder())
+
+ def test_getting_protected_folder_returns_path(self):
+ self.assertIn('web-ui/dist/protected', get_protected_static_folder())
diff --git a/service/test/unit/resources/test_login_resource.py b/service/test/unit/resources/test_login_resource.py
index cec57123..733583a3 100644
--- a/service/test/unit/resources/test_login_resource.py
+++ b/service/test/unit/resources/test_login_resource.py
@@ -23,7 +23,7 @@ from twisted.internet import defer
from twisted.trial import unittest
from twisted.web.test.requesthelper import DummyRequest
-from pixelated.resources.login_resource import LoginResource
+from pixelated.resources.login_resource import LoginResource, LoginStatusResource
from pixelated.resources.login_resource import parse_accept_language
from test.unit.resources import DummySite
@@ -87,23 +87,15 @@ class TestLoginResource(unittest.TestCase):
d = self.web.get(request)
- def assert_form_rendered(_):
+ def assert_login_page_rendered(_):
self.assertEqual(200, request.responseCode)
- form_action = 'action="/login"'
- form_method = 'method="post"'
- input_username = 'name="username"'
- input_password = 'name="password"'
- input_submit = 'name="login"'
+ title = 'Pixelated - Login'
default_disclaimer = 'Some disclaimer'
written_response = ''.join(request.written)
- self.assertIn(form_action, written_response)
- self.assertIn(form_method, written_response)
- self.assertIn(input_password, written_response)
- self.assertIn(input_submit, written_response)
- self.assertIn(input_username, written_response)
+ self.assertIn(title, written_response)
self.assertIn(default_disclaimer, written_response)
- d.addCallback(assert_form_rendered)
+ d.addCallback(assert_login_page_rendered)
return d
def _write(self, filename, content):
@@ -211,22 +203,23 @@ class TestLoginPOST(unittest.TestCase):
return d
@patch('pixelated.config.leap.BootstrapUserServices.setup')
+ @patch('twisted.web.util.redirectTo')
@patch('pixelated.authentication.Authenticator.authenticate')
- def test_should_return_form_back_with_error_message_when_login_fails(self, mock_authenticate,
- mock_user_bootstrap_setup):
+ def test_should_redirect_to_login_with_error_flag_when_login_fails(self, mock_authenticate,
+ mock_redirect,
+ mock_user_bootstrap_setup):
mock_authenticate.side_effect = UnauthorizedLogin()
+ mock_redirect.return_value = "mocked redirection"
d = self.web.get(self.request)
- def assert_error_response_and_user_services_not_setup(_):
+ def assert_redirected_to_login(_):
mock_authenticate.assert_called_once_with(self.username, self.password)
- self.assertEqual(401, self.request.responseCode)
- written_response = ''.join(self.request.written)
- self.assertIn('Invalid username or password', written_response)
+ mock_redirect.assert_called_once_with('/login?auth-error', self.request)
self.assertFalse(mock_user_bootstrap_setup.called)
self.assertFalse(self.resource.get_session(self.request).is_logged_in())
- d.addCallback(assert_error_response_and_user_services_not_setup)
+ d.addCallback(assert_redirected_to_login)
return d
@patch('pixelated.config.leap.BootstrapUserServices.setup')
@@ -238,7 +231,7 @@ class TestLoginPOST(unittest.TestCase):
def assert_interstitial_in_response(_):
mock_authenticate.assert_called_once_with(self.username, self.password)
- interstitial_js_in_template = '<script src="startup-assets/Interstitial.js"></script>'
+ interstitial_js_in_template = '<script src="/public/interstitial.js"></script>'
self.assertIn(interstitial_js_in_template, self.request.written[0])
d.addCallback(assert_interstitial_in_response)
@@ -259,7 +252,7 @@ class TestLoginPOST(unittest.TestCase):
@patch('pixelated.config.leap.BootstrapUserServices.setup')
@patch('pixelated.authentication.Authenticator.authenticate')
- def test_successful_adds_cookies_to_indicat_logged_in_status_when_services_are_loaded(self, mock_authenticate, mock_user_bootstrap_setup):
+ def test_successful_adds_cookies_to_indicate_logged_in_status_when_services_are_loaded(self, mock_authenticate, mock_user_bootstrap_setup):
mock_authenticate.return_value = self.user_auth
irrelevant = None
mock_user_bootstrap_setup.return_value = defer.succeed(irrelevant)
@@ -271,3 +264,79 @@ class TestLoginPOST(unittest.TestCase):
d.addCallback(assert_login_setup_service_for_user)
return d
+
+ @patch('pixelated.resources.session.PixelatedSession.login_started')
+ @patch('pixelated.authentication.Authenticator.authenticate')
+ def test_session_adds_login_started_status_after_authentication(self, mock_authenticate, mock_login_started):
+ mock_authenticate.return_value = self.user_auth
+
+ d = self.web.get(self.request)
+
+ def assert_login_started_called(_):
+ mock_login_started.assert_called_once()
+
+ d.addCallback(assert_login_started_called)
+ return d
+
+ @patch('pixelated.resources.session.PixelatedSession.login_successful')
+ @patch('pixelated.config.leap.BootstrapUserServices.setup')
+ @patch('pixelated.authentication.Authenticator.authenticate')
+ def test_session_adds_login_successful_status_when_services_setup_finishes(self, mock_authenticate, mock_user_bootstrap_setup, mock_login_successful):
+ mock_authenticate.return_value = self.user_auth
+ mock_user_bootstrap_setup.return_value = defer.succeed(None)
+
+ d = self.web.get(self.request)
+
+ def assert_login_successful_called(_):
+ mock_login_successful.assert_called_once()
+
+ d.addCallback(assert_login_successful_called)
+ return d
+
+ @patch('pixelated.resources.session.PixelatedSession.login_error')
+ @patch('pixelated.config.leap.BootstrapUserServices.setup')
+ @patch('pixelated.authentication.Authenticator.authenticate')
+ def test_session_adds_login_error_status_when_services_setup_gets_error(self, mock_authenticate, mock_user_bootstrap_setup, mock_login_error):
+ mock_authenticate.return_value = self.user_auth
+ mock_user_bootstrap_setup.return_value = defer.fail(Exception('Could not setup user services'))
+
+ d = self.web.get(self.request)
+
+ def assert_login_error_called(_):
+ mock_login_error.assert_called_once()
+
+ d.addCallback(assert_login_error_called)
+ return d
+
+
+class TestLoginStatus(unittest.TestCase):
+ def setUp(self):
+ self.services_factory = mock()
+ self.resource = LoginStatusResource(self.services_factory)
+ self.web = DummySite(self.resource)
+
+ self.request = DummyRequest(['/status'])
+
+ def test_login_status_completed_when_single_user(self):
+ self.services_factory.mode = mock()
+ self.services_factory.mode.is_single_user = True
+ d = self.web.get(self.request)
+
+ def assert_login_completed(_):
+ self.assertIn('completed', self.request.written[0])
+
+ d.addCallback(assert_login_completed)
+ return d
+
+ @patch('pixelated.resources.session.PixelatedSession.check_login_status')
+ def test_login_status_when_multi_user_returns_check_login_status(self, mock_login_status):
+ self.services_factory.mode = mock()
+ self.services_factory.mode.is_single_user = False
+ mock_login_status.return_value = 'started'
+ d = self.web.get(self.request)
+
+ def assert_login_completed(_):
+ self.assertIn('started', self.request.written[0])
+
+ d.addCallback(assert_login_completed)
+ return d