diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/conftest.py | 38 | ||||
| -rw-r--r-- | tests/test_cli.py | 91 | ||||
| -rw-r--r-- | tests/test_envtoolkit_instance.py | 17 | ||||
| -rw-r--r-- | tests/test_envtoolkit_instance_static.py | 80 |
4 files changed, 108 insertions, 118 deletions
diff --git a/tests/conftest.py b/tests/conftest.py index 6cc8b9f..2e8eaf1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py | |||
| @@ -16,14 +16,14 @@ | |||
| 16 | """Common fixtures""" | 16 | """Common fixtures""" |
| 17 | 17 | ||
| 18 | import json | 18 | import json |
| 19 | import pathlib | ||
| 19 | 20 | ||
| 20 | import pytest | 21 | import pytest |
| 21 | 22 | ||
| 22 | 23 | ||
| 23 | @pytest.fixture | 24 | @pytest.fixture |
| 24 | def config_data(): | 25 | def config_data() -> dict: |
| 25 | """config_data for testing""" | 26 | """config_data for testing""" |
| 26 | |||
| 27 | return { | 27 | return { |
| 28 | 'general': { | 28 | 'general': { |
| 29 | 'MASTER_PASSWORD_HASH': ( | 29 | 'MASTER_PASSWORD_HASH': ( |
| @@ -60,18 +60,16 @@ def config_data(): | |||
| 60 | 60 | ||
| 61 | 61 | ||
| 62 | @pytest.fixture | 62 | @pytest.fixture |
| 63 | def config_file(tmp_path, config_data): | 63 | def config_file(tmp_path: pathlib.Path, config_data: dict) -> str: |
| 64 | """Temporary config file for testing that includes config_data""" | 64 | """Temporary config file for testing that includes config_data""" |
| 65 | |||
| 66 | cf = tmp_path / 'etoolkit.json' | 65 | cf = tmp_path / 'etoolkit.json' |
| 67 | cf.write_text(json.dumps(config_data)) | 66 | cf.write_text(json.dumps(config_data)) |
| 68 | return str(cf) | 67 | return str(cf) |
| 69 | 68 | ||
| 70 | 69 | ||
| 71 | @pytest.fixture | 70 | @pytest.fixture |
| 72 | def long_encrypted_value(): | 71 | def long_encrypted_value() -> str: |
| 73 | """enc. value corresponding to 'Nobody expects the Spanish inquisition'""" | 72 | """enc. value corresponding to 'Nobody expects the Spanish inquisition'""" |
| 74 | |||
| 75 | return ( | 73 | return ( |
| 76 | 'enc-val$2$uYpZM1VfAGq0CDZL2duITs076CQj+hIFEgx+F4mn80o=$' | 74 | 'enc-val$2$uYpZM1VfAGq0CDZL2duITs076CQj+hIFEgx+F4mn80o=$' |
| 77 | 'UWP5YeRsh5/2vZ2J1UOS+BJti73Kbp6C1pJmCo8hF' | 75 | 'UWP5YeRsh5/2vZ2J1UOS+BJti73Kbp6C1pJmCo8hF' |
| @@ -80,27 +78,26 @@ def long_encrypted_value(): | |||
| 80 | 78 | ||
| 81 | 79 | ||
| 82 | @pytest.fixture | 80 | @pytest.fixture |
| 83 | def long_value(): | 81 | def long_value() -> str: |
| 84 | """standard value (> 32 bytes)""" | 82 | """standard value (> 32 bytes)""" |
| 85 | return 'Nobody expects the Spanish inquisition' | 83 | return 'Nobody expects the Spanish inquisition' |
| 86 | 84 | ||
| 87 | 85 | ||
| 88 | @pytest.fixture | 86 | @pytest.fixture |
| 89 | def master_password(): | 87 | def master_password() -> str: |
| 90 | """Master passord""" | 88 | """Master passord""" |
| 91 | return 'The very secret passwd' | 89 | return 'The very secret passwd' |
| 92 | 90 | ||
| 93 | 91 | ||
| 94 | @pytest.fixture | 92 | @pytest.fixture |
| 95 | def new_master_password(): | 93 | def new_master_password() -> str: |
| 96 | """Master passord""" | 94 | """Master passord""" |
| 97 | return 'New very secret passwd' | 95 | return 'New very secret passwd' |
| 98 | 96 | ||
| 99 | 97 | ||
| 100 | @pytest.fixture | 98 | @pytest.fixture |
| 101 | def non_random_bytes_32(): | 99 | def non_random_bytes_32() -> bytes: |
| 102 | """always use the same bytes instead of os.urandom(32)""" | 100 | """always use the same bytes instead of os.urandom(32)""" |
| 103 | |||
| 104 | return ( | 101 | return ( |
| 105 | b'\xb9\x8aY3U_\x00j\xb4\x086K\xd9\xdb\x88N' | 102 | b'\xb9\x8aY3U_\x00j\xb4\x086K\xd9\xdb\x88N' |
| 106 | b'\xcd;\xe8$#\xfa\x12\x05\x12\x0c~\x17\x89\xa7\xf3J' | 103 | b'\xcd;\xe8$#\xfa\x12\x05\x12\x0c~\x17\x89\xa7\xf3J' |
| @@ -108,9 +105,8 @@ def non_random_bytes_32(): | |||
| 108 | 105 | ||
| 109 | 106 | ||
| 110 | @pytest.fixture | 107 | @pytest.fixture |
| 111 | def non_random_bytes_57(): | 108 | def non_random_bytes_57() -> bytes: |
| 112 | """always use the same bytes instead of os.urandom(57)""" | 109 | """always use the same bytes instead of os.urandom(57)""" |
| 113 | |||
| 114 | return ( | 110 | return ( |
| 115 | b'D$\x99\xaa\xafiZ\xb4C\xa0%XTz)\xca\xedK\xcd\xa2F~\xff+\xa1[\xe2\xaa' | 111 | b'D$\x99\xaa\xafiZ\xb4C\xa0%XTz)\xca\xedK\xcd\xa2F~\xff+\xa1[\xe2\xaa' |
| 116 | b'\xb2\xd3\x07\x13\xedb\xc2\x84\xfe\tS\r\xf0\x02_\xef\xe3\xde\xf1?e' | 112 | b'\xb2\xd3\x07\x13\xedb\xc2\x84\xfe\tS\r\xf0\x02_\xef\xe3\xde\xf1?e' |
| @@ -119,16 +115,14 @@ def non_random_bytes_57(): | |||
| 119 | 115 | ||
| 120 | 116 | ||
| 121 | @pytest.fixture | 117 | @pytest.fixture |
| 122 | def nonexistent_config_file(tmp_path): | 118 | def nonexistent_config_file(tmp_path: pathlib.Path) -> str: |
| 123 | """temporary config file for testing that includes config_data""" | 119 | """temporary config file for testing that includes config_data""" |
| 124 | |||
| 125 | return str(tmp_path / 'etoolkitt.json') | 120 | return str(tmp_path / 'etoolkitt.json') |
| 126 | 121 | ||
| 127 | 122 | ||
| 128 | @pytest.fixture | 123 | @pytest.fixture |
| 129 | def password_hash(): | 124 | def password_hash() -> str: |
| 130 | """password hash for testing, corresponding to 'The very secret passwd'""" | 125 | """password hash for testing, corresponding to 'The very secret passwd'""" |
| 131 | |||
| 132 | return ( | 126 | return ( |
| 133 | 'pbkdf2_sha256$500000$UY3o78KUM1Btzxk3k3JCsijnwtJ2lx+hH9NewpVKxo8=$' | 127 | 'pbkdf2_sha256$500000$UY3o78KUM1Btzxk3k3JCsijnwtJ2lx+hH9NewpVKxo8=$' |
| 134 | 'tHwDm8OVKanC4DoYTigTCb0R3lQIa/CbBYj0B3TZtHg=' | 128 | 'tHwDm8OVKanC4DoYTigTCb0R3lQIa/CbBYj0B3TZtHg=' |
| @@ -136,9 +130,8 @@ def password_hash(): | |||
| 136 | 130 | ||
| 137 | 131 | ||
| 138 | @pytest.fixture | 132 | @pytest.fixture |
| 139 | def short_encrypted_value(): | 133 | def short_encrypted_value() -> str: |
| 140 | """enc. value corresponding to 'secret1'""" | 134 | """enc. value corresponding to 'secret1'""" |
| 141 | |||
| 142 | return ( | 135 | return ( |
| 143 | 'enc-val$2$RCSZqq9pWrRDoCVYVHopyu1LzaJGfv8roVviqrLTBxM=$' | 136 | 'enc-val$2$RCSZqq9pWrRDoCVYVHopyu1LzaJGfv8roVviqrLTBxM=$' |
| 144 | '+YYrZbwTBuG0Pl+WMQrvxLUtq5j8qYuQqzoIwgoGt7AaWZCJz+E7qoDeg3wke70ST8U=' | 137 | '+YYrZbwTBuG0Pl+WMQrvxLUtq5j8qYuQqzoIwgoGt7AaWZCJz+E7qoDeg3wke70ST8U=' |
| @@ -146,9 +139,8 @@ def short_encrypted_value(): | |||
| 146 | 139 | ||
| 147 | 140 | ||
| 148 | @pytest.fixture | 141 | @pytest.fixture |
| 149 | def short_encrypted_value_v1(): | 142 | def short_encrypted_value_v1() -> str: |
| 150 | """enc. value (enc-val 1) corresponding to 'secret1'""" | 143 | """enc. value (enc-val 1) corresponding to 'secret1'""" |
| 151 | |||
| 152 | return ( | 144 | return ( |
| 153 | 'enc-val$1$/cXpEMoZrTlb9yokGhw8tLTSUkqnqJ4ZoAkurNgMYx' | 145 | 'enc-val$1$/cXpEMoZrTlb9yokGhw8tLTSUkqnqJ4ZoAkurNgMYx' |
| 154 | 'w=$1VdkSMcZnLRwLiu1M8VlYcbelwmiVNY=' | 146 | 'w=$1VdkSMcZnLRwLiu1M8VlYcbelwmiVNY=' |
| @@ -156,12 +148,12 @@ def short_encrypted_value_v1(): | |||
| 156 | 148 | ||
| 157 | 149 | ||
| 158 | @pytest.fixture | 150 | @pytest.fixture |
| 159 | def short_value(): | 151 | def short_value() -> str: |
| 160 | """standard value (< 32 bytes)""" | 152 | """standard value (< 32 bytes)""" |
| 161 | return 'secret1' | 153 | return 'secret1' |
| 162 | 154 | ||
| 163 | 155 | ||
| 164 | @pytest.fixture | 156 | @pytest.fixture |
| 165 | def wrong_master_password(): | 157 | def wrong_master_password() -> str: |
| 166 | """Wrong master passord""" | 158 | """Wrong master passord""" |
| 167 | return 'the very secret passwd' | 159 | return 'the very secret passwd' |
diff --git a/tests/test_cli.py b/tests/test_cli.py index b7913da..6e28378 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py | |||
| @@ -26,9 +26,13 @@ from etoolkit.__main__ import main | |||
| 26 | 26 | ||
| 27 | 27 | ||
| 28 | @unittest.mock.patch('builtins.input') | 28 | @unittest.mock.patch('builtins.input') |
| 29 | def test_decrypt_v1(binput, capsys, config_file, master_password): | 29 | def test_decrypt_v1( |
| 30 | binput: unittest.mock.MagicMock, | ||
| 31 | capsys: pytest.CaptureFixture, | ||
| 32 | config_file: str, | ||
| 33 | master_password: str, | ||
| 34 | ) -> None: | ||
| 30 | """Tests v1 decryption via the CLI interface""" | 35 | """Tests v1 decryption via the CLI interface""" |
| 31 | |||
| 32 | binput.return_value = ( | 36 | binput.return_value = ( |
| 33 | 'enc-val$1$rye0sMGEnd35gOWyISE1FQa6dzS+8/jf6aopMO5tPr4=$' | 37 | 'enc-val$1$rye0sMGEnd35gOWyISE1FQa6dzS+8/jf6aopMO5tPr4=$' |
| 34 | 'RjnRY0bUJWFOiejTlM3OhKNimQ==' | 38 | 'RjnRY0bUJWFOiejTlM3OhKNimQ==' |
| @@ -44,15 +48,14 @@ def test_decrypt_v1(binput, capsys, config_file, master_password): | |||
| 44 | 48 | ||
| 45 | @unittest.mock.patch('builtins.input') | 49 | @unittest.mock.patch('builtins.input') |
| 46 | def test_decrypt_v2( | 50 | def test_decrypt_v2( |
| 47 | binput, | 51 | binput: unittest.mock.MagicMock, |
| 48 | capsys, | 52 | capsys: pytest.CaptureFixture, |
| 49 | config_file, | 53 | config_file: str, |
| 50 | master_password, | 54 | master_password: str, |
| 51 | short_encrypted_value, | 55 | short_encrypted_value: str, |
| 52 | short_value, | 56 | short_value: str, |
| 53 | ): | 57 | ) -> None: |
| 54 | """Tests v2 decryption via the CLI interface""" | 58 | """Tests v2 decryption via the CLI interface""" |
| 55 | |||
| 56 | binput.return_value = short_encrypted_value | 59 | binput.return_value = short_encrypted_value |
| 57 | with unittest.mock.patch.dict( | 60 | with unittest.mock.patch.dict( |
| 58 | os.environ, {'ETOOLKIT_MASTER_PASSWORD': master_password} | 61 | os.environ, {'ETOOLKIT_MASTER_PASSWORD': master_password} |
| @@ -68,17 +71,16 @@ def test_decrypt_v2( | |||
| 68 | @unittest.mock.patch('os.urandom') | 71 | @unittest.mock.patch('os.urandom') |
| 69 | @unittest.mock.patch('builtins.input') | 72 | @unittest.mock.patch('builtins.input') |
| 70 | def test_encrypt_with_echo( | 73 | def test_encrypt_with_echo( |
| 71 | binput, | 74 | binput: unittest.mock.MagicMock, |
| 72 | urandom, | 75 | urandom: unittest.mock.MagicMock, |
| 73 | capsys, | 76 | capsys: pytest.CaptureFixture, |
| 74 | non_random_bytes_57, | 77 | non_random_bytes_57: bytes, |
| 75 | config_file, | 78 | config_file: str, |
| 76 | master_password, | 79 | master_password: str, |
| 77 | short_encrypted_value, | 80 | short_encrypted_value: str, |
| 78 | short_value, | 81 | short_value: str, |
| 79 | ): | 82 | ) -> None: |
| 80 | """Tests encryption via the CLI interface""" | 83 | """Tests encryption via the CLI interface""" |
| 81 | |||
| 82 | binput.return_value = short_value | 84 | binput.return_value = short_value |
| 83 | urandom.return_value = non_random_bytes_57 | 85 | urandom.return_value = non_random_bytes_57 |
| 84 | with unittest.mock.patch.dict( | 86 | with unittest.mock.patch.dict( |
| @@ -95,17 +97,16 @@ def test_encrypt_with_echo( | |||
| 95 | @unittest.mock.patch('os.urandom') | 97 | @unittest.mock.patch('os.urandom') |
| 96 | @unittest.mock.patch('getpass.getpass') | 98 | @unittest.mock.patch('getpass.getpass') |
| 97 | def test_encrypt_without_echo( | 99 | def test_encrypt_without_echo( |
| 98 | getpass, | 100 | getpass: unittest.mock.MagicMock, |
| 99 | urandom, | 101 | urandom: unittest.mock.MagicMock, |
| 100 | capsys, | 102 | capsys: pytest.CaptureFixture, |
| 101 | non_random_bytes_57, | 103 | non_random_bytes_57: bytes, |
| 102 | config_file, | 104 | config_file: str, |
| 103 | master_password, | 105 | master_password: str, |
| 104 | short_encrypted_value, | 106 | short_encrypted_value: str, |
| 105 | short_value, | 107 | short_value: str, |
| 106 | ): | 108 | ) -> None: |
| 107 | """Tests encryption via the CLI interface""" | 109 | """Tests encryption via the CLI interface""" |
| 108 | |||
| 109 | getpass.return_value = short_value | 110 | getpass.return_value = short_value |
| 110 | urandom.return_value = non_random_bytes_57 | 111 | urandom.return_value = non_random_bytes_57 |
| 111 | with unittest.mock.patch.dict( | 112 | with unittest.mock.patch.dict( |
| @@ -119,20 +120,26 @@ def test_encrypt_without_echo( | |||
| 119 | ) | 120 | ) |
| 120 | 121 | ||
| 121 | 122 | ||
| 122 | def test_fetch_encrypted_value(config_file, master_password, short_value): | 123 | def test_fetch_encrypted_value( |
| 124 | config_file: str, master_password: str, short_value: str | ||
| 125 | ) -> None: | ||
| 123 | """Tests decryption of encrypted value""" | 126 | """Tests decryption of encrypted value""" |
| 124 | |||
| 125 | with unittest.mock.patch.dict( | 127 | with unittest.mock.patch.dict( |
| 126 | os.environ, {'ETOOLKIT_MASTER_PASSWORD': master_password} | 128 | os.environ, {'ETOOLKIT_MASTER_PASSWORD': master_password} |
| 127 | ): | 129 | ): |
| 128 | assert os.environ.get('ETOOLKIT_TEST_PASSWORD') is None | 130 | assert os.environ.get('ETOOLKIT_TEST_PASSWORD') is None |
| 129 | main(['-c', f'{config_file}', '-q', '-s', '/bin/false', 'secret']) | 131 | with pytest.raises(SystemExit) as exit_info: |
| 132 | main(['-c', f'{config_file}', '-q', '-s', '/bin/false', 'secret']) | ||
| 133 | assert exit_info.value.code == 0 | ||
| 130 | assert os.environ.get('ETOOLKIT_TEST_PASSWORD') == short_value | 134 | assert os.environ.get('ETOOLKIT_TEST_PASSWORD') == short_value |
| 131 | 135 | ||
| 132 | 136 | ||
| 133 | def test_list(capsys, config_file, nonexistent_config_file): | 137 | def test_list( |
| 138 | capsys: pytest.CaptureFixture, | ||
| 139 | config_file: str, | ||
| 140 | nonexistent_config_file: str, | ||
| 141 | ) -> None: | ||
| 134 | """Tests list via the CLI interface""" | 142 | """Tests list via the CLI interface""" |
| 135 | |||
| 136 | with pytest.raises(SystemExit) as exit_info: | 143 | with pytest.raises(SystemExit) as exit_info: |
| 137 | main(['-c', nonexistent_config_file, '-l']) | 144 | main(['-c', nonexistent_config_file, '-l']) |
| 138 | assert exit_info.value.code == errno.EIO | 145 | assert exit_info.value.code == errno.EIO |
| @@ -142,9 +149,8 @@ def test_list(capsys, config_file, nonexistent_config_file): | |||
| 142 | assert capsys.readouterr().out.strip() == f'dev{os.linesep}secret' | 149 | assert capsys.readouterr().out.strip() == f'dev{os.linesep}secret' |
| 143 | 150 | ||
| 144 | 151 | ||
| 145 | def test_help(capsys): | 152 | def test_help(capsys: pytest.CaptureFixture) -> None: |
| 146 | """Dummy test checking if the CLI is available at all""" | 153 | """Dummy test checking if the CLI is available at all""" |
| 147 | |||
| 148 | with pytest.raises(SystemExit) as exit_info: | 154 | with pytest.raises(SystemExit) as exit_info: |
| 149 | main(['-h']) | 155 | main(['-h']) |
| 150 | assert exit_info.value.code == 0 | 156 | assert exit_info.value.code == 0 |
| @@ -154,10 +160,12 @@ def test_help(capsys): | |||
| 154 | @unittest.mock.patch('os.urandom') | 160 | @unittest.mock.patch('os.urandom') |
| 155 | @unittest.mock.patch('getpass.getpass') | 161 | @unittest.mock.patch('getpass.getpass') |
| 156 | def test_generate_master_password_hash( | 162 | def test_generate_master_password_hash( |
| 157 | getpass, urandom, capsys, non_random_bytes_32 | 163 | getpass: unittest.mock.MagicMock, |
| 158 | ): | 164 | urandom: unittest.mock.MagicMock, |
| 165 | capsys: pytest.CaptureFixture, | ||
| 166 | non_random_bytes_32: bytes, | ||
| 167 | ) -> None: | ||
| 159 | """Tests master password hash generation via the CLI interface""" | 168 | """Tests master password hash generation via the CLI interface""" |
| 160 | |||
| 161 | getpass.return_value = 'The very secret passwd' | 169 | getpass.return_value = 'The very secret passwd' |
| 162 | urandom.return_value = non_random_bytes_32 | 170 | urandom.return_value = non_random_bytes_32 |
| 163 | with pytest.raises(SystemExit) as exit_info: | 171 | with pytest.raises(SystemExit) as exit_info: |
| @@ -169,9 +177,8 @@ def test_generate_master_password_hash( | |||
| 169 | ) | 177 | ) |
| 170 | 178 | ||
| 171 | 179 | ||
| 172 | def test_version(capsys): | 180 | def test_version(capsys: pytest.CaptureFixture) -> None: |
| 173 | """Dummy test checking if the CLI is available at all""" | 181 | """Dummy test checking if the CLI is available at all""" |
| 174 | |||
| 175 | with pytest.raises(SystemExit) as exit_info: | 182 | with pytest.raises(SystemExit) as exit_info: |
| 176 | main(['-v']) | 183 | main(['-v']) |
| 177 | assert exit_info.value.code == 0 | 184 | assert exit_info.value.code == 0 |
diff --git a/tests/test_envtoolkit_instance.py b/tests/test_envtoolkit_instance.py index 5137e9f..3235736 100644 --- a/tests/test_envtoolkit_instance.py +++ b/tests/test_envtoolkit_instance.py | |||
| @@ -20,9 +20,8 @@ import pytest | |||
| 20 | import etoolkit | 20 | import etoolkit |
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | def test_instantiation(config_data): | 23 | def test_instantiation(config_data: dict) -> None: |
| 24 | """Tests for object instatiation""" | 24 | """Tests for object instatiation""" |
| 25 | |||
| 26 | with pytest.raises(etoolkit.EtoolkitInstanceError) as exc_info: | 25 | with pytest.raises(etoolkit.EtoolkitInstanceError) as exc_info: |
| 27 | instance = etoolkit.EtoolkitInstance('devv', config_data) | 26 | instance = etoolkit.EtoolkitInstance('devv', config_data) |
| 28 | assert exc_info.type is etoolkit.EtoolkitInstanceError | 27 | assert exc_info.type is etoolkit.EtoolkitInstanceError |
| @@ -43,10 +42,12 @@ def test_instantiation(config_data): | |||
| 43 | 42 | ||
| 44 | 43 | ||
| 45 | def test_get_environ( | 44 | def test_get_environ( |
| 46 | config_data, master_password, short_value, wrong_master_password | 45 | config_data: dict, |
| 47 | ): | 46 | master_password: str, |
| 47 | short_value: str, | ||
| 48 | wrong_master_password: str, | ||
| 49 | ) -> None: | ||
| 48 | """Tests the EtoolkitInstance.get_environ method""" | 50 | """Tests the EtoolkitInstance.get_environ method""" |
| 49 | |||
| 50 | instance = etoolkit.EtoolkitInstance('secret', config_data) | 51 | instance = etoolkit.EtoolkitInstance('secret', config_data) |
| 51 | with pytest.raises(etoolkit.EtoolkitInstanceError) as exc_info: | 52 | with pytest.raises(etoolkit.EtoolkitInstanceError) as exc_info: |
| 52 | env = instance.get_environ() | 53 | env = instance.get_environ() |
| @@ -68,16 +69,14 @@ def test_get_environ( | |||
| 68 | assert 'ETOOLKIT_TEST_PASSWORD2' in instance.sensitive_env_variables | 69 | assert 'ETOOLKIT_TEST_PASSWORD2' in instance.sensitive_env_variables |
| 69 | 70 | ||
| 70 | 71 | ||
| 71 | def test_get_full_name(config_data): | 72 | def test_get_full_name(config_data: dict) -> None: |
| 72 | """Tests the EtoolkitInstance.get_full_name method""" | 73 | """Tests the EtoolkitInstance.get_full_name method""" |
| 73 | |||
| 74 | instance = etoolkit.EtoolkitInstance('secret', config_data) | 74 | instance = etoolkit.EtoolkitInstance('secret', config_data) |
| 75 | assert instance.get_full_name('->') == '_default->secret' | 75 | assert instance.get_full_name('->') == '_default->secret' |
| 76 | 76 | ||
| 77 | 77 | ||
| 78 | def test_parent_vars(config_data): | 78 | def test_parent_vars(config_data: dict) -> None: |
| 79 | """Tests the EtoolkitInstance.get_full_name method""" | 79 | """Tests the EtoolkitInstance.get_full_name method""" |
| 80 | |||
| 81 | instance = etoolkit.EtoolkitInstance('dev', config_data) | 80 | instance = etoolkit.EtoolkitInstance('dev', config_data) |
| 82 | assert instance.get_full_name('->') == '_default->dev' | 81 | assert instance.get_full_name('->') == '_default->dev' |
| 83 | assert instance.get_environ()['ETOOLKIT_TEST_PYTHONPATH'] == ( | 82 | assert instance.get_environ()['ETOOLKIT_TEST_PYTHONPATH'] == ( |
diff --git a/tests/test_envtoolkit_instance_static.py b/tests/test_envtoolkit_instance_static.py index e13d439..8c21a0f 100644 --- a/tests/test_envtoolkit_instance_static.py +++ b/tests/test_envtoolkit_instance_static.py | |||
| @@ -23,9 +23,10 @@ import etoolkit | |||
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | @unittest.mock.patch('getpass.getpass') | 25 | @unittest.mock.patch('getpass.getpass') |
| 26 | def test_confirm_password_prompt(getpass, password_hash, master_password): | 26 | def test_confirm_password_prompt( |
| 27 | getpass: unittest.mock.MagicMock, password_hash: str, master_password: str | ||
| 28 | ) -> None: | ||
| 27 | """Tests the static EtoolkitInstance.confirm_password_prompt method""" | 29 | """Tests the static EtoolkitInstance.confirm_password_prompt method""" |
| 28 | |||
| 29 | getpass.return_value = master_password | 30 | getpass.return_value = master_password |
| 30 | assert ( | 31 | assert ( |
| 31 | etoolkit.EtoolkitInstance.confirm_password_prompt(password_hash) | 32 | etoolkit.EtoolkitInstance.confirm_password_prompt(password_hash) |
| @@ -37,9 +38,10 @@ def test_confirm_password_prompt(getpass, password_hash, master_password): | |||
| 37 | ) | 38 | ) |
| 38 | 39 | ||
| 39 | 40 | ||
| 40 | def test_decrypt_v1(master_password, short_encrypted_value_v1, short_value): | 41 | def test_decrypt_v1( |
| 42 | master_password: str, short_encrypted_value_v1: str, short_value: str | ||
| 43 | ) -> None: | ||
| 41 | """Tests the static EtoolkitInstance.decrypt method""" | 44 | """Tests the static EtoolkitInstance.decrypt method""" |
| 42 | |||
| 43 | assert ( | 45 | assert ( |
| 44 | etoolkit.EtoolkitInstance.decrypt( | 46 | etoolkit.EtoolkitInstance.decrypt( |
| 45 | master_password, short_encrypted_value_v1 | 47 | master_password, short_encrypted_value_v1 |
| @@ -59,10 +61,9 @@ def test_decrypt_v1(master_password, short_encrypted_value_v1, short_value): | |||
| 59 | 61 | ||
| 60 | 62 | ||
| 61 | def test_decrypt_v2_no_padding( | 63 | def test_decrypt_v2_no_padding( |
| 62 | master_password, long_encrypted_value, long_value | 64 | master_password: str, long_encrypted_value: str, long_value: str |
| 63 | ): | 65 | ) -> None: |
| 64 | """Tests the static EtoolkitInstance.decrypt method for v2 - no padding""" | 66 | """Tests the static EtoolkitInstance.decrypt method for v2 - no padding""" |
| 65 | |||
| 66 | assert ( | 67 | assert ( |
| 67 | etoolkit.EtoolkitInstance.decrypt( | 68 | etoolkit.EtoolkitInstance.decrypt( |
| 68 | master_password, long_encrypted_value | 69 | master_password, long_encrypted_value |
| @@ -80,10 +81,9 @@ def test_decrypt_v2_no_padding( | |||
| 80 | 81 | ||
| 81 | 82 | ||
| 82 | def test_decrypt_v2_with_padding( | 83 | def test_decrypt_v2_with_padding( |
| 83 | master_password, short_encrypted_value, short_value | 84 | master_password: str, short_encrypted_value: str, short_value: str |
| 84 | ): | 85 | ) -> None: |
| 85 | """Tests the static EtoolkitInstance.decrypt method for v2 with padding""" | 86 | """Tests the static EtoolkitInstance.decrypt method for v2 with padding""" |
| 86 | |||
| 87 | assert ( | 87 | assert ( |
| 88 | etoolkit.EtoolkitInstance.decrypt( | 88 | etoolkit.EtoolkitInstance.decrypt( |
| 89 | master_password, short_encrypted_value | 89 | master_password, short_encrypted_value |
| @@ -99,9 +99,8 @@ def test_decrypt_v2_with_padding( | |||
| 99 | assert exc_info.value.args[0] == f'Invalid tag when decrypting: {edata}' | 99 | assert exc_info.value.args[0] == f'Invalid tag when decrypting: {edata}' |
| 100 | 100 | ||
| 101 | 101 | ||
| 102 | def test_encrypt_no_padding(master_password, long_value): | 102 | def test_encrypt_no_padding(master_password: str, long_value: str) -> None: |
| 103 | """Tests the static EtoolkitInstance.encrypt method with a long string""" | 103 | """Tests the static EtoolkitInstance.encrypt method with a long string""" |
| 104 | |||
| 105 | edata = etoolkit.EtoolkitInstance.encrypt(master_password, long_value) | 104 | edata = etoolkit.EtoolkitInstance.encrypt(master_password, long_value) |
| 106 | assert edata.startswith('enc-val$2$') | 105 | assert edata.startswith('enc-val$2$') |
| 107 | assert len(edata) == 131 | 106 | assert len(edata) == 131 |
| @@ -111,9 +110,8 @@ def test_encrypt_no_padding(master_password, long_value): | |||
| 111 | ) | 110 | ) |
| 112 | 111 | ||
| 113 | 112 | ||
| 114 | def test_encrypt_with_padding(master_password, short_value): | 113 | def test_encrypt_with_padding(master_password: str, short_value: str) -> None: |
| 115 | """Tests the static EtoolkitInstance.encrypt method with a short string""" | 114 | """Tests the static EtoolkitInstance.encrypt method with a short string""" |
| 116 | |||
| 117 | edata = etoolkit.EtoolkitInstance.encrypt(master_password, short_value) | 115 | edata = etoolkit.EtoolkitInstance.encrypt(master_password, short_value) |
| 118 | assert edata.startswith('enc-val$2$') | 116 | assert edata.startswith('enc-val$2$') |
| 119 | assert len(edata) == 123 | 117 | assert len(edata) == 123 |
| @@ -125,14 +123,13 @@ def test_encrypt_with_padding(master_password, short_value): | |||
| 125 | 123 | ||
| 126 | @unittest.mock.patch('os.urandom') | 124 | @unittest.mock.patch('os.urandom') |
| 127 | def test_encrypt_staticly_no_padding( | 125 | def test_encrypt_staticly_no_padding( |
| 128 | urandom, | 126 | urandom: unittest.mock.MagicMock, |
| 129 | master_password, | 127 | master_password: str, |
| 130 | non_random_bytes_32, | 128 | non_random_bytes_32: bytes, |
| 131 | long_encrypted_value, | 129 | long_encrypted_value: str, |
| 132 | long_value, | 130 | long_value: str, |
| 133 | ): | 131 | ) -> None: |
| 134 | """Tests the EtoolkitInstance.encrypt method always with the same salt""" | 132 | """Tests the EtoolkitInstance.encrypt method always with the same salt""" |
| 135 | |||
| 136 | urandom.return_value = non_random_bytes_32 | 133 | urandom.return_value = non_random_bytes_32 |
| 137 | edata = etoolkit.EtoolkitInstance.encrypt(master_password, long_value) | 134 | edata = etoolkit.EtoolkitInstance.encrypt(master_password, long_value) |
| 138 | assert edata == long_encrypted_value | 135 | assert edata == long_encrypted_value |
| @@ -144,14 +141,13 @@ def test_encrypt_staticly_no_padding( | |||
| 144 | 141 | ||
| 145 | @unittest.mock.patch('os.urandom') | 142 | @unittest.mock.patch('os.urandom') |
| 146 | def test_encrypt_staticly_with_padding( | 143 | def test_encrypt_staticly_with_padding( |
| 147 | urandom, | 144 | urandom: unittest.mock.MagicMock, |
| 148 | master_password, | 145 | master_password: str, |
| 149 | non_random_bytes_57, | 146 | non_random_bytes_57: bytes, |
| 150 | short_encrypted_value, | 147 | short_encrypted_value: str, |
| 151 | short_value, | 148 | short_value: str, |
| 152 | ): | 149 | ) -> None: |
| 153 | """Tests the EtoolkitInstance.encrypt method always with the same salt""" | 150 | """Tests the EtoolkitInstance.encrypt method always with the same salt""" |
| 154 | |||
| 155 | urandom.return_value = non_random_bytes_57 | 151 | urandom.return_value = non_random_bytes_57 |
| 156 | edata = etoolkit.EtoolkitInstance.encrypt(master_password, short_value) | 152 | edata = etoolkit.EtoolkitInstance.encrypt(master_password, short_value) |
| 157 | assert edata == short_encrypted_value | 153 | assert edata == short_encrypted_value |
| @@ -160,9 +156,8 @@ def test_encrypt_staticly_with_padding( | |||
| 160 | ) | 156 | ) |
| 161 | 157 | ||
| 162 | 158 | ||
| 163 | def test_get_new_password_hash(master_password): | 159 | def test_get_new_password_hash(master_password: str) -> None: |
| 164 | """Tests the static EtoolkitInstance.get_new_password_hash method""" | 160 | """Tests the static EtoolkitInstance.get_new_password_hash method""" |
| 165 | |||
| 166 | new_hash = etoolkit.EtoolkitInstance.get_new_password_hash(master_password) | 161 | new_hash = etoolkit.EtoolkitInstance.get_new_password_hash(master_password) |
| 167 | # all pbkdf2 params are the same / hardcoded for the time being | 162 | # all pbkdf2 params are the same / hardcoded for the time being |
| 168 | assert new_hash.startswith('pbkdf2_sha256$500000$') | 163 | assert new_hash.startswith('pbkdf2_sha256$500000$') |
| @@ -173,9 +168,8 @@ def test_get_new_password_hash(master_password): | |||
| 173 | ) | 168 | ) |
| 174 | 169 | ||
| 175 | 170 | ||
| 176 | def test_parse_value(): | 171 | def test_parse_value() -> None: |
| 177 | """Tests the static EtoolkitInstance.parse_value method""" | 172 | """Tests the static EtoolkitInstance.parse_value method""" |
| 178 | |||
| 179 | assert ( | 173 | assert ( |
| 180 | etoolkit.EtoolkitInstance.parse_value('t%bs%t', {'%b': 'e', '%t': 't'}) | 174 | etoolkit.EtoolkitInstance.parse_value('t%bs%t', {'%b': 'e', '%t': 't'}) |
| 181 | == 'test' | 175 | == 'test' |
| @@ -183,10 +177,9 @@ def test_parse_value(): | |||
| 183 | 177 | ||
| 184 | 178 | ||
| 185 | def test_password_matches( | 179 | def test_password_matches( |
| 186 | password_hash, master_password, wrong_master_password | 180 | password_hash: str, master_password: str, wrong_master_password: str |
| 187 | ): | 181 | ) -> None: |
| 188 | """Tests the static EtoolkitInstance.password_matches method""" | 182 | """Tests the static EtoolkitInstance.password_matches method""" |
| 189 | |||
| 190 | assert etoolkit.EtoolkitInstance.password_matches( | 183 | assert etoolkit.EtoolkitInstance.password_matches( |
| 191 | master_password, password_hash | 184 | master_password, password_hash |
| 192 | ) | 185 | ) |
| @@ -197,16 +190,15 @@ def test_password_matches( | |||
| 197 | 190 | ||
| 198 | @unittest.mock.patch('os.urandom') | 191 | @unittest.mock.patch('os.urandom') |
| 199 | def test_reencrypt_staticly_with_padding( | 192 | def test_reencrypt_staticly_with_padding( |
| 200 | urandom, | 193 | urandom: unittest.mock.MagicMock, |
| 201 | master_password, | 194 | master_password: str, |
| 202 | new_master_password, | 195 | new_master_password: str, |
| 203 | non_random_bytes_57, | 196 | non_random_bytes_57: bytes, |
| 204 | short_encrypted_value, | 197 | short_encrypted_value: str, |
| 205 | short_encrypted_value_v1, | 198 | short_encrypted_value_v1: str, |
| 206 | short_value, | 199 | short_value: str, |
| 207 | ): | 200 | ) -> None: |
| 208 | """Tests the EtoolkitInstance.reencrypt method always with the same salt""" | 201 | """Tests the EtoolkitInstance.reencrypt method always with the same salt""" |
| 209 | |||
| 210 | urandom.return_value = non_random_bytes_57 | 202 | urandom.return_value = non_random_bytes_57 |
| 211 | # reencrypt (migrate) v1 to current using the same password | 203 | # reencrypt (migrate) v1 to current using the same password |
| 212 | edata = etoolkit.EtoolkitInstance.reencrypt( | 204 | edata = etoolkit.EtoolkitInstance.reencrypt( |
