diff options
author | Dylan Baker <dylan@pnwbakers.com> | 2017-08-24 11:13:34 -0700 |
---|---|---|
committer | Ruben Pollan <meskio@sindominio.net> | 2017-09-25 12:34:43 +0200 |
commit | 24ebb8bf44691ada1232b4308ae90518817fece8 (patch) | |
tree | 1f012ecc0cea87a8a074e63ceb14a9746f554207 | |
parent | 018aa2e339f9cb3bb4af1d26cce31cbad003409d (diff) |
tests/commands/utils: Add tests for alot/commands/utils.py
-rw-r--r-- | tests/commands/utils_tests.py | 171 |
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, {}) |