# encoding=utf-8
# Copyright © 2017-2018 Dylan Baker
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
"""Tests for global commands."""
import os
import tempfile
import unittest
from unittest import mock
from alot.commands import globals as g_commands
from .. import utilities
class Stop(Exception):
"""exception for stopping testing of giant unmanagable functions."""
pass
class TestComposeCommand(unittest.TestCase):
"""Tests for the compose command."""
@staticmethod
def _make_envelope_mock():
envelope = mock.Mock()
envelope.headers = {'From': 'foo '}
envelope.get = envelope.headers.get
envelope.sign_key = None
envelope.sign = False
return envelope
@staticmethod
def _make_account_mock(
sign_by_default=True, gpg_key=mock.sentinel.gpg_key):
account = mock.Mock()
account.sign_by_default = sign_by_default
account.gpg_key = gpg_key
account.signature = None
return account
def test_set_gpg_sign_by_default_okay(self):
envelope = self._make_envelope_mock()
envelope.account = self._make_account_mock()
cmd = g_commands.ComposeCommand(envelope=envelope)
cmd._set_gpg_sign(mock.Mock())
self.assertTrue(envelope.sign)
self.assertIs(envelope.sign_key, mock.sentinel.gpg_key)
def test_set_gpg_sign_by_default_false_doesnt_set_key(self):
envelope = self._make_envelope_mock()
envelope.account = self._make_account_mock(sign_by_default=False)
cmd = g_commands.ComposeCommand(envelope=envelope)
cmd._set_gpg_sign(mock.Mock())
self.assertFalse(envelope.sign)
self.assertIs(envelope.sign_key, None)
def test_set_gpg_sign_by_default_but_no_key(self):
envelope = self._make_envelope_mock()
envelope.account = self._make_account_mock(gpg_key=None)
cmd = g_commands.ComposeCommand(envelope=envelope)
cmd._set_gpg_sign(mock.Mock())
self.assertFalse(envelope.sign)
self.assertIs(envelope.sign_key, None)
def test_get_template_decode(self):
subject = 'This is a täßϑ subject.'
to = 'recipient@mail.com'
_from = 'foo.bar@mail.fr'
body = 'Body\n地初店会継思識棋御招告外児山望掲領環。\n€mail body €nd.'
with tempfile.NamedTemporaryFile('wb', delete=False) as f:
txt = 'Subject: {}\nTo: {}\nFrom: {}\n{}'.format(subject, to,
_from, body)
f.write(txt.encode('utf-8'))
self.addCleanup(os.unlink, f.name)
cmd = g_commands.ComposeCommand(template=f.name)
cmd._set_envelope()
cmd._get_template(mock.Mock())
self.assertEqual({'To': [to],
'From': [_from],
'Subject': [subject]}, cmd.envelope.headers)
self.assertEqual(body, cmd.envelope.body)
class TestExternalCommand(unittest.TestCase):
@utilities.async_test
async def test_no_spawn_no_stdin_success(self):
ui = utilities.make_ui()
cmd = g_commands.ExternalCommand('true', refocus=False)
await cmd.apply(ui)
ui.notify.assert_not_called()
@utilities.async_test
async def test_no_spawn_stdin_success(self):
ui = utilities.make_ui()
cmd = g_commands.ExternalCommand("awk '{ exit $0 }'", stdin='0',
refocus=False)
await cmd.apply(ui)
ui.notify.assert_not_called()
@utilities.async_test
async def test_no_spawn_no_stdin_attached(self):
ui = utilities.make_ui()
cmd = g_commands.ExternalCommand('test -t 0', refocus=False)
await cmd.apply(ui)
ui.notify.assert_not_called()
@utilities.async_test
async def test_no_spawn_stdin_attached(self):
ui = utilities.make_ui()
cmd = g_commands.ExternalCommand(
"test -t 0", stdin='0', refocus=False)
await cmd.apply(ui)
ui.notify.assert_called_once_with(
'editor has exited with error code 1 -- No stderr output',
priority='error')
@utilities.async_test
async def test_no_spawn_failure(self):
ui = utilities.make_ui()
cmd = g_commands.ExternalCommand('false', refocus=False)
await cmd.apply(ui)
ui.notify.assert_called_once_with(
'editor has exited with error code 1 -- No stderr output',
priority='error')
@utilities.async_test
@mock.patch(
'alot.commands.globals.settings.get', mock.Mock(return_value=''))
@mock.patch.dict(os.environ, {'DISPLAY': ':0'})
async def test_spawn_no_stdin_success(self):
ui = utilities.make_ui()
cmd = g_commands.ExternalCommand('true', refocus=False, spawn=True)
await cmd.apply(ui)
ui.notify.assert_not_called()
@utilities.async_test
@mock.patch(
'alot.commands.globals.settings.get', mock.Mock(return_value=''))
@mock.patch.dict(os.environ, {'DISPLAY': ':0'})
async def test_spawn_stdin_success(self):
ui = utilities.make_ui()
cmd = g_commands.ExternalCommand(
"awk '{ exit $0 }'",
stdin='0', refocus=False, spawn=True)
await cmd.apply(ui)
ui.notify.assert_not_called()
@utilities.async_test
@mock.patch(
'alot.commands.globals.settings.get', mock.Mock(return_value=''))
@mock.patch.dict(os.environ, {'DISPLAY': ':0'})
async def test_spawn_failure(self):
ui = utilities.make_ui()
cmd = g_commands.ExternalCommand('false', refocus=False, spawn=True)
await cmd.apply(ui)
ui.notify.assert_called_once_with(
'editor has exited with error code 1 -- No stderr output',
priority='error')
class TestCallCommand(unittest.TestCase):
@utilities.async_test
async def test_synchronous_call(self):
ui = mock.Mock()
cmd = g_commands.CallCommand('ui()')
await cmd.apply(ui)
ui.assert_called_once()
@utilities.async_test
async def test_async_call(self):
async def func(obj):
obj()
ui = mock.Mock()
hooks = mock.Mock()
hooks.ui = None
hooks.func = func
with mock.patch('alot.commands.globals.settings.hooks', hooks):
cmd = g_commands.CallCommand('hooks.func(ui)')
await cmd.apply(ui)
ui.assert_called_once()