26973402aac5d216a66ae3fc8f2d7bcb0fd7ea89
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 Move `sequin` and `ssh_agen...

Marco Ricci authored 1 month ago

20) from derivepassphrase import 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,
311)         config: dpp.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 (
612)                 b'not a valid config' in result.stderr_bytes
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 (
702)                 b'cannot load config' in result.stderr_bytes
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 (
727)                 b'cannot load config' in result.stderr_bytes
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 (
750)                 b'cannot write config' in result.stderr_bytes
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 (
776)                 b'cannot load config' in result.stderr_bytes
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'',
941)                 b'cannot update global settings without actual settings',
942)             ),
943)             (
944)                 ['sv'],
945)                 b'',
946)                 b'cannot update service settings without actual settings',
947)             ),
948)             (['--phrase', 'sv'], b'', b'no passphrase given'),
949)             (['--key'], b'', b'no valid SSH key selected'),
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 (
1036)             b'no passphrase or key given' in result.stderr_bytes
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)
1097)             with pytest.raises(FileExistsError):
1098)                 runner.invoke(
1099)                     cli.derivepassphrase,
1100)                     ['--config', '-p'],
1101)                     catch_exceptions=False,
1102)                     input='abc\n',
1103)                 )
1104) 
Marco Ricci Add finished command-line i...

Marco Ricci authored 2 months ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

1109)         with (
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1198)             try:
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1232) Boo.
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1254) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1281)     def test_203_repeated_config_deletion(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1295)                 )
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1310)         )
1311) 
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1330)     def test_227_get_suitable_ssh_keys(
Marco Ricci Reformat everything with ruff

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1339)         match conn_hint:
1340)             case 'client':
Marco Ricci Move `sequin` and `ssh_agen...

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

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

Marco Ricci authored 1 month ago

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

Marco Ricci authored 2 months ago

1354)             exception = e
1355)         finally: