62317bc2b46db2cd7ea7686f742975f41bc1d507
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

1) # SPDX-FileCopyrightText: 2024 Marco Ricci <m@the13thletter.info>
2) #
3) # SPDX-License-Identifier: MIT
4) 
5) """Test passphrase generation via derivepassphrase.Vault."""
6) 
7) from __future__ import annotations
8) 
9) import math
10) from typing import Any
11) 
12) import derivepassphrase
13) import pytest
14) 
15) Vault = derivepassphrase.Vault
16) 
17) class TestVault:
18) 
19)     phrase = b'She cells C shells bye the sea shoars'
20)     google_phrase = rb': 4TVH#5:aZl8LueOT\{'
21)     twitter_phrase = rb"[ (HN_N:lI&<ro=)3'g9"
22) 
23)     @pytest.mark.parametrize(['service', 'expected'], [
24)         (b'google', google_phrase),
25)         ('twitter', twitter_phrase),
26)     ])
27)     def test_200_basic_configuration(self, service, expected):
28)         assert Vault(phrase=self.phrase).generate(service) == expected
29) 
30)     def test_201_phrase_dependence(self):
31)         assert (
32)             Vault(phrase=(self.phrase + b'X')).generate('google') ==
33)             b'n+oIz6sL>K*lTEWYRO%7'
34)         )
35) 
36)     def test_202_reproducibility_and_bytes_service_name(self):
37)         assert (
38)             Vault(phrase=self.phrase).generate(b'google') ==
39)             Vault(phrase=self.phrase).generate('google')
40)         )
41) 
42)     def test_203_reproducibility_and_bytearray_service_name(self):
43)         assert (
44)             Vault(phrase=self.phrase).generate(b'google') ==
45)             Vault(phrase=self.phrase).generate(bytearray(b'google'))
46)         )
47) 
48)     def test_210_nonstandard_length(self):
49)         assert (
50)             Vault(phrase=self.phrase, length=4).generate('google')
51)             == b'xDFu'
52)         )
53) 
54)     def test_211_repetition_limit(self):
55)         assert (
56)             Vault(phrase=b'', length=24, symbol=0, number=0,
57)                   repeat=1).generate('asd') ==
58)             b'IVTDzACftqopUXqDHPkuCIhV'
59)         )
60) 
61)     def test_212_without_symbols(self):
62)         assert (
63)             Vault(phrase=self.phrase, symbol=0).generate('google') ==
64)             b'XZ4wRe0bZCazbljCaMqR'
65)         )
66) 
67)     def test_213_no_numbers(self):
68)         assert (
69)             Vault(phrase=self.phrase, number=0).generate('google') ==
70)             b'_*$TVH.%^aZl(LUeOT?>'
71)         )
72) 
73)     def test_214_no_lowercase_letters(self):
74)         assert (
75)             Vault(phrase=self.phrase, lower=0).generate('google') ==
76)             b':{?)+7~@OA:L]!0E$)(+'
77)         )
78) 
79)     def test_215_at_least_5_digits(self):
80)         assert (
81)             Vault(phrase=self.phrase, length=8, number=5)
82)             .generate('songkick') == b'i0908.7['
83)         )
84) 
85)     def test_216_lots_of_spaces(self):
86)         assert (
87)             Vault(phrase=self.phrase, space=12)
88)             .generate('songkick') == b' c   6 Bq  % 5fR    '
89)         )
90) 
91)     def test_217_all_character_classes(self):
92)         assert (
93)             Vault(phrase=self.phrase, lower=2, upper=2, number=1,
94)                   space=3, dash=2, symbol=1)
95)             .generate('google') == b': : fv_wqt>a-4w1S  R'
96)         )
97) 
98)     def test_218_only_numbers_and_very_high_repetition_limit(self):
99)         generated = Vault(phrase=b'', length=40, lower=0, upper=0, space=0,
100)                           dash=0, symbol=0, repeat=4).generate('abcdef')
101)         forbidden_substrings = {b'0000', b'1111', b'2222', b'3333', b'4444',
102)                                 b'5555', b'6666', b'7777', b'8888', b'9999'}
103)         for substring in forbidden_substrings:
104)             assert substring not in generated
105) 
106)     def test_219_very_limited_character_set(self):
107)         generated = Vault(phrase=b'', length=24, lower=0, upper=0,
108)                           space=0, symbol=0).generate('testing')
109)         assert b'763252593304946694588866' == generated
110) 
111)     def test_220_character_set_subtraction(self):
112)         assert Vault._subtract(b'be', b'abcdef') == bytearray(b'acdf')
113) 
114)     @pytest.mark.parametrize(['length', 'settings', 'entropy'], [
115)         (20, {}, math.log2(math.factorial(20)) + 20 * math.log2(94)),
116)         (
117)             20,
118)             {'upper': 0, 'number': 0, 'space': 0, 'symbol': 0},
119)             math.log2(math.factorial(20)) + 20 * math.log2(26)
120)         ),
121)         (0, {}, float('-inf')),
122)         (0, {'lower': 0, 'number': 0, 'space': 0, 'symbol': 0}, float('-inf')),
123)         (1, {}, math.log2(94)),
124)         (1, {'upper': 0, 'lower': 0, 'number': 0, 'symbol': 0}, 0.0),
125)     ])
126)     def test_221_entropy(
127)         self, length: int, settings: dict[str, int], entropy: int
128)     ) -> None:
129)         v = Vault(length=length, **settings)  # type: ignore[arg-type]
130)         assert math.isclose(v._entropy(), entropy)
131)         assert v._estimate_sufficient_hash_length() > 0
132)         if math.isfinite(entropy) and entropy:
133)             assert (
134)                 v._estimate_sufficient_hash_length(1.0) ==
135)                 math.ceil(entropy / 8)
136)             )
137)         assert v._estimate_sufficient_hash_length(8.0) >= entropy
138) 
139)     def test_222_hash_length_estimation(self) -> None:
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 2 months ago

140)         v = Vault(phrase=self.phrase, lower=0, upper=0, number=0,
Marco Ricci Rename and regroup all test...

Marco Ricci authored 2 months ago

141)                    symbol=0, space=1, length=1)
Marco Ricci Fix style issues with ruff...

Marco Ricci authored 2 months ago

142)         assert v._entropy() == 0.0
143)         assert v._estimate_sufficient_hash_length() > 0