summaryrefslogtreecommitdiff
path: root/tests/test_main.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_main.py')
-rw-r--r--tests/test_main.py225
1 files changed, 225 insertions, 0 deletions
diff --git a/tests/test_main.py b/tests/test_main.py
new file mode 100644
index 0000000..3c75621
--- /dev/null
+++ b/tests/test_main.py
@@ -0,0 +1,225 @@
1# SPDX-License-Identifier: BSD-2-Clause
2#
3# Copyright (c) 2020-2026, Simeon Simeonov
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright notice,
12# this list of conditions and the following disclaimer in the documentation
13# and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
16# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25"""Tests for otp2289.__main__"""
26
27import os
28import unittest.mock
29
30import pytest
31
32from otp2289.__main__ import main
33
34
35def test_main_generate_otp_response(capsys: pytest.CaptureFixture) -> None:
36 """tests main"""
37 args = [
38 '--generate-otp-response',
39 '-a',
40 'sha1',
41 '-i',
42 '99',
43 '-s',
44 'TesT',
45 '-p',
46 'This is a test.',
47 ]
48 with pytest.raises(SystemExit) as exit_info:
49 main(args)
50 captured = capsys.readouterr()
51 assert captured.out == (
52 f'Seed: TesT, Step: 99, Hash: sha1{os.linesep}'
53 f'0x87fec7768b73ccf9{os.linesep}'
54 )
55 assert exit_info.value.code == 0
56 args.extend(['-f', 'token'])
57 with pytest.raises(SystemExit) as exit_info:
58 main(args)
59 captured = capsys.readouterr()
60 assert captured.out == (
61 f'Seed: TesT, Step: 99, Hash: sha1{os.linesep}'
62 f'GAFF WAIT SKID GIG SKY EYED{os.linesep}'
63 )
64 assert exit_info.value.code == 0
65 args.append('-q')
66 with pytest.raises(SystemExit) as exit_info:
67 main(args)
68 captured = capsys.readouterr()
69 assert captured.out == f'GAFF WAIT SKID GIG SKY EYED{os.linesep}'
70 assert exit_info.value.code == 0
71
72
73def test_main_generate_otp_response_env_passwd(
74 capsys: pytest.CaptureFixture,
75) -> None:
76 """tests main by fetching password from the env. var. 'OTP2289_PASSWORD'"""
77 args = ['--generate-otp-response', '-a', 'sha1', '-i', '99', '-s', 'TesT']
78 with unittest.mock.patch.dict(
79 os.environ, {'OTP2289_PASSWORD': 'This is a test.'}
80 ):
81 with pytest.raises(SystemExit) as exit_info:
82 main(args)
83 captured = capsys.readouterr()
84 assert captured.out == (
85 f'Seed: TesT, Step: 99, Hash: sha1{os.linesep}'
86 f'0x87fec7768b73ccf9{os.linesep}'
87 )
88 assert exit_info.value.code == 0
89 args.extend(['-f', 'token'])
90 with pytest.raises(SystemExit) as exit_info:
91 main(args)
92 captured = capsys.readouterr()
93 assert captured.out == (
94 f'Seed: TesT, Step: 99, Hash: sha1{os.linesep}'
95 f'GAFF WAIT SKID GIG SKY EYED{os.linesep}'
96 )
97 assert exit_info.value.code == 0
98 args.append('-q')
99 with pytest.raises(SystemExit) as exit_info:
100 main(args)
101 captured = capsys.readouterr()
102 assert captured.out == f'GAFF WAIT SKID GIG SKY EYED{os.linesep}'
103 assert exit_info.value.code == 0
104
105
106def test_main_generate_otp_range(capsys: pytest.CaptureFixture) -> None:
107 """tests main"""
108 args = [
109 '--generate-otp-range',
110 '-i',
111 '2',
112 '-s',
113 'TesT',
114 '-r',
115 '5',
116 '-p',
117 'This is a test.',
118 ]
119 with pytest.raises(SystemExit) as exit_info:
120 main(args)
121 captured = capsys.readouterr()
122 assert captured.out == (
123 f'Seed: TesT, Step: 2, Hash: md5, Range: 3'
124 f'{os.linesep}'
125 f'2: 0x4049f8b161669b7b{os.linesep}'
126 f'1: 0x7965e05436f5029f{os.linesep}'
127 f'0: 0x9e876134d90499dd{os.linesep}'
128 )
129 assert exit_info.value.code == 0
130 args.append('-q')
131 with pytest.raises(SystemExit) as exit_info:
132 main(args)
133 captured = capsys.readouterr()
134 assert captured.out == (
135 f'2: 0x4049f8b161669b7b{os.linesep}'
136 f'1: 0x7965e05436f5029f{os.linesep}'
137 f'0: 0x9e876134d90499dd{os.linesep}'
138 )
139 assert exit_info.value.code == 0
140 args.extend(['-f', 'token'])
141 with pytest.raises(SystemExit) as exit_info:
142 main(args)
143 captured = capsys.readouterr()
144 assert captured.out == (
145 f'2: THY AVON NO NECK COKE MOLL{os.linesep}'
146 f'1: EASE OIL FUM CURE AWRY AVIS{os.linesep}'
147 f'0: INCH SEA ANNE LONG AHEM TOUR{os.linesep}'
148 )
149 assert exit_info.value.code == 0
150
151
152@pytest.mark.parametrize(
153 'args',
154 [
155 ['--generate-otp-range', '-i', '2', '-s', 'TesT', '-r', '5'],
156 ['--generate-otp-range', '-i', '2', '-s', 'TesT', '-r', '5', '-P'],
157 ],
158)
159@unittest.mock.patch('getpass.getpass')
160def test_main_generate_otp_range_passwd_prompt(
161 getpass: unittest.mock.MagicMock,
162 capsys: pytest.CaptureFixture,
163 args: list[str],
164) -> None:
165 """tests main by prompting for password (with or without -P)"""
166 args = ['--generate-otp-range', '-i', '2', '-s', 'TesT', '-r', '5']
167 getpass.return_value = 'This is a test.'
168 with pytest.raises(SystemExit) as exit_info:
169 main(args)
170 captured = capsys.readouterr()
171 assert captured.out == (
172 f'Seed: TesT, Step: 2, Hash: md5, Range: 3'
173 f'{os.linesep}'
174 f'2: 0x4049f8b161669b7b{os.linesep}'
175 f'1: 0x7965e05436f5029f{os.linesep}'
176 f'0: 0x9e876134d90499dd{os.linesep}'
177 )
178 assert exit_info.value.code == 0
179 args.append('-q')
180 with pytest.raises(SystemExit) as exit_info:
181 main(args)
182 captured = capsys.readouterr()
183 assert captured.out == (
184 f'2: 0x4049f8b161669b7b{os.linesep}'
185 f'1: 0x7965e05436f5029f{os.linesep}'
186 f'0: 0x9e876134d90499dd{os.linesep}'
187 )
188 assert exit_info.value.code == 0
189 args.extend(['-f', 'token'])
190 with pytest.raises(SystemExit) as exit_info:
191 main(args)
192 captured = capsys.readouterr()
193 assert captured.out == (
194 f'2: THY AVON NO NECK COKE MOLL{os.linesep}'
195 f'1: EASE OIL FUM CURE AWRY AVIS{os.linesep}'
196 f'0: INCH SEA ANNE LONG AHEM TOUR{os.linesep}'
197 )
198 assert exit_info.value.code == 0
199
200
201def test_main_initiate(capsys: pytest.CaptureFixture) -> None:
202 """tests main"""
203 args = [
204 '--initiate-new-sequence',
205 '-i',
206 '500',
207 '-s',
208 'TesT',
209 '-p',
210 'This is a test.',
211 ]
212 with pytest.raises(SystemExit) as exit_info:
213 main(args)
214 captured = capsys.readouterr()
215 assert captured.out == (
216 f'Seed: TesT, Step: 500, Hash: md5{os.linesep}'
217 f'0x2b8d82b6ac14346c{os.linesep}'
218 )
219 assert exit_info.value.code == 0
220 args.append('-q')
221 with pytest.raises(SystemExit) as exit_info:
222 main(args)
223 captured = capsys.readouterr()
224 assert captured.out == f'0x2b8d82b6ac14346c{os.linesep}'
225 assert exit_info.value.code == 0