summaryrefslogtreecommitdiff
path: root/tests/commands
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2017-08-24 11:13:34 -0700
committerRuben Pollan <meskio@sindominio.net>2017-09-25 12:34:43 +0200
commit24ebb8bf44691ada1232b4308ae90518817fece8 (patch)
tree1f012ecc0cea87a8a074e63ceb14a9746f554207 /tests/commands
parent018aa2e339f9cb3bb4af1d26cce31cbad003409d (diff)
tests/commands/utils: Add tests for alot/commands/utils.py
Diffstat (limited to 'tests/commands')
-rw-r--r--tests/commands/utils_tests.py171
1 files changed, 171 insertions, 0 deletions
diff --git a/tests/commands/utils_tests.py b/tests/commands/utils_tests.py
new file mode 100644
index 00000000..9abc36e1
--- /dev/null
+++ b/tests/commands/utils_tests.py
@@ -0,0 +1,171 @@
+# encoding=utf-8
+# Copyright © 2017 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 <http://www.gnu.org/licenses/>.
+
+from __future__ import absolute_import
+import tempfile
+import os
+import shutil
+
+import gpg
+import mock
+from twisted.trial import unittest
+from twisted.internet.defer import inlineCallbacks
+
+from alot import crypto
+from alot import errors
+from alot.commands import utils
+from alot.db.envelope import Envelope
+
+from .. import utilities
+
+MOD_CLEAN = utilities.ModuleCleanup()
+
+# A useful single fingerprint for tests that only care about one key. This
+# key will not be ambiguous
+FPR = "F74091D4133F87D56B5D343C1974EC55FBC2D660"
+
+# Some additional keys, these keys may be ambigiuos
+EXTRA_FPRS = [
+ "DD19862809A7573A74058FF255937AFBB156245D",
+ "2071E9C8DB4EF5466F4D233CF730DF92C4566CE7",
+]
+
+DEVNULL = open('/dev/null', 'w')
+MOD_CLEAN.add_cleanup(DEVNULL.close)
+
+
+@MOD_CLEAN.wrap_setup
+def setUpModule():
+ home = tempfile.mkdtemp()
+ MOD_CLEAN.add_cleanup(shutil.rmtree, home)
+ mock_home = mock.patch.dict(os.environ, {'GNUPGHOME': home})
+ mock_home.start()
+ MOD_CLEAN.add_cleanup(mock_home.stop)
+
+ with gpg.core.Context(armor=True) as ctx:
+ # Add the public and private keys. They have no password
+ search_dir = os.path.join(os.path.dirname(__file__), '../static/gpg-keys')
+ for each in os.listdir(search_dir):
+ if os.path.splitext(each)[1] == '.gpg':
+ with open(os.path.join(search_dir, each)) as f:
+ ctx.op_import(f)
+
+
+@MOD_CLEAN.wrap_teardown
+def tearDownModule():
+ pass
+
+
+class TestGetKeys(unittest.TestCase):
+
+ # pylint: disable=protected-access
+
+ @inlineCallbacks
+ def test_get_keys(self):
+ """Test that getting keys works when all keys are present."""
+ expected = crypto.get_key(FPR, validate=True, encrypt=True,
+ signed_only=False)
+ ui = mock.Mock()
+ ids = [FPR]
+ actual = yield utils._get_keys(ui, ids)
+ self.assertIn(FPR, actual)
+ self.assertEqual(actual[FPR].fpr, expected.fpr)
+
+ @inlineCallbacks
+ def test_get_keys_missing(self):
+ """Test that getting keys works when some keys are missing."""
+ expected = crypto.get_key(FPR, validate=True, encrypt=True,
+ signed_only=False)
+ ui = mock.Mock()
+ ids = [FPR, "6F6B15509CF8E59E6E469F327F438280EF8D349F"]
+ actual = yield utils._get_keys(ui, ids)
+ self.assertIn(FPR, actual)
+ self.assertEqual(actual[FPR].fpr, expected.fpr)
+
+ @inlineCallbacks
+ def test_get_keys_signed_only(self):
+ """Test gettings keys when signed only is required."""
+ ui = mock.Mock()
+ ids = [FPR]
+ actual = yield utils._get_keys(ui, ids, signed_only=True)
+ self.assertEqual(actual, {})
+
+ @inlineCallbacks
+ def test_get_keys_ambiguous(self):
+ """Test gettings keys when when the key is ambiguous."""
+ key = crypto.get_key(FPR, validate=True, encrypt=True, signed_only=False)
+ ui = mock.Mock()
+
+ # Creat a ui.choice object that can satisfy twisted, but can also be
+ # queried for calls as a mock
+ @inlineCallbacks
+ def choice(*args, **kwargs):
+ yield None
+ ui.choice = mock.Mock(wraps=choice)
+
+ ids = [FPR]
+ with mock.patch('alot.commands.utils.crypto.get_key',
+ mock.Mock(side_effect=errors.GPGProblem(
+ 'test', errors.GPGCode.AMBIGUOUS_NAME))):
+ with mock.patch('alot.commands.utils.crypto.list_keys',
+ mock.Mock(return_value=[key])):
+ yield utils._get_keys(ui, ids, signed_only=False)
+ ui.choice.assert_called_once()
+
+
+class TestSetEncrypt(unittest.TestCase):
+
+ @inlineCallbacks
+ def test_get_keys_from_to(self):
+ ui = mock.Mock()
+ envelope = Envelope()
+ envelope['To'] = 'ambig@example.com, test@example.com'
+ yield utils.set_encrypt(ui, envelope)
+ self.assertTrue(envelope.encrypt)
+ self.assertEqual(
+ [f.fpr for f in envelope.encrypt_keys.itervalues()],
+ [crypto.get_key(FPR).fpr, crypto.get_key(EXTRA_FPRS[0]).fpr])
+
+ @inlineCallbacks
+ def test_get_keys_from_cc(self):
+ ui = mock.Mock()
+ envelope = Envelope()
+ envelope['Cc'] = 'ambig@example.com, test@example.com'
+ yield utils.set_encrypt(ui, envelope)
+ self.assertTrue(envelope.encrypt)
+ self.assertEqual(
+ [f.fpr for f in envelope.encrypt_keys.itervalues()],
+ [crypto.get_key(FPR).fpr, crypto.get_key(EXTRA_FPRS[0]).fpr])
+
+ @inlineCallbacks
+ def test_get_partial_keys(self):
+ ui = mock.Mock()
+ envelope = Envelope()
+ envelope['Cc'] = 'foo@example.com, test@example.com'
+ yield utils.set_encrypt(ui, envelope)
+ self.assertTrue(envelope.encrypt)
+ self.assertEqual(
+ [f.fpr for f in envelope.encrypt_keys.itervalues()],
+ [crypto.get_key(FPR).fpr])
+
+ @inlineCallbacks
+ def test_get_no_keys(self):
+ ui = mock.Mock()
+ envelope = Envelope()
+ envelope['To'] = 'foo@example.com'
+ yield utils.set_encrypt(ui, envelope)
+ self.assertFalse(envelope.encrypt)
+ self.assertEqual(envelope.encrypt_keys, {})