diff options
Diffstat (limited to 'service/test')
| -rw-r--r-- | service/test/functional/features/environment.py | 145 | ||||
| -rw-r--r-- | service/test/functional/features/smoke.feature | 36 | ||||
| -rw-r--r-- | service/test/functional/features/steps/attachments.py | 24 | ||||
| -rw-r--r-- | service/test/functional/features/steps/common.py | 46 | ||||
| -rw-r--r-- | service/test/functional/features/steps/compose.py | 7 | ||||
| -rw-r--r-- | service/test/functional/features/steps/data_setup.py | 4 | ||||
| -rw-r--r-- | service/test/functional/features/steps/login.py | 24 | ||||
| -rw-r--r-- | service/test/functional/features/steps/mail_list.py | 44 | ||||
| -rw-r--r-- | service/test/functional/features/steps/mail_view.py | 12 | ||||
| -rw-r--r-- | service/test/functional/features/steps/search.py | 6 | ||||
| -rw-r--r-- | service/test/functional/features/steps/signup.py | 44 | ||||
| -rw-r--r-- | service/test/functional/features/steps/tag_list.py | 10 | ||||
| -rw-r--r-- | service/test/integration/test_multi_user_login.py | 2 | ||||
| -rw-r--r-- | service/test/unit/adapter/services/test_mail_sender.py | 20 | ||||
| -rw-r--r-- | service/test/unit/resources/test_login_resource.py | 2 | 
15 files changed, 300 insertions, 126 deletions
| diff --git a/service/test/functional/features/environment.py b/service/test/functional/features/environment.py index 77efc499..d49016b6 100644 --- a/service/test/functional/features/environment.py +++ b/service/test/functional/features/environment.py @@ -13,31 +13,29 @@  #  # 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 uuid  import os +import re +import time +from urlparse import urlparse +import uuid -from selenium import webdriver  from crochet import setup, wait_for - -from twisted.internet import defer -from twisted.logger import globalLogBeginner, textFileLogObserver, Logger - -from test.support.integration import AppTestClient -from steps.common import * -  from leap.common.events.server import ensure_server +from selenium import webdriver +from twisted.internet import defer  from pixelated.application import UserAgentMode  from pixelated.config.site import PixelatedSite  from pixelated.resources.features_resource import FeaturesResource +from test.support.integration import AppTestClient +from steps.common import DEFAULT_IMPLICIT_WAIT_TIMEOUT_IN_S -setup() -observers = [textFileLogObserver(open(os.devnull, 'w'))] +class UnsuportedWebDriverError(Exception): +    pass -globalLogBeginner.beginLoggingTo(observers) -Logger('twisted') +setup()  @wait_for(timeout=5.0) @@ -46,61 +44,116 @@ def start_app_test_client(client, mode):  def before_all(context): +    _setup_webdriver(context) +    userdata = context.config.userdata +    context.host = userdata.get('host', 'http://localhost') + +    if not context.host.startswith('http'): +        context.host = 'https://{}'.format(context.host) + +    hostname = urlparse(context.host).hostname +    context.signup_url = 'https://{}/signup'.format(hostname) +    context.login_url = 'https://mail.{}/login'.format(hostname) +    context.username = 'testuser_{}'.format(uuid.uuid4()) + +    if 'localhost' in context.host: +        _mock_user_agent(context) +        context.login_url = context.multi_user_url + '/login' +        context.username = 'username' + + +def _setup_webdriver(context): +    browser = context.config.userdata.get('webdriver', 'phantomjs') +    supported_webdrivers = { +        'phantomjs': webdriver.PhantomJS, +        'firefox': webdriver.Firefox, +        'chrome': webdriver.Chrome, +    } + +    try: +        context.browser = supported_webdrivers[browser]() +    except KeyError: +        raise UnsuportedWebDriverError('{} is not a supported webdriver'.format(browser)) + +    context.browser.set_window_size(1280, 1024) +    context.browser.implicitly_wait(DEFAULT_IMPLICIT_WAIT_TIMEOUT_IN_S) +    context.browser.set_page_load_timeout(60) + + +def _mock_user_agent(context):      ensure_server()      PixelatedSite.disable_csp_requests() -    client = AppTestClient() -    start_app_test_client(client, UserAgentMode(is_single_user=True)) -    client.listenTCP(port=8889)      FeaturesResource.DISABLED_FEATURES.append('autoRefresh') -    context.client = client -    multi_user_client = AppTestClient() -    start_app_test_client(multi_user_client, UserAgentMode(is_single_user=False)) -    multi_user_client.listenTCP(port=MULTI_USER_PORT) -    context.multi_user_client = multi_user_client +    context.single_user_url = _define_url(8889) +    context.single_user_client = _start_user_agent(8889, is_single_user=True) + +    context.multi_user_url = _define_url(4568) +    context.multi_user_client = _start_user_agent(4568, is_single_user=False) + + +def _start_user_agent(port, is_single_user): +    client = AppTestClient() +    start_app_test_client(client, UserAgentMode(is_single_user=is_single_user)) +    client.listenTCP(port=port) +    return client + + +def _define_url(port): +    return 'http://localhost:{port}'.format(port=port)  def after_all(context): -    context.client.stop() +    context.browser.quit() +    if 'localhost' in context.host: +        context.single_user_client.stop()  def before_feature(context, feature): -    # context.browser = webdriver.Chrome() -    # context.browser = webdriver.Firefox() -    context.browser = webdriver.PhantomJS() -    context.browser.set_window_size(1280, 1024) -    context.browser.implicitly_wait(DEFAULT_IMPLICIT_WAIT_TIMEOUT_IN_S) -    context.browser.set_page_load_timeout(60)  # wait for data -    context.browser.get(HOMEPAGE_URL) +    if 'localhost' in context.host: +        context.browser.get(context.single_user_url) + + +def after_feature(context, feature): +    if 'localhost' in context.host: +        cleanup_all_mails(context) +        context.last_mail = None  def after_step(context, step): -    if step.status == 'failed': -        id = str(uuid.uuid4()) -        os.chdir("screenshots") -        context.browser.save_screenshot('failed ' + str(step.name) + '_' + id + ".png") -        save_source(context, 'failed ' + str(step.name) + '_' + id + ".html") -        os.chdir("../") +    _debug_on_error(context, step) +    _save_screenshot(context, step) -def after_feature(context, feature): -    context.browser.quit() +def _debug_on_error(context, step): +    if step.status == 'failed' and context.config.userdata.getbool("debug"): +        try: +            import ipdb +            ipdb.post_mortem(step.exc_traceback) +        except ImportError: +            import pdb +            pdb.post_mortem(step.exc_traceback) -    cleanup_all_mails(context) -    context.last_mail = None + +def _save_screenshot(context, step): +    if (step.status == 'failed' and +            context.config.userdata.getbool("screenshots", True)): +        timestamp = time.strftime("%Y-%m-%d-%H-%M-%S") +        filename = _slugify('{} failed {}'.format(timestamp, str(step.name))) +        filepath = os.path.join('screenshots', filename + '.png') +        context.browser.save_screenshot(filepath) + + +def _slugify(string_): +    return re.sub('\W', '-', string_)  @wait_for(timeout=10.0)  def cleanup_all_mails(context):      @defer.inlineCallbacks      def _delete_all_mails(): -        mails = yield context.client.mail_store.all_mails() +        mails = yield context.single_user_client.mail_store.all_mails()          for mail in mails: -            yield context.client.mail_store.delete_mail(mail.ident) +            yield context.single_user_client.mail_store.delete_mail(mail.ident)      return _delete_all_mails() - - -def save_source(context, filename='/tmp/source.html'): -    with open(filename, 'w') as out: -        out.write(context.browser.page_source.encode('utf8')) diff --git a/service/test/functional/features/smoke.feature b/service/test/functional/features/smoke.feature new file mode 100644 index 00000000..724c680c --- /dev/null +++ b/service/test/functional/features/smoke.feature @@ -0,0 +1,36 @@ +# +# Copyright (c) 2016 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated 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.  See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see <http://www.gnu.org/licenses/>. + +@smoke +Feature: sign up, login and logout +  As a visitor of Pixelated +  I want to sign up +  So I can log in to my account and see the welcome email + +  Scenario: Visitor creates his account +    Given a user is accessing the signup page +    When I enter username, password and password confirmation +    And I click on the signup button +    Then I should see the user control panel + +  Scenario: Existing user logs into his account +    Given a user is accessing the login page +    When I enter username and password as credentials +    And I click on the login button +    Then I should see the fancy interstitial +    Then I have mails +    When I logout +    Then I should see the login page diff --git a/service/test/functional/features/steps/attachments.py b/service/test/functional/features/steps/attachments.py index 28d88343..43948016 100644 --- a/service/test/functional/features/steps/attachments.py +++ b/service/test/functional/features/steps/attachments.py @@ -13,16 +13,21 @@  #  # 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 email.mime.application import MIMEApplication -from time import sleep -from leap.bitmask.mail.mail import Message -from common import * -from test.support.integration import MailBuilder -from behave import given -from crochet import wait_for -from uuid import uuid4  from email.MIMEMultipart import MIMEMultipart +from email.mime.application import MIMEApplication  from email.mime.text import MIMEText +from uuid import uuid4 + +from behave import given, then, when +from crochet import wait_for +from selenium.webdriver.common.by import By + +from common import ( +    fill_by_css_selector, +    find_element_by_css_selector, +    find_elements_by_css_selector, +    page_has_css, +    wait_until_element_is_visible_by_locator)  @given(u'I have a mail with an attachment in my inbox') @@ -46,7 +51,7 @@ def build_mail_with_attachment(subject):  @wait_for(timeout=10.0)  def load_mail_into_soledad(context, mail): -    return context.client.mail_store.add_mail('INBOX', mail.as_string()) +    return context.single_user_client.mail_store.add_mail('INBOX', mail.as_string())  @then(u'I see the mail has an attachment') @@ -107,6 +112,5 @@ def click_remove_icon(context):  @then(u'I should not see it attached')  def assert_attachment_removed(context): -    attachments_list_ul = find_elements_by_css_selector(context, '#attachment-list-item')      attachments_list_li = context.browser.find_elements(By.CSS_SELECTOR, '#attachment-list-item li a')      assert len(attachments_list_li) == 0 diff --git a/service/test/functional/features/steps/common.py b/service/test/functional/features/steps/common.py index ccad842c..f2cab1a6 100644 --- a/service/test/functional/features/steps/common.py +++ b/service/test/functional/features/steps/common.py @@ -13,25 +13,22 @@  #  # 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 time + +from selenium.common.exceptions import ( +    StaleElementReferenceException, +    TimeoutException)  from selenium.webdriver.common.by import By  from selenium.webdriver.support import expected_conditions as EC  from selenium.webdriver.support.wait import WebDriverWait -from selenium.common.exceptions import TimeoutException, StaleElementReferenceException -import time -from test.support.integration import MailBuilder -LOADING = 'loading' +from test.support.integration import MailBuilder  TIMEOUT_IN_S = 20  DEFAULT_IMPLICIT_WAIT_TIMEOUT_IN_S = 10.0 -HOMEPAGE_URL = 'http://localhost:8889/' - -MULTI_USER_PORT = 4568 - -MULTI_USER_URL = 'http://localhost:%d/' % MULTI_USER_PORT -  class ImplicitWait(object):      def __init__(self, context, timeout=5.0): @@ -69,15 +66,9 @@ def wait_until_elements_are_visible_by_locator(context, locator_tuple, timeout=T      return context.browser.find_elements(locator_tuple[0], locator_tuple[1]) -def wait_until_elements_are_visible_by_xpath(context, locator_tuple, timeout=TIMEOUT_IN_S): -    wait = WebDriverWait(context.browser, timeout) -    wait.until(EC.presence_of_all_elements_located(locator_tuple)) -    return context.browser.find_elements(locator_tuple[0], locator_tuple[1]) - -  def wait_until_element_is_visible_by_locator(context, locator_tuple, timeout=TIMEOUT_IN_S):      wait = WebDriverWait(context.browser, timeout) -    wait.until(EC.visibility_of_element_located(locator_tuple)) +    wait.until(EC.presence_of_element_located(locator_tuple))      return context.browser.find_element(locator_tuple[0], locator_tuple[1]) @@ -91,8 +82,8 @@ def fill_by_xpath(context, xpath, text):      field.send_keys(text) -def fill_by_css_selector(context, css_selector, text): -    field = find_element_by_css_selector(context, css_selector) +def fill_by_css_selector(context, css_selector, text, timeout=TIMEOUT_IN_S): +    field = find_element_by_css_selector(context, css_selector, timeout=timeout)      field.send_keys(text) @@ -100,11 +91,6 @@ def take_screenshot(context, filename):      context.browser.save_screenshot(filename) -def dump_source_to(context, filename): -    with open(filename, 'w') as out: -        out.write(context.browser.page_source.encode('utf8')) - -  def page_has_css(context, css):      try:          find_element_by_css_selector(context, css) @@ -121,8 +107,8 @@ def find_element_by_id(context, id):      return wait_until_element_is_visible_by_locator(context, (By.ID, id)) -def find_element_by_css_selector(context, css_selector): -    return wait_until_element_is_visible_by_locator(context, (By.CSS_SELECTOR, css_selector)) +def find_element_by_css_selector(context, css_selector, timeout=TIMEOUT_IN_S): +    return wait_until_element_is_visible_by_locator(context, (By.CSS_SELECTOR, css_selector), timeout=timeout)  def find_element_by_class_name(context, class_name): @@ -133,8 +119,8 @@ def find_elements_by_css_selector(context, css_selector, timeout=TIMEOUT_IN_S):      return wait_until_elements_are_visible_by_locator(context, (By.CSS_SELECTOR, css_selector), timeout=timeout) -def find_elements_by_xpath(context, xpath): -    return wait_until_elements_are_visible_by_xpath(context, (By.XPATH, xpath)) +def find_elements_by_xpath(context, xpath, timeout=TIMEOUT_IN_S): +    return wait_until_elements_are_visible_by_locator(context, (By.XPATH, xpath), timeout=timeout)  def find_element_containing_text(context, text, element_type='*'): @@ -186,9 +172,9 @@ def get_console_log(context):      for entry in logs:          msg = entry['message']          if not (msg.startswith('x  off') or msg.startswith('<- on')): -            print entry['message'] +            print(entry['message'])  def create_email(context):      input_mail = MailBuilder().build_input_mail() -    context.client.add_mail_to_inbox(input_mail) +    context.single_user_client.add_mail_to_inbox(input_mail) diff --git a/service/test/functional/features/steps/compose.py b/service/test/functional/features/steps/compose.py index 67b1bd51..c72b25e2 100644 --- a/service/test/functional/features/steps/compose.py +++ b/service/test/functional/features/steps/compose.py @@ -16,7 +16,12 @@  from time import sleep  from behave import when -from common import * +from selenium.webdriver.common.by import By + +from common import ( +    fill_by_css_selector, +    wait_until_element_is_visible_by_locator, +    find_element_by_css_selector)  @when('I compose a message with') diff --git a/service/test/functional/features/steps/data_setup.py b/service/test/functional/features/steps/data_setup.py index 167acf9a..3d28baed 100644 --- a/service/test/functional/features/steps/data_setup.py +++ b/service/test/functional/features/steps/data_setup.py @@ -26,8 +26,8 @@ def add_mail_impl(context):      input_mail = MailBuilder().with_subject(subject).build_input_mail() -    context.client.add_mail_to_inbox(input_mail) -    wait_for_condition(context, lambda _: context.client.search_engine.search(subject)[1] > 0, poll_frequency=0.1) +    context.single_user_client.add_mail_to_inbox(input_mail) +    wait_for_condition(context, lambda _: context.single_user_client.search_engine.search(subject)[1] > 0, poll_frequency=0.1)      context.last_subject = subject diff --git a/service/test/functional/features/steps/login.py b/service/test/functional/features/steps/login.py index 2a653030..b5e88608 100644 --- a/service/test/functional/features/steps/login.py +++ b/service/test/functional/features/steps/login.py @@ -15,49 +15,45 @@  # along with Pixelated. If not, see <http://www.gnu.org/licenses/>.  import time -from behave import when, then -from selenium.webdriver.common.by import By +from behave import given, when, then  from common import (      fill_by_css_selector, -    find_element_by_css_selector, -    MULTI_USER_URL, -    wait_until_element_is_visible_by_locator) +    find_element_by_css_selector) +@given(u'a user is accessing the login page')  @when(u'I open the login page')  def login_page(context): -    context.browser.get(MULTI_USER_URL + '/login') +    context.browser.get(context.login_url)  @when(u'I enter {username} and {password} as credentials')  def enter_credentials(context, username, password): -    fill_by_css_selector(context, 'input#email', username) +    fill_by_css_selector(context, 'input#email', context.username)      fill_by_css_selector(context, 'input#password', password)  @when(u'I click on the login button')  def click_login(context): -    login_button = wait_until_element_is_visible_by_locator(context, (By.CSS_SELECTOR, 'input[name="login"]')) -    login_button.click() +    find_element_by_css_selector(context, 'input[name="login"]').click()  @then(u'I should see the fancy interstitial')  def step_impl(context): -    assert find_element_by_css_selector(context, 'section#hive-section') +    find_element_by_css_selector(context, 'section#hive-section')      _wait_for_interstitial_to_reload()  def _wait_for_interstitial_to_reload(): -    time.sleep(6) +    time.sleep(10)  @when(u'I logout')  def click_logout(context): -    logout_button = wait_until_element_is_visible_by_locator(context, (By.CSS_SELECTOR, 'ul#logout')) -    logout_button.click() +    find_element_by_css_selector(context, '#logout-form div').click()  @then(u'I should see the login page')  def see_login_page(context): -    assert find_element_by_css_selector(context, 'form#login_form') +    find_element_by_css_selector(context, 'form#login_form') diff --git a/service/test/functional/features/steps/mail_list.py b/service/test/functional/features/steps/mail_list.py index 82faa7af..23724bf2 100644 --- a/service/test/functional/features/steps/mail_list.py +++ b/service/test/functional/features/steps/mail_list.py @@ -13,12 +13,25 @@  #  # 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 common import * -from selenium.common.exceptions import NoSuchElementException + +from behave import when, then, given +from selenium.common.exceptions import TimeoutException +from selenium.webdriver.common.by import By + +from common import ( +    ImplicitWait, +    execute_ignoring_staleness, +    find_element_by_id, +    find_element_by_css_selector, +    mail_list_with_subject_exists, +    wait_for_condition, +    wait_for_loading_to_finish, +    wait_until_element_is_visible_by_locator, +    wait_until_elements_are_visible_by_locator)  def find_current_mail(context): -    print 'searching for mail [%s]' % context.current_mail_id +    print('searching for mail [%s]' % context.current_mail_id)      return find_element_by_id(context, '%s' % context.current_mail_id) @@ -78,31 +91,28 @@ def impl(context):  @given('I have mails')  @then(u'I have mails')  def impl(context): -    emails = wait_until_elements_are_visible_by_locator(context, (By.CSS_SELECTOR, '.mail-list-entry__item')) +    emails = wait_until_elements_are_visible_by_locator(context, (By.CSS_SELECTOR, '.mail-list-entry'))      assert len(emails) > 0  @when('I mark the first unread email as read')  def impl(context): -    emails = wait_until_elements_are_visible_by_locator(context, (By.CSS_SELECTOR, '.mail-list-entry')) +    mail_id = find_element_by_css_selector( +        context, '.mail-list-entry:not(.status-read)').get_attribute('id') -    for email in emails: -        if 'status-read' not in email.get_attribute('class'): -            context.current_mail_id = email.get_attribute('id')  # we need to get the mail id before manipulating the page -            email.find_element_by_tag_name('input').click() -            find_element_by_id(context, 'mark-selected-as-read').click() -            break -    wait_until_elements_are_visible_by_locator(context, (By.CSS_SELECTOR, '#%s.status-read' % context.current_mail_id)) +    find_element_by_css_selector(context, '#%s input' % mail_id).click() +    find_element_by_id(context, 'mark-selected-as-read').click() + +    find_element_by_css_selector(context, '#%s.status-read' % mail_id)  @when('I delete the email')  def impl(context): -    def last_email(): -        return wait_until_element_is_visible_by_locator(context, (By.CSS_SELECTOR, '.mail-list-entry')) -    mail = last_email() -    context.current_mail_id = mail.get_attribute('id') -    mail.find_element_by_tag_name('input').click() +    mail_id = find_element_by_css_selector(context, '.mail-list-entry').get_attribute('id') + +    find_element_by_css_selector(context, '#%s input' % mail_id).click()      find_element_by_id(context, 'delete-selected').click() +      _wait_for_mail_list_to_be_empty(context) diff --git a/service/test/functional/features/steps/mail_view.py b/service/test/functional/features/steps/mail_view.py index 2db6dfc5..88ee5c5a 100644 --- a/service/test/functional/features/steps/mail_view.py +++ b/service/test/functional/features/steps/mail_view.py @@ -13,8 +13,18 @@  #  # 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 then, when  from selenium.webdriver.common.keys import Keys -from common import * +from selenium.webdriver.common.by import By + +from common import ( +    click_button, +    find_element_by_css_selector, +    find_elements_by_css_selector, +    reply_subject, +    wait_until_button_is_visible, +    wait_until_element_is_visible_by_locator)  @then('I see that the subject reads \'{subject}\'') diff --git a/service/test/functional/features/steps/search.py b/service/test/functional/features/steps/search.py index 879e834d..5a6d2d1c 100644 --- a/service/test/functional/features/steps/search.py +++ b/service/test/functional/features/steps/search.py @@ -13,10 +13,12 @@  #  # 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 selenium.webdriver import ActionChains +from behave import when, then +from selenium.webdriver import ActionChains  from selenium.webdriver.common.keys import Keys -from common import * + +from common import find_element_by_css_selector, find_elements_by_css_selector  @when('I search for a mail with the words "{search_term}"') diff --git a/service/test/functional/features/steps/signup.py b/service/test/functional/features/steps/signup.py new file mode 100644 index 00000000..43480666 --- /dev/null +++ b/service/test/functional/features/steps/signup.py @@ -0,0 +1,44 @@ +# +# Copyright (c) 2016 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated 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.  See the +# GNU Affero General Public License for more details. +# +# 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 given, then, when + +from common import ( +    element_should_have_content, +    fill_by_css_selector, +    find_element_by_css_selector) + + +@given(u'a user is accessing the signup page')  # noqa +def step_impl(context): +    context.browser.get(context.signup_url) + + +@when(u'I enter username, password and password confirmation')  # noqa +def step_impl(context): +    fill_by_css_selector(context, '#srp_username', context.username) +    fill_by_css_selector(context, '#srp_password', 'password') +    fill_by_css_selector(context, '#srp_password_confirmation', 'password') + + +@when(u'I click on the signup button')  # noqa +def step_impl(context): +    find_element_by_css_selector(context, 'button[type=submit]').click() + + +@then(u'I should see the user control panel')  # noqa +def step_impl(context): +    element_should_have_content(context, 'h1', 'user control panel') diff --git a/service/test/functional/features/steps/tag_list.py b/service/test/functional/features/steps/tag_list.py index 8550a886..b9adea0a 100644 --- a/service/test/functional/features/steps/tag_list.py +++ b/service/test/functional/features/steps/tag_list.py @@ -13,7 +13,15 @@  #  # 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 common import * +from behave import when +from selenium.common.exceptions import TimeoutException +from selenium.webdriver.common.by import By + +from common import ( +    find_element_by_class_name, +    find_element_by_id, +    wait_for_user_alert_to_disapear, +    wait_until_element_is_visible_by_locator)  def click_first_element_with_class(context, classname): diff --git a/service/test/integration/test_multi_user_login.py b/service/test/integration/test_multi_user_login.py index e1f58202..2008b320 100644 --- a/service/test/integration/test_multi_user_login.py +++ b/service/test/integration/test_multi_user_login.py @@ -53,4 +53,4 @@ class MultiUserLoginTest(MultiUserSoledadTestBase):          response, login_request = self.app_test_client.login('username', 'wrong_password', session=first_request.getSession())          response_str = yield response          self.assertEqual(401, login_request.responseCode) -        self.assertIn('Invalid credentials', login_request.written) +        self.assertIn('Invalid username or password', login_request.written) diff --git a/service/test/unit/adapter/services/test_mail_sender.py b/service/test/unit/adapter/services/test_mail_sender.py index 4daa7f24..23951214 100644 --- a/service/test/unit/adapter/services/test_mail_sender.py +++ b/service/test/unit/adapter/services/test_mail_sender.py @@ -14,6 +14,7 @@  # 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 leap.bitmask.mail.outgoing.service import OutgoingMail +from mock import patch  from twisted.mail.smtp import User  from twisted.trial import unittest @@ -104,6 +105,25 @@ class MailSenderTest(unittest.TestCase):                  self.assertTrue(recipient in e.email_error_map)      @defer.inlineCallbacks +    def test_keymanager_encrypt_problem_raises_exception(self): +        input_mail = InputMail.from_dict(mail_dict(), from_address='pixelated@org') + +        when(OutgoingMail)._maybe_attach_key(any(), any(), any()).thenReturn( +            defer.succeed(None)) +        when(OutgoingMail)._fix_headers(any(), any(), any()).thenReturn( +            defer.succeed((None, mock()))) +        when(self._keymanager_mock).encrypt(any(), any(), sign=any(), +                                            fetch_remote=any()).thenReturn(defer.fail(Exception('pretend key expired'))) + +        with patch('leap.bitmask.mail.outgoing.service.emit_async'): +            try: +                yield self.sender.sendmail(input_mail) +                self.fail('Exception expected!') +            except MailSenderException, e: +                for recipient in flatten([input_mail.to, input_mail.cc, input_mail.bcc]): +                    self.assertTrue(recipient in e.email_error_map) + +    @defer.inlineCallbacks      def test_iterates_over_recipients_and_send_whitout_bcc_field(self):          input_mail = InputMail.from_dict(mail_dict(), from_address='pixelated@org')          bccs = input_mail.bcc diff --git a/service/test/unit/resources/test_login_resource.py b/service/test/unit/resources/test_login_resource.py index fcf76f5a..1161acc4 100644 --- a/service/test/unit/resources/test_login_resource.py +++ b/service/test/unit/resources/test_login_resource.py @@ -219,7 +219,7 @@ class TestLoginPOST(unittest.TestCase):              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 credentials', written_response) +            self.assertIn('Invalid username or password', written_response)              self.assertFalse(mock_user_bootstrap_setup.called)              self.assertFalse(self.resource.get_session(self.request).is_logged_in()) | 
