c9e62dd6c58a3b4c627dd5d6dda0b4c4d4ec1330
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
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

19) import tests
Marco Ricci Consolidate `types` submodu...

Marco Ricci authored 1 month ago

20) from derivepassphrase import _types, cli, ssh_agent
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

87) ]
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

219) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

223)     def test_201_disable_character_set(
224)         self, monkeypatch: Any, charset_name: str
225)     ) -> None:
226)         monkeypatch.setattr(cli, '_prompt_for_passphrase', tests.auto_prompt)
227)         option = f'--{charset_name}'
Marco Ricci Move `sequin` and `ssh_agen...

Marco Ricci authored 1 month ago

228)         charset = dpp.vault.Vault._CHARSETS[charset_name].decode('ascii')
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

279) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

308)     def test_204a_key_from_config(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

309)         self,
310)         monkeypatch: Any,
Marco Ricci Consolidate `types` submodu...

Marco Ricci authored 1 month ago

311)         config: _types.VaultConfig,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

314)         with tests.isolated_config(
315)             monkeypatch=monkeypatch, runner=runner, config=config
316)         ):
317)             monkeypatch.setattr(
Marco Ricci Move `sequin` and `ssh_agen...

Marco Ricci authored 1 month ago

318)                 dpp.vault.Vault, 'phrase_from_key', tests.phrase_from_key
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

319)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

336)         with tests.isolated_config(
337)             monkeypatch=monkeypatch,
338)             runner=runner,
339)             config={'services': {DUMMY_SERVICE: DUMMY_CONFIG_SETTINGS}},
340)         ):
341)             monkeypatch.setattr(
342)                 cli, '_get_suitable_ssh_keys', tests.suitable_ssh_keys
343)             )
344)             monkeypatch.setattr(
Marco Ricci Move `sequin` and `ssh_agen...

Marco Ricci authored 1 month ago

345)                 dpp.vault.Vault, 'phrase_from_key', tests.phrase_from_key
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

346)             )
347)             result = runner.invoke(
348)                 cli.derivepassphrase,
349)                 ['-k', DUMMY_SERVICE],
350)                 input=b'1\n',
351)                 catch_exceptions=False,
352)             )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

362) 
Marco Ricci Avoid crashing when overrid...

Marco Ricci authored 1 month ago

363)     @tests.skip_if_no_agent
364)     @pytest.mark.parametrize(
365)         'config',
366)         [
367)             pytest.param(
368)                 {
369)                     'global': {'key': DUMMY_KEY1_B64},
370)                     'services': {DUMMY_SERVICE: {}},
371)                 },
372)                 id='global_config',
373)             ),
374)             pytest.param(
375)                 {'services': {DUMMY_SERVICE: {'key': DUMMY_KEY2_B64}}},
376)                 id='service_config',
377)             ),
378)             pytest.param(
379)                 {
380)                     'global': {'key': DUMMY_KEY1_B64},
381)                     'services': {DUMMY_SERVICE: {'key': DUMMY_KEY2_B64}},
382)                 },
383)                 id='full_config',
384)             ),
385)         ],
386)     )
387)     @pytest.mark.parametrize('key_index', [1, 2, 3], ids=lambda i: f'index{i}')
388)     def test_204c_key_override_on_command_line(
389)         self,
390)         monkeypatch: Any,
391)         config: dict[str, Any],
392)         key_index: int,
393)     ) -> None:
394)         def sign(
395)             _, key: bytes | bytearray, message: bytes | bytearray
396)         ) -> bytes:
397)             del message  # Unused.
398)             for value in tests.SUPPORTED_KEYS.values():
399)                 if value['public_key_data'] == key:
400)                     assert value['expected_signature'] is not None
401)                     return value['expected_signature']
402)             raise AssertionError
403) 
404)         monkeypatch.setattr(
Marco Ricci Move `sequin` and `ssh_agen...

Marco Ricci authored 1 month ago

405)             ssh_agent.SSHAgentClient, 'list_keys', tests.list_keys
Marco Ricci Avoid crashing when overrid...

Marco Ricci authored 1 month ago

406)         )
Marco Ricci Move `sequin` and `ssh_agen...

Marco Ricci authored 1 month ago

407)         monkeypatch.setattr(ssh_agent.SSHAgentClient, 'sign', sign)
Marco Ricci Avoid crashing when overrid...

Marco Ricci authored 1 month ago

408)         runner = click.testing.CliRunner(mix_stderr=False)
409)         with tests.isolated_config(
410)             monkeypatch=monkeypatch, runner=runner, config=config
411)         ):
412)             result = runner.invoke(
413)                 cli.derivepassphrase,
414)                 ['-k', DUMMY_SERVICE],
415)                 input=f'{key_index}\n'.encode('ASCII'),
416)             )
417)             assert result.stderr_bytes is not None
418)             assert (
419)                 b'Error:' not in result.stderr_bytes
420)             ), 'program exited with failure'
421)             assert result.stdout_bytes, 'program output expected'
422)             assert result.exit_code == 0, 'program exited with failure'
423) 
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

424)     def test_205_service_phrase_if_key_in_global_config(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

443)         ):
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

456) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

532)                 )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

536)             else:
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

541)         if check_success:
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

555)                 )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

569)     def test_212_incompatible_options(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

593)     def test_213_import_bad_config_not_vault_config(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

606)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

607)             assert result.exit_code > 0, 'program unexpectedly succeeded'
608)             assert (
609)                 result.stderr_bytes
610)             ), 'program did not print any error message'
611)             assert (
Marco Ricci Use better error message ha...

Marco Ricci authored 1 month ago

612)                 b'Invalid vault config' in result.stderr_bytes
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

613)             ), 'program did not print the expected error message'
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

615)     def test_213a_import_bad_config_not_json_data(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

628)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

637)     def test_213b_import_bad_config_not_a_file(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

657)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

677)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

683)     def test_214a_export_settings_bad_stored_config(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

696)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

697)             assert result.exit_code > 0, 'program unexpectedly succeeded'
698)             assert (
699)                 result.stderr_bytes
700)             ), 'program did not print any error message'
701)             assert (
Marco Ricci Use better error message ha...

Marco Ricci authored 1 month ago

702)                 b'Cannot load config' in result.stderr_bytes
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

703)             ), 'program did not print the expected error message'
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

705)     def test_214b_export_settings_not_a_file(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

721)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

722)             assert result.exit_code > 0, 'program unexpectedly succeeded'
723)             assert (
724)                 result.stderr_bytes
725)             ), 'program did not print any error message'
726)             assert (
Marco Ricci Use better error message ha...

Marco Ricci authored 1 month ago

727)                 b'Cannot load config' in result.stderr_bytes
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

728)             ), 'program did not print the expected error message'
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

730)     def test_214c_export_settings_target_not_a_file(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

744)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

745)             assert result.exit_code > 0, 'program unexpectedly succeeded'
746)             assert (
747)                 result.stderr_bytes
748)             ), 'program did not print any error message'
749)             assert (
Marco Ricci Use better error message ha...

Marco Ricci authored 1 month ago

750)                 b'Cannot store config' in result.stderr_bytes
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

751)             ), 'program did not print the expected error message'
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

752) 
Marco Ricci Create the configuration di...

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

776)                 b'Cannot load config' in result.stderr_bytes
Marco Ricci Create the configuration di...

Marco Ricci authored 1 month ago

777)             ), 'program did not print the expected error message'
778) 
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

794)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

816)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

835)             )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

906)     def test_224_store_config_good(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

934) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

935)     @pytest.mark.parametrize(
936)         ['command_line', 'input', 'err_text'],
937)         [
938)             (
939)                 [],
940)                 b'',
Marco Ricci Fix error message capitaliz...

Marco Ricci authored 1 month ago

941)                 b'Cannot update global settings without actual settings',
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

942)             ),
943)             (
944)                 ['sv'],
945)                 b'',
Marco Ricci Fix error message capitaliz...

Marco Ricci authored 1 month ago

946)                 b'Cannot update service settings without actual settings',
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

947)             ),
Marco Ricci Fix error message capitaliz...

Marco Ricci authored 1 month ago

948)             (['--phrase', 'sv'], b'', b'No passphrase given'),
949)             (['--key'], b'', b'No valid SSH key selected'),
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

950)         ],
951)     )
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

952)     def test_225_store_config_fail(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1006) 
Marco Ricci Isolate tests properly and...

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1022) 
Marco Ricci Isolate tests properly and...

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

1035)         assert (
Marco Ricci Fix error message capitaliz...

Marco Ricci authored 1 month ago

1036)             b'No passphrase or key given' in result.stderr_bytes
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1037)         ), 'expected error message missing'
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

1038) 
Marco Ricci Create the configuration di...

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

1097)             result = runner.invoke(
1098)                 cli.derivepassphrase,
1099)                 ['--config', '-p'],
1100)                 catch_exceptions=False,
1101)                 input='abc\n',
1102)             )
1103)             assert result.exit_code != 0, 'program unexpectedly succeeded?!'
1104)             assert (
1105)                 b'Cannot store config' in result.stderr_bytes
1106)             ), 'program unexpectedly failed?!'
Marco Ricci Create the configuration di...

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

1112)         with (
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1179) [1] Egg and bacon
1180) [2] Egg, sausage and bacon
1181) [3] Egg and spam
1182) [4] Egg, bacon and spam
1183) [5] Egg, bacon, sausage and spam
1184) [6] Spam, bacon, sausage and spam
1185) [7] Spam, egg, spam, spam, bacon and spam
1186) [8] Spam, spam, spam, egg and spam
1187) [9] Spam, spam, spam, spam, spam, spam, baked beans, spam, spam, spam and spam
1188) [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

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1201)             try:
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1235) Boo.
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1257) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1284)     def test_203_repeated_config_deletion(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1285)         self,
1286)         monkeypatch: Any,
1287)         command_line: list[str],
Marco Ricci Consolidate `types` submodu...

Marco Ricci authored 1 month ago

1288)         config: _types.VaultConfig,
1289)         result_config: _types.VaultConfig,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1298)                 )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1304)                     config_readback = json.load(infile)
1305)                 assert config_readback == result_config
1306) 
1307)     def test_204_phrase_from_key_manually(self) -> None:
1308)         assert (
Marco Ricci Move `sequin` and `ssh_agen...

Marco Ricci authored 1 month ago

1309)             dpp.vault.Vault(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1310)                 phrase=DUMMY_PHRASE_FROM_KEY1, **DUMMY_CONFIG_SETTINGS
1311)             ).generate(DUMMY_SERVICE)
1312)             == DUMMY_RESULT_KEY1
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1313)         )
1314) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1333)     def test_227_get_suitable_ssh_keys(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

1338)         monkeypatch.setattr(
Marco Ricci Move `sequin` and `ssh_agen...

Marco Ricci authored 1 month ago

1339)             ssh_agent.SSHAgentClient, 'list_keys', tests.list_keys
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

1340)         )
Marco Ricci Move `sequin` and `ssh_agen...

Marco Ricci authored 1 month ago

1341)         hint: ssh_agent.SSHAgentClient | socket.socket | None
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1342)         match conn_hint:
1343)             case 'client':
Marco Ricci Move `sequin` and `ssh_agen...

Marco Ricci authored 1 month ago

1344)                 hint = ssh_agent.SSHAgentClient()
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1357)             exception = e
1358)         finally: