0ea17f021eb19d00de8d7583cab2cf260ce6ff1f
Marco Ricci Add prototype command-line...

Marco Ricci authored 2 months ago

1) # SPDX-FileCopyrightText: 2024 Marco Ricci <m@the13thletter.info>
2) #
3) # SPDX-License-Identifier: MIT
4) 
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

5) from __future__ import annotations
6) 
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

7) import contextlib
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

8) import json
9) import os
Marco Ricci Create the configuration di...

Marco Ricci authored 1 month ago

10) import shutil
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

11) import socket
Marco Ricci Fix typing issues in mypy s...

Marco Ricci authored 1 month ago

12) from typing import TYPE_CHECKING
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

13) 
Marco Ricci Add prototype command-line...

Marco Ricci authored 2 months ago

14) import click.testing
15) import pytest
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

16) from typing_extensions import NamedTuple
17) 
18) import derivepassphrase as dpp
19) import ssh_agent_client
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

20) import tests
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

21) from derivepassphrase import cli
22) 
23) if TYPE_CHECKING:
24)     from collections.abc import Callable
25) 
26)     from typing_extensions import Any
Marco Ricci Add prototype command-line...

Marco Ricci authored 2 months ago

27) 
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

28) DUMMY_SERVICE = tests.DUMMY_SERVICE
29) DUMMY_PASSPHRASE = tests.DUMMY_PASSPHRASE
30) DUMMY_CONFIG_SETTINGS = tests.DUMMY_CONFIG_SETTINGS
31) DUMMY_RESULT_PASSPHRASE = tests.DUMMY_RESULT_PASSPHRASE
32) DUMMY_RESULT_KEY1 = tests.DUMMY_RESULT_KEY1
33) DUMMY_PHRASE_FROM_KEY1_RAW = tests.DUMMY_PHRASE_FROM_KEY1_RAW
34) DUMMY_PHRASE_FROM_KEY1 = tests.DUMMY_PHRASE_FROM_KEY1
35) 
36) DUMMY_KEY1 = tests.DUMMY_KEY1
37) DUMMY_KEY1_B64 = tests.DUMMY_KEY1_B64
38) DUMMY_KEY2 = tests.DUMMY_KEY2
Marco Ricci Avoid crashing when overrid...

Marco Ricci authored 1 month ago

39) DUMMY_KEY2_B64 = tests.DUMMY_KEY2_B64
40) DUMMY_KEY3 = tests.DUMMY_KEY3
41) DUMMY_KEY3_B64 = tests.DUMMY_KEY3_B64
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

42) 
43) 
44) class IncompatibleConfiguration(NamedTuple):
45)     other_options: list[tuple[str, ...]]
46)     needs_service: bool | None
47)     input: bytes | None
48) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

49) 
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

50) class SingleConfiguration(NamedTuple):
51)     needs_service: bool | None
52)     input: bytes | None
53)     check_success: bool
54) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

55) 
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

56) class OptionCombination(NamedTuple):
57)     options: list[str]
58)     incompatible: bool
59)     needs_service: bool | None
60)     input: bytes | None
61)     check_success: bool
62) 
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

63) 
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

64) PASSWORD_GENERATION_OPTIONS: list[tuple[str, ...]] = [
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

65)     ('--phrase',),
66)     ('--key',),
67)     ('--length', '20'),
68)     ('--repeat', '20'),
69)     ('--lower', '1'),
70)     ('--upper', '1'),
71)     ('--number', '1'),
72)     ('--space', '1'),
73)     ('--dash', '1'),
74)     ('--symbol', '1'),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

75) ]
76) CONFIGURATION_OPTIONS: list[tuple[str, ...]] = [
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

77)     ('--notes',),
78)     ('--config',),
79)     ('--delete',),
80)     ('--delete-globals',),
81)     ('--clear',),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

82) ]
83) CONFIGURATION_COMMANDS: list[tuple[str, ...]] = [
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

84)     ('--notes',),
85)     ('--delete',),
86)     ('--delete-globals',),
87)     ('--clear',),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

88) ]
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

89) STORAGE_OPTIONS: list[tuple[str, ...]] = [('--export', '-'), ('--import', '-')]
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

90) INCOMPATIBLE: dict[tuple[str, ...], IncompatibleConfiguration] = {
91)     ('--phrase',): IncompatibleConfiguration(
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

92)         [('--key',), *CONFIGURATION_COMMANDS, *STORAGE_OPTIONS],
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

93)         True,
94)         DUMMY_PASSPHRASE,
95)     ),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

96)     ('--key',): IncompatibleConfiguration(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

97)         CONFIGURATION_COMMANDS + STORAGE_OPTIONS, True, DUMMY_PASSPHRASE
98)     ),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

99)     ('--length', '20'): IncompatibleConfiguration(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

100)         CONFIGURATION_COMMANDS + STORAGE_OPTIONS, True, DUMMY_PASSPHRASE
101)     ),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

102)     ('--repeat', '20'): IncompatibleConfiguration(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

103)         CONFIGURATION_COMMANDS + STORAGE_OPTIONS, True, DUMMY_PASSPHRASE
104)     ),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

105)     ('--lower', '1'): IncompatibleConfiguration(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

106)         CONFIGURATION_COMMANDS + STORAGE_OPTIONS, True, DUMMY_PASSPHRASE
107)     ),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

108)     ('--upper', '1'): IncompatibleConfiguration(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

109)         CONFIGURATION_COMMANDS + STORAGE_OPTIONS, True, DUMMY_PASSPHRASE
110)     ),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

111)     ('--number', '1'): IncompatibleConfiguration(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

112)         CONFIGURATION_COMMANDS + STORAGE_OPTIONS, True, DUMMY_PASSPHRASE
113)     ),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

114)     ('--space', '1'): IncompatibleConfiguration(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

115)         CONFIGURATION_COMMANDS + STORAGE_OPTIONS, True, DUMMY_PASSPHRASE
116)     ),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

117)     ('--dash', '1'): IncompatibleConfiguration(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

118)         CONFIGURATION_COMMANDS + STORAGE_OPTIONS, True, DUMMY_PASSPHRASE
119)     ),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

120)     ('--symbol', '1'): IncompatibleConfiguration(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

121)         CONFIGURATION_COMMANDS + STORAGE_OPTIONS, True, DUMMY_PASSPHRASE
122)     ),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

123)     ('--notes',): IncompatibleConfiguration(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

124)         [
125)             ('--config',),
126)             ('--delete',),
127)             ('--delete-globals',),
128)             ('--clear',),
129)             *STORAGE_OPTIONS,
130)         ],
131)         True,
132)         None,
133)     ),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

134)     ('--config', '-p'): IncompatibleConfiguration(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

135)         [('--delete',), ('--delete-globals',), ('--clear',), *STORAGE_OPTIONS],
136)         None,
137)         DUMMY_PASSPHRASE,
138)     ),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

139)     ('--delete',): IncompatibleConfiguration(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

140)         [('--delete-globals',), ('--clear',), *STORAGE_OPTIONS], True, None
141)     ),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

142)     ('--delete-globals',): IncompatibleConfiguration(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

143)         [('--clear',), *STORAGE_OPTIONS], False, None
144)     ),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

145)     ('--clear',): IncompatibleConfiguration(STORAGE_OPTIONS, False, None),
146)     ('--export', '-'): IncompatibleConfiguration(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

147)         [('--import', '-')], False, None
148)     ),
149)     ('--import', '-'): IncompatibleConfiguration([], False, None),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

150) }
151) SINGLES: dict[tuple[str, ...], SingleConfiguration] = {
152)     ('--phrase',): SingleConfiguration(True, DUMMY_PASSPHRASE, True),
153)     ('--key',): SingleConfiguration(True, None, False),
154)     ('--length', '20'): SingleConfiguration(True, DUMMY_PASSPHRASE, True),
155)     ('--repeat', '20'): SingleConfiguration(True, DUMMY_PASSPHRASE, True),
156)     ('--lower', '1'): SingleConfiguration(True, DUMMY_PASSPHRASE, True),
157)     ('--upper', '1'): SingleConfiguration(True, DUMMY_PASSPHRASE, True),
158)     ('--number', '1'): SingleConfiguration(True, DUMMY_PASSPHRASE, True),
159)     ('--space', '1'): SingleConfiguration(True, DUMMY_PASSPHRASE, True),
160)     ('--dash', '1'): SingleConfiguration(True, DUMMY_PASSPHRASE, True),
161)     ('--symbol', '1'): SingleConfiguration(True, DUMMY_PASSPHRASE, True),
162)     ('--notes',): SingleConfiguration(True, None, False),
163)     ('--config', '-p'): SingleConfiguration(None, DUMMY_PASSPHRASE, False),
164)     ('--delete',): SingleConfiguration(True, None, False),
165)     ('--delete-globals',): SingleConfiguration(False, None, True),
166)     ('--clear',): SingleConfiguration(False, None, True),
167)     ('--export', '-'): SingleConfiguration(False, None, True),
168)     ('--import', '-'): SingleConfiguration(False, b'{"services": {}}', True),
169) }
170) INTERESTING_OPTION_COMBINATIONS: list[OptionCombination] = []
Marco Ricci Fix miscellaneous type chec...

Marco Ricci authored 2 months ago

171) config: IncompatibleConfiguration | SingleConfiguration
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

172) for opt, config in INCOMPATIBLE.items():
173)     for opt2 in config.other_options:
174)         INTERESTING_OPTION_COMBINATIONS.extend([
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

175)             OptionCombination(
176)                 options=list(opt + opt2),
177)                 incompatible=True,
178)                 needs_service=config.needs_service,
179)                 input=config.input,
180)                 check_success=False,
181)             ),
182)             OptionCombination(
183)                 options=list(opt2 + opt),
184)                 incompatible=True,
185)                 needs_service=config.needs_service,
186)                 input=config.input,
187)                 check_success=False,
188)             ),
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

189)         ])
190) for opt, config in SINGLES.items():
191)     INTERESTING_OPTION_COMBINATIONS.append(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

192)         OptionCombination(
193)             options=list(opt),
194)             incompatible=False,
195)             needs_service=config.needs_service,
196)             input=config.input,
197)             check_success=config.check_success,
198)         )
199)     )
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

200) 
201) 
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

202) class TestCLI:
Marco Ricci Isolate tests properly and...

Marco Ricci authored 1 month ago

203)     def test_200_help_output(self, monkeypatch: Any) -> None:
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

204)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Isolate tests properly and...

Marco Ricci authored 1 month ago

205)         with tests.isolated_config(
206)             monkeypatch=monkeypatch,
207)             runner=runner,
208)             config={'services': {}},
209)         ):
210)             result = runner.invoke(
211)                 cli.derivepassphrase, ['--help'], catch_exceptions=False
212)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

213)         assert result.exit_code == 0
214)         assert (
215)             'Password generation:\n' in result.output
216)         ), 'Option groups not respected in help text.'
217)         assert (
218)             'Use NUMBER=0, e.g. "--symbol 0"' in result.output
219)         ), 'Option group epilog not printed.'
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

220) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

221)     @pytest.mark.parametrize(
222)         'charset_name', ['lower', 'upper', 'number', 'space', 'dash', 'symbol']
223)     )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

224)     def test_201_disable_character_set(
225)         self, monkeypatch: Any, charset_name: str
226)     ) -> None:
227)         monkeypatch.setattr(cli, '_prompt_for_passphrase', tests.auto_prompt)
228)         option = f'--{charset_name}'
229)         charset = dpp.Vault._CHARSETS[charset_name].decode('ascii')
230)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Isolate tests properly and...

Marco Ricci authored 1 month ago

231)         with tests.isolated_config(
232)             monkeypatch=monkeypatch,
233)             runner=runner,
234)             config={'services': {}},
235)         ):
236)             result = runner.invoke(
237)                 cli.derivepassphrase,
238)                 [option, '0', '-p', DUMMY_SERVICE],
239)                 input=DUMMY_PASSPHRASE,
240)                 catch_exceptions=False,
241)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

242)         assert (
243)             result.exit_code == 0
244)         ), f'program died unexpectedly with exit code {result.exit_code}'
245)         assert (
246)             not result.stderr_bytes
247)         ), f'program barfed on stderr: {result.stderr_bytes!r}'
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

248)         for c in charset:
249)             assert c not in result.stdout, (
250)                 f'derived password contains forbidden character {c!r}: '
251)                 f'{result.stdout!r}'
252)             )
Marco Ricci Add prototype command-line...

Marco Ricci authored 2 months ago

253) 
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

254)     def test_202_disable_repetition(self, monkeypatch: Any) -> None:
255)         monkeypatch.setattr(cli, '_prompt_for_passphrase', tests.auto_prompt)
256)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Isolate tests properly and...

Marco Ricci authored 1 month ago

257)         with tests.isolated_config(
258)             monkeypatch=monkeypatch,
259)             runner=runner,
260)             config={'services': {}},
261)         ):
262)             result = runner.invoke(
263)                 cli.derivepassphrase,
264)                 ['--repeat', '0', '-p', DUMMY_SERVICE],
265)                 input=DUMMY_PASSPHRASE,
266)                 catch_exceptions=False,
267)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

268)         assert (
269)             result.exit_code == 0
270)         ), f'program died unexpectedly with exit code {result.exit_code}'
271)         assert (
272)             not result.stderr_bytes
273)         ), f'program barfed on stderr: {result.stderr_bytes!r}'
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

274)         passphrase = result.stdout.rstrip('\r\n')
275)         for i in range(len(passphrase) - 1):
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

276)             assert passphrase[i : i + 1] != passphrase[i + 1 : i + 2], (
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

277)                 f'derived password contains repeated character '
278)                 f'at position {i}: {result.stdout!r}'
279)             )
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

280) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

281)     @pytest.mark.parametrize(
282)         'config',
283)         [
284)             pytest.param(
285)                 {
286)                     'global': {'key': DUMMY_KEY1_B64},
287)                     'services': {DUMMY_SERVICE: DUMMY_CONFIG_SETTINGS},
288)                 },
289)                 id='global',
290)             ),
291)             pytest.param(
292)                 {
293)                     'global': {
294)                         'phrase': DUMMY_PASSPHRASE.rstrip(b'\n').decode(
295)                             'ASCII'
296)                         )
297)                     },
298)                     'services': {
299)                         DUMMY_SERVICE: {
300)                             'key': DUMMY_KEY1_B64,
301)                             **DUMMY_CONFIG_SETTINGS,
302)                         }
303)                     },
304)                 },
305)                 id='service',
306)             ),
307)         ],
308)     )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

309)     def test_204a_key_from_config(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

310)         self,
311)         monkeypatch: Any,
312)         config: dpp.types.VaultConfig,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

313)     ) -> None:
314)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

315)         with tests.isolated_config(
316)             monkeypatch=monkeypatch, runner=runner, config=config
317)         ):
318)             monkeypatch.setattr(
319)                 dpp.Vault, 'phrase_from_key', tests.phrase_from_key
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

320)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

321)             result = runner.invoke(
322)                 cli.derivepassphrase, [DUMMY_SERVICE], catch_exceptions=False
323)             )
324)             assert (result.exit_code, result.stderr_bytes) == (
325)                 0,
326)                 b'',
327)             ), 'program exited with failure'
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

328)             assert (
329)                 result.stdout_bytes.rstrip(b'\n') != DUMMY_RESULT_PASSPHRASE
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

330)             ), 'program generated unexpected result (phrase instead of key)'
331)             assert (
332)                 result.stdout_bytes.rstrip(b'\n') == DUMMY_RESULT_KEY1
333)             ), 'program generated unexpected result (wrong settings?)'
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

334) 
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

335)     def test_204b_key_from_command_line(self, monkeypatch: Any) -> None:
336)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

337)         with tests.isolated_config(
338)             monkeypatch=monkeypatch,
339)             runner=runner,
340)             config={'services': {DUMMY_SERVICE: DUMMY_CONFIG_SETTINGS}},
341)         ):
342)             monkeypatch.setattr(
343)                 cli, '_get_suitable_ssh_keys', tests.suitable_ssh_keys
344)             )
345)             monkeypatch.setattr(
346)                 dpp.Vault, 'phrase_from_key', tests.phrase_from_key
347)             )
348)             result = runner.invoke(
349)                 cli.derivepassphrase,
350)                 ['-k', DUMMY_SERVICE],
351)                 input=b'1\n',
352)                 catch_exceptions=False,
353)             )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

354)             assert result.exit_code == 0, 'program exited with failure'
355)             assert result.stdout_bytes, 'program output expected'
356)             last_line = result.stdout_bytes.splitlines(True)[-1]
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

357)             assert (
358)                 last_line.rstrip(b'\n') != DUMMY_RESULT_PASSPHRASE
359)             ), 'program generated unexpected result (phrase instead of key)'
360)             assert (
361)                 last_line.rstrip(b'\n') == DUMMY_RESULT_KEY1
362)             ), 'program generated unexpected result (wrong settings?)'
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

363) 
Marco Ricci Avoid crashing when overrid...

Marco Ricci authored 1 month ago

364)     @tests.skip_if_no_agent
365)     @pytest.mark.parametrize(
366)         'config',
367)         [
368)             pytest.param(
369)                 {
370)                     'global': {'key': DUMMY_KEY1_B64},
371)                     'services': {DUMMY_SERVICE: {}},
372)                 },
373)                 id='global_config',
374)             ),
375)             pytest.param(
376)                 {'services': {DUMMY_SERVICE: {'key': DUMMY_KEY2_B64}}},
377)                 id='service_config',
378)             ),
379)             pytest.param(
380)                 {
381)                     'global': {'key': DUMMY_KEY1_B64},
382)                     'services': {DUMMY_SERVICE: {'key': DUMMY_KEY2_B64}},
383)                 },
384)                 id='full_config',
385)             ),
386)         ],
387)     )
388)     @pytest.mark.parametrize('key_index', [1, 2, 3], ids=lambda i: f'index{i}')
389)     def test_204c_key_override_on_command_line(
390)         self,
391)         monkeypatch: Any,
392)         config: dict[str, Any],
393)         key_index: int,
394)     ) -> None:
395)         def sign(
396)             _, key: bytes | bytearray, message: bytes | bytearray
397)         ) -> bytes:
398)             del message  # Unused.
399)             for value in tests.SUPPORTED_KEYS.values():
400)                 if value['public_key_data'] == key:
401)                     assert value['expected_signature'] is not None
402)                     return value['expected_signature']
403)             raise AssertionError
404) 
405)         monkeypatch.setattr(
406)             ssh_agent_client.SSHAgentClient, 'list_keys', tests.list_keys
407)         )
408)         monkeypatch.setattr(ssh_agent_client.SSHAgentClient, 'sign', sign)
409)         runner = click.testing.CliRunner(mix_stderr=False)
410)         with tests.isolated_config(
411)             monkeypatch=monkeypatch, runner=runner, config=config
412)         ):
413)             result = runner.invoke(
414)                 cli.derivepassphrase,
415)                 ['-k', DUMMY_SERVICE],
416)                 input=f'{key_index}\n'.encode('ASCII'),
417)             )
418)             assert result.stderr_bytes is not None
419)             assert (
420)                 b'Error:' not in result.stderr_bytes
421)             ), 'program exited with failure'
422)             assert result.stdout_bytes, 'program output expected'
423)             assert result.exit_code == 0, 'program exited with failure'
424) 
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

425)     def test_205_service_phrase_if_key_in_global_config(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

426)         self,
427)         monkeypatch: Any,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

428)     ) -> None:
429)         runner = click.testing.CliRunner(mix_stderr=False)
430)         with tests.isolated_config(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

431)             monkeypatch=monkeypatch,
432)             runner=runner,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

433)             config={
434)                 'global': {'key': DUMMY_KEY1_B64},
435)                 'services': {
436)                     DUMMY_SERVICE: {
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

437)                         'phrase': DUMMY_PASSPHRASE.rstrip(b'\n').decode(
438)                             'ASCII'
439)                         ),
440)                         **DUMMY_CONFIG_SETTINGS,
441)                     }
442)                 },
443)             },
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

444)         ):
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

445)             result = runner.invoke(
446)                 cli.derivepassphrase, [DUMMY_SERVICE], catch_exceptions=False
447)             )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

448)             assert result.exit_code == 0, 'program exited with failure'
449)             assert result.stdout_bytes, 'program output expected'
450)             last_line = result.stdout_bytes.splitlines(True)[-1]
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

451)             assert (
452)                 last_line.rstrip(b'\n') != DUMMY_RESULT_KEY1
453)             ), 'program generated unexpected result (key instead of phrase)'
454)             assert (
455)                 last_line.rstrip(b'\n') == DUMMY_RESULT_PASSPHRASE
456)             ), 'program generated unexpected result (wrong settings?)'
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

457) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

458)     @pytest.mark.parametrize(
459)         'option',
460)         [
461)             '--lower',
462)             '--upper',
463)             '--number',
464)             '--space',
465)             '--dash',
466)             '--symbol',
467)             '--repeat',
468)             '--length',
469)         ],
470)     )
Marco Ricci Isolate tests properly and...

Marco Ricci authored 1 month ago

471)     def test_210_invalid_argument_range(
472)         self, monkeypatch: Any, option: str
473)     ) -> None:
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

474)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Isolate tests properly and...

Marco Ricci authored 1 month ago

475)         with tests.isolated_config(
476)             monkeypatch=monkeypatch,
477)             runner=runner,
478)             config={'services': {}},
479)         ):
480)             for value in '-42', 'invalid':
481)                 result = runner.invoke(
482)                     cli.derivepassphrase,
483)                     [option, value, '-p', DUMMY_SERVICE],
484)                     input=DUMMY_PASSPHRASE,
485)                     catch_exceptions=False,
486)                 )
487)                 assert result.exit_code > 0, 'program unexpectedly succeeded'
488)                 assert (
489)                     result.stderr_bytes
490)                 ), 'program did not print any error message'
491)                 assert (
492)                     b'Error: Invalid value' in result.stderr_bytes
493)                 ), 'program did not print the expected error message'
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

494) 
495)     @pytest.mark.parametrize(
496)         ['options', 'service', 'input', 'check_success'],
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

497)         [
498)             (o.options, o.needs_service, o.input, o.check_success)
499)             for o in INTERESTING_OPTION_COMBINATIONS
500)             if not o.incompatible
501)         ],
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

502)     )
503)     def test_211_service_needed(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

504)         self,
505)         monkeypatch: Any,
506)         options: list[str],
507)         service: bool | None,
508)         input: bytes | None,
509)         check_success: bool,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

510)     ) -> None:
511)         monkeypatch.setattr(cli, '_prompt_for_passphrase', tests.auto_prompt)
512)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

513)         with tests.isolated_config(
514)             monkeypatch=monkeypatch,
515)             runner=runner,
516)             config={'global': {'phrase': 'abc'}, 'services': {}},
517)         ):
518)             result = runner.invoke(
519)                 cli.derivepassphrase,
520)                 options if service else [*options, DUMMY_SERVICE],
521)                 input=input,
522)                 catch_exceptions=False,
523)             )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

524)             if service is not None:
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

525)                 assert result.exit_code > 0, 'program unexpectedly succeeded'
526)                 assert (
527)                     result.stderr_bytes
528)                 ), 'program did not print any error message'
529)                 err_msg = (
530)                     b' requires a SERVICE'
531)                     if service
532)                     else b' does not take a SERVICE argument'
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

533)                 )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

534)                 assert (
535)                     err_msg in result.stderr_bytes
536)                 ), 'program did not print the expected error message'
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

537)             else:
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

538)                 assert (result.exit_code, result.stderr_bytes) == (
539)                     0,
540)                     b'',
541)                 ), 'program unexpectedly failed'
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

542)         if check_success:
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

543)             with tests.isolated_config(
544)                 monkeypatch=monkeypatch,
545)                 runner=runner,
546)                 config={'global': {'phrase': 'abc'}, 'services': {}},
547)             ):
548)                 monkeypatch.setattr(
549)                     cli, '_prompt_for_passphrase', tests.auto_prompt
550)                 )
551)                 result = runner.invoke(
552)                     cli.derivepassphrase,
553)                     [*options, DUMMY_SERVICE] if service else options,
554)                     input=input,
555)                     catch_exceptions=False,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

556)                 )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

557)                 assert (result.exit_code, result.stderr_bytes) == (
558)                     0,
559)                     b'',
560)                 ), 'program unexpectedly failed'
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

561) 
562)     @pytest.mark.parametrize(
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

563)         ['options', 'service'],
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

564)         [
565)             (o.options, o.needs_service)
566)             for o in INTERESTING_OPTION_COMBINATIONS
567)             if o.incompatible
568)         ],
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

569)     )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

570)     def test_212_incompatible_options(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

571)         self,
Marco Ricci Isolate tests properly and...

Marco Ricci authored 1 month ago

572)         monkeypatch: Any,
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

573)         options: list[str],
574)         service: bool | None,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

575)     ) -> None:
576)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Isolate tests properly and...

Marco Ricci authored 1 month ago

577)         with tests.isolated_config(
578)             monkeypatch=monkeypatch,
579)             runner=runner,
580)             config={'services': {}},
581)         ):
582)             result = runner.invoke(
583)                 cli.derivepassphrase,
584)                 [*options, DUMMY_SERVICE] if service else options,
585)                 input=DUMMY_PASSPHRASE,
586)                 catch_exceptions=False,
587)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

588)         assert result.exit_code > 0, 'program unexpectedly succeeded'
589)         assert result.stderr_bytes, 'program did not print any error message'
590)         assert (
591)             b'mutually exclusive with ' in result.stderr_bytes
592)         ), 'program did not print the expected error message'
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

593) 
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

594)     def test_213_import_bad_config_not_vault_config(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

595)         self,
596)         monkeypatch: Any,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

597)     ) -> None:
598)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

599)         with tests.isolated_config(
600)             monkeypatch=monkeypatch, runner=runner, config={'services': {}}
601)         ):
602)             result = runner.invoke(
603)                 cli.derivepassphrase,
604)                 ['--import', '-'],
605)                 input=b'null',
606)                 catch_exceptions=False,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

607)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

608)             assert result.exit_code > 0, 'program unexpectedly succeeded'
609)             assert (
610)                 result.stderr_bytes
611)             ), 'program did not print any error message'
612)             assert (
613)                 b'not a valid config' in result.stderr_bytes
614)             ), 'program did not print the expected error message'
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

615) 
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

616)     def test_213a_import_bad_config_not_json_data(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

617)         self,
618)         monkeypatch: Any,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

619)     ) -> None:
620)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

621)         with tests.isolated_config(
622)             monkeypatch=monkeypatch, runner=runner, config={'services': {}}
623)         ):
624)             result = runner.invoke(
625)                 cli.derivepassphrase,
626)                 ['--import', '-'],
627)                 input=b'This string is not valid JSON.',
628)                 catch_exceptions=False,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

629)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

630)             assert result.exit_code > 0, 'program unexpectedly succeeded'
631)             assert (
632)                 result.stderr_bytes
633)             ), 'program did not print any error message'
634)             assert (
635)                 b'cannot decode JSON' in result.stderr_bytes
636)             ), 'program did not print the expected error message'
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

637) 
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

638)     def test_213b_import_bad_config_not_a_file(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

639)         self,
640)         monkeypatch: Any,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

641)     ) -> None:
642)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Fix miscellaneous type chec...

Marco Ricci authored 2 months ago

643)         # `isolated_config` validates the configuration.  So, to pass an
644)         # actual broken configuration, we must open the configuration file
645)         # ourselves afterwards, inside the context.
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

646)         with tests.isolated_config(
647)             monkeypatch=monkeypatch, runner=runner, config={'services': {}}
648)         ):
649)             with open(
650)                 cli._config_filename(), 'w', encoding='UTF-8'
651)             ) as outfile:
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

652)                 print('This string is not valid JSON.', file=outfile)
Marco Ricci Fix miscellaneous type chec...

Marco Ricci authored 2 months ago

653)             dname = os.path.dirname(cli._config_filename())
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

654)             result = runner.invoke(
655)                 cli.derivepassphrase,
Marco Ricci Fix miscellaneous type chec...

Marco Ricci authored 2 months ago

656)                 ['--import', os.fsdecode(dname)],
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

657)                 catch_exceptions=False,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

658)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

659)             assert result.exit_code > 0, 'program unexpectedly succeeded'
660)             assert (
661)                 result.stderr_bytes
662)             ), 'program did not print any error message'
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

663)             # Don't test the actual error message, because it is subject to
664)             # locale settings.  TODO: find a way anyway.
665) 
666)     def test_214_export_settings_no_stored_settings(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

667)         self,
668)         monkeypatch: Any,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

669)     ) -> None:
670)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

671)         with tests.isolated_config(
672)             monkeypatch=monkeypatch, runner=runner, config={'services': {}}
673)         ):
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

674)             with contextlib.suppress(FileNotFoundError):
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

675)                 os.remove(cli._config_filename())
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

676)             result = runner.invoke(
677)                 cli.derivepassphrase, ['--export', '-'], catch_exceptions=False
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

678)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

679)             assert (result.exit_code, result.stderr_bytes) == (
680)                 0,
681)                 b'',
682)             ), 'program exited with failure'
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

683) 
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

684)     def test_214a_export_settings_bad_stored_config(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

685)         self,
686)         monkeypatch: Any,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

687)     ) -> None:
688)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

689)         with tests.isolated_config(
690)             monkeypatch=monkeypatch, runner=runner, config={}
691)         ):
692)             result = runner.invoke(
693)                 cli.derivepassphrase,
694)                 ['--export', '-'],
695)                 input=b'null',
696)                 catch_exceptions=False,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

697)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

698)             assert result.exit_code > 0, 'program unexpectedly succeeded'
699)             assert (
700)                 result.stderr_bytes
701)             ), 'program did not print any error message'
702)             assert (
703)                 b'cannot load config' in result.stderr_bytes
704)             ), 'program did not print the expected error message'
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

705) 
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

706)     def test_214b_export_settings_not_a_file(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

707)         self,
708)         monkeypatch: Any,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

709)     ) -> None:
710)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

711)         with tests.isolated_config(
712)             monkeypatch=monkeypatch, runner=runner, config={'services': {}}
713)         ):
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

714)             with contextlib.suppress(FileNotFoundError):
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

715)                 os.remove(cli._config_filename())
716)             os.makedirs(cli._config_filename())
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

717)             result = runner.invoke(
718)                 cli.derivepassphrase,
719)                 ['--export', '-'],
720)                 input=b'null',
721)                 catch_exceptions=False,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

722)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

723)             assert result.exit_code > 0, 'program unexpectedly succeeded'
724)             assert (
725)                 result.stderr_bytes
726)             ), 'program did not print any error message'
727)             assert (
728)                 b'cannot load config' in result.stderr_bytes
729)             ), 'program did not print the expected error message'
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

730) 
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

731)     def test_214c_export_settings_target_not_a_file(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

732)         self,
733)         monkeypatch: Any,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

734)     ) -> None:
735)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

736)         with tests.isolated_config(
737)             monkeypatch=monkeypatch, runner=runner, config={'services': {}}
738)         ):
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

739)             dname = os.path.dirname(cli._config_filename())
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

740)             result = runner.invoke(
741)                 cli.derivepassphrase,
742)                 ['--export', os.fsdecode(dname)],
743)                 input=b'null',
744)                 catch_exceptions=False,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

745)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

746)             assert result.exit_code > 0, 'program unexpectedly succeeded'
747)             assert (
748)                 result.stderr_bytes
749)             ), 'program did not print any error message'
750)             assert (
751)                 b'cannot write config' in result.stderr_bytes
752)             ), 'program did not print the expected error message'
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

753) 
Marco Ricci Create the configuration di...

Marco Ricci authored 1 month ago

754)     def test_214d_export_settings_settings_directory_not_a_directory(
755)         self,
756)         monkeypatch: Any,
757)     ) -> None:
758)         runner = click.testing.CliRunner(mix_stderr=False)
759)         with tests.isolated_config(
760)             monkeypatch=monkeypatch, runner=runner, config={'services': {}}
761)         ):
762)             with contextlib.suppress(FileNotFoundError):
763)                 shutil.rmtree('.derivepassphrase')
764)             with open('.derivepassphrase', 'w', encoding='UTF-8') as outfile:
765)                 print('Obstruction!!', file=outfile)
766)             result = runner.invoke(
767)                 cli.derivepassphrase,
768)                 ['--export', '-'],
769)                 input=b'null',
770)                 catch_exceptions=False,
771)             )
772)             assert result.exit_code > 0, 'program unexpectedly succeeded'
773)             assert (
774)                 result.stderr_bytes
775)             ), 'program did not print any error message'
776)             assert (
777)                 b'cannot load config' in result.stderr_bytes
778)             ), 'program did not print the expected error message'
779) 
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

780)     def test_220_edit_notes_successfully(self, monkeypatch: Any) -> None:
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

781)         edit_result = """
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

782) 
783) # - - - - - >8 - - - - - >8 - - - - - >8 - - - - - >8 - - - - -
784) contents go here
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

785) """
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

786)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

787)         with tests.isolated_config(
788)             monkeypatch=monkeypatch,
789)             runner=runner,
790)             config={'global': {'phrase': 'abc'}, 'services': {}},
791)         ):
792)             monkeypatch.setattr(click, 'edit', lambda *a, **kw: edit_result)  # noqa: ARG005
793)             result = runner.invoke(
794)                 cli.derivepassphrase, ['--notes', 'sv'], catch_exceptions=False
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

795)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

796)             assert (result.exit_code, result.stderr_bytes) == (
797)                 0,
798)                 b'',
799)             ), 'program exited with failure'
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

800)             with open(cli._config_filename(), encoding='UTF-8') as infile:
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

801)                 config = json.load(infile)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

802)             assert config == {
803)                 'global': {'phrase': 'abc'},
804)                 'services': {'sv': {'notes': 'contents go here'}},
805)             }
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

806) 
807)     def test_221_edit_notes_noop(self, monkeypatch: Any) -> None:
808)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

809)         with tests.isolated_config(
810)             monkeypatch=monkeypatch,
811)             runner=runner,
812)             config={'global': {'phrase': 'abc'}, 'services': {}},
813)         ):
814)             monkeypatch.setattr(click, 'edit', lambda *a, **kw: None)  # noqa: ARG005
815)             result = runner.invoke(
816)                 cli.derivepassphrase, ['--notes', 'sv'], catch_exceptions=False
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

817)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

818)             assert (result.exit_code, result.stderr_bytes) == (
819)                 0,
820)                 b'',
821)             ), 'program exited with failure'
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

822)             with open(cli._config_filename(), encoding='UTF-8') as infile:
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

823)                 config = json.load(infile)
824)             assert config == {'global': {'phrase': 'abc'}, 'services': {}}
825) 
826)     def test_222_edit_notes_marker_removed(self, monkeypatch: Any) -> None:
827)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

828)         with tests.isolated_config(
829)             monkeypatch=monkeypatch,
830)             runner=runner,
831)             config={'global': {'phrase': 'abc'}, 'services': {}},
832)         ):
833)             monkeypatch.setattr(click, 'edit', lambda *a, **kw: 'long\ntext')  # noqa: ARG005
834)             result = runner.invoke(
835)                 cli.derivepassphrase, ['--notes', 'sv'], catch_exceptions=False
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

836)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

837)             assert (result.exit_code, result.stderr_bytes) == (
838)                 0,
839)                 b'',
840)             ), 'program exited with failure'
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

841)             with open(cli._config_filename(), encoding='UTF-8') as infile:
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

842)                 config = json.load(infile)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

843)             assert config == {
844)                 'global': {'phrase': 'abc'},
845)                 'services': {'sv': {'notes': 'long\ntext'}},
846)             }
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

847) 
848)     def test_223_edit_notes_abort(self, monkeypatch: Any) -> None:
849)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

850)         with tests.isolated_config(
851)             monkeypatch=monkeypatch,
852)             runner=runner,
853)             config={'global': {'phrase': 'abc'}, 'services': {}},
854)         ):
855)             monkeypatch.setattr(click, 'edit', lambda *a, **kw: '\n\n')  # noqa: ARG005
856)             result = runner.invoke(
857)                 cli.derivepassphrase, ['--notes', 'sv'], catch_exceptions=False
858)             )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

859)             assert result.exit_code != 0, 'program unexpectedly succeeded'
Marco Ricci Fix miscellaneous type chec...

Marco Ricci authored 2 months ago

860)             assert result.stderr_bytes is not None
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

861)             assert (
862)                 b'user aborted request' in result.stderr_bytes
863)             ), 'expected error message missing'
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

864)             with open(cli._config_filename(), encoding='UTF-8') as infile:
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

865)                 config = json.load(infile)
866)             assert config == {'global': {'phrase': 'abc'}, 'services': {}}
867) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

868)     @pytest.mark.parametrize(
869)         ['command_line', 'input', 'result_config'],
870)         [
871)             (
872)                 ['--phrase'],
873)                 b'my passphrase\n',
874)                 {'global': {'phrase': 'my passphrase'}, 'services': {}},
875)             ),
876)             (
877)                 ['--key'],
878)                 b'1\n',
879)                 {'global': {'key': DUMMY_KEY1_B64}, 'services': {}},
880)             ),
881)             (
882)                 ['--phrase', 'sv'],
883)                 b'my passphrase\n',
884)                 {
885)                     'global': {'phrase': 'abc'},
886)                     'services': {'sv': {'phrase': 'my passphrase'}},
887)                 },
888)             ),
889)             (
890)                 ['--key', 'sv'],
891)                 b'1\n',
892)                 {
893)                     'global': {'phrase': 'abc'},
894)                     'services': {'sv': {'key': DUMMY_KEY1_B64}},
895)                 },
896)             ),
897)             (
898)                 ['--key', '--length', '15', 'sv'],
899)                 b'1\n',
900)                 {
901)                     'global': {'phrase': 'abc'},
902)                     'services': {'sv': {'key': DUMMY_KEY1_B64, 'length': 15}},
903)                 },
904)             ),
905)         ],
906)     )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

907)     def test_224_store_config_good(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

908)         self,
909)         monkeypatch: Any,
910)         command_line: list[str],
911)         input: bytes,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

912)         result_config: Any,
913)     ) -> None:
914)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

915)         with tests.isolated_config(
916)             monkeypatch=monkeypatch,
917)             runner=runner,
918)             config={'global': {'phrase': 'abc'}, 'services': {}},
919)         ):
920)             monkeypatch.setattr(
921)                 cli, '_get_suitable_ssh_keys', tests.suitable_ssh_keys
922)             )
923)             result = runner.invoke(
924)                 cli.derivepassphrase,
925)                 ['--config', *command_line],
926)                 catch_exceptions=False,
927)                 input=input,
928)             )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

929)             assert result.exit_code == 0, 'program exited with failure'
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

930)             with open(cli._config_filename(), encoding='UTF-8') as infile:
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

931)                 config = json.load(infile)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

932)             assert (
933)                 config == result_config
934)             ), 'stored config does not match expectation'
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

935) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

936)     @pytest.mark.parametrize(
937)         ['command_line', 'input', 'err_text'],
938)         [
939)             (
940)                 [],
941)                 b'',
942)                 b'cannot update global settings without actual settings',
943)             ),
944)             (
945)                 ['sv'],
946)                 b'',
947)                 b'cannot update service settings without actual settings',
948)             ),
949)             (['--phrase', 'sv'], b'', b'no passphrase given'),
950)             (['--key'], b'', b'no valid SSH key selected'),
951)         ],
952)     )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

953)     def test_225_store_config_fail(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

954)         self,
955)         monkeypatch: Any,
956)         command_line: list[str],
957)         input: bytes,
958)         err_text: bytes,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

959)     ) -> None:
960)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

961)         with tests.isolated_config(
962)             monkeypatch=monkeypatch,
963)             runner=runner,
964)             config={'global': {'phrase': 'abc'}, 'services': {}},
965)         ):
966)             monkeypatch.setattr(
967)                 cli, '_get_suitable_ssh_keys', tests.suitable_ssh_keys
968)             )
969)             result = runner.invoke(
970)                 cli.derivepassphrase,
971)                 ['--config', *command_line],
972)                 catch_exceptions=False,
973)                 input=input,
974)             )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

975)             assert result.exit_code != 0, 'program unexpectedly succeeded?!'
Marco Ricci Fix miscellaneous type chec...

Marco Ricci authored 2 months ago

976)             assert result.stderr_bytes is not None
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

977)             assert (
978)                 err_text in result.stderr_bytes
979)             ), 'expected error message missing'
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

980) 
981)     def test_225a_store_config_fail_manual_no_ssh_key_selection(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

982)         self,
983)         monkeypatch: Any,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

984)     ) -> None:
985)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

986)         with tests.isolated_config(
987)             monkeypatch=monkeypatch,
988)             runner=runner,
989)             config={'global': {'phrase': 'abc'}, 'services': {}},
990)         ):
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

991)             custom_error = 'custom error message'
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

992) 
Marco Ricci Fix typing issues in mypy s...

Marco Ricci authored 1 month ago

993)             def raiser() -> None:
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

994)                 raise RuntimeError(custom_error)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

995) 
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

996)             monkeypatch.setattr(cli, '_select_ssh_key', raiser)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

997)             result = runner.invoke(
998)                 cli.derivepassphrase,
999)                 ['--key', '--config'],
1000)                 catch_exceptions=False,
1001)             )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1002)             assert result.exit_code != 0, 'program unexpectedly succeeded'
Marco Ricci Fix miscellaneous type chec...

Marco Ricci authored 2 months ago

1003)             assert result.stderr_bytes is not None
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1004)             assert (
1005)                 custom_error.encode() in result.stderr_bytes
1006)             ), 'expected error message missing'
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1007) 
Marco Ricci Isolate tests properly and...

Marco Ricci authored 1 month ago

1008)     def test_226_no_arguments(self, monkeypatch: Any) -> None:
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1009)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Isolate tests properly and...

Marco Ricci authored 1 month ago

1010)         with tests.isolated_config(
1011)             monkeypatch=monkeypatch,
1012)             runner=runner,
1013)             config={'services': {}},
1014)         ):
1015)             result = runner.invoke(
1016)                 cli.derivepassphrase, [], catch_exceptions=False
1017)             )
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

1018)         assert result.exit_code != 0, 'program unexpectedly succeeded'
Marco Ricci Fix miscellaneous type chec...

Marco Ricci authored 2 months ago

1019)         assert result.stderr_bytes is not None
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1020)         assert (
1021)             b'SERVICE is required' in result.stderr_bytes
1022)         ), 'expected error message missing'
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

1023) 
Marco Ricci Isolate tests properly and...

Marco Ricci authored 1 month ago

1024)     def test_226a_no_passphrase_or_key(self, monkeypatch: Any) -> None:
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1025)         runner = click.testing.CliRunner(mix_stderr=False)
Marco Ricci Isolate tests properly and...

Marco Ricci authored 1 month ago

1026)         with tests.isolated_config(
1027)             monkeypatch=monkeypatch,
1028)             runner=runner,
1029)             config={'services': {}},
1030)         ):
1031)             result = runner.invoke(
1032)                 cli.derivepassphrase, [DUMMY_SERVICE], catch_exceptions=False
1033)             )
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

1034)         assert result.exit_code != 0, 'program unexpectedly succeeded'
Marco Ricci Fix miscellaneous type chec...

Marco Ricci authored 2 months ago

1035)         assert result.stderr_bytes is not None
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1036)         assert (
1037)             b'no passphrase or key given' in result.stderr_bytes
1038)         ), 'expected error message missing'
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

1039) 
Marco Ricci Create the configuration di...

Marco Ricci authored 1 month ago

1040)     def test_230_config_directory_nonexistant(self, monkeypatch: Any) -> None:
1041)         """the-13th-letter/derivepassphrase#6"""
1042)         runner = click.testing.CliRunner(mix_stderr=False)
1043)         with tests.isolated_config(
1044)             monkeypatch=monkeypatch,
1045)             runner=runner,
1046)             config={'services': {}},
1047)         ):
1048)             os.remove('.derivepassphrase/settings.json')
1049)             os.rmdir('.derivepassphrase')
1050)             os_makedirs_called = False
1051)             real_os_makedirs = os.makedirs
1052) 
1053)             def makedirs(*args: Any, **kwargs: Any) -> Any:
1054)                 nonlocal os_makedirs_called
1055)                 os_makedirs_called = True
1056)                 return real_os_makedirs(*args, **kwargs)
1057) 
1058)             monkeypatch.setattr(os, 'makedirs', makedirs)
1059)             result = runner.invoke(
1060)                 cli.derivepassphrase,
1061)                 ['--config', '-p'],
1062)                 catch_exceptions=False,
1063)                 input='abc\n',
1064)             )
1065)             assert (
1066)                 result.stderr_bytes == b'Passphrase:'
1067)             ), 'program unexpectedly failed?!'
1068)             assert result.exit_code == 0, 'program unexpectedly failed?!'
1069)             assert os_makedirs_called, 'os.makedirs has not been called?!'
1070)             with open(cli._config_filename(), encoding='UTF-8') as infile:
1071)                 config_readback = json.load(infile)
1072)             assert config_readback == {
1073)                 'global': {'phrase': 'abc'},
1074)                 'services': {},
1075)             }, 'config mismatch'
1076) 
1077)     def test_230a_config_directory_not_a_file(self, monkeypatch: Any) -> None:
1078)         """the-13th-letter/derivepassphrase#6"""
1079)         runner = click.testing.CliRunner(mix_stderr=False)
1080)         with tests.isolated_config(
1081)             monkeypatch=monkeypatch,
1082)             runner=runner,
1083)             config={'services': {}},
1084)         ):
1085)             _save_config = cli._save_config
1086) 
1087)             def obstruct_config_saving(*args: Any, **kwargs: Any) -> Any:
1088)                 with contextlib.suppress(FileNotFoundError):
1089)                     shutil.rmtree('.derivepassphrase')
1090)                 with open(
1091)                     '.derivepassphrase', 'w', encoding='UTF-8'
1092)                 ) as outfile:
1093)                     print('Obstruction!!', file=outfile)
1094)                 monkeypatch.setattr(cli, '_save_config', _save_config)
1095)                 return _save_config(*args, **kwargs)
1096) 
1097)             monkeypatch.setattr(cli, '_save_config', obstruct_config_saving)
1098)             with pytest.raises(FileExistsError):
1099)                 runner.invoke(
1100)                     cli.derivepassphrase,
1101)                     ['--config', '-p'],
1102)                     catch_exceptions=False,
1103)                     input='abc\n',
1104)                 )
1105) 
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

1106) 
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1107) class TestCLIUtils:
1108)     def test_100_save_bad_config(self, monkeypatch: Any) -> None:
1109)         runner = click.testing.CliRunner()
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

1110)         with (
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1111)             tests.isolated_config(
1112)                 monkeypatch=monkeypatch, runner=runner, config={}
1113)             ),
1114)             pytest.raises(ValueError, match='Invalid vault config'),
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

1115)         ):
1116)             cli._save_config(None)  # type: ignore
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1117) 
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

1118)     def test_101_prompt_for_selection_multiple(self) -> None:
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1119)         @click.command()
1120)         @click.option('--heading', default='Our menu:')
1121)         @click.argument('items', nargs=-1)
Marco Ricci Fix typing issues in mypy s...

Marco Ricci authored 1 month ago

1122)         def driver(heading: str, items: list[str]) -> None:
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1123)             # from https://montypython.fandom.com/wiki/Spam#The_menu
1124)             items = items or [
1125)                 'Egg and bacon',
1126)                 'Egg, sausage and bacon',
1127)                 'Egg and spam',
1128)                 'Egg, bacon and spam',
1129)                 'Egg, bacon, sausage and spam',
1130)                 'Spam, bacon, sausage and spam',
1131)                 'Spam, egg, spam, spam, bacon and spam',
1132)                 'Spam, spam, spam, egg and spam',
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1133)                 (
1134)                     'Spam, spam, spam, spam, spam, spam, baked beans, '
1135)                     'spam, spam, spam and spam'
1136)                 ),
1137)                 (
1138)                     'Lobster thermidor aux crevettes with a mornay sauce '
1139)                     'garnished with truffle paté, brandy '
1140)                     'and a fried egg on top and spam'
1141)                 ),
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1142)             ]
1143)             index = cli._prompt_for_selection(items, heading=heading)
1144)             click.echo('A fine choice: ', nl=False)
1145)             click.echo(items[index])
1146)             click.echo('(Note: Vikings strictly optional.)')
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1147) 
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1148)         runner = click.testing.CliRunner(mix_stderr=True)
1149)         result = runner.invoke(driver, [], input='9')
1150)         assert result.exit_code == 0, 'driver program failed'
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1151)         assert (
1152)             result.stdout
1153)             == """\
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1154) Our menu:
1155) [1] Egg and bacon
1156) [2] Egg, sausage and bacon
1157) [3] Egg and spam
1158) [4] Egg, bacon and spam
1159) [5] Egg, bacon, sausage and spam
1160) [6] Spam, bacon, sausage and spam
1161) [7] Spam, egg, spam, spam, bacon and spam
1162) [8] Spam, spam, spam, egg and spam
1163) [9] Spam, spam, spam, spam, spam, spam, baked beans, spam, spam, spam and spam
1164) [10] Lobster thermidor aux crevettes with a mornay sauce garnished with truffle paté, brandy and a fried egg on top and spam
1165) Your selection? (1-10, leave empty to abort): 9
1166) A fine choice: Spam, spam, spam, spam, spam, spam, baked beans, spam, spam, spam and spam
1167) (Note: Vikings strictly optional.)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1168) """  # noqa: E501
1169)         ), 'driver program produced unexpected output'
1170)         result = runner.invoke(
1171)             driver, ['--heading='], input='', catch_exceptions=True
1172)         )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1173)         assert result.exit_code > 0, 'driver program succeeded?!'
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1174)         assert (
1175)             result.stdout
1176)             == """\
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1177) [1] Egg and bacon
1178) [2] Egg, sausage and bacon
1179) [3] Egg and spam
1180) [4] Egg, bacon and spam
1181) [5] Egg, bacon, sausage and spam
1182) [6] Spam, bacon, sausage and spam
1183) [7] Spam, egg, spam, spam, bacon and spam
1184) [8] Spam, spam, spam, egg and spam
1185) [9] Spam, spam, spam, spam, spam, spam, baked beans, spam, spam, spam and spam
1186) [10] Lobster thermidor aux crevettes with a mornay sauce garnished with truffle paté, brandy and a fried egg on top and spam
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1187) Your selection? (1-10, leave empty to abort):\x20
1188) """  # noqa: E501
1189)         ), 'driver program produced unexpected output'
1190)         assert isinstance(
1191)             result.exception, IndexError
1192)         ), 'driver program did not raise IndexError?!'
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1193) 
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

1194)     def test_102_prompt_for_selection_single(self) -> None:
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1195)         @click.command()
1196)         @click.option('--item', default='baked beans')
1197)         @click.argument('prompt')
Marco Ricci Fix typing issues in mypy s...

Marco Ricci authored 1 month ago

1198)         def driver(item: str, prompt: str) -> None:
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1199)             try:
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1200)                 cli._prompt_for_selection(
1201)                     [item], heading='', single_choice_prompt=prompt
1202)                 )
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

1203)             except IndexError:
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1204)                 click.echo('Boo.')
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

1205)                 raise
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1206)             else:
1207)                 click.echo('Great!')
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1208) 
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1209)         runner = click.testing.CliRunner(mix_stderr=True)
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1210)         result = runner.invoke(
1211)             driver, ['Will replace with spam. Confirm, y/n?'], input='y'
1212)         )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1213)         assert result.exit_code == 0, 'driver program failed'
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1214)         assert (
1215)             result.stdout
1216)             == """\
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1217) [1] baked beans
1218) Will replace with spam. Confirm, y/n? y
1219) Great!
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1220) """
1221)         ), 'driver program produced unexpected output'
1222)         result = runner.invoke(
1223)             driver,
1224)             ['Will replace with spam, okay? ' '(Please say "y" or "n".)'],
1225)             input='',
1226)         )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1227)         assert result.exit_code > 0, 'driver program succeeded?!'
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1228)         assert (
1229)             result.stdout
1230)             == """\
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1231) [1] baked beans
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

1232) Will replace with spam, okay? (Please say "y" or "n".):\x20
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1233) Boo.
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1234) """
1235)         ), 'driver program produced unexpected output'
1236)         assert isinstance(
1237)             result.exception, IndexError
1238)         ), 'driver program did not raise IndexError?!'
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1239) 
1240)     def test_103_prompt_for_passphrase(self, monkeypatch: Any) -> None:
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1241)         monkeypatch.setattr(
1242)             click,
1243)             'prompt',
1244)             lambda *a, **kw: json.dumps({'args': a, 'kwargs': kw}),
1245)         )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1246)         res = json.loads(cli._prompt_for_passphrase())
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

1247)         err_msg = 'missing arguments to passphrase prompt'
1248)         assert 'args' in res, err_msg
1249)         assert 'kwargs' in res, err_msg
1250)         assert res['args'][:1] == ['Passphrase'], err_msg
1251)         assert res['kwargs'].get('default') == '', err_msg
1252)         assert not res['kwargs'].get('show_default', True), err_msg
1253)         assert res['kwargs'].get('err'), err_msg
1254)         assert res['kwargs'].get('hide_input'), err_msg
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1255) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1256)     @pytest.mark.parametrize(
1257)         ['command_line', 'config', 'result_config'],
1258)         [
1259)             (
1260)                 ['--delete-globals'],
1261)                 {'global': {'phrase': 'abc'}, 'services': {}},
1262)                 {'services': {}},
1263)             ),
1264)             (
1265)                 ['--delete', DUMMY_SERVICE],
1266)                 {
1267)                     'global': {'phrase': 'abc'},
1268)                     'services': {DUMMY_SERVICE: {'notes': '...'}},
1269)                 },
1270)                 {'global': {'phrase': 'abc'}, 'services': {}},
1271)             ),
1272)             (
1273)                 ['--clear'],
1274)                 {
1275)                     'global': {'phrase': 'abc'},
1276)                     'services': {DUMMY_SERVICE: {'notes': '...'}},
1277)                 },
1278)                 {'services': {}},
1279)             ),
1280)         ],
1281)     )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1282)     def test_203_repeated_config_deletion(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1283)         self,
1284)         monkeypatch: Any,
1285)         command_line: list[str],
1286)         config: dpp.types.VaultConfig,
1287)         result_config: dpp.types.VaultConfig,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1288)     ) -> None:
1289)         runner = click.testing.CliRunner(mix_stderr=False)
1290)         for start_config in [config, result_config]:
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1291)             with tests.isolated_config(
1292)                 monkeypatch=monkeypatch, runner=runner, config=start_config
1293)             ):
1294)                 result = runner.invoke(
1295)                     cli.derivepassphrase, command_line, catch_exceptions=False
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1296)                 )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1297)                 assert (result.exit_code, result.stderr_bytes) == (
1298)                     0,
1299)                     b'',
1300)                 ), 'program exited with failure'
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

1301)                 with open(cli._config_filename(), encoding='UTF-8') as infile:
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1302)                     config_readback = json.load(infile)
1303)                 assert config_readback == result_config
1304) 
1305)     def test_204_phrase_from_key_manually(self) -> None:
1306)         assert (
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1307)             dpp.Vault(
1308)                 phrase=DUMMY_PHRASE_FROM_KEY1, **DUMMY_CONFIG_SETTINGS
1309)             ).generate(DUMMY_SERVICE)
1310)             == DUMMY_RESULT_KEY1
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1311)         )
1312) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1313)     @pytest.mark.parametrize(
1314)         ['vfunc', 'input'],
1315)         [
1316)             (cli._validate_occurrence_constraint, 20),
1317)             (cli._validate_length, 20),
1318)         ],
1319)     )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1320)     def test_210a_validate_constraints_manually(
1321)         self,
1322)         vfunc: Callable[[click.Context, click.Parameter, Any], int | None],
1323)         input: int,
1324)     ) -> None:
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

1325)         ctx = cli.derivepassphrase.make_context(cli.PROG_NAME, [])
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1326)         param = cli.derivepassphrase.params[0]
1327)         assert vfunc(ctx, param, input) == input
1328) 
1329)     @tests.skip_if_no_agent
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

1330)     @pytest.mark.parametrize('conn_hint', ['none', 'socket', 'client'])
Marco Ricci Fix miscellaneous type chec...

Marco Ricci authored 2 months ago

1331)     def test_227_get_suitable_ssh_keys(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1332)         self,
1333)         monkeypatch: Any,
1334)         conn_hint: str,
Marco Ricci Fix miscellaneous type chec...

Marco Ricci authored 2 months ago

1335)     ) -> None:
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1336)         monkeypatch.setattr(
1337)             ssh_agent_client.SSHAgentClient, 'list_keys', tests.list_keys
1338)         )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1339)         hint: ssh_agent_client.SSHAgentClient | socket.socket | None
1340)         match conn_hint:
1341)             case 'client':
1342)                 hint = ssh_agent_client.SSHAgentClient()
1343)             case 'socket':
1344)                 hint = socket.socket(family=socket.AF_UNIX)
1345)                 hint.connect(os.environ['SSH_AUTH_SOCK'])
1346)             case _:
1347)                 assert conn_hint == 'none'
1348)                 hint = None
1349)         exception: Exception | None = None
1350)         try:
1351)             list(cli._get_suitable_ssh_keys(hint))
1352)         except RuntimeError:  # pragma: no cover
1353)             pass
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

1354)         except Exception as e:  # noqa: BLE001 # pragma: no cover
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1355)             exception = e
1356)         finally: