add output tests

pull/16/head v1.5.0
scito 2 years ago
parent eac342c0cc
commit 9d08ebaa38

@ -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

@ -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()

@ -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…
Cancel
Save