2 # This Python file uses the following encoding: utf-8
4 # The software in this package is distributed under the GNU General
5 # Public License version 2 (with a special exception described below).
7 # A copy of GNU General Public License (GPL) is included in this distribution,
8 # in the file COPYING.GPL.
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.
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.
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.
22 # Copyright (c) 2016-2018 Intra2net AG <info@intra2net.com>
25 from traceback import print_exc
26 from tempfile import mkstemp
30 from src.simple_cnf import SimpleCnf
31 from src.simple_cnf import InvalidCnf
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"
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: ""
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: ""
97 #: encoding for text files, set in :py:func:`setUpModule`
102 """Called once before all tests; determines encoding
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".
109 ENCODING = sys.getfilesystemencoding()
110 if ENCODING.lower() in ('ascii', 'ansi_x3.4-1968'):
112 print('\nWARNING: Using fallback encoding {} for temp file creation'
116 class SimpleCnfTest(unittest.TestCase):
117 """ The one and only test case in this module `-->` see module doc """
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)
132 """ before running tests: write conf var string to temp file """
134 sys_file_descriptor, cls.import_file = mkstemp()
135 os.close(sys_file_descriptor)
136 with open(cls.import_file, 'wb') as file_handle:
137 file_handle.write(TEST_SET.encode(ENCODING))
139 print('\nWARNING: exception creating temp file:')
151 def tearDownClass(cls):
152 """ after all tests have run, delete temp file """
153 if cls.import_file is not None:
155 os.unlink(cls.import_file)
157 print('\nWARNING: exception deleting temp file:')
162 def test_ctor_ok (self):
164 Test initializer :py:meth:`SimpleCnf.__init__` must succeed on sane
167 self.assertNotEqual (SimpleCnf ({"cnf": []}), None)
168 self.assertNotEqual (SimpleCnf ([]), None)
169 self.assertNotEqual (SimpleCnf (), None)
171 def test_ctor_fail (self):
173 Test initializer :py:meth:`SimpleCnf.__init__` must reject inputs that
174 ``cnfvar.py`` does not handle.
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"]))
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])
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": []}))
197 """ test method :py:meth:`SimpleCnf.__len__` """
198 self.assertEqual(len(self.cnf), 8)
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)
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)
215 def test_get_value(self):
216 """ test method :py:meth:`SimpleCnf.get_value` """
218 with self.assertRaises(ValueError):
221 self.assertEqual(self.cnf[56].get_value(), '1')
222 self.assertEqual(self.cnf[61].get_value(), 'test')
224 def test_get_children(self):
225 """ test method :py:meth:`SimpleCnf.get_children` """
226 with self.assertRaises(ValueError):
227 self.cnf.get_children()
228 self.assertEqual(len(self.cnf.get(name='user', value='mueller')
229 .get_children()), 16)
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'))
234 self.assertEqual(len(self.cnf[57].get_children()), 1)
235 self.assertEqual(self.cnf[57].get_children().get_value(), '7200')
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
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)
249 def test_add_on_top(self):
250 """ test method :py:meth:`SimpleCnf.add` on regular conf """
252 self.assertEqual(len(cnf), 0)
253 cnf.append_file(self.import_file)
254 self.assertEqual(len(cnf), 8)
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)
263 def test_add_with_children(self):
264 """ test method :py:meth:`SimpleCnf.add` by adding var with children"""
267 cnf.append_file(self.import_file)
268 self.assertEqual(len(cnf['user']), 3)
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)
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)
281 if __name__ == '__main__':