mirror of
https://github.com/scito/extract_otp_secret_keys.git
synced 2025-12-06 14:54:57 +01:00
add output tests
This commit is contained in:
parent
eac342c0cc
commit
9d08ebaa38
5 changed files with 255 additions and 7 deletions
|
|
@ -84,24 +84,23 @@ devbox shell
|
|||
|
||||
### PyTest
|
||||
|
||||
There are basic pytests, see `test_extract_otp_secret_keys_pytest.py`.
|
||||
There are basic [pytest](https://pytest.org)s, see `test_extract_otp_secret_keys_pytest.py`.
|
||||
|
||||
Run tests:
|
||||
|
||||
```
|
||||
pytest unittest
|
||||
pytest
|
||||
```
|
||||
or
|
||||
|
||||
```
|
||||
python -m pytest
|
||||
```
|
||||
|
||||
### unittest
|
||||
|
||||
There are basic unit tests, see `test_extract_otp_secret_keys_unittest.py`.
|
||||
There are basic [unittest](https://docs.python.org/3.10/library/unittest.html)s, see `test_extract_otp_secret_keys_unittest.py`.
|
||||
|
||||
Run unit tests:
|
||||
Run tests:
|
||||
|
||||
```
|
||||
python -m unittest
|
||||
|
|
|
|||
106
test/printqr_output.txt
Normal file
106
test/printqr_output.txt
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
Name: pi@raspberrypi
|
||||
Secret: 7KSQL2JTUDIS5EF65KLMRQIIGY
|
||||
Issuer: raspberrypi
|
||||
Type: OTP_TOTP
|
||||
|
||||
|
||||
█▀▀▀▀▀█ ▄▀▄▄█ █▀ ▀▀▀▀▀█ ▄▄ █▀▀▀▀▀█
|
||||
█ ███ █ ███▀ ▀█ █▄ ▀ ▀▄▀█▄▄ █ █ ███ █
|
||||
█ ▀▀▀ █ ██▄▄ ██ ▀█▀█▄▄▀▄ ▄▄█ █ ▀▀▀ █
|
||||
▀▀▀▀▀▀▀ █ █ █▄▀ █ ▀▄▀▄█ █ ▀ █ ▀▀▀▀▀▀▀
|
||||
█▄█▀▀█▀ ▄▀▀ ▄▀██▄▀ ▄█▄█▄ ▄▄ ██▀▀█▄
|
||||
▀ █▀▀▀ ██▀█ ▄▀▀▄ ██ ▄▀▄█ █ ▄▄▀█
|
||||
▄█▀█ ▄▀█▄▄ ▄▀▄▄▀ ▄█▄█▄ ▀ ▀ ▀▄▀▀█
|
||||
▀▄ ▄▄▄▀▄█▄██▀▄██▀ █▄█▄ ▄▄▀▄█ ▄ █▀ ▀
|
||||
▄ ▄█ ▀▀▄▄ ▄▄▀█▄█▀▀▄██▄▀▄▀▀ █▀█ █▄███
|
||||
▀▀▄▀ ▀ ▀▄▀▀█ █▀▀█ █▄ █▄██ ▀█▀▀█▀
|
||||
▀█▄██▀▀█ ▄▀█▀███▄▄▀▄█▄ ▀▄▀██▀▀▀▄ ▀▄
|
||||
█▄█ ▀ ▀▀▀▄▄▄ ▀ ▀█▄ ▄▀▀█▄██ ▄ ▀▄
|
||||
█▀ ▀ ▀▄ █▀▀█▀▀█▄ ██▄▄█▄ ▀▀▀▄█▀▀▀ ▀ ▀
|
||||
█ █▀▄▄▀█▀█▀▀▀ ▀ ▄ ▄ ▄ ▄▄ ▀▀▀▀█▄▄▄ █▀
|
||||
▀ ▀▀ ▀▀ ▄ █▀▀▀ █ ▄▄▄█▄▀█▄▀█▀▀▀█ ▀▀▀
|
||||
█▀▀▀▀▀█ ▄▀█▀█ ███▄ ▄▄▄█ ▄ █ ▀ █ ▄
|
||||
█ ███ █ █▄█▄▄▀█▄▀ ▄▄▄ █▄ ▀█▀███▀█ ▀▀
|
||||
█ ▀▀▀ █ ▀█▄▄▄█▀█▀ ▄ █▄▄▄ █ ▀ ██ █
|
||||
▀▀▀▀▀▀▀ ▀ ▀ ▀▀▀▀▀▀ ▀ ▀ ▀▀ ▀ ▀▀ ▀ ▀▀
|
||||
|
||||
|
||||
|
||||
Name: pi@raspberrypi
|
||||
Secret: 7KSQL2JTUDIS5EF65KLMRQIIGY
|
||||
Type: OTP_TOTP
|
||||
|
||||
|
||||
█▀▀▀▀▀█ ▀▀██ █▄▀█ ▀▄▄▀█▀▄ █▀▀▀▀▀█
|
||||
█ ███ █ ▄ ▀▀▀ ▀▀█▀█▀▄ ▄█▀ █ ███ █
|
||||
█ ▀▀▀ █ █▀▄▄▄█▄▄▀ ▄ ▄ ▀▄▄ █ ▀▀▀ █
|
||||
▀▀▀▀▀▀▀ █ █▄▀ ▀ ▀▄█ ▀▄█ █ ▀▀▀▀▀▀▀
|
||||
▀▄▄▄█▄▀██▄█▀█ ▄███ █ █ ▀▀▀▀█▄▄▀
|
||||
▄▀ ▀ █ █▀█▀▀█▀ ▄█▀██▀█▀▀ █▄
|
||||
█▀█ ▄▀▀▀ ███▄█▄ ▀ █▀▄█▀▀█▀▀▀█▄▀▀
|
||||
▀▄▀▄▄ ▀▄▄ ▀▀▄█▀██▄▄ █▄ ▄ █▀█ █▄
|
||||
▀██▄█▄▀█ ▄▄ ▀▀▄▄█▀ ▀▄▀█▄▀█▀▄▀ ▄
|
||||
▀▄▄▀▄▀▀▀▄ █ ▀█▀█▄▄ ▄█ █▄ ▀█▀ █▄
|
||||
▄█ ▄ ▀ ▀ ▄ ▀█ ▄ ▀▄█ ▀▄▄█ ▄█▀ ▄▄
|
||||
▄█▀▄▀▀ ██ ▄ ▀ █ █▀██ ███ █ ▀█▄
|
||||
▀▀▀ ▀▀ ▄██▀█▀███▀▄ ▄▀▀██▀▀▀█▀▄ ▀
|
||||
█▀▀▀▀▀█ ▀█▀▄██▀█ ▀█ █ ▄ █ ▀ █ ▄
|
||||
█ ███ █ ▀█▄▄█▀▀▄ ▀▀▄▄ ▄▀████▀▄█
|
||||
█ ▀▀▀ █ ▄ █ █▀▀▀▄ ▄█▀▄▀ ▀ █▀▀
|
||||
▀▀▀▀▀▀▀ ▀ ▀ ▀ ▀▀ ▀ ▀▀ ▀▀ ▀▀ ▀
|
||||
|
||||
|
||||
|
||||
Name: pi@raspberrypi
|
||||
Secret: 7KSQL2JTUDIS5EF65KLMRQIIGY
|
||||
Type: OTP_TOTP
|
||||
|
||||
|
||||
█▀▀▀▀▀█ ▀▀██ █▄▀█ ▀▄▄▀█▀▄ █▀▀▀▀▀█
|
||||
█ ███ █ ▄ ▀▀▀ ▀▀█▀█▀▄ ▄█▀ █ ███ █
|
||||
█ ▀▀▀ █ █▀▄▄▄█▄▄▀ ▄ ▄ ▀▄▄ █ ▀▀▀ █
|
||||
▀▀▀▀▀▀▀ █ █▄▀ ▀ ▀▄█ ▀▄█ █ ▀▀▀▀▀▀▀
|
||||
▀▄▄▄█▄▀██▄█▀█ ▄███ █ █ ▀▀▀▀█▄▄▀
|
||||
▄▀ ▀ █ █▀█▀▀█▀ ▄█▀██▀█▀▀ █▄
|
||||
█▀█ ▄▀▀▀ ███▄█▄ ▀ █▀▄█▀▀█▀▀▀█▄▀▀
|
||||
▀▄▀▄▄ ▀▄▄ ▀▀▄█▀██▄▄ █▄ ▄ █▀█ █▄
|
||||
▀██▄█▄▀█ ▄▄ ▀▀▄▄█▀ ▀▄▀█▄▀█▀▄▀ ▄
|
||||
▀▄▄▀▄▀▀▀▄ █ ▀█▀█▄▄ ▄█ █▄ ▀█▀ █▄
|
||||
▄█ ▄ ▀ ▀ ▄ ▀█ ▄ ▀▄█ ▀▄▄█ ▄█▀ ▄▄
|
||||
▄█▀▄▀▀ ██ ▄ ▀ █ █▀██ ███ █ ▀█▄
|
||||
▀▀▀ ▀▀ ▄██▀█▀███▀▄ ▄▀▀██▀▀▀█▀▄ ▀
|
||||
█▀▀▀▀▀█ ▀█▀▄██▀█ ▀█ █ ▄ █ ▀ █ ▄
|
||||
█ ███ █ ▀█▄▄█▀▀▄ ▀▀▄▄ ▄▀████▀▄█
|
||||
█ ▀▀▀ █ ▄ █ █▀▀▀▄ ▄█▀▄▀ ▀ █▀▀
|
||||
▀▀▀▀▀▀▀ ▀ ▀ ▀ ▀▀ ▀ ▀▀ ▀▀ ▀▀ ▀
|
||||
|
||||
|
||||
|
||||
Name: pi@raspberrypi
|
||||
Secret: 7KSQL2JTUDIS5EF65KLMRQIIGY
|
||||
Issuer: raspberrypi
|
||||
Type: OTP_TOTP
|
||||
|
||||
|
||||
█▀▀▀▀▀█ ▄▀▄▄█ █▀ ▀▀▀▀▀█ ▄▄ █▀▀▀▀▀█
|
||||
█ ███ █ ███▀ ▀█ █▄ ▀ ▀▄▀█▄▄ █ █ ███ █
|
||||
█ ▀▀▀ █ ██▄▄ ██ ▀█▀█▄▄▀▄ ▄▄█ █ ▀▀▀ █
|
||||
▀▀▀▀▀▀▀ █ █ █▄▀ █ ▀▄▀▄█ █ ▀ █ ▀▀▀▀▀▀▀
|
||||
█▄█▀▀█▀ ▄▀▀ ▄▀██▄▀ ▄█▄█▄ ▄▄ ██▀▀█▄
|
||||
▀ █▀▀▀ ██▀█ ▄▀▀▄ ██ ▄▀▄█ █ ▄▄▀█
|
||||
▄█▀█ ▄▀█▄▄ ▄▀▄▄▀ ▄█▄█▄ ▀ ▀ ▀▄▀▀█
|
||||
▀▄ ▄▄▄▀▄█▄██▀▄██▀ █▄█▄ ▄▄▀▄█ ▄ █▀ ▀
|
||||
▄ ▄█ ▀▀▄▄ ▄▄▀█▄█▀▀▄██▄▀▄▀▀ █▀█ █▄███
|
||||
▀▀▄▀ ▀ ▀▄▀▀█ █▀▀█ █▄ █▄██ ▀█▀▀█▀
|
||||
▀█▄██▀▀█ ▄▀█▀███▄▄▀▄█▄ ▀▄▀██▀▀▀▄ ▀▄
|
||||
█▄█ ▀ ▀▀▀▄▄▄ ▀ ▀█▄ ▄▀▀█▄██ ▄ ▀▄
|
||||
█▀ ▀ ▀▄ █▀▀█▀▀█▄ ██▄▄█▄ ▀▀▀▄█▀▀▀ ▀ ▀
|
||||
█ █▀▄▄▀█▀█▀▀▀ ▀ ▄ ▄ ▄ ▄▄ ▀▀▀▀█▄▄▄ █▀
|
||||
▀ ▀▀ ▀▀ ▄ █▀▀▀ █ ▄▄▄█▄▀█▄▀█▀▀▀█ ▀▀▀
|
||||
█▀▀▀▀▀█ ▄▀█▀█ ███▄ ▄▄▄█ ▄ █ ▀ █ ▄
|
||||
█ ███ █ █▄█▄▄▀█▄▀ ▄▄▄ █▄ ▀█▀███▀█ ▀▀
|
||||
█ ▀▀▀ █ ▀█▄▄▄█▀█▀ ▄ █▄▄▄ █ ▀ ██ █
|
||||
▀▀▀▀▀▀▀ ▀ ▀ ▀▀▀▀▀▀ ▀ ▀ ▀▀ ▀ ▀▀ ▀ ▀▀
|
||||
|
||||
|
||||
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
from utils import read_csv, read_json, remove_file
|
||||
from utils import read_csv, read_json, remove_file, read_file_to_str
|
||||
|
||||
import extract_otp_secret_keys
|
||||
|
||||
|
|
@ -47,6 +47,7 @@ def test_extract_json():
|
|||
# Act
|
||||
extract_otp_secret_keys.main(['-q', '-j', 'test_example_output.json', 'example_export.txt'])
|
||||
|
||||
# Assert
|
||||
expected_json = read_json('example_output.json')
|
||||
actual_json = read_json('test_example_output.json')
|
||||
|
||||
|
|
@ -56,6 +57,50 @@ def test_extract_json():
|
|||
cleanup()
|
||||
|
||||
|
||||
def test_extract_stdout(capsys):
|
||||
# Act
|
||||
extract_otp_secret_keys.main(['example_export.txt'])
|
||||
|
||||
# Assert
|
||||
captured = capsys.readouterr()
|
||||
|
||||
expected_stdout = '''Name: pi@raspberrypi
|
||||
Secret: 7KSQL2JTUDIS5EF65KLMRQIIGY
|
||||
Issuer: raspberrypi
|
||||
Type: OTP_TOTP
|
||||
|
||||
Name: pi@raspberrypi
|
||||
Secret: 7KSQL2JTUDIS5EF65KLMRQIIGY
|
||||
Type: OTP_TOTP
|
||||
|
||||
Name: pi@raspberrypi
|
||||
Secret: 7KSQL2JTUDIS5EF65KLMRQIIGY
|
||||
Type: OTP_TOTP
|
||||
|
||||
Name: pi@raspberrypi
|
||||
Secret: 7KSQL2JTUDIS5EF65KLMRQIIGY
|
||||
Issuer: raspberrypi
|
||||
Type: OTP_TOTP
|
||||
|
||||
'''
|
||||
|
||||
assert captured.out == expected_stdout
|
||||
assert captured.err == ''
|
||||
|
||||
|
||||
def test_extract_printqr(capsys):
|
||||
# Act
|
||||
extract_otp_secret_keys.main(['-p', 'example_export.txt'])
|
||||
|
||||
# Assert
|
||||
captured = capsys.readouterr()
|
||||
|
||||
expected_stdout = read_file_to_str('test/printqr_output.txt')
|
||||
|
||||
assert captured.out == expected_stdout
|
||||
assert captured.err == ''
|
||||
|
||||
|
||||
def cleanup():
|
||||
remove_file('test_example_output.csv')
|
||||
remove_file('test_example_output.json')
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@
|
|||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import unittest
|
||||
from utils import read_csv, read_json, remove_file
|
||||
import io
|
||||
from contextlib import redirect_stdout
|
||||
from utils import read_csv, read_json, remove_file, Capturing, read_file_to_str
|
||||
|
||||
import extract_otp_secret_keys
|
||||
|
||||
|
|
@ -42,6 +44,70 @@ class TestExtract(unittest.TestCase):
|
|||
|
||||
self.assertEqual(actual_json, expected_json)
|
||||
|
||||
def test_extract_stdout_1(self):
|
||||
with Capturing() as output:
|
||||
extract_otp_secret_keys.main(['example_export.txt'])
|
||||
|
||||
expected_output = [
|
||||
'Name: pi@raspberrypi',
|
||||
'Secret: 7KSQL2JTUDIS5EF65KLMRQIIGY',
|
||||
'Issuer: raspberrypi',
|
||||
'Type: OTP_TOTP',
|
||||
'',
|
||||
'Name: pi@raspberrypi',
|
||||
'Secret: 7KSQL2JTUDIS5EF65KLMRQIIGY',
|
||||
'Type: OTP_TOTP',
|
||||
'',
|
||||
'Name: pi@raspberrypi',
|
||||
'Secret: 7KSQL2JTUDIS5EF65KLMRQIIGY',
|
||||
'Type: OTP_TOTP',
|
||||
'',
|
||||
'Name: pi@raspberrypi',
|
||||
'Secret: 7KSQL2JTUDIS5EF65KLMRQIIGY',
|
||||
'Issuer: raspberrypi',
|
||||
'Type: OTP_TOTP',
|
||||
''
|
||||
]
|
||||
self.assertEqual(output, expected_output)
|
||||
|
||||
# Ref for capturing https://stackoverflow.com/a/40984270
|
||||
def test_extract_stdout_2(self):
|
||||
out = io.StringIO()
|
||||
with redirect_stdout(out):
|
||||
extract_otp_secret_keys.main(['example_export.txt'])
|
||||
actual_output = out.getvalue()
|
||||
|
||||
expected_output = '''Name: pi@raspberrypi
|
||||
Secret: 7KSQL2JTUDIS5EF65KLMRQIIGY
|
||||
Issuer: raspberrypi
|
||||
Type: OTP_TOTP
|
||||
|
||||
Name: pi@raspberrypi
|
||||
Secret: 7KSQL2JTUDIS5EF65KLMRQIIGY
|
||||
Type: OTP_TOTP
|
||||
|
||||
Name: pi@raspberrypi
|
||||
Secret: 7KSQL2JTUDIS5EF65KLMRQIIGY
|
||||
Type: OTP_TOTP
|
||||
|
||||
Name: pi@raspberrypi
|
||||
Secret: 7KSQL2JTUDIS5EF65KLMRQIIGY
|
||||
Issuer: raspberrypi
|
||||
Type: OTP_TOTP
|
||||
|
||||
'''
|
||||
self.assertEqual(actual_output, expected_output)
|
||||
|
||||
def test_extract_printqr(self):
|
||||
out = io.StringIO()
|
||||
with redirect_stdout(out):
|
||||
extract_otp_secret_keys.main(['-p', 'example_export.txt'])
|
||||
actual_output = out.getvalue()
|
||||
|
||||
expected_output = read_file_to_str('test/printqr_output.txt')
|
||||
|
||||
self.assertEqual(actual_output, expected_output)
|
||||
|
||||
def setUp(self):
|
||||
self.cleanup()
|
||||
|
||||
|
|
|
|||
32
utils.py
32
utils.py
|
|
@ -16,6 +16,27 @@
|
|||
import csv
|
||||
import json
|
||||
import os
|
||||
from io import StringIO
|
||||
import sys
|
||||
|
||||
|
||||
# Ref. https://stackoverflow.com/a/16571630
|
||||
class Capturing(list):
|
||||
'''Capture stdout and stderr
|
||||
Usage:
|
||||
with Capturing() as output:
|
||||
print("Output")
|
||||
'''
|
||||
def __enter__(self):
|
||||
self._stdout = sys.stdout
|
||||
sys.stdout = self._stringio = StringIO()
|
||||
return self
|
||||
|
||||
def __exit__(self, *args):
|
||||
self.extend(self._stringio.getvalue().splitlines())
|
||||
del self._stringio # free up some memory
|
||||
sys.stdout = self._stdout
|
||||
|
||||
|
||||
def remove_file(filename):
|
||||
if os.path.exists(filename): os.remove(filename)
|
||||
|
|
@ -35,3 +56,14 @@ def read_json(filename):
|
|||
"""Returns a list or a dictionary."""
|
||||
with open(filename, "r") as infile:
|
||||
return json.load(infile)
|
||||
|
||||
|
||||
def read_file_to_list(filename):
|
||||
"""Returns a list of lines."""
|
||||
with open(filename, "r") as infile:
|
||||
return infile.readlines()
|
||||
|
||||
|
||||
def read_file_to_str(filename):
|
||||
"""Returns a str."""
|
||||
return "".join(read_file_to_list(filename))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue