add email to Person.all_names and Config.all_names
[utils.git] / src / budget_sync / test / test_config.py
1 import unittest
2 import io
3 from budget_sync.config import Config, ConfigParseError
4
5
6 class TestConfig(unittest.TestCase):
7 def test_config_parsing(self):
8 def check_error(text: str, expected_error_text: str):
9 with self.assertRaises(ConfigParseError) as e:
10 Config.from_str(text)
11 self.assertEqual(str(e.exception), expected_error_text)
12
13 def check(text: str, expected_repr_text: str):
14 self.assertEqual(repr(Config.from_str(text)), expected_repr_text)
15
16 check_error(
17 "bad-toml=",
18 "TOML parse error: Empty value is invalid "
19 "(line 1 column 1 char 0)")
20 check_error(
21 """
22 """,
23 "`bugzilla_url` field is missing")
24 check_error(
25 """
26 [bugzilla_url]
27 """,
28 "`bugzilla_url` must be a string")
29 check_error(
30 """
31 bugzilla_url = ""
32 """,
33 "`people` table is missing")
34 check_error(
35 """
36 blah = ""
37 """,
38 "unknown config entry: `blah`")
39 check_error(
40 """
41 bugzilla_url = ""
42 people = []
43 """,
44 "`people` field must be a table")
45 check_error(
46 """
47 bugzilla_url = ""
48 [people]
49 person1 = 1
50 """,
51 "person entry for 'person1' must be a table")
52 check_error(
53 """
54 bugzilla_url = ""
55 [people."person1"]
56 aliases = ""
57 """,
58 "`aliases` field in person entry for 'person1' must be a list "
59 "of strings")
60 check_error(
61 """
62 bugzilla_url = ""
63 [people."person1"]
64 aliases = [1]
65 """,
66 "`aliases` field in person entry for 'person1' must be a list "
67 "of strings")
68 check_error(
69 """
70 bugzilla_url = ""
71 [people."person1"]
72 aliases = ["a", "a"]
73 """,
74 "duplicate alias in person entry for 'person1': 'a'")
75 check_error(
76 """
77 bugzilla_url = ""
78 [people]
79 """,
80 "`milestones` table is missing")
81 check_error(
82 """
83 bugzilla_url = ""
84 [people."person1"]
85 """,
86 "`output_markdown_file` field is missing in person entry for "
87 "'person1'")
88 check_error(
89 """
90 bugzilla_url = ""
91 [people."person1"]
92 output_markdown_file = 1
93 """,
94 "`output_markdown_file` field in person entry for 'person1' must "
95 "be a string")
96 check(
97 """
98 bugzilla_url = ""
99 [milestones]
100 [people."person1"]
101 aliases = ["a"]
102 output_markdown_file = "person1.mdwn"
103 [people."person2"]
104 aliases = ["b"]
105 output_markdown_file = "person2.mdwn"
106 """,
107 "Config(bugzilla_url='', people={"
108 "'person1': Person(config=..., identifier='person1', "
109 "output_markdown_file='person1.mdwn', "
110 "aliases={'a'}, email=None), "
111 "'person2': Person(config=..., identifier='person2', "
112 "output_markdown_file='person2.mdwn', "
113 "aliases={'b'}, email=None)}, milestones={})")
114 check_error(
115 """
116 bugzilla_url = ""
117 [people."person1"]
118 email = 123
119 output_markdown_file = "person1.mdwn"
120 """,
121 "`email` field in person entry for 'person1' must be a string")
122 check(
123 """
124 bugzilla_url = ""
125 [people]
126 [milestones]
127 """,
128 "Config(bugzilla_url='', people={}, milestones={})")
129 check(
130 """
131 bugzilla_url = ""
132 [milestones]
133 [people."person1"]
134 email = "email@example.com"
135 output_markdown_file = "person1.mdwn"
136 """,
137 "Config(bugzilla_url='', people={"
138 "'person1': Person(config=..., identifier='person1', "
139 "output_markdown_file='person1.mdwn', "
140 "aliases=set(), email='email@example.com')}, milestones={})")
141 check_error(
142 """
143 bugzilla_url = ""
144 [people."person1"]
145 blah = 123
146 output_markdown_file = "person1.mdwn"
147 """,
148 "unknown field in person entry for 'person1': `blah`")
149 check_error(
150 """
151 bugzilla_url = ""
152 [milestones]
153 [people."person1"]
154 output_markdown_file = "person1.mdwn"
155 [people."person2"]
156 aliases = ["person1"]
157 output_markdown_file = "person2.mdwn"
158 """,
159 "alias is not allowed to be the same as any person's identifier: "
160 "in person entry for 'person2': 'person1' is also the identifier "
161 "for person 'person1'")
162 check_error(
163 """
164 bugzilla_url = ""
165 [milestones]
166 [people."person1"]
167 output_markdown_file = "person1.mdwn"
168 aliases = ["a"]
169 [people."person2"]
170 aliases = ["a"]
171 output_markdown_file = "person2.mdwn"
172 """,
173 "alias is not allowed to be the same as another person's alias or "
174 "email: in person entry for 'person2': 'a' is also an alias or "
175 "email for person 'person1'")
176 check_error(
177 """
178 bugzilla_url = ""
179 [milestones]
180 [people."person1"]
181 output_markdown_file = "person1.mdwn"
182 aliases = ["abc@example.com"]
183 [people."person2"]
184 email = "abc@example.com"
185 output_markdown_file = "person2.mdwn"
186 """,
187 "email is not allowed to be the same as another person's alias or "
188 "email: in person entry for 'person2': 'abc@example.com' is also "
189 "an alias or email for person 'person1'")
190 check_error(
191 """
192 bugzilla_url = ""
193 [milestones]
194 [people."person2"]
195 email = "abc@example.com"
196 output_markdown_file = "person2.mdwn"
197 [people."person1"]
198 output_markdown_file = "person1.mdwn"
199 aliases = ["abc@example.com"]
200 """,
201 "alias is not allowed to be the same as another person's alias or "
202 "email: in person entry for 'person1': 'abc@example.com' is also "
203 "an alias or email for person 'person2'")
204 check_error(
205 """
206 bugzilla_url = ""
207 [milestones]
208 "abc" = 1
209 [people]
210 """,
211 "milestones entry for 'abc' must be a table")
212 check_error(
213 """
214 bugzilla_url = ""
215 [milestones]
216 "abc" = { canonical_bug_id = "abc" }
217 [people]
218 """,
219 "`canonical_bug_id` field in milestones entry for 'abc' must "
220 "be an integer")
221 check_error(
222 """
223 bugzilla_url = ""
224 [milestones]
225 "abc" = { blah = "def" }
226 [people]
227 """,
228 "unknown field in milestones entry for 'abc': `blah`")
229 check_error(
230 """
231 bugzilla_url = ""
232 [milestones]
233 "abc" = {}
234 [people]
235 """,
236 "`canonical_bug_id` field is missing in milestones entry for 'abc'")
237 check_error(
238 """
239 bugzilla_url = ""
240 milestones = 1
241 [people]
242 """,
243 "`milestones` field must be a table")
244 check_error(
245 """
246 bugzilla_url = ""
247 [milestones]
248 "abc" = { canonical_bug_id = 1 }
249 "def" = { canonical_bug_id = 1 }
250 [people]
251 """,
252 "canonical_bug_id is not allowed to be the same as another "
253 "milestone's canonical_bug_id: in milestone entry for 'def': "
254 "1 is also the canonical_bug_id for milestone 'abc'")
255
256 def test_all_names(self):
257 config = Config.from_str(
258 """
259 bugzilla_url = ""
260 [milestones]
261 [people."person1"]
262 aliases = ["person1_alias1", "alias1"]
263 output_markdown_file = "person1.mdwn"
264 [people."person2"]
265 aliases = ["person2_alias2", "alias2"]
266 output_markdown_file = "person2.mdwn"
267 """)
268 person1 = config.people['person1']
269 person2 = config.people['person2']
270 self.assertEqual(config.all_names,
271 {
272 'person1': person1,
273 'person1_alias1': person1,
274 'alias1': person1,
275 'person2': person2,
276 'person2_alias2': person2,
277 'alias2': person2,
278 })
279
280 def test_canonical_bug_ids(self):
281 config = Config.from_str(
282 """
283 bugzilla_url = ""
284 [people]
285 [milestones]
286 "Milestone 1" = { canonical_bug_id = 1 }
287 "Milestone 2" = { canonical_bug_id = 2 }
288 """)
289 milestone1 = config.milestones['Milestone 1']
290 milestone2 = config.milestones['Milestone 2']
291 self.assertEqual(config.canonical_bug_ids,
292 {
293 1: milestone1,
294 2: milestone2,
295 })
296
297 def test_bugzilla_url_stripped(self):
298 c = Config.from_str(
299 """
300 bugzilla_url = "https://bugzilla.example.com/prefix"
301 [people]
302 [milestones]
303 """
304 )
305 self.assertEqual(c.bugzilla_url_stripped,
306 "https://bugzilla.example.com/prefix")
307 c = Config.from_str(
308 """
309 bugzilla_url = "https://bugzilla.example.com/prefix/"
310 [people]
311 [milestones]
312 """
313 )
314 self.assertEqual(c.bugzilla_url_stripped,
315 "https://bugzilla.example.com/prefix")
316 c = Config.from_str(
317 """
318 bugzilla_url = "https://bugzilla.example.com/"
319 [people]
320 [milestones]
321 """
322 )
323 self.assertEqual(c.bugzilla_url_stripped,
324 "https://bugzilla.example.com")
325
326 def test_from_file(self):
327 def load(text):
328 with io.StringIO(text) as file:
329 return Config.from_file(file)
330
331 with self.assertRaisesRegex(TypeError,
332 "^list is not a valid file or path$"):
333 Config.from_file([])
334
335 with self.assertRaisesRegex(
336 ConfigParseError,
337 "^TOML parse error: Empty value is invalid"):
338 load("""bad-toml=""")
339
340 self.assertEqual(str(load(
341 """
342 bugzilla_url = "https://bugzilla.example.com/"
343 [people."person1"]
344 email = "person1@example.com"
345 aliases = ["alias1"]
346 output_markdown_file = "person1.mdwn"
347 [milestones]
348 "Milestone 1" = { canonical_bug_id = 123 }
349 """)),
350 "Config(bugzilla_url='https://bugzilla.example.com/', "
351 "people={'person1': Person(config=..., identifier='person1', "
352 "output_markdown_file='person1.mdwn', "
353 "aliases={'alias1'}, email='person1@example.com')}, "
354 "milestones={'Milestone 1': Milestone(config=..., "
355 "identifier='Milestone 1', canonical_bug_id=123)})")
356
357
358 if __name__ == "__main__":
359 unittest.main()