Commit | Line | Data |
---|---|---|
f49f6323 PD |
1 | #!/usr/bin/env python |
2 | # This Python file uses the following encoding: utf-8 | |
3 | ||
11cbb815 PD |
4 | # The software in this package is distributed under the GNU General |
5 | # Public License version 2 (with a special exception described below). | |
6 | # | |
7 | # A copy of GNU General Public License (GPL) is included in this distribution, | |
8 | # in the file COPYING.GPL. | |
9 | # | |
10 | # As a special exception, if other files instantiate templates or use macros | |
11 | # or inline functions from this file, or you compile this file and link it | |
12 | # with other works to produce a work based on this file, this file | |
13 | # does not by itself cause the resulting work to be covered | |
14 | # by the GNU General Public License. | |
15 | # | |
16 | # However the source code for this file must still be made available | |
17 | # in accordance with section (3) of the GNU General Public License. | |
18 | # | |
19 | # This exception does not invalidate any other reasons why a work based | |
20 | # on this file might be covered by the GNU General Public License. | |
21 | # | |
22 | # Copyright (c) 2016-2018 Intra2net AG <info@intra2net.com> | |
23 | ||
f49f6323 PD |
24 | import unittest |
25 | from traceback import print_exc | |
26 | from tempfile import mkstemp | |
27 | import os | |
0ba9936c | 28 | import sys |
f49f6323 PD |
29 | |
30 | from src.simple_cnf import SimpleCnf | |
ce20f5b6 | 31 | from src.simple_cnf import InvalidCnf |
f49f6323 PD |
32 | |
33 | TEST_SET = """ | |
34 | 1 USER,1: "admin" | |
35 | 2 (1) USER_DISABLED,0: "0" | |
36 | 3 (1) USER_FULLNAME,0: "Administrator" | |
37 | 4 (1) USER_GROUPWARE_FOLDER_CALENDAR,0: "INBOX/Kalender" | |
38 | 5 (1) USER_GROUPWARE_FOLDER_CONTACTS,0: "INBOX/Kontakte" | |
39 | 6 (1) USER_GROUPWARE_FOLDER_DRAFTS,0: "INBOX/Entwürfe" | |
40 | 7 (1) USER_GROUPWARE_FOLDER_NOTES,0: "INBOX/Notizen" | |
41 | 8 (1) USER_GROUPWARE_FOLDER_OUTBOX,0: "INBOX/Gesendete Elemente" | |
42 | 9 (1) USER_GROUPWARE_FOLDER_TASKS,0: "INBOX/Aufgaben" | |
43 | 10 (1) USER_GROUPWARE_FOLDER_TRASH,0: "INBOX/Gelöschte Elemente" | |
44 | 11 (1) USER_GROUP_MEMBER_REF,0: "1" | |
45 | 12 (1) USER_GROUP_MEMBER_REF,1: "2" | |
46 | 13 (1) USER_LOCALE,0: "" | |
47 | 14 (1) USER_PASSWORD,0: "test1234" | |
48 | 15 (1) USER_TRASH_DELETEDAYS,0: "30" | |
49 | 16 USER,2: "test" | |
50 | 17 (16) USER_DISABLED,0: "0" | |
51 | 18 (16) USER_EMAIL_VACATION,0: "ON" | |
52 | 19 (16) USER_EMAIL_VACATION_AUTOMATIC_END,0: "" | |
53 | 20 (16) USER_EMAIL_VACATION_AUTOMATIC_START,0: "" | |
54 | 21 (16) USER_EMAIL_VACATION_AUTOMATIC_STATE,0: "UNKNOWN" | |
55 | 22 (16) USER_EMAIL_VACATION_REPLYDAYS,0: "1" | |
56 | 23 (16) USER_EMAIL_VACATION_TEXT,0: "Bin im Urlaub" | |
57 | 24 (16) USER_FULLNAME,0: "testnutzer" | |
58 | 25 (16) USER_GROUPWARE_FOLDER_CALENDAR,0: "INBOX/Kalender" | |
59 | 26 (16) USER_GROUPWARE_FOLDER_CONTACTS,0: "INBOX/Kontakte" | |
60 | 27 (16) USER_GROUPWARE_FOLDER_DRAFTS,0: "INBOX/Entwürfe" | |
61 | 28 (16) USER_GROUPWARE_FOLDER_NOTES,0: "INBOX/Notizen" | |
62 | 29 (16) USER_GROUPWARE_FOLDER_OUTBOX,0: "INBOX/Gesendete Elemente" | |
63 | 30 (16) USER_GROUPWARE_FOLDER_TASKS,0: "INBOX/Aufgaben" | |
64 | 31 (16) USER_GROUPWARE_FOLDER_TRASH,0: "INBOX/Gelöschte Elemente" | |
65 | 32 (16) USER_GROUP_MEMBER_REF,0: "2" | |
66 | 33 (16) USER_GROUP_MEMBER_REF,1: "3" | |
67 | 34 (16) USER_LOCALE,0: "" | |
68 | 35 (16) USER_PASSWORD,0: "test1234" | |
69 | 36 (16) USER_TRASH_DELETEDAYS,0: "30" | |
70 | 37 (16) USER_WEBMAIL_MESSAGES_PER_PAGE,0: "25" | |
71 | 38 (16) USER_WEBMAIL_SIGNATURE,0: "" | |
72 | 39 USER,3: "mueller" | |
73 | 40 (39) USER_DISABLED,0: "0" | |
74 | 41 (39) USER_FULLNAME,0: "Kärößü" | |
75 | 42 (39) USER_GROUPWARE_FOLDER_CALENDAR,0: "INBOX/Kalender" | |
76 | 43 (39) USER_GROUPWARE_FOLDER_CONTACTS,0: "INBOX/Kontakte" | |
77 | 44 (39) USER_GROUPWARE_FOLDER_DRAFTS,0: "INBOX/Entwürfe" | |
78 | 45 (39) USER_GROUPWARE_FOLDER_NOTES,0: "INBOX/Notizen" | |
79 | 46 (39) USER_GROUPWARE_FOLDER_OUTBOX,0: "INBOX/Gesendete Elemente" | |
80 | 47 (39) USER_GROUPWARE_FOLDER_TASKS,0: "INBOX/Aufgaben" | |
81 | 48 (39) USER_GROUPWARE_FOLDER_TRASH,0: "INBOX/Gelöschte Elemente" | |
82 | 49 (39) USER_GROUP_MEMBER_REF,0: "2" | |
83 | 50 (39) USER_GROUP_MEMBER_REF,1: "3" | |
84 | 51 (39) USER_LOCALE,0: "" | |
85 | 52 (39) USER_PASSWORD,0: "grmpfl" | |
86 | 53 (39) USER_TRASH_DELETEDAYS,0: "30" | |
87 | 54 (39) USER_WEBMAIL_MESSAGES_PER_PAGE,0: "25" | |
88 | 55 (39) USER_WEBMAIL_SIGNATURE,0: "" | |
89 | 56 BACKUP_COMPRESS_ENABLE,0: "1" | |
90 | 57 BACKUP_CRON,0: "0123456" | |
91 | 58 (57) BACKUP_CRON_BEGIN,0: "7200" | |
92 | 59 BACKUP_ENCRYPT_ENABLE,0: "0" | |
93 | 60 BACKUP_ENCRYPT_PASSWORD,0: "" | |
94 | 61 TESTVAR,0: "test" | |
95 | """ | |
96 | ||
0ba9936c CH |
97 | #: encoding for text files, set in :py:func:`setUpModule` |
98 | ENCODING = None | |
99 | ||
100 | ||
101 | def setUpModule(): | |
102 | """Called once before all tests; determines encoding | |
103 | ||
104 | This test might run in very limited build environments without locale, so | |
105 | auto-selection of temp-file text encoding may return 'ASCII'. | |
106 | Therefore, do the encoding "manually". | |
107 | """ | |
108 | global ENCODING | |
109 | ENCODING = sys.getfilesystemencoding() | |
110 | if ENCODING.lower() in ('ascii', 'ansi_x3.4-1968'): | |
111 | ENCODING = 'utf8' | |
8468f520 | 112 | print('\nWARNING: Using fallback encoding {} for temp file creation' |
0ba9936c CH |
113 | .format(ENCODING)) |
114 | ||
f49f6323 PD |
115 | |
116 | class SimpleCnfTest(unittest.TestCase): | |
117 | """ The one and only test case in this module `-->` see module doc """ | |
118 | ||
119 | # setup and cleanup | |
120 | ||
121 | import_file = None | |
122 | cnf = None | |
123 | ||
124 | @classmethod | |
125 | def _import_cnf(cls): | |
126 | """ import conf var data from temp file """ | |
127 | cls.cnf = SimpleCnf() | |
128 | cls.cnf.append_file(cls.import_file) | |
129 | ||
130 | @classmethod | |
131 | def setUpClass(cls): | |
132 | """ before running tests: write conf var string to temp file """ | |
133 | try: | |
0ba9936c | 134 | sys_file_descriptor, cls.import_file = mkstemp() |
f49f6323 | 135 | os.close(sys_file_descriptor) |
0ba9936c CH |
136 | with open(cls.import_file, 'wb') as file_handle: |
137 | file_handle.write(TEST_SET.encode(ENCODING)) | |
f49f6323 | 138 | except Exception: |
8468f520 | 139 | print('\nWARNING: exception creating temp file:') |
f49f6323 PD |
140 | print_exc() |
141 | ||
142 | # clean up | |
143 | cls.tearDownClass() | |
144 | ||
145 | # re-raise | |
146 | raise | |
147 | ||
148 | cls._import_cnf() | |
149 | ||
150 | @classmethod | |
151 | def tearDownClass(cls): | |
152 | """ after all tests have run, delete temp file """ | |
153 | if cls.import_file is not None: | |
154 | try: | |
155 | os.unlink(cls.import_file) | |
f49f6323 | 156 | except Exception: |
8468f520 | 157 | print('\nWARNING: exception deleting temp file:') |
f49f6323 PD |
158 | print_exc() |
159 | ||
160 | # tests | |
161 | ||
ce20f5b6 PG |
162 | def test_ctor_ok (self): |
163 | """ | |
164 | Test initializer :py:meth:`SimpleCnf.__init__` must succeed on sane | |
165 | inputs. | |
166 | """ | |
167 | self.assertNotEqual (SimpleCnf ({"cnf": []}), None) | |
168 | self.assertNotEqual (SimpleCnf ([]), None) | |
169 | self.assertNotEqual (SimpleCnf (), None) | |
170 | ||
171 | def test_ctor_fail (self): | |
172 | """ | |
173 | Test initializer :py:meth:`SimpleCnf.__init__` must reject inputs that | |
174 | ``cnfvar.py`` does not handle. | |
175 | """ | |
176 | with self.assertRaises (InvalidCnf): | |
177 | _void = SimpleCnf (b"junk") | |
178 | with self.assertRaises (InvalidCnf): | |
179 | _void = SimpleCnf (42) | |
180 | with self.assertRaises (InvalidCnf): | |
181 | _void = SimpleCnf (tuple ([1701, 1337])) | |
182 | with self.assertRaises (InvalidCnf): | |
183 | _void = SimpleCnf (set (["one", "two"])) | |
184 | ||
f49f6323 PD |
185 | def test_eq(self): |
186 | """ test method :py:meth:`SimpleCnf.__eq__` """ | |
187 | self.assertEqual(self.cnf[61], self.cnf[61]) | |
188 | self.assertEqual(self.cnf['testvar'], self.cnf[61]) | |
189 | self.assertEqual(self.cnf, self.cnf) | |
190 | self.assertNotEqual(self.cnf[56], self.cnf[57]) | |
ee39385c PG |
191 | self.assertNotEqual(SimpleCnf ({"cnf": []}), None) |
192 | self.assertNotEqual(SimpleCnf ({"cnf": []}), 42) | |
193 | self.assertNotEqual(SimpleCnf ({"cnf": []}), "got wood?") | |
194 | self.assertEqual(SimpleCnf (), SimpleCnf ({"cnf": []})) | |
f49f6323 PD |
195 | |
196 | def test_len(self): | |
197 | """ test method :py:meth:`SimpleCnf.__len__` """ | |
198 | self.assertEqual(len(self.cnf), 8) | |
199 | ||
200 | def test_getitem(self): | |
201 | """ test method :py:meth:`SimpleCnf.__item__` """ | |
202 | self.assertEqual(len(self.cnf['user']), 3) | |
203 | self.assertEqual(self.cnf['USER'], self.cnf['user']) | |
204 | self.assertEqual(len(self.cnf['backup_encrypt_password']), 1) | |
205 | self.assertEqual(len(self.cnf[12232]), 0) | |
206 | self.assertEqual(len(self.cnf[55]), 0) | |
207 | self.assertEqual(len(self.cnf[61]), 1) | |
208 | self.assertEqual(len(self.cnf['user_webmail_signature']), 0) | |
209 | ||
210 | def test_get(self): | |
211 | """ test method :py:meth:`SimpleCnf.get` """ | |
212 | self.assertEqual(len(self.cnf.get()), 8) | |
213 | self.assertEqual(len(self.cnf.get(name='user')), 3) | |
214 | ||
215 | def test_get_value(self): | |
216 | """ test method :py:meth:`SimpleCnf.get_value` """ | |
217 | ||
218 | with self.assertRaises(ValueError): | |
219 | self.cnf.get_value() | |
220 | ||
221 | self.assertEqual(self.cnf[56].get_value(), '1') | |
222 | self.assertEqual(self.cnf[61].get_value(), 'test') | |
223 | ||
224 | def test_get_children(self): | |
225 | """ test method :py:meth:`SimpleCnf.get_children` """ | |
226 | with self.assertRaises(ValueError): | |
227 | self.cnf.get_children() | |
f49f6323 PD |
228 | self.assertEqual(len(self.cnf.get(name='user', value='mueller') |
229 | .get_children()), 16) | |
cfcef185 PG |
230 | self.assertEqual(self.cnf.get(name='user'), |
231 | self.cnf.get(name='USER')) | |
232 | self.assertEqual(self.cnf.get(name='user', value='mueller'), | |
233 | self.cnf.get(name='USER', value='mueller')) | |
f49f6323 PD |
234 | self.assertEqual(len(self.cnf[57].get_children()), 1) |
235 | self.assertEqual(self.cnf[57].get_children().get_value(), '7200') | |
236 | ||
237 | def test_add_alone(self): | |
238 | """ test method :py:meth:`SimpleCnf.add` on empty conf """ | |
239 | # do not use self.cnf since that would void other test methods | |
240 | cnf = SimpleCnf() | |
241 | self.assertEqual(len(cnf), 0) | |
242 | cnf.add('new_var', 'new_value') | |
243 | self.assertEqual(len(cnf), 1) | |
244 | cnf_var = cnf.get(name='new_var').get_single_dict() | |
245 | self.assertEqual(cnf_var['data'], 'new_value') | |
246 | self.assertIsInstance(cnf_var['data'], str) | |
247 | self.assertEqual(cnf_var['number'], 1) | |
248 | ||
249 | def test_add_on_top(self): | |
250 | """ test method :py:meth:`SimpleCnf.add` on regular conf """ | |
251 | cnf = SimpleCnf() | |
252 | self.assertEqual(len(cnf), 0) | |
253 | cnf.append_file(self.import_file) | |
254 | self.assertEqual(len(cnf), 8) | |
255 | ||
256 | cnf.add('new_var', 'new_value') | |
257 | self.assertEqual(len(cnf), 9) | |
258 | cnf_var = cnf.get(name='new_var').get_single_dict() | |
259 | self.assertEqual(cnf_var['data'], 'new_value') | |
260 | self.assertIsInstance(cnf_var['data'], str) | |
261 | self.assertEqual(cnf_var['number'], 62) | |
262 | ||
263 | def test_add_with_children(self): | |
264 | """ test method :py:meth:`SimpleCnf.add` by adding var with children""" | |
265 | # load config | |
266 | cnf = SimpleCnf() | |
267 | cnf.append_file(self.import_file) | |
268 | self.assertEqual(len(cnf['user']), 3) | |
269 | ||
270 | # get a certain user with all its sub config | |
271 | user_cnf = cnf.get(name='user', value='admin') | |
272 | self.assertEqual(len(user_cnf), 1) | |
273 | ||
274 | # copy as new user with different name but same children | |
275 | cnf.add('user', 'admin2', children=user_cnf.get_children()) | |
276 | self.assertEqual(len(cnf['user']), 4) | |
277 | self.assertEqual(len(cnf.get(name='user', value='admin2')), 1) | |
278 | self.assertEqual(len(cnf.get(name='user', value='admin2').get_children()), 14) | |
279 | ||
280 | ||
281 | if __name__ == '__main__': | |
282 | unittest.main() |