Update baseconfig tests to use schema correctly.
[leap_pycommon.git] / src / leap / common / config / tests / test_baseconfig.py
1 # -*- coding: utf-8 -*-
2 # test_baseconfig.py
3 # Copyright (C) 2013 LEAP
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 """
18 Tests for baseconfig
19 """
20 import json
21 import unittest
22 import copy
23
24 from leap.common.config.baseconfig import BaseConfig, LocalizedKey
25 from leap.common.testing.basetest import BaseLeapTest
26
27 from mock import Mock
28
29 # reduced eipconfig sample config
30 sample_config = {
31     "gateways": [
32     {
33         "capabilities": {
34             "adblock": False,
35             "transport": ["openvpn"],
36             "user_ips": False
37         },
38         "host": "host.dev.example.org",
39     }, {
40         "capabilities": {
41             "adblock": False,
42             "transport": ["openvpn"],
43             "user_ips": False
44         },
45         "host": "host2.dev.example.org",
46     }
47     ],
48     "default_language": "en",
49     "languages": [
50         "en",
51         "es"
52     ],
53     "name": {
54         "en": "Baseconfig testing environment",
55         "es": "Entorno de pruebas de Baseconfig"
56     },
57     "serial": 1,
58     "version": 1
59 }
60
61 # reduced eipconfig.spec version
62 sample_spec = {
63     'description': 'sample eip service config',
64     'type': 'object',
65     'properties': {
66         'serial': {
67             'type': int,
68             'default': 1,
69             'required': ["True"]
70         },
71         'version': {
72             'type': int,
73             'default': 1,
74             'required': ["True"]
75         },
76         "default_language": {
77             'type': unicode,
78             'default': 'en'
79         },
80         'languages': {
81             'type': list,
82             'default': ['en']
83         },
84         'name': {
85             'type': dict,
86             'format': 'translatable',
87             'default': {u'en': u'Test Provider'}
88         },
89         'gateways': {
90             'type': list,
91             'default': [
92                 {"capabilities": {
93                     "adblock": True,
94                     "transport": ["openvpn"],
95                     "user_ips": False},
96                  "host": "location.example.org",
97                  }]
98         },
99     }
100 }
101
102
103 class TestConfig(BaseConfig):
104     """
105     BaseConfig implementation for testing purposes only.
106     """
107     def get_gateways(self):
108         return self._safe_get_value("gateways")
109
110     def get_serial(self):
111         return self._safe_get_value("serial")
112
113     def get_version(self):
114         return self._safe_get_value("version")
115
116     def _get_schema(self):
117         return sample_spec
118
119     def _get_spec(self):
120         return self._get_schema()
121
122     def get_default_language(self):
123         return self._safe_get_value("default_language")
124
125     @LocalizedKey
126     def get_name(self):
127         return self._safe_get_value("name")
128
129
130 class BaseConfigTest(BaseLeapTest):
131
132     def setUp(self):
133         pass
134
135     def tearDown(self):
136         pass
137
138     def _write_config(self, data):
139         """
140         Helper to write some data to a temp config file.
141
142         :param data: data to be used to save in the config file.
143         :data type: dict (valid json)
144         """
145         self.config_file = self.get_tempfile("config.json")
146         conf = open(self.config_file, "w")
147         conf.write(json.dumps(data))
148         conf.close()
149
150     def _get_config(self, fromfile=False, data=sample_config):
151         """
152         Helper that returns a TestConfig object using the data parameter
153         or a sample data.
154
155         :param fromfile: sets if we should use a file or a string
156         :fromfile type: bool
157         :param data: sets the data to be used to load in the TestConfig object
158         :data type: dict (valid json)
159         :rtype: TestConfig
160         """
161         config = TestConfig()
162
163         loaded = False
164         if fromfile:
165             self._write_config(data)
166             loaded = config.load(self.config_file, relative=False)
167         else:
168             json_string = json.dumps(data)
169             loaded = config.load(data=json_string)
170
171         if not loaded:
172             return None
173
174         return config
175
176     def test_loads_from_file(self):
177         config = self._get_config(fromfile=True)
178         self.assertIsNotNone(config)
179
180     def test_loads_from_data(self):
181         config = self._get_config()
182         self.assertIsNotNone(config)
183
184     def test_load_valid_config_from_file(self):
185         config = self._get_config(fromfile=True)
186         self.assertIsNotNone(config)
187
188         self.assertEqual(config.get_version(), sample_config["version"])
189         self.assertEqual(config.get_serial(), sample_config["serial"])
190         self.assertEqual(config.get_gateways(), sample_config["gateways"])
191
192     def test_load_valid_config_from_data(self):
193         config = self._get_config()
194         self.assertIsNotNone(config)
195
196         self.assertEqual(config.get_version(), sample_config["version"])
197         self.assertEqual(config.get_serial(), sample_config["serial"])
198         self.assertEqual(config.get_gateways(), sample_config["gateways"])
199
200     def test_safe_get_value_no_config(self):
201         config = TestConfig()
202
203         with self.assertRaises(AssertionError):
204             config.get_version()
205
206     def test_safe_get_value_non_existent_value(self):
207         config = self._get_config()
208
209         self.assertIsNone(config._safe_get_value('non-existent-value'))
210
211     def test_loaded(self):
212         config = self._get_config()
213         self.assertTrue(config.loaded())
214
215     def test_not_loaded(self):
216         config = TestConfig()
217         self.assertFalse(config.loaded())
218
219     def test_save_and_load(self):
220         config = self._get_config()
221         config.get_path_prefix = Mock(return_value=self.tempdir)
222         config_file = 'test_config.json'
223         self.assertTrue(config.save([config_file]))
224
225         config_saved = TestConfig()
226         config_file_path = self.get_tempfile(config_file)
227         self.assertTrue(config_saved.load(config_file_path, relative=False))
228
229         self.assertEqual(config.get_version(), config_saved.get_version())
230         self.assertEqual(config.get_serial(), config_saved.get_serial())
231         self.assertEqual(config.get_gateways(), config_saved.get_gateways())
232
233     def test_localizations(self):
234         conf = self._get_config()
235
236         self.assertEqual(conf.get_name(lang='en'), sample_config['name']['en'])
237         self.assertEqual(conf.get_name(lang='es'), sample_config['name']['es'])
238
239     def _localized_config(self, lang):
240         """
241         Helper to change default language of the provider config.
242         """
243         conf = copy.deepcopy(sample_config)
244         conf['default_language'] = lang
245         json_string = json.dumps(conf)
246         config = TestConfig()
247         config.load(data=json_string)
248
249         return config
250
251     def test_default_localization1(self):
252         default_language = sample_config['languages'][0]
253         config = self._localized_config(default_language)
254
255         default_name = sample_config['name'][default_language]
256
257         self.assertEqual(config.get_name(lang='xx'), default_name)
258         self.assertEqual(config.get_name(), default_name)
259
260     def test_default_localization2(self):
261         default_language = sample_config['languages'][1]
262         config = self._localized_config(default_language)
263
264         default_name = sample_config['name'][default_language]
265
266         self.assertEqual(config.get_name(lang='xx'), default_name)
267         self.assertEqual(config.get_name(), default_name)
268
269
270 if __name__ == "__main__":
271     unittest.main(verbosity=2)