blob: 03b75c31aedc8626211e3d7413aa916b73c4663f [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from tg import tmpl_context as c
import mock
from ming.base import Object
from alluratest.tools import assert_equal, assert_raises
from formencode import validators as fev
from alluratest.controller import setup_unit_test
from allura import app
from allura.lib.app_globals import Icon
from allura.lib import mail_util
from allura.tests import with_nose_compatibility
def setup_method(self, method):
setup_unit_test()
c.user._id = None
c.project = mock.Mock()
c.project.name = 'Test Project'
c.project.shortname = 'tp'
c.project._id = 'testproject/'
c.project.url = lambda: '/testproject/'
app_config = mock.Mock()
app_config._id = None
app_config.project_id = 'testproject/'
app_config.tool_name = 'tool'
app_config.options = Object(mount_point='foo')
c.app = mock.Mock()
c.app.config = app_config
c.app.config.script_name = lambda: '/testproject/test_application/'
c.app.config.url = lambda: 'http://testproject/test_application/'
c.app.url = c.app.config.url()
c.app.__version__ = '0.0'
def test_config_options():
options = [
app.ConfigOption('test1', str, 'MyTestValue'),
app.ConfigOption('test2', str, lambda:'MyTestValue')]
assert options[0].default == 'MyTestValue'
assert options[1].default == 'MyTestValue'
def test_config_options_render_attrs():
opt = app.ConfigOption('test1', str, None, extra_attrs={'type': 'url'})
assert opt.render_attrs() == 'type="url"'
def test_config_option_without_validator():
opt = app.ConfigOption('test1', str, None)
assert opt.validate(None) == None
assert opt.validate('') == ''
assert opt.validate('val') == 'val'
def test_config_option_with_validator():
v = fev.NotEmpty()
opt = app.ConfigOption('test1', str, None, validator=v)
assert opt.validate('val') == 'val'
assert_raises(fev.Invalid, opt.validate, None)
assert_raises(fev.Invalid, opt.validate, '')
def test_options_on_install_default():
a = app.Application(c.project, c.app.config)
assert a.options_on_install() == []
def test_options_on_install():
opts = [app.ConfigOption('url', str, None),
app.ConfigOption('private', bool, None)]
class TestApp(app.Application):
config_options = app.Application.config_options + opts + [
app.ConfigOption('not_on_install', str, None),
]
config_on_install = ['url', 'private']
a = TestApp(c.project, c.app.config)
assert a.options_on_install() == opts
def test_main_menu():
class TestApp(app.Application):
@property
def sitemap(self):
children = [app.SitemapEntry('New', 'new', ui_icon=Icon('some-icon')),
app.SitemapEntry('Recent', 'recent'),
]
return [app.SitemapEntry('My Tool', '.')[children]]
a = TestApp(c.project, c.app.config)
main_menu = a.main_menu()
assert len(main_menu) == 1
assert main_menu[0].children == [] # default main_menu implementation should drop the children from sitemap()
def test_sitemap():
sm = app.SitemapEntry('test', '')[
app.SitemapEntry('a', 'a/'),
app.SitemapEntry('b', 'b/')]
sm[app.SitemapEntry(lambda app:app.config.script_name(), 'c/')]
bound_sm = sm.bind_app(c.app)
assert bound_sm.url == 'http://testproject/test_application/', bound_sm.url
assert bound_sm.children[
-1].label == '/testproject/test_application/', bound_sm.children[-1].label
assert len(sm.children) == 3
sm.extend([app.SitemapEntry('a', 'a/')[
app.SitemapEntry('d', 'd/')]])
assert len(sm.children) == 3
@mock.patch('allura.app.Application.PostClass.query.get')
def test_handle_artifact_unicode(qg):
"""
Tests that app.handle_artifact_message can accept utf strings
"""
ticket = mock.MagicMock()
ticket.get_discussion_thread.return_value = (mock.MagicMock(), mock.MagicMock())
post = mock.MagicMock()
qg.return_value = post
a = app.Application(c.project, c.app.config)
msg = dict(payload='foo ƒ†©¥˙¨ˆ'.encode(), message_id=1, headers={})
a.handle_artifact_message(ticket, msg)
assert post.attach.call_args[0][1].getvalue() == 'foo ƒ†©¥˙¨ˆ'.encode()
msg = dict(payload=b'foo', message_id=1, headers={})
a.handle_artifact_message(ticket, msg)
assert post.attach.call_args[0][1].getvalue() == b'foo'
msg = dict(payload="\x94my quote\x94".encode(), message_id=1, headers={})
a.handle_artifact_message(ticket, msg)
assert post.attach.call_args[0][1].getvalue() == '\x94my quote\x94'.encode()
# assert against prod example
msg_raw = """Message-Id: <1502352031.3216858.1068961568.19EF48C6@webmail.messagingengine.com>
From: foo <foo@bar.com>
To: "[forge:site-support]" <15391@site-support.forge.p.re.sf.net>
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Type: multipart/alternative; boundary="_----------=_150235203132168580"
Date: Thu, 10 Aug 2017 10:00:31 +0200
Subject: Re: [forge:site-support] #15391 Unable to join (my own) mailing list
This is a multi-part message in MIME format.
--_----------=_150235203132168580
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"
Hi
--_----------=_150235203132168580
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="utf-8"
<!DOCTYPE html>
<html><body>Hi</body></html>
--_----------=_150235203132168580--
"""
msg = mail_util.parse_message(msg_raw)
for p in [p for p in msg['parts'] if p['payload'] is not None]:
# filter here mimics logic in `route_email`
a.handle_artifact_message(ticket, p)