summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorSimeon Simeonov2021-12-23 14:41:14 +0100
committerSimeon Simeonov2021-12-23 14:41:14 +0100
commit4914b0c74ed669d6631897950ff1660ce91ef918 (patch)
tree5bef79607256853f41fb3bb666e1c16604a7b258 /tests
Initial commit and release for Christmas with love1.0.0
Diffstat (limited to 'tests')
-rw-r--r--tests/conftest.py59
-rw-r--r--tests/test_cli.py40
-rw-r--r--tests/test_envtoolkit_instance.py64
-rw-r--r--tests/test_envtoolkit_instance_static.py102
4 files changed, 265 insertions, 0 deletions
diff --git a/tests/conftest.py b/tests/conftest.py
new file mode 100644
index 0000000..1f70259
--- /dev/null
+++ b/tests/conftest.py
@@ -0,0 +1,59 @@
1# etoolkit
2# Copyright (C) 2021 Simeon Simeonov
3
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16"""Common fixtures"""
17import pytest
18
19
20@pytest.fixture
21def config_data():
22 """config_data for testing"""
23 return {
24 'general': {
25 'MASTER_PASSWORD_HASH': (
26 'pbkdf2_sha256$100000$kFOQkAPtStZ/Ny/O4501ygHGQnqh5Y+ySxF9qVHr'
27 'iv8=$3BujuWzn3CfDnw4yiD9m3F+GjeW1MHHW40R/ThHNcn0='
28 )
29 },
30 'instances': {
31 'default': {'ETOOLKIT_PROMPT': '(%i)'},
32 'dev': {
33 'ETOOLKIT_PARENT': 'default',
34 'PYTHONPATH': ':/home/user/.pythonpath',
35 'DB_CONNECTION': (
36 'enc-val$1$Y/TBb1F3siHTw6qZg9ERzZfA8PLPf2CwGSQLpu9jYWw=$FT'
37 '5tS9o+ABvsxogIXpJim16Gz5SVtV8='
38 ),
39 },
40 'secret': {
41 'ETOOLKIT_PARENT': 'default',
42 'ETOOLKIT_SENSITIVE': ['PASSWORD'],
43 'GNUPGHOME': '%h/private/.gnupg',
44 'PASSWORD': (
45 'enc-val$1$vIBcoCNiYrsDLtF41uLuSEnppBjhliD0B8jwcBJcj/c=$Kw'
46 'OGe/y1dlxktDaCnJPIVNuaQ4Q7yNo='
47 ),
48 },
49 },
50 }
51
52
53@pytest.fixture
54def password_hash():
55 """password hash for testing, corresponding to 'the very secret passwd'"""
56 return (
57 'pbkdf2_sha256$100000$kFOQkAPtStZ/Ny/O4501ygHGQnqh5Y+ySxF9qVHr'
58 'iv8=$3BujuWzn3CfDnw4yiD9m3F+GjeW1MHHW40R/ThHNcn0='
59 )
diff --git a/tests/test_cli.py b/tests/test_cli.py
new file mode 100644
index 0000000..1bd9be1
--- /dev/null
+++ b/tests/test_cli.py
@@ -0,0 +1,40 @@
1# etoolkit
2# Copyright (C) 2021 Simeon Simeonov
3
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16"""Tests for the CLI (etoolkit.__main__"""
17import pytest
18
19import etoolkit
20from etoolkit.__main__ import main
21
22
23def test_help(capsys):
24 """Dummy test checking if the CLI is available at all"""
25 with pytest.raises(SystemExit) as exit_info:
26 main(['-h'])
27 assert exit_info.type == SystemExit
28 assert exit_info.value.code == 0
29 assert capsys.readouterr().out.startswith('usage: etoolkit')
30
31
32def test_version(capsys):
33 """Dummy test checking if the CLI is available at all"""
34 with pytest.raises(SystemExit) as exit_info:
35 main(['-v'])
36 assert exit_info.type == SystemExit
37 assert exit_info.value.code == 0
38 assert capsys.readouterr().out.startswith(
39 f'etoolkit {etoolkit.__version__}'
40 )
diff --git a/tests/test_envtoolkit_instance.py b/tests/test_envtoolkit_instance.py
new file mode 100644
index 0000000..2ffacd2
--- /dev/null
+++ b/tests/test_envtoolkit_instance.py
@@ -0,0 +1,64 @@
1# etoolkit
2# Copyright (C) 2021 Simeon Simeonov
3
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16"""Tests for etoolkit.EtoolkitInstance"""
17import pytest
18
19import etoolkit
20
21
22def test_instantiation(config_data, password_hash):
23 """Tests for object instatiation"""
24 with pytest.raises(etoolkit.EtoolkitInstanceError) as exc_info:
25 instance = etoolkit.EtoolkitInstance('devv', config_data)
26 assert exc_info.type is etoolkit.EtoolkitInstanceError
27 assert exc_info.value.args[0] == 'Unknown instance "devv"'
28
29 instance = etoolkit.EtoolkitInstance('secret', config_data)
30 assert 'ETOOLKIT_PARENT' not in instance.raw_env_variables
31 assert 'ETOOLKIT_SENSITIVE' not in instance.raw_env_variables
32 assert 'DB_CONNECTION' not in instance.sensitive_env_variables
33 assert 'PASSWORD' in instance.sensitive_env_variables
34 assert instance.name == 'secret'
35 assert instance.master_password_hash == password_hash
36 assert instance.master_password is None
37
38
39def test_get_environ(config_data):
40 """Tests the EtoolkitInstance.get_environ method"""
41 instance = etoolkit.EtoolkitInstance('secret', config_data)
42 with pytest.raises(etoolkit.EtoolkitInstanceError) as exc_info:
43 env = instance.get_environ()
44 assert exc_info.type is etoolkit.EtoolkitInstanceError
45 assert exc_info.value.args[0] == 'Neither password or prompt function set'
46
47 instance.master_password = 'The very secret passwd' # wrong passwd
48 with pytest.raises(etoolkit.EtoolkitInstanceError) as exc_info:
49 env = instance.get_environ()
50 assert exc_info.type is etoolkit.EtoolkitInstanceError
51 assert exc_info.value.args[0].startswith(
52 'Invalid tag when decrypting: enc-val$'
53 )
54
55 instance.master_password = 'the very secret passwd' # correct passwd
56 env = instance.get_environ()
57 assert isinstance(env, dict)
58 assert env['PASSWORD'] == 'secret2'
59
60
61def test_get_full_name(config_data):
62 """Tests the EtoolkitInstance.get_full_name method"""
63 instance = etoolkit.EtoolkitInstance('secret', config_data)
64 assert instance.get_full_name('->') == 'default->secret'
diff --git a/tests/test_envtoolkit_instance_static.py b/tests/test_envtoolkit_instance_static.py
new file mode 100644
index 0000000..d7ac857
--- /dev/null
+++ b/tests/test_envtoolkit_instance_static.py
@@ -0,0 +1,102 @@
1# etoolkit
2# Copyright (C) 2021 Simeon Simeonov
3
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16"""Tests for etoolkit.EtoolkitInstance static methods"""
17import unittest.mock
18
19import pytest
20
21import etoolkit
22
23
24@unittest.mock.patch('getpass.getpass')
25def test_confirm_password_prompt(getpass, password_hash):
26 """Tests the static EtoolkitInstance.confirm_password_prompt method"""
27 getpass.return_value = 'the very secret passwd'
28 assert (
29 etoolkit.EtoolkitInstance.confirm_password_prompt(password_hash)
30 == 'the very secret passwd'
31 )
32 assert (
33 etoolkit.EtoolkitInstance.confirm_password_prompt(password_hash, False)
34 == 'the very secret passwd'
35 )
36
37
38def test_decrypt():
39 """Tests the static EtoolkitInstance.decrypt method"""
40 assert (
41 etoolkit.EtoolkitInstance.decrypt(
42 'the very secret passwd',
43 (
44 'enc-val$1$Y/TBb1F3siHTw6qZg9ERzZfA8PLPf2CwGSQLpu9jYWw=$FT5tS9'
45 'o+ABvsxogIXpJim16Gz5SVtV8='
46 ),
47 )
48 == 'secret1'
49 )
50
51 # now test with modified edata
52 with pytest.raises(etoolkit.EtoolkitInstanceError) as exc_info:
53 edata = (
54 'enc-val$1$Y/TBb1F3siHTw6qZg9ERzZfA8PLPf2CwGSQLpu9jYWw=$FT5tS9'
55 'o+ABvsxogIXpJim17Gz5SVtV8='
56 )
57 etoolkit.EtoolkitInstance.decrypt(
58 'the very secret passwd', edata
59 ) == 'secret1'
60 assert exc_info.type is etoolkit.EtoolkitInstanceError
61 assert exc_info.value.args[0] == f'Invalid tag when decrypting: {edata}'
62
63
64def test_encrypt():
65 """Tests the static EtoolkitInstance.encrypt method"""
66 edata = etoolkit.EtoolkitInstance.encrypt('foo', 'bar')
67 assert edata.startswith('enc-val$')
68 assert len(edata) == 83
69 # the edata should always be different because of random salting
70 assert edata != etoolkit.EtoolkitInstance.encrypt('foo', 'bar')
71
72
73def test_get_new_password_hash():
74 """Tests the static EtoolkitInstance.get_new_password_hash method"""
75 new_hash = etoolkit.EtoolkitInstance.get_new_password_hash(
76 'the very secret passwd'
77 )
78 # all pbkdf2 params are the same / hardcoded for the time being
79 assert new_hash.startswith('pbkdf2_sha256$100000$')
80 assert len(new_hash) == 110
81 # the hash should always be different because of random salting
82 assert new_hash != etoolkit.EtoolkitInstance.get_new_password_hash(
83 'the very secret passwd'
84 )
85
86
87def test_parse_value():
88 """Tests the static EtoolkitInstance.parse_value method"""
89 assert (
90 etoolkit.EtoolkitInstance.parse_value('t%bs%t', {'%b': 'e', '%t': 't'})
91 == 'test'
92 )
93
94
95def test_password_matches(password_hash):
96 """Tests the static EtoolkitInstance.password_matches method"""
97 assert etoolkit.EtoolkitInstance.password_matches(
98 'the very secret passwd', password_hash
99 )
100 assert not etoolkit.EtoolkitInstance.password_matches(
101 'the very secret passwdo', password_hash
102 )